0

I'm working on integration, where I'm updating a product stock. But Whenever I set product stock to zero the product gets out-of-stock(as intended) from the backend but is still visible on the storefront.
Code used for product/stock update

if ($quantity > 0) {
     $prod->setStockData(array('use_config_manage_stock' => 0,
                               'manage_stock' => 1,
                               'is_in_stock' => 1,
                               'qty' => $quantity
                                ));
} else {
     $prod->setStockData(array('use_config_manage_stock' => 0,
                               'manage_stock' => 1,
                               'is_in_stock' => 0,
                               'qty' => 0
                                ));
}
$prodmodel->save();

The Indexer is set to Update on save.
display out-of-stock product is set to No from store config.

P.S
Whenever I do reindexing everything works perfectly. one option is to reindexing the after every product save but we've thousands of products and this can be very inefficient.
I can't share the full code.
enter image description here


enter image description here


enter image description here


Any kind of information is appreciated. Thanks!

1 Answer 1

0

At a first glance, it looks like the stock indexer is not triggered for some reason.
You can easily check this by running your code for a product (that should change the stock status to out of stock) then checking the table cataloginventory_stock_status. Check the value of the field stock_status for the record with the product_id the same as your product id. It should be 9 in your case. if it's not, then it meas the indexing for stock is not triggered.
I see 2 options here...

  • start investigating why the indexing is not triggered.
  • hide the dirt under the rug and trigger indexing for your updated product only, manually.

I have no advice for the first option, but for the quick and dirty one, you can inject in your class and instance of Magento\CatalogInventory\Model\Indexer\Stock\Action\Rows and call the method execute from it.

Here is a sample:

private \Magento\CatalogInventory\Model\Indexer\Stock\Action\Rows $indexer;

public function __construct(
    .....
    \Magento\CatalogInventory\Model\Indexer\Stock\Action\Rows $indexer
) {
     ....
    $this->indexer = $indexer;
}

then, after your code above call this

$this->indexer->execute([$prod->getId()]);

Or, if you are updating multiple products at once, collect all the ids into an array and at the end of everything trigger the indexing for all ids.

Side note, I see you are using in your code $prod->setStockData() and then calling $prodmodel->save();. are $prod and $prodmodel the same thing?

Side note 2: don't use $product->save. It is deprecated. Use the product repository instead.

6
  • Thanks for the response. Yes, $prod and $prodmodel are the same thing, and I don't have access to the DB. Is there any other way to check if the stock indexer is triggered?
    – Anurag
    Jul 17, 2023 at 11:10
  • you can do a select from your code and write the result somewhere
    – Marius
    Jul 17, 2023 at 11:37
  • I've checked the stock_status as you suggested and indeed it is changing from 0 to 1. Can you suggest any other method that will work apart from manually reindexing? and also my client is using some third part module for reindexing.
    – Anurag
    Jul 18, 2023 at 6:46
  • hmmm. I have no clear idea of what's happening. I still think there is one index that is not triggering (maybe I'm wrong). You can try to put some logs in every index to see what is triggered and what not when you save your product and when you do a full reindex and check the differences. other than that, I got nothing.
    – Marius
    Jul 18, 2023 at 8:47
  • Thanks, @Marius for the time being I'm marking this as the solution because the 2nd method worked for me (The code snippet you provided is deprecated). The code I'm currently using for reindexing. // reindexing after product update. $indexerFactory = $objectManager->get('Magento\Indexer\Model\IndexerFactory'); $indexer = $indexerFactory->create(); $indexer->load('cataloginventory_stock'); $indexer->reindexList([$prod->getId()]);
    – Anurag
    Jul 18, 2023 at 11:46

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.