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