diff --git a/src/data/repositories/utils/DiseaseOutbreakMapper.ts b/src/data/repositories/utils/DiseaseOutbreakMapper.ts index 660ce1fb..67a09203 100644 --- a/src/data/repositories/utils/DiseaseOutbreakMapper.ts +++ b/src/data/repositories/utils/DiseaseOutbreakMapper.ts @@ -74,23 +74,34 @@ export function mapTrackedEntityAttributesToDiseaseOutbreak( ), laboratoryConfirmation: { date: new Date(getValueFromMap("laboratoryConfirmationDate", trackedEntity)), - na: getValueFromMap("laboratoryConfirmationNA", trackedEntity) === "true", + na: + getValueFromMap("laboratoryConfirmationNA", trackedEntity) === "true" + ? false + : true, }, appropriateCaseManagement: { date: new Date(getValueFromMap("appropriateCaseManagementDate", trackedEntity)), - na: getValueFromMap("appropriateCaseManagementNA", trackedEntity) === "true", + na: + getValueFromMap("appropriateCaseManagementNA", trackedEntity) === "true" + ? false + : true, }, initiatePublicHealthCounterMeasures: { date: new Date( - getValueFromMap("initiatePublicHealthCounterMeasuresNA", trackedEntity) + getValueFromMap("initiatePublicHealthCounterMeasuresDate", trackedEntity) ), na: - getValueFromMap("initiatePublicHealthCounterMeasuresDate", trackedEntity) === - "true", + getValueFromMap("initiatePublicHealthCounterMeasuresNA", trackedEntity) === + "true" + ? false + : true, }, initiateRiskCommunication: { date: new Date(getValueFromMap("initiateRiskCommunicationDate", trackedEntity)), - na: getValueFromMap("initiateRiskCommunicationNA", trackedEntity) === "true", + na: + getValueFromMap("initiateRiskCommunicationNA", trackedEntity) === "true" + ? false + : true, }, establishCoordination: new Date( getValueFromMap("establishCoordination", trackedEntity) @@ -165,7 +176,7 @@ function getValueFromDiseaseOutbreak( ): string { switch (key) { case "RTSL_ZEB_TEA_EVENT_id": - return diseaseOutbreak.eventId.toString(); + return diseaseOutbreak.eventId?.toString() || ""; case "RTSL_ZEB_TEA_EVENT_NAME": return diseaseOutbreak.name; case "RTSL_ZEB_TEA_HAZARD_TYPE": @@ -213,7 +224,7 @@ function getValueFromDiseaseOutbreak( case "RTSL_ZEB_TEA_LABORATORY_CONFIRMATION": return diseaseOutbreak.earlyResponseActions.laboratoryConfirmation.na ? "true" : ""; case "RTSL_ZEB_TEA_SPECIFY_DATE1": - return diseaseOutbreak.earlyResponseActions.laboratoryConfirmation.date.toISOString(); + return diseaseOutbreak.earlyResponseActions.laboratoryConfirmation.date?.toISOString(); case "RTSL_ZEB_TEA_APPROPRIATE_CASE_MANAGEMENT": return diseaseOutbreak.earlyResponseActions.appropriateCaseManagement.na ? "true" : ""; case "RTSL_ZEB_TEA_SPECIFY_DATE2": diff --git a/src/domain/entities/ValidationError.ts b/src/domain/entities/ValidationError.ts new file mode 100644 index 00000000..68ea0518 --- /dev/null +++ b/src/domain/entities/ValidationError.ts @@ -0,0 +1,11 @@ +export type ValidationErrorKey = + | "field_is_required" + | "field_is_required_na" + | "detected_before_emerged" + | "notified_before_emerged"; + +export type ValidationError = { + property: string; + value: unknown; + errors: ValidationErrorKey[]; +}; diff --git a/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEvent.ts b/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEvent.ts index 20275af3..07861bb2 100644 --- a/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEvent.ts +++ b/src/domain/entities/disease-outbreak-event/DiseaseOutbreakEvent.ts @@ -6,6 +6,7 @@ import { OrgUnit } from "../OrgUnit"; import { Id, NamedRef } from "../Ref"; import { RiskAssessment } from "../risk-assessment/RiskAssessment"; import { Maybe } from "../../../utils/ts-utils"; +import { ValidationError, ValidationErrorKey } from "../ValidationError"; export type HazardType = | "Biological:Human" @@ -38,7 +39,7 @@ type EarlyResponseActions = { }; export type DiseaseOutbreakEventBaseAttrs = NamedRef & { - eventId: number; + eventId: Maybe; created: Date; lastUpdated: Date; createdByName: Maybe; @@ -52,12 +53,12 @@ export type DiseaseOutbreakEventBaseAttrs = NamedRef & { emerged: DateWithNarrative; detected: DateWithNarrative; notified: DateWithNarrative; - earlyResponseActions: EarlyResponseActions; //TO DO : mandatory field + earlyResponseActions: EarlyResponseActions; incidentManagerName: string; notes: Maybe; }; -type DiseaseOutbreakEventAttrs = DiseaseOutbreakEventBaseAttrs & { +export type DiseaseOutbreakEventAttrs = DiseaseOutbreakEventBaseAttrs & { createdBy: Maybe; mainSyndrome: NamedRef; suspectedDisease: NamedRef; @@ -76,7 +77,45 @@ type DiseaseOutbreakEventAttrs = DiseaseOutbreakEventBaseAttrs & { **/ export class DiseaseOutbreakEvent extends Struct() { - static validateEventName() { - //TO DO : Ensure event name is unique on event creation. + //TODO: Add required validations, this is an example: + static validate(data: DiseaseOutbreakEventBaseAttrs): ValidationError[] { + const validationErrors: ValidationError[] = [ + { + property: "detected_date" as const, + errors: DiseaseOutbreakEvent.validateDateDetectedBeforeEmerged(data), + value: data.id, + }, + { + property: "notified_date" as const, + errors: DiseaseOutbreakEvent.validateDateNotifiedBeforeEmerged(data), + value: data.id, + }, + ]; + + const filteredValidationErrorsWithErrors = validationErrors.filter( + v => v.errors.length > 0 + ); + + return filteredValidationErrorsWithErrors.length ? validationErrors : []; + } + + static validateDateDetectedBeforeEmerged( + data: DiseaseOutbreakEventBaseAttrs + ): ValidationErrorKey[] { + return data.detected.date && + data.emerged.date && + data.detected.date.getTime() < data.emerged.date.getTime() + ? ["detected_before_emerged"] + : []; + } + + static validateDateNotifiedBeforeEmerged( + data: DiseaseOutbreakEventBaseAttrs + ): ValidationErrorKey[] { + return data.notified.date && + data.emerged.date && + data.notified.date.getTime() < data.emerged.date.getTime() + ? ["notified_before_emerged"] + : []; } }