lib: amount styling: add a final styling pass to all reports

This commit is contained in:
Simon Michael 2023-08-31 04:14:12 +01:00
parent 77aeb18bbd
commit fd97c40266
7 changed files with 31 additions and 23 deletions

View File

@ -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

View File

@ -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")

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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