diff --git a/src/data/repositories/AlertD2Repository.ts b/src/data/repositories/AlertD2Repository.ts index 010c2a27..f2369292 100644 --- a/src/data/repositories/AlertD2Repository.ts +++ b/src/data/repositories/AlertD2Repository.ts @@ -22,33 +22,45 @@ export class AlertD2Repository implements AlertRepository { updateAlerts(alertOptions: AlertOptions): FutureData { const { eventId, filter, incidentStatus } = alertOptions; - return this.getTrackedEntitiesByTEACode(filter).flatMap(response => { - const alertsToMap = response.map(trackedEntity => ({ - ...trackedEntity, - attributes: [ - { - attribute: RTSL_ZEBRA_ALERTS_NATIONAL_DISEASE_OUTBREAK_EVENT_ID_TEA_ID, - value: eventId, - }, - { - attribute: RTSL_ZEBRA_ALERTS_NATIONAL_INCIDENT_STATUS_TEA_ID, - value: incidentStatus, - }, - ], - })); + return this.getTEAOptions(RTSL_ZEBRA_ALERTS_NATIONAL_INCIDENT_STATUS_TEA_ID).flatMap( + response => { + const options = response.objects[0]?.optionSet.options ?? []; + const incidentStatusCode = options.find( + option => option.name === incidentStatus + )?.code; + + if (!incidentStatusCode) throw new Error("Incident status code not found"); - if (alertsToMap.length === 0) return Future.success(undefined); + return this.getTrackedEntitiesByTEACode(filter).flatMap(response => { + const alertsToMap = response.map(trackedEntity => ({ + ...trackedEntity, + attributes: [ + { + attribute: + RTSL_ZEBRA_ALERTS_NATIONAL_DISEASE_OUTBREAK_EVENT_ID_TEA_ID, + value: eventId, + }, + { + attribute: RTSL_ZEBRA_ALERTS_NATIONAL_INCIDENT_STATUS_TEA_ID, + value: incidentStatusCode, + }, + ], + })); - return apiToFuture( - this.api.tracker.post( - { importStrategy: "UPDATE" }, - { trackedEntities: alertsToMap } - ) - ).map(saveResponse => { - if (saveResponse.status === "ERROR") - throw new Error("Error mapping disease outbreak event id to alert"); - }); - }); + if (alertsToMap.length === 0) return Future.success(undefined); + + return apiToFuture( + this.api.tracker.post( + { importStrategy: "UPDATE" }, + { trackedEntities: alertsToMap } + ) + ).map(saveResponse => { + if (saveResponse.status === "ERROR") + throw new Error("Error mapping disease outbreak event id to alert"); + }); + }); + } + ); } private async getTrackedEntitiesByTEACodeAsync(filter: { @@ -97,4 +109,24 @@ export class AlertD2Repository implements AlertRepository { }): FutureData { return Future.fromPromise(this.getTrackedEntitiesByTEACodeAsync(filter)); } + + private getTEAOptions(trackedEntityAttributeId: Id) { + return apiToFuture( + this.api.models.trackedEntityAttributes.get({ + fields: { + optionSet: { + options: { + code: true, + name: true, + }, + }, + }, + filter: { + id: { + eq: trackedEntityAttributeId, + }, + }, + }) + ); + } } diff --git a/src/data/repositories/consts/DiseaseOutbreakConstants.ts b/src/data/repositories/consts/DiseaseOutbreakConstants.ts index 3c7fe9d5..73699157 100644 --- a/src/data/repositories/consts/DiseaseOutbreakConstants.ts +++ b/src/data/repositories/consts/DiseaseOutbreakConstants.ts @@ -1,6 +1,7 @@ import { DiseaseOutbreakEventBaseAttrs, HazardType, + IncidentStatusType, } from "../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEvent"; import { GetValue, Maybe } from "../../../utils/ts-utils"; import { getDateAsIsoString } from "../utils/DateTimeHelper"; @@ -13,7 +14,7 @@ export const RTSL_ZEBRA_ALERTS_PROGRAM_ID = "MQtbs8UkBxy"; export const RTSL_ZEBRA_ALERTS_NATIONAL_DISEASE_OUTBREAK_EVENT_ID_TEA_ID = "Pq1drzz2HJk"; export const RTSL_ZEBRA_ALERTS_DISEASE_TEA_ID = "agsVaIpit4S"; export const RTSL_ZEBRA_ALERTS_EVENT_TYPE_TEA_ID = "ydsfY6zyvt7"; -export const RTSL_ZEBRA_ALERTS_NATIONAL_INCIDENT_STATUS_TEA_ID = "IpGLuK0W5y2"; +export const RTSL_ZEBRA_ALERTS_NATIONAL_INCIDENT_STATUS_TEA_ID = "KeUbzfFQYCX"; export const hazardTypeCodeMap: Record = { "Biological:Human": "BIOLOGICAL_HUMAN", @@ -24,6 +25,14 @@ export const hazardTypeCodeMap: Record = { Unknown: "UNKNOWN", }; +export const incidentStatusTypeMap: Record = { + WATCH: "Watch", + ALERT: "Alert", + RESPOND: "Respond", + CLOSED: "Closed", + DISCARDED: "Discarded", +}; + export const diseaseOutbreakCodes = { name: "RTSL_ZEB_TEA_EVENT_NAME", dataSource: "RTSL_ZEB_TEA_DATA_SOURCE", diff --git a/src/domain/repositories/AlertRepository.ts b/src/domain/repositories/AlertRepository.ts index c3e054c8..c86b6ed8 100644 --- a/src/domain/repositories/AlertRepository.ts +++ b/src/domain/repositories/AlertRepository.ts @@ -10,5 +10,5 @@ export interface AlertRepository { export type AlertOptions = { eventId: Id; filter: { id: Id; value: Maybe }; - incidentStatus: IncidentStatusType; + incidentStatus: Maybe; }; diff --git a/src/domain/usecases/MapDiseaseOutbreakToAlertsUseCase.ts b/src/domain/usecases/MapDiseaseOutbreakToAlertsUseCase.ts index 28cb4068..59de71ed 100644 --- a/src/domain/usecases/MapDiseaseOutbreakToAlertsUseCase.ts +++ b/src/domain/usecases/MapDiseaseOutbreakToAlertsUseCase.ts @@ -6,6 +6,7 @@ import { DiseaseOutbreakEventBaseAttrs } from "../entities/disease-outbreak-even import { Future } from "../entities/generic/Future"; import { hazardTypeCodeMap, + incidentStatusTypeMap, RTSL_ZEBRA_ALERTS_DISEASE_TEA_ID, RTSL_ZEBRA_ALERTS_EVENT_TYPE_TEA_ID, } from "../../data/repositories/consts/DiseaseOutbreakConstants"; @@ -26,7 +27,9 @@ export class MapDiseaseOutbreakToAlertsUseCase { ): FutureData { const { dataSource, hazardType, incidentStatus, suspectedDiseaseCode } = diseaseOutbreakEventData; + const hazardTypeCode = hazardType ? hazardTypeCodeMap[hazardType] : undefined; + const incidentStatusTypeCode = incidentStatusTypeMap[incidentStatus]; if (!diseaseOutbreakEventId) return Future.error(new Error("Disease Outbreak Event Id is required")); @@ -39,7 +42,7 @@ export class MapDiseaseOutbreakToAlertsUseCase { return this.alertRepository.updateAlerts({ eventId: diseaseOutbreakEventId, filter: filter, - incidentStatus: incidentStatus, + incidentStatus: incidentStatusTypeCode, }); } }