/** * Update stock item on the stock and distribute qty by lots. * * @param \Magento\CatalogInventory\Model\StockManagement $subject * @param \Closure $proceed * @param array $items * @param int $websiteId is not used * @throws \Magento\Framework\Exception\LocalizedException * @return null */ public function aroundRegisterProductsSale(\Magento\CatalogInventory\Model\StockManagement $subject, \Closure $proceed, array $items, $websiteId) { /* This code is moved from original 'registerProductsSale' method. */ /* replace websiteId by stockId */ $stockId = $this->_manStock->getCurrentStockId(); $def = $this->_manTrans->begin(); $lockedItems = $this->_resourceStock->lockProductsStock(array_keys($items), $stockId); $fullSaveItems = $registeredItems = []; foreach ($lockedItems as $lockedItemRecord) { $productId = $lockedItemRecord['product_id']; $orderedQty = $items[$productId]; /** @var \Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem */ $stockItem = $this->_providerStockRegistry->getStockItem($productId, $stockId); $stockItemId = $stockItem->getItemId(); $canSubtractQty = $stockItemId && $this->_canSubtractQty($stockItem); if (!$canSubtractQty || !$this->_configStock->isQty($lockedItemRecord['type_id'])) { continue; } if (!$stockItem->hasAdminArea() && !$this->_stockState->checkQty($productId, $orderedQty)) { $this->_manTrans->rollback($def); 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) || $this->_stockState->verifyNotification($productId)) { $fullSaveItems[] = $stockItem; } } $this->_resourceStock->correctItemsQty($registeredItems, $stockId, '-'); $this->_manTrans->commit($def); return $fullSaveItems; }
/** * 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; }
/** * @inheritdoc */ public function save(\Magento\CatalogInventory\Api\Data\StockItemInterface $stockItem) { try { /** @var \Magento\Catalog\Model\Product $product */ $product = $this->productFactory->create(); $product->load($stockItem->getProductId()); if (!$product->getId()) { return $stockItem; } $typeId = $product->getTypeId() ?: $product->getTypeInstance()->getTypeId(); $isQty = $this->stockConfiguration->isQty($typeId); if ($isQty) { $isInStock = $this->stockStateProvider->verifyStock($stockItem); if ($stockItem->getManageStock() && !$isInStock) { $stockItem->setIsInStock(false)->setStockStatusChangedAutomaticallyFlag(true); } // if qty is below notify qty, update the low stock date to today date otherwise set null $stockItem->setLowStockDate(null); if ($this->stockStateProvider->verifyNotification($stockItem)) { $stockItem->setLowStockDate((new \DateTime())->format('Y-m-d H:i:s')); } $stockItem->setStockStatusChangedAuto(0); if ($stockItem->hasStockStatusChangedAutomaticallyFlag()) { $stockItem->setStockStatusChangedAuto((int) $stockItem->getStockStatusChangedAutomaticallyFlag()); } } else { $stockItem->setQty(0); } $stockItem->setWebsiteId($stockItem->getWebsiteId()); $stockItem->setStockId($stockItem->getStockId()); $this->resource->save($stockItem); $this->indexProcessor->reindexRow($stockItem->getProductId()); } catch (\Exception $exception) { throw new CouldNotSaveException(__($exception->getMessage())); } return $stockItem; }
/** * Stock item saving. * * @return $this */ protected function _saveStockItem() { $indexer = $this->indexerRegistry->get('catalog_product_category'); /** @var $stockResource \Magento\CatalogInventory\Model\ResourceModel\Stock\Item */ $stockResource = $this->_stockResItemFac->create(); $entityTable = $stockResource->getMainTable(); while ($bunch = $this->_dataSourceModel->getNextBunch()) { $stockData = []; $productIdsToReindex = []; // Format bunch to stock data rows foreach ($bunch as $rowNum => $rowData) { if (!$this->isRowAllowedToImport($rowData, $rowNum)) { continue; } $row = []; $row['product_id'] = $this->skuProcessor->getNewSku($rowData[self::COL_SKU])['entity_id']; $productIdsToReindex[] = $row['product_id']; $row['website_id'] = $this->stockConfiguration->getDefaultWebsiteId(); $row['stock_id'] = $this->stockRegistry->getStock($row['website_id'])->getStockId(); $stockItemDo = $this->stockRegistry->getStockItem($row['product_id'], $row['website_id']); $existStockData = $stockItemDo->getData(); $row = array_merge($this->defaultStockData, array_intersect_key($existStockData, $this->defaultStockData), array_intersect_key($rowData, $this->defaultStockData), $row); if ($this->stockConfiguration->isQty($this->skuProcessor->getNewSku($rowData[self::COL_SKU])['type_id'])) { $stockItemDo->setData($row); $row['is_in_stock'] = $this->stockStateProvider->verifyStock($stockItemDo); if ($this->stockStateProvider->verifyNotification($stockItemDo)) { $row['low_stock_date'] = $this->_localeDate->date(null, null, false)->format('Y-m-d H:i:s'); } $row['stock_status_changed_auto'] = (int) (!$this->stockStateProvider->verifyStock($stockItemDo)); } else { $row['qty'] = 0; } $stockData[] = $row; } // Insert rows if (!empty($stockData)) { $this->_connection->insertOnDuplicate($entityTable, $stockData); } if ($productIdsToReindex) { $indexer->reindexList($productIdsToReindex); } } return $this; }