feat(server): convert invoice status after sending mail notification

This commit is contained in:
Ahmed Bouhuolia
2024-01-24 00:00:15 +02:00
parent 429159acf9
commit c8e7a2c7d9
8 changed files with 129 additions and 14 deletions

View File

@@ -4,7 +4,6 @@ import { ServiceError } from '@/exceptions';
import {
ISaleInvoiceDeliveringPayload,
ISaleInvoiceEventDeliveredPayload,
ISystemUser,
} from '@/interfaces';
import { ERRORS } from './constants';
import { Inject, Service } from 'typedi';
@@ -36,8 +35,7 @@ export class DeliverSaleInvoice {
*/
public async deliverSaleInvoice(
tenantId: number,
saleInvoiceId: number,
authorizedUser: ISystemUser
saleInvoiceId: number
): Promise<void> {
const { SaleInvoice } = this.tenancy.models(tenantId);

View File

@@ -1,6 +1,6 @@
import { Inject, Service } from 'typedi';
import Mail from '@/lib/Mail';
import { SendInvoiceMailDTO } from '@/interfaces';
import { ISaleInvoiceMailSend, SendInvoiceMailDTO } from '@/interfaces';
import { SaleInvoicePdf } from './SaleInvoicePdf';
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon';
import {
@@ -8,6 +8,8 @@ import {
DEFAULT_INVOICE_MAIL_SUBJECT,
} from './constants';
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
import events from '@/subscribers/events';
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
@Service()
export class SendSaleInvoiceMail {
@@ -20,6 +22,9 @@ export class SendSaleInvoiceMail {
@Inject('agenda')
private agenda: any;
@Inject()
private eventPublisher: EventPublisher;
/**
* Sends the invoice mail of the given sale invoice.
* @param {number} tenantId
@@ -29,14 +34,21 @@ export class SendSaleInvoiceMail {
public async triggerMail(
tenantId: number,
saleInvoiceId: number,
messageDTO: SendInvoiceMailDTO
messageOptions: SendInvoiceMailDTO
) {
const payload = {
tenantId,
saleInvoiceId,
messageDTO,
messageOptions,
};
await this.agenda.now('sale-invoice-mail-send', payload);
// Triggers the event `onSaleInvoicePreMailSend`.
await this.eventPublisher.emitAsync(events.saleInvoice.onPreMailSend, {
tenantId,
saleInvoiceId,
messageOptions,
} as ISaleInvoiceMailSend);
}
/**
@@ -64,7 +76,7 @@ export class SendSaleInvoiceMail {
public async sendMail(
tenantId: number,
saleInvoiceId: number,
messageDTO: SendInvoiceMailDTO
messageOptions: SendInvoiceMailDTO
) {
const defaultMessageOpts = await this.getMailOption(
tenantId,
@@ -73,7 +85,7 @@ export class SendSaleInvoiceMail {
// Merge message opts with default options and validate the incoming options.
const messageOpts = parseAndValidateMailOptions(
defaultMessageOpts,
messageDTO
messageOptions
);
const mail = new Mail()
.setSubject(messageOpts.subject)
@@ -90,6 +102,20 @@ export class SendSaleInvoiceMail {
{ filename: 'invoice.pdf', content: invoicePdfBuffer },
]);
}
// Triggers the event `onSaleInvoiceSend`.
await this.eventPublisher.emitAsync(events.saleInvoice.onMailSend, {
tenantId,
saleInvoiceId,
messageOptions,
} as ISaleInvoiceMailSend);
await mail.send();
// Triggers the event `onSaleInvoiceSend`.
await this.eventPublisher.emitAsync(events.saleInvoice.onMailSent, {
tenantId,
saleInvoiceId,
messageOptions,
} as ISaleInvoiceMailSend);
}
}

View File

@@ -19,11 +19,11 @@ export class SendSaleInvoiceMailJob {
* Triggers sending invoice mail.
*/
private handler = async (job, done: Function) => {
const { tenantId, saleInvoiceId, messageDTO } = job.attrs.data;
const { tenantId, saleInvoiceId, messageOptions } = job.attrs.data;
const sendInvoiceMail = Container.get(SendSaleInvoiceMail);
try {
await sendInvoiceMail.sendMail(tenantId, saleInvoiceId, messageDTO);
await sendInvoiceMail.sendMail(tenantId, saleInvoiceId, messageOptions);
done();
} catch (error) {
console.log(error);

View File

@@ -1,5 +1,9 @@
import { Inject, Service } from 'typedi';
import { SendInvoiceMailDTO } from '@/interfaces';
import {
ISaleInvoiceMailSend,
ISaleInvoiceMailSent,
SendInvoiceMailDTO,
} from '@/interfaces';
import Mail from '@/lib/Mail';
import { SaleInvoicePdf } from './SaleInvoicePdf';
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon';
@@ -8,6 +12,8 @@ import {
DEFAULT_INVOICE_REMINDER_MAIL_SUBJECT,
} from './constants';
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
import events from '@/subscribers/events';
@Service()
export class SendInvoiceMailReminder {
@@ -20,6 +26,9 @@ export class SendInvoiceMailReminder {
@Inject()
private invoiceCommonMail: SendSaleInvoiceMailCommon;
@Inject()
private eventPublisher: EventPublisher;
/**
* Triggers the reminder mail of the given sale invoice.
* @param {number} tenantId
@@ -86,6 +95,18 @@ export class SendInvoiceMailReminder {
{ filename: 'invoice.pdf', content: invoicePdfBuffer },
]);
}
// Triggers the event `onSaleInvoiceSend`.
await this.eventPublisher.emitAsync(events.saleInvoice.onMailReminderSend, {
saleInvoiceId,
messageOptions,
} as ISaleInvoiceMailSend);
await mail.send();
// Triggers the event `onSaleInvoiceSent`.
await this.eventPublisher.emitAsync(events.saleInvoice.onMailReminderSent, {
saleInvoiceId,
messageOptions,
} as ISaleInvoiceMailSent);
}
}

View File

@@ -0,0 +1,49 @@
import { Inject, Service } from 'typedi';
import events from '@/subscribers/events';
import { ISaleInvoiceMailSent } from '@/interfaces';
import { DeliverSaleInvoice } from '../DeliverSaleInvoice';
import { ServiceError } from '@/exceptions';
import { ERRORS } from '../constants';
@Service()
export class InvoiceChangeStatusOnMailSentSubscriber {
@Inject()
private markInvoiceDelivedService: DeliverSaleInvoice;
/**
* Attaches events.
*/
public attach(bus) {
bus.subscribe(events.saleInvoice.onPreMailSend, this.markInvoiceDelivered);
bus.subscribe(
events.saleInvoice.onMailReminderSent,
this.markInvoiceDelivered
);
}
/**
* Marks the invoice delivered once the invoice mail sent.
* @param {ISaleInvoiceMailSent}
* @returns {Promise<void>}
*/
private markInvoiceDelivered = async ({
tenantId,
saleInvoiceId,
messageOptions,
}: ISaleInvoiceMailSent) => {
try {
await this.markInvoiceDelivedService.deliverSaleInvoice(
tenantId,
saleInvoiceId
);
} catch (error) {
if (
error instanceof ServiceError &&
error.errorType === ERRORS.SALE_INVOICE_ALREADY_DELIVERED
) {
} else {
throw error;
}
}
};
}