File: D:/HostingSpaces/SBogers10/topswtw.komma.pro/app/KommaApp/Shop/Orders/Order.php
<?php
/**
* Created by PhpStorm.
* User: mike
* Date: 13/01/15
* Time: 15:20
*/
namespace KommaApp\Shop\Orders;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Log;
use Komma\Kms\Shipments\Shipment;
use KommaApp\Shop\Shops\Models\Domain;
class Order extends Model
{
// Moet gelijk zijn aan back-end
const OPEN = "openstaand";
const PAYED = "betaald";
const SENT = "verzonden";
const COMPLETE = "voltooid";
const CANCELLED = "geannuleerd";
const TREATMENT = "in_behandeling";
const BACKORDER = "in_backorder";
const PARTLYSHIPPED = "gedeeltelijk_verzonden";
/*
* Fillable for invoice address
* Snake-case for they are database-table names
*/
protected $invoiceFillable = [
'invoice_id',
'invoice_gender',
'invoice_title',
'invoice_first_name',
'invoice_name_insertion',
'invoice_last_name',
'invoice_email',
'invoice_company',
'invoice_company_vat',
'invoice_postal',
'invoice_house_number',
'invoice_house_number_suffix',
'invoice_street',
'invoice_city',
'invoice_country',
'invoice_telephone',
];
/*
* Fillable for shipping address
* Snake-case for they are database-table names
*/
protected $shippingFillable = [
'shipping_gender',
'shipping_title',
'shipping_first_name',
'shipping_name_insertion',
'shipping_last_name',
'shipping_company',
'shipping_postal',
'shipping_house_number',
'shipping_house_number_suffix',
'shipping_street',
'shipping_city',
'shipping_country',
'shipping_telephone'
];
/*
* Total fillable for order
*/
protected $fillable = [
'order_number',
'shop_id',
'language_id',
'domain_country',
'customer_id',
'status',
'shipping_costs',
'price_total',
'original_price',
'discount_description',
'discount',
'discount_price',
'discount_percentage',
'coupon_code',
'ordered_at',
'payment_method',
'payment_date',
'payment_status',
'payment_currency',
'payment_acceptance',
'payment_card_number',
'payment_cardholder_name',
'payment_provider_id',
'payment_error_code',
'payment_card_brand',
'payment_ip',
'kiyoh_response',
'remarks',
'internal_remarks',
'original_order',
'dpd_carrier_shop_id',
'dpd_carrier_shop_details',
'product_total_ex'
];
function __construct()
{
$this->fillable = array_merge($this->fillable, $this->invoiceFillable, $this->shippingFillable);
}
public function createNewTransaction()
{
// Separator should be a dash, can't be an underscore
$transaction = new OrderTransaction([
'custom_identifier' => $this->order_number . '-' . (count($this->transactions) + 1)
]);
$this->transactions()->save($transaction);
return $transaction;
}
public static function findByCustomTransactionIdentifier($customTransactionIdentifier)
{
if(!$ot = OrderTransaction::where('custom_identifier', $customTransactionIdentifier)->first()) return false;
return $ot->order;
}
public static function getUnnotifiedOpenOrders()
{
return self::where('status', self::OPEN)
->whereNull('payment_open_notification_on')
->where('ordered_at', '<=', Carbon::now()->subDays(
\Config::get('komma/tops.openOrderNotificationDelayInDays')
))
->orderBy('invoice_email')
->get();
}
public static function getOrdersForFirstNotification()
{
$start = new \DateTime((\Config::get('komma/tops.openOrderFirstReminderInDays') + 1) . ' days ago');
$end = new \DateTime(\Config::get('komma/tops.openOrderFirstReminderInDays') . ' days ago');
return self::where('status', self::OPEN)
->whereNull('payment_open_notification_on')
->whereBetween('ordered_at', array($start, $end))
->whereHas('transactions', function ($query) {
$query->where('payment_method', 'not like', 'Bank transfer%');
})
->orderBy('invoice_email')
->get();
}
public static function getOrdersForSeccondNotification()
{
$start = new \DateTime((\Config::get('komma/tops.openOrderLastReminderInDays') + 1) . ' days ago');
$end = new \DateTime(\Config::get('komma/tops.openOrderLastReminderInDays') . ' days ago');
return self::where('status', self::OPEN)
->whereNull('payment_open_notification_reminder_on')
->whereBetween('ordered_at', array($start, $end))
->orderBy('invoice_email')
->get();
}
public static function getNotifiedOpenOrders()
{
return self::where('status', self::OPEN)
->whereNotNull('payment_open_notification_on')
->where('ordered_at', '<=', Carbon::now()->subDays(
\Config::get('komma/tops.openOrderReminderDelayInDays')
))
->orderBy('invoice_email')
->get();
}
public static function getOrdersReadyToShip()
{
return self::select('orders.*')
->leftJoin('order_shipment', 'order_shipment.order_id', '=', 'orders.id')
->where(function ($q) {
$q = $q->orWhere('status', self::TREATMENT);
$q = $q->whereNull('order_shipment.order_id');
})
->orWhere(function ($q) {
$q = $q->orWhere('status', self::PAYED);
$q = $q->orWhere('status', self::PARTLYSHIPPED);
})
->groupBy('orders.id')
->orderBy('shop_id')
->orderBy('created_at')
//todo check if they are not in an open shipment
->get();
}
public static function getBackorders()
{
return self::select('orders.*')
->leftJoin('order_shipment', 'order_shipment.order_id', '=', 'orders.id')
->Where(function ($q) {
$q = $q->orWhere('status', self::BACKORDER);
})
->groupBy('orders.id')
->orderBy('shop_id')
->orderBy('created_at')
->get();
}
public static function getOrdersForShipment($shipmentId)
{
return self::where('shipment_id', $shipmentId)
->with('customer')
->with('language')
->get();
}
public function language()
{
return $this->belongsTo('\Komma\Kms\Languages\Language');
}
public function products()
{
return $this->hasMany('\KommaApp\Shop\Orders\OrderProduct', 'order_id', 'id');
}
public function transactions()
{
return $this->hasMany('\KommaApp\Shop\Orders\OrderTransaction');
}
public function customer()
{
return $this->belongsTo('\KommaApp\Shop\Customers\Customer');
}
/**
* @return array
*/
public function invoiceFields()
{
return $this->invoiceFillable;
}
/**
* @return array
*/
public function shippingFields()
{
return $this->shippingFillable;
}
public function getFullInvoiceAddress()
{
$address = [];
if ($this->invoice_company) $address[] = $this->invoice_company;
$address[] = $this->getFullInvoiceName();
$address[] = $this->invoice_street . ' ' . $this->invoice_house_number . ($this->invoice_house_number_suffix != '' ? ' - ' . $this->invoice_house_number_suffix : '');
$address[] = $this->invoice_postal . ' ' . $this->invoice_city;
$address[] = \Lang::get('countries.' . strtoupper($this->invoice_country));
if ($this->invoice_telephone) $address[] = $this->invoice_telephone;
return implode('<br/>', $address);
}
public function getFullShippingAddress()
{
$address = [];
if ($this->shipping_company) $address[] = $this->shipping_company;
$address[] = $this->getFullShippingName();
$address[] = $this->shipping_street . ' ' . $this->shipping_house_number . ($this->shipping_house_number_suffix != '' ? ' - ' . $this->shipping_house_number_suffix : '');
$address[] = $this->shipping_postal . ' ' . $this->shipping_city;
$address[] = \Lang::get('countries.' . strtoupper($this->shipping_country));
if ($this->shipping_telephone) $address[] = $this->shipping_telephone;
return implode('<br/>', $address);
}
public function getFullDpdAddress()
{
$address = [];
if (!helper_isJSON($this->dpd_carrier_shop_details)) return '';
$dpdData = json_decode($this->dpd_carrier_shop_details);
$address[] = \Lang::get('checkout/checkout.dpd_name');
$address[] = $dpdData->company;
$address[] = $dpdData->street . ' ' . $dpdData->houseNo;
$address[] = $dpdData->zipCode . ' ' . $dpdData->city;
$address[] = \Lang::get('countries.' . strtoupper($dpdData->isoAlpha2));
return implode('<br/>', $address);
}
public function getFullInvoiceName()
{
$name = [];
if ($this->invoice_first_name) $name[] = $this->invoice_first_name;
if ($this->invoice_name_insertion) $name[] = $this->invoice_name_insertion;
if ($this->invoice_last_name) $name[] = $this->invoice_last_name;
return implode(' ', $name);
}
public function getFullInvoiceLastName()
{
$name = [];
if ($this->invoice_name_insertion) $name[] = ucfirst($this->invoice_name_insertion);
if ($this->invoice_last_name) $name[] = ucfirst($this->invoice_last_name);
return implode(' ', $name);
}
public function getFullShippingName()
{
$name = [];
if ($this->shipping_first_name) $name[] = $this->shipping_first_name;
if ($this->shipping_name_insertion) $name[] = $this->shipping_name_insertion;
if ($this->shipping_last_name) $name[] = $this->shipping_last_name;
return implode(' ', $name);
}
public function getSubTotal()
{
$subTotal = 0;
foreach ($this->products as $product) {
$subTotal += $product->price;
}
return $subTotal;
}
public function getSubTotalExVat()
{
$subTotal = 0;
foreach ($this->products as $product) {
$subTotal += $product->getPriceExVat();
}
return $subTotal;
}
public function getDiscountPriceExVat()
{
return round($this->getSubTotalExVat() * ($this->discount_percentage / 100));
}
public function getShippingCostsExVat()
{
return round($this->shipping_costs / (1 + ($this->getHighestProductTaxRate() / 100)));
}
public function getPriceTotalExVat()
{
return round($this->getSubTotalExVat() + $this->getShippingCostsExVat() - $this->getDiscountPriceExVat());
}
public static function getNewOrderNumber()
{
if (self::max('order_number') > 0) {
return self::max('order_number') + 1;
}
return \Config::get('komma/tops.orderNumberStart');
}
public static function getNewInvoiceId()
{
if (self::max('invoice_id') > 0) {
return self::max('invoice_id') + 1;
}
return \Config::get('komma/tops.invoiceIdStart');
}
public function getTaxTotals()
{
$taxTotals = [];
foreach ($this->products as $product) {
if (!isset($taxTotals[$product->tax_rate])) $taxTotals[$product->tax_rate] = [
'name' => $product->tax_name,
'total' => 0
];
$taxTotals[$product->tax_rate]['rate'] = $product->tax_rate;
$taxTotals[$product->tax_rate]['name'] = $product->tax_name;
$taxTotals[$product->tax_rate]['total'] += ($product->price - $product->getPriceExVat());
}
// Subtract order discount percentage
if (!isset($taxTotals[$this->getHighestProductTaxRate()])) {
//throw new \Exception('KMS: Invalid tax rate');
echo '||ERROR||';
return [];
}
$taxTotals[$this->getHighestProductTaxRate()]['total'] = $taxTotals[$this->getHighestProductTaxRate()]['total'] * (1 - ($this->discount_percentage / 100));
// Add shipping costs tax to highest tax rate
$taxTotals[$this->getHighestProductTaxRate()]['total'] += ($this->shipping_costs - $this->getShippingCostsExVat());
return $taxTotals;
}
public function getTotalToPay()
{
if ($this->invoice_company_vat && $this->invoice_country != 'NL')
return $this->getPriceTotalExVat();
return $this->price_total;
}
public function getVat()
{
return $this->price_total - $this->getPriceTotalExVat();
}
protected function getHighestProductTaxRate()
{
$highestTaxRate = 0;
foreach ($this->products as $product) {
if ($product->tax_rate > $highestTaxRate) $highestTaxRate = $product->tax_rate;
}
return $highestTaxRate;
}
public function getSalutation()
{
// Salutation
$salutation[] = \Lang::get('form.salutation_' . $this->invoice_title);
// Name
if ($this->invoice_name_insertion) $salutation[] = ucfirst($this->invoice_name_insertion);
if ($this->invoice_last_name) $salutation[] = $this->invoice_last_name;
return implode(' ', $salutation);
}
public function getInvoiceGender($input)
{
// Get gender from title
if ($input['invoice-title'] == 'mr') {
return 'male';
} else {
return 'female';
}
}
public function getGenderCodeShipping()
{
switch ($this->shipping_gender)
{
case 'male':
return '♂';
break;
case 'female':
return '♀';
break;
default:
return '⚥?';
}
}
public function getGenderCodeInvoice()
{
switch ($this->invoice_gender)
{
case 'male':
return '♂';
break;
case 'female':
return '♀';
break;
default:
return '⚥?';
}
}
public function getShippingGender($input)
{
// Get gender from title
if ($input['shipping-title'] == 'mr') {
return 'male';
} else {
return 'female';
}
}
public function getPaymentMethod()
{
if(!$this->transactions->last()) return '-';
return $this->transactions->last()->payment_method;
}
public function shipments()
{
// Let op: Frontend Model
return $this->belongsToMany('Komma\Kms\Shipments\Shipment')->withPivot('order_id');
}
public function getPaymentLink()
{
//if Order is canceld return status text CANCELLED
if ($this->status == $this::CANCELLED) return $this::CANCELLED;
//If the order isnot open return text PAYED
if ($this->status != $this::OPEN) return $this::PAYED;
//Load the url of shop where is payed
/***
* Select the domain string from Domains
* Where the domain country equals the domain country from the order
* Where the domain shop id equals the the order country
* With multiple results the domain witch is the shop.name gets the preference
*/
$domain = Domain::select('domains.domain', \Db::raw('IF( shops.name = domains.domain,1,0 ) as preferred_domain'))
->leftJoin('countries', 'countries.id', '=', 'domains.country_id')
->leftJoin('shops', 'shops.id', '=', 'domains.shop_id')
->where('domains.shop_id', '=', $this->shop_id)
->where('countries.iso_2', '=', $this->domain_country)
->orderBy('preferred_domain', 'DESC')
->first();
if (empty($domain)) return ' - ';
//Get the correct page
if (!$route = \Shop::getPageService()->getPageByShopAndLang('pendingPayment', $this->shop_id, $this->language_id)) return ' - ';
//Glue together
$url = 'http';
if (\Config::get('komma/tops.https')) $url .= 's';
$url .= '://';
if (\Config::get('komma/tops.www')) $url .= 'www.';
$url .= $domain->domain;
$url .= '/';
$url .= $route;
$url .= '?token=' . $this->order_token;
return $url;
}
public function googleEcommercePurchaseData()
{
$data = [
'ecommerce' => [
'purchase' => [
'actionField' => [
'id' => $this->order_number, // Transaction ID. Required for purchases and refunds.
'affiliation' => $this->shop_id,
'revenue' => $this->price_total / 100, // Total transaction value (incl. tax and shipping)
'shipping' => $this->shipping_costs / 100
],
'products' => [
]
],
]
];
foreach($this->products as $orderdProduct)
{
/** @var \KommaApp\Shop\Orders\OrderProduct $orderdProduct */
$data['ecommerce']['purchase']['products'][] = $orderdProduct->googleEcommerceProductFieldObjectData();
}
return $data;
}
}