Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update: [AEA-4048] - Validate terminal status indicator value #305

Merged
merged 17 commits into from
May 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e1f52ee
Add patient action required statuses
kris-szlapa May 28, 2024
14b2057
trigger build
kris-szlapa May 28, 2024
f3419ce
Merge branch 'main' of https://github.com/NHSDigital/eps-prescription…
kris-szlapa May 28, 2024
72c1208
Add unit tests for validation of status against business status
kris-szlapa May 28, 2024
89009fa
Refactor unit tests
kris-szlapa May 28, 2024
0575755
Refactor unit tests for validation of status against business status
kris-szlapa May 28, 2024
da95a92
Merge branch 'main' of https://github.com/NHSDigital/eps-prescription…
kris-szlapa May 28, 2024
861b275
Add the logic and tests for the terminal status completed
kris-szlapa May 29, 2024
1f37f50
Merge branch 'main' of https://github.com/NHSDigital/eps-prescription…
kris-szlapa May 29, 2024
60f1472
Amend diagnostic messages for the validation failures
kris-szlapa May 29, 2024
647e23a
Add return messages for missing fields and split the unit test
kris-szlapa May 29, 2024
e74aebf
Remove unnecessary return messages
kris-szlapa May 30, 2024
2eb57a7
Merge branch 'main' of https://github.com/NHSDigital/eps-prescription…
kris-szlapa May 30, 2024
4e46426
Amend BUSINESS_STATUSES definition and update unit tests
kris-szlapa May 30, 2024
e56d95d
Refactor unit tests for validation of status against business status
kris-szlapa May 30, 2024
bd4c439
Add a unit test for the case when business status is unsupported
kris-szlapa May 30, 2024
09110af
Cleanup the code
kris-szlapa May 30, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}
}
],
"status": "in-progress",
"status": "completed",
"businessStatus": {
"coding": [
{
Expand Down
44 changes: 20 additions & 24 deletions packages/updatePrescriptionStatus/src/validation/content.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */

import {
BundleEntry,
CodeableConcept,
Coding,
Task
} from "fhir/r4"
/* eslint-disable @typescript-eslint/no-explicit-any, max-len */

import {BundleEntry, Task} from "fhir/r4"
import {validatePrescriptionID} from "../utils/prescriptionID"
import {validateNhsNumber} from "../utils/nhsNumber"
import {validateFields} from "./fields"
Expand All @@ -25,18 +20,20 @@ export const ODS_CODE_CODESYSTEM = "https://fhir.nhs.uk/Id/ods-organization-code
export const PRESCRIPTION_ID_CODESYSTEM = "https://fhir.nhs.uk/Id/prescription-order-number"
export const STATUS_CODESYSTEM = "https://fhir.nhs.uk/CodeSystem/task-businessStatus-nppt"

export const BUSINESS_STATUSES = [
export const COMPLETED_BUSINESS_STATUSES = ["collected", "not dispensed", "dispatched"]

export const IN_PROGRESS_BUSINESS_STATUSES = [
"with pharmacy",
"with pharmacy - preparing remainder",
"ready to collect",
"ready to collect - partial",
"collected",
"ready to dispatch",
"ready to dispatch - partial",
"dispatched",
"not dispensed"
"ready to collect - partial"
]

export const BUSINESS_STATUSES = COMPLETED_BUSINESS_STATUSES.concat(IN_PROGRESS_BUSINESS_STATUSES, [
"ready to dispatch",
"ready to dispatch - partial"
])

export function transactionBundle(body: any): boolean {
return body.resourceType === "Bundle" && body.type === "transaction"
}
Expand Down Expand Up @@ -113,15 +110,14 @@ export function businessStatus(task: Task): string | undefined {

export function statuses(task: Task): string | undefined {
const status = task.status
if (status === "completed") {
const businessStatus: CodeableConcept | undefined = task.businessStatus
if (businessStatus) {
const coding: Coding = businessStatus.coding![0]
const code = coding.code
if (code && ["with pharmacy", "ready to collect"].includes(code.toLowerCase())) {
return "Completed state indicated for a prescription status requiring patient action."
}
}
const businessStatus: string = task.businessStatus!.coding![0].code!
const lowercaseCode = businessStatus.toLowerCase()
if (status === "completed" && IN_PROGRESS_BUSINESS_STATUSES.includes(lowercaseCode)) {
return `Task.status field set to '${status}' but Task.businessStatus value of '${businessStatus}' requires follow up action.`
} else if (status === "in-progress" && COMPLETED_BUSINESS_STATUSES.includes(lowercaseCode)) {
return `Task.status field set to '${status}' but Task.businessStatus value of '${businessStatus}' has no possible follow up action.`
} else if (!BUSINESS_STATUSES.includes(lowercaseCode)) {
return `Unsupported Task.businessStatus '${businessStatus}'.`
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/updatePrescriptionStatus/tests/utils/testUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const TASK_VALUES = [
odsCode: "C9Z1O",
lineItemID: "6989b7bd-8db6-428c-a593-4022e3044c00",
id: TASK_ID_0,
status: "in-progress",
status: "completed",
businessStatus: "Dispatched",
lastModified: "2023-09-11T10:11:12Z"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable max-len */

import {
expect,
Expand Down Expand Up @@ -211,42 +211,70 @@ describe("Unit tests for validation of NHS number", () => {
})

describe("Unit tests for validation of status against business status", () => {
it.each([
{
taskStatus: "completed",
businessStatus: "With Pharmacy",
expected: "Completed state indicated for a prescription status requiring patient action."
},
{
taskStatus: "completed",
businessStatus: "Ready to collect",
expected: "Completed state indicated for a prescription status requiring patient action."
},
{
taskStatus: "completed",
businessStatus: "ReAdY tO cOlLeCt",
expected: "Completed state indicated for a prescription status requiring patient action."
},
{
taskStatus: "in-progress",
businessStatus: "With Pharmacy",
expected: undefined
},
{
taskStatus: "in-progress",
businessStatus: "Ready to collect",
expected: undefined
}
])(
"When status is '$status' and business status is '$businessStatus', should return expected issue.",
async ({taskStatus, businessStatus, expected}) => {
const task = {status: taskStatus, businessStatus: {coding: [{code: businessStatus}]}}
describe("When task status is 'completed'", () => {
it.each([
{isValid: false, businessStatus: "With Pharmacy"},
{isValid: false, businessStatus: "With Pharmacy - preparing remainder"},
{isValid: false, businessStatus: "Ready to collect"},
{isValid: false, businessStatus: "ReAdY tO cOlLeCt"},
{isValid: false, businessStatus: "Ready to collect - partial"},
{isValid: false, businessStatus: "rEaDy To ColLEcT - pArtIAl"},
{isValid: true, businessStatus: "Collected"},
{isValid: true, businessStatus: "Not dispensed"},
{isValid: true, businessStatus: "Dispatched"},
{isValid: true, businessStatus: "Ready to dispatch"},
{isValid: true, businessStatus: "Ready to dispatch - partial"}
])(
"When status is 'completed' and business status is '$businessStatus', should return expected issue.",
({isValid, businessStatus}) => {
const task = {status: "completed", businessStatus: {coding: [{code: businessStatus}]}}
const actual = statuses(task as Task)
const expected = isValid
? undefined
: `Task.status field set to 'completed' but Task.businessStatus value of '${businessStatus}' requires follow up action.`
expect(actual).toEqual(expected)
}
)
})

const actual = statuses(task as Task)
describe("When task status is 'in-progress'", () => {
it.each([
{isValid: true, businessStatus: "With Pharmacy"},
{isValid: true, businessStatus: "With Pharmacy - preparing remainder"},
{isValid: true, businessStatus: "Ready to collect"},
{isValid: true, businessStatus: "Ready to collect - partial"},
{isValid: true, businessStatus: "Ready to dispatch"},
{isValid: true, businessStatus: "Ready to dispatch - partial"},
{isValid: false, businessStatus: "Collected"},
{isValid: false, businessStatus: "Not dispensed"},
{isValid: false, businessStatus: "Dispatched"}
])(
"When status is 'in-progress' and business status is '$businessStatus', should return expected issue.",
({isValid, businessStatus}) => {
const task = {status: "in-progress", businessStatus: {coding: [{code: businessStatus}]}}
const actual = statuses(task as Task)
const expected = isValid
? undefined
: `Task.status field set to 'in-progress' but Task.businessStatus value of '${businessStatus}' has no possible follow up action.`
expect(actual).toEqual(expected)
}
)
})

expect(actual).toEqual(expected)
}
)
describe("When business status is unsupported", () => {
it.each([
{status: "completed", businessStatus: "unsupported-status"},
{status: "in-progress", businessStatus: "another-unsupported-status"}
])(
"When status is '$status' and business status is '$businessStatus', should return unsupported issue.",
({status, businessStatus}) => {
const task = {status, businessStatus: {coding: [{code: businessStatus}]}}
const actual = statuses(task as Task)
const expected = `Unsupported Task.businessStatus '${businessStatus}'.`
expect(actual).toEqual(expected)
}
)
})
})

describe("Unit tests for validation of resourceType", () => {
Expand Down Expand Up @@ -287,7 +315,8 @@ describe("Unit tests for validation of transaction bundle", () => {
type: "transaction",
expected: true
}
])("When resourceType is $resourceType and type is $type, should return $expected.",
])(
"When resourceType is $resourceType and type is $type, should return $expected.",
async ({resourceType, type, expected}) => {
const body = {resourceType: resourceType, type: type}

Expand All @@ -299,15 +328,13 @@ describe("Unit tests for validation of transaction bundle", () => {
})

describe("Unit tests for validation of businessStatus", () => {
it.each(BUSINESS_STATUSES)("When businessStatus is valid, should return undefined.",
async (status) => {
const task = {businessStatus: {coding: [{code: status}]}}
it.each(BUSINESS_STATUSES)("When businessStatus is valid, should return undefined.", async (status) => {
const task = {businessStatus: {coding: [{code: status}]}}

const actual = businessStatus(task as Task)
const actual = businessStatus(task as Task)

expect(actual).toEqual(undefined)
}
)
expect(actual).toEqual(undefined)
})

it("When businessStatus is invalid, should return expected message.", async () => {
const task = {businessStatus: {coding: [{code: "Invalid"}]}}
Expand Down