public function parameterFields() { $fields = new FieldList(); // Check if any order exist if (Order::get()->exists()) { $first_order = Order::get()->sort('Created ASC')->first(); $months = array('All'); $statuses = Order::config()->statuses; array_unshift($statuses, 'All'); for ($i = 1; $i <= 12; $i++) { $months[] = date("F", mktime(0, 0, 0, $i + 1, 0, 0)); } // Get the first order, then count down from current year to that $firstyear = new SS_Datetime('FirstDate'); $firstyear->setValue($first_order->Created); $years = array(); for ($i = date('Y'); $i >= $firstyear->Year(); $i--) { $years[$i] = $i; } //Result Limit $result_limit_options = array(0 => 'All', 50 => 50, 100 => 100, 200 => 200, 500 => 500); $fields->push(DropdownField::create('Filter_Month', 'Filter by month', $months)); $fields->push(DropdownField::create('Filter_Year', 'Filter by year', $years)); $fields->push(DropdownField::create('Filter_Status', 'Filter By Status', $statuses)); $fields->push(DropdownField::create("ResultsLimit", "Limit results to", $result_limit_options)); } return $fields; }
function export() { $orders = Order::get()->innerJoin("Address", "\"Order\".\"ShippingAddressID\" = \"Address\".\"ID\"")->filter("SentToDispatchIT", 0)->filter("Status", Order::config()->placed_status)->filter("Address.Country", "NZ")->sort(array("Placed" => "ASC", "Created" => "ASC")); $output = ""; if ($orders->exists()) { foreach ($orders as $order) { $address = $order->getShippingAddress(); $name = $address->Company; //TODO: company if (!$name || $name == "") { $name = $order->Name; } $line = array($order->ID, $order->MemberID, $name, $address->Address, $address->AddressLine2, $address->Suburb, $address->State, $address->City, "", "0", "1", "", $address->Phone, "", $order->Fax, $order->Email, "1", "", "0", "", "0"); $output .= implode("\t", $line) . "\n"; $order->SentToDispatchIT = true; $order->write(); } //store output in a local file, then output the contents, or a link to the file //name format: DDcxxxxxxx.TXT $filename = "DDc" . uniqid() . "_" . date('YmdHis') . ".txt"; $exportpath = ASSETS_PATH . "/_dispatchitexports"; if (!is_dir($exportpath)) { mkdir($exportpath); } if (file_put_contents($exportpath . "/{$filename}", $output) === false) { $output = "failed to save file"; } } else { $output = "no new orders"; } header('Content-type: text/plain'); echo $output; die; }
/** * Return all past orders for current member / session. */ public function PastOrders($paginated = false) { $orders = $this->allorders()->filter("Status", Order::config()->placed_status); if ($paginated) { $orders = new PaginatedList($orders, $this->owner->getRequest()); } return $orders; }
/** * Behaviour can be overwritten by creating a processPaymentResponse method * on the controller owning this form. It takes a Symfony\Component\HttpFoundation\Response argument, * and expects an SS_HTTPResponse in return. */ public function submitpayment($data, $form) { $data = $form->getData(); if ($this->getSuccessLink()) { $data['returnUrl'] = $this->getSuccessLink(); } $data['cancelUrl'] = $this->getFailureLink() ? $this->getFailureLink() : $this->controller->Link(); $order = $this->config->getOrder(); // final recalculation, before making payment $order->calculate(); // handle cases where order total is 0. Note that the order will appear // as "paid", but without a Payment record attached. if ($order->GrandTotal() == 0 && Order::config()->allow_zero_order_total) { if (!$this->orderProcessor->placeOrder()) { $form->sessionMessage($this->orderProcessor->getError()); return $this->controller->redirectBack(); } return $this->controller->redirect($this->getSuccessLink()); } // try to place order before payment, if configured if (Order::config()->place_before_payment) { if (!$this->orderProcessor->placeOrder()) { $form->sessionMessage($this->orderProcessor->getError()); return $this->controller->redirectBack(); } $data['cancelUrl'] = $this->orderProcessor->getReturnUrl(); } // if we got here from checkoutSubmit and there's a namespaced OnsitePaymentCheckoutComponent // in there, we need to strip the inputs down to only the checkout component. $components = $this->config->getComponents(); if ($components->first() instanceof CheckoutComponent_Namespaced) { foreach ($components as $component) { if ($component->Proxy() instanceof OnsitePaymentCheckoutComponent) { $data = $component->unnamespaceData($data); } } } // This is where the payment is actually attempted $paymentResponse = $this->orderProcessor->makePayment(Checkout::get($order)->getSelectedPaymentMethod(false), $data); $response = null; if ($paymentResponse) { if ($this->controller->hasMethod('processPaymentResponse')) { $response = $this->controller->processPaymentResponse($paymentResponse, $form); } else { if ($paymentResponse->isRedirect() || $paymentResponse->isSuccessful()) { $response = $paymentResponse->redirect(); } else { $form->sessionMessage($paymentResponse->getMessage(), 'bad'); $response = $this->controller->redirectBack(); } } } else { $form->sessionMessage($this->orderProcessor->getError(), 'bad'); $response = $this->controller->redirectBack(); } return $response; }
public function testModifierCalculation() { $order = $this->createOrder(); $this->assertEquals(510, $order->calculate(), "Total with 25% tax"); //remove modifiers Order::config()->modifiers = null; $order->calculate(); $this->assertEquals(408, $order->calculate(), "Total with no modification"); }
/** * Restrict list to non-hidden statuses */ public function getList() { $context = $this->getSearchContext(); $params = $this->request->requestVar('q'); //TODO update params DateTo, to include the day, ie 23:59:59 $list = $context->getResults($params)->exclude("Status", Order::config()->hidden_status); //exclude hidden statuses $this->extend('updateList', $list); return $list; }
public function setUp() { parent::setUp(); ShopTest::setConfiguration(); Order::config()->modifiers = array("FlatTaxModifier"); FlatTaxModifier::config()->name = "GST"; FlatTaxModifier::config()->rate = 0.15; $this->cart = ShoppingCart::singleton(); $this->mp3player = $this->objFromFixture('Product', 'mp3player'); $this->mp3player->publish('Stage', 'Live'); }
public function onBeforeInit() { $controller = $this->owner->request->param("Controller"); $action = $this->owner->request->param("Action"); if ($controller != "DevelopmentAdmin" && $action != "build") { $config = SiteConfig::current_site_config(); // Set the default currency symbol for this site Currency::config()->currency_symbol = Checkout::config()->currency_symbol; // Auto inject the order prefix to the orders module if it exists if (class_exists("Order") && class_exists("SiteConfig") && $config) { Order::config()->order_prefix = $config->PaymentNumberPrefix; } } }
public function getCMSFields() { $fields = parent::getCMSFields(); $status_field = DropdownField::create("Status", $this->fieldLabel("Status"), Order::config()->statuses); $fields->replaceField("Status", $status_field); $vendor = $fields->dataFieldByName("VendorEmail"); if ($vendor) { $vendor->setDescription(_t("Orders.VendorEmailDescription", "Only needed when notification sent to vendor (or both)")); } $subject = $fields->dataFieldByName("CustomSubject"); if ($subject) { $subject->setDescription(_t("Orders.CustomSubjectDescription", "Overwrite the default subject created in the notification email")); } return $fields; }
/** * Behaviour can be overwritten by creating a processPaymentResponse method * on the controller owning this form. It takes a Symfony\Component\HttpFoundation\Response argument, * and expects an SS_HTTPResponse in return. */ public function submitpayment($data, $form) { $data = $form->getData(); if ($this->getSuccessLink()) { $data['returnUrl'] = $this->getSuccessLink(); } $data['cancelUrl'] = $this->getFailureLink() ? $this->getFailureLink() : $this->controller->Link(); $order = $this->config->getOrder(); //final recalculation, before making payment $order->calculate(); //handle cases where order total is 0. Note that the order will appear //as "paid", but without a Payment record attached. if ($order->GrandTotal() == 0 && Order::config()->allow_zero_order_total) { if (!$this->orderProcessor->placeOrder()) { $form->sessionMessage($this->orderProcessor->getError()); return $this->controller->redirectBack(); } return $this->controller->redirect($this->getSuccessLink()); } //try to place order before payment, if configured if (Order::config()->place_before_payment) { if (!$this->orderProcessor->placeOrder()) { $form->sessionMessage($this->orderProcessor->getError()); return $this->controller->redirectBack(); } $data['cancelUrl'] = $this->orderProcessor->getReturnUrl(); } $paymentResponse = $this->orderProcessor->makePayment(Checkout::get($order)->getSelectedPaymentMethod(false), $data); $response = null; if ($paymentResponse) { if ($this->controller->hasMethod('processPaymentResponse')) { $response = $this->controller->processPaymentResponse($paymentResponse, $form); } else { if ($paymentResponse->isRedirect() || $paymentResponse->isSuccessful()) { $response = $paymentResponse->redirect(); } else { $form->sessionMessage($paymentResponse->getMessage(), 'bad'); $response = $this->controller->redirectBack(); } } } else { $form->sessionMessage($this->orderProcessor->getError(), 'bad'); $response = $this->controller->redirectBack(); } return $response; }
function setUp() { parent::setUp(); ShopTest::setConfiguration(); Order::config()->modifiers = array("OrderDiscountModifier"); $this->socks = $this->objFromFixture("Product", "socks"); $this->socks->publish("Stage", "Live"); $this->tshirt = $this->objFromFixture("Product", "tshirt"); $this->tshirt->publish("Stage", "Live"); $this->mp3player = $this->objFromFixture("Product", "mp3player"); $this->mp3player->publish("Stage", "Live"); $this->cart = $this->objFromFixture("Order", "cart"); $this->othercart = $this->objFromFixture("Order", "othercart"); $this->megacart = $this->objFromFixture("Order", "megacart"); $this->emptycart = $this->objFromFixture("Order", "emptycart"); $this->modifiedcart = $this->objFromFixture("Order", "modifiedcart"); }
/** * Modifies the incoming value by adding, * subtracting or ignoring the value this modifier calculates. * * Sets $this->Amount to the calculated value; * * @param $subtotal - running total to be modified * @param $forcecalculation - force calculating the value, if order isn't in cart * * @return $subtotal - updated subtotal */ public function modify($subtotal, $forcecalculation = false) { $order = $this->Order(); $value = $order->IsCart() || $forcecalculation ? $this->value($subtotal) : $this->Amount; switch ($this->Type) { case "Chargable": $subtotal += $value; break; case "Deductable": $subtotal -= $value; break; case "Ignored": break; } $value = round($value, Order::config()->rounding_precision); $this->Amount = $value; return $subtotal; }
function calculate() { $runningtotal = $this->order->SubTotal(); $modifiertotal = 0; $sort = 1; $existingmodifiers = $this->order->Modifiers(); $modifierclasses = Order::config()->modifiers; //check if modifiers are even in use if (!is_array($modifierclasses) || empty($modifierclasses)) { return $runningtotal; } foreach ($modifierclasses as $ClassName) { if ($modifier = $this->getModifier($ClassName)) { $modifier->Sort = $sort; $runningtotal = $modifier->modify($runningtotal); if ($modifier->isChanged()) { $modifier->write(); } } $sort++; } //clear old modifiers out if ($existingmodifiers) { foreach ($existingmodifiers as $modifier) { if (!in_array($modifier->ClassName, $modifierclasses)) { $modifier->delete(); $modifier->destroy(); } } } //prevent negative sales from ever occurring if ($runningtotal < 0) { SS_Log::log("Order (ID = {$this->order->ID}) was calculated to equal {$runningtotal}.\n\n\t\t\t\tOrder totals should never be negative!\n\n\t\t\t\tThe order total was set to \$0", SS_Log::ERR); $runningtotal = 0; } return $runningtotal; }
/** * Get the past orders for this member * * @return DataList list of orders */ public function getPastOrders() { return Order::get()->filter("MemberID", $this->owner->ID)->filter("Status:not", Order::config()->hidden_status); }
/** * The raw retail price the visitor will get when they * add to cart. Can include discounts or markups on the base price. */ public function sellingPrice() { $price = $this->BasePrice; //TODO: this is not ideal, because prices manipulations will not happen in a known order $this->extend("updateSellingPrice", $price); //prevent negative values $price = $price < 0 ? 0 : $price; // NOTE: Ideally, this would be dependent on the locale but as of // now the Silverstripe Currency field type has 2 hardcoded all over // the place. In the mean time there is an issue where the displayed // unit price can not exactly equal the multiplied price on an order // (i.e. if the calculated price is 3.145 it will display as 3.15. // so if I put 10 of them in my cart I will expect the price to be // 31.50 not 31.45). return round($price, Order::config()->rounding_precision); }
public function parameterFields() { $fields = new FieldList(); if (class_exists("Subsite")) { $first_order = Subsite::get_from_all_subsites("Order")->sort('Created', 'ASC')->first(); } else { $first_order = Order::get()->sort('Created', 'ASC')->first(); } // Check if any order exist if ($first_order) { // List all months $months = array('All'); for ($i = 1; $i <= 12; $i++) { $months[] = date("F", mktime(0, 0, 0, $i + 1, 0, 0)); } // Get the first order, then count down from current year to that $firstyear = new SS_Datetime('FirstDate'); $firstyear->setValue($first_order->Created); $years = array(); for ($i = date('Y'); $i >= $firstyear->Year(); $i--) { $years[$i] = $i; } // Order Status $statuses = Order::config()->statuses; array_unshift($statuses, 'All'); $fields->push(TextField::create('Filter_FirstName', 'Customer First Name')); $fields->push(TextField::create('Filter_Surname', 'Customer Surname')); $fields->push(TextField::create('Filter_StockID', 'Stock ID')); $fields->push(TextField::create('Filter_ProductName', 'Product Name')); $fields->push(DropdownField::create('Filter_Month', 'Month', $months)); $fields->push(DropdownField::create('Filter_Year', 'Year', $years)); $fields->push(DropdownField::create('Filter_Status', 'Order Status', $statuses)); } return $fields; }
/** * Get the tax amount to charge on the order. */ public function value($incoming) { $this->Rate = self::config()->rate; //inclusive tax requires a different calculation return self::config()->exclusive ? $incoming * $this->Rate : $incoming - round($incoming / (1 + $this->Rate), Order::config()->rounding_precision); }
public function setUp() { parent::setUp(); Order::config()->modifiers = array('GlobalTaxModifier'); GlobalTaxModifier::config()->country_rates = array('NZ' => array('rate' => 0.15, 'name' => 'GST', 'exclusive' => false), 'UK' => array('rate' => 0.175, 'name' => 'VAT', 'exclusive' => true)); }
/** * Complete payment processing * - send receipt * - update order status accordingling * - fire event hooks */ public function completePayment() { if (!$this->order->IsPaid()) { // recalculate order to be sure we have the correct total $this->order->calculate(); $this->order->extend('onPayment'); //a payment has been made //place the order, if not already placed if ($this->canPlace($this->order)) { $this->placeOrder(); } else { if ($this->order->Locale) { ShopTools::install_locale($this->order->Locale); } } if ($this->order->GrandTotal() > 0 && $this->order->TotalOutstanding(false) <= 0 || $this->order->GrandTotal() == 0 && Order::config()->allow_zero_order_total) { //set order as paid $this->order->Status = 'Paid'; $this->order->write(); } } }
/** * Complete payment processing * - send receipt * - update order status accordingling * - fire event hooks */ public function completePayment() { if (!$this->order->Paid) { $this->order->extend('onPayment'); //a payment has been made //place the order, if not already placed if ($this->canPlace($this->order)) { $this->placeOrder(); } else { if ($this->order->Locale) { ShopTools::install_locale($this->order->Locale); } } if ($this->order->GrandTotal() > 0 && $this->order->TotalOutstanding() <= 0 || $this->order->GrandTotal() == 0 && Order::config()->allow_zero_order_total) { //set order as paid $this->order->Status = 'Paid'; $this->order->Paid = SS_Datetime::now()->Rfc2822(); $this->order->write(); foreach ($this->order->Items() as $item) { $item->onPayment(); } //all payment is settled $this->order->extend('onPaid'); } if (!$this->order->ReceiptSent) { $this->notifier->sendReceipt(); } } }
/** * Get all orders that have been generated and are marked as dispatched or * canceled * * @return DataList */ public function getHistoricOrders() { return $this->owner->Orders()->filter(array("Status" => Order::config()->historic_statuses)); }
public function value($incoming) { $rate = $this->Type == "Chargable" ? $this->Rate() : round(1 - 1 / (1 + $this->Rate()), Order::config()->rounding_precision); return $incoming * $rate; }