Skip to content

Commit

Permalink
assert only a single commodity, like Ledger (fixes #195)
Browse files Browse the repository at this point in the history
This change means you can make assertions on a multi-commodity account
balance (asserting one commodity at a time). On the flip side, you can
no longer assert the complete balance of an account (new unexpected
commodities will not be detected.) We might restore that ability later,
using the == syntax.
  • Loading branch information
simonmichael committed Jul 2, 2014
1 parent 0c3148a commit 8ae303f
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 13 deletions.
5 changes: 5 additions & 0 deletions hledger-lib/Hledger/Data/Amount.hs
Expand Up @@ -74,6 +74,7 @@ module Hledger.Data.Amount (
missingmixedamt,
mixed,
amounts,
filterMixedAmount,
normaliseMixedAmountPreservingFirstPrice,
normaliseMixedAmountPreservingPrices,
-- ** arithmetic
Expand Down Expand Up @@ -419,6 +420,10 @@ sumAmountsUsingFirstPrice as = (sum as){aprice=aprice $ head as}
amounts :: MixedAmount -> [Amount]
amounts (Mixed as) = as

-- | Filter a mixed amount's component amounts by a predicate.
filterMixedAmount :: (Amount -> Bool) -> MixedAmount -> MixedAmount
filterMixedAmount p (Mixed as) = Mixed $ filter p as

-- | Convert a mixed amount's component amounts to the commodity of their
-- assigned price, if any.
costOfMixedAmount :: MixedAmount -> MixedAmount
Expand Down
26 changes: 14 additions & 12 deletions hledger-lib/Hledger/Data/Journal.hs
Expand Up @@ -59,6 +59,7 @@ import Data.List
-- import Data.Map (findWithDefault)
import Data.Maybe
import Data.Ord
import Safe (headMay)
import Data.Time.Calendar
import Data.Time.LocalTime
import Data.Tree
Expand Down Expand Up @@ -427,28 +428,29 @@ checkBalanceAssertionsForAccount ps
-- If it does, return the new balance, otherwise add an error to the
-- error list. Intended to be called from a fold.
checkBalanceAssertion :: ([String],MixedAmount) -> [Posting] -> ([String],MixedAmount)
checkBalanceAssertion (errs,bal) ps
| null ps = (errs,bal)
| isNothing assertion = (errs,bal)
checkBalanceAssertion (errs,startbal) ps
| null ps = (errs,startbal)
| isNothing assertion = (errs,startbal)
|
-- bal' /= assertedbal -- MixedAmount's Eq instance currently gets confused by different precisions
not $ isReallyZeroMixedAmount (bal' - assertedbal)
-- or, compare only the balance of that commodity, like Ledger
-- not $ isReallyZeroMixedAmount (filterCommodity () bal' - assertedbal)
= (errs++[err], bal')
| otherwise = (errs,bal')
not $ isReallyZeroMixedAmount (bal - assertedbal) = (errs++[err], bal)
| otherwise = (errs,bal)
where
p = last ps
assertion = pbalanceassertion p
Just assertedbal = assertion
bal' = sum $ [bal] ++ map pamount ps
err = printf "Balance assertion failed for account %s on %s\n%sAfter posting:\n %s\nexpected balance is %s, actual balance was %s."
Just assertedbal = dbg2 "assertedbal" assertion
fullbal = dbg2 "fullbal" $ sum $ [dbg2 "startbal" startbal] ++ map pamount ps
singlebal = dbg2 "singlebal" $
let c = maybe "" acommodity $ headMay $ amounts assertedbal
in filterMixedAmount (\a -> acommodity a == c) fullbal
bal = singlebal -- check single-commodity balance like Ledger; maybe add == FULLBAL later
err = printf "Balance assertion failed for account %s on %s\n%sAfter posting:\n %s\nexpected commodity balance is %s, actual balance was %s."
(paccount p)
(show $ postingDate p)
(maybe "" (("In transaction:\n"++).show) $ ptransaction p)
(show p)
(showMixedAmount assertedbal)
(showMixedAmount bal')
(showMixedAmount singlebal)

-- Given a sequence of postings to a single account, split it into
-- sub-sequences consisting of ordinary postings followed by a single
Expand Down
14 changes: 13 additions & 1 deletion tests/journal/balance-assertions.test
Expand Up @@ -89,7 +89,19 @@ hledgerdev -f - stats
>>>2
>>>=0

# 6. what should happen here ? Currently,
# 6. assertions currently check only a single commodity's balance, like Ledger
hledgerdev -f - stats
<<<
1/2
(a) A1
(a) B1 = A1
(a) 0 = A1
(a) C0 = D0
>>> /Transactions/
>>>2
>>>=0

# 7. what should happen here ? Currently,
# in a, 3.4 EUR @@ $5.6 and -3.4 EUR cancel out (wrong ?)
# in b,
#
Expand Down

0 comments on commit 8ae303f

Please sign in to comment.