dev: CompoundBalanceCommand: refactor table rendering

This commit is contained in:
Simon Michael 2024-06-12 00:25:59 +01:00
parent 9d6cb0f969
commit 1260a68596

View File

@ -19,11 +19,11 @@ import qualified Data.Text as T
import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Builder as TB import qualified Data.Text.Lazy.Builder as TB
import Data.Time.Calendar (Day, addDays) import Data.Time.Calendar (Day, addDays)
import System.Console.CmdArgs.Explicit as C import System.Console.CmdArgs.Explicit as C (Mode, flagNone, flagReq)
import Hledger.Read.CsvUtils (CSV, printCSV, printTSV) import Hledger.Read.CsvUtils (CSV, printCSV, printTSV)
import Lucid as L hiding (value_) import Lucid as L hiding (value_)
import Safe (tailDef) import Safe (tailDef)
import Text.Tabular.AsciiWide as Tab hiding (render) import Text.Tabular.AsciiWide as Tabular hiding (render)
import Hledger import Hledger
import Hledger.Cli.Commands.Balance import Hledger.Cli.Commands.Balance
@ -215,40 +215,60 @@ Balance Sheet
-} -}
compoundBalanceReportAsText :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> TL.Text compoundBalanceReportAsText :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> TL.Text
compoundBalanceReportAsText ropts compoundBalanceReportAsText ropts (CompoundPeriodicReport title _colspans subreports totalsrow) =
(CompoundPeriodicReport title _colspans subreports netrow) = TB.toLazyText $
TB.toLazyText $ TB.fromText title <> TB.fromText "\n\n" <>
TB.fromText title <> TB.fromText "\n\n" <> balanceReportTableAsText ropts bigtablewithtotalsrow
balanceReportTableAsText ropts bigtable'
where where
bigtable = bigtable =
case map (subreportAsTable ropts) subreports of case map (subreportAsTable ropts) subreports of
[] -> Tab.empty [] -> Tabular.empty
r:rs -> foldl' (concatTables DoubleLine) r rs r:rs -> foldl' (concatTables tableInterSubreportBorder) r rs
bigtable' bigtablewithtotalsrow =
| no_total_ ropts || length subreports == 1 = if no_total_ ropts || length subreports == 1
bigtable then bigtable
| otherwise = else concatTables tableGrandTotalsTopBorder bigtable totalstable
let totalrows = multiBalanceRowAsTableText ropts netrow where
rh = Tab.Group NoLine $ map Header ("Net:" : replicate (length totalrows - 1) "") -- Append the report's grand column totals at the bottom of the table.
ch = Header [] -- ignored -- Note "row" is confusingly overloaded here; *Report rows, Table rows,
in ((concatTables Tab.DoubleLine) bigtable $ Table rh ch totalrows) -- and visually apparent table rows are all distinct.
-- With multiple currencies, in some layout modes, the column totals (a single report row)
-- occupy multiple lines, which currently we put into multiple table rows,
-- for convenience I guess, borderless so they look like a single visual row.
--
-- multiBalanceRowAsTableText gets a matrix of each line of each column total rendered as text
-- (actually as WideBuilders), in line-major-order:
-- [
-- [COL1LINE1, COL2LINE1]
-- [COL1LINE2, COL2LINE2]
-- ]
coltotalslines = multiBalanceRowAsTableText ropts totalsrow
totalstable = Table
(Group NoLine $ map Header $ "Net:" : replicate (length coltotalslines - 1) "") -- row headers
(Header []) -- column headers, concatTables will discard these
coltotalslines -- cell values
-- | Convert a named multi balance report to a table suitable for -- | Convert a named multi balance report to a table suitable for
-- concatenating with others to make a compound balance report table. -- concatenating with others to make a compound balance report table.
subreportAsTable ropts1 (title1, r, _) = t subreportAsTable ropts1 (title1, r, _) = tablewithtitle
where where
-- convert to table tablewithtitle = Table
Table lefthdrs tophdrs cells = balanceReportAsTable ropts1 r (Group tableSubreportTitleBottomBorder [Header title1, lefthdrs]) -- row headers
-- tweak the layout tophdrs -- column headers
t = Table (Tab.Group Tab.SingleLine [Tab.Header title1, lefthdrs]) tophdrs ([]:cells) ([]:cells) -- cell values
where
Table lefthdrs tophdrs cells = balanceReportAsTable ropts1 r
tableSubreportTitleBottomBorder = SingleLine
tableInterSubreportBorder = DoubleLine
tableGrandTotalsTopBorder = DoubleLine
-- | 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
-- subreport title row, and an overall title row, one headings row, and an -- subreport title row, and an overall title row, one headings row, and an
-- optional overall totals row is added. -- optional overall totals row is added.
compoundBalanceReportAsCsv :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> CSV compoundBalanceReportAsCsv :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> CSV
compoundBalanceReportAsCsv ropts (CompoundPeriodicReport title colspans subreports netrow) = compoundBalanceReportAsCsv ropts (CompoundPeriodicReport title colspans subreports totalrow) =
addtotals $ addtotals $
padRow title padRow title
: ( "Account" : ( "Account"
@ -276,13 +296,13 @@ compoundBalanceReportAsCsv ropts (CompoundPeriodicReport title colspans subrepor
map (length . prDates . second3) subreports map (length . prDates . second3) subreports
addtotals addtotals
| no_total_ ropts || length subreports == 1 = id | no_total_ ropts || length subreports == 1 = id
| otherwise = (++ fmap ("Net:" : ) (multiBalanceRowAsCsvText ropts colspans netrow)) | otherwise = (++ fmap ("Net:" : ) (multiBalanceRowAsCsvText ropts colspans totalrow))
-- | Render a compound balance report as HTML. -- | Render a compound balance report as HTML.
compoundBalanceReportAsHtml :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> Html () compoundBalanceReportAsHtml :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> Html ()
compoundBalanceReportAsHtml ropts cbr = compoundBalanceReportAsHtml ropts cbr =
let let
CompoundPeriodicReport title colspans subreports netrow = cbr CompoundPeriodicReport title colspans subreports totalrow = cbr
colspanattr = colspan_ $ T.pack $ show $ sum [ colspanattr = colspan_ $ T.pack $ show $ sum [
1, 1,
length colspans, length colspans,
@ -318,7 +338,7 @@ compoundBalanceReportAsHtml ropts cbr =
++ [blankrow] ++ [blankrow]
totalrows | no_total_ ropts || length subreports == 1 = [] totalrows | no_total_ ropts || length subreports == 1 = []
| otherwise = multiBalanceReportHtmlFootRow ropts <$> (("Net:" :) <$> multiBalanceRowAsCsvText ropts colspans netrow) | otherwise = multiBalanceReportHtmlFootRow ropts <$> (("Net:" :) <$> multiBalanceRowAsCsvText ropts colspans totalrow)
in do in do
style_ (T.unlines ["" style_ (T.unlines [""
,"td { padding:0 0.5em; }" ,"td { padding:0 0.5em; }"