diff --git a/hledger-lib/Hledger/Data/Journal.hs b/hledger-lib/Hledger/Data/Journal.hs index 7168d48d7a4..294febc5726 100644 --- a/hledger-lib/Hledger/Data/Journal.hs +++ b/hledger-lib/Hledger/Data/Journal.hs @@ -583,50 +583,53 @@ 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. +-- | Are the asserted balance and the actual balance +-- exactly equal (disregarding display precision) ? +-- The posting is used for creating an error message. checkBalanceAssertionCommodity :: Posting -> Amount -> MixedAmount -> Either String () checkBalanceAssertionCommodity p assertedamt actualbal - | isZeroAmount diff = Right () - | True = Left err + | pass = Right () + | otherwise = Left err where - diff = - -- traceWith (("diff:"++).showAmountDebug) $ + assertedcomm = acommodity assertedamt + actualbalincommodity = fromMaybe nullamt $ find ((== assertedcomm) . acommodity) (amounts actualbal) + pass = + aquantity -- traceWith (("asserted:"++).showAmountDebug) - assertedamt - + assertedamt == + aquantity -- traceWith (("actual:"++).showAmountDebug) actualbalincommodity - assertedcomm = acommodity assertedamt - actualbalincommodity = fromMaybe nullamt $ find ((== assertedcomm) . acommodity) (amounts actualbal) - diffplus | isNegativeAmount diff == False = "+" - | otherwise = "" + diff = aquantity assertedamt - aquantity actualbalincommodity err = printf (unlines - [ "balance assertion error%s", - "after posting:", - "%s", - "balance assertion details:", + [ "balance assertion: %s", + "\nassertion details:", "date: %s", "account: %s", "commodity: %s", - "calculated: %s", - "asserted: %s (difference: %s)" + -- "display precision: %d", + "calculated: %s", -- (at display precision: %s)", + "asserted: %s", -- (at display precision: %s)", + "difference: %s" ]) (case ptransaction p of - Nothing -> ":" -- shouldn't happen - Just t -> printf " in %s:\nin transaction:\n%s" - (showGenericSourcePos pos) (chomp $ showTransaction t) :: String - where pos = baposition $ fromJust $ pbalanceassertion p) - (showPostingLine p) + Nothing -> "?" -- shouldn't happen + Just t -> printf "%s\ntransaction:\n%s" + (showGenericSourcePos pos) + (chomp $ showTransaction t) + :: String + where + pos = baposition $ fromJust $ pbalanceassertion p + ) (showDate $ postingDate p) (T.unpack $ paccount p) -- XXX pack assertedcomm - (showAmount actualbalincommodity) - (showAmount assertedamt) - (diffplus ++ showAmount diff) + -- (asprecision $ astyle actualbalincommodity) -- should be the standard display precision I think + (show $ aquantity actualbalincommodity) + -- (showAmount actualbalincommodity) + (show $ aquantity assertedamt) + -- (showAmount assertedamt) + (show diff) -- | Fill in any missing amounts and check that all journal transactions -- balance and all balance assertions pass, or return an error message. diff --git a/hledger-lib/Hledger/Data/Transaction.hs b/hledger-lib/Hledger/Data/Transaction.hs index 8c758a07b07..7a1fa7e0d49 100644 --- a/hledger-lib/Hledger/Data/Transaction.hs +++ b/hledger-lib/Hledger/Data/Transaction.hs @@ -35,7 +35,7 @@ module Hledger.Data.Transaction ( showTransaction, showTransactionUnelided, showTransactionUnelidedOneLineAmounts, - showPostingLine, + -- showPostingLine, showPostingLines, -- * GenericSourcePos sourceFilePath, @@ -246,14 +246,17 @@ postingAsLines elideamount onelineamounts pstoalignwith p = concat [ case renderCommentLines (pcomment p) of [] -> ("",[]) c:cs -> (c,cs) --- | Show a posting's status, account name and amount on one line. --- Used in balance assertion errors. -showPostingLine p = - indent $ - if pstatus p == Cleared then "* " else "" ++ - showAccountName Nothing (ptype p) (paccount p) ++ - " " ++ - showMixedAmountOneLine (pamount p) +-- | Render a posting, simply. Used in balance assertion errors. +-- showPostingLine p = +-- indent $ +-- if pstatus p == Cleared then "* " else "" ++ -- XXX show ! +-- showAccountName Nothing (ptype p) (paccount p) ++ +-- " " ++ +-- showMixedAmountOneLine (pamount p) ++ +-- assertion +-- where +-- -- XXX extract, handle == +-- assertion = maybe "" ((" = " ++) . showAmountWithZeroCommodity . baamount) $ pbalanceassertion p -- | Render a posting, at the appropriate width for aligning with -- its siblings if any. Used by the rewrite command. diff --git a/hledger-lib/hledger_journal.m4.md b/hledger-lib/hledger_journal.m4.md index 68c2a3683a2..e5bd04491bc 100644 --- a/hledger-lib/hledger_journal.m4.md +++ b/hledger-lib/hledger_journal.m4.md @@ -468,71 +468,11 @@ flag or `real:` query. ### Assertions and precision -A [commodity directive](http://hledger.org/journal.html#declaring-commodities) -which limits the display precision, can affect assertions. - -In general, hledger balance assertions should pass or fail as you would -expect from doing visual inspection and manual arithmetic with the amounts -shown in reports and error messages, ie at display precision. - -More specifically, currently 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 - -2019/01/01 - (a) $0.006 - -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 -``` - -Asserting an inexact balance with too many decimal places (fails): -```journal -commodity $1000.00 - -2019/01/01 - (a) $0.006 - -2019/01/02 - (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 assertions compare the exactly calculated amounts, +which are not always what is shown by reports. +Eg a [commodity directive](http://hledger.org/journal.html#declaring-commodities) +may limit the display precision, but this will not affect balance assertions. +Balance assertion failure messages show exact amounts. ## Balance Assignments diff --git a/tests/journal/balance-assertions.test b/tests/journal/balance-assertions.test index 2a42bbd7410..b9bc08acffb 100755 --- a/tests/journal/balance-assertions.test +++ b/tests/journal/balance-assertions.test @@ -57,7 +57,7 @@ hledger -f - stats b $-1 = $-3 >>> ->>>2 /balance assertion error.*line 11, column 12/ +>>>2 /balance assertion.*line 11, column 12/ >>>=1 # 4. should also work without commodity symbols @@ -335,7 +335,7 @@ hledger -f - stats 2016/1/3 a 0 == $1 ->>>2 /balance assertion error.*line 10, column 15/ +>>>2 /balance assertion.*line 10, column 15/ >>>=1 # 19. Mix different commodities and exact assignments @@ -366,17 +366,7 @@ hledger -f- stats >>>2 /unexpected '@'/ >>>=1 -# 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 +# 21. The exact amounts are compared; display precision does not affect assertions. hledger -f- stats <<< commodity $1000.00 @@ -391,13 +381,7 @@ commodity $1000.00 >>>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 +# 22. This fails hledger -f- stats <<< commodity $1000.00 @@ -408,17 +392,10 @@ commodity $1000.00 2019/01/02 (a) $1.00 = $1.01 ->>> /Transactions/ ->>>2 ->>>=0 +>>>2 /difference: 0\.004/ +>>>=1 -# 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 +# 23. This fails hledger -f- stats <<< commodity $1000.00 @@ -429,6 +406,5 @@ commodity $1000.00 2019/01/02 (a) $1.00 = $1.0061 ->>> ->>>2 /difference: \+\$0\.0001/ +>>>2 /difference: 0\.0001/ >>>=1