From 54ee68976b193aadc024e3318cab362f93654c17 Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Sat, 22 Nov 2008 20:32:58 +0000 Subject: [PATCH] support converting amounts to cost, using their saved price. And do this by default for auto-balancing transactions, as ledger seems to. --- Ledger/Amount.hs | 12 ++++++++++++ Ledger/Entry.hs | 5 +++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Ledger/Amount.hs b/Ledger/Amount.hs index 1843afc7b..ff43cd0ec 100644 --- a/Ledger/Amount.hs +++ b/Ledger/Amount.hs @@ -71,6 +71,14 @@ amountop :: (Double -> Double -> Double) -> Amount -> Amount -> Amount amountop op a@(Amount ac aq ap) b@(Amount bc bq bp) = Amount bc ((quantity $ convertAmountTo bc a) `op` bq) Nothing +-- | Convert an amount to the commodity of its saved price, if any. +costOfAmount :: Amount -> Amount +costOfAmount a@(Amount _ _ Nothing) = a +costOfAmount a@(Amount _ q (Just price)) + | isZeroMixedAmount price = nullamt + | otherwise = Amount pc (pq*q) Nothing + where (Amount pc pq _) = head $ amounts price + -- | Convert an amount to the specified commodity using the appropriate -- exchange rate (which is currently always 1). convertAmountTo :: Commodity -> Amount -> Amount @@ -137,6 +145,10 @@ normaliseMixedAmount (Mixed as) = Mixed $ map sum $ grouped symbols = sort $ nub $ map (symbol . commodity) as hassymbol s a = s == (symbol $ commodity a) +-- | Convert a mixed amount's component amounts to the commodity of their +-- saved price, if any. +costOfMixedAmount :: MixedAmount -> MixedAmount +costOfMixedAmount (Mixed as) = Mixed $ map costOfAmount as -- | The empty simple amount. nullamt :: Amount diff --git a/Ledger/Entry.hs b/Ledger/Entry.hs index eda52d45a..82367cedb 100644 --- a/Ledger/Entry.hs +++ b/Ledger/Entry.hs @@ -76,8 +76,9 @@ isEntryBalanced (Entry {etransactions=ts}) = -- | Fill in a missing balance in this entry, if we have enough -- information to do that. Excluding virtual transactions, there should be -- at most one missing balance. Otherwise, raise an error. +-- The new balance will be converted to cost basis if possible. balanceEntry :: Entry -> Entry -balanceEntry e@(Entry{etransactions=ts}) = e{etransactions=ts'} +balanceEntry e@Entry{etransactions=ts} = e{etransactions=ts'} where (withamounts, missingamounts) = partition hasAmount $ filter isReal ts ts' = case (length missingamounts) of @@ -86,5 +87,5 @@ balanceEntry e@(Entry{etransactions=ts}) = e{etransactions=ts'} otherwise -> error $ "could not balance this entry, too many missing amounts:\n" ++ show e otherstotal = sum $ map tamount withamounts balance t - | isReal t && not (hasAmount t) = t{tamount = -otherstotal} + | isReal t && not (hasAmount t) = t{tamount = costOfMixedAmount (-otherstotal)} | otherwise = t