123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- namespace Magento\CatalogInventory\Model;
- use Magento\CatalogInventory\Api\Data\StockItemInterface;
- use Magento\CatalogInventory\Api\RegisterProductSaleInterface;
- use Magento\CatalogInventory\Api\RevertProductSaleInterface;
- use Magento\CatalogInventory\Api\StockConfigurationInterface;
- use Magento\CatalogInventory\Api\StockManagementInterface;
- use Magento\CatalogInventory\Model\ResourceModel\QtyCounterInterface;
- use Magento\CatalogInventory\Model\Spi\StockRegistryProviderInterface;
- use Magento\Catalog\Api\ProductRepositoryInterface;
- use Magento\CatalogInventory\Model\ResourceModel\Stock as ResourceStock;
- /**
- * Implements a few interfaces for backward compatibility
- */
- class StockManagement implements StockManagementInterface, RegisterProductSaleInterface, RevertProductSaleInterface
- {
- /**
- * @var StockRegistryProviderInterface
- */
- protected $stockRegistryProvider;
- /**
- * @var StockState
- */
- protected $stockState;
- /**
- * @var StockConfigurationInterface
- */
- protected $stockConfiguration;
- /**
- * @var ProductRepositoryInterface
- */
- protected $productRepository;
- /**
- * @var ResourceStock
- */
- protected $resource;
- /**
- * @var QtyCounterInterface
- */
- private $qtyCounter;
- /**
- * @var StockRegistryStorage
- */
- private $stockRegistryStorage;
- /**
- * @param ResourceStock $stockResource
- * @param StockRegistryProviderInterface $stockRegistryProvider
- * @param StockState $stockState
- * @param StockConfigurationInterface $stockConfiguration
- * @param ProductRepositoryInterface $productRepository
- * @param QtyCounterInterface $qtyCounter
- * @param StockRegistryStorage|null $stockRegistryStorage
- */
- public function __construct(
- ResourceStock $stockResource,
- StockRegistryProviderInterface $stockRegistryProvider,
- StockState $stockState,
- StockConfigurationInterface $stockConfiguration,
- ProductRepositoryInterface $productRepository,
- QtyCounterInterface $qtyCounter,
- StockRegistryStorage $stockRegistryStorage = null
- ) {
- $this->stockRegistryProvider = $stockRegistryProvider;
- $this->stockState = $stockState;
- $this->stockConfiguration = $stockConfiguration;
- $this->productRepository = $productRepository;
- $this->qtyCounter = $qtyCounter;
- $this->resource = $stockResource;
- $this->stockRegistryStorage = $stockRegistryStorage ?: \Magento\Framework\App\ObjectManager::getInstance()
- ->get(StockRegistryStorage::class);
- }
- /**
- * Subtract product qtys from stock.
- *
- * Return array of items that require full save.
- *
- * @param string[] $items
- * @param int $websiteId
- * @return StockItemInterface[]
- * @throws \Magento\Framework\Exception\LocalizedException
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
- */
- public function registerProductsSale($items, $websiteId = null)
- {
- //if (!$websiteId) {
- $websiteId = $this->stockConfiguration->getDefaultScopeId();
- //}
- $this->getResource()->beginTransaction();
- $lockedItems = $this->getResource()->lockProductsStock(array_keys($items), $websiteId);
- $fullSaveItems = $registeredItems = [];
- foreach ($lockedItems as $lockedItemRecord) {
- $productId = $lockedItemRecord['product_id'];
- $this->stockRegistryStorage->removeStockItem($productId, $websiteId);
- /** @var StockItemInterface $stockItem */
- $orderedQty = $items[$productId];
- $stockItem = $this->stockRegistryProvider->getStockItem($productId, $websiteId);
- $stockItem->setQty($lockedItemRecord['qty']); // update data from locked item
- $canSubtractQty = $stockItem->getItemId() && $this->canSubtractQty($stockItem);
- if (!$canSubtractQty || !$this->stockConfiguration->isQty($lockedItemRecord['type_id'])) {
- continue;
- }
- if (!$stockItem->hasAdminArea()
- && !$this->stockState->checkQty($productId, $orderedQty, $stockItem->getWebsiteId())
- ) {
- $this->getResource()->commit();
- throw new \Magento\Framework\Exception\LocalizedException(
- __('Not all of your products are available in the requested quantity.')
- );
- }
- if ($this->canSubtractQty($stockItem)) {
- $stockItem->setQty($stockItem->getQty() - $orderedQty);
- }
- $registeredItems[$productId] = $orderedQty;
- if (!$this->stockState->verifyStock($productId, $stockItem->getWebsiteId())
- || $this->stockState->verifyNotification(
- $productId,
- $stockItem->getWebsiteId()
- )
- ) {
- $fullSaveItems[] = $stockItem;
- }
- }
- $this->qtyCounter->correctItemsQty($registeredItems, $websiteId, '-');
- $this->getResource()->commit();
-
- return $fullSaveItems;
- }
- /**
- * @inheritdoc
- */
- public function revertProductsSale($items, $websiteId = null)
- {
- //if (!$websiteId) {
- $websiteId = $this->stockConfiguration->getDefaultScopeId();
- //}
- $revertItems = [];
- foreach ($items as $productId => $qty) {
- $stockItem = $this->stockRegistryProvider->getStockItem($productId, $websiteId);
- $canSubtractQty = $stockItem->getItemId() && $this->canSubtractQty($stockItem);
- if (!$canSubtractQty || !$this->stockConfiguration->isQty($stockItem->getTypeId())) {
- continue;
- }
- $revertItems[$productId] = $qty;
- }
- $this->qtyCounter->correctItemsQty($revertItems, $websiteId, '+');
- return $revertItems;
- }
- /**
- * Get back to stock (when order is canceled or whatever else)
- *
- * @param int $productId
- * @param float $qty
- * @param int $scopeId
- * @return bool
- */
- public function backItemQty($productId, $qty, $scopeId = null)
- {
- //if (!$scopeId) {
- $scopeId = $this->stockConfiguration->getDefaultScopeId();
- //}
- $stockItem = $this->stockRegistryProvider->getStockItem($productId, $scopeId);
- if ($stockItem->getItemId() && $this->stockConfiguration->isQty($this->getProductType($productId))) {
- if ($this->canSubtractQty($stockItem)) {
- $stockItem->setQty($stockItem->getQty() + $qty);
- }
- if ($this->stockConfiguration->getCanBackInStock($stockItem->getStoreId()) && $stockItem->getQty()
- > $stockItem->getMinQty()
- ) {
- $stockItem->setIsInStock(true);
- $stockItem->setStockStatusChangedAutomaticallyFlag(true);
- }
- $stockItem->save();
- }
- return true;
- }
- /**
- * Get Product type
- *
- * @param int $productId
- * @return string
- */
- protected function getProductType($productId)
- {
- return $this->productRepository->getById($productId)->getTypeId();
- }
- /**
- * Get stock resource.
- *
- * @return ResourceStock
- */
- protected function getResource()
- {
- return $this->resource;
- }
- /**
- * Check if is possible subtract value from item qty
- *
- * @param StockItemInterface $stockItem
- * @return bool
- */
- protected function canSubtractQty(StockItemInterface $stockItem)
- {
- return $stockItem->getManageStock() && $this->stockConfiguration->canSubtractQty();
- }
- }
|