Recently I've received the following requirement which is being quite hard to implement. The system is a Windows Forms financial system and the requirement is as follows:
When the system is opened in the last day of the month, it should ask whether or not an admin user wants to generate the next months billets.
It turns out there is another requirement like that:
When the system is opened in the first day of the month, it should ask whether or not an admin user wants to generate the antecipated invoices for that month.
The system already has functionality developed that allows the generation of billets and invoices, so that is not the issue.
The issue here is: given that it is a certain day of the months and certain specific rules are met, the system must allow for a specific functionality to be called.
In the case of billets, the day is the last day of the month, the rule to be met is that the billets to be generated are for all charges to be paid in the next month, and the functionality is the generation of these billets.
In the case of invoices the day is the first day of the month, the rule to be met is that the invoices should be marked as antecipated and the functionality is the generation of these invoices.
My only idea was to make a slight generalization and approach the problem in the following way:
IPeriodicTaskwith two methods:
Excute. The first tells whether or not today is a day to run that functionality and
Executeruns it. Second, create one
PeriodicTaskConditionwhich encapsulates one integer representing the day of the month. This class has one
IsMetTodaymethod which returns true if today is the said day of the month and false otherwise.
PeriodicBilletGenerationfor the first task and
IPeriodicTask. They hold one reference to
Then in the first form which opens when the app is run, I implement a sort of dashboard which will list all tasks that should be done today. Each of them has a description of the task and a button to run it.
I create then one
PeriodicTaskExecutedevent which signals the task was executed in a certain month. Then to make this list in the dashboard, I check for all concrete implementations of
IPeriodicTaskthese events to see which still have to be run, and if there is any, I show them there.
The only issues I've come accross when trying to implement this were: (i) how to manage the fact that the user will need to edit and persist the
PeriodicTaskConfiguration for each task and (ii) deal with these events correctly.
The bigger problem is persistence. Persistence is usually delt with using repositories for aggregates. The problem here is that we just need to persist one instance of
PeriodicTaskConfiguration per class. So we need a way to say that "this particular instance" corresponds to "
PeriodicBilletGeneration" and "that particular instance" corresponds to "
PeriodicInvoiceGeneration". I really don't know how to do this.
This reminds me a little bit of CQRS: it seems I'm just creating commands and adding support to check with custom rules that these commands should be ran on specific dates. The execution then raises and saves events.
Anyway, my question here is twofold:
Is my approach reasonable? I don't know, I feel like I'm "inventing too much here". I don't know if this is the right way to do object oriented design. I mean this idea came out of thin air, not by any specific process of analysizng the requirements or whatever. It is just one abstraction that seemed correct to me. Is my solution valid and my way of thinking correct?
Is there any better way to approach this particular problem? If there is, how could I have thought of it, instead of following this route?