diff --git a/src/config-schema.ts b/src/config-schema.ts index bb25ca3b..33fd5f9d 100644 --- a/src/config-schema.ts +++ b/src/config-schema.ts @@ -128,6 +128,8 @@ export const configSchema = { }; export interface PharmacyConfig { + checkDuplicateDispense: any; + enableDuplicateDispenseCheck: any; appName: string; actionButtons: { pauseButton: { diff --git a/src/forms/dispense-form.workspace.tsx b/src/forms/dispense-form.workspace.tsx index 4dfc2b8b..1255da9b 100644 --- a/src/forms/dispense-form.workspace.tsx +++ b/src/forms/dispense-form.workspace.tsx @@ -5,6 +5,7 @@ import { type DefaultWorkspaceProps, ExtensionSlot, getCoreTranslation, + showModal, showSnackbar, useConfig, usePatient, @@ -54,23 +55,38 @@ 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(); - - // whether or not the form is valid and ready to submit const [isValid, setIsValid] = useState(false); - - // to prevent duplicate submits const [isSubmitting, setIsSubmitting] = useState(false); - // Submit medication dispense form + const isDuplicateMedication = (dispense: MedicationDispense): boolean => { + const dispenses = medicationRequestBundle?.dispenses ?? []; + + return dispenses.some((existingDispense) => { + return ( + existingDispense.medicationCodeableConcept?.coding?.[0]?.code === + dispense.medicationCodeableConcept?.coding?.[0]?.code && + existingDispense.performer?.[0]?.actor?.reference === dispense.performer?.[0]?.actor?.reference && + existingDispense.quantity?.value === dispense.quantity?.value && + existingDispense.quantity?.code === dispense.quantity?.code && + existingDispense.dosageInstruction?.[0]?.doseAndRate?.[0]?.doseQuantity?.value === + dispense.dosageInstruction?.[0]?.doseAndRate?.[0]?.doseQuantity?.value && + existingDispense.dosageInstruction?.[0]?.doseAndRate?.[0]?.doseQuantity?.code === + dispense.dosageInstruction?.[0]?.doseAndRate?.[0]?.doseQuantity?.code && + existingDispense.dosageInstruction?.[0]?.route?.coding?.[0]?.code === + dispense.dosageInstruction?.[0]?.route?.coding?.[0]?.code && + existingDispense.dosageInstruction?.[0]?.timing?.code?.coding?.[0]?.code === + dispense.dosageInstruction?.[0]?.timing?.code?.coding?.[0]?.code + ); + }); + }; + const handleSubmit = () => { if (!isSubmitting) { setIsSubmitting(true); const abortController = new AbortController(); + saveMedicationDispense(medicationDispensePayload, MedicationDispenseStatus.completed, abortController) .then((response) => { if (response.ok) { @@ -81,9 +97,7 @@ const DispenseForm: React.FC = ({ ); if (getFulfillerStatus(medicationRequestBundle.request) !== newFulfillerStatus) { return updateMedicationRequestFulfillerStatus( - getUuidFromReference( - medicationDispensePayload.authorizingPrescription[0].reference, // assumes authorizing prescription exist - ), + getUuidFromReference(medicationDispensePayload.authorizingPrescription[0].reference), newFulfillerStatus, ); } @@ -148,6 +162,16 @@ const DispenseForm: React.FC = ({ } }; + const handleDuplicateMedication = () => { + const dispose = showModal('duplicate-prescription-modal', { + onClose: () => dispose(), + medicationName: medicationDispensePayload?.medicationCodeableConcept?.text || '', + onConfirm: () => { + handleSubmit(); + }, + }); + }; + const checkIsValid = () => { if ( medicationDispensePayload && @@ -160,9 +184,9 @@ const DispenseForm: React.FC = ({ medicationDispensePayload.dosageInstruction[0]?.doseAndRate[0]?.doseQuantity?.code && medicationDispensePayload.dosageInstruction[0]?.route?.coding[0].code && medicationDispensePayload.dosageInstruction[0]?.timing?.code.coding[0].code && - (!medicationDispensePayload.substitution.wasSubstituted || - (medicationDispensePayload.substitution.reason[0]?.coding[0].code && - medicationDispensePayload.substitution.type?.coding[0].code)) + (!medicationDispensePayload.substitution?.wasSubstituted || + (medicationDispensePayload.substitution.reason?.[0]?.coding?.[0]?.code && + medicationDispensePayload.substitution.type?.coding?.[0]?.code)) ) { setIsValid(true); } else { @@ -170,10 +194,7 @@ const DispenseForm: React.FC = ({ } }; - // initialize the internal dispense payload with the dispenses passed in as props useEffect(() => setMedicationDispensePayload(medicationDispense), [medicationDispense]); - - // check is valid on any changes useEffect(checkIsValid, [medicationDispensePayload, quantityRemaining, inventoryItem]); const isButtonDisabled = (config.enableStockDispense ? !inventoryItem : false) || !isValid || isSubmitting; @@ -232,7 +253,15 @@ const DispenseForm: React.FC = ({ - + + + + ); +}; + +export default DuplicatePrescriptionModal; diff --git a/src/index.ts b/src/index.ts index 08f79360..1bd64ec2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -45,6 +45,10 @@ export const pauseDispenseWorkspace = getAsyncLifecycle(() => import('./forms/pa export const printPrescriptionPreviewModal = getSyncLifecycle(PrescriptionPrintPreviewModal, options); export const deleteConfirmModal = getAsyncLifecycle(() => import('./history/delete-confrim.modal'), options); +export const duplicatePrescriptionModal = getAsyncLifecycle( + () => import('./forms/duplicate-prescription.modal'), + options, +); export const patientDiagnoses = getAsyncLifecycle(() => import('./diagnoses/diagnoses.component'), options); export const patientConditions = getAsyncLifecycle(() => import('./conditions/conditions.component'), options); diff --git a/src/location/location.resource.test.tsx b/src/location/location.resource.test.tsx index 3a2aa795..0e6b52e0 100644 --- a/src/location/location.resource.test.tsx +++ b/src/location/location.resource.test.tsx @@ -36,6 +36,8 @@ const pharmacyConfig: PharmacyConfig = { enableStockDispense: false, validateBatch: false, leftNavMode: 'collapsed', + checkDuplicateDispense: false, + enableDuplicateDispenseCheck: false, }; describe('Location Resource tests', () => { diff --git a/src/routes.json b/src/routes.json index 398399fb..4d27bf53 100644 --- a/src/routes.json +++ b/src/routes.json @@ -95,7 +95,10 @@ { "name": "delete-confirm-modal", "component": "deleteConfirmModal" - + }, + { + "name": "duplicate-prescription-modal", + "component": "duplicatePrescriptionModal" } ] } \ No newline at end of file