Skip to content

Commit

Permalink
Feature returns required purposes (#1064)
Browse files Browse the repository at this point in the history
* Check your requirements - purposes

Due to the estimated complexity of adding fetch services for purposes, points and other display items. We have broken down the complex display items into their own branches of work.

https://eaflood.atlassian.net/browse/WATER-4386

This branch will add purposes to the return requirement summary card

Previous work done here - #1019
  • Loading branch information
jonathangoulding authored Jun 4, 2024
1 parent 8c7c791 commit 5f97578
Show file tree
Hide file tree
Showing 9 changed files with 400 additions and 128 deletions.
48 changes: 6 additions & 42 deletions app/presenters/return-requirements/check.presenter.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,71 +5,35 @@
* @module CheckPresenter
*/

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

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

const returnsRequired = journey === 'returns-required'

return {
additionalSubmissionOptions: additionalSubmissionOptions ?? [],
journey,
licenceRef: licence.licenceRef,
note: note ? note.content : null,
pageTitle: `Check the return requirements for ${licence.licenceHolder}`,
reason: returnRequirementReasons[reason],
reasonLink: _reasonLink(sessionId, journey),
requirements: _requirements(session),
reasonLink: _reasonLink(sessionId, returnsRequired),
sessionId,
startDate: _startDate(session),
userEmail: note ? note.userEmail : 'No notes added'
}
}

function _abstractionPeriod (abstractionPeriod) {
const { 'start-abstraction-period-day': startDay, 'start-abstraction-period-month': startMonth, 'end-abstraction-period-day': endDay, 'end-abstraction-period-month': endMonth } = abstractionPeriod
const startDate = formatAbstractionDate(startDay, startMonth)
const endDate = formatAbstractionDate(endDay, endMonth)

return `From ${startDate} to ${endDate}`
}

function _reasonLink (sessionId, journey) {
if (journey === 'returns-required') {
function _reasonLink (sessionId, returnsRequired) {
if (returnsRequired) {
return `/system/return-requirements/${sessionId}/reason`
}

return `/system/return-requirements/${sessionId}/no-returns-required`
}

function _requirements (session) {
const { requirements } = session

const completedRequirements = []

for (const [index, requirement] of requirements.entries()) {
const { agreementsExceptions } = requirement
// NOTE: We determine a requirement is complete because agreement exceptions is populated and it is the last step in
// the journey
if (agreementsExceptions) {
completedRequirements.push(_mapRequirement(requirement, index))
}
}

return completedRequirements
}

function _mapRequirement (requirement, index) {
return {
abstractionPeriod: _abstractionPeriod(requirement.abstractionPeriod),
frequencyCollected: requirement.frequencyCollected,
frequencyReported: requirement.frequencyReported,
index,
purposes: 'purpose',
siteDescription: requirement.siteDescription
}
}

function _startDate (session) {
const { licence, startDateOptions, startDateDay, startDateMonth, startDateYear } = session

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
'use strict'

const { formatAbstractionDate } = require('../../base.presenter.js')

/**
* Formats return requirements data for the `/return-requirements/{sessionId}/check` page
* @module ReturnRequirementsPresenter
*/

/**
* Formats return requirements data for the `/return-requirements/{sessionId}/check` page
*
* @param {Object[]} requirements - The existing return requirements in the current session
* @param {module:PurposeModel[]} purposes - All purposes that match those selected across the return requirements
* @param {string} journey - Whether the setup journey is 'no-returns-required' or 'returns-required'
*
* @returns {Object} returns requirement data needed by the view template
*/
function go (requirements, purposes, journey) {
return {
returnsRequired: journey === 'returns-required',
requirements: _requirements(requirements, purposes)
}
}

function _abstractionPeriod (abstractionPeriod) {
const { 'start-abstraction-period-day': startDay, 'start-abstraction-period-month': startMonth, 'end-abstraction-period-day': endDay, 'end-abstraction-period-month': endMonth } = abstractionPeriod
const startDate = formatAbstractionDate(startDay, startMonth)
const endDate = formatAbstractionDate(endDay, endMonth)

return `From ${startDate} to ${endDate}`
}

function _requirements (requirements, purposes) {
const completedRequirements = []

for (const [index, requirement] of requirements.entries()) {
const { agreementsExceptions } = requirement
// NOTE: We determine a requirement is complete because agreement exceptions is populated and it is the last step in
// the journey
if (agreementsExceptions) {
completedRequirements.push(_mapRequirement(requirement, index, purposes))
}
}

return completedRequirements
}

function _mapPurposes (requirementPurposes, purposes) {
return requirementPurposes.map((requirementPurpose) => {
const matchedPurpose = purposes.find((purpose) => {
return purpose.id === requirementPurpose
})

return matchedPurpose.description
})
}

function _mapRequirement (requirement, index, purposes) {
return {
abstractionPeriod: _abstractionPeriod(requirement.abstractionPeriod),
frequencyCollected: requirement.frequencyCollected,
frequencyReported: requirement.frequencyReported,
index,
purposes: _mapPurposes(requirement.purposes, purposes),
siteDescription: requirement.siteDescription
}
}

module.exports = {
go
}
4 changes: 4 additions & 0 deletions app/services/return-requirements/check.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

const CheckPresenter = require('../../presenters/return-requirements/check.presenter.js')
const ReturnRequirementsService = require('./check/returns-requirements.service.js')
const SessionModel = require('../../models/session.model.js')

/**
Expand All @@ -21,13 +22,16 @@ async function go (sessionId, yar) {

await _markCheckPageVisited(session)

const returnRequirements = await ReturnRequirementsService.go(session)

const formattedData = CheckPresenter.go(session)

const notification = yar.flash('notification')[0]

return {
activeNavBar: 'search',
notification,
...returnRequirements,
...formattedData
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
'use strict'

/**
* Orchestrates fetching and presenting the return requirements for the check page
* @module ReturnRequirementsService
*/

const PurposeModel = require('../../../models/purpose.model.js')
const ReturnRequirementsPresenter = require('../../../presenters/return-requirements/check/returns-requirements.presenter.js')

/**
* Orchestrates fetching and presenting the return requirements for `/return-requirements/{sessionId}/check` page
*
* @param {module:SessionModel} session - The session for the return requirement journey
*
* @returns {Promise<Object>} page data needed by the view template
*/
async function go (session) {
const { requirements, journey } = session.data

const purposeIds = _purposeIds(requirements)
const purposes = await _fetchPurposes(purposeIds)

return ReturnRequirementsPresenter.go(requirements, purposes, journey)
}

async function _fetchPurposes (purposeIds) {
return PurposeModel.query()
.select([
'purposes.id',
'purposes.description'
])
.findByIds(purposeIds)
}

function _purposeIds (requirements) {
const requirementPurposes = requirements.flatMap((requirement) => {
if (requirement.purposes) {
return requirement.purposes
}

return []
})

return [...new Set(requirementPurposes)]
}

module.exports = {
go
}
48 changes: 28 additions & 20 deletions app/views/return-requirements/check.njk
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
{% from "govuk/components/notification-banner/macro.njk" import govukNotificationBanner %}
{% from "govuk/components/summary-list/macro.njk" import govukSummaryList %}


{% macro newLine(array) %}
{% for item in array %}
<p> {{ item }}</p>
{% endfor %}
{% endmacro %}

{% block content %}
{% if notification %}
{{ govukNotificationBanner({
Expand Down Expand Up @@ -66,7 +73,7 @@
</div>

<div class="govuk-!-margin-bottom-9">
<h2 class="govuk-heading-l govuk-!-margin-bottom-4" >Notes</h2>
<h2 class="govuk-heading-l govuk-!-margin-bottom-4">Notes</h2>
<hr class="govuk-section-break govuk-!-margin-bottom-2 govuk-section-break--visible">
{{ govukSummaryList({
classes: 'govuk-!-margin-bottom-2',
Expand Down Expand Up @@ -98,10 +105,10 @@
<hr class="govuk-section-break govuk-!-margin-bottom-2 govuk-section-break--visible">
</div>

{% if journey == 'returns-required' %}
{% if returnsRequired %}
<div class="govuk-!-margin-bottom-9">
<h2 class="govuk-heading-l govuk-!-margin-bottom-4" >Requirements for returns</h2>
<form method= "post" action= "/system/return-requirements/{{sessionId}}/add">
<h2 class="govuk-heading-l govuk-!-margin-bottom-4">Requirements for returns</h2>
<form method="post" action="/system/return-requirements/{{ sessionId }}/add">
{{ govukButton({
text: "Add another requirement",
classes: "govuk-button--secondary",
Expand All @@ -123,7 +130,7 @@
text: "Purpose"
},
value: {
html: "requirement.purposes"
html: newLine(requirement.purposes)
},
actions: {
items: [
Expand All @@ -137,7 +144,7 @@
},
{
key: {
text: "Point"
text: "Points"
},
value: {
html: "requirement.points"
Expand Down Expand Up @@ -253,29 +260,27 @@
}
]
}
},
{
key: {
html: govukButton({
text: "Remove requirement",
classes: "govuk-button--secondary",
preventDoubleClick: true,
href: "/system/return-requirements/" + sessionId + "/remove/" + requirement.index
}) if requirements.length >= 2
}
}
]
}) }}
{% if requirements.length >= 2 %}
{{ govukButton({
text: "Remove requirement",
classes: "govuk-button--warning",
preventDoubleClick: true,
href: "/system/return-requirements/" + sessionId + "/remove/" + requirement.index
}) }}
{% endif %}
</div>
{% endfor %}
</div>
{% endif %}

<form method="post">
<div class="govuk-body">
{% if journey == 'no-returns-required' %}
<h3 class="govuk-heading-m">Returns are not required for this licence</h3>
<hr class="govuk-!-margin-bottom-5 govuk-section-break--s govuk-section-break--visible">
{% endif %}
{% if journey == 'returns-required' %}
{% if returnsRequired %}
{{ govukSummaryList({
classes: 'govuk-!-margin-bottom-2',
rows: [
Expand Down Expand Up @@ -309,12 +314,15 @@
}
]
}) }}
{% else %}
<h3 class="govuk-heading-m">Returns are not required for this licence</h3>
<hr class="govuk-!-margin-bottom-5 govuk-section-break--s govuk-section-break--visible">
{% endif %}

<hr class="govuk-section-break govuk-section-break--xl govuk-section-break--visible">

{{ govukButton({
html: '<span data-test="meta-data-approve">' + "Approve returns requirements" + "</span>",
text: "Approve returns requirements",
classes: "govuk-!-margin-right-6",
preventDoubleClick: true
}) }}
Expand Down
Loading

0 comments on commit 5f97578

Please sign in to comment.