A Somewhat Exact API

Summary

This note explains why the Exact API is not “exact”, provides a background on processing amounts and helps API developers to choose an appropriate approach to work around the deviations.

The Brand “Exact”

The company name “Exact” and it’s logo “=Exact” stress the importance of accuracy in accounting.

Besides being great at addition, subtraction and classification, accuracy is everything in accounting. I recall from my childhood when my mother went through a traditional Ledger Papers for hours to discover the origin of a difference of exactly 1 cent. Just to discover: it was in fact quite a large sum accounted wrong. She was excited about how she finished the challenge and happy because she had found a major problem due this seemingly small inaccuracy.

Exact API is only Somewhat Exact

Most applications of Exact also implement this dedication for accuracy. However, the API system of Exact Online is “somewhat exact”. The amounts you will get through the API only resemble the financial numbers you will find in the application after rounding.

Amounts retrieved through the API are an approximation of the actual amount used.

As a customer today reported his findings on a test version of a new EDI-interface (translated from Dutch):

vatbasemon [VAT base amount]: has now many decimals, please correct number of decimals

Yes, the customer is right. Well, a customer is always right; if a customer has a different opinion from a sales rep, the sales rep needs to listen better and work together with the customer to come to a shared opinion. And yes, we at Invantive should have known better when writing the SQL script for the EDI-interface because we know the amounts are wrong.

Money makes the World Go Round

In the old days, before the Euro, the Neuro and the minibot, we had a lot of currencies within Europe alone. These currencies were initially released in units which simplified daily use such as “1 bread = 1 coin”. However, inflation, and especially hyperinflation by issuing more money than economic growth justified, occurred frequently.

Nowadays there is a lot of talk about countries like Italy and Spain not being sufficiently productive to match their use of money. Before the Euro this was also a problem; each Italian Lira and Spanish Peseta reflected a very small amount before the Euro with frequent market-triggered depreciations and governmental devaluations, whereas other national monetary units had a much larger value. In itself, it is not bad to change the exchange rate of money; it is an artificial something. But the reasons signal the actual problems.

The governmental capacities to issue or revalue money was also (ab)used in Germany. Looking back to the Weimar republic between the two World Wars, we have had the “Papiermark” which was later succeeded by the Reichsmark. A Reichsmark was made equal to 1 trillion Papiermark (10e12 Papiermark). This type hyperinflation from “1 bread = 1 coin” to “1 bread = 10e12 coins” was a signal of deeper problems in Germany, ultimately leading to the electoral success of Hitler and World War II. I can understand from this perspective that especially the German government is very sensitive about monetary financing as for instance currently executed IMHO by the running quantitative easing programs.

Amount Accuracy in Exact Online

Financial accounting systems like Exact Online need to support real-life scenarios as depicted above: an amount is based upon a number with a precision and scale and a monetary unit. Some monetary units have very little monetary value, some don’t. And Exact Online needs to support this to a certain level.

And besides handling monetary units, there is also a need for appropriate precisions and scales. When working at a bank, it is not uncommon to find a traditional calculator with 14 or 16 digits and a triple-zero key for quick entry of large amounts. And when selling high volumes of low-price pieces with a small eco-tax surcharge, you need a lot of digits behind the decimal separator to avoid rounding errors.

Exact Online allows you to enter amounts with 16 digits (probably Exact Online uses a so-called ‘double’ internally for processing and storage and the accuracy is somewhat less), multiplied by an exponent. In the picture below it is visible that rounding errors occur when mixing amounts which span more than 16 digits:

exact-online-precision-bug

It is wise to use significantly smaller amounts in terms of digits to avoid accumulating errors like this. Exact Online doesn’t complain about these rounding errors and silently uses the wrong numbers. But the real-world probability of needing so many digits is limited, although I would feel embarrassed when somebody at a cocktail party would joke “exact is not exact”.

For the precision of the amounts, Exact Online uses settings per currency as shown below:

exact-online-precision

The “Prices” concerns the number of digits behind the decimal separator for sales prices. These precisions are used during entry and display of amounts through the web front-end of Exact Online.

An overview of the price precisions and accounting precisions in use is shown below, with the red grouping on price precision, the red grouping on accounting precision, illustrating a currency with an accounting precision of 3 digits and illustrating a currency with 0 digits accounting precision:

(Guessed) Inner Workings

Based upon the typical rounding errors and the documentation of the API, it seems that Exact Online uses a double for storing and processing amounts.

The double data type is based upon an IEEE standard. Some CPU’s from the old days had an additional arithmetic module which incredibly sped up calculations on values of this type. I have seen use of doubles especially in solutions on Microsoft environments and their use is a relict from the past in my opinion for financial systems with increased CPU power and storage capacity. Doubles are still a great choice for other systems, especially when used by system developers which understand the ramifications of the type. It seems that engineers with a background in electrical engineering can better cope with these limitations than engineers from information science. Well, maybe that’s why IEEE standardized it, ensuring prosperous careers for their members :slight_smile:

Note that the Oracle and Sybase platforms were traditionally strong in banking and this industry doesn’t like rounding errors. These platforms better support an accurate representation of numbers, such as with Binary Coded Decimals, which closely follow the decimal system (a double is based on the binary numeral system). For the future I expect that newly constructed financial systems will more and more restrain from the use of double for storage in favor of a more accurate representation of numbers such as number (BCD), Decimal or Money.

Coping with “Somewhat Exact”

The Exact Online web front-end hides away the (guessed) internal working from a user. However, the API doesn’t hide this and reflects the internal structure. This holds for both the XML as well as REST APIs.

For instance, the unrounded sum of all unrounded amounts of the balance and P&L sheet in a company almost never equals 0.00. Even worse, the rounded sum of all unrounded amounts neither matches 0, but is for instance 0.03. As an API developer you need to round each amount separately and sum them to reconstruct the financial numbers from the web front-end. And since the APIs use a string representation in the decimal numeral system instead of using a matching binary format, transport through the APIs can further reduce accuracy.

The probable cause of this deviation between the application and the APIs is that the APIs don’t consider the financial setup of the companies involved.

At Invantive we’ve chosen so far to not correct the numbers since there is no official documentation on which correction to apply and the deviations are generally small. In some edge cases the deviations can be notable and require changes such as the screenshot above on Exact Online or the error report on an EDI-interface.

It seems that as an API developer there are a number of approaches available in general:

  • Quick-and-dirty: blindly round everything to 2 decimals. This works great when you create software targeting solely companies working fully within the European Union and having no need for additional price precision. The covers well above 95% of all companies in Exact Online.
  • Rewrite: although rewriting amounts provided by the ultimate source is bad practice, it is sometimes better to rewrite every amounts on receipt. Use the price and amount precision of the REST API Currencies for the company to derive the correct amount based upon the currency of the entry.
  • Not-my-problem: exchange data using the unrounded amounts for your users and software applications you are exchanging data with. Manually round when absolutely necessary.

The “Quick-and-dirty” approach has the advantage that it is easy to comprehend and analyze: when an amount is wrong, check whether another amount of rounding should have been applied. Additionally, rounding to two digits in general always leads to the correct amount for individual amounts in currencies such as Andorra Peseta. Even for aggregated amounts rounding to two digits almost always leads to the correct amount.

The “Rewrite” approach should be able to repair the API flaw of showing internal structure, but requires a lot of attention, functional knowledge and might deliver wrong results when the inner workings change. In general, industrial inertia will probably never lead to changed inner working of Exact Online, but there is no 100% guarantee.

The “Not-my-problem” approach has the advantage that rounding problems in general do not surface, the problem remains visible and that there is no risk of an unintentional correction on the amounts as with the other two approaches.

Based upon the properties of the three scenarios at Invantive, the risks and the investments required we have chosen to stick with the “not-my-problem” approach for the near future.