Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(feat) O3-2100: Unknown patient name and estimated D.O.B config #697

Merged
merged 25 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
577e366
(fix) unkown patient name and estimated dob config fix
Jexsie May 15, 2023
c138e52
Merge branch 'main' into name
Jexsie May 22, 2023
c776b59
Merge branch 'main' into name
Jexsie May 22, 2023
c1f33c7
Updated config schema for updation in config point for unknown name
vasharma05 May 24, 2023
c8bff81
Made the attribute Unknown patient as the only source of truth
vasharma05 May 24, 2023
edccc2c
BirthdateEstimation configuration added
vasharma05 May 25, 2023
64f7f3b
Fixed type
vasharma05 May 25, 2023
0f53971
Merge branch 'name' of https://github.com/Jexsie/openmrs-esm-patient-…
vasharma05 May 25, 2023
6b8e163
Review changes
vasharma05 May 25, 2023
8ecb7d3
Completed the configuration for estimated date of birth
vasharma05 May 30, 2023
6c3553b
Merge branch 'main' of https://www.github.com/openmrs/openmrs-esm-pat…
vasharma05 May 30, 2023
3a17e2a
Review changes
vasharma05 May 30, 2023
e8d2b6f
Fixed failing test
vasharma05 May 30, 2023
723d103
Merge branch 'main' into name
vasharma05 Jun 14, 2023
e156422
Merge branch 'main' of https://www.github.com/openmrs/openmrs-esm-pat…
vasharma05 Jul 5, 2023
5fae7e6
Review changes
vasharma05 Jul 7, 2023
686e76d
Update config-schema.ts
vasharma05 Jul 9, 2023
7bb8228
Update config-schema.ts
vasharma05 Jul 9, 2023
535d160
Merge branch 'main' into name
vasharma05 Jul 9, 2023
e8a19b0
Merge branch 'main' into name
vasharma05 Jul 11, 2023
25f8f0d
Review changes
vasharma05 Jul 11, 2023
913a326
Fix
vasharma05 Jul 11, 2023
27e490d
Update dob.component.tsx
vasharma05 Jul 11, 2023
379f1d0
Lint fixes
vasharma05 Jul 11, 2023
5e4094e
Merge branch 'main' into name
vasharma05 Jul 11, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions packages/esm-patient-registration-app/src/config-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export interface RegistrationConfig {
fieldConfigurations: {
name: {
displayMiddleName: boolean;
unidentifiedPatient: boolean;
allowUnidentifiedPatients: boolean;
vasharma05 marked this conversation as resolved.
Show resolved Hide resolved
defaultUnknownGivenName: string;
defaultUnknownFamilyName: string;
displayCapturePhoto: boolean;
Expand All @@ -52,6 +52,7 @@ export interface RegistrationConfig {
};
};
dateOfBirth: {
allowEstimatedDateOfBirth: boolean;
useEstimatedDateOfBirth: {
enabled: boolean;
dayOfMonth: number;
Expand Down Expand Up @@ -201,10 +202,10 @@ export const esmPatientRegistrationSchema = {
fieldConfigurations: {
name: {
displayMiddleName: { _type: Type.Boolean, _default: true },
unidentifiedPatient: {
allowUnidentifiedPatients: {
_type: Type.Boolean,
_default: true,
_description: 'Whether to allow patients to be registered without names.',
_description: 'Whether to allow registering unidentified patients.',
},
defaultUnknownGivenName: {
_type: Type.String,
Expand Down Expand Up @@ -296,10 +297,15 @@ export const esmPatientRegistrationSchema = {
},
},
dateOfBirth: {
allowEstimatedDateOfBirth: {
ibacher marked this conversation as resolved.
Show resolved Hide resolved
_type: Type.Boolean,
_description: 'Whether to allow estimated date of birth for a patient during registration',
_default: true,
},
useEstimatedDateOfBirth: {
enabled: {
_type: Type.Boolean,
_description: 'Whether to use custom day and month for estimated date of birth',
_description: 'Whether to use a fixed day and month for estimated date of birth',
_default: false,
},
dayOfMonth: {
Expand All @@ -309,7 +315,7 @@ export const esmPatientRegistrationSchema = {
},
month: {
_type: Type.Number,
_description: 'The custom month to use on the estimated date of birth i.e 0 = Jan 11 = Dec',
_description: 'The custom month to use on the estimated date of birth i.e 0 = Jan & 11 = Dec',
_default: 0,
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ export const DobField: React.FC = () => {
const { t } = useTranslation();
const {
fieldConfigurations: { dateOfBirth },
} = useConfig() as RegistrationConfig;
const [dobUnknown] = useField('birthdateEstimated');
const dobKnown = !dobUnknown.value;
} = useConfig<RegistrationConfig>();
const allowEstimatedBirthDate = dateOfBirth?.allowEstimatedDateOfBirth;
const [{ value: dobUnknown }] = useField('birthdateEstimated');
const [birthdate, birthdateMeta] = useField('birthdate');
const [yearsEstimated, yearsEstimateMeta] = useField('yearsEstimated');
const [monthsEstimated, monthsEstimateMeta] = useField('monthsEstimated');
Expand Down Expand Up @@ -75,17 +75,19 @@ export const DobField: React.FC = () => {
return (
<div className={styles.halfWidthInDesktopView}>
<h4 className={styles.productiveHeading02Light}>{t('birthFieldLabelText', 'Birth')}</h4>
<div className={styles.dobField}>
<div className={styles.dobContentSwitcherLabel}>
<span className={styles.label01}>{t('dobToggleLabelText', 'Date of Birth Known?')}</span>
{(allowEstimatedBirthDate || dobUnknown) && (
<div className={styles.dobField}>
<div className={styles.dobContentSwitcherLabel}>
<span className={styles.label01}>{t('dobToggleLabelText', 'Date of Birth Known?')}</span>
</div>
<ContentSwitcher onChange={onToggle} selectedIndex={dobUnknown ? 1 : 0}>
<Switch name="known" text={t('yes', 'Yes')} />
<Switch name="unknown" text={t('no', 'No')} />
</ContentSwitcher>
</div>
<ContentSwitcher onChange={onToggle}>
<Switch name="known" text={t('yes', 'Yes')} />
<Switch name="unknown" text={t('no', 'No')} />
</ContentSwitcher>
</div>
)}
<Layer>
{dobKnown ? (
{!dobUnknown ? (
<div className={styles.dobField}>
<DatePicker dateFormat={dateFormat} datePickerType="single" onChange={onDateChange} maxDate={format(today)}>
<DatePickerInput
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ jest.mock('@openmrs/esm-framework', () => {
return {
...originalModule,
useConfig: jest.fn().mockImplementation(() => ({
fieldConfigurations: { dateOfBirth: { useEstimatedDateOfBirth: { enabled: true, dayOfMonth: 0, month: 0 } } },
fieldConfigurations: {
dateOfBirth: {
allowEstimatedDateOfBirth: true,
useEstimatedDateOfBirth: { enabled: true, dayOfMonth: 0, month: 0 },
},
},
})),
};
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { PatientRegistrationContext } from '../../patient-registration-context';
import styles from '../field.scss';
import { RegistrationConfig } from '../../../config-schema';

export const unidentifiedPatientAttributeTypeUuid = '8b56eac7-5c76-4b9c-8c6f-1deab8d3fc47';
const containsNoNumbers = /^([^0-9]*)$/;

function checkNumber(value: string) {
Expand All @@ -19,17 +20,26 @@ function checkNumber(value: string) {
}

export const NameField = () => {
const { t } = useTranslation();
const { setCapturePhotoProps, currentPhoto, setFieldValue } = useContext(PatientRegistrationContext);
const {
fieldConfigurations: {
name: { displayCapturePhoto, displayReverseFieldOrder },
name: {
displayCapturePhoto,
allowUnidentifiedPatients,
defaultUnknownGivenName,
defaultUnknownFamilyName,
displayMiddleName,
displayReverseFieldOrder,
},
},
} = useConfig() as RegistrationConfig;
const { t } = useTranslation();
const { setCapturePhotoProps, currentPhoto, setFieldValue } = useContext(PatientRegistrationContext);
const { fieldConfigurations } = useConfig();
const fieldConfigs = fieldConfigurations?.name;
const [{ value: unidentified }] = useField('unidentifiedPatient');
const nameKnown = !unidentified;
vasharma05 marked this conversation as resolved.
Show resolved Hide resolved
} = useConfig<RegistrationConfig>();

const [{ value: isPatientUnknownValue }, , { setValue: setUnknownPatient }] = useField<string>(
`attributes.${unidentifiedPatientAttributeTypeUuid}`,
);

const isPatientUnknown = isPatientUnknownValue === 'true';

const onCapturePhoto = useCallback(
(dataUri: string, photoDateTime: string) => {
Expand All @@ -47,11 +57,11 @@ export const NameField = () => {
if (e.name === 'known') {
setFieldValue('givenName', '');
setFieldValue('familyName', '');
setFieldValue('unidentifiedPatient', false);
setUnknownPatient('false');
} else {
setFieldValue('givenName', fieldConfigs.defaultUnknownGivenName);
setFieldValue('familyName', fieldConfigs.defaultUnknownFamilyName);
setFieldValue('unidentifiedPatient', true);
setFieldValue('givenName', defaultUnknownGivenName);
setFieldValue('familyName', defaultUnknownFamilyName);
setUnknownPatient('true');
}
};

Expand All @@ -65,7 +75,7 @@ export const NameField = () => {
/>
);

const middleNameField = fieldConfigs.displayMiddleName && (
const middleNameField = displayMiddleName && (
<Input
id="middleName"
name="middleName"
Expand Down Expand Up @@ -98,14 +108,21 @@ export const NameField = () => {
)}

<div className={styles.nameField}>
<div className={styles.dobContentSwitcherLabel}>
<span className={styles.label01}>{t('patientNameKnown', "Patient's Name is Known?")}</span>
</div>
<ContentSwitcher className={styles.contentSwitcher} onChange={toggleNameKnown}>
<Switch name="known" text={t('yes', 'Yes')} />
<Switch name="unknown" text={t('no', 'No')} />
</ContentSwitcher>
{nameKnown &&
{(allowUnidentifiedPatients || isPatientUnknown) && (
<>
vasharma05 marked this conversation as resolved.
Show resolved Hide resolved
<div className={styles.dobContentSwitcherLabel}>
<span className={styles.label01}>{t('patientNameKnown', "Patient's Name is Known?")}</span>
</div>
<ContentSwitcher
className={styles.contentSwitcher}
selectedIndex={isPatientUnknown ? 1 : 0}
onChange={toggleNameKnown}>
<Switch name="known" text={t('yes', 'Yes')} />
<Switch name="unknown" text={t('no', 'No')} />
</ContentSwitcher>
</>
)}
{!isPatientUnknown &&
(!displayReverseFieldOrder ? (
<>
{firstNameField}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const formValues: FormValues = {
givenName: '',
middleName: '',
familyName: '',
unidentifiedPatient: false,
ibacher marked this conversation as resolved.
Show resolved Hide resolved
additionalGivenName: '',
additionalMiddleName: '',
additionalFamilyName: '',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,14 +364,6 @@ export class FormManager {
}
}

if (values.unidentifiedPatient) {
ibacher marked this conversation as resolved.
Show resolved Hide resolved
attributes.push({
// The UUID of the 'Unknown Patient' attribute-type will always be static across all implementations of OpenMRS
attributeType: '8b56eac7-5c76-4b9c-8c6f-1deab8d3fc47',
value: 'true',
});
}

return attributes;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export const dummyFormValues: FormValues = {
givenName: 'John',
middleName: '',
familyName: 'Smith',
unidentifiedPatient: false,
additionalGivenName: 'Joey',
additionalMiddleName: '',
additionalFamilyName: 'Smitty',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
latestFirstEncounter,
} from './patient-registration-utils';
import { useInitialPatientRelationships } from './section/patient-relationships/relationships.resource';
import dayjs from 'dayjs';

export function useInitialFormValues(patientUuid: string): [FormValues, Dispatch<FormValues>] {
const { isLoading: isLoadingPatientToEdit, patient: patientToEdit } = usePatient(patientUuid);
Expand All @@ -34,7 +35,6 @@ export function useInitialFormValues(patientUuid: string): [FormValues, Dispatch
givenName: '',
middleName: '',
familyName: '',
unidentifiedPatient: false,
additionalGivenName: '',
additionalMiddleName: '',
additionalFamilyName: '',
Expand All @@ -56,11 +56,22 @@ export function useInitialFormValues(patientUuid: string): [FormValues, Dispatch
useEffect(() => {
(async () => {
if (patientToEdit) {
const birthdateEstimated = !/^\d{4}-\d{2}-\d{2}$/.test(patientToEdit.birthDate);
const [years = 0, months = 0] = patientToEdit.birthDate.split('-').map((val) => parseInt(val));
// Please refer: https://github.com/openmrs/openmrs-esm-patient-management/pull/697#issuecomment-1562706118
const estimatedMonthsAvailable = patientToEdit.birthDate.split('-').length > 1;
const yearsEstimated = birthdateEstimated ? Math.floor(dayjs().diff(patientToEdit.birthDate, 'month') / 12) : 0;
const monthsEstimated =
birthdateEstimated && estimatedMonthsAvailable ? dayjs().diff(patientToEdit.birthDate, 'month') % 12 : 0;

setInitialFormValues({
...initialFormValues,
...getFormValuesFromFhirPatient(patientToEdit),
address: getAddressFieldValuesFromFhirPatient(patientToEdit),
...getPhonePersonAttributeValueFromFhirPatient(patientToEdit),
birthdateEstimated: !/^\d{4}-\d{2}-\d{2}$/.test(patientToEdit.birthDate),
yearsEstimated,
monthsEstimated,
});
} else if (!isLoadingPatientToEdit && patientUuid) {
const registration = await getPatientRegistration(patientUuid);
Expand Down Expand Up @@ -107,6 +118,7 @@ export function useInitialFormValues(patientUuid: string): [FormValues, Dispatch
? attribute.value?.uuid
: attribute.value;
});

setInitialFormValues((initialFormValues) => ({
...initialFormValues,
attributes: personAttributes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,6 @@ export interface FormValues {
givenName: string;
middleName: string;
familyName: string;
unidentifiedPatient: boolean;
additionalGivenName: string;
additionalMiddleName: string;
additionalFamilyName: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,6 @@ export function getFormValuesFromFhirPatient(patient: fhir.Patient) {
result.givenName = patientName?.given[0];
result.middleName = patientName?.given[1];
result.familyName = patientName?.family;
result.unidentifiedPatient =
patientName.given[0] === 'UNKNOWN' && patientName.family === 'unknown' ? true : undefined;

result.addNameInLocalLanguage = !!additionalPatientName ? true : undefined;
result.additionalGivenName = additionalPatientName?.given[0];
result.additionalMiddleName = additionalPatientName?.given[1];
Expand Down
Loading