Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2a8c48a
Add empty state for no pharmacies
caitlinroach-nhs Jun 16, 2026
74c95ef
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Jun 17, 2026
25aba43
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Jun 17, 2026
bc7a20c
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Jun 17, 2026
7c878c3
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Jun 18, 2026
e8f6a32
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Jul 2, 2026
849369f
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Jul 6, 2026
fe671c1
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Jul 13, 2026
7357ef2
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Jul 20, 2026
0059675
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Jul 21, 2026
2b44e2d
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Jul 22, 2026
4b791da
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Jul 30, 2026
93723fd
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Aug 4, 2026
228770c
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Aug 12, 2026
13f58c4
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Aug 20, 2026
74c0c30
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Aug 20, 2026
5056739
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Aug 20, 2026
0765baf
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Aug 24, 2026
4251b80
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Aug 27, 2026
56e4a82
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Sep 3, 2026
b86562b
Merge branch 'main' of https://github.com/NHSDigital/record-a-vaccina…
caitlinroach-nhs Sep 7, 2026
7d21a40
vaccs records added
caitlinroach-nhs Sep 9, 2026
75b9067
Button text change and details component
caitlinroach-nhs Sep 9, 2026
fc7f567
update
caitlinroach-nhs Sep 9, 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
264 changes: 264 additions & 0 deletions app/data/vaccinations-recorded.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,270 @@ module.exports = [
injectionSite: "Left arm",
notes: "",
editable: true
},

// Additional records below ensure every batch at Jane Smith's organisation
// (Central Manchester Trust, RW3) has at least 2 vaccination records

{
id: "700001",
date: { day: "24", month: "11", year: "2025" },
vaccine: "COVID-19",
vaccineProduct: "Comirnaty 3 LP.8.1",
patient: {
name: "Priya Patel",
nhsNumber: "9111222333"
},
batchNumber: "8535345", // Batch AB2514
batchExpiryDate: "2028-03-06",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW3NM", // North Manchester General Hospital
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Right arm",
notes: "",
editable: true
},
{
id: "700002",
date: { day: "24", month: "11", year: "2025" },
vaccine: "flu",
vaccineProduct: "Adjuvanted Trivalent Influenza Vaccine (aTIV)",
patient: {
name: "Michael Osei",
nhsNumber: "9111222334"
},
batchNumber: "634643636", // Batch 914-151
batchExpiryDate: "2028-02-19",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW3NM", // North Manchester General Hospital
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Left arm",
notes: "",
editable: true
},
{
id: "700003",
date: { day: "23", month: "11", year: "2025" },
vaccine: "flu",
vaccineProduct: "Adjuvanted Trivalent Influenza Vaccine (aTIV)",
patient: {
name: "Sarah Kowalski",
nhsNumber: "9111222335"
},
batchNumber: "634643636", // Batch 914-151
batchExpiryDate: "2028-02-19",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW3NM", // North Manchester General Hospital
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Right arm",
notes: "",
editable: true
},
{
id: "700004",
date: { day: "22", month: "11", year: "2025" },
vaccine: "COVID-19",
vaccineProduct: "Comirnaty 3 LP.8.1",
patient: {
name: "Liam O'Connor",
nhsNumber: "9111222336"
},
batchNumber: "343643636", // Batch NT2524
batchExpiryDate: "2028-03-06",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW3HT", // Heaton Moor Health Centre
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Left arm",
notes: "",
editable: true
},
{
id: "700005",
date: { day: "21", month: "11", year: "2025" },
vaccine: "COVID-19",
vaccineProduct: "Comirnaty 3 LP.8.1",
patient: {
name: "Grace Nakamura",
nhsNumber: "9111222337"
},
batchNumber: "343643636", // Batch NT2524
batchExpiryDate: "2028-03-06",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW3HT", // Heaton Moor Health Centre
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Right arm",
notes: "",
editable: true
},
{
id: "700006",
date: { day: "20", month: "11", year: "2025" },
vaccine: "pertussis",
vaccineProduct: "Adacel vaccine suspension",
patient: {
name: "Daniel Wojcik",
nhsNumber: "9111222338"
},
batchNumber: "46464363", // Batch M8-25-14
batchExpiryDate: "2027-11-19",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW3HT", // Heaton Moor Health Centre
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Left arm",
notes: "",
editable: true
},
{
id: "700007",
date: { day: "19", month: "11", year: "2025" },
vaccine: "pertussis",
vaccineProduct: "Adacel vaccine suspension",
patient: {
name: "Freya Thomsen",
nhsNumber: "9111222339"
},
batchNumber: "46464363", // Batch M8-25-14
batchExpiryDate: "2027-11-19",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW3HT", // Heaton Moor Health Centre
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Right arm",
notes: "",
editable: true
},
{
id: "700008",
date: { day: "18", month: "11", year: "2025" },
vaccine: "flu",
vaccineProduct: "Adjuvanted Trivalent Influenza Vaccine (aTIV)",
patient: {
name: "Tomasz Nowak",
nhsNumber: "9111222340"
},
batchNumber: "25523523", // Batch 194-151
batchExpiryDate: "2027-12-04",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW3HT", // Heaton Moor Health Centre
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Left arm",
notes: "",
editable: true
},
{
id: "700009",
date: { day: "17", month: "11", year: "2025" },
vaccine: "flu",
vaccineProduct: "Adjuvanted Trivalent Influenza Vaccine (aTIV)",
patient: {
name: "Amara Okafor",
nhsNumber: "9111222341"
},
batchNumber: "25523523", // Batch 194-151
batchExpiryDate: "2027-12-04",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW3HT", // Heaton Moor Health Centre
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Right arm",
notes: "",
editable: true
},
{
id: "700010",
date: { day: "16", month: "11", year: "2025" },
vaccine: "RSV",
vaccineProduct: "Abrysvo",
patient: {
name: "Harold Fitzgerald",
nhsNumber: "9111222342"
},
batchNumber: "46436346", // Batch ANEUEC-91
batchExpiryDate: "2027-11-23",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW3HT", // Heaton Moor Health Centre
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Left arm",
notes: "",
editable: true
},
{
id: "700011",
date: { day: "15", month: "11", year: "2025" },
vaccine: "RSV",
vaccineProduct: "Abrysvo",
patient: {
name: "Beatrice Lindqvist",
nhsNumber: "9111222343"
},
batchNumber: "46436346", // Batch ANEUEC-91
batchExpiryDate: "2027-11-23",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW3HT", // Heaton Moor Health Centre
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Right arm",
notes: "",
editable: true
},
{
id: "700012",
date: { day: "14", month: "11", year: "2025" },
vaccine: "COVID-19",
vaccineProduct: "Comirnaty 3 LP.8.1",
patient: {
name: "Ellis Marsh",
nhsNumber: "9111222344"
},
batchNumber: "325252145", // Batch PN8471
batchExpiryDate: "2024-02-06",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW07E", // Central Manchester Medical Centre
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Left arm",
notes: "",
editable: true
},
{
id: "700013",
date: { day: "13", month: "11", year: "2025" },
vaccine: "COVID-19",
vaccineProduct: "Comirnaty 3 LP.8.1",
patient: {
name: "Nadia Hussain",
nhsNumber: "9111222345"
},
batchNumber: "325252145", // Batch PN8471
batchExpiryDate: "2024-02-06",
organisationId: "RW3", // Central Manchester Trust
siteId: "RW07E", // Central Manchester Medical Centre
vaccinatorId: "2387441662601", // Jane Smith
eligibility: "Based on age",
consent: "patient",
injectionSite: "Right arm",
notes: "",
editable: true
}
]

50 changes: 49 additions & 1 deletion app/routes/vaccines.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,8 @@ module.exports = (router) => {
const addedType = req.query.addedType
const deactivated = req.query.deactivated === 'true'
const reactivated = req.query.reactivated === 'true'
const updated = req.query.updated === 'true'
const updatedRecordsCount = parseInt(req.query.updatedRecordsCount) || 0
const updatedBatchNumber = req.query.batchNumber

const vaccine = data.vaccineStock.find((vaccine) => vaccine.id === req.params.id)
Expand Down Expand Up @@ -370,6 +372,8 @@ module.exports = (router) => {
addedType,
deactivated,
reactivated,
updated,
updatedRecordsCount,
updatedBatchNumber
})
})
Expand Down Expand Up @@ -450,6 +454,31 @@ module.exports = (router) => {
})
})

// Checking how many records will be affected by an update to a batch
router.post('/vaccines/:vaccineId/:batchNumber/update-check', (req, res) => {

const data = req.session.data
const vaccine = data.vaccineStock.find((vaccine) => vaccine.id === req.params.vaccineId)
if (!vaccine) { res.redirect('/vaccines'); return }
const batch = vaccine.batches.find((batch) => batch.batchNumber === req.params.batchNumber)
if (!batch) { res.redirect(`/vaccines/${vaccine.id}`); return }

const affectedRecordsCount = (data.vaccinationsRecorded || []).filter((record) => {
return record.organisationId === vaccine.organisationId &&
record.siteId === vaccine.siteId &&
record.vaccine === vaccine.vaccine &&
record.vaccineProduct === vaccine.vaccineProduct &&
record.batchNumber === batch.id
}).length

res.render('vaccines/update-batch-check', {
data,
vaccine,
batch,
affectedRecordsCount
})
})

// Updating a batch
router.post('/vaccines/:vaccineId/:batchNumber/update', (req, res) => {

Expand All @@ -461,10 +490,29 @@ module.exports = (router) => {

const expiryDate = new Date(data.batchExpiryDate.year, (parseInt(data.batchExpiryDate.month) - 1), data.batchExpiryDate.day, 12).toISOString().substring(0,10)

let updatedRecordsCount = 0

if (data.updateExistingRecords === 'yes') {
for (const record of (data.vaccinationsRecorded || [])) {
if (record.organisationId === vaccine.organisationId &&
record.siteId === vaccine.siteId &&
record.vaccine === vaccine.vaccine &&
record.vaccineProduct === vaccine.vaccineProduct &&
record.batchNumber === batch.id) {
record.batchExpiryDate = expiryDate
updatedRecordsCount++
}
}
}

const updatedBatchNumber = data.batchNumber

batch.batchNumber = data.batchNumber;
batch.expiryDate = expiryDate;

res.redirect('/vaccines/' + vaccine.id)
req.session.data.updateExistingRecords = ''

res.redirect(`/vaccines/${vaccine.id}?updated=true&batchNumber=${encodeURIComponent(updatedBatchNumber)}&updatedRecordsCount=${updatedRecordsCount}`)
})

// View page to deactivate a batch
Expand Down
4 changes: 1 addition & 3 deletions app/views/vaccines/edit-batch.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@

<h1 class="nhsuks-heading-l">Edit batch</h1>

<p class="nhsuk-body-m">Your changes will only apply to vaccination records saved in future.</p>

<form action="/vaccines/{{ vaccine.id }}/{{ batch.batchNumber }}/update" method="post" novalidate="true">
<form action="/vaccines/{{ vaccine.id }}/{{ batch.batchNumber }}/update-check" method="post" novalidate="true">

{{ input({
"label": {
Expand Down
19 changes: 19 additions & 0 deletions app/views/vaccines/product-page.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,25 @@ <h3 class="nhsuk-notification-banner__heading">
}) }}
{% endif %}

{% if updated %}
{% set html %}
<h3 class="nhsuk-notification-banner__heading">
Batch edited
</h3>
<p>
{{ ("Batch " + updatedBatchNumber + " has been edited.") if updatedBatchNumber else "Batch has been edited." }}
{% if updatedRecordsCount > 0 %}
{{ updatedRecordsCount }} vaccination record{{ "s" if updatedRecordsCount != 1 }} {{ "was" if updatedRecordsCount == 1 else "were" }} also updated to use the new batch details.
{% endif %}
</p>
{% endset %}

{{ notificationBanner({
html: html,
type: "success"
}) }}
{% endif %}

<h1 class="nhsuk-heading-l">{{ vaccine.vaccineProduct }}</h1>

{{ summaryList({
Expand Down
Loading