/** * Checks and repairs the internal consistency of the object. * * This method is executed after an already-instantiated object is re-hydrated * from the database. It exists to check any foreign keys to make sure that * the objects related to the current object are correct based on foreign key. * * You can override this method in the stub class, but you should always invoke * the base method from the overridden method (i.e. parent::ensureConsistency()), * in case your model changes. * * @throws PropelException */ public function ensureConsistency() { if ($this->aCartItem !== null && $this->cart_item_id !== $this->aCartItem->getId()) { $this->aCartItem = null; } if ($this->aAttribute !== null && $this->attribute_id !== $this->aAttribute->getId()) { $this->aAttribute = null; } if ($this->aAttributeAv !== null && $this->attribute_av_id !== $this->aAttributeAv->getId()) { $this->aAttributeAv = null; } }
/** * Add an item within an order * * @param Cart $item * @throws Exception * @return unknown */ public static function addOrderItem(CartItem $item) { if (empty(self::$order)) { throw new Exception('The order has not been created yet', 1000); } try { // get the item subtotals $subtotals = $item->getSubtotals(); // get the options $options = $item->getOptions(); // Get the order object previously created $order = self::$order; // add a new item $orderitem = new OrdersItems(); $orderitem->order_id = $order['order_id']; if ("domain" == $item->getType()) { // Create a new domain order item $orderitem->tld_id = !empty($options['domain']['tld']) ? $options['domain']['tld'] : null; $orderitem->parameters = json_encode($options); } else { $orderitem->product_id = $item->getId(); $orderitem->parameters = json_encode(ProductsAttributes::getSystemAttributes($item->getId())); } $orderitem->status_id = Statuses::id("tobepaid", "orders"); $orderitem->date_start = date('Y-m-d H:i:s'); $orderitem->date_end = null; $orderitem->description = $item->getName(); $orderitem->quantity = $item->getQty(); $orderitem->price = $item->getUnitprice(); $orderitem->billing_cycle_id = $item->getBillingid(); $orderitem->vat = $subtotals['taxes']; $orderitem->percentage = $subtotals['percentage']; $orderitem->uuid = $item->getUid(); // Count of the day until the expiring if ($item->getIsrecurring()) { // get the months until of the next service expiration $months = $subtotals['months']; if ($months > 0) { $totmonths = intval($item->getQty() * $months); // Calculate the total of the months $date_end = Shineisp_Commons_Utilities::add_date(date('d-m-Y H:i:s'), null, $totmonths); $orderitem->date_end = Shineisp_Commons_Utilities::formatDateIn($date_end); } else { $orderitem->date_end = null; } } $orderitem->cost = $item->getCost(); $orderitem->setupfee = $subtotals['setupfee']; $orderitem->subtotal = $subtotals['subtotal']; // Save the order item if ($orderitem->trySave()) { // Attach all the the domain to the order if ("domain" == $item->getType()) { $domain = $options['domain']['name']; $tld = $options['domain']['tld']; $domainId = Domains::Create($domain, $tld, $order->customer_id, $orderitem->detail_id); if (is_numeric($domainId)) { $ordersitemsdomains = new OrdersItemsDomains(); $ordersitemsdomains->domain_id = $domainId; $ordersitemsdomains->order_id = $order['order_id']; $ordersitemsdomains->orderitem_id = $orderitem->detail_id; $ordersitemsdomains->save(); } } // Update the totals of the order self::updateTotalsOrder($order['order_id']); return $orderitem; } } catch (Exception $e) { Shineisp_Commons_Utilities::log('There was a problem during the order creation: ' . $e->getMessage()); } return false; }
/** * All the cart functionalities are handled here * * Add a product to the cart, remove a product from the cart, checkout, etc * @return string */ public function handleCart($action) { switch ($action) { case 'Add': //Add a new product to the cart $productId = e(@$_REQUEST["productId"]); $product = new Product($productId); if (!$product->getId()) { return $this->smarty->fetch("Error.tpl"); } require_once 'plugins/products/ECommProduct.php'; $hookResults = ECommProduct::clientPluginHooks("BeforeAddToCart", $product, $this); //Add the product to cart $session = Session::getActiveSession(); $cartItem = new CartItem(); $cartItem->setSession($session->getId()); $cartItem->setProduct($productId); $cartItem->setQuantity(@$_REQUEST["quantity"]); $cartItem->setTransaction(0); $cartItem->save(); $hookResults = ECommProduct::clientPluginHooks("AfterAddToCart", $cartItem, $this); $returnURL = @$_REQUEST["returnURL"]; if (!$returnURL) { $returnURL = "/Store/"; } $this->smarty->assign('returnURL', $returnURL); return $this->smarty->fetch("ProductAddedToCart.tpl"); case 'Details': //Get the details of the cart for an ajax call, it will have the format: "subTotal tax shipping total" $cartDetails = Module_EComm::getCartDetails(); return $cartDetails["subTotal"] . " " . $cartDetails["tax"] . " " . $cartDetails["shipping"] . " " . $cartDetails["total"]; break; case 'Delete': //Delete an item from the cart $cartItem = new CartItem(@$_REQUEST["id"]); if ($cartItem->getId()) { if ($cartItem->getSession() == @$_SESSION["ECommSessionId"]) { $cartItem->delete(); return "True"; } } return "Could not be deleted"; break; case 'Display': //Display the cart (before the checkout page) $session = Session::getActiveSession(); $sessionId = $session->getId(); $cartProducts = CartItem::getAll($sessionId); $cartDetails = Module_EComm::getCartDetails($sessionId, $cartProducts); $this->smarty->assign('cartProducts', $cartProducts); $this->smarty->assign('cartDetails', $cartDetails); $auth_container = new User(); $auth = new Auth($auth_container, null, 'authInlineHTML'); $auth->start(); if ($auth->checkAuth()) { $this->smarty->assign('loggedIn', 1); } $user = Module::factory("User"); $form = $user->getUserAddEditForm('/Store/Cart/&action=Checkout&createAccount=1'); $form->removeElement('a_group'); //In case the administrator is logged in, remove this element because it is not needed $form->removeElement('a_status'); //In case the administrator is logged in, remove this element because it is not needed $form->removeElement('section'); //Remove the section hidden variable from here $form->removeElement('action'); //Remove the action hidden variable from here $this->smarty->assign('user_form', $form); $this->smarty->assign('userExist', @$_REQUEST["userExist"]); $this->smarty->assign('loginFail', @$_REQUEST["loginFail"]); return $this->smarty->fetch("DisplayCart.tpl"); break; case 'displayCartProduct': //Display a product in a cart (similar to display a product from the database but without the option of adding to cart and with some other differences) $cartItem = new CartItem(@$_REQUEST["cartItemId"]); if ($cartItem->getId()) { if ($cartItem->getSession() == @$_SESSION["ECommSessionId"]) { //Make sure the owner of this item is viewing it $product = $cartItem->getCartItemProduct(); $this->smarty->assign('cartItem', $cartItem); require_once 'plugins/products/ECommProduct.php'; $hookResults = ECommProduct::clientPluginHooks("BeforeDisplayCartItem", $cartItem, $this); $html = ""; foreach ($hookResults as $key => $val) { $html .= @$val['HTML']; } $this->smarty->assign('html', $html); $this->smarty->assign('returnURL', '/Store/Cart/&action=' . @$_REQUEST["returnURL"]); return $this->smarty->fetch("DisplayCartItem.tpl"); } } return "Item could not be displayed"; break; case 'Checkout': //Display the checkout page if (@$_REQUEST["createAccount"] == 1) { //Create a new user $user = Module::factory("User"); $form = $user->getUserAddEditForm(); //Then try to log the user in using their username and password $auth_container = new CMSAuthContainer(); $auth = new Auth($auth_container, null, 'authInlineHTML'); //First, log the current user out (if exists) unset($_SESSION['authenticated_user']); $auth->logout(); //And then, log the new user in using the new username and password $_POST["username"] = @$_REQUEST["a_username"]; $_POST["password"] = @$_REQUEST["a_password"]; $_POST["doLogin"] = "******"; $auth->start(); if (!$auth->checkAuth()) { //The login did not happen successfully, which means creating a new user was not successful header('Location: /Store/Cart/&action=Display&userExist=1'); exit; } $this->sendEmailAccountCreated(); } $auth_container = new User(); $auth = new Auth($auth_container, null, 'authInlineHTML'); $auth->start(); if (!$auth->checkAuth()) { //You need to login to access this page header('Location: /Store/Cart/&action=Display&loginFail=1'); //Invalid username or password exit; } //From this point on, the user is actually logged in $userId = $_SESSION['authenticated_user']->getId(); require_once 'plugins/shipping/ECommShipping.php'; require_once 'plugins/payment/ECommPayment.php'; $this->smarty->assign('username', $_SESSION['authenticated_user']->getUsername()); $session = Session::getActiveSession(); $session->setUser($userId); //Set the default shipping class and payment option, if empty if (!$session->getShippingClass()) { $session->setShippingClass(ECommShipping::getDefaultPlugIn()); } if (!$session->getPaymentClass()) { $session->setPaymentClass(ECommPayment::getDefaultPlugIn()); } $session->save(); $sessionId = $session->getId(); $cartProducts = CartItem::getAll($sessionId); $cartDetails = Module_EComm::getCartDetails($sessionId, $cartProducts); $this->smarty->assign('cartProducts', $cartProducts); $this->smarty->assign('cartDetails', $cartDetails); $userDetails = UserDetails::getUserDetailsBasedOnUserId($userId); $this->smarty->assign('userDetails', $userDetails); $ECommShipping = new ECommShipping(); $this->smarty->assign('shippingClass', $ECommShipping); $this->smarty->assign('selectedShipping', $session->getShippingClass()); $this->smarty->assign('shippingClassDetails', $ECommShipping->getPlugin($session->getShippingClass())->getShippingDetails()); $ECommPayment = new ECommPayment(); $this->smarty->assign('paymentClass', $ECommPayment); $this->smarty->assign('selectedPayment', $session->getPaymentClass()); $this->smarty->assign('paymentClassDetails', $ECommPayment->getPlugin($session->getPaymentClass())->getPaymentDetails()); $this->smarty->assign('paymentForm', $ECommPayment->getPlugin($session->getPaymentClass())->getPaymentForm()); return $this->smarty->fetch("Checkout.tpl"); break; case 'ShippingChange': //Change the shipping class through an ajax call. It returns the details of the new shipping class so it is displayed for the end user if (@$_REQUEST["shippingClass"]) { $session = Session::getActiveSession(); $session->setShippingClass($_REQUEST["shippingClass"]); $session->save(); } require_once 'plugins/shipping/ECommShipping.php'; $ECommShipping = new ECommShipping(); return $ECommShipping->getPlugin(@$_REQUEST["shippingClass"])->getShippingDetails(); break; case 'PaymentChange': //Change the payment class as an ajax call. Returns the details of the new payment method to be displayed to the end user if (@$_REQUEST["paymentClass"]) { $session = Session::getActiveSession(); $session->setPaymentClass($_REQUEST["paymentClass"]); $session->save(); } require_once 'plugins/payment/ECommPayment.php'; $ECommPayment = new ECommPayment(); $details = $ECommPayment->getPlugin(@$_REQUEST["paymentClass"])->getPaymentDetails(); $form = $ECommPayment->getPlugin(@$_REQUEST["paymentClass"])->getPaymentForm(); //This will return the details and the form separated by a new line. //The details must not contain any new line and neither must the form //The ajax call will split the result by \n. The first will will be the details and the second line will be the form return str_replace("\n", " ", $details) . "\n" . str_replace("\n", " ", $form); break; case 'Address': //Change the address or the phone number of the end user in an ajax call $userId = $_SESSION['authenticated_user']->getId(); if (!$userId) { //If the user is not logged in, don't do anything return ""; } $userDetails = UserDetails::getUserDetailsBasedOnUserId($userId); $adr_type = @$_REQUEST['adr_type']; if ($adr_type == "phone_number") { //Change the phone number $form = new Form('phone_addedit', 'post', '/Store/Cart/&action=Address'); $form->addElement('text', 'number', 'Phone Number', array('value' => $userDetails->getPhoneNumber())); $form->setConstants(array('adr_type' => $adr_type)); $form->addElement('hidden', 'adr_type'); $form->addElement('submit', 'submit', 'Submit'); if (isset($_REQUEST['submit'])) { $userDetails->setPhoneNumber(trim($_REQUEST['number'])); $userDetails->save(); $this->smarty->assign('phoneNumber', $userDetails->getPhoneNumber()); return $this->smarty->fetch('PhoneNumber.tpl'); } else { return $form->display(); } } else { //Change the shipping address or billing address $address = $userDetails->getAddress($adr_type); $form = $address->getAddEditForm(); $form->addElement('submit', 'submit', 'Submit'); $form->updateAttributes(array('action' => '/Store/Cart/&action=Address')); $form->setConstants(array('adr_type' => $adr_type)); $form->addElement('hidden', 'adr_type'); if (isset($_REQUEST['submit'])) { $userDetails->setAddress($adr_type, $address); $userDetails->save(); $this->smarty->assign('address', $address); $this->smarty->assign('adr_type', $adr_type); return $this->smarty->fetch('Address.tpl'); } else { return $form->display(); } } break; case 'CheckBeforePayment': //This action is called when the user clicks on the "Buy now" button //Mmake sure that they can checkout in an ajax call before redirecting the user to the payment //For example, the shipping address must be present, the billing address, etc //If the user can checkout, return "0" to the ajax call. Right after doing that, there will be another ajax call to refresh the payment form and then submitting the form $session = Session::getActiveSession(); $cartDetails = Module_EComm::getCartDetails(); $canPurchase = Module_EComm::canUserCheckOut($session, $cartDetails); if ($canPurchase == "0") { //The user can checkout //Create a new transaction and fill it with all the details that the user has enetered $userDetails = UserDetails::getUserDetailsBasedOnUserId($session->getUser()); $shippingAddress = $userDetails->getAddress('shipping_address'); $billingAddress = $userDetails->getAddress('billing_address'); //Proceed to payment: //Create a transaction entity //and change the session so the user won't mess up with it //First, create a random transaction number (30 digits) $tid = Transaction::generateNewTID(); $transaction = new Transaction(); $transaction->setTid($tid); $transaction->setSession($session->getId()); $transaction->setUser($session->getUser()); $transaction->setPhone($userDetails->getPhoneNumber()); $transaction->setShippingStreet($shippingAddress->getStreetAddress()); $transaction->setShippingCity($shippingAddress->getCity()); $transaction->setShippingPostal($shippingAddress->getPostalCode()); $transaction->setShippingProvince($shippingAddress->getStateName()); $transaction->setShippingCountry($shippingAddress->getCountryName()); $transaction->setBillingStreet($billingAddress->getStreetAddress()); $transaction->setBillingCity($billingAddress->getCity()); $transaction->setBillingPostal($billingAddress->getPostalCode()); $transaction->setBillingProvince($billingAddress->getStateName()); $transaction->setBillingCountry($billingAddress->getCountryName()); $transaction->setCostSubtotal((double) $cartDetails["subTotal"]); $transaction->setCostTax((double) $cartDetails["tax"]); $transaction->setCostShipping((double) $cartDetails["shipping"]); $transaction->setCostTotal((double) $cartDetails["total"]); $transaction->setIp($session->getIpAddress()); $transaction->setShippingClass($session->getShippingClass()); $transaction->setPaymentClass($session->getPaymentClass()); $transaction->setDeliveryInstructions(@$_REQUEST["deliveryInstructions"]); $transaction->save(); $_SESSION['ECommTID'] = $tid; //Store $tid in PHP session so when the payment form is generated, we can include it there. //After creating the transaction, regenerate the session ID to prevent users from messing up with the session after proceeding to payment //The user will be assigned a new session. So, their cart will be empty. They can add new items to the cart if they want, and that will not affect their transaction $session->reGenerateSession(); } return $canPurchase; break; } }
/** * Calculate the subtotal for each product in the cart * * @param integer $id * @param integer $qty * @param boolean $isvatfree * @return ArrayObject */ private function calcSubtotal(CartItem $item, $isvatfree = false) { foreach ($this->items as $item) { $isrecurring = false; $months = 0; $percentage = 0; $tax = 0; if ("domain" == $item->getType()) { $item->setIsrecurring(true); // Get the billyng cycle / term / recurring period price if ($item->getTerm()) { $priceInfo = ProductsTranches::getTranchebyId($item->getTerm()); $item->setBillingid($priceInfo['BillingCycle']['billing_cycle_id']); $months = $priceInfo['BillingCycle']['months']; } else { $priceInfo = BillingCycle::getDefaultDomainBillingCycle(); $item->setBillingid($priceInfo['billing_cycle_id']); $months = $priceInfo['months']; } $unitprice = $item->getUnitPrice(); $setupfee = 0; // Calculate the price per Quantity $subtotal = $unitprice * $item->getQty(); // check the taxes if (Taxes::get_percentage($item->getTaxId())) { $percentage = Taxes::get_percentage($item->getTaxId()); $tax = $subtotal * $percentage / 100; $price = $subtotal * (100 + $percentage) / 100; } } else { // Get all the product information $product = Products::getAllInfo($item->getId()); // Check the type of the product and get the price information if ($product['ProductsAttributesGroups']['isrecurring']) { $item->setIsrecurring(true); // Get the billyng cycle / term / recurring period price $priceInfo = ProductsTranches::getTranchebyId($item->getTerm()); // Price multiplier $months = $priceInfo['BillingCycle']['months']; $unitprice = $priceInfo['price']; $setupfee = $priceInfo['setupfee']; // Calculate the price per the months per Quantity $subtotal = $unitprice * $months * $item->getQty(); $item->setBillingid($priceInfo['BillingCycle']['billing_cycle_id']); } else { $item->setIsrecurring(false); $unitprice = $product['price_1']; $setupfee = $product['setupfee']; // Calculate the price per Quantity $subtotal = $unitprice * $item->getQty(); } // check the taxes for each product if (!empty($product['tax_id']) && !$isvatfree) { if (!empty($product['Taxes']['percentage']) && is_numeric($product['Taxes']['percentage'])) { $percentage = $product['Taxes']['percentage']; $tax = $subtotal * $percentage / 100; $price = $subtotal * (100 + $percentage) / 100; } } } // ... and add the setup fees $price = $subtotal + $setupfee; $item->setSubtotals(array('months' => $months, 'subtotal' => $subtotal, 'setupfee' => $setupfee, 'price' => $price, 'taxes' => $tax, 'percentage' => $percentage)); } return $this->items; }