fix: bal: Make sure boring parent accounts in compound balance reports
include historical postings when account declarations have undeclared parents. (#1698)
This commit is contained in:
parent
3b5262e54a
commit
62351dd329
@ -25,7 +25,8 @@ module Hledger.Reports.MultiBalanceReport (
|
|||||||
makeReportQuery,
|
makeReportQuery,
|
||||||
getPostingsByColumn,
|
getPostingsByColumn,
|
||||||
getPostings,
|
getPostings,
|
||||||
startingBalances,
|
startingPostings,
|
||||||
|
startingBalancesFromPostings,
|
||||||
generateMultiBalanceReport,
|
generateMultiBalanceReport,
|
||||||
balanceReportTableAsText,
|
balanceReportTableAsText,
|
||||||
|
|
||||||
@ -121,7 +122,8 @@ multiBalanceReportWith rspec' j priceoracle = report
|
|||||||
|
|
||||||
-- The matched accounts with a starting balance. All of these should appear
|
-- The matched accounts with a starting balance. All of these should appear
|
||||||
-- in the report, even if they have no postings during the report period.
|
-- in the report, even if they have no postings during the report period.
|
||||||
startbals = dbg5 "startbals" $ startingBalances rspec j priceoracle reportspan
|
startbals = dbg5 "startbals" . startingBalancesFromPostings rspec j priceoracle
|
||||||
|
$ startingPostings rspec j priceoracle reportspan
|
||||||
|
|
||||||
-- Generate and postprocess the report, negating balances and taking percentages if needed
|
-- Generate and postprocess the report, negating balances and taking percentages if needed
|
||||||
report = dbg4 "multiBalanceReportWith" $
|
report = dbg4 "multiBalanceReportWith" $
|
||||||
@ -147,9 +149,9 @@ compoundBalanceReportWith rspec' j priceoracle subreportspecs = cbr
|
|||||||
-- Group postings into their columns.
|
-- Group postings into their columns.
|
||||||
colps = dbg5 "colps" $ getPostingsByColumn rspec j priceoracle reportspan
|
colps = dbg5 "colps" $ getPostingsByColumn rspec j priceoracle reportspan
|
||||||
|
|
||||||
-- The matched accounts with a starting balance. All of these should appear
|
-- The matched postings with a starting balance. All of these should appear
|
||||||
-- in the report, even if they have no postings during the report period.
|
-- in the report, even if they have no postings during the report period.
|
||||||
startbals = dbg5 "startbals" $ startingBalances rspec j priceoracle reportspan
|
startps = dbg5 "startps" $ startingPostings rspec j priceoracle reportspan
|
||||||
|
|
||||||
subreports = map generateSubreport subreportspecs
|
subreports = map generateSubreport subreportspecs
|
||||||
where
|
where
|
||||||
@ -163,7 +165,8 @@ compoundBalanceReportWith rspec' j priceoracle subreportspecs = cbr
|
|||||||
where
|
where
|
||||||
-- Filter the column postings according to each subreport
|
-- Filter the column postings according to each subreport
|
||||||
colps' = filter (matchesPosting q) <$> colps
|
colps' = filter (matchesPosting q) <$> colps
|
||||||
startbals' = HM.filterWithKey (\k _ -> matchesAccount q k) startbals
|
-- We need to filter historical postings directly, rather than their accumulated balances. (#1698)
|
||||||
|
startbals' = startingBalancesFromPostings rspec j priceoracle $ filter (matchesPosting q) startps
|
||||||
ropts = cbcsubreportoptions $ _rsReportOpts rspec
|
ropts = cbcsubreportoptions $ _rsReportOpts rspec
|
||||||
q = cbcsubreportquery j
|
q = cbcsubreportquery j
|
||||||
|
|
||||||
@ -180,28 +183,31 @@ compoundBalanceReportWith rspec' j priceoracle subreportspecs = cbr
|
|||||||
|
|
||||||
cbr = CompoundPeriodicReport "" (M.keys colps) subreports overalltotals
|
cbr = CompoundPeriodicReport "" (M.keys colps) subreports overalltotals
|
||||||
|
|
||||||
|
-- | Calculate starting balances from postings, if needed for -H.
|
||||||
|
startingBalancesFromPostings :: ReportSpec -> Journal -> PriceOracle -> [Posting]
|
||||||
|
-> HashMap AccountName Account
|
||||||
|
startingBalancesFromPostings rspec j priceoracle =
|
||||||
|
fmap (M.findWithDefault nullacct emptydatespan)
|
||||||
|
. calculateReportMatrix rspec j priceoracle mempty
|
||||||
|
. M.singleton emptydatespan
|
||||||
|
|
||||||
-- | Calculate starting balances, if needed for -H
|
-- | Postings needed to calculate starting balances.
|
||||||
--
|
--
|
||||||
-- Balances at report start date, from all earlier postings which otherwise match the query.
|
-- Balances at report start date, from all earlier postings which otherwise match the query.
|
||||||
-- These balances are unvalued.
|
-- These balances are unvalued.
|
||||||
-- TODO: Do we want to check whether to bother calculating these? isHistorical
|
-- TODO: Do we want to check whether to bother calculating these? isHistorical
|
||||||
-- and startDate is not nothing, otherwise mempty? This currently gives a
|
-- and startDate is not nothing, otherwise mempty? This currently gives a
|
||||||
-- failure with some totals which are supposed to be 0 being blank.
|
-- failure with some totals which are supposed to be 0 being blank.
|
||||||
startingBalances :: ReportSpec -> Journal -> PriceOracle -> DateSpan -> HashMap AccountName Account
|
startingPostings :: ReportSpec -> Journal -> PriceOracle -> DateSpan -> [Posting]
|
||||||
startingBalances rspec@ReportSpec{_rsQuery=query,_rsReportOpts=ropts} j priceoracle reportspan =
|
startingPostings rspec@ReportSpec{_rsQuery=query,_rsReportOpts=ropts} j priceoracle reportspan =
|
||||||
fmap (M.findWithDefault nullacct precedingspan) acctmap
|
map fst $ getPostings rspec' j priceoracle
|
||||||
where
|
where
|
||||||
acctmap = calculateReportMatrix rspec' j priceoracle mempty
|
|
||||||
. M.singleton precedingspan . map fst $ getPostings rspec' j priceoracle
|
|
||||||
|
|
||||||
rspec' = rspec{_rsQuery=startbalq,_rsReportOpts=ropts'}
|
rspec' = rspec{_rsQuery=startbalq,_rsReportOpts=ropts'}
|
||||||
-- If we're re-valuing every period, we need to have the unvalued start
|
-- If we're re-valuing every period, we need to have the unvalued start
|
||||||
-- balance, so we can do it ourselves later.
|
-- balance, so we can do it ourselves later.
|
||||||
ropts' = case value_ ropts of
|
ropts' = case value_ ropts of
|
||||||
Just (AtEnd _) -> ropts''{value_=Nothing}
|
Just (AtEnd _) -> ropts{period_=precedingperiod, value_=Nothing}
|
||||||
_ -> ropts''
|
_ -> ropts{period_=precedingperiod}
|
||||||
where ropts'' = ropts{period_=precedingperiod, no_elide_=accountlistmode_ ropts == ALTree}
|
|
||||||
|
|
||||||
-- q projected back before the report start date.
|
-- q projected back before the report start date.
|
||||||
-- When there's no report start date, in case there are future txns (the hledger-ui case above),
|
-- When there's no report start date, in case there are future txns (the hledger-ui case above),
|
||||||
|
|||||||
@ -327,3 +327,38 @@ $ hledger -f - balancesheet --tree --output-format=csv --drop 1
|
|||||||
"Liabilities",""
|
"Liabilities",""
|
||||||
"total"
|
"total"
|
||||||
"Net:","$1"
|
"Net:","$1"
|
||||||
|
|
||||||
|
# 14. When declaring account types, we want boring parents to include their
|
||||||
|
# interesting children, including their historical postings. (#1698)
|
||||||
|
<
|
||||||
|
account assets:foobar:reserve ; type: Cash
|
||||||
|
account assets:foobar:current ; type: Cash
|
||||||
|
account assets:receivable:anon ; type: Asset
|
||||||
|
|
||||||
|
2018-12-06
|
||||||
|
assets:foobar:current 1 A
|
||||||
|
expenses:example
|
||||||
|
|
||||||
|
2019-01-04
|
||||||
|
assets:foobar:current 1 A
|
||||||
|
expenses:example
|
||||||
|
|
||||||
|
$ hledger -f - balancesheet --tree --no-elide --begin 2019-01-01
|
||||||
|
Balance Sheet 2019-01-04
|
||||||
|
|
||||||
|
|| 2019-01-04
|
||||||
|
=============++============
|
||||||
|
Assets ||
|
||||||
|
-------------++------------
|
||||||
|
assets || 2 A
|
||||||
|
foobar || 2 A
|
||||||
|
current || 2 A
|
||||||
|
-------------++------------
|
||||||
|
|| 2 A
|
||||||
|
=============++============
|
||||||
|
Liabilities ||
|
||||||
|
-------------++------------
|
||||||
|
-------------++------------
|
||||||
|
||
|
||||||
|
=============++============
|
||||||
|
Net: || 2 A
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user