import { DeleteResult, EntityManager, InsertResult, UpdateResult } from "typeorm"; import { dataSource } from "../data-source"; import { protocolPresence } from "../entity/protocolPresence"; import InternalException from "../exceptions/internalException"; import ProtocolPresenceService from "../service/protocolPrecenseService"; import { ProtocolPresenceCommand, SynchronizeProtocolPresenceCommand } from "./protocolPresenceCommand"; export default abstract class ProtocolPresenceCommandHandler { /** * @description sync protocolPresence * @param {SynchronizeProtocolPresenceCommand} * @returns {Promise<void>} */ static async sync(syncProtocolPresences: SynchronizeProtocolPresenceCommand): Promise<void> { let currentPresence = await ProtocolPresenceService.getAll(syncProtocolPresences.protocolId); return await dataSource.manager .transaction(async (manager) => { let newMembers = syncProtocolPresences.members.filter( (r) => !currentPresence.some((cp) => cp.memberId == r.memberId) ); let removeMembers = currentPresence.filter( (r) => !syncProtocolPresences.members.some((cp) => cp.memberId == r.memberId) ); let keptMembers = syncProtocolPresences.members.filter( (m) => currentPresence.some((cd) => cd.memberId == m.memberId) && !removeMembers.some((cd) => cd.memberId == m.memberId) ); if (newMembers.length != 0) { await this.syncPresenceAdd(manager, syncProtocolPresences.protocolId, newMembers); } if (removeMembers.length != 0) { await this.syncPresenceRemove(manager, syncProtocolPresences.protocolId, removeMembers); } for (const member of keptMembers) { await this.syncPresenceUpdate(manager, syncProtocolPresences.protocolId, member); } }) .then(() => {}) .catch((err) => { throw new InternalException("Failed saving protocol presence", err); }); } private static async syncPresenceAdd( manager: EntityManager, protocolId: number, memberIds: Array<ProtocolPresenceCommand> ): Promise<InsertResult> { return await manager .createQueryBuilder() .insert() .into(protocolPresence) .values( memberIds.map((m) => ({ ...m, protocolId, })) ) .execute(); } private static async syncPresenceUpdate( manager: EntityManager, protocolId: number, member: ProtocolPresenceCommand ): Promise<UpdateResult> { return await manager .createQueryBuilder() .update(protocolPresence) .set({ absent: member.absent, }) .where("memberId = :memberId", { memberId: member.memberId }) .andWhere("protocolId = :protocolId", { protocolId }) .execute(); } private static async syncPresenceRemove( manager: EntityManager, protocolId: number, members: Array<ProtocolPresenceCommand> ): Promise<DeleteResult> { return await manager .createQueryBuilder() .delete() .from(protocolPresence) .where("memberId IN (:...ids)", { ids: members.map((m) => m.memberId) }) .andWhere("protocolId = :protocolId", { protocolId }) .execute(); } }