12
12
use Magento \Framework \App \ResourceConnection ;
13
13
use Magento \Framework \EntityManager \MetadataPool ;
14
14
use Magento \Framework \Module \Manager as ModuleManager ;
15
+ use Magento \Store \Api \WebsiteRepositoryInterface ;
16
+ use Magento \Store \Model \StoreManagerInterface ;
17
+ use Magmodules \Sooqr \Api \Log \RepositoryInterface as LogRepository ;
15
18
16
19
/**
17
20
* Service class for stock data
@@ -35,39 +38,51 @@ class Stock
35
38
* @var ModuleManager
36
39
*/
37
40
private $ moduleManager ;
41
+ /**
42
+ * @var StoreManagerInterface
43
+ */
44
+ private $ storeManager ;
45
+ /**
46
+ * @var WebsiteRepositoryInterface
47
+ */
48
+ private $ websiteRepository ;
49
+ /**
50
+ * @var LogRepository
51
+ */
52
+ private $ logRepository ;
38
53
/**
39
54
* @var string
40
55
*/
41
56
private $ linkField ;
42
57
43
- /**
44
- * Stock constructor.
45
- * @param ResourceConnection $resource
46
- * @param ModuleManager $moduleManager
47
- * @param MetadataPool $metadataPool
48
- * @throws Exception
49
- */
50
58
public function __construct (
51
59
ResourceConnection $ resource ,
52
60
ModuleManager $ moduleManager ,
61
+ StoreManagerInterface $ storeManager ,
62
+ WebsiteRepositoryInterface $ websiteRepository ,
63
+ LogRepository $ logRepository ,
53
64
MetadataPool $ metadataPool
54
65
) {
55
66
$ this ->resource = $ resource ;
56
67
$ this ->moduleManager = $ moduleManager ;
68
+ $ this ->storeManager = $ storeManager ;
69
+ $ this ->websiteRepository = $ websiteRepository ;
70
+ $ this ->logRepository = $ logRepository ;
57
71
$ this ->linkField = $ metadataPool ->getMetadata (ProductInterface::class)->getLinkField ();
58
72
}
59
73
60
74
/**
61
75
* Get stock data
62
76
*
63
77
* @param array $productIds
78
+ * @param int $storeId
64
79
* @return array[]
65
80
*/
66
- public function execute (array $ productIds = []): array
81
+ public function execute (array $ productIds = [], int $ storeId = 0 ): array
67
82
{
68
83
$ this ->setData ('entity_ids ' , $ productIds );
69
84
return ($ this ->isMsiEnabled ())
70
- ? $ this ->getMsiStock ()
85
+ ? $ this ->getMsiStock ($ storeId )
71
86
: $ this ->getNoMsiStock ();
72
87
}
73
88
@@ -116,29 +131,26 @@ private function isMsiEnabled(): bool
116
131
*
117
132
* @return array[]
118
133
*/
119
- private function getMsiStock (): array
134
+ private function getMsiStock (int $ storeId ): array
120
135
{
121
- $ channels = $ this ->getChannels ();
122
- $ stockData = $ this ->collectMsi ($ channels );
123
- $ result = $ this ->getNoMsiStock (true );
136
+ $ stockId = $ this ->getStockId ($ storeId );
137
+ $ stockData = $ this ->collectMsi ($ stockId );
138
+ $ reservations = $ this ->collectMsiReservations ($ stockId );
139
+ $ result = $ this ->getNoMsiStock ();
124
140
125
141
foreach ($ stockData as $ value ) {
126
- foreach ($ channels as $ channel ) {
127
- if (!array_key_exists ($ value ['product_id ' ], $ result )) {
128
- continue ;
129
- }
142
+ if (!array_key_exists ($ value ['product_id ' ], $ result )) {
143
+ continue ;
144
+ }
130
145
131
- $ qty = $ value [sprintf ('quantity_%s ' , (int )$ channel )];
132
- $ reserved = max ($ result [$ value ['product_id ' ]]['reserved ' ], 0 );
133
- $ salableQty = $ qty - $ reserved ;
146
+ $ quantity = (int )($ value ['quantity ' ] ?? 0 );
147
+ $ reservations = max ($ reservations [$ value ['product_id ' ]] ?? 0 , 0 );
134
148
135
- $ result [$ value ['product_id ' ]]['msi ' ][$ channel ] = [
136
- 'qty ' => (int )($ value [sprintf ('quantity_%s ' , (int )$ channel )] ?? 0 ),
137
- 'is_salable ' => $ value [sprintf ('is_salable_%s ' , (int )$ channel )] ?? 0 ,
138
- 'availability ' => $ value [sprintf ('is_salable_%s ' , (int )$ channel )] ?? 0 ,
139
- 'salable_qty ' => $ salableQty ?: 0
140
- ];
141
- }
149
+ $ result [$ value ['product_id ' ]]['qty ' ] = $ quantity ;
150
+ $ result [$ value ['product_id ' ]]['is_salable ' ] = $ value ['is_salable ' ] ?? 0 ;
151
+ $ result [$ value ['product_id ' ]]['availability ' ] = $ value ['is_salable ' ] ?? 0 ;
152
+ $ result [$ value ['product_id ' ]]['is_in_stock ' ] = $ value ['is_salable ' ] ?? 0 ;
153
+ $ result [$ value ['product_id ' ]]['salable_qty ' ] = $ quantity - $ reservations ;
142
154
}
143
155
144
156
return $ result ;
@@ -147,52 +159,78 @@ private function getMsiStock(): array
147
159
/**
148
160
* Get MSI stock channels
149
161
*
150
- * @return array[]
162
+ * @param int $storeId
163
+ * @return int
151
164
*/
152
- private function getChannels ( ): array
165
+ private function getStockId ( int $ storeId ): int
153
166
{
154
- $ select = $ this ->resource ->getConnection ()->select ()
155
- ->from (
156
- $ this ->resource ->getTableName ('inventory_stock_sales_channel ' ),
157
- ['stock_id ' ]
158
- )
159
- ->where (
160
- 'type = ? ' ,
161
- 'website '
162
- );
163
- return array_unique ($ this ->resource ->getConnection ()->fetchCol ($ select ));
167
+ try {
168
+ $ store = $ this ->storeManager ->getStore ($ storeId );
169
+ $ website = $ this ->websiteRepository ->getById ($ store ->getWebsiteId ());
170
+ $ select = $ this ->resource ->getConnection ()->select ()
171
+ ->from (
172
+ $ this ->resource ->getTableName ('inventory_stock_sales_channel ' ),
173
+ ['stock_id ' ]
174
+ )
175
+ ->where (
176
+ 'type = ? ' ,
177
+ 'website '
178
+ )->where (
179
+ 'code = ? ' ,
180
+ $ website ->getCode ()
181
+ )->limit (1 );
182
+ return (int )$ this ->resource ->getConnection ()->fetchOne ($ select );
183
+ } catch (\Exception $ exception ) {
184
+ $ this ->logRepository ->addErrorLog ('MSI getStockId ' , $ exception ->getMessage ());
185
+ return 1 ;
186
+ }
164
187
}
165
188
166
189
/**
167
190
* Collect MSI stock data
168
191
*
169
- * @param array[] $channels
192
+ * @param int $stockId
170
193
* @return array[]
171
194
*/
172
- private function collectMsi (array $ channels ): array
195
+ private function collectMsi (int $ stockId ): array
173
196
{
197
+ $ stockView = sprintf ('inventory_stock_%s ' , (int )$ stockId );
174
198
$ select = $ this ->resource ->getConnection ()->select ()
175
199
->from (
176
200
['cpe ' => $ this ->resource ->getTableName ('catalog_product_entity ' )],
177
201
['product_id ' => 'entity_id ' , $ this ->linkField ]
178
202
)->where (
179
203
'cpe.entity_id IN (?) ' ,
180
204
$ this ->entityIds
205
+ )->joinLeft (
206
+ ['inv_stock ' => $ this ->resource ->getTableName ($ stockView )],
207
+ "cpe.sku = inv_stock.sku " ,
208
+ ['inv_stock.quantity ' , 'inv_stock.is_salable ' ]
181
209
);
182
210
183
- foreach ($ channels as $ channel ) {
184
- $ table = sprintf ('inventory_stock_%s ' , (int )$ channel );
185
- $ select ->joinLeft (
186
- [$ table => $ this ->resource ->getTableName ($ table )],
187
- "cpe.sku = {$ table }.sku " ,
188
- [
189
- sprintf ('quantity_%s ' , (int )$ channel ) => "{$ table }.quantity " ,
190
- sprintf ('is_salable_%s ' , (int )$ channel ) => "{$ table }.is_salable "
191
- ]
211
+ return $ this ->resource ->getConnection ()->fetchAll ($ select );
212
+ }
213
+
214
+ /**
215
+ * @param int $stockId
216
+ * @return array
217
+ */
218
+ private function collectMsiReservations (int $ stockId ): array
219
+ {
220
+ $ select = $ this ->resource ->getConnection ()->select ()
221
+ ->from (
222
+ ['cpe ' => $ this ->resource ->getTableName ('catalog_product_entity ' )],
223
+ ['product_id ' => 'entity_id ' ]
224
+ )->where (
225
+ 'cpe.entity_id IN (?) ' ,
226
+ $ this ->entityIds
227
+ )->joinLeft (
228
+ ['inv_res ' => $ this ->resource ->getTableName ('inventory_reservation ' )],
229
+ "inv_res.sku = cpe.sku AND inv_res.stock_id = {$ stockId }" ,
230
+ ['reserved ' => 'SUM(COALESCE(inv_res.quantity, 0)) ' ]
192
231
);
193
- }
194
232
195
- return $ this ->resource ->getConnection ()->fetchAll ($ select );
233
+ return $ this ->resource ->getConnection ()->fetchPairs ($ select );
196
234
}
197
235
198
236
/**
@@ -209,10 +247,9 @@ private function collectMsi(array $channels): array
209
247
* min_sale_qty
210
248
* ]
211
249
*
212
- * @param bool $addMsi
213
250
* @return array[]
214
251
*/
215
- private function getNoMsiStock (bool $ addMsi = false ): array
252
+ private function getNoMsiStock (): array
216
253
{
217
254
$ result = [];
218
255
$ select = $ this ->resource ->getConnection ()
@@ -235,36 +272,25 @@ private function getNoMsiStock(bool $addMsi = false): array
235
272
['css ' => $ this ->resource ->getTableName ('cataloginventory_stock_status ' )],
236
273
'css.product_id = catalog_product_entity.entity_id ' ,
237
274
['stock_status ' ]
275
+ )->where (
276
+ 'cataloginventory_stock_item.product_id IN (?) ' ,
277
+ $ this ->entityIds
278
+ )->group (
279
+ 'product_id '
238
280
);
239
- if ($ addMsi ) {
240
- $ select ->joinLeft (
241
- ['inventory_reservation ' => $ this ->resource ->getTableName ('inventory_reservation ' )],
242
- 'inventory_reservation.sku = catalog_product_entity.sku ' ,
243
- ['reserved ' => 'SUM(COALESCE(inventory_reservation.quantity, 0)) ' ]
244
- );
245
- }
246
- $ select ->where ('cataloginventory_stock_item.product_id IN (?) ' , $ this ->entityIds );
247
- $ select ->group ('product_id ' );
248
281
$ values = $ this ->resource ->getConnection ()->fetchAll ($ select );
249
282
250
283
foreach ($ values as $ value ) {
251
- $ result [$ value ['product_id ' ]] =
252
- [
253
- 'qty ' => (int )$ value ['qty ' ],
254
- 'is_in_stock ' => (int )$ value ['stock_status ' ],
255
- 'availability ' => (int )$ value ['stock_status ' ],
256
- 'manage_stock ' => (int )$ value ['manage_stock ' ],
257
- 'qty_increments ' => (int )$ value ['qty_increments ' ],
258
- 'min_sale_qty ' => (int )$ value ['min_sale_qty ' ]
259
- ];
260
- if ($ addMsi ) {
261
- $ reserved = (int )$ value ['reserved ' ] * -1 ;
262
- $ result [$ value ['product_id ' ]] += [
263
- 'reserved ' => $ reserved ,
264
- 'salable_qty ' => (int )($ value ['qty ' ] - $ reserved )
265
- ];
266
- }
284
+ $ result [$ value ['product_id ' ]] = [
285
+ 'qty ' => (int )$ value ['qty ' ],
286
+ 'is_in_stock ' => (int )$ value ['stock_status ' ],
287
+ 'availability ' => (int )$ value ['stock_status ' ],
288
+ 'manage_stock ' => (int )$ value ['manage_stock ' ],
289
+ 'qty_increments ' => (int )$ value ['qty_increments ' ],
290
+ 'min_sale_qty ' => (int )$ value ['min_sale_qty ' ]
291
+ ];
267
292
}
293
+
268
294
return $ result ;
269
295
}
270
296
0 commit comments