Skip to content

Commit 110b309

Browse files
authored
Clinics refactoring: clinic setup model relationships (#255)
Switched the storage of clinic vaccination periods from a foreign key-based approach to using embedded objects in the session. This will allow simplification of sessions checking and using values in the vaccination periods during wizard journeys, as well as simplification of providing data to summaryRows, reducing duplication and complexity. * Reduce dependencies in ClinicVaccinationPeriod Removed the session_id foreign key and the getter to return the object, as neither was being used. * Remove references to vaccination period's session ID * Embed clinic vaccination periods in Session This is side-by-side with existing array of IDs for now, but will ultimately replace that. Added add and remove method for these embedded vaccination periods too. * Replace vaccination period IDs array with embedded periods Note: this is not a working build; I'm still part way through the wider refactoring of clinic session models. * Stop creating an empty file of vaccination period data * Directly access a session's vaccination periods in Nunjucks Also renamed the Session class's clinicVaccinationPeriods to just vaccinationPeriods. * Update session with vaccination period details This commit fixes earlier ones that still had attempts to use ClinicVaccinationPeriod.update (which no longer exists). It also fixes a couple of linter issues. * Set clinic session vaccinator count correctly Was previously trying to call a non-existent method that I expected to create but decided against. * Fix editing of vaccination periods in clinic sessions Previously, when editing an existing clinic, the addition of a new vaccination period left its vaccinator count uninitialised, which caused an inability to calculate the total number of appointments, littering the UI with NaN in places.
1 parent e13ddf6 commit 110b309

8 files changed

Lines changed: 112 additions & 247 deletions

File tree

app/controllers/session.js

Lines changed: 37 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import {
1515
} from '../enums.js'
1616
import {
1717
Clinic,
18-
ClinicVaccinationPeriod,
1918
DefaultBatch,
2019
Instruction,
2120
PatientSession,
@@ -496,25 +495,14 @@ export const sessionController = {
496495
// Copy the saved session to the wizard context, if not already there
497496
let session = Session.findOne(session_id, data.wizard)
498497
if (!session) {
499-
// NB: response.locals.session was set in read()
498+
// NB: response.locals.session was read from the global context in read()
500499
session = Session.create(response.locals.session, data.wizard)
501-
if (session.type === SessionType.Clinic) {
502-
response.locals.session.vaccinationPeriods.forEach(
503-
(vaccinationPeriod) => {
504-
ClinicVaccinationPeriod.create(vaccinationPeriod, data.wizard)
505-
}
506-
)
507-
}
508500
}
509501

510502
// Set up the transaction metadata that controls how some clinic values are entered
511503
if (session.type === SessionType.Clinic) {
512504
const vaccinatorCounts = new Set(
513-
session.vaccination_period_ids.map(
514-
(period_id) =>
515-
ClinicVaccinationPeriod.findOne(period_id, data.wizard)
516-
?.vaccinatorCount
517-
)
505+
session.vaccinationPeriods.map((period) => period.vaccinatorCount)
518506
)
519507
const variableVaccinatorCounts = vaccinatorCounts.size > 1
520508
data.transaction = {
@@ -533,9 +521,7 @@ export const sessionController = {
533521

534522
if (session.type === SessionType.Clinic) {
535523
response.locals.vaccinationPeriodsSummary = getVaccinationPeriodsSummary(
536-
session.vaccination_period_ids.map((period_id) =>
537-
ClinicVaccinationPeriod.findOne(period_id, data.wizard)
538-
),
524+
session.vaccinationPeriods,
539525
session.appointmentLength
540526
)
541527
}
@@ -559,17 +545,6 @@ export const sessionController = {
559545
data
560546
)
561547

562-
// Update any clinic vaccination periods
563-
if (session.type === SessionType.Clinic) {
564-
session.vaccination_period_ids.forEach((period_id) => {
565-
const vaccinationPeriod = ClinicVaccinationPeriod.findOne(
566-
period_id,
567-
data.wizard
568-
)
569-
ClinicVaccinationPeriod.update(period_id, vaccinationPeriod, data)
570-
})
571-
}
572-
573548
// Clean up session data
574549
delete data.vaccinationPeriods
575550
delete data.transaction
@@ -597,13 +572,6 @@ export const sessionController = {
597572
}
598573
response.locals.session = new Session(session, data)
599574

600-
const vaccinationPeriods = session.vaccinationPeriods
601-
if (vaccinationPeriods) {
602-
response.locals.vaccinationPeriods = vaccinationPeriods.map(
603-
(period) => new ClinicVaccinationPeriod(period, data)
604-
)
605-
}
606-
607575
const journey = {
608576
[`/`]: {},
609577
[`/${session_id}/${type}/type`]: {},
@@ -670,10 +638,10 @@ export const sessionController = {
670638
}
671639

672640
// Generate summary info for the check-answers page
673-
if (vaccinationPeriods) {
641+
if (session.vaccinationPeriods) {
674642
response.locals.vaccinationPeriodsSummary =
675643
getVaccinationPeriodsSummary(
676-
vaccinationPeriods,
644+
session.vaccinationPeriods,
677645
session.appointmentLength
678646
)
679647
}
@@ -731,95 +699,72 @@ export const sessionController = {
731699

732700
if (session.type === SessionType.Clinic) {
733701
// Add the first vaccination period, if not already there
734-
if (!session.vaccination_period_ids?.length) {
735-
const vaccination_period_ids = [
736-
ClinicVaccinationPeriod.create(
737-
{ session_id: session.id },
738-
data.wizard
739-
).uuid
740-
]
741-
Session.update(session_id, { vaccination_period_ids }, data.wizard)
702+
if (!session.vaccinationPeriods?.length) {
703+
session.addVaccinationPeriod()
704+
Session.update(session_id, session, data.wizard)
742705
}
743706

744707
// Act accordingly for each of the possible button clicks in the vaccination periods page
745708
if (view === 'vaccination-periods') {
746709
// Save the times entered, no matter what we're doing next
747-
for (const [period_id, vaccinationPeriod] of Object.entries(
710+
for (let [period_uuid, vaccinationPeriodValues] of Object.entries(
748711
request.body.vaccinationPeriods
749712
)) {
713+
// Make sure the period start and end have date information as well as time
750714
const sessionDate_ = session.date
751715
? session.date_
752716
: convertIsoDateToObject(today())
753-
ClinicVaccinationPeriod.update(
754-
period_id,
755-
_.merge(
756-
// make sure the period start and end have date information as well as time
757-
{ startAt_: { ...sessionDate_ }, endAt_: { ...sessionDate_ } },
758-
vaccinationPeriod
759-
),
760-
data.wizard
761-
)
717+
const dateValues = {
718+
startAt_: { ...sessionDate_ },
719+
endAt_: { ...sessionDate_ }
720+
}
721+
vaccinationPeriodValues = _.merge(dateValues, vaccinationPeriodValues)
722+
723+
const vaccinationPeriod = session.getVaccinationPeriod(period_uuid)
724+
vaccinationPeriod.startAt_ = vaccinationPeriodValues.startAt_
725+
vaccinationPeriod.endAt_ = vaccinationPeriodValues.endAt_
726+
727+
Session.update(session_id, session, data.wizard)
762728
}
763729

764730
// Add or remove vaccination periods, if requested
765731
const action = request.body.action
766732
if (action === 'add-period') {
767-
// Add another vaccination period
768-
const vaccination_period_ids = [
769-
...session.vaccination_period_ids,
770-
ClinicVaccinationPeriod.create(
771-
{ session_id: session.id },
772-
data.wizard
773-
).uuid
774-
]
775-
Session.update(session_id, { vaccination_period_ids }, data.wizard)
733+
session.addVaccinationPeriod()
734+
Session.update(session_id, session, data.wizard)
776735

777736
nextPage = request.originalUrl
778737
} else if (action.startsWith('remove-period-')) {
779738
// Remove a vaccination period
780-
const periodIndex = parseInt(
781-
action.substring('remove-period-'.length),
782-
10
783-
)
784-
const period_id = session.vaccination_period_ids[periodIndex]
785-
const vaccination_period_ids =
786-
session.vaccination_period_ids.toSpliced(periodIndex, 1)
787-
Session.update(session_id, { vaccination_period_ids }, data.wizard)
788-
789-
ClinicVaccinationPeriod.delete(period_id, data.wizard)
739+
const index = parseInt(action.substring('remove-period-'.length))
740+
const period_id = session.vaccinationPeriods[index].uuid
741+
session.removeVaccinationPeriod(period_id)
742+
Session.update(session_id, session, data.wizard)
790743

791744
nextPage = request.originalUrl
792745
}
793746
} else if (view === 'vaccinators') {
794747
if (
795-
session.vaccination_period_ids.length > 1 &&
748+
session?.vaccinationPeriods.length > 1 &&
796749
request.body.transaction.hasVariableVaccinatorCounts === 'false'
797750
) {
798751
// Set the same number of vaccinators in all vaccination periods
799-
for (const period_id of session.vaccination_period_ids) {
800-
ClinicVaccinationPeriod.update(
801-
period_id,
802-
{
803-
vaccinatorCount: parseInt(
804-
request.body.transaction.consistentVaccinatorCount,
805-
10
806-
)
807-
},
808-
data.wizard
809-
)
752+
const vaccinatorCount = parseInt(
753+
request.body.transaction.consistentVaccinatorCount
754+
)
755+
for (const period of session.vaccinationPeriods) {
756+
period.vaccinatorCount = vaccinatorCount
810757
}
811758
} else {
812759
// Each vaccination period gets its own number of vaccinators
813-
for (const [period_id, vaccinationPeriod] of Object.entries(
760+
for (const [period_uuid, vaccinationPeriodValues] of Object.entries(
814761
request.body.vaccinationPeriods
815762
)) {
816-
ClinicVaccinationPeriod.update(
817-
period_id,
818-
vaccinationPeriod,
819-
data.wizard
820-
)
763+
session.getVaccinationPeriod(period_uuid).vaccinatorCount =
764+
vaccinationPeriodValues.vaccinatorCount
821765
}
822766
}
767+
Session.update(session_id, session, data.wizard)
823768
}
824769
}
825770

app/data.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import vaccines from './datasets/vaccines.js'
22
import batches from '../.data/batches.json' with { type: 'json' }
33
import clinicAppointments from '../.data/clinic-appointments.json' with { type: 'json' }
44
import clinicBookings from '../.data/clinic-bookings.json' with { type: 'json' }
5-
import clinicVaccinationPeriods from '../.data/clinic-vaccination-periods.json' with { type: 'json' }
65
import clinics from '../.data/clinics.json' with { type: 'json' }
76
import instructions from '../.data/instructions.json' with { type: 'json' }
87
import moves from '../.data/moves.json' with { type: 'json' }
@@ -35,7 +34,6 @@ const data = {
3534
batches,
3635
clinicAppointments,
3736
clinicBookings,
38-
clinicVaccinationPeriods,
3937
clinics,
4038
counts: {},
4139
defaultBatches: {},

app/generators/clinic-vaccination-periods.js

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
import { fakerEN_GB as faker } from '@faker-js/faker'
22
import { addMinutes } from 'date-fns'
33

4-
import { ClinicVaccinationPeriod } from '../models.js'
4+
import { Session } from '../models.js'
55

66
/**
77
* Generate one or more time periods during which vaccinations will be administered at a clinic
88
*
9-
* @param {string} session_id - session ID for the clinic whose vaccination periods we're creating
10-
* @param {Date} sessionDate - the date on which the clinic's running
11-
* @returns {Array<ClinicVaccinationPeriod>} - one or more vaccination periods
9+
* @param {Session} session - the session to which we're adding vaccination periods
1210
*/
13-
export function generateClinicVaccinationPeriods(session_id, sessionDate) {
11+
export function generateClinicVaccinationPeriods(session) {
1412
const periodCount = faker.helpers.weightedArrayElement([
1513
{ value: 1, weight: 70 },
1614
{ value: 2, weight: 30 }
@@ -27,6 +25,7 @@ export function generateClinicVaccinationPeriods(session_id, sessionDate) {
2725
vaccinationPeriodLengths.reduce((total, next) => total + next, 0) +
2826
breakLength
2927

28+
const sessionDate = new Date(session.date)
3029
const earliestSessionStartTime = new Date(sessionDate.setUTCHours(9, 0)) // 9am
3130
const latestSessionFinishTime = new Date(sessionDate.setUTCHours(20, 0)) // 8pm
3231
const sessionWindow = Math.floor(
@@ -42,9 +41,8 @@ export function generateClinicVaccinationPeriods(session_id, sessionDate) {
4241
const sessionStartTime = addMinutes(earliestSessionStartTime, startOffset)
4342

4443
let nextPeriodStartTime = sessionStartTime
45-
return vaccinationPeriodLengths.map((periodLength) => {
46-
const vaccinationPeriod = new ClinicVaccinationPeriod({
47-
session_id,
44+
vaccinationPeriodLengths.forEach((periodLength) => {
45+
session.addVaccinationPeriod({
4846
startAt: nextPeriodStartTime,
4947
endAt: addMinutes(nextPeriodStartTime, periodLength),
5048
vaccinatorCount: faker.helpers.weightedArrayElement([
@@ -57,7 +55,5 @@ export function generateClinicVaccinationPeriods(session_id, sessionDate) {
5755
nextPeriodStartTime,
5856
periodLength + breakLength
5957
)
60-
61-
return vaccinationPeriod
6258
})
6359
}

0 commit comments

Comments
 (0)