Skip to content

Commit

Permalink
Merge domain entities in useIMTeamBuilder to create presentation entity
Browse files Browse the repository at this point in the history
  • Loading branch information
anagperal committed Oct 24, 2024
1 parent 616639c commit c5c4c46
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 46 deletions.
10 changes: 10 additions & 0 deletions src/CompositionRoot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ import { SystemD2Repository } from "./data/repositories/SystemD2Repository";
import { SystemTestRepository } from "./data/repositories/test/SystemTestRepository";
import { GetOverviewCardsUseCase } from "./domain/usecases/GetOverviewCardsUseCase";
import { GetDiseaseOutbreakEventAggregateRootByIdUseCase } from "./domain/usecases/GetDiseaseOutbreakEventAggregateRootByIdUseCase";
import { GetAllRolesUseCase } from "./domain/usecases/GetAllRolesUseCase";
import { GetTeamMembersForIncidentManagementTeamUseCase } from "./domain/usecases/GetTeamMembersForIncidentManagementTeamUseCase";

export type CompositionRoot = ReturnType<typeof getCompositionRoot>;

Expand Down Expand Up @@ -117,6 +119,14 @@ function getCompositionRoot(repositories: Repositories) {
charts: {
getCases: new GetChartConfigByTypeUseCase(repositories.chartConfigRepository),
},
teamMembers: {
getForIncidentManagementTeam: new GetTeamMembersForIncidentManagementTeamUseCase(
repositories.teamMemberRepository
),
},
roles: {
getAll: new GetAllRolesUseCase(repositories.roleRepository),
},
};
}

Expand Down
57 changes: 37 additions & 20 deletions src/data/repositories/DiseaseOutbreakEventD2Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,29 +284,46 @@ export class DiseaseOutbreakEventD2Repository implements DiseaseOutbreakEventRep
}

private getIncidentManagementTeamInAggregateRoot(
diseaseOutbreakId: Id
diseaseOutbreakEventId: Id
): FutureData<IncidentManagementTeamInAggregateRoot> {
return apiToFuture(
this.api.tracker.events.get({
program: RTSL_ZEBRA_PROGRAM_ID,
orgUnit: RTSL_ZEBRA_ORG_UNIT_ID,
trackedEntity: diseaseOutbreakId,
programStage: RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_PROGRAM_STAGE_ID,
fields: {
dataValues: {
dataElement: dataElementFields,
value: true,
},
trackedEntity: true,
event: true,
},
})
return getProgramStage(
this.api,
RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_PROGRAM_STAGE_ID
)
.flatMap(response =>
assertOrError(response.instances, `Incident management team not found`)
.flatMap(incidentManagementTeamBuilderResponse =>
assertOrError(
incidentManagementTeamBuilderResponse.objects[0],
`Incident management team builder program stage not found`
)
)
.flatMap(d2Events => {
return Future.success(mapD2EventsToIncidentManagementTeamInAggregateRoot(d2Events));
.flatMap(programStageDataElementsMetadata => {
return apiToFuture(
this.api.tracker.events.get({
program: RTSL_ZEBRA_PROGRAM_ID,
orgUnit: RTSL_ZEBRA_ORG_UNIT_ID,
trackedEntity: diseaseOutbreakEventId,
programStage: RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_PROGRAM_STAGE_ID,
fields: {
dataValues: {
dataElement: dataElementFields,
value: true,
},
trackedEntity: true,
event: true,
},
})
)
.flatMap(response =>
assertOrError(response.instances, `Incident management team not found`)
)
.flatMap(d2Events => {
return Future.success(
mapD2EventsToIncidentManagementTeamInAggregateRoot(
d2Events,
programStageDataElementsMetadata.programStageDataElements
)
);
});
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/data/repositories/TeamMemberD2Repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class TeamMemberD2Repository implements TeamMemberRepository {
return this.getTeamMembersByUserGroup(RTSL_ZEBRA_RISKASSESSOR);
}

getForIncidentManagementTeamMembers(): FutureData<TeamMember[]> {
getForIncidentManagementTeam(): FutureData<TeamMember[]> {
return this.getTeamMembersByUserGroup(RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_MEMBERS);
}

Expand Down
2 changes: 1 addition & 1 deletion src/data/repositories/test/TeamMemberTestRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class TeamMemberTestRepository implements TeamMemberRepository {
return Future.success([teamMember]);
}

getForIncidentManagementTeamMembers(): FutureData<TeamMember[]> {
getForIncidentManagementTeam(): FutureData<TeamMember[]> {
const teamMember: TeamMember = new TeamMember({
id: "incidentManagementTeamMember",
username: "incidentManagementTeamMember",
Expand Down
89 changes: 80 additions & 9 deletions src/data/repositories/utils/IncidentManagementTeamMapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import {
RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_IDS_WITHOUT_ROLES,
} from "../consts/IncidentManagementTeamBuilderConstants";
import { D2ProgramStageDataElementsMetadata } from "./MetadataHelper";
import { IncidentManagementTeamInAggregateRoot } from "../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot";
import {
IncidentManagementTeamInAggregateRoot,
IncidentManagementTeamRole,
} from "../../../domain/entities/disease-outbreak-event/DiseaseOutbreakEventAggregateRoot";

export function mapD2EventsToIncidentManagementTeam(
diseaseOutbreakId: Id,
Expand Down Expand Up @@ -192,17 +195,85 @@ function getValueFromIncidentManagementTeamMember(
}

export function mapD2EventsToIncidentManagementTeamInAggregateRoot(
d2Events: D2TrackerEvent[]
d2Events: D2TrackerEvent[],
incidentManagementTeamProgramStageDataElements: D2ProgramStageDataElementsMetadata[]
): IncidentManagementTeamInAggregateRoot {
const incidentManagementTeamMembers = d2Events.map(event => {
const teamMemberAssignedUsername = getValueById(
event.dataValues,
RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_IDS_WITHOUT_ROLES.teamMemberAssigned
);
return teamMemberAssignedUsername;
});
const incidentManagementTeamRolesByUsername = getIncidentManagementTeamRolesByUsername(
d2Events,
incidentManagementTeamProgramStageDataElements
);

const incidentManagementTeamMembers = Object.keys(incidentManagementTeamRolesByUsername).map(
username => {
const teamRoles = incidentManagementTeamRolesByUsername[username];
return teamRoles
? {
username: username,
teamRoles: teamRoles,
}
: null;
}
);

return new IncidentManagementTeamInAggregateRoot({
teamHierarchy: _c(incidentManagementTeamMembers).compact().toArray(),
});
}

function getIncidentManagementTeamRolesByUsername(
d2Events: D2TrackerEvent[],
incidentManagementTeamProgramStageDataElements: D2ProgramStageDataElementsMetadata[]
): Record<string, IncidentManagementTeamRole[]> {
return d2Events.reduce(
(acc: Record<string, IncidentManagementTeamRole[]>, event: D2TrackerEvent) => {
const teamMemberAssignedUsername = getValueById(
event.dataValues,
RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_IDS_WITHOUT_ROLES.teamMemberAssigned
);

if (!teamMemberAssignedUsername) {
return acc;
}

const teamRoles = incidentManagementTeamProgramStageDataElements.reduce(
(accTeamRoles: IncidentManagementTeamRole[], programStage) => {
const roleId = programStage.dataElement.id;
const reportsToUsername = getValueById(
event.dataValues,
RTSL_ZEBRA_INCIDENT_MANAGEMENT_TEAM_BUILDER_IDS_WITHOUT_ROLES.reportsToUsername
);

if (getValueById(event.dataValues, roleId) === "true") {
return [
...accTeamRoles,
{
id: event.event,
roleId: roleId,
reportsToUsername: reportsToUsername,
},
];
}

return accTeamRoles;
},
[]
);

if (acc[teamMemberAssignedUsername]) {
return {
...acc,
[teamMemberAssignedUsername]: [
...(acc[teamMemberAssignedUsername] || []),
...teamRoles,
],
};
} else {
return {
...acc,
[teamMemberAssignedUsername]: teamRoles,
};
}
},
{}
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,19 @@ export type DiseaseOutbreakEventAggregateRootBaseAttrs = NamedRef & {
notes: Maybe<string>;
};

type IncidentManagementTeamMemberUsername = string;
export type IncidentManagementTeamRole = {
id: Id;
roleId: Id;
reportsToUsername: Maybe<string>;
};

type IncidentManagementTeamMember = {
username: string;
teamRoles: IncidentManagementTeamRole[];
};

interface IncidentManagementTeamAttrsInAggregateRoot {
teamHierarchy: IncidentManagementTeamMemberUsername[];
teamHierarchy: IncidentManagementTeamMember[];
}

export class IncidentManagementTeamInAggregateRoot extends Struct<IncidentManagementTeamAttrsInAggregateRoot>() {}
Expand Down
2 changes: 1 addition & 1 deletion src/domain/repositories/TeamMemberRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ export interface TeamMemberRepository {
get(id: Id): FutureData<TeamMember>;
getIncidentManagers(): FutureData<TeamMember[]>;
getRiskAssessors(): FutureData<TeamMember[]>;
getForIncidentManagementTeamMembers(): FutureData<TeamMember[]>;
getForIncidentManagementTeam(): FutureData<TeamMember[]>;
}
11 changes: 11 additions & 0 deletions src/domain/usecases/GetAllRolesUseCase.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { FutureData } from "../../data/api-futures";
import { Role } from "../entities/incident-management-team/Role";
import { RoleRepository } from "../repositories/RoleRepository";

export class GetAllRolesUseCase {
constructor(private roleRepository: RoleRepository) {}

public execute(): FutureData<Role[]> {
return this.roleRepository.getAll();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { FutureData } from "../../data/api-futures";
import { TeamMember } from "../entities/incident-management-team/TeamMember";
import { TeamMemberRepository } from "../repositories/TeamMemberRepository";

export class GetTeamMembersForIncidentManagementTeamUseCase {
constructor(private teamMemberRepository: TeamMemberRepository) {}

public execute(): FutureData<TeamMember[]> {
return this.teamMemberRepository.getForIncidentManagementTeam();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export function getIncidentManagementTeamById(
diseaseOutbreakEventRepository: DiseaseOutbreakEventRepository;
}
): FutureData<Maybe<IncidentManagementTeam>> {
return repositories.teamMemberRepository.getAll().flatMap(teamMembers => {
return repositories.teamMemberRepository.getForIncidentManagementTeam().flatMap(teamMembers => {
return repositories.diseaseOutbreakEventRepository.getIncidentManagementTeam(
diseaseOutbreakId,
teamMembers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export function getIncidentManagementTeamWithOptions(
): FutureData<IncidentManagementTeamMemberFormData> {
return Future.joinObj({
roles: repositories.roleRepository.getAll(),
teamMembers: repositories.teamMemberRepository.getForIncidentManagementTeamMembers(),
teamMembers: repositories.teamMemberRepository.getForIncidentManagementTeam(),
incidentManagers: repositories.teamMemberRepository.getIncidentManagers(),
incidentManagementTeam: getIncidentManagementTeamById(eventTrackerDetails.id, repositories),
}).flatMap(({ roles, teamMembers, incidentManagers, incidentManagementTeam }) => {
Expand Down
Loading

0 comments on commit c5c4c46

Please sign in to comment.