-
Notifications
You must be signed in to change notification settings - Fork 9.3k
/
ChangeParentStockStatus.php
128 lines (113 loc) · 4.12 KB
/
ChangeParentStockStatus.php
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
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
namespace Magento\ConfigurableProduct\Model\Inventory;
use Magento\CatalogInventory\Api\Data\StockItemInterface;
use Magento\CatalogInventory\Api\StockConfigurationInterface;
use Magento\CatalogInventory\Api\StockItemCriteriaInterfaceFactory;
use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
/***
* Update stock status of configurable products based on children products stock status
*/
class ChangeParentStockStatus
{
/**
* @var Configurable
*/
private $configurableType;
/**
* @var StockItemCriteriaInterfaceFactory
*/
private $criteriaInterfaceFactory;
/**
* @var StockItemRepositoryInterface
*/
private $stockItemRepository;
/**
* @var StockConfigurationInterface
*/
private $stockConfiguration;
/**
* @param Configurable $configurableType
* @param StockItemCriteriaInterfaceFactory $criteriaInterfaceFactory
* @param StockItemRepositoryInterface $stockItemRepository
* @param StockConfigurationInterface $stockConfiguration
*/
public function __construct(
Configurable $configurableType,
StockItemCriteriaInterfaceFactory $criteriaInterfaceFactory,
StockItemRepositoryInterface $stockItemRepository,
StockConfigurationInterface $stockConfiguration
) {
$this->configurableType = $configurableType;
$this->criteriaInterfaceFactory = $criteriaInterfaceFactory;
$this->stockItemRepository = $stockItemRepository;
$this->stockConfiguration = $stockConfiguration;
}
/**
* Update stock status of configurable products based on children products stock status
*
* @param array $childrenIds
* @return void
*/
public function execute(array $childrenIds): void
{
$parentIds = $this->configurableType->getParentIdsByChild($childrenIds);
foreach (array_unique($parentIds) as $productId) {
$this->processStockForParent((int)$productId);
}
}
/**
* Update stock status of configurable product based on children products stock status
*
* @param int $productId
* @return void
*/
private function processStockForParent(int $productId): void
{
$criteria = $this->criteriaInterfaceFactory->create();
$criteria->setScopeFilter($this->stockConfiguration->getDefaultScopeId());
$criteria->setProductsFilter($productId);
$stockItemCollection = $this->stockItemRepository->getList($criteria);
$allItems = $stockItemCollection->getItems();
if (empty($allItems)) {
return;
}
$parentStockItem = array_shift($allItems);
$childrenIds = $this->configurableType->getChildrenIds($productId);
$criteria->setProductsFilter($childrenIds);
$stockItemCollection = $this->stockItemRepository->getList($criteria);
$allItems = $stockItemCollection->getItems();
$childrenIsInStock = false;
foreach ($allItems as $childItem) {
if ($childItem->getIsInStock() === true) {
$childrenIsInStock = true;
break;
}
}
if ($this->isNeedToUpdateParent($parentStockItem, $childrenIsInStock)) {
$parentStockItem->setIsInStock($childrenIsInStock);
$parentStockItem->setStockStatusChangedAuto(1);
$parentStockItem->setStockStatusChangedAutomaticallyFlag(true);
$this->stockItemRepository->save($parentStockItem);
}
}
/**
* Check if parent item should be updated
*
* @param StockItemInterface $parentStockItem
* @param bool $childrenIsInStock
* @return bool
*/
private function isNeedToUpdateParent(
StockItemInterface $parentStockItem,
bool $childrenIsInStock
): bool {
return $parentStockItem->getIsInStock() !== $childrenIsInStock &&
($childrenIsInStock === false || $parentStockItem->getStockStatusChangedAuto());
}
}