import { DeleteResult, EntityManager, InsertResult, UpdateResult } from "typeorm"; import { dataSource } from "../data-source"; import InternalException from "../exceptions/internalException"; import NewsletterRecipientsService from "../service/newsletterRecipientsService"; import { NewsletterRecipientCommand, SynchronizeNewsletterRecipientsCommand } from "./newsletterRecipientsCommand"; import { newsletterRecipients } from "../entity/newsletterRecipients"; export default abstract class NewsletterRecipientsCommandHandler { /** * @description sync newsletterRecipients * @param {SynchronizeNewsletterRecipientsCommand} syncNewsletterRecipients * @returns {Promise} */ static async sync(syncNewsletterRecipients: SynchronizeNewsletterRecipientsCommand): Promise { let currentRecipients = await NewsletterRecipientsService.getAll(syncNewsletterRecipients.newsletterId); return await dataSource.manager .transaction(async (manager) => { let newRecipients = syncNewsletterRecipients.recipients.filter( (r) => !currentRecipients.map((np) => np.memberId).includes(r.memberId) ); let removeRecipients = currentRecipients.filter( (r) => !syncNewsletterRecipients.recipients.map((np) => np.memberId).includes(r.memberId) ); let keptRecipients = currentRecipients.filter((r) => syncNewsletterRecipients.recipients.map((np) => np.memberId).includes(r.memberId) ); if (newRecipients.length != 0) { await this.syncPresenceAdd(manager, syncNewsletterRecipients.newsletterId, newRecipients); } if (removeRecipients.length != 0) { await this.syncPresenceRemove(manager, syncNewsletterRecipients.newsletterId, removeRecipients); } for (const recipient of keptRecipients) { await this.syncPresenceUpdate(manager, syncNewsletterRecipients.newsletterId, recipient); } }) .then(() => {}) .catch((err) => { throw new InternalException("Failed syncing newsletter recipients", err); }); } private static async syncPresenceAdd( manager: EntityManager, newsletterId: number, recipients: Array ): Promise { return await manager .createQueryBuilder() .insert() .into(newsletterRecipients) .values( recipients.map((d) => ({ ...d, newsletterId: newsletterId, })) ) .execute(); } private static async syncPresenceUpdate( manager: EntityManager, newsletterId: number, recipient: NewsletterRecipientCommand ): Promise { return await manager .createQueryBuilder() .update(newsletterRecipients) .set({ addedManually: recipient.addedManually, }) .where("memberId = :memberId", { memberId: recipient.memberId }) .andWhere("newsletterId = :newsletterId", { newsletterId }) .execute(); } private static async syncPresenceRemove( manager: EntityManager, newsletterId: number, recipients: Array ): Promise { return await manager .createQueryBuilder() .delete() .from(newsletterRecipients) .where("memberId IN (:...ids)", { ids: recipients.map((d) => d.memberId) }) .andWhere("newsletterId = :newsletterId", { newsletterId }) .execute(); } }