{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Hledger.Cli.CompoundBalanceCommand (
CompoundBalanceCommandSpec(..)
,compoundBalanceCommandMode
,compoundBalanceCommand
) where
import Data.List (foldl')
import Data.Maybe (fromMaybe, mapMaybe)
import qualified Data.Text as T
import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Builder as TB
import Data.Time.Calendar (Day, addDays)
import System.Console.CmdArgs.Explicit as C
import Hledger.Read.CsvReader (CSV, printCSV)
import Lucid as L hiding (value_)
import Text.Tabular.AsciiWide as Tab
import Hledger
import Hledger.Cli.Commands.Balance
import Hledger.Cli.CliOptions
import Hledger.Cli.Utils (unsupportedOutputFormatError, writeOutputLazyText)
data CompoundBalanceCommandSpec = CompoundBalanceCommandSpec {
CompoundBalanceCommandSpec -> CommandDoc
cbcdoc :: CommandDoc,
CompoundBalanceCommandSpec -> CommandDoc
cbctitle :: String,
CompoundBalanceCommandSpec -> [CBCSubreportSpec DisplayName]
cbcqueries :: [CBCSubreportSpec DisplayName],
CompoundBalanceCommandSpec -> BalanceType
cbctype :: BalanceType
}
compoundBalanceCommandMode :: CompoundBalanceCommandSpec -> Mode RawOpts
compoundBalanceCommandMode :: CompoundBalanceCommandSpec -> Mode RawOpts
compoundBalanceCommandMode CompoundBalanceCommandSpec{CommandDoc
[CBCSubreportSpec DisplayName]
BalanceType
cbctype :: BalanceType
cbcqueries :: [CBCSubreportSpec DisplayName]
cbctitle :: CommandDoc
cbcdoc :: CommandDoc
cbctype :: CompoundBalanceCommandSpec -> BalanceType
cbcqueries :: CompoundBalanceCommandSpec -> [CBCSubreportSpec DisplayName]
cbctitle :: CompoundBalanceCommandSpec -> CommandDoc
cbcdoc :: CompoundBalanceCommandSpec -> CommandDoc
..} =
CommandDoc
-> [Flag RawOpts]
-> [(CommandDoc, [Flag RawOpts])]
-> [Flag RawOpts]
-> ([Arg RawOpts], Maybe (Arg RawOpts))
-> Mode RawOpts
hledgerCommandMode
CommandDoc
cbcdoc
([[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"sum"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"sum")
CommandDoc
"show sum of posting amounts (default)"
,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"valuechange"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"valuechange")
CommandDoc
"show change of value of period-end historical balances"
,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"budget"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"budget")
CommandDoc
"show sum of posting amounts compared to budget goals defined by periodic transactions\n "
,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"change"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"change")
(CommandDoc
"accumulate amounts from column start to column end (in multicolumn reports)"
CommandDoc -> CommandDoc -> CommandDoc
forall a. [a] -> [a] -> [a]
++ BalanceType -> CommandDoc
defType BalanceType
PeriodChange)
,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"cumulative"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"cumulative")
(CommandDoc
"accumulate amounts from report start (specified by e.g. -b/--begin) to column end"
CommandDoc -> CommandDoc -> CommandDoc
forall a. [a] -> [a] -> [a]
++ BalanceType -> CommandDoc
defType BalanceType
CumulativeChange)
,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"historical",CommandDoc
"H"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"historical")
(CommandDoc
"accumulate amounts from journal start to column end (includes postings before report start date)"
CommandDoc -> CommandDoc -> CommandDoc
forall a. [a] -> [a] -> [a]
++ BalanceType -> CommandDoc
defType BalanceType
HistoricalBalance CommandDoc -> CommandDoc -> CommandDoc
forall a. [a] -> [a] -> [a]
++ CommandDoc
"\n ")
]
[Flag RawOpts] -> [Flag RawOpts] -> [Flag RawOpts]
forall a. [a] -> [a] -> [a]
++ Bool -> [Flag RawOpts]
flattreeflags Bool
True [Flag RawOpts] -> [Flag RawOpts] -> [Flag RawOpts]
forall a. [a] -> [a] -> [a]
++
[[CommandDoc]
-> Update RawOpts -> CommandDoc -> CommandDoc -> Flag RawOpts
forall a.
[CommandDoc] -> Update a -> CommandDoc -> CommandDoc -> Flag a
flagReq [CommandDoc
"drop"] (\CommandDoc
s RawOpts
opts -> RawOpts -> Either CommandDoc RawOpts
forall a b. b -> Either a b
Right (RawOpts -> Either CommandDoc RawOpts)
-> RawOpts -> Either CommandDoc RawOpts
forall a b. (a -> b) -> a -> b
$ CommandDoc -> CommandDoc -> RawOpts -> RawOpts
setopt CommandDoc
"drop" CommandDoc
s RawOpts
opts) CommandDoc
"N" CommandDoc
"flat mode: omit N leading account name parts"
,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"average",CommandDoc
"A"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"average") CommandDoc
"show a row average column (in multicolumn reports)"
,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"row-total",CommandDoc
"T"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"row-total") CommandDoc
"show a row total column (in multicolumn reports)"
,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"no-total",CommandDoc
"N"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"no-total") CommandDoc
"omit the final total row"
,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"no-elide"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"no-elide") CommandDoc
"don't squash boring parent accounts (in tree mode); don't show only 2 commodities per amount"
,[CommandDoc]
-> Update RawOpts -> CommandDoc -> CommandDoc -> Flag RawOpts
forall a.
[CommandDoc] -> Update a -> CommandDoc -> CommandDoc -> Flag a
flagReq [CommandDoc
"format"] (\CommandDoc
s RawOpts
opts -> RawOpts -> Either CommandDoc RawOpts
forall a b. b -> Either a b
Right (RawOpts -> Either CommandDoc RawOpts)
-> RawOpts -> Either CommandDoc RawOpts
forall a b. (a -> b) -> a -> b
$ CommandDoc -> CommandDoc -> RawOpts -> RawOpts
setopt CommandDoc
"format" CommandDoc
s RawOpts
opts) CommandDoc
"FORMATSTR" CommandDoc
"use this custom line format (in simple reports)"
,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"pretty-tables"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"pretty-tables") CommandDoc
"use unicode when displaying tables"
,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"sort-amount",CommandDoc
"S"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"sort-amount") CommandDoc
"sort by amount instead of account code/name"
,[CommandDoc] -> (RawOpts -> RawOpts) -> CommandDoc -> Flag RawOpts
forall a. [CommandDoc] -> (a -> a) -> CommandDoc -> Flag a
flagNone [CommandDoc
"percent", CommandDoc
"%"] (CommandDoc -> RawOpts -> RawOpts
setboolopt CommandDoc
"percent") CommandDoc
"express values in percentage of each column's total"
,[CommandDoc] -> Flag RawOpts
outputFormatFlag [CommandDoc
"txt",CommandDoc
"html",CommandDoc
"csv",CommandDoc
"json"]
,Flag RawOpts
outputFileFlag
])
[(CommandDoc, [Flag RawOpts])
generalflagsgroup1]
[Flag RawOpts]
hiddenflags
([], Arg RawOpts -> Maybe (Arg RawOpts)
forall a. a -> Maybe a
Just (Arg RawOpts -> Maybe (Arg RawOpts))
-> Arg RawOpts -> Maybe (Arg RawOpts)
forall a b. (a -> b) -> a -> b
$ CommandDoc -> Arg RawOpts
argsFlag CommandDoc
"[QUERY]")
where
defType :: BalanceType -> String
defType :: BalanceType -> CommandDoc
defType BalanceType
bt | BalanceType
bt BalanceType -> BalanceType -> Bool
forall a. Eq a => a -> a -> Bool
== BalanceType
cbctype = CommandDoc
" (default)"
| Bool
otherwise = CommandDoc
""
compoundBalanceCommand :: CompoundBalanceCommandSpec -> (CliOpts -> Journal -> IO ())
compoundBalanceCommand :: CompoundBalanceCommandSpec -> CliOpts -> Journal -> IO ()
compoundBalanceCommand CompoundBalanceCommandSpec{CommandDoc
[CBCSubreportSpec DisplayName]
BalanceType
cbctype :: BalanceType
cbcqueries :: [CBCSubreportSpec DisplayName]
cbctitle :: CommandDoc
cbcdoc :: CommandDoc
cbctype :: CompoundBalanceCommandSpec -> BalanceType
cbcqueries :: CompoundBalanceCommandSpec -> [CBCSubreportSpec DisplayName]
cbctitle :: CompoundBalanceCommandSpec -> CommandDoc
cbcdoc :: CompoundBalanceCommandSpec -> CommandDoc
..} opts :: CliOpts
opts@CliOpts{reportspec_ :: CliOpts -> ReportSpec
reportspec_=ReportSpec
rspec, rawopts_ :: CliOpts -> RawOpts
rawopts_=RawOpts
rawopts} Journal
j = do
CliOpts -> Text -> IO ()
writeOutputLazyText CliOpts
opts (Text -> IO ()) -> Text -> IO ()
forall a b. (a -> b) -> a -> b
$ CompoundPeriodicReport DisplayName MixedAmount -> Text
render CompoundPeriodicReport DisplayName MixedAmount
cbr
where
ropts :: ReportOpts
ropts@ReportOpts{Bool
Int
[Text]
[Status]
Maybe Int
Maybe ValuationType
Maybe DateSpan
Maybe NormalSign
ReportType
BalanceType
AccountListMode
Costing
StringFormat
Period
Interval
period_ :: ReportOpts -> Period
interval_ :: ReportOpts -> Interval
statuses_ :: ReportOpts -> [Status]
cost_ :: ReportOpts -> Costing
value_ :: ReportOpts -> Maybe ValuationType
infer_value_ :: ReportOpts -> Bool
depth_ :: ReportOpts -> Maybe Int
date2_ :: ReportOpts -> Bool
empty_ :: ReportOpts -> Bool
no_elide_ :: ReportOpts -> Bool
real_ :: ReportOpts -> Bool
format_ :: ReportOpts -> StringFormat
querystring_ :: ReportOpts -> [Text]
average_ :: ReportOpts -> Bool
related_ :: ReportOpts -> Bool
txn_dates_ :: ReportOpts -> Bool
reporttype_ :: ReportOpts -> ReportType
balancetype_ :: ReportOpts -> BalanceType
accountlistmode_ :: ReportOpts -> AccountListMode
drop_ :: ReportOpts -> Int
row_total_ :: ReportOpts -> Bool
no_total_ :: ReportOpts -> Bool
show_costs_ :: ReportOpts -> Bool
pretty_tables_ :: ReportOpts -> Bool
sort_amount_ :: ReportOpts -> Bool
percent_ :: ReportOpts -> Bool
invert_ :: ReportOpts -> Bool
normalbalance_ :: ReportOpts -> Maybe NormalSign
color_ :: ReportOpts -> Bool
forecast_ :: ReportOpts -> Maybe DateSpan
transpose_ :: ReportOpts -> Bool
transpose_ :: Bool
forecast_ :: Maybe DateSpan
color_ :: Bool
normalbalance_ :: Maybe NormalSign
invert_ :: Bool
percent_ :: Bool
sort_amount_ :: Bool
pretty_tables_ :: Bool
show_costs_ :: Bool
no_total_ :: Bool
row_total_ :: Bool
drop_ :: Int
accountlistmode_ :: AccountListMode
balancetype_ :: BalanceType
reporttype_ :: ReportType
txn_dates_ :: Bool
related_ :: Bool
average_ :: Bool
querystring_ :: [Text]
format_ :: StringFormat
real_ :: Bool
no_elide_ :: Bool
empty_ :: Bool
date2_ :: Bool
depth_ :: Maybe Int
infer_value_ :: Bool
value_ :: Maybe ValuationType
cost_ :: Costing
statuses_ :: [Status]
interval_ :: Interval
period_ :: Period
..} = ReportSpec -> ReportOpts
rsOpts ReportSpec
rspec
mBalanceTypeOverride :: Maybe BalanceType
mBalanceTypeOverride = RawOpts -> Maybe BalanceType
balanceTypeOverride RawOpts
rawopts
balancetype :: BalanceType
balancetype = BalanceType -> Maybe BalanceType -> BalanceType
forall a. a -> Maybe a -> a
fromMaybe BalanceType
cbctype Maybe BalanceType
mBalanceTypeOverride
ropts' :: ReportOpts
ropts' = ReportOpts
ropts{balancetype_ :: BalanceType
balancetype_=BalanceType
balancetype}
title :: Text
title =
CommandDoc -> Text
T.pack CommandDoc
cbctitle
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" "
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
titledatestr
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text -> (Text -> Text) -> Maybe Text -> Text
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Text
"" (Text
" "Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<>) Maybe Text
mtitleclarification
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
valuationdesc
where
titledatestr :: Text
titledatestr = case BalanceType
balancetype of
BalanceType
HistoricalBalance -> [Day] -> Text
showEndDates [Day]
enddates
BalanceType
_ -> DateSpan -> Text
showDateSpan DateSpan
requestedspan
where
enddates :: [Day]
enddates = (Day -> Day) -> [Day] -> [Day]
forall a b. (a -> b) -> [a] -> [b]
map (Integer -> Day -> Day
addDays (-Integer
1)) ([Day] -> [Day]) -> ([DateSpan] -> [Day]) -> [DateSpan] -> [Day]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (DateSpan -> Maybe Day) -> [DateSpan] -> [Day]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe DateSpan -> Maybe Day
spanEnd ([DateSpan] -> [Day]) -> [DateSpan] -> [Day]
forall a b. (a -> b) -> a -> b
$ CompoundPeriodicReport DisplayName MixedAmount -> [DateSpan]
forall a b. CompoundPeriodicReport a b -> [DateSpan]
cbrDates CompoundPeriodicReport DisplayName MixedAmount
cbr
requestedspan :: DateSpan
requestedspan = Journal -> ReportSpec -> DateSpan
reportSpan Journal
j ReportSpec
rspec
mtitleclarification :: Maybe Text
mtitleclarification = ((BalanceType -> Text) -> Maybe BalanceType -> Maybe Text)
-> Maybe BalanceType -> (BalanceType -> Text) -> Maybe Text
forall a b c. (a -> b -> c) -> b -> a -> c
flip (BalanceType -> Text) -> Maybe BalanceType -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe BalanceType
mBalanceTypeOverride ((BalanceType -> Text) -> Maybe Text)
-> (BalanceType -> Text) -> Maybe Text
forall a b. (a -> b) -> a -> b
$ \case
BalanceType
PeriodChange | Bool
changingValuation -> Text
"(Period-End Value Changes)"
BalanceType
PeriodChange -> Text
"(Balance Changes)"
BalanceType
CumulativeChange -> Text
"(Cumulative Ending Balances)"
BalanceType
HistoricalBalance -> Text
"(Historical Ending Balances)"
valuationdesc :: Text
valuationdesc =
(case Costing
cost_ of
Costing
Cost -> Text
", converted to cost"
Costing
NoCost -> Text
"")
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> (case Maybe ValuationType
value_ of
Just (AtThen Maybe Text
_mc) -> Text
", valued at posting date"
Just (AtEnd Maybe Text
_mc) | Bool
changingValuation -> Text
""
Just (AtEnd Maybe Text
_mc) -> Text
", valued at period ends"
Just (AtNow Maybe Text
_mc) -> Text
", current value"
Just (AtDate Day
today Maybe Text
_mc) -> Text
", valued at " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Day -> Text
showDate Day
today
Maybe ValuationType
Nothing -> Text
"")
changingValuation :: Bool
changingValuation = case (ReportType
reporttype_, BalanceType
balancetype_) of
(ReportType
ValueChangeReport, BalanceType
PeriodChange) -> Bool
True
(ReportType
ValueChangeReport, BalanceType
CumulativeChange) -> Bool
True
(ReportType, BalanceType)
_ -> Bool
False
cbr' :: CompoundPeriodicReport DisplayName MixedAmount
cbr' = ReportSpec
-> Journal
-> [CBCSubreportSpec DisplayName]
-> CompoundPeriodicReport DisplayName MixedAmount
forall a.
ReportSpec
-> Journal
-> [CBCSubreportSpec a]
-> CompoundPeriodicReport a MixedAmount
compoundBalanceReport ReportSpec
rspec{rsOpts :: ReportOpts
rsOpts=ReportOpts
ropts'} Journal
j [CBCSubreportSpec DisplayName]
cbcqueries
cbr :: CompoundPeriodicReport DisplayName MixedAmount
cbr = CompoundPeriodicReport DisplayName MixedAmount
cbr'{cbrTitle :: Text
cbrTitle=Text
title}
render :: CompoundPeriodicReport DisplayName MixedAmount -> Text
render = case CliOpts -> CommandDoc
outputFormatFromOpts CliOpts
opts of
CommandDoc
"txt" -> ReportOpts
-> CompoundPeriodicReport DisplayName MixedAmount -> Text
compoundBalanceReportAsText ReportOpts
ropts'
CommandDoc
"csv" -> CSV -> Text
printCSV (CSV -> Text)
-> (CompoundPeriodicReport DisplayName MixedAmount -> CSV)
-> CompoundPeriodicReport DisplayName MixedAmount
-> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> CSV
compoundBalanceReportAsCsv ReportOpts
ropts'
CommandDoc
"html" -> Html () -> Text
forall a. Html a -> Text
L.renderText (Html () -> Text)
-> (CompoundPeriodicReport DisplayName MixedAmount -> Html ())
-> CompoundPeriodicReport DisplayName MixedAmount
-> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReportOpts
-> CompoundPeriodicReport DisplayName MixedAmount -> Html ()
compoundBalanceReportAsHtml ReportOpts
ropts'
CommandDoc
"json" -> CompoundPeriodicReport DisplayName MixedAmount -> Text
forall a. ToJSON a => a -> Text
toJsonText
CommandDoc
x -> CommandDoc
-> CompoundPeriodicReport DisplayName MixedAmount -> Text
forall a. CommandDoc -> a
error' (CommandDoc
-> CompoundPeriodicReport DisplayName MixedAmount -> Text)
-> CommandDoc
-> CompoundPeriodicReport DisplayName MixedAmount
-> Text
forall a b. (a -> b) -> a -> b
$ CommandDoc -> CommandDoc
unsupportedOutputFormatError CommandDoc
x
showEndDates :: [Day] -> T.Text
showEndDates :: [Day] -> Text
showEndDates [Day]
es = case [Day]
es of
(Day
e:Day
_:[Day]
_) -> Day -> Text
showDate Day
e Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Day -> Text
showDate ([Day] -> Day
forall a. [a] -> a
last [Day]
es)
[Day
e] -> Day -> Text
showDate Day
e
[] -> Text
""
compoundBalanceReportAsText :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> TL.Text
compoundBalanceReportAsText :: ReportOpts
-> CompoundPeriodicReport DisplayName MixedAmount -> Text
compoundBalanceReportAsText ReportOpts
ropts
(CompoundPeriodicReport Text
title [DateSpan]
_colspans [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
subreports (PeriodicReportRow ()
_ [MixedAmount]
coltotals MixedAmount
grandtotal MixedAmount
grandavg)) =
Builder -> Text
TB.toLazyText (Builder -> Text) -> Builder -> Text
forall a b. (a -> b) -> a -> b
$
Text -> Builder
TB.fromText Text
title Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
TB.fromText Text
"\n\n" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>
ReportOpts -> Table Text Text MixedAmount -> Builder
balanceReportTableAsText ReportOpts
ropts Table Text Text MixedAmount
bigtable'
where
bigtable :: Table Text Text MixedAmount
bigtable =
case ((Text, PeriodicReport DisplayName MixedAmount, Bool)
-> Table Text Text MixedAmount)
-> [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
-> [Table Text Text MixedAmount]
forall a b. (a -> b) -> [a] -> [b]
map (ReportOpts
-> (Text, PeriodicReport DisplayName MixedAmount, Bool)
-> Table Text Text MixedAmount
forall c.
ReportOpts
-> (Text, PeriodicReport DisplayName MixedAmount, c)
-> Table Text Text MixedAmount
subreportAsTable ReportOpts
ropts) [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
subreports of
[] -> Table Text Text MixedAmount
forall rh ch a. Table rh ch a
Tab.empty
Table Text Text MixedAmount
r:[Table Text Text MixedAmount]
rs -> (Table Text Text MixedAmount
-> Table Text Text MixedAmount -> Table Text Text MixedAmount)
-> Table Text Text MixedAmount
-> [Table Text Text MixedAmount]
-> Table Text Text MixedAmount
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Table Text Text MixedAmount
-> Table Text Text MixedAmount -> Table Text Text MixedAmount
forall rh ch a ch. Table rh ch a -> Table rh ch a -> Table rh ch a
concatTables Table Text Text MixedAmount
r [Table Text Text MixedAmount]
rs
bigtable' :: Table Text Text MixedAmount
bigtable'
| ReportOpts -> Bool
no_total_ ReportOpts
ropts Bool -> Bool -> Bool
|| [(Text, PeriodicReport DisplayName MixedAmount, Bool)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
subreports Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 =
Table Text Text MixedAmount
bigtable
| Bool
otherwise =
Table Text Text MixedAmount
bigtable
Table Text Text MixedAmount
-> SemiTable Text MixedAmount -> Table Text Text MixedAmount
forall rh ch a. Table rh ch a -> SemiTable rh a -> Table rh ch a
+====+
Text -> [MixedAmount] -> SemiTable Text MixedAmount
forall rh a. rh -> [a] -> SemiTable rh a
row Text
"Net:" (
[MixedAmount]
coltotals
[MixedAmount] -> [MixedAmount] -> [MixedAmount]
forall a. [a] -> [a] -> [a]
++ (if ReportOpts -> Bool
row_total_ ReportOpts
ropts then [MixedAmount
grandtotal] else [])
[MixedAmount] -> [MixedAmount] -> [MixedAmount]
forall a. [a] -> [a] -> [a]
++ (if ReportOpts -> Bool
average_ ReportOpts
ropts then [MixedAmount
grandavg] else [])
)
subreportAsTable :: ReportOpts
-> (Text, PeriodicReport DisplayName MixedAmount, c)
-> Table Text Text MixedAmount
subreportAsTable ReportOpts
ropts (Text
title, PeriodicReport DisplayName MixedAmount
r, c
_) = Table Text Text MixedAmount
t
where
Table Header Text
lefthdrs Header Text
tophdrs [[MixedAmount]]
cells = ReportOpts
-> PeriodicReport DisplayName MixedAmount
-> Table Text Text MixedAmount
balanceReportAsTable ReportOpts
ropts PeriodicReport DisplayName MixedAmount
r
t :: Table Text Text MixedAmount
t = Header Text
-> Header Text -> [[MixedAmount]] -> Table Text Text MixedAmount
forall rh ch a. Header rh -> Header ch -> [[a]] -> Table rh ch a
Table (Properties -> [Header Text] -> Header Text
forall h. Properties -> [Header h] -> Header h
Tab.Group Properties
SingleLine [Text -> Header Text
forall h. h -> Header h
Header Text
title, Header Text
lefthdrs]) Header Text
tophdrs ([][MixedAmount] -> [[MixedAmount]] -> [[MixedAmount]]
forall a. a -> [a] -> [a]
:[[MixedAmount]]
cells)
concatTables :: Table rh ch a -> Table rh ch a -> Table rh ch a
concatTables (Table Header rh
hLeft Header ch
hTop [[a]]
dat) (Table Header rh
hLeft' Header ch
_ [[a]]
dat') =
Header rh -> Header ch -> [[a]] -> Table rh ch a
forall rh ch a. Header rh -> Header ch -> [[a]] -> Table rh ch a
Table (Properties -> [Header rh] -> Header rh
forall h. Properties -> [Header h] -> Header h
Tab.Group Properties
DoubleLine [Header rh
hLeft, Header rh
hLeft']) Header ch
hTop ([[a]]
dat [[a]] -> [[a]] -> [[a]]
forall a. [a] -> [a] -> [a]
++ [[a]]
dat')
compoundBalanceReportAsCsv :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> CSV
compoundBalanceReportAsCsv :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> CSV
compoundBalanceReportAsCsv ReportOpts
ropts (CompoundPeriodicReport Text
title [DateSpan]
colspans [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
subreports (PeriodicReportRow ()
_ [MixedAmount]
coltotals MixedAmount
grandtotal MixedAmount
grandavg)) =
CSV -> CSV
addtotals (CSV -> CSV) -> CSV -> CSV
forall a b. (a -> b) -> a -> b
$
Text -> [Text]
forall a. IsString a => a -> [a]
padRow Text
title
[Text] -> CSV -> CSV
forall a. a -> [a] -> [a]
: ( Text
"Account"
Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
: (DateSpan -> Text) -> [DateSpan] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (BalanceType -> [DateSpan] -> DateSpan -> Text
reportPeriodName (ReportOpts -> BalanceType
balancetype_ ReportOpts
ropts) [DateSpan]
colspans) [DateSpan]
colspans
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (if ReportOpts -> Bool
row_total_ ReportOpts
ropts then [Text
"Total"] else [])
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (if ReportOpts -> Bool
average_ ReportOpts
ropts then [Text
"Average"] else [])
)
[Text] -> CSV -> CSV
forall a. a -> [a] -> [a]
: ((Text, PeriodicReport DisplayName MixedAmount, Bool) -> CSV)
-> [(Text, PeriodicReport DisplayName MixedAmount, Bool)] -> CSV
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (ReportOpts
-> (Text, PeriodicReport DisplayName MixedAmount, Bool) -> CSV
forall c.
ReportOpts
-> (Text, PeriodicReport DisplayName MixedAmount, c) -> CSV
subreportAsCsv ReportOpts
ropts) [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
subreports
where
subreportAsCsv :: ReportOpts
-> (Text, PeriodicReport DisplayName MixedAmount, c) -> CSV
subreportAsCsv ReportOpts
ropts (Text
subreporttitle, PeriodicReport DisplayName MixedAmount
multibalreport, c
_) =
Text -> [Text]
forall a. IsString a => a -> [a]
padRow Text
subreporttitle [Text] -> CSV -> CSV
forall a. a -> [a] -> [a]
:
CSV -> CSV
forall a. [a] -> [a]
tail (ReportOpts -> PeriodicReport DisplayName MixedAmount -> CSV
multiBalanceReportAsCsv ReportOpts
ropts PeriodicReport DisplayName MixedAmount
multibalreport)
padRow :: a -> [a]
padRow a
s = Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
take Int
numcols ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ a
s a -> [a] -> [a]
forall a. a -> [a] -> [a]
: a -> [a]
forall a. a -> [a]
repeat a
""
where
numcols :: Int
numcols
| [(Text, PeriodicReport DisplayName MixedAmount, Bool)] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
subreports = Int
1
| Bool
otherwise =
(Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+) (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$
(if ReportOpts -> Bool
row_total_ ReportOpts
ropts then (Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+) else Int -> Int
forall a. a -> a
id) (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$
(if ReportOpts -> Bool
average_ ReportOpts
ropts then (Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+) else Int -> Int
forall a. a -> a
id) (Int -> Int) -> Int -> Int
forall a b. (a -> b) -> a -> b
$
[Int] -> Int
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ([Int] -> Int) -> [Int] -> Int
forall a b. (a -> b) -> a -> b
$
((Text, PeriodicReport DisplayName MixedAmount, Bool) -> Int)
-> [(Text, PeriodicReport DisplayName MixedAmount, Bool)] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map ([DateSpan] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([DateSpan] -> Int)
-> ((Text, PeriodicReport DisplayName MixedAmount, Bool)
-> [DateSpan])
-> (Text, PeriodicReport DisplayName MixedAmount, Bool)
-> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PeriodicReport DisplayName MixedAmount -> [DateSpan]
forall a b. PeriodicReport a b -> [DateSpan]
prDates (PeriodicReport DisplayName MixedAmount -> [DateSpan])
-> ((Text, PeriodicReport DisplayName MixedAmount, Bool)
-> PeriodicReport DisplayName MixedAmount)
-> (Text, PeriodicReport DisplayName MixedAmount, Bool)
-> [DateSpan]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text, PeriodicReport DisplayName MixedAmount, Bool)
-> PeriodicReport DisplayName MixedAmount
forall a b c. (a, b, c) -> b
second3) [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
subreports
addtotals :: CSV -> CSV
addtotals
| ReportOpts -> Bool
no_total_ ReportOpts
ropts Bool -> Bool -> Bool
|| [(Text, PeriodicReport DisplayName MixedAmount, Bool)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
subreports Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = CSV -> CSV
forall a. a -> a
id
| Bool
otherwise = (CSV -> CSV -> CSV
forall a. [a] -> [a] -> [a]
++
[Text
"Net:" Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:
(MixedAmount -> Text) -> [MixedAmount] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (WideBuilder -> Text
wbToText (WideBuilder -> Text)
-> (MixedAmount -> WideBuilder) -> MixedAmount -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AmountDisplayOpts -> MixedAmount -> WideBuilder
showMixedAmountB AmountDisplayOpts
oneLine) (
[MixedAmount]
coltotals
[MixedAmount] -> [MixedAmount] -> [MixedAmount]
forall a. [a] -> [a] -> [a]
++ (if ReportOpts -> Bool
row_total_ ReportOpts
ropts then [MixedAmount
grandtotal] else [])
[MixedAmount] -> [MixedAmount] -> [MixedAmount]
forall a. [a] -> [a] -> [a]
++ (if ReportOpts -> Bool
average_ ReportOpts
ropts then [MixedAmount
grandavg] else [])
)
])
compoundBalanceReportAsHtml :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> Html ()
compoundBalanceReportAsHtml :: ReportOpts
-> CompoundPeriodicReport DisplayName MixedAmount -> Html ()
compoundBalanceReportAsHtml ReportOpts
ropts CompoundPeriodicReport DisplayName MixedAmount
cbr =
let
CompoundPeriodicReport Text
title [DateSpan]
colspans [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
subreports (PeriodicReportRow ()
_ [MixedAmount]
coltotals MixedAmount
grandtotal MixedAmount
grandavg) = CompoundPeriodicReport DisplayName MixedAmount
cbr
colspanattr :: Attribute
colspanattr = Text -> Attribute
colspan_ (Text -> Attribute) -> Text -> Attribute
forall a b. (a -> b) -> a -> b
$ CommandDoc -> Text
T.pack (CommandDoc -> Text) -> CommandDoc -> Text
forall a b. (a -> b) -> a -> b
$ Int -> CommandDoc
forall a. Show a => a -> CommandDoc
show (Int -> CommandDoc) -> Int -> CommandDoc
forall a b. (a -> b) -> a -> b
$
Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ [DateSpan] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [DateSpan]
colspans Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (if ReportOpts -> Bool
row_total_ ReportOpts
ropts then Int
1 else Int
0) Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (if ReportOpts -> Bool
average_ ReportOpts
ropts then Int
1 else Int
0)
leftattr :: Attribute
leftattr = Text -> Attribute
forall arg result. TermRaw arg result => arg -> result
style_ Text
"text-align:left"
blankrow :: Html ()
blankrow = Html () -> Html ()
forall arg result. Term arg result => arg -> result
tr_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
td_ [Attribute
colspanattr] (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ CommandDoc -> Html ()
forall a (m :: * -> *). (ToHtml a, Monad m) => a -> HtmlT m ()
toHtmlRaw (CommandDoc
" "::String)
titlerows :: [Html ()]
titlerows =
[Html () -> Html ()
forall arg result. Term arg result => arg -> result
tr_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
th_ [Attribute
colspanattr, Attribute
leftattr] (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ Html () -> Html ()
forall arg result. Term arg result => arg -> result
h2_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ Text -> Html ()
forall a (m :: * -> *). (ToHtml a, Monad m) => a -> HtmlT m ()
toHtml Text
title]
[Html ()] -> [Html ()] -> [Html ()]
forall a. [a] -> [a] -> [a]
++ [[Text] -> Html ()
thRow ([Text] -> Html ()) -> [Text] -> Html ()
forall a b. (a -> b) -> a -> b
$
Text
"" Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
:
(DateSpan -> Text) -> [DateSpan] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (BalanceType -> [DateSpan] -> DateSpan -> Text
reportPeriodName (ReportOpts -> BalanceType
balancetype_ ReportOpts
ropts) [DateSpan]
colspans) [DateSpan]
colspans
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (if ReportOpts -> Bool
row_total_ ReportOpts
ropts then [Text
"Total"] else [])
[Text] -> [Text] -> [Text]
forall a. [a] -> [a] -> [a]
++ (if ReportOpts -> Bool
average_ ReportOpts
ropts then [Text
"Average"] else [])
]
thRow :: [T.Text] -> Html ()
thRow :: [Text] -> Html ()
thRow = Html () -> Html ()
forall arg result. Term arg result => arg -> result
tr_ (Html () -> Html ()) -> ([Text] -> Html ()) -> [Text] -> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Html ()] -> Html ()
forall a. Monoid a => [a] -> a
mconcat ([Html ()] -> Html ())
-> ([Text] -> [Html ()]) -> [Text] -> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Html ()) -> [Text] -> [Html ()]
forall a b. (a -> b) -> [a] -> [b]
map (Html () -> Html ()
forall arg result. Term arg result => arg -> result
th_ (Html () -> Html ()) -> (Text -> Html ()) -> Text -> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Html ()
forall a (m :: * -> *). (ToHtml a, Monad m) => a -> HtmlT m ()
toHtml)
subreportrows :: (T.Text, MultiBalanceReport, Bool) -> [Html ()]
subreportrows :: (Text, PeriodicReport DisplayName MixedAmount, Bool) -> [Html ()]
subreportrows (Text
subreporttitle, PeriodicReport DisplayName MixedAmount
mbr, Bool
_increasestotal) =
let
(Html ()
_,[Html ()]
bodyrows,Maybe (Html ())
mtotalsrow) = ReportOpts
-> PeriodicReport DisplayName MixedAmount
-> (Html (), [Html ()], Maybe (Html ()))
multiBalanceReportHtmlRows ReportOpts
ropts PeriodicReport DisplayName MixedAmount
mbr
in
[Html () -> Html ()
forall arg result. Term arg result => arg -> result
tr_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
th_ [Attribute
colspanattr, Attribute
leftattr] (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ Text -> Html ()
forall a (m :: * -> *). (ToHtml a, Monad m) => a -> HtmlT m ()
toHtml Text
subreporttitle]
[Html ()] -> [Html ()] -> [Html ()]
forall a. [a] -> [a] -> [a]
++ [Html ()]
bodyrows
[Html ()] -> [Html ()] -> [Html ()]
forall a. [a] -> [a] -> [a]
++ [Html ()] -> (Html () -> [Html ()]) -> Maybe (Html ()) -> [Html ()]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] (Html () -> [Html ()] -> [Html ()]
forall a. a -> [a] -> [a]
:[]) Maybe (Html ())
mtotalsrow
[Html ()] -> [Html ()] -> [Html ()]
forall a. [a] -> [a] -> [a]
++ [Html ()
blankrow]
totalrows :: [Html ()]
totalrows | ReportOpts -> Bool
no_total_ ReportOpts
ropts Bool -> Bool -> Bool
|| [(Text, PeriodicReport DisplayName MixedAmount, Bool)] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
subreports Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1 = []
| Bool
otherwise =
let defstyle :: Attribute
defstyle = Text -> Attribute
forall arg result. TermRaw arg result => arg -> result
style_ Text
"text-align:right"
orEmpty :: Bool -> p -> p
orEmpty Bool
b p
x = if Bool
b then p
x else p
forall a. Monoid a => a
mempty
in [Html () -> Html ()
forall arg result. Term arg result => arg -> result
tr_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ [Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
th_ [Text -> Attribute
class_ Text
"", Text -> Attribute
forall arg result. TermRaw arg result => arg -> result
style_ Text
"text-align:left"] Html ()
"Net:"
Html () -> Html () -> Html ()
forall a. Semigroup a => a -> a -> a
<> (MixedAmount -> Html ()) -> [MixedAmount] -> Html ()
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ([Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
th_ [Text -> Attribute
class_ Text
"amount coltotal", Attribute
defstyle] (Html () -> Html ())
-> (MixedAmount -> Html ()) -> MixedAmount -> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandDoc -> Html ()
forall a (m :: * -> *). (ToHtml a, Monad m) => a -> HtmlT m ()
toHtml (CommandDoc -> Html ())
-> (MixedAmount -> CommandDoc) -> MixedAmount -> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WideBuilder -> CommandDoc
wbUnpack (WideBuilder -> CommandDoc)
-> (MixedAmount -> WideBuilder) -> MixedAmount -> CommandDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. AmountDisplayOpts -> MixedAmount -> WideBuilder
showMixedAmountB AmountDisplayOpts
oneLine) [MixedAmount]
coltotals
Html () -> Html () -> Html ()
forall a. Semigroup a => a -> a -> a
<> Bool -> Html () -> Html ()
forall p. Monoid p => Bool -> p -> p
orEmpty (ReportOpts -> Bool
row_total_ ReportOpts
ropts) ([Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
th_ [Text -> Attribute
class_ Text
"amount coltotal", Attribute
defstyle] (Html () -> Html ())
-> (WideBuilder -> Html ()) -> WideBuilder -> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandDoc -> Html ()
forall a (m :: * -> *). (ToHtml a, Monad m) => a -> HtmlT m ()
toHtml (CommandDoc -> Html ())
-> (WideBuilder -> CommandDoc) -> WideBuilder -> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WideBuilder -> CommandDoc
wbUnpack (WideBuilder -> Html ()) -> WideBuilder -> Html ()
forall a b. (a -> b) -> a -> b
$ AmountDisplayOpts -> MixedAmount -> WideBuilder
showMixedAmountB AmountDisplayOpts
oneLine MixedAmount
grandtotal)
Html () -> Html () -> Html ()
forall a. Semigroup a => a -> a -> a
<> Bool -> Html () -> Html ()
forall p. Monoid p => Bool -> p -> p
orEmpty (ReportOpts -> Bool
average_ ReportOpts
ropts) ([Attribute] -> Html () -> Html ()
forall arg result. Term arg result => arg -> result
th_ [Text -> Attribute
class_ Text
"amount colaverage", Attribute
defstyle] (Html () -> Html ())
-> (WideBuilder -> Html ()) -> WideBuilder -> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CommandDoc -> Html ()
forall a (m :: * -> *). (ToHtml a, Monad m) => a -> HtmlT m ()
toHtml (CommandDoc -> Html ())
-> (WideBuilder -> CommandDoc) -> WideBuilder -> Html ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WideBuilder -> CommandDoc
wbUnpack (WideBuilder -> Html ()) -> WideBuilder -> Html ()
forall a b. (a -> b) -> a -> b
$ AmountDisplayOpts -> MixedAmount -> WideBuilder
showMixedAmountB AmountDisplayOpts
oneLine MixedAmount
grandavg)
]
in do
Text -> Html ()
forall arg result. TermRaw arg result => arg -> result
style_ ([Text] -> Text
T.unlines [Text
""
,Text
"td { padding:0 0.5em; }"
,Text
"td:nth-child(1) { white-space:nowrap; }"
,Text
"tr:nth-child(even) td { background-color:#eee; }"
])
[Attribute] -> Html ()
forall (m :: * -> *). Applicative m => [Attribute] -> HtmlT m ()
link_ [Text -> Attribute
rel_ Text
"stylesheet", Text -> Attribute
href_ Text
"hledger.css"]
Html () -> Html ()
forall arg result. Term arg result => arg -> result
table_ (Html () -> Html ()) -> Html () -> Html ()
forall a b. (a -> b) -> a -> b
$ [Html ()] -> Html ()
forall a. Monoid a => [a] -> a
mconcat ([Html ()] -> Html ()) -> [Html ()] -> Html ()
forall a b. (a -> b) -> a -> b
$
[Html ()]
titlerows
[Html ()] -> [Html ()] -> [Html ()]
forall a. [a] -> [a] -> [a]
++ [Html ()
blankrow]
[Html ()] -> [Html ()] -> [Html ()]
forall a. [a] -> [a] -> [a]
++ ((Text, PeriodicReport DisplayName MixedAmount, Bool) -> [Html ()])
-> [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
-> [Html ()]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Text, PeriodicReport DisplayName MixedAmount, Bool) -> [Html ()]
subreportrows [(Text, PeriodicReport DisplayName MixedAmount, Bool)]
subreports
[Html ()] -> [Html ()] -> [Html ()]
forall a. [a] -> [a] -> [a]
++ [Html ()]
totalrows