lib: amount styling: add a final styling pass to all reports
This commit is contained in:
parent
77aeb18bbd
commit
fd97c40266
@ -99,8 +99,10 @@ aregister opts@CliOpts{rawopts_=rawopts,reportspec_=rspec} j = do
|
|||||||
-- run the report
|
-- run the report
|
||||||
-- TODO: need to also pass the queries so we can choose which date to render - move them into 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 = accountTransactionsReport rspec' j thisacctq
|
||||||
items' = (if empty_ ropts' then id else filter (not . mixedAmountLooksZero . fifth6)) $
|
items' =
|
||||||
reverse items
|
styleAmounts (journalCommodityStyles j) $
|
||||||
|
(if empty_ ropts' then id else filter (not . mixedAmountLooksZero . fifth6)) $
|
||||||
|
reverse items
|
||||||
-- select renderer
|
-- select renderer
|
||||||
render | fmt=="txt" = accountTransactionsReportAsText opts (_rsQuery rspec') thisacctq
|
render | fmt=="txt" = accountTransactionsReportAsText opts (_rsQuery rspec') thisacctq
|
||||||
| fmt=="html" = accountTransactionsReportAsHTML opts (_rsQuery rspec') thisacctq
|
| fmt=="html" = accountTransactionsReportAsHTML opts (_rsQuery rspec') thisacctq
|
||||||
|
|||||||
@ -347,7 +347,7 @@ balance :: CliOpts -> Journal -> IO ()
|
|||||||
balance opts@CliOpts{reportspec_=rspec} j = case balancecalc_ of
|
balance opts@CliOpts{reportspec_=rspec} j = case balancecalc_ of
|
||||||
CalcBudget -> do -- single or multi period budget report
|
CalcBudget -> do -- single or multi period budget report
|
||||||
let rspan = fst $ reportSpan j rspec
|
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
|
render = case fmt of
|
||||||
"txt" -> budgetReportAsText ropts
|
"txt" -> budgetReportAsText ropts
|
||||||
"json" -> (<>"\n") . toJsonText
|
"json" -> (<>"\n") . toJsonText
|
||||||
@ -356,7 +356,7 @@ balance opts@CliOpts{reportspec_=rspec} j = case balancecalc_ of
|
|||||||
writeOutputLazyText opts $ render budgetreport
|
writeOutputLazyText opts $ render budgetreport
|
||||||
|
|
||||||
_ | multiperiod -> do -- multi period balance report
|
_ | multiperiod -> do -- multi period balance report
|
||||||
let report = multiBalanceReport rspec j
|
let report = styleAmounts styles $ multiBalanceReport rspec j
|
||||||
render = case fmt of
|
render = case fmt of
|
||||||
"txt" -> multiBalanceReportAsText ropts
|
"txt" -> multiBalanceReportAsText ropts
|
||||||
"csv" -> printCSV . multiBalanceReportAsCsv ropts
|
"csv" -> printCSV . multiBalanceReportAsCsv ropts
|
||||||
@ -366,7 +366,7 @@ balance opts@CliOpts{reportspec_=rspec} j = case balancecalc_ of
|
|||||||
writeOutputLazyText opts $ render report
|
writeOutputLazyText opts $ render report
|
||||||
|
|
||||||
_ -> do -- single period simple balance 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
|
render = case fmt of
|
||||||
"txt" -> \ropts1 -> TB.toLazyText . balanceReportAsText ropts1
|
"txt" -> \ropts1 -> TB.toLazyText . balanceReportAsText ropts1
|
||||||
"csv" -> \ropts1 -> printCSV . balanceReportAsCsv ropts1
|
"csv" -> \ropts1 -> printCSV . balanceReportAsCsv ropts1
|
||||||
@ -375,6 +375,7 @@ balance opts@CliOpts{reportspec_=rspec} j = case balancecalc_ of
|
|||||||
_ -> error' $ unsupportedOutputFormatError fmt -- PARTIAL:
|
_ -> error' $ unsupportedOutputFormatError fmt -- PARTIAL:
|
||||||
writeOutputLazyText opts $ render ropts report
|
writeOutputLazyText opts $ render ropts report
|
||||||
where
|
where
|
||||||
|
styles = journalCommodityStyles j
|
||||||
ropts@ReportOpts{..} = _rsReportOpts rspec
|
ropts@ReportOpts{..} = _rsReportOpts rspec
|
||||||
-- Tidy csv should be consistent between single period and multiperiod reports.
|
-- Tidy csv should be consistent between single period and multiperiod reports.
|
||||||
multiperiod = interval_ /= NoInterval || (layout_ == LayoutTidy && fmt == "csv")
|
multiperiod = interval_ /= NoInterval || (layout_ == LayoutTidy && fmt == "csv")
|
||||||
|
|||||||
@ -78,7 +78,7 @@ invertPrice a =
|
|||||||
-- But keep the number of decimal places unchanged.
|
-- But keep the number of decimal places unchanged.
|
||||||
stylePriceDirectiveExceptPrecision :: M.Map CommoditySymbol AmountStyle -> PriceDirective -> PriceDirective
|
stylePriceDirectiveExceptPrecision :: M.Map CommoditySymbol AmountStyle -> PriceDirective -> PriceDirective
|
||||||
stylePriceDirectiveExceptPrecision styles pd@PriceDirective{pdamount=a} =
|
stylePriceDirectiveExceptPrecision styles pd@PriceDirective{pdamount=a} =
|
||||||
pd{pdamount = styleAmountExceptPrecision styles a}
|
pd{pdamount = amountSetStylesExceptPrecision styles a}
|
||||||
|
|
||||||
allPostings :: Journal -> [Posting]
|
allPostings :: Journal -> [Posting]
|
||||||
allPostings = concatMap tpostings . jtxns
|
allPostings = concatMap tpostings . jtxns
|
||||||
|
|||||||
@ -28,6 +28,7 @@ import Hledger.Read.CsvUtils (CSV, printCSV)
|
|||||||
import Hledger.Cli.CliOptions
|
import Hledger.Cli.CliOptions
|
||||||
import Hledger.Cli.Utils
|
import Hledger.Cli.Utils
|
||||||
import System.Exit (exitFailure)
|
import System.Exit (exitFailure)
|
||||||
|
import qualified Data.Map as M (map)
|
||||||
|
|
||||||
|
|
||||||
printmode = hledgerCommandMode
|
printmode = hledgerCommandMode
|
||||||
@ -69,8 +70,11 @@ print' opts j = do
|
|||||||
|
|
||||||
printEntries :: CliOpts -> Journal -> IO ()
|
printEntries :: CliOpts -> Journal -> IO ()
|
||||||
printEntries opts@CliOpts{reportspec_=rspec} j =
|
printEntries opts@CliOpts{reportspec_=rspec} j =
|
||||||
writeOutputLazyText opts . render $ entriesReport rspec j
|
writeOutputLazyText opts . render $
|
||||||
|
styleAmounts styles $
|
||||||
|
entriesReport rspec j
|
||||||
where
|
where
|
||||||
|
styles = journalCommodityStyles j
|
||||||
fmt = outputFormatFromOpts opts
|
fmt = outputFormatFromOpts opts
|
||||||
render | fmt=="txt" = entriesReportAsText opts
|
render | fmt=="txt" = entriesReportAsText opts
|
||||||
| fmt=="csv" = printCSV . entriesReportAsCsv
|
| fmt=="csv" = printCSV . entriesReportAsCsv
|
||||||
|
|||||||
@ -79,11 +79,12 @@ register opts@CliOpts{rawopts_=rawopts, reportspec_=rspec} j
|
|||||||
where pri = (Just (postingDate p)
|
where pri = (Just (postingDate p)
|
||||||
,Nothing
|
,Nothing
|
||||||
,tdescription <$> ptransaction p
|
,tdescription <$> ptransaction p
|
||||||
,p
|
,styleAmounts styles p
|
||||||
,nullmixedamt)
|
,styleAmounts styles nullmixedamt)
|
||||||
-- normal register report, list postings
|
-- normal register report, list postings
|
||||||
| otherwise = writeOutputLazyText opts $ render rpt
|
| otherwise = writeOutputLazyText opts $ render $ styleAmounts styles rpt
|
||||||
where
|
where
|
||||||
|
styles = journalCommodityStyles j
|
||||||
rpt = postingsReport rspec j
|
rpt = postingsReport rspec j
|
||||||
render | fmt=="txt" = postingsReportAsText opts
|
render | fmt=="txt" = postingsReportAsText opts
|
||||||
| fmt=="csv" = printCSV . postingsReportAsCsv
|
| fmt=="csv" = printCSV . postingsReportAsCsv
|
||||||
|
|||||||
@ -129,16 +129,16 @@ roi CliOpts{rawopts_=rawopts, reportspec_=rspec@ReportSpec{_rsReportOpts=ReportO
|
|||||||
thisSpan = dbg3 "processing span" $
|
thisSpan = dbg3 "processing span" $
|
||||||
OneSpan b e valueBefore valueAfter cashFlow pnl
|
OneSpan b e valueBefore valueAfter cashFlow pnl
|
||||||
|
|
||||||
irr <- internalRateOfReturn showCashFlow prettyTables thisSpan
|
irr <- internalRateOfReturn styles showCashFlow prettyTables thisSpan
|
||||||
(periodTwr, annualizedTwr) <- timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountValue thisSpan
|
(periodTwr, annualizedTwr) <- timeWeightedReturn styles showCashFlow prettyTables investmentsQuery trans mixedAmountValue thisSpan
|
||||||
let cashFlowAmt = maNegate . maSum $ map snd cashFlow
|
let cashFlowAmt = maNegate . maSum $ map snd cashFlow
|
||||||
let smallIsZero x = if abs x < 0.01 then 0.0 else x
|
let smallIsZero x = if abs x < 0.01 then 0.0 else x
|
||||||
return [ showDate b
|
return [ showDate b
|
||||||
, showDate (addDays (-1) e)
|
, showDate (addDays (-1) e)
|
||||||
, T.pack $ showMixedAmount valueBefore
|
, T.pack $ showMixedAmount $ styleAmounts styles $ valueBefore
|
||||||
, T.pack $ showMixedAmount cashFlowAmt
|
, T.pack $ showMixedAmount $ styleAmounts styles $ cashFlowAmt
|
||||||
, T.pack $ showMixedAmount valueAfter
|
, T.pack $ showMixedAmount $ styleAmounts styles $ valueAfter
|
||||||
, T.pack $ showMixedAmount (valueAfter `maMinus` (valueBefore `maPlus` cashFlowAmt))
|
, T.pack $ showMixedAmount $ styleAmounts styles $ (valueAfter `maMinus` (valueBefore `maPlus` cashFlowAmt))
|
||||||
, T.pack $ printf "%0.2f%%" $ smallIsZero irr
|
, T.pack $ printf "%0.2f%%" $ smallIsZero irr
|
||||||
, T.pack $ printf "%0.2f%%" $ smallIsZero periodTwr
|
, T.pack $ printf "%0.2f%%" $ smallIsZero periodTwr
|
||||||
, T.pack $ printf "%0.2f%%" $ smallIsZero annualizedTwr ]
|
, 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
|
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 valueBefore = unMix valueBeforeAmt
|
||||||
let initialUnitPrice = 100 :: Decimal
|
let initialUnitPrice = 100 :: Decimal
|
||||||
let initialUnits = valueBefore / initialUnitPrice
|
let initialUnits = valueBefore / initialUnitPrice
|
||||||
@ -263,17 +263,17 @@ timeWeightedReturn showCashFlow prettyTables investmentsQuery trans mixedAmountV
|
|||||||
| val <- map showDecimal valuesOnDate
|
| val <- map showDecimal valuesOnDate
|
||||||
| oldBalance <- map showDecimal (0:unitBalances)
|
| oldBalance <- map showDecimal (0:unitBalances)
|
||||||
| balance <- map showDecimal unitBalances
|
| balance <- map showDecimal unitBalances
|
||||||
| pnl' <- map showMixedAmount pnls
|
| pnl' <- map (showMixedAmount . styleAmounts styles) pnls
|
||||||
| cashflow <- map showMixedAmount cashflows
|
| cashflow <- map (showMixedAmount . styleAmounts styles) cashflows
|
||||||
| prc <- map showDecimal unitPrices
|
| prc <- map showDecimal unitPrices
|
||||||
| udelta <- map showDecimal unitsBoughtOrSold ])
|
| udelta <- map showDecimal unitsBoughtOrSold ])
|
||||||
|
|
||||||
printf "Final unit price: %s/%s units = %s\nTotal TWR: %s%%.\nPeriod: %.2f years.\nAnnualized TWR: %.2f%%\n\n"
|
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)
|
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)
|
let prefix = (begin, maNegate valueBefore)
|
||||||
|
|
||||||
postfix = (end, valueAfter)
|
postfix = (end, valueAfter)
|
||||||
@ -287,7 +287,7 @@ internalRateOfReturn showCashFlow prettyTables (OneSpan begin end valueBefore va
|
|||||||
(Table
|
(Table
|
||||||
(Tab.Group Tab.NoLine (map (Header . showDate) dates))
|
(Tab.Group Tab.NoLine (map (Header . showDate) dates))
|
||||||
(Tab.Group Tab.SingleLine [Header "Amount"])
|
(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
|
-- 0% is always a solution, so require at least something here
|
||||||
case totalCF of
|
case totalCF of
|
||||||
|
|||||||
@ -109,7 +109,7 @@ compoundBalanceCommandMode CompoundBalanceCommandSpec{..} =
|
|||||||
-- | Generate a runnable command from a compound balance command specification.
|
-- | Generate a runnable command from a compound balance command specification.
|
||||||
compoundBalanceCommand :: CompoundBalanceCommandSpec -> (CliOpts -> Journal -> IO ())
|
compoundBalanceCommand :: CompoundBalanceCommandSpec -> (CliOpts -> Journal -> IO ())
|
||||||
compoundBalanceCommand CompoundBalanceCommandSpec{..} opts@CliOpts{reportspec_=rspec, rawopts_=rawopts} j = do
|
compoundBalanceCommand CompoundBalanceCommandSpec{..} opts@CliOpts{reportspec_=rspec, rawopts_=rawopts} j = do
|
||||||
writeOutputLazyText opts $ render cbr
|
writeOutputLazyText opts $ render $ styleAmounts (journalCommodityStyles j) cbr
|
||||||
where
|
where
|
||||||
ropts@ReportOpts{..} = _rsReportOpts rspec
|
ropts@ReportOpts{..} = _rsReportOpts rspec
|
||||||
-- use the default balance type for this report, unless the user overrides
|
-- use the default balance type for this report, unless the user overrides
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user