0

I'm trying to update product quantities when something sells or is revised on another selling channel. I have a platform notification which is received, and everything works fine except when I'm trying to revise an out of stock product. In this situation, the quantity will change, buy the salable quantity will not. If I then locate the product in Admin->Catalog->Products and save it without making any changes, the salable quantity will update. What am I doing wrong?

My code is below.

 public function updateProduct(string $sku, int $qty): void
{
        $sourceItem = $this->sourceItemFactory->create();
        $sourceItem->setSourceCode('default');
        $sourceItem->setSku($sku);
        $sourceItem->setQuantity($qty);

    if ($qty > 0) {
        $sourceItem->setStatus(SourceItemInterface::STATUS_IN_STOCK);
    } else {
        $sourceItem->setStatus(SourceItemInterface::STATUS_OUT_OF_STOCK);
    }
    $this->sourceItemsSaveInterface->execute([$sourceItem]);

    $this->reIndex();
}

2 Answers 2

1

I got it. I had to update the stockItem after saving the sourceItem. Below is full working code.

use Magento\InventoryApi\Api\SourceItemsSaveInterface;
use Magento\InventoryApi\Api\Data\SourceItemInterfaceFactory;
use Magento\Framework\ObjectManagerInterface;
use Magento\Inventory\Model\SourceItem\Command\GetSourceItemsBySku;

class UpdateProduct
{

/** @var SourceItemsSaveInterface */
protected $sourceItemsSaveInterface;

/** @var SourceItemInterfaceFactory */
protected $sourceItemInterfaceFactory;

/** @var GetSourceItemsBySku */
protected $getSourceItemsBySku;

/** @var ObjectManagerInterface */
protected $objectManager;

/**
 *
 * @param SourceItemsSaveInterface      $sourceItemsSaveInterface
 * @param SourceItemInterfaceFactory    $sourceItemInterfaceFactory
 * @param ObjectManagerInterface        $objectManager
 * @param GetSourceItemsBySku           $getSourceItemsBySku
 //* @param SourceItemInterface           $sourceItemInterface
 */
public function __construct(
    SourceItemsSaveInterface $sourceItemsSaveInterface,
    SourceItemInterfaceFactory $sourceItemInterfaceFactory,
    ObjectManagerInterface $objectManager,
    GetSourceItemsBySku $getSourceItemsBySku,
) {
    $this->sourceItemsSaveInterface = $sourceItemsSaveInterface;
    $this->sourceItemInterfaceFactory = $sourceItemInterfaceFactory;
    $this->objectManager = $objectManager;
    $this->getSourceItemsBySku = $getSourceItemsBySku;
}



/**
 * Updates product quantityn and stock status
 *
 * @param string $sku
 * @param int    $qty
 *
 * @return void
 * @throws \Magento\Framework\Exception\CouldNotSaveException
 * @throws \Magento\Framework\Exception\InputException
 * @throws \Magento\Framework\Validation\ValidationException
 * @throws \Throwable
 */
public function updateProduct(string $sku, int $qty): void
{
        $sourceItems = $this->getSourceItemsBySku->execute($sku);

        foreach ($sourceItems as $item){

            if ($item->getSourceCode() === 'default'){

                $sourceItem = $this->sourceItemInterfaceFactory->create();
                $sourceItem->setSourceCode('default');
                $sourceItem->setSku($sku);
                $sourceItem->setQuantity($qty);
                $sourceItem->setStatus((bool)$qty);
                $this->sourceItemsSaveInterface->execute([$sourceItem]);
                $product = $this->objectManager->get('Magento\Catalog\Model\Product');
                $stockRegistry = $this->objectManager->create('Magento\CatalogInventory\Api\StockRegistryInterface');

                if($product->getIdBySku($sku)) {
                    $stockItem = $stockRegistry->getStockItem($product->getId());
                    $stockItem->setQty($qty);
                    $stockItem->setIsInStock((bool)$qty);
                    $stockRegistry->updateStockItemBySku($sku, $stockItem);
                }

                break;
            }
        }
}

}
4
  • Hello! Could you tell me what class and method should I override with that code? Thanks! Commented Dec 26, 2022 at 17:24
  • Nothing to override. I have an API set up to receive notifications from eBay, and it sends them to my updateProduct function.
    – Swappart
    Commented Jan 2, 2023 at 16:51
  • I edited my answer to include the complete working code.
    – Swappart
    Commented Jan 2, 2023 at 17:24
  • Thanks for your answer! Commented Jan 4, 2023 at 19:30
0

I guess your issue might be related to MSI and Reservation functionality

I recommend to review data in inventory_reservation table

Unfortunately, you cannot disable this functionality with configuration, but you can install plugin like https://github.com/AmpersandHQ/magento2-disable-stock-reservation for do this.

If it's a revision logic and you need to set available saleable qty for product you can clear inventory_reservation table data for updating product.

2
  • I don't think that's the issue. The salable quantity will go up or down if it isn't out of stock. The issue affects products which are out of stock because of sales, as well as ones which were created with a zero stock quantity. In the latter, there would be no stock reservation.
    – Swappart
    Commented Aug 14, 2022 at 16:31
  • I'm still having this issue. I discovered that the cataloginventory_stock_item table was not populated. I fixed that with an SQL query, and the above code does correctly update the quantity. The problem is that the cataloginventory_stock_status does not get updated. If I manually change the stock status from 0 to 1 in the database, the salable quantity will be correct. How can I make that happen programmatically when I update the quantity?
    – Swappart
    Commented Nov 1, 2022 at 18:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.