register: be better at showing empty intervals with --empty and a query pattern

This commit is contained in:
Simon Michael 2011-09-23 00:09:39 +00:00
parent 4a7b3b9b74
commit c22e4e85d0
4 changed files with 103 additions and 61 deletions

View File

@ -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)

View File

@ -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

View 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

View File

@ -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