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

Feature returns required purposes #1064

Merged
merged 37 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
53bed41
Check your requirements - purposes
jonathangoulding May 31, 2024
0f571f1
test: update check service test output
jonathangoulding May 31, 2024
6a40821
chore: nit
jonathangoulding May 31, 2024
8597ed4
fix: syntax
jonathangoulding Jun 3, 2024
845e102
fix: unknown span
jonathangoulding Jun 3, 2024
df1172d
Merge branch 'main' into feature-returns-required-purposes
jonathangoulding Jun 3, 2024
867ae43
feat: move Remove requirement button into card
jonathangoulding Jun 3, 2024
f33c637
test: return requirements
jonathangoulding Jun 3, 2024
305f761
Merge branch 'main' into feature-returns-required-purposes
jonathangoulding Jun 3, 2024
ec9e956
fix: alpha
jonathangoulding Jun 3, 2024
d08e418
fix: alpha case in file path
jonathangoulding Jun 3, 2024
387c05c
Merge branch 'main' into feature-returns-required-purposes
jonathangoulding Jun 4, 2024
7b88424
fix: use session, remove necessary query
jonathangoulding Jun 4, 2024
34e31c4
chore: nit alpha
jonathangoulding Jun 4, 2024
a3d2389
chore: nit alpha purpose funcs
jonathangoulding Jun 4, 2024
5b62b35
chore: fix njk format
jonathangoulding Jun 4, 2024
7e34783
chore: fix njk format
jonathangoulding Jun 4, 2024
e175afe
chore: fix njk format
jonathangoulding Jun 4, 2024
177110c
chore: fix njk format
jonathangoulding Jun 4, 2024
803c14b
chore: fix comment
jonathangoulding Jun 4, 2024
fbc6ba4
fix: conditional render
jonathangoulding Jun 4, 2024
62fff11
Update returns-requirements.presenter.js
jonathangoulding Jun 4, 2024
3402ecf
Update returns-requirements.presenter.js
jonathangoulding Jun 4, 2024
e22f6e7
Update returns-requirements.service.js
jonathangoulding Jun 4, 2024
e98c03c
Update returns-requirements.service.js
jonathangoulding Jun 4, 2024
db156b1
Update returns-requirements.presenter.test.js
jonathangoulding Jun 4, 2024
149c4e9
Update returns-requirements.presenter.test.js
jonathangoulding Jun 4, 2024
a9e9429
fix: njk html to text
jonathangoulding Jun 4, 2024
8fb2c2b
fix: use of purposes over purposeIds
jonathangoulding Jun 4, 2024
874bd6f
chore: updated jsdocs
jonathangoulding Jun 4, 2024
aa5d677
test: update purpose test structure
jonathangoulding Jun 4, 2024
ae443c7
Update app/presenters/return-requirements/check/returns-requirements.…
jonathangoulding Jun 4, 2024
0a901b8
Update app/services/return-requirements/check/returns-requirements.se…
jonathangoulding Jun 4, 2024
aa08920
Update app/presenters/return-requirements/check/returns-requirements.…
jonathangoulding Jun 4, 2024
b8a43e0
Update app/services/return-requirements/check/returns-requirements.se…
jonathangoulding Jun 4, 2024
678fa8c
Update app/presenters/return-requirements/check/returns-requirements.…
jonathangoulding Jun 4, 2024
5223f13
fix: spans for test
jonathangoulding Jun 4, 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
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) {
jonathangoulding marked this conversation as resolved.
Show resolved Hide resolved
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
jonathangoulding marked this conversation as resolved.
Show resolved Hide resolved
Cruikshanks marked this conversation as resolved.
Show resolved Hide resolved
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>",
jonathangoulding marked this conversation as resolved.
Show resolved Hide resolved
text: "Approve returns requirements",
jonathangoulding marked this conversation as resolved.
Show resolved Hide resolved
classes: "govuk-!-margin-right-6",
preventDoubleClick: true
}) }}
Expand Down
Loading
Loading