Skip to content

Commit

Permalink
(feat) Add ability to cancel orders (openmrs#1640)
Browse files Browse the repository at this point in the history
* (feat) cancel order

* clean up

* pr changes, reload fixes and clean up

* translations

* wip cancel order via action

* mutate orders on cancel

* order mutations and pr comments

* fixes to labs

* button text change

* Fixup

* More tweaks

---------

Co-authored-by: Dennis Kigen <[email protected]>
  • Loading branch information
2 people authored and jnsereko committed Mar 4, 2024
1 parent 8b8f357 commit 75e40bd
Show file tree
Hide file tree
Showing 21 changed files with 916 additions and 248 deletions.
45 changes: 42 additions & 3 deletions packages/esm-patient-common-lib/src/orders/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { type OpenmrsResource } from '@openmrs/esm-framework';

export type OrderAction = 'NEW' | 'REVISE' | 'DISCONTINUE' | 'RENEW';

export interface OrderBasketItem {
action: 'NEW' | 'REVISE' | 'DISCONTINUE' | 'RENEW' | undefined;
action?: OrderAction;
display: string;
uuid?: string;
orderer?: string;
Expand All @@ -19,7 +21,7 @@ export interface OrderBasketItem {
}

export interface OrderPost {
action?: 'NEW' | 'REVISE' | 'DISCONTINUE';
action?: OrderAction;
patient?: string;
careSetting?: string;
orderer?: string;
Expand Down Expand Up @@ -53,7 +55,7 @@ export interface PatientOrderFetchResponse {

export interface Order {
uuid: string;
action: string;
action: OrderAction;
asNeeded: boolean;
asNeededCondition?: string;
autoExpireDate: string;
Expand Down Expand Up @@ -122,6 +124,7 @@ export interface Order {
clinicalHistory: string;
numberOfRepeats: string;
type: string;
labReferenceNumber?: string;
}

export interface OrderTypeFetchResponse {
Expand All @@ -145,3 +148,39 @@ export interface Drug {
}

export type PostDataPrepFunction = (order: OrderBasketItem, patientUuid: string, encounterUuid: string) => OrderPost;

// Adopted from @openmrs/esm-patient-medications-app package. We should consider maintaining a single shared types file
export interface DrugOrderBasketItem extends OrderBasketItem {
drug: Drug;
unit: any;
commonMedicationName: string;
dosage: number;
frequency: any;
route: any;
quantityUnits: any;
patientInstructions: string;
asNeeded: boolean;
asNeededCondition: string;
startDate: Date | string;
durationUnit: any;
duration: number | null;
pillsDispensed: number;
numRefills: number;
indication: string;
isFreeTextDosage: boolean;
freeTextDosage: string;
previousOrder?: string;
template?: any;
}

export interface LabOrderBasketItem extends OrderBasketItem {
testType?: {
label: string;
conceptUuid: string;
};
labReferenceNumber?: string;
urgency?: string;
instructions?: string;
previousOrder?: string;
orderReason?: string;
}
24 changes: 20 additions & 4 deletions packages/esm-patient-common-lib/src/orders/useOrders.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import useSWR, { mutate } from 'swr';
import useSWR, { useSWRConfig } from 'swr';
import { type FetchResponse, openmrsFetch, restBaseUrl } from '@openmrs/esm-framework';
import { useCallback, useMemo } from 'react';
import { type OrderTypeFetchResponse, type PatientOrderFetchResponse } from '@openmrs/esm-patient-common-lib';

export const careSettingUuid = '6f0c9a92-6f24-11e3-af88-005056821db0';

export function usePatientOrders(patientUuid: string, status: 'ACTIVE' | 'any', orderType?: string) {
const baseOrdersUrl = `${restBaseUrl}/order?v=full&patient=${patientUuid}&careSetting=${careSettingUuid}&status=${status}`;
export const drugCustomRepresentation =
'custom:(uuid,dosingType,orderNumber,accessionNumber,' +
'patient:ref,action,careSetting:ref,previousOrder:ref,dateActivated,scheduledDate,dateStopped,autoExpireDate,' +
'orderType:ref,encounter:ref,orderer:(uuid,display,person:(display)),orderReason,orderReasonNonCoded,orderType,urgency,instructions,' +
'commentToFulfiller,drug:(uuid,display,strength,dosageForm:(display,uuid),concept),dose,doseUnits:ref,' +
'frequency:ref,asNeeded,asNeededCondition,quantity,quantityUnits:ref,numRefills,dosingInstructions,' +
'duration,durationUnits:ref,route:ref,brandName,dispenseAsWritten)';

export function usePatientOrders(patientUuid: string, status?: 'ACTIVE' | 'any', orderType?: string) {
const { mutate } = useSWRConfig();
const baseOrdersUrl = `${restBaseUrl}/order?patient=${patientUuid}&careSetting=${careSettingUuid}&v=full&status=${status}`;
const ordersUrl = orderType ? `${baseOrdersUrl}&orderType=${orderType}` : baseOrdersUrl;

const { data, error, isLoading, isValidating } = useSWR<FetchResponse<PatientOrderFetchResponse>, Error>(
Expand All @@ -15,7 +24,10 @@ export function usePatientOrders(patientUuid: string, status: 'ACTIVE' | 'any',
);

const mutateOrders = useCallback(
() => mutate((key) => typeof key === 'string' && key.startsWith(`${restBaseUrl}/order?patient=${patientUuid}`)),
() =>
mutate((key) => {
return typeof key === 'string' && key.startsWith(`${restBaseUrl}/order?patient=${patientUuid}`);
}, data),
[patientUuid],
);

Expand Down Expand Up @@ -50,3 +62,7 @@ export function useOrderTypes() {
isValidating,
};
}

export function getDrugOrderByUuid(orderUuid: string) {
return openmrsFetch(`${restBaseUrl}/order/${orderUuid}?v=${drugCustomRepresentation}`);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import {
type DefaultWorkspaceProps,
launchPatientWorkspace,
type OrderBasketItem,
type LabOrderBasketItem,
} from '@openmrs/esm-patient-common-lib';
import { type LabOrderBasketItem } from '../api';
import { TestTypeSearch } from './test-type-search';
import { LabOrderForm } from './lab-order-form.component';
import styles from './add-lab-order.scss';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import React, { useCallback, useEffect, useState } from 'react';
import classNames from 'classnames';
import { type DefaultWorkspaceProps, launchPatientWorkspace, useOrderBasket } from '@openmrs/esm-patient-common-lib';
import {
type LabOrderBasketItem,
type DefaultWorkspaceProps,
launchPatientWorkspace,
promptBeforeClosing,
useOrderBasket,
} from '@openmrs/esm-patient-common-lib';
import { translateFrom, useLayoutType, useSession, useConfig } from '@openmrs/esm-framework';
import { careSettingUuid, type LabOrderBasketItem, prepLabOrderPostData, useOrderReasons } from '../api';
import { careSettingUuid, prepLabOrderPostData, useOrderReasons } from '../api';
import {
Button,
ButtonSet,
Expand Down Expand Up @@ -37,9 +43,7 @@ const labOrderFormSchema = z.object({
urgency: z.string().refine((value) => value !== '', {
message: translateFrom(moduleName, 'addLabOrderPriorityRequired', 'Priority is required'),
}),
labReferenceNumber: z.string().refine((value) => value !== '', {
message: translateFrom(moduleName, 'addLabOrderLabReferenceRequired', 'Lab reference number is required'),
}),
labReferenceNumber: z.string().optional(),
testType: z.object(
{ label: z.string(), conceptUuid: z.string() },
{
Expand Down Expand Up @@ -74,8 +78,6 @@ export function LabOrderForm({
mode: 'all',
resolver: zodResolver(labOrderFormSchema),
defaultValues: {
instructions: '',
labReferenceNumber: '',
...initialOrder,
},
});
Expand All @@ -87,6 +89,7 @@ export function LabOrderForm({

const handleFormSubmission = useCallback(
(data: LabOrderBasketItem) => {
data.action = 'NEW';
data.careSetting = careSettingUuid;
data.orderer = session.currentProvider.uuid;
const newOrders = [...orders];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { type LabOrderBasketItem } from '../api';
import { type LabOrderBasketItem } from '@openmrs/esm-patient-common-lib';
import { type TestType } from './useTestTypes';

// See the Urgency enum in https://github.com/openmrs/openmrs-core/blob/492dcd35b85d48730bd19da48f6db146cc882c22/api/src/main/java/org/openmrs/Order.java
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,13 @@ import { useTranslation } from 'react-i18next';
import { Button, ButtonSkeleton, Search, SkeletonText, Tile } from '@carbon/react';
import { ArrowRight, ShoppingCartArrowDown, ShoppingCartArrowUp } from '@carbon/react/icons';
import { useDebounce, useLayoutType, useSession, ResponsiveWrapper } from '@openmrs/esm-framework';
import { closeWorkspace, launchPatientWorkspace, useOrderBasket } from '@openmrs/esm-patient-common-lib';
import { type LabOrderBasketItem, prepLabOrderPostData } from '../api';
import {
type LabOrderBasketItem,
closeWorkspace,
launchPatientWorkspace,
useOrderBasket,
} from '@openmrs/esm-patient-common-lib';
import { prepLabOrderPostData } from '../api';
import { type TestType, useTestTypes } from './useTestTypes';
import { createEmptyLabOrder } from './lab-order';
import styles from './test-type-search.scss';
Expand Down
63 changes: 41 additions & 22 deletions packages/esm-patient-labs-app/src/lab-orders/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import useSWR, { mutate } from 'swr';
import { type FetchResponse, openmrsFetch, useConfig, restBaseUrl, showSnackbar } from '@openmrs/esm-framework';
import { type ConfigObject } from '../config-schema';
import { useCallback, useMemo } from 'react';
import { type OrderBasketItem, type OrderPost, type PatientOrderFetchResponse } from '@openmrs/esm-patient-common-lib';
import type { OrderPost, PatientOrderFetchResponse, LabOrderBasketItem } from '@openmrs/esm-patient-common-lib';
import useSWRImmutable from 'swr/immutable';

export const careSettingUuid = '6f0c9a92-6f24-11e3-af88-005056821db0';
Expand Down Expand Up @@ -69,29 +69,48 @@ export function useOrderReasons(conceptUuids: Array<string>) {

return { orderReasons: orderReasons, isLoading };
}
export interface LabOrderBasketItem extends OrderBasketItem {
testType?: {
label: string;
conceptUuid: string;
};
labReferenceNumber?: string;
urgency?: string;
instructions?: string;
orderReason?: string;
}

export function prepLabOrderPostData(order: LabOrderBasketItem, patientUuid: string, encounterUuid: string): OrderPost {
return {
action: 'NEW',
patient: patientUuid,
type: 'testorder',
careSetting: careSettingUuid,
orderer: order.orderer,
encounter: encounterUuid,
concept: order.testType.conceptUuid,
instructions: order.instructions,
orderReason: order.orderReason,
};
if (order.action === 'NEW' || order.action === 'RENEW') {
return {
action: 'NEW',
type: 'testorder',
patient: patientUuid,
careSetting: careSettingUuid,
orderer: order.orderer,
encounter: encounterUuid,
concept: order.testType.conceptUuid,
instructions: order.instructions,
orderReason: order.orderReason,
};
} else if (order.action === 'REVISE') {
return {
action: 'REVISE',
type: 'testorder',
patient: patientUuid,
careSetting: order.careSetting,
orderer: order.orderer,
encounter: encounterUuid,
concept: order.testType.conceptUuid,
instructions: order.instructions,
orderReason: order.orderReason,
previousOrder: order.previousOrder,
};
} else if (order.action === 'DISCONTINUE') {
return {
action: 'DISCONTINUE',
type: 'testorder',
patient: patientUuid,
careSetting: order.careSetting,
orderer: order.orderer,
encounter: encounterUuid,
concept: order.testType.conceptUuid,
orderReason: order.orderReason,
previousOrder: order.previousOrder,
};
} else {
throw new Error(`Unknown order action: ${order.action}.`);
}
}
const chunkSize = 10;
export function getConceptReferenceUrls(conceptUuids: Array<string>) {
Expand Down
Loading

0 comments on commit 75e40bd

Please sign in to comment.