mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 05:40:31 +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;
|
saleInvoiceId: number;
|
||||||
messageDTO: SendInvoiceMailDTO;
|
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 { BillTaxRateValidateSubscriber } from '@/services/TaxRates/subscribers/BillTaxRateValidateSubscriber';
|
||||||
import { WriteBillTaxTransactionsSubscriber } from '@/services/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber';
|
import { WriteBillTaxTransactionsSubscriber } from '@/services/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber';
|
||||||
import { SyncItemTaxRateOnEditTaxSubscriber } from '@/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber';
|
import { SyncItemTaxRateOnEditTaxSubscriber } from '@/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber';
|
||||||
|
import { InvoiceChangeStatusOnMailSentSubscriber } from '@/services/Sales/Invoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber';
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
return new EventPublisher();
|
return new EventPublisher();
|
||||||
@@ -152,6 +153,7 @@ export const susbcribers = () => {
|
|||||||
// #Invoices
|
// #Invoices
|
||||||
InvoicePaymentGLRewriteSubscriber,
|
InvoicePaymentGLRewriteSubscriber,
|
||||||
InvoiceCostGLEntriesSubscriber,
|
InvoiceCostGLEntriesSubscriber,
|
||||||
|
InvoiceChangeStatusOnMailSentSubscriber,
|
||||||
|
|
||||||
BillPaymentsGLEntriesRewriteSubscriber,
|
BillPaymentsGLEntriesRewriteSubscriber,
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import { ServiceError } from '@/exceptions';
|
|||||||
import {
|
import {
|
||||||
ISaleInvoiceDeliveringPayload,
|
ISaleInvoiceDeliveringPayload,
|
||||||
ISaleInvoiceEventDeliveredPayload,
|
ISaleInvoiceEventDeliveredPayload,
|
||||||
ISystemUser,
|
|
||||||
} from '@/interfaces';
|
} from '@/interfaces';
|
||||||
import { ERRORS } from './constants';
|
import { ERRORS } from './constants';
|
||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
@@ -36,8 +35,7 @@ export class DeliverSaleInvoice {
|
|||||||
*/
|
*/
|
||||||
public async deliverSaleInvoice(
|
public async deliverSaleInvoice(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
saleInvoiceId: number,
|
saleInvoiceId: number
|
||||||
authorizedUser: ISystemUser
|
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const { SaleInvoice } = this.tenancy.models(tenantId);
|
const { SaleInvoice } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import Mail from '@/lib/Mail';
|
import Mail from '@/lib/Mail';
|
||||||
import { SendInvoiceMailDTO } from '@/interfaces';
|
import { ISaleInvoiceMailSend, SendInvoiceMailDTO } from '@/interfaces';
|
||||||
import { SaleInvoicePdf } from './SaleInvoicePdf';
|
import { SaleInvoicePdf } from './SaleInvoicePdf';
|
||||||
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon';
|
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon';
|
||||||
import {
|
import {
|
||||||
@@ -8,6 +8,8 @@ import {
|
|||||||
DEFAULT_INVOICE_MAIL_SUBJECT,
|
DEFAULT_INVOICE_MAIL_SUBJECT,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SendSaleInvoiceMail {
|
export class SendSaleInvoiceMail {
|
||||||
@@ -20,6 +22,9 @@ export class SendSaleInvoiceMail {
|
|||||||
@Inject('agenda')
|
@Inject('agenda')
|
||||||
private agenda: any;
|
private agenda: any;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the invoice mail of the given sale invoice.
|
* Sends the invoice mail of the given sale invoice.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -29,14 +34,21 @@ export class SendSaleInvoiceMail {
|
|||||||
public async triggerMail(
|
public async triggerMail(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
saleInvoiceId: number,
|
saleInvoiceId: number,
|
||||||
messageDTO: SendInvoiceMailDTO
|
messageOptions: SendInvoiceMailDTO
|
||||||
) {
|
) {
|
||||||
const payload = {
|
const payload = {
|
||||||
tenantId,
|
tenantId,
|
||||||
saleInvoiceId,
|
saleInvoiceId,
|
||||||
messageDTO,
|
messageOptions,
|
||||||
};
|
};
|
||||||
await this.agenda.now('sale-invoice-mail-send', payload);
|
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(
|
public async sendMail(
|
||||||
tenantId: number,
|
tenantId: number,
|
||||||
saleInvoiceId: number,
|
saleInvoiceId: number,
|
||||||
messageDTO: SendInvoiceMailDTO
|
messageOptions: SendInvoiceMailDTO
|
||||||
) {
|
) {
|
||||||
const defaultMessageOpts = await this.getMailOption(
|
const defaultMessageOpts = await this.getMailOption(
|
||||||
tenantId,
|
tenantId,
|
||||||
@@ -73,7 +85,7 @@ export class SendSaleInvoiceMail {
|
|||||||
// Merge message opts with default options and validate the incoming options.
|
// Merge message opts with default options and validate the incoming options.
|
||||||
const messageOpts = parseAndValidateMailOptions(
|
const messageOpts = parseAndValidateMailOptions(
|
||||||
defaultMessageOpts,
|
defaultMessageOpts,
|
||||||
messageDTO
|
messageOptions
|
||||||
);
|
);
|
||||||
const mail = new Mail()
|
const mail = new Mail()
|
||||||
.setSubject(messageOpts.subject)
|
.setSubject(messageOpts.subject)
|
||||||
@@ -90,6 +102,20 @@ export class SendSaleInvoiceMail {
|
|||||||
{ filename: 'invoice.pdf', content: invoicePdfBuffer },
|
{ filename: 'invoice.pdf', content: invoicePdfBuffer },
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
// Triggers the event `onSaleInvoiceSend`.
|
||||||
|
await this.eventPublisher.emitAsync(events.saleInvoice.onMailSend, {
|
||||||
|
tenantId,
|
||||||
|
saleInvoiceId,
|
||||||
|
messageOptions,
|
||||||
|
} as ISaleInvoiceMailSend);
|
||||||
|
|
||||||
await mail.send();
|
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.
|
* Triggers sending invoice mail.
|
||||||
*/
|
*/
|
||||||
private handler = async (job, done: Function) => {
|
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);
|
const sendInvoiceMail = Container.get(SendSaleInvoiceMail);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await sendInvoiceMail.sendMail(tenantId, saleInvoiceId, messageDTO);
|
await sendInvoiceMail.sendMail(tenantId, saleInvoiceId, messageOptions);
|
||||||
done();
|
done();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import { SendInvoiceMailDTO } from '@/interfaces';
|
import {
|
||||||
|
ISaleInvoiceMailSend,
|
||||||
|
ISaleInvoiceMailSent,
|
||||||
|
SendInvoiceMailDTO,
|
||||||
|
} from '@/interfaces';
|
||||||
import Mail from '@/lib/Mail';
|
import Mail from '@/lib/Mail';
|
||||||
import { SaleInvoicePdf } from './SaleInvoicePdf';
|
import { SaleInvoicePdf } from './SaleInvoicePdf';
|
||||||
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon';
|
import { SendSaleInvoiceMailCommon } from './SendInvoiceInvoiceMailCommon';
|
||||||
@@ -8,6 +12,8 @@ import {
|
|||||||
DEFAULT_INVOICE_REMINDER_MAIL_SUBJECT,
|
DEFAULT_INVOICE_REMINDER_MAIL_SUBJECT,
|
||||||
} from './constants';
|
} from './constants';
|
||||||
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
||||||
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SendInvoiceMailReminder {
|
export class SendInvoiceMailReminder {
|
||||||
@@ -20,6 +26,9 @@ export class SendInvoiceMailReminder {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private invoiceCommonMail: SendSaleInvoiceMailCommon;
|
private invoiceCommonMail: SendSaleInvoiceMailCommon;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers the reminder mail of the given sale invoice.
|
* Triggers the reminder mail of the given sale invoice.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -86,6 +95,18 @@ export class SendInvoiceMailReminder {
|
|||||||
{ filename: 'invoice.pdf', content: invoicePdfBuffer },
|
{ filename: 'invoice.pdf', content: invoicePdfBuffer },
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
// Triggers the event `onSaleInvoiceSend`.
|
||||||
|
await this.eventPublisher.emitAsync(events.saleInvoice.onMailReminderSend, {
|
||||||
|
saleInvoiceId,
|
||||||
|
messageOptions,
|
||||||
|
} as ISaleInvoiceMailSend);
|
||||||
|
|
||||||
await mail.send();
|
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',
|
onNotifiedSms: 'onSaleInvoiceNotifiedSms',
|
||||||
|
|
||||||
onNotifyMail: 'onSaleInvoiceNotifyMail',
|
onNotifyMail: 'onSaleInvoiceNotifyMail',
|
||||||
onNotifyReminderMail: 'onSaleInvoiceNotifyReminderMail'
|
onNotifyReminderMail: 'onSaleInvoiceNotifyReminderMail',
|
||||||
|
|
||||||
|
onPreMailSend: 'onSaleInvoicePreMailSend',
|
||||||
|
onMailSend: 'onSaleInvoiceMailSend',
|
||||||
|
onMailSent: 'onSaleInvoiceMailSent',
|
||||||
|
|
||||||
|
onMailReminderSend: 'onSaleInvoiceMailReminderSend',
|
||||||
|
onMailReminderSent: 'onSaleInvoiceMailReminderSent',
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -164,7 +171,7 @@ export default {
|
|||||||
onRejecting: 'onSaleEstimateRejecting',
|
onRejecting: 'onSaleEstimateRejecting',
|
||||||
onRejected: 'onSaleEstimateRejected',
|
onRejected: 'onSaleEstimateRejected',
|
||||||
|
|
||||||
onNotifyMail: 'onSaleEstimateNotifyMail'
|
onNotifyMail: 'onSaleEstimateNotifyMail',
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -580,6 +587,6 @@ export default {
|
|||||||
onActivated: 'onTaxRateActivated',
|
onActivated: 'onTaxRateActivated',
|
||||||
|
|
||||||
onInactivating: 'onTaxRateInactivating',
|
onInactivating: 'onTaxRateInactivating',
|
||||||
onInactivated: 'onTaxRateInactivated'
|
onInactivated: 'onTaxRateInactivated',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user