Skip to content

Commit

Permalink
code-review
Browse files Browse the repository at this point in the history
  • Loading branch information
CynthiaKamau committed Jan 14, 2025
1 parent 561f6fe commit ee9e145
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 95 deletions.
40 changes: 9 additions & 31 deletions src/adapters/encounter-diagnosis-adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ const formContext = {
customDependencies: {
patientPrograms: [],
},
deletedFields: [],
getFormField: jest.fn(),
addFormField: jest.fn(),
updateFormField: jest.fn(),
Expand All @@ -39,6 +40,7 @@ const formContext = {
removeInvalidField: jest.fn(),
setInvalidFields: jest.fn(),
setForm: jest.fn(),
setDeletedFields: jest.fn(),
} as FormContextProps;

const field = {
Expand Down Expand Up @@ -173,18 +175,6 @@ describe('EncounterDiagnosisAdapter', () => {

const value = '128138AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
field.meta = {
previousValue: {
patient: '833db896-c1f0-11eb-8529-0242ac130003',
condition: null,
diagnosis: {
coded: '127133AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
},
certainty: 'PROVISIONAL',
rank: 1,
formFieldPath: 'rfe-forms-DiagNosIS',
formFieldNamespace: 'rfe-forms',
uuid: '0e20bb67-5d7f-41e0-96a1-751efc21a96f',
},
initialValue: {
omrsObject: {
uuid: '0e20bb67-5d7f-41e0-96a1-751efc21a96f',
Expand Down Expand Up @@ -215,23 +205,10 @@ describe('EncounterDiagnosisAdapter', () => {
expect(field.meta.submission.voidedValue).toBe(undefined);
});

it('should handle deleting a diagnosis', () => {
it('should void removed diagnosis in edit mode', () => {
formContext.sessionMode = 'edit';

const value = null;
field.meta = {
previousValue: {
patient: '833db896-c1f0-11eb-8529-0242ac130003',
condition: null,
diagnosis: {
coded: '127133AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
},
certainty: 'PROVISIONAL',
rank: 1,
formFieldPath: 'rfe-forms-DiagNosIS',
formFieldNamespace: 'rfe-forms',
uuid: '0e20bb67-5d7f-41e0-96a1-751efc21a96f',
},
initialValue: {
omrsObject: {
uuid: '0e20bb67-5d7f-41e0-96a1-751efc21a96f',
Expand All @@ -244,11 +221,12 @@ describe('EncounterDiagnosisAdapter', () => {
},
refinedValue: null,
},
repeat: {
wasDeleted: true,
},
};
EncounterDiagnosisAdapter.transformFieldValue(field, value, formContext);
expect(field.meta.submission.voidedValue).toEqual({ uuid: '0e20bb67-5d7f-41e0-96a1-751efc21a96f', voided: true });

EncounterDiagnosisAdapter.transformFieldValue(field, null, formContext);
expect(field.meta.submission.voidedValue).toEqual({
voided: true,
uuid: '0e20bb67-5d7f-41e0-96a1-751efc21a96f',
});
});
});
82 changes: 50 additions & 32 deletions src/adapters/encounter-diagnosis-adapter.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
import { type OpenmrsResource } from '@openmrs/esm-framework';
import { type DiagnosisPayload, type FormFieldValueAdapter, type FormProcessorContextProps } from '../types';
import { type OpenmrsObs, type FormFieldValueAdapter, type FormProcessorContextProps } from '../types';
import { type FormContextProps } from '../provider/form-provider';
import { type OpenmrsEncounter, type FormField } from '../types';
import { clearSubmission, gracefullySetSubmission } from '../utils/common-utils';
import { gracefullySetSubmission } from '../utils/common-utils';
import { isEmpty } from '../validators/form-validator';
import { voidObs } from './obs-adapter';
import { isTrue } from '../utils/boolean-utils';

export let assignedDiagnosesIds: string[] = [];

export const EncounterDiagnosisAdapter: FormFieldValueAdapter = {
transformFieldValue: function (field: FormField, value: any, context: FormContextProps) {
if (context.sessionMode == 'edit' && field.meta?.previousValue?.uuid) {
return editDiagnosis(value, field, context.patient.id);
if (field.meta.initialValue?.omrsObject && isEmpty(value)) {
return gracefullySetSubmission(field, undefined, voidObs(field.meta.initialValue.omrsObject as OpenmrsObs));
}
if (!isEmpty(value)) {
const previousDiagnosis = field.meta.initialValue?.omrsObject as OpenmrsResource;
if (hasPreviousDiagnosisValueChanged(previousDiagnosis, value)) {
return gracefullySetSubmission(
field,
editDiagnosis(value, field, previousDiagnosis, context.patient.id),
undefined,
);
}
}
const newValue = constructNewDiagnosis(value, field, context.patient.id);
gracefullySetSubmission(field, newValue, null);
Expand All @@ -26,7 +39,13 @@ export const EncounterDiagnosisAdapter: FormFieldValueAdapter = {
);

if (matchedDiagnosis) {
field.meta = { ...(field.meta || {}), previousValue: matchedDiagnosis };
field.meta = {
...(field.meta || {}),
initialValue: {
omrsObject: matchedDiagnosis,
refinedValue: matchedDiagnosis.diagnosis?.coded.uuid,
},
};
if (!assignedDiagnosesIds.includes(matchedDiagnosis.diagnosis?.coded?.uuid)) {
assignedDiagnosesIds.push(matchedDiagnosis.diagnosis?.coded?.uuid);
}
Expand All @@ -49,47 +68,46 @@ export const EncounterDiagnosisAdapter: FormFieldValueAdapter = {
},
};

const constructNewDiagnosis = (value: any, field: FormField, patientUuid: string, uuid?: string) => {
const constructNewDiagnosis = (value: any, field: FormField, patientUuid: string) => {
if (!value) {
return null;
}
const diagnosis: DiagnosisPayload = {
return {
patient: patientUuid,
condition: null,
diagnosis: {
coded: value,
},
certainty: field.questionOptions?.diagnosis?.isConfirmed ? 'CONFIRMED' : 'PROVISIONAL',
certainty: isTrue(field.questionOptions?.diagnosis?.isConfirmed) ? 'CONFIRMED' : 'PROVISIONAL',
rank: field.questionOptions.diagnosis?.rank ?? 1, // rank 1 denotes a diagnosis is primary, else secondary
formFieldPath: `rfe-forms-${field.id}`,
formFieldNamespace: 'rfe-forms',
};

if (uuid && uuid.trim() !== '') {
diagnosis.uuid = uuid;
}

return diagnosis;
};

function editDiagnosis(newEncounterDiagnosis: any, field: FormField, patientUuid: string) {
if (newEncounterDiagnosis === field.meta.previousValue?.diagnosis?.coded?.uuid && !field.meta.repeat?.wasDeleted) {
clearSubmission(field);
return null;
}
function editDiagnosis(
newEncounterDiagnosis: any,
field: FormField,
previousDiagnosis: OpenmrsResource,
patientUuid: string,
) {
return {
patient: patientUuid,
condition: null,
diagnosis: {
coded: newEncounterDiagnosis,
},
certainty: isTrue(field.questionOptions?.diagnosis?.isConfirmed) ? 'CONFIRMED' : 'PROVISIONAL',
rank: field.questionOptions.diagnosis?.rank ?? 1, // rank 1 denotes a diagnosis is primary, else secondary
formFieldPath: `rfe-forms-${field.id}`,
formFieldNamespace: 'rfe-forms',
uuid: previousDiagnosis.uuid,
};
}

//the field has been deleted
if (field.meta.repeat?.wasDeleted) {
const voided = {
uuid: field.meta.previousValue?.uuid,
voided: true,
};
gracefullySetSubmission(field, constructNewDiagnosis(newEncounterDiagnosis, field, null), voided);
return field.meta.submission.newValue || null;
} else {
const oldDiagnosis = field.meta.initialValue?.omrsObject as OpenmrsResource;
const newValue = constructNewDiagnosis(newEncounterDiagnosis, field, patientUuid, oldDiagnosis.uuid);
gracefullySetSubmission(field, newValue, null);
return newValue;
export function hasPreviousDiagnosisValueChanged(previousDiagnosis: OpenmrsResource, newValue: any) {
if (isEmpty(previousDiagnosis)) {
return false;
}
return previousDiagnosis.value !== newValue;
}
12 changes: 7 additions & 5 deletions src/datasources/concept-data-source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ export class ConceptDataSource extends BaseOpenMRSDataSource {
const urlParts = searchUrl.split('searchType=fuzzy');
searchUrl = `${urlParts[0]}searchType=fuzzy&class=${config.class}&${urlParts[1]}`;
} else {
return openmrsFetch(searchTerm ? `${searchUrl}&q=${searchTerm}` : searchUrl).then(({ data }) => {
return data.results.filter(
(concept) => concept.conceptClass && config.class.includes(concept.conceptClass.uuid),
);
});
return openmrsFetch(searchTerm ? `${searchUrl}&q=${searchTerm}` : `${searchUrl}&q=${'Diagnosis'}`).then(
({ data }) => {
return data.results.filter(
(concept) => concept.conceptClass && config.class.includes(concept.conceptClass.uuid),
);
},
);
}
}

Expand Down
47 changes: 20 additions & 27 deletions src/processors/encounter/encounter-processor-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export function prepareEncounter(
prepareObs(obsForSubmission, allFormFields);
const ordersForSubmission = prepareOrders(allFormFields);
const diagnosesForSubmission = prepareDiagnosis(allFormFields);

let encounterForSubmission: OpenmrsEncounter = {};

if (encounter) {
Expand Down Expand Up @@ -321,38 +322,28 @@ export async function hydrateRepeatField(

const unMappedDiagnoses = encounter.diagnoses.filter((diagnosis) => {
return (
!diagnosis.voided &&
!assignedDiagnosesIds.includes(diagnosis?.diagnosis?.coded.uuid) &&
diagnosis.formFieldPath.startsWith(`rfe-forms-${field.id}_`)
);
});

const sortedDiagnoses = unMappedDiagnoses
.filter((diagnosis) => !diagnosis.voided)
.sort((a, b) => {
// Extract numeric part of formFieldPath for sorting
const numberA = parseInt(a.formFieldPath.split('_')[1], 10);
const numberB = parseInt(b.formFieldPath.split('_')[1], 10);
return numberA - numberB; // Sort numerically based on formFieldPath
});

if (field.type === 'diagnosis') {
return Promise.all(
sortedDiagnoses
.filter((diagnosis) => !diagnosis.voided)
.map(async (diagnosis) => {
const clone = cloneRepeatField(field, diagnosis, counter++);
initialValues[clone.id] = await formFieldAdapters[field.type].getInitialValue(
clone,
{ diagnoses: [diagnosis] } as any,
context,
);

if (!assignedDiagnosesIds.includes(diagnosis.diagnosis.coded.uuid)) {
assignedDiagnosesIds.push(diagnosis.diagnosis.coded.uuid);
}
unMappedDiagnoses.map(async (diagnosis) => {
const idSuffix = parseInt(diagnosis.formFieldPath.split('_')[1]);
const clone = cloneRepeatField(field, diagnosis, idSuffix);
initialValues[clone.id] = await formFieldAdapters[field.type].getInitialValue(
clone,
{ diagnoses: [diagnosis] } as any,
context,
);
if (!assignedDiagnosesIds.includes(diagnosis.diagnosis.coded.uuid)) {
assignedDiagnosesIds.push(diagnosis.diagnosis.coded.uuid);
}

return clone;
}),
return clone;
}),
);
}
// handle obs groups
Expand All @@ -375,8 +366,10 @@ export async function hydrateRepeatField(
}

function prepareDiagnosis(fields: FormField[]) {
return fields
const diagnoses = fields
.filter((field) => field.type === 'diagnosis' && hasSubmission(field))
.flatMap((field) => [field.meta.submission.newValue, field.meta.submission.voidedValue])
.filter((d) => d);
.map((field) => field.meta.submission.newValue || field.meta.submission.voidedValue)
.filter((o) => o);

return diagnoses;
}
13 changes: 13 additions & 0 deletions src/transformers/default-schema-transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,19 @@ function handleDiagnosis(question: FormField) {
class: question.questionOptions.diagnosis?.conceptClasses,
},
};
if (question.questionOptions.diagnosis?.conceptSet) {
question.questionOptions = {
...question.questionOptions,
concept: question.questionOptions.diagnosis?.conceptSet,
datasource: {
name: 'problem_datasource',
config: {
useSetMembersByConcept: true,
},
},
};
}

delete question.questionOptions['dataSource'];
}
}
1 change: 1 addition & 0 deletions src/types/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ export interface FormQuestionOptions {
rank?: number;
isConfirmed?: boolean;
conceptClasses?: Array<string>;
conceptSet?: string;
};
}

Expand Down

0 comments on commit ee9e145

Please sign in to comment.