@kenyaemr/esm-morgue-app 5.4.2-pre.2344 → 5.4.2-pre.2349

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/.turbo/turbo-build.log +21 -26
  2. package/dist/162.js +2 -0
  3. package/dist/162.js.map +1 -0
  4. package/dist/197.js +1 -1
  5. package/dist/221.js +1 -1
  6. package/dist/221.js.map +1 -1
  7. package/dist/293.js +1 -1
  8. package/dist/294.js +1 -1
  9. package/dist/300.js +1 -1
  10. package/dist/351.js +1 -0
  11. package/dist/351.js.map +1 -0
  12. package/dist/38.js +1 -1
  13. package/dist/38.js.map +1 -1
  14. package/dist/404.js +1 -0
  15. package/dist/404.js.map +1 -0
  16. package/dist/441.js +1 -0
  17. package/dist/441.js.map +1 -0
  18. package/dist/467.js +1 -1
  19. package/dist/467.js.map +1 -1
  20. package/dist/500.js +1 -0
  21. package/dist/500.js.map +1 -0
  22. package/dist/570.js +1 -0
  23. package/dist/570.js.map +1 -0
  24. package/dist/608.js +2 -0
  25. package/dist/608.js.map +1 -0
  26. package/dist/611.js +2 -0
  27. package/dist/611.js.map +1 -0
  28. package/dist/632.js +2 -1
  29. package/dist/632.js.map +1 -1
  30. package/dist/653.js +1 -1
  31. package/dist/653.js.map +1 -1
  32. package/dist/657.js +1 -0
  33. package/dist/657.js.map +1 -0
  34. package/dist/805.js +1 -1
  35. package/dist/805.js.map +1 -1
  36. package/dist/814.js +2 -0
  37. package/dist/814.js.LICENSE.txt +5 -0
  38. package/dist/814.js.map +1 -0
  39. package/dist/824.js +1 -1
  40. package/dist/824.js.map +1 -1
  41. package/dist/845.js +1 -0
  42. package/dist/845.js.map +1 -0
  43. package/dist/888.js +1 -0
  44. package/dist/888.js.map +1 -0
  45. package/dist/899.js +1 -0
  46. package/dist/899.js.map +1 -0
  47. package/dist/918.js +1 -1
  48. package/dist/918.js.map +1 -1
  49. package/dist/990.js +1 -0
  50. package/dist/990.js.map +1 -0
  51. package/dist/kenyaemr-esm-morgue-app.js +1 -1
  52. package/dist/kenyaemr-esm-morgue-app.js.buildmanifest.json +258 -184
  53. package/dist/kenyaemr-esm-morgue-app.js.map +1 -1
  54. package/dist/main.js +1 -1
  55. package/dist/main.js.LICENSE.txt +0 -6
  56. package/dist/main.js.map +1 -1
  57. package/dist/routes.json +1 -1
  58. package/package.json +1 -1
  59. package/src/bed/bed.component.tsx +63 -134
  60. package/src/bed/components/deceased-patient-card-header.component.tsx +73 -0
  61. package/src/bed/components/deceased-patient-info.component.tsx +47 -0
  62. package/src/bed/components/deceased-patient-status-footer.component.tsx +43 -0
  63. package/src/bed-layout/admitted/admitted-bed-layout.component.tsx +175 -96
  64. package/src/bed-layout/awaiting/awaiting-bed-layout.component.tsx +103 -36
  65. package/src/bed-layout/bed-layout.scss +4 -0
  66. package/src/bed-layout/discharged/discharged-bed-layout.component.tsx +131 -73
  67. package/src/bed-linelist-view/admitted/admitted-bed-linelist-view.component.tsx +182 -134
  68. package/src/bed-linelist-view/awaiting/awaiting-bed-linelist-view.component.tsx +115 -71
  69. package/src/bed-linelist-view/discharged/discharged-bed-line-view.component.tsx +181 -109
  70. package/src/config-schema.ts +140 -4
  71. package/src/context/deceased-person-context.tsx +33 -0
  72. package/src/extension/actionButton.component.tsx +1 -1
  73. package/src/forms/admit-deceased-person-workspace/admit-deceased-person.resource.ts +84 -166
  74. package/src/forms/admit-deceased-person-workspace/admit-deceased-person.scss +14 -0
  75. package/src/forms/admit-deceased-person-workspace/admit-deceased-person.workspace.tsx +504 -334
  76. package/src/forms/discharge-deceased-person-workspace/discharge-body.resource.ts +0 -1
  77. package/src/forms/discharge-deceased-person-workspace/discharge-body.scss +15 -0
  78. package/src/forms/discharge-deceased-person-workspace/discharge-body.workspace.tsx +303 -244
  79. package/src/helpers/expression-helper.ts +122 -0
  80. package/src/home/home.component.tsx +23 -4
  81. package/src/index.ts +0 -2
  82. package/src/metrics/metrics-card.component.tsx +2 -2
  83. package/src/routes.json +0 -6
  84. package/src/schemas/index.ts +243 -51
  85. package/src/summary/summary.component.tsx +16 -9
  86. package/src/switcher/content-switcher.component.tsx +61 -35
  87. package/src/switcher/content-switcher.scss +13 -0
  88. package/src/types/index.ts +43 -1
  89. package/translations/am.json +16 -6
  90. package/translations/en.json +16 -6
  91. package/translations/sw.json +16 -6
  92. package/dist/347.js +0 -1
  93. package/dist/347.js.map +0 -1
  94. package/dist/373.js +0 -2
  95. package/dist/373.js.map +0 -1
  96. package/dist/398.js +0 -1
  97. package/dist/398.js.map +0 -1
  98. package/dist/410.js +0 -1
  99. package/dist/410.js.map +0 -1
  100. package/dist/429.js +0 -2
  101. package/dist/429.js.map +0 -1
  102. package/dist/579.js +0 -2
  103. package/dist/579.js.map +0 -1
  104. package/dist/619.js +0 -1
  105. package/dist/619.js.map +0 -1
  106. package/dist/633.js +0 -1
  107. package/dist/633.js.map +0 -1
  108. package/dist/712.js +0 -1
  109. package/dist/712.js.map +0 -1
  110. package/dist/713.js +0 -1
  111. package/dist/713.js.map +0 -1
  112. package/dist/723.js +0 -1
  113. package/dist/723.js.map +0 -1
  114. package/dist/989.js +0 -2
  115. package/dist/989.js.map +0 -1
  116. package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.resource.ts +0 -18
  117. package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.scss +0 -84
  118. package/src/forms/dispose-deceased-person-workspace/dispose-deceased-person.workspace.tsx +0 -505
  119. /package/dist/{989.js.LICENSE.txt → 162.js.LICENSE.txt} +0 -0
  120. /package/dist/{373.js.LICENSE.txt → 608.js.LICENSE.txt} +0 -0
  121. /package/dist/{429.js.LICENSE.txt → 611.js.LICENSE.txt} +0 -0
  122. /package/dist/{579.js.LICENSE.txt → 632.js.LICENSE.txt} +0 -0
@@ -48,10 +48,10 @@ export const configSchema = {
48
48
  _description: 'UUID for next of kin relationship concept',
49
49
  _default: 'd0aa9fd1-2ac5-45d8-9c5e-4317c622c8f5',
50
50
  },
51
- nextOfKinAddressUuid: {
51
+ nextOfKinNationalIdUuid: {
52
52
  _type: Type.String,
53
- _description: 'UUID for next of kin address concept',
54
- _default: '7cf22bec-d90a-46ad-9f48-035952261294',
53
+ _description: 'UUID for next of kin national ID concept',
54
+ _default: '73d34479-2f9e-4de3-a5e6-1f79a17459bb',
55
55
  },
56
56
  nextOfKinPhoneUuid: {
57
57
  _type: Type.String,
@@ -118,6 +118,128 @@ export const configSchema = {
118
118
  _description: 'UUID for serial number concept',
119
119
  _default: '1646AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
120
120
  },
121
+ receivingAreaUuid: {
122
+ _type: Type.String,
123
+ _description: 'UUID for receiving area concept',
124
+ _default: '159495AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
125
+ },
126
+ reasonForTransferUuid: {
127
+ _type: Type.String,
128
+ _description: 'UUID for reason for transfer concept',
129
+ _default: '162720AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
130
+ },
131
+ locationOfDeathQuestionUuid: {
132
+ _type: Type.String,
133
+ _description: 'UUID for location of death question concept',
134
+ _default: '1541AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
135
+ },
136
+ locationOfDeathTypesList: {
137
+ _type: Type.Array,
138
+ _description: 'List of location of death types',
139
+ _default: [
140
+ {
141
+ concept: '1589AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
142
+ label: 'InPatient',
143
+ },
144
+ {
145
+ concept: '160473AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
146
+ label: 'Outpatient',
147
+ },
148
+ {
149
+ concept: '1601AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
150
+ label: 'Dead on arrival',
151
+ },
152
+ {
153
+ concept: '1536AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
154
+ label: 'Home',
155
+ },
156
+ {
157
+ concept: '1067AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
158
+ label: 'Unknown (Police case)',
159
+ },
160
+ ],
161
+ },
162
+ deathConfirmationTypes: {
163
+ _type: Type.Array,
164
+ _description: 'List of death confirmation types',
165
+ _default: [
166
+ {
167
+ concept: '1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
168
+ label: 'Yes',
169
+ },
170
+ {
171
+ concept: '1066AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
172
+ label: 'No',
173
+ },
174
+ ],
175
+ },
176
+ deathConfirmationQuestionUuid: {
177
+ _type: Type.String,
178
+ _description: 'UUID for death confirmation question concept',
179
+ _default: '165793AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
180
+ },
181
+ deathNotificationUuid: {
182
+ _type: Type.String,
183
+ _description: 'UUID for death notification concept',
184
+ _default: '162727AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
185
+ },
186
+ attendingClinicianUuid: {
187
+ _type: Type.String,
188
+ _description: 'UUID for attending clinician concept',
189
+ _default: '160632AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
190
+ },
191
+ doctorRemarksUuid: {
192
+ _type: Type.String,
193
+ _description: 'UUID for doctor remarks concept',
194
+ _default: '161011AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
195
+ },
196
+ causeOfDeathUuid: {
197
+ _type: Type.String,
198
+ _description: 'UUID for cause of death concept',
199
+ _default: '160218AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
200
+ },
201
+ deadBodyPreservationTypeUuid: {
202
+ _type: Type.Array,
203
+ _description: 'List of dead body preservation types',
204
+ _default: [
205
+ {
206
+ concept: 'bb78fcee-99c8-4073-9224-69c668917405',
207
+ label: 'Body embalment',
208
+ },
209
+ {
210
+ concept: '167231AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
211
+ label: 'Cold storage',
212
+ },
213
+ ],
214
+ },
215
+ deadBodyPreservationQuestionUuid: {
216
+ _type: Type.String,
217
+ _description: 'UUID for dead body preservation question concept',
218
+ _default: 'c67be9a5-f497-4082-af81-11753f65ed4b',
219
+ },
220
+ bodyEmbalmmentTypesUuid: {
221
+ _type: Type.Array,
222
+ _description: 'List of body embalmment types',
223
+ _default: [
224
+ {
225
+ concept: '166402AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
226
+ label: 'Arterial',
227
+ },
228
+ {
229
+ concept: '160494AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
230
+ label: 'Cavity',
231
+ },
232
+ {
233
+ concept: '151870AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
234
+ label: 'Hypodermic',
235
+ },
236
+ ],
237
+ },
238
+ autopsyPermissionUuid: {
239
+ _type: Type.String,
240
+ _description: 'UUID for autopsy permission concept',
241
+ _default: '1707AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
242
+ },
121
243
  };
122
244
 
123
245
  export interface BillingConfig {
@@ -151,7 +273,7 @@ export type ConfigObject = {
151
273
  morgueAdmissionEncounterTypeUuid: string;
152
274
  nextOfKinNameUuid: string;
153
275
  nextOfKinRelationshipUuid: string;
154
- nextOfKinAddressUuid: string;
276
+ nextOfKinNationalIdUuid: string;
155
277
  nextOfKinPhoneUuid: string;
156
278
  visitPaymentMethodAttributeUuid: string;
157
279
  policeStatementUuid: string;
@@ -167,4 +289,18 @@ export type ConfigObject = {
167
289
  autopsyEncounterFormUuid: string;
168
290
  courtOrderCaseNumberUuid: string;
169
291
  serialNumberUuid: string;
292
+ receivingAreaUuid: string;
293
+ reasonForTransferUuid: string;
294
+ locationOfDeathQuestionUuid: string;
295
+ locationOfDeathTypesList: Array<{ concept: string; label: string }>;
296
+ deathConfirmationTypes: Array<{ concept: string; label: string }>;
297
+ deathConfirmationQuestionUuid: string;
298
+ deathNotificationUuid: string;
299
+ attendingClinicianUuid: string;
300
+ doctorRemarksUuid: string;
301
+ causeOfDeathUuid: string;
302
+ deadBodyPreservationTypeUuid: Array<{ concept: string; label: string }>;
303
+ deadBodyPreservationQuestionUuid: string;
304
+ bodyEmbalmmentTypesUuid: Array<{ concept: string; label: string }>;
305
+ autopsyPermissionUuid: string;
170
306
  };
@@ -0,0 +1,33 @@
1
+ import React, { createContext, useContext, ReactNode } from 'react';
2
+ import { type Patient, type MortuaryPatient, type MortuaryLocationResponse, type EnhancedPatient } from '../types';
3
+
4
+ interface PatientContextValue {
5
+ mortuaryLocation: MortuaryLocationResponse | null;
6
+ isLoading: boolean;
7
+ mutate?: () => void;
8
+ onAdmit?: (patient: EnhancedPatient | MortuaryPatient | Patient) => void;
9
+ onPostmortem?: (patientUuid: string, bedInfo?: { bedNumber: string; bedId: number }) => void;
10
+ onDischarge?: (patientUuid: string, bedId?: number) => void;
11
+ onSwapCompartment?: (patientUuid: string, bedId?: number) => void;
12
+ onPrintGatePass?: (patient: EnhancedPatient | Patient, encounterDate?: string) => void;
13
+ onViewDetails?: (patientUuid: string, bedInfo?: { bedNumber: string; bedId: number }) => void;
14
+ }
15
+
16
+ const PatientContext = createContext<PatientContextValue | undefined>(undefined);
17
+
18
+ export const usePatientContext = () => {
19
+ const context = useContext(PatientContext);
20
+ if (context === undefined) {
21
+ throw new Error('usePatientContext must be used within a PatientProvider');
22
+ }
23
+ return context;
24
+ };
25
+
26
+ interface PatientProviderProps {
27
+ children: ReactNode;
28
+ value: PatientContextValue;
29
+ }
30
+
31
+ export const PatientProvider: React.FC<PatientProviderProps> = ({ children, value }) => (
32
+ <PatientContext.Provider value={value}>{children}</PatientContext.Provider>
33
+ );
@@ -22,7 +22,7 @@ const ActionButton: React.FC<ActionButtonProps> = ({ patientUuid }) => {
22
22
  <div className={styles.actionButton}>
23
23
  <UserHasAccess privilege="o3 : View Mortuary Dashboard">
24
24
  <Button kind="primary" size="sm" renderIcon={Return} onClick={handleNavigateToHomePage}>
25
- {t('allocation', 'Allocation View')}
25
+ {t('backToHome', 'Back to Home')}
26
26
  </Button>
27
27
  </UserHasAccess>
28
28
  </div>
@@ -19,9 +19,8 @@ import {
19
19
  type VisitTypeResponse,
20
20
  } from '../../types';
21
21
  import { useCallback, useMemo, useState } from 'react';
22
- import { deceasedPatientAdmitSchema, dischargeSchema, disposeSchema } from '../../schemas';
22
+ import { deceasedPatientAdmitSchema, dischargeFormSchema, DischargeType } from '../../schemas';
23
23
  import useSWRImmutable from 'swr/immutable';
24
-
25
24
  import { z } from 'zod';
26
25
  import dayjs from 'dayjs';
27
26
  import { customRepProps } from '../../constants';
@@ -118,118 +117,55 @@ export function removeQueuedPatient(
118
117
  export const useMortuaryOperation = (location?: string) => {
119
118
  const { currentProvider } = useSession();
120
119
  const { emrConfiguration, isLoadingEmrConfiguration, errorFetchingEmrConfiguration } = useEmrConfiguration();
121
- const {
122
- visitPaymentMethodAttributeUuid,
123
- tagNumberUuid,
124
- obNumberUuid,
125
- burialPermitNumberUuid,
126
- policeNameUuid,
127
- policeIDNumber,
128
- dischargeAreaUuid,
129
- serialNumberUuid,
130
- nextOfKinNameUuid,
131
- courtOrderCaseNumberUuid,
132
- morgueDischargeEncounterTypeUuid,
133
- morgueAdmissionEncounterTypeUuid,
134
- } = useConfig<ConfigObject>();
135
-
136
- const createDisposalMortuaryEncounter = useCallback(
137
- async (visit: Visit, data: z.infer<typeof disposeSchema>, encounterDateTime: Date) => {
138
- const obs = [];
139
-
140
- if (data.courtOrderCaseNumber && data.courtOrderCaseNumber.trim() !== '' && courtOrderCaseNumberUuid) {
141
- obs.push({
142
- concept: courtOrderCaseNumberUuid,
143
- value: data.courtOrderCaseNumber.trim(),
144
- });
145
- }
120
+ const config = useConfig<ConfigObject>();
146
121
 
147
- if (data.serialNumber && data.serialNumber.trim() !== '' && serialNumberUuid) {
148
- obs.push({
149
- concept: serialNumberUuid,
150
- value: data.serialNumber.trim(),
151
- });
152
- }
122
+ const createObservation = (conceptUuid: string | undefined, value: any, formatter?: (val: any) => any) => {
123
+ if (!conceptUuid || !value || (typeof value === 'string' && value.trim() === '')) {
124
+ return null;
125
+ }
153
126
 
154
- const encounterPayload = {
155
- encounterDatetime: encounterDateTime.toISOString(),
156
- patient: visit?.patient?.uuid,
157
- encounterType: morgueDischargeEncounterTypeUuid,
158
- location: visit?.location?.uuid,
159
- encounterProviders: [
160
- {
161
- provider: currentProvider?.uuid,
162
- encounterRole: emrConfiguration?.clinicianEncounterRole?.uuid,
163
- },
164
- ],
165
- visit: visit?.uuid,
166
- ...(obs.length > 0 && { obs }),
167
- };
127
+ const formattedValue = formatter ? formatter(value) : typeof value === 'string' ? value.trim() : value;
128
+ return { concept: conceptUuid, value: formattedValue };
129
+ };
168
130
 
169
- return openmrsFetch<Encounter>(`${restBaseUrl}/encounter`, {
170
- method: 'POST',
171
- headers: {
172
- 'content-type': 'application/json',
173
- },
174
- body: encounterPayload,
175
- });
176
- },
177
- [
178
- currentProvider?.uuid,
179
- emrConfiguration?.clinicianEncounterRole?.uuid,
180
- courtOrderCaseNumberUuid,
181
- serialNumberUuid,
182
- morgueDischargeEncounterTypeUuid,
183
- ],
184
- );
131
+ const getObservationMappings = (formData: z.infer<typeof deceasedPatientAdmitSchema>) => [
132
+ { uuid: config?.tagNumberUuid, value: formData?.tagNumber, formatter: undefined },
133
+ { uuid: config?.locationOfDeathQuestionUuid, value: formData?.placeOfDeath, formatter: undefined },
134
+ { uuid: config?.deathConfirmationQuestionUuid, value: formData?.deathConfirmed, formatter: undefined },
135
+ { uuid: config?.deathNotificationUuid, value: formData?.deathNotificationNumber, formatter: undefined },
185
136
 
186
- const createMortuaryAdmissionEncounter = useCallback(
187
- async (
188
- patientUuid: string,
189
- {
190
- availableCompartment,
191
- dateOfAdmission,
192
- insuranceScheme,
193
- dischargeArea,
194
- obNumber,
195
- paymentMethod,
196
- period,
197
- policeIDNo,
198
- policeName,
199
- tagNumber,
200
- visitType,
201
- }: z.infer<typeof deceasedPatientAdmitSchema>,
202
- ) => {
203
- const obs = [];
137
+ { uuid: config?.attendingClinicianUuid, value: formData?.attendingClinician, formatter: undefined },
138
+ { uuid: config?.doctorRemarksUuid, value: formData?.doctorsRemarks, formatter: undefined },
139
+ { uuid: config?.causeOfDeathUuid, value: formData?.causeOfDeath, formatter: undefined },
140
+ { uuid: config?.autopsyPermissionUuid, value: formData?.autopsyPermission, formatter: undefined },
141
+ { uuid: config?.deadBodyPreservationQuestionUuid, value: formData?.deadBodyPreservation, formatter: undefined },
142
+ { uuid: config?.deadBodyPreservationQuestionUuid, value: formData?.bodyEmbalmentType, formatter: undefined },
204
143
 
205
- if (tagNumber && tagNumber.trim() !== '' && tagNumberUuid) {
206
- obs.push({ concept: tagNumberUuid, value: tagNumber.trim() });
207
- }
208
- if (obNumber && obNumber.trim() !== '' && obNumberUuid) {
209
- obs.push({ concept: obNumberUuid, value: obNumber.trim() });
210
- }
211
- if (policeName && policeName.trim() !== '' && policeNameUuid) {
212
- obs.push({ concept: policeNameUuid, value: policeName.trim() });
213
- }
214
- if (policeIDNo && policeIDNo.trim() !== '' && policeIDNumber) {
215
- obs.push({ concept: policeIDNumber, value: policeIDNo.trim() });
216
- }
217
- if (dischargeArea && dischargeArea.trim() !== '' && dischargeAreaUuid) {
218
- obs.push({ concept: dischargeAreaUuid, value: dischargeArea.trim() });
219
- }
144
+ { uuid: config.obNumberUuid, value: formData.obNumber, formatter: undefined },
145
+ { uuid: config.policeNameUuid, value: formData.policeName, formatter: undefined },
146
+ { uuid: config.policeIDNumber, value: formData.policeIDNo, formatter: undefined },
147
+ ];
148
+
149
+ const createMortuaryAdmissionEncounter = useCallback(
150
+ async (patientUuid: string, formData: z.infer<typeof deceasedPatientAdmitSchema>) => {
151
+ const observationMappings = getObservationMappings(formData);
152
+ const obs = observationMappings
153
+ .map(({ uuid, value, formatter }) => createObservation(uuid, value, formatter))
154
+ .filter(Boolean);
220
155
 
221
156
  const visitAttributes = [];
222
157
  const encounterPayload = {
223
158
  visit: {
224
159
  patient: patientUuid,
225
- startDatetime: dayjs(dateOfAdmission).toISOString(),
226
- visitType: visitType,
160
+ startDatetime: dayjs(formData.dateOfAdmission).toISOString(),
161
+ visitType: formData.visitType,
227
162
  location: location,
228
163
  ...(visitAttributes.length > 0 && { attributes: visitAttributes }),
229
164
  },
230
165
  patient: patientUuid,
231
- encounterType: morgueAdmissionEncounterTypeUuid,
166
+ encounterType: config.morgueAdmissionEncounterTypeUuid,
232
167
  location,
168
+ encounterDatetime: dayjs(formData.dateOfAdmission).toISOString(),
233
169
  encounterProviders: [
234
170
  {
235
171
  provider: currentProvider?.uuid,
@@ -247,32 +183,43 @@ export const useMortuaryOperation = (location?: string) => {
247
183
  body: encounterPayload,
248
184
  });
249
185
  },
250
- [
251
- currentProvider?.uuid,
252
- dischargeAreaUuid,
253
- emrConfiguration?.admissionEncounterType?.uuid,
254
- emrConfiguration?.clinicianEncounterRole?.uuid,
255
- location,
256
- obNumberUuid,
257
- policeIDNumber,
258
- policeNameUuid,
259
- tagNumberUuid,
260
- morgueAdmissionEncounterTypeUuid,
261
- ],
186
+ [currentProvider?.uuid, emrConfiguration?.clinicianEncounterRole?.uuid, location, config],
262
187
  );
263
188
 
264
- const createDischargeMortuaryEncounter = useCallback(
265
- async (visit: Visit, data: z.infer<typeof dischargeSchema>, encounterDateTime: Date) => {
266
- const obs = [];
189
+ const getDischargeObservationMappings = (data: z.infer<typeof dischargeFormSchema>) => {
190
+ const baseFields = [
191
+ { uuid: config.burialPermitNumberUuid, value: data.burialPermitNumber },
192
+ { uuid: config.dischargeAreaUuid, value: data.dischargeArea },
193
+ ];
194
+
195
+ const transferFields =
196
+ data.dischargeType === 'transfer'
197
+ ? [
198
+ { uuid: config.receivingAreaUuid, value: data.receivingArea },
199
+ { uuid: config.reasonForTransferUuid, value: data.reasonForTransfer },
200
+ ]
201
+ : [];
202
+
203
+ const disposeFields =
204
+ data.dischargeType === 'dispose'
205
+ ? [
206
+ { uuid: config.serialNumberUuid, value: data.serialNumber },
207
+ { uuid: config.courtOrderCaseNumberUuid, value: data.courtOrderCaseNumber },
208
+ ]
209
+ : [];
210
+
211
+ return [...baseFields, ...transferFields, ...disposeFields];
212
+ };
267
213
 
268
- if (data.burialPermitNumber && data.burialPermitNumber.trim() !== '' && burialPermitNumberUuid) {
269
- obs.push({ concept: burialPermitNumberUuid, value: data.burialPermitNumber.trim() });
270
- }
214
+ const createDischargeEncounter = useCallback(
215
+ async (visit: Visit, data: z.infer<typeof dischargeFormSchema>, encounterDateTime: Date) => {
216
+ const observationMappings = getDischargeObservationMappings(data);
217
+ const obs = observationMappings.map(({ uuid, value }) => createObservation(uuid, value)).filter(Boolean);
271
218
 
272
219
  const encounterPayload = {
273
220
  encounterDatetime: encounterDateTime.toISOString(),
274
221
  patient: visit?.patient?.uuid,
275
- encounterType: morgueDischargeEncounterTypeUuid,
222
+ encounterType: config.morgueDischargeEncounterTypeUuid,
276
223
  location: visit?.location?.uuid,
277
224
  encounterProviders: [
278
225
  {
@@ -292,13 +239,9 @@ export const useMortuaryOperation = (location?: string) => {
292
239
  body: encounterPayload,
293
240
  });
294
241
  },
295
- [
296
- burialPermitNumberUuid,
297
- currentProvider?.uuid,
298
- emrConfiguration?.clinicianEncounterRole?.uuid,
299
- morgueDischargeEncounterTypeUuid,
300
- ],
242
+ [config, currentProvider?.uuid, emrConfiguration?.clinicianEncounterRole?.uuid],
301
243
  );
244
+
302
245
  const assignDeceasedToCompartment = useCallback(
303
246
  async (patientUuid: string, bedId: number, encounterUuid: string) =>
304
247
  openmrsFetch(`${restBaseUrl}/beds/${bedId}`, {
@@ -318,10 +261,8 @@ export const useMortuaryOperation = (location?: string) => {
318
261
  async (patientUuid: string, data: z.infer<typeof deceasedPatientAdmitSchema>) => {
319
262
  try {
320
263
  const admissionEncounter = await createMortuaryAdmissionEncounter(patientUuid, data);
321
-
322
- const encounterUuid = admissionEncounter?.data?.uuid || admissionEncounter?.data?.uuid;
264
+ const encounterUuid = admissionEncounter?.data?.uuid;
323
265
  const compartment = await assignDeceasedToCompartment(patientUuid, data.availableCompartment, encounterUuid);
324
-
325
266
  return { admissionEncounter, compartment };
326
267
  } catch (error) {
327
268
  throw error;
@@ -341,7 +282,6 @@ export const useMortuaryOperation = (location?: string) => {
341
282
  const endCurrentVisit = useCallback(
342
283
  async (currentVisit: Visit, queueEntry: MappedVisitQueueEntry, stopDateTime: Date) => {
343
284
  const abortController = new AbortController();
344
-
345
285
  const response = await updateVisit(
346
286
  currentVisit.uuid,
347
287
  {
@@ -363,50 +303,30 @@ export const useMortuaryOperation = (location?: string) => {
363
303
  );
364
304
 
365
305
  const dischargeBody = useCallback(
366
- async (visit: Visit, queueEntry: MappedVisitQueueEntry, bedId: number, data: z.infer<typeof dischargeSchema>) => {
306
+ async (
307
+ visit: Visit,
308
+ queueEntry: MappedVisitQueueEntry,
309
+ bedId: number,
310
+ data: z.infer<typeof dischargeFormSchema>,
311
+ ) => {
367
312
  try {
368
- const dischargeDateTime = parseDischargeDateTime({
369
- ...data,
370
- dateOfDischarge: data.dateOfDischarge ?? new Date(),
371
- });
372
-
373
- const dischargeEncounter = await createDischargeMortuaryEncounter(visit, data, dischargeDateTime);
374
-
313
+ const dischargeDateTime =
314
+ data.dischargeType === 'dispose'
315
+ ? new Date()
316
+ : parseDischargeDateTime({
317
+ ...data,
318
+ dateOfDischarge: data.dateOfDischarge ?? new Date(),
319
+ });
320
+
321
+ const dischargeEncounter = await createDischargeEncounter(visit, data, dischargeDateTime);
375
322
  const compartment = await removeDeceasedFromCompartment(visit?.patient?.uuid, bedId);
376
323
 
377
- const visitStopTime = new Date(dischargeDateTime.getTime() + 60000); // 1 minute after discharge
378
-
379
- await endCurrentVisit(visit, queueEntry, visitStopTime);
380
-
381
324
  return { dischargeEncounter, compartment };
382
325
  } catch (error) {
383
326
  throw error;
384
327
  }
385
328
  },
386
- [createDischargeMortuaryEncounter, endCurrentVisit, removeDeceasedFromCompartment, parseDischargeDateTime],
387
- );
388
- const disposeBody = useCallback(
389
- async (visit: Visit, queueEntry: MappedVisitQueueEntry, bedId: number, data: z.infer<typeof disposeSchema>) => {
390
- try {
391
- const disposalDateTime = parseDischargeDateTime({
392
- ...data,
393
- dateOfDischarge: data.dateOfDischarge ?? new Date(),
394
- });
395
-
396
- const disposeEncounter = await createDisposalMortuaryEncounter(visit, data, disposalDateTime);
397
-
398
- const compartment = await removeDeceasedFromCompartment(visit?.patient?.uuid, bedId);
399
-
400
- const visitStopTime = new Date(disposalDateTime.getTime() + 60000);
401
-
402
- await endCurrentVisit(visit, queueEntry, visitStopTime);
403
-
404
- return { disposeEncounter, compartment };
405
- } catch (error) {
406
- throw error;
407
- }
408
- },
409
- [createDisposalMortuaryEncounter, endCurrentVisit, removeDeceasedFromCompartment, parseDischargeDateTime],
329
+ [createDischargeEncounter, endCurrentVisit, removeDeceasedFromCompartment, parseDischargeDateTime],
410
330
  );
411
331
 
412
332
  const createEncounterForCompartmentSwap = useCallback(
@@ -441,8 +361,6 @@ export const useMortuaryOperation = (location?: string) => {
441
361
 
442
362
  return {
443
363
  admitBody,
444
- disposeBody,
445
- createDisposalMortuaryEncounter,
446
364
  createEncounterForCompartmentSwap,
447
365
  assignDeceasedToCompartment,
448
366
  removeDeceasedFromCompartment,
@@ -141,3 +141,17 @@
141
141
  .sectionField {
142
142
  padding-top: layout.$spacing-03;
143
143
  }
144
+ .radioButton {
145
+ padding: 0;
146
+ margin-top: layout.$spacing-03;
147
+ }
148
+
149
+ .radioButton:last-child {
150
+ margin-bottom: 0;
151
+ }
152
+
153
+ .supportingDocuments {
154
+ margin-top: layout.$spacing-05;
155
+ margin-bottom: layout.$spacing-05;
156
+ border-bottom: 1px solid colors.$gray-20;
157
+ }