From 0d6e696699e32f8b7bd14ac4df1baa94be17303b Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Sun, 14 Nov 2010 23:29:04 +0000 Subject: [PATCH] some more tests and fixes for amount & price display precision --- hledger-lib/Hledger/Data/Amount.hs | 18 ++++++++++++++++++ hledger-lib/Hledger/Data/Journal.hs | 5 +++-- hledger-lib/Hledger/Data/Transaction.hs | 10 ---------- tests/precision.test | 20 +++++++++++++++++--- 4 files changed, 38 insertions(+), 15 deletions(-) diff --git a/hledger-lib/Hledger/Data/Amount.hs b/hledger-lib/Hledger/Data/Amount.hs index 016eac5b0..0215ab957 100644 --- a/hledger-lib/Hledger/Data/Amount.hs +++ b/hledger-lib/Hledger/Data/Amount.hs @@ -40,6 +40,9 @@ price-discarding arithmetic which ignores and discards prices. module Hledger.Data.Amount where +import qualified Data.Map as Map +import Data.Map (findWithDefault) + import Hledger.Data.Utils import Hledger.Data.Types import Hledger.Data.Commodity @@ -269,6 +272,21 @@ normaliseMixedAmount (Mixed as) = Mixed as'' | otherwise = nonzeros (zeros,nonzeros) = partition isReallyZeroAmount as +-- | Set a mixed amount's commodity to the canonicalised commodity from +-- the provided commodity map. +canonicaliseMixedAmount :: Maybe (Map.Map String Commodity) -> MixedAmount -> MixedAmount +canonicaliseMixedAmount canonicalcommoditymap (Mixed as) = Mixed $ map (canonicaliseAmount canonicalcommoditymap) as + +-- | Set an amount's commodity to the canonicalised commodity from +-- the provided commodity map. +canonicaliseAmount :: Maybe (Map.Map String Commodity) -> Amount -> Amount +canonicaliseAmount Nothing = id +canonicaliseAmount (Just canonicalcommoditymap) = fixamount + where + -- like journalCanonicaliseAmounts + fixamount a@Amount{commodity=c} = a{commodity=fixcommodity c} + fixcommodity c@Commodity{symbol=s} = findWithDefault c s canonicalcommoditymap + -- various sum variants.. sumAmountsDiscardingPrice [] = nullamt diff --git a/hledger-lib/Hledger/Data/Journal.hs b/hledger-lib/Hledger/Data/Journal.hs index 8c14ea1e9..8717dab87 100644 --- a/hledger-lib/Hledger/Data/Journal.hs +++ b/hledger-lib/Hledger/Data/Journal.hs @@ -254,7 +254,7 @@ journalCanonicaliseAmounts j@Journal{jtxns=ts} = j{jtxns=map fixtransaction ts} fixtransaction t@Transaction{tpostings=ps} = t{tpostings=map fixposting ps} fixposting p@Posting{pamount=a} = p{pamount=fixmixedamount a} fixmixedamount (Mixed as) = Mixed $ map fixamount as - fixamount a@Amount{commodity=c,price=p} = a{commodity=fixcommodity c, price=maybe Nothing (Just . fixmixedamount) p} + fixamount a@Amount{commodity=c} = a{commodity=fixcommodity c} fixcommodity c@Commodity{symbol=s} = findWithDefault c s canonicalcommoditymap canonicalcommoditymap = journalCanonicalCommodities j @@ -287,10 +287,11 @@ journalCloseTimeLogEntries now j@Journal{jtxns=ts, open_timelog_entries=es} = journalConvertAmountsToCost :: Journal -> Journal journalConvertAmountsToCost j@Journal{jtxns=ts} = j{jtxns=map fixtransaction ts} where + -- similar to journalCanonicaliseAmounts fixtransaction t@Transaction{tpostings=ps} = t{tpostings=map fixposting ps} fixposting p@Posting{pamount=a} = p{pamount=fixmixedamount a} fixmixedamount (Mixed as) = Mixed $ map fixamount as - fixamount = costOfAmount + fixamount = canonicaliseAmount (Just $ journalCanonicalCommodities j) . costOfAmount -- | Get this journal's unique, display-preference-canonicalised commodities, by symbol. journalCanonicalCommodities :: Journal -> Map.Map String Commodity diff --git a/hledger-lib/Hledger/Data/Transaction.hs b/hledger-lib/Hledger/Data/Transaction.hs index 6267f6eaa..123dcf181 100644 --- a/hledger-lib/Hledger/Data/Transaction.hs +++ b/hledger-lib/Hledger/Data/Transaction.hs @@ -9,7 +9,6 @@ plus a date and optional metadata like description and cleared status. module Hledger.Data.Transaction where import qualified Data.Map as Map -import Data.Map (findWithDefault) import Hledger.Data.Utils import Hledger.Data.Types @@ -134,15 +133,6 @@ isTransactionBalanced canonicalcommoditymap t = rsum' = canonicaliseMixedAmount canonicalcommoditymap $ costOfMixedAmount rsum bvsum' = canonicaliseMixedAmount canonicalcommoditymap $ costOfMixedAmount bvsum -canonicaliseMixedAmount :: Maybe (Map.Map String Commodity) -> MixedAmount -> MixedAmount -canonicaliseMixedAmount Nothing = id -canonicaliseMixedAmount (Just canonicalcommoditymap) = fixmixedamount - where - -- like journalCanonicaliseAmounts - fixmixedamount (Mixed as) = Mixed $ map fixamount as - fixamount a@Amount{commodity=c} = a{commodity=fixcommodity c} - fixcommodity c@Commodity{symbol=s} = findWithDefault c s canonicalcommoditymap - -- | Ensure that this entry is balanced, possibly auto-filling a missing -- amount first. We can auto-fill if there is just one non-virtual -- transaction without an amount. The auto-filled balance will be diff --git a/tests/precision.test b/tests/precision.test index 98fa55899..439623c36 100644 --- a/tests/precision.test +++ b/tests/precision.test @@ -14,14 +14,28 @@ bin/hledger -f - print --cost a $1.00 a $-1.00 ->>>2 -# with $'s display precision at 3 or more, this txn should not balance +# and here the price should be printed with its original precision, not +# the canonical display precision +bin/hledger -f - print +<<< +2010/1/1 + a $0.00 + a 1C @ $1.0049 + a +>>> +2010/01/01 + a 0 + a 1C @ $1.0049 + a -1C @ $1.0049 + +# with $'s display precision at 3 or more, this txn should not balance. +# The error message shows the difference with full precision. bin/hledger -f - balance --no-total --cost --empty <<< 2010/1/1 a 1C @ $1.0049 a $-1.000 ->>>2 /off by \$0.005/ +>>>2 /off by \$0.0049/ >>>= 1 # with $'s display precision at 2 or less, this txn should balance bin/hledger -f - balance --no-total --cost --empty