Adding "--value"/"-V" option for balancesheet/incomestatement/cashflow and register (#361)
* Added --value options for specialized balance ouputs balancesheet, incomestatement, cashflow * --value option for 'register' command lib: postingsValue to convert posting amounts to market value
This commit is contained in:
parent
419f5f2a2a
commit
b935cd2243
@ -9,6 +9,7 @@ module Hledger.Reports.PostingsReport (
|
||||
PostingsReport,
|
||||
PostingsReportItem,
|
||||
postingsReport,
|
||||
postingsReportValue,
|
||||
mkpostingsReportItem,
|
||||
|
||||
-- * Tests
|
||||
@ -28,6 +29,7 @@ import Test.HUnit
|
||||
import Hledger.Data
|
||||
import Hledger.Query
|
||||
import Hledger.Utils
|
||||
import Hledger.Reports.BalanceReport
|
||||
import Hledger.Reports.ReportOptions
|
||||
|
||||
|
||||
@ -87,6 +89,31 @@ postingsReport opts q j = (totallabel, items)
|
||||
|
||||
totallabel = "Total"
|
||||
|
||||
-- | Convert all the amounts in a postings report to
|
||||
-- their value on the given date in their default valuation
|
||||
-- commodities.
|
||||
postingsReportValue :: Journal -> Day -> PostingsReport -> PostingsReport
|
||||
postingsReportValue j d r = r'
|
||||
where
|
||||
(label,items) = r
|
||||
r' = dbg8 "postingsReportValue" $
|
||||
(label,[(pb,pe,pd,postingValue j d pp,mixedAmountValue j d a) | (pb,pe,pd,pp,a) <- items])
|
||||
|
||||
postingValue :: Journal -> Day -> Posting -> Posting
|
||||
postingValue j d p = p'
|
||||
where
|
||||
Posting {pamount = pa, pbalanceassertion = pb, ptransaction = pt} = p
|
||||
p' = p{pamount = mixedAmountValue j d pa
|
||||
,pbalanceassertion = mixedAmountValue j d <$> pb
|
||||
,ptransaction = transactionValue j d <$> pt
|
||||
}
|
||||
|
||||
transactionValue :: Journal -> Day -> Transaction -> Transaction
|
||||
transactionValue j d t = t'
|
||||
where
|
||||
Transaction {tpostings = tp} = t
|
||||
t' = t{tpostings = map (postingValue j d) tp}
|
||||
|
||||
-- | Adjust report start/end dates to more useful ones based on
|
||||
-- journal data and report intervals. Ie:
|
||||
-- 1. If the start date is unspecified, use the earliest date in the journal (if any)
|
||||
|
||||
@ -11,6 +11,7 @@ module Hledger.Cli.Balancesheet (
|
||||
,tests_Hledger_Cli_Balancesheet
|
||||
) where
|
||||
|
||||
import Data.Maybe (fromMaybe)
|
||||
import qualified Data.Text.Lazy.IO as LT
|
||||
import System.Console.CmdArgs.Explicit
|
||||
import Test.HUnit
|
||||
@ -28,6 +29,7 @@ balancesheetmode = (defCommandMode $ ["balancesheet"]++aliases) {
|
||||
groupUnnamed = [
|
||||
flagNone ["flat"] (\opts -> setboolopt "flat" opts) "show accounts as a list"
|
||||
,flagReq ["drop"] (\s opts -> Right $ setopt "drop" s opts) "N" "flat mode: omit N leading account name parts"
|
||||
,flagNone ["value","V"] (setboolopt "value") "show amounts as their current market value in their default valuation commodity"
|
||||
]
|
||||
,groupHidden = []
|
||||
,groupNamed = [generalflagsgroup1]
|
||||
@ -41,18 +43,23 @@ balancesheet CliOpts{reportopts_=ropts} j = do
|
||||
-- let lines = case lineFormatFromOpts ropts of Left err, Right ...
|
||||
d <- getCurrentDay
|
||||
let q = queryFromOpts d (withoutBeginDate ropts)
|
||||
valuedate = fromMaybe d $ queryEndDate False $ queryFromOpts d ropts
|
||||
assetreport@(_,assets) = balanceReport ropts (And [q, journalAssetAccountQuery j]) j
|
||||
liabilityreport@(_,liabilities) = balanceReport ropts (And [q, journalLiabilityAccountQuery j]) j
|
||||
total = assets + liabilities
|
||||
convertReport | value_ ropts = balanceReportValue j valuedate
|
||||
| otherwise = id
|
||||
convertTotal | value_ ropts = mixedAmountValue j valuedate
|
||||
| otherwise = id
|
||||
LT.putStr $ [lt|Balance Sheet
|
||||
|
||||
Assets:
|
||||
#{balanceReportAsText ropts assetreport}
|
||||
#{balanceReportAsText ropts (convertReport assetreport)}
|
||||
Liabilities:
|
||||
#{balanceReportAsText ropts liabilityreport}
|
||||
#{balanceReportAsText ropts (convertReport liabilityreport)}
|
||||
Total:
|
||||
--------------------
|
||||
#{padleft 20 $ showMixedAmountWithoutPrice total}
|
||||
#{padleft 20 $ showMixedAmountWithoutPrice (convertTotal total)}
|
||||
|]
|
||||
|
||||
withoutBeginDate :: ReportOpts -> ReportOpts
|
||||
|
||||
@ -14,6 +14,7 @@ module Hledger.Cli.Cashflow (
|
||||
,tests_Hledger_Cli_Cashflow
|
||||
) where
|
||||
|
||||
import Data.Maybe (fromMaybe)
|
||||
import qualified Data.Text.Lazy.IO as LT
|
||||
import System.Console.CmdArgs.Explicit
|
||||
import Test.HUnit
|
||||
@ -31,6 +32,7 @@ cashflowmode = (defCommandMode ["cashflow","cf"]) {
|
||||
groupUnnamed = [
|
||||
flagNone ["flat"] (\opts -> setboolopt "flat" opts) "show accounts as a list"
|
||||
,flagReq ["drop"] (\s opts -> Right $ setopt "drop" s opts) "N" "flat mode: omit N leading account name parts"
|
||||
,flagNone ["value","V"] (setboolopt "value") "show amounts as their current market value in their default valuation commodity"
|
||||
]
|
||||
,groupHidden = []
|
||||
,groupNamed = [generalflagsgroup1]
|
||||
@ -43,18 +45,23 @@ cashflow CliOpts{reportopts_=ropts} j = do
|
||||
-- let lines = case lineFormatFromOpts ropts of Left err, Right ...
|
||||
d <- getCurrentDay
|
||||
let q = queryFromOpts d ropts
|
||||
valuedate = fromMaybe d $ queryEndDate False $ queryFromOpts d ropts
|
||||
cashreport@(_,total) = balanceReport ropts (And [q, journalCashAccountQuery j]) j
|
||||
-- operatingreport@(_,operating) = balanceReport ropts (And [q, journalOperatingAccountMatcher j]) j
|
||||
-- investingreport@(_,investing) = balanceReport ropts (And [q, journalInvestingAccountMatcher j]) j
|
||||
-- financingreport@(_,financing) = balanceReport ropts (And [q, journalFinancingAccountMatcher j]) j
|
||||
-- total = operating + investing + financing
|
||||
convertReport | value_ ropts = balanceReportValue j valuedate
|
||||
| otherwise = id
|
||||
convertTotal | value_ ropts = mixedAmountValue j valuedate
|
||||
| otherwise = id
|
||||
LT.putStr $ [lt|Cashflow Statement
|
||||
|
||||
Cash flows:
|
||||
#{balanceReportAsText ropts cashreport}
|
||||
#{balanceReportAsText ropts (convertReport cashreport)}
|
||||
Total:
|
||||
--------------------
|
||||
#{padleft 20 $ showMixedAmountWithoutPrice total}
|
||||
#{padleft 20 $ showMixedAmountWithoutPrice (convertTotal total)}
|
||||
|]
|
||||
|
||||
tests_Hledger_Cli_Cashflow :: Test
|
||||
|
||||
@ -11,6 +11,7 @@ module Hledger.Cli.Incomestatement (
|
||||
,tests_Hledger_Cli_Incomestatement
|
||||
) where
|
||||
|
||||
import Data.Maybe (fromMaybe)
|
||||
import qualified Data.Text.Lazy.IO as LT
|
||||
import System.Console.CmdArgs.Explicit
|
||||
import Test.HUnit
|
||||
@ -28,6 +29,7 @@ incomestatementmode = (defCommandMode $ ["incomestatement"]++aliases) {
|
||||
groupUnnamed = [
|
||||
flagNone ["flat"] (\opts -> setboolopt "flat" opts) "show accounts as a list"
|
||||
,flagReq ["drop"] (\s opts -> Right $ setopt "drop" s opts) "N" "flat mode: omit N leading account name parts"
|
||||
,flagNone ["value","V"] (setboolopt "value") "show amounts as their current market value in their default valuation commodity"
|
||||
]
|
||||
,groupHidden = []
|
||||
,groupNamed = [generalflagsgroup1]
|
||||
@ -40,18 +42,23 @@ incomestatement :: CliOpts -> Journal -> IO ()
|
||||
incomestatement CliOpts{reportopts_=ropts} j = do
|
||||
d <- getCurrentDay
|
||||
let q = queryFromOpts d ropts
|
||||
valuedate = fromMaybe d $ queryEndDate False $ queryFromOpts d ropts
|
||||
incomereport@(_,income) = balanceReport ropts (And [q, journalIncomeAccountQuery j]) j
|
||||
expensereport@(_,expenses) = balanceReport ropts (And [q, journalExpenseAccountQuery j]) j
|
||||
total = income + expenses
|
||||
convertReport | value_ ropts = balanceReportValue j valuedate
|
||||
| otherwise = id
|
||||
convertTotal | value_ ropts = mixedAmountValue j valuedate
|
||||
| otherwise = id
|
||||
LT.putStr $ [lt|Income Statement
|
||||
|
||||
Revenues:
|
||||
#{balanceReportAsText ropts incomereport}
|
||||
#{balanceReportAsText ropts (convertReport incomereport)}
|
||||
Expenses:
|
||||
#{balanceReportAsText ropts expensereport}
|
||||
#{balanceReportAsText ropts (convertReport expensereport)}
|
||||
Total:
|
||||
--------------------
|
||||
#{padleft 20 $ showMixedAmountWithoutPrice total}
|
||||
#{padleft 20 $ showMixedAmountWithoutPrice (convertTotal total)}
|
||||
|]
|
||||
|
||||
tests_Hledger_Cli_Incomestatement :: Test
|
||||
|
||||
@ -39,6 +39,7 @@ registermode = (defCommandMode $ ["register"] ++ aliases) {
|
||||
,flagNone ["average","A"] (\opts -> setboolopt "average" opts)
|
||||
"show running average of posting amounts instead of total (implies --empty)"
|
||||
,flagNone ["related","r"] (\opts -> setboolopt "related" opts) "show postings' siblings instead"
|
||||
,flagNone ["value","V"] (setboolopt "value") "show amounts as their current market value in their default valuation commodity"
|
||||
,flagReq ["width","w"] (\s opts -> Right $ setopt "width" s opts) "N"
|
||||
("set output width (default: " ++
|
||||
#ifdef mingw32_HOST_OS
|
||||
@ -61,9 +62,12 @@ register :: CliOpts -> Journal -> IO ()
|
||||
register opts@CliOpts{reportopts_=ropts} j = do
|
||||
d <- getCurrentDay
|
||||
let fmt = outputFormatFromOpts opts
|
||||
valuedate = fromMaybe d $ queryEndDate False $ queryFromOpts d ropts
|
||||
convert | value_ ropts = postingsReportValue j valuedate
|
||||
| otherwise = id
|
||||
render | fmt=="csv" = const ((++"\n") . printCSV . postingsReportAsCsv)
|
||||
| otherwise = postingsReportAsText
|
||||
writeOutput opts $ render opts $ postingsReport ropts (queryFromOpts d ropts) j
|
||||
writeOutput opts $ render opts $ convert $ postingsReport ropts (queryFromOpts d ropts) j
|
||||
|
||||
postingsReportAsCsv :: PostingsReport -> CSV
|
||||
postingsReportAsCsv (_,is) =
|
||||
|
||||
Loading…
Reference in New Issue
Block a user