diff --git a/packages/server/src/interfaces/PaymentReceive.ts b/packages/server/src/interfaces/PaymentReceive.ts index 2926d923c..329d0d944 100644 --- a/packages/server/src/interfaces/PaymentReceive.ts +++ b/packages/server/src/interfaces/PaymentReceive.ts @@ -173,3 +173,9 @@ export type IPaymentReceiveGLCommonEntry = Pick< export interface PaymentReceiveMailOpts extends CommonMailOptions {} export interface PaymentReceiveMailOptsDTO extends CommonMailOptionsDTO {} + +export interface PaymentReceiveMailPresendEvent { + tenantId: number; + paymentReceiveId: number; + messageOptions: PaymentReceiveMailOptsDTO; +} diff --git a/packages/server/src/interfaces/SaleEstimate.ts b/packages/server/src/interfaces/SaleEstimate.ts index 171c8a0d1..9ac17295c 100644 --- a/packages/server/src/interfaces/SaleEstimate.ts +++ b/packages/server/src/interfaces/SaleEstimate.ts @@ -132,4 +132,10 @@ export interface SaleEstimateMailOptions extends CommonMailOptions { export interface SaleEstimateMailOptionsDTO extends CommonMailOptionsDTO { attachEstimate?: boolean; -} \ No newline at end of file +} + +export interface ISaleEstimateMailPresendEvent { + tenantId: number; + saleEstimateId: number; + messageOptions: SaleEstimateMailOptionsDTO; +} diff --git a/packages/server/src/interfaces/SaleReceipt.ts b/packages/server/src/interfaces/SaleReceipt.ts index 1e8ffa98e..8904767c6 100644 --- a/packages/server/src/interfaces/SaleReceipt.ts +++ b/packages/server/src/interfaces/SaleReceipt.ts @@ -143,3 +143,9 @@ export interface SaleReceiptMailOpts extends CommonMailOptions { export interface SaleReceiptMailOptsDTO extends CommonMailOptionsDTO { attachReceipt?: boolean; } + +export interface ISaleReceiptMailPresend { + tenantId: number; + saleReceiptId: number; + messageOptions: SaleReceiptMailOptsDTO; +} diff --git a/packages/server/src/loaders/eventEmitter.ts b/packages/server/src/loaders/eventEmitter.ts index 5e052f376..5d3269646 100644 --- a/packages/server/src/loaders/eventEmitter.ts +++ b/packages/server/src/loaders/eventEmitter.ts @@ -85,6 +85,8 @@ import { BillTaxRateValidateSubscriber } from '@/services/TaxRates/subscribers/B import { WriteBillTaxTransactionsSubscriber } from '@/services/TaxRates/subscribers/WriteBillTaxTransactionsSubscriber'; import { SyncItemTaxRateOnEditTaxSubscriber } from '@/services/TaxRates/SyncItemTaxRateOnEditTaxSubscriber'; import { InvoiceChangeStatusOnMailSentSubscriber } from '@/services/Sales/Invoices/subscribers/InvoiceChangeStatusOnMailSentSubscriber'; +import { SaleReceiptMarkClosedOnMailSentSubcriber } from '@/services/Sales/Receipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber'; +import { SaleEstimateMarkApprovedOnMailSent } from '@/services/Sales/Estimates/subscribers/SaleEstimateMarkApprovedOnMailSent'; export default () => { return new EventPublisher(); @@ -105,8 +107,12 @@ export const susbcribers = () => { InventorySubscriber, CustomerWriteGLOpeningBalanceSubscriber, VendorsWriteGLOpeningSubscriber, + + // # Estimate SaleEstimateAutoSerialSubscriber, SaleEstimateSmsNotificationSubscriber, + SaleEstimateMarkApprovedOnMailSent, + ExpensesWriteGLSubscriber, SaleReceiptAutoSerialSubscriber, SaleInvoiceAutoIncrementSubscriber, @@ -159,6 +165,7 @@ export const susbcribers = () => { // # Receipts SaleReceiptCostGLEntriesSubscriber, + SaleReceiptMarkClosedOnMailSentSubcriber, // Transaction locking. SalesTransactionLockingGuardSubscriber, @@ -201,6 +208,6 @@ export const susbcribers = () => { BillTaxRateValidateSubscriber, WriteBillTaxTransactionsSubscriber, - SyncItemTaxRateOnEditTaxSubscriber + SyncItemTaxRateOnEditTaxSubscriber, ]; }; diff --git a/packages/server/src/services/Accounts/AccountTransactionTransformer.ts b/packages/server/src/services/Accounts/AccountTransactionTransformer.ts index 857fe5ccc..d0e3e487f 100644 --- a/packages/server/src/services/Accounts/AccountTransactionTransformer.ts +++ b/packages/server/src/services/Accounts/AccountTransactionTransformer.ts @@ -1,6 +1,5 @@ import { IAccountTransaction } from '@/interfaces'; import { Transformer } from '@/lib/Transformer/Transformer'; -import { transaction } from 'objection'; export default class AccountTransactionTransformer extends Transformer { /** diff --git a/packages/server/src/services/Accounts/AccountTransform.ts b/packages/server/src/services/Accounts/AccountTransform.ts index 9297994be..98e19553e 100644 --- a/packages/server/src/services/Accounts/AccountTransform.ts +++ b/packages/server/src/services/Accounts/AccountTransform.ts @@ -34,7 +34,7 @@ export class AccountTransformer extends Transformer { /** * Retrieve formatted account amount. - * @param {IAccount} invoice + * @param {IAccount} invoice * @returns {string} */ protected formattedAmount = (account: IAccount): string => { diff --git a/packages/server/src/services/Accounts/ActivateAccount.ts b/packages/server/src/services/Accounts/ActivateAccount.ts index 1fcd104f6..26afd836d 100644 --- a/packages/server/src/services/Accounts/ActivateAccount.ts +++ b/packages/server/src/services/Accounts/ActivateAccount.ts @@ -5,7 +5,6 @@ import { IAccountEventActivatedPayload } from '@/interfaces'; import events from '@/subscribers/events'; import UnitOfWork from '@/services/UnitOfWork'; import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; -import { CommandAccountValidators } from './CommandAccountValidators'; @Service() export class ActivateAccount { @@ -18,9 +17,6 @@ export class ActivateAccount { @Inject() private uow: UnitOfWork; - @Inject() - private validator: CommandAccountValidators; - /** * Activates/Inactivates the given account. * @param {number} tenantId diff --git a/packages/server/src/services/Sales/Estimates/SendSaleEstimateMail.ts b/packages/server/src/services/Sales/Estimates/SendSaleEstimateMail.ts index 258496306..0ac580b90 100644 --- a/packages/server/src/services/Sales/Estimates/SendSaleEstimateMail.ts +++ b/packages/server/src/services/Sales/Estimates/SendSaleEstimateMail.ts @@ -8,11 +8,14 @@ import { import { SaleEstimatesPdf } from './SaleEstimatesPdf'; import { GetSaleEstimate } from './GetSaleEstimate'; import { + ISaleEstimateMailPresendEvent, SaleEstimateMailOptions, SaleEstimateMailOptionsDTO, } from '@/interfaces'; import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification'; import { parseAndValidateMailOptions } from '@/services/MailNotification/utils'; +import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; +import events from '@/subscribers/events'; @Service() export class SendSaleEstimateMail { @@ -31,6 +34,9 @@ export class SendSaleEstimateMail { @Inject('agenda') private agenda: any; + @Inject() + private eventPublisher: EventPublisher; + /** * Triggers the reminder mail of the given sale estimate. * @param {number} tenantId - @@ -49,6 +55,13 @@ export class SendSaleEstimateMail { messageOptions, }; await this.agenda.now('sale-estimate-mail-send', payload); + + // Triggers `onSaleEstimatePreMailSend` event. + await this.eventPublisher.emitAsync(events.saleEstimate.onPreMailSend, { + tenantId, + saleEstimateId, + messageOptions, + } as ISaleEstimateMailPresendEvent); } /** @@ -99,7 +112,7 @@ export class SendSaleEstimateMail { return { ...mailOptions, data: formatterData, - attachEstimate: true + attachEstimate: true, }; }; diff --git a/packages/server/src/services/Sales/Estimates/subscribers/SaleEstimateMarkApprovedOnMailSent.ts b/packages/server/src/services/Sales/Estimates/subscribers/SaleEstimateMarkApprovedOnMailSent.ts new file mode 100644 index 000000000..99caa3952 --- /dev/null +++ b/packages/server/src/services/Sales/Estimates/subscribers/SaleEstimateMarkApprovedOnMailSent.ts @@ -0,0 +1,43 @@ +import { Inject, Service } from 'typedi'; +import events from '@/subscribers/events'; +import { ISaleEstimateMailPresendEvent } from '@/interfaces'; +import { DeliverSaleEstimate } from '../DeliverSaleEstimate'; +import { ServiceError } from '@/exceptions'; +import { ERRORS } from '../constants'; + +@Service() +export class SaleEstimateMarkApprovedOnMailSent { + @Inject() + private deliverEstimateService: DeliverSaleEstimate; + + /** + * Attaches events. + */ + public attach(bus) { + bus.subscribe(events.saleEstimate.onPreMailSend, this.markEstimateApproved); + } + + /** + * Marks the given estimate approved on submitting mail. + * @param {ISaleEstimateMailPresendEvent} + */ + private markEstimateApproved = async ({ + tenantId, + saleEstimateId, + }: ISaleEstimateMailPresendEvent) => { + try { + await this.deliverEstimateService.deliverSaleEstimate( + tenantId, + saleEstimateId + ); + } catch (error) { + if ( + error instanceof ServiceError && + error.errorType === ERRORS.SALE_ESTIMATE_ALREADY_DELIVERED + ) { + } else { + throw error; + } + } + }; +} diff --git a/packages/server/src/services/Sales/PaymentReceives/PaymentReceiveMailNotification.ts b/packages/server/src/services/Sales/PaymentReceives/PaymentReceiveMailNotification.ts index acb1ea7a1..bd8d4fa64 100644 --- a/packages/server/src/services/Sales/PaymentReceives/PaymentReceiveMailNotification.ts +++ b/packages/server/src/services/Sales/PaymentReceives/PaymentReceiveMailNotification.ts @@ -2,6 +2,7 @@ import { Inject, Service } from 'typedi'; import { PaymentReceiveMailOpts, PaymentReceiveMailOptsDTO, + PaymentReceiveMailPresendEvent, SendInvoiceMailDTO, } from '@/interfaces'; import Mail from '@/lib/Mail'; @@ -13,6 +14,8 @@ import { import { GetPaymentReceive } from './GetPaymentReceive'; import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification'; import { parseAndValidateMailOptions } from '@/services/MailNotification/utils'; +import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; +import events from '@/subscribers/events'; @Service() export class SendPaymentReceiveMailNotification { @@ -28,6 +31,9 @@ export class SendPaymentReceiveMailNotification { @Inject('agenda') private agenda: any; + @Inject() + private eventPublisher: EventPublisher; + /** * Sends the mail of the given payment receive. * @param {number} tenantId @@ -46,6 +52,13 @@ export class SendPaymentReceiveMailNotification { messageDTO, }; await this.agenda.now('payment-receive-mail-send', payload); + + // Triggers `onPaymentReceivePreMailSend` event. + await this.eventPublisher.emitAsync(events.paymentReceive.onPreMailSend, { + tenantId, + paymentReceiveId, + messageOptions: messageDTO, + } as PaymentReceiveMailPresendEvent); } /** diff --git a/packages/server/src/services/Sales/Receipts/SaleReceiptMailNotification.ts b/packages/server/src/services/Sales/Receipts/SaleReceiptMailNotification.ts index 572bed2f8..24add40cc 100644 --- a/packages/server/src/services/Sales/Receipts/SaleReceiptMailNotification.ts +++ b/packages/server/src/services/Sales/Receipts/SaleReceiptMailNotification.ts @@ -7,9 +7,15 @@ import { DEFAULT_RECEIPT_MAIL_CONTENT, DEFAULT_RECEIPT_MAIL_SUBJECT, } from './constants'; -import { SaleReceiptMailOpts, SaleReceiptMailOptsDTO } from '@/interfaces'; +import { + ISaleReceiptMailPresend, + SaleReceiptMailOpts, + SaleReceiptMailOptsDTO, +} from '@/interfaces'; import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification'; import { parseAndValidateMailOptions } from '@/services/MailNotification/utils'; +import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; +import events from '@/subscribers/events'; @Service() export class SaleReceiptMailNotification { @@ -25,6 +31,9 @@ export class SaleReceiptMailNotification { @Inject() private contactMailNotification: ContactMailNotification; + @Inject() + private eventPublisher: EventPublisher; + @Inject('agenda') private agenda: any; @@ -37,14 +46,21 @@ export class SaleReceiptMailNotification { public async triggerMail( tenantId: number, saleReceiptId: number, - messageOpts: SaleReceiptMailOptsDTO + messageOptions: SaleReceiptMailOptsDTO ) { const payload = { tenantId, saleReceiptId, - messageOpts, + messageOpts: messageOptions, }; await this.agenda.now('sale-receipt-mail-send', payload); + + // Triggers the event `onSaleReceiptPreMailSend`. + await this.eventPublisher.emitAsync(events.saleReceipt.onPreMailSend, { + tenantId, + saleReceiptId, + messageOptions, + } as ISaleReceiptMailPresend); } /** diff --git a/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts b/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts index 5e6311005..39590198b 100644 --- a/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts +++ b/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptCostGLEntriesSubscriber.ts @@ -6,7 +6,7 @@ import { SaleReceiptCostGLEntries } from '../SaleReceiptCostGLEntries'; @Service() export class SaleReceiptCostGLEntriesSubscriber { @Inject() - saleReceiptCostEntries: SaleReceiptCostGLEntries; + private saleReceiptCostEntries: SaleReceiptCostGLEntries; /** * Attaches events. diff --git a/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber.ts b/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber.ts new file mode 100644 index 000000000..3a8d26394 --- /dev/null +++ b/packages/server/src/services/Sales/Receipts/subscribers/SaleReceiptMarkClosedOnMailSentSubcriber.ts @@ -0,0 +1,41 @@ +import { ISaleReceiptMailPresend } from '@/interfaces'; +import events from '@/subscribers/events'; +import { CloseSaleReceipt } from '../CloseSaleReceipt'; +import { Inject, Service } from 'typedi'; +import { ServiceError } from '@/exceptions'; +import { ERRORS } from '../constants'; + +@Service() +export class SaleReceiptMarkClosedOnMailSentSubcriber { + @Inject() + private closeReceiptService: CloseSaleReceipt; + + /** + * Attaches events. + */ + public attach(bus) { + bus.subscribe(events.saleReceipt.onPreMailSend, this.markReceiptClosed); + } + + /** + * Marks the sale receipt closed on submitting mail. + * @param {ISaleReceiptMailPresend} + */ + private markReceiptClosed = async ({ + tenantId, + saleReceiptId, + messageOptions, + }: ISaleReceiptMailPresend) => { + try { + await this.closeReceiptService.closeSaleReceipt(tenantId, saleReceiptId); + } catch (error) { + if ( + error instanceof ServiceError && + error.errorType === ERRORS.SALE_RECEIPT_IS_ALREADY_CLOSED + ) { + } else { + throw error; + } + } + }; +} diff --git a/packages/server/src/subscribers/events.ts b/packages/server/src/subscribers/events.ts index a46c32696..882027f98 100644 --- a/packages/server/src/subscribers/events.ts +++ b/packages/server/src/subscribers/events.ts @@ -172,6 +172,10 @@ export default { onRejected: 'onSaleEstimateRejected', onNotifyMail: 'onSaleEstimateNotifyMail', + + onPreMailSend: 'onSaleEstimatePreMailSend', + onMailSend: 'onSaleEstimateMailSend', + onMailSent: 'onSaleEstimateMailSend', }, /** @@ -195,6 +199,10 @@ export default { onNotifySms: 'onSaleReceiptNotifySms', onNotifiedSms: 'onSaleReceiptNotifiedSms', + + onPreMailSend: 'onSaleReceiptPreMailSend', + onMailSend: 'onSaleReceiptMailSend', + onMailSent: 'onSaleReceiptMailSent', }, /** @@ -215,6 +223,10 @@ export default { onNotifySms: 'onPaymentReceiveNotifySms', onNotifiedSms: 'onPaymentReceiveNotifiedSms', + + onPreMailSend: 'onPaymentReceivePreMailSend', + onMailSend: 'onPaymentReceiveMailSend', + onMailSent: 'onPaymentReceiveMailSent', }, /**