@kenyaemr/esm-ward-app 8.5.1-pre.25 → 8.5.1-pre.35

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 (61) hide show
  1. package/.turbo/turbo-build.log +12 -12
  2. package/dist/1352.js +2 -0
  3. package/dist/1352.js.map +1 -0
  4. package/dist/1580.js +2 -0
  5. package/dist/1580.js.map +1 -0
  6. package/dist/1879.js +1 -1
  7. package/dist/1879.js.map +1 -1
  8. package/dist/1917.js +1 -1
  9. package/dist/2557.js +1 -1
  10. package/dist/2557.js.map +1 -1
  11. package/dist/2932.js +1 -1
  12. package/dist/3365.js +1 -1
  13. package/dist/3365.js.map +1 -1
  14. package/dist/3423.js +1 -1
  15. package/dist/3423.js.map +1 -1
  16. package/dist/3737.js +1 -1
  17. package/dist/4300.js +1 -1
  18. package/dist/4430.js +1 -1
  19. package/dist/465.js +1 -1
  20. package/dist/465.js.map +1 -1
  21. package/dist/4743.js +1 -1
  22. package/dist/6012.js +1 -1
  23. package/dist/6012.js.map +1 -1
  24. package/dist/6871.js +2 -1
  25. package/dist/6871.js.LICENSE.txt +9 -0
  26. package/dist/6871.js.map +1 -1
  27. package/dist/7179.js +1 -1
  28. package/dist/7179.js.map +1 -1
  29. package/dist/7524.js +1 -1
  30. package/dist/7661.js +1 -1
  31. package/dist/7661.js.map +1 -1
  32. package/dist/8205.js +1 -1
  33. package/dist/9045.js +1 -1
  34. package/dist/9880.js +1 -1
  35. package/dist/9880.js.map +1 -1
  36. package/dist/kenyaemr-esm-ward-app.js +1 -1
  37. package/dist/kenyaemr-esm-ward-app.js.buildmanifest.json +95 -95
  38. package/dist/main.js +1 -1
  39. package/dist/main.js.map +1 -1
  40. package/dist/routes.json +1 -1
  41. package/package.json +1 -1
  42. package/src/config-schema.ts +84 -23
  43. package/src/hooks/useAdmissionLocation.ts +2 -2
  44. package/src/hooks/useInpatientAdmission.ts +1 -1
  45. package/src/ward-patients/admitted-patients.tsx +5 -6
  46. package/src/ward-patients/discharge-in-patients.tsx +12 -10
  47. package/src/ward-patients/patient-cells.tsx +91 -9
  48. package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.scss +34 -21
  49. package/src/ward-workspace/admit-patient-form-workspace/admit-patient-form.workspace.tsx +291 -66
  50. package/src/ward-workspace/admit-patient-form-workspace/diagnosis-input.component.tsx +42 -0
  51. package/src/ward-workspace/admit-patient-form-workspace/patient-admission.resources.ts +118 -0
  52. package/src/ward-workspace/bed-selector.component.tsx +11 -5
  53. package/src/ward-workspace/kenya-emr-patient-discharge/patient-discharge.resource.tsx +63 -0
  54. package/src/ward.resource.ts +2 -2
  55. package/translations/en.json +19 -1
  56. package/dist/2728.js +0 -2
  57. package/dist/2728.js.map +0 -1
  58. package/dist/2775.js +0 -2
  59. package/dist/2775.js.map +0 -1
  60. /package/dist/{2728.js.LICENSE.txt → 1352.js.LICENSE.txt} +0 -0
  61. /package/dist/{2775.js.LICENSE.txt → 1580.js.LICENSE.txt} +0 -0
@@ -1,17 +1,39 @@
1
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
- import { Button, ButtonSet, Column, Form, InlineNotification, Row } from '@carbon/react';
1
+ import {
2
+ Button,
3
+ ButtonSet,
4
+ Column,
5
+ ComboBox,
6
+ DatePicker,
7
+ DatePickerInput,
8
+ Dropdown,
9
+ Form,
10
+ InlineNotification,
11
+ RadioButton,
12
+ RadioButtonGroup,
13
+ Row,
14
+ Stack,
15
+ TextInput,
16
+ } from '@carbon/react';
3
17
  import { zodResolver } from '@hookform/resolvers/zod';
18
+ import { showSnackbar, useAppContext, useConfig } from '@openmrs/esm-framework';
19
+ import React, { useCallback, useEffect, useState } from 'react';
4
20
  import { Controller, useForm } from 'react-hook-form';
5
21
  import { useTranslation } from 'react-i18next';
6
- import { z } from 'zod';
7
- import { showSnackbar, useAppContext } from '@openmrs/esm-framework';
8
- import type { WardPatientWorkspaceProps, WardViewContext } from '../../types';
22
+ import { type WardConfigObject } from '../../config-schema';
9
23
  import { useAssignedBedByPatient } from '../../hooks/useAssignedBedByPatient';
10
- import { assignPatientToBed, removePatientFromBed, useAdmitPatient } from '../../ward.resource';
11
24
  import useWardLocation from '../../hooks/useWardLocation';
25
+ import type { WardPatientWorkspaceProps, WardViewContext } from '../../types';
26
+ import { assignPatientToBed, removePatientFromBed, useAdmitPatient } from '../../ward.resource';
12
27
  import BedSelector from '../bed-selector.component';
13
28
  import WardPatientWorkspaceBanner from '../patient-banner/patient-banner.component';
14
29
  import styles from './admit-patient-form.scss';
30
+ import DiagnosisInput from './diagnosis-input.component';
31
+ import {
32
+ formValuesToObs,
33
+ type InapatientAdmissionFormData,
34
+ inpatientAdmissionSchema,
35
+ useProviders,
36
+ } from './patient-admission.resources';
15
37
 
16
38
  /**
17
39
  * This form gets rendered when the user clicks "admit patient" in
@@ -27,7 +49,7 @@ const AdmitPatientFormWorkspace: React.FC<WardPatientWorkspaceProps> = ({
27
49
  }) => {
28
50
  const { patient, inpatientRequest, visit } = wardPatient ?? {};
29
51
  const dispositionType = inpatientRequest?.dispositionType ?? 'ADMIT';
30
-
52
+ const config = useConfig<WardConfigObject>();
31
53
  const { t } = useTranslation();
32
54
  const { location } = useWardLocation();
33
55
  const [isSubmitting, setIsSubmitting] = useState(false);
@@ -41,33 +63,32 @@ const AdmitPatientFormWorkspace: React.FC<WardPatientWorkspaceProps> = ({
41
63
  );
42
64
  const beds = isLoading ? [] : wardPatientGroupDetails?.bedLayouts ?? [];
43
65
 
44
- const zodSchema = useMemo(
45
- () =>
46
- z.object({
47
- bedId: z.number().optional(),
48
- }),
49
- [],
50
- );
51
-
52
- type FormValues = z.infer<typeof zodSchema>;
53
-
54
66
  const {
55
67
  control,
56
68
  formState: { errors, isDirty },
57
69
  handleSubmit,
58
- } = useForm<FormValues>({
59
- resolver: zodResolver(zodSchema),
70
+ watch,
71
+ } = useForm<InapatientAdmissionFormData>({
72
+ defaultValues: { admissionDate: new Date() },
73
+ resolver: zodResolver(inpatientAdmissionSchema),
60
74
  });
75
+ const { isLoading: isLoadingProviders, providers } = useProviders();
76
+ const [paymentMethodObservable, insuaranceTypeObservable, bedIdObservable] = watch([
77
+ 'paymentMode',
78
+ 'insuranceType',
79
+ 'bedId',
80
+ ]);
61
81
 
62
82
  useEffect(() => {
63
83
  promptBeforeClosing(() => isDirty);
64
84
  }, [isDirty, promptBeforeClosing]);
65
85
 
66
- const onSubmit = (values: FormValues) => {
86
+ const onSubmit = (values: InapatientAdmissionFormData) => {
67
87
  setShowErrorNotifications(false);
68
88
  setIsSubmitting(true);
69
89
  const bedSelected = beds.find((bed) => bed.bedId === values.bedId);
70
- admitPatient(patient, dispositionType, visit.uuid)
90
+ const obs = formValuesToObs(values, config);
91
+ admitPatient(patient, dispositionType, visit.uuid, obs)
71
92
  .then(
72
93
  async (response) => {
73
94
  if (response.ok) {
@@ -143,34 +164,232 @@ const AdmitPatientFormWorkspace: React.FC<WardPatientWorkspaceProps> = ({
143
164
  if (!wardPatientGroupDetails) return <></>;
144
165
 
145
166
  return (
146
- <div className={styles.flexWrapper}>
147
- <WardPatientWorkspaceBanner {...{ wardPatient }} />
148
- <Form control={control} className={styles.form} onSubmit={handleSubmit(onSubmit, onError)}>
149
- <div className={styles.formContent}>
150
- <Row>
151
- <Column>
152
- <h2 className={styles.productiveHeading02}>{t('selectABed', 'Select a bed')}</h2>
153
- <div className={styles.bedSelectionDropdown}>
154
- <Controller
155
- control={control}
156
- name="bedId"
157
- render={({ field: { onChange, value }, fieldState: { error } }) => {
158
- return (
159
- <BedSelector
160
- beds={beds}
161
- isLoadingBeds={isLoading}
162
- currentPatient={patient}
163
- selectedBedId={value}
164
- error={error}
165
- control={control}
166
- onChange={onChange}
167
- />
168
- );
167
+ <Form control={control} className={styles.form} onSubmit={handleSubmit(onSubmit, onError)}>
168
+ <Stack gap={4} className={styles.grid}>
169
+ <WardPatientWorkspaceBanner {...{ wardPatient }} />
170
+ <Column>
171
+ <Controller
172
+ control={control}
173
+ name="admissionDate"
174
+ render={({ field: { onChange, value }, fieldState: { error } }) => {
175
+ return (
176
+ <DatePicker
177
+ value={value}
178
+ datePickerType="single"
179
+ onChange={([date]) => {
180
+ onChange(date);
169
181
  }}
182
+ className={styles.datePickerInput}>
183
+ <DatePickerInput
184
+ id="admission-date"
185
+ labelText={t('admissionDate', 'Admission Date')}
186
+ placeholder="mm/dd/yyyy"
187
+ invalid={error?.message}
188
+ invalidText={error?.message}
189
+ />
190
+ </DatePicker>
191
+ );
192
+ }}
193
+ />
194
+ </Column>
195
+ <Column>
196
+ <DiagnosisInput control={control} name={'diagnosis'} />
197
+ </Column>
198
+ <Column>
199
+ <Controller
200
+ control={control}
201
+ name="primaryDoctor"
202
+ render={({ field: { onChange, value }, fieldState: { error } }) => {
203
+ return (
204
+ <ComboBox
205
+ id="primary-doctor"
206
+ invalid={error?.message}
207
+ helperText={isLoadingProviders ? 'Loading....' : undefined}
208
+ invalidText={error?.message}
209
+ itemToString={(provider) => providers.find((p) => p.uuid === provider)?.display ?? ''}
210
+ items={providers.map((p) => p.uuid)}
211
+ selectedItem={value}
212
+ onChange={({ selectedItem }) => onChange(selectedItem)}
213
+ placeholder={t('primaryDoctor', 'Primary Doctor')}
214
+ titleText={t('primaryDoctor', 'Primary Doctor')}
215
+ type="default"
170
216
  />
171
- </div>
217
+ );
218
+ }}
219
+ />
220
+ </Column>
221
+ <Column>
222
+ <Controller
223
+ control={control}
224
+ name="primaryDoctorPhoneNumber"
225
+ render={({ field, fieldState: { error } }) => {
226
+ return (
227
+ <TextInput
228
+ {...field}
229
+ invalid={error?.message}
230
+ invalidText={error?.message}
231
+ id="primary-doctor-phone-number"
232
+ labelText={t('primaryDoctorPhoneNumber', 'Primary doctor phone number')}
233
+ placeholder={t('phoneNumber', 'Phone number')}
234
+ size="md"
235
+ type="text"
236
+ />
237
+ );
238
+ }}
239
+ />
240
+ </Column>
241
+ <Column>
242
+ <Controller
243
+ control={control}
244
+ name="emergencyDoctor"
245
+ render={({ field: { onChange, value }, fieldState: { error } }) => {
246
+ return (
247
+ <ComboBox
248
+ id="emergency-doctor"
249
+ invalid={error?.message}
250
+ helperText={isLoadingProviders ? 'Loading....' : undefined}
251
+ invalidText={error?.message}
252
+ itemToString={(provider) => providers.find((p) => p.uuid === provider)?.display ?? ''}
253
+ items={providers.map((p) => p.uuid)}
254
+ selectedItem={value}
255
+ onChange={({ selectedItem }) => onChange(selectedItem)}
256
+ placeholder={t('emergencyDoctor', 'Emergence Doctor')}
257
+ titleText={t('emergencyDoctor', 'Emergency Doctor')}
258
+ type="default"
259
+ />
260
+ );
261
+ }}
262
+ />
263
+ </Column>
264
+ <Column>
265
+ <Controller
266
+ control={control}
267
+ name="emergencyDoctorPhoneNumber"
268
+ render={({ field, fieldState: { error } }) => {
269
+ return (
270
+ <TextInput
271
+ {...field}
272
+ invalid={error?.message}
273
+ invalidText={error?.message}
274
+ id="emergency-doctor-phone-number"
275
+ labelText={t('emergencyDoctorPhoneNumber', 'Emergency doctor phone number')}
276
+ placeholder={t('phoneNumber', 'Phone number')}
277
+ size="md"
278
+ type="text"
279
+ />
280
+ );
281
+ }}
282
+ />
283
+ </Column>
284
+ <Column>
285
+ <Controller
286
+ control={control}
287
+ name="paymentMode"
288
+ render={({ field: { onChange, value }, fieldState: { error } }) => {
289
+ return (
290
+ <RadioButtonGroup
291
+ legendText={t('paymentMode', 'Payment mode')}
292
+ name="payment-mode"
293
+ defaultSelected={value}
294
+ invalid={error?.message}
295
+ invalidText={error?.message}
296
+ onChange={onChange}
297
+ orientation="vertical">
298
+ <RadioButton
299
+ labelText={t('cash', 'Cash')}
300
+ value={config.conceptUuidForWardAdmission.cashPaymentMethod}
301
+ />
302
+ <RadioButton
303
+ labelText={t('mpesa', 'MPESA')}
304
+ value={config.conceptUuidForWardAdmission.mpesaPaymentMethod}
305
+ />
306
+ <RadioButton
307
+ labelText={t('insuarance', 'Insuarance')}
308
+ value={config.conceptUuidForWardAdmission.insurancePaymentMethod}
309
+ />
310
+ </RadioButtonGroup>
311
+ );
312
+ }}
313
+ />
314
+ </Column>
315
+ {paymentMethodObservable === config.conceptUuidForWardAdmission.insurancePaymentMethod && (
316
+ <Column>
317
+ <Controller
318
+ control={control}
319
+ name="insuranceType"
320
+ render={({ field: { onChange, value }, fieldState: { error } }) => {
321
+ return (
322
+ <Dropdown
323
+ invalid={error?.message}
324
+ invalidText={error?.message}
325
+ selectedItem={value}
326
+ onChange={({ selectedItem }) => onChange(selectedItem)}
327
+ id="insurance-type"
328
+ itemToString={(concept) =>
329
+ config.insuaranceTypes.find((type) => type.concept === concept)?.label ?? ''
330
+ }
331
+ items={config.insuaranceTypes.map((type) => type.concept)}
332
+ label={t('insuranceType', 'Insurance type')}
333
+ titleText={t('insuranceType', 'Insurance type')}
334
+ type="default"
335
+ />
336
+ );
337
+ }}
338
+ />
339
+ </Column>
340
+ )}
341
+ {paymentMethodObservable === config.conceptUuidForWardAdmission.insurancePaymentMethod &&
342
+ insuaranceTypeObservable === config.conceptUuidForWardAdmission.otherInsuaranceType && (
343
+ <Column>
344
+ <Controller
345
+ control={control}
346
+ name="otherInsuranceType"
347
+ render={({ field, fieldState: { error } }) => {
348
+ return (
349
+ <TextInput
350
+ {...field}
351
+ invalid={error?.message}
352
+ invalidText={error?.message}
353
+ id="other-insurance-type"
354
+ labelText={t('otherInsuranceType', 'Other Insurance Type')}
355
+ placeholder={t('pleaseSpecify', 'Please specify')}
356
+ size="md"
357
+ type="text"
358
+ />
359
+ );
360
+ }}
361
+ />
172
362
  </Column>
173
- </Row>
363
+ )}
364
+ <Column>
365
+ <Controller
366
+ control={control}
367
+ name="bedId"
368
+ render={({ field: { onChange, value }, fieldState: { error } }) => {
369
+ return (
370
+ <BedSelector
371
+ beds={beds}
372
+ isLoadingBeds={isLoading}
373
+ currentPatient={patient}
374
+ selectedBedId={value}
375
+ error={error}
376
+ control={control}
377
+ onChange={onChange}
378
+ />
379
+ );
380
+ }}
381
+ />
382
+ </Column>
383
+ <Column>
384
+ <TextInput
385
+ value={beds?.find((b) => b.bedId === bedIdObservable)?.bedType?.displayName ?? ''}
386
+ readOnly
387
+ labelText={t('bedType', 'Bed type')}
388
+ placeholder={t('notConfigured', 'Bed type not configured')}
389
+ />
390
+ </Column>
391
+
392
+ <Column>
174
393
  <div className={styles.errorNotifications}>
175
394
  {showErrorNotifications &&
176
395
  Object.entries(errors).map(([key, value]) => {
@@ -183,26 +402,32 @@ const AdmitPatientFormWorkspace: React.FC<WardPatientWorkspaceProps> = ({
183
402
  );
184
403
  })}
185
404
  </div>
186
- </div>
187
- <ButtonSet className={styles.buttonSet}>
188
- <Button size="xl" kind="secondary" onClick={() => closeWorkspace({ ignoreChanges: true })}>
189
- {t('cancel', 'Cancel')}
190
- </Button>
191
- <Button
192
- type="submit"
193
- size="xl"
194
- disabled={
195
- isSubmitting ||
196
- isLoadingEmrConfiguration ||
197
- errorFetchingEmrConfiguration ||
198
- isLoading ||
199
- isLoadingBedsAssignedToPatient
200
- }>
201
- {!isSubmitting ? t('admit', 'Admit') : t('admitting', 'Admitting...')}
202
- </Button>
203
- </ButtonSet>
204
- </Form>
205
- </div>
405
+ </Column>
406
+ </Stack>
407
+
408
+ <ButtonSet className={styles.buttonSet}>
409
+ <Button
410
+ className={styles.button}
411
+ size="xl"
412
+ kind="secondary"
413
+ onClick={() => closeWorkspace({ ignoreChanges: true })}>
414
+ {t('cancel', 'Cancel')}
415
+ </Button>
416
+ <Button
417
+ className={styles.button}
418
+ type="submit"
419
+ size="xl"
420
+ disabled={
421
+ isSubmitting ||
422
+ isLoadingEmrConfiguration ||
423
+ errorFetchingEmrConfiguration ||
424
+ isLoading ||
425
+ isLoadingBedsAssignedToPatient
426
+ }>
427
+ {!isSubmitting ? t('admit', 'Admit') : t('admitting', 'Admitting...')}
428
+ </Button>
429
+ </ButtonSet>
430
+ </Form>
206
431
  );
207
432
  };
208
433
 
@@ -0,0 +1,42 @@
1
+ import { ComboBox } from '@carbon/react';
2
+ import React from 'react';
3
+ import { type Control, Controller, type Path } from 'react-hook-form';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { useDiagnoses } from './patient-admission.resources';
6
+
7
+ type Props<T> = {
8
+ control: Control<T>;
9
+ name: Path<T>;
10
+ };
11
+ const DiagnosisInput = <T,>({ control, name }: Props<T>) => {
12
+ const { t } = useTranslation();
13
+ const { diagnoses, onSearchTermChange, isLoading } = useDiagnoses();
14
+ return (
15
+ <Controller
16
+ control={control}
17
+ name={name}
18
+ render={({ field: { onChange, value }, fieldState: { error } }) => {
19
+ return (
20
+ <ComboBox
21
+ id="diagnosis"
22
+ invalid={error?.message}
23
+ invalidText={error?.message}
24
+ itemToString={(concept) => diagnoses.find((c) => c.uuid === concept)?.display ?? ''}
25
+ items={diagnoses.map((d) => d.uuid)}
26
+ placeholder={t('diagnosis', 'Diagnosis')}
27
+ titleText={t('majorComplaintOrDiagnosis', 'Major Complaint/Diagnosis')}
28
+ onInputChange={onSearchTermChange}
29
+ type="default"
30
+ selectedItem={value}
31
+ helperText={isLoading ? 'Loading....' : undefined}
32
+ onChange={({ selectedItem }) => {
33
+ onChange(selectedItem);
34
+ }}
35
+ />
36
+ );
37
+ }}
38
+ />
39
+ );
40
+ };
41
+
42
+ export default DiagnosisInput;
@@ -0,0 +1,118 @@
1
+ import { type Concept, restBaseUrl, useConfig, useDebounce, useOpenmrsFetchAll } from '@openmrs/esm-framework';
2
+ import { useMemo, useState } from 'react';
3
+ import z from 'zod';
4
+ import { type WardConfigObject } from '../../config-schema';
5
+ import dayjs from 'dayjs';
6
+ export const useDiagnoses = () => {
7
+ const { diagnosisConceptSourceUud } = useConfig<WardConfigObject>();
8
+ const [q, setQ] = useState('');
9
+ const debouncedSearchTerm = useDebounce(q, 500);
10
+ const rep =
11
+ 'custom:(uuid,name:(uuid,display),conceptClass:(uuid,display),setMembers,mappings:(conceptReferenceTerm:(code,name,display,conceptSource:(uuid))))';
12
+ const url = `${restBaseUrl}/concept?q=${debouncedSearchTerm}&v=${rep}&references=${diagnosisConceptSourceUud}`;
13
+ const { data, error, isLoading } = useOpenmrsFetchAll<Concept>(debouncedSearchTerm?.length >= 3 ? url : null);
14
+ const diagnoses = useMemo(
15
+ () =>
16
+ (data ?? [])
17
+ .filter(
18
+ (c) => c.mappings?.some((m) => m?.conceptReferenceTerm?.conceptSource?.uuid === diagnosisConceptSourceUud),
19
+ )
20
+ .map((c) => {
21
+ const code = c.mappings?.find(
22
+ (m) => m?.conceptReferenceTerm?.conceptSource?.uuid === diagnosisConceptSourceUud,
23
+ )?.conceptReferenceTerm?.code;
24
+
25
+ return {
26
+ display: `${code}-${c.name.display}`,
27
+ uuid: c.uuid,
28
+ };
29
+ }),
30
+ [data, diagnosisConceptSourceUud],
31
+ );
32
+ return {
33
+ diagnoses,
34
+ isLoading,
35
+ error,
36
+ searchTerm: q,
37
+ onSearchTermChange: setQ,
38
+ };
39
+ };
40
+
41
+ type Provider = {
42
+ uuid: string;
43
+ display: string;
44
+ };
45
+
46
+ export const useProviders = () => {
47
+ const url = `${restBaseUrl}/provider?v=custom:(uuid,display)`;
48
+ const { data, error, isLoading } = useOpenmrsFetchAll<Provider>(url);
49
+ return {
50
+ providers: data ?? [],
51
+ error,
52
+ isLoading,
53
+ };
54
+ };
55
+
56
+ export const inpatientAdmissionSchema = z.object({
57
+ bedId: z.number().optional(),
58
+ admissionDate: z.date({ coerce: true }),
59
+ diagnosis: z.string().optional(),
60
+ primaryDoctor: z.string().optional(),
61
+ primaryDoctorPhoneNumber: z.string().optional(),
62
+ emergencyDoctor: z.string().optional(),
63
+ emergencyDoctorPhoneNumber: z.string().optional(),
64
+ paymentMode: z.string().optional(),
65
+ insuranceType: z.string().optional(),
66
+ otherInsuranceType: z.string().optional(),
67
+ });
68
+
69
+ const formartDate = (date: Date) => {
70
+ return date ? dayjs(date).format('YYYY-MM-DD HH:mm:ss') : '';
71
+ };
72
+
73
+ export type InapatientAdmissionFormData = z.infer<typeof inpatientAdmissionSchema>;
74
+ export const formValuesToObs = (data: InapatientAdmissionFormData, config: WardConfigObject) => {
75
+ const obs = [
76
+ {
77
+ concept: config.conceptUuidForWardAdmission.admissionDateTime,
78
+ value: formartDate(data?.admissionDate),
79
+ },
80
+ {
81
+ concept: config.conceptUuidForWardAdmission.primaryDoctor,
82
+ value: data.primaryDoctor,
83
+ },
84
+ {
85
+ concept: config.conceptUuidForWardAdmission.chiefComplaint,
86
+ value: data.diagnosis,
87
+ },
88
+ {
89
+ concept: config.conceptUuidForWardAdmission.primaryDoctorPhoneNumber,
90
+ value: data.primaryDoctorPhoneNumber,
91
+ },
92
+ {
93
+ concept: config.conceptUuidForWardAdmission.emmergencyDoctor,
94
+ value: data.emergencyDoctor,
95
+ },
96
+ {
97
+ concept: config.conceptUuidForWardAdmission.emmergencyDoctorPhoneNumber,
98
+ value: data.emergencyDoctorPhoneNumber,
99
+ },
100
+ {
101
+ concept: config.conceptUuidForWardAdmission.paymentMethod,
102
+ value: data.paymentMode,
103
+ },
104
+ ];
105
+ if (data.paymentMode === config.conceptUuidForWardAdmission.insurancePaymentMethod) {
106
+ obs.push({
107
+ concept: config.conceptUuidForWardAdmission.insurancePaymentMethod,
108
+ value: data.insuranceType,
109
+ });
110
+ if (data.otherInsuranceType === config.conceptUuidForWardAdmission.otherInsuaranceType) {
111
+ obs.push({
112
+ concept: config.conceptUuidForWardAdmission.insuranceOtherSpecify,
113
+ value: data.otherInsuranceType,
114
+ });
115
+ }
116
+ }
117
+ return obs.filter((o) => Boolean(o.value));
118
+ };
@@ -22,6 +22,7 @@ interface BedDropdownItem {
22
22
  bedId: number;
23
23
  label: string;
24
24
  disabled: boolean;
25
+ bedType: string;
25
26
  }
26
27
 
27
28
  const BedSelector: React.FC<BedSelectorProps> = ({
@@ -43,14 +44,19 @@ const BedSelector: React.FC<BedSelectorProps> = ({
43
44
  bedLayout.patients.length === 0
44
45
  ? [t('emptyText', 'Empty')]
45
46
  : bedLayout.patients.map((patient) => patient?.person?.preferredName?.display);
46
- return [bedNumber, ...patients].join(' · ');
47
+ return [bedNumber, bedLayout?.bedType?.displayName ?? 'Type unconfigured', ...patients].join(' · ');
47
48
  };
48
49
 
49
50
  const bedDropdownItems: BedDropdownItem[] = [
50
- { bedId: 0, label: t('noBed', 'No bed'), disabled: false },
51
+ { bedId: 0, label: t('noBed', 'No bed'), bedType: '', disabled: false },
51
52
  ...beds.map((bed) => {
52
53
  const isPatientAssignedToBed = bed.patients.some((bedPatient) => bedPatient.uuid === currentPatient.uuid);
53
- return { bedId: bed.bedId, label: getBedRepresentation(bed), disabled: isPatientAssignedToBed };
54
+ return {
55
+ bedId: bed.bedId,
56
+ label: getBedRepresentation(bed),
57
+ bedType: bed?.bedType?.displayName ?? '',
58
+ disabled: isPatientAssignedToBed,
59
+ };
54
60
  }),
55
61
  ];
56
62
  const selectedItem = bedDropdownItems.find((bed) => bed.bedId === selectedBedId);
@@ -82,7 +88,7 @@ const BedSelector: React.FC<BedSelectorProps> = ({
82
88
  return (
83
89
  <Dropdown
84
90
  id="default"
85
- titleText=""
91
+ titleText={t('selectABed', 'Select a bed')}
86
92
  helperText=""
87
93
  label={!selectedItem && t('chooseAnOption', 'Choose an option')}
88
94
  items={bedDropdownItems}
@@ -101,7 +107,7 @@ const BedSelector: React.FC<BedSelectorProps> = ({
101
107
  onChange={onChange}
102
108
  invalid={!!error}
103
109
  invalidText={error?.message}>
104
- {bedDropdownItems.map(({ bedId, label, disabled }) => (
110
+ {bedDropdownItems.map(({ bedId, label, bedType, disabled }) => (
105
111
  <RadioButton
106
112
  key={bedId}
107
113
  labelText={label}