Source of file Order.php
Size: 43,736 Bytes - Last Modified: 2021-12-24T06:40:39+00:00
/var/www/docs.ssmods.com/process/src/src/model/Order.php
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346 | <?php namespace Cita\eCommerce\Model; use SilverStripe\Core\Convert; use SilverStripe\Dev\Debug; use Cita\eCommerce\eCommerce; use SilverStripe\SiteConfig\SiteConfig; use SilverStripe\ORM\DataObject; use SilverStripe\Forms\TextField; use SilverStripe\Forms\TextareaField; use SilverStripe\Security\Member; use SilverStripe\Security\Security; use Cita\eCommerce\Model\Customer; use Cita\eCommerce\Model\Variant; use SilverStripe\Core\Config\Config; use Cita\eCommerce\API\DPS; use Cita\eCommerce\API\Poli; use Cita\eCommerce\API\Paystation; use Cita\eCommerce\Model\Freight; use SilverStripe\Control\Cookie; use Leochenftw\PdfInvoice\InvoicePrinter; use SilverStripe\Control\Email\Email; use SilverStripe\Control\Director; use Leochenftw\Grid; use Dynamic\CountryDropdownField\Fields\CountryDropdownField; use SilverStripe\Omnipay\Model\Payment; use Cita\eCommerce\Model\Bundle; use Leochenftw\Debugger; use Psr\Log\LoggerInterface; use SilverStripe\Forms\LiteralField; use SilverStripe\View\ViewableData; use SilverStripe\Core\Environment; /** * Description * * @package silverstripe * @subpackage mysite */ class Order extends DataObject implements \JsonSerializable { private static $dependencies = [ 'Logger' => '%$' . LoggerInterface::class, ]; /** * Defines the database table name * @var string */ private static $table_name = 'Cita_eCommerce_Order'; /** * Database fields * @var array */ private static $db = [ 'MerchantReference' => 'Varchar(64)', 'CustomerReference' => 'Varchar(8)', 'Status' => 'Enum("Pending,Invoice Pending,Debit Pending,Payment Received,Shipped,Cancelled,Refunded,CardCreated,Completed,Free Order")', 'AnonymousCustomer' => 'Varchar(128)', 'TotalAmount' => 'Currency', 'DiscountableTaxable' => 'Currency', 'DiscountableNonTaxable' => 'Currency', 'NonDiscountableTaxable' => 'Currency', 'NonDiscountableNonTaxable' => 'Currency', 'TaxIncludedTotal' => 'Currency', 'TotalWeight' => 'Decimal', 'PayableTotal' => 'Currency', 'Email' => 'Varchar(256)', 'ShippingFirstname' => 'Varchar(128)', 'ShippingSurname' => 'Varchar(128)', 'ShippingAddress' => 'Text', 'ShippingOrganisation' => 'Varchar(128)', 'ShippingApartment' => 'Varchar(64)', 'ShippingSuburb' => 'Varchar(128)', 'ShippingTown' => 'Varchar(128)', 'ShippingRegion' => 'Varchar(128)', 'ShippingCountry' => 'Varchar(128)', 'ShippingPostcode' => 'Varchar(128)', 'ShippingPhone' => 'Varchar(128)', 'SameBilling' => 'Boolean', 'BillingFirstname' => 'Varchar(128)', 'BillingSurname' => 'Varchar(128)', 'BillingAddress' => 'Text', 'BillingOrganisation' => 'Varchar(128)', 'BillingApartment' => 'Varchar(64)', 'BillingSuburb' => 'Varchar(128)', 'BillingTown' => 'Varchar(128)', 'BillingRegion' => 'Varchar(128)', 'BillingCountry' => 'Varchar(128)', 'BillingPostcode' => 'Varchar(128)', 'BillingPhone' => 'Varchar(128)', 'Comment' => 'Text', 'TrackingNumber' => 'Varchar(128)', 'ShippingCost' => 'Currency', 'Paidat' => 'Datetime', ]; private static $indexes = [ 'MerchantReference' => true, 'CustomerReference' => true ]; private static $cascade_deletes = [ 'Payments' ]; public function canView($member = null) { if (!$member) { $member = Security::getCurrentUser(); } if ($member && ($member->inGroup('administrators') || $this->CustomerID == $member->ID)) { return true; } if (!Environment::isCli()) { return $this->AnonymousCustomer == Cookie::get('eCommerceCookie'); } return parent::canView($member); } /** * Defines summary fields commonly used in table columns * as a quick overview of the data for this dataobject * @var array */ private static $summary_fields = [ 'ID' => 'ID', 'ItemCount' => 'Item(s)', 'Status' => 'Status' ]; /** * Defines a default list of filters for the search context * @var array */ private static $searchable_fields = [ 'ID', 'CustomerReference', 'ShippingFirstname', 'ShippingSurname', 'Status', ]; /** * Has_one relationship * @var array */ private static $has_one = [ 'Discount' => Discount::class, 'Customer' => Customer::class, 'Freight' => Freight::class, 'Snapshot' => OrderSnapshot::class, ]; /** * Default sort ordering * @var array */ private static $default_sort = [ 'Paidat' => 'DESC', 'ID' => 'DESC', ]; public function populateDefaults() { parent::populateDefaults(); $this->SameBilling = true; $member = Member::currentUser(); if (!Environment::isCli()) { $cookie = Cookie::get('eCommerceCookie'); if (empty($cookie)) { $cookie = session_id(); if (empty($cookie)) { session_start(); $cookie = session_id(); } Cookie::set('eCommerceCookie', $cookie, $expiry = 30); } } if (!empty($member) && $member->ClassName == Customer::class) { $this->CustomerID = $member->ID; } else { $this->AnonymousCustomer = !Environment::isCli() ? $cookie : 'CLI Imported'; } $this->MerchantReference = sha1(md5(round(microtime(true) * 1000) . '-' . session_id())); $this->CustomerReference = strtoupper(substr($this->MerchantReference, 0, 8)); if ($member && ($group = $member->Groups()->first())) { if ($group->Discount()->exists()) { $this->DiscountID = $group->DiscountID; } } } /** * Has_many relationship * @var array */ private static $has_many = [ 'Bundles' => BundleEntry::class, 'Payments' => Payment::class, 'Messages' => OrderMessage::class ]; private static $many_many = [ 'Variants' => Variant::class ]; private static $many_many_extraFields = [ 'Variants' => [ 'Quantity' => 'Decimal', 'isRefunded' => 'Boolean', 'Delivered' => 'Boolean', 'StoredTitle' => 'Varchar(128)', 'StoredUnitWeight' => 'Decimal', 'StoredUnitPrice' => 'Currency', 'StoredisDigital' => 'Boolean', 'StoredisExempt' => 'Boolean', 'StoredGSTIncluded' => 'Boolean', 'StoredNoDiscount' => 'Boolean', ] ]; public function getSuccessPayment() { if ($this->exists() && $this->Payments()->exists()) { return $this->Payments()->filter(['Status' => 'Captured'])->first(); } return null; } /** * CMS Fields * @return FieldList */ public function getCMSFields() { $fields = parent::getCMSFields(); $fields->removeByName([ 'SnapshotID', 'ShippingServiceName', 'MerchantReference', 'CustomerReference', 'AnonymousCustomer', 'TotalAmount', 'DiscountableTaxable', 'DiscountableNonTaxable', 'NonDiscountableTaxable', 'NonDiscountableNonTaxable', 'TaxIncludedTotal', 'TotalWeight', 'PayableTotal', 'Email', 'SameBilling', 'TrackingNumber', 'ShippingCost', 'Paidat', 'ShippingFirstname', 'ShippingSurname', 'ShippingOrganisation', 'ShippingApartment', 'ShippingSuburb', 'ShippingTown', 'ShippingRegion', 'ShippingCountry', 'ShippingPostcode', 'ShippingPhone', 'BillingFirstname', 'BillingSurname', 'BillingOrganisation', 'BillingApartment', 'BillingSuburb', 'BillingTown', 'BillingRegion', 'BillingCountry', 'BillingPostcode', 'Status', 'ShippingAddress', 'BillingAddress', 'BillingPhone', 'Comment', 'DiscountID', 'CustomerID', 'FreightID', 'Bundles', 'Variants', 'Messages', ]); $fields->addFieldToTab( 'Root.Main', LiteralField::create('OrderVue', ViewableData::create()->customise([ 'RawData' => json_encode($this->VueUIData), 'NonShippable' => empty($this->ShippableVariants) ? 1 : 0, 'ShippingAddressIncomplete' => $this->ShippingAddressIncomplete() ? 1 : 0, 'BillingAddressIncomplete' => $this->BillingAddressIncomplete() ? 1 : 0, ])->renderWith("Form\\Field\\OrderVue")), 'ShippingServiceName' ); return $fields; } protected function prep_pdf() { $siteconfig = SiteConfig::current_site_config(); $payment = $this->SuccessPayment; $invoice = new InvoicePrinter(); if ($siteconfig->StoreLogo()->exists()) { $invoice->setLogo($siteconfig->StoreLogo()->getAbsoluteURL()); //logo image path } $invoice->setColor("#000000"); // pdf color scheme $invoice->setType($payment ? "Receipt" : "Invoice"); // Invoice Type $invoice->setReference($this->CustomerReference); // Reference $invoice->setDate(date('d/m/Y', time())); //Billing Date $invoice->setTime(date('h:i:s A', time())); //Billing Time $billing_from = []; if (!empty($siteconfig->TradingName)) { $billing_from[] = $siteconfig->TradingName; } if (!empty($siteconfig->GST)) { $billing_from[] = 'GST Number: ' . $siteconfig->GST; } if (!empty($siteconfig->StoreLocation)) { $chunks = explode("\n", $siteconfig->StoreLocation); $billing_from = array_merge($billing_from, $chunks); } if (!empty($siteconfig->ContactEmail)) { $billing_from[] = $siteconfig->ContactEmail . ( !empty($siteconfig->ContactNumber) ? (', ' . $siteconfig->ContactNumber) : '' ); } $billing_to = []; $billing_to[] = trim($this->BillingFirstname . ' ' . $this->BillingSurname); $billing_to[] = 'Email: ' . $this->Email; if (!empty($this->BillingPhone)) { $billing_to[] = 'Phone: ' . $this->BillingPhone; } if (!empty($this->BillingOrganisation)) { $billing_to[] = $this->BillingOrganisation; } if (!empty($this->BillingApartment)) { $billing_to[] = $this->BillingApartment; } if (!empty($this->BillingAddress)) { $billing_to[] = $this->BillingAddress; } if (!empty($this->BillingSuburb)) { $billing_to[] = $this->BillingSuburb; } if (!empty($this->BillingTown)) { $billing_to[] = $this->BillingTown . (!empty($this->BillingRegion) ? (', ' . $this->BillingRegion) : ''); } if (!empty($this->BillingCountry)) { $billing_to[] = eCommerce::translate_country($this->BillingCountry) . (!empty($this->BillingPostcode) ? (', ' . $this->BillingPostcode) : ''); } $size = count($billing_from) > count($billing_to) ? count($billing_from) : count($billing_to); $billing_from = array_pad($billing_from, $size, ''); $billing_to = array_pad($billing_to, $size, ''); $invoice->setFrom($billing_from); $invoice->setTo($billing_to); $this->extend('createInvoiceRows', $invoice); if ($payment) { $invoice->addBadge("Payment Received"); } elseif ($this->Status == 'Free Order') { $invoice->addBadge("Free Order"); } else { $invoice->addBadge("Payment Outstanding"); $invoice->addTitle("Cheque payment"); } $this->extend('createInvoiceParagraph', $invoice); $invoice->setFooternote(SiteConfig::current_site_config()->Title); return $invoice; } public function download_invoice() { $invoice = $this->prep_pdf(); $siteconfig = SiteConfig::current_site_config(); return $invoice->render($siteconfig->TradingName . ' Invoice #' . $this->ID . '.pdf', 'D'); } public function send_invoice($skip_admin = false) { $siteconfig = SiteConfig::current_site_config(); $invoice = $this->prep_pdf(); $str = $invoice->render($siteconfig->TradingName . ' Reference - ' . $this->CustomerReference . '.pdf', 'S'); $from = Config::inst()->get(Email::class, 'noreply_email'); $to = $this->Email; if (!empty($to)) { $customer_sent_flag = ['sent' => false]; $this->extend('SendCustomerEmail', $from, $to, $str, $customer_sent_flag); if (!$customer_sent_flag['sent']) { $subject = $siteconfig->Title . ': order invoice #' . $this->ID; $email = Email::create($from, $to, $subject); $email->setBody('Hi, <br /><br />Please find your order invoice in the attachment.<br /><br />Kind regards<br />' . $siteconfig->Title . ' team'); $email->addAttachmentFromData($str, $siteconfig->TradingName . ' Invoice #' . $this->ID . '.pdf'); $email->send(); } } $admin_sent_flag = ['sent' => false]; $to_admin = !empty($siteconfig->OrderEmail) ? explode(',', $siteconfig->OrderEmail) : $siteconfig->ContactEmail; if (!empty($to_admin) && !$skip_admin) { $this->extend('SendAdminEmail', $from, $to_admin, $str, $admin_sent_flag); if (!$admin_sent_flag['sent']) { $admin_email = Email::create($from, $to_admin, $siteconfig->TradingName . ': New order received (#' . $this->ID . ')'); if (!empty($siteconfig->InvoiceBccEmail)) { $admin_email->setBCC($siteconfig->InvoiceBccEmail); } $admin_email->setBody('Hi, <br /><br />There is a new order. Please <a target="_blank" href="' . Director::absoluteBaseURL() . 'admin/orders/Cita-eCommerce-Model-Order/EditForm/field/Cita-eCommerce-Model-Order/item/' . $this->ID . '/edit' . '">click here</a> to view the details. <br /><br />' . $siteconfig->TradingName); $admin_email->send(); } } } public function ItemCount() { $bundled_items = 0; if ($this->Bundles()->exists()) { foreach ($this->Bundles() as $bundle) { $bundled_items += $bundle->Variants()->sum('Quantity'); } } return ($this->Variants()->exists() ? $this->Variants()->sum('Quantity') : 0) + $bundled_items ; } public function ShippableItemCount() { $count = 0; foreach ($this->Variants() as $v) { if ($v->isDigital) { continue; } $count++; } foreach ($this->Bundles() as $bundle) { foreach ($bundle->Variants() as $v) { if ($v->isDigital) { continue; } $count++; } } return $count; } public function UpdateAmountWeight() { $amount = 0; $weight = 0; $distax = 0; $nondistax = 0; $disnontax = 0; $nondisnontax = 0; $taxincluded = 0; foreach ($this->Variants() as $item) { $subtotal = $item->Price * $item->Quantity; $amount += $subtotal; $weight += $item->UnitWeight * $item->Quantity; if ($item->NoDiscount) { if ($item->isExempt || $item->GSTIncluded) { $nondisnontax += $subtotal; } else { $nondistax += $subtotal; } } else { if ($item->isExempt || $item->GSTIncluded) { $disnontax += $subtotal; } else { $distax += $subtotal; } } if ($item->GSTIncluded) { $taxincluded += $subtotal; } } foreach ($this->Bundles() as $item) { $subtotal = $item->Price * $item->Quantity; $amount += $subtotal; $weight += $item->UnitWeight * $item->Quantity; if ($item->Bundle()->NoDiscount) { if ($item->Bundle()->isExempt || $item->Bundle()->GSTIncluded) { $nondisnontax += $subtotal; } else { $nondistax += $subtotal; } } else { if ($item->Bundle()->isExempt || $item->Bundle()->GSTIncluded) { $disnontax += $subtotal; } else { $distax += $subtotal; } } if ($item->Bundle()->GSTIncluded) { $taxincluded += $subtotal; } } $this->TotalAmount = $amount; $this->TotalWeight = $weight; $this->DiscountableTaxable = $distax; $this->DiscountableNonTaxable = $disnontax; $this->NonDiscountableTaxable = $nondistax; $this->NonDiscountableNonTaxable = $nondisnontax; $this->TaxIncludedTotal = $taxincluded; $this->PayableTotal = $this->CalculatePayableTotal(); $this->extend('updateOrderFields', $this); $this->write(); } public function makeSnapshot() { if ($this->Snapshot()->exists()) { $this->Snapshot()->delete(); } $this->SnapshotID = OrderSnapshot::create()->StoreJSON($this); $this->write(); } public function completePayment($status) { if ($this->Status == 'Payment Received' || $this->Status == 'Shipped' || $this->Status == 'Cancelled' || $this->Status == 'Refunded' || $this->Status == 'Completed') { return false; } if ($status != 'CardCreated' && $status != 'Captured' && $status != 'Invoice Pending' && $status != 'Debit Pending' && $status != 'Free Order') { return false; } if ($status == 'Success' || $status == 'Captured') { $this->Status = 'Payment Received'; } else { $this->Status = $status; } if ($status == 'Free Order') { $this->Paidat = time(); } if ($this->Snapshot()->exists()) { $this->Snapshot()->delete(); } $this->SnapshotID = OrderSnapshot::create()->StoreJSON($this); $this->write(); foreach ($this->Variants() as $item) { $this->Variants()->add($item->ID, [ 'StoredTitle' => $item->Title, 'StoredUnitWeight' => $item->UnitWeight, 'StoredUnitPrice' => $item->UnitPrice, 'StoredisDigital' => $item->isDigital, 'StoredisExempt' => $item->isExempt, 'StoredGSTIncluded' => $item->GSTIncluded, 'StoredNoDiscount' => $item->NoDiscount, ]); } if ($this->Status == 'Payment Received' || $this->Status == 'Shipped' || $this->Status == 'Free Order' || $this->Status == 'Completed') { if ($this->Discount()->exists()) { $discount = $this->Discount(); if (!$discount->InfiniteUse) { $discount->LifePoint--; } $discount->write(); } $this->extend('doPaymentSuccessAction', $this); if (empty($this->config()->no_send_invoice)) { $this->send_invoice(); } } } /** * Event handler called before writing to the database. */ public function onBeforeWrite() { parent::onBeforeWrite(); if (empty($this->CustomerReference)) { $this->CustomerReference = strtoupper(substr($this->MerchantReference, 0, 8)); } if (!$this->Customer()->exists() && Member::currentUser()) { if (Member::currentUser()->ClassName == Customer::class) { $this->CustomerID = Member::currentUser()->ID; } } if ($this->Status == 'Pending') { if ($this->SameBilling) { $this->BillingFirstname = $this->ShippingFirstname; $this->BillingSurname = $this->ShippingSurname; $this->BillingOrganisation = $this->ShippingOrganisation; $this->BillingApartment = $this->ShippingApartment; $this->BillingAddress = $this->ShippingAddress; $this->BillingSuburb = $this->ShippingSuburb; $this->BillingTown = $this->ShippingTown; $this->BillingRegion = $this->ShippingRegion; $this->BillingCountry = $this->ShippingCountry; $this->BillingPostcode = $this->ShippingPostcode; $this->BillingPhone = $this->ShippingPhone; } } elseif ($this->Status == 'Payment Received') { if ($this->isAllShipped()) { $this->Status = 'Shipped'; } } if ($payment = $this->SuccessPayment) { $this->Paidat = $payment->LastEdited; } } public function getDiscounted() { $dt = $this->DiscountableTaxable; $dnt = $this->DiscountableNonTaxable; return $this->Discount()->calc_discount($dt + $dnt); } public function getGST() { $dt = $this->DiscountableTaxable; $ndt = $this->NonDiscountableTaxable; $gst_rate = SiteConfig::current_site_config()->GSTRate; $discounted_taxable = $this->Discount()->exists() ? $this->Discount()->calc_discount($dt) : 0; $gst_base = $dt - $discounted_taxable + $ndt; $gst_base = $gst_base < 0 ? 0 : $gst_base; $gst = $gst_base * $gst_rate; return number_format($gst, 2); } public function getIncludedGST() { $gst_rate = SiteConfig::current_site_config()->GSTRate; $dis_amount = 0; if ($this->Discount()->exists()) { $dis_amount = $this->Discounted; } $includedGST = ($this->TaxIncludedTotal - $dis_amount) * $gst_rate / (1 + $gst_rate); return number_format($includedGST, 2); } public function send_tracking() { if ($this->Status == 'Payment Received') { $this->Status = 'Shipped'; $this->write(); } $siteconfig = SiteConfig::current_site_config(); $from = Config::inst()->get(Email::class, 'noreply_email'); $to = $this->Email; if (!empty($to)) { $customer_sent_flag = ['sent' => false]; $this->extend('SendTracking', $from, $to, $customer_sent_flag); if (!$customer_sent_flag['sent']) { $subject = $siteconfig->Title . ': order #' . $this->ID . ' has been dispatched'; $email = Email::create($from, $to, $subject); $email->setBody('Hi, <br /><br />The trakcing number for your order #' . $this->ID . ' is: ' . $this->TrackingNumber . '.<br /><br />Kind regards<br />' . $siteconfig->Title . ' team'); $email->send(); } } } public function refund() { if ($this->hasMethod('doRefund')) { return $this->doRefund(); } if ($this->Status == 'Payment Received' || $this->Status == 'Shipped' || $this->Status == 'Completed' ) { $this->Status = 'Refunded'; $this->write(); } } public function cheque_cleared() { if ($this->exists() && $this->Payments()->exists()) { $payment = $this->Payments()->filter(['Status' => 'Invoice Pending'])->first(); $payment->Status = 'Success'; $payment->write(); } $this->completePayment('Success'); } public function debit_cleared() { if ($this->exists() && $this->Payments()->exists()) { $payment = $this->Payments()->filter(['Status' => 'Debit Pending'])->first(); $payment->Status = 'Success'; $payment->write(); } $this->completePayment('Success'); } public function is_freeshipping() { $result = $this->extend('isFreeShipping'); if (!empty($result)) { return $result[0]; } return empty($this->ShippableVariants); } public function AddToCart($vid, $qty, $isupdate = false) { if ($variant = Variant::get()->byID($vid)) { if (empty($qty) || $qty <= 0) { $this->Variants()->removeByID($vid); } else { $count = $qty; if (!$isupdate) { if ($existing = $this->Variants()->byID($vid)) { $count += $existing->Quantity; } } $this->Variants()->add($vid, [ 'Quantity' => $count, 'StoredTitle' => $variant->Title, 'StoredUnitWeight' => $variant->UnitWeight, 'StoredUnitPrice' => $variant->Price, 'StoredisDigital' => $variant->isDigital, 'StoredisExempt' => $variant->isExempt, 'StoredGSTIncluded' => $variant->GSTIncluded, 'StoredNoDiscount' => $variant->NoDiscount ]); } if ($this->Discount()->exists()) { $this->DiscountID = 0; } $this->UpdateAmountWeight(); } return $this->getData(); } public function CheckOrderRoutine() { // check bundle $bundle = Bundle::MatchBundle($this); while ($bundle) { $bundle = Bundle::MatchBundle($this); } // // bundle and discount item count type cannot be used together! if ($this->Bundles()->exists()) { return; } if ($discount = Discount::get()->filter(['Type' => 'Item Count'])->first()) { if ($discount->CheckOrder($this)) { $this->DiscountID = $discount->ID; } else { $this->DiscountID = 0; } $this->UpdateAmountWeight(); } } public function Log($message, $admin = false) { OrderMessage::create([ 'Message' => $message, 'AdminUse' => $admin, 'OrderID' => $this->ID ])->write(); } public function getData() { if ($this->Status == 'Pending') { $this->CheckOrderRoutine(); } $amount = round($this->TotalAmount * 100) * 0.01; $gst = $this->GST; $data = [ 'id' => $this->ID, 'ref' => $this->CustomerReference, 'count' => $this->ItemCount(), 'messages' => $this->Messages()->filter(['Displayed' => false, 'AdminUse' => false])->getData(), 'items' => $this->Items, 'amount' => $amount, 'amounts' => [ 'discountable_taxable' => $this->DiscountableTaxable, 'discountable_nontaxable' => $this->DiscountableNonTaxable, 'nondiscountable_taxable' => $this->NonDiscountableTaxable, 'nondiscountable_nontaxable' => $this->NonDiscountableNonTaxable, 'gst_included_amount' => $this->TaxIncludedTotal ], 'gst' => $gst, 'gst_included' => $this->IncludedGST, 'grand_total' => $gst + $amount, 'weight' => $this->TotalWeight, 'comment' => $this->Comment, 'discount' => $this->Discount()->getData(), 'shipping_cost' => $this->ShippingCost ]; if ($this->Discount()->exists()) { $dt = $this->DiscountableTaxable; $dnt = $this->DiscountableNonTaxable; $data['discount']['amount'] = $this->Discounted; } $this->extend('getData', $data); return $data; } public function jsonSerialize() { return $this->Data; } public function getItems() { $items = $this->Variants()->sort(['ID' => 'ASC']); $list = []; foreach ($items as $item) { $list[] = array_merge( $item->Data, [ 'quantity' => $item->Quantity, 'delivered' => $item->Delivered, ] ); } $bundles = $this->Bundles(); foreach ($bundles as $bundled) { $list[] = $bundled->Data; } return $list; } public function digest(&$data, $cal_freight = true) { $this->Email = $data->email; $this->FreightID = $data->freight; $this->ShippingFirstname = $data->shipping->firstname; $this->ShippingSurname = $data->shipping->surname; $this->ShippingAddress = $data->shipping->address; $this->ShippingOrganisation = $data->shipping->org; $this->ShippingApartment = $data->shipping->apartment; $this->ShippingSuburb = $data->shipping->suburb; $this->ShippingTown = $data->shipping->town; $this->ShippingRegion = $data->shipping->region; $this->ShippingCountry = $data->shipping->country; $this->ShippingPostcode = $data->shipping->postcode; $this->ShippingPhone = $data->shipping->phone; $this->SameBilling = $data->same_addr; if (!$data->same_addr) { $this->BillingFirstname = $data->billing->firstname; $this->BillingSurname = $data->billing->surname; $this->BillingAddress = $data->billing->address; $this->BillingOrganisation = $data->billing->org; $this->BillingApartment = $data->billing->apartment; $this->BillingSuburb = $data->billing->suburb; $this->BillingTown = $data->billing->town; $this->BillingRegion = $data->billing->region; $this->BillingCountry = $data->billing->country; $this->BillingPostcode = $data->billing->postcode; $this->BillingPhone = $data->billing->phone; } if (!empty($data->discount)) { if ($discount = Discount::check_valid(Convert::raw2sql($data->discount->code))) { $this->DiscountID = $discount->ID; } else { $this->DiscountID = 0; } } else { $this->DiscountID = 0; } $this->Comment = !empty($data->comment) ? $data->comment : null; if ($cal_freight) { if ($freight = $this->get_freight_data()) { if (is_array($freight)) { $this->ShippingCost = $freight['cost']; $this->ShippingServiceName = $freight['title']; } } else { $this->ShippingCost = 0; } } $this->extend('ExtraDigest', $data); $this->UpdateAmountWeight(); } public function get_freight_data() { if ($this->is_freeshipping()) { return [ 'title' => 'Free shipping', 'cost' => 0 ]; } elseif ($this->Freight()->exists()) { $freight = $this->Freight(); try { $result = $freight->Calculate($this); return $result; } catch (\Exception $e) { } } return null; } public function CalculatePayableTotal() { $dt = $this->DiscountableTaxable; $dnt = $this->DiscountableNonTaxable; $ndt = $this->NonDiscountableTaxable; $ndnt = $this->NonDiscountableNonTaxable; $gst_rate = SiteConfig::current_site_config()->GSTRate; $shipping = $this->ShippingCost; $discounted_taxable = $this->Discount()->exists() ? $this->Discount()->calc_discount($dt) : 0; $nondiscounted_taxable = $this->Discount()->exists() ? $this->Discount()->calc_discount($dnt) : 0; $discounted = $this->Discount()->exists() ? $this->Discount()->calc_discount($dt + $dnt) : 0; $gst_base = $dt - $discounted_taxable + $ndt; $gst_base = $gst_base < 0 ? 0 : $gst_base; $gst = $gst_base * $gst_rate; return $this->TotalAmount - $discounted + $gst + $shipping; } public function getShippingData($translate_country = true) { return [ 'firstname' => $this->ShippingFirstname, 'surname' => $this->ShippingSurname, 'org' => $this->ShippingOrganisation, 'address' => $this->ShippingAddress, 'apartment' => $this->ShippingApartment, 'suburb' => $this->ShippingSuburb, 'town' => $this->ShippingTown, 'region' => $this->ShippingRegion, 'country_code' => $this->ShippingCountry, 'country' => $translate_country ? eCommerce::translate_country($this->ShippingCountry) : $this->ShippingCountry, 'postcode' => $this->ShippingPostcode, 'phone' => $this->ShippingPhone ]; } public function getBillingData($translate_country = true) { return [ 'same_addr' => $this->SameBilling, 'firstname' => $this->BillingFirstname, 'surname' => $this->BillingSurname, 'org' => $this->BillingOrganisation, 'address' => $this->BillingAddress, 'apartment' => $this->BillingApartment, 'suburb' => $this->BillingSuburb, 'town' => $this->BillingTown, 'region' => $this->BillingRegion, 'country_code' => $this->BillingCountry, 'country' => $translate_country ? eCommerce::translate_country($this->BillingCountry) : $this->BillingCountry, 'postcode' => $this->BillingPostcode, 'phone' => $this->BillingPhone ]; } public function getAllVariants() { $variants = []; foreach ($this->Variants() as $v) { $variants[] = $v; } foreach ($this->Bundles() as $bundle) { foreach ($bundle->Variants() as $v) { $variants[] = $v; } } return $variants; } public function getAllVariantsStacked() { $variants = []; foreach ($this->Variants() as $v) { if (empty($variants[$v->ID])) { $variants[$v->ID] = $v; } else { $variants[$v->ID]->Quantity += $v->Quantity; } } foreach ($this->Bundles() as $bundle) { foreach ($bundle->Variants() as $v) { if (empty($variants[$v->ID])) { $variants[$v->ID] = $v; } else { $variants[$v->ID]->Quantity += $v->Quantity; } } } return $variants; } public function getDigitalVariants() { $variants = []; $this->extend('UpdateDigitalVariants', $variants); if (empty($variants)) { foreach ($this->Variants() as $v) { if (!$v->isDigital) { continue; } $variants[] = $v; } foreach ($this->Bundles() as $bundle) { foreach ($bundle->Variants() as $v) { if (!$v->isDigital) { continue; } $variants[] = $v; } } } return $variants; } public function getDigitalVariantsStacked() { $variants = []; $this->extend('UpdateDigitalVariantsStacked', $variants); if (empty($variants)) { foreach ($this->Variants() as $v) { if (!$v->isDigital) { continue; } if (empty($variants[$v->ID])) { $variants[$v->ID] = $v; } else { $variants[$v->ID]->Quantity += $v->Quantity; } } foreach ($this->Bundles() as $bundle) { foreach ($bundle->Variants() as $v) { if (!$v->isDigital) { continue; } if (empty($variants[$v->ID])) { $variants[$v->ID] = $v; } else { $variants[$v->ID]->Quantity += $v->Quantity; } } } } return $variants; } public function getShippableVariants() { $variants = []; foreach ($this->Variants() as $v) { if ($v->isDigital) { continue; } $variants[] = $v; } foreach ($this->Bundles() as $bundle) { foreach ($bundle->Variants() as $v) { if ($v->isDigital) { continue; } $variants[] = $v; } } return $variants; } public function getShippableVariantsStacked() { $variants = []; foreach ($this->Variants() as $v) { if ($v->isDigital) { continue; } if (empty($variants[$v->ID])) { $variants[$v->ID] = $v; } else { $variants[$v->ID]->Quantity += $v->Quantity; } } foreach ($this->Bundles() as $bundle) { foreach ($bundle->Variants() as $v) { if ($v->isDigital) { continue; } if (empty($variants[$v->ID])) { $variants[$v->ID] = $v; } else { $variants[$v->ID]->Quantity += $v->Quantity; } } } return $variants; } public function getDirectCartItemList() { if ($this->hasMethod('CustomDirectCartItemList')) { return $this->CustomDirectCartItemList(); } return null; } public function getCartItemList() { if ($this->hasMethod('CustomCartItemList')) { return $this->CustomCartItemList(); } $list = ''; foreach ($this->AllVariantsStacked as $vid => $variant) { $list .= "<li>$v->Title x $v->Quantity</li>"; } if (!empty($list)) { return "<ul style='padding-left: 1.5em; margin: 0;'>$list</ul>"; } return null; } public function getListData() { return [ 'Ref' => $this->CustomerReference, 'Items' => $this->ItemCount(), 'Details' => $this->CartItemList, 'Amount' => $this->PayableTotal, 'Status' => $this->Status, 'PaidAt' => $this->Paidat, ]; } public function isAllShipped() { foreach ($this->Variants() as $v) { if (!$v->isDigital && !$v->Delivered) { return false; } } foreach ($this->Bundles() as $bundle) { foreach ($bundle->Variants() as $v) { if (!$v->isDigital && !$v->Delivered) { return false; } } } return true; } public function getShippingCustomerFullname() { return trim("$this->ShippingFirstname $this->ShippingSurname"); } public function getBillingCustomerFullname() { return trim("$this->BillingFirstname $this->BillingSurname"); } public function getVueUIData() { $cartData = $this->Data; if (!empty(trim($cartData['comment']))) { $cartData['comment'] = '--------------<br />' . nl2br(trim($cartData['comment'])); } $data = [ 'title' => "Order#$this->ID", 'status' => $this->Status == 'Free Order' ? 'Payment Received' : $this->Status, 'payment' => $this->Payments()->first() ? $this->Payments()->first()->Data : null, 'cart' => $cartData, 'shipping' => $this->ShippingData, 'billing' => $this->BillingData, 'email' => $this->Email, 'freight' => $this->Freight()->exists() ? array_merge($this->Freight()->Data, ['price' => $this->ShippingCost]) : null, 'countries' => eCommerce::get_all_countries(), ]; $this->extend('UpdateVueUIData', $data); return $data; } public function getCommentText() { $comment = $this->Comment; if ($this->hasMethod('extraComment')) { $comment .= !empty(trim($comment)) ? "\n\n" : ''; $comment .= $this->extraComment(); } return $comment; } public function ShippingAddressIncomplete() { if (empty($this->ShippingAddress) || empty($this->ShippingTown) || empty($this->ShippingCountry) ) { return true; } return false; } public function BillingAddressIncomplete() { if ((empty($this->BillingAddress) || empty($this->BillingTown) || empty($this->BillingCountry)) && !$this->SameBilling) { return true; } return false; } } |