<p>Setting the <code>saleAmount</code> in addition to setting the <code>price</code> prevents Craft from applying the sale amount later.</p>

CC BY-SA 4.0
2020-01-18T22:27:04.217Z
2020-01-18T22:27:04.217Z
Sheldon
<p>In your <code>LineItems::EVENT_POPULATE_LINE_ITEM</code> event function, you can do something like this to change the sale amount:</p>

<pre><code>Event::on(LineItems::class, LineItems::EVENT_POPULATE_LINE_ITEM, function(LineItemEvent $e) {
        $orderId = $e-&gt;lineItem-&gt;orderId;
        if ($e-&gt;lineItem-&gt;getOrder()-&gt;getPaymentCurrency() !== 'GBP') {
            $price = $e-&gt;lineItem-&gt;getPurchasable()-&gt;getFieldValues()['priceIn'.ucfirst(strtolower($e-&gt;lineItem-&gt;getOrder()-&gt;getPaymentCurrency()))];
            if ($e-&gt;lineItem-&gt;onSale) {
                $percentageProduct = $e-&gt;lineItem-&gt;getPurchasable()-&gt;getSales()[0]-&gt;applyAmount;
                $e-&gt;lineItem-&gt;saleAmount = $price * ($percentageProduct);
            }
        } else {
            $price = $e-&gt;lineItem-&gt;price;
        }

        $cart = $e-&gt;lineItem-&gt;getOrder();
        $cart-&gt;setPaymentCurrency($e-&gt;lineItem-&gt;getOrder()-&gt;getPaymentCurrency());
        $e-&gt;lineItem-&gt;price = $price;
        $e-&gt;lineItem-&gt;note  = $e-&gt;lineItem-&gt;getOrder()-&gt;getPaymentCurrency();
});
</code></pre>

<p>You might need a different logic depending on the kind of sales you do, % or amount etc, but the above works for me using %.</p>

CC BY-SA 4.0
2020-01-09T04:17:29.190Z
The EVENT_POPULATE_LINE_ITEM event is where I am setting Country B's price for that item. But if sales are applied to that item from within CraftCommerce's control panel, that price is then adjusted using Country A's sales price which results in an incorrect price for Country B.  Your solution doesn't address the problem.
Sheldon
CC BY-SA 4.0
2020-01-09T20:43:55.547Z
It does address it exactly I think? Line 3 I'm pulling the sales %, then I apply it to the currency B price (defined in line 1), and that's my sale amount for currency B.
I've edited my answer to add the whole content of my event if that helps make it clearer. In my code, GBP is my main currency.
Seb
CC BY-SA 4.0
2020-01-11T00:33:45.497Z
Just chipping in here but as I understand Craft re-applies the sale amount (calculated from Currency A) on currency B still (however currency B is calculated). That's the issue... trying to stop Craft from changing that price in the cart, no?
Mike
CC BY-SA 4.0
2020-01-14T19:57:39.560Z
I don't think there is a way to "stop" this behaviour, but you can control it using something like the code above.
If you don't want any sale at all, then it's even simpler, just set the $e->lineItem->saleAmount to 0
Seb
CC BY-SA 4.0
2020-01-07T08:25:49.507Z
2020-01-09T20:44:20.957Z
2020-01-09T20:44:20.957Z
Seb
<p>I am trying to implement flat pricing for Craft (ie. different fixed prices for products, based on the currency).  I have it working thanks to this post (<a href="https://craftcms.stackexchange.com/q/18683">Craft Commerce: Hard code different product prices based on currency?</a>), but where I am having problems is with applying sales.</p>

<p>The site I am working on has different prices for different currencies.  These are fixed prices that are not based on Craft’s built-in exchange rates for different currencies. For example, a product in Currency A has a price of $100, which is stored in the Commerce’s default price field. However, the price for that product in Currency B has a price of $1000 - and that is stored in a custom text field for that product.</p>

<p>When a person orders a product in Currency B, I intervene on the <code>LineItems::EVENT_POPULATE_LINE_ITEM</code> event and manually set the price to Currency B’s price (from the custom text field on that product).  This works except for when there are sales for that product.</p>

<p>If there is a sale which applies a 10% discount to the product, then Currency A’s price would be $90 (reduced by $10). However, when someone ordering with Currency B buys that product (which is $1000), that price gets reduced by only $10 (instead of $100).  So it appears Commerce is calculating the discount based on Currency A’s price of $100 and applying that to whatever is the line item’s price.</p>

<p>I’ve written a method to calculate Currency B’s final sale price based on the discounts applied to Currency A.</p>

<p>However, it seems the sale’s discount is applied again after the populate line item event so even if I use my method to apply and calculate the correct Currency B sale price, Craft still applies the $10 sales discount again.</p>

<p>Is there a way for me to tell Craft not to apply the sale discount and let me do it manually if a product is being ordered in Currency B?</p>

CC BY-SA 4.0
2020-01-03T18:07:16.557Z
This is something we'd like information on as well. We've used Commerce 1 and 2 on ecommerce sites where pricing was set by currency/country (not by a rate from a base currency) and are not certain how we'd handle sale pricing for prices set in custom fields. As an aside, I've been developing ecommerce sites for 25 years and have yet to have a client who prices their products the way Commerce has this set up... it really needs to support flat pricing and/or multiple stores, etc.
Mike
<craft3><plugin-craftcommerce2>
Flat pricing for different currencies with sales
# Flat pricing for different currencies with sales

(Asked by: username_0 on 2020-01-01)

I am trying to implement flat pricing for Craft (ie. different fixed prices for products, based on the currency). I have it working thanks to this post ([Craft Commerce: Hard code different product prices based on currency?](https://craftcms.stackexchange.com/q/18683)), but where I am having problems is with applying sales.

The site I am working on has different prices for different currencies. These are fixed prices that are not based on Craft’s built-in exchange rates for different currencies. For example, a product in Currency A has a price of $100, which is stored in the Commerce’s default price field. However, the price for that product in Currency B has a price of $1000 - and that is stored in a custom text field for that product.

When a person orders a product in Currency B, I intervene on the `LineItems::EVENT_POPULATE_LINE_ITEM` event and manually set the price to Currency B’s price (from the custom text field on that product). This works except for when there are sales for that product.

If there is a sale which applies a 10% discount to the product, then Currency A’s price would be $90 (reduced by $10). However, when someone ordering with Currency B buys that product (which is $1000), that price gets reduced by only $10 (instead of $100). So it appears Commerce is calculating the discount based on Currency A’s price of $100 and applying that to whatever is the line item’s price.

I’ve written a method to calculate Currency B’s final sale price based on the discounts applied to Currency A.

However, it seems the sale’s discount is applied again after the populate line item event so even if I use my method to apply and calculate the correct Currency B sale price, Craft still applies the $10 sales discount again.

Is there a way for me to tell Craft not to apply the sale discount and let me do it manually if a product is being ordered in Currency B?

**Tags:** craft3, plugin-craftcommerce2

> **Comments:**
> **username_1**: This is something we'd like information on as well. We've used Commerce 1 and 2 on ecommerce sites where pricing was set by currency/country (not by a rate from a base currency) and are not certain how we'd handle sale pricing for prices set in custom fields. As an aside, I've been developing ecommerce sites for 25 years and have yet to have a client who prices their products the way Commerce has this set up... it really needs to support flat pricing and/or multiple stores, etc.  

---

## 2 answers

### Answer by username_0 on 2020-01-18. Score: 2 | Accepted answer

Setting the `saleAmount` in addition to setting the `price` prevents Craft from applying the sale amount later.


---

### Answer by username_2 on 2020-01-07. Score: 0

In your LineItems::EVENT_POPULATE_LINE_ITEM event function, you can do something like this to change the sale amount:
Event::on(LineItems::class, LineItems::EVENT_POPULATE_LINE_ITEM, function(LineItemEvent $e) {
        $orderId = $e->lineItem->orderId;
        if ($e->lineItem->getOrder()->getPaymentCurrency() !== 'GBP') {
            $price = $e->lineItem->getPurchasable()->getFieldValues()['priceIn'.ucfirst(strtolower($e->lineItem->getOrder()->getPaymentCurrency()))];
            if ($e->lineItem->onSale) {
                $percentageProduct = $e->lineItem->getPurchasable()->getSales()[0]->applyAmount;
                $e->lineItem->saleAmount = $price * ($percentageProduct);
            }
        } else {
            $price = $e->lineItem->price;
        }

        $cart = $e->lineItem->getOrder();
        $cart->setPaymentCurrency($e->lineItem->getOrder()->getPaymentCurrency());
        $e->lineItem->price = $price;
        $e->lineItem->note  = $e->lineItem->getOrder()->getPaymentCurrency();
});

You might need a different logic depending on the kind of sales you do, % or amount etc, but the above works for me using %.

> **Comments:**
> **username_0**: The EVENT_POPULATE_LINE_ITEM event is where I am setting Country B's price for that item. But if sales are applied to that item from within CraftCommerce's control panel, that price is then adjusted using Country A's sales price which results in an incorrect price for Country B.  Your solution doesn't address the problem.  
> **username_2**: It does address it exactly I think? Line 3 I'm pulling the sales %, then I apply it to the currency B price (defined in line 1), and that's my sale amount for currency B. I've edited my answer to add the whole content of my event if that helps make it clearer. In my code, GBP is my main currency.  
> **username_1**: Just chipping in here but as I understand Craft re-applies the sale amount (calculated from Currency A) on currency B still (however currency B is calculated). That's the issue... trying to stop Craft from changing that price in the cart, no?  
> **username_2**: I don't think there is a way to "stop" this behaviour, but you can control it using something like the code above. If you don't want any sale at all, then it's even simpler, just set the $e->lineItem->saleAmount to 0  

---

