8
8
namespace Magento \Bundle \Model \Inventory ;
9
9
10
10
use Magento \Bundle \Model \Product \Type ;
11
- use Magento \Catalog \Model \ResourceModel \Product \Website \Link as ProductWebsiteLink ;
12
11
use Magento \CatalogInventory \Api \Data \StockItemInterface ;
13
12
use Magento \CatalogInventory \Api \StockConfigurationInterface ;
14
13
use Magento \CatalogInventory \Api \StockItemCriteriaInterfaceFactory ;
15
14
use Magento \CatalogInventory \Api \StockItemRepositoryInterface ;
16
- use Magento \CatalogInventory \Api \StockRegistryInterface ;
17
15
18
16
/***
19
17
* Update stock status of bundle products based on children products stock status
20
18
*/
21
19
class ChangeParentStockStatus
22
20
{
23
- /**
24
- * @var StockRegistryInterface
25
- */
26
- private $ stockRegistry ;
27
-
28
21
/**
29
22
* @var Type
30
23
*/
@@ -46,32 +39,21 @@ class ChangeParentStockStatus
46
39
private $ stockConfiguration ;
47
40
48
41
/**
49
- * @var ProductWebsiteLink
50
- */
51
- private $ productWebsiteLink ;
52
-
53
- /**
54
- * @param StockRegistryInterface $stockRegistry
55
42
* @param StockItemCriteriaInterfaceFactory $criteriaInterfaceFactory
56
43
* @param StockItemRepositoryInterface $stockItemRepository
57
44
* @param StockConfigurationInterface $stockConfiguration
58
45
* @param Type $bundleType
59
- * @param ProductWebsiteLink $productWebsiteLink
60
46
*/
61
47
public function __construct (
62
- StockRegistryInterface $ stockRegistry ,
63
48
StockItemCriteriaInterfaceFactory $ criteriaInterfaceFactory ,
64
49
StockItemRepositoryInterface $ stockItemRepository ,
65
50
StockConfigurationInterface $ stockConfiguration ,
66
- Type $ bundleType ,
67
- ProductWebsiteLink $ productWebsiteLink
51
+ Type $ bundleType
68
52
) {
69
- $ this ->stockRegistry = $ stockRegistry ;
70
53
$ this ->bundleType = $ bundleType ;
71
54
$ this ->criteriaInterfaceFactory = $ criteriaInterfaceFactory ;
72
55
$ this ->stockItemRepository = $ stockItemRepository ;
73
56
$ this ->stockConfiguration = $ stockConfiguration ;
74
- $ this ->productWebsiteLink = $ productWebsiteLink ;
75
57
}
76
58
77
59
/**
@@ -96,27 +78,24 @@ public function execute(array $childrenIds): void
96
78
*/
97
79
private function processStockForParent (int $ productId ): void
98
80
{
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
+ }
115
90
}
116
91
}
117
92
118
93
/**
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)
120
99
*
121
100
* @param int $productId
122
101
* @return bool
@@ -125,17 +104,14 @@ private function isChildrenInStock(int $productId) : bool
125
104
{
126
105
$ childrenIsInStock = false ;
127
106
$ 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 )));
131
108
foreach ($ childrenIds as $ childrenIdsPerOption ) {
132
109
$ childrenIsInStock = false ;
133
110
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 ;
139
115
}
140
116
}
141
117
if (!$ childrenIsInStock ) {
@@ -160,4 +136,25 @@ private function isNeedToUpdateParent(
160
136
return $ parentStockItem ->getIsInStock () !== $ childrenIsInStock &&
161
137
($ childrenIsInStock === false || $ parentStockItem ->getStockStatusChangedAuto ());
162
138
}
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
+ }
163
160
}
0 commit comments