Rounding and issuing change in multiple currencies

Yes, I applied a Math.round() to the result, which works, but I think it’s not perfect because you would have to decide if you apply this rounding to each payment method (eg, probably not for card payments). I think it would be more robust to store the true amount taken/given alongside the payment date and exchange rate.

1 Like

I don’t think {CHANGE TOTAL} is listed anywhere as a tag that we can use. I had to use the same equation as you in my recipt template.

It is a tag in the main Ticket Values section, which makes it usable anywhere in the [LAYOUT] section. I was using it before all this currency stuff. But now it does not work (returns 0.00).

That tag is working outside of the Exchange Rate stuff you guys are doing… just fyi. I am using it now.

1 Like

Oh yeah, silly me!

It returns 0.00 for me too.

Yep - This is definitely not a solution, becuase I was just doing some more examples where I used a credit card to pay 1000.00 MXN, but this is what the ticket looks like:

(As you can see the cash amounts are rounded using Math.round(), but since sometimes I would have a fraction for cards I have not rounded it).

@Emre - Do you think it will be possible to store the foreign transaction amount?

Total:                                  $ 485.00
────────────────────────────────────────────────
Payments:
Cash (USD)                                400.00
Visa/Mastercard (1234)
 β”” 1,000.02 @ 21.00 MXN/USD                47.62
Cash (MXN)
 β”” 1,000.00 @ 21.00 MXN/USD                47.62
Total paid                                495.24
────────────────────────────────────────────────
Change:
Cash (USD)                                  5.00
Cash (MXN)                
 β”” 110.00 @ 21.00 MXN/USD                   5.24
Total change                               10.24
════════════════════════════════════════════════

The Payment Values are never stored for Foreign Currencies; The Values are only stored in the (converted) Default Currency.

That said, if you look deeper through the related DB tables, you will find that the original Foreign Currency amount is stored in the [AccountTransactionValues] table, so it is there for the record …

I did a similar example to yours, where I pay exactly 1000 HNL via CC (@23 = 43.478261). The β€œproblem” is that the Ticket Print converts the rounded value of 43.48 USD to HNL, which results in 1000.04 HNL, which we know is β€œincorrect”.

If we look at the [Payments] table in the DB, we see the following (as mentioned, only Default (converted) Currency Amount is stored in this table):

If we use that ^ value (43.478261 (USD)) and reverse the XR (@23), we get the β€œcorrect” value of 1000.000003.

There must be a way to use the non-rounded value as seen in the DB so that we can get a β€œcorrect” value on the Ticket Print for Foreign Currencies. Or maybe we can get the non-converted value stored in that table. (FYI, I have my DB set to 6 decimal places)

@emre, what do you think? Is there a trick we can use in the Template? Or is there something that needs to be done on your end?

P.S. this would probably be helpful in the same manner for the [ChangePayments] table as well.

I had an idea thinking I could β€œtrick” the Template into using non-rounded values, but it does not work.

Here is the problem: Even though the Payment Amount is stored at 6 decimals in the [Payments] Table (on my setup), the Printer Template cannot access that non-rounded value. This is how I tested it:

[PAYMENTS:Credit Card HNL]
<J00>{PAYMENT NAME} [=F('{PAYMENT AMOUNT}','0.000000')+' '+F('{EXCHANGE RATE}','0.000000')]

That ^ produces the following, where you can see the XR is correct, but the Payment Amount is not (it is rounded):

Credit Card HNL 43.480000 0.043478

@emre, can you look at this please?

As the simplest solution I can think I added {EXCHANGE AMOUNT} tag for both templates so you can read exact amount without rounding.

1 Like

That ^ seems to work good, and it is included in PAYMENTS, CHANGES, and Calculations (SERVICES and DISCOUNTS).

I think it may be helpful also to have {PAYMENT TOTAL} tag in Ticket Values section use non-rounded amount, because you can see that value is not correct …

<J00>PAYMENT TOTAL:|(L[=F(TN('{PAYMENT TOTAL}')/TN('{EXCHANGE RATE:HNL}'))]) [=F(TN('{PAYMENT TOTAL}'))]]


P.S. {CHANGE TOTAL} is still returning nothing as well.

1 Like

{PAYMENT TOTAL} just returns the amount saved to database. If it is not correct the amount saved the database is not correct. Can you tell me your values (Exchange rate / Ticket / Payment amounts) so I can test that?

OK Sorry I think I misunderstood that. Let me check it.

First I tested {CHANGE TOTAL} tag and it seems working fine for me.

Hmm while checking ticket based {PAYMENT TOTAL} I thought it might not be a good idea to use it with exchange rate as it might be tendered via multiple currencies. Maybe we should leave it in base currency and show foreign currency payments on payment details.

It might work fine for you. In the past, I used that tag and it worked fine. But after adding in all the Foreign Currency setup, like Change Transactions and Change Payment Types for both currencies, then that tag stopped working.

I think it is a good idea :wink:

The issue here is the same issue that we have with the rounding and conversion in the Payments and Changes sections before you gave us {EXCHANGE AMOUNT}.

The value 43.48 @23 = 1000.04 The problem is that 43.48 is a rounded value to begin with, so dividing by the XR gives incorrect amount. The value it should be using is 43.478261 @23 = 1000.000003 which when rounded becomes the correct amount of 1000.00

I guess what I don’t understand is why Template Tags are using values that are rounded to 2 decimal places? I have my DB set to 6 decimals, so I would expect the Tags to give values at 6 decimals, not at 2 decimals rounded. I assume it is doing this because of β€œlegacy” reasons, and you have hard-coded the tags to round at 2 decimals. I am pushing for you to change that.

It uses Visible Decimal Places setting so users won’t deal with formatting prices manually on printouts.

1 Like

LOL, funny you mention that. Immediately after my last post I had that exact thought: β€œmaybe it is linked to Visible Decimal Places?”

Ok, that makes sense, and probably for most users, that is a good β€œdefault” decision. It saves needing to wrap all the values in [=F('{AMOUNT}','0.00')]

Hmmm… what to do now? I don’t want this, and probably almost nobody want this:

However, what we should be able to do is proper calculations/math in a Printer Template using non-rounded values, and then format them if necessary afterwards.

Maybe I am being too picky? That’s just me? Attention to detail and accuracy? :stuck_out_tongue_winking_eye:

Do you think it would be much trouble to have an option to β€œunlink” the Visible Decimal Places setting from Printer Tags? So that we can still display 2 decimals on screen, but β€œdetach” that setting from Printer Tags and then if needed, we use F() functions.

Perhaps like this?


<J00>PAYMENT TOTAL:|(L[=F(TN('{PAYMENT TOTAL}')/TN('{EXCHANGE RATE:HNL}'),'0.00')]) [=F(TN('{PAYMENT TOTAL}'),'0.00')]
<J00>PAYMENT TOTAL:|(L[=F(TN('{PAYMENT TOTAL}')/TN('{EXCHANGE RATE:HNL}'))]) [=F(TN('{PAYMENT TOTAL}'))]

@emre, any chance we could have the Add Calculation Payment Processor option for β€œApply when fully Tendered” changed to operate off of the Remaining Amount (Balance) rather than the Ticket Total?

Or have an additional switch for β€œApply when BALANCE fully Tendered”

The issue I am having right now is that if I apply a partial Payment (currency does not matter, nor does Payment Type), then when I subsequently apply the remaining Amount using the Payment Type that has this Payment Processor, the Calculation does not fire, because it appears to be checking the Payment amount against the Ticket Total rather than the Balance.

This video shows partial payment in USD, then the remaining amount in HNL. You can see there is no Calculation fired for the HNL Cash Payment Processor to round the Total (as shown above). The amount I expect to be rounded UP from 483 to 490 so that the Change Amount becomes 10 instead of 17 …

Can you please PM me a backup? It should display 490 under HNL flag as soon as you click on currency button.

@QMcKay Do you want it to round always up?

Yes, I think so - at least that has been my intention so far. The idea being that I don’t ever want to lose money. Or if I must lose sometimes, it cannot be very much.

It continues to be a complex subject because there seems to be a tradeoff between being β€œfair” and not losing at the same time. The basic idea I am shooting for is still this:

  • I don’t want HNL 5’s or 1’s in my cash drawer for change so the Ticket must be divisible by 10 when paying in HNL
  • I don’t want USD coins in my cash drawer (5’s and 1’s are ok) so the Ticket must not have any decimals when paying in USD

That means:

  • if they are about to pay in HNL, I need to round to the nearest 10.
  • if they pay in USD, after paying in HNL, I will have decimals, so I need to round to nearest 1.

I continue to struggle with how to make it all work in a β€œfair” manner. But it all seems to depend on which currency is used first, or if only 1 currency is used.

I may need to concede at some point and have HNL 5’s and 1’s. They have the value of USD coins (ie. 1 is approximately a nickel (5c) or USD 0.05). But if I can avoid that I would be happier.