magento2: Magento2 multi-store price-per-website: Wrong price indexed for configurable products

I have a multi-website Magento 2.1.0 CE installation, with 2 websites and different prices per-website. Prices are note related to each other, for the same product across the two websites.

In product listing pages (PLP), I keep seeing “as low as $55.55” for configurable prices, along with the correct prices, in non-default website 2, even though prices have been set correctly, all configurable children have the same prices $55.55 in website 1 (default) and $77.77 in website 2 (non-default). Configurable product itself has been priced accordingly, there are no special nor tier prices applied.

I’ve checked price attribute values in database, all prices are save correctly per-website. Checking the price index table, though, returns correct min_price and max_price for simple products but prices from the wrong website for the configurable products, which is causing the “as low as” issue in product listing pages.

No 3rd-party modules are affecting indexing (vanilla Magento).

Preconditions

  1. Magento version CE 2.1.0 (or previous), not tested with more recent versions at the moment.

Steps to reproduce

  1. Install vanilla Magento 2.1.0 CE
  2. Create a second website, store and store view
  3. Configure price scope to be per-website
  4. Create a configurable product, to be in both websites, with price 55.55 for website 1 (default) and price 77.77 for website 2 (non-default), set all prices for the children simple products to 55.55 for website 1 and to 77.77 for website 2, enable the product, make it visible in catalog and search, assign to at least one category and save;
  5. Perform a full reindex

Expected result

Prices should be shown as 55.55 in website 1 (store 1, default) and 77.77 in website 2 (store 2, non-default), in category page containing the product. No “as low as” prices is supposed to be shown.

Actual result

  1. Navigate to product listing (category) page containing the product just added in default store (default website 1), you’ll see the price stated as 55.55;
  2. Switch store to store 2 (website 2), navigate to product listing (category) page in store 2 (website 2), you will see the price stated as 77.77 (as low as 55.55) even though you have not defined any promotions, tier prices or discounts and all simple children products have price of 77.77 in website 2. Select in database from catalog_product_index_price table for website_id IN (1,2) AND entity_id IN (1,2,3), where 1,2,3 are the IDs of the configurable product and its two children simple products. You should always see 55.55 for website 1 and 77.77 for website 2, in all price, min_price, max_price columns, instead you’ll see 55.00 in min_price for website 2.

Cause

In vendor/magento/module-configurable-product/Model/ResourceModel/Product/Indexer/Price/Configurable.php, line 192:

$priceColumn = $this->_addAttributeToSelect($select, 'price', 'l.product_id', 0, null, true);

The fourth parameter to Magento\Catalog\Api\Data\ProductInterface\AbstractIndexer::_addAttributeToSelect() is supposed to the the store_id for the (non-default) price to join from the attribute “decimal” value table, instead Magento passes the hard-coded “0”, which is causing default store (website) prices to be put in product price index for configurable products, regardless to the website_id.

Proposed solution

Replace line 192 mentioned above with the following:

$select->join(
    ['sg' => $this->getTable('store_group')],
    'sg.website_id = i.website_id',
    []
);
$priceColumn = $this->_addAttributeToSelect($select, 'price', 'l.product_id', 'sg.default_store_id', null, true);

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 2
  • Comments: 59 (20 by maintainers)

Most upvoted comments

Guys, I hate to underline the obvious, but if the bug was discovered on 2.1.x and then reportedly “fixed”, it is commonly expected to see that fix in the closest patch (2.1.x) release. I was about to write more about that, but then I realized Magento Inc. just happens to have a different vision: they expect to see community contributors involved into backporting while their own priorities are elsewhere. That’s fine, if you ask me. But until that changes, maybe we could at least have some honest responses here?

IMHO if the bugfix is not released yet, the phrasing should look like the following:

Hey you all, here’s a piece of code that fixes this bug: <insert commit hash(es) here>. Well, no, we can’t tell when the next version will be released and whether this patch will be included. Actually, we have to admit: there is a high probability that we won’t release it anytime soon. So, you know, until then… just select one of these marvelous options we offer you in the meantime (using those, you’ll have the bug fixed exclusively for you in hours or days, and not months):

  • patch the core files according to the commits referenced (not recommended because you’ll lose the edits once you update the Magento to the next released version, so… just repeat that after every upgrade until the fix finds its way into a release)
  • fork the repository, and cherry-pick these commits into your local 2.1 branch and use that instead of composer-installed version we released earlier (not recommended if you don’t plan to contribute to the project, so… just do a merge from main repository and resolve some conflicts after each release, no biggie. And while you’re at it, could you please also make a pull request pointing back into 2.1-develop of our repository? That’d be great)
  • read all the devdocs and write a module that’ll do these changes “the right way” using all those shiny extends and overrides and plugins and observers and so on (requires some development skills, so if you’re a merchant… just call your friendly neighborhood developer guy to do it for you)

Hey, I just thought of something that could be included along with all those “Known Issues” into the release notes: “Known workarounds and how to use them”. That’d be great. Right?

in 2.2 issue still present. @surabhinsi fix works

protected function _applyConfigurableOption()
...
        $select->columns(
            [
                'min_price' => new \Zend_Db_Expr('io.min_price'),
                'max_price' => new \Zend_Db_Expr('io.max_price'),
                'tier_price' => 'io.tier_price',
                /*'min_price' => new \Zend_Db_Expr('i.min_price - i.orig_price + io.min_price'),
                'max_price' => new \Zend_Db_Expr('i.max_price - i.orig_price + io.max_price'),
                'tier_price' => 'io.tier_price',*/
            ]
        );
...

I have done the changes in vendor/magento/module-configurable-product/Model/ResourceModel/Product/Indexer/Price/Configurable.php and it is working now in Magento 2.1.8 Attached is the file Configurable.docx

This is still an issue in 2.3.0.

Even after removing pricing from the catalog_product_entity_decimal table, the reindex that occurs every few minutes powered by the catalog_product_price_cl table still wrongly sets the min_price to 0 in the price index.

As a hotfix I’ve changed line 221 of Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\Query\BaseFinalPrice from :

$select->where(sprintf('e.entity_id BETWEEN %s AND %s', min($entityIds), max($entityIds)));

To

$select->where('e.entity_id IN (?)', $entityIds);

I don’t understand the pricing indexer super well, but it looks as though on line 200 of Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price\Configurable, the WHERE clause is using an IN. So if the previous query was using a BETWEEN, there could potentially be 1000’s of rows without a result.

This issue is not fixed. The cause for the negative pricing is because data imported from M1 probably has prices set on configurable products in the catalog_product_entity_decimal table. That is what causes the negative prices. You need to remove pricing for all configurable products from that table and then reindex. In M2 you can’t set prices on configurable products, you could do that in M1.

For this issue to be fixed code should either clean data in the data migration tool or the indexer should be changed to disregard the deprecated data, then the issue will be fixed.

Why topic closed?

I’m reopening this since there are multiple users reporting that the issue is still present.

Hi @kervin, I’ve tried that already. It doesn’t actually work for me.

When I do a full reindex it works fine, however when the partial reindex runs every few minutes. It sets all of the min_prices to 0 in the index table.

Somebody has detailed the problem I’m having in this post: https://magento.stackexchange.com/questions/242801/magento-2-2-6-possible-problems#answer-244821

Cheers

Going from Magento 2.2.3 to Magento 2.2.6. In Magento 2.2.3 the table catalog_product_index_price shows correct price, final_price, min_price, max_price and tier_price. In Magento 2.2.6 min_price and max_price are set to 0 and tier_priceto null.

This issue reappeared in 2.2.6. The old solution doesn’t work anymore.

+1, image After reindex, some configurable products prices become negative. Values are random. This is causing lot of issues in price sorting. Re-index don’t help.