journal: clarify balance assertion/display precision more (#941)

This commit is contained in:
Simon Michael 2019-01-06 18:30:43 +00:00
parent 187fcf75ed
commit c331be7f23
3 changed files with 100 additions and 17 deletions

View File

@ -583,16 +583,25 @@ checkBalanceAssertion p@Posting{pbalanceassertion=Just (BalanceAssertion{baamoun
| otherwise = []
checkBalanceAssertion _ _ = Right ()
-- | Does the difference between the asserted balance
-- and (the corresponding part of) the actual balance
-- appear as zero, when rendered to the greater of
-- 1. the standard display precision for the commodity
-- 2. the full precision of the asserted amount ?
-- The posting is used when creating an error message.
checkBalanceAssertionCommodity :: Posting -> Amount -> MixedAmount -> Either String ()
checkBalanceAssertionCommodity p assertedamt actualbal
-- 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
where
diff =
-- traceWith (("diff:"++).showAmountDebug) $
-- traceWith (("asserted:"++).showAmountDebug)
assertedamt -
-- traceWith (("actual:"++).showAmountDebug)
actualbalincommodity
assertedcomm = acommodity assertedamt
actualbalincommodity = fromMaybe nullamt $ find ((== assertedcomm) . acommodity) (amounts actualbal)
diff = assertedamt - actualbalincommodity
diffplus | isNegativeAmount diff == False = "+"
| otherwise = ""
err = printf (unlines

View File

@ -468,10 +468,37 @@ 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:
A commodity directive which limits the display precision, can affect assertions.
In general, hledger balance assertions should pass or fail as you would
expect from visual inspection and manual summing of the amounts shown
in reports and error messages.
More specifically, assertions pass if the difference between asserted
and actual amounts appears to be zero, when rendered to the greater of
the standard display precision and the asserted amount's precision.
Here are some examples of this in action.
Asserting the exact balance:
```journal
commodity $1000.00
2019/01/01
(a) $0.006
2019/01/02
(a) $1.00 = $1.006
; Actual balance: 1.006
; Asserted balence: 1.006
; Difference: 0.000
; Standard & asserted precisions: 2, 3
; Difference rendered: 0.000
; Result: pass
```
Asserting the balance rounded to fewer decimal places:
```journal
commodity $1000.00
@ -480,9 +507,16 @@ commodity $1000.00
2019/01/02
(a) $1.00 = $1.01
; Actual balance: 1.006
; Asserted balence: 1.01
; Difference: 0.004
; Standard & asserted precisions: 2, 2
; Difference rendered: 0.00
; Result: pass
```
The asserted balance is not rounded to display precision. So this assertion fails:
Asserting an inexact balance with too many decimal places (fails):
```journal
commodity $1000.00
@ -490,9 +524,14 @@ commodity $1000.00
(a) $0.006
2019/01/02
(a) $1.00 = $1.007
# calculated: $1.01
# asserted: $1.007 (difference: +$0.001)
(a) $1.00 = $1.0061
; Actual balance: 1.006
; Asserted balence: 1.0061
; Difference: 0.0001
; Standard & asserted precisions: 2, 4
; Difference rendered: 0.0001
; Result: fail
```
## Balance Assignments

View File

@ -366,9 +366,38 @@ hledger -f- stats
>>>2 /unexpected '@'/
>>>=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).
# 21. With a commodity directive limiting the display precision.
# Assertions pass if the difference between asserted and actual amounts
# appears to be zero, when rendered to the greater of the standard
# display precision and the asserted amount's precision.
# Here,
# Actual balance: 1.006
# Asserted balence: 1.006
# Difference: 0.000
# Standard & asserted precisions: 2, 3
# Difference rendered: 0.000
# Result: pass
hledger -f- stats
<<<
commodity $1000.00
2019/01/01
(a) $0.006
2019/01/02
(a) $1.00 = $1.006
>>> /Transactions/
>>>2
>>>=0
# 22. A rounded assertion amount can also pass. Here,
# Actual balance: 1.006
# Asserted balence: 1.01
# Difference: 0.004
# Standard & asserted precisions: 2, 2
# Difference rendered: 0.00
# Result: pass
hledger -f- stats
<<<
commodity $1000.00
@ -383,7 +412,13 @@ commodity $1000.00
>>>2
>>>=0
# 22. The asserted balance is not rounded to display precision.
# 23. A more precise assertion amount can fail. Here,
# Actual balance: 1.006
# Asserted balence: 1.0061
# Difference: 0.0001
# Standard & asserted precisions: 2, 4
# Difference rendered: 0.0001
# Result: fail
hledger -f- stats
<<<
commodity $1000.00
@ -392,8 +427,8 @@ commodity $1000.00
(a) $0.006
2019/01/02
(a) $1.00 = $1.007
(a) $1.00 = $1.0061
>>>
>>>2 /difference: \+\$0\.001/
>>>2 /difference: \+\$0\.0001/
>>>=1