mirror of
https://github.com/simonmichael/hledger.git
synced 2024-12-26 20:02:27 +03:00
feat: bal: select budget( transaction)s by name (#1612)
This makes it possible to keep multiple named budgets in one journal, and select the one you want with --budget's argument. More precisely, you can select the subset of periodic transactions rules which contain a certain fixed, case-insensitive substring. Only one such --budget argument is supported, the last one on the command line takes precedence.
This commit is contained in:
parent
b0aa70b27a
commit
d2b799a717
@ -98,14 +98,21 @@ budgetReport rspec bopts reportspan j = dbg4 "sortedbudgetreport" budgetreport
|
||||
-- their purpose and effect is to define balance change goals, per account and period,
|
||||
-- for BudgetReport.
|
||||
journalAddBudgetGoalTransactions :: BalancingOpts -> ReportOpts -> DateSpan -> Journal -> Journal
|
||||
journalAddBudgetGoalTransactions bopts _ropts reportspan j =
|
||||
journalAddBudgetGoalTransactions bopts ropts reportspan j =
|
||||
either error' id $ journalBalanceTransactions bopts j{ jtxns = budgetts } -- PARTIAL:
|
||||
where
|
||||
budgetspan = dbg3 "budget span" $ reportspan
|
||||
pat = fromMaybe "" $ dbg3 "budget pattern" $ T.toLower <$> budgetpat_ ropts
|
||||
-- select periodic transactions matching a pattern
|
||||
-- (the argument of the (final) --budget option).
|
||||
-- XXX two limitations/wishes, requiring more extensive type changes:
|
||||
-- - give an error if pat is non-null and matches no periodic txns
|
||||
-- - allow a regexp or a full hledger query, not just a substring
|
||||
budgetts =
|
||||
dbg5 "budget goal txns" $
|
||||
[makeBudgetTxn t
|
||||
| pt <- jperiodictxns j
|
||||
, pat `T.isInfixOf` T.toLower (ptdescription pt)
|
||||
, t <- runPeriodicTransaction pt budgetspan
|
||||
]
|
||||
makeBudgetTxn t = txnTieKnot $ t { tdescription = T.pack "Budget transaction" }
|
||||
|
@ -117,8 +117,11 @@ data ReportOpts = ReportOpts {
|
||||
-- for account transactions reports (aregister)
|
||||
,txn_dates_ :: Bool
|
||||
-- for balance reports (bal, bs, cf, is)
|
||||
,balancecalc_ :: BalanceCalculation
|
||||
,balanceaccum_ :: BalanceAccumulation
|
||||
,balancecalc_ :: BalanceCalculation -- ^ What to calculate in balance report cells
|
||||
,balanceaccum_ :: BalanceAccumulation -- ^ How to accumulate balance report values over time
|
||||
,budgetpat_ :: Maybe T.Text -- ^ A case-insensitive description substring
|
||||
-- to select periodic transactions for budget reports.
|
||||
-- (Not a regexp, nor a full hledger query, for now.)
|
||||
,accountlistmode_ :: AccountListMode
|
||||
,drop_ :: Int
|
||||
,row_total_ :: Bool
|
||||
@ -167,6 +170,7 @@ defreportopts = ReportOpts
|
||||
, txn_dates_ = False
|
||||
, balancecalc_ = def
|
||||
, balanceaccum_ = def
|
||||
, budgetpat_ = Nothing
|
||||
, accountlistmode_ = ALFlat
|
||||
, drop_ = 0
|
||||
, row_total_ = False
|
||||
@ -212,8 +216,9 @@ rawOptsToReportOpts rawopts = do
|
||||
,average_ = boolopt "average" rawopts
|
||||
,related_ = boolopt "related" rawopts
|
||||
,txn_dates_ = boolopt "txn-dates" rawopts
|
||||
,balancecalc_ = balancecalcopt rawopts
|
||||
,balancecalc_ = balancecalcopt rawopts
|
||||
,balanceaccum_ = balanceaccumopt rawopts
|
||||
,budgetpat_ = maybebudgetpatternopt rawopts
|
||||
,accountlistmode_ = accountlistmodeopt rawopts
|
||||
,drop_ = posintopt "drop" rawopts
|
||||
,row_total_ = boolopt "row-total" rawopts
|
||||
@ -289,6 +294,10 @@ accountlistmodeopt =
|
||||
"flat" -> Just ALFlat
|
||||
_ -> Nothing
|
||||
|
||||
-- Get the argument of the --budget option if any, or the empty string.
|
||||
maybebudgetpatternopt :: RawOpts -> Maybe T.Text
|
||||
maybebudgetpatternopt = fmap T.pack . maybestringopt "budget"
|
||||
|
||||
balancecalcopt :: RawOpts -> BalanceCalculation
|
||||
balancecalcopt =
|
||||
fromMaybe CalcChange . choiceopt parse where
|
||||
|
@ -277,8 +277,14 @@ balancemode = hledgerCommandMode
|
||||
(
|
||||
[flagNone ["sum"] (setboolopt "sum")
|
||||
"show sum of posting amounts (default)"
|
||||
,flagNone ["budget"] (setboolopt "budget")
|
||||
"show sum of posting amounts compared to budget goals defined by periodic transactions\n "
|
||||
-- XXX --budget[=DESCPAT], --forecast[=PERIODEXP], could be more consistent
|
||||
,flagOpt "" ["budget"] (\s opts -> Right $ setopt "budget" s opts) "DESCPAT"
|
||||
(unlines
|
||||
[ "show sum of posting amounts together with budget goals defined by periodic"
|
||||
, "transactions. With a DESCPAT argument (must be separated by = not space),"
|
||||
, "use only periodic transactions with matching description"
|
||||
, "(case insensitive substring match)."
|
||||
])
|
||||
,flagNone ["valuechange"] (setboolopt "valuechange")
|
||||
"show change of value of period-end historical balances"
|
||||
,flagNone ["change"] (setboolopt "change")
|
||||
|
@ -606,7 +606,7 @@ Budget performance in 2020-01-01..2020-01-15:
|
||||
|| $400 [80% of $500]
|
||||
```
|
||||
|
||||
#### Nested budgets
|
||||
#### Budgets and subaccounts
|
||||
|
||||
You can add budgets to any account in your account hierarchy. If you have budgets on both parent account and some of its children, then budget(s)
|
||||
of the child account(s) would be added to the budget of their parent, much like account balances behave.
|
||||
@ -685,6 +685,27 @@ Budget performance in 2019/01:
|
||||
|| 0 [ 0]
|
||||
```
|
||||
|
||||
#### Selecting budget goals
|
||||
|
||||
The budget report evaluates periodic transaction rules to generate special "goal transactions",
|
||||
which generate the goal amounts for each account in each report subperiod.
|
||||
When troubleshooting, you can use the print command to show these as forecasted transactions:
|
||||
```shell
|
||||
$ hledger print --forecast=BUDGETREPORTPERIOD tag:generated
|
||||
```
|
||||
|
||||
By default, the budget report uses all available periodic transaction rules to generate goals.
|
||||
This includes rules with a different report interval from your report.
|
||||
Eg if you have daily, weekly and monthly periodic rules,
|
||||
all of these will contribute to the goals in a monthly budget report.
|
||||
|
||||
You can select a subset of periodic rules by providing an argument to the `--budget` flag.
|
||||
`--budget=DESCPAT` will match all periodic rules whose description contains DESCPAT,
|
||||
a case-insensitive substring (not a regular expression or query).
|
||||
This means you can give your periodic rules descriptions
|
||||
(remember that [two spaces are needed](#two-spaces-between-period-expression-and-description)),
|
||||
and then select from multiple budgets defined in your journal.
|
||||
|
||||
### Customising single-period balance reports
|
||||
|
||||
For single-period balance reports displayed in the terminal (only),
|
||||
|
@ -595,3 +595,19 @@ Budget performance in 2020Q1:
|
||||
expenses:food || $400 [80% of $500] 0 [0% of $500] $600 [120% of $500]
|
||||
---------------++-----------------------------------------------------------
|
||||
|| 0 [ 0% of $500] 0 [0% of $500] 0 [ 0% of $500]
|
||||
|
||||
# 30. Select from multiple named budgets.
|
||||
<
|
||||
~ weekly weekly budget
|
||||
(aaa) 1
|
||||
|
||||
~ monthly monthly budget
|
||||
(bbb) 10
|
||||
|
||||
$ hledger -f- bal --budget=weekly -p 2021-01
|
||||
> /aaa/
|
||||
>=
|
||||
|
||||
$ hledger -f- bal --budget=monthly -p 2021-01
|
||||
> !/aaa/
|
||||
>=
|
||||
|
Loading…
Reference in New Issue
Block a user