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 = [] | otherwise = []
checkBalanceAssertion _ _ = Right () 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 :: Posting -> Amount -> MixedAmount -> Either String ()
checkBalanceAssertionCommodity p assertedamt actualbal 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 () | isZeroAmount diff = Right ()
| True = Left err | True = Left err
where where
diff =
-- traceWith (("diff:"++).showAmountDebug) $
-- traceWith (("asserted:"++).showAmountDebug)
assertedamt -
-- traceWith (("actual:"++).showAmountDebug)
actualbalincommodity
assertedcomm = acommodity assertedamt assertedcomm = acommodity assertedamt
actualbalincommodity = fromMaybe nullamt $ find ((== assertedcomm) . acommodity) (amounts actualbal) actualbalincommodity = fromMaybe nullamt $ find ((== assertedcomm) . acommodity) (amounts actualbal)
diff = assertedamt - actualbalincommodity
diffplus | isNegativeAmount diff == False = "+" diffplus | isNegativeAmount diff == False = "+"
| otherwise = "" | otherwise = ""
err = printf (unlines err = printf (unlines

View File

@ -468,10 +468,37 @@ flag or `real:` query.
### Assertions and precision ### Assertions and precision
The calculated account balance is rounded to display precision before checking. A commodity directive which limits the display precision, can affect assertions.
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, In general, hledger balance assertions should pass or fail as you would
so this assertion passes: 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 ```journal
commodity $1000.00 commodity $1000.00
@ -480,9 +507,16 @@ commodity $1000.00
2019/01/02 2019/01/02
(a) $1.00 = $1.01 (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 ```journal
commodity $1000.00 commodity $1000.00
@ -490,9 +524,14 @@ commodity $1000.00
(a) $0.006 (a) $0.006
2019/01/02 2019/01/02
(a) $1.00 = $1.007 (a) $1.00 = $1.0061
# calculated: $1.01
# asserted: $1.007 (difference: +$0.001) ; Actual balance: 1.006
; Asserted balence: 1.0061
; Difference: 0.0001
; Standard & asserted precisions: 2, 4
; Difference rendered: 0.0001
; Result: fail
``` ```
## Balance Assignments ## Balance Assignments

View File

@ -366,9 +366,38 @@ hledger -f- stats
>>>2 /unexpected '@'/ >>>2 /unexpected '@'/
>>>=1 >>>=1
# 21. The calculated balance is rounded to display precision before checking. # 21. With a commodity directive limiting the display precision.
# Here the calculated balance is $1.005 but users, and balance assertions, # Assertions pass if the difference between asserted and actual amounts
# see it as $1.00 (because the commodity directive set display precision to 2). # 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 hledger -f- stats
<<< <<<
commodity $1000.00 commodity $1000.00
@ -383,7 +412,13 @@ commodity $1000.00
>>>2 >>>2
>>>=0 >>>=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 hledger -f- stats
<<< <<<
commodity $1000.00 commodity $1000.00
@ -392,8 +427,8 @@ commodity $1000.00
(a) $0.006 (a) $0.006
2019/01/02 2019/01/02
(a) $1.00 = $1.007 (a) $1.00 = $1.0061
>>> >>>
>>>2 /difference: \+\$0\.001/ >>>2 /difference: \+\$0\.0001/
>>>=1 >>>=1