-
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.
Licence import flagging for supplementary billing (#1338)
https://eaflood.atlassian.net/browse/WATER-4591 During the licence import process, we need to check if a licence has been lapsed/revoked or ended. A licence can end at any time, either in the past or the future. If the licence has ended in the past then the licence bills will be incorrect. This means the licence will need to be flagged for either pre-sroc supplementary billing, sroc supplementary billing or two-part tariff supplementary billing (depending on what is affected). This PR is building the service needed to check the licence lapsed/revoked or ended date and flagging if necessary.
- Loading branch information
1 parent
488fc86
commit ebab844
Showing
10 changed files
with
970 additions
and
4 deletions.
There are no files selected for viewing
91 changes: 91 additions & 0 deletions
91
app/services/import/determine-supplementary-billing-flags.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,91 @@ | ||
'use strict' | ||
|
||
/** | ||
* Determines if an imported licence has a new end date | ||
* @module DetermineSupplementaryBillingFlagsService | ||
*/ | ||
|
||
const LicenceModel = require('../../models/licence.model.js') | ||
const ProcessImportedLicenceService = require('../licences/supplementary/process-imported-licence.service.js') | ||
|
||
/** | ||
* Determines if an imported licence has a new end date. | ||
* | ||
* This service is responsible for determining whether a licence imported has a new end day and therefore should be | ||
* flagged for supplementary billing. | ||
* | ||
* It compares the licences end dates (such as lapsed, revoked or expired dates) between WRLS licence and the imported | ||
* data, and if there is a change in the dates allows the licence to go on to determining the flags. | ||
* | ||
* @param {object} importedLicence - The imported licence | ||
* @param {string} licenceId - The UUID of the licence being updated by the import | ||
* | ||
* @returns {Promise} A promise is returned but it does not resolve to anything we expect the caller to use | ||
*/ | ||
async function go (importedLicence, licenceId) { | ||
try { | ||
const licenceChanged = await _licenceChanged(importedLicence, licenceId) | ||
|
||
if (!licenceChanged) { | ||
return | ||
} | ||
|
||
return ProcessImportedLicenceService.go(importedLicence, licenceId) | ||
} catch (error) { | ||
global.GlobalNotifier.omfg('Determine supplementary billing flags on import failed ', { licenceId }, error) | ||
} | ||
} | ||
|
||
async function _licenceChanged (importedLicence, licenceId) { | ||
const query = LicenceModel.query() | ||
.select(['id']) | ||
.where('id', licenceId) | ||
|
||
_whereClauses(query, importedLicence) | ||
|
||
const result = await query | ||
|
||
return result.length === 0 | ||
} | ||
|
||
/** | ||
* Adds where clauses to compare the end dates (expired, revoked, lapsed) of the imported licence with those stored | ||
* in the database. It handles where the end dates can be null. | ||
* | ||
* In SQL, comparing `null` values using a regular `where` clause does not work as expected because | ||
* `null` represents the absence of a value and `null = null` returns false. To address this, we use | ||
* `whereNull` to explicitly check for null values in the database. | ||
* | ||
* If an end date is present on the imported licence, the query uses a standard `where` clause to check | ||
* for a match. If the end date is null, the query uses `whereNull` to compare against the null values. | ||
* | ||
* This ensures that value types (dates and null) can be correctly compared, allowing us to detect changes | ||
* between the imported licence and the existing WRLS licence data. | ||
* | ||
* @private | ||
*/ | ||
function _whereClauses (query, importedLicence) { | ||
const { expiredDate, lapsedDate, revokedDate } = importedLicence | ||
|
||
if (expiredDate) { | ||
query.where('expiredDate', expiredDate) | ||
} else { | ||
query.whereNull('expiredDate') | ||
} | ||
|
||
if (revokedDate) { | ||
query.where('revokedDate', revokedDate) | ||
} else { | ||
query.whereNull('revokedDate') | ||
} | ||
|
||
if (lapsedDate) { | ||
query.where('lapsedDate', lapsedDate) | ||
} else { | ||
query.whereNull('lapsedDate') | ||
} | ||
} | ||
|
||
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
89 changes: 89 additions & 0 deletions
89
app/services/licences/supplementary/fetch-existing-licence-details.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,89 @@ | ||
'use strict' | ||
|
||
/** | ||
* Fetches existing supplementary details about a licence being updated during import | ||
* @module FetchExistingLicenceDetailsService | ||
*/ | ||
|
||
const { db } = require('../../../../db/db.js') | ||
|
||
/** | ||
* Fetches existing supplementary details about a licence being updated during import | ||
* | ||
* We need to get the existing end dates so we can compare with those being imported to determine which have been | ||
* changed (it could be more than one). | ||
* | ||
* The query also determines what relevant charge versions exist for the licence. When processing the licence we have | ||
* to work out whether to set the include in presroc, include in sroc, and include in two-part tariff (by way of | ||
* supplementary billing years) flags on the licence. | ||
* | ||
* We can skip those steps if we know the licence being updated doesn't have the relevant charge versions. If it doesn't | ||
* have them, then it could never have been previously billed for them! | ||
* | ||
* @param {string} licenceId - The UUID of the licence details being fetched | ||
* | ||
* @returns {Promise<object>} - The data needed to determine which supplementary flags the licence needs | ||
*/ | ||
async function go (licenceId) { | ||
const query = _query() | ||
|
||
const { rows: [row] } = await db.raw(query, [licenceId]) | ||
|
||
return row | ||
} | ||
|
||
function _query () { | ||
return ` | ||
SELECT | ||
l.id, | ||
l.expired_date, | ||
l.lapsed_date, | ||
l.revoked_date, | ||
(CASE l.include_in_presroc_billing | ||
WHEN 'yes' THEN TRUE | ||
ELSE FALSE | ||
END) AS flagged_for_presroc, | ||
l.include_in_sroc_billing AS flagged_for_sroc, | ||
EXISTS( | ||
SELECT | ||
1 | ||
FROM | ||
public.charge_versions cv | ||
WHERE | ||
cv.licence_id = l.id | ||
AND cv.start_date < '2022-04-01' | ||
) AS pre_sroc_charge_versions, | ||
EXISTS( | ||
SELECT | ||
1 | ||
FROM | ||
public.charge_versions cv | ||
WHERE | ||
cv.licence_id = l.id | ||
AND cv.start_date > '2022-03-31' | ||
) AS sroc_charge_versions, | ||
EXISTS( | ||
SELECT | ||
1 | ||
FROM | ||
public.charge_versions cv | ||
INNER JOIN | ||
public.charge_references cr ON cr.charge_version_id = cv.id | ||
INNER JOIN | ||
public.charge_elements ce ON ce.charge_reference_id = cr.id | ||
WHERE | ||
cv.licence_id = l.id | ||
AND cv.start_date > '2022-03-31' | ||
AND cr.adjustments->>'s127' = 'true' | ||
AND ce.section_127_Agreement = TRUE | ||
) AS two_part_tariff_charge_versions | ||
FROM | ||
public.licences l | ||
WHERE | ||
l.id = ?; | ||
` | ||
} | ||
|
||
module.exports = { | ||
go | ||
} |
59 changes: 59 additions & 0 deletions
59
app/services/licences/supplementary/persist-supplementary-billing-flags.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,59 @@ | ||
'use strict' | ||
|
||
/** | ||
* Persists the supplementary billing flags for a licence | ||
* @module PersistSupplementaryBillingFlagsService | ||
*/ | ||
|
||
const CreateLicenceSupplementaryYearService = require('./create-licence-supplementary-year.service.js') | ||
const LicenceModel = require('../../../models/licence.model.js') | ||
|
||
/** | ||
* Persists the supplementary billing flags for a licence | ||
* | ||
* Updates the licences includeInPresrocBilling and includeInSrocBilling flags. | ||
* Adds financial years related to two-part tariff billing into the LicenceSupplementaryYears table. | ||
* | ||
* NOTE: Due to the column data type of the includeInPresrocBilling & includeInSrocBilling, one is a string value and | ||
* one is a boolean. | ||
* | ||
* @param {object[]} twoPartTariffBillingYears - The years that need persisting in the LicenceSupplementaryYears table | ||
* @param {boolean} flagForPreSrocSupplementary - `true` or `false` depending on if the licence needs to be flagged | ||
* for pre sroc billing | ||
* @param {boolean} flagForSrocSupplementary - `true` or `false` depending on if the licence needs to be flagged for | ||
* sroc billing | ||
* @param {string} licenceId - The UUID of the licence that needs the flags persisting for | ||
* | ||
* @returns {Promise<object>} - Resolves with the result of persisting two-part tariff billing years, | ||
*/ | ||
async function go (twoPartTariffBillingYears, flagForPreSrocSupplementary, flagForSrocSupplementary, licenceId) { | ||
const includeInPresrocBilling = flagForPreSrocSupplementary ? 'yes' : 'no' | ||
|
||
await _updateLicenceFlags(includeInPresrocBilling, flagForSrocSupplementary, licenceId) | ||
|
||
return _flagForLicenceSupplementaryYears(twoPartTariffBillingYears, licenceId) | ||
} | ||
|
||
/** | ||
* Persists two-part tariff financial years in the LicenceSupplementaryYears table. | ||
* @private | ||
*/ | ||
async function _flagForLicenceSupplementaryYears (twoPartTariffBillingYears, licenceId) { | ||
if (twoPartTariffBillingYears.length === 0) { | ||
return | ||
} | ||
|
||
const twoPartTariff = true | ||
|
||
return CreateLicenceSupplementaryYearService.go(licenceId, twoPartTariffBillingYears, twoPartTariff) | ||
} | ||
|
||
async function _updateLicenceFlags (includeInPresrocBilling, flagForSrocSupplementary, licenceId) { | ||
return LicenceModel.query() | ||
.patch({ includeInPresrocBilling, includeInSrocBilling: flagForSrocSupplementary }) | ||
.where('id', licenceId) | ||
} | ||
|
||
module.exports = { | ||
go | ||
} |
Oops, something went wrong.