magento2: Multi-Currency not working when setting Custom Prices on adding product to Cart. This occurs on version 2.4.2 and previous versions as well

Preconditions (*)

  1. Magento version 2.4.2.
  2. Clean instance of Magento.
  3. Sample products has been imported.
  4. Two currencies have been defined: dollar and euro.
  5. Dollar is default currency.
  6. One website has been defined with two stores: English(default one) and Spanish store.
  7. A custom module that catches checkout_cart_product_add_after event to set Custom Price according to some specific business logic: https://www.mageplaza.com/devdocs/add-product-to-cart-with-custom-price-magento-2.html

Steps to reproduce (*)

  1. Enter PDP in front-end.
  2. Add product to Cart(dollar currency).
  3. For this product prices has been set(in the code) to 100 dollars.
  4. Product has been added to Cart.
  5. @magento give me 2.4-develop instance - upcoming 2.4.x release

Expected result (*)

  1. Either in mini-cart section or Cart Page the price must be the calculated in the custom module.
  2. For dollar currency the price should be 100 dollars.
  3. For euro currency the price should be 87 euros.

Actual result (*)

  1. For dollar currency the price is 100 dollars.
  2. For euro currency the price is 100 euros.

Please provide Severity assessment for the Issue as Reporter. This information will help during Confirmation and Issue triage processes.

  • [ x] Severity: S0 - Affects critical data or functionality and leaves users without workaround.

Hi @engcom-Alfa. Thank you for working on this issue. In order to make sure that issue has enough information and ready for development, please read and check the following instruction: point_down

* [ ]  1. Verify that issue has all the required information. (**Preconditions**, **Steps to reproduce**, **Expected result**, **Actual result**).DetailsIf the issue has a valid description, the label `Issue: Format is valid` will be added to the issue automatically. Please, edit issue description if needed, until label `Issue: Format is valid` appears.

* [ ]  2. Verify that issue has a meaningful description and provides enough information to reproduce the issue. If the report is valid, add `Issue: Clear Description` label to the issue by yourself.

* [ ]  3. Add `Component: XXXXX` label(s) to the ticket, indicating the components it may be related to.

* [ ]  4. Verify that the issue is reproducible on `2.4-develop` branchDetails- Add the comment `@magento give me 2.4-develop instance` to deploy test instance on Magento infrastructure.  - If the issue is reproducible on `2.4-develop` branch, please, add the label `Reproduced on 2.4.x`.- If the issue is not reproducible, add your comment that issue is not reproducible and close the issue and **_stop verification process here_**!

* [ ]  5. Add label `Issue: Confirmed` once verification is complete.

* [ ]  6. Make sure that automatic system confirms that report has been added to the backlog.

I’d really like to add the labels you require in previous answer but I cant’ find a way to do that over here

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Comments: 33 (8 by maintainers)

Most upvoted comments

[Magento Version 2.4.6]

I faced the same issue while using the above code to add a custom price. I found there is one file where the getCustomPrice() function is called but it is not implemented that’s why we did not get the proper custom price.

Path: /vendor/magento/module-quote/Model/Quote/Item.php

After I solved addtocart event issue there was one more problem because of the currency switcher. I checked the quote_item table and found a difference between normal and custom price values. I created a plugin for it and fixed that issue.

Path: vendor/magento/module-directory/Controller/Currency/SwitchAction.php

I added the whole solution here.

app/code/Msquare/ModuleName/etc/frontend

events.xml

<?xml version="1.0"?>
<!--
/**
 * @category Msquare
 * @package Msquare_CustomPriceFix
 * @author Mahesh Makwana <maheshmakwana588@gmail.com>
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="checkout_cart_product_add_after">
        <observer name="custom_price_add" instance="Msquare\CustomPriceFix\Observer\CustomPrice" />
    </event>
</config>

app/code/Msquare/ModuleName/Observer

CustomPrice.php

<?php
/**
 * @category Msquare
 * @package Msquare_CustomPriceFix
 * @author Mahesh Makwana <maheshmakwana588@gmail.com>
 */
namespace Msquare\CustomPriceFix\Observer;

use Msquare\CustomPriceFix\Helper\Data as DataHelper;
use Magento\Framework\Currency\Data\Currency as CurrencyData;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class CustomPrice implements ObserverInterface
{
    /**
     * @param DataHelper $dataHelper
     */
    public function __construct(
        protected DataHelper $dataHelper
    ) {}

    public function execute(Observer $observer)
    {
        $item = $observer->getEvent()->getData('quote_item');
        $item = ($item->getParentItem() ? $item->getParentItem() : $item);
        $price = 100; //set your price here

        $curentCurrency = $this->dataHelper->getCurrentCurrency();
        $baseCurrency = $this->dataHelper->getBaseCurrency();
        if ($curentCurrency != $baseCurrency) {
            $currencyObj = $this->dataHelper->getCurrencyFactory();
            $rate = $currencyObj->load($baseCurrency)->getAnyRate($curentCurrency);
            $price *= $rate;
            $price = (float) $currencyObj->format($price, ['display' => CurrencyData::NO_SYMBOL], false);
        }

        $item->setCustomPrice($price);
        $item->setOriginalCustomPrice($price);
        $item->getProduct()->setIsSuperMode(true);
    }

}

app/code/Msquare/ModuleName/Helper

Data.php

<?php
/**
 * @category Msquare
 * @package Msquare_CustomPriceFix
 * @author Mahesh Makwana <maheshmakwana588@gmail.com>
 */
namespace Msquare\CustomPriceFix\Helper;

use Magento\Checkout\Model\CartFactory;
use Magento\Directory\Model\CurrencyFactory;
use Magento\Store\Model\StoreManagerInterface;

class Data
{
    public function __construct(
        protected StoreManagerInterface $storeManager,
        protected CurrencyFactory $currencyFactory,
        protected CartFactory $cartFactory
    ) {}

    /**
     * Get base currency code
     *
     * @return string
     */
    public function getBaseCurrency()
    {
        return $this->storeManager->getStore()->getBaseCurrency()->getCurrencyCode();
    }

    /**
     * Get current currency code
     *
     * @return string
     */
    public function getCurrentCurrency()
    {
        return $this->storeManager->getStore()->getCurrentCurrency()->getCurrencyCode();
    }

    /**
     * Get currency factory
     *
     * @return CurrencyFactory
     */
    public function getCurrencyFactory()
    {
        return $this->currencyFactory->create();
    }

    /**
     * Get cart items
     *
     * @return CartFactory
     */
    public function getCartItems()
    {
        return $this->cartFactory->create()->getQuote()->getAllItems();
    }

}

app/code/Msquare/ModuleName/etc/frontend

di.xml

<?xml version="1.0"?>
<!--
/**
 * @category Msquare
 * @package Msquare_CustomPriceFix
 * @author Mahesh Makwana <maheshmakwana588@gmail.com>
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Directory\Controller\Currency\SwitchAction">
        <plugin name="custom_price_fix"
                type="Msquare\CustomPriceFix\Plugin\Direcotry\Controller\Currency\SwitchAction"
                sortOrder="10"/>
    </type>
</config>

app/code/Msquare/ModuleName/Plugin/Direcotry/Controller/Currency

SwitchAction.php

<?php
/**
 * @category Msquare
 * @package Msquare_CustomPriceFix
 * @author Mahesh Makwana <maheshmakwana588@gmail.com>
 */
namespace Msquare\CustomPriceFix\Plugin\Direcotry\Controller\Currency;

use Msquare\CustomPriceFix\Helper\Data as DataHelper;
use Magento\Directory\Controller\Currency\SwitchAction as SwitchActionParent;
use Magento\Framework\Currency\Data\Currency as CurrencyData;

class SwitchAction
{
    /**
     * @param DataHelper $dataHelper
     */
    public function __construct(
        protected DataHelper $dataHelper
    ) {}

    /**
     * Currency switcher before plugin
     *
     * @param SwitchActionParent $subject
     *
     * @return void
     */
    public function beforeExecute(SwitchActionParent $subject)
    {
        $items = $this->dataHelper->getCartItems();
        $currencyObj = $this->dataHelper->getCurrencyFactory();
        $baseCurrency = $this->dataHelper->getBaseCurrency();
        $newCurrency = (string) $subject->getRequest()->getParam('currency');
        if ($newCurrency != $baseCurrency) {
            /* Update Price for Other Currency */
            $rate = $currencyObj->load($baseCurrency)->getAnyRate($newCurrency);
            foreach ($items as $item) {
                $customPrice = $item->getBasePrice();
                $customPrice *= $rate;
                $customPrice = (float) $currencyObj->format($customPrice, ['display' => CurrencyData::NO_SYMBOL], false);
                $item->setCustomPrice($customPrice);
                $item->setOriginalCustomPrice($customPrice);
                $item->getProduct()->setIsSuperMode(true);
                $item->save();
            }

        } else {
            /* Update Price for Base Currency */
            foreach ($items as $item) {
                $item->setCustomPrice($item->getBasePrice());
                $item->setOriginalCustomPrice($item->getBasePrice());
                $item->getProduct()->setIsSuperMode(true);
                $item->save();
            }
        }
    }
}

Note: Here NO_SYMBOL constant value is 1. You can also add static value. Path: vendor/magento/framework/Currency/Data/Currency.php