mirror of
https://github.com/simonmichael/hledger.git
synced 2025-01-01 14:54:28 +03:00
imp: csv: Allow for generating tidy csv with --layout=tidy.
This puts every date in a separate row, which is more suitable for many graphing programs.
This commit is contained in:
parent
3884f90cc6
commit
7ccf7430d0
@ -112,6 +112,7 @@ instance Default AccountListMode where def = ALFlat
|
|||||||
data Layout = LayoutWide (Maybe Int)
|
data Layout = LayoutWide (Maybe Int)
|
||||||
| LayoutTall
|
| LayoutTall
|
||||||
| LayoutBare
|
| LayoutBare
|
||||||
|
| LayoutTidy
|
||||||
deriving (Eq, Show)
|
deriving (Eq, Show)
|
||||||
|
|
||||||
-- | Standard options for customising report filtering and output.
|
-- | Standard options for customising report filtering and output.
|
||||||
@ -348,6 +349,7 @@ layoutopt rawopts = fromMaybe (LayoutWide Nothing) $ layout <|> column
|
|||||||
checkNames = [ ("wide", LayoutWide w)
|
checkNames = [ ("wide", LayoutWide w)
|
||||||
, ("tall", LayoutTall)
|
, ("tall", LayoutTall)
|
||||||
, ("bare", LayoutBare)
|
, ("bare", LayoutBare)
|
||||||
|
, ("tidy", LayoutTidy)
|
||||||
]
|
]
|
||||||
-- For `--layout=elided,n`, elide to the given width
|
-- For `--layout=elided,n`, elide to the given width
|
||||||
(s,n) = break (==',') $ map toLower opt
|
(s,n) = break (==',') $ map toLower opt
|
||||||
@ -356,7 +358,7 @@ layoutopt rawopts = fromMaybe (LayoutWide Nothing) $ layout <|> column
|
|||||||
c | Just w <- readMay c -> Just w
|
c | Just w <- readMay c -> Just w
|
||||||
_ -> usageError "width in --layout=wide,WIDTH must be an integer"
|
_ -> usageError "width in --layout=wide,WIDTH must be an integer"
|
||||||
|
|
||||||
err = usageError "--layout's argument should be \"wide[,WIDTH]\", \"tall\", or \"bare\""
|
err = usageError "--layout's argument should be \"wide[,WIDTH]\", \"tall\", \"bare\", or \"tidy\""
|
||||||
|
|
||||||
-- Get the period specified by any -b/--begin, -e/--end and/or -p/--period
|
-- Get the period specified by any -b/--begin, -e/--end and/or -p/--period
|
||||||
-- options appearing in the command line.
|
-- options appearing in the command line.
|
||||||
|
@ -525,13 +525,17 @@ multiBalanceReportAsCsv opts@ReportOpts{..} =
|
|||||||
|
|
||||||
multiBalanceReportAsCsv' :: ReportOpts -> MultiBalanceReport -> (CSV, CSV)
|
multiBalanceReportAsCsv' :: ReportOpts -> MultiBalanceReport -> (CSV, CSV)
|
||||||
multiBalanceReportAsCsv' opts@ReportOpts{..} (PeriodicReport colspans items tr) =
|
multiBalanceReportAsCsv' opts@ReportOpts{..} (PeriodicReport colspans items tr) =
|
||||||
( ("account" : ["commodity" | layout_ == LayoutBare] ++ map showDateSpan colspans
|
( headers : concatMap (fullRowAsTexts (accountNameDrop drop_ . prrFullName)) items
|
||||||
++ ["total" | row_total_]
|
, totalrows
|
||||||
++ ["average" | average_]
|
)
|
||||||
) : concatMap (fullRowAsTexts (accountNameDrop drop_ . prrFullName)) items
|
|
||||||
, totalrows)
|
|
||||||
where
|
where
|
||||||
fullRowAsTexts render row = (render row :) <$> multiBalanceRowAsCsvText opts row
|
headers = "account" : case layout_ of
|
||||||
|
LayoutTidy -> ["date", "commodity", "value"]
|
||||||
|
LayoutBare -> "commodity" : dateHeaders
|
||||||
|
_ -> dateHeaders
|
||||||
|
dateHeaders = map showDateSpan colspans ++ ["total" | row_total_] ++ ["average" | average_]
|
||||||
|
|
||||||
|
fullRowAsTexts render row = map (render row :) $ multiBalanceRowAsCsvText opts colspans row
|
||||||
totalrows
|
totalrows
|
||||||
| no_total_ = mempty
|
| no_total_ = mempty
|
||||||
| otherwise = fullRowAsTexts (const "total") tr
|
| otherwise = fullRowAsTexts (const "total") tr
|
||||||
@ -692,8 +696,8 @@ balanceReportAsTable opts@ReportOpts{average_, row_total_, balanceaccum_}
|
|||||||
maybetranspose | transpose_ opts = \(Table rh ch vals) -> Table ch rh (transpose vals)
|
maybetranspose | transpose_ opts = \(Table rh ch vals) -> Table ch rh (transpose vals)
|
||||||
| otherwise = id
|
| otherwise = id
|
||||||
|
|
||||||
multiBalanceRowAsWbs :: AmountDisplayOpts -> ReportOpts -> PeriodicReportRow a MixedAmount -> [[WideBuilder]]
|
multiBalanceRowAsWbs :: AmountDisplayOpts -> ReportOpts -> [DateSpan] -> PeriodicReportRow a MixedAmount -> [[WideBuilder]]
|
||||||
multiBalanceRowAsWbs bopts ReportOpts{..} (PeriodicReportRow _ as rowtot rowavg) =
|
multiBalanceRowAsWbs bopts ReportOpts{..} colspans (PeriodicReportRow _ as rowtot rowavg) =
|
||||||
case layout_ of
|
case layout_ of
|
||||||
LayoutWide width -> [fmap (showMixedAmountB bopts{displayMaxWidth=width}) all]
|
LayoutWide width -> [fmap (showMixedAmountB bopts{displayMaxWidth=width}) all]
|
||||||
LayoutTall -> paddedTranspose mempty
|
LayoutTall -> paddedTranspose mempty
|
||||||
@ -703,12 +707,20 @@ multiBalanceRowAsWbs bopts ReportOpts{..} (PeriodicReportRow _ as rowtot rowavg)
|
|||||||
. transpose -- each row becomes a list of Text quantities
|
. transpose -- each row becomes a list of Text quantities
|
||||||
. fmap (showMixedAmountLinesB bopts{displayOrder=Just cs, displayMinWidth=Nothing})
|
. fmap (showMixedAmountLinesB bopts{displayOrder=Just cs, displayMinWidth=Nothing})
|
||||||
$ all
|
$ all
|
||||||
|
LayoutTidy -> concat
|
||||||
|
. zipWith (\d -> map (wbFromText d :)) dates
|
||||||
|
. fmap ( zipWith (\c a -> [wbFromText c, a]) cs
|
||||||
|
. showMixedAmountLinesB bopts{displayOrder=Just cs, displayMinWidth=Nothing})
|
||||||
|
$ all
|
||||||
where
|
where
|
||||||
totalscolumn = row_total_ && balanceaccum_ `notElem` [Cumulative, Historical]
|
totalscolumn = row_total_ && balanceaccum_ `notElem` [Cumulative, Historical]
|
||||||
cs = S.toList . foldl' S.union mempty $ fmap maCommodities all
|
cs = S.toList . foldl' S.union mempty $ fmap maCommodities all
|
||||||
all = as
|
all = as
|
||||||
++ [rowtot | totalscolumn && not (null as)]
|
++ [rowtot | totalscolumn && not (null as)]
|
||||||
++ [rowavg | average_ && not (null as)]
|
++ [rowavg | average_ && not (null as)]
|
||||||
|
dates = map showDateSpan colspans
|
||||||
|
++ ["Total" | totalscolumn && not (null as)]
|
||||||
|
++ ["Average" | average_ && not (null as)]
|
||||||
|
|
||||||
paddedTranspose :: a -> [[a]] -> [[a]]
|
paddedTranspose :: a -> [[a]] -> [[a]]
|
||||||
paddedTranspose _ [] = [[]]
|
paddedTranspose _ [] = [[]]
|
||||||
@ -724,11 +736,11 @@ multiBalanceRowAsWbs bopts ReportOpts{..} (PeriodicReportRow _ as rowtot rowavg)
|
|||||||
m (x:xs) = x:xs
|
m (x:xs) = x:xs
|
||||||
m [] = [n]
|
m [] = [n]
|
||||||
|
|
||||||
multiBalanceRowAsCsvText :: ReportOpts -> PeriodicReportRow a MixedAmount -> [[T.Text]]
|
multiBalanceRowAsCsvText :: ReportOpts -> [DateSpan] -> PeriodicReportRow a MixedAmount -> [[T.Text]]
|
||||||
multiBalanceRowAsCsvText opts = fmap (fmap wbToText) . multiBalanceRowAsWbs (balanceOpts False opts) opts
|
multiBalanceRowAsCsvText opts colspans = fmap (fmap wbToText) . multiBalanceRowAsWbs (balanceOpts False opts) opts colspans
|
||||||
|
|
||||||
multiBalanceRowAsTableText :: ReportOpts -> PeriodicReportRow a MixedAmount -> [[WideBuilder]]
|
multiBalanceRowAsTableText :: ReportOpts -> PeriodicReportRow a MixedAmount -> [[WideBuilder]]
|
||||||
multiBalanceRowAsTableText opts = multiBalanceRowAsWbs (balanceOpts True opts) opts
|
multiBalanceRowAsTableText opts = multiBalanceRowAsWbs (balanceOpts True opts) opts []
|
||||||
|
|
||||||
-- | Amount display options to use for balance reports
|
-- | Amount display options to use for balance reports
|
||||||
balanceOpts :: Bool -> ReportOpts -> AmountDisplayOpts
|
balanceOpts :: Bool -> ReportOpts -> AmountDisplayOpts
|
||||||
|
@ -272,7 +272,7 @@ compoundBalanceReportAsCsv ropts (CompoundPeriodicReport title colspans subrepor
|
|||||||
map (length . prDates . second3) subreports
|
map (length . prDates . second3) subreports
|
||||||
addtotals
|
addtotals
|
||||||
| no_total_ ropts || length subreports == 1 = id
|
| no_total_ ropts || length subreports == 1 = id
|
||||||
| otherwise = (++ fmap ("Net:" : ) (multiBalanceRowAsCsvText ropts netrow))
|
| otherwise = (++ fmap ("Net:" : ) (multiBalanceRowAsCsvText ropts colspans netrow))
|
||||||
|
|
||||||
-- | Render a compound balance report as HTML.
|
-- | Render a compound balance report as HTML.
|
||||||
compoundBalanceReportAsHtml :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> Html ()
|
compoundBalanceReportAsHtml :: ReportOpts -> CompoundPeriodicReport DisplayName MixedAmount -> Html ()
|
||||||
@ -309,7 +309,7 @@ compoundBalanceReportAsHtml ropts cbr =
|
|||||||
++ [blankrow]
|
++ [blankrow]
|
||||||
|
|
||||||
totalrows | no_total_ ropts || length subreports == 1 = []
|
totalrows | no_total_ ropts || length subreports == 1 = []
|
||||||
| otherwise = multiBalanceReportHtmlFootRow ropts <$> (("Net:" :) <$> multiBalanceRowAsCsvText ropts netrow)
|
| otherwise = multiBalanceReportHtmlFootRow ropts <$> (("Net:" :) <$> multiBalanceRowAsCsvText ropts colspans netrow)
|
||||||
in do
|
in do
|
||||||
style_ (T.unlines [""
|
style_ (T.unlines [""
|
||||||
,"td { padding:0 0.5em; }"
|
,"td { padding:0 0.5em; }"
|
||||||
|
@ -235,3 +235,49 @@ Balance Sheet 2014-10-11
|
|||||||
|| VEA 36.00
|
|| VEA 36.00
|
||||||
|| VHT 294.00
|
|| VHT 294.00
|
||||||
>=0
|
>=0
|
||||||
|
|
||||||
|
# 13. Multicolumn balance report csv output with --layout=tidy
|
||||||
|
$ hledger -f bcexample.hledger bal -T -Y assets.*etrade -3 -O csv --layout=tidy
|
||||||
|
>
|
||||||
|
"account","date","commodity","value"
|
||||||
|
"Assets:US:ETrade","2012","GLD","0"
|
||||||
|
"Assets:US:ETrade","2012","ITOT","10.00"
|
||||||
|
"Assets:US:ETrade","2012","USD","337.18"
|
||||||
|
"Assets:US:ETrade","2012","VEA","12.00"
|
||||||
|
"Assets:US:ETrade","2012","VHT","106.00"
|
||||||
|
"Assets:US:ETrade","2013","GLD","70.00"
|
||||||
|
"Assets:US:ETrade","2013","ITOT","18.00"
|
||||||
|
"Assets:US:ETrade","2013","USD","-98.12"
|
||||||
|
"Assets:US:ETrade","2013","VEA","10.00"
|
||||||
|
"Assets:US:ETrade","2013","VHT","18.00"
|
||||||
|
"Assets:US:ETrade","2014","GLD","0"
|
||||||
|
"Assets:US:ETrade","2014","ITOT","-11.00"
|
||||||
|
"Assets:US:ETrade","2014","USD","4881.44"
|
||||||
|
"Assets:US:ETrade","2014","VEA","14.00"
|
||||||
|
"Assets:US:ETrade","2014","VHT","170.00"
|
||||||
|
"Assets:US:ETrade","Total","GLD","70.00"
|
||||||
|
"Assets:US:ETrade","Total","ITOT","17.00"
|
||||||
|
"Assets:US:ETrade","Total","USD","5120.50"
|
||||||
|
"Assets:US:ETrade","Total","VEA","36.00"
|
||||||
|
"Assets:US:ETrade","Total","VHT","294.00"
|
||||||
|
"total","2012","GLD","0"
|
||||||
|
"total","2012","ITOT","10.00"
|
||||||
|
"total","2012","USD","337.18"
|
||||||
|
"total","2012","VEA","12.00"
|
||||||
|
"total","2012","VHT","106.00"
|
||||||
|
"total","2013","GLD","70.00"
|
||||||
|
"total","2013","ITOT","18.00"
|
||||||
|
"total","2013","USD","-98.12"
|
||||||
|
"total","2013","VEA","10.00"
|
||||||
|
"total","2013","VHT","18.00"
|
||||||
|
"total","2014","GLD","0"
|
||||||
|
"total","2014","ITOT","-11.00"
|
||||||
|
"total","2014","USD","4881.44"
|
||||||
|
"total","2014","VEA","14.00"
|
||||||
|
"total","2014","VHT","170.00"
|
||||||
|
"total","Total","GLD","70.00"
|
||||||
|
"total","Total","ITOT","17.00"
|
||||||
|
"total","Total","USD","5120.50"
|
||||||
|
"total","Total","VEA","36.00"
|
||||||
|
"total","Total","VHT","294.00"
|
||||||
|
>=0
|
||||||
|
Loading…
Reference in New Issue
Block a user