ProcessInventoryDataObserver.php 4.33 KB
Newer Older
Ketan's avatar
Ketan committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Magento\CatalogInventory\Observer;

use Magento\Catalog\Model\Product;
use Magento\CatalogInventory\Api\Data\StockItemInterface;
use Magento\CatalogInventory\Model\Stock\Item;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer as EventObserver;

/**
 * Prepares stock data for saving
 *
 * @deprecated 100.2.0 Stock data should be processed using the module API
 * @see StockItemInterface when you want to change the stock data
 * @see StockStatusInterface when you want to read the stock data for representation layer (storefront)
 * @see StockItemRepositoryInterface::save as extension point for customization of saving process
 */
class ProcessInventoryDataObserver implements ObserverInterface
{
    /**
     * Stock Registry
     *
     * @var \Magento\CatalogInventory\Api\StockRegistryInterface
     */
    private $stockRegistry;

    /**
     * Construct
     *
     * @param \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
     */
    public function __construct(
        \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry
    ) {
        $this->stockRegistry = $stockRegistry;
    }

    /**
     * Process stock item data
     *
     * @param EventObserver $observer
     * @return void
     */
    public function execute(EventObserver $observer)
    {
        $product = $observer->getEvent()->getProduct();
        $this->processStockData($product);
    }

    /**
     * Process stock item data
     *
     * Synchronize stock data from different sources (stock_data, quantity_and_stock_status, StockItem) and set it to
     * stock_data key
     *
     * @param Product $product
     * @return void
     */
    private function processStockData(Product $product)
    {
        $quantityAndStockStatus = $product->getData('quantity_and_stock_status');
        if (is_array($quantityAndStockStatus)) {
            /** @var Item $stockItem */
            $stockItem = $this->stockRegistry->getStockItem($product->getId(), $product->getStore()->getWebsiteId());

            $quantityAndStockStatus = $this->prepareQuantityAndStockStatus($stockItem, $quantityAndStockStatus);

            if ($quantityAndStockStatus) {
                $this->setStockDataToProduct($product, $stockItem, $quantityAndStockStatus);
            }
        }
    }

    /**
     * Prepare quantity_and_stock_status data
     *
     * Remove not changed values from quantity_and_stock_status data
     * Set null value for qty if passed empty
     *
     * @param StockItemInterface $stockItem
     * @param array $quantityAndStockStatus
     * @return array
     */
    private function prepareQuantityAndStockStatus(StockItemInterface $stockItem, array $quantityAndStockStatus)
    {
        $stockItemId = $stockItem->getItemId();

        if (null !== $stockItemId) {
            if (isset($quantityAndStockStatus['is_in_stock'])
                && $stockItem->getIsInStock() == $quantityAndStockStatus['is_in_stock']
            ) {
                unset($quantityAndStockStatus['is_in_stock']);
            }
            if (array_key_exists('qty', $quantityAndStockStatus)
                && $stockItem->getQty() == $quantityAndStockStatus['qty']
            ) {
                unset($quantityAndStockStatus['qty']);
            }
        }

        if (array_key_exists('qty', $quantityAndStockStatus) && $quantityAndStockStatus['qty'] === '') {
            $quantityAndStockStatus['qty'] = null;
        }
        return $quantityAndStockStatus;
    }

    /**
     * Set stock data to product
     *
     * First of all we take stock_data data, replace it from quantity_and_stock_status data (if was changed) and finally
     * replace it with data from Stock Item object (only if Stock Item was changed)
     *
     * @param Product $product
     * @param Item $stockItem
     * @param array $quantityAndStockStatus
     * @return void
     */
    private function setStockDataToProduct(Product $product, Item $stockItem, array $quantityAndStockStatus)
    {
        $stockData = array_replace((array)$product->getData('stock_data'), $quantityAndStockStatus);
        if ($stockItem->hasDataChanges()) {
            $stockData = array_replace($stockData, $stockItem->getData());
        }
        $product->setData('stock_data', $stockData);
    }
}