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;
 }