-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix re-processing REPLACED charge versions #192
Merged
Cruikshanks
merged 10 commits into
main
from
fix-already-processed-replaced-charge-versions
Apr 20, 2023
Merged
Fix re-processing REPLACED charge versions #192
Cruikshanks
merged 10 commits into
main
from
fix-already-processed-replaced-charge-versions
Apr 20, 2023
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Though have confirmed manually locally via a number of scenarios this does the trick.
Remove the commented out line and update the documentation to reflect what is now going on. Also tidied up the imports.
We're going to have to make some changes to the tests. But now we know better what we expect the service to do, and that it is more charge version than licence focused, we take the opportunity to update the test descriptions.
Fix those tests that focused on checking we were only returning 'current' (APPROVED) charge versions.
One of our failing tests highlighted we had been a bit to eager when deleting the status WHERE condition. Though we've not seen much evidence of its use, charge versions do have a status of 'draft'. So, just in case we add that WHERE condition back in and update the tests appropriately.
We have shied away from adding the table name to the licence fields in the WHERE clauses on the basis if it works don't fix it. But by adding `chargeVersions.` to all the charge version based ones we hope to make it clearer where the source of each comes from.
Cruikshanks
force-pushed
the
fix-already-processed-replaced-charge-versions
branch
from
April 20, 2023 08:32
821c4f6
to
1be03b0
Compare
Now REPLACED charge versions are included in the initial result set and processed in our main loop we don't need to deal with REPLACED charge versions as an extra step.
This is now redundant based on the other changes we made.
Again, with the changes we have made to the process this is no longer needed.
The SonarCloud issue might be valid. But it's highlighting code we haven't touched and don't want to play with until we have more unit test coverage. So, not gonna close it. But am ignoring it for now. |
Jozzey
approved these changes
Apr 20, 2023
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
https://eaflood.atlassian.net/browse/WATER-3950
This change was the result of looking into an edge case found during testing. We'll try to explain with an example. But to summarise.
The new process for handling REPLACED charge versions we just added, was processing a charge version that had already been processed. This led to a credit being added to the billing batch that shouldn't be.
Our fix, though small in how it affects
ProcessBillingBatchService
, is to scrap theProcessReplacedChargeVersionsService
and deal with REPLACED charge versions outside of the main process. Instead, our primaryFetchChargeVersionsService
will now return both REPLACED and APPROVED records.Before the fix
So, imagine we have licence
01/123/456
and linked to it are 2 charge versions both for the same account.Bill run 1
The annual bill run was generated resulting in
Bill run 2
Then, a new charge version linked to a different billing account is added which replaces
CHG01
.The supplementary bill run is generated resulting in
The first thing to note is
CHG02
doesn't make an appearance. It's worth understanding why because this is part of the reason this edge case eventually fails. Prior to this change we only fetched APPROVED charge versions and calculated their billable days. We then compared this with previous billing transactions.So, when processing
CHG02
we findTRN01
andTRN02
. This is because we're looking for previous transactions forACC88
, the invoice account linked toCHG02
. We then compare them to our calculated transaction.TRN02
matches (same licence, invoice account and billable days), so we cancel both out of the bill run.TRN01
doesn't match (212 to 153 billable days) so is reversed (debit to credit) and included in the bill run.Because
TRN01
is being included we need to create a billing invoice record forACC88
as part of this bill run.CHG03
goes through the same process. Only we find no previous transactions forACC99
. So nothing gets cancelled out and the calculated transaction is included in the bill run.Bill run 3
Another new charge version is added linked to
ACC99
which replacesCHG03
. A possible reason for this is a mistake with the details entered forCHG03
.The supplementary bill run is generated. It should result in an empty bill run. Instead, it was resulting in this
It should be empty because the change hasn't impacted what we have previously billed.
ACC88
got their credit for April to August in Bill run 2.ACC99
was correctly charged for the same period in the same bill run.CHG04
has not changed the abstraction period or the billing account and as it replacesCHG03
it is for exactly the same period.But we have ended up with a credit. This is because the new stage in the process we added to handle REPLACED charge versions that have invoice accounts that have not been processed has gone wrong.
Remember why
CHG02
didn't make an appearance in bill run 2? For the same reason, it doesn't appear in bill run 3. What has changed is the previous transactions returned as part of that process. Now, it findsTRN01
,TRN02
, andTRN03
. Before we even compare our calculated lines against these results we first cleanse them of matching debits and credits. This is because if we have a debit matched by a credit for the invoice account, we can safely assume that is something which has already been dealt with as part of a previous change to the charge versions.That is true for this case.
TRN01
which is a debit from bill run 1, was credited byTRN03
as part of bill run 2. So, all that is left to compareCHG02
against isTRN02
. They cancel each other out which means at this point in the process there is nothing to bill forACC88
. Because of this we do not create a billing invoice record forACC88
.CHG04
then gets processed. We findTRN04
as part of that, compare it to our calculated transaction, and get a match so both get cancelled out.At this point, we have nothing in the bill run which is correct. But then we kick off our new replaced charge versions process. That grabs any REPLACED charge versions flagged for supplementary billing that as yet have not been processed. We determine this by cross-checking their invoice account with those in billing invoices.
And there is the flaw! We have processed
ACC88
as part of looking atCHG02
. But we didn't create a billing invoice. So,CHG01
gets returned and processed. TheProcessReplacedChargeVersionsService
doesn't do any calculations. But it does go looking for previous transactions for the invoice account. It will returnTRN01
,TRN02
, andTRN03
. As beforeTRN01
andTRN03
will cancel each other out. But nowTRN02
has nothing to cancel it out, which means we add it to the bill run.😱🤦😩
Explaining the fix
Once we realised what was going on our initial plan was to add another query to
ProcessReplacedChargeVersionsService
to filter out REPLACED charge versions with invoice accounts also linked to APPROVED charge versions. But withFetchChargeVersions
,FetchReplacedChargeVersions
and this new one we'd be running almost identical queries 3 times.What if we could process REPLACED charge versions at the same time as APPROVED ones? In Reverse previous SROC billing batches in supplementary bill run process we realised only pulling out previous debit transactions was causing things to go wrong. Using the same premise, if we pulled all charge versions through would the whole compare and cancel idea work better? It would certainly reduce the complexity and improve performance.
Our testing confirmed this.
Bill run 3 (fixed)
Remember the situation prior to running bill run 3.
Our expectation is an empty bill run.
ProcessBillingBatchService
will look atCHG01
. We've added some logic that says 'this is replaced - do not bother calculating' which means it will iterate toCHG02
. That will generate a calculated line.CHG03
comes next but before we process it we trigger a call to finalise the current billing invoice forACC88
. That's where we look at previous transactions and returnTRN01
,TRN02
, andTRN03
. As we covered earlier,TRN01
andTRN03
cancel each other out and our calculated line when matched toTRN02
also gets cancelled.This leaves us with nothing to bill which is what we want. And as we've removed the
ProcessReplacedChargeVersionsService
step, we're no longer making the mistake of adding something that's been processed.Nothing broken
We are also still handling the scenario
ProcessReplacedChargeVersionsService
was built to handle. Imagine we had a single all-year charge version linked toACC66
debited in the annual bill run. We then replace it with a charge version linked to a new invoice account.When the supplementary billing is run previously
CHG05
would have been handled by theProcessReplacedChargeVersionsService
. Now, it's included in our main process. When we finalise the billing invoice forACC66
we'll see that debit, reverse it and include it in the bill run. With nothing calculated and no other transactions, it won't get cancelled out.