journal: clarify balance assertion/display precision interaction

Surprisingly, balance assertions were checking to maximum precision,
which meant it was possible, with a display-precision-limiting
commodity directive, to have a failing assertion with the error
message showing asserted and actual amounts that looked the same.

Now we round the calculated account balance (but not the asserted
balance) to display precision before comparing. This should ensure
assertions always behave as you would expect from visual inspection.
This commit is contained in:
Simon Michael 2019-01-06 08:30:54 +00:00
parent 72eb48bb29
commit 187fcf75ed
3 changed files with 63 additions and 1 deletions

View File

@ -585,7 +585,9 @@ checkBalanceAssertion _ _ = Right ()
checkBalanceAssertionCommodity :: Posting -> Amount -> MixedAmount -> Either String () checkBalanceAssertionCommodity :: Posting -> Amount -> MixedAmount -> Either String ()
checkBalanceAssertionCommodity p assertedamt actualbal checkBalanceAssertionCommodity p assertedamt actualbal
| isReallyZeroAmount diff = Right () -- this effectively compares the actual balance rounded to display precision (I believe),
-- with the asserted balance as written. See examples in balance assertions manual.
| isZeroAmount diff = Right ()
| True = Left err | True = Left err
where where
assertedcomm = acommodity assertedamt assertedcomm = acommodity assertedamt

View File

@ -466,6 +466,34 @@ Balance assertions are checked against all postings, both real and
[virtual](#virtual-postings). They are not affected by the `--real/-R` [virtual](#virtual-postings). They are not affected by the `--real/-R`
flag or `real:` query. flag or `real:` query.
### Assertions and precision
The calculated account balance is rounded to display precision before checking.
Eg: here the calculated balance is $1.006. The commodity directive causes
users, and balance assertions, to see this rounded to two decimal places, ie $1.01,
so this assertion passes:
```journal
commodity $1000.00
2019/01/01
(a) $0.006
2019/01/02
(a) $1.00 = $1.01
```
The asserted balance is not rounded to display precision. So this assertion fails:
```journal
commodity $1000.00
2019/01/01
(a) $0.006
2019/01/02
(a) $1.00 = $1.007
# calculated: $1.01
# asserted: $1.007 (difference: +$0.001)
```
## Balance Assignments ## Balance Assignments

View File

@ -365,3 +365,35 @@ hledger -f- stats
>>> >>>
>>>2 /unexpected '@'/ >>>2 /unexpected '@'/
>>>=1 >>>=1
# 21. The calculated balance is rounded to display precision before checking.
# Here the calculated balance is $1.005 but users, and balance assertions,
# see it as $1.00 (because the commodity directive set display precision to 2).
hledger -f- stats
<<<
commodity $1000.00
2019/01/01
(a) $0.006
2019/01/02
(a) $1.00 = $1.01
>>> /Transactions/
>>>2
>>>=0
# 22. The asserted balance is not rounded to display precision.
hledger -f- stats
<<<
commodity $1000.00
2019/01/01
(a) $0.006
2019/01/02
(a) $1.00 = $1.007
>>>
>>>2 /difference: \+\$0\.001/
>>>=1