import { DeleteResult, EntityManager, InsertResult, UpdateResult } from "typeorm"; import { dataSource } from "../data-source"; import InternalException from "../exceptions/internalException"; import NewsletterDatesService from "../service/newsletterDatesService"; import { NewsletterDateCommand, SynchronizeNewsletterDatesCommand } from "./newsletterDatesCommand"; import { newsletterDates } from "../entity/newsletterDates"; export default abstract class NewsletterDatesCommandHandler { /** * @description sync newsletter dates * @param {SynchronizeNewsletterDatesCommand} syncNewsletterDates * @returns {Promise} */ static async sync(syncNewsletterDates: SynchronizeNewsletterDatesCommand): Promise { let currentDates = await NewsletterDatesService.getAll(syncNewsletterDates.newsletterId); return await dataSource.manager .transaction(async (manager) => { let newDates = syncNewsletterDates.dates.filter( (r) => !currentDates.map((np) => np.calendarId).includes(r.calendarId) ); let removeDates = currentDates.filter( (r) => !syncNewsletterDates.dates.map((np) => np.calendarId).includes(r.calendarId) ); let keptDates = currentDates.filter((r) => syncNewsletterDates.dates.map((np) => np.calendarId).includes(r.calendarId) ); if (newDates.length != 0) { await this.syncPresenceAdd(manager, syncNewsletterDates.newsletterId, newDates); } if (removeDates.length != 0) { await this.syncPresenceRemove(manager, syncNewsletterDates.newsletterId, removeDates); } for (const date of keptDates) { await this.syncPresenceUpdate(manager, syncNewsletterDates.newsletterId, date); } }) .then(() => {}) .catch((err) => { throw new InternalException("Failed syncing newsletter dates", err); }); } private static async syncPresenceAdd( manager: EntityManager, newsletterId: number, dates: Array ): Promise { return await manager .createQueryBuilder() .insert() .into(newsletterDates) .values( dates.map((d) => ({ ...d, newsletterId: newsletterId, })) ) .execute(); } private static async syncPresenceUpdate( manager: EntityManager, newsletterId: number, date: NewsletterDateCommand ): Promise { return await manager .createQueryBuilder() .update(newsletterDates) .set({ diffTitle: date.diffTitle, diffDescription: date.diffDescription, }) .where("calendarId = :calendarId", { calendarId: date.calendarId }) .andWhere("newsletterId = :newsletterId", { newsletterId }) .execute(); } private static async syncPresenceRemove( manager: EntityManager, newsletterId: number, dates: Array ): Promise { return await manager .createQueryBuilder() .delete() .from(newsletterDates) .where("calendarId IN (:...ids)", { ids: dates.map((d) => d.calendarId) }) .andWhere("newsletterId = :newsletterId", { newsletterId }) .execute(); } }