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
|
where a = if isJust a1 then a1 else a2
|
||||||
b = if isJust b1 then b1 else b2
|
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
|
-- | Parse a period expression to an Interval and overall DateSpan using
|
||||||
-- the provided reference date, or return a parse error.
|
-- the provided reference date, or return a parse error.
|
||||||
parsePeriodExpr :: Day -> String -> Either ParseError (Interval, DateSpan)
|
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 (+))
|
postingsReport opts fspec j = (totallabel, postingsReportItems ps nullposting startbal (+))
|
||||||
where
|
where
|
||||||
ps | interval == NoInterval = displayableps
|
ps | interval == NoInterval = displayableps
|
||||||
| otherwise = summarisePostingsByInterval interval depth empty filterspan displayableps
|
| otherwise = summarisePostingsByInterval interval depth empty reportspan displayableps
|
||||||
|
j' = journalSelectingDateFromOpts opts
|
||||||
|
$ journalSelectingAmountFromOpts opts
|
||||||
|
j
|
||||||
(precedingps, displayableps, _) = postingsMatchingDisplayExpr (display_ opts)
|
(precedingps, displayableps, _) = postingsMatchingDisplayExpr (display_ opts)
|
||||||
$ depthClipPostings depth
|
$ depthClipPostings depth
|
||||||
$ journalPostings
|
$ journalPostings
|
||||||
$ filterJournalPostings fspec{depth=Nothing}
|
$ filterJournalPostings fspec{depth=Nothing}
|
||||||
$ journalSelectingDateFromOpts opts
|
j'
|
||||||
$ journalSelectingAmountFromOpts opts
|
(interval, depth, empty, displayexpr) = (intervalFromOpts opts, depth_ opts, empty_ opts, display_ opts)
|
||||||
j
|
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
|
startbal = sumPostings precedingps
|
||||||
filterspan = datespan fspec
|
|
||||||
(interval, depth, empty) = (intervalFromOpts opts, depth_ opts, empty_ opts)
|
|
||||||
|
|
||||||
totallabel = "Total"
|
totallabel = "Total"
|
||||||
balancelabel = "Balance"
|
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
|
-- are one per account per interval and aggregated to the specified depth
|
||||||
-- if any.
|
-- if any.
|
||||||
summarisePostingsByInterval :: Interval -> Maybe Int -> Bool -> DateSpan -> [Posting] -> [Posting]
|
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
|
where
|
||||||
summarisespan s = summarisePostingsInDateSpan s depth empty (postingsinspan s)
|
summarisespan s = summarisePostingsInDateSpan s depth empty (postingsinspan s)
|
||||||
postingsinspan s = filter (isPostingInDateSpan s) ps
|
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
|
-- | Given a date span (representing a reporting interval) and a list of
|
||||||
-- postings within it: aggregate the postings so there is only one per
|
-- 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