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);
}
}