mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-11 18:30:30 +00:00
feat(server): convert invoice status after sending mail notification
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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',
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user