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