magento2: Duplicated product is out of stock when index set to UPDATE BY SCHEDULE

Preconditions

  1. Install Magento Open Source 2.2.4 with sample data
  2. Setup CRON
  3. Change all indexes to “UPDATE BY SCHEDULE”

Steps to reproduce

  1. Locate a simple product in the backend
  2. Click “Save & Duplicate”
  3. Set the following attribute values on the newly created product and then click “Save”:
    • Enabled: True
    • Quantity: 1
    • Stock Status: In Stock
  4. Load the product on the frontend (either by loading the url key or by accessing the product directly via /catalog/product/view/<ID>)

Expected result

  1. The product should show with an “Add to Cart” button: 11-08-27 tp - meta title-onn3t

Actual result

  1. The product shows as “Out of Stock”: 11-06-49 tp - meta title-pk0l0
  2. If I run these commands, then the product shows as in stock:
bin/magento indexer:reindex cataloginventory_stock
bin/magento cache:flush

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 22 (12 by maintainers)

Most upvoted comments

Still facing this issue on latest 2.4-develop

Preconditions

  1. Magento 2.4-develop
  2. Setup CRON
  3. Change all indexes to “UPDATE BY SCHEDULE” Indexer

Steps to Rerpoduce:

  1. Select existing product in backend or create new
  2. Click “Save & Duplicate”
  3. Set the following attribute values on the newly created product and then click “Save”: Enabled: True Quantity: 1 Stock Status: In Stock Save and duplicate
  4. Load the product on the frontend

Actual Result: The product shows as “Out of Stock”: Out

@engcom-backlog-nazar yep, looks like #12205 does not actually fix this particular issue… apologies.

Upon investigating this one further - this looks to be due to an omission in the way the stock indexer changelog is triggered on INSERT / UPDATES / DELETES…

For example…

  1. Updating a product’s details relating to inventory (ie: qty or stock status), will result in the item being scheduled for update in the stock index - as such, the product becomes available for sale after the schedule update is completed.

  2. Updating a product’s attribute details (ie: enabling / disabling a product’s status), will NOT result in the item being scheduled for an update in the stock index — this can result in the item becoming available in Magento’s frontend, but in a state where it will appear as “Out Of Stock”

The problem would also appear to be related to “disabled” products not containing an entry in the cataloginventory_stock_status table. As such, once it’s enabled, it never gets this entry.

For example — updates to the catalog_product_entity and catalog_product_entity_int tables does not trigger updates to the stock indexer changelog.

catalog_product_entity triggers

BEGIN
INSERT IGNORE INTO `catalogsearch_fulltext_cl` (`entity_id`) VALUES (OLD.`entity_id`);
INSERT IGNORE INTO `catalog_product_price_cl` (`entity_id`) VALUES (OLD.`entity_id`);
INSERT IGNORE INTO `catalogrule_product_cl` (`entity_id`) VALUES (OLD.`entity_id`);
END

catalog_product_entity_int triggers

BEGIN
IF (NEW.`value_id` != OLD.`value_id` OR NEW.`attribute_id` != OLD.`attribute_id` OR NEW.`store_id` != OLD.`store_id` OR NEW.`entity_id` != OLD.`entity_id` OR NEW.`value` != OLD.`value`) THEN INSERT IGNORE INTO `catalogsearch_fulltext_cl` (`entity_id`) VALUES (NEW.`entity_id`); END IF;
IF (NEW.`value_id` != OLD.`value_id` OR NEW.`attribute_id` != OLD.`attribute_id` OR NEW.`store_id` != OLD.`store_id` OR NEW.`entity_id` != OLD.`entity_id` OR NEW.`value` != OLD.`value`) THEN INSERT IGNORE INTO `catalog_product_category_cl` (`entity_id`) VALUES (NEW.`entity_id`); END IF;
IF (NEW.`value_id` != OLD.`value_id` OR NEW.`attribute_id` != OLD.`attribute_id` OR NEW.`store_id` != OLD.`store_id` OR NEW.`entity_id` != OLD.`entity_id` OR NEW.`value` != OLD.`value`) THEN INSERT IGNORE INTO `catalog_product_price_cl` (`entity_id`) VALUES (NEW.`entity_id`); END IF;
IF (NEW.`value_id` != OLD.`value_id` OR NEW.`attribute_id` != OLD.`attribute_id` OR NEW.`store_id` != OLD.`store_id` OR NEW.`entity_id` != OLD.`entity_id` OR NEW.`value` != OLD.`value`) THEN INSERT IGNORE INTO `catalog_product_attribute_cl` (`entity_id`) VALUES (NEW.`entity_id`); END IF;
IF (NEW.`value_id` != OLD.`value_id` OR NEW.`attribute_id` != OLD.`attribute_id` OR NEW.`store_id` != OLD.`store_id` OR NEW.`entity_id` != OLD.`entity_id` OR NEW.`value` != OLD.`value`) THEN INSERT IGNORE INTO `catalogrule_product_cl` (`entity_id`) VALUES (NEW.`entity_id`); END IF;
END