diff --git a/src/data/repositories/DiseaseOutbreakEventD2Repository.ts b/src/data/repositories/DiseaseOutbreakEventD2Repository.ts index a1d6727c..b986ea03 100644 --- a/src/data/repositories/DiseaseOutbreakEventD2Repository.ts +++ b/src/data/repositories/DiseaseOutbreakEventD2Repository.ts @@ -24,10 +24,7 @@ export class DiseaseOutbreakEventD2Repository implements DiseaseOutbreakEventRep fields: { attributes: true, trackedEntity: true }, }) ) - .flatMap( - (response): FutureData => - assertOrError(response.instances[0], "Tracked entity") - ) + .flatMap(response => assertOrError(response.instances[0], "Tracked entity")) .map(trackedEntity => { return mapTrackedEntityAttributesToDiseaseOutbreak(trackedEntity); }); diff --git a/src/data/repositories/consts/DiseaseOutbreakConstants.ts b/src/data/repositories/consts/DiseaseOutbreakConstants.ts index 5587de46..02b40227 100644 --- a/src/data/repositories/consts/DiseaseOutbreakConstants.ts +++ b/src/data/repositories/consts/DiseaseOutbreakConstants.ts @@ -1,14 +1,25 @@ +import { getAvatarUtilityClass } from "@mui/material"; import { DiseaseOutbreakEventBaseAttrs, HazardType, + hazardTypes, } from "../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEvent"; -import { GetValue } from "../../../utils/ts-utils"; +import { GetValue, Maybe } from "../../../utils/ts-utils"; +import { getDateAsIsoString } from "../utils/DateTimeHelper"; export const RTSL_ZEBRA_PROGRAM_ID = "qkOTdxkte8V"; export const RTSL_ZEBRA_ORG_UNIT_ID = "PS5JpkoHHio"; export const RTSL_ZEBRA_TRACKED_ENTITY_TYPE_ID = "lIzNjLOUAKA"; -export const DiseaseOutbreakCodes = { +export const hazardTypeCodeMap: Record = { + "Biological:Human": "BIOLOGICAL_HUMAN", + "Biological:Animal": "BIOLOGICAL_ANIMAL", + Chemical: "CHEMICAL", + Environmental: "ENVIRONMENTAL", + Unknown: "UNKNOWN", +}; + +export const diseaseOutbreakCodes = { eventId: "RTSL_ZEB_TEA_EVENT_id", name: "RTSL_ZEB_TEA_EVENT_NAME", hazardType: "RTSL_ZEB_TEA_HAZARD_TYPE", @@ -40,22 +51,19 @@ export const DiseaseOutbreakCodes = { notes: "RTSL_ZEB_TEA_NOTES", } as const; -export type DiseaseOutbreakCode = GetValue; +export type DiseaseOutbreakCode = GetValue; -export type KeyCode = (typeof DiseaseOutbreakCodes)[keyof typeof DiseaseOutbreakCodes]; +export type KeyCode = (typeof diseaseOutbreakCodes)[keyof typeof diseaseOutbreakCodes]; export function isStringInDiseaseOutbreakCodes(code: string): code is KeyCode { - return Object.values(DiseaseOutbreakCodes).includes(code as KeyCode); + return (Object.values(diseaseOutbreakCodes) as string[]).includes(code); } -export function isHazardType(hazardType: string): hazardType is HazardType { - return [ - "Biological:Animal", - "Biological:Human", - "Chemical", - "Environmental", - "Unknown", - ].includes(hazardType); +export function getHazardTypeValue(hazardType: string): HazardType { + const hazardTypeString = Object.keys(hazardTypeCodeMap).find( + key => hazardTypeCodeMap[key as HazardType] === hazardType + ); + return hazardTypeString ? (hazardTypeString as HazardType) : "Unknown"; } export function getValueFromDiseaseOutbreak( @@ -64,7 +72,7 @@ export function getValueFromDiseaseOutbreak( return { RTSL_ZEB_TEA_EVENT_id: diseaseOutbreak.eventId.toString(), RTSL_ZEB_TEA_EVENT_NAME: diseaseOutbreak.name, - RTSL_ZEB_TEA_HAZARD_TYPE: getHazardTypeCode(diseaseOutbreak.hazardType), + RTSL_ZEB_TEA_HAZARD_TYPE: hazardTypeCodeMap[diseaseOutbreak.hazardType], RTSL_ZEB_TEA_MAIN_SYNDROME: diseaseOutbreak.mainSyndromeCode, RTSL_ZEB_TEA_SUSPECTED_DISEASE: diseaseOutbreak.suspectedDiseaseCode, RTSL_ZEB_TEA_NOTIFICATION_SOURCE: diseaseOutbreak.notificationSourceCode, @@ -75,66 +83,57 @@ export function getValueFromDiseaseOutbreak( diseaseOutbreak.areasAffectedDistrictIds ), RTSL_ZEB_TEA_INCIDENT_STATUS: diseaseOutbreak.incidentStatus, - RTSL_ZEB_TEA_DATE_EMERGED: diseaseOutbreak.emerged.date.toISOString(), + RTSL_ZEB_TEA_DATE_EMERGED: getDateAsIsoString(diseaseOutbreak.emerged.date), RTSL_ZEB_TEA_DATE_EMERGED_NARRATIVE: diseaseOutbreak.emerged.narrative, - RTSL_ZEB_TEA_DATE_DETECTED: diseaseOutbreak.detected.date.toISOString(), + RTSL_ZEB_TEA_DATE_DETECTED: getDateAsIsoString(diseaseOutbreak.detected.date), RTSL_ZEB_TEA_DATE_DETECTED_NARRATIVE: diseaseOutbreak.detected.narrative, - RTSL_ZEB_TEA_DATE_NOTIFIED: diseaseOutbreak.notified.date.toISOString(), + RTSL_ZEB_TEA_DATE_NOTIFIED: getDateAsIsoString(diseaseOutbreak.notified.date), RTSL_ZEB_TEA_DATE_NOTIFIED_NARRATIVE: diseaseOutbreak.notified.narrative, - RTSL_ZEB_TEA_INITIATE_INVESTIGATION: - diseaseOutbreak.earlyResponseActions.initiateInvestigation.toISOString(), - RTSL_ZEB_TEA_CONDUCT_EPIDEMIOLOGICAL_ANALYSIS: - diseaseOutbreak.earlyResponseActions.conductEpidemiologicalAnalysis.toISOString(), - RTSL_ZEB_TEA_LABORATORY_CONFIRMATION: diseaseOutbreak.earlyResponseActions - .laboratoryConfirmation.na - ? "true" - : "", - RTSL_ZEB_TEA_SPECIFY_DATE1: - diseaseOutbreak.earlyResponseActions.laboratoryConfirmation.date?.toISOString() ?? "", - RTSL_ZEB_TEA_APPROPRIATE_CASE_MANAGEMENT: diseaseOutbreak.earlyResponseActions - .appropriateCaseManagement.na - ? "true" - : "", - RTSL_ZEB_TEA_SPECIFY_DATE2: - diseaseOutbreak.earlyResponseActions.appropriateCaseManagement.date?.toISOString() ?? - "", - RTSL_ZEB_TEA_APPROPRIATE_PUBLIC_HEALTH: diseaseOutbreak.earlyResponseActions - .initiatePublicHealthCounterMeasures.na - ? "true" - : "", - RTSL_ZEB_TEA_SPECIFY_DATE3: - diseaseOutbreak.earlyResponseActions.initiatePublicHealthCounterMeasures.date?.toISOString() ?? - "", - RTSL_ZEB_TEA_APPROPRIATE_RISK_COMMUNICATION: diseaseOutbreak.earlyResponseActions - .initiateRiskCommunication.na - ? "true" - : "", - RTSL_ZEB_TEA_SPECIFY_DATE4: - diseaseOutbreak.earlyResponseActions.initiateRiskCommunication.date?.toISOString() ?? - "", - RTSL_ZEB_TEA_ESTABLISH_COORDINATION_MECHANISM: - diseaseOutbreak.earlyResponseActions.establishCoordination.toISOString(), + RTSL_ZEB_TEA_INITIATE_INVESTIGATION: getDateAsIsoString( + diseaseOutbreak.earlyResponseActions.initiateInvestigation + ), + RTSL_ZEB_TEA_CONDUCT_EPIDEMIOLOGICAL_ANALYSIS: getDateAsIsoString( + diseaseOutbreak.earlyResponseActions.conductEpidemiologicalAnalysis + ), + RTSL_ZEB_TEA_LABORATORY_CONFIRMATION: getNaValue( + diseaseOutbreak.earlyResponseActions.laboratoryConfirmation.na + ), + RTSL_ZEB_TEA_SPECIFY_DATE1: getDateAsIsoString( + diseaseOutbreak.earlyResponseActions.laboratoryConfirmation.date + ), + RTSL_ZEB_TEA_APPROPRIATE_CASE_MANAGEMENT: getNaValue( + diseaseOutbreak.earlyResponseActions.appropriateCaseManagement.na + ), + + RTSL_ZEB_TEA_SPECIFY_DATE2: getDateAsIsoString( + diseaseOutbreak.earlyResponseActions.appropriateCaseManagement.date + ), + RTSL_ZEB_TEA_APPROPRIATE_PUBLIC_HEALTH: getNaValue( + diseaseOutbreak.earlyResponseActions.initiatePublicHealthCounterMeasures.na + ), + + RTSL_ZEB_TEA_SPECIFY_DATE3: getDateAsIsoString( + diseaseOutbreak.earlyResponseActions.initiatePublicHealthCounterMeasures.date + ), + RTSL_ZEB_TEA_APPROPRIATE_RISK_COMMUNICATION: getNaValue( + diseaseOutbreak.earlyResponseActions.initiateRiskCommunication.na + ), + RTSL_ZEB_TEA_SPECIFY_DATE4: getDateAsIsoString( + diseaseOutbreak.earlyResponseActions.initiateRiskCommunication.date + ), + RTSL_ZEB_TEA_ESTABLISH_COORDINATION_MECHANISM: getDateAsIsoString( + diseaseOutbreak.earlyResponseActions.establishCoordination + ), RTSL_ZEB_TEA_RESPONSE_NARRATIVE: diseaseOutbreak.earlyResponseActions.responseNarrative, RTSL_ZEB_TEA_ASSIGN_INCIDENT_MANAGER: diseaseOutbreak.incidentManagerName, RTSL_ZEB_TEA_NOTES: diseaseOutbreak.notes ?? "", }; } -function getHazardTypeCode(hazardType: HazardType): string { - switch (hazardType) { - case "Biological:Animal": - return "BIOLOGICAL_ANIMAL"; - case "Biological:Human": - return "BIOLOGICAL_HUMAN"; - case "Chemical": - return "CHEMICAL"; - case "Environmental": - return "ENVIRONMENTAL"; - case "Unknown": - return "UNKNOWN"; - } -} - function getOUTextFromList(OUs: string[]): string { return OUs[0] ?? ""; //TO DO : Handle multiple provinces/districts once metadata change is done } + +function getNaValue(naValue: Maybe): string { + return naValue ? "true" : ""; +} diff --git a/src/data/repositories/utils/AssertOrError.ts b/src/data/repositories/utils/AssertOrError.ts index 45b7057b..e23fe88c 100644 --- a/src/data/repositories/utils/AssertOrError.ts +++ b/src/data/repositories/utils/AssertOrError.ts @@ -1,7 +1,7 @@ import { Future } from "../../../domain/entities/generic/Future"; import { FutureData } from "../../api-futures"; -export function assertOrError(objects: T, name: string): FutureData> { - if (!objects) return Future.error(new Error(`${name} not found`)); - else return Future.success(objects); +export function assertOrError(obj: T, name: string): FutureData> { + if (!obj) return Future.error(new Error(`${name} not found`)); + else return Future.success(obj); } diff --git a/src/data/repositories/utils/DateTimeHelper.ts b/src/data/repositories/utils/DateTimeHelper.ts index 18e0d4c7..d2131e69 100644 --- a/src/data/repositories/utils/DateTimeHelper.ts +++ b/src/data/repositories/utils/DateTimeHelper.ts @@ -1,3 +1,9 @@ +import { Maybe } from "../../../utils/ts-utils"; + export function getCurrentTimeString(): string { return new Date().getTime().toString(); } + +export function getDateAsIsoString(date: Maybe): string { + return date ? date.toISOString() : ""; +} diff --git a/src/data/repositories/utils/DiseaseOutbreakMapper.ts b/src/data/repositories/utils/DiseaseOutbreakMapper.ts index 2edff2dd..dc851d7d 100644 --- a/src/data/repositories/utils/DiseaseOutbreakMapper.ts +++ b/src/data/repositories/utils/DiseaseOutbreakMapper.ts @@ -1,14 +1,13 @@ import { DiseaseOutbreakEventBaseAttrs, - HazardType, IncidentStatusType, } from "../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEvent"; import { D2TrackerTrackedEntity, Attribute } from "@eyeseetea/d2-api/api/trackerTrackedEntities"; import { DiseaseOutbreakCode, - DiseaseOutbreakCodes, + diseaseOutbreakCodes, + getHazardTypeValue, getValueFromDiseaseOutbreak, - isHazardType, isStringInDiseaseOutbreakCodes, KeyCode, RTSL_ZEBRA_ORG_UNIT_ID, @@ -32,14 +31,6 @@ type D2TrackedEntityAttribute = { >; }; -function getHazardTypeValue(hazardType: string): HazardType { - if (isHazardType(hazardType)) { - return hazardType; - } else { - return "Unknown"; - } -} - export function mapTrackedEntityAttributesToDiseaseOutbreak( trackedEntity: D2TrackerTrackedEntity ): DiseaseOutbreakEventBaseAttrs { @@ -174,8 +165,8 @@ export function mapDiseaseOutbreakEventToTrackedEntityAttributes( } function getValueFromMap( - key: keyof typeof DiseaseOutbreakCodes, + key: keyof typeof diseaseOutbreakCodes, trackedEntity: D2TrackerTrackedEntity ): string { - return trackedEntity.attributes?.find(a => a.code === DiseaseOutbreakCodes[key])?.value ?? ""; + return trackedEntity.attributes?.find(a => a.code === diseaseOutbreakCodes[key])?.value ?? ""; } diff --git a/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEvent.ts b/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEvent.ts index 2decfa6f..be54a941 100644 --- a/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEvent.ts +++ b/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEvent.ts @@ -7,12 +7,15 @@ import { Id, NamedRef } from "../Ref"; import { RiskAssessment } from "../risk-assessment/RiskAssessment"; import { Maybe } from "../../../utils/ts-utils"; -export type HazardType = - | "Biological:Human" - | "Biological:Animal" - | "Chemical" - | "Environmental" - | "Unknown"; +export const hazardTypes = [ + "Biological:Human", + "Biological:Animal", + "Chemical", + "Environmental", + "Unknown", +] as const; + +export type HazardType = (typeof hazardTypes)[number]; export type IncidentStatusType = "Watch" | "Alert" | "Respond" | "Closed" | "Discarded";