Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create a single point of stock data processing #19

Closed
naydav opened this issue May 19, 2017 · 0 comments
Closed

Create a single point of stock data processing #19

naydav opened this issue May 19, 2017 · 0 comments
Assignees

Comments

@naydav
Copy link

naydav commented May 19, 2017

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

@naydav naydav self-assigned this May 19, 2017
@naydav naydav closed this as completed Jul 10, 2017
larsroettig pushed a commit to magento-techdivision/inventory-deprecated that referenced this issue Jul 9, 2019
mmansoor-magento pushed a commit that referenced this issue Dec 6, 2020
[Arrows] MC-33288: [2.4][MSI][MFTF] StorefrontLoggedInCustomerCreateOrderAllOptionQuantityConfigurableProductCustomStockTest fails because of bad design
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant