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

Fix: [AEA-4170] - Added mapping for all item statuses in CPSU format 1 #443

Merged
merged 3 commits into from
Jun 26, 2024
Merged
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
49 changes: 18 additions & 31 deletions packages/cpsuLambda/src/schema/format_1/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,17 @@ import {
requestType,
deliveryType
} from "./request"
import {
Err,
Just,
Maybe,
Ok,
Result,
get
} from "pratica"
import {Ok, Result} from "pratica"
import {v4 as uuidv4} from "uuid"
import {Transformer} from "../../handler"
import {Logger} from "@aws-lambda-powertools/logger"
import {wrap_with_status} from "../../utils"
import {Md5} from "ts-md5"

export const transformer: Transformer<requestType> = (requestBody, logger, headers) => {
export const transformer: Transformer<requestType> = (requestBody, _logger, headers) => {
const bundle_entry_template = generateTemplate(requestBody)

return requestBody.items
.map((item) => populateTemplate(bundle_entry_template, item, requestBody, logger))
.map((item) => populateTemplate(bundle_entry_template, item, requestBody))
.all_ok()
.map(bundle_entries)
.mapErr(wrap_with_status(400, headers))
Expand Down Expand Up @@ -86,22 +78,13 @@ function generateTemplate(requestBody: requestType): string {
function populateTemplate(
template: string,
prescriptionItem: itemType,
prescriptionDetails: requestType,
logger: Logger
prescriptionDetails: requestType
): Result<BundleEntry<Task>, string> {
const entry = JSON.parse(template) as BundleEntry<Task>

const businessStatus = getBusinessStatus(prescriptionDetails.deliveryType, prescriptionItem.status)
if (businessStatus.isNothing()) {
logger.info(
`Invalid business status on item ${prescriptionItem.itemID}.` +
`Unable to map delivery type ${prescriptionDetails.deliveryType} and item status ${prescriptionItem.status}`
)
return Err(`Invalid business status on item ${prescriptionItem.itemID}`)
} else {
entry.resource!.businessStatus!.coding![0].code = businessStatus.value()
}

entry.resource!.businessStatus!.coding![0].code = businessStatus
entry.resource!.status = TASK_STATUS_MAP[prescriptionItem.status]
entry.resource!.focus!.identifier!.value = prescriptionItem.itemID
entry.resource!.lastModified = prescriptionDetails.messageDate
Expand Down Expand Up @@ -153,27 +136,31 @@ function generate_uuid(prescriptionItem: itemType, prescriptionDetails: requestT
return uuidv4({random: seed})
}

export function getBusinessStatus(deliveryType: deliveryType, itemStatus: itemStatusType): Maybe<string> {
return get([itemStatus])(BUSINESS_STATUS_MAP).chain((status) => {
if (typeof status === "string") {
return Just(status)
}
return get([deliveryType])(status) as Maybe<string>
})
export function getBusinessStatus(deliveryType: deliveryType, itemStatus: itemStatusType): string {
let status = BUSINESS_STATUS_MAP[itemStatus]
if (typeof status === "string") {
return status
}
return status[deliveryType]
}

type DeliveryTypeMap = Partial<Record<deliveryType, string>>
type ItemStatusMap = Partial<Record<itemStatusType, string | DeliveryTypeMap>>
type DeliveryTypeMap = Record<deliveryType, string>
type ItemStatusMap = Record<itemStatusType, string | DeliveryTypeMap>
const BUSINESS_STATUS_MAP: ItemStatusMap = {
Pending: "With Pharmacy",
Owed: "With Pharmacy",
NotDispensed: "Not Dispensed",
Cancelled: "Not Dispensed",
Expired: "Not Dispensed",
ReadyForCollection: {
"Not known": "Ready to Collect",
"In-Store Collection": "Ready to Collect",
"Robot Collection": "Ready to Collect",
"Delivery required": "Ready to Dispatch"
},
PartOwed: "With Pharmacy - Preparing Remainder",
DispensingComplete: {
"Not known": "Collected",
"In-Store Collection": "Collected",
"Robot Collection": "Collected",
"Delivery required": "Dispatched"
Expand Down
8 changes: 4 additions & 4 deletions packages/cpsuLambda/tests/format_1/business_states.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,21 @@ it("should convert a delivery type business status", () => {
const deliveryType: deliveryType = "Robot Collection"

const businessStatus = getBusinessStatus(deliveryType, itemStatus)
expect(businessStatus.value()).toEqual("Ready to Collect")
expect(businessStatus).toEqual("Ready to Collect")
})

it("should convert an item status business status", () => {
const itemStatus: itemStatusType = "NotDispensed"
const deliveryType: deliveryType = "Robot Collection"

const businessStatus = getBusinessStatus(deliveryType, itemStatus)
expect(businessStatus.value()).toEqual("Not Dispensed")
expect(businessStatus).toEqual("Not Dispensed")
})

it("should return Nothing if the item status is not in the map", () => {
it("should map the Expired status", () => {
const itemStatus: itemStatusType = "Expired"
const deliveryType: deliveryType = "Robot Collection"

const businessStatus = getBusinessStatus(deliveryType, itemStatus)
expect(businessStatus.isNothing()).toBeTruthy()
expect(businessStatus).toEqual("Not Dispensed")
})
29 changes: 0 additions & 29 deletions packages/cpsuLambda/tests/testHandler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,35 +193,6 @@ describe("format_1 handler", () => {
expect(responseBody).toEqual(expectedResponse)
})

test("Request with invalid business state returns 400", async () => {
const body = format_1_request()
body.items[0].status = "Expired"
body.deliveryType = "Robot Collection"

const event = {
headers: {},
body: body
}

const logger = new Logger({serviceName: "testService"})
const logger_info = jest.spyOn(logger, "info")

const handler = newHandler({
params: FORMAT_1_PARAMS,
middleware: [MIDDLEWARE.validator, MIDDLEWARE.validationErrorHandler],
logger: logger,
schema: format_1.eventSchema
})

const response = await handler(event as format_1.eventType, dummyContext)
expect(response.statusCode).toEqual(400)
expect(JSON.parse(response.body)).toEqual([`Invalid business status on item ${body.items[0].itemID}`])
expect(logger_info).toHaveBeenCalledWith(
`Invalid business status on item ${body.items[0].itemID}.` +
`Unable to map delivery type ${body.deliveryType} and item status ${body.items[0].status}`
)
})

test("Repeat messages are translated with matching UUIDs", async () => {
const event = {
headers: {},
Expand Down