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

(feat) Add ability to cancel orders #1640

Merged
merged 11 commits into from
Feb 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
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;
pirupius marked this conversation as resolved.
Show resolved Hide resolved
}

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}`);
pirupius marked this conversation as resolved.
Show resolved Hide resolved
}, 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
Loading