public function createOrder() { $order = new Order(); $order->write(); $item1a = $this->mp3player->createItem(2); $item1a->write(); $order->Items()->add($item1a); $item1b = $this->socks->createItem(); $item1b->write(); $order->Items()->add($item1b); return $order; }
public function createValidator() { $validator = RequiredFields::create(); $items = $this->order->Items(); if ($items) { foreach ($items as $item) { $validator->addRequiredField('Quantity[' . $item->ID . ']'); } } $this->extend('updateValidator', $validator); $validator->setForm($this); return $validator; }
/** * Add a XeroTaxModification to the order by applying tax rates to Items and Modifications in the order using * the taxCalculator. * * @param Order $order * @param Mixed $value Unused */ public function add($order, $value = null) { // Go through the items and modifications in the order and apply a tax rate to them // Calculate tax based on rates for each item and modification $items = $order->Items(); if ($items && $items->exists()) { foreach ($items as $item) { $this->taxCalculator->applyItemTaxRate($item); } } $mods = $order->Modifications(); if ($mods && $mods->exists()) { foreach ($mods as $mod) { $this->taxCalculator->applyModificationTaxRate($mod); } } // Create new modification using rates for each item and modification in the order $taxAmount = $this->taxCalculator->calculate($order); $mod = new XeroTaxModification(); $mod->Price = $taxAmount->getAmount(); $mod->Description = _t('Xero.TAX', 'Tax'); $mod->OrderID = $order->ID; $mod->Value = null; $mod->write(); }
/** * Iterate over the order items and calculate the gst * for each depending on StreakGSTModule.config.currency_percentages() * * @param Order $order * @param null $value * @throws ValidationException * @throws null */ public function add($order, $value = null) { $gst = new Price(); $gst->setCurrency(ShopConfig::current_shop_config()->BaseCurrency); $descriptions = array(); /** @var Price|null $calculated */ $calculated = null; /** @var Item $item */ foreach ($order->Items() as $item) { if ($price = $item->Price()) { $currency = $price->getCurrency(); if ($rate = self::rate_for_currency($currency)) { if (!$calculated) { $calculated = new Price(); } $percentage = Zend_Locale_Math::Div($rate, 100.0, 10); $taxed = Zend_Locale_Math::Mul($price, $percentage, 10); $temp = Zend_Locale_Math::Add($calculated, $taxed, 10); $calculated->setAmount($temp); $descriptions[$currency] = static::description($currency); } } } if ($calculated) { $mod = new StreakGST_Modification(); $mod->OrderID = $order->ID; $mod->Price = 0; $mod->Description = implode("<br/>\n", $descriptions); $mod->GST = $calculated->getAmount(); $mod->Value = $calculated->getAmount(); $mod->write(); } }
/** * Test {@link Order::process()} */ function testProcess() { $var1 = $this->objFromFixture('ProductVariation', 'variation1'); $var2 = $this->objFromFixture('ProductVariation', 'variation2'); $member = $this->objFromFixture('Member', 'member1'); $this->get("cart/add/{$var1->ID}/{$var1->class}?quantity=3"); $this->get("cart/add/{$var2->ID}/{$var2->class}"); $order = new Order(); $this->assertType('DataObjectSet', $order->Items(), 'Items are in the cart, returned as a DataObjectSet'); $this->assertType('DataObjectSet', $order->Modifiers(), 'Modifiers are in the cart, returned as a DataObjectSet'); $order->process($member->ID); $this->assertType('ComponentSet', $order->Items(), 'Items are now a component set because they are in the DB'); $this->assertType('ComponentSet', $order->Modifiers(), 'Modifiers are now a component set because they are in the DB'); $this->assertEquals(104, $order->Subtotal()); $this->assertEquals(104, $order->Total()); $this->assertFalse($order->process($member->ID), 'The order in the DB cannot be processed again'); }
public function doProcess($data, $form, $request) { $order = new Order(); $items = $order->Items(); $member = Member::currentUserID() ? Member::currentUser() : new Member(); $paymentClass = isset($data['PaymentMethod']) ? $data['PaymentMethod'] : null; $payment = class_exists($paymentClass) ? new $paymentClass() : null; $requirePayment = $order->Subtotal() > 0 ? true : false; if (!($items && $items->Count() > 0)) { $form->sessionMessage(_t('OrderForm.NOITEMS', 'Error placing order: You have no items in your cart.'), 'bad'); return Director::redirectBack(); } if ($requirePayment) { if (!($payment && $payment instanceof Payment)) { user_error("OrderForm::doProcess(): '{$paymentClass}' is not a valid payment class!", E_USER_ERROR); } } // Ensure existing members don't get their record hijacked (IMPORTANT!) if (!$member->checkUniqueFieldValue($data)) { $uniqueField = Member::get_unique_identifier_field(); $uniqueValue = $data[$uniqueField]; $uniqueError = "Error placing order: The %s \"%d\" is\n\t\t\t\talready taken by another member. If this belongs to you, please\n\t\t\t\tlog in first before placing your order."; $form->sessionMessage(_t('EcommerceMemberExtension.ALREADYEXISTS', printf($uniqueError, strtolower($uniqueField), $uniqueValue), PR_MEDIUM, 'Let the user know that member already exists (e.g. %s could be "Email", %d could be "joe@somewhere.com)'), 'bad'); return Director::redirectBack(); } $form->saveInto($member); if (!$member->Password) { $member->setField('Password', Member::create_new_password()); } $member->write(); $form->saveInto($order); try { $result = $order->process($member->ID); } catch (Exception $e) { $form->sessionMessage(_t('OrderForm.PROCESSERROR', "An error occurred while placing your order: {$e->getMessage()}.<br>\n\t\t\t\t\tPlease contact the website administrator."), 'bad'); // Send an email to site admin with $e->getMessage() error return Director::redirectBack(); } if ($requirePayment) { $form->saveInto($payment); $payment->write(); $result = $payment->processPayment($data, $form); if ($result->isSuccess()) { $order->sendReceipt(); } // Long payment process. e.g. user goes to external site to pay (PayPal, WorldPay) if ($result->isProcessing()) { return $result->getValue(); } } Director::redirect($order->Link()); }
/** * Add the member to the order, in case the member is not an admin. * @param Order $order * @return Boolean **/ public function doStep(Order $order) { $logClassName = $this->getRelevantLogEntryClassName(); $obj = $logClassName::get()->filter(array("OrderID" => $order->ID))->first(); if (!$obj) { $files = new ArrayList(); $items = $order->Items(); if ($items && $items->count()) { foreach ($items as $item) { $buyable = $item->Buyable(); if ($buyable) { $method = $this->Config()->get("download_method_in_byable"); if ($buyable->hasMethod($method)) { $itemDownloadFiles = $buyable->{$method}(); if ($itemDownloadFiles) { if ($itemDownloadFiles instanceof DataList) { if ($itemDownloadFiles->count()) { foreach ($itemDownloadFiles as $itemDownloadFile) { $files->push($itemDownloadFile); } } } else { user_error("{$method} should return a Datalist. Specifically watch for has_one methods as they return a DataObject.", E_USER_NOTICE); } } } } } } if ($files->count()) { //additional files ar only added to orders //with downloads $additionalFiles = $this->AdditionalFiles(); foreach ($additionalFiles as $additionalFile) { $files->push($additionalFile); } //create log with information... $obj = $logClassName::create(); $obj->OrderID = $order->ID; $obj->AuthorID = $order->MemberID; $obj->NumberOfHoursBeforeDownloadGetsDeleted = $this->NumberOfHoursBeforeDownloadGetsDeleted; $obj->write(); $obj->AddFiles($files); } else { //do nothingh.... } } return true; }
/** * Calculate the tax component based on tax rates for the items and modifications in the order * * @param Order $order * @return Price The tax amount for the order */ public function calculate(Order $order) { $taxAmount = 0; $shopConfig = ShopConfig::current_shop_config(); $items = $order->Items(); if ($items && $items->exists()) { foreach ($items as $item) { $taxAmount += $item->Total()->getAmount() * ($item->XeroTaxRate / 100); } } $mods = $order->Modifications(); if ($mods && $mods->exists()) { foreach ($mods as $mod) { $taxAmount += $mod->Amount()->getAmount() * ($mod->XeroTaxRate / 100); } } $amount = new Price(); $amount->setAmount($taxAmount); $amount->setCurrency($shopConfig->BaseCurrency); $amount->setSymbol($shopConfig->BaseCurrencySymbol); return $amount; }
/** * @param Order $order * @param null $value * @throws ValidationException * @throws null */ public function add($order, $value = null) { if ($order->ShippingRegionCode) { if ($orderRegion = Region_Shipping::get()->filter('Code', $order->ShippingRegionCode)->first()) { $shippingCost = 0.0; /** @var Item $item */ foreach ($order->Items() as $item) { $productRegion = $item->Product()->Shippables()->filter('RegionID', $orderRegion->ID)->first(); if ($productRegion) { $shippingCost = Zend_Locale_Math::Add($shippingCost, Zend_Locale_Math::Mul($productRegion->Price, $item->Quantity)); } } //Generate the Modification now that we have picked the correct rate $mod = new StreakRegionalShipping_Modification(); $mod->OrderID = $order->ID; $mod->RegionID = $orderRegion->ID; $mod->Price = $shippingCost; $mod->Description = "Shipping to {$orderRegion->Title}"; $mod->Value = $shippingCost; $mod->write(); } } }
/** * Takes an order from being a cart to awaiting payment. * * @param Member $member - assign a member to the order * * @return boolean - success/failure */ public function placeOrder() { if (!$this->order) { $this->error(_t("OrderProcessor.NoOrderStarted", "A new order has not yet been started.")); return false; } if (!$this->canPlace($this->order)) { //final cart validation return false; } if ($this->order->Locale) { ShopTools::install_locale($this->order->Locale); } // recalculate order to be sure we have the correct total $this->order->calculate(); if (ShopTools::DBConn()->supportsTransactions()) { ShopTools::DBConn()->transactionStart(); } //update status if ($this->order->TotalOutstanding(false)) { $this->order->Status = 'Unpaid'; } else { $this->order->Status = 'Paid'; } if (!$this->order->Placed) { $this->order->Placed = SS_Datetime::now()->Rfc2822(); //record placed order datetime if ($request = Controller::curr()->getRequest()) { $this->order->IPAddress = $request->getIP(); //record client IP } } // Add an error handler that throws an exception upon error, so that we can catch errors as exceptions // in the following block. set_error_handler(function ($severity, $message, $file, $line) { throw new ErrorException($message, 0, $severity, $file, $line); }, E_ALL & ~(E_STRICT | E_NOTICE)); try { //re-write all attributes and modifiers to make sure they are up-to-date before they can't be changed again $items = $this->order->Items(); if ($items->exists()) { foreach ($items as $item) { $item->onPlacement(); $item->write(); } } $modifiers = $this->order->Modifiers(); if ($modifiers->exists()) { foreach ($modifiers as $modifier) { $modifier->write(); } } //add member to order & customers group if ($member = Member::currentUser()) { if (!$this->order->MemberID) { $this->order->MemberID = $member->ID; } $cgroup = ShopConfig::current()->CustomerGroup(); if ($cgroup->exists()) { $member->Groups()->add($cgroup); } } //allow decorators to do stuff when order is saved. $this->order->extend('onPlaceOrder'); $this->order->write(); } catch (Exception $ex) { // Rollback the transaction if an error occurred if (ShopTools::DBConn()->supportsTransactions()) { ShopTools::DBConn()->transactionRollback(); } $this->error($ex->getMessage()); return false; } finally { // restore the error handler, no matter what restore_error_handler(); } // Everything went through fine, complete the transaction if (ShopTools::DBConn()->supportsTransactions()) { ShopTools::DBConn()->transactionEnd(); } //remove from session $cart = ShoppingCart::curr(); if ($cart && $cart->ID == $this->order->ID) { // clear the cart, but don't write the order in the process (order is finalized and should NOT be overwritten) ShoppingCart::singleton()->clear(false); } //send confirmation if configured and receipt hasn't been sent if (self::config()->send_confirmation && !$this->order->ReceiptSent) { $this->notifier->sendConfirmation(); } //notify admin, if configured if (self::config()->send_admin_notification) { $this->notifier->sendAdminNotification(); } // Save order reference to session OrderManipulation::add_session_order($this->order); return true; //report success }
/** * Takes an order from being a cart to awaiting payment. * * @param Member $member - assign a member to the order * * @return boolean - success/failure */ public function placeOrder() { if (!$this->order) { $this->error(_t("OrderProcessor.NULL", "A new order has not yet been started.")); return false; } if (!$this->canPlace($this->order)) { //final cart validation return false; } if ($this->order->Locale) { ShopTools::install_locale($this->order->Locale); } //remove from session $cart = ShoppingCart::curr(); if ($cart && $cart->ID == $this->order->ID) { ShoppingCart::singleton()->clear(); } //update status if ($this->order->TotalOutstanding()) { $this->order->Status = 'Unpaid'; } else { $this->order->Status = 'Paid'; } if (!$this->order->Placed) { $this->order->Placed = SS_Datetime::now()->Rfc2822(); //record placed order datetime if ($request = Controller::curr()->getRequest()) { $this->order->IPAddress = $request->getIP(); //record client IP } } //re-write all attributes and modifiers to make sure they are up-to-date before they can't be changed again $items = $this->order->Items(); if ($items->exists()) { foreach ($items as $item) { $item->onPlacement(); $item->write(); } } $modifiers = $this->order->Modifiers(); if ($modifiers->exists()) { foreach ($modifiers as $modifier) { $modifier->write(); } } //add member to order & customers group if ($member = Member::currentUser()) { if (!$this->order->MemberID) { $this->order->MemberID = $member->ID; } $cgroup = ShopConfig::current()->CustomerGroup(); if ($cgroup->exists()) { $member->Groups()->add($cgroup); } } //allow decorators to do stuff when order is saved. $this->order->extend('onPlaceOrder'); $this->order->write(); //send confirmation if configured and receipt hasn't been sent if (self::config()->send_confirmation && !$this->order->ReceiptSent) { $this->notifier->sendConfirmation(); } //notify admin, if configured if (self::config()->send_admin_notification) { $this->notifier->sendAdminNotification(); } // Save order reference to session OrderManipulation::add_session_order($this->order); return true; //report success }
/** * Action that gets called before we interface with our payment * method. * * This action is responsible for setting up an order and * saving it into the database (as well as a session) and also then * generating an order summary before the user performs any final * actions needed. * * This action is then mapped directly to the index action of the * Handler for the payment method that was selected by the user * in the "Postage and Payment" form. * */ public function index() { $cart = ShoppingCart::get(); // If shopping cart doesn't exist, redirect to base if (!$cart->getItems()->exists() || $this->getPaymentHandler() === null) { return $this->redirect(Director::BaseURL()); } // Get billing and delivery details and merge into an array $billing_data = Session::get("Commerce.BillingDetailsForm.data"); $delivery_data = Session::get("Commerce.DeliveryDetailsForm.data"); $postage = PostageArea::get()->byID(Session::get('Commerce.PostageID')); if (!$postage || !$billing_data || !$delivery_data) { return $this->redirect(Checkout_Controller::create()->Link()); } // Work out if an order prefix string has been set in siteconfig $config = SiteConfig::current_site_config(); $order_prefix = $config->OrderPrefix ? $config->OrderPrefix . '-' : ''; // Merge billand and delivery data into an array $data = array_merge((array) $billing_data, (array) $delivery_data); // Set discount info $data['DiscountAmount'] = $cart->DiscountAmount(); // Get postage data $data['PostageType'] = $postage->Title; $data['PostageCost'] = $postage->Cost; $data['PostageTax'] = $config->TaxRate > 0 && $postage->Cost > 0 ? (double) $postage->Cost / 100 * $config->TaxRate : 0; // Set status $data['Status'] = 'incomplete'; // Setup an order based on the data from the shopping cart and load data $order = new Order(); $order->update($data); // If user logged in, track it against an order if (Member::currentUserID()) { $order->CustomerID = Member::currentUserID(); } // Write so we can setup our foreign keys $order->write(); // Loop through each session cart item and add that item to the order foreach ($cart->getItems() as $cart_item) { $order_item = new OrderItem(); $order_item->Title = $cart_item->Title; $order_item->SKU = $cart_item->SKU; $order_item->Price = $cart_item->Price; $order_item->Tax = $cart_item->Tax; $order_item->Customisation = serialize($cart_item->Customised); $order_item->Quantity = $cart_item->Quantity; $order_item->write(); $order->Items()->add($order_item); } $order->write(); // Add order to session so our payment handler can process it Session::set("Commerce.Order", $order); $this->payment_handler->setOrder($order); // Get gateway data $return = $this->payment_handler->index(); return $this->customise($return)->renderWith(array("Payment", "Commerce", "Page")); }
/** * Add item fields for each item in the current order. * * @param Array $fields Array of fields * @param OrderFormValidator $validator Checkout form validator * @param Order $order The current order */ private function addItemFields(&$fields, &$validator, $order) { $items = $order->Items(); if ($items) { foreach ($items as $item) { $fields['Items'][] = new OrderItemField($item); } } }
function old_testProductOrderItems() { $product1a = $this->objFromFixture('Product', 'p1a'); $product1b = $this->objFromFixture('Product', 'p1b'); $order = new Order(); $order->Currency = 'USD'; $order->write(); $item1a = new ProductOrderItem(null, null, $product1a, 2); $item1a->write(); $order->Items()->add($item1a); $item1b = new ProductOrderItem(null, null, $product1b, 1); $item1b->write(); $order->Items()->add($item1b); $item1c = new ProductOrderItem(null, null, $product1a, 1); $item1c->write(); $order->Items()->add($item1c); $items = $order->ProductOrderItems(); $testString = 'ProductList: '; foreach ($items as $item) { $testString .= $item->Product()->Title . ";"; } $this->assertEquals($testString, "ProductList: Product 1a;Product 1b;Product 1a;"); }
/** * Create a RepeatOrder from a regular Order and its Order Items * @param Order $Order * @return RepeatOrder */ public static function create_repeat_order_from_order(Order $Order) { $repeatOrder = new RepeatOrder(); $repeatOrder->Status = 'Pending'; $repeatOrder->MemberID = $Order->MemberID; $repeatOrder->write(); $orderItems = $Order->Items(); if ($orderItems) { foreach ($orderItems as $orderItem) { $buyable = $orderItem->Buyable(); if ($buyable && $buyable instanceof Product) { $repeatOrder_orderItem = new RepeatOrder_OrderItem(); $repeatOrder_orderItem->OrderID = $repeatOrder->ID; $repeatOrder_orderItem->ProductID = $orderItem->BuyableID; $repeatOrder_orderItem->Quantity = $orderItem->Quantity; $repeatOrder_orderItem->write(); } } } $repeatOrder->write(); return $repeatOrder; }