diff --git a/app/models/legacy-base.model.js b/app/models/legacy-base.model.js index e310695d1c..e289a91575 100644 --- a/app/models/legacy-base.model.js +++ b/app/models/legacy-base.model.js @@ -23,7 +23,6 @@ class LegacyBaseModel extends BaseModel { static get modelPaths () { const currentPath = __dirname return [ - path.join(currentPath, 'returns'), path.join(currentPath, 'water'), path.join(currentPath, 'crm-v2'), path.join(currentPath, 'idm') diff --git a/app/models/returns/line.model.js b/app/models/returns/line.model.js deleted file mode 100644 index cb15454166..0000000000 --- a/app/models/returns/line.model.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict' - -/** - * Model for line - * @module LineModel - */ - -const { Model } = require('objection') - -const ReturnsBaseModel = require('./returns-base.model.js') - -class LineModel extends ReturnsBaseModel { - static get tableName () { - return 'lines' - } - - static get idColumn () { - return 'lineId' - } - - static get translations () { - return [] - } - - // Defining which fields contain json allows us to insert an object without needing to stringify it first - static get jsonAttributes () { - return [ - 'metadata' - ] - } - - static get relationMappings () { - return { - version: { - relation: Model.BelongsToOneRelation, - modelClass: 'version.model', - join: { - from: 'lines.versionId', - to: 'versions.versionId' - } - } - } - } -} - -module.exports = LineModel diff --git a/app/models/returns/return.model.js b/app/models/returns/return.model.js deleted file mode 100644 index 8e578dee9b..0000000000 --- a/app/models/returns/return.model.js +++ /dev/null @@ -1,46 +0,0 @@ -'use strict' - -/** - * Model for return - * @module ReturnModel - */ - -const { Model } = require('objection') - -const ReturnsBaseModel = require('./returns-base.model.js') - -class ReturnModel extends ReturnsBaseModel { - static get tableName () { - return 'returns' - } - - static get idColumn () { - return 'returnId' - } - - static get translations () { - return [] - } - - // Defining which fields contain json allows us to insert an object without needing to stringify it first - static get jsonAttributes () { - return [ - 'metadata' - ] - } - - static get relationMappings () { - return { - versions: { - relation: Model.HasManyRelation, - modelClass: 'version.model', - join: { - from: 'returns.returnId', - to: 'versions.returnId' - } - } - } - } -} - -module.exports = ReturnModel diff --git a/app/models/returns/returns-base.model.js b/app/models/returns/returns-base.model.js deleted file mode 100644 index e5584daae1..0000000000 --- a/app/models/returns/returns-base.model.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict' - -/** - * Base class for all models based on the legacy 'returns' schema - * @module ReturnsBaseModel - */ - -const LegacyBaseModel = require('../legacy-base.model.js') - -class ReturnsBaseModel extends LegacyBaseModel { - static get schema () { - return 'returns' - } -} - -module.exports = ReturnsBaseModel diff --git a/app/models/returns/version.model.js b/app/models/returns/version.model.js deleted file mode 100644 index 6a53b15c6d..0000000000 --- a/app/models/returns/version.model.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict' - -/** - * Model for version - * @module VersionModel - */ - -const { Model } = require('objection') - -const ReturnsBaseModel = require('./returns-base.model.js') - -class VersionModel extends ReturnsBaseModel { - static get tableName () { - return 'versions' - } - - static get idColumn () { - return 'versionId' - } - - static get translations () { - return [] - } - - // Defining which fields contain json allows us to insert an object without needing to stringify it first - static get jsonAttributes () { - return [ - 'metadata' - ] - } - - static get relationMappings () { - return { - return: { - relation: Model.BelongsToOneRelation, - modelClass: 'return.model', - join: { - from: 'versions.returnId', - to: 'returns.returnId' - } - }, - lines: { - relation: Model.HasManyRelation, - modelClass: 'line.model', - join: { - from: 'versions.versionId', - to: 'lines.versionId' - } - } - } - } -} - -module.exports = VersionModel diff --git a/app/services/bill-runs/two-part-tariff/fetch-returns-for-licence.service.js b/app/services/bill-runs/two-part-tariff/fetch-return-logs-for-licence.service.js similarity index 55% rename from app/services/bill-runs/two-part-tariff/fetch-returns-for-licence.service.js rename to app/services/bill-runs/two-part-tariff/fetch-return-logs-for-licence.service.js index 19a366e495..88badc4973 100644 --- a/app/services/bill-runs/two-part-tariff/fetch-returns-for-licence.service.js +++ b/app/services/bill-runs/two-part-tariff/fetch-return-logs-for-licence.service.js @@ -1,30 +1,31 @@ 'use strict' /** - * Fetches SROC Returns linked to licences flagged for inclusion in next SROC 2PT billing - * @module FetchReturnsForLicenceService + * Fetches SROC return logs linked to licences flagged for inclusion in next SROC 2PT billing + * @module FetchReturnLogsForLicenceService */ const { ref } = require('objection') -const ReturnModel = require('../../../models/returns/return.model') +const ReturnLogModel = require('../../../models/return-log.model.js') /** - * Fetch all SROC returns to be processed as part of two-part-tariff billing + * Fetch all SROC return logs to be processed as part of two-part-tariff billing * * - * @param {String} licenceRef The reference of the licence that the return relates to + * @param {String} licenceRef The reference of the licence that the return log relates to * @param {Object} billingPeriod Object with a `startDate` and `endDate` property representing the period being billed * - * @returns {Object} Contains an array of Returns and the associated current Version, and Lines if they exist + * @returns {Object} Contains an array of `returnLogs` and the associated current `returnSubmissions`, and + * `returnSubmissionLines` if they exist */ async function go (licenceRef, billingPeriod) { return _fetch(licenceRef, billingPeriod) } async function _fetch (licenceRef, billingPeriod) { - const returns = await ReturnModel.query() + const returnLogs = await ReturnLogModel.query() .select([ - 'returnId', + 'id', 'returnRequirement', ref('metadata:description').castText().as('description'), 'startDate', @@ -40,37 +41,37 @@ async function _fetch (licenceRef, billingPeriod) { ref('metadata:purposes').as('purposes') ]) .where('licenceRef', licenceRef) - // water-abstraction-service filters out old returns in this way: see `src/lib/services/returns/api-connector.js` + // water-abstraction-service filters out old return logs in this way: see `src/lib/services/returns/api-connector.js` .where('startDate', '>=', '2008-04-01') .where('startDate', '<=', billingPeriod.endDate) .where('endDate', '>=', billingPeriod.startDate) .whereJsonPath('metadata', '$.isTwoPartTariff', '=', true) .orderBy('startDate', 'ASC') .orderBy('returnRequirement', 'ASC') - .withGraphFetched('versions') - .modifyGraph('versions', builder => { + .withGraphFetched('returnSubmissions') + .modifyGraph('returnSubmissions', builder => { builder .select([ - 'versionId', + 'id', 'nilReturn' ]) - .where('versions.current', true) + .where('returnSubmissions.current', true) }) - .withGraphFetched('versions.lines') - .modifyGraph('versions.lines', builder => { + .withGraphFetched('returnSubmissions.returnSubmissionLines') + .modifyGraph('returnSubmissions.returnSubmissionLines', builder => { builder .select([ - 'lineId', + 'id', 'startDate', 'endDate', 'quantity' ]) - .where('lines.quantity', '>', 0) - .where('lines.startDate', '<=', billingPeriod.endDate) - .where('lines.endDate', '>=', billingPeriod.startDate) + .where('returnSubmissionLines.quantity', '>', 0) + .where('returnSubmissionLines.startDate', '<=', billingPeriod.endDate) + .where('returnSubmissionLines.endDate', '>=', billingPeriod.startDate) }) - return returns + return returnLogs } module.exports = { diff --git a/app/services/check/allocate-returns-volumes.service.js b/app/services/check/allocate-returns-volumes.service.js index 8e8ef76d56..adf7efec9a 100644 --- a/app/services/check/allocate-returns-volumes.service.js +++ b/app/services/check/allocate-returns-volumes.service.js @@ -7,10 +7,10 @@ function go (chargeReference) { let returnVolumeInMegalitres - // Loop through each return - chargeReference.returns.forEach((returnData) => { - // The volumes on the return are in Cubic Metres so we convert to Megalitres to match the charge version data - returnVolumeInMegalitres = returnData.volumes.total / 1000 + // Loop through each return log + chargeReference.returnLogs.forEach((returnLogData) => { + // The volumes on the return log are in Cubic Metres so we convert to Megalitres to match the charge version data + returnVolumeInMegalitres = returnLogData.volumes.total / 1000 // Loop through each charge element chargeReference.chargeElements.forEach((chargeElement) => { if (!chargeElement.allocatedReturnVolume) { @@ -18,11 +18,11 @@ function go (chargeReference) { } // Check the chargeElement is not already fully allocated if (chargeElement.allocatedReturnVolume < chargeElement.authorisedAnnualQuantity) { - // Check if the return's purpose and abstraction period match the charge element - if (_matchReturnToElement(returnData.metadata, chargeElement)) { + // Check if the return log's purpose and abstraction period match the charge element + if (_matchReturnToElement(returnLogData.metadata, chargeElement)) { // Calculate how much is left to allocated to the ChargeElement from the return let volumeLeftToAllocate = chargeElement.authorisedAnnualQuantity - chargeElement.allocatedReturnVolume - // Check for the case that the return does not cover the full allocation + // Check for the case that the return log does not cover the full allocation if (returnVolumeInMegalitres < volumeLeftToAllocate) { volumeLeftToAllocate = returnVolumeInMegalitres } @@ -35,9 +35,9 @@ function go (chargeReference) { if (returnVolumeInMegalitres > 0) { // Convert any remaining volume back to Cubic Metres and add it to the volumes object - returnData.volumes.unallocated = returnVolumeInMegalitres * 1000 + returnLogData.volumes.unallocated = returnVolumeInMegalitres * 1000 } else { - returnData.volumes.unallocated = 0 + returnLogData.volumes.unallocated = 0 } }) } diff --git a/app/services/check/calculate-returns-volumes.service.js b/app/services/check/calculate-returns-volumes.service.js index a73a9c116e..bd7f3da4d2 100644 --- a/app/services/check/calculate-returns-volumes.service.js +++ b/app/services/check/calculate-returns-volumes.service.js @@ -1,40 +1,40 @@ 'use strict' /** - * Used to calculate the abstraction volumes for the given returns + * Used to calculate the abstraction volumes for the given return logs * @module CalculateReturnsVolumes */ -function go (billingPeriod, returns) { - returns.forEach((returnData) => { - const lines = returnData?.versions[0]?.lines ? returnData?.versions[0]?.lines : [] +function go (billingPeriod, returnLogs) { + returnLogs.forEach((returnLogData) => { + const returnSubmissionLines = returnLogData?.returnSubmissions[0]?.returnSubmissionLines ? returnLogData?.returnSubmissions[0]?.returnSubmissionLines : [] let billableAbstractionPeriods = [] - if (lines) { - billableAbstractionPeriods = _billableAbstractionPeriods(billingPeriod, returnData) + if (returnSubmissionLines) { + billableAbstractionPeriods = _billableAbstractionPeriods(billingPeriod, returnLogData) } - returnData.volumes = _calculateReturnLinesVolumes(lines, billableAbstractionPeriods) + returnLogData.volumes = _calculateReturnLinesVolumes(returnSubmissionLines, billableAbstractionPeriods) }) } -function _calculateReturnLinesVolumes (lines, billableAbstractionPeriods) { +function _calculateReturnLinesVolumes (returnSubmissionLines, billableAbstractionPeriods) { const inPeriodLines = [] const outsidePeriodLines = [] - lines.forEach((line) => { - if (!line.quantity) { + returnSubmissionLines.forEach((returnSubmissionLine) => { + if (!returnSubmissionLine.quantity) { return } const isInsideBillablePeriod = billableAbstractionPeriods.some((period) => { - return (line.startDate <= period.endDate && line.endDate >= period.startDate) + return (returnSubmissionLine.startDate <= period.endDate && returnSubmissionLine.endDate >= period.startDate) }) if (isInsideBillablePeriod) { - inPeriodLines.push(line) + inPeriodLines.push(returnSubmissionLine) } else { - outsidePeriodLines.push(line) + outsidePeriodLines.push(returnSubmissionLine) } }) @@ -53,8 +53,8 @@ function _addOneYear (date) { return new Date(date.getFullYear() + 1, date.getMonth(), date.getDate()) } -function _billableAbstractionPeriods (billingPeriod, returnData) { - const abstractionPeriodsWithYears = _determineAbstractionPeriodYears(billingPeriod, returnData) +function _billableAbstractionPeriods (billingPeriod, returnLogData) { + const abstractionPeriodsWithYears = _determineAbstractionPeriodYears(billingPeriod, returnLogData) return abstractionPeriodsWithYears.map((abstractionPeriod) => { return _calculateAbstractionOverlapPeriod(billingPeriod, abstractionPeriod) @@ -71,12 +71,12 @@ function _calculateAbstractionOverlapPeriod (billingPeriod, abstractionPeriod) { } } -function _determineAbstractionPeriodYears (billingPeriod, returnData) { +function _determineAbstractionPeriodYears (billingPeriod, returnLogData) { const periodStartYear = billingPeriod.startDate.getFullYear() - const startDay = returnData.metadata.nald.periodStartDay - const startMonth = returnData.metadata.nald.periodStartMonth - const endDay = returnData.metadata.nald.periodEndDay - const endMonth = returnData.metadata.nald.periodEndMonth + const startDay = returnLogData.metadata.nald.periodStartDay + const startMonth = returnLogData.metadata.nald.periodStartMonth + const endDay = returnLogData.metadata.nald.periodEndDay + const endMonth = returnLogData.metadata.nald.periodEndMonth // Reminder! Because of the unique qualities of Javascript, Year and Day are literal values, month is an index! So, // January is actually 0, February is 1 etc. This is why we are always deducting 1 from the months. @@ -120,9 +120,9 @@ function _isPeriodValid (billingPeriod, abstractionPeriod) { return true } -function _totalLineQuantities (lines) { - return lines.reduce((accumulator, line) => { - return accumulator + line.quantity +function _totalLineQuantities (returnSubmissionLines) { + return returnSubmissionLines.reduce((accumulator, returnSubmissionLine) => { + return accumulator + returnSubmissionLine.quantity }, 0) } diff --git a/app/services/check/friendly-response.service.js b/app/services/check/friendly-response.service.js index 4716574377..95262f443e 100644 --- a/app/services/check/friendly-response.service.js +++ b/app/services/check/friendly-response.service.js @@ -69,7 +69,7 @@ function _formatFriendlyChargeReferences (friendlyChargeReferences, chargeRefere eiucRegion, isRestrictedSource, loss, - returns, + returnLogs, source, volume, waterModel @@ -94,10 +94,10 @@ function _formatFriendlyChargeReferences (friendlyChargeReferences, chargeRefere additionalCharges: formattedAdditionalCharges, adjustments: formattedAdjustments, chargeElements: [], - returns: [] + returnLogs: [] } - _formatFriendlyReturns(friendlyChargeReference.returns, returns) + _formatFriendlyReturns(friendlyChargeReference.returnLogs, returnLogs) _formatFriendlyChargeElements(friendlyChargeReference.chargeElements, chargeElements) friendlyChargeReferences.push(friendlyChargeReference) @@ -141,14 +141,14 @@ function _formatFriendlyChargeElements (friendlyChargeElements, chargeElements) }) } -function _formatFriendlyReturns (returns, matchedReturns) { - matchedReturns.forEach((matchedReturn) => { - const { returnId, endDate, metadata, startDate, status, volumes } = matchedReturn +function _formatFriendlyReturns (returnLogs, matchedReturnLogs) { + matchedReturnLogs.forEach((matchedReturnLog) => { + const { id, endDate, metadata, startDate, status, volumes } = matchedReturnLog const { periodEndDay, periodEndMonth, periodStartDay, periodStartMonth } = metadata.nald const friendlyReturn = { - id: returnId, + id, siteDescription: _titleCaseAllWords(metadata.description), purpose: _formatPurpose(metadata.purposes[0]), returnPeriod: `${formatLongDate(startDate)} to ${formatLongDate(endDate)}`, @@ -159,7 +159,7 @@ function _formatFriendlyReturns (returns, matchedReturns) { volumes } - returns.push(friendlyReturn) + returnLogs.push(friendlyReturn) }) } diff --git a/app/services/check/two-part.service.js b/app/services/check/two-part.service.js index 556deebff1..0202377181 100644 --- a/app/services/check/two-part.service.js +++ b/app/services/check/two-part.service.js @@ -13,7 +13,7 @@ const ChargeReferenceModel = require('../../models/water/charge-reference.model. const ChargeVersionModel = require('../../models/water/charge-version.model.js') const FriendlyResponseService = require('./friendly-response.service.js') const DetermineBillingPeriodsService = require('../bill-runs/determine-billing-periods.service.js') -const ReturnModel = require('../../models/returns/return.model.js') +const ReturnLogModel = require('../../models/return-log.model.js') const Workflow = require('../../models/water/workflow.model.js') async function go (naldRegionId, format = 'friendly') { @@ -97,9 +97,9 @@ async function _fetchAndApplyReturns (billingPeriod, chargeVersion) { for (const chargeReference of chargeReferences) { const purposeUseLegacyIds = _extractPurposeUseLegacyIds(chargeReference) - chargeReference.returns = await ReturnModel.query() + chargeReference.returnLogs = await ReturnLogModel.query() .select([ - 'returnId', + 'id', 'returnRequirement', 'startDate', 'endDate', @@ -114,22 +114,22 @@ async function _fetchAndApplyReturns (billingPeriod, chargeVersion) { .where('endDate', '>=', billingPeriod.startDate) .whereJsonPath('metadata', '$.isTwoPartTariff', '=', true) .whereIn(ref('metadata:purposes[0].tertiary.code').castInt(), purposeUseLegacyIds) - .withGraphFetched('versions') - .modifyGraph('versions', builder => { - builder.where('versions.current', true) + .withGraphFetched('returnSubmissions') + .modifyGraph('returnSubmissions', builder => { + builder.where('returnSubmissions.current', true) }) - .withGraphFetched('versions.lines') - .modifyGraph('versions.lines', builder => { + .withGraphFetched('returnSubmissions.returnSubmissionLines') + .modifyGraph('returnSubmissions.returnSubmissionLines', builder => { builder - .where('lines.quantity', '>', 0) - .where('lines.startDate', '<=', billingPeriod.endDate) - .where('lines.endDate', '>=', billingPeriod.startDate) + .where('returnSubmissionLines.quantity', '>', 0) + .where('returnSubmissionLines.startDate', '<=', billingPeriod.endDate) + .where('returnSubmissionLines.endDate', '>=', billingPeriod.startDate) }) - CalculateReturnsVolumes.go(billingPeriod, chargeReference.returns) + CalculateReturnsVolumes.go(billingPeriod, chargeReference.returnLogs) AllocateReturnsVolumes.go(chargeReference) - const chargeReferenceReturnsStatuses = chargeReference.returns.map((matchedReturn) => { + const chargeReferenceReturnsStatuses = chargeReference.returnLogs.map((matchedReturn) => { if (matchedReturn.underQuery) { returnsUnderQuery = true } diff --git a/test/models/returns/line.model.test.js b/test/models/returns/line.model.test.js deleted file mode 100644 index 01d6f53e61..0000000000 --- a/test/models/returns/line.model.test.js +++ /dev/null @@ -1,68 +0,0 @@ -'use strict' - -// Test framework dependencies -const Lab = require('@hapi/lab') -const Code = require('@hapi/code') - -const { describe, it, beforeEach } = exports.lab = Lab.script() -const { expect } = Code - -// Test helpers -const DatabaseHelper = require('../../support/helpers/database.helper.js') -const LineHelper = require('../../support/helpers/returns/line.helper.js') -const VersionHelper = require('../../support/helpers/returns/version.helper.js') -const VersionModel = require('../../../app/models/returns/version.model.js') - -// Thing under test -const LineModel = require('../../../app/models/returns/line.model.js') - -describe('Line model', () => { - let testRecord - - beforeEach(async () => { - await DatabaseHelper.clean() - }) - - describe('Basic query', () => { - beforeEach(async () => { - testRecord = await LineHelper.add() - }) - - it('can successfully run a basic query', async () => { - const result = await LineModel.query().findById(testRecord.lineId) - - expect(result).to.be.an.instanceOf(LineModel) - expect(result.lineId).to.equal(testRecord.lineId) - }) - }) - - describe('Relationships', () => { - describe('when linking to version', () => { - let testVersion - - beforeEach(async () => { - testVersion = await VersionHelper.add() - testRecord = await LineHelper.add({ versionId: testVersion.versionId }) - }) - - it('can successfully run a related query', async () => { - const query = await LineModel.query() - .innerJoinRelated('version') - - expect(query).to.exist() - }) - - it('can eager load the version', async () => { - const result = await LineModel.query() - .findById(testRecord.lineId) - .withGraphFetched('version') - - expect(result).to.be.instanceOf(LineModel) - expect(result.lineId).to.equal(testRecord.lineId) - - expect(result.version).to.be.an.instanceOf(VersionModel) - expect(result.version).to.equal(testVersion) - }) - }) - }) -}) diff --git a/test/models/returns/return.model.test.js b/test/models/returns/return.model.test.js deleted file mode 100644 index 8cf6eb5a14..0000000000 --- a/test/models/returns/return.model.test.js +++ /dev/null @@ -1,74 +0,0 @@ -'use strict' - -// Test framework dependencies -const Lab = require('@hapi/lab') -const Code = require('@hapi/code') - -const { describe, it, beforeEach } = exports.lab = Lab.script() -const { expect } = Code - -// Test helpers -const DatabaseHelper = require('../../support/helpers/database.helper.js') -const ReturnHelper = require('../../support/helpers/returns/return.helper.js') -const VersionHelper = require('../../support/helpers/returns/version.helper.js') -const VersionModel = require('../../../app/models/returns/version.model.js') - -// Thing under test -const ReturnModel = require('../../../app/models/returns/return.model.js') - -describe('Return model', () => { - let testRecord - - beforeEach(async () => { - await DatabaseHelper.clean() - - testRecord = await ReturnHelper.add() - }) - - describe('Basic query', () => { - it('can successfully run a basic query', async () => { - const result = await ReturnModel.query().findById(testRecord.returnId) - - expect(result).to.be.an.instanceOf(ReturnModel) - expect(result.returnId).to.equal(testRecord.returnId) - }) - }) - - describe('Relationships', () => { - describe('when linking to version', () => { - let testVersions - - beforeEach(async () => { - const { returnId } = testRecord - - testVersions = [] - for (let i = 0; i < 2; i++) { - const versionNumber = i - const version = await VersionHelper.add({ returnId, versionNumber }) - testVersions.push(version) - } - }) - - it('can successfully run a related query', async () => { - const query = await ReturnModel.query() - .innerJoinRelated('versions') - - expect(query).to.exist() - }) - - it('can eager load the version', async () => { - const result = await ReturnModel.query() - .findById(testRecord.returnId) - .withGraphFetched('versions') - - expect(result).to.be.instanceOf(ReturnModel) - expect(result.returnId).to.equal(testRecord.returnId) - - expect(result.versions).to.be.an.array() - expect(result.versions[0]).to.be.an.instanceOf(VersionModel) - expect(result.versions).to.include(testVersions[0]) - expect(result.versions).to.include(testVersions[1]) - }) - }) - }) -}) diff --git a/test/models/returns/version.model.test.js b/test/models/returns/version.model.test.js deleted file mode 100644 index 1e5944ad60..0000000000 --- a/test/models/returns/version.model.test.js +++ /dev/null @@ -1,109 +0,0 @@ -'use strict' - -// Test framework dependencies -const Lab = require('@hapi/lab') -const Code = require('@hapi/code') - -const { describe, it, beforeEach } = exports.lab = Lab.script() -const { expect } = Code - -// Test helpers -const DatabaseHelper = require('../../support/helpers/database.helper.js') -const LineHelper = require('../../support/helpers/returns/line.helper.js') -const LineModel = require('../../../app/models/returns/line.model.js') -const ReturnHelper = require('../../support/helpers/returns/return.helper.js') -const ReturnModel = require('../../../app/models/returns/return.model.js') -const VersionHelper = require('../../support/helpers/returns/version.helper.js') - -// Thing under test -const VersionModel = require('../../../app/models/returns/version.model.js') - -describe('Version model', () => { - let testRecord - - beforeEach(async () => { - await DatabaseHelper.clean() - }) - - describe('Basic query', () => { - beforeEach(async () => { - testRecord = await VersionHelper.add() - }) - - it('can successfully run a basic query', async () => { - const result = await VersionModel.query().findById(testRecord.versionId) - - expect(result).to.be.an.instanceOf(VersionModel) - expect(result.versionId).to.equal(testRecord.versionId) - }) - }) - - describe('Relationships', () => { - describe('when linking to return', () => { - let testReturn - - beforeEach(async () => { - testReturn = await ReturnHelper.add() - testRecord = await VersionHelper.add({ returnId: testReturn.returnId }) - }) - - it('can successfully run a related query', async () => { - const query = await VersionModel.query() - .innerJoinRelated('return') - - expect(query).to.exist() - }) - - it('can eager load the return', async () => { - const result = await VersionModel.query() - .findById(testRecord.versionId) - .withGraphFetched('return') - - expect(result).to.be.instanceOf(VersionModel) - expect(result.versionId).to.equal(testRecord.versionId) - - expect(result.return).to.be.an.instanceOf(ReturnModel) - expect(result.return).to.equal(testReturn) - }) - }) - - describe('when linking to lines', () => { - let testLines - - beforeEach(async () => { - testRecord = await VersionHelper.add() - const { versionId } = testRecord - - testLines = [] - for (let i = 0; i < 2; i++) { - // NOTE: A constraint in the lines table means you cannot have 2 records with the same versionId, substance, - // startDate and endDate - const substance = i === 0 ? 'water' : 'dirt' - const line = await LineHelper.add({ versionId, substance }) - testLines.push(line) - } - }) - - it('can successfully run a related query', async () => { - const query = await VersionModel.query() - .innerJoinRelated('lines') - - expect(query).to.exist() - }) - - it('can eager load the lines', async () => { - const result = await VersionModel.query() - .findById(testRecord.versionId) - .withGraphFetched('lines') - - expect(result).to.be.instanceOf(VersionModel) - expect(result.versionId).to.equal(testRecord.versionId) - - expect(result.lines).to.be.an.array() - expect(result.lines[0]).to.be.an.instanceOf(LineModel) - expect(result.lines).to.include(testLines[0]) - expect(result.lines).to.include(testLines[1]) - }) - }) - }) -}) diff --git a/test/services/bill-runs/two-part-tariff/fetch-return-logs-for-licence.service.test.js b/test/services/bill-runs/two-part-tariff/fetch-return-logs-for-licence.service.test.js new file mode 100644 index 0000000000..efd0ae636a --- /dev/null +++ b/test/services/bill-runs/two-part-tariff/fetch-return-logs-for-licence.service.test.js @@ -0,0 +1,214 @@ +'use strict' + +// Test framework dependencies +const Lab = require('@hapi/lab') +const Code = require('@hapi/code') + +const { describe, it, beforeEach } = exports.lab = Lab.script() +const { expect } = Code + +// Test helpers +const DatabaseHelper = require('../../../support/helpers/database.helper.js') +const ReturnLogHelper = require('../../../support/helpers/return-log.helper.js') +const ReturnSubmissionHelper = require('../../../support/helpers/return-submission.helper.js') +const ReturnSubmissionLineHelper = require('../../../support/helpers/return-submission-line.helper.js') + +// Thing under test +const FetchReturnLogsForLicenceService = require('../../../../app/services/bill-runs/two-part-tariff/fetch-return-logs-for-licence.service.js') + +describe('Fetch Return Logs for Licence service', () => { + const billingPeriod = { startDate: new Date('2022-04-01'), endDate: new Date('2023-03-31') } + let returnLogRecord + + beforeEach(async () => { + await DatabaseHelper.clean() + }) + + describe('when there are valid return logs that should be considered', () => { + beforeEach(async () => { + const metadata = { + nald: { + periodEndDay: '31', + periodEndMonth: '3', + periodStartDay: '1', + periodStartMonth: '4' + }, + purposes: [ + { + tertiary: { + code: '400', + description: 'Spray Irrigation - Direct' + } + } + ], + description: 'The Description', + isTwoPartTariff: true + } + + returnLogRecord = await ReturnLogHelper.add({ metadata }) + }) + + describe('which have return submission lines within the billing period', () => { + beforeEach(async () => { + const { id } = returnLogRecord + const { id: returnSubmissionId } = await ReturnSubmissionHelper.add({ returnLogId: id }) + + await ReturnSubmissionLineHelper.add({ + returnSubmissionId, + startDate: new Date('2022-05-01'), + endDate: new Date('2022-05-07'), + quantity: 1234 + }) + await ReturnSubmissionLineHelper.add({ + returnSubmissionId, + startDate: new Date('2022-05-08'), + endDate: new Date('2022-05-14'), + quantity: 5678 + }) + }) + + it('returns the return log and return submission lines that are applicable', async () => { + const { licenceRef } = returnLogRecord + const result = await FetchReturnLogsForLicenceService.go(licenceRef, billingPeriod) + + expect(result).to.have.length(1) + expect(result[0].id).to.equal(returnLogRecord.id) + expect(result[0].description).to.equal('The Description') + expect(result[0].startDate).to.equal(new Date('2022-04-01')) + expect(result[0].endDate).to.equal(new Date('2023-03-31')) + expect(result[0].periodStartDay).to.equal(1) + expect(result[0].periodStartMonth).to.equal(4) + expect(result[0].periodEndDay).to.equal(31) + expect(result[0].periodEndMonth).to.equal(3) + + expect(result[0].purposes).to.have.length(1) + expect(result[0].purposes[0].tertiary.code).to.equal('400') + expect(result[0].purposes[0].tertiary.description).to.equal('Spray Irrigation - Direct') + + expect(result[0].returnSubmissions).to.have.length(1) + expect(result[0].returnSubmissions[0].nilReturn).to.equal(false) + + expect(result[0].returnSubmissions[0].returnSubmissionLines).to.have.length(2) + expect(result[0].returnSubmissions[0].returnSubmissionLines[0].startDate).to.equal(new Date('2022-05-01')) + expect(result[0].returnSubmissions[0].returnSubmissionLines[0].endDate).to.equal(new Date('2022-05-07')) + expect(result[0].returnSubmissions[0].returnSubmissionLines[0].quantity).to.equal(1234) + expect(result[0].returnSubmissions[0].returnSubmissionLines[1].startDate).to.equal(new Date('2022-05-08')) + expect(result[0].returnSubmissions[0].returnSubmissionLines[1].endDate).to.equal(new Date('2022-05-14')) + expect(result[0].returnSubmissions[0].returnSubmissionLines[1].quantity).to.equal(5678) + }) + }) + + describe('which have NO return submission lines within the billing period', () => { + beforeEach(async () => { + const { id } = returnLogRecord + const { id: returnSubmissionId } = await ReturnSubmissionHelper.add({ returnLogId: id }) + + await ReturnSubmissionLineHelper.add({ + returnSubmissionId, + startDate: new Date('2023-05-01'), + endDate: new Date('2023-05-07'), + quantity: 1234 + }) + await ReturnSubmissionLineHelper.add({ + returnSubmissionId, + startDate: new Date('2023-05-08'), + endDate: new Date('2023-05-14'), + quantity: 5678 + }) + }) + + it('returns the return log with no return submission lines', async () => { + const { licenceRef } = returnLogRecord + const result = await FetchReturnLogsForLicenceService.go(licenceRef, billingPeriod) + + expect(result).to.have.length(1) + + expect(result[0].returnSubmissions[0].returnSubmissionLines).to.have.length(0) + }) + }) + + describe('which is a nil return', () => { + beforeEach(async () => { + const { id } = returnLogRecord + + await ReturnSubmissionHelper.add({ returnLogId: id, nilReturn: true }) + }) + + it('returns the return log with `nilreturn` set to `true` and no return submission lines', async () => { + const { licenceRef } = returnLogRecord + const result = await FetchReturnLogsForLicenceService.go(licenceRef, billingPeriod) + + expect(result).to.have.length(1) + + expect(result[0].returnSubmissions).to.have.length(1) + expect(result[0].returnSubmissions[0].nilReturn).to.equal(true) + + expect(result[0].returnSubmissions[0].returnSubmissionLines).to.have.length(0) + }) + }) + }) + + describe('when there are NO valid return logs that should be considered', () => { + describe('because the return log is outside the billing period', () => { + beforeEach(async () => { + returnLogRecord = await ReturnLogHelper.add({ + startDate: new Date('2023-04-01'), + endDate: new Date('2024-03-31') + }) + const { id } = returnLogRecord + + await ReturnSubmissionHelper.add({ returnLogId: id }) + }) + + it('returns no records', async () => { + const { licenceRef } = returnLogRecord + const result = await FetchReturnLogsForLicenceService.go(licenceRef, billingPeriod) + + expect(result).to.have.length(0) + }) + }) + + describe('because the return log is not two-part-tariff', () => { + beforeEach(async () => { + const metadata = { + nald: { + periodEndDay: '31', + periodEndMonth: '3', + periodStartDay: '1', + periodStartMonth: '4' + }, + purposes: [ + { + tertiary: { + code: '400', + description: 'Spray Irrigation - Direct' + } + } + ], + description: 'The Description', + isTwoPartTariff: false + } + + returnLogRecord = await ReturnLogHelper.add({ metadata }) + const { id } = returnLogRecord + + await ReturnSubmissionHelper.add({ returnLogId: id }) + }) + + it('returns no records', async () => { + const { licenceRef } = returnLogRecord + const result = await FetchReturnLogsForLicenceService.go(licenceRef, billingPeriod) + + expect(result).to.have.length(0) + }) + }) + + describe('because there are no return logs', () => { + it('returns no records', async () => { + const result = await FetchReturnLogsForLicenceService.go('LicenceRefWithNoReturnLogs', billingPeriod) + + expect(result).to.have.length(0) + }) + }) + }) +}) diff --git a/test/services/bill-runs/two-part-tariff/fetch-returns-for-licence.service.test.js b/test/services/bill-runs/two-part-tariff/fetch-returns-for-licence.service.test.js deleted file mode 100644 index d5ee9604ff..0000000000 --- a/test/services/bill-runs/two-part-tariff/fetch-returns-for-licence.service.test.js +++ /dev/null @@ -1,191 +0,0 @@ -'use strict' - -// Test framework dependencies -const Lab = require('@hapi/lab') -const Code = require('@hapi/code') - -const { describe, it, beforeEach } = exports.lab = Lab.script() -const { expect } = Code - -// Test helpers -const DatabaseHelper = require('../../../support/helpers/database.helper.js') -const LineHelper = require('../../../support/helpers/returns/line.helper.js') -const ReturnHelper = require('../../../support/helpers/returns/return.helper.js') -const VersionHelper = require('../../../support/helpers/returns/version.helper.js') - -// Thing under test -const FetchReturnsForLicenceService = require('../../../../app/services/bill-runs/two-part-tariff/fetch-returns-for-licence.service.js') - -describe('Fetch Returns for Licence service', () => { - const billingPeriod = { startDate: new Date('2022-04-01'), endDate: new Date('2023-03-31') } - let returnRecord - - beforeEach(async () => { - await DatabaseHelper.clean() - }) - - describe('when there are valid Returns that should be considered', () => { - beforeEach(async () => { - const metadata = { - nald: { - periodEndDay: '31', - periodEndMonth: '3', - periodStartDay: '1', - periodStartMonth: '4' - }, - purposes: [ - { - tertiary: { - code: '400', - description: 'Spray Irrigation - Direct' - } - } - ], - description: 'The Description', - isTwoPartTariff: true - } - - returnRecord = await ReturnHelper.add({ metadata }) - }) - - describe('which have return lines within the billing period', () => { - beforeEach(async () => { - const { returnId } = returnRecord - const { versionId } = await VersionHelper.add({ returnId }) - - await LineHelper.add({ versionId, startDate: new Date('2022-05-01'), endDate: new Date('2022-05-07'), quantity: 1234 }) - await LineHelper.add({ versionId, startDate: new Date('2022-05-08'), endDate: new Date('2022-05-14'), quantity: 5678 }) - }) - - it('returns the Return and Lines that are applicable', async () => { - const { licenceRef } = returnRecord - const result = await FetchReturnsForLicenceService.go(licenceRef, billingPeriod) - - expect(result).to.have.length(1) - expect(result[0].returnId).to.equal(returnRecord.returnId) - expect(result[0].description).to.equal('The Description') - expect(result[0].startDate).to.equal(new Date('2022-04-01')) - expect(result[0].endDate).to.equal(new Date('2023-03-31')) - expect(result[0].periodStartDay).to.equal(1) - expect(result[0].periodStartMonth).to.equal(4) - expect(result[0].periodEndDay).to.equal(31) - expect(result[0].periodEndMonth).to.equal(3) - - expect(result[0].purposes).to.have.length(1) - expect(result[0].purposes[0].tertiary.code).to.equal('400') - expect(result[0].purposes[0].tertiary.description).to.equal('Spray Irrigation - Direct') - - expect(result[0].versions).to.have.length(1) - expect(result[0].versions[0].nilReturn).to.equal(false) - - expect(result[0].versions[0].lines).to.have.length(2) - expect(result[0].versions[0].lines[0].startDate).to.equal(new Date('2022-05-01')) - expect(result[0].versions[0].lines[0].endDate).to.equal(new Date('2022-05-07')) - expect(result[0].versions[0].lines[0].quantity).to.equal(1234) - expect(result[0].versions[0].lines[1].startDate).to.equal(new Date('2022-05-08')) - expect(result[0].versions[0].lines[1].endDate).to.equal(new Date('2022-05-14')) - expect(result[0].versions[0].lines[1].quantity).to.equal(5678) - }) - }) - - describe('which have NO return lines within the billing period', () => { - beforeEach(async () => { - const { returnId } = returnRecord - const { versionId } = await VersionHelper.add({ returnId }) - - await LineHelper.add({ versionId, startDate: new Date('2023-05-01'), endDate: new Date('2023-05-07'), quantity: 1234 }) - await LineHelper.add({ versionId, startDate: new Date('2023-05-08'), endDate: new Date('2023-05-14'), quantity: 5678 }) - }) - - it('returns the Return with no lines', async () => { - const { licenceRef } = returnRecord - const result = await FetchReturnsForLicenceService.go(licenceRef, billingPeriod) - - expect(result).to.have.length(1) - - expect(result[0].versions[0].lines).to.have.length(0) - }) - }) - - describe('which is a nil return', () => { - beforeEach(async () => { - const { returnId } = returnRecord - - await VersionHelper.add({ returnId, nilReturn: true }) - }) - - it('returns the Return with `nilreturn` set to `true` and no lines', async () => { - const { licenceRef } = returnRecord - const result = await FetchReturnsForLicenceService.go(licenceRef, billingPeriod) - - expect(result).to.have.length(1) - - expect(result[0].versions).to.have.length(1) - expect(result[0].versions[0].nilReturn).to.equal(true) - - expect(result[0].versions[0].lines).to.have.length(0) - }) - }) - }) - - describe('when there are NO valid Returns that should be considered', () => { - describe('because the return is outside the billing period', () => { - beforeEach(async () => { - returnRecord = await ReturnHelper.add({ startDate: new Date('2023-04-01'), endDate: new Date('2024-03-31') }) - const { returnId } = returnRecord - - await VersionHelper.add({ returnId }) - }) - - it('returns no records', async () => { - const { licenceRef } = returnRecord - const result = await FetchReturnsForLicenceService.go(licenceRef, billingPeriod) - - expect(result).to.have.length(0) - }) - }) - - describe('because the return is not two-part-tariff', () => { - beforeEach(async () => { - const metadata = { - nald: { - periodEndDay: '31', - periodEndMonth: '3', - periodStartDay: '1', - periodStartMonth: '4' - }, - purposes: [ - { - tertiary: { - code: '400', - description: 'Spray Irrigation - Direct' - } - } - ], - description: 'The Description', - isTwoPartTariff: false - } - - returnRecord = await ReturnHelper.add({ metadata }) - const { returnId } = returnRecord - - await VersionHelper.add({ returnId }) - }) - - it('returns no records', async () => { - const { licenceRef } = returnRecord - const result = await FetchReturnsForLicenceService.go(licenceRef, billingPeriod) - - expect(result).to.have.length(0) - }) - }) - - describe('because there are no returns', () => { - it('returns no records', async () => { - const result = await FetchReturnsForLicenceService.go('LicenceRefWithNoReturns', billingPeriod) - - expect(result).to.have.length(0) - }) - }) - }) -}) diff --git a/test/support/helpers/returns/line.helper.js b/test/support/helpers/returns/line.helper.js deleted file mode 100644 index cc0a9591e4..0000000000 --- a/test/support/helpers/returns/line.helper.js +++ /dev/null @@ -1,80 +0,0 @@ -'use strict' - -/** - * @module LineHelper - */ - -const { generateUUID } = require('../../../../app/lib/general.lib.js') -const LineModel = require('../../../../app/models/returns/line.model.js') - -/** - * Add a new line - * - * If no `data` is provided, default values will be used. These are - * - * - `versionId` - [random UUID] - * - `substance` - water - * - `quantity` - 4380 - * - `unit` - m³ - * - `startDate` - 2021-12-26 - * - `endDate` - 2022-01-01 - * - `timePeriod` - week - * - `metadata` - {} - * - `createdAt` - 2022-11-16 09:42:11.000 - * - `updatedAt` - null - * - `readingType` - measured - * - `userUnit` - m³ - * - * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database - * - * @returns {module:LineModel} The instance of the newly created record - */ -function add (data = {}) { - const insertData = defaults(data) - - return LineModel.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 = { - lineId: generateUUID(), - versionId: generateUUID(), - substance: 'water', - quantity: 4380, - unit: 'm³', - startDate: new Date('2021-12-26'), - endDate: new Date('2022-01-01'), - timePeriod: 'week', - metadata: {}, - // INFO: The lines 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, something we'll never actually need - // to do because it's a static table. 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 ('2023-01-05T08:37:05.575Z') and PostgreSQL can do the conversion - // https://stackoverflow.com/a/61912776/6117745 - createdAt: new Date('2022-11-16 09:42:11.000').toISOString(), - updatedAt: null, - readingType: 'measured', - userUnit: 'm³' - } - - return { - ...defaults, - ...data - } -} - -module.exports = { - add, - defaults -} diff --git a/test/support/helpers/returns/return.helper.js b/test/support/helpers/returns/return.helper.js deleted file mode 100644 index 055bbd0652..0000000000 --- a/test/support/helpers/returns/return.helper.js +++ /dev/null @@ -1,110 +0,0 @@ -'use strict' - -/** - * @module ReturnHelper - */ - -const { randomInteger } = require('../general.helper.js') -const { generateUUID } = require('../../../../app/lib/general.lib.js') -const ReturnModel = require('../../../../app/models/returns/return.model.js') - -/** - * Add a new return - * - * If no `data` is provided, default values will be used. These are - * - * - `returnId` - v1:1:[the generated licenceRef]:[the generated returnRequirement]:2022-04-01:2023-03-31 - * - `regime` - water - * - `licenceType` - abstraction - * - `licenceRef` - [randomly generated - 1/23/45/76/3672] - * - `startDate` - 2022-04-01 - * - `endDate` - 2023-03-31 - * - `returnsFrequency` - month - * - `status` - completed - * - `source` - NALD - * - `metadata` - {} - * - `receivedDate` - 2023-04-12 - * - `returnRequirement` - [randomly generated - 10000321] - * - `dueDate` - 2023-04-28 - * - `returnCycleId` - [random UUID] - * - * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database - * - * @returns {module:ReturnModel} The instance of the newly created record - */ -function add (data = {}) { - const insertData = defaults(data) - - return ReturnModel.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 licenceRef = data.licenceRef ? data.licenceRef : _generateLicenceRef() - const returnRequirement = data.returnRequirement ? data.returnRequirement : randomInteger(10000000, 19999999) - - const defaults = { - returnId: generateReturnId('2022-04-01', '2023-03-31', 1, licenceRef, returnRequirement), - regime: 'water', - licenceType: 'abstraction', - licenceRef, - startDate: new Date('2022-04-01'), - endDate: new Date('2023-03-31'), - returnsFrequency: 'month', - status: 'completed', - source: 'NALD', - metadata: {}, - receivedDate: new Date('2023-04-12'), - returnRequirement, - dueDate: new Date('2023-04-28'), - returnCycleId: generateUUID() - } - - return { - ...defaults, - ...data - } -} - -function generateReturnId ( - startDate = '2022-04-01', - endDate = '2023-03-31', - version = 1, - licenceRef, - returnRequirement -) { - if (!licenceRef) { - licenceRef = _generateLicenceRef() - } - - if (!returnRequirement) { - returnRequirement = randomInteger(10000000, 19999999) - } - - return `v${version}:1:${licenceRef}:${returnRequirement}:${startDate}:${endDate}` -} - -function _generateLicenceRef () { - const part1 = randomInteger(1, 9) - const part2 = randomInteger(10, 99) - const part3 = randomInteger(10, 99) - const part4 = randomInteger(10, 99) - const part5 = randomInteger(1000, 9999) - - return `${part1}/${part2}/${part3}/${part4}/${part5}` -} - -module.exports = { - add, - defaults, - generateReturnId -} diff --git a/test/support/helpers/returns/version.helper.js b/test/support/helpers/returns/version.helper.js deleted file mode 100644 index f6722299b8..0000000000 --- a/test/support/helpers/returns/version.helper.js +++ /dev/null @@ -1,75 +0,0 @@ -'use strict' - -/** - * @module VersionHelper - */ - -const { generateUUID } = require('../../../../app/lib/general.lib.js') -const { generateReturnId } = require('./return.helper.js') -const VersionModel = require('../../../../app/models/returns/version.model.js') - -/** - * Add a new version - * - * If no `data` is provided, default values will be used. These are - * - * `returnId` - [randomly generated - v1:1:03/28/78/0033:10025289:2022-04-01:2023-03-31] - * `userId` - admin-internal@wrls.gov.uk - * `userType` - internal - * `versionNumber` - 1 - * `metadata` - {} - * `createdAt` - 2022-11-16 09:42:11.000 - * `updatedAt` - null - * `nilReturn` - false - * `current` - true - * - * @param {Object} [data] Any data you want to use instead of the defaults used here or in the database - * - * @returns {module:VersionModel} The instance of the newly created record - */ -function add (data = {}) { - const insertData = defaults(data) - - return VersionModel.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 = { - versionId: generateUUID(), - returnId: generateReturnId(), - userId: 'admin-internal@wrls.gov.uk', - userType: 'internal', - versionNumber: 1, - metadata: {}, - // INFO: The lines 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, something we'll never actually need - // to do because it's a static table. 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 ('2023-01-05T08:37:05.575Z') and PostgreSQL can do the conversion - // https://stackoverflow.com/a/61912776/6117745 - createdAt: new Date('2022-11-16 09:42:11.000').toISOString(), - updatedAt: null, - nilReturn: false, - current: true - } - - return { - ...defaults, - ...data - } -} - -module.exports = { - add, - defaults -}