![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/Ecombricks/InventoryInventorySales/Model/ |
<?php /** * Copyright © eComBricks. All rights reserved. * See LICENSE.txt for license details. */ declare(strict_types=1); namespace Ecombricks\InventoryInventorySales\Model; /** * Source item management */ class SourceItemManagement { /** * Product repository * * @var \Magento\Catalog\Model\ProductRepository */ protected $productRepository; /** * Get source items resource * * @var \Ecombricks\InventoryInventorySales\Model\ResourceModel\SourceItem\Get */ protected $getSourceItemsResource; /** * Source item factory * * @var \Ecombricks\InventoryInventorySales\Model\SourceItemInterfaceFactory */ protected $sourceItemFactory; /** * Current stock provider * * @var \Ecombricks\InventoryInventoryCatalog\Api\CurrentStockProviderInterface */ protected $currentStockProvider; /** * Source items * * @var \Ecombricks\InventoryInventorySales\Model\SourceItemInterface[][] */ protected $sourceItems = []; /** * Constructor * * @param \Magento\Catalog\Model\ProductRepository $productRepository * @param \Ecombricks\InventoryInventorySales\Model\ResourceModel\SourceItem\Get $getSourceItemsResource * @param \Ecombricks\InventoryInventorySales\Model\SourceItemInterfaceFactory $sourceItemFactory * @param \Ecombricks\InventoryInventoryCatalog\Api\CurrentStockProviderInterface $currentStockProvider * @return void */ public function __construct( \Magento\Catalog\Model\ProductRepository $productRepository, \Ecombricks\InventoryInventorySales\Model\ResourceModel\SourceItem\Get $getSourceItemsResource, \Ecombricks\InventoryInventorySales\Model\SourceItemInterfaceFactory $sourceItemFactory, \Ecombricks\InventoryInventoryCatalog\Api\CurrentStockProviderInterface $currentStockProvider ) { $this->productRepository = $productRepository; $this->getSourceItemsResource = $getSourceItemsResource; $this->sourceItemFactory = $sourceItemFactory; $this->currentStockProvider = $currentStockProvider; } /** * Get product * * @param string $sku * @return \Magento\Catalog\Api\Data\ProductInterface */ protected function getProduct(string $sku): \Magento\Catalog\Api\Data\ProductInterface { return $this->productRepository->get($sku); } /** * Get product SKU * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @return string */ public function getProductSku(\Magento\Catalog\Api\Data\ProductInterface $product): string { return $product->getData(\Magento\Catalog\Api\Data\ProductInterface::SKU); } /** * Get product SKUs * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @return array */ public function getProductSkus(\Magento\Catalog\Api\Data\ProductInterface $product): array { $skus = []; if ($product->isComposite()) { foreach ($product->getTypeInstance()->getProductsToPurchaseByReqGroups($product) as $childGroupProducts) { foreach ($childGroupProducts as $childProduct) { $childSku = $this->getProductSku($childProduct); if (in_array($childSku, $skus)) { continue; } $skus[] = $childSku; } } } else { $skus[] = $this->getProductSku($product); } return $skus; } /** * Load list * * @param array $skus * @param int $stockId * @return array */ protected function loadList(array $skus, int $stockId): array { $sourceItems = []; $data = $this->getSourceItemsResource->execute($skus, $stockId); if (empty($data)) { return $sourceItems; } foreach ($data as $sourceItemData) { $sourceItem = $this->sourceItemFactory->create(); $sourceItem ->setSku((string) $sourceItemData['sku']) ->setSourceCode((string) $sourceItemData['source_code']) ->setQuantity((float) $sourceItemData['quantity']) ->setIsSalable((bool) $sourceItemData['is_salable']); $sourceItems[$sourceItem->getSku()][$sourceItem->getSourceCode()] = $sourceItem; } return $sourceItems; } /** * Get source items source codes * * @param array $sourceItems * @return array */ protected function getSourceItemsSourceCodes(array $sourceItems): array { $sourceCodes = []; foreach ($sourceItems as $productSourceItems) { foreach (array_keys($productSourceItems) as $sourceCode) { if (!in_array($sourceCode, $sourceCodes)) { $sourceCodes[] = $sourceCode; } } } return $sourceCodes; } /** * Get composite product source item * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param string $sourceCode * @param array $sourceItems * @return \Ecombricks\InventoryInventorySales\Model\SourceItemInterface */ protected function getCompositeProductSourceItem( \Magento\Catalog\Api\Data\ProductInterface $product, string $sourceCode, array $sourceItems ): \Ecombricks\InventoryInventorySales\Model\SourceItemInterface { $qty = $isSalable = null; foreach ($product->getTypeInstance()->getProductsToPurchaseByReqGroups($product) as $childGroupProducts) { $childGroupQty = 0; $childGroupIsSalable = false; foreach ($childGroupProducts as $childProduct) { $childSku = $this->getProductSku($childProduct); $childSourceItem = $sourceItems[$childSku][$sourceCode] ?? null; $childQty = $childSourceItem ? $childSourceItem->getQuantity() : 0; $childIsSalable = $childSourceItem ? $childSourceItem->getIsSalable() : false; $childGroupQty += $childQty; $childGroupIsSalable = $childGroupIsSalable || $childIsSalable; } $qty = ($qty !== null) ? min($qty, $childGroupQty) : $childGroupQty; $isSalable = ($isSalable !== null) ? $isSalable && $childGroupIsSalable : $childGroupIsSalable; } return $this->sourceItemFactory->create() ->setSku($this->getProductSku($product)) ->setSourceCode($sourceCode) ->setQuantity((float) $qty) ->setIsSalable((bool) $isSalable); } /** * Get source item list * * @param string $sku * @param int $stockId * @return \Ecombricks\InventoryInventorySales\Model\SourceItemInterface[] */ public function getList(string $sku, int $stockId): array { if ( array_key_exists($sku, $this->sourceItems) && array_key_exists($stockId, $this->sourceItems[$sku]) ) { return $this->sourceItems[$sku][$stockId]; } $this->sourceItems[$sku][$stockId] = []; $product = $this->getProduct($sku); $sourceItems = $this->loadList($this->getProductSkus($product), $stockId); foreach ($this->getSourceItemsSourceCodes($sourceItems) as $sourceCode) { $sourceItem = $product->isComposite() ? $this->getCompositeProductSourceItem($product, $sourceCode, $sourceItems): $sourceItems[$sku][$sourceCode] ?? null; if (empty($sourceItem)) { continue; } $this->sourceItems[$sku][$stockId][$sourceCode] = $sourceItem; } return $this->sourceItems[$sku][$stockId]; } /** * Get source item * * @param string $sku * @param int $stockId * @param string $sourceCode * @return \Ecombricks\InventoryInventorySales\Model\SourceItemInterface|null */ public function get(string $sku, int $stockId, string $sourceCode): ?\Ecombricks\InventoryInventorySales\Model\SourceItemInterface { $sourceItems = $this->getList($sku, $stockId); return $sourceItems[$sourceCode] ?? null; } /** * Get salable list * * @param string $sku * @param int $stockId * @return \Ecombricks\InventoryInventorySales\Model\SourceItemInterface[] */ public function getSalableList(string $sku, int $stockId): array { $sourceItems = []; foreach ($this->getList($sku, $stockId) as $sourceCode => $sourceItem) { if (!$sourceItem->isSalable() || $sourceItem->getQuantity() <= 0) { continue; } $sourceItems[$sourceCode] = $sourceItem; } return $sourceItems; } /** * Get current stock salable list * * @param string $sku * @param int|null $storeId * @return \Ecombricks\InventoryInventorySales\Model\SourceItemInterface[] */ public function getCurrentStockSalableList(string $sku, int $storeId = null): array { $stockId = $this->currentStockProvider->getId($storeId); return $this->getSalableList($sku, $stockId); } /** * Get current stock salable source codes * * @param string $sku * @param int|null $storeId * @return array */ public function getCurrentStockSalableSourceCodes(string $sku, int $storeId = null): array { return array_keys($this->getCurrentStockSalableList($sku, $storeId)); } /** * Get product current stock salable source codes * * @param \Magento\Catalog\Api\Data\ProductInterface $product * @param int|null $storeId * @return array */ public function getProductCurrentStockSalableSourceCodes( \Magento\Catalog\Api\Data\ProductInterface $product, int $storeId = null ): array { return $this->getCurrentStockSalableSourceCodes($this->getProductSku($product), $storeId); } }