Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
8614054
Add a page to show we creating the report to the Reports section
Anna-Sutton Jun 23, 2026
cd64eb1
Update creating report page
Anna-Sutton Jun 23, 2026
1835671
Create alt-index.html for Reports section
Anna-Sutton Jun 23, 2026
d21897a
Update report download message
Anna-Sutton Jun 23, 2026
bc27116
Replaced inset html with nunjucks
Anna-Sutton Jun 23, 2026
62da774
Amended inset text
Anna-Sutton Jun 23, 2026
b87e58a
Updated inset text
Anna-Sutton Jun 23, 2026
8ac9397
Change redirect URL in creating-report.html
Anna-Sutton Jun 24, 2026
84e7d7b
Changed url for redirect
Anna-Sutton Jun 24, 2026
c15cac8
Remove specific wait time from report message
Anna-Sutton Jul 2, 2026
7ccffe7
Modify report creation message and remove loader
Anna-Sutton Jul 2, 2026
ce0536a
Update report creation message for user guidance
Anna-Sutton Jul 2, 2026
99d863d
Split report creation message into two paragraphs
Anna-Sutton Jul 2, 2026
3cdca38
Update report creation page title and content
Anna-Sutton Jul 2, 2026
07dea42
Add endblock tag to creating-report.html
Anna-Sutton Jul 2, 2026
159727c
Remove bottom margin from Reports heading
Anna-Sutton Jul 5, 2026
c1a83c2
Add margin bottom to Reports heading
Anna-Sutton Jul 5, 2026
1988473
Updates to reporting data selection screens
caitlinroach-nhs Jul 6, 2026
e510181
Updates to how data is shown and linking up new pages
caitlinroach-nhs Jul 6, 2026
3621b88
Fix typo in site name
caitlinroach-nhs Jul 6, 2026
2a14635
Updates to sites and vaccines on check and confirm
caitlinroach-nhs Jul 6, 2026
b22f363
Update error message for report data selection
Anna-Sutton Jul 17, 2026
d910312
Update fieldset legend and vaccination text
Anna-Sutton Jul 17, 2026
033334f
Update vaccine selection page title and legend
Anna-Sutton Jul 17, 2026
0bacec1
Update legend text in choose-data.html
Anna-Sutton Jul 17, 2026
35e6e59
Update page name for pharmacy selection
Anna-Sutton Jul 17, 2026
0e55bbd
Update vaccine selection text for clarity
Anna-Sutton Jul 17, 2026
15f3c03
Update page name for pharmacy selection
Anna-Sutton Jul 17, 2026
96043e8
Update page name and fieldset legend text
Anna-Sutton Jul 17, 2026
d804500
Updates to reporting timeframes
caitlinroach-nhs Jul 20, 2026
425b9b8
Update vaccinationDataOptions to replace vaccination site with vaccin…
Anna-Sutton Jul 20, 2026
26c4fd1
Add 'Contact details' to patient data options
Anna-Sutton Jul 20, 2026
e526236
Update custom date range text to include duration
Anna-Sutton Jul 20, 2026
e90e7ba
Revise hint text for vaccination date clarification
Anna-Sutton Jul 20, 2026
f3171d5
Fix punctuation in hint text for vaccination report
Anna-Sutton Jul 20, 2026
7e0e4e8
Update hint text for vaccination report timeframe
Anna-Sutton Jul 20, 2026
4860cf7
Shorten hint text for report timeframe
Anna-Sutton Jul 20, 2026
585ce91
Update report processing message for clarity
Anna-Sutton Jul 20, 2026
536ed1d
Update hint text for report date selection
Anna-Sutton Jul 20, 2026
95d806b
Update hint text for report date selection
Anna-Sutton Jul 21, 2026
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
2 changes: 1 addition & 1 deletion app/data/organisations.js
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,7 @@ module.exports = [
},
{
id: "RW382",
name: "Ear nose and throad RMCH"
name: "Ear nose and throat RMCH"
},
{
id: "RW391",
Expand Down
4 changes: 2 additions & 2 deletions app/data/session-data-defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ module.exports = {
vaccinationsRecorded: vaccinationsRecorded,

// These are the options for extracting CSV reports
patientDataOptions: ["Name", "NHS number", "Gender", "Date of birth", "Address", "Postcode", "ODS code of their GP"],
patientDataOptions: ["Name", "NHS number", "Gender", "Date of birth", "Address", "Postcode", "Contact details", "GP (ODS code only)"],
staffDataOptions: ["Recorder", "Vaccinator"],
locationDataOptions: ["Site name", "Site ODS code", "Location type"],
consentAndEligibilityDataOptions: ["Consent", "Eligibility", "Estimated due date"],
vaccinationDataOptions: ["Vaccine type", "Product", "Batch", "Batch expiry date", "Dose sequence", "Dose amount", "Vaccination site", "Vaccination date", "Comments"],
vaccinationDataOptions: ["Vaccine type", "Product", "Batch", "Batch expiry date", "Dose sequence", "Dose amount", "Vaccination route", "Vaccination date", "Comments"],
paymentDataOptions: [
{text: "Deposit ID", hint: "Set before we send the claim to NHSBSA"},
{text: "Claim ID", hint: "Set when NHSBSA have received the claim"}
Expand Down
14 changes: 14 additions & 0 deletions app/locals.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ module.exports = function(req, res, next) {
'December'
]

const now = new Date()
const lastMonthDate = new Date(now.getFullYear(), now.getMonth() - 1, 1)
res.locals.lastCalendarMonth = `${monthNames[lastMonthDate.getMonth()]} ${lastMonthDate.getFullYear()}`

const dayOfWeek = now.getDay() // 0 = Sunday, 1 = Monday
const daysSinceMonday = (dayOfWeek === 0 ? 7 : dayOfWeek) - 1
const lastMonday = new Date(now.getFullYear(), now.getMonth(), now.getDate() - daysSinceMonday - 7)
const lastSunday = new Date(lastMonday.getFullYear(), lastMonday.getMonth(), lastMonday.getDate() + 6)
const formatWeekDay = (d) => {
const suffix = d.getDate() === lastSunday.getDate() && d.getMonth() === lastSunday.getMonth() ? ` ${monthNames[d.getMonth()]} ${d.getFullYear()}` : (d.getMonth() !== lastSunday.getMonth() ? ` ${monthNames[d.getMonth()]}` : '')
return `${d.getDate()}${suffix}`
}
res.locals.lastCalendarWeek = `${formatWeekDay(lastMonday)} to ${lastSunday.getDate()} ${monthNames[lastSunday.getMonth()]} ${lastSunday.getFullYear()}`

const dashboardUpdatedAt = new Date(Date.now() - (30 * 60 * 1000))
const hours24 = dashboardUpdatedAt.getHours()
const hours12 = (hours24 % 12) || 12
Expand Down
67 changes: 53 additions & 14 deletions app/routes/reports.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,15 @@ module.exports = (router) => {
})

router.post('/reports/choose-vaccines-answer', (req, res) => {
const data = req.session.data
const currentOrganisation = res.locals.currentOrganisation
const sites = currentOrganisation.sites || []

if (res.locals.currentOrganisation.type === "Pharmacy HQ") {
if (currentOrganisation.type === "Pharmacy HQ") {
res.redirect('/reports/choose-pharmacies')
} else if (sites.length === 1) {
data.siteIdsToReport = [sites[0].id]
res.redirect('/reports/choose-data')
} else {
res.redirect('/reports/choose-site')
}
Expand Down Expand Up @@ -106,9 +112,17 @@ module.exports = (router) => {
})

router.get('/reports/choose-site', (req, res) => {
const data = req.session.data
const currentOrganisation = res.locals.currentOrganisation

const sites = currentOrganisation.sites || []

if (sites.length === 1) {
data.siteIdsToReport = [sites[0].id]
res.redirect('/reports/choose-data')
return
}

res.render('reports/choose-site', {
sites
})
Expand Down Expand Up @@ -170,7 +184,7 @@ module.exports = (router) => {
} else {

const error = {
text: "Select data for report",
text: "Select the data you want to include",
href: "#data-1"
}

Expand All @@ -186,6 +200,7 @@ module.exports = (router) => {
const data = req.session.data
const currentOrganisation = res.locals.currentOrganisation
const siteIds = data.siteIdsToReport || []
const selectedVaccines = data.vaccinesToReport || []
const today = new Date()
const days = 86400000 // number of milliseconds in a day

Expand All @@ -203,6 +218,22 @@ module.exports = (router) => {
const dateOption = data.date

let from, to
let vaccinesToReportDisplay = selectedVaccines.filter((vaccineName) => vaccineName !== 'all')

if (selectedVaccines.includes('all')) {
const organisationVaccines = currentOrganisation.vaccines || []
let enabledVaccines = organisationVaccines.filter((vaccine) => vaccine.status === "enabled")

// Temporary: show all vaccines if none have batches added
if (enabledVaccines.length === 0) {
enabledVaccines = data.vaccines
}

vaccinesToReportDisplay = enabledVaccines.map((vaccine) => vaccine.name)
}

vaccinesToReportDisplay = [...new Set(vaccinesToReportDisplay)]
.sort((a, b) => a.localeCompare(b))

switch (dateOption) {
case 'custom_date_range':
Expand All @@ -217,18 +248,25 @@ module.exports = (router) => {
from = new Date(today.getTime() - (1 * days)).toISOString().substring(0,10)
to = new Date(today.getTime() - (1 * days)).toISOString().substring(0,10)
break
case 'Last7days':
from = new Date(today.getTime() - (7 * days)).toISOString().substring(0,10)
to = today.toISOString().substring(0,10)
break
case 'Last14days':
from = new Date(today.getTime() - (14 * days)).toISOString().substring(0,10)
to = today.toISOString().substring(0,10)
case 'LastCalendarWeek': {
const dayOfWeek = today.getDay() // 0 = Sunday, 1 = Monday, ...
const daysSinceMonday = (dayOfWeek === 0 ? 7 : dayOfWeek) - 1
const lastMonday = new Date(today.getFullYear(), today.getMonth(), today.getDate() - daysSinceMonday - 7)
const lastSunday = new Date(lastMonday.getTime() + (6 * days))

from = lastMonday.toISOString().substring(0,10)
to = lastSunday.toISOString().substring(0,10)
break
case 'Last31days':
from = new Date(today.getTime() - (31 * days)).toISOString().substring(0,10)
to = today.toISOString().substring(0,10)
}
case 'LastCalendarMonth': {
const firstDayOfThisMonth = new Date(today.getFullYear(), today.getMonth(), 1)
const firstDayOfLastMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1)
const lastDayOfLastMonth = new Date(firstDayOfThisMonth.getTime() - days)

from = firstDayOfLastMonth.toISOString().substring(0,10)
to = lastDayOfLastMonth.toISOString().substring(0,10)
break
}
}


Expand All @@ -237,7 +275,8 @@ module.exports = (router) => {
sites,
pharmacies,
from,
to
to,
vaccinesToReportDisplay
})

})
Expand All @@ -252,7 +291,7 @@ module.exports = (router) => {
data.vaccinesToReport = null


res.redirect('/reports/download')
res.redirect('/reports/creating-report')
})

}
37 changes: 37 additions & 0 deletions app/views/reports/alt-index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{% extends 'layout.html' %}

{% set pageName = "Reports" %}

{% set currentSection = "reports" %}

{% block content %}

<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-two-thirds">

{% include "includes/notification.html" %}

</div>
</div>

<div class="nhsuk-grid-row">
<div class="nhsuk-grid-column-full">

<h1 class="nhsuk-heading-l nhsuk-u-margin-bottom-2">Reports</h1>
<p>Create and download reports.</p>

{% from "inset-text/macro.njk" import insetText %}

{% set insetTextHtml %}
<p>You need to wait before you can start creating a report. This is because another report is already in progress for your organisation.</p>
{% endset %}

{{ insetText({
html: insetTextHtml
}) }}


</div>
</div>

{% endblock %}
91 changes: 54 additions & 37 deletions app/views/reports/check.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,37 +19,55 @@

<h1 class="nhsuk-heading-l">{{ pageName }}</h1>

{% set dataFields = [] %}

{% for field in data.patientDataToReport %}
{% set dataFields = (dataFields.push(field), dataFields) %}
{% endfor %}
{% for field in data.staffDataToReport %}
{% set dataFields = (dataFields.push(field), dataFields) %}
{% endfor %}
{% for field in data.siteDataToReport %}
{% set dataFields = (dataFields.push(field), dataFields) %}
{% endfor %}
{% for field in data.consentAndEligibilityDataToReport %}
{% set dataFields = (dataFields.push(field), dataFields) %}
{% endfor %}
{% for field in data.vaccinationDataToReport %}
{% set dataFields = (dataFields.push(field), dataFields) %}
{% endfor %}
{% for field in data.paymentDataToReport %}
{% set dataFields = (dataFields.push(field), dataFields) %}
{% endfor %}
{% set patientData = data.patientDataToReport or [] %}
{% set staffData = data.staffDataToReport or [] %}
{% set siteData = data.siteDataToReport or [] %}
{% set consentAndEligibilityData = data.consentAndEligibilityDataToReport or [] %}
{% set vaccinationData = data.vaccinationDataToReport or [] %}
{% set paymentData = data.paymentDataToReport or [] %}

{% set dataValue %}
{{ dataFields | join(", ") }}
{% if (patientData | length) > 0 %}
<h4 class="nhsuk-heading-xs nhsuk-u-margin-bottom-1">Patient data</h4>
<p class="nhsuk-u-margin-bottom-3">{{ patientData | join(", ") }}</p>
{% endif %}

{% if (staffData | length) > 0 %}
<h4 class="nhsuk-heading-xs nhsuk-u-margin-bottom-1">Staff data</h4>
<p class="nhsuk-u-margin-bottom-3">{{ staffData | join(", ") }}</p>
{% endif %}

{% if (siteData | length) > 0 %}
<h4 class="nhsuk-heading-xs nhsuk-u-margin-bottom-1">Site data</h4>
<p class="nhsuk-u-margin-bottom-3">{{ siteData | join(", ") }}</p>
{% endif %}

{% if (consentAndEligibilityData | length) > 0 %}
<h4 class="nhsuk-heading-xs nhsuk-u-margin-bottom-1">Consent and eligibility data</h4>
<p class="nhsuk-u-margin-bottom-3">{{ consentAndEligibilityData | join(", ") }}</p>
{% endif %}

{% if (vaccinationData | length) > 0 %}
<h4 class="nhsuk-heading-xs nhsuk-u-margin-bottom-1">Vaccination data</h4>
<p class="nhsuk-u-margin-bottom-3">{{ vaccinationData | join(", ") }}</p>
{% endif %}

{% if (paymentData | length) > 0 %}
<h4 class="nhsuk-heading-xs nhsuk-u-margin-bottom-1">Payment information</h4>
<p class="nhsuk-u-margin-bottom-0">{{ paymentData | join(", ") }}</p>
{% endif %}
{% endset %}

{% set sitesHtml %}
<ul class="nhsuk-list">
{% for site in sites | sort(false, false, "name") %}
<li>{{ site.name }} ({{ site.id }})</li>
{% endfor %}
</ul>
{% if (sites | length) > 2 %}
{{ sites | length }} sites selected
{% else %}
<ul class="nhsuk-list">
{% for site in sites | sort(false, false, "name") %}
<li>{{ site.name }} ({{ site.id }})</li>
{% endfor %}
</ul>
{% endif %}
{% endset %}

{% set pharmaciesHtml %}
Expand All @@ -60,14 +78,13 @@ <h1 class="nhsuk-heading-l">{{ pageName }}</h1>
</ul>
{% endset %}

{% set vaccinesToReportText = "" %}
{% if data.vaccinesToReport %}
{% set vaccinesToReportDisplay = [] %}
{% for vaccine in (data.vaccinesToReport | sort(false, false, "name")) %}
{% set vaccinesToReportDisplay = (vaccinesToReportDisplay.push(vaccine ), vaccinesToReportDisplay) %}
{% endfor %}
{% set vaccinesToReportText = vaccinesToReportDisplay | join(", ") %}
{% endif %}
{% set vaccinesToReportHtml %}
<ul class="nhsuk-list">
{% for vaccine in vaccinesToReportDisplay or [] %}
<li>{{ vaccine | capitaliseFirstLetter }}</li>
{% endfor %}
</ul>
{% endset %}

{{ summaryList({
rows: [
Expand Down Expand Up @@ -110,10 +127,10 @@ <h1 class="nhsuk-heading-l">{{ pageName }}</h1>
},
{
key: {
text: ("Vaccines" if (data.vaccinesToReport | length) > 1 else "Vaccine")
text: ("Vaccines" if (vaccinesToReportDisplay | length) > 1 else "Vaccine")
},
value: {
text: vaccinesToReportText if data.vaccines
html: vaccinesToReportHtml
},
actions: {
items: [
Expand Down Expand Up @@ -181,7 +198,7 @@ <h1 class="nhsuk-heading-l">{{ pageName }}</h1>
text: "Data"
},
value: {
text: dataValue
html: dataValue
},
actions: {
items: [
Expand Down
16 changes: 12 additions & 4 deletions app/views/reports/choose-data.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
{% extends 'layout.html' %}

{% set pageName = "Data details" %}
{% set pageName = "Which details do you want to include?" %}

{% set currentSection = "reports" %}


{% block beforeContent %}
{% if currentOrganisation.type == "Pharmacy HQ" %}
{% set backLinkHref = "/reports/choose-pharmacies" %}
{% elif (currentOrganisation.sites | length) == 1 %}
{% set backLinkHref = "/reports/choose-vaccines" %}
{% else %}
{% set backLinkHref = "/reports/choose-site" %}
{% endif %}

{{ backLink({
href: "/reports/choose-site",
href: backLinkHref,
text: "Back"
}) }}
{% endblock %}
Expand Down Expand Up @@ -178,7 +186,7 @@
} if error,
fieldset: {
legend: {
text: "Which details would you like to include?",
text: "Which details do you want to include?",
isPageHeading: true,
classes: "nhsuk-fieldset__legend--l"
}
Expand Down Expand Up @@ -215,7 +223,7 @@
},
{
value: "Vaccination",
text: "Vaccination",
text: "Vaccinations",
conditional: {
html: vaccinationHtml
}
Expand Down
Loading