/** * Update/add SKU/quantity to cart, update the price in the cart, save old price and inventory level (if requested) * * @param int SKU ID * @param string Update Method: add - adds to the existing quantity, * set - ignores existing quantity and sets a new value, * sync - simply checks/updates inventory and pricing * @param int Quantity * @param bool Flag determining whether the old qty should be saved (only when it goes down); * price get saved in either case * @return void */ protected function doItem($sId, $mode = 'add', $qty = 1, $retainOldValue = false) { // Check quantity: must be a positive integer or zero if (!Cart_Helper::isNonNegativeInt($qty)) { throw new Exception(Lang::txt('COM_CART_INCORRECT_QTY')); } elseif ($qty == 0 && !$retainOldValue) { // Delete if quantity is set to zero if ($mode == 'set') { $this->deleteItem($sId); return; } else { throw new Exception(Lang::txt('COM_CART_INCORRECT_QTY')); } } // Check if there is enough inventory (if tracking inventory) taking into account current quantity in the cart // Get the quantity already in the cart (if appending or simply syncing) if ($mode == 'add' || $mode == 'sync') { $skuCartInfo = $this->getCartItem($sId); } else { $skuCartInfo = new stdClass(); $skuCartInfo->crtiQty = 0; } // Get SKU pricing and inventory level & policies include_once JPATH_BASE . DS . 'components' . DS . 'com_storefront' . DS . 'models' . DS . 'Warehouse.php'; $warehouse = new StorefrontModelWarehouse(); $allSkuInfo = $warehouse->getSkusInfo(array($sId)); if (empty($allSkuInfo)) { throw new Exception(Lang::txt('COM_STOREFRONT_SKU_NOT_FOUND')); } $skuInfo = $allSkuInfo[$sId]['info']; $skuName = $skuInfo->pName; if (!empty($allSkuInfo[$sId]['options']) && count($allSkuInfo[$sId]['options'])) { foreach ($allSkuInfo[$sId]['options'] as $oName) { $skuName .= ', ' . $oName; } } // Check inventory rules (sync mode doesn't check inventory level, just pricing) if ($mode != 'sync') { // Don't allow purchasing multiple products (same & different SKUs) for those that are not allowed if (!$skuInfo->pAllowMultiple) { // Check this SKU qty to make sure no multiple SKUs are there if (!empty($skuCartInfo->crtiQty) && $skuCartInfo->crtiQty > 0 || $qty > 1) { throw new Exception($skuInfo->pName . Lang::txt('COM_CART_NO_MULTIPLE_ITEMS')); } // Check if there is this project already in the cart (different SKU) $allSkus = $warehouse->getProductSkus($skuInfo->pId); foreach ($allSkus as $skuId) { // Skip the current SKU, look only at other SKUs if ($skuId != $sId) { $otherSkuInfo = $this->getCartItem($skuId); // Error if there is already another SKU of the same product in the cart if (!empty($otherSkuInfo->crtiQty) && $otherSkuInfo->crtiQty > 0) { throw new Exception($skuInfo->pName . Lang::txt('COM_CART_NO_MULTIPLE_ITEMS')); } } } } // Don't allow purchasing multiple SKUs for those that are not allowed if (!$skuInfo->sAllowMultiple && (!empty($skuCartInfo->crtiQty) && $skuCartInfo->crtiQty > 0 || $qty > 1)) { throw new Exception($skuName . Lang::txt('COM_CART_NO_MULTIPLE_ITEMS')); } // Make sure there is enough inventory if ($skuInfo->sTrackInventory) { // See if qty can be added if ($qty > $skuInfo->sInventory) { throw new Exception(Lang::txt('COM_CART_NOT_ENOUGH_INVENTORY')); } elseif (!empty($skuCartInfo->crtiQty) && $qty + $skuCartInfo->crtiQty > $skuInfo->sInventory) { // This is how much they can add: $skuInfo->sInventory - $skuCartInfo->crtiQty throw new Exception(Lang::txt('COM_CART_ADD_TOO_MANY_CART')); } } } // Run the auditor if ($mode != 'sync') { require_once JPATH_BASE . DS . 'components' . DS . 'com_cart' . DS . 'helpers' . DS . 'Audit.php'; $auditor = Audit::getAuditor($skuInfo, $this->crtId); $auditorResponse = $auditor->audit(); if ($auditorResponse->status == 'error') { throw new Exception($skuInfo->pName . $auditor->getResponseError()); } } // Insert new values, if exists save the previous price (for possible price changes messaging) // and old inventory level (if needed) $sql = "INSERT INTO `#__cart_cart_items`\n\t\t\t\t(`crtId`, `sId`, `crtiQty`, `crtiOldQty`, `crtiPrice`, `crtiOldPrice`, `crtiName`)\n\t\t\t\tVALUES\n\t\t\t\t({$this->crtId}, '{$sId}', {$qty}, NULL, {$skuInfo->sPrice}, NULL, " . $this->_db->quote($skuName) . ")\n\t\t\t\tON DUPLICATE KEY UPDATE `crtiOldPrice` = `crtiPrice`, `crtiPrice` = {$skuInfo->sPrice}, `crtiName` = " . $this->_db->quote($skuName); // Check if old value has to be retained if ($retainOldValue) { $sql .= ", `crtiOldQty` = `crtiQty`"; } else { $sql .= ", `crtiOldQty` = NULL"; } // add to the existing qty value if ($mode == 'add') { $sql .= ", `crtiQty` = `crtiQty` + {$qty}"; } elseif ($mode == 'set') { $sql .= ", `crtiQty` = {$qty}"; } // keep the qty value if syncing $this->_db->setQuery($sql); $this->_db->query(); }
public function addTask() { $response = new stdClass(); $response->status = 'ok'; include_once JPATH_COMPONENT . DS . 'models' . DS . 'cart.php'; $cart = new CartModelCurrentCart(); // update cart $updateCartRequest = Request::getVar('updateCart', false, 'post'); $pIds = Request::getVar('pId', false, 'post'); //print_r($pIds); die; // If pIds are posted, convert them to SKUs if (!empty($pIds)) { $skus = array(); include_once JPATH_BASE . DS . 'components' . DS . 'com_storefront' . DS . 'models' . DS . 'Warehouse.php'; $warehouse = new StorefrontModelWarehouse(); foreach ($pIds as $pId => $qty) { $product_skus = $warehouse->getProductSkus($pId); // must be only one sku to work if (sizeof($product_skus) != 1) { // each pId must map to one SKU, otherwise ignored continue; } $skus[$product_skus[0]] = $qty; } } else { $skus = Request::getVar('skus', false, 'post'); } //print_r($skus); die; // Initialize errors array $errors = array(); if ($updateCartRequest && $skus) { // Turn off syncing to prevent redundant session update queries $cart->setSync(false); foreach ($skus as $sId => $qty) { try { $cart->update($sId, $qty); } catch (Exception $e) { $errors[] = $e->getMessage(); } } } // add coupon if needed $addCouponRequest = Request::getVar('addCouponCode', false, 'post'); $couponCode = Request::getVar('couponCode', false, 'post'); if ($addCouponRequest && $couponCode) { // Sync cart before pontial coupons applying $cart->getCartInfo(true); // Initialize errors array $errors = array(); // Add coupon try { $cart->addCoupon($couponCode); } catch (Exception $e) { $errors[] = $e->getMessage(); } } if (!empty($errors)) { $response->status = 'error'; $response->errors = $errors; } echo htmlspecialchars(json_encode($response), ENT_NOQUOTES); die; }
/** * Update product info * * @param void * @return object info */ public function update() { // For single product update SKU must save the original SKU ID (since SKU was generated automatically) // Find the SKU ID for this product and save include_once PATH_CORE . DS . 'components' . DS . 'com_storefront' . DS . 'models' . DS . 'Warehouse.php'; $warehouse = new StorefrontModelWarehouse(); $sku = $warehouse->getProductSkus($this->data->id); // Must be just one SKU if (sizeof($sku) != 1) { throw new Exception(Lang::txt('Only one SKU is allowed')); } $skuId = $sku[0]; // save product sku with the current ID to resave the changes with this ID $sku = $this->getSku()->setId($skuId); return parent::update(); }
/** * Display default page * * @return void */ public function homeTask() { $cart = new CartModelCurrentCart(); // Initialize errors array $errors = array(); // Update cart if needed $updateCartRequest = Request::getVar('updateCart', false, 'post'); // If pIds are posted, convert them to SKUs $pIds = Request::getVar('pId', false, 'post'); //print_r($pIds); die; $skus = Request::getVar('skus', false, 'post'); if ($updateCartRequest && ($pIds || $skus)) { if (!empty($pIds)) { $skus = array(); include_once PATH_CORE . DS . 'components' . DS . 'com_storefront' . DS . 'models' . DS . 'Warehouse.php'; $warehouse = new StorefrontModelWarehouse(); foreach ($pIds as $pId => $qty) { $product_skus = $warehouse->getProductSkus($pId); // each pId must map to one SKU, otherwise ignored, since there is no way which SKU is being added // Must be only one sku... if (sizeof($product_skus) != 1) { continue; } $skus[$product_skus[0]] = $qty; } } else { if (!is_array($skus)) { $skus = array($skus => 1); } } //print_r($skus); die; // Turn off syncing to prevent redundant session update queries $cart->setSync(false); foreach ($skus as $sId => $qty) { try { $cart->update($sId, $qty); } catch (Exception $e) { $cart->setMessage($e->getMessage(), 'error'); } } // set flag to redirect $redirect = true; if ($cart->hasMessages()) { $redirect = false; } } else { $allPost = Request::request(); foreach ($allPost as $var => $val) { if ($val == 'delete') { $toDelete = explode('_', $var); //print_r($toDelete); die; if ($toDelete[0] == 'delete') { $sId = $toDelete[1]; // Delete the requested item by setting its QTY to zero $redirect = true; try { $cart->update($sId, 0); } catch (Exception $e) { $cart->setMessage($e->getMessage(), 'error'); $redirect = false; } } } } } // Add coupon if needed $addCouponRequest = Request::getVar('addCouponCode', false, 'post'); $couponCode = Request::getVar('couponCode', false, 'post'); if ($addCouponRequest && $couponCode) { // Sync cart before pontial coupons applying $cart->getCartInfo(true); // Add coupon try { $cart->addCoupon($couponCode); } catch (Exception $e) { $cart->setMessage($e->getMessage(), 'error'); } // set flag to redirect $redirect = true; if ($cart->hasMessages()) { $redirect = false; } } // Check for express add to cart if (!empty($redirect) && $redirect) { // If this is an express checkout (go to the confirm page right away) there shouldn't be any items in the cart // Since redirect is set, there are no errors $expressCheckout = Request::getVar('expressCheckout', false, 'post'); // make sure the cart is empty if ($expressCheckout && !empty($skus) && $cart->isEmpty()) { // Get the latest synced cart info, it will also enable cart syncing that was turned off before $cart->getCartInfo(true); // Redirect directly to checkout, skip the cart page $redirect_url = Route::url('index.php?option=' . 'com_cart') . DS . 'checkout'; App::redirect($redirect_url); } // prevent resubmitting form by refresh // redirect to cart $redirect_url = Route::url('index.php?option=' . 'com_cart'); App::redirect($redirect_url); } // Get the latest synced cart info, it will also enable cart syncing that was turned off before $cartInfo = $cart->getCartInfo(true); $this->view->cartInfo = $cartInfo; // Handle coupons $couponPerks = $cart->getCouponPerks(); //print_r($couponPerks); die; $this->view->couponPerks = $couponPerks; // Handle memberships $membershipInfo = $cart->getMembershipInfo(); //print_r($membershipInfo); die; $this->view->membershipInfo = $membershipInfo; // At this point the cart is lifted and may have some issues/errors (say, after merging), get them if ($cart->hasMessages()) { $cartMessages = $cart->getMessages(); $this->view->notifications = $cartMessages; } $this->view->display(); }