diff --git a/hledger-lib/Hledger/Data/Amount.hs b/hledger-lib/Hledger/Data/Amount.hs index 11f82e624..1dfb00f74 100644 --- a/hledger-lib/Hledger/Data/Amount.hs +++ b/hledger-lib/Hledger/Data/Amount.hs @@ -73,6 +73,7 @@ module Hledger.Data.Amount ( noColour, noPrice, oneLine, + csvDisplay, amountstyle, styleAmount, styleAmountExceptPrecision, @@ -200,6 +201,7 @@ quoteCommoditySymbolIfNeeded s data AmountDisplayOpts = AmountDisplayOpts { displayPrice :: Bool -- ^ Whether to display the Price of an Amount. , displayZeroCommodity :: Bool -- ^ If the Amount rounds to 0, whether to display its commodity string. + , displayThousandsSep :: Bool -- ^ Whether to display thousands separators. , displayColour :: Bool -- ^ Whether to colourise negative Amounts. , displayOneLine :: Bool -- ^ Whether to display on one line. , displayMinWidth :: Maybe Int -- ^ Minimum width to pad to @@ -217,6 +219,7 @@ noColour :: AmountDisplayOpts noColour = AmountDisplayOpts { displayPrice = True , displayColour = False , displayZeroCommodity = False + , displayThousandsSep = True , displayOneLine = False , displayMinWidth = Just 0 , displayMaxWidth = Nothing @@ -231,6 +234,10 @@ noPrice = def{displayPrice=False} oneLine :: AmountDisplayOpts oneLine = def{displayOneLine=True, displayPrice=False} +-- | Display Amount and MixedAmount in a form suitable for CSV output. +csvDisplay :: AmountDisplayOpts +csvDisplay = oneLine{displayThousandsSep=False} + ------------------------------------------------------------------------------- -- Amount styles @@ -472,7 +479,7 @@ showAmountB opts a@Amount{astyle=style} = L -> showC (wbFromText c) space <> quantity' <> price R -> quantity' <> showC space (wbFromText c) <> price where - quantity = showamountquantity a + quantity = showamountquantity $ if displayThousandsSep opts then a else a{astyle=(astyle a){asdigitgroups=Nothing}} (quantity',c) | amountLooksZero a && not (displayZeroCommodity opts) = (WideBuilder (TB.singleton '0') 1,"") | otherwise = (quantity, quoteCommoditySymbolIfNeeded $ acommodity a) space = if not (T.null c) && ascommodityspaced style then WideBuilder (TB.singleton ' ') 1 else mempty diff --git a/hledger/Hledger/Cli/Commands/Aregister.hs b/hledger/Hledger/Cli/Commands/Aregister.hs index 556888ab6..8e4db17d4 100644 --- a/hledger/Hledger/Cli/Commands/Aregister.hs +++ b/hledger/Hledger/Cli/Commands/Aregister.hs @@ -120,8 +120,8 @@ accountTransactionsReportItemAsCsvRecord where idx = T.pack $ show tindex date = showDate $ transactionRegisterDate wd reportq thisacctq t - amt = wbToText $ showMixedAmountB oneLine change - bal = wbToText $ showMixedAmountB oneLine balance + amt = wbToText $ showMixedAmountB csvDisplay change + bal = wbToText $ showMixedAmountB csvDisplay balance -- | Render a register report as plain text suitable for console output. accountTransactionsReportAsText :: CliOpts -> Query -> Query -> AccountTransactionsReport -> TL.Text diff --git a/hledger/Hledger/Cli/Commands/Balance.hs b/hledger/Hledger/Cli/Commands/Balance.hs index 44c246c73..5fb521873 100644 --- a/hledger/Hledger/Cli/Commands/Balance.hs +++ b/hledger/Hledger/Cli/Commands/Balance.hs @@ -422,7 +422,7 @@ balanceReportAsCsv opts (items, total) = showName = accountNameDrop (drop_ opts) renderAmount amt = wbToText $ showMixedAmountB bopts amt - where bopts = (balanceOpts False opts){displayOrder = order} + where bopts = csvDisplay{displayOrder = order} order = if layout_ opts == LayoutBare then Just (S.toList $ maCommodities amt) else Nothing -- | Render a single-column balance report as plain text. @@ -455,7 +455,7 @@ balanceReportAsText' opts ((items, total)) = [ Cell TopRight damts , Cell TopLeft (fmap wbFromText cs) , Cell TopLeft (replicate (length damts - 1) mempty ++ [wbFromText dispname]) ] - where dopts = (balanceOpts True opts){displayOrder=Just cs} + where dopts = oneLine{displayColour=color_ opts, displayOrder=Just cs} cs = S.toList $ maCommodities amt dispname = T.replicate ((depth - 1) * 2) " " <> acctname damts = showMixedAmountLinesB dopts amt @@ -512,7 +512,7 @@ renderComponent topaligned oneline opts (acctname, depth, total) (FormatField lj | topaligned = TopRight | ljust = BottomLeft | otherwise = BottomRight - dopts = (balanceOpts True opts){displayOneLine=oneline, displayMinWidth=mmin, displayMaxWidth=mmax} + dopts = noPrice{displayColour=color_ opts, displayOneLine=oneline, displayMinWidth=mmin, displayMaxWidth=mmax} -- rendering multi-column balance reports @@ -742,14 +742,10 @@ multiBalanceRowAsWbs bopts ReportOpts{..} colspans (PeriodicReportRow _ as rowto m [] = [n] multiBalanceRowAsCsvText :: ReportOpts -> [DateSpan] -> PeriodicReportRow a MixedAmount -> [[T.Text]] -multiBalanceRowAsCsvText opts colspans = fmap (fmap wbToText) . multiBalanceRowAsWbs (balanceOpts False opts) opts colspans +multiBalanceRowAsCsvText opts colspans = fmap (fmap wbToText) . multiBalanceRowAsWbs csvDisplay opts colspans multiBalanceRowAsTableText :: ReportOpts -> PeriodicReportRow a MixedAmount -> [[WideBuilder]] -multiBalanceRowAsTableText opts = multiBalanceRowAsWbs (balanceOpts True opts) opts [] - --- | Amount display options to use for balance reports -balanceOpts :: Bool -> ReportOpts -> AmountDisplayOpts -balanceOpts isTable ReportOpts{..} = oneLine {displayColour = isTable && color_} +multiBalanceRowAsTableText opts = multiBalanceRowAsWbs oneLine{displayColour=color_ opts} opts [] tests_Balance = testGroup "Balance" [ diff --git a/hledger/Hledger/Cli/Commands/Print.hs b/hledger/Hledger/Cli/Commands/Print.hs index fa42da5d6..81ce90bd9 100644 --- a/hledger/Hledger/Cli/Commands/Print.hs +++ b/hledger/Hledger/Cli/Commands/Print.hs @@ -179,8 +179,8 @@ postingToCSV p = map (\(a@(Amount {aquantity=q,acommodity=c})) -> -- commodity goes into separate column, so we suppress it, along with digit group -- separators and prices - let a_ = a{acommodity="",astyle=(astyle a){asdigitgroups=Nothing},aprice=Nothing} in - let showamt = wbToText . showAmountB noColour in + let a_ = amountStripPrices a{acommodity=""} in + let showamt = wbToText . showAmountB csvDisplay in let amount = showamt a_ in let credit = if q < 0 then showamt $ negate a_ else "" in let debit = if q >= 0 then showamt a_ else "" in diff --git a/hledger/Hledger/Cli/Commands/Register.hs b/hledger/Hledger/Cli/Commands/Register.hs index 41365e3ca..c2a08e84e 100644 --- a/hledger/Hledger/Cli/Commands/Register.hs +++ b/hledger/Hledger/Cli/Commands/Register.hs @@ -88,8 +88,8 @@ postingsReportItemAsCsvRecord (_, _, _, p, b) = [idx,date,code,desc,acct,amt,bal VirtualPosting -> wrap "(" ")" _ -> id -- Since postingsReport strips prices from all Amounts when not used, we can display prices. - amt = wbToText . showMixedAmountB oneLine $ pamount p - bal = wbToText $ showMixedAmountB oneLine b + amt = wbToText . showMixedAmountB csvDisplay $ pamount p + bal = wbToText $ showMixedAmountB csvDisplay b -- | Render a register report as plain text suitable for console output. postingsReportAsText :: CliOpts -> PostingsReport -> TL.Text diff --git a/hledger/test/balance/balance.test b/hledger/test/balance/balance.test index 82b72198b..52da4000b 100644 --- a/hledger/test/balance/balance.test +++ b/hledger/test/balance/balance.test @@ -168,7 +168,19 @@ hledger -f - balance -N --output-format=csv --tree "Assets:Cash","$-1" >>>= 0 -# 9. --declared includes all declared leaf accounts, even if they have no postings. +# 9. CSV output always does not show thousands separators +hledger -f - balance -N --output-format=csv +<<< +2021-01-01 Test + Assets:ABC $10 000.00 + Assets:Cash -$10 000.00 +>>> +"account","balance" +"Assets:ABC","$10000.00" +"Assets:Cash","$-10000.00" +>>>= 0 + +# 10. --declared includes all declared leaf accounts, even if they have no postings. # They are filtered, depth-clipped, and form trees like the others. hledger -f - balance -NE --declared --tree --depth 2 a <<< @@ -183,7 +195,7 @@ account b 0 ab >>>= 0 -# 10. In list mode we can see that non-leaf declared accounts are excluded. +# 11. In list mode we can see that non-leaf declared accounts are excluded. hledger -f - balance -NE --declared --flat <<< account a diff --git a/hledger/test/balancesheet.test b/hledger/test/balancesheet.test index f8705ef72..d1265f4a6 100644 --- a/hledger/test/balancesheet.test +++ b/hledger/test/balancesheet.test @@ -328,7 +328,23 @@ $ hledger -f - balancesheet --tree --output-format=csv --drop 1 "total" "Net:","$1" -# 14. In compound reports like balancesheet, parent accounts might not have +< +2020-03-01 * Rent + assets:a -$10 000.00 + expenses + +# 14. CSV output drops thousands separators +$ hledger -f - balancesheet --output-format=csv +"Balance Sheet 2020-03-01","" +"Account","2020-03-01" +"Assets","" +"assets:a","$-10000.00" +"total","$-10000.00" +"Liabilities","" +"total" +"Net:","$-10000.00" + +# 15. In compound reports like balancesheet, parent accounts might not have # the appropriate type for a subreport, but in tree reports they should be # displayed anyway, and with the right inclusive amounts and starting # balances. (#1698) diff --git a/hledger/test/print/csv.test b/hledger/test/print/csv.test new file mode 100644 index 000000000..4204b468e --- /dev/null +++ b/hledger/test/print/csv.test @@ -0,0 +1,11 @@ +< +2009/1/1 + a $10 000.00 + b -$10 000.00 + +# csv output should not display thousands separators +$ hledger -f- print -O csv +"txnidx","date","date2","status","code","description","comment","account","amount","commodity","credit","debit","posting-status","posting-comment" +"1","2009-01-01","","","","","","a","10000.00","$","","10000.00","","" +"1","2009-01-01","","","","","","b","-10000.00","$","10000.00","","","" +>= 0 diff --git a/hledger/test/register/csv.test b/hledger/test/register/csv.test new file mode 100644 index 000000000..95b40d1de --- /dev/null +++ b/hledger/test/register/csv.test @@ -0,0 +1,8 @@ +2019-1-1 + (a) 10 000 000.0 + +# 1. Csv output will not display thousands separators +$ hledger -f- register -O csv +"txnidx","date","code","description","account","amount","total" +"1","2019-01-01","","","(a)","10000000.0","10000000.0" +>=