/** * Calculates and returns the current price for the given order product and product prices. * * @param \Aimeos\MShop\Order\Item\Base\Product\Iface $product Ordered product item * @param \Aimeos\MShop\Price\Item\Iface[] $prices List of price items * @param integer $quantity New product quantity * @return \Aimeos\MShop\Price\Item\Iface Price item with calculated price */ protected function calcPrice(\Aimeos\MShop\Order\Item\Base\Product\Iface $product, array $prices, $quantity) { $context = $this->getContext(); if (empty($prices)) { $manager = \Aimeos\MShop\Factory::createManager($this->getContext(), 'product'); $prices = $manager->getItem($product->getProductId(), array('price'))->getRefItems('price', 'default'); } $priceManager = \Aimeos\MShop\Factory::createManager($context, 'price'); $price = $priceManager->getLowestPrice($prices, $quantity); foreach ($this->getAttributeItems($product->getAttributes()) as $attrItem) { $prices = $attrItem->getRefItems('price', 'default'); if (count($prices) > 0) { $attrPrice = $priceManager->getLowestPrice($prices, $quantity); $price->addItem($attrPrice); } } // remove product rebate of original price in favor to rebates granted for the order $price->setRebate('0.00'); return $price; }
/** * 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 \Aimeos\MShop\Order\Item\Base\Product\Iface $item Order product item * @return integer Positon of the same product in the product list * @throws \Aimeos\MShop\Order\Exception If no similar item was found */ protected function getSameProduct(\Aimeos\MShop\Order\Item\Base\Product\Iface $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; }
/** * Adds attribute items to an array. * * @param \Aimeos\MShop\Common\Item\Iface $item Item containing the properties to be added as attributes * @param \Aimeos\MShop\Order\Item\Base\Product\Iface $product Product containing attributes * @param Array $properties List of item properties to be converted * @return Array List of attributes */ protected function addAttributes(\Aimeos\MShop\Common\Item\Iface $item, \Aimeos\MShop\Order\Item\Base\Product\Iface $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 \Aimeos\MShop\Order\Item\Base\Product\Iface $orderProduct Ordered product * @param array $refPrices Prices associated to the original product * @param \Aimeos\MShop\Attribute\Item\Iface[] $attributes Attribute items with prices * @param integer $pos Position of the product in the basket * @return \Aimeos\MShop\Price\Item\Iface Price item including the calculated price */ private function getPrice(\Aimeos\MShop\Order\Item\Base\Product\Iface $orderProduct, array $refPrices, array $attributes, $pos) { $context = $this->getContext(); // fetch prices of selection/parent products if (empty($refPrices)) { $productManager = \Aimeos\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 \Aimeos\MShop\Plugin\Provider\Exception($msg, -1, null, $codes); } $priceManager = \Aimeos\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; }