Skip to content

Commit 776bc9c

Browse files
committed
ACP2E-262: Bundle product status in backend does not change automatically
1 parent 497bdaf commit 776bc9c

File tree

1 file changed

+41
-44
lines changed

1 file changed

+41
-44
lines changed

app/code/Magento/Bundle/Model/Inventory/ChangeParentStockStatus.php

Lines changed: 41 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,16 @@
88
namespace Magento\Bundle\Model\Inventory;
99

1010
use Magento\Bundle\Model\Product\Type;
11-
use Magento\Catalog\Model\ResourceModel\Product\Website\Link as ProductWebsiteLink;
1211
use Magento\CatalogInventory\Api\Data\StockItemInterface;
1312
use Magento\CatalogInventory\Api\StockConfigurationInterface;
1413
use Magento\CatalogInventory\Api\StockItemCriteriaInterfaceFactory;
1514
use Magento\CatalogInventory\Api\StockItemRepositoryInterface;
16-
use Magento\CatalogInventory\Api\StockRegistryInterface;
1715

1816
/***
1917
* Update stock status of bundle products based on children products stock status
2018
*/
2119
class ChangeParentStockStatus
2220
{
23-
/**
24-
* @var StockRegistryInterface
25-
*/
26-
private $stockRegistry;
27-
2821
/**
2922
* @var Type
3023
*/
@@ -46,32 +39,21 @@ class ChangeParentStockStatus
4639
private $stockConfiguration;
4740

4841
/**
49-
* @var ProductWebsiteLink
50-
*/
51-
private $productWebsiteLink;
52-
53-
/**
54-
* @param StockRegistryInterface $stockRegistry
5542
* @param StockItemCriteriaInterfaceFactory $criteriaInterfaceFactory
5643
* @param StockItemRepositoryInterface $stockItemRepository
5744
* @param StockConfigurationInterface $stockConfiguration
5845
* @param Type $bundleType
59-
* @param ProductWebsiteLink $productWebsiteLink
6046
*/
6147
public function __construct(
62-
StockRegistryInterface $stockRegistry,
6348
StockItemCriteriaInterfaceFactory $criteriaInterfaceFactory,
6449
StockItemRepositoryInterface $stockItemRepository,
6550
StockConfigurationInterface $stockConfiguration,
66-
Type $bundleType,
67-
ProductWebsiteLink $productWebsiteLink
51+
Type $bundleType
6852
) {
69-
$this->stockRegistry = $stockRegistry;
7053
$this->bundleType = $bundleType;
7154
$this->criteriaInterfaceFactory = $criteriaInterfaceFactory;
7255
$this->stockItemRepository = $stockItemRepository;
7356
$this->stockConfiguration = $stockConfiguration;
74-
$this->productWebsiteLink = $productWebsiteLink;
7557
}
7658

7759
/**
@@ -96,27 +78,24 @@ public function execute(array $childrenIds): void
9678
*/
9779
private function processStockForParent(int $productId): void
9880
{
99-
$criteria = $this->criteriaInterfaceFactory->create();
100-
$criteria->setScopeFilter($this->stockConfiguration->getDefaultScopeId());
101-
102-
$criteria->setProductsFilter($productId);
103-
$stockItemCollection = $this->stockItemRepository->getList($criteria);
104-
$allItems = $stockItemCollection->getItems();
105-
if (empty($allItems)) {
106-
return;
107-
}
108-
$parentStockItem = array_shift($allItems);
109-
$childrenIsInStock = $this->isChildrenInStock($productId);
110-
111-
if ($this->isNeedToUpdateParent($parentStockItem, $childrenIsInStock)) {
112-
$parentStockItem->setIsInStock($childrenIsInStock);
113-
$parentStockItem->setStockStatusChangedAuto(1);
114-
$this->stockItemRepository->save($parentStockItem);
81+
$stockItems = $this->getStockItems([$productId]);
82+
$parentStockItem = $stockItems[$productId] ?? null;
83+
if ($parentStockItem) {
84+
$childrenIsInStock = $this->isChildrenInStock($productId);
85+
if ($this->isNeedToUpdateParent($parentStockItem, $childrenIsInStock)) {
86+
$parentStockItem->setIsInStock($childrenIsInStock);
87+
$parentStockItem->setStockStatusChangedAuto(1);
88+
$this->stockItemRepository->save($parentStockItem);
89+
}
11590
}
11691
}
11792

11893
/**
119-
* Check if any of bundle children products is in stock
94+
* Returns stock status of bundle product based on children stock status
95+
*
96+
* Returns TRUE if any of the following conditions is true:
97+
* - At least one product is in-stock in each required option
98+
* - Any product is in-stock (if all options are optional)
12099
*
121100
* @param int $productId
122101
* @return bool
@@ -125,17 +104,14 @@ private function isChildrenInStock(int $productId) : bool
125104
{
126105
$childrenIsInStock = false;
127106
$childrenIds = $this->bundleType->getChildrenIds($productId, true);
128-
$websiteIds = $this->productWebsiteLink->getWebsiteIdsByProductId($productId);
129-
//prepend global scope
130-
array_unshift($websiteIds, null);
107+
$stockItems = $this->getStockItems(array_merge(...array_values($childrenIds)));
131108
foreach ($childrenIds as $childrenIdsPerOption) {
132109
$childrenIsInStock = false;
133110
foreach ($childrenIdsPerOption as $id) {
134-
foreach ($websiteIds as $scopeId) {
135-
if ((int)$this->stockRegistry->getProductStockStatus($id, $scopeId) === 1) {
136-
$childrenIsInStock = true;
137-
break 2;
138-
}
111+
$stockItem = $stockItems[$id] ?? null;
112+
if ($stockItem && $stockItem->getIsInStock()) {
113+
$childrenIsInStock = true;
114+
break;
139115
}
140116
}
141117
if (!$childrenIsInStock) {
@@ -160,4 +136,25 @@ private function isNeedToUpdateParent(
160136
return $parentStockItem->getIsInStock() !== $childrenIsInStock &&
161137
($childrenIsInStock === false || $parentStockItem->getStockStatusChangedAuto());
162138
}
139+
140+
/**
141+
* Get stock items for provided product IDs
142+
*
143+
* @param array $productIds
144+
* @return StockItemInterface[]
145+
*/
146+
private function getStockItems(array $productIds): array
147+
{
148+
$criteria = $this->criteriaInterfaceFactory->create();
149+
$criteria->setScopeFilter($this->stockConfiguration->getDefaultScopeId());
150+
$criteria->setProductsFilter(array_unique($productIds));
151+
$stockItemCollection = $this->stockItemRepository->getList($criteria);
152+
153+
$stockItems = [];
154+
foreach ($stockItemCollection->getItems() as $stockItem) {
155+
$stockItems[$stockItem->getProductId()] = $stockItem;
156+
}
157+
158+
return $stockItems;
159+
}
163160
}

0 commit comments

Comments
 (0)