Reputation: 14628
I am making a BI system for a bank-like institution. This system should manage credit contracts, invoices, payments, penalties and interest.
Now, I need to make a method that builds an invoice. I have to calculate how much the customer has to pay right now. He has a debt, which he has to pay for. He also has to pay for the interest. If he was ever late with due payment, penalties are applied for each day he's late.
I thought there were 2 ways of doing this:
The benefits of the first variant:
The flaws of the first variant:
The benefits of the second variant:
The flaws of the second variant:
Is there any other way? Can I combine the benefits from these two? Which one is used in other similar systems you've encountered? Please share any experience.
Upvotes: 1
Views: 280
Reputation: 16928
Problems of this nature are always more complicated than they first appear. This is a consequence of what I like to call the Rumsfeldian problem of the unknown unknown. Basically, whatever you do now, be prepared to make adjustments for arbitrary future rules.
This is a tough proposition. some future possibilities that may have a significant impact on your calculation model are back dated payments, adjustments and charges. Forgiven interest periods may also become an issue (particularly if back dated). Requirements to provide various point-in-time (PIT) calculations based on either what was "known" at that PIT (past view of the past) or taking into account transactions occurring after the reference PIT that were back dated to a PIT before the reference (current view of the past). Calculations of this nature can be a real pain in the head.
My advice would be to calculate from "scratch" (ie. first variant). Implement optimizations (eg. second variant) only when necessary to meet performance constraints. Doing calculations from the beginning is a compute intensive model but is generally more flexible with respect to accommodating unexpected left turns.
If performance is a problem but the frequency of complicating factors (eg. back dated transactions) is relatively low you could explore a hybrid model employing the best of both variants. Here you store the current state and calculate forward using only those transactions that posted since the last stored state to create a new current state. If you hit a "complication" re-do the entire account from the beginning to reestablish the current state.
Being able to accommodate the unexpected without triggering a re-write is probably more important in the long run than shaving calculation time right now. Do not place restrictions on your computation model until you have to. Saving current state often brings with it a number of built in assumptions and restrictions that reduce wiggle room for accommodating future requirements.
Upvotes: 3