Painfully debugged Magento core code (log all queries and reviewed step-by-step), the issue is 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, for any website_id.
Quick&Dirty Solution:
Replace 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);
with:
$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);
This way, Magento will select the price for non-default websites from the correct associated value for the default store in those websites, instead of statically assigning the default website price to each result.
Don't forget to reindex:
php bin/magento indexer:reindex catalog_product_price
Proper solution:
Create a custom module and overload the
Magento\ConfigurableProduct\Model\ResourceModel\Product\Indexer\Price\Configurable
class with your own modified version (see Quick&Dirty Solution) using DI preference ({your module}/etc/di.xml).
Don't forget to specify that your module depends on Magento_ConfigurableProduct module in your etc/module.xml and composer.json files.
Best Answer
I was able to resolve my problem with below code. I used
saveAttribute
method to save attribute values (price, special price, etc.) which will only save attribute value to database without saving complete product.Reference