Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
560 changes: 560 additions & 0 deletions app/data/organisations.js

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions app/data/session-data-defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ module.exports = {
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"],

// Amanda White (6424325235325) — default temporary pharmacy access
groupAdminTemporaryPharmacyIds: ["FX9141", "FX4825"],
groupAdminTemporaryPharmacyAddedDates: {
"FX9141": "2026-06-20",
"FX4825": "2026-07-07"
},
groupAdminTemporaryPharmacyDeactivatedDates: {},

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
188 changes: 188 additions & 0 deletions app/routes/auth.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
module.exports = router => {

const asArray = (value) => {
if (value === undefined || value === null) {
return []
}

return Array.isArray(value) ? value : [value]
}

const getDefaultLandingPath = (data, organisationId) => {
const organisation = (data.organisations || []).find((item) => item.id === organisationId)

Expand All @@ -22,6 +30,95 @@ module.exports = router => {
return '/home'
}

const getCurrentUserFromSessionData = (data) => {
if (!data) {
return null
}

if (data.currentUserId) {
return (data.users || []).find((user) => user.id === data.currentUserId) || null
}

if (data.email) {
return (data.users || []).find((user) => user.email === data.email) || null
}

return null
}

const isTemporaryAccessInactive = (addedOnIsoDate, deactivatedOnIsoDate) => {
if (deactivatedOnIsoDate) {
return true
}

if (!addedOnIsoDate) {
return false
}

const expiryDate = new Date(`${addedOnIsoDate}T12:00:00`)
expiryDate.setDate(expiryDate.getDate() + 7)

const today = new Date()
today.setHours(0, 0, 0, 0)

return expiryDate < today
}

const getGroupAdminSwitchContext = (data, user) => {
if (!data || !user) {
return {
isEligible: false,
groupOrganisation: null,
temporaryPharmacies: []
}
}

const activeGroupAdminOrganisationIds = (user.organisations || [])
.filter((organisation) => organisation.permissionLevel === 'Group administrator' && organisation.status === 'Active')
.map((organisation) => organisation.id)

const groupOrganisation = (data.organisations || []).find((organisation) => {
return organisation.type === 'Pharmacy HQ' && activeGroupAdminOrganisationIds.includes(organisation.id)
})

if (!groupOrganisation) {
return {
isEligible: false,
groupOrganisation: null,
temporaryPharmacies: []
}
}

const temporaryPharmacyIds = [...new Set(asArray(data.groupAdminTemporaryPharmacyIds))]
const temporaryPharmacyAddedDates = data.groupAdminTemporaryPharmacyAddedDates || {}
const temporaryPharmacyDeactivatedDates = data.groupAdminTemporaryPharmacyDeactivatedDates || {}

const temporaryPharmacies = temporaryPharmacyIds
.map((pharmacyId) => {
const organisation = (data.organisations || []).find((item) => item.id === pharmacyId)

return {
organisation,
addedOn: temporaryPharmacyAddedDates[pharmacyId],
deactivatedOn: temporaryPharmacyDeactivatedDates[pharmacyId]
}
})
.filter((item) => item.organisation)
.filter((organisation) => {
return organisation.organisation.status === 'Active' && organisation.organisation.companyId === groupOrganisation.id
})
.filter((item) => {
return !isTemporaryAccessInactive(item.addedOn, item.deactivatedOn)
})
.map((item) => item.organisation)

return {
isEligible: temporaryPharmacies.length > 1,
groupOrganisation,
temporaryPharmacies
}
}

router.post('/auth/sign-in', (req, res) => {

const data = req.session.data
Expand Down Expand Up @@ -119,6 +216,97 @@ module.exports = router => {
}
})

router.get('/auth/switch-organisation/work-type', (req, res) => {
const data = req.session.data
const user = getCurrentUserFromSessionData(data)
const context = getGroupAdminSwitchContext(data, user)

if (!user || !context.isEligible) {
return res.redirect('/auth/select-organisation')
}

res.render('auth/switch-work-type', {
groupOrganisation: context.groupOrganisation
})
})

router.post('/auth/switch-organisation/work-type', (req, res) => {
const data = req.session.data
const user = getCurrentUserFromSessionData(data)
const context = getGroupAdminSwitchContext(data, user)
const switchOrganisationWorkType = req.body.switchOrganisationWorkType

if (!user || !context.isEligible) {
return res.redirect('/auth/select-organisation')
}

if (!switchOrganisationWorkType) {
return res.render('auth/switch-work-type', {
groupOrganisation: context.groupOrganisation,
error: {
text: 'Select the type of work you want to do'
}
})
}

if (switchOrganisationWorkType === 'group-admin') {
data.currentOrganisationId = context.groupOrganisation.id
return res.redirect(getDefaultLandingPath(data, context.groupOrganisation.id))
}

if (switchOrganisationWorkType === 'individual-pharmacy') {
return res.redirect('/auth/switch-organisation/select-pharmacy')
}

res.render('auth/switch-work-type', {
groupOrganisation: context.groupOrganisation,
error: {
text: 'Select the type of work you want to do'
}
})
})

router.get('/auth/switch-organisation/select-pharmacy', (req, res) => {
const data = req.session.data
const user = getCurrentUserFromSessionData(data)
const context = getGroupAdminSwitchContext(data, user)

if (!user || !context.isEligible) {
return res.redirect('/auth/select-organisation')
}

res.render('auth/select-pharmacy-for-access', {
groupOrganisation: context.groupOrganisation,
pharmacies: context.temporaryPharmacies
})
})

router.post('/auth/switch-organisation/select-pharmacy', (req, res) => {
const data = req.session.data
const user = getCurrentUserFromSessionData(data)
const context = getGroupAdminSwitchContext(data, user)
const switchOrganisationPharmacyId = req.body.switchOrganisationPharmacyId

if (!user || !context.isEligible) {
return res.redirect('/auth/select-organisation')
}

const isValidSelection = context.temporaryPharmacies.some((pharmacy) => pharmacy.id === switchOrganisationPharmacyId)

if (!switchOrganisationPharmacyId || !isValidSelection) {
return res.render('auth/select-pharmacy-for-access', {
groupOrganisation: context.groupOrganisation,
pharmacies: context.temporaryPharmacies,
error: {
text: 'Select a pharmacy to access'
}
})
}

data.currentOrganisationId = switchOrganisationPharmacyId
res.redirect(getDefaultLandingPath(data, switchOrganisationPharmacyId))
})

router.get('/sign-out', (req, res) => {
req.session.data.currentUserId = null
req.session.data.currentOrganisationId = null
Expand Down
Loading