219 lines
8 KiB
TypeScript
219 lines
8 KiB
TypeScript
|
import Mail from "nodemailer/lib/mailer";
|
||
|
import { member } from "../entity/member";
|
||
|
import { newsletter } from "../entity/newsletter";
|
||
|
import { newsletterDates } from "../entity/newsletterDates";
|
||
|
import { newsletterRecipients } from "../entity/newsletterRecipients";
|
||
|
import MemberService from "../service/memberService";
|
||
|
import NewsletterDatesService from "../service/newsletterDatesService";
|
||
|
import NewsletterRecipientsService from "../service/newsletterRecipientsService";
|
||
|
import NewsletterService from "../service/newsletterService";
|
||
|
import { CalendarHelper } from "./calendarHelper";
|
||
|
import DynamicQueryBuilder from "./dynamicQueryBuilder";
|
||
|
import { FileSystemHelper } from "./fileSystemHelper";
|
||
|
import MailHelper from "./mailHelper";
|
||
|
import { CLUB_NAME } from "../env.defaults";
|
||
|
import { TemplateHelper } from "./templateHelper";
|
||
|
import { PdfExport } from "./pdfExport";
|
||
|
import NewsletterConfigService from "../service/newsletterConfigService";
|
||
|
import { NewsletterConfigType } from "../enums/newsletterConfigType";
|
||
|
import InternalException from "../exceptions/internalException";
|
||
|
|
||
|
export abstract class NewsletterHelper {
|
||
|
public static buildData(
|
||
|
newsletter: newsletter,
|
||
|
dates: Array<newsletterDates>,
|
||
|
recipient?: member,
|
||
|
showAdress: boolean = false
|
||
|
) {
|
||
|
return {
|
||
|
title: newsletter.title,
|
||
|
description: newsletter.description,
|
||
|
newsletterTitle: newsletter.newsletterTitle,
|
||
|
newsletterText: newsletter.newsletterText,
|
||
|
newsletterSignatur: newsletter.newsletterSignatur,
|
||
|
dates: dates.map((d) => ({
|
||
|
title: d.diffTitle ?? d.calendar.title,
|
||
|
content: d.diffDescription ?? d.calendar.content,
|
||
|
starttime: d.calendar.starttime,
|
||
|
formattedStarttime: new Date(d.calendar.starttime).toLocaleDateString("de-DE", {
|
||
|
weekday: "long",
|
||
|
day: "2-digit",
|
||
|
month: "long",
|
||
|
}),
|
||
|
formattedFullStarttime: new Date(d.calendar.starttime).toLocaleDateString("de-DE", {
|
||
|
weekday: "long",
|
||
|
day: "2-digit",
|
||
|
month: "long",
|
||
|
year: "numeric",
|
||
|
hour: "2-digit",
|
||
|
minute: "2-digit",
|
||
|
}),
|
||
|
endtime: d.calendar.endtime,
|
||
|
formattedEndtime: new Date(d.calendar.endtime).toLocaleDateString("de-DE", {
|
||
|
weekday: "long",
|
||
|
day: "2-digit",
|
||
|
month: "long",
|
||
|
}),
|
||
|
formattedFullEndtime: new Date(d.calendar.endtime).toLocaleDateString("de-DE", {
|
||
|
weekday: "long",
|
||
|
day: "2-digit",
|
||
|
month: "long",
|
||
|
year: "numeric",
|
||
|
hour: "2-digit",
|
||
|
minute: "2-digit",
|
||
|
}),
|
||
|
location: d.calendar.location,
|
||
|
})),
|
||
|
...(recipient
|
||
|
? {
|
||
|
recipient: {
|
||
|
firstname: recipient.firstname,
|
||
|
lastname: recipient.lastname,
|
||
|
salutation: recipient.salutation,
|
||
|
nameaffix: recipient.nameaffix,
|
||
|
...(showAdress
|
||
|
? {
|
||
|
street: recipient.sendNewsletter.street ?? "",
|
||
|
streetNumber: recipient.sendNewsletter.streetNumber ?? "",
|
||
|
streetNumberAdd: recipient.sendNewsletter.streetNumberAddition ?? "",
|
||
|
}
|
||
|
: {}),
|
||
|
},
|
||
|
}
|
||
|
: {}),
|
||
|
};
|
||
|
}
|
||
|
|
||
|
public static async transformRecipientsToMembers(
|
||
|
newsletter: newsletter,
|
||
|
recipients: Array<newsletterRecipients>
|
||
|
): Promise<Array<member>> {
|
||
|
let useQuery = newsletter.recipientsByQuery?.query;
|
||
|
|
||
|
let queryMemberIds: Array<number> = [];
|
||
|
if (useQuery) {
|
||
|
let result = await DynamicQueryBuilder.executeQuery(
|
||
|
useQuery.startsWith("{") ? JSON.parse(useQuery) : useQuery,
|
||
|
0,
|
||
|
1000
|
||
|
);
|
||
|
if (result.stats == "success") {
|
||
|
let keys = Object.keys(result.rows?.[0] ?? {});
|
||
|
let memberKey = keys.find((k) => k.includes("member_id"));
|
||
|
queryMemberIds = result.rows.map((t) => parseInt((t[memberKey] ?? t.id) as string));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (let recipient of recipients) {
|
||
|
if (!queryMemberIds.includes(recipient.memberId)) {
|
||
|
queryMemberIds.push(recipient.memberId);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
console.log(queryMemberIds);
|
||
|
|
||
|
let members = await MemberService.getAll(0, 1000);
|
||
|
|
||
|
return members[0].filter((m) => queryMemberIds.includes(m.id));
|
||
|
}
|
||
|
|
||
|
public static getICSFilePath(newsletter: newsletter) {
|
||
|
return FileSystemHelper.formatPath(
|
||
|
"newsletter",
|
||
|
`${newsletter.id}_${newsletter.title.replace(" ", "")}`,
|
||
|
`events.ics`
|
||
|
);
|
||
|
}
|
||
|
|
||
|
public static saveIcsToFile(newsletter: newsletter, ics: string) {
|
||
|
FileSystemHelper.writeFile(`newsletter/${newsletter.id}_${newsletter.title.replace(" ", "")}`, "events.ics", ics);
|
||
|
}
|
||
|
|
||
|
public static async sendMails(newsletterId: number) {
|
||
|
let newsletter = await NewsletterService.getById(newsletterId);
|
||
|
let dates = await NewsletterDatesService.getAll(newsletterId);
|
||
|
let recipients = await NewsletterRecipientsService.getAll(newsletterId);
|
||
|
let config = await NewsletterConfigService.getAll();
|
||
|
|
||
|
const { value, error } = CalendarHelper.buildICS(dates.map((r) => r.calendar));
|
||
|
if (error) throw new InternalException("Failed Building ICS form Mail", error);
|
||
|
this.saveIcsToFile(newsletter, value);
|
||
|
|
||
|
let allowedForMail = config.filter((c) => c.config == NewsletterConfigType.mail).map((c) => c.comTypeId);
|
||
|
|
||
|
const members = await this.transformRecipientsToMembers(newsletter, recipients);
|
||
|
const mailRecipients = members.filter(
|
||
|
(m) =>
|
||
|
m.sendNewsletter != null &&
|
||
|
m.sendNewsletter?.email != null &&
|
||
|
allowedForMail.includes(m.sendNewsletter?.type?.id)
|
||
|
);
|
||
|
|
||
|
for (const rec of mailRecipients) {
|
||
|
let data = this.buildData(newsletter, dates, rec);
|
||
|
const { body } = await TemplateHelper.renderFileForModule({
|
||
|
module: "newsletter",
|
||
|
bodyData: data,
|
||
|
title: `Newsletter von ${CLUB_NAME}`,
|
||
|
});
|
||
|
await MailHelper.sendMail(rec.sendNewsletter.email, `Newsletter von ${CLUB_NAME}`, body, [
|
||
|
{ filename: "events.ics", path: this.getICSFilePath(newsletter) },
|
||
|
])
|
||
|
.then(() => {})
|
||
|
.catch((err) => {
|
||
|
console.log("mail send", err);
|
||
|
});
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static async printPdfs(newsletterId: number) {
|
||
|
let newsletter = await NewsletterService.getById(newsletterId);
|
||
|
let dates = await NewsletterDatesService.getAll(newsletterId);
|
||
|
let recipients = await NewsletterRecipientsService.getAll(newsletterId);
|
||
|
let config = await NewsletterConfigService.getAll();
|
||
|
|
||
|
FileSystemHelper.clearDirectoryByFiletype(
|
||
|
`newsletter/${newsletter.id}_${newsletter.title.replace(" ", "")}`,
|
||
|
".pdf"
|
||
|
);
|
||
|
|
||
|
const { value, error } = CalendarHelper.buildICS(dates.map((r) => r.calendar));
|
||
|
if (error) throw new InternalException("Failed Building ICS form Pdf", error);
|
||
|
this.saveIcsToFile(newsletter, value);
|
||
|
|
||
|
let notAllowedForPdf = config.filter((c) => c.config == NewsletterConfigType.mail).map((c) => c.comTypeId);
|
||
|
let printWithAdress = config.filter((c) => c.config == NewsletterConfigType.pdf).map((c) => c.comTypeId);
|
||
|
|
||
|
const members = await this.transformRecipientsToMembers(newsletter, recipients);
|
||
|
const pdfRecipients = members.filter(
|
||
|
(m) => !notAllowedForPdf.includes(m.sendNewsletter?.type?.id) || m.sendNewsletter == null
|
||
|
);
|
||
|
|
||
|
for (const rec of pdfRecipients) {
|
||
|
let data = this.buildData(newsletter, dates, rec, printWithAdress.includes(rec.sendNewsletter?.type?.id));
|
||
|
|
||
|
await PdfExport.renderFile({
|
||
|
template: "newsletter",
|
||
|
title: `Newsletter von ${CLUB_NAME}`,
|
||
|
filename: `${rec.lastname}_${rec.firstname}_${rec.id}`,
|
||
|
folder: `newsletter/${newsletter.id}_${newsletter.title.replace(" ", "")}`,
|
||
|
data: data,
|
||
|
})
|
||
|
.then(() => {})
|
||
|
.catch((err) => {
|
||
|
console.log("pdf print", err);
|
||
|
});
|
||
|
}
|
||
|
|
||
|
await PdfExport.sqashToSingleFile(
|
||
|
`newsletter/${newsletter.id}_${newsletter.title.replace(" ", "")}`,
|
||
|
"allPdfsTogether",
|
||
|
`newsletter/${newsletter.id}_${newsletter.title.replace(" ", "")}`
|
||
|
)
|
||
|
.then(() => {})
|
||
|
.catch((err) => {
|
||
|
console.log("pdf squash", err);
|
||
|
});
|
||
|
}
|
||
|
}
|