Beancount itself is a double-book accounting tool, and does not know of the concept of "budgets".
But the more I use fava I wish there would be a way to display information if a certain account is over budget. I do practice setting budgets for various "accounts" myself to enforce certain spending behavior, and it would be nice to integrate this into the system.
In the "budgeting"-branch I drafted a first version of how this might work and look:
There is a new file which contains the budget-rules. It is a simple plain-text-file and has content like this:
Expenses:Food:Groceries 2013-W52 100.00 USD 2016-W01 120.00 USD 2016-W02 110.00 USD 2016-W06 150.00 USD Expenses:Food:Alcohol 2016-W01 20.00 USD 2016-W02 10.00 USD 2016-W06 5.00 USD ...
The format is very simple: First, the account name (
Expenses:Food:Groceries
). Then, lines with the week of the year where this budget applies to (and starts) (2016-W01
), and finally the amount and currency (20.00 USD
). I will call these lines "Budget entries".These budget entries represent the budget for the specified week of the year, and all weeks thereafter, until a new rule is set for a week after that. So you can set a budget of
10.00 USD
at the very first week of 2015 (2015-W01
), and this budget applies to all weeks until a new entry starting in week 5 of that same year (2015-W05
) appears and sets the new budget to20.00 USD
.A budget for a specific account, currency, start-date and end-date is then calculated by stepping through each day in that period, and adding the budget for the week of that day (divided by 7) to the total sum, until the end-date is reached.
I included a test-file in
fava/util/test-budget.budget
, which contains the rules above for Groceries and Alcohol (accounts in the file generated bybean-example
).You can test it by starting fava with a
bean-example
-generated file, and navigating to http://localhost:5000/account/Expenses:Food/monthly_changes/ (for example). It should look like thisThings to do:
- Discussing if this is a good idea or not
- Discussing if it is to be included in fava or not
- Discussing if the core functionality of this should be factored out into it's own package or should stay within fava
- Writing tests for the "custom language parser"
- The budget is currently "generated" and displayed in the
account.html
-template, but should ultimately be either part of the API or in a second API (BudgetAPI
?).
What do you think @yagebu @corani @redstreet @jbms @xentac @blais
—
Reply to this email directly or view it on GitHub.
I also had the feeling that this should be a feature of beancount rather than just fava.
Where I am pretty sure now is how it should work:
Set the budget for a specific period (day, week, month, quarter, year), and be able to change it with a new entry with a date after the previous entry, as in my example above.
I can't come up with a situation that this does not cover, from in-period budget changes to periods without a budget (setting it to None after a specific date, until the next budget entry comes along).
What I am still struggling with is how/where it should be implemented. That it should live in/near beancount is clear for me now, but exactly how is open. From your suggestions, and some new ideas of my own:
In a separate file, like my example at the top.
In the beancount-file, as metadata:
2009-05-05 open Expenses:Food:Groceries budget: "2015-01-01 monthly 150.00 USD" budget: "2016-01-01 daily 25.00 USD"
Pro: No change necessary to beancount itself. Accessable by plugins.
Con: No real integration with beancount. Errors not along with beancount-errors. Hack-ish.In the beancount-file, as a new type of directive:
2015-01-01 budget Expenses:Food:Groceries weekly 150.00 USD
Pro: Official support, part of the language, "strongly typed", errors along existing errors.
Con: Large change to beancount.
In the beancount-file, as comments:
;budget Expenses:Food:Groceries weekly 150.00 USD
Pro: Quick prototype for beancount possible.
Con: Ugly, hack-ish.If this is to be included in a beancount-file, then the question of organizing is also relevant. I personally like having all budget-related infos next to the Account in one spot, like my example at the top and (1) and like the metadata-solution (2).
I made some progress with the prototype, and one key learning is that (2) "In the beancount-file, as metadata" works well, but there are two drawbacks:
The syntax suggested is not working, because metadata-keys have to be unique (duh, that was obvious).
There is no "open"-directive for the root-level-accounts, eg.
2016-01-01 open Expenses
. So with this method it is not possible to set metadata for the root-level-accounts, and therefore no budget info.(@blais is there a way around this? As far as I see when I do create an
open
entry forExpenses
, it will be stripped.)So I came up with a new "syntax", looking like this:
2015-10-01 open Expenses:Books budget-2015-10: "50.00 EUR" budget-2015-11-01: "45.00 EUR" budget-2015-W50: "60.00 EUR" budget-2016: "30.00 EUR" budget-2016-Q2: "20.00 EUR"I think it looks nice, and it is integrated in the beancount-file, where I think it belongs to. And it would be accessible to beancount-plugins, so it could be better integrated into beancount.
On integrating this directly into beancount:
- I try to interate quickly on how the "Interface" (way of storing budget data) should look like.
- When this is settled, moving this from fava/the 'budgeting'-branch to beancount should be the next step. Checking the input for errors can be done by a plugin, and the reporting-part has to be integrated into the beancount-code.
- In beancount, there are two things that would make sense IMHO: Integration with
bean-report
, and integration withbean-query
.