From 3e60e784f327a301d7d25f3a701d8a0c0cb77101 Mon Sep 17 00:00:00 2001 From: Stephen Morgan Date: Fri, 8 Jul 2022 22:36:56 +1000 Subject: [PATCH] fix: bal: Allow cumulative gain and valuechange reports Previously, --cumulative with --gain or --valuechange would produce an empty report. This fixes this issue to produce a reasonable report. --- .../Hledger/Reports/MultiBalanceReport.hs | 28 +++++++++---------- hledger/test/journal/gain.test | 16 +++++++++-- 2 files changed, 27 insertions(+), 17 deletions(-) diff --git a/hledger-lib/Hledger/Reports/MultiBalanceReport.hs b/hledger-lib/Hledger/Reports/MultiBalanceReport.hs index 9da221420..3b61a368c 100644 --- a/hledger-lib/Hledger/Reports/MultiBalanceReport.hs +++ b/hledger-lib/Hledger/Reports/MultiBalanceReport.hs @@ -315,20 +315,22 @@ calculateReportMatrix rspec@ReportSpec{_rsReportOpts=ropts} j priceoracle startb -- The valued row amounts to be displayed: per-period changes, -- zero-based cumulative totals, or -- starting-balance-based historical balances. - rowbals name changes = dbg5 "rowbals" $ case balanceaccum_ ropts of - PerPeriod -> changeamts + rowbals name unvaluedChanges = dbg5 "rowbals" $ case balanceaccum_ ropts of + PerPeriod -> changes Cumulative -> cumulative Historical -> historical where - -- changes to report on: usually just the changes itself, but use the - -- differences in the historical amount for ValueChangeReports. - changeamts = case balancecalc_ ropts of - CalcChange -> M.mapWithKey avalue changes - CalcBudget -> M.mapWithKey avalue changes + -- changes to report on: usually just the valued changes themselves, but use the + -- differences in the valued historical amount for CalcValueChange and CalcGain. + changes = case balancecalc_ ropts of + CalcChange -> M.mapWithKey avalue unvaluedChanges + CalcBudget -> M.mapWithKey avalue unvaluedChanges CalcValueChange -> periodChanges valuedStart historical CalcGain -> periodChanges valuedStart historical - cumulative = cumulativeSum avalue nullacct changeamts - historical = cumulativeSum avalue startingBalance changes + -- the historical balance is the valued cumulative sum of all unvalued changes + historical = M.mapWithKey avalue $ cumulativeSum startingBalance unvaluedChanges + -- since this is a cumulative sum of valued amounts, it should not be valued again + cumulative = cumulativeSum nullacct changes startingBalance = HM.lookupDefault nullacct name startbals valuedStart = avalue (DateSpan Nothing historicalDate) startingBalance @@ -580,11 +582,9 @@ periodChanges start amtmap = M.fromDistinctAscList . zip dates $ zipWith subtractAcct amts (start:amts) where (dates, amts) = unzip $ M.toAscList amtmap --- | Calculate a cumulative sum from a list of period changes and a valuation --- function. -cumulativeSum :: (DateSpan -> Account -> Account) -> Account -> Map DateSpan Account -> Map DateSpan Account -cumulativeSum value start = snd . M.mapAccumWithKey accumValued start - where accumValued startAmt date newAmt = let s = sumAcct startAmt newAmt in (s, value date s) +-- | Calculate a cumulative sum from a list of period changes. +cumulativeSum :: Account -> Map DateSpan Account -> Map DateSpan Account +cumulativeSum start = snd . M.mapAccum (\a b -> let s = sumAcct a b in (s, s)) start -- | Given a table representing a multi-column balance report (for example, -- made using 'balanceReportAsTable'), render it in a format suitable for diff --git a/hledger/test/journal/gain.test b/hledger/test/journal/gain.test index 009afdfef..6ce954150 100644 --- a/hledger/test/journal/gain.test +++ b/hledger/test/journal/gain.test @@ -49,7 +49,17 @@ Historical gain in 2000-01-01..2000-02-29, valued at period ends: assets:new || -1 A 0 assets:old || 0 2 A -# 4. use a different valuation strategy +# 4. cumulative gain report +$ hledger -f- bal -M --gain -b 2000 --no-total --cumulative +Cumulative gain in 2000-01-01..2000-02-29, valued at period ends: + + || 2000-01-31 2000-02-29 +============++======================== + assets:b || -13 A -15 A + assets:new || -1 A 0 + assets:old || 2 A 4 A + +# 5. use a different valuation strategy $ hledger -f- bal -M --gain --no-total --value=2000-02-01 Incremental gain in 1999-12-01..2000-01-31, valued at 2000-02-01: @@ -58,7 +68,7 @@ Incremental gain in 1999-12-01..2000-01-31, valued at 2000-02-01: assets:b || 0 -15 A assets:old || 2 A 0 -# 5. use a different valuation strategy for historical +# 6. use a different valuation strategy for historical $ hledger -f- bal -M --gain --no-total --value=2000-02-01 -b 2000 --historical Historical gain in 2000-01, valued at 2000-02-01: @@ -67,7 +77,7 @@ Historical gain in 2000-01, valued at 2000-02-01: assets:b || -15 A assets:old || 2 A -# 6. also works in balancesheet +# 7. also works in balancesheet $ hledger -f- bs -M --gain --no-total Balance Sheet 1999-12-31..2000-02-29 (Historical Gain), valued at period ends