Rounding issues are an everyday occurrence when creating invoices.
Initial architecture of SoEasy never really addressed the issue well.
This is a technical description of the issues and the solutions.
The Problems of Rounding
There are many problems regarding rounding that are not easy to identify and can be frustrating to users.
This analysis is designed to help us work out the solution for the new version of SoEasy (Gen III).
Unfortunately the solution cannot be implemented in previous versions.
Note: For the purpose of this review, we will use GST to refer to all value added taxes (VAT/GST)
Problem 1: GST Display
SoEasy allows you to sell pre GST or inclusive of GST.
You can specify the setting on a 'customer by customer' basis and an 'Invoice by Invoice' basis.
This means all invoice display screens need to accommodate for the individual setting of each invoice, quotation, and credit note.
Over the years this has become impossible to manage because there are literally 100s of different invoice layout screens and dialogs.
Of course customers only see their own displays and do not realise the complexities of managing the many variations.
In Generation III the solution to the display problem was established through creating the following architecture:
Header Record
The Header File Record stores a value TAXDisplay.FINV and can be either "Inclusive" or "Exclusive".
Note: Non Tax Invoice value would be "NoTax".
This setting influences various other settings on the form occurrence. For example the column heading for the line item total will be influenced by the TAXDisplay setting as will the footer display.
Line Item Displays
- For each line item there are two calculated totals fields; A PreTAX.FINVDTL and IncTAX.FINVDTL fields.
- Then there is a field recognising the desired GST setting; TAXDisplay.FINVDTL (Inc/Exc).
- Finally a non stored calculated field tests the TAXDisplay and populates the required PreTAX or IncTAX value.
Edit of the Header
If a user edits the TAXDisplay.FINV, the process must also go through each line item and update TAXDisplay.FINVDTL and the linked values.
Problem 2: Decimal Place Rounding
The calculation of GST is not a perfect science.
In NZ, 2019, GST is 15% added to the Pre GST value but when working backwards we have to divide by 7.666666666 (recurring) and this front/back calculation causes issues.
The example below shows two scenarios; An Invoice is created GST Inclusive, and GST Exclusive. They should work out to the same values but they do not.
GST Inclusive | GST Exclusive | |||||
QTY | Rate | Total | Qty | Rate | Total | |
1.5 | $65.00 | $97.50 | 1 | $56.52 | $84.78 | |
1.5 | $66.00 | $99.00 | 1.5 | $57.39 | $86.085 | |
1 | $10.00 | $10.00 | 1 | $8.70 | $8.70 | |
Total | $206.50 | Sub Total | $179.565 | |||
GST (divide by 7.666666) | $26.93478 | GST (15%) | $26.93475 | |||
Total | $206.49975 | |||||
No Rounding Required | Rounding Required | .0002 | ||||
Display Without Rounding | $206.50 | Display Without Rounding | $206.49 |
Software tables store to many decimal places and the display can sometimes be random meaning sometimes the display will round and other times it will not.
To resolve the randomness we have a new non stored field called FinalTotal.FINV that always displays the correct rounded total to 2 decimal places.
Problem 3: Currency Rounding
Finally we need to accommodate for the availability of currency. This has been a historical progression issue.
Once upon a time, people paid cash, cheque, credit card, and then came EFTPOS.
When paying by cash people could not pay less than a 5c coin and so currency rounding was required.
BUT you only know if currency rounding is required when the customer identifies they are paying by cash because all other methods of payment can pay any denomination.
Then frequently at POS, customers would use split payment of cash and card.
This is now a very big problem. Do we automatically invoke currency rounding or do we wait for the customer to identify how they are paying?
The scenario is impossible to consider that each transaction will be halted whilst we wait to find out what method of payment the customer thinks they will use, and then the system re-calculates the total.
In the past, this has been how SoEasy operated but as society moves on, it is an unsustainable practice. Or is it?
- Customer paying on account can always pay cents so no rounding on accounts.
- Cash invoices: During the payment process, are asked which method of payment?
- If Cash involved at all, the invoice is rounded
Solution: Generation III automatically adjusts the total to the nearest system settable option of :
Cash Invoices Only, invoke rounding if user not paying by Cash to 0c, 5c, or 10c.