Skip to content

Commit

Permalink
Merge pull request #85 from EyeSeeTea/feat/v41-upgrade
Browse files Browse the repository at this point in the history
Feat/v41 upgrade
  • Loading branch information
MiquelAdell authored Feb 6, 2025
2 parents 3892559 + 90de614 commit 9d810c0
Show file tree
Hide file tree
Showing 12 changed files with 349 additions and 782 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@dhis2/ui": "6.12.0",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@eyeseetea/d2-api": "1.14.0",
"@eyeseetea/d2-api": "1.18.0-beta.1",
"@eyeseetea/d2-ui-components": "2.7.0",
"@eyeseetea/feedback-component": "0.0.3",
"@material-ui/core": "4.12.4",
Expand Down
24 changes: 24 additions & 0 deletions src/data/entities/D2Survey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,27 @@ export const keyToDataElementMap: SurveyKeyDataElementMapType[] = [
{ key: "astGuideline", dataElements: [AMR_SURVEYS_PREVALENCE_DEA_AST_GUIDELINES] },
{ key: "customAstGuideline", dataElements: [AMR_SURVEYS_PREVALENCE_DEA_CUSTOM_AST_GUIDE] },
];

//ParentPrevalenceSurveyId Fields
export const parentPrevalenceSurveyIdList = [
SURVEY_ID_FACILITY_LEVEL_DATAELEMENT_ID,
AMR_SURVEYS_PREVALENCE_TEA_SURVEY_ID_SSTF,
AMR_SURVEYS_PREVALENCE_TEA_SURVEY_ID_CRL,
AMR_SURVEYS_PREVALENCE_TEA_SURVEY_ID_PIS,
AMR_SURVEYS_PREVALENCE_TEA_SURVEY_ID_SRL,
AMR_SURVEYS_PREVALENCE_TEA_SURVEY_ID_CRF,
AMR_SURVEYS_MORTALITY_TEA_SURVEY_ID_FUP,
AMR_SURVEYS_MORTALITY_TEA_SURVEY_ID_DF,
AMR_SURVEYS_MORTALITY_TEA_SURVEY_ID_COH,
];

export const patientIdList = [
AMR_SURVEYS_PREVALENCE_TEA_UNIQUE_PATIENT_ID,
AMR_SURVEYS_PREVALENCE_TEA_PATIENT_ID,
AMR_SURVEYS_PREVALENCE_TEA_AMRPATIENT_IDPREVALENCE,
AMR_SURVEYS_PREVALENCE_TEA_PATIENT_IDA19,
AMR_SURVEYS_MORTALITY_TEA_PAT_ID_FUP2,
AMR_SURVEYS_MORTALITY_TEA_PAT_ID_DF2,
AMR_SURVEYS_MORTALITY_TEA_PAT_ID_COH2,
SURVEY_PATIENT_ID_TEA_ID,
];
33 changes: 22 additions & 11 deletions src/data/repositories/PaginatedSurveyD2Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ import {
SURVEY_PATIENT_ID_TEA_ID,
WARD_ID_TEA_ID,
} from "../entities/D2Survey";
import { mapEventToSurvey, mapTrackedEntityToSurvey } from "../utils/surveyListMappers";
import {
mapEventToSurvey,
mapTrackedEntityToSurvey,
trackedEntityFields,
} from "../utils/surveyListMappers";
import { getSurveyChildCount, SurveyChildCountType } from "../utils/surveyChildCountHelper";

export class PaginatedSurveyD2Repository implements PaginatedSurveyRepository {
Expand Down Expand Up @@ -57,13 +61,13 @@ export class PaginatedSurveyD2Repository implements PaginatedSurveyRepository {
page: number,
pageSize: number
): FutureData<PaginatedReponse<Survey[]>> {
const ouMode = undefined;
const ouMode = "SELECTED";

const filterParentDEId = getParentDataElementForProgram(programId);

return apiToFuture(
this.api.tracker.trackedEntities.get({
fields: { attributes: true, enrollments: true, trackedEntity: true, orgUnit: true },
fields: trackedEntityFields,
program: programId,
orgUnit: orgUnitId,
ouMode: ouMode,
Expand All @@ -73,7 +77,8 @@ export class PaginatedSurveyD2Repository implements PaginatedSurveyRepository {
filter: `${filterParentDEId}:eq:${parentId}`,
})
).flatMap(trackedEntities => {
const surveys = mapTrackedEntityToSurvey(trackedEntities, surveyFormType);
const instances = trackedEntities.instances;
const surveys = mapTrackedEntityToSurvey(instances, surveyFormType);

const paginatedSurveys: PaginatedReponse<Survey[]> = {
pager: {
Expand All @@ -96,7 +101,7 @@ export class PaginatedSurveyD2Repository implements PaginatedSurveyRepository {
page: number,
pageSize: number
): FutureData<PaginatedReponse<Survey[]>> {
const ouMode = undefined;
const ouMode = "SELECTED";
return apiToFuture(
this.api.tracker.events.get({
fields: { $all: true },
Expand Down Expand Up @@ -133,15 +138,17 @@ export class PaginatedSurveyD2Repository implements PaginatedSurveyRepository {
): FutureData<PaginatedReponse<Survey[]>> {
return apiToFuture(
this.api.tracker.trackedEntities.get({
fields: { attributes: true, enrollments: true, trackedEntity: true, orgUnit: true },
fields: trackedEntityFields,
program: PPS_PATIENT_REGISTER_ID,
orgUnit: orgUnitId,
ouMode: "SELECTED",
pageSize: 10,
totalPages: true,
filter: ` ${SURVEY_PATIENT_ID_TEA_ID}:like:${keyword}, ${WARD_ID_TEA_ID}:eq:${parentId}`,
})
).flatMap(trackedEntities => {
const surveys = mapTrackedEntityToSurvey(trackedEntities, "PPSPatientRegister");
const instances = trackedEntities.instances;
const surveys = mapTrackedEntityToSurvey(instances, "PPSPatientRegister");

const paginatedSurveys: PaginatedReponse<Survey[]> = {
pager: {
Expand All @@ -163,15 +170,17 @@ export class PaginatedSurveyD2Repository implements PaginatedSurveyRepository {
): FutureData<PaginatedReponse<Survey[]>> {
return apiToFuture(
this.api.tracker.trackedEntities.get({
fields: { attributes: true, enrollments: true, trackedEntity: true, orgUnit: true },
fields: trackedEntityFields,
program: PPS_PATIENT_REGISTER_ID,
orgUnit: orgUnitId,
ouMode: "SELECTED",
pageSize: 10,
totalPages: true,
filter: ` ${SURVEY_PATIENT_CODE_TEA_ID}:like:${keyword}, ${WARD_ID_TEA_ID}:eq:${parentId}`,
})
).flatMap(trackedEntities => {
const surveys = mapTrackedEntityToSurvey(trackedEntities, "PPSPatientRegister");
const instances = trackedEntities.instances;
const surveys = mapTrackedEntityToSurvey(instances, "PPSPatientRegister");

const paginatedSurveys: PaginatedReponse<Survey[]> = {
pager: {
Expand All @@ -193,15 +202,17 @@ export class PaginatedSurveyD2Repository implements PaginatedSurveyRepository {
): FutureData<PaginatedReponse<Survey[]>> {
return apiToFuture(
this.api.tracker.trackedEntities.get({
fields: { attributes: true, enrollments: true, trackedEntity: true, orgUnit: true },
fields: trackedEntityFields,
program: PREVALENCE_CASE_REPORT_FORM_ID,
orgUnit: orgUnitId,
ouMode: "SELECTED",
pageSize: 10,
totalPages: true,
filter: ` ${AMR_SURVEYS_PREVALENCE_TEA_UNIQUE_PATIENT_ID}:like:${keyword}, ${AMR_SURVEYS_PREVALENCE_TEA_SURVEY_ID_CRF}:eq:${parentId}`,
})
).flatMap(trackedEntities => {
const surveys = mapTrackedEntityToSurvey(trackedEntities, "PrevalenceCaseReportForm");
const instances = trackedEntities.instances;
const surveys = mapTrackedEntityToSurvey(instances, "PrevalenceCaseReportForm");

const paginatedSurveys: PaginatedReponse<Survey[]> = {
pager: {
Expand Down
129 changes: 90 additions & 39 deletions src/data/repositories/SurveyFormD2Repository.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { D2Api } from "@eyeseetea/d2-api/2.36";
import { D2TrackerEvent } from "@eyeseetea/d2-api/api/trackerEvents";
import { Future } from "../../domain/entities/generic/Future";
import { Id } from "../../domain/entities/Ref";
import { Id, NamedRef } from "../../domain/entities/Ref";
import { SurveyRepository } from "../../domain/repositories/SurveyRepository";
import { apiToFuture, FutureData } from "../api-futures";
import _ from "../../domain/entities/generic/Collection";
import { ImportStrategy } from "../../domain/entities/Program";
import { Survey, SURVEY_FORM_TYPES } from "../../domain/entities/Survey";
import {
D2TrackerTrackedEntity,
D2TrackerTrackedEntity as TrackedEntity,
TrackedEntitiesGetResponse,
D2TrackedEntityInstanceToPost,
D2TrackerTrackedEntity,
} from "@eyeseetea/d2-api/api/trackerTrackedEntities";
import {
getParentDataElementForProgram,
Expand All @@ -27,19 +26,27 @@ import {
PREVALENCE_SURVEY_NAME_DATAELEMENT_ID,
AMR_SURVEYS_PREVALENCE_DEA_CUSTOM_AST_GUIDE,
AMR_SURVEYS_PREVALENCE_DEA_AST_GUIDELINES,
PPS_COUNTRY_QUESTIONNAIRE_ID,
PREVALENCE_SURVEY_FORM_ID,
} from "../entities/D2Survey";
import { ProgramDataElement, ProgramMetadata } from "../entities/D2Program";
import {
mapProgramToQuestionnaire,
mapQuestionnaireToEvent,
mapQuestionnaireToTrackedEntities,
} from "../utils/surveyFormMappers";
import { mapEventToSurvey, mapTrackedEntityToSurvey } from "../utils/surveyListMappers";
import {
D2TrackerEntitySelectedPick,
mapEventToSurvey,
mapTrackedEntityToSurvey,
trackedEntityFields,
} from "../utils/surveyListMappers";
import { Questionnaire } from "../../domain/entities/Questionnaire/Questionnaire";
import { ASTGUIDELINE_TYPES } from "../../domain/entities/ASTGuidelines";
import { getSurveyChildCount, SurveyChildCountType } from "../utils/surveyChildCountHelper";
import { TrackerPostResponse } from "@eyeseetea/d2-api/api/tracker";
import { TrackerPostRequest, TrackerPostResponse } from "@eyeseetea/d2-api/api/tracker";
import { Maybe } from "../../utils/ts-utils";
import { D2TrackerEvent, D2TrackerEventToPost } from "@eyeseetea/d2-api/api/trackerEvents";

const OU_CHUNK_SIZE = 500;

Expand Down Expand Up @@ -258,7 +265,6 @@ export class SurveyD2Repository implements SurveyRepository {
return filter;
}

//Currently tracker programs are only in Prevalence module
private getTrackerProgramSurveys(
surveyFormType: SURVEY_FORM_TYPES,
programId: Id,
Expand All @@ -281,19 +287,24 @@ export class SurveyD2Repository implements SurveyRepository {
(orgUnitId !== "" && programId === PREVALENCE_FACILITY_LEVEL_FORM_ID) ||
programId === PPS_PATIENT_REGISTER_ID
? "DESCENDANTS"
: undefined;
: "SELECTED";

return apiToFuture(
this.api.tracker.trackedEntities.get({
fields: { attributes: true, enrollments: true, trackedEntity: true, orgUnit: true },
fields: trackedEntityFields,
program: programId,
orgUnit: orgUnitId,
ouMode: ouMode,
filter: filter ? `${filter.id}:eq:${filter.value}` : undefined,
})
).flatMap((trackedEntities: TrackedEntitiesGetResponse) => {
const surveys = mapTrackedEntityToSurvey(trackedEntities, surveyFormType);
return Future.success(surveys);
).flatMap((trackedEntities: TrackedEntitiesGetResponse<typeof trackedEntityFields>) => {
const instances: D2TrackerEntitySelectedPick[] = trackedEntities.instances;
return this.getOrgUnitNames(instances.map(instance => instance.orgUnit)).flatMap(
orgUnits => {
const surveys = mapTrackedEntityToSurvey(instances, surveyFormType, orgUnits);
return Future.success(surveys);
}
);
});
}

Expand All @@ -310,24 +321,46 @@ export class SurveyD2Repository implements SurveyRepository {
chunkedOUs.flatMap(ouChunk => {
return apiToFuture(
this.api.tracker.trackedEntities.get({
fields: {
attributes: true,
enrollments: true,
trackedEntity: true,
orgUnit: true,
},
fields: trackedEntityFields,
program: programId,
orgUnit: ouChunk.join(";"),
ouMode: "SELECTED",
filter: filter ? `${filter.id}:eq:${filter.value}` : undefined,
})
).flatMap((trackedEntities: TrackedEntitiesGetResponse) => {
const surveys = mapTrackedEntityToSurvey(trackedEntities, surveyFormType);
return Future.success(surveys);
});
).flatMap(
(trackedEntities: TrackedEntitiesGetResponse<typeof trackedEntityFields>) => {
const instances: D2TrackerEntitySelectedPick[] = trackedEntities.instances;
return this.getOrgUnitNames(
instances.map(instance => instance.orgUnit)
).flatMap(orgUnits => {
const surveys = mapTrackedEntityToSurvey(
instances,
surveyFormType,
orgUnits
);
return Future.success(surveys);
});
}
);
})
).flatMap(listOfSurveys => Future.success(_(listOfSurveys).flatten().value()));
}

private getOrgUnitNames(orgUnitIds: Id[]): FutureData<NamedRef[]> {
return apiToFuture(
this.api.models.organisationUnits.get({
fields: { id: true, name: true },
filter: { id: { in: orgUnitIds } },
paging: false,
})
).flatMap(orgUnitsResponse => {
const orgUnits = orgUnitsResponse.objects.map(ou => {
return { id: ou.id, name: ou.name };
});
return Future.success(orgUnits);
});
}

private getEventProgramSurveys(
surveyFormType: SURVEY_FORM_TYPES,
programId: Id,
Expand All @@ -336,9 +369,12 @@ export class SurveyD2Repository implements SurveyRepository {
): FutureData<Survey[]> {
const ouMode =
orgUnitId !== "" &&
(programId === PPS_WARD_REGISTER_ID || programId === PPS_HOSPITAL_FORM_ID)
(programId === PPS_WARD_REGISTER_ID ||
programId === PPS_HOSPITAL_FORM_ID ||
programId === PPS_COUNTRY_QUESTIONNAIRE_ID ||
programId === PREVALENCE_SURVEY_FORM_ID)
? "DESCENDANTS"
: undefined;
: "SELECTED";

return apiToFuture(
this.api.tracker.events.get({
Expand All @@ -350,8 +386,11 @@ export class SurveyD2Repository implements SurveyRepository {
})
).flatMap(response => {
const events = response.instances;
const surveys = mapEventToSurvey(events, surveyFormType, programId);
return Future.success(surveys);

return this.getOrgUnitNames(events.map(event => event.orgUnit)).flatMap(orgUnits => {
const surveys = mapEventToSurvey(events, surveyFormType, programId, orgUnits);
return Future.success(surveys);
});
});
}

Expand Down Expand Up @@ -379,18 +418,22 @@ export class SurveyD2Repository implements SurveyRepository {
private getTrackerProgramById(
trackedEntityId: Id,
programId: Id
): FutureData<TrackedEntity | void> {
): FutureData<D2TrackerTrackedEntity | void> {
return apiToFuture(
this.api.tracker.trackedEntities.get({
fields: { attributes: true, enrollments: true, trackedEntity: true, orgUnit: true },
fields: { $all: true },
program: programId,
trackedEntity: trackedEntityId,
ouMode: "DESCENDANTS",
ouMode: "ALL",
enrollmentEnrolledBefore: new Date().toISOString(),
})
).flatMap(resp => {
if (resp) return Future.success(resp.instances[0]);
else return Future.success(undefined);
).flatMap(trackedEntities => {
const instances = trackedEntities.instances;

if (instances[0]) {
const instance: D2TrackerTrackedEntity = instances[0];
return Future.success(instance);
} else return Future.success(undefined);
});
}

Expand Down Expand Up @@ -458,17 +501,22 @@ export class SurveyD2Repository implements SurveyRepository {
}

deleteEventSurvey(eventId: Id, orgUnitId: Id, programId: Id): FutureData<void> {
const event: D2TrackerEvent = {
const event: D2TrackerEventToPost = {
event: eventId,
orgUnit: orgUnitId,
program: programId,
// status doesn't play a part in deleting but is required
status: "ACTIVE",
occurredAt: "",
dataValues: [],
programStage: "",
};

const payload: TrackerPostRequest = {
events: [event],
};
return apiToFuture(
this.api.tracker.postAsync({ importStrategy: "DELETE" }, { events: [event] })
this.api.tracker.postAsync({ importStrategy: "DELETE" }, payload)
).flatMap(response => {
return apiToFuture(
// eslint-disable-next-line testing-library/await-async-utils
Expand All @@ -486,17 +534,20 @@ export class SurveyD2Repository implements SurveyRepository {
}

deleteTrackerProgramSurvey(teiId: Id, orgUnitId: Id, programId: Id): FutureData<void> {
const trackedEntity: D2TrackerTrackedEntity = {
const trackedEntity: D2TrackedEntityInstanceToPost = {
orgUnit: orgUnitId,
trackedEntity: teiId,
trackedEntityType: getTrackedEntityAttributeType(programId),
enrollments: [],
attributes: [],
};

const payload: TrackerPostRequest = {
trackedEntities: [trackedEntity],
};

return apiToFuture(
this.api.tracker.postAsync(
{ importStrategy: "DELETE" },
{ trackedEntities: [trackedEntity] }
)
this.api.tracker.postAsync({ importStrategy: "DELETE" }, payload)
).flatMap(response => {
return apiToFuture(
// eslint-disable-next-line testing-library/await-async-utils
Expand Down
Loading

0 comments on commit 9d810c0

Please sign in to comment.