Skip to content

Commit

Permalink
Persist a new return version and its requirements (#1137)
Browse files Browse the repository at this point in the history
https://eaflood.atlassian.net/browse/WATER-4519

Having completed the return requirements setup journey (returns-required), we need to persist both the return version (start date, reason and notes) along with its return requirements to the database.

When "Approve" is clicked in the `/check` page the data in the session needs to be persisted to:

- water.return_versions
- water.return_requirements
- water.return_requirement_points
- water.return_requirement_purposes
  • Loading branch information
Jozzey authored Jul 16, 2024
1 parent bde4913 commit 1502d56
Show file tree
Hide file tree
Showing 35 changed files with 1,040 additions and 100 deletions.
3 changes: 2 additions & 1 deletion app/controllers/return-requirements.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,9 @@ async function submitCancel (request, h) {

async function submitCheck (request, h) {
const { sessionId } = request.params
const { id: userId } = request.auth.credentials.user

const licenceId = await SubmitCheckService.go(sessionId)
const licenceId = await SubmitCheckService.go(sessionId, userId)

return h.redirect(`/system/return-requirements/${licenceId}/approved`)
}
Expand Down
4 changes: 2 additions & 2 deletions app/presenters/return-requirements/cancel.presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

const { formatLongDate } = require('../base.presenter.js')
const { returnRequirementReasons } = require('../../lib/static-lookups.lib.js')
const { returnRequirementFrequencies, returnRequirementReasons } = require('../../lib/static-lookups.lib.js')

/**
* Formats data for the `/return-requirements/{sessionId}/cancel` page
Expand Down Expand Up @@ -38,7 +38,7 @@ function _returnRequirements (journey, requirements) {
const { frequencyReported, returnsCycle, siteDescription } = requirement
const cycle = returnsCycle === 'summer' ? 'Summer' : 'Winter and all year'

return `${cycle} ${frequencyReported} requirements for returns, ${siteDescription}.`
return `${cycle} ${returnRequirementFrequencies[frequencyReported]} requirements for returns, ${siteDescription}.`
})
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const { formatAbstractionDate } = require('../../base.presenter.js')
const { generateAbstractionPointDetail } = require('../../../lib/general.lib.js')
const { returnRequirementFrequencies } = require('../../../lib/static-lookups.lib.js')

const agreementsExceptionsText = {
none: 'None',
Expand Down Expand Up @@ -93,8 +94,8 @@ function _mapRequirement (requirement, index, points) {
return {
abstractionPeriod: _abstractionPeriod(requirement.abstractionPeriod),
agreementsExceptions: _agreementsExceptions(requirement.agreementsExceptions),
frequencyCollected: requirement.frequencyCollected,
frequencyReported: requirement.frequencyReported,
frequencyCollected: returnRequirementFrequencies[requirement.frequencyCollected],
frequencyReported: returnRequirementFrequencies[requirement.frequencyReported],
index,
points: _mapPoints(requirement.points, points),
purposes: _mapPurposes(requirement.purposes),
Expand Down
3 changes: 2 additions & 1 deletion app/presenters/return-requirements/remove.presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

const { formatLongDate } = require('../base.presenter.js')
const { returnRequirementFrequencies } = require('../../lib/static-lookups.lib.js')

/**
* Formats data for the `/return-requirements/{sessionId}/remove/{requirementIndex}` page
Expand Down Expand Up @@ -39,7 +40,7 @@ function _formattedReturnRequirement (requirement) {
const { frequencyReported, returnsCycle, siteDescription } = requirement
const cycle = returnsCycle === 'summer' ? 'Summer' : 'Winter and all year'

return `${cycle} ${frequencyReported} requirements for returns, ${siteDescription}.`
return `${cycle} ${returnRequirementFrequencies[frequencyReported]} requirements for returns, ${siteDescription}.`
}

function _startDate (session) {
Expand Down
12 changes: 3 additions & 9 deletions app/services/return-requirements/fetch-points.service.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use strict'

/**
* Fetches points details needed for `/return-requirements/{sessionId}/points` page
* Fetches the points data for a licence
* @module FetchPointsService
*/

Expand All @@ -10,11 +10,11 @@ const { ref } = require('objection')
const LicenceModel = require('../../models/licence.model.js')

/**
* Fetches points details needed for `/return-requirements/{sessionId}/points` page
* Fetches the points data for a licence
*
* @param {string} licenceId - The UUID for the licence to fetch
*
* @returns {Promise<Object>} The points details for the matching licenceId
* @returns {Promise<Object>} The points data for the matching licenceId
*/
async function go (licenceId) {
const data = await _fetchPoints(licenceId)
Expand All @@ -25,12 +25,6 @@ async function go (licenceId) {
async function _fetchPoints (licenceId) {
const result = await LicenceModel.query()
.findById(licenceId)
.withGraphFetched('region')
.modifyGraph('region', (builder) => {
builder.select([
'id'
])
})
.withGraphFetched('permitLicence')
.modifyGraph('permitLicence', (builder) => {
builder.select([
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
*/

const ReturnVersionModel = require('../../models/return-version.model.js')
const { returnRequirementFrequencies } = require('../../lib/static-lookups.lib.js')

/**
* Fetches an existing return version and generates setup return requirements from it
Expand Down Expand Up @@ -151,8 +150,8 @@ function _transformForSetup (returnVersion) {
'start-abstraction-period-day': abstractionPeriodStartDay,
'start-abstraction-period-month': abstractionPeriodStartMonth
},
frequencyReported: returnRequirementFrequencies[reportingFrequency],
frequencyCollected: returnRequirementFrequencies[collectionFrequency],
frequencyReported: reportingFrequency,
frequencyCollected: collectionFrequency,
agreementsExceptions: _agreementExceptions(returnRequirement)
}
})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
'use strict'

/**
* Uses the session data to generate the data sets required to create the return version requirements for a licence
* @module GenerateReturnVersionRequirementsService
*/

const FetchPointsService = require('./fetch-points.service.js')
const LicenceModel = require('../../models/licence.model.js')
const LicenceVersionModel = require('../../models/licence-version.model.js')
const ReturnRequirementModel = require('../../models/return-requirement.model.js')

/**
* Uses the session data to generate the data sets required to create the return version requirements for a licence
*
* Creates the data needed to populate the `return_requirements`, `return_requirement_points` and
* `return_requirement_purposes` tables.
*
* @param {String} licenceId - The UUID of the licence the requirements are for
* @param {Object[]} requirements - The return requirements data from the session
*
* @returns {Promise<Object>} The new return version requirements data for a licence
*/
async function go (licenceId, requirements) {
const naldRegionId = await _fetchNaldRegionId(licenceId)
const licencePoints = await FetchPointsService.go(licenceId)
const returnRequirements = []

let legacyId = await _nextLegacyId(naldRegionId)

for (const requirement of requirements) {
const externalId = `${naldRegionId}:${legacyId}`

const returnRequirement = {
abstractionPeriodStartDay: requirement.abstractionPeriod['start-abstraction-period-day'],
abstractionPeriodStartMonth: requirement.abstractionPeriod['start-abstraction-period-month'],
abstractionPeriodEndDay: requirement.abstractionPeriod['end-abstraction-period-day'],
abstractionPeriodEndMonth: requirement.abstractionPeriod['end-abstraction-period-month'],
collectionFrequency: requirement.frequencyCollected,
externalId,
fiftySixException: requirement.agreementsExceptions.includes('56-returns-exception'),
gravityFill: requirement.agreementsExceptions.includes('gravity-fill'),
legacyId,
reabstraction: requirement.agreementsExceptions.includes('transfer-re-abstraction-scheme'),
reportingFrequency: requirement.frequencyReported,
returnsFrequency: 'year',
returnRequirementPoints: _generateReturnRequirementPoints(licencePoints, externalId, requirement.points),
returnRequirementPurposes: await _generateReturnRequirementPurposes(licenceId, requirement.purposes),
siteDescription: requirement.siteDescription,
summer: requirement.returnsCycle === 'summer',
twoPartTariff: requirement.agreementsExceptions.includes('two-part-tariff')
}

legacyId++

returnRequirements.push(returnRequirement)
}

return returnRequirements
}

async function _fetchNaldRegionId (licenceId) {
const { naldRegionId } = await LicenceModel.query()
.findById(licenceId)
.select('region.naldRegionId')
.innerJoinRelated('region')

return naldRegionId
}

function _generateReturnRequirementPoints (licencePoints, requirementExternalId, requirementPoints) {
const returnRequirementPoints = []

requirementPoints.forEach((requirementPoint) => {
const point = licencePoints.find((licencePoint) => {
return licencePoint.ID === requirementPoint
})

const returnRequirementPoint = {
description: point.LOCAL_NAME,
externalId: `${requirementExternalId}:${point.ID}`,
naldPointId: point.ID,
ngr1: point.NGR1_SHEET !== 'null' ? `${point.NGR1_SHEET} ${point.NGR1_EAST} ${point.NGR1_NORTH}` : null,
ngr2: point.NGR2_SHEET !== 'null' ? `${point.NGR2_SHEET} ${point.NGR2_EAST} ${point.NGR2_NORTH}` : null,
ngr3: point.NGR3_SHEET !== 'null' ? `${point.NGR3_SHEET} ${point.NGR3_EAST} ${point.NGR3_NORTH}` : null,
ngr4: point.NGR4_SHEET !== 'null' ? `${point.NGR4_SHEET} ${point.NGR4_EAST} ${point.NGR4_NORTH}` : null
}

returnRequirementPoints.push(returnRequirementPoint)
})

return returnRequirementPoints
}

async function _generateReturnRequirementPurposes (licenceId, purposes) {
const returnRequirementPurposes = []

for (const purpose of purposes) {
const { primaryPurposeId, secondaryPurposeId } = await LicenceVersionModel.query()
.select('primaryPurposeId', 'secondaryPurposeId')
.innerJoinRelated('licenceVersionPurposes')
.where('licenceId', licenceId)
.andWhere('status', 'current')
.andWhere('purposeId', purpose.id)
.first()

const returnRequirementPurpose = {
alias: purpose.alias !== '' ? purpose.alias : null,
primaryPurposeId,
purposeId: purpose.id,
secondaryPurposeId
}

returnRequirementPurposes.push(returnRequirementPurpose)
}

return returnRequirementPurposes
}

async function _nextLegacyId (naldRegionId) {
const { lastLegacyId } = await ReturnRequirementModel.query()
.max('legacyId as lastLegacyId')
.whereLike('externalId', `${naldRegionId}%`)
.first()

if (lastLegacyId) {
return lastLegacyId + 1
}

return 1
}

module.exports = {
go
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use strict'

/**
* Uses the session data to generate the data sets required to create a new return version for a licence
* @module GenerateReturnVersionService
*/

const GenerateReturnVersionRequirementsService = require('./generate-return-version-requirements.service.js')
const ReturnVersionModel = require('../../models/return-version.model.js')

/**
* Uses the session data to generate the data sets required to create a new return version for a licence
*
* Creates the data needed to populate the `return_versions`, `return_requirements`, `return_requirement_points` and
* `return_requirement_purposes` tables.
*
* @param {string} sessionData - The session data required to set up a new return version for a licence
* @param {number} userId - The id of the logged in user
*
* @returns {Promise<Object>} The new return version and requirement data for a licence
*/
async function go (sessionData, userId) {
const returnVersion = await _generateReturnVersion(sessionData, userId)
const returnRequirements = await GenerateReturnVersionRequirementsService.go(sessionData.licence.id, sessionData.requirements)

return {
returnRequirements,
returnVersion
}
}

function _calculateStartDate (sessionData) {
if (sessionData.startDateOptions === 'anotherStartDate') {
// 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 deduct 1 from the month.
return new Date(sessionData.startDateYear, sessionData.startDateMonth - 1, sessionData.startDateDay)
}

return sessionData.licence.currentVersionStartDate
}

async function _generateReturnVersion (sessionData, userId) {
return {
createdBy: userId,
endDate: null,
licenceId: sessionData.licence.id,
multipleUpload: _multipleUpload(sessionData?.additionalSubmissionOptions),
notes: sessionData?.note?.content,
reason: sessionData.reason,
startDate: _calculateStartDate(sessionData),
status: 'current',
version: await _nextVersionNumber(sessionData.licence.id)
}
}

async function _nextVersionNumber (licenceId) {
const { lastVersionNumber } = await ReturnVersionModel.query()
.max('version as lastVersionNumber')
.where({ licenceId })
.first()

if (lastVersionNumber) {
return lastVersionNumber + 1
}

return 1
}

function _multipleUpload (additionalSubmissionOptions) {
return additionalSubmissionOptions ? additionalSubmissionOptions.includes('multiple-upload') : false
}

module.exports = {
go
}
Loading

0 comments on commit 1502d56

Please sign in to comment.