/** * Validate stock of a quoteItem * * @param Mage_Sales_Model_Quote_Item $item * @param float $priceInclTax * @param float $priceExclTax * * @return ShopgateCartItem $result */ public function validateStock(Mage_Sales_Model_Quote_Item $item, $priceInclTax, $priceExclTax) { $product = $item->getProduct(); /** @var Mage_CatalogInventory_Model_Stock_Item $stockItem */ $stockItem = $product->getStockItem(); $errors = array(); $isBuyable = true; $qtyBuyable = null; foreach ($item->getChildren() as $childItem) { /** @var Mage_Catalog_Model_Product $childProduct */ $childProduct = $childItem->getProduct(); /** @var Mage_CatalogInventory_Model_Stock_Item $childStock */ $childStock = $childProduct->getStockItem(); if ($childStock->getManageStock() && !$childProduct->isSaleable() && !$childStock->getBackorders()) { $isBuyable = false; $error = array(); $error['type'] = ShopgateLibraryException::CART_ITEM_OUT_OF_STOCK; $error['message'] = ShopgateLibraryException::getMessageFor(ShopgateLibraryException::CART_ITEM_OUT_OF_STOCK); $errors[] = $error; } else { if ($childStock->getManageStock() && !$childStock->checkQty($childItem->getQty()) && !$childStock->getBackorders()) { $isBuyable = false; $error = array(); $error['type'] = ShopgateLibraryException::CART_ITEM_REQUESTED_QUANTITY_NOT_AVAILABLE; $error['message'] = ShopgateLibraryException::getMessageFor(ShopgateLibraryException::CART_ITEM_REQUESTED_QUANTITY_NOT_AVAILABLE); $errors[] = $error; if ($qtyBuyable == null || $qtyBuyable > $childStock->getQty()) { $qtyBuyable = $childStock->getQty(); } } else { if (Mage::helper('shopgate/config')->getIsMagentoVersionLower1410()) { $checkIncrements = Mage::helper('shopgate')->checkQtyIncrements($childStock, $childItem->getQty()); } else { $checkIncrements = $childStock->checkQtyIncrements($childItem->getQty()); } if ($childStock->getManageStock() && $checkIncrements->getHasError()) { $isBuyable = false; $error = array(); $error['type'] = ShopgateLibraryException::CART_ITEM_REQUESTED_QUANTITY_NOT_AVAILABLE; $error['message'] = ShopgateLibraryException::getMessageFor(ShopgateLibraryException::CART_ITEM_REQUESTED_QUANTITY_NOT_AVAILABLE); $errors[] = $error; $stockItem->setQty((int) ($item->getQtyToAdd() / $stockItem->getQtyIncrements()) * $stockItem->getQtyIncrements()); } } } } $qtyBuyable = $qtyBuyable == null ? (int) $item->getQty() : (int) $qtyBuyable; return Mage::helper('shopgate')->generateShopgateCartItem($product, $isBuyable, $qtyBuyable, $priceInclTax, $priceExclTax, $errors, (int) $stockItem->getQty()); }
/** * Validate stock of a quoteItem * * @param Mage_Sales_Model_Quote_Item $item * @param float $priceInclTax * @param float $priceExclTax * @return ShopgateCartItem $result */ public function validateStock(Mage_Sales_Model_Quote_Item $item, $priceInclTax, $priceExclTax) { /** @var Mage_Catalog_Model_Product $product */ $product = $item->getProduct(); /** @var Mage_CatalogInventory_Model_Stock_Item $stockItem */ $stockItem = $product->getStockItem(); $isBuyable = true; if ($product->isConfigurable()) { $parent = $product; $product = $product->getCustomOption('simple_product')->getProduct(); $product->setShopgateItemNumber($parent->getShopgateItemNumber()); $product->setShopgateOptions($parent->getShopgateOptions()); $product->setShopgateInputs($parent->getShopgateInputs()); $product->setShhopgateAttributes($parent->getShhopgateAttributes()); $stockItem = $item->getProduct()->getCustomOption('simple_product')->getProduct()->getStockItem(); } $errors = array(); if (Mage::helper('shopgate/config')->getIsMagentoVersionLower1410()) { $checkIncrements = Mage::helper('shopgate')->checkQtyIncrements($stockItem, $item->getQty()); } else { $checkIncrements = $stockItem->checkQtyIncrements($item->getQty()); } if ($stockItem->getManageStock() && !$product->isSaleable() && (!$stockItem->getBackorders() || !$stockItem->getIsInStock())) { $isBuyable = false; $error = array(); $error['type'] = ShopgateLibraryException::CART_ITEM_OUT_OF_STOCK; $error['message'] = ShopgateLibraryException::getMessageFor(ShopgateLibraryException::CART_ITEM_OUT_OF_STOCK); $errors[] = $error; } else { if ($stockItem->getManageStock() && !$stockItem->checkQty($item->getQty()) && !$stockItem->getBackorders()) { $isBuyable = false; $error = array(); $error['type'] = ShopgateLibraryException::CART_ITEM_REQUESTED_QUANTITY_NOT_AVAILABLE; $error['message'] = ShopgateLibraryException::getMessageFor(ShopgateLibraryException::CART_ITEM_REQUESTED_QUANTITY_NOT_AVAILABLE); $errors[] = $error; } else { if ($stockItem->getManageStock() && $checkIncrements->getHasError()) { $isBuyable = false; $error = array(); $error['type'] = ShopgateLibraryException::CART_ITEM_REQUESTED_QUANTITY_NOT_AVAILABLE; $error['message'] = ShopgateLibraryException::getMessageFor(ShopgateLibraryException::CART_ITEM_REQUESTED_QUANTITY_NOT_AVAILABLE); $errors[] = $error; $stockItem->setQty((int) ($item->getQtyToAdd() / $stockItem->getQtyIncrements()) * $stockItem->getQtyIncrements()); } } } $qtyBuyable = $isBuyable ? (int) $item->getQty() : (int) $stockItem->getQty(); return Mage::helper('shopgate')->generateShopgateCartItem($product, $isBuyable, $qtyBuyable, $priceInclTax, $priceExclTax, $errors, (int) $stockItem->getQty()); }
public function handleRequest(array $data = array()) { $errortext = ''; $this->setEnableErrorReporting(); // log incoming request $this->log(ShopgateLogger::getInstance()->cleanParamsForLog($data), ShopgateLogger::LOGTYPE_ACCESS); // save the params $this->params = $data; // save trace_id if (isset($this->params['trace_id'])) { $this->trace_id = $this->params['trace_id']; } try { if (!in_array($this->params['action'], $this->authlessActionWhitelist)) { $this->authService->checkAuthentication(); } // set error handler to Shopgate's handler if requested if (!empty($this->params['use_errorhandler'])) { if (isset($this->params['print_stack_trace'])) { $printStackTrace = $this->params['print_stack_trace']; } set_error_handler('ShopgateErrorHandler'); $this->setEnablePrintErrorsToLog($this->config->getErrorLogPath()); } if (!empty($this->params['use_shutdown_handler'])) { register_shutdown_function('ShopgateShutdownHandler'); } // enable debugging if requested if (!empty($this->params['debug_log'])) { ShopgateLogger::getInstance()->enableDebug(); ShopgateLogger::getInstance()->keepDebugLog(!empty($this->params['keep_debug_log'])); } // enable error reporting if requested if (!empty($this->params['error_reporting'])) { error_reporting($this->params['error_reporting']); ini_set('display_errors', version_compare(PHP_VERSION, '5.2.4', '>=') ? 'stdout' : true); } // memory logging size unit setup if (!empty($this->params['memory_logging_unit'])) { ShopgateLogger::getInstance()->setMemoryAnalyserLoggingSizeUnit($this->params['memory_logging_unit']); } else { // MB by default if none is set ShopgateLogger::getInstance()->setMemoryAnalyserLoggingSizeUnit('MB'); } // check if the request is for the correct shop number or an adapter-plugin if (!$this->config->getIsShopgateAdapter() && !empty($this->params['shop_number']) && $this->params['shop_number'] != $this->config->getShopNumber()) { throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_UNKNOWN_SHOP_NUMBER, "{$this->params['shop_number']}"); } // check if an action to call has been passed, is known and enabled if (empty($this->params['action'])) { throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_NO_ACTION, 'Passed parameters: ' . var_export($this->params, true)); } // check if the action is white-listed if (!in_array($this->params['action'], $this->actionWhitelist)) { throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_UNKNOWN_ACTION, "{$this->params['action']}"); } // check if action is enabled in the config $configArray = $this->config->toArray(); if (empty($configArray['enable_' . $this->params['action']])) { throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_DISABLED_ACTION, "{$this->params['action']}"); } // response output is active by default and can be deactivated to allow actions to print a custom output $this->preventResponseOutput = false; // call the action $action = $this->camelize($this->params['action']); if (in_array($this->params['action'], $this->exportActionList)) { if (isset($this->params['memory_limit'])) { $this->plugin->setExportMemoryLimit((int) $this->params['memory_limit']); } else { $this->plugin->setExportMemoryLimit($this->config->getDefaultMemoryLimit()); } if (isset($this->params['max_execution_time'])) { $this->plugin->setExportTimeLimit((int) $this->params['max_execution_time']); } else { $this->plugin->setExportTimeLimit($this->config->getDefaultExecutionTime()); } } $this->{$action}(); } catch (ShopgateLibraryException $e) { $error = $e->getCode(); $errortext = $e->getMessage(); } catch (ShopgateMerchantApiException $e) { $error = ShopgateLibraryException::MERCHANT_API_ERROR_RECEIVED; $errortext = ShopgateLibraryException::getMessageFor(ShopgateLibraryException::MERCHANT_API_ERROR_RECEIVED) . ': "' . $e->getCode() . ' - ' . $e->getMessage() . '"'; } catch (Exception $e) { $message = "\n" . get_class($e) . "\n"; $message .= 'with code: ' . $e->getCode() . "\n"; $message .= 'and message: \'' . $e->getMessage() . "'\n"; // new ShopgateLibraryException to build proper error message and perform logging $se = new ShopgateLibraryException($message, null, false, true, $e); $error = $se->getCode(); $errortext = $se->getMessage(); } // print out the response if (!empty($error)) { if (empty($this->response)) { $this->response = new ShopgatePluginApiResponseAppJson($this->trace_id); } $this->response->markError($error, $errortext); } if (empty($this->response)) { trigger_error('No response object defined. This should _never_ happen.', E_USER_ERROR); } if (!$this->preventResponseOutput) { $this->response->setData($this->responseData); if (empty($this->params['error_reporting']) && ob_get_contents()) { ob_clean(); } $this->response->send(); } // return true or false return empty($error); }
/** * Returns all items from quote and validates * them by quantity and addresses. * * @param Mage_Sales_Model_Quote $quote * @param ShopgateCart $cart * * @return array */ public function getItems($quote, ShopgateCart $cart) { $validator = Mage::getModel('shopgate/shopgate_cart_validation_stock'); $items = array(); $quote->collectTotals(); /** @var Mage_Sales_Model_Quote_Item $_item */ foreach ($quote->getAllVisibleItems() as $_item) { /** @var Mage_Catalog_Model_Product $_item */ $items[] = $validator->validateStock($_item, $_item->getPriceInclTax(), $_item->getPrice()); } foreach (Mage::helper('shopgate')->fetchMissingQuoteItems($cart, $quote) as $_item) { $item = Mage::helper('shopgate')->generateShopgateCartItem($_item->getProduct()); $catchedErrors = $quote->getShopgateError(); $sgError = ShopgateLibraryException::CART_ITEM_OUT_OF_STOCK; if ($catchedErrors) { if (array_key_exists($item->getItemNumber(), $catchedErrors)) { foreach ($catchedErrors[$item->getItemNumber()] as $error) { if ($error == Mage::helper('catalog')->__('The text is too long')) { $sgError = ShopgateLibraryException::CART_ITEM_INPUT_VALIDATION_FAILED; } } } } $item->setError($sgError); $item->setErrorText(ShopgateLibraryException::getMessageFor($sgError)); $items[] = $item; } return $items; }
/** * Check coupons for validation * Function will throw an ShopgateLibraryException if * * Count of coupons > 1 * * Coupon cannot found * * Magento throws an exception * * @param $mageCart * @param ShopgateCart $cart * * @return mixed|null|ShopgateExternalCoupon * @throws ShopgateLibraryException */ public function checkCoupons($mageCart, ShopgateCart $cart) { /* @var $mageQuote Mage_Sales_Model_Quote */ /* @var $mageCart Mage_Checkout_Model_Cart */ /* @var $mageCoupon Mage_SalesRule_Model_Coupon */ /* @var $mageRule Mage_SalesRule_Model_Rule */ if (!$cart->getExternalCoupons()) { return null; } $externalCoupons = array(); $mageQuote = $mageCart->getQuote(); $validCouponsInCart = 0; foreach ($cart->getExternalCoupons() as $coupon) { /** @var ShopgateExternalCoupon $coupon */ $externalCoupon = new ShopgateExternalCoupon(); $externalCoupon->setIsValid(true); $externalCoupon->setCode($coupon->getCode()); try { $mageQuote->setCouponCode($coupon->getCode()); $mageQuote->setTotalsCollectedFlag(false)->collectTotals(); } catch (Exception $e) { $externalCoupon->setIsValid(false); $externalCoupon->setNotValidMessage($e->getMessage()); } if ($this->_getConfigHelper()->getIsMagentoVersionLower1410()) { $mageRule = Mage::getModel('salesrule/rule')->load($coupon->getCode(), 'coupon_code'); $mageCoupon = $mageRule; } else { $mageCoupon = Mage::getModel('salesrule/coupon')->load($coupon->getCode(), 'code'); $mageRule = Mage::getModel('salesrule/rule')->load($mageCoupon->getRuleId()); } if ($mageRule->getId() && $mageQuote->getCouponCode()) { $couponInfo = array(); $couponInfo["coupon_id"] = $mageCoupon->getId(); $couponInfo["rule_id"] = $mageRule->getId(); $amountCoupon = $mageQuote->getSubtotal() - $mageQuote->getSubtotalWithDiscount(); $storeLabel = $mageRule->getStoreLabel(Mage::app()->getStore()->getId()); $externalCoupon->setName($storeLabel ? $storeLabel : $mageRule->getName()); $externalCoupon->setDescription($mageRule->getDescription()); $externalCoupon->setIsFreeShipping((bool) $mageQuote->getShippingAddress()->getFreeShipping()); $externalCoupon->setInternalInfo($this->jsonEncode($couponInfo)); $externalCoupon->setAmountGross($amountCoupon); if (!$amountCoupon && !$externalCoupon->getIsFreeShipping()) { $externalCoupon->setIsValid(false); $externalCoupon->setNotValidMessage($this->_getHelper()->__('Coupon code "%s" is not valid.', Mage::helper('core')->htmlEscape($coupon->getCode()))); } $externalCoupon->setTaxType('not_taxable'); } else { $externalCoupon->setIsValid(false); $externalCoupon->setNotValidMessage($this->_getHelper()->__('Coupon code "%s" is not valid.', Mage::helper('core')->htmlEscape($coupon->getCode()))); } if ($externalCoupon->getIsValid() && $validCouponsInCart >= 1) { $errorCode = ShopgateLibraryException::COUPON_TOO_MANY_COUPONS; $externalCoupon->setIsValid(false); $externalCoupon->setNotValidMessage(ShopgateLibraryException::getMessageFor($errorCode)); } if ($externalCoupon->getIsValid()) { $validCouponsInCart++; } $externalCoupons[] = $externalCoupon; } return $externalCoupons; }
/** * add a item exception * * @param ShopgateCartItem $item * @param $code * @param mixed $message */ protected function _addItemException(ShopgateCartItem $item, $code, $message = false) { $item->setError($code); /** * add custom message */ if ($message) { $item->setErrorText($message); } else { $item->setErrorText(ShopgateLibraryException::getMessageFor($code)); } }
public function handleRequest(array $data = array()) { // log incoming request $this->log(ShopgateLogger::getInstance()->cleanParamsForLog($data), ShopgateLogger::LOGTYPE_ACCESS); // save the params $this->params = $data; // save trace_id if (isset($this->params['trace_id'])) { $this->trace_id = $this->params['trace_id']; } try { $this->authService->checkAuthentification(); // set error handler to Shopgate's handler if requested if (!empty($this->params['use_errorhandler'])) { set_error_handler('ShopgateErrorHandler'); } // check if the request is for the correct shop number or an adapter-plugin if (!$this->config->getIsShopgateAdapter() && !empty($this->params['shop_number']) && $this->params['shop_number'] != $this->config->getShopNumber()) { throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_UNKNOWN_SHOP_NUMBER, "{$this->params['shop_number']}"); } // check if an action to call has been passed, is known and enabled if (empty($this->params['action'])) { throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_NO_ACTION, 'Passed parameters: ' . var_export($data, true)); } // check if the action is white-listed if (!in_array($this->params['action'], $this->actionWhitelist)) { throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_UNKNOWN_ACTION, "{$this->params['action']}"); } // check if action is enabled in the config $configArray = $this->config->toArray(); if (empty($configArray['enable_' . $this->params['action']])) { throw new ShopgateLibraryException(ShopgateLibraryException::PLUGIN_API_DISABLED_ACTION, "{$this->params['action']}"); } // enable debugging if requested if (!empty($data['debug_log'])) { ShopgateLogger::getInstance()->enableDebug(); ShopgateLogger::getInstance()->keepDebugLog(!empty($data['keep_debug_log'])); } // enable error handler if requested if (!empty($data['error_reporting'])) { error_reporting($data['error_reporting']); } // call the action $action = $this->camelize($this->params['action']); $this->{$action}(); } catch (ShopgateLibraryException $e) { $error = $e->getCode(); $errortext = $e->getMessage(); } catch (ShopgateMerchantApiException $e) { $error = ShopgateLibraryException::MERCHANT_API_ERROR_RECEIVED; $errortext = ShopgateLibraryException::getMessageFor(ShopgateLibraryException::MERCHANT_API_ERROR_RECEIVED) . ': "' . $e->getCode() . ' - ' . $e->getMessage() . '"'; } catch (Exception $e) { $message = "\n" . get_class($e) . "\n"; $message .= 'with code: ' . $e->getCode() . "\n"; $message .= 'and message: \'' . $e->getMessage() . "'\n"; // new ShopgateLibraryException to build proper error message and perform logging $se = new ShopgateLibraryException($message); $error = $se->getCode(); $errortext = $se->getMessage(); } // print out the response if (!empty($error)) { if (empty($this->response)) { $this->response = new ShopgatePluginApiResponseAppJson($this->trace_id); } $this->response->markError($error, $errortext); } if (empty($this->response)) { trigger_error('No response object defined. This should _never_ happen.', E_USER_ERROR); } $this->response->setData($this->responseData); $this->response->send(); // return true or false return empty($error); }