From f057b303a78cf7b0d82e3ba23fac34fa05bbc0a4 Mon Sep 17 00:00:00 2001 From: Shivank Kacker Date: Tue, 6 Aug 2024 16:35:11 +0530 Subject: [PATCH] Added support for Investigations, and Prescriptions --- src/Components/Patient/DailyRounds.tsx | 328 +++++++++++++++---------- src/Components/Scribe/formDetails.ts | 75 ++++-- 2 files changed, 251 insertions(+), 152 deletions(-) diff --git a/src/Components/Patient/DailyRounds.tsx b/src/Components/Patient/DailyRounds.tsx index 3482fefc8f9..31c91ecf8dc 100644 --- a/src/Components/Patient/DailyRounds.tsx +++ b/src/Components/Patient/DailyRounds.tsx @@ -47,6 +47,7 @@ import useAuthUser from "../../Common/hooks/useAuthUser"; import CheckBoxFormField from "../Form/FormFields/CheckBoxFormField"; import SymptomsApi from "../Symptoms/api"; import DiagnosesRoutes from "../Diagnosis/routes"; +import MedicineRoutes from "../Medicine/routes"; const Loading = lazy(() => import("../Common/Loading")); @@ -56,6 +57,8 @@ export const DailyRounds = (props: any) => { const { goBack } = useAppHistory(); const { facilityId, patientId, consultationId, id } = props; const [symptomsSeed, setSymptomsSeed] = useState(1); + const [diagnosisSeed, setDiagnosesSeed] = useState(1); + const [prescriptionSeed, setPrescriptionSeed] = useState(1); const initForm: any = { physical_examination_info: "", @@ -170,7 +173,7 @@ export const DailyRounds = (props: any) => { ...data, patient_category: data.patient_category ? PATIENT_CATEGORIES.find((i) => i.text === data.patient_category) - ?.id ?? "" + ?.id ?? "" : "", rhythm: (data.rhythm && @@ -492,13 +495,11 @@ export const DailyRounds = (props: any) => { }); if (res?.ok) setSymptomsSeed((s) => s + 1); } - rounds_type = "DOCTORS_LOG"; } // ICD11 Diagnosis if (fields.icd11_diagnosis) { for (const diagnosis of fields.icd11_diagnosis) { - // Fetch available diagnoses const { res: icdRes, data: icdData } = await request( @@ -506,7 +507,7 @@ export const DailyRounds = (props: any) => { { query: { query: diagnosis.diagnosis }, }, - ) + ); if (!icdRes?.ok) { error({ @@ -515,11 +516,11 @@ export const DailyRounds = (props: any) => { continue; } - const awailableDiagnosis = icdData?.[0]?.id; + const availableDiagnosis = icdData?.[0]?.id; - if (!awailableDiagnosis) { + if (!availableDiagnosis) { error({ - text: "Diagnosis not found", + text: "Could not find the requested diagnosis. Please enter manually.", }); continue; } @@ -528,20 +529,82 @@ export const DailyRounds = (props: any) => { DiagnosesRoutes.createConsultationDiagnosis, { pathParams: { consultation: consultationId }, - body: diagnosis, + body: { + ...diagnosis, + diagnosis: availableDiagnosis, + }, }, ); if (res?.ok) setDiagnoses((diagnoses) => [ ...(diagnoses || []), - fields.icd11_diagnosis, + { + ...diagnosis, + diagnosis_object: icdData?.[0], + }, ]); + setDiagnosesSeed((s) => s + 1); } - rounds_type = "DOCTORS_LOG"; } - if ("investigations" in fields) { + // Prescriptions + if (fields.prescriptions || fields.prn_prescriptions) { + const combined_prescriptions = [ + ...(fields.prescriptions || []), + ...(fields.prn_prescriptions || []), + ]; + for (const prescription of combined_prescriptions) { + // fetch medicine + const { res: medicineRes, data: medicineData } = await request( + routes.listMedibaseMedicines, + { + query: { query: prescription.medicine }, + }, + ); + + if (!medicineRes?.ok) { + error({ + text: "Failed to fetch medicine", + }); + continue; + } + + const availableMedicine = medicineData?.[0]?.id; + + if (!availableMedicine) { + error({ + text: "Could not find the requested medicine. Please enter manually.", + }); + continue; + } + + const { res } = await request( + MedicineRoutes.createPrescription, + { + pathParams: { consultation: consultationId }, + body: { + ...prescription, + medicine: availableMedicine, + }, + }, + ); + + if (res?.ok) setPrescriptionSeed((s) => s + 1); + } + } + + if ( + Object.keys(fields).some((f) => + [ + "investigations", + "icd11_diagnosis", + "additional_symptoms", + "prescriptions", + "prn_prescriptions", + ].includes(f), + ) + ) { rounds_type = "DOCTORS_LOG"; } @@ -655,124 +718,124 @@ export const DailyRounds = (props: any) => { {["NORMAL", "TELEMEDICINE", "DOCTORS_LOG"].includes( state.form.rounds_type, ) && ( - <> -

Vitals

- - - - - - - - - - - - option.desc} - optionValue={(option) => option.id} - /> - - - - ({ - label: level.text, - value: level.id, - }))} - optionDisplay={(option) => option.label} - optionValue={(option) => option.value} - unselectLabel="Unknown" - containerClassName="grid gap-1 grid-cols-1" - /> - - )} + <> +

Vitals

+ + + + + + + + + + + + option.desc} + optionValue={(option) => option.id} + /> + + + + ({ + label: level.text, + value: level.id, + }))} + optionDisplay={(option) => option.label} + optionValue={(option) => option.value} + unselectLabel="Unknown" + containerClassName="grid gap-1 grid-cols-1" + /> + + )} {state.form.rounds_type === "DOCTORS_LOG" && ( <> @@ -783,7 +846,10 @@ export const DailyRounds = (props: any) => { {/* */} {diagnoses ? ( - + ) : (
Fetching existing diagnosis of patient... @@ -824,6 +890,7 @@ export const DailyRounds = (props: any) => { discontinued={ showDiscontinuedPrescriptions ? undefined : false } + key={prescriptionSeed} actions={["discontinue"]} />
@@ -848,6 +915,7 @@ export const DailyRounds = (props: any) => { showDiscontinuedPrescriptions ? undefined : false } actions={["discontinue"]} + key={prescriptionSeed} /> diff --git a/src/Components/Scribe/formDetails.ts b/src/Components/Scribe/formDetails.ts index f9c7f41e15f..4cc96160f0e 100644 --- a/src/Components/Scribe/formDetails.ts +++ b/src/Components/Scribe/formDetails.ts @@ -5,10 +5,7 @@ import { RHYTHM_CHOICES, TELEMEDICINE_ACTIONS, } from "../../Common/constants"; -import routes from "../../Redux/api"; -import request from "../../Utils/request/request"; import { loadInvestigations } from "../Common/prescription-builder/InvestigationBuilder"; -import { ICD11DiagnosisModel } from "../Diagnosis/types"; import { SYMPTOM_CHOICES } from "../Symptoms/types"; import { Field, ScribeForm } from "./Scribe"; @@ -225,14 +222,14 @@ const DAILY_ROUND_FORM_SCRIBE_DATA: Field[] = [ example: "[{diagnosis: '4A42.0 Paediatric onset systemic sclerosis', verification_status: 'confirmed', is_principal: true}, {diagnosis: 2, verification_status: 'provisional', is_principal: false}]", description: - "A list of objects to store the patient's diagnosis along with their verification status and whether it is the principal diagnosis. By default set is_principal to false. NOTE: only one principal diagnosis can exist. The diagnosis field should be a string that may contain a corresponding diagnosis ID. The verification_status field should be a string with one of the following values: 'unconfirmed', 'provisional', 'differential', or 'confirmed'. The is_principal field should be a boolean value.", + "A list of objects to store the patient's diagnosis along with their verification status and whether it is the principal diagnosis. If not specifically said, set is_principal to false. NOTE: only one principal diagnosis can exist. The diagnosis field should be a string that may contain a corresponding diagnosis ID. The verification_status field should be a string with one of the following values: 'unconfirmed', 'provisional', 'differential', or 'confirmed'.", validator: (value) => { if (!Array.isArray(value)) return false; - value.forEach(d => { + value.forEach((d) => { if (!d.diagnosis || !d.verification_status) return false; }); return true; - } + }, }, { friendlyName: "Investigations", @@ -274,12 +271,58 @@ const DAILY_ROUND_FORM_SCRIBE_DATA: Field[] = [ friendlyName: "Prescriptions", id: "prescriptions", type: `{ - + base_dosage: number + " " + ("mg" | "g" | "ml" | "drop(s)" | "ampule(s)" | "tsp" | "mcg" | "unit(s)"), + days: number, + dosage_type: "REGULAR" | "TITRATED", + frequency: "STAT" | "OD" | "HS" | "BD" | "TID" | "QID" | "Q4H" | "QOD" | "QWK", + medicine: string, + notes: string, + route: "ORAL" | "IV" | "IM" | "SC" | "INHALATION" | "NASOGASTRIC" | "INTRATHECAL" | "TRANSDERMAL" | "RECTAL" | "SUBLINGUAL", + instruction_on_titration: string, + target_dosage: number + " " + ("mg" | "g" | "ml" | "drop(s)" | "ampule(s)" | "tsp" | "mcg" | "unit(s)"), }[]`, default: [], - example: "", - description: "Leave blank.", - validator: () => { + example: `[ + {base_dosage: "5 ampule(s)", days: 7, dosage_type: "REGULAR", frequency: "STAT", medicine: "DOLO", notes: "Give with water", route: "ORAL"}, + {base_dosage: "7 ml", days: 3, dosage_type: "TITRATED", frequency: "Q4H", medicine: "Albumin", route: "INHALATION", instruction_on_titration: "Example", target_dosage: "40 ml"}, + ]`, + description: `A list of objects to store the patient's prescriptions. The prescription can be regular or titrated. If titrated, the prescription should also include instruction_on_titration, and a target_dosage. NOTE: target_dosage should have the same unit as base_dosage. + The frequency should be any of the mentioned ones. They are short for: + STAT: Imediately, + OD: Once daily, + HS: Night Only, + BD: Twice Daily, + TID: 8th Hourly, + QID: 6th Hourly, + Q4H: 4th Hourly, + QOD: Alternate Day, + QWK: Once a Week + `, + validator: (value) => { + if (!Array.isArray(value)) return false; + return true; + }, + }, + { + friendlyName: "PRN Prescriptions", + id: "prn_prescriptions", + type: `{ + base_dosage: number + " " + ("mg" | "g" | "ml" | "drop(s)" | "ampule(s)" | "tsp" | "mcg" | "unit(s)"), + dosage_type: "PRN", + medicine: string, + notes: string, + route: "ORAL" | "IV" | "IM" | "SC" | "INHALATION" | "NASOGASTRIC" | "INTRATHECAL" | "TRANSDERMAL" | "RECTAL" | "SUBLINGUAL", + indicator: string, + min_hours_between_doses: number, + max_dosage: number + " " + ("mg" | "g" | "ml" | "drop(s)" | "ampule(s)" | "tsp" | "mcg" | "unit(s)"), + }[]`, + default: [], + example: `[ + {base_dosage: "3 drop(s)", dosage_type:"PRN", indicator: "If patient gets fever", max_dosage: "5 drops(s)", min_hours_between_doses: 12, route: "IV", medicine: "Glentona", notes: "Example"} + ]`, + description: "A list of objects to store the patient's PRN prescriptions.", + validator: (value) => { + if (!Array.isArray(value)) return false; return true; }, }, @@ -315,18 +358,6 @@ export const SCRIBE_FORMS: { [key: string]: ScribeForm } = { id: "daily_round", name: "Daily Round", fields: async () => { - const { res, data } = await request(routes.listICD11Diagnosis, { - silent: true, - }); - let icd11Diagnoses: ICD11DiagnosisModel[] = []; - - if (res?.ok && data) icd11Diagnoses = data; - - const icd11DiagnosisOptions = icd11Diagnoses?.map((diagnosis) => ({ - id: diagnosis.id, - text: diagnosis.label, - })); - const investigations = await loadInvestigations(); return DAILY_ROUND_FORM_SCRIBE_DATA.map((field) => {