/**
  * Receives a notification from a publisher object
  *
  * @param \Aimeos\MW\Observer\Publisher\Iface $order Shop basket instance implementing publisher interface
  * @param string $action Name of the action to listen for
  * @param mixed $value Object or value changed in publisher
  * @throws \Aimeos\MShop\Plugin\Provider\Exception if checks fail
  * @return bool true if checks succeed
  */
 public function update(\Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null)
 {
     if (!$order instanceof \Aimeos\MShop\Order\Item\Base\Iface) {
         $msg = $this->getContext()->getI18n()->dt('mshop', 'Object is not of required type "%1$s"');
         throw new \Aimeos\MShop\Plugin\Exception(sprintf($msg, '\\Aimeos\\MShop\\Order\\Item\\Base\\Iface'));
     }
     if ($value & \Aimeos\MShop\Order\Item\Base\Base::PARTS_ADDRESS) {
         $problems = array();
         $availableAddresses = $order->getAddresses();
         foreach ($this->getItemBase()->getConfig() as $type => $value) {
             if ($value == true && !isset($availableAddresses[$type])) {
                 $problems[$type] = 'available.none';
             }
             if ($value !== null && $value !== '' && $value == false && isset($availableAddresses[$type])) {
                 $problems[$type] = 'available.notallowed';
             }
         }
         if (count($problems) > 0) {
             $code = array('address' => $problems);
             $msg = $this->getContext()->getI18n()->dt('mshop', 'Checks for available addresses in basket failed');
             throw new \Aimeos\MShop\Plugin\Provider\Exception($msg, -1, null, $code);
         }
     }
     return true;
 }
Example #2
0
 /**
  * Receives a notification from a publisher object
  *
  * @param \Aimeos\MW\Observer\Publisher\Iface $order Shop basket instance implementing publisher interface
  * @param string $action Name of the action to listen for
  * @param mixed $value Object or value changed in publisher
  * @throws \Aimeos\MShop\Plugin\Provider\Exception if an error occurs
  * @return bool true if subsequent plugins should be processed
  */
 public function update(\Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null)
 {
     if (!$order instanceof \Aimeos\MShop\Order\Item\Base\Iface) {
         $msg = $this->getContext()->getI18n()->dt('mshop', 'Object is not of required type "%1$s"');
         throw new \Aimeos\MShop\Plugin\Exception(sprintf($msg, '\\Aimeos\\MShop\\Order\\Item\\Base\\Iface'));
     }
     $context = $this->getContext();
     $services = $order->getServices();
     $addresses = $order->getAddresses();
     if (($userid = $context->getUserId()) !== null && (bool) $this->getConfigValue('autofill.useorder', false) === true && (empty($addresses) || empty($services))) {
         $orderManager = \Aimeos\MShop\Factory::createManager($context, 'order');
         $search = $orderManager->createSearch();
         $search->setConditions($search->compare('==', 'order.base.customerid', $userid));
         $search->setSortations(array($search->sort('-', 'order.ctime')));
         $search->setSlice(0, 1);
         $result = $orderManager->searchItems($search);
         if (($item = reset($result)) !== false) {
             $this->setAddresses($order, $item);
             $this->setServices($order, $item);
         }
     }
     $this->setAddressDefault($order);
     $this->setServicesDefault($order);
     return true;
 }
Example #3
0
 /**
  * Receives a notification from a publisher object
  *
  * @param \Aimeos\MW\Observer\Publisher\Iface $order Shop basket instance implementing publisher interface
  * @param string $action Name of the action to listen for
  * @param mixed $value Object or value changed in publisher
  */
 public function update(\Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null)
 {
     if (!$order instanceof \Aimeos\MShop\Order\Item\Base\Iface) {
         $msg = $this->getContext()->getI18n()->dt('mshop', 'Object is not of required type "%1$s"');
         throw new \Aimeos\MShop\Plugin\Exception(sprintf($msg, '\\Aimeos\\MShop\\Order\\Item\\Base\\Iface'));
     }
     $notAvailable = array();
     if (self::$lock === false) {
         self::$lock = true;
         $couponManager = \Aimeos\MShop\Factory::createManager($this->getContext(), 'coupon');
         foreach ($order->getCoupons() as $code => $products) {
             $search = $couponManager->createSearch(true);
             $expr = array($search->compare('==', 'coupon.code.code', $code), $search->getConditions());
             $search->setConditions($search->combine('&&', $expr));
             $search->setSlice(0, 1);
             $results = $couponManager->searchItems($search);
             if (($couponItem = reset($results)) !== false) {
                 $couponProvider = $couponManager->getProvider($couponItem, $code);
                 $couponProvider->updateCoupon($order);
             } else {
                 $notAvailable[$code] = 'coupon.gone';
             }
         }
         self::$lock = false;
     }
     if (count($notAvailable) > 0) {
         $codes = array('coupon' => $notAvailable);
         $msg = $this->getContext()->getI18n()->dt('mshop', 'Coupon in basket is not available any more');
         throw new \Aimeos\MShop\Plugin\Provider\Exception($msg, -1, null, $codes);
     }
     return true;
 }
Example #4
0
 /**
  * Receives a notification from a publisher object
  *
  * @param \Aimeos\MW\Observer\Publisher\Iface $order Shop basket instance implementing publisher interface
  * @param string $action Name of the action to listen for
  * @param mixed $value Object or value changed in publisher
  * @throws \Aimeos\MShop\Plugin\Provider\Exception if checks fail
  * @return bool true if checks succeed
  */
 public function update(\Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null)
 {
     $class = '\\Aimeos\\MShop\\Order\\Item\\Base\\Iface';
     if (!$order instanceof $class) {
         throw new \Aimeos\MShop\Plugin\Order\Exception(sprintf('Object is not of required type "%1$s"', $class));
     }
     if (!($value & \Aimeos\MShop\Order\Item\Base\Base::PARTS_PRODUCT)) {
         return true;
     }
     $attrIds = $prodCodes = $changedProducts = array();
     $orderProducts = $order->getProducts();
     foreach ($orderProducts as $pos => $item) {
         if ($item->getFlags() & \Aimeos\MShop\Order\Item\Base\Product\Base::FLAG_IMMUTABLE) {
             unset($orderProducts[$pos]);
         }
         $prodCodes[] = $item->getProductCode();
         foreach ($item->getAttributes() as $ordAttrItem) {
             if (($id = $ordAttrItem->getAttributeId()) != '') {
                 $attrIds[$id] = null;
             }
         }
     }
     $attributes = $this->getAttributes(array_keys($attrIds));
     $prodMap = $this->getProducts($prodCodes);
     foreach ($orderProducts as $pos => $orderProduct) {
         $refPrices = array();
         // fetch prices of articles/sub-products
         if (isset($prodMap[$orderProduct->getProductCode()])) {
             $refPrices = $prodMap[$orderProduct->getProductCode()]->getRefItems('price', 'default', 'default');
         }
         $orderPosPrice = $orderProduct->getPrice();
         $price = $this->getPrice($orderProduct, $refPrices, $attributes, $pos);
         if ($orderPosPrice->compare($price) === false) {
             $orderProduct->setPrice($price);
             $order->deleteProduct($pos);
             $order->addProduct($orderProduct, $pos);
             $changedProducts[$pos] = 'price.changed';
         }
     }
     if (count($changedProducts) > 0) {
         $code = array('product' => $changedProducts);
         $msg = sprintf('Please have a look at the prices of the products in your basket');
         throw new \Aimeos\MShop\Plugin\Provider\Exception($msg, -1, null, $code);
     }
     return true;
 }
Example #5
0
 /**
  * Receives a notification from a publisher object
  *
  * @param \Aimeos\MW\Observer\Publisher\Iface $order Shop basket instance implementing publisher interface
  * @param string $action Name of the action to listen for
  * @param mixed $value Object or value changed in publisher
  */
 public function update(\Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null)
 {
     if (!$order instanceof \Aimeos\MShop\Order\Item\Base\Iface) {
         $msg = $this->getContext()->getI18n()->dt('mshop', 'Object is not of required type "%1$s"');
         throw new \Aimeos\MShop\Plugin\Exception(sprintf($msg, '\\Aimeos\\MShop\\Order\\Item\\Base\\Iface'));
     }
     $config = $this->getItemBase()->getConfig();
     if (!isset($config['threshold'])) {
         return true;
     }
     try {
         $delivery = $order->getService('delivery');
     } catch (\Aimeos\MShop\Order\Exception $oe) {
         // no delivery item available yet
         return true;
     }
     $this->checkThreshold($order, $delivery->getPrice(), $config['threshold']);
     return true;
 }
Example #6
0
 /**
  * Receives a notification from a publisher object
  *
  * @param \Aimeos\MW\Observer\Publisher\Iface $order Shop basket instance implementing publisher interface
  * @param string $action Name of the action to listen for
  * @param mixed $value Object or value changed in publisher
  * @throws \Aimeos\MShop\Plugin\Provider\Exception if checks fail
  * @return bool true if checks succeed
  */
 public function update(\Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null)
 {
     if (!$order instanceof \Aimeos\MShop\Order\Item\Base\Iface) {
         $msg = $this->getContext()->getI18n()->dt('mshop', 'Object is not of required type "%1$s"');
         throw new \Aimeos\MShop\Plugin\Exception(sprintf($msg, '\\Aimeos\\MShop\\Order\\Item\\Base\\Iface'));
     }
     if (!($value & \Aimeos\MShop\Order\Item\Base\Base::PARTS_PRODUCT)) {
         return true;
     }
     $productIds = array();
     foreach ($order->getProducts() as $pr) {
         $productIds[] = $pr->getProductId();
     }
     $productManager = \Aimeos\MShop\Factory::createManager($this->getContext(), 'product');
     $search = $productManager->createSearch();
     $search->setConditions($search->compare('==', 'product.id', $productIds));
     $checkItems = $productManager->searchItems($search);
     $notAvailable = array();
     $now = date('Y-m-d H-i-s');
     foreach ($order->getProducts() as $position => $orderProduct) {
         if (!array_key_exists($orderProduct->getProductId(), $checkItems)) {
             $notAvailable[$position] = 'gone.notexist';
             continue;
         }
         $product = $checkItems[$orderProduct->getProductId()];
         if ($product->getStatus() <= 0) {
             $notAvailable[$position] = 'gone.status';
             continue;
         }
         $start = $product->getDateStart();
         $end = $product->getDateEnd();
         if ($start !== null && $start >= $now || $end !== null && $now > $end) {
             $notAvailable[$position] = 'gone.timeframe';
         }
     }
     if (count($notAvailable) > 0) {
         $code = array('product' => $notAvailable);
         $msg = $this->getContext()->getI18n()->dt('mshop', 'Products in basket not available');
         throw new \Aimeos\MShop\Plugin\Provider\Exception($msg, -1, null, $code);
     }
     return true;
 }
Example #7
0
 /**
  * Receives a notification from a publisher object
  *
  * @param \Aimeos\MW\Observer\Publisher\Iface $order Shop basket instance implementing publisher interface
  * @param string $action Name of the action to listen for
  * @param mixed $value Object or value changed in publisher
  * @throws \Aimeos\MShop\Plugin\Provider\Exception if checks fail
  * @return bool true if checks succeed
  */
 public function update(\Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null)
 {
     if (!$order instanceof \Aimeos\MShop\Order\Item\Base\Iface) {
         $msg = $this->getContext()->getI18n()->dt('mshop', 'Object is not of required type "%1$s"');
         throw new \Aimeos\MShop\Plugin\Exception(sprintf($msg, '\\Aimeos\\MShop\\Order\\Item\\Base\\Iface'));
     }
     if (!($value & \Aimeos\MShop\Order\Item\Base\Base::PARTS_PRODUCT)) {
         return true;
     }
     $context = $this->getContext();
     $outOfStock = $productQuantities = $positions = array();
     $siteConfig = $context->getLocale()->getSite()->getConfig();
     foreach ($order->getProducts() as $position => $pr) {
         $productQuantities[$pr->getProductId()] = $pr->getQuantity();
         $positions[$pr->getProductId()] = $position;
     }
     $stockManager = \Aimeos\MShop\Factory::createManager($context, 'product/stock');
     $search = $stockManager->createSearch();
     $expr = array($search->compare('==', 'product.stock.parentid', array_keys($productQuantities)));
     if (isset($siteConfig['repository'])) {
         $expr[] = $search->compare('==', 'product.stock.warehouse.code', $siteConfig['warehouse']);
     }
     $search->setConditions($search->combine('&&', $expr));
     $checkItems = $stockManager->searchItems($search);
     foreach ($checkItems as $checkItem) {
         $parentid = $checkItem->getParentId();
         $stocklevel = $checkItem->getStocklevel();
         if ($stocklevel !== null && $stocklevel < $productQuantities[$parentid]) {
             $outOfStock[$positions[$parentid]] = 'stock.notenough';
         }
     }
     if (count($outOfStock) > 0) {
         $code = array('product' => $outOfStock);
         $msg = $this->getContext()->getI18n()->dt('mshop', 'Products out of stock');
         throw new \Aimeos\MShop\Plugin\Provider\Exception($msg, -1, null, $code);
     }
     return true;
 }
Example #8
0
 /**
  * Receives a notification from a publisher object
  *
  * @param \Aimeos\MW\Observer\Publisher\Iface $order Shop basket instance implementing publisher interface
  * @param string $action Name of the action to listen for
  * @param mixed $value Object or value changed in publisher
  * @throws \Aimeos\MShop\Plugin\Provider\Exception if checks fail
  * @return bool true if checks succeed
  */
 public function update(\Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null)
 {
     if (!$order instanceof \Aimeos\MShop\Order\Item\Base\Iface) {
         $msg = $this->getContext()->getI18n()->dt('mshop', 'Object is not of required type "%1$s"');
         throw new \Aimeos\MShop\Plugin\Exception(sprintf($msg, '\\Aimeos\\MShop\\Order\\Item\\Base\\Iface'));
     }
     if (!($value & \Aimeos\MShop\Order\Item\Base\Base::PARTS_PRODUCT)) {
         return true;
     }
     $context = $this->getContext();
     /** mshop/plugin/provider/order/complete/disable
      * Disables the basket limits check
      *
      * If the BasketLimits plug-in is enabled, it enforces the configured
      * limits before customers or anyone on behalf of them can continue the
      * checkout process.
      *
      * This option enables e.g. call center agents to place orders which
      * doesn't satisfy all requirements. It may be useful if you want to
      * allow them to send free or replacements for lost or damaged products.
      *
      * @param boolean True to disable the check, false to keep it enabled
      * @category Developer
      * @category User
      * @since 2014.03
      */
     if ($context->getConfig()->get('mshop/plugin/provider/order/complete/disable', false)) {
         return true;
     }
     $count = 0;
     $sum = \Aimeos\MShop\Factory::createManager($context, 'price')->createItem();
     foreach ($order->getProducts() as $product) {
         $sum->addItem($product->getPrice(), $product->getQuantity());
         $count += $product->getQuantity();
     }
     $this->checkLimits($sum, $count);
     return true;
 }
Example #9
0
 /**
  * Receives a notification from a publisher object
  *
  * @param \Aimeos\MW\Observer\Publisher\Iface $order Shop basket instance implementing publisher interface
  * @param string $action Name of the action to listen for
  * @param mixed $value Object or value changed in publisher
  * @throws \Aimeos\MShop\Plugin\Provider\Exception if checks fail
  * @return bool true if checks succeed
  */
 public function update(\Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null)
 {
     $class = '\\Aimeos\\MShop\\Order\\Item\\Base\\Iface';
     if (!$order instanceof $class) {
         throw new \Aimeos\MShop\Plugin\Exception(sprintf('Object is not of required type "%1$s"', $class));
     }
     $ids = array();
     $context = $this->getContext();
     $services = $order->getServices();
     if (count($order->getProducts()) === 0) {
         $priceManager = \Aimeos\MShop\Factory::createManager($context, 'price');
         foreach ($services as $type => $service) {
             $service->setPrice($priceManager->createItem());
         }
         return true;
     }
     foreach ($services as $type => $service) {
         $ids[$type] = $service->getServiceId();
     }
     $serviceManager = \Aimeos\MShop\Factory::createManager($context, 'service');
     $search = $serviceManager->createSearch(true);
     $expr = array($search->compare('==', 'service.id', $ids), $search->getConditions());
     $search->setConditions($search->combine('&&', $expr));
     $result = $serviceManager->searchItems($search, array('price'));
     foreach ($services as $type => $service) {
         if (isset($result[$service->getServiceId()])) {
             $provider = $serviceManager->getProvider($result[$service->getServiceId()]);
             if ($provider->isAvailable($order)) {
                 $service->setPrice($provider->calcPrice($order));
                 $order->setService($service, $type);
                 continue;
             }
         }
         $order->deleteService($type);
     }
     return true;
 }
Example #10
0
 /**
  * Receives a notification from a publisher object
  *
  * @param \Aimeos\MW\Observer\Publisher\Iface $order Shop basket instance implementing publisher interface
  * @param string $action Name of the action to listen for
  * @param mixed $value Object or value changed in publisher
  * @throws \Aimeos\MShop\Plugin\Provider\Exception if checks fail
  * @return bool true if checks succeed
  */
 public function update(\Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null)
 {
     $class = '\\Aimeos\\MShop\\Order\\Item\\Base\\Iface';
     if (!$order instanceof $class) {
         throw new \Aimeos\MShop\Plugin\Exception(sprintf('Object is not of required type "%1$s"', $class));
     }
     if ($value & \Aimeos\MShop\Order\Item\Base\Base::PARTS_SERVICE) {
         $problems = array();
         $availableServices = $order->getServices();
         foreach ($this->getItemBase()->getConfig() as $type => $value) {
             if ($value == true && !isset($availableServices[$type])) {
                 $problems[$type] = 'available.none';
             }
             if ($value !== null && $value !== '' && $value == false && isset($availableServices[$type])) {
                 $problems[$type] = 'available.notallowed';
             }
         }
         if (count($problems) > 0) {
             $code = array('service' => $problems);
             throw new \Aimeos\MShop\Plugin\Provider\Exception(sprintf('Checks for available service items in basket failed'), -1, null, $code);
         }
     }
     return true;
 }
Example #11
0
 /**
  * Receives a notification from a publisher object
  *
  * @param \Aimeos\MW\Observer\Publisher\Iface $order Shop basket instance implementing publisher interface
  * @param string $action Name of the action to listen for
  * @param mixed $value Object or value changed in publisher
  */
 public function update(\Aimeos\MW\Observer\Publisher\Iface $order, $action, $value = null)
 {
     $class = '\\Aimeos\\MShop\\Order\\Item\\Base\\Iface';
     if (!$order instanceof $class) {
         throw new \Aimeos\MShop\Plugin\Exception(sprintf('Object is not of required type "%1$s"', $class));
     }
     $config = $this->getItemBase()->getConfig();
     if (!isset($config['threshold'])) {
         return true;
     }
     try {
         $delivery = $order->getService('delivery');
     } catch (\Aimeos\MShop\Order\Exception $oe) {
         // no delivery item available yet
         return true;
     }
     $price = $delivery->getPrice();
     $currency = $price->getCurrencyId();
     if (!isset($config['threshold'][$currency])) {
         return true;
     }
     $sum = \Aimeos\MShop\Factory::createManager($this->getContext(), 'price')->createItem();
     foreach ($order->getProducts() as $product) {
         $sum->addItem($product->getPrice(), $product->getQuantity());
     }
     if ($sum->getValue() + $sum->getRebate() >= $config['threshold'][$currency] && $price->getCosts() > '0.00') {
         $price->setRebate($price->getCosts());
         $price->setCosts('0.00');
     } else {
         if ($sum->getValue() + $sum->getRebate() < $config['threshold'][$currency] && $price->getRebate() > '0.00') {
             $price->setCosts($price->getRebate());
             $price->setRebate('0.00');
         }
     }
     return true;
 }
Example #12
0
 /**
  * Subscribes itself to a publisher.
  *
  * @param \Aimeos\MW\Observer\Publisher\Iface $p Object implementing publisher interface
  */
 public function register(\Aimeos\MW\Observer\Publisher\Iface $p)
 {
     $p->addListener($this, 'addProduct.after');
 }