From 2c01541de13385b3e41a03b712f940e31220defb Mon Sep 17 00:00:00 2001 From: Dmitry Astapov Date: Sun, 24 Apr 2011 22:10:33 +0000 Subject: [PATCH] Fix for auto-balancing transactions which have negative amount in the first posting --- hledger-lib/Hledger/Data/Transaction.hs | 9 +++++---- hledger-lib/Hledger/Data/Types.hs | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/hledger-lib/Hledger/Data/Transaction.hs b/hledger-lib/Hledger/Data/Transaction.hs index 8d831a67c..e7215c838 100644 --- a/hledger-lib/Hledger/Data/Transaction.hs +++ b/hledger-lib/Hledger/Data/Transaction.hs @@ -189,9 +189,10 @@ balanceTransaction canonicalcommoditymap t@Transaction{tpostings=ps} where conversionprice c | c == unpricedcommodity -- assign a balancing price. Use @@ for more exact output when possible. + -- invariant: prices should always be positive. Enforced with "abs" = if length ramountsinunpricedcommodity == 1 - then Just $ TotalPrice $ Mixed [setAmountPrecision maxprecision $ negate $ targetcommodityamount] - else Just $ UnitPrice $ Mixed [setAmountPrecision maxprecision $ negate $ targetcommodityamount `divideAmount` (quantity unpricedamount)] + then Just $ TotalPrice $ Mixed [setAmountPrecision maxprecision $ abs $ targetcommodityamount] + else Just $ UnitPrice $ Mixed [setAmountPrecision maxprecision $ abs $ targetcommodityamount `divideAmount` (quantity unpricedamount)] | otherwise = Nothing where unpricedcommodity = head $ filter (`elem` (map commodity rsumamounts)) rcommoditiesinorder @@ -214,8 +215,8 @@ balanceTransaction canonicalcommoditymap t@Transaction{tpostings=ps} where conversionprice c | c == unpricedcommodity = if length bvamountsinunpricedcommodity == 1 - then Just $ TotalPrice $ Mixed [setAmountPrecision maxprecision $ negate $ targetcommodityamount] - else Just $ UnitPrice $ Mixed [setAmountPrecision maxprecision $ negate $ targetcommodityamount `divideAmount` (quantity unpricedamount)] + then Just $ TotalPrice $ Mixed [setAmountPrecision maxprecision $ abs $ targetcommodityamount] + else Just $ UnitPrice $ Mixed [setAmountPrecision maxprecision $ abs $ targetcommodityamount `divideAmount` (quantity unpricedamount)] | otherwise = Nothing where unpricedcommodity = head $ filter (`elem` (map commodity bvsumamounts)) bvcommoditiesinorder diff --git a/hledger-lib/Hledger/Data/Types.hs b/hledger-lib/Hledger/Data/Types.hs index a924fe3cc..8a2064fe5 100644 --- a/hledger-lib/Hledger/Data/Types.hs +++ b/hledger-lib/Hledger/Data/Types.hs @@ -71,7 +71,8 @@ data Commodity = Commodity { -- | An amount's price may be written as \@ unit price or \@\@ total price. -- Note although Price has a MixedAmount, it should hold only --- single-commodity amounts, cf costOfAmount. +-- single-commodity amounts, cf costOfAmount. Moreover, price should always +-- be positive, though it is currently not enforced. data Price = UnitPrice MixedAmount | TotalPrice MixedAmount deriving (Eq,Ord)