-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create SROC two-part tariff flagging endpoint for new charge versions (…
…#1239) https://eaflood.atlassian.net/browse/WATER-4622 https://eaflood.atlassian.net/browse/WATER-4588 This is a part of the work for two-part tariff supplementary billing. A licence can be added to a two-part tariff supplementary bill run in 5 ways. Editing a return, adding a historic charge version, removing a licence from the annual two-part tariff bill run, recalculating a bill and if a licence is lapsed or revoked. Out of these 5 ways, 4 of them are in the legacy code base. To keep the new code for the supplementary billing within our system code base, we have decided to create a new endpoint that the legacy code can hit to calculate if the changed licence needs to be added to a supplementary bill run. This PR sets up the endpoint and flags a licence in need of a supplementary bill run when a historic charge version is added.
- Loading branch information
1 parent
a8a22c3
commit 5a8d0b7
Showing
11 changed files
with
730 additions
and
0 deletions.
There are no files selected for viewing
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
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
61 changes: 61 additions & 0 deletions
61
app/services/licences/supplementary/determine-billing-years.service.js
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
'use strict' | ||
|
||
/** | ||
* Determines which financial year ends are between the date ranges | ||
* @module DetermineBillingYearsService | ||
*/ | ||
|
||
const APRIL = 3 | ||
const LAST_PRE_SROC_FINANCIAL_YEAR_END = 2022 | ||
|
||
/** | ||
* Determines the financial years impacted by changes between the start date and end dates, considering only the | ||
* financial year ends that are relevant for SROC supplementary billing. | ||
* | ||
* It determines the financial year ends for the given `startDate` and `endDate`, and returns | ||
* an array of years that are greater than the last pre-SROC financial year end. | ||
* | ||
* @param {Date} startDate - The start date from which to begin calculating financial years. | ||
* @param {Date} endDate - The end date up to which to calculate financial years. If not provided, | ||
* the current date will be used. | ||
* | ||
* @returns {Object[]} - The financial year end that are impacted by the changes between the start and end dates and are | ||
* relevant for SROC. | ||
*/ | ||
function go (startDate, endDate) { | ||
const years = [] | ||
|
||
const startYear = _adjustedFinancialYearEnd(startDate) | ||
// As some changes don't have an end date we need to take this into consideration | ||
const endYear = _adjustedFinancialYearEnd(endDate || new Date()) | ||
|
||
for (let year = startYear; year <= endYear; year++) { | ||
// SROC supplementary billing started in the financial year 2022/2023. Anything before this year is not considered | ||
// to be SROC | ||
if (year > LAST_PRE_SROC_FINANCIAL_YEAR_END) { | ||
years.push(year) | ||
} | ||
} | ||
|
||
return years | ||
} | ||
|
||
/** | ||
* When flagging a licence for the supplementary bill run, we need to consider which financial years have been | ||
* impacted by the change. We only care about the financial year ends. So if the startDate for a new chargeVersion is | ||
* `2022-05-31`, the financial year end is considered to be `2023` since the financial years run April to March. Same | ||
* goes for if a charge versions endDate is `2023-03-05`, the financial year end is `2023`. | ||
*/ | ||
function _adjustedFinancialYearEnd (date) { | ||
let year = date.getFullYear() | ||
|
||
if (date.getMonth() >= APRIL) { | ||
year++ | ||
} | ||
|
||
return year | ||
} | ||
|
||
module.exports = { | ||
go | ||
} |
76 changes: 76 additions & 0 deletions
76
app/services/licences/supplementary/determine-charge-version-years.service.js
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
'use strict' | ||
|
||
/** | ||
* Determines if a licence with a change in charge version should be flagged for supplementary billing | ||
* @module DetermineChargeVersionYearsService | ||
*/ | ||
|
||
const ChargeVersionModel = require('../../../models/charge-version.model.js') | ||
|
||
/** | ||
* Determines if a licence with a change in charge version should be flagged for supplementary billing. | ||
* | ||
* The service is passed the id of a new charge version and determines if it should be flagged for supplementary | ||
* billing. This is worked out based on the charge versions scheme and if any related charge reference has a two-part | ||
* tariff indicator. If they do, then flagForBilling is set to true. | ||
* | ||
* @param {String} chargeVersionId - The UUID for the charge version to fetch | ||
* | ||
* @returns {Object} - An object containing the related licence, charge version start and end date and if the licence | ||
* should be flagged for two-part tariff supplementary billing | ||
*/ | ||
async function go (chargeVersionId) { | ||
const { chargeReferences, licence, endDate, startDate, scheme } = await _fetchChargeVersion(chargeVersionId) | ||
const result = { | ||
licence, | ||
startDate, | ||
endDate, | ||
twoPartTariff: false, | ||
flagForBilling: false | ||
} | ||
|
||
if (scheme === 'alcs') { | ||
return result | ||
} | ||
|
||
result.twoPartTariff = _twoPartTariffIndicators(chargeReferences) | ||
|
||
// When we can support non two-part tariff billing flags we can remove this line | ||
result.flagForBilling = result.twoPartTariff | ||
|
||
return result | ||
} | ||
|
||
async function _fetchChargeVersion (chargeVersionId) { | ||
return ChargeVersionModel.query() | ||
.findById(chargeVersionId) | ||
.select([ | ||
'id', | ||
'scheme', | ||
'startDate', | ||
'endDate']) | ||
.withGraphFetched('chargeReferences') | ||
.modifyGraph('chargeReferences', (builder) => { | ||
builder.select([ | ||
'id', | ||
'adjustments' | ||
]) | ||
}) | ||
.withGraphFetched('licence') | ||
.modifyGraph('licence', (builder) => { | ||
builder.select([ | ||
'id', | ||
'regionId' | ||
]) | ||
}) | ||
} | ||
|
||
function _twoPartTariffIndicators (chargeReferences) { | ||
return chargeReferences.some((chargeReference) => { | ||
return chargeReference.adjustments?.s127 | ||
}) | ||
} | ||
|
||
module.exports = { | ||
go | ||
} |
52 changes: 52 additions & 0 deletions
52
app/services/licences/supplementary/determine-existing-bill-run-years.service.js
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
'use strict' | ||
|
||
/** | ||
* Determines from the years provided which ones have an annual or two-part tariff bill run created | ||
* @module DetermineExistingBillRunYearsService | ||
*/ | ||
|
||
const BillRunModel = require('../../../models/bill-run.model.js') | ||
|
||
/** | ||
* Determines from the years provided which ones have an annual or two-part tariff bill run created | ||
* | ||
* This service is responsible for determining the years an annual or two part tariff bill run has been created for. | ||
* This allows those years to be flagged on the licence for supplementary billing. | ||
* | ||
* The service has been passed an array of years that the change on the licence covers. It then verify whether an annual | ||
* or two-part tariff bill run has already been sent for those years. If it has then the year is returned. We do not | ||
* want to flag any years on the licence that hasn't had a bill run already created, as the change on the licence will | ||
* get picked up when the annual/ two-part tariff bill run is created for that year. | ||
* | ||
* @param {String} regionId - The UUID of the region to search for | ||
* @param {Object[]} years - The years that the licence can be flagged for | ||
* @param {Boolean} twoPartTariff - If there are two-part tariff indicators on the licence | ||
* | ||
* @returns {Object[]} - The years that can be flagged for supplementary billing | ||
*/ | ||
async function go (regionId, years, twoPartTariff) { | ||
return _supplementaryBillingYears(regionId, years, twoPartTariff) | ||
} | ||
|
||
/** | ||
* We need to verify which years annual two-part tariff bill runs have been sent. A year shouldn't be flagged for a | ||
* supplementary bill run if the annual bill run hasn't been sent yet, as any licence changes will be handled in the | ||
* annual run. | ||
*/ | ||
async function _supplementaryBillingYears (regionId, years, twoPartTariff) { | ||
const batchType = twoPartTariff ? 'two_part_tariff' : 'annual' | ||
|
||
const billRuns = await BillRunModel.query() | ||
.distinct('toFinancialYearEnding') | ||
.where('regionId', regionId) | ||
.where('batchType', batchType) | ||
.whereIn('toFinancialYearEnding', years) | ||
|
||
return billRuns.map((billRun) => { | ||
return billRun.toFinancialYearEnding | ||
}) | ||
} | ||
|
||
module.exports = { | ||
go | ||
} |
74 changes: 74 additions & 0 deletions
74
app/services/licences/supplementary/process-billing-flag.service.js
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
'use strict' | ||
|
||
/** | ||
* Orchestrates flagging a licence for supplementary billing | ||
* @module ProcessBillingFlagService | ||
*/ | ||
|
||
const CreateLicenceSupplementaryYearService = require('./create-licence-supplementary-year.service.js') | ||
const DetermineBillingYearsService = require('./determine-billing-years.service.js') | ||
const DetermineExistingBillRunYearsService = require('./determine-existing-bill-run-years.service.js') | ||
const DetermineChargeVersionYearsService = require('./determine-charge-version-years.service.js') | ||
const { calculateAndLogTimeTaken, currentTimeInNanoseconds } = require('../../../lib/general.lib.js') | ||
|
||
/** | ||
* Orchestrates flagging a licence for supplementary billing | ||
* | ||
* This service orchestrates the process of flagging a licence for supplementary billing. | ||
* It retrieves details of the charge version, including the licence information, start and end dates, whether the | ||
* charge version has two-part tariff indicators, and if it should be flagged for supplementary billing. | ||
* | ||
* If the licence qualifies for flagging, the relevant dates are passed to the `DetermineBillingYearsService`, which | ||
* calculates the years affected by the changes to the licence. | ||
* | ||
* If any SROC years are affected, they are passed to the `DetermineExistingBillRunYearsService`. This service checks | ||
* the affected years to see if they have had an annual or two-part tariff bill runs created. We avoid flagging any | ||
* years that haven't had an annual or two-part tariff bill run, as those changes will be captured when the bill run is | ||
* created. | ||
* | ||
* Finally, we call the `CreateLicenceSupplementaryYearService`, which persists our final list of years along with the | ||
* licence ID and whether two-part tariff is true. | ||
* | ||
* @param {Object} payload - The payload from the request | ||
*/ | ||
async function go (payload) { | ||
try { | ||
const startTime = currentTimeInNanoseconds() | ||
|
||
let result | ||
|
||
if (payload.chargeVersionId) { | ||
result = await DetermineChargeVersionYearsService.go(payload.chargeVersionId) | ||
} else { | ||
return | ||
} | ||
|
||
const { licence, startDate, endDate, twoPartTariff, flagForBilling } = result | ||
|
||
if (!flagForBilling) { | ||
return | ||
} | ||
|
||
const years = DetermineBillingYearsService.go(startDate, endDate) | ||
|
||
if (!years) { | ||
return | ||
} | ||
|
||
const financialYearEnds = await DetermineExistingBillRunYearsService.go(licence.regionId, years, twoPartTariff) | ||
|
||
if (financialYearEnds.length === 0) { | ||
return | ||
} | ||
|
||
await CreateLicenceSupplementaryYearService.go(licence.id, financialYearEnds, twoPartTariff) | ||
|
||
calculateAndLogTimeTaken(startTime, 'Supplementary Billing Flag complete', { licenceId: licence.id }) | ||
} catch (error) { | ||
global.GlobalNotifier.omfg('Supplementary Billing Flag failed', payload, error) | ||
} | ||
} | ||
|
||
module.exports = { | ||
go | ||
} |
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
Oops, something went wrong.