/** * Checks for the product limits when the configuration contains limits per currency. * * @param MShop_Order_Item_Base_Interface $order Basket object * @param MShop_Order_Item_Base_Product_Interface $value Order product item * @throws MShop_Plugin_Provider_Exception If one limit is exceeded */ protected function _checkWithCurrency(MShop_Order_Item_Base_Interface $order, MShop_Order_Item_Base_Product_Interface $value) { $config = $this->_getItem()->getConfig(); $currencyId = $value->getPrice()->getCurrencyId(); if (isset($config['single-value-max'][$currencyId]) && $value->getPrice()->getValue() * $value->getQuantity() > (double) $config['single-value-max'][$currencyId]) { $msg = sprintf('The maximum product value is %1$s', $config['single-value-max'][$currencyId]); throw new MShop_Plugin_Provider_Exception($msg); } if (isset($config['total-value-max'][$currencyId])) { $price = clone $value->getPrice(); $price->setValue($price->getValue() * $value->getQuantity()); foreach ($order->getProducts() as $product) { $price->addItem($product->getPrice(), $product->getQuantity()); } if ((double) $price->getValue() > (double) $config['total-value-max'][$currencyId]) { $msg = sprintf('The maximum value of all products is %1$s', $config['total-value-max'][$currencyId]); throw new MShop_Plugin_Provider_Exception($msg); } } }
/** * Compares the properties of the given order product item with its own ones. * * @param MShop_Order_Item_Base_Product_Interface $item Order product item * @return boolean True if the item properties are equal, false if not * @since 2014.09 */ public function compare(MShop_Order_Item_Base_Product_Interface $item) { if ($this->getFlags() === $item->getFlags() && $this->getName() === $item->getName() && $this->getProductCode() === $item->getProductCode() && $this->getSupplierCode() === $item->getSupplierCode() && $this->getPrice()->compare($item->getPrice()) === true) { return true; } return false; }
/** * Tests if the given product is similar to an existing one. * Similarity is described by the equality of properties so the quantity of * the existing product can be updated. * * @param MShop_Order_Item_Base_Product_Interface $item Order product item * @return integer Positon of the same product in the product list * @throws MShop_Order_Exception If no similar item was found */ protected function _getSameProduct(MShop_Order_Item_Base_Product_Interface $item) { $attributeMap = array(); foreach ($item->getAttributes() as $attributeItem) { $attributeMap[$attributeItem->getCode()] = $attributeItem; } foreach ($this->_products as $position => $product) { if ($product->compare($item) === false) { continue; } $prodAttributes = $product->getAttributes(); if (count($prodAttributes) !== count($attributeMap)) { continue; } foreach ($prodAttributes as $attribute) { if (array_key_exists($attribute->getCode(), $attributeMap) === false || $attributeMap[$attribute->getCode()]->getValue() != $attribute->getValue()) { continue 2; // jump to outer loop } } return $position; } return false; }
/** * Checks if a order product contains all required values. * * @param MShop_Order_Item_Base_Product_Interface $item Order product item * @throws MShop_Exception if the price item or product code is missing */ protected function _checkProduct(MShop_Order_Item_Base_Product_Interface $item) { if ($item->getProductCode() === '') { throw new MShop_Order_Exception(sprintf('Product does not contain all required values. Product code for item not available.')); } }
/** * Adds attribute items to an array. * * @param MShop_Common_Item_Interface $item Item containing the properties to be added as attributes * @param MShop_Order_Item_Base_Product_Interface $product Product containing attributes * @param Array $properties List of item properties to be converted * @return Array List of attributes */ protected function _addAttributes(MShop_Common_Item_Interface $item, MShop_Order_Item_Base_Product_Interface $product, array $properties) { $attributeList = $product->getAttributes(); $itemProperties = $item->toArray(); foreach ($properties as $code) { if (array_key_exists($code, $itemProperties) && $product->getAttribute($code, $this->_type) === null) { $new = $this->_orderAttrManager->createItem(); $new->setCode($code); $new->setType($this->_type); $new->setValue($itemProperties[$code]); $attributeList[] = $new; } } return $attributeList; }
/** * Returns the actual price for the given order product. * * @param MShop_Order_Item_Base_Product_Interface $orderProduct Ordered product * @param array $refPrices Prices associated to the original product * @param MShop_Attribute_Item_Interface[] $attributes Attribute items with prices * @param integer $pos Position of the product in the basket * @return MShop_Price_Item_Interface Price item including the calculated price */ private function _getPrice(MShop_Order_Item_Base_Product_Interface $orderProduct, array $refPrices, array $attributes, $pos) { $context = $this->_getContext(); // fetch prices of selection/parent products if (empty($refPrices)) { $productManager = MShop_Factory::createManager($context, 'product'); $product = $productManager->getItem($orderProduct->getProductId(), array('price')); $refPrices = $product->getRefItems('price', 'default', 'default'); } if (empty($refPrices)) { $pid = $orderProduct->getProductId(); $pcode = $orderProduct->getProductCode(); $codes = array('product' => array($pos => 'product.price')); $msg = sprintf('No price for product ID "%1$s" or product code "%2$s" available', $pid, $pcode); throw new MShop_Plugin_Provider_Exception($msg, -1, null, $codes); } $priceManager = MShop_Factory::createManager($context, 'price'); $price = $priceManager->getLowestPrice($refPrices, $orderProduct->getQuantity()); // add prices of product attributes to compute the end price for comparison foreach ($orderProduct->getAttributes() as $orderAttribute) { $attrPrices = array(); $attrId = $orderAttribute->getAttributeId(); if (isset($attributes[$attrId])) { $attrPrices = $attributes[$attrId]->getRefItems('price', 'default', 'default'); } if (!empty($attrPrices)) { $price->addItem($priceManager->getLowestPrice($attrPrices, $orderProduct->getQuantity())); } } // reset product rebates like in the basket controller $price->setRebate('0.00'); return $price; }
/** * Returns the variant attributes and updates the price list if necessary. * * @param MShop_Order_Item_Base_Product_Interface $orderBaseProductItem Order product item * @param MShop_Product_Item_Interface &$productItem Product item which is replaced if necessary * @param array &$prices List of product prices that will be updated if necessary * @param array $variantAttributeIds List of product variant attribute IDs * @param array $options Associative list of options * @return MShop_Order_Item_Base_Product_Attribute_Interface[] List of order product attributes * @throws Controller_Frontend_Basket_Exception If no product variant is found */ private function _getVariantDetails(MShop_Order_Item_Base_Product_Interface $orderBaseProductItem, MShop_Product_Item_Interface &$productItem, array &$prices, array $variantAttributeIds, array $options) { $attr = array(); $productItems = $this->_getProductVariants($productItem, $variantAttributeIds); if (count($productItems) > 1) { $msg = sprintf('No unique article found for selected attributes and product ID "%1$s"', $productItem->getId()); throw new Controller_Frontend_Basket_Exception($msg); } else { if (($result = reset($productItems)) !== false) { $productItem = $result; $orderBaseProductItem->setProductCode($productItem->getCode()); $subprices = $productItem->getRefItems('price', 'default', 'default'); if (count($subprices) > 0) { $prices = $subprices; } $orderProductAttrManager = MShop_Factory::createManager($this->_getContext(), 'order/base/product/attribute'); $variantAttributes = $productItem->getRefItems('attribute', null, 'variant'); foreach ($this->_getAttributes(array_keys($variantAttributes), array('text')) as $attrItem) { $orderAttributeItem = $orderProductAttrManager->createItem(); $orderAttributeItem->copyFrom($attrItem); $orderAttributeItem->setType('variant'); $attr[] = $orderAttributeItem; } } else { if (!isset($options['variant']) || $options['variant'] != false) { $msg = sprintf('No article found for selected attributes and product ID "%1$s"', $productItem->getId()); throw new Controller_Frontend_Basket_Exception($msg); } } } return $attr; }
/** * Creates an attribute with given values for code, type, name and value * * @param String $code Value for attribute code * @param String $value Value for attribute value * @param String $name Optional value for attribute name * @return MShop_Order_Item_Base_Product_Attribute_Interface Newly created attribte item */ protected function _createAttribute(MShop_Order_Item_Base_Product_Interface $product, $code, $value, $name = null) { if ($product->getAttribute($code) !== null) { return null; } $new = $this->_orderAttrManager->createItem(); $new->setCode($code); $new->setType($this->_type); $new->setName($name); $new->setValue($value); return $new; }