2

I am in the process of writing a web app to track expenses and which will be multiuser.

Everything is fine with a single expense, but I am struggling to find the best way to represent recurring expenses, i.e. expenses of the same amount and category that repeat regularly until cancelled.

I am thinking to model recurring expenses as an instance of a more generic ExpenseGenerator which as properties has a starting date and a frequency pattern, which then will automatically create one or more Expenses, beginning from the starting date of the generator.

Given that this approach is correct (if not, please suggest some other options), I am unsure about how to trigger the creation of the expenses. Should I create something like a cronjob that creates the new expense as soon as it occurs or check the generator status every time a user does the login?

Both the solutions have some concern point:

  1. Cronjob: this will create a job for each existing expense of each existing user, plus I should deal with different time zones, daylight savings time and so on.
  2. Creation at Login: if the user does not log in for a long period, there might be a lot of expenses to be created.

Am I going in the right direction or is there a more efficient approach to model recurring events and solve all these problems?

3 Answers 3

3

I'll assume that you are tracking occurred expenses (in the past) and not planned expenses (in the future).

The approach of the expense generator is fine:

  • keep track of all the recurring expenses in a collection (or a special table), sorted by date of the next occurence;
  • every time the generator is executed, it shall go through the collection until it reaches the date of today. For every matching item:
    • create the real Expense with the date of occurrence;
    • calculate the next date of occurence and insert the updated item it in the collection (so the same item could be processed several time), unless the end-date (if any) is reached.

As you have a web application, the simplest would be to have the app execute the generator every day (at every startup in order to handle immediately any unforeseen backlog, and then every day based on a timer event), and always for every user. If you have many users, the processing could be spread over a longer period if executed in a separate thread. Be careful however with the consistency in case of user activity (i.e. cancelation of expenses that have a next occurence in the past or on the same day), especially if you have 24/24 requirements due to a large set of timezones.

The option of processing expenditures on demand could be considered as well. However, do this only if it is justified, in particular if there is a high risk of having many ghost users polluting your database with unused accounts. I'd avoid the login scenario as much as possible, because:

  • higher risk to experience delays due to backlog processing at login
  • if backlog processing is done in a separate thread, data might be updated while the user is working, showing an inconsistent/incomplete picture of the account ("wow ! I've $1000 left ! Oops, no, finally it's only $200").
  • what if a user delegates access rights to another user as well ?
  • but most of all, you could not evolve to a push style of applications, with notifications for the user when not logged-in.
2
  • Hey Christophe, out of curiosity what would be your advice if they were tracking planned expenses for the future? I have a similar problem and was about to open a new question for it. Commented Jan 11, 2019 at 0:16
  • 1
    @JordanMackie Tracking for future raises IMHO the question of generating all the planned expenses (e.g. the next 240 months of mortgage), or generating expenses only for a given time horizon (e.g. the next 12 month) or generating only occurred expenses and calculate (and forget) future expenses for the displayed period. It also requires to cope with use cases related to change of expenditure value from a given date in the future (e.g. price revision).
    – Christophe
    Commented Jan 11, 2019 at 8:46
1

Assume a user sets up recurring expenses and never logs in after that. What is the behavior you want? Should expenses be automatically submitted and reimbursed, or, does the user have to log in to approve or confirm recurring expenses?

These are not questions of modeling representation and execution efficiency, but rather questions to ask at the level of the business domain and its stakeholders.  When you have that sorted, you can turn to implementation.

1
  • Thanks for answering, the scope of the app is simply to track expenses so that the user can see them. As soon as user will log in, he/she will trigger their creation. There's no need to create expenses in the exact moment they happen. I am just a bit worried that this approach might cause some trouble if there are a lot of expenses to create.
    – Vektor88
    Commented Nov 10, 2018 at 16:01
1

When creating an expense, simply mark it as reoccurring with an option of the frequency. A daily batch job can then query all UNIQUE past expenses that should reoccur today and create them.

Last Wednesday => Create Expense Title:"Pay Utility bill" Frequency:Weekly, Id: 7

This Week Wednesday => Select Expense where Timestamp + Frequency = Today (Should bring back 7) Create Expense "Pay Utility bill" Frequency - Weekly - Id 34

Next Week Wednesday => Select Expense where Timestamp + Frequency = Today (Should bring back 34) Create Expense Title:"Pay Utility bill", Frequency:Weekly, Id: 48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.