balance: support CSV for multi-column balance reports

This commit is contained in:
Simon Michael 2014-10-23 05:11:48 -07:00
parent 9d1ef010ac
commit 21ed3dc73d
4 changed files with 49 additions and 30 deletions

View File

@ -242,11 +242,7 @@ module Hledger.Cli.Balance (
,tests_Hledger_Cli_Balance
) where
import Data.List
import Data.Maybe
-- import System.Console.CmdArgs
import System.Console.CmdArgs.Explicit as C
-- import System.Console.CmdArgs.Text
import Text.CSV
import Test.HUnit
import Text.Printf (printf)
@ -254,8 +250,6 @@ import Text.Tabular as T
import Text.Tabular.AsciiArt
import Hledger
import Prelude hiding (putStr)
import Hledger.Utils.UTF8IOCompat (putStr)
import Hledger.Data.OutputFormat
import Hledger.Cli.Options
import Hledger.Cli.Utils
@ -287,34 +281,43 @@ balance :: CliOpts -> Journal -> IO ()
balance opts@CliOpts{reportopts_=ropts} j = do
d <- getCurrentDay
case lineFormatFromOpts ropts of
Left err -> putStr $ unlines [err]
Left err -> error' $ unlines [err]
Right _ -> do
let fmt = outputFormatFromOpts opts
case intervalFromOpts ropts of
let format = outputFormatFromOpts opts
interval = intervalFromOpts ropts
baltype = balancetype_ ropts
case interval of
NoInterval -> do
let render | fmt=="csv" = \_ r -> printCSV (balanceReportAsCsv ropts r) ++ "\n"
| otherwise = \ropts r -> unlines $ balanceReportAsText ropts r
writeOutput opts $ render ropts $ balanceReport ropts (queryFromOpts d ropts) j
_ ->
if fmt=="csv"
then error' "Sorry, CSV output with a report period is not supported yet"
else do
let render = case balancetype_ ropts of
let report = balanceReport ropts (queryFromOpts d ropts) j
render = case format of
"csv" -> \ropts r -> (++ "\n") $ printCSV $ balanceReportAsCsv ropts r
_ -> balanceReportAsText
writeOutput opts $ render ropts report
_ -> do
let report = multiBalanceReport ropts (queryFromOpts d ropts) j
render = case format of
"csv" -> \ropts r -> (++ "\n") $ printCSV $ multiBalanceReportAsCsv ropts r
_ -> case baltype of
PeriodBalance -> periodBalanceReportAsText
CumulativeBalance -> cumulativeBalanceReportAsText
HistoricalBalance -> historicalBalanceReportAsText
writeOutput opts $ unlines $ render ropts $ multiBalanceReport ropts (queryFromOpts d ropts) j
writeOutput opts $ render ropts report
-- single-column balance reports
-- | Render a single-column balance report as CSV.
balanceReportAsCsv :: ReportOpts -> BalanceReport -> CSV
balanceReportAsCsv _ (items,_) =
balanceReportAsCsv opts (items, total) =
["account","balance"] :
[[a, showMixedAmountWithoutPrice b] | ((a, _, _), b) <- items]
++
if no_total_ opts
then []
else [["total", showMixedAmountOneLineWithoutPrice total]]
-- | Render a single-column balance report as plain text.
balanceReportAsText :: ReportOpts -> BalanceReport -> [String]
balanceReportAsText opts ((items, total)) = concat lines ++ t
balanceReportAsText :: ReportOpts -> BalanceReport -> String
balanceReportAsText opts ((items, total)) = unlines $ concat lines ++ t
where
lines = case lineFormatFromOpts opts of
Right f -> map (balanceReportItemAsText opts f) items
@ -333,6 +336,7 @@ tests_balanceReportAsText = [
"2009/01/01 * медвежья шкура\n расходы:покупки 100\n актив:наличные\n"
let opts = defreportopts
balanceReportAsText opts (balanceReport opts (queryFromOpts (parsedate "2008/11/26") opts) j) `is`
unlines
[" -100 актив:наличные"
," 100 расходы:покупки"
,"--------------------"
@ -385,9 +389,22 @@ formatField opts accountName depth total ljust min max field = case field of
TotalField -> formatValue ljust min max $ showAmountWithoutPrice total
_ -> ""
-- multi-column balance reports
-- | Render a multi-column balance report as CSV.
multiBalanceReportAsCsv :: ReportOpts -> MultiBalanceReport -> CSV
multiBalanceReportAsCsv opts (MultiBalanceReport (colspans, items, coltotals)) =
("account" : "short account" : "indent" : map showDateSpan colspans) :
[a : a' : show i : map showMixedAmountOneLineWithoutPrice amts | ((a,a',i), amts) <- items]
++
if no_total_ opts
then []
else [["totals", "", ""] ++ map showMixedAmountOneLineWithoutPrice coltotals]
-- | Render a multi-column period balance report as plain text suitable for console output.
periodBalanceReportAsText :: ReportOpts -> MultiBalanceReport -> [String]
periodBalanceReportAsText :: ReportOpts -> MultiBalanceReport -> String
periodBalanceReportAsText opts r@(MultiBalanceReport (colspans, items, coltotals)) =
unlines $
([printf "Balance changes in %s:" (showDateSpan $ multiBalanceReportSpan r)] ++) $
trimborder $ lines $
render
@ -413,8 +430,9 @@ periodBalanceReportAsText opts r@(MultiBalanceReport (colspans, items, coltotals
| otherwise = row "" coltotals
-- | Render a multi-column cumulative balance report as plain text suitable for console output.
cumulativeBalanceReportAsText :: ReportOpts -> MultiBalanceReport -> [String]
cumulativeBalanceReportAsText :: ReportOpts -> MultiBalanceReport -> String
cumulativeBalanceReportAsText opts r@(MultiBalanceReport (colspans, items, coltotals)) =
unlines $
([printf "Ending balances (cumulative) in %s:" (showDateSpan $ multiBalanceReportSpan r)] ++) $
trimborder $ lines $
render id ((" "++) . maybe "" (showDate . prevday) . spanEnd) showMixedAmountOneLineWithoutPrice $
@ -434,8 +452,9 @@ cumulativeBalanceReportAsText opts r@(MultiBalanceReport (colspans, items, colto
| otherwise = (+----+ row "" coltotals)
-- | Render a multi-column historical balance report as plain text suitable for console output.
historicalBalanceReportAsText :: ReportOpts -> MultiBalanceReport -> [String]
historicalBalanceReportAsText :: ReportOpts -> MultiBalanceReport -> String
historicalBalanceReportAsText opts r@(MultiBalanceReport (colspans, items, coltotals)) =
unlines $
([printf "Ending balances (historical) in %s:" (showDateSpan $ multiBalanceReportSpan r)] ++) $
trimborder $ lines $
render id ((" "++) . maybe "" (showDate . prevday) . spanEnd) showMixedAmountOneLineWithoutPrice $

View File

@ -47,9 +47,9 @@ balancesheet CliOpts{reportopts_=ropts} j = do
LT.putStr $ [lt|Balance Sheet
Assets:
#{unlines $ balanceReportAsText ropts assetreport}
#{balanceReportAsText ropts assetreport}
Liabilities:
#{unlines $ balanceReportAsText ropts liabilityreport}
#{balanceReportAsText ropts liabilityreport}
Total:
--------------------
#{padleft 20 $ showMixedAmountWithoutPrice total}

View File

@ -51,7 +51,7 @@ cashflow CliOpts{reportopts_=ropts} j = do
LT.putStr $ [lt|Cashflow Statement
Cash flows:
#{unlines $ balanceReportAsText ropts cashreport}
#{balanceReportAsText ropts cashreport}
Total:
--------------------
#{padleft 20 $ showMixedAmountWithoutPrice total}

View File

@ -46,9 +46,9 @@ incomestatement CliOpts{reportopts_=ropts} j = do
LT.putStr $ [lt|Income Statement
Revenues:
#{unlines $ balanceReportAsText ropts incomereport}
#{balanceReportAsText ropts incomereport}
Expenses:
#{unlines $ balanceReportAsText ropts expensereport}
#{balanceReportAsText ropts expensereport}
Total:
--------------------
#{padleft 20 $ showMixedAmountWithoutPrice total}