bal: support CSV output for --budget reports (#1155)

This commit is contained in:
Simon Michael 2020-11-18 13:23:31 -08:00
parent 211ae7742c
commit 5bb9006b6c
4 changed files with 74 additions and 2 deletions

View File

@ -18,6 +18,7 @@ module Hledger.Reports.BudgetReport (
budgetReport, budgetReport,
budgetReportAsTable, budgetReportAsTable,
budgetReportAsText, budgetReportAsText,
budgetReportAsCsv,
-- * Helpers -- * Helpers
reportPeriodName, reportPeriodName,
-- * Tests -- * Tests
@ -44,12 +45,14 @@ import qualified Data.Text as T
--import qualified Data.Text.Lazy as TL --import qualified Data.Text.Lazy as TL
--import System.Console.CmdArgs.Explicit as C --import System.Console.CmdArgs.Explicit as C
--import Lucid as L --import Lucid as L
import Text.Printf (printf) import Text.Printf (printf)
import Text.Tabular as T import Text.Tabular as T
import Text.Tabular.AsciiWide as T import Text.Tabular.AsciiWide as T
import Hledger.Data import Hledger.Data
import Hledger.Utils import Hledger.Utils
import Hledger.Read.CsvReader (CSV)
import Hledger.Reports.ReportOptions import Hledger.Reports.ReportOptions
import Hledger.Reports.ReportTypes import Hledger.Reports.ReportTypes
import Hledger.Reports.MultiBalanceReport import Hledger.Reports.MultiBalanceReport
@ -335,6 +338,45 @@ reportPeriodName balancetype spans =
multiyear = (>1) $ length $ nubSort $ map spanStartYear spans multiyear = (>1) $ length $ nubSort $ map spanStartYear spans
_ -> maybe "" (showDate . prevday) . spanEnd _ -> maybe "" (showDate . prevday) . spanEnd
-- XXX generalise this with multiBalanceReportAsCsv ?
-- | Render a budget report as CSV. Like multiBalanceReportAsCsv,
-- but includes alternating actual and budget amount columns.
budgetReportAsCsv :: ReportOpts -> BudgetReport -> CSV
budgetReportAsCsv
ReportOpts{average_, row_total_, no_total_, transpose_}
(PeriodicReport colspans items (PeriodicReportRow _ abtotals (magrandtot,mbgrandtot) (magrandavg,mbgrandavg)))
= (if transpose_ then transpose else id) $
-- heading row
("Account" :
concatMap (\span -> [showDateSpan span, "budget"]) colspans
++ concat [["Total" ,"budget"] | row_total_]
++ concat [["Average","budget"] | average_]
) :
-- account rows
[T.unpack (displayFull a) :
map showmamt (flattentuples abamts)
++ concat [[showmamt mactualrowtot, showmamt mbudgetrowtot] | row_total_]
++ concat [[showmamt mactualrowavg, showmamt mbudgetrowavg] | average_]
| PeriodicReportRow a abamts (mactualrowtot,mbudgetrowtot) (mactualrowavg,mbudgetrowavg) <- items
]
-- totals row
++ concat [
[
"Total:" :
map showmamt (flattentuples abtotals)
++ concat [[showmamt magrandtot,showmamt mbgrandtot] | row_total_]
++ concat [[showmamt magrandavg,showmamt mbgrandavg] | average_]
]
| not no_total_
]
where
flattentuples abs = concat [[a,b] | (a,b) <- abs]
showmamt = maybe "" (showMixedAmountOneLineWithoutPrice False)
-- tests -- tests
tests_BudgetReport = tests "BudgetReport" [ tests_BudgetReport = tests "BudgetReport" [

View File

@ -273,6 +273,7 @@ import Hledger
import Hledger.Cli.CliOptions import Hledger.Cli.CliOptions
import Hledger.Cli.Utils import Hledger.Cli.Utils
import Hledger.Read.CsvReader (CSV, printCSV) import Hledger.Read.CsvReader (CSV, printCSV)
import Hledger.Reports.BudgetReport (budgetReportAsCsv)
-- | Command line options for this command. -- | Command line options for this command.
@ -322,6 +323,7 @@ balance opts@CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do
render = case fmt of render = case fmt of
"txt" -> budgetReportAsText ropts "txt" -> budgetReportAsText ropts
"json" -> (++"\n") . TL.unpack . toJsonText "json" -> (++"\n") . TL.unpack . toJsonText
"csv" -> (++"\n") . printCSV . budgetReportAsCsv ropts
_ -> const $ error' $ unsupportedOutputFormatError fmt _ -> const $ error' $ unsupportedOutputFormatError fmt
writeOutput opts $ render budgetreport writeOutput opts $ render budgetreport
@ -345,6 +347,10 @@ balance opts@CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do
_ -> const $ error' $ unsupportedOutputFormatError fmt -- PARTIAL: _ -> const $ error' $ unsupportedOutputFormatError fmt -- PARTIAL:
writeOutput opts $ render ropts report writeOutput opts $ render ropts report
-- XXX should all the per-report, per-format rendering code live in the command module,
-- like the below, or in the report module, like budgetReportAsText/budgetReportAsCsv ?
-- rendering single-column balance reports -- rendering single-column balance reports
-- | Render a single-column balance report as CSV. -- | Render a single-column balance report as CSV.

View File

@ -531,4 +531,4 @@ This command also supports the
[output destination](hledger.html#output-destination) and [output destination](hledger.html#output-destination) and
[output format](hledger.html#output-format) options [output format](hledger.html#output-format) options
The output formats supported are The output formats supported are
`txt`, `csv`, (multicolumn non-budget reports only) `html`, and (experimental) `json`. `txt`, `csv`, `html`, and `json`.

View File

@ -515,7 +515,7 @@ Budget performance in 2019-01-01..2019-01-02:
------------------++------------------------ ------------------++------------------------
|| 0 [ 0] || 0 [ 0]
# 25. -E shows d # 25. -E shows d and e
$ hledger bal -f- --budget -E $ hledger bal -f- --budget -E
Budget performance in 2019-01-01..2019-01-02: Budget performance in 2019-01-01..2019-01-02:
@ -532,3 +532,27 @@ Budget performance in 2019-01-01..2019-01-02:
------------------++------------------------ ------------------++------------------------
|| 0 [ 0] || 0 [ 0]
# 26. The totals row shows correct totals.
# -T/--total and -A/--average adds those columns.
$ hledger bal -f- --budget -TA not:income
Budget performance in 2019-01-01..2019-01-02:
|| 2019-01-01..2019-01-02 Total Average
==================++==============================================================
expenses:bills || $80 [22% of $370] $80 [22% of $370] $80 [22% of $370]
expenses:bills:a || $10 [50% of $20] $10 [50% of $20] $10 [50% of $20]
expenses:bills:b || $40 [20% of $200] $40 [20% of $200] $40 [20% of $200]
expenses:bills:c || 0 [ 0% of $50] 0 [ 0% of $50] 0 [ 0% of $50]
expenses:bills:f || $10 [ 0] $10 [ 0] $10 [ 0]
------------------++--------------------------------------------------------------
|| $80 [22% of $370] $80 [22% of $370] $80 [22% of $370]
# 27. CSV output works.
$ hledger bal -f- --budget -TA not:income -O csv
"Account","2019-01-01..2019-01-02","budget","Total","budget","Average","budget"
"expenses:bills","$80","$370","$80","$370","$80","$370"
"expenses:bills:a","$10","$20","$10","$20","$10","$20"
"expenses:bills:b","$40","$200","$40","$200","$40","$200"
"expenses:bills:c","","$50","","$50","","$50"
"expenses:bills:f","$10","0","$10","0","$10","0"
"Total:","$80","$370","$80","$370","$80","$370"