From 347959b07d45ffa10fbe14dbf7da8872707c0ee5 Mon Sep 17 00:00:00 2001 From: Donald Kibet Date: Tue, 28 May 2024 16:21:47 +0300 Subject: [PATCH] (feat) O3-3259 Add ability to deduct stock items while performing dispensing medication (#107) * (chore) upgrade `@openmrs/esm-framework` version * (feat) O3-3259 Add ability to deduct stock items while performing dispensing * code reviews changes updated * code reviews changes --- src/config-schema.ts | 6 ++ src/forms/dispense-form.component.tsx | 63 ++++++++++++++--- .../stock-dispense.component.tsx | 63 +++++++++++++++++ src/forms/stock-dispense/stock.resource.tsx | 67 +++++++++++++++++++ src/location/location.resource.test.tsx | 1 + src/types.ts | 35 ++++++++++ 6 files changed, 226 insertions(+), 9 deletions(-) create mode 100644 src/forms/stock-dispense/stock-dispense.component.tsx create mode 100644 src/forms/stock-dispense/stock.resource.tsx diff --git a/src/config-schema.ts b/src/config-schema.ts index 0aa1126..9d32cd0 100644 --- a/src/config-schema.ts +++ b/src/config-schema.ts @@ -121,6 +121,11 @@ export const configSchema = { }, }, }, + enableStockDispense: { + _type: Type.Boolean, + _description: 'Enable or disable stock deduction during the dispensing process. Requires the stock management module to be installed and configured.', + _default: false, +}, }; export interface PharmacyConfig { @@ -162,4 +167,5 @@ export interface PharmacyConfig { uuid: string; }; }; + enableStockDispense: boolean; } diff --git a/src/forms/dispense-form.component.tsx b/src/forms/dispense-form.component.tsx index 67c1203..3285f7c 100644 --- a/src/forms/dispense-form.component.tsx +++ b/src/forms/dispense-form.component.tsx @@ -11,7 +11,12 @@ import { import { Button, FormLabel, InlineLoading } from '@carbon/react'; import styles from './forms.scss'; import { closeOverlay } from '../hooks/useOverlay'; -import { type MedicationDispense, MedicationDispenseStatus, type MedicationRequestBundle } from '../types'; +import { + type MedicationDispense, + MedicationDispenseStatus, + type MedicationRequestBundle, + type InventoryItem, +} from '../types'; import { saveMedicationDispense } from '../medication-dispense/medication-dispense.resource'; import MedicationDispenseReview from './medication-dispense-review.component'; import { @@ -22,6 +27,8 @@ import { } from '../utils'; import { updateMedicationRequestFulfillerStatus } from '../medication-request/medication-request.resource'; import { type PharmacyConfig } from '../config-schema'; +import StockDispense from './stock-dispense/stock-dispense.component'; +import { createStockDispenseRequestPayload, sendStockDispenseRequest } from './stock-dispense/stock.resource'; interface DispenseFormProps { medicationDispense: MedicationDispense; @@ -45,6 +52,9 @@ const DispenseForm: React.FC = ({ const { patient, isLoading } = usePatient(patientUuid); const config = useConfig(); + // Keep track of inventory item + const [inventoryItem, setInventoryItem] = useState(); + // Keep track of medication dispense payload const [medicationDispensePayload, setMedicationDispensePayload] = useState(); @@ -78,6 +88,31 @@ const DispenseForm: React.FC = ({ } return response; }) + .then((response) => { + const { status } = response; + if ((config.enableStockDispense && status === 201) || status === 200) { + const stockDispenseRequestPayload = createStockDispenseRequestPayload( + inventoryItem, + patientUuid, + encounterUuid, + medicationDispensePayload, + ); + sendStockDispenseRequest(stockDispenseRequestPayload, abortController).then( + () => { + showToast({ + critical: true, + title: t('stockDispensed', 'Stock dispensed'), + kind: 'success', + description: t('stockDispensedSuccessfully', 'Stock dispensed successfully and batch level updated.'), + }); + }, + (error) => { + showToast({ title: 'Stock dispense error', kind: 'error', description: error?.message }); + }, + ); + } + return response; + }) .then( ({ status }) => { if (status === 201 || status === 200) { @@ -134,7 +169,9 @@ const DispenseForm: React.FC = ({ useEffect(() => setMedicationDispensePayload(medicationDispense), [medicationDispense]); // check is valid on any changes - useEffect(checkIsValid, [medicationDispensePayload, quantityRemaining]); + useEffect(checkIsValid, [medicationDispensePayload, quantityRemaining, inventoryItem]); + + const isButtonDisabled = (config.enableStockDispense ? !inventoryItem : false) || !isValid || isSubmitting; const bannerState = useMemo(() => { if (patient) { @@ -159,7 +196,6 @@ const DispenseForm: React.FC = ({ )} {patient && }
- {/* 1. {t("drug", "Drug")}*/} {t( config.dispenseBehavior.allowModifyingPrescription ? 'drugHelpText' : 'drugHelpTextNoEdit', @@ -169,18 +205,27 @@ const DispenseForm: React.FC = ({ )} {medicationDispensePayload ? ( - +
+ + {config.enableStockDispense && ( + + )} +
) : null}
-