Logo Customgento

Store-Specific Product Prices Not Working in Magento 2

Petar Simon
07.01.2023
Many stores nowadays support multiple currencies. If you sell your products internationally, then offering the right currency for each region is a nice thing to do. In Magento, you would usually set the default product price on the global level, which also acts as a fallback for every website / store. If you want your prices to be different in a store, then you would need to switch to the respective store view and set the desired price there. But what to do if that does not work?

The Error

We encountered the issue that if we change the price of a product in a specific store view, the price would not change and the “Use default” checkbox was still checked. However, we did not want to use the default price from the global level, but wanted to have a store-specific price.

Debugging

After some debugging, we found out that the product price attributes were defined to be global. You can check this with the following query:

SELECT 
  `is_global` 
FROM 
  `catalog_eav_attribute` 
WHERE 
  `attribute_id` IN (
    SELECT 
      `attribute_id` 
    FROM 
      `eav_attribute` 
    WHERE 
      `frontend_input` = 'price'
  );

The meaning of the returned values can be looked up at Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface:

  • 0 means that the attribute scope is store.
  • 1 means that the attribute scope is global.
  • 2 means that the attribute scope is website.

We expected this to be 2 / website, but it was still 1 / global in our case - even though we configured Stores > Configuration > Catalog > Catalog > Price > Catalog Price Scope (catalog/price/scope) to be “Website”. We saw that we locked this configuration value in app/etc/config.php. After some further debugging, we bumped into the observer Magento\Catalog\Observer\SwitchPriceAttributeScopeOnConfigChange. It is called on each configuration change in the catalog area and sets the scope of the price attributes according to the setting catalog/price/scope. Since we locked this value via bin/magento and did not set it via the administration panel, this observer was never called, so the scope of the price attributes remained global.

Possible Solutions

We came up with multiple ideas to fix this issue:

  1. Simply change an unimportant setting in the catalog section (and revert the change afterwards), so that the observer is called.

  2. Call the observer manually in a REPL console via n98-magerun2.phar dev:console.

  3. Remove the lock from app/etc/config.php and set the desired value via the administration panel.

  4. Change the attribute scope in the database directly via:

    UPDATE 
      `catalog_eav_attribute` 
    SET 
      `is_global` = 2 
    WHERE 
      `attribute_id` IN (
        SELECT 
          `attribute_id` 
        FROM 
          `eav_attribute` 
        WHERE 
          `frontend_input` = 'price'
      );
    

In the end, it does not matter which solution you implement - all these suggestions should fix the issue. Even though this can be considered an edge case, it is a rather poor implementation choice by Adobe / Magento to rely on an observer being called, which is simply not happening if you lock the configuration value with bin/magento config:set --lock-env or --lock-config respectively.