register: be better at showing empty intervals with --empty and a query pattern
This commit is contained in:
parent
4a7b3b9b74
commit
c22e4e85d0
@ -116,6 +116,20 @@ orDatesFrom (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
|
||||
|
||||
-- | Calculate the intersection of two datespans.
|
||||
spanIntersect (DateSpan b1 e1) (DateSpan b2 e2) = DateSpan b e
|
||||
where
|
||||
b = latest b1 b2
|
||||
e = earliest e1 e2
|
||||
|
||||
latest d Nothing = d
|
||||
latest Nothing d = d
|
||||
latest (Just d1) (Just d2) = Just $ max d1 d2
|
||||
|
||||
earliest d Nothing = d
|
||||
earliest Nothing d = d
|
||||
earliest (Just d1) (Just d2) = Just $ min d1 d2
|
||||
|
||||
-- | Parse a period expression to an Interval and overall DateSpan using
|
||||
-- the provided reference date, or return a parse error.
|
||||
parsePeriodExpr :: Day -> String -> Either ParseError (Interval, DateSpan)
|
||||
|
||||
@ -224,17 +224,28 @@ postingsReport :: ReportOpts -> FilterSpec -> Journal -> PostingsReport
|
||||
postingsReport opts fspec j = (totallabel, postingsReportItems ps nullposting startbal (+))
|
||||
where
|
||||
ps | interval == NoInterval = displayableps
|
||||
| otherwise = summarisePostingsByInterval interval depth empty filterspan displayableps
|
||||
(precedingps, displayableps, _) = postingsMatchingDisplayExpr (display_ opts)
|
||||
| otherwise = summarisePostingsByInterval interval depth empty reportspan displayableps
|
||||
j' = journalSelectingDateFromOpts opts
|
||||
$ journalSelectingAmountFromOpts opts
|
||||
j
|
||||
(precedingps, displayableps, _) = postingsMatchingDisplayExpr (display_ opts)
|
||||
$ depthClipPostings depth
|
||||
$ journalPostings
|
||||
$ filterJournalPostings fspec{depth=Nothing}
|
||||
$ journalSelectingDateFromOpts opts
|
||||
$ journalSelectingAmountFromOpts opts
|
||||
j
|
||||
j'
|
||||
(interval, depth, empty, displayexpr) = (intervalFromOpts opts, depth_ opts, empty_ opts, display_ opts)
|
||||
journalspan = journalDateSpan j'
|
||||
-- requestedspan should be the intersection of any span specified
|
||||
-- with period options and any span specified with display option.
|
||||
-- The latter is not easily available, fake it for now.
|
||||
requestedspan = periodspan `spanIntersect` displayspan
|
||||
periodspan = datespan fspec
|
||||
displayspan = postingsDateSpan ps
|
||||
where (_,ps,_) = postingsMatchingDisplayExpr displayexpr $ journalPostings j'
|
||||
matchedspan = postingsDateSpan displayableps
|
||||
reportspan | empty = requestedspan `orDatesFrom` journalspan
|
||||
| otherwise = requestedspan `spanIntersect` matchedspan
|
||||
startbal = sumPostings precedingps
|
||||
filterspan = datespan fspec
|
||||
(interval, depth, empty) = (intervalFromOpts opts, depth_ opts, empty_ opts)
|
||||
|
||||
totallabel = "Total"
|
||||
balancelabel = "Balance"
|
||||
@ -309,13 +320,10 @@ depthClipPosting (Just d) p@Posting{paccount=a} = p{paccount=clipAccountName d a
|
||||
-- are one per account per interval and aggregated to the specified depth
|
||||
-- if any.
|
||||
summarisePostingsByInterval :: Interval -> Maybe Int -> Bool -> DateSpan -> [Posting] -> [Posting]
|
||||
summarisePostingsByInterval interval depth empty filterspan ps = concatMap summarisespan $ splitSpan interval reportspan
|
||||
summarisePostingsByInterval interval depth empty reportspan ps = concatMap summarisespan $ splitSpan interval reportspan
|
||||
where
|
||||
summarisespan s = summarisePostingsInDateSpan s depth empty (postingsinspan s)
|
||||
postingsinspan s = filter (isPostingInDateSpan s) ps
|
||||
dataspan = postingsDateSpan ps
|
||||
reportspan | empty = filterspan `orDatesFrom` dataspan
|
||||
| otherwise = dataspan
|
||||
|
||||
-- | Given a date span (representing a reporting interval) and a list of
|
||||
-- postings within it: aggregate the postings so there is only one per
|
||||
|
||||
70
tests/register-intervals.test
Normal file
70
tests/register-intervals.test
Normal file
@ -0,0 +1,70 @@
|
||||
# 1. monthly reporting interval, no end dates, shows just the intervals with data:
|
||||
bin/hledger -f- register --period 'monthly'
|
||||
<<<
|
||||
2011/2/1
|
||||
(a) 1
|
||||
>>>
|
||||
2011/02/01 - 2011/02/28 a 1 1
|
||||
>>>=0
|
||||
|
||||
# 2. or with a query pattern, just the intervals with matched data:
|
||||
bin/hledger -f- register --period 'monthly' b
|
||||
<<<
|
||||
2011/1/1
|
||||
(a) 1
|
||||
|
||||
2011/2/1
|
||||
(b) 1
|
||||
>>>
|
||||
2011/02/01 - 2011/02/28 b 1 1
|
||||
>>>=0
|
||||
|
||||
# 3. with --empty, show all intervals spanned by the journal
|
||||
# (unlike current ledger, but more useful)
|
||||
bin/hledger -f- register --period 'monthly' b --empty
|
||||
<<<
|
||||
2011/1/1
|
||||
(a) 1
|
||||
|
||||
2011/2/1
|
||||
(b) 1
|
||||
|
||||
2011/3/1
|
||||
(c) 1
|
||||
>>>
|
||||
2011/01/01 - 2011/01/31 0 0
|
||||
2011/02/01 - 2011/02/28 b 1 1
|
||||
2011/03/01 - 2011/03/31 0 1
|
||||
>>>=0
|
||||
|
||||
# 4. any specified begin/end dates limit the intervals reported
|
||||
bin/hledger -f- register --period 'monthly to 2011/3/1' b --empty
|
||||
<<<
|
||||
2011/1/1
|
||||
(a) 1
|
||||
|
||||
2011/2/1
|
||||
(b) 1
|
||||
|
||||
2011/3/1
|
||||
(c) 1
|
||||
>>>
|
||||
2011/01/01 - 2011/01/31 0 0
|
||||
2011/02/01 - 2011/02/28 b 1 1
|
||||
>>>=0
|
||||
|
||||
# 5. likewise for date-restricting display expressions
|
||||
bin/hledger -f- register --period 'monthly to 2011/2/1' b --empty --display 'd<[2011/2/1]'
|
||||
<<<
|
||||
2011/1/1
|
||||
(a) 1
|
||||
|
||||
2011/2/1
|
||||
(b) 1
|
||||
|
||||
2011/3/1
|
||||
(c) 1
|
||||
>>>
|
||||
2011/01/01 - 2011/01/31 0 0
|
||||
>>>=0
|
||||
|
||||
@ -1,50 +0,0 @@
|
||||
#
|
||||
# monthly reporting interval, no end dates, shows just the intervals with data:
|
||||
bin/hledger -f- register --period 'monthly'
|
||||
<<<
|
||||
2010/2/1 x
|
||||
a 1
|
||||
b
|
||||
>>>
|
||||
2010/02/01 - 2010/02/28 a 1 1
|
||||
b -1 0
|
||||
>>>=0
|
||||
|
||||
#
|
||||
# with --empty, the same:
|
||||
bin/hledger -f- register --period 'monthly' --empty
|
||||
<<<
|
||||
2010/2/1 x
|
||||
a 1
|
||||
b
|
||||
>>>
|
||||
2010/02/01 - 2010/02/28 a 1 1
|
||||
b -1 0
|
||||
>>>=0
|
||||
|
||||
#
|
||||
# with --empty and start/end dates, show all intervals covering the specified period
|
||||
bin/hledger -f- register --period 'monthly from 2010/1/10 to 2010/3/15' --empty
|
||||
<<<
|
||||
2010/2/1 x
|
||||
a 1
|
||||
b
|
||||
>>>
|
||||
2010/01/01 - 2010/01/31 0 0
|
||||
2010/02/01 - 2010/02/28 a 1 1
|
||||
b -1 0
|
||||
2010/03/01 - 2010/03/31 0 0
|
||||
>>>=0
|
||||
|
||||
#
|
||||
# with just one start/end date, get the other from the data
|
||||
bin/hledger -f- register --period 'monthly from 2010/1/10' --empty
|
||||
<<<
|
||||
2010/2/1 x
|
||||
a 1
|
||||
b
|
||||
>>>
|
||||
2010/01/01 - 2010/01/31 0 0
|
||||
2010/02/01 - 2010/02/28 a 1 1
|
||||
b -1 0
|
||||
>>>=0
|
||||
Loading…
Reference in New Issue
Block a user