balance: support CSV for multi-column balance reports
This commit is contained in:
parent
9d1ef010ac
commit
21ed3dc73d
@ -242,11 +242,7 @@ module Hledger.Cli.Balance (
|
|||||||
,tests_Hledger_Cli_Balance
|
,tests_Hledger_Cli_Balance
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.List
|
|
||||||
import Data.Maybe
|
|
||||||
-- import System.Console.CmdArgs
|
|
||||||
import System.Console.CmdArgs.Explicit as C
|
import System.Console.CmdArgs.Explicit as C
|
||||||
-- import System.Console.CmdArgs.Text
|
|
||||||
import Text.CSV
|
import Text.CSV
|
||||||
import Test.HUnit
|
import Test.HUnit
|
||||||
import Text.Printf (printf)
|
import Text.Printf (printf)
|
||||||
@ -254,8 +250,6 @@ import Text.Tabular as T
|
|||||||
import Text.Tabular.AsciiArt
|
import Text.Tabular.AsciiArt
|
||||||
|
|
||||||
import Hledger
|
import Hledger
|
||||||
import Prelude hiding (putStr)
|
|
||||||
import Hledger.Utils.UTF8IOCompat (putStr)
|
|
||||||
import Hledger.Data.OutputFormat
|
import Hledger.Data.OutputFormat
|
||||||
import Hledger.Cli.Options
|
import Hledger.Cli.Options
|
||||||
import Hledger.Cli.Utils
|
import Hledger.Cli.Utils
|
||||||
@ -287,34 +281,43 @@ balance :: CliOpts -> Journal -> IO ()
|
|||||||
balance opts@CliOpts{reportopts_=ropts} j = do
|
balance opts@CliOpts{reportopts_=ropts} j = do
|
||||||
d <- getCurrentDay
|
d <- getCurrentDay
|
||||||
case lineFormatFromOpts ropts of
|
case lineFormatFromOpts ropts of
|
||||||
Left err -> putStr $ unlines [err]
|
Left err -> error' $ unlines [err]
|
||||||
Right _ -> do
|
Right _ -> do
|
||||||
let fmt = outputFormatFromOpts opts
|
let format = outputFormatFromOpts opts
|
||||||
case intervalFromOpts ropts of
|
interval = intervalFromOpts ropts
|
||||||
|
baltype = balancetype_ ropts
|
||||||
|
case interval of
|
||||||
NoInterval -> do
|
NoInterval -> do
|
||||||
let render | fmt=="csv" = \_ r -> printCSV (balanceReportAsCsv ropts r) ++ "\n"
|
let report = balanceReport ropts (queryFromOpts d ropts) j
|
||||||
| otherwise = \ropts r -> unlines $ balanceReportAsText ropts r
|
render = case format of
|
||||||
writeOutput opts $ render ropts $ balanceReport ropts (queryFromOpts d ropts) j
|
"csv" -> \ropts r -> (++ "\n") $ printCSV $ balanceReportAsCsv ropts r
|
||||||
|
_ -> balanceReportAsText
|
||||||
_ ->
|
writeOutput opts $ render ropts report
|
||||||
if fmt=="csv"
|
_ -> do
|
||||||
then error' "Sorry, CSV output with a report period is not supported yet"
|
let report = multiBalanceReport ropts (queryFromOpts d ropts) j
|
||||||
else do
|
render = case format of
|
||||||
let render = case balancetype_ ropts of
|
"csv" -> \ropts r -> (++ "\n") $ printCSV $ multiBalanceReportAsCsv ropts r
|
||||||
|
_ -> case baltype of
|
||||||
PeriodBalance -> periodBalanceReportAsText
|
PeriodBalance -> periodBalanceReportAsText
|
||||||
CumulativeBalance -> cumulativeBalanceReportAsText
|
CumulativeBalance -> cumulativeBalanceReportAsText
|
||||||
HistoricalBalance -> historicalBalanceReportAsText
|
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.
|
-- | Render a single-column balance report as CSV.
|
||||||
balanceReportAsCsv :: ReportOpts -> BalanceReport -> CSV
|
balanceReportAsCsv :: ReportOpts -> BalanceReport -> CSV
|
||||||
balanceReportAsCsv _ (items,_) =
|
balanceReportAsCsv opts (items, total) =
|
||||||
["account","balance"] :
|
["account","balance"] :
|
||||||
[[a, showMixedAmountWithoutPrice b] | ((a, _, _), b) <- items]
|
[[a, showMixedAmountWithoutPrice b] | ((a, _, _), b) <- items]
|
||||||
|
++
|
||||||
|
if no_total_ opts
|
||||||
|
then []
|
||||||
|
else [["total", showMixedAmountOneLineWithoutPrice total]]
|
||||||
|
|
||||||
-- | Render a single-column balance report as plain text.
|
-- | Render a single-column balance report as plain text.
|
||||||
balanceReportAsText :: ReportOpts -> BalanceReport -> [String]
|
balanceReportAsText :: ReportOpts -> BalanceReport -> String
|
||||||
balanceReportAsText opts ((items, total)) = concat lines ++ t
|
balanceReportAsText opts ((items, total)) = unlines $ concat lines ++ t
|
||||||
where
|
where
|
||||||
lines = case lineFormatFromOpts opts of
|
lines = case lineFormatFromOpts opts of
|
||||||
Right f -> map (balanceReportItemAsText opts f) items
|
Right f -> map (balanceReportItemAsText opts f) items
|
||||||
@ -333,6 +336,7 @@ tests_balanceReportAsText = [
|
|||||||
"2009/01/01 * медвежья шкура\n расходы:покупки 100\n актив:наличные\n"
|
"2009/01/01 * медвежья шкура\n расходы:покупки 100\n актив:наличные\n"
|
||||||
let opts = defreportopts
|
let opts = defreportopts
|
||||||
balanceReportAsText opts (balanceReport opts (queryFromOpts (parsedate "2008/11/26") opts) j) `is`
|
balanceReportAsText opts (balanceReport opts (queryFromOpts (parsedate "2008/11/26") opts) j) `is`
|
||||||
|
unlines
|
||||||
[" -100 актив:наличные"
|
[" -100 актив:наличные"
|
||||||
," 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
|
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.
|
-- | 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)) =
|
periodBalanceReportAsText opts r@(MultiBalanceReport (colspans, items, coltotals)) =
|
||||||
|
unlines $
|
||||||
([printf "Balance changes in %s:" (showDateSpan $ multiBalanceReportSpan r)] ++) $
|
([printf "Balance changes in %s:" (showDateSpan $ multiBalanceReportSpan r)] ++) $
|
||||||
trimborder $ lines $
|
trimborder $ lines $
|
||||||
render
|
render
|
||||||
@ -413,8 +430,9 @@ periodBalanceReportAsText opts r@(MultiBalanceReport (colspans, items, coltotals
|
|||||||
| otherwise = row "" coltotals
|
| otherwise = row "" coltotals
|
||||||
|
|
||||||
-- | Render a multi-column cumulative balance report as plain text suitable for console output.
|
-- | 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)) =
|
cumulativeBalanceReportAsText opts r@(MultiBalanceReport (colspans, items, coltotals)) =
|
||||||
|
unlines $
|
||||||
([printf "Ending balances (cumulative) in %s:" (showDateSpan $ multiBalanceReportSpan r)] ++) $
|
([printf "Ending balances (cumulative) in %s:" (showDateSpan $ multiBalanceReportSpan r)] ++) $
|
||||||
trimborder $ lines $
|
trimborder $ lines $
|
||||||
render id ((" "++) . maybe "" (showDate . prevday) . spanEnd) showMixedAmountOneLineWithoutPrice $
|
render id ((" "++) . maybe "" (showDate . prevday) . spanEnd) showMixedAmountOneLineWithoutPrice $
|
||||||
@ -434,8 +452,9 @@ cumulativeBalanceReportAsText opts r@(MultiBalanceReport (colspans, items, colto
|
|||||||
| otherwise = (+----+ row "" coltotals)
|
| otherwise = (+----+ row "" coltotals)
|
||||||
|
|
||||||
-- | Render a multi-column historical balance report as plain text suitable for console output.
|
-- | 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)) =
|
historicalBalanceReportAsText opts r@(MultiBalanceReport (colspans, items, coltotals)) =
|
||||||
|
unlines $
|
||||||
([printf "Ending balances (historical) in %s:" (showDateSpan $ multiBalanceReportSpan r)] ++) $
|
([printf "Ending balances (historical) in %s:" (showDateSpan $ multiBalanceReportSpan r)] ++) $
|
||||||
trimborder $ lines $
|
trimborder $ lines $
|
||||||
render id ((" "++) . maybe "" (showDate . prevday) . spanEnd) showMixedAmountOneLineWithoutPrice $
|
render id ((" "++) . maybe "" (showDate . prevday) . spanEnd) showMixedAmountOneLineWithoutPrice $
|
||||||
|
|||||||
@ -47,9 +47,9 @@ balancesheet CliOpts{reportopts_=ropts} j = do
|
|||||||
LT.putStr $ [lt|Balance Sheet
|
LT.putStr $ [lt|Balance Sheet
|
||||||
|
|
||||||
Assets:
|
Assets:
|
||||||
#{unlines $ balanceReportAsText ropts assetreport}
|
#{balanceReportAsText ropts assetreport}
|
||||||
Liabilities:
|
Liabilities:
|
||||||
#{unlines $ balanceReportAsText ropts liabilityreport}
|
#{balanceReportAsText ropts liabilityreport}
|
||||||
Total:
|
Total:
|
||||||
--------------------
|
--------------------
|
||||||
#{padleft 20 $ showMixedAmountWithoutPrice total}
|
#{padleft 20 $ showMixedAmountWithoutPrice total}
|
||||||
|
|||||||
@ -51,7 +51,7 @@ cashflow CliOpts{reportopts_=ropts} j = do
|
|||||||
LT.putStr $ [lt|Cashflow Statement
|
LT.putStr $ [lt|Cashflow Statement
|
||||||
|
|
||||||
Cash flows:
|
Cash flows:
|
||||||
#{unlines $ balanceReportAsText ropts cashreport}
|
#{balanceReportAsText ropts cashreport}
|
||||||
Total:
|
Total:
|
||||||
--------------------
|
--------------------
|
||||||
#{padleft 20 $ showMixedAmountWithoutPrice total}
|
#{padleft 20 $ showMixedAmountWithoutPrice total}
|
||||||
|
|||||||
@ -46,9 +46,9 @@ incomestatement CliOpts{reportopts_=ropts} j = do
|
|||||||
LT.putStr $ [lt|Income Statement
|
LT.putStr $ [lt|Income Statement
|
||||||
|
|
||||||
Revenues:
|
Revenues:
|
||||||
#{unlines $ balanceReportAsText ropts incomereport}
|
#{balanceReportAsText ropts incomereport}
|
||||||
Expenses:
|
Expenses:
|
||||||
#{unlines $ balanceReportAsText ropts expensereport}
|
#{balanceReportAsText ropts expensereport}
|
||||||
Total:
|
Total:
|
||||||
--------------------
|
--------------------
|
||||||
#{padleft 20 $ showMixedAmountWithoutPrice total}
|
#{padleft 20 $ showMixedAmountWithoutPrice total}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user