cli: Refactor compoundBalanceCommand.
This commit is contained in:
		
							parent
							
								
									7e44b89bb4
								
							
						
					
					
						commit
						dbe7015502
					
				| @ -13,19 +13,19 @@ module Hledger.Cli.CompoundBalanceCommand ( | |||||||
| ) where | ) where | ||||||
| 
 | 
 | ||||||
| import Data.List (foldl') | import Data.List (foldl') | ||||||
| import Data.Maybe | import Data.Maybe (fromMaybe, mapMaybe) | ||||||
| import qualified Data.Text as TS | import qualified Data.Text as T | ||||||
| import qualified Data.Text.Lazy as TL | import qualified Data.Text.Lazy as TL | ||||||
| import Data.Time.Calendar | import Data.Time.Calendar (Day, addDays) | ||||||
| import System.Console.CmdArgs.Explicit as C | import System.Console.CmdArgs.Explicit as C | ||||||
| import Hledger.Read.CsvReader (CSV, printCSV) | import Hledger.Read.CsvReader (CSV, printCSV) | ||||||
| import Lucid as L hiding (value_) | import Lucid as L hiding (value_) | ||||||
| import Text.Tabular as T | import Text.Tabular as Tab | ||||||
| 
 | 
 | ||||||
| import Hledger | import Hledger | ||||||
| import Hledger.Cli.Commands.Balance | import Hledger.Cli.Commands.Balance | ||||||
| import Hledger.Cli.CliOptions | import Hledger.Cli.CliOptions | ||||||
| import Hledger.Cli.Utils (unsupportedOutputFormatError, writeOutput) | import Hledger.Cli.Utils (unsupportedOutputFormatError, writeOutputLazyText) | ||||||
| 
 | 
 | ||||||
| -- | Description of a compound balance report command, | -- | Description of a compound balance report command, | ||||||
| -- from which we generate the command's cmdargs mode and IO action. | -- from which we generate the command's cmdargs mode and IO action. | ||||||
| @ -89,71 +89,72 @@ compoundBalanceCommandMode CompoundBalanceCommandSpec{..} = | |||||||
| -- | Generate a runnable command from a compound balance command specification. | -- | Generate a runnable command from a compound balance command specification. | ||||||
| compoundBalanceCommand :: CompoundBalanceCommandSpec -> (CliOpts -> Journal -> IO ()) | compoundBalanceCommand :: CompoundBalanceCommandSpec -> (CliOpts -> Journal -> IO ()) | ||||||
| compoundBalanceCommand CompoundBalanceCommandSpec{..} opts@CliOpts{reportspec_=rspec, rawopts_=rawopts} j = do | compoundBalanceCommand CompoundBalanceCommandSpec{..} opts@CliOpts{reportspec_=rspec, rawopts_=rawopts} j = do | ||||||
|     let |     writeOutputLazyText opts $ render cbr | ||||||
|       ropts@ReportOpts{..} = rsOpts rspec |   where | ||||||
|       -- use the default balance type for this report, unless the user overrides |     ropts@ReportOpts{..} = rsOpts rspec | ||||||
|       mBalanceTypeOverride = |     -- use the default balance type for this report, unless the user overrides | ||||||
|         choiceopt parse rawopts where |     mBalanceTypeOverride = | ||||||
|           parse = \case |       choiceopt parse rawopts where | ||||||
|             "historical" -> Just HistoricalBalance |         parse = \case | ||||||
|             "cumulative" -> Just CumulativeChange |           "historical" -> Just HistoricalBalance | ||||||
|             "change"     -> Just PeriodChange |           "cumulative" -> Just CumulativeChange | ||||||
|             _            -> Nothing |           "change"     -> Just PeriodChange | ||||||
|       balancetype = fromMaybe cbctype mBalanceTypeOverride |           _            -> Nothing | ||||||
|       -- Set balance type in the report options. |     balancetype = fromMaybe cbctype mBalanceTypeOverride | ||||||
|       ropts' = ropts{balancetype_=balancetype} |     -- Set balance type in the report options. | ||||||
|  |     ropts' = ropts{balancetype_=balancetype} | ||||||
| 
 | 
 | ||||||
|       title = |     title = | ||||||
|         cbctitle |       cbctitle | ||||||
|         ++ " " |       ++ " " | ||||||
|         ++ titledatestr |       ++ titledatestr | ||||||
|         ++ maybe "" (' ':) mtitleclarification |       ++ maybe "" (' ':) mtitleclarification | ||||||
|         ++ valuationdesc |       ++ valuationdesc | ||||||
|         where |       where | ||||||
| 
 | 
 | ||||||
|           -- XXX #1078 the title of ending balance reports |         -- XXX #1078 the title of ending balance reports | ||||||
|           -- (HistoricalBalance) should mention the end date(s) shown as |         -- (HistoricalBalance) should mention the end date(s) shown as | ||||||
|           -- column heading(s) (not the date span of the transactions). |         -- column heading(s) (not the date span of the transactions). | ||||||
|           -- Also the dates should not be simplified (it should show |         -- Also the dates should not be simplified (it should show | ||||||
|           -- "2008/01/01-2008/12/31", not "2008"). |         -- "2008/01/01-2008/12/31", not "2008"). | ||||||
|           titledatestr = case balancetype of |         titledatestr = case balancetype of | ||||||
|               HistoricalBalance -> showEndDates enddates |             HistoricalBalance -> showEndDates enddates | ||||||
|               _                 -> showDateSpan requestedspan |             _                 -> showDateSpan requestedspan | ||||||
|             where |           where | ||||||
|               enddates = map (addDays (-1)) . mapMaybe spanEnd $ cbrDates cbr  -- these spans will always have a definite end date |             enddates = map (addDays (-1)) . mapMaybe spanEnd $ cbrDates cbr  -- these spans will always have a definite end date | ||||||
|               requestedspan = queryDateSpan date2_ (rsQuery rspec) |             requestedspan = queryDateSpan date2_ (rsQuery rspec) | ||||||
|                                   `spanDefaultsFrom` journalDateSpan date2_ j |                                 `spanDefaultsFrom` journalDateSpan date2_ j | ||||||
| 
 | 
 | ||||||
|           -- when user overrides, add an indication to the report title |         -- when user overrides, add an indication to the report title | ||||||
|           mtitleclarification = flip fmap mBalanceTypeOverride $ \case |         mtitleclarification = flip fmap mBalanceTypeOverride $ \case | ||||||
|               PeriodChange | changingValuation -> "(Period-End Value Changes)" |             PeriodChange | changingValuation -> "(Period-End Value Changes)" | ||||||
|               PeriodChange                     -> "(Balance Changes)" |             PeriodChange                     -> "(Balance Changes)" | ||||||
|               CumulativeChange                 -> "(Cumulative Ending Balances)" |             CumulativeChange                 -> "(Cumulative Ending Balances)" | ||||||
|               HistoricalBalance                -> "(Historical Ending Balances)" |             HistoricalBalance                -> "(Historical Ending Balances)" | ||||||
| 
 | 
 | ||||||
|           valuationdesc = case value_ of |         valuationdesc = case value_ of | ||||||
|             Just (AtCost _mc)       -> ", valued at cost" |           Just (AtCost _mc)       -> ", valued at cost" | ||||||
|             Just (AtThen _mc)       -> error' unsupportedValueThenError  -- TODO |           Just (AtThen _mc)       -> error' unsupportedValueThenError  -- TODO | ||||||
|             Just (AtEnd _mc) | changingValuation -> "" |           Just (AtEnd _mc) | changingValuation -> "" | ||||||
|             Just (AtEnd _mc)        -> ", valued at period ends" |           Just (AtEnd _mc)        -> ", valued at period ends" | ||||||
|             Just (AtNow _mc)        -> ", current value" |           Just (AtNow _mc)        -> ", current value" | ||||||
|             Just (AtDate today _mc) -> ", valued at "++showDate today |           Just (AtDate today _mc) -> ", valued at "++showDate today | ||||||
|             Nothing                 -> "" |           Nothing                 -> "" | ||||||
| 
 | 
 | ||||||
|           changingValuation = case (balancetype_, value_) of |         changingValuation = case (balancetype_, value_) of | ||||||
|               (PeriodChange, Just (AtEnd _)) -> interval_ /= NoInterval |             (PeriodChange, Just (AtEnd _)) -> interval_ /= NoInterval | ||||||
|               _                              -> False |             _                              -> False | ||||||
| 
 | 
 | ||||||
|       -- make a CompoundBalanceReport. |     -- make a CompoundBalanceReport. | ||||||
|       cbr' = compoundBalanceReport rspec{rsOpts=ropts'} j cbcqueries |     cbr' = compoundBalanceReport rspec{rsOpts=ropts'} j cbcqueries | ||||||
|       cbr  = cbr'{cbrTitle=title} |     cbr  = cbr'{cbrTitle=title} | ||||||
| 
 | 
 | ||||||
|     -- render appropriately |     -- render appropriately | ||||||
|     writeOutput opts $ case outputFormatFromOpts opts of |     render = case outputFormatFromOpts opts of | ||||||
|         "txt"  -> compoundBalanceReportAsText ropts' cbr |         "txt"  -> TL.pack . compoundBalanceReportAsText ropts' | ||||||
|         "csv"  -> printCSV (compoundBalanceReportAsCsv ropts cbr) ++ "\n" |         "csv"  -> TL.pack . printCSV . compoundBalanceReportAsCsv ropts' | ||||||
|         "html" -> (++"\n") $ TL.unpack $ L.renderText $ compoundBalanceReportAsHtml ropts cbr |         "html" -> L.renderText . compoundBalanceReportAsHtml ropts' | ||||||
|         "json" -> (++"\n") $ TL.unpack $ toJsonText cbr |         "json" -> toJsonText | ||||||
|         x      -> error' $ unsupportedOutputFormatError x |         x      -> error' $ unsupportedOutputFormatError x | ||||||
| 
 | 
 | ||||||
| -- | Summarise one or more (inclusive) end dates, in a way that's | -- | Summarise one or more (inclusive) end dates, in a way that's | ||||||
| @ -196,7 +197,7 @@ compoundBalanceReportAsText ropts | |||||||
|   where |   where | ||||||
|     bigtable = |     bigtable = | ||||||
|       case map (subreportAsTable ropts) subreports of |       case map (subreportAsTable ropts) subreports of | ||||||
|         []   -> T.empty |         []   -> Tab.empty | ||||||
|         r:rs -> foldl' concatTables r rs |         r:rs -> foldl' concatTables r rs | ||||||
|     bigtable' |     bigtable' | ||||||
|       | no_total_ ropts || length subreports == 1 = |       | no_total_ ropts || length subreports == 1 = | ||||||
| @ -217,11 +218,11 @@ compoundBalanceReportAsText ropts | |||||||
|         -- convert to table |         -- convert to table | ||||||
|         Table lefthdrs tophdrs cells = balanceReportAsTable ropts r |         Table lefthdrs tophdrs cells = balanceReportAsTable ropts r | ||||||
|         -- tweak the layout |         -- tweak the layout | ||||||
|         t = Table (T.Group SingleLine [Header title, lefthdrs]) tophdrs ([]:cells) |         t = Table (Tab.Group SingleLine [Header title, lefthdrs]) tophdrs ([]:cells) | ||||||
| 
 | 
 | ||||||
| -- | Add the second table below the first, discarding its column headings. | -- | Add the second table below the first, discarding its column headings. | ||||||
| concatTables (Table hLeft hTop dat) (Table hLeft' _ dat') = | concatTables (Table hLeft hTop dat) (Table hLeft' _ dat') = | ||||||
|     Table (T.Group DoubleLine [hLeft, hLeft']) hTop (dat ++ dat') |     Table (Tab.Group DoubleLine [hLeft, hLeft']) hTop (dat ++ dat') | ||||||
| 
 | 
 | ||||||
| -- | Render a compound balance report as CSV. | -- | Render a compound balance report as CSV. | ||||||
| -- Subreports' CSV is concatenated, with the headings rows replaced by a | -- Subreports' CSV is concatenated, with the headings rows replaced by a | ||||||
| @ -268,7 +269,7 @@ compoundBalanceReportAsHtml :: ReportOpts -> CompoundPeriodicReport DisplayName | |||||||
| compoundBalanceReportAsHtml ropts cbr = | compoundBalanceReportAsHtml ropts cbr = | ||||||
|   let |   let | ||||||
|     CompoundPeriodicReport title colspans subreports (PeriodicReportRow _ coltotals grandtotal grandavg) = cbr |     CompoundPeriodicReport title colspans subreports (PeriodicReportRow _ coltotals grandtotal grandavg) = cbr | ||||||
|     colspanattr = colspan_ $ TS.pack $ show $ |     colspanattr = colspan_ $ T.pack $ show $ | ||||||
|       1 + length colspans + (if row_total_ ropts then 1 else 0) + (if average_ ropts then 1 else 0) |       1 + length colspans + (if row_total_ ropts then 1 else 0) + (if average_ ropts then 1 else 0) | ||||||
|     leftattr = style_ "text-align:left" |     leftattr = style_ "text-align:left" | ||||||
|     blankrow = tr_ $ td_ [colspanattr] $ toHtmlRaw (" "::String) |     blankrow = tr_ $ td_ [colspanattr] $ toHtmlRaw (" "::String) | ||||||
| @ -309,7 +310,7 @@ compoundBalanceReportAsHtml ropts cbr = | |||||||
|                     ] |                     ] | ||||||
| 
 | 
 | ||||||
|   in do |   in do | ||||||
|     style_ (TS.unlines ["" |     style_ (T.unlines ["" | ||||||
|       ,"td { padding:0 0.5em; }" |       ,"td { padding:0 0.5em; }" | ||||||
|       ,"td:nth-child(1) { white-space:nowrap; }" |       ,"td:nth-child(1) { white-space:nowrap; }" | ||||||
|       ,"tr:nth-child(even) td { background-color:#eee; }" |       ,"tr:nth-child(even) td { background-color:#eee; }" | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user