<p>Are you using a custom <a href="https://craftcms.com/docs/commerce/3.x/extend/adjusters.html#designating-an-order-and-line-item" rel="nofollow noreferrer">adjuster</a> for the discount?
If yes, then just use <a href="https://www.php.net/manual/ru/function.round.php" rel="nofollow noreferrer">round()</a> to round up.</p>
<pre><code>...
$num = $adjustment-&gt;amount; // 12.48
$adjustment-&gt;amount = round($num, 1, PHP_ROUND_HALF_UP); // 12.5(or same as 12.50)
...
</code></pre>
<p><strong>UPD</strong>: It looks like I understand what you want. Change the price of the entire order, for example, the total of the current cart (active order)?
In my field of view, I have a bad news because it is not fully implementable.
The main problem is that you cannot simply change the value of the total, for example:</p>
<pre><code>$myOrder-&gt;setTotal(1337.37);
// Or
$myOrder-&gt;total = 1337.37;
$myOrder-&gt;save();
</code></pre>
<p>This is because most of the <a href="https://properties%20of%20the%20order" rel="nofollow noreferrer">properties of the order</a> (element) are <a href="https://i.sstatic.net/1MnAS.png" rel="nofollow noreferrer">only readable</a>.</p>
<p>However, you can change values directly via <strong>Records</strong>.
For example, on an <a href="https://github.com/craftcms/commerce/blob/develop/src/elements/Order.php#L1897" rel="nofollow noreferrer">event after updating/saving an order</a>.</p>
<pre><code>use craft\commerce\elements\Order;
use craft\events\ModelEvent;
use yii\base\Event;
use craft\commerce\records\Order as OrderRecord;

...

Event::on(
    Order::class,
    Order::EVENT_AFTER_SAVE,
    function (ModelEvent $e) {
        $order = $e-&gt;sender;
        if (!$order-&gt;id) {
            return;
        }
        $orderRecord = OrderRecord::findOne($order-&gt;id);
        if (!$orderRecord) {
            throw new Exception('Invalid order ID: ' . $this-&gt;id);
        }

        $orderRecord-&gt;total = '1337.37';
        $lineItems = $orderRecord-&gt;lineItems;
        foreach ($lineItems as $item) {
            $item-&gt;total = 1337.37;
            $item-&gt;subtotal = 1337.37;
            // Change whatever you need via $item-&gt;.... = ...;
            $item-&gt;save();
        }
    }
);
</code></pre>
<p>Unfortunately, for example, a different price will be shown in the admin panel, since it will calculate through the <a href="https://github.com/craftcms/commerce/blob/develop/src/elements/Order.php#L2341" rel="nofollow noreferrer">getTotal()</a> method, i.e. salePrice * qty + discounts/taxes
That is, not everywhere the value is taken <a href="https://i.sstatic.net/HP2CE.png" rel="nofollow noreferrer">directly from the database</a>, however, I think it can still be used in invoices / emails.</p>
<p>And as another option, you can change the output of the cart before the controller sends the data in JSON format.</p>
<pre><code>Event::on(
    BaseFrontEndController::class,
    BaseFrontEndController::EVENT_MODIFY_CART_INFO,
    function (Event $e) {
        // $e-&gt;cart mostly useless here since it's Order Element(property-read issue)
        $cartInfo = $e-&gt;cartInfo;
        // Change whatever you need depends on what you get from the cart JSON response 
        $cartInfo['itemTotal'] = 1337.37;
        $cartInfo['storedItemTotal'] = 1337.37;
        // $cartInfo['....'] = ...
        // ...
        $e-&gt;cartInfo = $cartInfo;

        return $e;
    }
);
</code></pre>
<p>In general, I recommend that you look at the <a href="https://craftcms.com/docs/commerce/3.x/extend/events.html#event-code-generator" rel="nofollow noreferrer">available events for craft commerce</a>.
Unfortunately, craft commerce is extremely inconvenient at some points, for example, like here, since you cannot easily change the total price of the order.</p>
<p><strong>UPD2</strong>:</p>
<pre><code>use craft\commerce\elements\Order;
use craft\events\ModelEvent;
use yii\base\Event;
use craft\commerce\records\OrderAdjustment as OrderAdjustmentRecorder; 

Event::on(
    Order::class,
    Order::EVENT_AFTER_SAVE,
    function (ModelEvent $e): void {
        $order = $e-&gt;sender;
        if (!$order-&gt;id) {
            return;
        }

        $lineItems = $order-&gt;lineItems;
        foreach ($lineItems as $item) {
            $adjustments = $item-&gt;adjustments;
            foreach($adjustments as $adjustment) {
                // !!! Change your DISCOUNT NAME here
                if ($adjustment['name'] !== 'MY PRODUCTS DISCOUNT NAME') {
                    continue;
                }

                $adjustmentRecord = OrderAdjustmentRecorder::findOne($adjustment-&gt;id);
                if (!$adjustmentRecord) {
                    throw new Exception('Invalid adjustment ID: ' . $adjustment-&gt;id);
                }

                $adjustmentRecord-&gt;amount = round($adjustment-&gt;amount, 1, PHP_ROUND_HALF_UP);
                $adjustmentRecord-&gt;save();
            }
        }
    }
);
</code></pre>

CC BY-SA 4.0
2022-06-01T11:38:05.473Z
thanks, this looks good, but i dont have a custom adjuster. the discount is something custom somebody else made, and i dont see really where the amount i being output. i add code to my question, where i try to adjust the totalCartPrice, together with your answer. Unfortunatly it is not working (my adjuster), the Total Price is not rounded.
Henrik
CC BY-SA 4.0
2022-06-02T07:32:41.640Z
@Henrik i updated my answer for you.
RomanAvr
CC BY-SA 4.0
2022-06-02T07:44:14.427Z
thanks for your profound answer! it sounds like it would be best to alter the discount price. Before i will try your second option with the event. I guess this Event::on would go into a module?
Henrik
CC BY-SA 4.0
2022-06-02T07:45:30.783Z
Exactly.
The event may have been implemented through your own module/plugin.
RomanAvr
CC BY-SA 4.0
2022-06-02T08:36:29.540Z
Having difficulties getting your events running. ...Besides that: you wrote its not possible to change the value of the total. but can i change the itemSubTotal? Meaning: item cost 10€, gets discount of 1.02€, itemSubTotal is now 8.98€, desired rounded itemSubTotal should be 8.95€
Henrik
CC BY-SA 4.0
2022-06-02T08:45:43.963Z
For an element, you can only change the salePrice and just the price.
You can only change others values(like totals,subTotals) through recorders.
RomanAvr
CC BY-SA 4.0
2022-06-02T08:46:01.687Z
Can you provide a code example?
RomanAvr
CC BY-SA 4.0
2022-06-02T08:48:24.263Z
Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/136761/discussion-between-romanavr-and-henrik).
RomanAvr
CC BY-SA 4.0
2022-05-31T11:52:23.667Z
2022-06-02T11:39:13.053Z
2022-06-02T11:39:13.053Z
RomanAvr
<p>i have a 10% Discount for more than 6 items.
With several items i get discounts like 12.48.</p>
<p>How can i round this discount amount, so that this
amount is also applied for the cart total amount?</p>
<p>The amount should rounded to either half or full number.
The example above should give 12.50</p>
<p>another option would be to round the cart total.
i know how to round the amounts for the frontend,
but they wont be passed along for the checkout process.
I the payment gateway, the not rounded price is always used.</p>
<p>Here is code for my custom adjuster, to round the cart Total Price, together with the given answer to round the price.
But its not working, the total price is not rounded:</p>
<pre><code>use craft\commerce\base\AdjusterInterface;
use craft\commerce\elements\Order;
use craft\commerce\models\OrderAdjustment;

class RoundOrderAdjuster implements AdjusterInterface
{

  const ADJUSTMENT_TYPE = 'discount';

  public function adjust(Order $order): array
  {
    $adjustments = [];
    $adjustment = new OrderAdjustment;

    $basePrice = $order-&gt;getTotalPrice();
    $roundAmount = round($basePrice, 1, PHP_ROUND_HALF_UP);

    $adjustment-&gt;amount = $roundAmount;

    $adjustments[] = $adjustment;

    return $adjustments;
  }
}
</code></pre>

<plugin-craftcommerce><discounts><rounding>
how to round Discounts (either half of full number) or total of cart
# how to round Discounts (either half of full number) or total of cart

(Asked by: username_0 on 2022-05-29)

i have a 10% Discount for more than 6 items.
With several items i get discounts like 12.48.
How can i round this discount amount, so that this
amount is also applied for the cart total amount?
The amount should rounded to either half or full number.
The example above should give 12.50
another option would be to round the cart total.
i know how to round the amounts for the frontend,
but they wont be passed along for the checkout process.
I the payment gateway, the not rounded price is always used.
Here is code for my custom adjuster, to round the cart Total Price, together with the given answer to round the price.
But its not working, the total price is not rounded:
use craft\commerce\base\AdjusterInterface;
use craft\commerce\elements\Order;
use craft\commerce\models\OrderAdjustment;

class RoundOrderAdjuster implements AdjusterInterface
{

  const ADJUSTMENT_TYPE = 'discount';

  public function adjust(Order $order): array
  {
    $adjustments = [];
    $adjustment = new OrderAdjustment;

    $basePrice = $order->getTotalPrice();
    $roundAmount = round($basePrice, 1, PHP_ROUND_HALF_UP);

    $adjustment->amount = $roundAmount;

    $adjustments[] = $adjustment;

    return $adjustments;
  }
}

**Tags:** plugin-craftcommerce, discounts, rounding

---

## 1 answers

### Answer by username_1 on 2022-05-31. Score: 3 | Accepted answer

Are you using a custom adjuster for the discount?
If yes, then just use round() to round up.
...
$num = $adjustment->amount; // 12.48
$adjustment->amount = round($num, 1, PHP_ROUND_HALF_UP); // 12.5(or same as 12.50)
...

UPD: It looks like I understand what you want. Change the price of the entire order, for example, the total of the current cart (active order)?
In my field of view, I have a bad news because it is not fully implementable.
The main problem is that you cannot simply change the value of the total, for example:
$myOrder->setTotal(1337.37);
// Or
$myOrder->total = 1337.37;
$myOrder->save();

This is because most of the properties of the order (element) are only readable.
However, you can change values directly via Records.
For example, on an event after updating/saving an order.
use craft\commerce\elements\Order;
use craft\events\ModelEvent;
use yii\base\Event;
use craft\commerce\records\Order as OrderRecord;

...

Event::on(
    Order::class,
    Order::EVENT_AFTER_SAVE,
    function (ModelEvent $e) {
        $order = $e->sender;
        if (!$order->id) {
            return;
        }
        $orderRecord = OrderRecord::findOne($order->id);
        if (!$orderRecord) {
            throw new Exception('Invalid order ID: ' . $this->id);
        }

        $orderRecord->total = '1337.37';
        $lineItems = $orderRecord->lineItems;
        foreach ($lineItems as $item) {
            $item->total = 1337.37;
            $item->subtotal = 1337.37;
            // Change whatever you need via $item->.... = ...;
            $item->save();
        }
    }
);

Unfortunately, for example, a different price will be shown in the admin panel, since it will calculate through the getTotal() method, i.e. salePrice * qty + discounts/taxes
That is, not everywhere the value is taken directly from the database, however, I think it can still be used in invoices / emails.
And as another option, you can change the output of the cart before the controller sends the data in JSON format.
Event::on(
    BaseFrontEndController::class,
    BaseFrontEndController::EVENT_MODIFY_CART_INFO,
    function (Event $e) {
        // $e->cart mostly useless here since it's Order Element(property-read issue)
        $cartInfo = $e->cartInfo;
        // Change whatever you need depends on what you get from the cart JSON response 
        $cartInfo['itemTotal'] = 1337.37;
        $cartInfo['storedItemTotal'] = 1337.37;
        // $cartInfo['....'] = ...
        // ...
        $e->cartInfo = $cartInfo;

        return $e;
    }
);

In general, I recommend that you look at the available events for craft commerce.
Unfortunately, craft commerce is extremely inconvenient at some points, for example, like here, since you cannot easily change the total price of the order.
UPD2:
use craft\commerce\elements\Order;
use craft\events\ModelEvent;
use yii\base\Event;
use craft\commerce\records\OrderAdjustment as OrderAdjustmentRecorder; 

Event::on(
    Order::class,
    Order::EVENT_AFTER_SAVE,
    function (ModelEvent $e): void {
        $order = $e->sender;
        if (!$order->id) {
            return;
        }

        $lineItems = $order->lineItems;
        foreach ($lineItems as $item) {
            $adjustments = $item->adjustments;
            foreach($adjustments as $adjustment) {
                // !!! Change your DISCOUNT NAME here
                if ($adjustment['name'] !== 'MY PRODUCTS DISCOUNT NAME') {
                    continue;
                }

                $adjustmentRecord = OrderAdjustmentRecorder::findOne($adjustment->id);
                if (!$adjustmentRecord) {
                    throw new Exception('Invalid adjustment ID: ' . $adjustment->id);
                }

                $adjustmentRecord->amount = round($adjustment->amount, 1, PHP_ROUND_HALF_UP);
                $adjustmentRecord->save();
            }
        }
    }
);

> **Comments:**
> **username_0**: thanks, this looks good, but i dont have a custom adjuster. the discount is something custom somebody else made, and i dont see really where the amount i being output. i add code to my question, where i try to adjust the totalCartPrice, together with your answer. Unfortunatly it is not working (my adjuster), the Total Price is not rounded.  
> **username_1**: @Henrik i updated my answer for you.  
> **username_0**: thanks for your profound answer! it sounds like it would be best to alter the discount price. Before i will try your second option with the event. I guess this Event::on would go into a module?  
> **username_1**: Exactly. The event may have been implemented through your own module/plugin.  
> **username_0**: Having difficulties getting your events running. ...Besides that: you wrote its not possible to change the value of the total. but can i change the itemSubTotal? Meaning: item cost 10€, gets discount of 1.02€, itemSubTotal is now 8.98€, desired rounded itemSubTotal should be 8.95€  
> **username_1**: For an element, you can only change the salePrice and just the price. You can only change others values(like totals,subTotals) through recorders.  
> **username_1**: Can you provide a code example?  
> **username_1**: Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/136761/discussion-between-romanavr-and-henrik).  

---

