createAvailabilityAbstract()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 9
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 2
1
<?php
2
3
/**
4
 * This file is part of the Spryker Commerce OS.
5
 * For full license information, please view the LICENSE file that was distributed with this source code.
6
 */
7
8
declare(strict_types = 1);
9
10
namespace Pyz\Zed\DataImport\Business\Model\ProductStock\Writer;
11
12
use Generated\Shared\Transfer\StoreTransfer;
0 ignored issues
show
Bug introduced by
The type Generated\Shared\Transfer\StoreTransfer was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
13
use Orm\Zed\Availability\Persistence\Map\SpyAvailabilityAbstractTableMap;
0 ignored issues
show
Bug introduced by
The type Orm\Zed\Availability\Per...abilityAbstractTableMap was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
14
use Orm\Zed\Availability\Persistence\Map\SpyAvailabilityTableMap;
0 ignored issues
show
Bug introduced by
The type Orm\Zed\Availability\Per...SpyAvailabilityTableMap was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use Orm\Zed\Availability\Persistence\SpyAvailabilityAbstract;
16
use Orm\Zed\Availability\Persistence\SpyAvailabilityAbstractQuery;
17
use Orm\Zed\Availability\Persistence\SpyAvailabilityQuery;
18
use Orm\Zed\Oms\Persistence\Map\SpyOmsProductReservationTableMap;
0 ignored issues
show
Bug introduced by
The type Orm\Zed\Oms\Persistence\...ductReservationTableMap was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use Orm\Zed\Oms\Persistence\SpyOmsProductReservationQuery;
20
use Orm\Zed\Oms\Persistence\SpyOmsProductReservationStoreQuery;
21
use Orm\Zed\Stock\Persistence\Map\SpyStockProductTableMap;
0 ignored issues
show
Bug introduced by
The type Orm\Zed\Stock\Persistenc...SpyStockProductTableMap was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
22
use Orm\Zed\Stock\Persistence\SpyStock;
23
use Orm\Zed\Stock\Persistence\SpyStockProductQuery;
24
use Orm\Zed\Stock\Persistence\SpyStockQuery;
25
use Pyz\Zed\DataImport\Business\Model\Product\Repository\ProductRepositoryInterface;
26
use Pyz\Zed\DataImport\Business\Model\ProductStock\ProductStockHydratorStep;
27
use Spryker\DecimalObject\Decimal;
28
use Spryker\Zed\Availability\Dependency\AvailabilityEvents;
29
use Spryker\Zed\DataImport\Business\Model\DataSet\DataSetInterface;
30
use Spryker\Zed\DataImport\Business\Model\DataSet\DataSetWriterInterface;
31
use Spryker\Zed\DataImport\Business\Model\Publisher\DataImporterPublisher;
32
use Spryker\Zed\ProductBundle\Business\ProductBundleFacadeInterface;
33
use Spryker\Zed\PropelOrm\Business\Runtime\ActiveQuery\Criteria;
34
use Spryker\Zed\Stock\Business\StockFacadeInterface;
35
use Spryker\Zed\Store\Business\StoreFacadeInterface;
36
37
class ProductStockPropelDataSetWriter implements DataSetWriterInterface
38
{
39
    protected const COLUMN_CONCRETE_SKU = ProductStockHydratorStep::COLUMN_CONCRETE_SKU;
40
41
    protected const COLUMN_IS_BUNDLE = ProductStockHydratorStep::COLUMN_IS_BUNDLE;
42
43
    protected const COLUMN_IS_NEVER_OUT_OF_STOCK = ProductStockHydratorStep::COLUMN_IS_NEVER_OUT_OF_STOCK;
44
45
    /**
46
     * @var string
47
     */
48
    protected const KEY_AVAILABILITY_SKU = 'KEY_AVAILABILITY_SKU';
49
50
    /**
51
     * @var string
52
     */
53
    protected const KEY_AVAILABILITY_QUANTITY = 'KEY_AVAILABILITY_QUANTITY';
54
55
    /**
56
     * @var string
57
     */
58
    protected const KEY_AVAILABILITY_ID_STORE = 'KEY_AVAILABILITY_ID_STORE';
59
60
    /**
61
     * @var string
62
     */
63
    protected const KEY_AVAILABILITY_IS_NEVER_OUT_OF_STOCK = 'KEY_AVAILABILITY_IS_NEVER_OUT_OF_STOCK';
64
65
    /**
66
     * @var string
67
     */
68
    protected const KEY_AVAILABILITY_ID_AVAILABILITY_ABSTRACT = 'KEY_AVAILABILITY_ID_AVAILABILITY_ABSTRACT';
69
70
    /**
71
     * @var string
72
     */
73
    protected const COL_AVAILABILITY_TOTAL_QUANTITY = 'availabilityTotalQuantity';
74
75
    /**
76
     * @var string
77
     */
78
    protected const COL_STOCK_PRODUCT_TOTAL_QUANTITY = 'stockProductTotalQuantity';
79
80
    /**
81
     * @var array<string, array<int, \Orm\Zed\Availability\Persistence\SpyAvailabilityAbstract>>
82
     */
83
    protected static $availabilityAbstractEntitiesIndexedByAbstractSkuAndIdStore = [];
84
85
    /**
86
     * @var array<string>
87
     */
88
    protected static $productAbstractSkus = [];
89
90
    /**
91
     * @var \Pyz\Zed\DataImport\Business\Model\Product\Repository\ProductRepositoryInterface
92
     */
93
    protected $productRepository;
94
95
    /**
96
     * @var \Spryker\Zed\ProductBundle\Business\ProductBundleFacadeInterface
97
     */
98
    protected $productBundleFacade;
99
100
    /**
101
     * @var \Spryker\Zed\Store\Business\StoreFacadeInterface
102
     */
103
    protected $storeFacade;
104
105
    /**
106
     * @var \Spryker\Zed\Stock\Business\StockFacadeInterface
107
     */
108
    protected $stockFacade;
109
110
    /**
111
     * @param \Spryker\Zed\ProductBundle\Business\ProductBundleFacadeInterface $productBundleFacade
112
     * @param \Pyz\Zed\DataImport\Business\Model\Product\Repository\ProductRepositoryInterface $productRepository
113
     * @param \Spryker\Zed\Store\Business\StoreFacadeInterface $storeFacade
114
     * @param \Spryker\Zed\Stock\Business\StockFacadeInterface $stockFacade
115
     */
116
    public function __construct(
117
        ProductBundleFacadeInterface $productBundleFacade,
118
        ProductRepositoryInterface $productRepository,
119
        StoreFacadeInterface $storeFacade,
120
        StockFacadeInterface $stockFacade,
121
    ) {
122
        $this->productBundleFacade = $productBundleFacade;
123
        $this->productRepository = $productRepository;
124
        $this->storeFacade = $storeFacade;
125
        $this->stockFacade = $stockFacade;
126
    }
127
128
    /**
129
     * @param \Spryker\Zed\DataImport\Business\Model\DataSet\DataSetInterface $dataSet
130
     *
131
     * @return void
132
     */
133
    public function write(DataSetInterface $dataSet): void
134
    {
135
        $stockEntity = $this->createOrUpdateStock($dataSet);
136
        $this->createOrUpdateProductStock($dataSet, $stockEntity);
137
        $this->collectProductAbstractSku($dataSet);
138
        $this->updateAvailability($dataSet);
139
140
        if ($dataSet[static::COLUMN_IS_BUNDLE]) {
141
            $this->productBundleFacade->updateBundleAvailability($dataSet[static::COLUMN_CONCRETE_SKU]);
142
        } else {
143
            $this->productBundleFacade->updateAffectedBundlesAvailability($dataSet[static::COLUMN_CONCRETE_SKU]);
144
            $this->productBundleFacade->updateAffectedBundlesStock($dataSet[static::COLUMN_CONCRETE_SKU]);
145
        }
146
    }
147
148
    /**
149
     * @return void
150
     */
151
    public function flush(): void
152
    {
153
        $this->triggerAvailabilityPublishEvents();
154
        $this->productRepository->flush();
155
    }
156
157
    /**
158
     * @param \Spryker\Zed\DataImport\Business\Model\DataSet\DataSetInterface $dataSet
159
     *
160
     * @return \Orm\Zed\Stock\Persistence\SpyStock
161
     */
162
    protected function createOrUpdateStock(DataSetInterface $dataSet): SpyStock
163
    {
164
        $stockTransfer = $dataSet[ProductStockHydratorStep::STOCK_ENTITY_TRANSFER];
165
        $stockEntity = SpyStockQuery::create()
166
            ->filterByName($stockTransfer->getName())
167
            ->findOneOrCreate();
168
        $stockEntity->fromArray($stockTransfer->modifiedToArray());
169
        $stockEntity->save();
170
171
        return $stockEntity;
172
    }
173
174
    /**
175
     * @param \Spryker\Zed\DataImport\Business\Model\DataSet\DataSetInterface $dataSet
176
     * @param \Orm\Zed\Stock\Persistence\SpyStock $stockEntity
177
     *
178
     * @return void
179
     */
180
    protected function createOrUpdateProductStock(DataSetInterface $dataSet, SpyStock $stockEntity): void
181
    {
182
        $stockProductEntityTransfer = $dataSet[ProductStockHydratorStep::STOCK_PRODUCT_ENTITY_TRANSFER];
183
        $idProductConcrete = $this->productRepository->getIdProductByConcreteSku($dataSet[static::COLUMN_CONCRETE_SKU]);
184
        $stockProductEntity = SpyStockProductQuery::create()
185
            ->filterByFkProduct($idProductConcrete)
186
            ->filterByFkStock($stockEntity->getIdStock())
187
            ->findOneOrCreate();
188
        $stockProductEntity->fromArray($stockProductEntityTransfer->modifiedToArray());
189
        $stockProductEntity->save();
190
    }
191
192
    /**
193
     * @param \Spryker\Zed\DataImport\Business\Model\DataSet\DataSetInterface $dataSet
194
     *
195
     * @return void
196
     */
197
    protected function collectProductAbstractSku(DataSetInterface $dataSet): void
198
    {
199
        $productConcreteSku = $dataSet[static::COLUMN_CONCRETE_SKU];
200
        static::$productAbstractSkus[] = $this->productRepository->getAbstractSkuByConcreteSku($productConcreteSku);
201
    }
202
203
    /**
204
     * @return void
205
     */
206
    protected function triggerAvailabilityPublishEvents(): void
207
    {
208
        $availabilityAbstractIds = $this->getAvailabilityAbstractIdsForCollectedAbstractSkus();
209
210
        foreach ($availabilityAbstractIds as $availabilityAbstractId) {
211
            DataImporterPublisher::addEvent(AvailabilityEvents::AVAILABILITY_ABSTRACT_PUBLISH, $availabilityAbstractId);
212
        }
213
    }
214
215
    /**
216
     * @return array<int>
217
     */
218
    protected function getAvailabilityAbstractIdsForCollectedAbstractSkus(): array
219
    {
220
        $storeIds = $this->getStoreIds();
221
222
        return SpyAvailabilityAbstractQuery::create()
223
            ->joinWithSpyAvailability()
224
            ->filterByAbstractSku_In(static::$productAbstractSkus)
225
            ->useSpyAvailabilityQuery()
226
                ->filterByFkStore_In($storeIds)
227
            ->endUse()
228
            ->select([
229
                SpyAvailabilityAbstractTableMap::COL_ID_AVAILABILITY_ABSTRACT,
230
            ])
231
            ->find()
232
            ->getData();
233
    }
234
235
    /**
236
     * @return array<int>
237
     */
238
    protected function getStoreIds(): array
239
    {
240
        $storeIds = [];
241
242
        foreach ($this->storeFacade->getAllStores() as $storeTransfer) {
243
            $storeIds[] = $storeTransfer->getIdStoreOrFail();
244
        }
245
246
        return $storeIds;
247
    }
248
249
    /**
250
     * @param \Spryker\Zed\DataImport\Business\Model\DataSet\DataSetInterface $dataSet
251
     *
252
     * @return void
253
     */
254
    protected function updateAvailability(DataSetInterface $dataSet): void
255
    {
256
        foreach ($this->storeFacade->getAllStores() as $storeTransfer) {
257
            $this->updateAvailabilityForStore($dataSet, $storeTransfer);
258
        }
259
    }
260
261
    /**
262
     * @param \Spryker\Zed\DataImport\Business\Model\DataSet\DataSetInterface $dataSet
263
     * @param \Generated\Shared\Transfer\StoreTransfer $storeTransfer
264
     *
265
     * @return void
266
     */
267
    protected function updateAvailabilityForStore(DataSetInterface $dataSet, StoreTransfer $storeTransfer): void
268
    {
269
        $concreteSku = $dataSet[static::COLUMN_CONCRETE_SKU];
270
        $abstractSku = $this->productRepository->getAbstractSkuByConcreteSku($concreteSku);
271
        $idStore = $this->getIdStore($storeTransfer);
272
273
        $availabilityQuantity = $this->getProductAvailabilityForStore($concreteSku, $storeTransfer);
274
        $availabilityAbstractEntity = $this->getAvailabilityAbstract($abstractSku, $idStore);
275
        $this->persistAvailabilityData([
276
            static::KEY_AVAILABILITY_SKU => $concreteSku,
277
            static::KEY_AVAILABILITY_QUANTITY => $availabilityQuantity,
278
            static::KEY_AVAILABILITY_ID_AVAILABILITY_ABSTRACT => $availabilityAbstractEntity->getIdAvailabilityAbstract(),
279
            static::KEY_AVAILABILITY_ID_STORE => $idStore,
280
            static::KEY_AVAILABILITY_IS_NEVER_OUT_OF_STOCK => $dataSet[static::COLUMN_IS_NEVER_OUT_OF_STOCK],
281
        ]);
282
283
        $this->updateAbstractAvailabilityQuantity($availabilityAbstractEntity, $idStore);
284
    }
285
286
    /**
287
     * @param string $concreteSku
288
     * @param \Generated\Shared\Transfer\StoreTransfer $storeTransfer
289
     *
290
     * @return \Spryker\DecimalObject\Decimal
291
     */
292
    protected function getProductAvailabilityForStore(string $concreteSku, StoreTransfer $storeTransfer): Decimal
293
    {
294
        $physicalItems = $this->calculateProductStockForSkuAndStore($concreteSku, $storeTransfer);
295
        $reservedItems = $this->getReservationQuantityForStore($concreteSku, $storeTransfer);
296
        $stockProductQuantity = $physicalItems->subtract($reservedItems);
297
298
        return $stockProductQuantity->greatherThanOrEquals(0) ? $stockProductQuantity : new Decimal(0);
0 ignored issues
show
Deprecated Code introduced by
The function Spryker\DecimalObject\De...:greatherThanOrEquals() has been deprecated: Use {@link greaterThanOrEquals()} instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

298
        return /** @scrutinizer ignore-deprecated */ $stockProductQuantity->greatherThanOrEquals(0) ? $stockProductQuantity : new Decimal(0);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
299
    }
300
301
    /**
302
     * @param string $concreteSku
303
     * @param \Generated\Shared\Transfer\StoreTransfer $storeTransfer
304
     *
305
     * @return \Spryker\DecimalObject\Decimal
306
     */
307
    protected function calculateProductStockForSkuAndStore(string $concreteSku, StoreTransfer $storeTransfer): Decimal
308
    {
309
        $idProductConcrete = $this->productRepository->getIdProductByConcreteSku($concreteSku);
310
        $stockNames = $this->getStoreWarehouses($storeTransfer->getName());
311
312
        return $this->getStockProductQuantityByIdProductAndStockNames($idProductConcrete, $stockNames);
313
    }
314
315
    /**
316
     * @param string $storeName
317
     *
318
     * @return array<string>
319
     */
320
    protected function getStoreWarehouses(string $storeName): array
321
    {
322
        return $this->stockFacade->getStoreToWarehouseMapping()[$storeName] ?? [];
323
    }
324
325
    /**
326
     * @param int $idProductConcrete
327
     * @param array<string> $stockNames
328
     *
329
     * @return \Spryker\DecimalObject\Decimal
330
     */
331
    protected function getStockProductQuantityByIdProductAndStockNames(
332
        int $idProductConcrete,
333
        array $stockNames,
334
    ): Decimal {
335
        $stockProductTotalQuantity = SpyStockProductQuery::create()
336
            ->filterByFkProduct($idProductConcrete)
337
            ->useStockQuery()
338
                ->filterByName($stockNames, Criteria::IN)
339
            ->endUse()
340
            ->withColumn(sprintf('SUM(%s)', SpyStockProductTableMap::COL_QUANTITY), static::COL_STOCK_PRODUCT_TOTAL_QUANTITY)
341
            ->select([static::COL_STOCK_PRODUCT_TOTAL_QUANTITY])
342
            ->findOne();
343
344
        return new Decimal($stockProductTotalQuantity ?? 0);
345
    }
346
347
    /**
348
     * @param string $sku
349
     * @param \Generated\Shared\Transfer\StoreTransfer $storeTransfer
350
     *
351
     * @return \Spryker\DecimalObject\Decimal
352
     */
353
    protected function getReservationQuantityForStore(string $sku, StoreTransfer $storeTransfer): Decimal
354
    {
355
        $idStore = $this->getIdStore($storeTransfer);
356
357
        /** @var \Propel\Runtime\Collection\ArrayCollection $productReservations */
358
        $productReservations = SpyOmsProductReservationQuery::create()
359
            ->filterBySku($sku)
360
            ->filterByFkStore($idStore)
361
            ->select([
362
                SpyOmsProductReservationTableMap::COL_RESERVATION_QUANTITY,
363
            ])
364
            ->find();
365
366
        $reservationQuantity = new Decimal(0);
367
368
        foreach ($productReservations->toArray() as $productReservationQuantity) {
369
            $reservationQuantity = $reservationQuantity->add($productReservationQuantity);
370
        }
371
372
        $reservationQuantity = $reservationQuantity->add($this->getReservationsFromOtherStores($sku, $storeTransfer));
373
374
        return $reservationQuantity;
375
    }
376
377
    /**
378
     * @param string $sku
379
     * @param \Generated\Shared\Transfer\StoreTransfer $currentStoreTransfer
380
     *
381
     * @return \Spryker\DecimalObject\Decimal
382
     */
383
    protected function getReservationsFromOtherStores(string $sku, StoreTransfer $currentStoreTransfer): Decimal
384
    {
385
        $reservationQuantity = new Decimal(0);
386
        $reservationStores = SpyOmsProductReservationStoreQuery::create()
387
            ->filterBySku($sku)
388
            ->find();
389
390
        foreach ($reservationStores as $omsProductReservationStoreEntity) {
391
            if ($omsProductReservationStoreEntity->getStore() === $currentStoreTransfer->getName()) {
392
                continue;
393
            }
394
395
            $reservationQuantity = $reservationQuantity->add($omsProductReservationStoreEntity->getReservationQuantity());
396
        }
397
398
        return $reservationQuantity;
399
    }
400
401
    /**
402
     * @param \Generated\Shared\Transfer\StoreTransfer $storeTransfer
403
     *
404
     * @return int
405
     */
406
    protected function getIdStore(StoreTransfer $storeTransfer): int
407
    {
408
        if (!$storeTransfer->getIdStore()) {
409
            $idStore = $this->storeFacade
410
                ->getStoreByName($storeTransfer->getName())
411
                ->getIdStore();
412
            $storeTransfer->setIdStore($idStore);
413
        }
414
415
        return $storeTransfer->getIdStore();
416
    }
417
418
    /**
419
     * @param array<string, mixed> $availabilityData
420
     *
421
     * @return void
422
     */
423
    protected function persistAvailabilityData(array $availabilityData): void
424
    {
425
        $spyAvailabilityEntity = SpyAvailabilityQuery::create()
426
            ->filterByFkStore($availabilityData[static::KEY_AVAILABILITY_ID_STORE])
427
            ->filterBySku($availabilityData[static::KEY_AVAILABILITY_SKU])
428
            ->findOneOrCreate();
429
430
        $spyAvailabilityEntity->setFkAvailabilityAbstract($availabilityData[static::KEY_AVAILABILITY_ID_AVAILABILITY_ABSTRACT]);
431
        $spyAvailabilityEntity->setQuantity($availabilityData[static::KEY_AVAILABILITY_QUANTITY]);
432
        $spyAvailabilityEntity->setIsNeverOutOfStock($availabilityData[static::KEY_AVAILABILITY_IS_NEVER_OUT_OF_STOCK]);
433
434
        $spyAvailabilityEntity->save();
435
    }
436
437
    /**
438
     * @param string $abstractSku
439
     * @param int $idStore
440
     *
441
     * @return \Orm\Zed\Availability\Persistence\SpyAvailabilityAbstract
442
     */
443
    protected function getAvailabilityAbstract(string $abstractSku, int $idStore): SpyAvailabilityAbstract
444
    {
445
        if (!empty(static::$availabilityAbstractEntitiesIndexedByAbstractSkuAndIdStore[$abstractSku][$idStore])) {
446
            return static::$availabilityAbstractEntitiesIndexedByAbstractSkuAndIdStore[$abstractSku][$idStore];
447
        }
448
449
        $availabilityAbstractEntity = SpyAvailabilityAbstractQuery::create()
450
            ->filterByAbstractSku($abstractSku)
451
            ->filterByFkStore($idStore)
452
            ->findOne();
453
454
        if (!$availabilityAbstractEntity) {
455
            $availabilityAbstractEntity = $this->createAvailabilityAbstract($abstractSku, $idStore);
456
        }
457
458
        static::$availabilityAbstractEntitiesIndexedByAbstractSkuAndIdStore[$abstractSku][$idStore] = $availabilityAbstractEntity;
459
460
        return $availabilityAbstractEntity;
461
    }
462
463
    /**
464
     * @param string $abstractSku
465
     * @param int $idStore
466
     *
467
     * @return \Orm\Zed\Availability\Persistence\SpyAvailabilityAbstract
468
     */
469
    protected function createAvailabilityAbstract(string $abstractSku, int $idStore): SpyAvailabilityAbstract
470
    {
471
        $availableAbstractEntity = (new SpyAvailabilityAbstract())
472
            ->setAbstractSku($abstractSku)
473
            ->setFkStore($idStore);
474
475
        $availableAbstractEntity->save();
476
477
        return $availableAbstractEntity;
478
    }
479
480
    /**
481
     * @param \Orm\Zed\Availability\Persistence\SpyAvailabilityAbstract $availabilityAbstractEntity
482
     * @param int $idStore
483
     *
484
     * @return \Orm\Zed\Availability\Persistence\SpyAvailabilityAbstract
485
     */
486
    protected function updateAbstractAvailabilityQuantity(
487
        SpyAvailabilityAbstract $availabilityAbstractEntity,
488
        int $idStore,
489
    ): SpyAvailabilityAbstract {
490
        $sumQuantity = SpyAvailabilityQuery::create()
491
            ->filterByFkAvailabilityAbstract($availabilityAbstractEntity->getIdAvailabilityAbstract())
492
            ->filterByFkStore($idStore)
493
            ->withColumn(sprintf('SUM(%s)', SpyAvailabilityTableMap::COL_QUANTITY), static::COL_AVAILABILITY_TOTAL_QUANTITY)
494
            ->select([static::COL_AVAILABILITY_TOTAL_QUANTITY])
495
            ->findOne();
496
497
        $availabilityAbstractEntity->setFkStore($idStore);
498
        $availabilityAbstractEntity->setQuantity((string)$sumQuantity);
499
        $availabilityAbstractEntity->save();
500
501
        return $availabilityAbstractEntity;
502
    }
503
}
504