bal: support CSV output for --budget reports (#1155)
This commit is contained in:
parent
211ae7742c
commit
5bb9006b6c
@ -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" [
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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`.
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user