From fd97c40266a31c4f3df924b10e008e1d431b3cdd Mon Sep 17 00:00:00 2001 From: Simon Michael Date: Thu, 31 Aug 2023 04:14:12 +0100 Subject: [PATCH] lib: amount styling: add a final styling pass to all reports --- hledger/Hledger/Cli/Commands/Aregister.hs | 6 +++-- hledger/Hledger/Cli/Commands/Balance.hs | 7 +++--- hledger/Hledger/Cli/Commands/Prices.hs | 2 +- hledger/Hledger/Cli/Commands/Print.hs | 6 ++++- hledger/Hledger/Cli/Commands/Register.hs | 7 +++--- hledger/Hledger/Cli/Commands/Roi.hs | 24 +++++++++---------- hledger/Hledger/Cli/CompoundBalanceCommand.hs | 2 +- 7 files changed, 31 insertions(+), 23 deletions(-) diff --git a/hledger/Hledger/Cli/Commands/Aregister.hs b/hledger/Hledger/Cli/Commands/Aregister.hs index a544c93d5..55c38f907 100644 --- a/hledger/Hledger/Cli/Commands/Aregister.hs +++ b/hledger/Hledger/Cli/Commands/Aregister.hs @@ -99,8 +99,10 @@ aregister opts@CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do -- run the report -- TODO: need to also pass the queries so we can choose which date to render - move them into the report ? items = accountTransactionsReport rspec' j thisacctq - items' = (if empty_ ropts' then id else filter (not . mixedAmountLooksZero . fifth6)) $ - reverse items + items' = + styleAmounts (journalCommodityStyles j) $ + (if empty_ ropts' then id else filter (not . mixedAmountLooksZero . fifth6)) $ + reverse items -- select renderer render | fmt=="txt" = accountTransactionsReportAsText opts (_rsQuery rspec') thisacctq | fmt=="html" = accountTransactionsReportAsHTML opts (_rsQuery rspec') thisacctq diff --git a/hledger/Hledger/Cli/Commands/Balance.hs b/hledger/Hledger/Cli/Commands/Balance.hs index 6d2d8e90a..3e9b73b9b 100644 --- a/hledger/Hledger/Cli/Commands/Balance.hs +++ b/hledger/Hledger/Cli/Commands/Balance.hs @@ -347,7 +347,7 @@ balance :: CliOpts -> Journal -> IO () balance opts@CliOpts{reportspec_=rspec} j = case balancecalc_ of CalcBudget -> do -- single or multi period budget report let rspan = fst $ reportSpan j rspec - budgetreport = budgetReport rspec (balancingopts_ $ inputopts_ opts) rspan j + budgetreport = styleAmounts styles $ budgetReport rspec (balancingopts_ $ inputopts_ opts) rspan j render = case fmt of "txt" -> budgetReportAsText ropts "json" -> (<>"\n") . toJsonText @@ -356,7 +356,7 @@ balance opts@CliOpts{reportspec_=rspec} j = case balancecalc_ of writeOutputLazyText opts $ render budgetreport _ | multiperiod -> do -- multi period balance report - let report = multiBalanceReport rspec j + let report = styleAmounts styles $ multiBalanceReport rspec j render = case fmt of "txt" -> multiBalanceReportAsText ropts "csv" -> printCSV . multiBalanceReportAsCsv ropts @@ -366,7 +366,7 @@ balance opts@CliOpts{reportspec_=rspec} j = case balancecalc_ of writeOutputLazyText opts $ render report _ -> do -- single period simple balance report - let report = balanceReport rspec j -- simple Ledger-style balance report + let report = styleAmounts styles $ balanceReport rspec j -- simple Ledger-style balance report render = case fmt of "txt" -> \ropts1 -> TB.toLazyText . balanceReportAsText ropts1 "csv" -> \ropts1 -> printCSV . balanceReportAsCsv ropts1 @@ -375,6 +375,7 @@ balance opts@CliOpts{reportspec_=rspec} j = case balancecalc_ of _ -> error' $ unsupportedOutputFormatError fmt -- PARTIAL: writeOutputLazyText opts $ render ropts report where + styles = journalCommodityStyles j ropts@ReportOpts{..} = _rsReportOpts rspec -- Tidy csv should be consistent between single period and multiperiod reports. multiperiod = interval_ /= NoInterval || (layout_ == LayoutTidy && fmt == "csv") diff --git a/hledger/Hledger/Cli/Commands/Prices.hs b/hledger/Hledger/Cli/Commands/Prices.hs index 132a4446f..19dfcd2d7 100644 --- a/hledger/Hledger/Cli/Commands/Prices.hs +++ b/hledger/Hledger/Cli/Commands/Prices.hs @@ -78,7 +78,7 @@ invertPrice a = -- But keep the number of decimal places unchanged. stylePriceDirectiveExceptPrecision :: M.Map CommoditySymbol AmountStyle -> PriceDirective -> PriceDirective stylePriceDirectiveExceptPrecision styles pd@PriceDirective{pdamount=a} = - pd{pdamount = styleAmountExceptPrecision styles a} + pd{pdamount = amountSetStylesExceptPrecision styles a} allPostings :: Journal -> [Posting] allPostings = concatMap tpostings . jtxns diff --git a/hledger/Hledger/Cli/Commands/Print.hs b/hledger/Hledger/Cli/Commands/Print.hs index b517076b1..31aad5f6e 100644 --- a/hledger/Hledger/Cli/Commands/Print.hs +++ b/hledger/Hledger/Cli/Commands/Print.hs @@ -28,6 +28,7 @@ import Hledger.Read.CsvUtils (CSV, printCSV) import Hledger.Cli.CliOptions import Hledger.Cli.Utils import System.Exit (exitFailure) +import qualified Data.Map as M (map) printmode = hledgerCommandMode @@ -69,8 +70,11 @@ print' opts j = do printEntries :: CliOpts -> Journal -> IO () printEntries opts@CliOpts{reportspec_=rspec} j = - writeOutputLazyText opts . render $ entriesReport rspec j + writeOutputLazyText opts . render $ + styleAmounts styles $ + entriesReport rspec j where + styles = journalCommodityStyles j fmt = outputFormatFromOpts opts render | fmt=="txt" = entriesReportAsText opts | fmt=="csv" = printCSV . entriesReportAsCsv diff --git a/hledger/Hledger/Cli/Commands/Register.hs b/hledger/Hledger/Cli/Commands/Register.hs index 1cfcaf872..499999b8e 100644 --- a/hledger/Hledger/Cli/Commands/Register.hs +++ b/hledger/Hledger/Cli/Commands/Register.hs @@ -79,11 +79,12 @@ register opts@CliOpts{rawopts_=rawopts, reportspec_=rspec} j where pri = (Just (postingDate p) ,Nothing ,tdescription <$> ptransaction p - ,p - ,nullmixedamt) + ,styleAmounts styles p + ,styleAmounts styles nullmixedamt) -- normal register report, list postings - | otherwise = writeOutputLazyText opts $ render rpt + | otherwise = writeOutputLazyText opts $ render $ styleAmounts styles rpt where + styles = journalCommodityStyles j rpt = postingsReport rspec j render | fmt=="txt" = postingsReportAsText opts | fmt=="csv" = printCSV . postingsReportAsCsv diff --git a/hledger/Hledger/Cli/Commands/Roi.hs b/hledger/Hledger/Cli/Commands/Roi.hs index 810ab254a..18a3a767a 100644 --- a/hledger/Hledger/Cli/Commands/Roi.hs +++ b/hledger/Hledger/Cli/Commands/Roi.hs @@ -129,16 +129,16 @@ roi CliOpts{rawopts_=rawopts, reportspec_=rspec@ReportSpec{_rsReportOpts=ReportO thisSpan = dbg3 "processing span" $ OneSpan b e valueBefore valueAfter cashFlow pnl - irr <- internalRateOfReturn showCashFlow prettyTables thisSpan - (periodTwr, annualizedTwr) <- timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountValue thisSpan + irr <- internalRateOfReturn styles showCashFlow prettyTables thisSpan + (periodTwr, annualizedTwr) <- timeWeightedReturn styles showCashFlow prettyTables investmentsQuery trans mixedAmountValue thisSpan let cashFlowAmt = maNegate . maSum $ map snd cashFlow let smallIsZero x = if abs x < 0.01 then 0.0 else x return [ showDate b , showDate (addDays (-1) e) - , T.pack $ showMixedAmount valueBefore - , T.pack $ showMixedAmount cashFlowAmt - , T.pack $ showMixedAmount valueAfter - , T.pack $ showMixedAmount (valueAfter `maMinus` (valueBefore `maPlus` cashFlowAmt)) + , T.pack $ showMixedAmount $ styleAmounts styles $ valueBefore + , T.pack $ showMixedAmount $ styleAmounts styles $ cashFlowAmt + , T.pack $ showMixedAmount $ styleAmounts styles $ valueAfter + , T.pack $ showMixedAmount $ styleAmounts styles $ (valueAfter `maMinus` (valueBefore `maPlus` cashFlowAmt)) , T.pack $ printf "%0.2f%%" $ smallIsZero irr , T.pack $ printf "%0.2f%%" $ smallIsZero periodTwr , T.pack $ printf "%0.2f%%" $ smallIsZero annualizedTwr ] @@ -164,7 +164,7 @@ roi CliOpts{rawopts_=rawopts, reportspec_=rspec@ReportSpec{_rsReportOpts=ReportO TL.putStrLn $ Tab.render prettyTables id id id table -timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountValue (OneSpan begin end valueBeforeAmt valueAfter cashFlow pnl) = do +timeWeightedReturn styles showCashFlow prettyTables investmentsQuery trans mixedAmountValue (OneSpan begin end valueBeforeAmt valueAfter cashFlow pnl) = do let valueBefore = unMix valueBeforeAmt let initialUnitPrice = 100 :: Decimal let initialUnits = valueBefore / initialUnitPrice @@ -263,17 +263,17 @@ timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountV | val <- map showDecimal valuesOnDate | oldBalance <- map showDecimal (0:unitBalances) | balance <- map showDecimal unitBalances - | pnl' <- map showMixedAmount pnls - | cashflow <- map showMixedAmount cashflows + | pnl' <- map (showMixedAmount . styleAmounts styles) pnls + | cashflow <- map (showMixedAmount . styleAmounts styles) cashflows | prc <- map showDecimal unitPrices | udelta <- map showDecimal unitsBoughtOrSold ]) printf "Final unit price: %s/%s units = %s\nTotal TWR: %s%%.\nPeriod: %.2f years.\nAnnualized TWR: %.2f%%\n\n" - (showMixedAmount valueAfter) (showDecimal finalUnitBalance) (showDecimal finalUnitPrice) (showDecimal totalTWR) years annualizedTWR + (showMixedAmount $ styleAmounts styles valueAfter) (showDecimal finalUnitBalance) (showDecimal finalUnitPrice) (showDecimal totalTWR) years annualizedTWR return ((realToFrac totalTWR) :: Double, annualizedTWR) -internalRateOfReturn showCashFlow prettyTables (OneSpan begin end valueBefore valueAfter cashFlow _pnl) = do +internalRateOfReturn styles showCashFlow prettyTables (OneSpan begin end valueBefore valueAfter cashFlow _pnl) = do let prefix = (begin, maNegate valueBefore) postfix = (end, valueAfter) @@ -287,7 +287,7 @@ internalRateOfReturn showCashFlow prettyTables (OneSpan begin end valueBefore va (Table (Tab.Group Tab.NoLine (map (Header . showDate) dates)) (Tab.Group Tab.SingleLine [Header "Amount"]) - (map ((:[]) . T.pack . showMixedAmount) amts)) + (map ((:[]) . T.pack . showMixedAmount . styleAmounts styles) amts)) -- 0% is always a solution, so require at least something here case totalCF of diff --git a/hledger/Hledger/Cli/CompoundBalanceCommand.hs b/hledger/Hledger/Cli/CompoundBalanceCommand.hs index d8c1ed4e6..ce6cddd5e 100644 --- a/hledger/Hledger/Cli/CompoundBalanceCommand.hs +++ b/hledger/Hledger/Cli/CompoundBalanceCommand.hs @@ -109,7 +109,7 @@ compoundBalanceCommandMode CompoundBalanceCommandSpec{..} = -- | Generate a runnable command from a compound balance command specification. compoundBalanceCommand :: CompoundBalanceCommandSpec -> (CliOpts -> Journal -> IO ()) compoundBalanceCommand CompoundBalanceCommandSpec{..} opts@CliOpts{reportspec_=rspec, rawopts_=rawopts} j = do - writeOutputLazyText opts $ render cbr + writeOutputLazyText opts $ render $ styleAmounts (journalCommodityStyles j) cbr where ropts@ReportOpts{..} = _rsReportOpts rspec -- use the default balance type for this report, unless the user overrides