From 053902df4c3b1f1b09f46a40938b7ea41157b832 Mon Sep 17 00:00:00 2001 From: Alan Cruikshanks Date: Tue, 20 Aug 2024 21:59:24 +0100 Subject: [PATCH] Add Charge version change reasons to seeder (#1274) https://eaflood.atlassian.net/browse/WATER-4579 We recently started [seeding the test DB with reference data](https://github.com/DEFRA/water-abstraction-system/pull/1206). We then [Restructured that seeding to be Knex based](https://github.com/DEFRA/water-abstraction-system/pull/1230). We thought we'd covered all reference data with the seeding. But we've just spotted that we missed charge version change reasons (`ChangeReasonModel`). We're about to add some new unit tests in [Add history attributes to ChargeVersionModel](https://github.com/DEFRA/water-abstraction-system/pull/1272) that depend on them. So, rather than inserting more into the DB, this change switches change reasons to be 'reference' based, i.e., tests should select from pre-seeded reasons rather than adding generated ones. --- .../fetch-charge-versions.service.js | 2 +- db/seeds/12-change-reasons.seed.js | 52 ++ db/seeds/data/change-reasons.js | 183 +++++++ test/models/change-reason.model.test.js | 8 +- test/models/charge-version.model.test.js | 6 +- .../fetch-billing-accounts.service.test.js | 300 ++++++------ .../determine-minimum-charge.service.test.js | 32 +- .../fetch-charge-versions.service.test.js | 371 ++++++--------- .../process-billing-period.service.test.js | 165 +++---- .../fetch-charge-versions.service.test.js | 448 +++++++++--------- .../fetch-charge-versions.service.test.js | 11 +- .../fetch-licence-summary.service.test.js | 6 +- test/support/database.js | 2 + test/support/helpers/change-reason.helper.js | 58 +-- test/support/seeders/licence-holder.seeder.js | 21 +- 15 files changed, 917 insertions(+), 748 deletions(-) create mode 100644 db/seeds/12-change-reasons.seed.js create mode 100644 db/seeds/data/change-reasons.js diff --git a/app/services/bill-runs/two-part-tariff/fetch-charge-versions.service.js b/app/services/bill-runs/two-part-tariff/fetch-charge-versions.service.js index 8fc1806299..19d4e5e7b2 100644 --- a/app/services/bill-runs/two-part-tariff/fetch-charge-versions.service.js +++ b/app/services/bill-runs/two-part-tariff/fetch-charge-versions.service.js @@ -83,7 +83,7 @@ async function _fetch (regionId, billingPeriod) { // rather than have to remember that quirk we stick with whereJsonPath() which works in all cases. .whereJsonPath('chargeReferences.adjustments', '$.s127', '=', true) ) - .orderBy('chargeVersions.licenceRef') + .orderBy('chargeVersions.licenceRef', 'asc') .withGraphFetched('changeReason') .modifyGraph('changeReason', (builder) => { builder.select([ diff --git a/db/seeds/12-change-reasons.seed.js b/db/seeds/12-change-reasons.seed.js new file mode 100644 index 0000000000..0f21150b86 --- /dev/null +++ b/db/seeds/12-change-reasons.seed.js @@ -0,0 +1,52 @@ +'use strict' + +const { timestampForPostgres } = require('../../app/lib/general.lib.js') +const { data: changeReasons } = require('./data/change-reasons.js') +const ChangeReasonModel = require('../../app/models/change-reason.model.js') + +async function seed () { + for (const changeReason of changeReasons) { + const exists = await _exists(changeReason) + + if (exists) { + await _update(changeReason) + } else { + await _insert(changeReason) + } + } +} + +async function _exists (changeReason) { + const { description, type } = changeReason + + const result = await ChangeReasonModel.query() + .select('id') + .where('description', description) + .where('type', type) + .limit(1) + .first() + + return !!result +} + +async function _insert (changeReason) { + // NOTE: The table does not auto populate the created and updated at fields, but does define them as not nullable! + return ChangeReasonModel.query().insert({ + ...changeReason, + createdAt: timestampForPostgres(), + updatedAt: timestampForPostgres() + }) +} + +async function _update (changeReason) { + const { description, enabledForNewChargeVersions, triggersMinimumCharge, type } = changeReason + + return ChangeReasonModel.query() + .patch({ enabledForNewChargeVersions, triggersMinimumCharge, updatedAt: timestampForPostgres() }) + .where('description', description) + .where('type', type) +} + +module.exports = { + seed +} diff --git a/db/seeds/data/change-reasons.js b/db/seeds/data/change-reasons.js new file mode 100644 index 0000000000..ba21ad66d7 --- /dev/null +++ b/db/seeds/data/change-reasons.js @@ -0,0 +1,183 @@ +'use strict' + +const data = [ + { + id: '4e8ee7ee-ea1f-4966-a01c-372d8451ee44', + description: 'Major change', + triggersMinimumCharge: false, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '5decf55d-4206-497c-bb33-afa5e2c5e78c', + description: 'Minor change', + triggersMinimumCharge: false, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: 'e327eb32-6680-445e-a4eb-ef5bf8c62c82', + description: 'New special agreement', + triggersMinimumCharge: false, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '2cd3c47a-3284-47aa-94e6-61432d0c8ef7', + description: 'Change to a special agreement', + triggersMinimumCharge: false, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: 'e76e3c36-5e26-4af8-b258-fbc0993a656a', + description: 'Licence holder name or address change', + triggersMinimumCharge: false, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: 'c88af35e-7afd-4150-8eba-967c086b540a', + description: 'Billing contact change', + triggersMinimumCharge: false, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '9fadddb6-e272-41e8-8f3c-757677f22c28', + description: 'Limited extension of licence validity (LEV)', + triggersMinimumCharge: false, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: 'a0d73154-23ce-40c4-ad8b-aa08ba49095f', + description: 'Charge information cancelled before licence expiry date', + triggersMinimumCharge: false, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '65330ae7-80b0-4f1f-8898-87a92bcb3301', + description: 'Succession or transfer of licence', + triggersMinimumCharge: true, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: 'd6bd26d5-af97-4256-b483-09b150f47795', + description: 'Succession to a remainder licence or licence apportionment', + triggersMinimumCharge: true, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: 'f54e7435-b547-43d8-b984-af24ad5b3a62', + description: 'New licence in part succession or licence apportionment', + triggersMinimumCharge: true, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: 'd37dbced-348a-4e69-9018-8c52d7943632', + description: 'New licence', + triggersMinimumCharge: true, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '5c1aad75-d40d-4492-9fa7-3ec7719f3d0d', + description: 'Licence transferred and now chargeable', + triggersMinimumCharge: true, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '0cb79169-098b-4031-87c3-ebe8eab21e35', + description: 'Held by Environment Agency', + triggersMinimumCharge: false, + type: 'new_non_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '5f908870-813a-4c78-b69d-cc3244418d78', + description: 'Aggregate licence', + triggersMinimumCharge: false, + type: 'new_non_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '1055d6ad-bf1c-4cae-a966-847b67fecd01', + description: 'Chloride content more than 8000 milligrams per litre', + triggersMinimumCharge: false, + type: 'new_non_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '3098b9fb-f1d6-479e-adf7-6cf24f50222f', + description: 'Abatement (S126)', + triggersMinimumCharge: false, + type: 'new_non_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '2ec83d68-453a-4b1c-9370-87410b59a14b', + description: 'Power generation less than 5 megawatts (S125)', + triggersMinimumCharge: false, + type: 'new_non_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '362809bf-96c3-457d-90a3-19b5cf5e88b9', + description: 'Temporary trade', + triggersMinimumCharge: false, + type: 'new_non_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '74d96ebd-018d-4f64-a4e2-65c97825821e', + description: 'Temporary type licence', + triggersMinimumCharge: false, + type: 'new_non_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '7557c1e8-e342-4a62-bf3c-aa87a2865814', + description: 'Transfer type licence', + triggersMinimumCharge: false, + type: 'new_non_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: 'ca51e7a2-340f-48d4-8ecb-f5d470e2a4d0', + description: 'Shell licence ', + triggersMinimumCharge: false, + type: 'new_non_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '9770b866-f32a-4b26-ad83-7f89c1e47d31', + description: 'NALD gap', + triggersMinimumCharge: false, + type: 'new_non_chargeable_charge_version', + enabledForNewChargeVersions: false + }, + { + id: 'f002cfd2-2ea5-483a-93e5-865a6aed9873', + description: 'Licence revoked within a month of annual billing', + triggersMinimumCharge: false, + type: 'new_non_chargeable_charge_version', + enabledForNewChargeVersions: true + }, + { + id: '620c85f1-14da-4549-b0d3-94293e657587', + description: 'Strategic review of charges (SRoC)', + triggersMinimumCharge: false, + type: 'new_chargeable_charge_version', + enabledForNewChargeVersions: true + } +] + +module.exports = { + data +} diff --git a/test/models/change-reason.model.test.js b/test/models/change-reason.model.test.js index 8adce42487..66e5e959e9 100644 --- a/test/models/change-reason.model.test.js +++ b/test/models/change-reason.model.test.js @@ -4,7 +4,7 @@ const Lab = require('@hapi/lab') const Code = require('@hapi/code') -const { describe, it, beforeEach } = exports.lab = Lab.script() +const { describe, it, before, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers @@ -15,11 +15,13 @@ const ChargeVersionModel = require('../../app/models/charge-version.model.js') // Thing under test const ChangeReasonModel = require('../../app/models/change-reason.model.js') +const CHANGE_REASON_SUCCESSION_REMAINDER_INDEX = 9 + describe('Change Reason model', () => { let testRecord - beforeEach(async () => { - testRecord = await ChangeReasonHelper.add() + before(async () => { + testRecord = ChangeReasonHelper.select(CHANGE_REASON_SUCCESSION_REMAINDER_INDEX) }) describe('Basic query', () => { diff --git a/test/models/charge-version.model.test.js b/test/models/charge-version.model.test.js index 75296580bd..926ef9fbf3 100644 --- a/test/models/charge-version.model.test.js +++ b/test/models/charge-version.model.test.js @@ -26,6 +26,8 @@ const ModLogModel = require('../../app/models/mod-log.model.js') const ReviewChargeVersionHelper = require('../support/helpers/review-charge-version.helper.js') const ReviewChargeVersionModel = require('../../app/models/review-charge-version.model.js') +const CHANGE_REASON_NEW_LICENCE_PART_INDEX = 10 + // Thing under test const ChargeVersionModel = require('../../app/models/charge-version.model.js') @@ -117,7 +119,7 @@ describe('Charge Version model', () => { let testChangeReason beforeEach(async () => { - testChangeReason = await ChangeReasonHelper.add() + testChangeReason = ChangeReasonHelper.select(CHANGE_REASON_NEW_LICENCE_PART_INDEX) const { id: changeReasonId } = testChangeReason @@ -140,7 +142,7 @@ describe('Charge Version model', () => { expect(result.id).to.equal(testRecord.id) expect(result.changeReason).to.be.an.instanceOf(ChangeReasonModel) - expect(result.changeReason).to.equal(testChangeReason) + expect(result.changeReason).to.equal(testChangeReason, { skip: ['createdAt', 'updatedAt'] }) }) }) diff --git a/test/services/bill-runs/annual/fetch-billing-accounts.service.test.js b/test/services/bill-runs/annual/fetch-billing-accounts.service.test.js index e12821c079..e3eea5609c 100644 --- a/test/services/bill-runs/annual/fetch-billing-accounts.service.test.js +++ b/test/services/bill-runs/annual/fetch-billing-accounts.service.test.js @@ -4,7 +4,7 @@ const Lab = require('@hapi/lab') const Code = require('@hapi/code') -const { describe, it, beforeEach } = exports.lab = Lab.script() +const { describe, it, before, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers @@ -16,7 +16,6 @@ const ChargeElementHelper = require('../../../support/helpers/charge-element.hel const ChargeReferenceHelper = require('../../../support/helpers/charge-reference.helper.js') const ChargeVersionHelper = require('../../../support/helpers/charge-version.helper.js') const WorkflowHelper = require('../../../support/helpers/workflow.helper.js') -const DatabaseSupport = require('../../../support/database.js') const LicenceHelper = require('../../../support/helpers/licence.helper.js') const RegionHelper = require('../../../support/helpers/region.helper.js') @@ -25,69 +24,187 @@ const { determineCurrentFinancialYear } = require('../../../../app/lib/general.l // Thing under test const FetchBillingAccountsService = require('../../../../app/services/bill-runs/annual/fetch-billing-accounts.service.js') +const CHANGE_REASON_NEW_LICENCE_PART_INDEX = 10 +const REGION_ANGLIAN_INDEX = 0 +const REGION_MIDLANDS_INDEX = 1 + describe('Fetch Billing Accounts service', () => { const billingPeriod = determineCurrentFinancialYear() let billingAccount - let billingAccountId let licence - let licenceId + let minimumChargeChangeReason let region - let regionId - beforeEach(async () => { - await DatabaseSupport.clean() + before(async () => { + minimumChargeChangeReason = ChangeReasonHelper.select(CHANGE_REASON_NEW_LICENCE_PART_INDEX) + }) + + describe('when there are no billing accounts that should be considered for the annual bill run', () => { + before(() => { + region = RegionHelper.select(REGION_MIDLANDS_INDEX) + }) + + beforeEach(async () => { + licence = await LicenceHelper.add({ regionId: region.id }) + billingAccount = await BillingAccountHelper.add() + }) + + describe('because all their charge versions do not have a status of "current"', () => { + beforeEach(async () => { + await ChargeVersionHelper.add({ + status: 'draft', + billingAccountId: billingAccount.id, + licenceId: licence.id + }) + }) + + it('returns empty results', async () => { + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) + + describe('because all their charge versions are for the "alcs" (presroc) scheme', () => { + beforeEach(async () => { + await ChargeVersionHelper.add({ + scheme: 'alcs', + billingAccountId: billingAccount.id, + licenceId: licence.id + }) + }) + + it('returns empty results', async () => { + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) - region = RegionHelper.select() - regionId = region.id + describe('because all their charge versions have start dates after the billing period', () => { + beforeEach(async () => { + const financialStartYear = billingPeriod.endDate.getFullYear() - licence = await LicenceHelper.add({ regionId }) - licenceId = licence.id + // This creates an charge version with a start date after the billing period + await ChargeVersionHelper.add({ + startDate: new Date(financialStartYear, 8, 15), + billingAccountId: billingAccount.id, + licenceId: licence.id + }) + }) + + it('returns empty results', async () => { + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) + + describe('because all their charge versions have end dates before the billing period', () => { + beforeEach(async () => { + const financialEndYear = billingPeriod.startDate.getFullYear() - billingAccount = await BillingAccountHelper.add() - billingAccountId = billingAccount.id + // This creates an charge version with a end date before the billing period starts + await ChargeVersionHelper.add({ + endDate: new Date(financialEndYear, 2, 31), + billingAccountId: billingAccount.id, + licenceId: licence.id + }) + }) + + it('returns empty results', async () => { + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) + + describe('because they are all linked to licences in a different region', () => { + beforeEach(async () => { + const { id: licenceId } = await LicenceHelper.add({ regionId: 'e117b501-e3c1-4337-ad35-21c60ed9ad73' }) + + // This creates an charge version linked to a licence with an different region than selected + await ChargeVersionHelper.add({ billingAccountId: billingAccount.id, licenceId }) + }) + + it('returns empty results', async () => { + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) + + describe('because they are all linked to licences that ended before the billing period', () => { + beforeEach(async () => { + const { id: licenceId } = await LicenceHelper.add({ revokedDate: new Date('2023-02-01') }) + + // This creates a charge version linked to a licence that ends before the billing period + await ChargeVersionHelper.add({ billingAccountId: billingAccount.id, licenceId }) + }) + + it('returns empty results', async () => { + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) + + describe('because they are all linked to licences in workflow', () => { + beforeEach(async () => { + await ChargeVersionHelper.add({ billingAccountId: billingAccount.id, licenceId: licence.id }) + await WorkflowHelper.add({ licenceId: licence.id }) + }) + + it('returns empty results', async () => { + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) }) describe('when there are billing accounts that should be considered for annual billing', () => { - let changeReason let chargeCategory let chargeElement let chargeReference let chargeVersion - beforeEach(async () => { - changeReason = await ChangeReasonHelper.add({ triggersMinimumCharge: true }) - - const { id: licenceId, licenceRef } = licence - const { id: changeReasonId } = changeReason + before(async () => { + region = RegionHelper.select(REGION_ANGLIAN_INDEX) + licence = await LicenceHelper.add({ regionId: region.id }) + billingAccount = await BillingAccountHelper.add() chargeVersion = await ChargeVersionHelper.add( - { startDate: new Date('2023-11-01'), changeReasonId, billingAccountId, licenceId, licenceRef } + { + startDate: new Date('2023-11-01'), + changeReasonId: minimumChargeChangeReason.id, + billingAccountId: billingAccount.id, + licenceId: licence.id, + licenceRef: licence.licenceRef + } ) - const { id: chargeVersionId } = chargeVersion chargeCategory = await ChargeCategoryHelper.add() - const { id: chargeCategoryId } = chargeCategory - - chargeReference = await ChargeReferenceHelper.add({ chargeVersionId, chargeCategoryId }) - const { id: chargeReferenceId } = chargeReference - - chargeElement = await ChargeElementHelper.add({ chargeReferenceId }) + chargeReference = await ChargeReferenceHelper.add({ + chargeVersionId: chargeVersion.id, chargeCategoryId: chargeCategory.id + }) + chargeElement = await ChargeElementHelper.add({ chargeReferenceId: chargeReference.id }) }) it('returns the applicable billing accounts', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) expect(results).to.have.length(1) expect(results[0]).to.be.instanceOf(BillingAccountModel) - expect(results[0].id).to.equal(billingAccountId) + expect(results[0].id).to.equal(billingAccount.id) expect(results[0].accountNumber).to.equal(billingAccount.accountNumber) }) describe('that have applicable related charge versions', () => { it('includes the charge versions in each result', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) const { chargeVersions } = results[0] @@ -95,12 +212,12 @@ describe('Fetch Billing Accounts service', () => { expect(chargeVersions[0].scheme).to.equal('sroc') expect(chargeVersions[0].startDate).to.equal(new Date('2023-11-01')) expect(chargeVersions[0].endDate).to.be.null() - expect(chargeVersions[0].billingAccountId).to.equal(billingAccountId) + expect(chargeVersions[0].billingAccountId).to.equal(billingAccount.id) expect(chargeVersions[0].status).to.equal('current') }) it('includes the licence and region in each result', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) const { licence } = results[0].chargeVersions[0] @@ -109,12 +226,12 @@ describe('Fetch Billing Accounts service', () => { expect(licence.waterUndertaker).to.equal(false) expect(licence.historicalAreaCode).to.equal('SAAR') expect(licence.regionalChargeArea).to.equal('Southern') - expect(licence.region.id).to.equal(regionId) + expect(licence.region.id).to.equal(region.id) expect(licence.region.chargeRegionId).to.equal(region.chargeRegionId) }) it('includes the change reason in each result', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) const { changeReason } = results[0].chargeVersions[0] @@ -123,7 +240,7 @@ describe('Fetch Billing Accounts service', () => { }) it('includes the charge references, charge category and charge elements in each result', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) const { chargeReferences } = results[0].chargeVersions[0] @@ -157,15 +274,19 @@ describe('Fetch Billing Accounts service', () => { describe('that have inapplicable related charge versions', () => { beforeEach(async () => { - const licenceInWorkflow = await LicenceHelper.add({ regionId }) + const licenceInWorkflow = await LicenceHelper.add({ regionId: region.id }) const { id: licenceInWorkflowId, licenceRef } = licenceInWorkflow - await ChargeVersionHelper.add({ billingAccountId, licenceId: licenceInWorkflowId, licenceRef }) + await ChargeVersionHelper.add({ + billingAccountId: billingAccount.id, + licenceId: licenceInWorkflowId, + licenceRef + }) await WorkflowHelper.add({ licenceId: licenceInWorkflowId }) }) it('excludes the charge versions in each result', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) + const results = await FetchBillingAccountsService.go(region.id, billingPeriod) const { chargeVersions } = results[0] @@ -174,107 +295,4 @@ describe('Fetch Billing Accounts service', () => { }) }) }) - - describe('when there are no billing accounts that should be considered for the annual bill run', () => { - describe('because all their charge versions do not have a status of "current"', () => { - beforeEach(async () => { - await ChargeVersionHelper.add({ status: 'draft', billingAccountId, licenceId }) - }) - - it('returns empty results', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) - - describe('because all their charge versions are for the "alcs" (presroc) scheme', () => { - beforeEach(async () => { - await ChargeVersionHelper.add({ scheme: 'alcs', billingAccountId, licenceId }) - }) - - it('returns empty results', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) - - describe('because all their charge versions have start dates after the billing period', () => { - beforeEach(async () => { - const financialStartYear = billingPeriod.endDate.getFullYear() - - // This creates an charge version with a start date after the billing period - await ChargeVersionHelper.add( - { startDate: new Date(financialStartYear, 8, 15), billingAccountId, licenceId } - ) - }) - - it('returns empty results', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) - - describe('because all their charge versions have end dates before the billing period', () => { - beforeEach(async () => { - const financialEndYear = billingPeriod.startDate.getFullYear() - - // This creates an charge version with a end date before the billing period starts - await ChargeVersionHelper.add( - { endDate: new Date(financialEndYear, 2, 31), billingAccountId, licenceId } - ) - }) - - it('returns empty results', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) - - describe('because they are all linked to licences in a different region', () => { - beforeEach(async () => { - const { id: licenceId } = await LicenceHelper.add({ regionId: 'e117b501-e3c1-4337-ad35-21c60ed9ad73' }) - - // This creates an charge version linked to a licence with an different region than selected - await ChargeVersionHelper.add({ billingAccountId, licenceId }) - }) - - it('returns empty results', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) - - describe('because they are all linked to licences that ended before the billing period', () => { - beforeEach(async () => { - const { id: licenceId } = await LicenceHelper.add({ revokedDate: new Date('2023-02-01') }) - - // This creates a charge version linked to a licence that ends before the billing period - await ChargeVersionHelper.add({ billingAccountId, licenceId }) - }) - - it('returns empty results', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) - - describe('because they are all linked to licences in workflow', () => { - beforeEach(async () => { - await ChargeVersionHelper.add({ billingAccountId, licenceId }) - await WorkflowHelper.add({ licenceId }) - }) - - it('returns empty results', async () => { - const results = await FetchBillingAccountsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) - }) }) diff --git a/test/services/bill-runs/determine-minimum-charge.service.test.js b/test/services/bill-runs/determine-minimum-charge.service.test.js index d6fcd561b0..ae3e754994 100644 --- a/test/services/bill-runs/determine-minimum-charge.service.test.js +++ b/test/services/bill-runs/determine-minimum-charge.service.test.js @@ -4,38 +4,42 @@ const Lab = require('@hapi/lab') const Code = require('@hapi/code') -const { describe, it, beforeEach } = exports.lab = Lab.script() +const { describe, it, before, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers const ChangeReasonHelper = require('../../support/helpers/change-reason.helper.js') const ChargeVersionHelper = require('../../support/helpers/charge-version.helper.js') -const DatabaseSupport = require('../../support/database.js') // Thing under test const DetermineMinimumChargeService = require('../../../app/services/bill-runs/determine-minimum-charge.service.js') +const CHANGE_REASON_CHARGE_CANCELLED_INDEX = 7 +const CHANGE_REASON_NEW_LICENCE_PART_INDEX = 10 + describe('Determine Minimum Charge service', () => { const chargePeriod = { startDate: new Date('2023-04-01'), endDate: new Date('2024-03-31') } + + let minimumChargeChangeReason + let noMinimumChargeChangeReason let chargeVersion - beforeEach(async () => { - await DatabaseSupport.clean() + before(() => { + minimumChargeChangeReason = ChangeReasonHelper.select(CHANGE_REASON_NEW_LICENCE_PART_INDEX) + noMinimumChargeChangeReason = ChangeReasonHelper.select(CHANGE_REASON_CHARGE_CANCELLED_INDEX) }) describe('where the charge version start date is the same as the charge period', () => { describe('and the charge version change reason triggers a minimum charge', () => { beforeEach(async () => { - const changeReason = await ChangeReasonHelper.add({ triggersMinimumCharge: true }) - chargeVersion = await ChargeVersionHelper.add({ startDate: new Date('2023-04-01'), - changeReasonId: changeReason.changeReasonId + changeReasonId: minimumChargeChangeReason.id }) - chargeVersion.changeReason = changeReason + chargeVersion.changeReason = minimumChargeChangeReason chargeVersion.licence = { startDate: new Date('2022-01-01') } }) @@ -48,13 +52,11 @@ describe('Determine Minimum Charge service', () => { describe('and the charge version change reason does not trigger a minimum charge', () => { beforeEach(async () => { - const changeReason = await ChangeReasonHelper.add({ triggersMinimumCharge: false }) - chargeVersion = await ChargeVersionHelper.add({ startDate: new Date('2022-05-01'), - changeReasonId: changeReason.changeReasonId + changeReasonId: noMinimumChargeChangeReason.id }) - chargeVersion.changeReason = changeReason + chargeVersion.changeReason = noMinimumChargeChangeReason chargeVersion.licence = { startDate: new Date('2022-01-01') } }) @@ -68,13 +70,11 @@ describe('Determine Minimum Charge service', () => { describe('where the charge version start date is not the same as the charge period', () => { beforeEach(async () => { - const changeReason = await ChangeReasonHelper.add({ triggersMinimumCharge: true }) - chargeVersion = await ChargeVersionHelper.add({ startDate: new Date('2022-03-01'), - changeReasonId: changeReason.changeReasonId + changeReasonId: minimumChargeChangeReason.id }) - chargeVersion.changeReason = changeReason + chargeVersion.changeReason = minimumChargeChangeReason chargeVersion.licence = { startDate: new Date('2022-01-01') } }) diff --git a/test/services/bill-runs/supplementary/fetch-charge-versions.service.test.js b/test/services/bill-runs/supplementary/fetch-charge-versions.service.test.js index cb29e5696c..42f9ad8dcc 100644 --- a/test/services/bill-runs/supplementary/fetch-charge-versions.service.test.js +++ b/test/services/bill-runs/supplementary/fetch-charge-versions.service.test.js @@ -4,7 +4,7 @@ const Lab = require('@hapi/lab') const Code = require('@hapi/code') -const { describe, it, beforeEach } = exports.lab = Lab.script() +const { describe, it, before, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers @@ -14,26 +14,152 @@ const ChargeElementHelper = require('../../../support/helpers/charge-element.hel const ChargeReferenceHelper = require('../../../support/helpers/charge-reference.helper.js') const ChargeVersionHelper = require('../../../support/helpers/charge-version.helper.js') const WorkflowHelper = require('../../../support/helpers/workflow.helper.js') -const DatabaseSupport = require('../../../support/database.js') const LicenceHelper = require('../../../support/helpers/licence.helper.js') const RegionHelper = require('../../../support/helpers/region.helper.js') // Thing under test const FetchChargeVersionsService = require('../../../../app/services/bill-runs/supplementary/fetch-charge-versions.service.js') +const CHANGE_REASON_NEW_LICENCE_PART_INDEX = 10 +const REGION_THAMES_INDEX = 6 +const REGION_WALES_INDEX = 7 + describe('Fetch Charge Versions service', () => { + const billingPeriod = { + startDate: new Date('2023-04-01'), + endDate: new Date('2024-03-31') + } const licenceDefaults = LicenceHelper.defaults() - let testRecords - let billingPeriod + let changeReason + let licence let region - let regionId + let testRecords + + before(async () => { + changeReason = ChangeReasonHelper.select(CHANGE_REASON_NEW_LICENCE_PART_INDEX) + }) + + describe('when there are no charge version that should be considered for the next supplementary billing', () => { + before(() => { + region = RegionHelper.select(REGION_THAMES_INDEX) + }) + + describe('because they all have start dates after the billing period', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ regionId: region.id, includeInSrocBilling: true }) + + // This creates an SROC charge version with a start date after the billing period. This will be picked in + // next years bill runs + await ChargeVersionHelper.add({ + licenceId: licence.id, licenceRef: licence.licenceRef, startDate: new Date('2025-04-01') + }) + }) + + it('returns no applicable licenceIds or charge versions', async () => { + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(result.chargeVersions).to.be.empty() + expect(result.licenceIdsForPeriod).to.be.empty() + }) + }) + + describe('because the licences flagged for supplementary billing are linked to a different region', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ + regionId: 'e117b501-e3c1-4337-ad35-21c60ed9ad73', includeInSrocBilling: true + }) + + // This creates an SROC charge version linked to a licence with an different region than selected + await ChargeVersionHelper.add({ licenceId: licence.id, licenceRef: licence.licenceRef }) + }) + + it('returns no applicable licenceIds or charge versions', async () => { + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(result.chargeVersions).to.be.empty() + expect(result.licenceIdsForPeriod).to.be.empty() + }) + }) + + describe('because they are all linked to licences in workflow', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ regionId: region.id, includeInSrocBilling: true }) + + await ChargeVersionHelper.add({ licenceId: licence.id, licenceRef: licence.licenceRef }) + + await WorkflowHelper.add({ licenceId: licence.id }) + }) - beforeEach(async () => { - await DatabaseSupport.clean() + it('returns no applicable licenceIds or charge versions', async () => { + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(result.chargeVersions).to.be.empty() + expect(result.licenceIdsForPeriod).to.be.empty() + }) + }) + + describe('because none of them are linked to a licence flagged "includeInSrocBilling"', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ includeInSrocBilling: false, regionId: region.id }) + await ChargeVersionHelper.add({ licenceId: licence.id, licenceRef: licence.licenceRef }) + }) - region = RegionHelper.select() - regionId = region.id + it('returns no applicable licenceIds or charge versions', async () => { + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(result.chargeVersions).to.be.empty() + expect(result.licenceIdsForPeriod).to.be.empty() + }) + }) + + describe('because all the applicable charge versions have a "draft" status', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ regionId: region.id, includeInSrocBilling: true }) + + await ChargeVersionHelper.add({ licenceId: licence.id, licenceRef: licence.licenceRef, status: 'draft' }) + }) + + it('returns no applicable licenceIds or charge versions', async () => { + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(result.chargeVersions).to.be.empty() + expect(result.licenceIdsForPeriod).to.be.empty() + }) + }) + + describe('because all of them are for the "alcs" (presroc) scheme', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ regionId: region.id, includeInPresrocBilling: 'yes' }) + + // This creates an ALCS (presroc) charge version linked to a licence marked for supplementary billing + await ChargeVersionHelper.add({ licenceId: licence.id, licenceRef: licence.licenceRef, scheme: 'alcs' }) + }) + + it('returns no applicable licenceIds or charge versions', async () => { + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(result.chargeVersions).to.be.empty() + expect(result.licenceIdsForPeriod).to.be.empty() + }) + }) + + describe('because none of them have a "billingAccountId"', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ regionId: region.id, includeInSrocBilling: true }) + + // This creates a charge version with no `billingAccountId` + await ChargeVersionHelper.add({ billingAccountId: null, licenceId: licence.id, licenceRef: licence.licenceRef }) + }) + + it('returns the licenceId but no applicable charge versions', async () => { + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(result.chargeVersions).to.be.empty() + expect(result.licenceIdsForPeriod).to.have.length(1) + expect(result.licenceIdsForPeriod[0]).to.equal(licence.id) + }) + }) }) describe('when there are charge versions that should be considered for the next supplementary billing', () => { @@ -44,44 +170,39 @@ describe('Fetch Charge Versions service', () => { let chargeElement2023 let chargeElement2023And24 let chargeElement2024 - let changeReason let licence - beforeEach(async () => { - billingPeriod = { - startDate: new Date('2023-04-01'), - endDate: new Date('2024-03-31') - } + before(async () => { + region = RegionHelper.select(REGION_WALES_INDEX) + licence = await LicenceHelper.add({ - regionId, + regionId: region.id, waterUndertaker: true, includeInSrocBilling: true, includeInPresrocBilling: 'yes' }) - changeReason = await ChangeReasonHelper.add({ triggersMinimumCharge: true }) const { id: licenceId, licenceRef } = licence - const { id: changeReasonId } = changeReason const billingAccountId = '77483323-daec-443e-912f-b87e1e9d0721' // This creates a 'current' SROC charge version which covers only FYE 2024 const sroc2024ChargeVersion = await ChargeVersionHelper.add( - { startDate: new Date('2023-11-01'), changeReasonId, billingAccountId, licenceId, licenceRef } + { startDate: new Date('2023-11-01'), changeReasonId: changeReason.id, billingAccountId, licenceId, licenceRef } ) // This creates a 'current' SROC charge version which covers both FYE 2023 and 2024 const sroc2023And24ChargeVersion = await ChargeVersionHelper.add( - { endDate: new Date('2023-10-31'), changeReasonId, billingAccountId, licenceId, licenceRef } + { endDate: new Date('2023-10-31'), changeReasonId: changeReason.id, billingAccountId, licenceId, licenceRef } ) // This creates a 'current' SROC charge version which covers only FYE 2023 const sroc2023ChargeVersion = await ChargeVersionHelper.add( - { endDate: new Date('2022-10-31'), changeReasonId, billingAccountId, licenceId, licenceRef } + { endDate: new Date('2022-10-31'), changeReasonId: changeReason.id, billingAccountId, licenceId, licenceRef } ) // This creates a 'superseded' SROC charge version const srocSupersededChargeVersion = await ChargeVersionHelper.add( - { changeReasonId, status: 'superseded', billingAccountId, licenceId, licenceRef } + { changeReasonId: changeReason.id, status: 'superseded', billingAccountId, licenceId, licenceRef } ) // This creates an ALCS (presroc) charge version @@ -130,12 +251,12 @@ describe('Fetch Charge Versions service', () => { }) describe('including those linked to soft-deleted workflow records', () => { - beforeEach(async () => { + before(async () => { await WorkflowHelper.add({ licenceId: licence.id, deletedAt: new Date('2022-04-01') }) }) it('returns the SROC charge versions that are applicable', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) expect(result.chargeVersions).to.have.length(4) @@ -150,7 +271,7 @@ describe('Fetch Charge Versions service', () => { }) it('returns a unique list of licenceIds from SROC charge versions that are applicable', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) expect(result.licenceIdsForPeriod).to.have.length(1) expect(result.licenceIdsForPeriod[0]).to.equal(licence.id) @@ -158,7 +279,7 @@ describe('Fetch Charge Versions service', () => { }) it('returns both "current" and "superseded" SROC charge version that are applicable', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) expect(result.chargeVersions).to.have.length(4) @@ -173,24 +294,24 @@ describe('Fetch Charge Versions service', () => { }) it('includes the related licence and region', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) expect(result.chargeVersions[0].licence.licenceRef).to.equal(licence.licenceRef) expect(result.chargeVersions[0].licence.waterUndertaker).to.equal(true) expect(result.chargeVersions[0].licence.historicalAreaCode).to.equal(licenceDefaults.regions.historicalAreaCode) expect(result.chargeVersions[0].licence.regionalChargeArea).to.equal(licenceDefaults.regions.regionalChargeArea) - expect(result.chargeVersions[0].licence.region.id).to.equal(regionId) + expect(result.chargeVersions[0].licence.region.id).to.equal(region.id) expect(result.chargeVersions[0].licence.region.chargeRegionId).to.equal(region.chargeRegionId) }) it('includes the related change reason', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) expect(result.chargeVersions[0].changeReason.triggersMinimumCharge).to.equal(changeReason.triggersMinimumCharge) }) it('includes the related charge references, charge category and charge elements', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) + const result = await FetchChargeVersionsService.go(region.id, billingPeriod) const expectedResult2024 = { id: chargeReference2024.id, @@ -260,194 +381,4 @@ describe('Fetch Charge Versions service', () => { expect(result.chargeVersions[2].chargeReferences[0]).to.equal(expectedResult2023) }) }) - - describe('when there are no charge version that should be considered for the next supplementary billing', () => { - describe('because none of them are linked to a licence flagged "includeInSrocSupplementaryBilling"', () => { - beforeEach(async () => { - billingPeriod = { - startDate: new Date('2022-04-01'), - endDate: new Date('2023-03-31') - } - - // This creates an SROC charge version linked to a licence. But the licence won't be marked for supplementary - // billing - const srocChargeVersion = await ChargeVersionHelper.add() - - testRecords = [srocChargeVersion] - }) - - it('returns no applicable licenceIds or charge versions', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(result.chargeVersions).to.be.empty() - expect(result.licenceIdsForPeriod).to.be.empty() - }) - }) - - describe('because all the applicable charge versions have a "draft" status', () => { - beforeEach(async () => { - billingPeriod = { - startDate: new Date('2022-04-01'), - endDate: new Date('2023-03-31') - } - - const { id: licenceId } = await LicenceHelper.add({ - regionId, - waterUndertaker: true, - includeInSrocBilling: true - }) - - const srocDraftChargeVersion = await ChargeVersionHelper.add({ status: 'draft', licenceId }) - - testRecords = [srocDraftChargeVersion] - }) - - it('returns no applicable licenceIds or charge versions', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(result.chargeVersions).to.be.empty() - expect(result.licenceIdsForPeriod).to.be.empty() - }) - }) - - describe('because all of them are for the "alcs" (presroc) scheme', () => { - beforeEach(async () => { - billingPeriod = { - startDate: new Date('2022-04-01'), - endDate: new Date('2023-03-31') - } - - const { id: licenceId } = await LicenceHelper.add({ - regionId, - includeInPresrocBilling: 'yes' - }) - - // This creates an ALCS (presroc) charge version linked to a licence marked for supplementary billing - const alcsChargeVersion = await ChargeVersionHelper.add({ scheme: 'alcs', licenceId }) - - testRecords = [alcsChargeVersion] - }) - - it('returns no applicable licenceIds or charge versions', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(result.chargeVersions).to.be.empty() - expect(result.licenceIdsForPeriod).to.be.empty() - }) - }) - - describe('because none of them have a "billingAccountId"', () => { - let licenceId - - beforeEach(async () => { - billingPeriod = { - startDate: new Date('2022-04-01'), - endDate: new Date('2023-03-31') - } - - const licence = await LicenceHelper.add({ - regionId, - includeInSrocBilling: true - }) - - licenceId = licence.id - - // This creates a charge version with no `billingAccountId` - const nullBillingAccountIdChargeVersion = await ChargeVersionHelper - .add({ billingAccountId: null, licenceId }) - - testRecords = [nullBillingAccountIdChargeVersion] - }) - - it('returns the licenceId but no applicable charge versions', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(result.chargeVersions).to.be.empty() - expect(result.licenceIdsForPeriod).to.have.length(1) - expect(result.licenceIdsForPeriod[0]).to.equal(licenceId) - }) - }) - - describe('because they all have start dates after the billing period', () => { - beforeEach(async () => { - billingPeriod = { - startDate: new Date('2022-04-01'), - endDate: new Date('2023-03-31') - } - - const { id: licenceId } = await LicenceHelper.add({ - regionId, - includeInSrocBilling: true - }) - - // This creates an SROC charge version with a start date after the billing period. This will be picked in - // next years bill runs - const srocChargeVersion = await ChargeVersionHelper.add( - { startDate: new Date('2023-04-01'), licenceId } - ) - - testRecords = [srocChargeVersion] - }) - - it('returns no applicable licenceIds or charge versions', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(result.chargeVersions).to.be.empty() - expect(result.licenceIdsForPeriod).to.be.empty() - }) - }) - - describe('because the licences flagged for supplementary billing are linked to a different region', () => { - beforeEach(async () => { - billingPeriod = { - startDate: new Date('2022-04-01'), - endDate: new Date('2023-03-31') - } - - const { id: licenceId } = await LicenceHelper.add({ - regionId: 'e117b501-e3c1-4337-ad35-21c60ed9ad73', - includeInSrocBilling: true - }) - - // This creates an SROC charge version linked to a licence with an different region than selected - const otherRegionChargeVersion = await ChargeVersionHelper.add({ licenceId }) - - testRecords = [otherRegionChargeVersion] - }) - - it('returns no applicable licenceIds or charge versions', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(result.chargeVersions).to.be.empty() - expect(result.licenceIdsForPeriod).to.be.empty() - }) - }) - - describe('because they are all linked to licences in workflow', () => { - beforeEach(async () => { - billingPeriod = { - startDate: new Date('2022-04-01'), - endDate: new Date('2023-03-31') - } - - const { id: licenceId } = await LicenceHelper.add({ - regionId, - includeInSrocBilling: true - }) - - const chargeVersion = await ChargeVersionHelper.add({ licenceId }) - - await WorkflowHelper.add({ licenceId }) - - testRecords = [chargeVersion] - }) - - it('returns no applicable licenceIds or charge versions', async () => { - const result = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(result.chargeVersions).to.be.empty() - expect(result.licenceIdsForPeriod).to.be.empty() - }) - }) - }) }) diff --git a/test/services/bill-runs/supplementary/process-billing-period.service.test.js b/test/services/bill-runs/supplementary/process-billing-period.service.test.js index 80aa138e62..865d8c881e 100644 --- a/test/services/bill-runs/supplementary/process-billing-period.service.test.js +++ b/test/services/bill-runs/supplementary/process-billing-period.service.test.js @@ -20,7 +20,6 @@ const ChargeReferenceHelper = require('../../../support/helpers/charge-reference const ChargeVersionHelper = require('../../../support/helpers/charge-version.helper.js') const FetchChargeVersionsService = require('../../../../app/services/bill-runs/supplementary/fetch-charge-versions.service.js') const LicenceHelper = require('../../../support/helpers/licence.helper.js') -const DatabaseSupport = require('../../../support/database.js') const RegionHelper = require('../../../support/helpers/region.helper.js') // Things we need to stub @@ -31,6 +30,9 @@ const SendTransactionsService = require('../../../../app/services/bill-runs/send // Thing under test const ProcessBillingPeriodService = require('../../../../app/services/bill-runs/supplementary/process-billing-period.service.js') +const CHANGE_NEW_AGREEMENT_INDEX = 2 +const REGION_SOUTH_WEST_INDEX = 4 + describe('Supplementary Process billing period service', () => { const billingPeriod = { startDate: new Date('2022-04-01'), @@ -43,18 +45,17 @@ describe('Supplementary Process billing period service', () => { let changeReason let chargeVersions let licence + let region beforeEach(async () => { - await DatabaseSupport.clean() - - const { id: regionId } = RegionHelper.select() + region = RegionHelper.select(REGION_SOUTH_WEST_INDEX) - licence = await LicenceHelper.add({ includeInSrocBilling: true, regionId }) - changeReason = await ChangeReasonHelper.add() + licence = await LicenceHelper.add({ includeInSrocBilling: true, regionId: region.id }) + changeReason = ChangeReasonHelper.select(CHANGE_NEW_AGREEMENT_INDEX) billingAccount = await BillingAccountHelper.add() chargeCategory = await ChargeCategoryHelper.add() - billRun = await BillRunHelper.add({ regionId }) + billRun = await BillRunHelper.add({ regionId: region.id }) }) afterEach(() => { @@ -75,6 +76,81 @@ describe('Supplementary Process billing period service', () => { }) describe('and there are charge versions to process', () => { + describe('but none of them are billable', () => { + describe('because the billable days calculated as 0', () => { + beforeEach(async () => { + const { id: chargeVersionId } = await ChargeVersionHelper.add( + { + changeReasonId: changeReason.id, + billingAccountId: billingAccount.id, + startDate: new Date(2022, 7, 1, 9), + licenceId: licence.id + } + ) + const { id: chargeReferenceId } = await ChargeReferenceHelper.add( + { chargeCategoryId: chargeCategory.id, chargeVersionId } + ) + + await ChargeElementHelper.add({ + chargeReferenceId, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 5 + }) + + const chargeVersionData = await FetchChargeVersionsService.go(licence.regionId, billingPeriod) + + chargeVersions = chargeVersionData.chargeVersions + }) + + describe('and there are no previous billed transactions', () => { + it('returns false (bill run is empty)', async () => { + const result = await ProcessBillingPeriodService.go(billRun, billingPeriod, chargeVersions) + + expect(result).to.be.false() + }) + }) + }) + + describe('because the charge version status is "superseded"', () => { + describe('and there are no previously billed transactions', () => { + beforeEach(async () => { + const { id: chargeVersionId } = await ChargeVersionHelper.add( + { + changeReasonId: changeReason.id, + billingAccountId: billingAccount.id, + startDate: new Date(2022, 7, 1, 9), + licenceId: licence.id, + status: 'superseded' + } + ) + const { chargeElementId } = await ChargeReferenceHelper.add( + { chargeCategoryId: chargeCategory.id, chargeVersionId } + ) + + await ChargeElementHelper.add({ + chargeElementId, + abstractionPeriodStartDay: 1, + abstractionPeriodStartMonth: 4, + abstractionPeriodEndDay: 31, + abstractionPeriodEndMonth: 3 + }) + + const chargeVersionData = await FetchChargeVersionsService.go(licence.regionId, billingPeriod) + + chargeVersions = chargeVersionData.chargeVersions + }) + + it('returns false (bill run is empty)', async () => { + const result = await ProcessBillingPeriodService.go(billRun, billingPeriod, chargeVersions) + + expect(result).to.be.false() + }) + }) + }) + }) + describe('and they are billable', () => { beforeEach(async () => { const { id: chargeVersionId } = await ChargeVersionHelper.add( @@ -151,81 +227,6 @@ describe('Supplementary Process billing period service', () => { expect(result).to.be.true() }) }) - - describe('but none of them are billable', () => { - describe('because the billable days calculated as 0', () => { - beforeEach(async () => { - const { id: chargeVersionId } = await ChargeVersionHelper.add( - { - changeReasonId: changeReason.id, - billingAccountId: billingAccount.id, - startDate: new Date(2022, 7, 1, 9), - licenceId: licence.id - } - ) - const { id: chargeReferenceId } = await ChargeReferenceHelper.add( - { chargeCategoryId: chargeCategory.id, chargeVersionId } - ) - - await ChargeElementHelper.add({ - chargeReferenceId, - abstractionPeriodStartDay: 1, - abstractionPeriodStartMonth: 4, - abstractionPeriodEndDay: 31, - abstractionPeriodEndMonth: 5 - }) - - const chargeVersionData = await FetchChargeVersionsService.go(licence.regionId, billingPeriod) - - chargeVersions = chargeVersionData.chargeVersions - }) - - describe('and there are no previous billed transactions', () => { - it('returns false (bill run is empty)', async () => { - const result = await ProcessBillingPeriodService.go(billRun, billingPeriod, chargeVersions) - - expect(result).to.be.false() - }) - }) - }) - - describe('because the charge version status is "superseded"', () => { - describe('and there are no previously billed transactions', () => { - beforeEach(async () => { - const { id: chargeVersionId } = await ChargeVersionHelper.add( - { - changeReasonId: changeReason.id, - billingAccountId: billingAccount.id, - startDate: new Date(2022, 7, 1, 9), - licenceId: licence.id, - status: 'superseded' - } - ) - const { chargeElementId } = await ChargeReferenceHelper.add( - { chargeCategoryId: chargeCategory.id, chargeVersionId } - ) - - await ChargeElementHelper.add({ - chargeElementId, - abstractionPeriodStartDay: 1, - abstractionPeriodStartMonth: 4, - abstractionPeriodEndDay: 31, - abstractionPeriodEndMonth: 3 - }) - - const chargeVersionData = await FetchChargeVersionsService.go(licence.regionId, billingPeriod) - - chargeVersions = chargeVersionData.chargeVersions - }) - - it('returns false (bill run is empty)', async () => { - const result = await ProcessBillingPeriodService.go(billRun, billingPeriod, chargeVersions) - - expect(result).to.be.false() - }) - }) - }) - }) }) }) diff --git a/test/services/bill-runs/two-part-tariff/fetch-charge-versions.service.test.js b/test/services/bill-runs/two-part-tariff/fetch-charge-versions.service.test.js index c9a220ff19..3744978d78 100644 --- a/test/services/bill-runs/two-part-tariff/fetch-charge-versions.service.test.js +++ b/test/services/bill-runs/two-part-tariff/fetch-charge-versions.service.test.js @@ -4,7 +4,7 @@ const Lab = require('@hapi/lab') const Code = require('@hapi/code') -const { describe, it, beforeEach } = exports.lab = Lab.script() +const { describe, it, before, beforeEach } = exports.lab = Lab.script() const { expect } = Code // Test helpers @@ -13,10 +13,9 @@ const ChargeCategoryHelper = require('../../../support/helpers/charge-category.h const ChargeElementHelper = require('../../../support/helpers/charge-element.helper.js') const ChargeReferenceHelper = require('../../../support/helpers/charge-reference.helper.js') const ChargeVersionHelper = require('../../../support/helpers/charge-version.helper.js') -const DatabaseSupport = require('../../../support/database.js') +const { generateUUID } = require('../../../../app/lib/general.lib.js') const LicenceHelper = require('../../../support/helpers/licence.helper.js') const LicenceHolderSeeder = require('../../../support/seeders/licence-holder.seeder.js') -const LicenceModel = require('../../../../app/models/licence.model.js') const PurposeHelper = require('../../../support/helpers/purpose.helper.js') const RegionHelper = require('../../../support/helpers/region.helper.js') const WorkflowHelper = require('../../../support/helpers/workflow.helper.js') @@ -24,120 +23,273 @@ const WorkflowHelper = require('../../../support/helpers/workflow.helper.js') // Thing under test const FetchChargeVersionsService = require('../../../../app/services/bill-runs/two-part-tariff/fetch-charge-versions.service.js') +const CHANGE_NEW_AGREEMENT_INDEX = 2 +const PURPOSE_SPRAY_IRRIGATION_INDEX = 41 +const REGION_NORTH_EAST_INDEX = 2 +const REGION_NORTH_WEST_INDEX = 3 + describe('Fetch Charge Versions service', () => { const billingPeriod = { startDate: new Date('2023-04-01'), endDate: new Date('2024-03-31') } - const licenceId = 'cee9ff5f-813a-49c7-ba04-c65cfecf67dd' - const licenceRef = '01/128' - let chargeCategoryId - let regionId - let purposeId + let changeReason + let chargeCategory + let chargeElement1 + let chargeElement2 + let chargeReference + let chargeVersion + let licence + let licenceHolderDetails + let otherChargeVersion + let otherChargeReference + let otherLicence + let region + let purpose + + before(async () => { + purpose = PurposeHelper.select(PURPOSE_SPRAY_IRRIGATION_INDEX) + chargeCategory = await ChargeCategoryHelper.add() + changeReason = ChangeReasonHelper.select(CHANGE_NEW_AGREEMENT_INDEX) + }) + + describe('when there are no applicable charge versions', () => { + before(() => { + region = RegionHelper.select(REGION_NORTH_WEST_INDEX) + }) + + describe('because the scheme is "presroc"', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ regionId: region.id }) + + chargeVersion = await ChargeVersionHelper.add( + { licenceId: licence.id, licenceRef: licence.licenceRef, scheme: 'alcs' } + ) + + chargeReference = await ChargeReferenceHelper.add( + { adjustments: { s127: true }, chargeVersionId: chargeVersion.id, chargeCategory: chargeCategory.id } + ) + }) + + it('returns no records', async () => { + const results = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) + + describe('because the start date is after the billing period ends', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ regionId: region.id }) + + chargeVersion = await ChargeVersionHelper.add( + { licenceId: licence.id, licenceRef: licence.licenceRef, startDate: new Date('2024-04-01') } + ) + + chargeReference = await ChargeReferenceHelper.add( + { adjustments: { s127: true }, chargeVersionId: chargeVersion.id, chargeCategory: chargeCategory.id } + ) + }) + + it('returns no records', async () => { + const results = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) + + describe('because the end date is before the billing period starts', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ regionId: region.id }) + + chargeVersion = await ChargeVersionHelper.add( + { endDate: new Date('2023-03-31'), licenceId: licence.id, licenceRef: licence.licenceRef } + ) + + chargeReference = await ChargeReferenceHelper.add( + { adjustments: { s127: true }, chargeVersionId: chargeVersion.id, chargeCategory: chargeCategory.id } + ) + }) + + it('returns no records', async () => { + const results = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) + + describe('because the status is not "current"', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ regionId: region.id }) + + chargeVersion = await ChargeVersionHelper.add( + { licenceId: licence.id, licenceRef: licence.licenceRef, status: 'superseded' } + ) + + chargeReference = await ChargeReferenceHelper.add( + { adjustments: { s127: true }, chargeVersionId: chargeVersion.id, chargeCategory: chargeCategory.id } + ) + }) + + it('returns no records', async () => { + const results = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) + + describe('because the region is different', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ regionId: generateUUID() }) + + chargeVersion = await ChargeVersionHelper.add({ licenceId: licence.id, licenceRef: licence.licenceRef }) + + chargeReference = await ChargeReferenceHelper.add( + { adjustments: { s127: true }, chargeVersionId: chargeVersion.id, chargeCategory: chargeCategory.id } + ) + }) + + it('returns no records', async () => { + const results = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) + + describe('because the licence is linked to a workflow', () => { + beforeEach(async () => { + licence = await LicenceHelper.add({ regionId: region.id }) + + chargeVersion = await ChargeVersionHelper.add( + { licenceId: licence.id, licenceRef: licence.licenceRef } + ) + + chargeReference = await ChargeReferenceHelper.add( + { adjustments: { s127: true }, chargeVersionId: chargeVersion.id, chargeCategory: chargeCategory.id } + ) - beforeEach(async () => { - await DatabaseSupport.clean() + await WorkflowHelper.add({ licenceId: licence.id }) + }) - purposeId = PurposeHelper.data.find((purpose) => { return purpose.legacyId === '420' }).id + it('returns no records', async () => { + const results = await FetchChargeVersionsService.go(region.id, billingPeriod) + + expect(results).to.be.empty() + }) + }) + + describe('because the licence ended (expired, lapsed or revoked) before the billing period', () => { + beforeEach(async () => { + // NOTE: To make things spicy (!) we have the licence expire _after_ the billing period starts but revoked + // before it. Where the licence has dates in more than one of these fields, it is considered ended on the + // earliest of them (we have found real examples that confirm this is possible) + licence = await LicenceHelper.add( + { expiredDate: new Date('2019-05-01'), regionId: region.id, revokedDate: new Date('2022-06-01') } + ) - const chargeCategory = await ChargeCategoryHelper.add({ reference: '4.3.41' }) + chargeVersion = await ChargeVersionHelper.add( + { licenceId: licence.id, licenceRef: licence.licenceRef } + ) - chargeCategoryId = chargeCategory.id + chargeReference = await ChargeReferenceHelper.add( + { adjustments: { s127: true }, chargeVersionId: chargeVersion.id, chargeCategory: chargeCategory.id } + ) + }) - const region = RegionHelper.select() + it('returns no records', async () => { + const results = await FetchChargeVersionsService.go(region.id, billingPeriod) - regionId = region.id + expect(results).to.be.empty() + }) + }) }) describe('when there are applicable charge versions', () => { - const chargeVersionId = '2c2f0ab5-4f73-416e-b3f8-5ed19d81bd59' + before(async () => { + region = RegionHelper.select(REGION_NORTH_EAST_INDEX) - beforeEach(async () => { - const { id: changeReasonId } = await ChangeReasonHelper.add() - - const licence = await LicenceHelper.add({ id: licenceId, licenceRef, regionId, expiredDate: new Date('2024-05-01') }) + licence = await LicenceHelper.add({ licenceRef: '01/128', regionId: region.id }) // NOTE: The first part of the setup creates a charge version we will test exactly matches what we expect. The // second part is to create another charge version with a different licence ref so we can test the order of the // results - await ChargeVersionHelper.add({ id: chargeVersionId, licenceId, licenceRef, changeReasonId }) + chargeVersion = await ChargeVersionHelper.add({ + changeReasonId: changeReason.id, licenceId: licence.id, licenceRef: licence.licenceRef + }) - const { id: chargeReferenceId } = await ChargeReferenceHelper.add({ - id: 'a86837fa-cf25-42fe-8216-ea8c2d2c939d', - chargeVersionId, - chargeCategoryId, + chargeReference = await ChargeReferenceHelper.add({ + chargeVersionId: chargeVersion.id, + chargeCategoryId: chargeCategory.id, adjustments: { s127: true, aggregate: 0.562114443 } }) - await ChargeElementHelper.add({ - id: '1a966bd1-dbce-499d-ae94-b1d6ab72f0b2', - chargeReferenceId, + chargeElement1 = await ChargeElementHelper.add({ + chargeReferenceId: chargeReference.id, authorisedAnnualQuantity: 100, - purposeId + purposeId: purpose.id }) - await ChargeElementHelper.add({ - id: 'dab91d76-6778-417f-8f2d-9124a270e926', - chargeReferenceId, + chargeElement2 = await ChargeElementHelper.add({ + chargeReferenceId: chargeReference.id, authorisedAnnualQuantity: 200, - purposeId + purposeId: purpose.id }) + // Create a licence holder for the licence with the default name 'Licence Holder Ltd' + licenceHolderDetails = await LicenceHolderSeeder.seed(licence.licenceRef) + // Second charge version to test ordering - const otherLicence = await LicenceHelper.add({ licenceRef: '01/130', regionId }) - const chargeVersion = await ChargeVersionHelper.add( - { licenceId: otherLicence.id, licenceRef: '01/130', changeReasonId } + otherLicence = await LicenceHelper.add({ licenceRef: '01/130', regionId: region.id }) + otherChargeVersion = await ChargeVersionHelper.add( + { changeReasonId: changeReason.id, licenceId: otherLicence.id, licenceRef: otherLicence.licenceRef } ) - const chargeReference = await ChargeReferenceHelper.add({ - chargeVersionId: chargeVersion.id, - chargeCategoryId, + otherChargeReference = await ChargeReferenceHelper.add({ + chargeVersionId: otherChargeVersion.id, + chargeCategoryId: chargeCategory.id, adjustments: { s127: true } }) await ChargeElementHelper.add({ - chargeReferenceId: chargeReference.id, + chargeReferenceId: otherChargeReference.id, authorisedAnnualQuantity: 100, - purposeId + purposeId: purpose.id }) - - // Create a licence holder for the licence with the default name 'Licence Holder Ltd' - await LicenceHolderSeeder.seed(licence.licenceRef) }) it('returns the charge version with related licence, charge references and charge elements', async () => { - const results = await FetchChargeVersionsService.go(regionId, billingPeriod) + const results = await FetchChargeVersionsService.go(region.id, billingPeriod) expect(results).to.have.length(2) expect(results[0]).to.equal({ - id: '2c2f0ab5-4f73-416e-b3f8-5ed19d81bd59', + id: chargeVersion.id, startDate: new Date('2022-04-01'), endDate: null, status: 'current', licence: { - id: 'cee9ff5f-813a-49c7-ba04-c65cfecf67dd', - licenceRef: '01/128', + id: licence.id, + licenceRef: licence.licenceRef, startDate: new Date('2022-01-01'), - expiredDate: new Date('2024-05-01'), + expiredDate: null, lapsedDate: null, revokedDate: null, licenceDocument: { - id: results[0].licence.licenceDocument.id, + id: licenceHolderDetails.licenceDocumentId, licenceDocumentRoles: [ { company: { - id: results[0].licence.licenceDocument.licenceDocumentRoles[0].company.id, + id: licenceHolderDetails.companyId, name: 'Licence Holder Ltd', type: 'organisation' }, contact: null, - id: results[0].licence.licenceDocument.licenceDocumentRoles[0].id + id: licenceHolderDetails.licenceDocumentRoleId } ] } }, chargeReferences: [{ - id: 'a86837fa-cf25-42fe-8216-ea8c2d2c939d', + id: chargeReference.id, volume: 6.819, description: 'Mineral washing', aggregate: 0.562114443, @@ -147,13 +299,13 @@ describe('Fetch Charge Versions service', () => { winter: null, charge: null, chargeCategory: { - reference: '4.3.41', + reference: chargeCategory.reference, shortDescription: 'Low loss, non-tidal, restricted water, up to and including 5,000 ML/yr, Tier 1 model', subsistenceCharge: 12000 }, chargeElements: [ { - id: 'dab91d76-6778-417f-8f2d-9124a270e926', + id: chargeElement2.id, description: 'Trickle Irrigation - Direct', abstractionPeriodStartDay: 1, abstractionPeriodStartMonth: 4, @@ -161,13 +313,13 @@ describe('Fetch Charge Versions service', () => { abstractionPeriodEndMonth: 3, authorisedAnnualQuantity: 200, purpose: { - id: purposeId, - legacyId: '420', - description: 'Spray Irrigation - Storage' + id: purpose.id, + legacyId: purpose.legacyId, + description: purpose.description } }, { - id: '1a966bd1-dbce-499d-ae94-b1d6ab72f0b2', + id: chargeElement1.id, description: 'Trickle Irrigation - Direct', abstractionPeriodStartDay: 1, abstractionPeriodStartMonth: 4, @@ -175,189 +327,31 @@ describe('Fetch Charge Versions service', () => { abstractionPeriodEndMonth: 3, authorisedAnnualQuantity: 100, purpose: { - id: purposeId, - legacyId: '420', - description: 'Spray Irrigation - Storage' + id: purpose.id, + legacyId: purpose.legacyId, + description: purpose.description } } ] }], changeReason: { - description: 'Strategic review of charges (SRoC)' + description: changeReason.description } }) }) it('returns the charge versions ordered by licence reference', async () => { - const results = await FetchChargeVersionsService.go(regionId, billingPeriod) + const results = await FetchChargeVersionsService.go(region.id, billingPeriod) - expect(results[0].licence.licenceRef).to.equal('01/128') - expect(results[1].licence.licenceRef).to.equal('01/130') + expect(results[0].licence.licenceRef).to.equal(licence.licenceRef) + expect(results[1].licence.licenceRef).to.equal(otherLicence.licenceRef) }) it('returns the charge elements within each charge version ordered by authorised annual quantity', async () => { - const results = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(results[0].chargeReferences[0].chargeElements[0].id).to.equal('dab91d76-6778-417f-8f2d-9124a270e926') - expect(results[0].chargeReferences[0].chargeElements[1].id).to.equal('1a966bd1-dbce-499d-ae94-b1d6ab72f0b2') - }) - }) - - describe('when there are no applicable charge versions', () => { - beforeEach(async () => { - await LicenceHelper.add({ id: licenceId, licenceRef, regionId }) - }) - - describe('because the scheme is "presroc"', () => { - beforeEach(async () => { - const { id: chargeVersionId } = await ChargeVersionHelper.add( - { scheme: 'alcs', licenceId, licenceRef } - ) - - await ChargeReferenceHelper.add({ - chargeVersionId, - chargeCategoryId, - adjustments: { s127: true } - }) - }) - - it('returns no records', async () => { - const results = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) - - describe('because the start date is after the billing period ends', () => { - beforeEach(async () => { - const { id: chargeVersionId } = await ChargeVersionHelper.add( - { startDate: new Date('2024-04-01'), licenceId, licenceRef } - ) - - await ChargeReferenceHelper.add({ - chargeVersionId, - chargeCategoryId, - adjustments: { s127: true } - }) - }) - - it('returns no records', async () => { - const results = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) - - describe('because the end date is before the billing period starts', () => { - beforeEach(async () => { - const { id: chargeVersionId } = await ChargeVersionHelper.add( - { endDate: new Date('2023-03-31'), licenceId, licenceRef } - ) - - await ChargeReferenceHelper.add({ - chargeVersionId, - chargeCategoryId, - adjustments: { s127: true } - }) - }) - - it('returns no records', async () => { - const results = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) + const results = await FetchChargeVersionsService.go(region.id, billingPeriod) - describe('because the status is not "current"', () => { - beforeEach(async () => { - const { id: chargeVersionId } = await ChargeVersionHelper.add( - { licenceId, licenceRef, status: 'superseded' } - ) - - await ChargeReferenceHelper.add({ - chargeVersionId, - chargeCategoryId, - adjustments: { s127: true } - }) - }) - - it('returns no records', async () => { - const results = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) - - describe('because the region is different', () => { - beforeEach(async () => { - const { id: otherLicenceId, licenceRef: otherLicenceRef } = await LicenceHelper.add({ regionId: 'eee44502-dd6f-4b13-8885-ebc50a7f54dc' }) - const { id: chargeVersionId } = await ChargeVersionHelper.add( - { licenceId: otherLicenceId, licenceRef: otherLicenceRef } - ) - - await ChargeReferenceHelper.add({ - chargeVersionId, - chargeCategoryId, - adjustments: { s127: true } - }) - }) - - it('returns no records', async () => { - const results = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) - - describe('because the licence is linked to a workflow', () => { - beforeEach(async () => { - const { id: chargeVersionId } = await ChargeVersionHelper.add( - { licenceId, licenceRef } - ) - - await ChargeReferenceHelper.add({ - chargeVersionId, - chargeCategoryId, - adjustments: { s127: true } - }) - - await WorkflowHelper.add({ licenceId }) - }) - - it('returns no records', async () => { - const results = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) - }) - - describe('because the licence ended (expired, lapsed or revoked) before the billing period', () => { - beforeEach(async () => { - // NOTE: To make things spicy (!) we have the licence expire _after_ the billing period starts but revoked - // before it. Where the licence has dates in more than one of these fields, it is considered ended on the - // earliest of them (we have found real examples that confirm this is possible) - await LicenceModel.query() - .update({ expiredDate: new Date('2019-05-01'), revokedDate: new Date('2022-06-01') }) - .where('id', licenceId) - - const { id: chargeVersionId } = await ChargeVersionHelper.add( - { licenceId, licenceRef } - ) - - await ChargeReferenceHelper.add({ - chargeVersionId, - chargeCategoryId, - adjustments: { s127: true } - }) - - await WorkflowHelper.add({ licenceId }) - }) - - it('returns no records', async () => { - const results = await FetchChargeVersionsService.go(regionId, billingPeriod) - - expect(results).to.be.empty() - }) + expect(results[0].chargeReferences[0].chargeElements[0].id).to.equal(chargeElement2.id) + expect(results[0].chargeReferences[0].chargeElements[1].id).to.equal(chargeElement1.id) }) }) }) diff --git a/test/services/licences/fetch-charge-versions.service.test.js b/test/services/licences/fetch-charge-versions.service.test.js index c66919ab4c..3dac09ae69 100644 --- a/test/services/licences/fetch-charge-versions.service.test.js +++ b/test/services/licences/fetch-charge-versions.service.test.js @@ -19,6 +19,7 @@ const FetchChargeVersionsService = describe('Fetch Charge Versions service', () => { const licenceId = generateUUID() + let changeReason let currentChargeVersionWithEndDateId let currentChargeVersionWithoutEndDateId let supersededChargeVersionWithEndDateId @@ -26,7 +27,7 @@ describe('Fetch Charge Versions service', () => { describe('when the licence has charge versions data', () => { beforeEach(async () => { - const changeReason = await ChangeReasonHelper.add() + changeReason = ChangeReasonHelper.select() // Create multiple charge versions to ensure we get them in the right order let chargeVersion = await ChargeVersionHelper.add({ @@ -82,7 +83,7 @@ describe('Fetch Charge Versions service', () => { expect(result).to.equal([ { changeReason: { - description: 'Strategic review of charges (SRoC)' + description: changeReason.description }, endDate: null, id: currentChargeVersionWithoutEndDateId, @@ -92,7 +93,7 @@ describe('Fetch Charge Versions service', () => { }, { changeReason: { - description: 'Strategic review of charges (SRoC)' + description: changeReason.description }, endDate: null, id: supersededChargeVersionWithoutEndDateId, @@ -102,7 +103,7 @@ describe('Fetch Charge Versions service', () => { }, { changeReason: { - description: 'Strategic review of charges (SRoC)' + description: changeReason.description }, endDate: new Date('2021-03-31'), id: currentChargeVersionWithEndDateId, @@ -112,7 +113,7 @@ describe('Fetch Charge Versions service', () => { }, { changeReason: { - description: 'Strategic review of charges (SRoC)' + description: changeReason.description }, endDate: new Date('2030-03-31'), id: supersededChargeVersionWithEndDateId, diff --git a/test/services/licences/fetch-licence-summary.service.test.js b/test/services/licences/fetch-licence-summary.service.test.js index 6856c3f1fd..8e77e677a2 100644 --- a/test/services/licences/fetch-licence-summary.service.test.js +++ b/test/services/licences/fetch-licence-summary.service.test.js @@ -26,6 +26,8 @@ const RegionHelper = require('../../support/helpers/region.helper.js') // Thing under test const FetchLicenceSummaryService = require('../../../app/services/licences/fetch-licence-summary.service.js') +const REGION_SOUTHERN_INDEX = 5 + describe('Fetch Licence Summary service', () => { let gaugingStation let licence @@ -45,7 +47,7 @@ describe('Fetch Licence Summary service', () => { return conditionType.displayTitle === 'Aggregate condition link between licences' }) - region = RegionHelper.select() + region = RegionHelper.select(REGION_SOUTHERN_INDEX) licence = await LicenceHelper.add({ expiredDate: null, @@ -164,7 +166,7 @@ describe('Fetch Licence Summary service', () => { licenceDocument: { id: licenceHolderSeed.licenceDocumentId, licenceDocumentRoles: [{ - id: licenceHolderSeed.id, + id: licenceHolderSeed.licenceDocumentRoleId, contact: null, company: { id: licenceHolderSeed.companyId, diff --git a/test/support/database.js b/test/support/database.js index ecd32402c8..2bcc9802ce 100644 --- a/test/support/database.js +++ b/test/support/database.js @@ -10,6 +10,7 @@ const { db, dbConfig } = require('../../db/db.js') +const ChangeReasonsSeeder = require('../../db/seeds/12-change-reasons.seed.js') const FinancialAgreementsSeeder = require('../../db/seeds/11-financial-agreements.seed.js') const GroupRolesSeeder = require('../../db/seeds/08-group-roles.seed.js') const GroupsSeeder = require('../../db/seeds/06-groups.seed.js') @@ -95,6 +96,7 @@ async function _seed () { await UsersSeeder.seed() await UserGroupsSeeder.seed() await FinancialAgreementsSeeder.seed() + await ChangeReasonsSeeder.seed() } async function _tableNames (schema) { diff --git a/test/support/helpers/change-reason.helper.js b/test/support/helpers/change-reason.helper.js index 4cd9c01e53..6f8372001b 100644 --- a/test/support/helpers/change-reason.helper.js +++ b/test/support/helpers/change-reason.helper.js @@ -4,58 +4,32 @@ * @module ChangeReasonHelper */ -const ChangeReasonModel = require('../../../app/models/change-reason.model.js') +const { data: changeReasons } = require('../../../db/seeds/data/change-reasons.js') +const { selectRandomEntry } = require('../general.js') /** - * Add a new change reason + * Select an entry from the reference data entries seeded at the start of testing * - * If no `data` is provided, default values will be used. These are + * Because this helper is linked to a reference record instead of a transaction, we don't expect these to be created + * when using the service. * - * - `description` - Strategic review of charges (SRoC) - * - `type` - new_chargeable_charge_version - * - `enabledForNewChargeVersions` - true, - * - `createdAt` - 2022-02-23 + * So, they are seeded automatically when tests are run. Tests that need to link to a record can use this method to + * select a specific entry, or have it it return one at random. * - * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database + * @param {Number} [index=-1] - The reference entry to select. Defaults to -1 which means an entry will be returned at + * random from the reference data * - * @returns {Promise} The instance of the newly created record + * @returns {Object} The selected reference entry or one picked at random */ -function add (data = {}) { - const insertData = defaults(data) - - return ChangeReasonModel.query() - .insert({ ...insertData }) - .returning('*') -} - -/** - * Returns the defaults used - * - * It will override or append to them any data provided. Mainly used by the `add()` method, we make it available - * for use in tests to avoid having to duplicate values. - * - * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database - */ -function defaults (data = {}) { - const defaults = { - description: 'Strategic review of charges (SRoC)', - type: 'new_chargeable_charge_version', - enabledForNewChargeVersions: true, - // INFO: The change_reasons table does not have a default for the date_created column. But it is set as 'not - // nullable'! So, we need to ensure we set it when creating a new record. Also, we can't use Date.now() because - // Javascript returns the time since the epoch in milliseconds, whereas a PostgreSQL timestamp field can only hold - // the seconds since the epoch. Pass it an ISO string though ('2022-02-23 09:19:39.953') and PostgreSQL can do the - // conversion https://stackoverflow.com/a/61912776/6117745 - createdAt: new Date('2022-02-23 09:19:39.953').toISOString() +function select (index = -1) { + if (index > -1) { + return changeReasons[index] } - return { - ...defaults, - ...data - } + return selectRandomEntry(changeReasons) } module.exports = { - add, - defaults + data: changeReasons, + select } diff --git a/test/support/seeders/licence-holder.seeder.js b/test/support/seeders/licence-holder.seeder.js index f3266f85d9..6536197fcf 100644 --- a/test/support/seeders/licence-holder.seeder.js +++ b/test/support/seeders/licence-holder.seeder.js @@ -20,22 +20,29 @@ const LicenceRoleHelper = require('../helpers/licence-role.helper.js') */ async function seed (licenceRef, name = 'Licence Holder Ltd') { // Create a licence role (the default is licenceHolder) - const licenceRole = await LicenceRoleHelper.add() + const { id: licenceRoleId } = await LicenceRoleHelper.add() // Create a company record - const company = await CompanyHelper.add({ name }) + const { id: companyId } = await CompanyHelper.add({ name }) // We have to create a licence document to link our licence record to (eventually!) the company or contact record that // is the 'licence holder' - const licenceDocument = await LicenceDocumentHelper.add({ licenceRef }) + const { id: licenceDocumentId } = await LicenceDocumentHelper.add({ licenceRef }) // Create the licence document role record that _is_ linked to the correct licence holder record - return LicenceDocumentRoleHelper.add({ - licenceDocumentId: licenceDocument.id, - licenceRoleId: licenceRole.id, - companyId: company.id, + const { id: licenceDocumentRoleId } = await LicenceDocumentRoleHelper.add({ + licenceDocumentId, + licenceRoleId, + companyId, startDate: new Date('2022-04-01') }) + + return { + companyId, + licenceDocumentId, + licenceDocumentRoleId, + licenceRoleId + } } module.exports = {