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.
This commit is contained in:
Stephen Morgan 2022-07-08 22:36:56 +10:00 committed by Simon Michael
parent dd14f9c822
commit 3e60e784f3
2 changed files with 27 additions and 17 deletions

View File

@ -315,20 +315,22 @@ calculateReportMatrix rspec@ReportSpec{_rsReportOpts=ropts} j priceoracle startb
-- The valued row amounts to be displayed: per-period changes, -- The valued row amounts to be displayed: per-period changes,
-- zero-based cumulative totals, or -- zero-based cumulative totals, or
-- starting-balance-based historical balances. -- starting-balance-based historical balances.
rowbals name changes = dbg5 "rowbals" $ case balanceaccum_ ropts of rowbals name unvaluedChanges = dbg5 "rowbals" $ case balanceaccum_ ropts of
PerPeriod -> changeamts PerPeriod -> changes
Cumulative -> cumulative Cumulative -> cumulative
Historical -> historical Historical -> historical
where where
-- changes to report on: usually just the changes itself, but use the -- changes to report on: usually just the valued changes themselves, but use the
-- differences in the historical amount for ValueChangeReports. -- differences in the valued historical amount for CalcValueChange and CalcGain.
changeamts = case balancecalc_ ropts of changes = case balancecalc_ ropts of
CalcChange -> M.mapWithKey avalue changes CalcChange -> M.mapWithKey avalue unvaluedChanges
CalcBudget -> M.mapWithKey avalue changes CalcBudget -> M.mapWithKey avalue unvaluedChanges
CalcValueChange -> periodChanges valuedStart historical CalcValueChange -> periodChanges valuedStart historical
CalcGain -> periodChanges valuedStart historical CalcGain -> periodChanges valuedStart historical
cumulative = cumulativeSum avalue nullacct changeamts -- the historical balance is the valued cumulative sum of all unvalued changes
historical = cumulativeSum avalue startingBalance 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 startingBalance = HM.lookupDefault nullacct name startbals
valuedStart = avalue (DateSpan Nothing historicalDate) startingBalance valuedStart = avalue (DateSpan Nothing historicalDate) startingBalance
@ -580,11 +582,9 @@ periodChanges start amtmap =
M.fromDistinctAscList . zip dates $ zipWith subtractAcct amts (start:amts) M.fromDistinctAscList . zip dates $ zipWith subtractAcct amts (start:amts)
where (dates, amts) = unzip $ M.toAscList amtmap where (dates, amts) = unzip $ M.toAscList amtmap
-- | Calculate a cumulative sum from a list of period changes and a valuation -- | Calculate a cumulative sum from a list of period changes.
-- function. cumulativeSum :: Account -> Map DateSpan Account -> Map DateSpan Account
cumulativeSum :: (DateSpan -> Account -> Account) -> Account -> Map DateSpan Account -> Map DateSpan Account cumulativeSum start = snd . M.mapAccum (\a b -> let s = sumAcct a b in (s, s)) start
cumulativeSum value start = snd . M.mapAccumWithKey accumValued start
where accumValued startAmt date newAmt = let s = sumAcct startAmt newAmt in (s, value date s)
-- | Given a table representing a multi-column balance report (for example, -- | Given a table representing a multi-column balance report (for example,
-- made using 'balanceReportAsTable'), render it in a format suitable for -- made using 'balanceReportAsTable'), render it in a format suitable for

View File

@ -49,7 +49,17 @@ Historical gain in 2000-01-01..2000-02-29, valued at period ends:
assets:new || -1 A 0 assets:new || -1 A 0
assets:old || 0 2 A 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 $ 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: 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:b || 0 -15 A
assets:old || 2 A 0 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 $ hledger -f- bal -M --gain --no-total --value=2000-02-01 -b 2000 --historical
Historical gain in 2000-01, valued at 2000-02-01: 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:b || -15 A
assets:old || 2 A assets:old || 2 A
# 6. also works in balancesheet # 7. also works in balancesheet
$ hledger -f- bs -M --gain --no-total $ hledger -f- bs -M --gain --no-total
Balance Sheet 1999-12-31..2000-02-29 (Historical Gain), valued at period ends Balance Sheet 1999-12-31..2000-02-29 (Historical Gain), valued at period ends