/**
  * Return creditmemo items qty to stock
  *
  * @param EventObserver $observer
  * @return void
  */
 public function execute(EventObserver $observer)
 {
     /* @var $creditmemo \Magento\Sales\Model\Order\Creditmemo */
     $creditmemo = $observer->getEvent()->getCreditmemo();
     $itemsToUpdate = [];
     foreach ($creditmemo->getAllItems() as $item) {
         $qty = $item->getQty();
         if ($item->getBackToStock() && $qty || $this->stockConfiguration->isAutoReturnEnabled()) {
             $productId = $item->getProductId();
             $parentItemId = $item->getOrderItem()->getParentItemId();
             /* @var $parentItem \Magento\Sales\Model\Order\Creditmemo\Item */
             $parentItem = $parentItemId ? $creditmemo->getItemByOrderId($parentItemId) : false;
             $qty = $parentItem ? $parentItem->getQty() * $qty : $qty;
             if (isset($itemsToUpdate[$productId])) {
                 $itemsToUpdate[$productId] += $qty;
             } else {
                 $itemsToUpdate[$productId] = $qty;
             }
         }
     }
     if (!empty($itemsToUpdate)) {
         $this->stockManagement->revertProductsSale($itemsToUpdate, $creditmemo->getStore()->getWebsiteId());
         $updatedItemIds = array_keys($itemsToUpdate);
         $this->stockIndexerProcessor->reindexList($updatedItemIds);
         $this->priceIndexer->reindexList($updatedItemIds);
     }
 }
 /**
  * Cancel order item
  *
  * @param   EventObserver $observer
  * @return  void
  */
 public function execute(EventObserver $observer)
 {
     /** @var \Magento\Sales\Model\Order\Item $item */
     $item = $observer->getEvent()->getItem();
     $children = $item->getChildrenItems();
     $qty = $item->getQtyOrdered() - max($item->getQtyShipped(), $item->getQtyInvoiced()) - $item->getQtyCanceled();
     if ($item->getId() && $item->getProductId() && empty($children) && $qty) {
         $this->stockManagement->backItemQty($item->getProductId(), $qty, $item->getStore()->getWebsiteId());
     }
     $this->priceIndexer->reindexRow($item->getProductId());
 }
 /**
  * Revert quote items inventory data (cover not success order place case)
  *
  * @param EventObserver $observer
  * @return void
  */
 public function execute(EventObserver $observer)
 {
     $quote = $observer->getEvent()->getQuote();
     $items = $this->productQty->getProductQty($quote->getAllItems());
     $this->stockManagement->revertProductsSale($items, $quote->getStore()->getWebsiteId());
     $productIds = array_keys($items);
     if (!empty($productIds)) {
         $this->stockIndexerProcessor->reindexList($productIds);
         $this->priceIndexer->reindexList($productIds);
     }
     // Clear flag, so if order placement retried again with success - it will be processed
     $quote->setInventoryProcessed(false);
 }
예제 #4
0
 public function testRefundOrderInventory()
 {
     $websiteId = 0;
     $ids = ['1', '14'];
     $items = [];
     $isAutoReturnEnabled = true;
     $itemsToUpdate = [];
     foreach ($ids as $id) {
         $item = $this->getCreditMemoItem($id);
         $items[] = $item;
         $itemsToUpdate[$item->getProductId()] = $item->getQty();
     }
     $creditMemo = $this->getMock('Magento\\Sales\\Model\\Order\\Creditmemo', [], [], '', false);
     $creditMemo->expects($this->once())->method('getAllItems')->will($this->returnValue($items));
     $store = $this->getMock('Magento\\Store\\Model\\Store', ['getWebsiteId', '__wakeup'], [], '', false);
     $store->expects($this->once())->method('getWebsiteId')->will($this->returnValue($websiteId));
     $creditMemo->expects($this->once())->method('getStore')->will($this->returnValue($store));
     $this->stockConfiguration->expects($this->any())->method('isAutoReturnEnabled')->will($this->returnValue($isAutoReturnEnabled));
     $this->stockManagement->expects($this->once())->method('revertProductsSale')->with($itemsToUpdate, $websiteId);
     $this->stockIndexerProcessor->expects($this->once())->method('reindexList')->with($ids);
     $this->priceIndexer->expects($this->once())->method('reindexList')->with($ids);
     $this->event->expects($this->once())->method('getCreditmemo')->will($this->returnValue($creditMemo));
     $this->eventObserver->expects($this->atLeastOnce())->method('getEvent')->will($this->returnValue($this->event));
     $this->observer->refundOrderInventory($this->eventObserver);
 }
 /**
  * Subtract quote items qtys from stock items related with quote items products.
  *
  * Used before order placing to make order save/place transaction smaller
  * Also called after every successful order placement to ensure subtraction of inventory
  *
  * @param EventObserver $observer
  * @return $this
  */
 public function execute(EventObserver $observer)
 {
     /** @var \Magento\Quote\Model\Quote $quote */
     $quote = $observer->getEvent()->getQuote();
     // Maybe we've already processed this quote in some event during order placement
     // e.g. call in event 'sales_model_service_quote_submit_before' and later in 'checkout_submit_all_after'
     if ($quote->getInventoryProcessed()) {
         return $this;
     }
     $items = $this->productQty->getProductQty($quote->getAllItems());
     /**
      * Remember items
      */
     $itemsForReindex = $this->stockManagement->registerProductsSale($items, $quote->getStore()->getWebsiteId());
     $this->itemsForReindex->setItems($itemsForReindex);
     $quote->setInventoryProcessed(true);
     return $this;
 }
 /**
  * Subtract items qtys from stock related with uncancel products.
  *
  * @param EventObserver $observer
  * @return $this
  */
 public function execute(EventObserver $observer)
 {
     $order = $observer->getEvent()->getOrder();
     $productQty = $observer->getEvent()->getProductQty();
     if ($order->getInventoryProcessed()) {
         return $this;
     }
     /**
      * Reindex items
      */
     $itemsForReindex = $this->stockManagement->registerProductsSale($productQty, $order->getStore()->getWebsiteId());
     $productIds = [];
     foreach ($itemsForReindex as $item) {
         $item->save();
         $productIds[] = $item->getProductId();
     }
     if (!empty($productIds)) {
         $this->stockIndexerProcessor->reindexList($productIds);
     }
     $order->setInventoryProcessed(true);
     return $this;
 }