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 | ||||
| @ -214,6 +218,7 @@ rawOptsToReportOpts rawopts = do | ||||
|           ,txn_dates_   = boolopt "txn-dates" 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