diff --git a/app/lib/ods.js b/app/lib/ods.js index debd8b46..bb7c8b50 100644 --- a/app/lib/ods.js +++ b/app/lib/ods.js @@ -1,3 +1,5 @@ +const { capitaliseFromOds } = require('./utils/capitalise-from-ods.js') + // There are 2 different ODS APIs, the old ORD API and the newer FHIR-based API. // The ORD API is officially deprecated and may be retired in the future. @@ -32,7 +34,7 @@ async function fetchPaginatedOrganisations(queryParams) { const results = (data.Organisations || []).map(function(org) { return { id: org.OrgId, - name: org.Name, + name: capitaliseFromOds(org.Name), address: { postcode: org.PostCode } @@ -81,10 +83,10 @@ async function getOrganisation(id) { const organisation = { id: data.id, - name: data.name, + name: capitaliseFromOds(data.name), address: { - line1: data.address[0].line[0], - town: data.address[0].city, + line1: capitaliseFromOds(data.address[0].line[0]), + town: capitaliseFromOds(data.address[0].city), postcode: data.address[0].postalCode } } diff --git a/app/lib/utils/capitalise-from-ods.js b/app/lib/utils/capitalise-from-ods.js new file mode 100644 index 00000000..d43b0630 --- /dev/null +++ b/app/lib/utils/capitalise-from-ods.js @@ -0,0 +1,39 @@ +// Words that should remain lowercase (unless at the start) +const lowercaseWords = ['and', 'the', 'of', 'in', 'for', 'on', 'at', 'to', 'by', 'with', 'a', 'an']; + +// Acronyms that should remain uppercase +const acronyms = ['NHS', 'GP', 'PCN', 'CCG', 'ICB', 'CIC', 'UK', 'LLP', 'PLC']; + +module.exports.capitaliseFromOds = function(input) { + if (!input) return input; + + const words = input.toLowerCase().split(/\s+/); + + const capitalisedWords = words.map((word, index) => { + // Check if word is initials (e.g. "p.g." or "a.b.c.") + if (/^([a-z]\.)+$/i.test(word)) { + return word.toUpperCase(); + } + + // Check if word is a single letter (keep uppercase) + if (/^[a-z]$/i.test(word)) { + return word.toUpperCase(); + } + + // Check if upper-cased word is an acronym + const upperWord = word.toUpperCase(); + if (acronyms.includes(upperWord)) { + return upperWord; + } + + // Check if word should remain lowercase (but not if it's the first word) + if (index !== 0 && lowercaseWords.includes(word)) { + return word; + } + + // Capitalise first letter, rest lowercase + return word.charAt(0).toUpperCase() + word.slice(1); + }); + + return capitalisedWords.join(' '); +} diff --git a/app/routes/apply.js b/app/routes/apply.js index 3abcbed4..acb4ff84 100644 --- a/app/routes/apply.js +++ b/app/routes/apply.js @@ -105,6 +105,17 @@ module.exports = router => { }) }) + // Check list of selected pharmacies + router.post('/apply/pharmacy-chain-check-remove-one', (req, res) => { + const data = req.session.data + const pharmacyIdToRemove = data.pharmacyIdToRemove + + data.pharmacyIds = data.pharmacyIds.filter(id => id !== pharmacyIdToRemove) + + res.redirect('/apply/pharmacy-chain-check') + }) + + // Check your answers page router.get('/apply/check', (req, res) => { const data = req.session.data @@ -157,6 +168,51 @@ module.exports = router => { res.redirect('/apply/check-your-email') }) + // Routing after the final check answers for chains page + router.post('/apply/check-chain-answer', async (req, res) => { + const data = req.session.data + + let pharmacies = await getPharmaciesBelongingToOrganisation(data.pharmacyChainId) + + pharmacies = pharmacies.filter((pharmacy) => { + return data.pharmacyIds.includes(pharmacy.id) + }) + + let userOrganisationPermissions = [] + + for (const pharmacy of pharmacies) { + + // Add the pharmacy itself as the single site + pharmacy.sites = [ + { + id: pharmacy.id, + name: pharmacy.name, + address: pharmacy.address + } + ] + + data.organisations.push(pharmacy) + userOrganisationPermissions.push({ + id: pharmacy.id, + permissionLevel: 'Lead administrator', + status: 'Active', + vaccinator: false + }) + } + + const user = { + id: Math.floor(Math.random() * 10000000).toString(), + firstName: data.firstName, + lastName: data.lastName, + email: data.email, + organisations: userOrganisationPermissions + } + + data.users.push(user) + + res.redirect('/apply/check-your-email-chain') + }) + // Welcome email mockup router.get('/apply/welcome-email', (req, res) => { const data = req.session.data diff --git a/app/routes/auth.js b/app/routes/auth.js index 20548c23..500b18cf 100644 --- a/app/routes/auth.js +++ b/app/routes/auth.js @@ -43,7 +43,7 @@ module.exports = router => { req.session.data.currentUserId = user.id; req.session.data.currentOrganisationId = userOrganisationIds[0] - res.redirect('/survey') + res.redirect('/home') } else if (userRegionIds.length === 1) { @@ -55,7 +55,10 @@ module.exports = router => { } else if (organisationsUserIsAnAdminAt.length > 1) { req.session.data.currentUserId = user.id - res.redirect('/auth/select-mode') + + // Skipping the select mode screen for research purposes + res.redirect('/auth/select-organisation') + // res.redirect('/auth/select-mode') } else { @@ -79,7 +82,7 @@ module.exports = router => { req.session.data.currentUserId = data.userId - res.redirect('/survey') + res.redirect('/home') } else { res.redirect('/auth/select-mode') } @@ -102,18 +105,12 @@ module.exports = router => { }) router.post('/select-organisation', (req, res) => { - - const data = req.session.data - const email = data.email - const user = data.users.find((user) => user.email === email) - const selectedOrganisationId = req.session.data.organisationId if (selectedOrganisationId) { - req.session.data.currentUserId = user.id; req.session.data.currentOrganisationId = selectedOrganisationId; - res.redirect('/survey') + res.redirect('/home') } else { res.redirect('/auth/select-organisation') diff --git a/app/routes/home.js b/app/routes/home.js index 5cd163cd..bc890a75 100644 --- a/app/routes/home.js +++ b/app/routes/home.js @@ -85,7 +85,7 @@ module.exports = router => { // organisation vaccinationsRecorded = allVaccinationsRecorded.filter((vaccination)=> vaccination.organisationId === currentOrganisation.id) - if (sites.length === 0) { + if (!sites.length || sites.length === 0) { sites = [currentOrganisation] } diff --git a/app/routes/vaccines.js b/app/routes/vaccines.js index 5ef4a696..1ed8a0f0 100644 --- a/app/routes/vaccines.js +++ b/app/routes/vaccines.js @@ -105,6 +105,8 @@ module.exports = (router) => { for (const vaccine of vaccinesAdded) { + currentOrganisation.vaccines ||= [] + let vaccineToEnable = currentOrganisation.vaccines.find((vaccine) => vaccine.name === vaccine) if (vaccineToEnable) { diff --git a/app/views/apply/check-chain.html b/app/views/apply/check-chain.html index 3fb1087a..7f8b8d07 100644 --- a/app/views/apply/check-chain.html +++ b/app/views/apply/check-chain.html @@ -15,10 +15,16 @@

{{ pageName }}

{% set pharmaciesHtml %} - {% for pharmacy in pharmacies %} - {{ pharmacy.name | capitalize }} ({{ pharmacy.id }}) -
- {% endfor %} + {% if (pharmacies | length) <= 10 %} + + {% else %} + {{ pharmacies | length }} pharmacies + {% endif %} + {% endset %}

Your pharmacies

@@ -29,7 +35,7 @@

Your pharmacies

text: "Company" }, value: { - html: (pharmacyChain.name | capitalize) + html: pharmacyChain.name }, actions: { items: [ @@ -146,7 +152,7 @@

2nd lead administrator

}) }} {% endif %} -
+ {{ button({ text: "Confirm" }) }} diff --git a/app/views/apply/check-pharmacy-chain.html b/app/views/apply/check-pharmacy-chain.html index a745c2f4..4f686713 100644 --- a/app/views/apply/check-pharmacy-chain.html +++ b/app/views/apply/check-pharmacy-chain.html @@ -22,7 +22,7 @@

{{ pageName }}

text: "Name" }, value: { - text: organisation.name | capitalize + text: organisation.name } }, { @@ -46,7 +46,7 @@

{{ pageName }}

text: "Address" }, value: { - html: (organisation.address.line1 | capitalize) + "
" + (organisation.address.town | capitalize) + "
" + organisation.address.postcode + html: organisation.address.line1 + "
" + organisation.address.town + "
" + organisation.address.postcode } } ] diff --git a/app/views/apply/pharmacies.html b/app/views/apply/pharmacies.html index e8c2af9d..9d770f7d 100644 --- a/app/views/apply/pharmacies.html +++ b/app/views/apply/pharmacies.html @@ -1,6 +1,6 @@ {% extends 'layout.html' %} -{% set pageName = "" %} +{% set pageName = "Select the pharmacies where you want to start using RAVS" %} {% block beforeContent %} @@ -16,22 +16,23 @@
- {% set items = [ - { - text: "Select all", - value: "", - attributes: { - "data-select-all": "true" - } - }, - { - divider: "or" - } - ] %} + {% set items = [] %} + {% if pharmacies | length > 1 %} + {% set items = (items.push({ + text: "Select all", + value: "", + attributes: { + "data-select-all": "true" + } + }), items) %} + {% set items = (items.push({ + divider: "or" + }), items) %} + {% endif %} {% for pharmacy in pharmacies %} {% set items = (items.push({ - text: (pharmacy.name | capitalize) + ", " + pharmacy.address.postcode + " (" + pharmacy.id + ")", + text: pharmacy.name + ", " + pharmacy.address.postcode + " (" + pharmacy.id + ")", value: pharmacy.id }), items) %} {% endfor %} @@ -44,7 +45,7 @@ values: data.pharmacyIds, fieldset: { legend: { - text: "Select the pharmacies where you want to start using RAVS", + text: pageName, size: "l" } }, diff --git a/app/views/apply/pharmacy-chain-check.html b/app/views/apply/pharmacy-chain-check.html index ed817f61..28621a51 100644 --- a/app/views/apply/pharmacy-chain-check.html +++ b/app/views/apply/pharmacy-chain-check.html @@ -15,7 +15,7 @@

{{ pageName }}

-

You have selected {{ pharmacies | length }} pharmacies.

+

You have selected {{ pharmacies | length | plural("pharmacy") }}.

@@ -28,12 +28,17 @@

{{ pageName }}

{% for pharmacy in pharmacies %} - + {% endfor %} diff --git a/app/views/apply/start.html b/app/views/apply/start.html index 7154561c..79ec5629 100644 --- a/app/views/apply/start.html +++ b/app/views/apply/start.html @@ -37,7 +37,7 @@ {% for pharmacyCompany in (allPharmacyCompanies | sort(false, false, "name")) %} {% set pharmacyCompanyItems = (pharmacyCompanyItems.push({ - text: (pharmacyCompany.name | capitalize) + " (" + (pharmacyCompany.id) + ")", + text: (pharmacyCompany.name) + " (" + (pharmacyCompany.id) + ")", value: pharmacyCompany.id }), pharmacyCompanyItems) %} {% endfor %} diff --git a/app/views/apply/welcome-email-chain.html b/app/views/apply/welcome-email-chain.html index 4b0acc01..338b7e82 100644 --- a/app/views/apply/welcome-email-chain.html +++ b/app/views/apply/welcome-email-chain.html @@ -26,18 +26,18 @@

1. Activate your Okta account

If you cannot find the email, check your spam or junk.

2. Log in to the Record a vaccination service

-

Once you’ve activated your Okta account, log in to www.ravs.england.nhs.uk using your Okta username and password.

+

Once you’ve activated your Okta account, log in to www.ravs.england.nhs.uk using your Okta username and password.

You can also access the service through your Okta account by clicking ‘RAVS (PROD) app’.

3. Add users to individual pharmacies

When you log in, you'll see a list of pharmacies where you now have access to the service.

-

To give more users access to the service at individual pharmacies:

- +

To give more users access to the service at individual pharmacies:

+
  • select a pharmacy from the list
  • go to the Manage users section and add users
- +

Training and support

To help you get started, you can:

    @@ -50,9 +50,9 @@

    Training and support

    Do not reply to this email as we do not check this inbox.

    To contact us, go to: Record a vaccination: Help and support

    - - + + diff --git a/app/views/auth/okta-sign-in.html b/app/views/auth/okta-sign-in.html index 7a0aea5b..0b913e3a 100644 --- a/app/views/auth/okta-sign-in.html +++ b/app/views/auth/okta-sign-in.html @@ -17,7 +17,7 @@
    -
    +
    {{ button({ classes: "app-button--okta nhsuk-u-margin-top-5", diff --git a/app/views/auth/select-organisation.html b/app/views/auth/select-organisation.html index ce1baa8a..eaa3304a 100644 --- a/app/views/auth/select-organisation.html +++ b/app/views/auth/select-organisation.html @@ -31,7 +31,7 @@ value: organisation.id, text: organisation.name + " (" + organisation.id + ")", hint: { - text: organisation.address.line1 + ", " + organisation.address.town + ", " + organisation.address.postcode + text: (organisation.address.line1 + ", " if organisation.address.line1 else "") + (organisation.address.town + ", " if organisation.address.town else "") + organisation.address.postcode } }), items) %} {% endfor %}
{{ pharmacy.name | capitalize }}, {{ pharmacy.address.postcode }} ({{ pharmacy.id }}){{ pharmacy.name }}, {{ pharmacy.address.postcode }} ({{ pharmacy.id }}) - {{ button({ - text: "Remove", - classes: "nhsuk-button--small nhsuk-button--secondary nhsuk-u-margin-bottom-0" - }) }} + {% if pharmacies | length > 1 %} + + + {{ button({ + text: "Remove", + classes: "nhsuk-button--small nhsuk-button--secondary nhsuk-u-margin-bottom-0" + }) }} + + {% endif %}