Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Select additional submission options page #988

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
82c696f
Select additional submission options page
Demwunz May 7, 2024
2900fe0
feat(app): add additional options
Demwunz May 10, 2024
4254b22
feat(app): amended options
Demwunz May 14, 2024
55b9d35
feat(app): updated tests
Demwunz May 14, 2024
c06f337
Merge branch 'main' into WATER-4306-select-additional-submission-opti…
Demwunz May 14, 2024
10791ed
feat(app): remove redundant comments
Demwunz May 14, 2024
9f37830
feat(app): fixing tests
Demwunz May 15, 2024
8008ecb
feat(app): fixing tests
Demwunz May 15, 2024
35559d8
Merge branch 'main' into WATER-4306-select-additional-submission-opti…
Demwunz May 15, 2024
c875061
feat(app): normalise arrays
Demwunz May 15, 2024
f443bea
fix(app): changing sonarcloud issues
Demwunz May 15, 2024
79ad8f2
Merge branch 'main' into WATER-4306-select-additional-submission-opti…
Demwunz May 15, 2024
0d5fa03
fix(app): revert validation
Demwunz May 15, 2024
355386a
fix(app): reduce func by 1 line for sonarcloud
Demwunz May 15, 2024
10ad08d
Merge branch 'main' into WATER-4306-select-additional-submission-opti…
Demwunz May 16, 2024
f3a5fe8
fix(app): reduce test complexity
Demwunz May 16, 2024
a60244f
fix(app): feedback amends
Demwunz May 16, 2024
80776c6
Merge branch 'main' into WATER-4306-select-additional-submission-opti…
Demwunz May 16, 2024
258e1cd
fix(app): amended var name
Demwunz May 16, 2024
747d4a1
Merge branch 'main' into WATER-4306-select-additional-submission-opti…
Demwunz May 16, 2024
64b40b2
fix(app): fix error from pasting in code
Demwunz May 16, 2024
88d1c15
fix(app): minor amends
Demwunz May 17, 2024
3933dc2
Merge branch 'main' into WATER-4306-select-additional-submission-opti…
Demwunz May 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions app/controllers/return-requirements.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

const AbstractionPeriodService = require('../services/return-requirements/abstraction-period.service.js')
const AdditionalSubmissionOptionsService = require('../services/return-requirements/additional-submission-options.service.js')
const AddService = require('../services/return-requirements/add.service.js')
const AgreementsExceptionsService = require('../services/return-requirements/agreements-exceptions.service.js')
const CancelService = require('../services/return-requirements/cancel.service.js')
Expand All @@ -25,6 +26,7 @@ const SetupService = require('../services/return-requirements/setup.service.js')
const SiteDescriptionService = require('../services/return-requirements/site-description.service.js')
const StartDateService = require('../services/return-requirements/start-date.service.js')
const SubmitAbstractionPeriod = require('../services/return-requirements/submit-abstraction-period.service.js')
const SubmitAdditionalSubmissionOptionsService = require('../services/return-requirements/submit-additional-submission-options.service.js')
const SubmitAgreementsExceptions = require('../services/return-requirements/submit-agreements-exceptions.service.js')
const SubmitCancel = require('../services/return-requirements/submit-cancel.service.js')
const SubmitCheckService = require('../services/return-requirements/submit-check.service.js')
Expand Down Expand Up @@ -59,6 +61,16 @@ async function add (request, h) {
return h.redirect(`/system/return-requirements/${sessionId}/purpose/${requirementIndex}`)
}

async function additionalSubmissionOptions (request, h) {
const { sessionId } = request.params

const pageData = await AdditionalSubmissionOptionsService.go(sessionId)

return h.view('return-requirements/additional-submission-options.njk', {
...pageData
})
}

async function agreementsExceptions (request, h) {
const { requirementIndex, sessionId } = request.params

Expand Down Expand Up @@ -265,6 +277,18 @@ async function submitAgreementsExceptions (request, h) {
return h.redirect(`/system/return-requirements/${sessionId}/check`)
}

async function submitAdditionalSubmissionOptions (request, h) {
const { params: { sessionId }, payload, yar } = request

const pageData = await SubmitAdditionalSubmissionOptionsService.go(sessionId, payload, yar)

if (pageData.error) {
return h.view('return-requirements/additional-submission-options.njk', pageData)
}

return h.redirect(`/system/return-requirements/${sessionId}/check`)
}

async function submitCancel (request, h) {
const { sessionId } = request.params
const { licenceId } = request.payload
Expand Down Expand Up @@ -468,6 +492,7 @@ async function submitStartDate (request, h) {
module.exports = {
abstractionPeriod,
add,
additionalSubmissionOptions,
agreementsExceptions,
approved,
cancel,
Expand All @@ -487,6 +512,7 @@ module.exports = {
siteDescription,
startDate,
submitAbstractionPeriod,
submitAdditionalSubmissionOptions,
submitAgreementsExceptions,
submitCancel,
submitCheck,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict'

/**
* Formats data for the `/return-requirements/{sessionId}/additional-submission-options` page
* @module AdditionalSubmissionOptionsPresenter
*/

/**
* Formats data for the `/return-requirements/{sessionId}/additional-submission-options` page
*
* @param {module:SessionModel} session - The returns requirements session instance
*
* @returns {Object} - The data formatted for the view template
*/
function go (session) {
const { id: sessionId, licence: { id: licenceId, licenceRef }, additionalSubmissionOptions } = session
const data = {
additionalSubmissionOptions: additionalSubmissionOptions ?? [],
backLink: `/system/return-requirements/${sessionId}/check`,
licenceId,
licenceRef,
sessionId
}

return data
}

module.exports = {
go
}
3 changes: 2 additions & 1 deletion app/presenters/return-requirements/check.presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ const { formatLongDate } = require('../base.presenter.js')
const { returnRequirementReasons } = require('../../lib/static-lookups.lib.js')

function go (session) {
const { id: sessionId, journey, licence, note, reason } = session
const { additionalSubmissionOptions, id: sessionId, journey, licence, note, reason } = session

return {
additionalSubmissionOptions: additionalSubmissionOptions ?? [],
journey,
licenceRef: licence.licenceRef,
note: note ? note.content : null,
Expand Down
26 changes: 26 additions & 0 deletions app/routes/return-requirement.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,32 @@ const routes = [
}

},
{
method: 'GET',
path: '/return-requirements/{sessionId}/additional-submission-options',
handler: ReturnRequirementsController.additionalSubmissionOptions,
options: {
auth: {
access: {
scope: ['billing']
}
},
description: 'Select additional submission options for the return requirement'
}
},
{
method: 'POST',
path: '/return-requirements/{sessionId}/additional-submission-options',
handler: ReturnRequirementsController.submitAdditionalSubmissionOptions,
options: {
auth: {
access: {
scope: ['billing']
}
},
description: 'Submit additional submission options for the return requirement'
}
},
{
method: 'GET',
path: '/return-requirements/{sessionId}/agreements-exceptions/{requirementIndex}',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
'use strict'

/**
* Orchestrates fetching and presenting the data for
* `/return-requirements/{sessionId}/additional-submission-options` page
* @module AdditionalSubmissionOptionsService
*/

const AdditionalSubmissionOptionsPresenter = require('../../presenters/return-requirements/additional-submission-options.presenter.js')
const SessionModel = require('../../models/session.model.js')

/**
* Orchestrates fetching and presenting the data for
* `/return-requirements/{sessionId}/additional-submission-options` page
*
* Supports generating the data needed for the points page in the return requirements setup journey. It fetches the
* current session record and combines it with the checkboxes and other information needed for the form.
*
* @param {string} sessionId - The UUID of the current session
*
* @returns {Promise<Object>} The view data for the points page
*/
async function go (sessionId) {
const session = await SessionModel.query().findById(sessionId)

const formattedData = AdditionalSubmissionOptionsPresenter.go(session)

return {
activeNavBar: 'search',
pageTitle: 'Select any additional submission options for the return requirements',
...formattedData
}
}

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

/**
* Orchestrates validating the data for `/return-requirements/{sessionId}/additional-submission-options` page
* @module AdditionalSubmissionOptionsService
*/

const AdditionalSubmissionOptionsPresenter = require('../../presenters/return-requirements/additional-submission-options.presenter.js')
const AdditionalSubmissionOptionsValidator = require('../../validators/return-requirements/additional-submission-options.validator.js')
const SessionModel = require('../../models/session.model.js')

/**
* Orchestrates validating the data for `/return-requirements/{sessionId}/additional-submission-options` page
*
* It first retrieves the session instance for the returns requirements journey in progress.
*
* The validation result is then combined with the output of the presenter to generate the page data needed by the view.
* If there was a validation error the controller will re-render the page so needs this information. If all is well the
* controller will redirect to the next page in the journey.
*
* @param {string} sessionId - The id of the current session
* @param {Object} payload - The submitted form data
* @param {Object} yar - The Hapi `request.yar` session manager passed on by the controller
*
* @returns {Promise<Object>} If no errors it returns an empty object else the page data for the note page including the
* validation error details
*/
async function go (sessionId, payload, yar) {
const session = await SessionModel.query().findById(sessionId)

_handleOneOptionSelected(payload)

const validationResult = _validate(payload)

if (!validationResult) {
const notification = _notification(session, payload)
await _save(session, payload)

if (notification) {
yar.flash('notification', notification)
}

return {}
}

const submittedSessionData = _submittedSessionData(session, payload)

return {
activeNavBar: 'search',
error: validationResult,
pageTitle: 'Select any additional submission options for the return requirements',
...submittedSessionData
}
}

/**
* When a single additional submission option is checked by the user, it returns as a string. When multiple options are
* checked, the 'additionalSubmissionOptions' is returned as an array.
* This function works to make those single selected string 'additionalSubmissionOptions' into an array for uniformity.
*/
function _handleOneOptionSelected (payload) {
if (!Array.isArray(payload.additionalSubmissionOptions)) {
payload.additionalSubmissionOptions = [payload.additionalSubmissionOptions]
}
}

function _notification (session, payload) {
const { additionalSubmissionOptions } = session ?? {}

if (additionalSubmissionOptions !== payload.additionalSubmissionOptions) {
return {
text: 'Changes updated',
title: 'Updated'
}
}

return null
}

async function _save (session, payload) {
session.additionalSubmissionOptions = payload.additionalSubmissionOptions

return session.$update()
}

function _submittedSessionData (session, payload) {
session.additionalSubmissionOptions = payload.additionalSubmissionOptions ?? []

return AdditionalSubmissionOptionsPresenter.go(session)
}

function _validate (payload) {
const validation = AdditionalSubmissionOptionsValidator.go(payload)

if (!validation.error) {
return null
}

const { message } = validation.error.details[0]

return {
text: message
}
}

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

/**
* Validates data submitted for the `/return-requirements/{sessionId}/additional-submission-options` page
* @module AdditionalSubmissionOptionsValidator
*/

const Joi = require('joi')

/**
* Validates data submitted for the `/return-requirements/{sessionId}/additional-submission-options` page
*
* When setting up a requirement users must specify additional-submission-options for the return requirement.
* Users must select one or more points linked to the licence.
* If these requirements are not met the validation will return an error.
*
* @param {Object} options - The options extracted from payload taken from the request to be validated
*
* @returns {Object} The result from calling Joi's schema.validate(). If any errors are found the `error:` property will
* also exist detailing what the issue is.
*/
function go (payload) {
const additionalSubmissionOptions = payload.additionalSubmissionOptions

const errorMessage = 'Select additional submission options for the requirements for returns'

const schema = Joi.object({
additionalSubmissionOptions: Joi.array()
.items(Joi.string())
.required()
}).messages({
'any.required': errorMessage,
'array.sparse': errorMessage
})

return schema.validate({ additionalSubmissionOptions }, { abortEarly: false })
}

module.exports = {
go
}
Loading
Loading