protected function checkoutconfig() { $config = new CheckoutComponentConfig(ShoppingCart::curr(), true); $config->addComponent($comp = new CouponCheckoutComponent()); $comp->setValidWhenBlank(true); return $config; }
/** * Get the cart, and do last minute calculation if necessary. */ public function Cart() { $order = ShoppingCart::curr(); if (!$order || !$order->Items() || !$order->Items()->exists()) { return false; } return $order; }
/** * Redirect back to start of checkout if no cart started */ public function onAfterInit() { $action = $this->owner->getRequest()->param('Action'); $steps = $this->getSteps(); if (!ShoppingCart::curr() && !empty($action) && isset($steps[$action])) { Controller::curr()->redirect($this->owner->Link()); return; } }
public function ConfirmationForm() { $config = new CheckoutComponentConfig(ShoppingCart::curr(), false); $config->addComponent(new NotesCheckoutComponent()); $config->addComponent(new TermsCheckoutComponent()); $form = new PaymentForm($this->owner, "ConfirmationForm", $config); $form->setFailureLink($this->owner->Link('summary')); $this->owner->extend('updateConfirmationForm', $form); return $form; }
public function testLoginDoesntJoinCart() { Member::config()->login_joins_cart = false; $order = $this->objFromFixture("Order", "cart"); ShoppingCart::singleton()->setCurrent($order); $member = $this->objFromFixture("Member", "jeremyperemy"); $member->logIn(); $this->assertEquals(0, $order->MemberID); $member->logOut(); $this->assertTrue((bool) ShoppingCart::curr()); }
/** * Update the cart using data collected */ public function updatecart($data, $form) { $items = $this->cart->Items(); $updatecount = $removecount = 0; $request = $this->getRequest(); $order = ShoppingCart::curr(); if ($request && $request->isAjax() && $order) { ShopTools::install_locale($order->Locale); } $messages = array(); if (isset($data['Items']) && is_array($data['Items'])) { foreach ($data['Items'] as $itemid => $fields) { $item = $items->byID($itemid); if (!$item) { continue; } //delete lines if (isset($fields['Remove']) || isset($fields['Quantity']) && (int) $fields['Quantity'] <= 0) { $items->remove($item); $removecount++; continue; } //update quantities if (isset($fields['Quantity']) && ($quantity = Convert::raw2sql($fields['Quantity']))) { $item->Quantity = $quantity; } //update variations if (isset($fields['ProductVariationID']) && ($id = Convert::raw2sql($fields['ProductVariationID']))) { if ($item->ProductVariationID != $id) { $item->ProductVariationID = $id; } } //TODO: make updates through ShoppingCart class //TODO: combine with items that now match exactly //TODO: validate changes if ($item->isChanged()) { $item->write(); $updatecount++; } } } if ($removecount) { $messages['remove'] = _t('CartForm.REMOVED_ITEMS', "Removed {count} items.", "count is the amount that was removed", array('count' => $removecount)); } if ($updatecount) { $messages['updatecount'] = _t('CartForm.UPDATED_ITEMS', "Updated {count} items.", "count is the amount that was updated", array('count' => $updatecount)); } if (count($messages)) { $form->sessionMessage(implode(" ", $messages), "good"); } $this->extend('updateCartFormResponse', $request, $response, $form); return $response ? $response : $this->controller->redirectBack(); }
public function registerconfig() { $order = ShoppingCart::curr(); //hack to make components work when there is no order if (!$order) { $order = Order::create(); } $config = new CheckoutComponentConfig($order, false); $config->addComponent(new CustomerDetailsCheckoutComponent()); $config->addComponent(new MembershipCheckoutComponent()); return $config; }
public static function get($order = null) { if ($order === null) { $order = ShoppingCart::curr(); //roll back to current cart } if ($order->exists() && $order->isInDB()) { //check if order can go through checkout return new Checkout($order); } return false; }
public function ContactDetailsForm() { $cart = ShoppingCart::curr(); if (!$cart) { return false; } $config = new CheckoutComponentConfig(ShoppingCart::curr()); $config->addComponent(CustomerDetailsCheckoutComponent::create()); $form = CheckoutForm::create($this->owner, 'ContactDetailsForm', $config); $form->setRedirectLink($this->NextStepLink()); $form->setActions(FieldList::create(FormAction::create("checkoutSubmit", _t('CheckoutStep.Continue', "Continue")))); $this->owner->extend('updateContactDetailsForm', $form); return $form; }
/** * Global setup */ public function onBeforeInit() { Requirements::css('shop_livepub/css/shoplivepub.css'); LivePubHelper::add_template_path('shop_livepub/templates/php'); if (!empty($_REQUEST['flushsessioncart']) || !empty($_REQUEST['flush'])) { $cart = ShoppingCart::curr(); if ($cart) { $cart->rebuildSessionCart(); } } if (!empty($_REQUEST['debugsessioncart'])) { Debug::dump(Session::get('Cart')); } }
public function testCheckoutForm() { $order = ShoppingCart::curr(); $config = new SinglePageCheckoutComponentConfig($order); $form = new CheckoutForm($this->checkoutcontroller, "OrderForm", $config); $data = array("CustomerDetailsCheckoutComponent_FirstName" => "Jane", "CustomerDetailsCheckoutComponent_Surname" => "Smith", "CustomerDetailsCheckoutComponent_Email" => "*****@*****.**", "ShippingAddressCheckoutComponent_Country" => "NZ", "ShippingAddressCheckoutComponent_Address" => "1234 Green Lane", "ShippingAddressCheckoutComponent_AddressLine2" => "Building 2", "ShippingAddressCheckoutComponent_City" => "Bleasdfweorville", "ShippingAddressCheckoutComponent_State" => "Trumpo", "ShippingAddressCheckoutComponent_PostalCode" => "4123", "ShippingAddressCheckoutComponent_Phone" => "032092277", "BillingAddressCheckoutComponent_Country" => "NZ", "BillingAddressCheckoutComponent_Address" => "1234 Green Lane", "BillingAddressCheckoutComponent_AddressLine2" => "Building 2", "BillingAddressCheckoutComponent_City" => "Bleasdfweorville", "BillingAddressCheckoutComponent_State" => "Trumpo", "BillingAddressCheckoutComponent_PostalCode" => "4123", "BillingAddressCheckoutComponent_Phone" => "032092277", "PaymentCheckoutComponent_PaymentMethod" => "Dummy", "NotesCheckoutComponent_Notes" => "Leave it around the back", "TermsCheckoutComponent_ReadTermsAndConditions" => "1"); $form->loadDataFrom($data, true); $valid = $form->validate(); $errors = $form->getValidator()->getErrors(); $this->assertTrue($valid); $form->checkoutSubmit($data, $form); $this->assertEquals("Jane", $order->FirstName); $shipping = $order->ShippingAddress(); $this->assertEquals("NZ", $shipping->Country); $this->assertEquals("Cart", $order->Status); $this->markTestIncomplete('test invalid data'); $this->markTestIncomplete('test components individually'); }
/** * @param SS_HTTPRequest $request * @param AjaxHTTPResponse $response * @param GroupedProduct $groupedProduct * @param array $data * @param GroupedCartForm $form [optional] */ public function updateGroupCartResponse(&$request, &$response, $groupedProduct, $data, $form = null) { if ($request->isAjax() && $this->owner->getController()->hasExtension('AjaxControllerExtension')) { if (!$response) { $response = $this->owner->getController()->getAjaxResponse(); } $this->setupRenderContexts($response, $groupedProduct, $form); // Because ShoppingCart::current() calculates the order once and // then remembers the total, and that was called BEFORE the product // was added, we need to recalculate again here. Under non-ajax // requests the redirect eliminates the need for this but under // ajax the total lags behind the subtotal without this. $order = ShoppingCart::curr(); $order->calculate(); $response->pushRegion('SideCart', $this->owner->getController()); $response->triggerEvent('cartadd'); $response->triggerEvent('cartchange', array('action' => 'add')); } }
public function testCheckoutFormForSingleCountrySiteWithReadonlyFieldsForCountry() { // Set as a single country site $this->loadFixture("shop/tests/fixtures/singlecountry.yml"); $singlecountry = SiteConfig::current_site_config(); $this->assertEquals("NZ", $singlecountry->getSingleCountry(), "Confirm that website is setup as a single country site"); $order = ShoppingCart::curr(); $config = new SinglePageCheckoutComponentConfig($order); $form = new CheckoutForm($this->checkoutcontroller, "OrderForm", $config); // no country fields due to readonly field $dataCountryAbsent = array("CustomerDetailsCheckoutComponent_FirstName" => "Jane", "CustomerDetailsCheckoutComponent_Surname" => "Smith", "CustomerDetailsCheckoutComponent_Email" => "*****@*****.**", "ShippingAddressCheckoutComponent_Address" => "1234 Green Lane", "ShippingAddressCheckoutComponent_AddressLine2" => "Building 2", "ShippingAddressCheckoutComponent_City" => "Bleasdfweorville", "ShippingAddressCheckoutComponent_State" => "Trumpo", "ShippingAddressCheckoutComponent_PostalCode" => "4123", "ShippingAddressCheckoutComponent_Phone" => "032092277", "BillingAddressCheckoutComponent_Address" => "1234 Green Lane", "BillingAddressCheckoutComponent_AddressLine2" => "Building 2", "BillingAddressCheckoutComponent_City" => "Bleasdfweorville", "BillingAddressCheckoutComponent_State" => "Trumpo", "BillingAddressCheckoutComponent_PostalCode" => "4123", "BillingAddressCheckoutComponent_Phone" => "032092277", "PaymentCheckoutComponent_PaymentMethod" => "Dummy", "NotesCheckoutComponent_Notes" => "Leave it around the back", "TermsCheckoutComponent_ReadTermsAndConditions" => "1"); $form->loadDataFrom($dataCountryAbsent, true); $valid = $form->validate(); $errors = $form->getValidator()->getErrors(); $this->assertTrue($valid, print_r($errors, true)); $this->assertTrue($form->Fields()->fieldByName("ShippingAddressCheckoutComponent_Country_readonly")->isReadonly(), "Shipping Address Country field is readonly"); $this->assertTrue($form->Fields()->fieldByName("BillingAddressCheckoutComponent_Country_readonly")->isReadonly(), "Billing Address Country field is readonly"); $form->checkoutSubmit($dataCountryAbsent, $form); $shipping = $order->ShippingAddress(); $this->assertEquals("NZ", $shipping->Country); $billing = $order->BillingAddress(); $this->assertEquals("NZ", $billing->Country); }
public function CouponForm() { if ($cart = ShoppingCart::curr()) { return new CouponForm($this->owner, "CouponForm", $cart); } }
public function testCartSingleton() { $this->assertTrue((bool) $this->cart->add($this->product), "add one item"); $order = $this->cart->current(); $this->assertEquals($order->ID, ShoppingCart::curr()->ID, "if singleton order ids will match"); }
public function testVariations() { $this->loadFixture('silvershop/tests/fixtures/variations.yml'); $ballRoot = $this->objFromFixture('Product', 'ball'); $ballRoot->publish('Stage', 'Live'); $ball1 = $this->objFromFixture('ProductVariation', 'redlarge'); $ball2 = $this->objFromFixture('ProductVariation', 'redsmall'); // Add the two variation items $this->get(ShoppingCart_Controller::add_item_link($ball1)); $this->get(ShoppingCart_Controller::add_item_link($ball2)); $items = ShoppingCart::curr()->Items(); $this->assertNotNull($items); $this->assertEquals($items->Count(), 2, 'There are 2 items in the cart'); // Remove one and see what happens $this->get(ShoppingCart_Controller::remove_all_item_link($ball1)); $this->assertEquals($items->Count(), 1, 'There is 1 item in the cart'); $this->assertFalse($this->cart->get($ball1), "first item not in cart"); $this->assertNotNull($this->cart->get($ball1), "second item is in cart"); }
/** * Displays order info and cart contents. */ public function debug() { if (Director::isDev() || Permission::check("ADMIN")) { //TODO: allow specifying a particular id to debug Requirements::css(SHOP_DIR . "/css/cartdebug.css"); $order = ShoppingCart::curr(); $content = $order ? Debug::text($order) : "Cart has not been created yet. Add a product."; return array('Content' => $content); } }
protected function checkoutconfig() { $config = new CheckoutComponentConfig(ShoppingCart::curr(), false); $config->addComponent(PaymentCheckoutComponent::create()); return $config; }
/** * 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 }
/** * @param SS_HTTPRequest $request * @param AjaxHTTPResponse $response * @param AddProductForm $form [optional] */ public function updateCartFormResponse(&$request, &$response, $form = null) { if ($request->isAjax()) { if (!$response) { $response = $this->owner->getAjaxResponse(); } // Because ShoppingCart::current() calculates the order once and // then remembers the total, and that was called BEFORE the product // was added, we need to recalculate again here. Under non-ajax // requests the redirect eliminates the need for this but under // ajax the total lags behind the subtotal without this. ShoppingCart::curr()->calculate(); $this->setupRenderContexts($response); $this->triggerStatusMessage($response, $form); $response->pushRegion('CartFormAjax', $this->owner, array('Editable' => true)); $response->pushRegion('SideCart', $this->owner); } }
public function testMemberOrder() { //log out the admin user Member::currentUser()->logOut(); $this->shoppingcart->add($this->mp3player); $joemember = $this->objFromFixture('Member', 'joebloggs'); $joemember->logIn(); $cart = ShoppingCart::curr(); $cart->calculate(); $this->assertTrue($this->placeOrder('Joseph', 'Blog', '*****@*****.**', '100 Melrose Place', null, 'Martinsonville', 'New Mexico', null, 'EG', 'newpassword', 'newpassword', $joemember), "Member order placed successfully"); $order = Order::get()->byID($cart->ID); $this->assertTrue((bool) $order, 'Order exists'); $this->assertEquals($order->Status, 'Unpaid', 'status is now "unpaid"'); $this->assertEquals($order->FirstName, 'Joseph', 'order first name'); $this->assertEquals($order->Surname, 'Blog', 'order surname'); $this->assertEquals($order->Email, '*****@*****.**', 'order email'); $shippingaddress = $order->ShippingAddress(); $this->assertEquals($shippingaddress->Address, '100 Melrose Place', 'order address'); $this->assertNull($shippingaddress->AddressLine2, 'order address2'); $this->assertEquals($shippingaddress->City, 'Martinsonville', 'order city'); $this->assertNull($shippingaddress->PostalCode, 'order postcode'); $this->assertEquals($shippingaddress->Country, 'EG', 'order country'); //ASSUMPTION: member details are NOT updated with order $this->assertEquals($order->MemberID, $joemember->ID, 'Order associated with member'); $this->assertEquals($order->Member()->FirstName, 'Joe', 'member first name has not changed'); $this->assertTrue($order->Member()->inGroup($this->objFromFixture("Group", "customers"), true), "Member has been added to ShopMembers group"); }
function testCartActivity() { /** @var Member $m1 */ $m1 = $this->objFromFixture('Member', 'm1'); /** @var Product $p1 */ $p1 = $this->objFromFixture('Product', 'p1'); $p1->publish('Stage', 'Live'); // Given an item in the shopping cart, the price should change when a user logs in ShoppingCart::singleton()->add($p1, 1); /** @var Order $order */ $order = ShoppingCart::curr(); $this->assertEquals($p1->BasePrice, $order->SubTotal()); $m1->logIn(); $this->assertEquals($p1->CustomerPrice, $order->SubTotal()); }
/** * Returns the number of items that are currently in other people's carts * which should be considered 'held'. * * @return int */ public function getTotalStockInCarts() { $current = ShoppingCart::curr(); $extra = ""; if ($current) { $extra = "AND \"ID\" != '{$current->ID}'"; } $pending = Order::get()->where("\"Status\" = 'Cart' {$extra}"); $used = 0; $identifier = $this->getStockBaseIdentifier(); $key = "{$identifier}ID"; foreach ($pending as $order) { foreach ($order->Items() as $item) { if ($item->{$key} == $this->owner->ID) { $used += $item->Quantity; } } } return $used; }
public function PaymentForm() { if (!(bool) $this->Cart()) { return false; } $config = CheckoutComponentConfig::create(ShoppingCart::curr(), false); $config->addComponent(OnsitePaymentCheckoutComponent::create()); $form = PaymentForm::create($this, "PaymentForm", $config); $form->setActions(new FieldList(FormAction::create("submitpayment", "Submit Payment"))); $form->setFailureLink($this->Link()); $this->extend('updatePaymentForm', $form); return $form; }
public function billingconfig() { $config = new CheckoutComponentConfig(ShoppingCart::curr()); $config->addComponent(new BillingAddressBookCheckoutComponent()); return $config; }
/** * Provide a copy of the current order's modifiers * @todo Only FlatTaxModifier tested * @return array of modifiers (note: this excludes subtotal and grandtotal) */ protected function getCurrentShoppingCartModifiers() { $result = array(); $modifiers = ShoppingCart::curr()->Modifiers(); if ($modifiers->exists()) { foreach ($modifiers->sort('Sort')->getIterator() as $modifier) { if ($modifier->ShowInTable()) { $data = array('id' => (string) $modifier->ID, 'tableTitle' => $modifier->TableTitle(), 'tableValue' => (double) $modifier->TableValue()); if (method_exists($modifier, 'Link')) { // add if there is a link $data["href"] = $modifier->Link(); } if (method_exists($modifier, 'removeLink')) { // add if there is a canRemove method $data["removeLink"] = $modifier->removeLink(); } $result[] = $data; } } } $this->owner->extend('updateGetCurrentShoppingCartModifiers', $result); return $result; }
/** * 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 }
public function testGlobalTiers() { $t1 = new PriceTier(array('MinQty' => 20, 'Percentage' => 0.5, 'SiteConfigID' => SiteConfig::current_site_config()->ID)); $t1->write(); $tiers = $this->p1->getPrices(); $this->assertEquals(2, $tiers->count()); $price1 = 27.5; $qty1 = 19; $price2 = round(27.5 * 0.5, 2); $qty2 = 20; ShoppingCart::singleton()->add($this->p1, $qty1); ShoppingCart::curr()->calculate(); $this->assertEquals($price1 * $qty1, ShoppingCart::curr()->SubTotal()); ShoppingCart::singleton()->setQuantity($this->p1, $qty2); ShoppingCart::curr()->calculate(); $this->assertEquals($price2 * $qty2, ShoppingCart::curr()->SubTotal()); }