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

@@ -201,3 +201,15 @@ export interface ISaleInvoiceNotifyPayload {
saleInvoiceId: number;
messageDTO: SendInvoiceMailDTO;
}
export interface ISaleInvoiceMailSend {
tenantId: number;
saleInvoiceId: number;
messageOptions: SendInvoiceMailDTO;
}
export interface ISaleInvoiceMailSent {
tenantId: number;
saleInvoiceId: number;
messageOptions: SendInvoiceMailDTO;
}

View File

@@ -84,6 +84,7 @@ import { WriteInvoiceTaxTransactionsSubscriber } from '@/services/TaxRates/subsc
import { BillTaxRateValidateSubscriber } from '@/services/TaxRates/subscribers/BillTaxRateValidateSubscriber';
import { WriteBillTaxTransactionsSubscriber } from '@/services/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber';
import { SyncItemTaxRateOnEditTaxSubscriber } from '@/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber';
import { InvoiceChangeStatusOnMailSentSubscriber } from '@/services/Sales/Invoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber';
export default () => {
return new EventPublisher();
@@ -152,6 +153,7 @@ export const susbcribers = () => {
// #Invoices
InvoicePaymentGLRewriteSubscriber,
InvoiceCostGLEntriesSubscriber,
InvoiceChangeStatusOnMailSentSubscriber,
BillPaymentsGLEntriesRewriteSubscriber,

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;
}
}
};
}

View File

@@ -131,7 +131,14 @@ export default {
onNotifiedSms: 'onSaleInvoiceNotifiedSms',
onNotifyMail: 'onSaleInvoiceNotifyMail',
onNotifyReminderMail: 'onSaleInvoiceNotifyReminderMail'
onNotifyReminderMail: 'onSaleInvoiceNotifyReminderMail',
onPreMailSend: 'onSaleInvoicePreMailSend',
onMailSend: 'onSaleInvoiceMailSend',
onMailSent: 'onSaleInvoiceMailSent',
onMailReminderSend: 'onSaleInvoiceMailReminderSend',
onMailReminderSent: 'onSaleInvoiceMailReminderSent',
},
/**
@@ -164,7 +171,7 @@ export default {
onRejecting: 'onSaleEstimateRejecting',
onRejected: 'onSaleEstimateRejected',
onNotifyMail: 'onSaleEstimateNotifyMail'
onNotifyMail: 'onSaleEstimateNotifyMail',
},
/**
@@ -580,6 +587,6 @@ export default {
onActivated: 'onTaxRateActivated',
onInactivating: 'onTaxRateInactivating',
onInactivated: 'onTaxRateInactivated'
onInactivated: 'onTaxRateInactivated',
},
};