fix: show historical balances even if report period is empty [#2403]
This adds a safer version of spanDefaultsFrom that won't create spans that end before they start, and updates all reports to use it. The only related change noticed so far is that close now gives an error instead of a malformed entry, when there's no data to close. [#2409]
This commit is contained in:
parent
ca631d9fca
commit
afd18a10bf
@ -63,6 +63,7 @@ module Hledger.Data.Dates (
|
||||
spanIntersect,
|
||||
spansIntersect,
|
||||
spanDefaultsFrom,
|
||||
spanValidDefaultsFrom,
|
||||
spanExtend,
|
||||
spanUnion,
|
||||
spansUnion,
|
||||
@ -348,10 +349,43 @@ spanIntersect (DateSpan b1 e1) (DateSpan b2 e2) = DateSpan (laterDefinite b1 b2)
|
||||
|
||||
-- | Fill any unspecified dates in the first span with the dates from
|
||||
-- the second one (if specified there). Sort of a one-way spanIntersect.
|
||||
-- This one can create an invalid span that'll always be empty.
|
||||
--
|
||||
-- >>> :{
|
||||
-- DateSpan (Just $ Exact $ fromGregorian 2024 1 1) Nothing
|
||||
-- `spanDefaultsFrom`
|
||||
-- DateSpan (Just $ Exact $ fromGregorian 2024 1 1) (Just $ Exact $ fromGregorian 2024 1 2)
|
||||
-- :}
|
||||
-- DateSpan 2024-01-01
|
||||
--
|
||||
-- >>> :{
|
||||
-- DateSpan (Just $ Exact $ fromGregorian 2025 1 1) Nothing
|
||||
-- `spanDefaultsFrom`
|
||||
-- DateSpan (Just $ Exact $ fromGregorian 2024 1 1) (Just $ Exact $ fromGregorian 2024 1 2)
|
||||
-- :}
|
||||
-- DateSpan 2025-01-01..2024-01-01
|
||||
--
|
||||
spanDefaultsFrom :: DateSpan -> DateSpan -> DateSpan
|
||||
spanDefaultsFrom (DateSpan a1 b1) (DateSpan a2 b2) = DateSpan a b
|
||||
where a = if isJust a1 then a1 else a2
|
||||
b = if isJust b1 then b1 else b2
|
||||
|
||||
-- | A smarter version of spanDefaultsFrom that avoids creating invalid
|
||||
-- spans ending before they begin. Kept separate for now to reduce risk.
|
||||
--
|
||||
-- >>> :{
|
||||
-- DateSpan (Just $ Exact $ fromGregorian 2025 1 1) Nothing
|
||||
-- `spanValidDefaultsFrom`
|
||||
-- DateSpan (Just $ Exact $ fromGregorian 2024 1 1) (Just $ Exact $ fromGregorian 2024 1 2)
|
||||
-- :}
|
||||
-- DateSpan 2025-01-01..
|
||||
--
|
||||
spanValidDefaultsFrom :: DateSpan -> DateSpan -> DateSpan
|
||||
spanValidDefaultsFrom s1 s2 =
|
||||
case s1 `spanDefaultsFrom` s2 of
|
||||
DateSpan b e | b >= e -> s1
|
||||
s -> s
|
||||
|
||||
-- | Calculate the union of two datespans.
|
||||
-- If either span is open-ended, the union will be too.
|
||||
--
|
||||
|
||||
@ -215,7 +215,7 @@ runPeriodicTransaction verbosetags PeriodicTransaction{..} requestedspan =
|
||||
alltxnspans = splitSpan adjust ptinterval span'
|
||||
where
|
||||
-- If the PT does not specify start or end dates, we take them from the requestedspan.
|
||||
span' = ptspan `spanDefaultsFrom` requestedspan
|
||||
span' = ptspan `spanValidDefaultsFrom` requestedspan
|
||||
-- Unless the PT specified a start date explicitly, we will adjust the start date to the previous interval boundary.
|
||||
adjust = isNothing $ spanStart span'
|
||||
|
||||
|
||||
@ -390,7 +390,7 @@ generatePeriodicReport makeRow treeAmt flatAmt ropts colspans acct =
|
||||
PeriodicReport colspans (buildAndSort acct) totalsrow
|
||||
where
|
||||
-- Build report rows and sort them
|
||||
buildAndSort = dbg5 "generatePeriodicReport buildAndSort" . case accountlistmode_ ropts of {}
|
||||
buildAndSort = dbg5 "generatePeriodicReport buildAndSort" . case accountlistmode_ ropts of
|
||||
ALTree | sort_amount_ ropts -> buildRows . sortTreeByAmount
|
||||
ALFlat | sort_amount_ ropts -> sortFlatByAmount . buildRows
|
||||
_ -> buildRows . sortAccountTreeByDeclaration
|
||||
|
||||
@ -793,9 +793,8 @@ reportSpanHelper bothdates j ReportSpec{_rsQuery=query, _rsReportOpts=ropts} =
|
||||
pricespan = dbg3 "pricespan" . DateSpan Nothing $ case value_ ropts of
|
||||
Just (AtEnd _) -> fmap (Exact . addDays 1) . maximumMay . map pddate $ jpricedirectives j
|
||||
_ -> Nothing
|
||||
-- If the requested span is open-ended, close it using the journal's start and end dates.
|
||||
-- This can still be the null (open) span if the journal is empty.
|
||||
requestedspan' = dbg3 "requestedspan'" $ requestedspan `spanDefaultsFrom` (journalspan `spanExtend` pricespan)
|
||||
-- If the requested span has open ends, fill those with the journal's start and/or end dates, if possible.
|
||||
requestedspan' = dbg3 "requestedspan'" $ requestedspan `spanValidDefaultsFrom` (journalspan `spanExtend` pricespan)
|
||||
-- The list of interval spans enclosing the requested span.
|
||||
-- This list can be empty if the journal was empty,
|
||||
-- or if hledger-ui has added its special date:-tomorrow to the query
|
||||
|
||||
@ -256,7 +256,7 @@ withJournalCached defaultJournalOverride cliopts cmd = do
|
||||
-- could use 'forecastPeriod') or to the journal end date (as
|
||||
-- forecast transactions are never generated before journal end
|
||||
-- unless specifically requested).
|
||||
Just forecastspan -> forecastspan `spanDefaultsFrom` reportspan_ iopts
|
||||
Just forecastspan -> forecastspan `spanValidDefaultsFrom` reportspan_ iopts
|
||||
-- Read stdin, or if we read it alread, use a cache
|
||||
-- readStdin :: InputOpts -> ExceptT String IO Journal
|
||||
readStdin = do
|
||||
|
||||
@ -232,3 +232,23 @@ Balance changes in 2014-01-10..2014-03-09:
|
||||
explicit report period || 10 0
|
||||
------------------------++------------------------------------------------
|
||||
|| 10 100
|
||||
|
||||
# ** 19. The historical balances are shown here even though the report period contains no postings. (#2403)
|
||||
<
|
||||
2024-01-01
|
||||
(a) 1000
|
||||
|
||||
$ hledger -f - bal -NHY -b 2025
|
||||
Ending balances (historical) in 2025:
|
||||
|
||||
|| 2025-12-31
|
||||
===++============
|
||||
a || 1000
|
||||
|
||||
# ** 20. Without -H, no balance changes are shown here, even with -E.
|
||||
# Should it show zero for each of the pre-report-period accounts ?
|
||||
$ hledger -f - bal -NY -b 2025
|
||||
Balance changes in 2025:
|
||||
|
||||
|| 2025
|
||||
==++======
|
||||
|
||||
@ -235,9 +235,10 @@ $ hledger -f- close
|
||||
>=
|
||||
|
||||
# ** 16. "override the closing date ... by specifying a report period, where last day of the report period will be the closing date"
|
||||
# With no data to close in the period, this is currently giving an error. XXX
|
||||
$ hledger -f- close -e 100000-01-01
|
||||
> /99999-12-31 closing balances/
|
||||
>=
|
||||
>2 /Error: balanceDataPeriodEnds: expected initial span to have an end date/
|
||||
>=1
|
||||
|
||||
# ** 17. close (and print) should add trailing decimal marks when needed to posting amounts and costs.
|
||||
<
|
||||
|
||||
Loading…
Reference in New Issue
Block a user