Skip to content

Commit

Permalink
feat: save custom questions in risk questionnaire
Browse files Browse the repository at this point in the history
  • Loading branch information
9sneha-n committed Oct 1, 2024
1 parent 00a4cf2 commit 3552466
Show file tree
Hide file tree
Showing 14 changed files with 305 additions and 100 deletions.
151 changes: 110 additions & 41 deletions src/data/repositories/RiskAssessmentD2Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {
RiskAssessmentQuestionnaireFormData,
RiskAssessmentSummaryFormData,
} from "../../domain/entities/ConfigurableForm";
import { SelectedPick } from "@eyeseetea/d2-api/api";
import { D2DataElementSchema } from "@eyeseetea/d2-api/2.36";

//SNEHA TO DO : Fetch from metadata on app load
export const riskAssessmentGradingIds = {
Expand Down Expand Up @@ -261,51 +263,113 @@ export class RiskAssessmentD2Repository implements RiskAssessmentRepository {
| RiskAssessmentQuestionnaireFormData,
diseaseOutbreakId: Id
): FutureData<void> {
const programStageId = this.getProgramStageByFormType(formData.type);
return getProgramStage(this.api, programStageId).flatMap(riskResponse => {
const riskDataElements = riskResponse.objects[0]?.programStageDataElements;
if (formData.type === "risk-assessment-questionnaire") {
const { stdQuestionnaireStageId, customQuestionnaireStageId } =
this.getRiskAssessmentQuestionnaireProgramStages();

if (!riskDataElements)
return Future.error(
new Error(` ${formData.type} Program Stage metadata not found`)
);

//Get the enrollment Id for the disease outbreak
return apiToFuture(
this.api.tracker.enrollments.get({
fields: {
enrollment: true,
},
trackedEntity: diseaseOutbreakId,
enrolledBefore: new Date().toISOString(),
program: RTSL_ZEBRA_PROGRAM_ID,
orgUnit: RTSL_ZEBRA_ORG_UNIT_ID,
})
).flatMap(enrollmentResponse => {
const enrollmentId = enrollmentResponse.instances[0]?.enrollment;
if (!enrollmentId) {
return Future.error(new Error(`Enrollment not found for Disease Outbreak`));
return getProgramStage(this.api, stdQuestionnaireStageId).flatMap(
stdQuestionnaireRes => {
const stdQuestionnaireDataElements =
stdQuestionnaireRes.objects[0]?.programStageDataElements;
if (!stdQuestionnaireDataElements)
return Future.error(
new Error(` ${formData.type} Program Stage metadata not found`)
);
return this.postRiskAssessmentQestionnaire(
stdQuestionnaireDataElements,
formData,
diseaseOutbreakId,
stdQuestionnaireStageId
).flatMap(() => {
return getProgramStage(this.api, customQuestionnaireStageId).flatMap(
customQuestionnaireRes => {
const customQuestionnaireDataElements =
customQuestionnaireRes.objects[0]?.programStageDataElements;
if (!customQuestionnaireDataElements)
return Future.error(
new Error(
` ${formData.type} Program Stage metadata not found`
)
);
return this.postRiskAssessmentQestionnaire(
customQuestionnaireDataElements,
formData,
diseaseOutbreakId,
customQuestionnaireStageId
);
}
);
});
}
const events: D2TrackerEvent = mapRiskAssessmentToDataElements(
);
} else {
const programStageId = this.getProgramStageByFormType(formData.type);
return getProgramStage(this.api, programStageId).flatMap(riskResponse => {
const riskDataElements = riskResponse.objects[0]?.programStageDataElements;
if (!riskDataElements)
return Future.error(
new Error(` ${formData.type} Program Stage metadata not found`)
);
return this.postRiskAssessmentQestionnaire(
riskDataElements,
formData,
programStageId,
diseaseOutbreakId,
enrollmentId,
riskDataElements
programStageId
);
});
}
}

return apiToFuture(
this.api.tracker.post(
{ importStrategy: "CREATE_AND_UPDATE" },
{ events: [events] }
)
).flatMap(saveResponse => {
if (saveResponse.status === "ERROR" || !diseaseOutbreakId) {
return Future.error(new Error(`Error Risk Assessment Grading`));
} else {
return Future.success(undefined);
}
});
private postRiskAssessmentQestionnaire(
riskDataElements: {
dataElement: SelectedPick<
D2DataElementSchema,
{
id: true;
valueType: true;
code: true;
}
>;
}[],
formData:
| RiskAssessmentGradingFormData
| RiskAssessmentSummaryFormData
| RiskAssessmentQuestionnaireFormData,
diseaseOutbreakId: Id,
programStageId: Id
): FutureData<void> {
//Get the enrollment Id for the disease outbreak
return apiToFuture(
this.api.tracker.enrollments.get({
fields: {
enrollment: true,
},
trackedEntity: diseaseOutbreakId,
enrolledBefore: new Date().toISOString(),
program: RTSL_ZEBRA_PROGRAM_ID,
orgUnit: RTSL_ZEBRA_ORG_UNIT_ID,
})
).flatMap(enrollmentResponse => {
const enrollmentId = enrollmentResponse.instances[0]?.enrollment;
if (!enrollmentId) {
return Future.error(new Error(`Enrollment not found for Disease Outbreak`));
}
const events: D2TrackerEvent[] = mapRiskAssessmentToDataElements(
formData,
programStageId,
diseaseOutbreakId,
enrollmentId,
riskDataElements
);

return apiToFuture(
this.api.tracker.post({ importStrategy: "CREATE_AND_UPDATE" }, { events: events })
).flatMap(saveResponse => {
if (saveResponse.status === "ERROR" || !diseaseOutbreakId) {
return Future.error(new Error(`Error Risk Assessment Grading`));
} else {
return Future.success(undefined);
}
});
});
}
Expand All @@ -315,10 +379,15 @@ export class RiskAssessmentD2Repository implements RiskAssessmentRepository {
return RTSL_ZEBRA_RISK_ASSESSMENT_GRADING_PROGRAM_STAGE_ID;
case "risk-assessment-summary":
return RTSL_ZEBRA_RISK_ASSESSMENT_SUMMARY_PROGRAM_STAGE_ID;
case "risk-assessment-questionnaire":
return RTSL_ZEBRA_RISK_ASSESSMENT_QUESTIONNAIRE_PROGRAM_STAGE_ID;
default:
throw new Error("Risk Form type not supported");
}
}
private getRiskAssessmentQuestionnaireProgramStages() {
return {
stdQuestionnaireStageId: RTSL_ZEBRA_RISK_ASSESSMENT_QUESTIONNAIRE_PROGRAM_STAGE_ID,
customQuestionnaireStageId:
RTSL_ZEBRA_RISK_ASSESSMENT_QUESTIONNAIRE_CUSTOM_PROGRAM_STAGE_ID,
};
}
}
13 changes: 11 additions & 2 deletions src/data/repositories/TeamMemberD2Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { apiToFuture, FutureData } from "../api-futures";
import { assertOrError } from "./utils/AssertOrError";
import { Future } from "../../domain/entities/generic/Future";

const RTSL_ZEBRA_INCIDENTMANAGER = "UOd3K79040G";
const RTSL_ZEBRA_INCIDENTMANAGER = "RTSL_ZEBRA_INCIDENTMANAGER";
const RTSL_ZEBRA_RISKASSESSOR = "RTSL_ZEBRA_RISKASSESSOR";

export class TeamMemberD2Repository implements TeamMemberRepository {
constructor(private api: D2Api) {}
Expand All @@ -29,11 +30,19 @@ export class TeamMemberD2Repository implements TeamMemberRepository {
});
}
getIncidentManagers(): FutureData<TeamMember[]> {
return this.getTeamMembersByUserGroup(RTSL_ZEBRA_INCIDENTMANAGER);
}

getRiskAssessors(): FutureData<TeamMember[]> {
return this.getTeamMembersByUserGroup(RTSL_ZEBRA_RISKASSESSOR);
}

private getTeamMembersByUserGroup(userGroupCode: string): FutureData<TeamMember[]> {
return apiToFuture(
this.api.metadata.get({
users: {
fields: d2UserFields,
filter: { "userGroups.id": { in: [RTSL_ZEBRA_INCIDENTMANAGER] } },
filter: { "userGroups.code": { in: [userGroupCode] } },
},
})
)
Expand Down
60 changes: 50 additions & 10 deletions src/data/repositories/consts/RiskAssessmentConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import {
RiskAssessmentGrading,
RiskAssessmentGradingAttrs,
} from "../../../domain/entities/risk-assessment/RiskAssessmentGrading";
import { RiskAssessmentQuestionnaire } from "../../../domain/entities/risk-assessment/RiskAssessmentQuestionnaire";
import {
RiskAssessmentQuestion,
RiskAssessmentQuestionnaire,
} from "../../../domain/entities/risk-assessment/RiskAssessmentQuestionnaire";
import { RiskAssessmentSummary } from "../../../domain/entities/risk-assessment/RiskAssessmentSummary";
import { GetValue } from "../../../utils/ts-utils";

Expand Down Expand Up @@ -68,7 +71,7 @@ export const riskAssessmentSummaryCodes = {
} as const;
export type RiskAssessmentSummaryCodes = GetValue<typeof riskAssessmentSummaryCodes>;

export const riskAssessmentQuestionnaireCodes = {
export const riskAssessmentStdQuestionnaireCodes = {
question: "RTSL_ZEB_DET_QUESTION",
likelihood1: "RTSL_ZEB_DET_LIKELIHOOD",
consequences1: "RTSL_ZEB_DET_CONSEQUENCES",
Expand All @@ -87,7 +90,22 @@ export const riskAssessmentQuestionnaireCodes = {
riskId3: "RTSL_ZEB_DET_RISK_ID_RAQ3",
} as const;

export type RiskAssessmentQuestionnaireCodes = GetValue<typeof riskAssessmentQuestionnaireCodes>;
export type RiskAssessmentStdQuestionnaireCodes = GetValue<
typeof riskAssessmentStdQuestionnaireCodes
>;

export const riskAssessmentCustomQuestionnaireCodes = {
question: "RTSL_ZEB_DET_QUESTION",
likelihood4: "RTSL_ZEB_DET_LIKELIHOOD4",
consequences4: "RTSL_ZEB_DET_CONSEQUENCES4",
risk4: "RTSL_ZEB_DET_RISK4",
rational4: "RTSL_ZEB_DET_RATIONALE4",
riskId: "RTSL_ZEB_DET_RISK_ID_RAQ4",
} as const;

export type RiskAssessmentCustomQuestionnaireCodes = GetValue<
typeof riskAssessmentCustomQuestionnaireCodes
>;

export function isStringInRiskAssessmentGradingOptionCodes(
code: string
Expand Down Expand Up @@ -174,9 +192,9 @@ export function isStringInRiskAssessmentSummaryCodes(
return (Object.values(riskAssessmentSummaryCodes) as string[]).includes(code);
}

export function getValueFromRiskAssessmentQuestionnaire(
export function getValueFromRiskAssessmentStdQuestionnaire(
riskAssessmentQuestionnaire: RiskAssessmentQuestionnaire
): Record<RiskAssessmentQuestionnaireCodes, string> {
): Record<RiskAssessmentStdQuestionnaireCodes, string> {
return {
RTSL_ZEB_DET_LIKELIHOOD:
riskAssessmentQuestionnaire.potentialRiskForHumanHealth.likelihood.id,
Expand All @@ -201,11 +219,33 @@ export function getValueFromRiskAssessmentQuestionnaire(
RTSL_ZEB_DET_RISK_ID_RAQ3: "",
};
}
export type RiskAssessmentQuestionnaireKeyCode =
(typeof riskAssessmentQuestionnaireCodes)[keyof typeof riskAssessmentQuestionnaireCodes];
export type RiskAssessmentStdQuestionnaireKeyCode =
(typeof riskAssessmentStdQuestionnaireCodes)[keyof typeof riskAssessmentStdQuestionnaireCodes];

export function isStringInRiskAssessmentStdQuestionnaireCodes(
code: string
): code is RiskAssessmentStdQuestionnaireKeyCode {
return (Object.values(riskAssessmentStdQuestionnaireCodes) as string[]).includes(code);
}

export function getValueFromRiskAssessmentCustomQuestionnaire(
riskAssessmentCustomQuestion: RiskAssessmentQuestion
): Record<RiskAssessmentCustomQuestionnaireCodes, string> {
return {
RTSL_ZEB_DET_QUESTION: riskAssessmentCustomQuestion.question ?? "",
RTSL_ZEB_DET_LIKELIHOOD4: riskAssessmentCustomQuestion.likelihood.id,
RTSL_ZEB_DET_CONSEQUENCES4: riskAssessmentCustomQuestion.consequences.id,
RTSL_ZEB_DET_RISK4: riskAssessmentCustomQuestion.risk.id,
RTSL_ZEB_DET_RATIONALE4: riskAssessmentCustomQuestion.rational,
RTSL_ZEB_DET_RISK_ID_RAQ4: "",
};
}

export type RiskAssessmentCustomQuestionnaireKeyCode =
(typeof riskAssessmentCustomQuestionnaireCodes)[keyof typeof riskAssessmentCustomQuestionnaireCodes];

export function isStringInRiskAssessmentQuestionnaireCodes(
export function isStringInRiskAssessmentCustomQuestionnaireCodes(
code: string
): code is RiskAssessmentQuestionnaireKeyCode {
return (Object.values(riskAssessmentQuestionnaireCodes) as string[]).includes(code);
): code is RiskAssessmentCustomQuestionnaireKeyCode {
return (Object.values(riskAssessmentCustomQuestionnaireCodes) as string[]).includes(code);
}
15 changes: 15 additions & 0 deletions src/data/repositories/test/TeamMemberTestRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ export class TeamMemberTestRepository implements TeamMemberRepository {

return Future.success([teamMember]);
}
getRiskAssessors(): FutureData<TeamMember[]> {
const teamMember: TeamMember = new TeamMember({
id: "riskAssessor",
username: "riskAssessor",
name: `Team Member Name test`,
email: `[email protected]`,
phone: `121-1234`,
role: { id: "1", name: "role" },
status: "Available",
photo: new URL("https://www.example.com"),
});

return Future.success([teamMember]);
}

getAll(): FutureData<TeamMember[]> {
const teamMember: TeamMember = new TeamMember({
id: "test",
Expand Down
9 changes: 9 additions & 0 deletions src/data/repositories/utils/DateTimeHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,12 @@ export function getDateAsLocaleDateTimeString(date: Date): string {
return "";
}
}

export function getDateAsLocaleDateString(date: Date): string {
try {
return `${date.toLocaleDateString()}`;
} catch (e) {
console.debug(e);
return "";
}
}
Loading

0 comments on commit 3552466

Please sign in to comment.