fix!: register: Tighten up spacing around the date in register reports. (#1655)
As a side effect, this changes the Json representation of the PostingsReport. The maybe report end date is now replaced with a maybe period.
This commit is contained in:
		
							parent
							
								
									4b654fff94
								
							
						
					
					
						commit
						06312c353a
					
				| @ -121,6 +121,7 @@ instance ToJSON PeriodicTransaction | |||||||
| instance ToJSON PriceDirective | instance ToJSON PriceDirective | ||||||
| instance ToJSON DateSpan | instance ToJSON DateSpan | ||||||
| instance ToJSON Interval | instance ToJSON Interval | ||||||
|  | instance ToJSON Period | ||||||
| instance ToJSON AccountAlias | instance ToJSON AccountAlias | ||||||
| instance ToJSON AccountType | instance ToJSON AccountType | ||||||
| instance ToJSONKey AccountType | instance ToJSONKey AccountType | ||||||
| @ -225,6 +226,7 @@ instance FromJSON (DecimalRaw Integer) | |||||||
| -- instance FromJSON Commodity | -- instance FromJSON Commodity | ||||||
| -- instance FromJSON DateSpan | -- instance FromJSON DateSpan | ||||||
| -- instance FromJSON Interval | -- instance FromJSON Interval | ||||||
|  | -- instance FromJSON Period | ||||||
| -- instance FromJSON PeriodicTransaction | -- instance FromJSON PeriodicTransaction | ||||||
| -- instance FromJSON PriceDirective | -- instance FromJSON PriceDirective | ||||||
| -- instance FromJSON TimeclockCode | -- instance FromJSON TimeclockCode | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ module Hledger.Data.Period ( | |||||||
|   ,simplifyPeriod |   ,simplifyPeriod | ||||||
|   ,isLastDayOfMonth |   ,isLastDayOfMonth | ||||||
|   ,isStandardPeriod |   ,isStandardPeriod | ||||||
|  |   ,periodTextWidth | ||||||
|   ,showPeriod |   ,showPeriod | ||||||
|   ,showPeriodMonthAbbrev |   ,showPeriodMonthAbbrev | ||||||
|   ,periodStart |   ,periodStart | ||||||
| @ -155,6 +156,20 @@ isStandardPeriod = isStandardPeriod' . simplifyPeriod | |||||||
|     isStandardPeriod' (YearPeriod _) = True |     isStandardPeriod' (YearPeriod _) = True | ||||||
|     isStandardPeriod' _ = False |     isStandardPeriod' _ = False | ||||||
| 
 | 
 | ||||||
|  | -- | The width of a period of this type when displayed. | ||||||
|  | periodTextWidth :: Period -> Int | ||||||
|  | periodTextWidth = periodTextWidth' . simplifyPeriod | ||||||
|  |   where | ||||||
|  |     periodTextWidth' DayPeriod{}     = 10  -- 2021-01-01 | ||||||
|  |     periodTextWidth' WeekPeriod{}    = 13  -- 2021-01-01W52 | ||||||
|  |     periodTextWidth' MonthPeriod{}   = 7   -- 2021-01 | ||||||
|  |     periodTextWidth' QuarterPeriod{} = 6   -- 2021Q1 | ||||||
|  |     periodTextWidth' YearPeriod{}    = 4   -- 2021 | ||||||
|  |     periodTextWidth' PeriodBetween{} = 22  -- 2021-01-01..2021-01-07 | ||||||
|  |     periodTextWidth' PeriodFrom{}    = 12  -- 2021-01-01.. | ||||||
|  |     periodTextWidth' PeriodTo{}      = 12  -- ..2021-01-01 | ||||||
|  |     periodTextWidth' PeriodAll       = 2   -- .. | ||||||
|  | 
 | ||||||
| -- | Render a period as a compact display string suitable for user output. | -- | Render a period as a compact display string suitable for user output. | ||||||
| -- | -- | ||||||
| -- >>> showPeriod (WeekPeriod (fromGregorian 2016 7 25)) | -- >>> showPeriod (WeekPeriod (fromGregorian 2016 7 25)) | ||||||
|  | |||||||
| @ -25,8 +25,8 @@ import Data.List (nub, sortOn) | |||||||
| import Data.List.Extra (nubSort) | import Data.List.Extra (nubSort) | ||||||
| import Data.Maybe (fromMaybe, isJust, isNothing) | import Data.Maybe (fromMaybe, isJust, isNothing) | ||||||
| import Data.Text (Text) | import Data.Text (Text) | ||||||
| import Data.Time.Calendar (Day, addDays) | import Data.Time.Calendar (Day) | ||||||
| import Safe (headMay, lastMay) | import Safe (headMay) | ||||||
| 
 | 
 | ||||||
| import Hledger.Data | import Hledger.Data | ||||||
| import Hledger.Query | import Hledger.Query | ||||||
| @ -43,9 +43,7 @@ type PostingsReportItem = (Maybe Day    -- The posting date, if this is the firs | |||||||
|                                          -- posting's date. Or if this a summary posting, the |                                          -- posting's date. Or if this a summary posting, the | ||||||
|                                          -- report interval's start date if this is the first |                                          -- report interval's start date if this is the first | ||||||
|                                          -- summary posting in the interval. |                                          -- summary posting in the interval. | ||||||
|                           ,Maybe Day    -- If this is a summary posting, the report interval's |                           ,Maybe Period  -- If this is a summary posting, the report interval's period. | ||||||
|                                         -- end date if this is the first summary posting in |  | ||||||
|                                         -- the interval. |  | ||||||
|                           ,Maybe Text    -- The posting's transaction's description, if this is the first posting in the transaction. |                           ,Maybe Text    -- The posting's transaction's description, if this is the first posting in the transaction. | ||||||
|                           ,Posting       -- The posting, possibly with the account name depth-clipped. |                           ,Posting       -- The posting, possibly with the account name depth-clipped. | ||||||
|                           ,MixedAmount   -- The running total after this posting, or with --average, |                           ,MixedAmount   -- The running total after this posting, or with --average, | ||||||
| @ -55,10 +53,10 @@ type PostingsReportItem = (Maybe Day    -- The posting date, if this is the firs | |||||||
|                           ) |                           ) | ||||||
| 
 | 
 | ||||||
| -- | A summary posting summarises the activity in one account within a report | -- | A summary posting summarises the activity in one account within a report | ||||||
| -- interval. It is kludgily represented by a regular Posting with no description, | -- interval. It is by a regular Posting with no description, the interval's | ||||||
| -- the interval's start date stored as the posting date, and the interval's end | -- start date stored as the posting date, and the interval's Period attached | ||||||
| -- date attached with a tuple. | -- with a tuple. | ||||||
| type SummaryPosting = (Posting, Day) | type SummaryPosting = (Posting, Period) | ||||||
| 
 | 
 | ||||||
| -- | Select postings from the journal and add running balance and other | -- | Select postings from the journal and add running balance and other | ||||||
| -- information to make a postings report. Used by eg hledger's register command. | -- information to make a postings report. Used by eg hledger's register command. | ||||||
| @ -74,8 +72,8 @@ postingsReport rspec@ReportSpec{_rsReportOpts=ropts@ReportOpts{..}} j = items | |||||||
|       (precedingps, reportps) = matchedPostingsBeforeAndDuring rspec j reportspan |       (precedingps, reportps) = matchedPostingsBeforeAndDuring rspec j reportspan | ||||||
| 
 | 
 | ||||||
|       -- Postings, or summary postings with their subperiod's end date, to be displayed. |       -- Postings, or summary postings with their subperiod's end date, to be displayed. | ||||||
|       displayps :: [(Posting, Maybe Day)] |       displayps :: [(Posting, Maybe Period)] | ||||||
|         | multiperiod = [(p, Just periodend) | (p, periodend) <- summariseps reportps] |         | multiperiod = [(p, Just period) | (p, period) <- summariseps reportps] | ||||||
|         | otherwise   = [(p, Nothing) | p <- reportps] |         | otherwise   = [(p, Nothing) | p <- reportps] | ||||||
|         where |         where | ||||||
|           summariseps = summarisePostingsByInterval interval_ whichdate mdepth showempty reportspan |           summariseps = summarisePostingsByInterval interval_ whichdate mdepth showempty reportspan | ||||||
| @ -142,14 +140,14 @@ matchedPostingsBeforeAndDuring rspec@ReportSpec{_rsReportOpts=ropts,_rsQuery=q} | |||||||
|         dateq = dbg4 "dateq" $ filterQuery queryIsDateOrDate2 $ dbg4 "q" q  -- XXX confused by multiple date:/date2: ? |         dateq = dbg4 "dateq" $ filterQuery queryIsDateOrDate2 $ dbg4 "q" q  -- XXX confused by multiple date:/date2: ? | ||||||
| 
 | 
 | ||||||
| -- | Generate postings report line items from a list of postings or (with | -- | Generate postings report line items from a list of postings or (with | ||||||
| -- non-Nothing dates attached) summary postings. | -- non-Nothing periods attached) summary postings. | ||||||
| postingsReportItems :: [(Posting,Maybe Day)] -> (Posting,Maybe Day) -> WhichDate -> Maybe Int -> MixedAmount -> (Int -> MixedAmount -> MixedAmount -> MixedAmount) -> Int -> [PostingsReportItem] | postingsReportItems :: [(Posting,Maybe Period)] -> (Posting,Maybe Period) -> WhichDate -> Maybe Int -> MixedAmount -> (Int -> MixedAmount -> MixedAmount -> MixedAmount) -> Int -> [PostingsReportItem] | ||||||
| postingsReportItems [] _ _ _ _ _ _ = [] | postingsReportItems [] _ _ _ _ _ _ = [] | ||||||
| postingsReportItems ((p,menddate):ps) (pprev,menddateprev) wd d b runningcalcfn itemnum = | postingsReportItems ((p,mperiod):ps) (pprev,mperiodprev) wd d b runningcalcfn itemnum = | ||||||
|     i:(postingsReportItems ps (p,menddate) wd d b' runningcalcfn (itemnum+1)) |     i:(postingsReportItems ps (p,mperiod) wd d b' runningcalcfn (itemnum+1)) | ||||||
|   where |   where | ||||||
|     i = mkpostingsReportItem showdate showdesc wd menddate p' b' |     i = mkpostingsReportItem showdate showdesc wd mperiod p' b' | ||||||
|     (showdate, showdesc) | isJust menddate = (menddate /= menddateprev,        False) |     (showdate, showdesc) | isJust mperiod = (mperiod /= mperiodprev,          False) | ||||||
|                          | otherwise      = (isfirstintxn || isdifferentdate, isfirstintxn) |                          | otherwise      = (isfirstintxn || isdifferentdate, isfirstintxn) | ||||||
|     isfirstintxn = ptransaction p /= ptransaction pprev |     isfirstintxn = ptransaction p /= ptransaction pprev | ||||||
|     isdifferentdate = case wd of PrimaryDate   -> postingDate p  /= postingDate pprev |     isdifferentdate = case wd of PrimaryDate   -> postingDate p  /= postingDate pprev | ||||||
| @ -160,10 +158,10 @@ postingsReportItems ((p,menddate):ps) (pprev,menddateprev) wd d b runningcalcfn | |||||||
| -- | Generate one postings report line item, containing the posting, | -- | Generate one postings report line item, containing the posting, | ||||||
| -- the current running balance, and optionally the posting date and/or | -- the current running balance, and optionally the posting date and/or | ||||||
| -- the transaction description. | -- the transaction description. | ||||||
| mkpostingsReportItem :: Bool -> Bool -> WhichDate -> Maybe Day -> Posting -> MixedAmount -> PostingsReportItem | mkpostingsReportItem :: Bool -> Bool -> WhichDate -> Maybe Period -> Posting -> MixedAmount -> PostingsReportItem | ||||||
| mkpostingsReportItem showdate showdesc wd menddate p b = | mkpostingsReportItem showdate showdesc wd mperiod p b = | ||||||
|   (if showdate then Just date else Nothing |   (if showdate then Just date else Nothing | ||||||
|   ,menddate |   ,mperiod | ||||||
|   ,if showdesc then tdescription <$> ptransaction p else Nothing |   ,if showdesc then tdescription <$> ptransaction p else Nothing | ||||||
|   ,p |   ,p | ||||||
|   ,b |   ,b | ||||||
| @ -194,19 +192,18 @@ summarisePostingsByInterval interval wd mdepth showempty reportspan ps = concatM | |||||||
| -- with 0 amount. | -- with 0 amount. | ||||||
| -- | -- | ||||||
| summarisePostingsInDateSpan :: DateSpan -> WhichDate -> Maybe Int -> Bool -> [Posting] -> [SummaryPosting] | summarisePostingsInDateSpan :: DateSpan -> WhichDate -> Maybe Int -> Bool -> [Posting] -> [SummaryPosting] | ||||||
| summarisePostingsInDateSpan (DateSpan b e) wd mdepth showempty ps | summarisePostingsInDateSpan span@(DateSpan b e) wd mdepth showempty ps | ||||||
|   | null ps && (isNothing b || isNothing e) = [] |   | null ps && (isNothing b || isNothing e) = [] | ||||||
|   | null ps && showempty = [(summaryp, e')] |   | null ps && showempty = [(summaryp, dateSpanAsPeriod span)] | ||||||
|   | otherwise = summarypes |   | otherwise = summarypes | ||||||
|   where |   where | ||||||
|     postingdate = if wd == PrimaryDate then postingDate else postingDate2 |     postingdate = if wd == PrimaryDate then postingDate else postingDate2 | ||||||
|     b' = fromMaybe (maybe nulldate postingdate $ headMay ps) b |     b' = fromMaybe (maybe nulldate postingdate $ headMay ps) b | ||||||
|     e' = fromMaybe (maybe (addDays 1 nulldate) postingdate $ lastMay ps) e |  | ||||||
|     summaryp = nullposting{pdate=Just b'} |     summaryp = nullposting{pdate=Just b'} | ||||||
|     clippedanames = nub $ map (clipAccountName mdepth) anames |     clippedanames = nub $ map (clipAccountName mdepth) anames | ||||||
|     summaryps | mdepth == Just 0 = [summaryp{paccount="...",pamount=sumPostings ps}] |     summaryps | mdepth == Just 0 = [summaryp{paccount="...",pamount=sumPostings ps}] | ||||||
|               | otherwise        = [summaryp{paccount=a,pamount=balance a} | a <- clippedanames] |               | otherwise        = [summaryp{paccount=a,pamount=balance a} | a <- clippedanames] | ||||||
|     summarypes = map (, e') $ (if showempty then id else filter (not . mixedAmountLooksZero . pamount)) summaryps |     summarypes = map (, dateSpanAsPeriod span) $ (if showempty then id else filter (not . mixedAmountLooksZero . pamount)) summaryps | ||||||
|     anames = nubSort $ map paccount ps |     anames = nubSort $ map paccount ps | ||||||
|     -- aggregate balances by account, like ledgerFromJournal, then do depth-clipping |     -- aggregate balances by account, like ledgerFromJournal, then do depth-clipping | ||||||
|     accts = accountsFromPostings ps |     accts = accountsFromPostings ps | ||||||
|  | |||||||
| @ -134,7 +134,7 @@ postingsReportAsText opts items = TB.toLazyText $ foldMap first3 linesWithWidths | |||||||
| -- Also returns the natural width (without padding) of the amount and balance | -- Also returns the natural width (without padding) of the amount and balance | ||||||
| -- fields. | -- fields. | ||||||
| postingsReportItemAsText :: CliOpts -> Int -> Int -> PostingsReportItem -> (TB.Builder, Int, Int) | postingsReportItemAsText :: CliOpts -> Int -> Int -> PostingsReportItem -> (TB.Builder, Int, Int) | ||||||
| postingsReportItemAsText opts preferredamtwidth preferredbalwidth (mdate, menddate, mdesc, p, b) = | postingsReportItemAsText opts preferredamtwidth preferredbalwidth (mdate, mperiod, mdesc, p, b) = | ||||||
|     (table <> TB.singleton '\n', thisamtwidth, thisbalwidth) |     (table <> TB.singleton '\n', thisamtwidth, thisbalwidth) | ||||||
|   where |   where | ||||||
|     table = renderRowB def{tableBorders=False, borderSpaces=False} . Group NoLine $ map Header |     table = renderRowB def{tableBorders=False, borderSpaces=False} . Group NoLine $ map Header | ||||||
| @ -154,11 +154,10 @@ postingsReportItemAsText opts preferredamtwidth preferredbalwidth (mdate, mendda | |||||||
|       where w = fullwidth - wbWidth amt |       where w = fullwidth - wbWidth amt | ||||||
|     -- calculate widths |     -- calculate widths | ||||||
|     (totalwidth,mdescwidth) = registerWidthsFromOpts opts |     (totalwidth,mdescwidth) = registerWidthsFromOpts opts | ||||||
|     (datewidth, date) = case (mdate,menddate) of |     datewidth = maybe 10 periodTextWidth mperiod | ||||||
|         (Just _, Just _)   -> (21, showDateSpan (DateSpan mdate menddate)) |     date = case mperiod of | ||||||
|         (Nothing, Just _)  -> (21, "") |              Just period -> if isJust mdate then showPeriod period else "" | ||||||
|         (Just d, Nothing)  -> (10, showDate d) |              Nothing     -> maybe "" showDate mdate | ||||||
|         _                  -> (10, "") |  | ||||||
|     (amtwidth, balwidth) |     (amtwidth, balwidth) | ||||||
|       | shortfall <= 0 = (preferredamtwidth, preferredbalwidth) |       | shortfall <= 0 = (preferredamtwidth, preferredbalwidth) | ||||||
|       | otherwise      = (adjustedamtwidth, adjustedbalwidth) |       | otherwise      = (adjustedamtwidth, adjustedbalwidth) | ||||||
| @ -172,10 +171,9 @@ postingsReportItemAsText opts preferredamtwidth preferredbalwidth (mdate, mendda | |||||||
| 
 | 
 | ||||||
|     remaining = totalwidth - (datewidth + 1 + 2 + amtwidth + 2 + balwidth) |     remaining = totalwidth - (datewidth + 1 + 2 + amtwidth + 2 + balwidth) | ||||||
|     (descwidth, acctwidth) |     (descwidth, acctwidth) | ||||||
|       | hasinterval = (0, remaining - 2) |       | isJust mperiod = (0, remaining - 2) | ||||||
|       | otherwise      = (w, remaining - 2 - w) |       | otherwise      = (w, remaining - 2 - w) | ||||||
|       where |       where | ||||||
|         hasinterval = isJust menddate |  | ||||||
|         w = fromMaybe ((remaining - 2) `div` 2) mdescwidth |         w = fromMaybe ((remaining - 2) `div` 2) mdescwidth | ||||||
| 
 | 
 | ||||||
|     -- gather content |     -- gather content | ||||||
|  | |||||||
| @ -69,3 +69,10 @@ $ hledger -f- register -p 'monthly 2014/1/10-2014/2/20' | |||||||
| 2014-02   after                                                  1             2 | 2014-02   after                                                  1             2 | ||||||
|           within                                                 1             3 |           within                                                 1             3 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | # 7. Custom ranges should display fully. | ||||||
|  | $ hledger -f- register -p 'every tue' | ||||||
|  | 2013-12-31..2014-01-06   before                                  1             1 | ||||||
|  | 2014-01-28..2014-02-03   within                                  1             2 | ||||||
|  | 2014-02-25..2014-03-03   after                                   1             3 | ||||||
|  | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user