-
Notifications
You must be signed in to change notification settings - Fork 254
Closed
Description
Full context in documentation
[HLD] Inconsistent saving of Stock Data
Description
1. Unite logic in a single processing point
The logic of the following classes:
- \Magento\CatalogInventory\Model\Plugin\AroundProductRepositorySave
- \Magento\CatalogInventory\Observer\SaveInventoryDataObserver
should be united in a single "processing" point. It could be a SaveInventoryProcessor class, like in the example below.
PAY ATTENTION: this logic is needed ONLY for BI (saving stock item data on product save). In proper way, we need to save StockItem only via StockItemRepositoryInterface
Also, we now save via stockregistry only for BI.
/**
* Dockblock like as "this logic is needed ONLY for BI (saving stock item data on product save). In propel way, we need to save StockItem only via StockItemRepository"
*/
class SaveInventoryProcessor (NOT INTERFACE)
{
/**
* Saving product inventory data
*
* @param Product $product
* @return $this
* @throws LocalizedException
*/
public function execute(Product $product)
{
$stockItem = $this->getStockItemToBeUpdated($product);
if (null !== $stockItem) {
$stockItem->setProductId($product->getId());
$stockItem->setWebsiteId($this->stockConfiguration->getDefaultScopeId());
$this->stockItemValidator->validate($product, $stockItem);
$this->stockRegistry->updateStockItemBySku($product->getSku(), $stockItem);
}
return $this;
}
/**
* Return the stock item that needs to be updated
*
* @param ProductInterface $product
* @return StockItemInterface|null
*/
private function getStockItemToBeUpdated($product)
{
$stockItem = null;
$extendedAttributes = $product->getExtensionAttributes();
if ($extendedAttributes !== null) {
$stockItem = $extendedAttributes->getStockItem();
}
if ($stockItem === null) {
$stockItem = $this->stockRegistry->getStockItem($product->getId());
}
return $stockItem;
}
}
The processing logic of saving data via model and via product repository must be the same!
2. Move validation logic from ProductRepositoryPlugin to a separate class.
For example:
<?php
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\CatalogInventory\Model;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\CatalogInventory\Api\Data\StockItemInterface;
use Magento\CatalogInventory\Api\StockConfigurationInterface;
use Magento\CatalogInventory\Api\StockRegistryInterface;
use Magento\Framework\Exception\LocalizedException;
/**
* StockItemValidator
*/
class StockItemValidator (NOT INTERFACE)
{
/**
* @var StockConfigurationInterface
*/
private $stockConfiguration;
/**
* @var StockRegistryInterface
*/
private $stockRegistry;
/**
* @param StockConfigurationInterface $stockConfiguration
* @param StockRegistryInterface $stockRegistry
*/
public function _construct(
StockConfigurationInterface $stockConfiguration,
StockRegistryInterface $stockRegistry
) {
$this->stockConfiguration = $stockConfiguration;
$this->stockRegistry = $stockRegistry;
}
/**
* @param ProductInterface $product
* @param StockItemInterface $stockItem
* @throws LocalizedException
* @return void
*/
public function validate(ProductInterface $product, StockItemInterface $stockItem)
{
$defaultScopeId = $this->stockConfiguration->getDefaultScopeId();
$defaultStockId = (int)$this->stockRegistry->getStock($defaultScopeId)->getStockId();
$stockId = (int)$stockItem->getStockId();
if ($stockId !== null && $stockId !== $defaultStockId) {
throw new LocalizedException(
__('Invalid stock id: %1. Only default stock with id %2 allowed', $stockId, $defaultStockId)
);
}
$stockItemId = $stockItem->getItemId();
if ($stockItemId !== null && (!is_numeric($stockItemId) || $stockItemId <= 0)) {
throw new LocalizedException(
__('Invalid stock item id: %1. Should be null or numeric value greater than 0', $stockItemId)
);
}
$defaultStockItemId = $this->stockRegistry->getStockItem($product->getId())->getItemId();
if ($defaultStockItemId && $stockItemId !== null && $defaultStockItemId !== $stockItemId) {
throw new LocalizedException(
__('Invalid stock item id: %1. Assigned stock item id is %2', $stockItemId, $defaultStockItemId)
);
}
}
}
Also need to investigate about moving this logic in StockItemRepository
Metadata
Metadata
Assignees
Labels
No labels