feat(server): change estimate and receipts status once delivering mail

This commit is contained in:
Ahmed Bouhuolia
2024-01-25 21:52:07 +02:00
parent 9d4e7cec9e
commit 760dbc6cfc
14 changed files with 171 additions and 13 deletions

View File

@@ -173,3 +173,9 @@ export type IPaymentReceiveGLCommonEntry = Pick<
export interface PaymentReceiveMailOpts extends CommonMailOptions {} export interface PaymentReceiveMailOpts extends CommonMailOptions {}
export interface PaymentReceiveMailOptsDTO extends CommonMailOptionsDTO {} export interface PaymentReceiveMailOptsDTO extends CommonMailOptionsDTO {}
export interface PaymentReceiveMailPresendEvent {
tenantId: number;
paymentReceiveId: number;
messageOptions: PaymentReceiveMailOptsDTO;
}

View File

@@ -133,3 +133,9 @@ export interface SaleEstimateMailOptions extends CommonMailOptions {
export interface SaleEstimateMailOptionsDTO extends CommonMailOptionsDTO { export interface SaleEstimateMailOptionsDTO extends CommonMailOptionsDTO {
attachEstimate?: boolean; attachEstimate?: boolean;
} }
export interface ISaleEstimateMailPresendEvent {
tenantId: number;
saleEstimateId: number;
messageOptions: SaleEstimateMailOptionsDTO;
}

View File

@@ -143,3 +143,9 @@ export interface SaleReceiptMailOpts extends CommonMailOptions {
export interface SaleReceiptMailOptsDTO extends CommonMailOptionsDTO { export interface SaleReceiptMailOptsDTO extends CommonMailOptionsDTO {
attachReceipt?: boolean; attachReceipt?: boolean;
} }
export interface ISaleReceiptMailPresend {
tenantId: number;
saleReceiptId: number;
messageOptions: SaleReceiptMailOptsDTO;
}

View File

@@ -85,6 +85,8 @@ import { BillTaxRateValidateSubscriber } from '@/services/TaxRates/subscribers/B
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'; 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 () => { export default () => {
return new EventPublisher(); return new EventPublisher();
@@ -105,8 +107,12 @@ export const susbcribers = () => {
InventorySubscriber, InventorySubscriber,
CustomerWriteGLOpeningBalanceSubscriber, CustomerWriteGLOpeningBalanceSubscriber,
VendorsWriteGLOpeningSubscriber, VendorsWriteGLOpeningSubscriber,
// # Estimate
SaleEstimateAutoSerialSubscriber, SaleEstimateAutoSerialSubscriber,
SaleEstimateSmsNotificationSubscriber, SaleEstimateSmsNotificationSubscriber,
SaleEstimateMarkApprovedOnMailSent,
ExpensesWriteGLSubscriber, ExpensesWriteGLSubscriber,
SaleReceiptAutoSerialSubscriber, SaleReceiptAutoSerialSubscriber,
SaleInvoiceAutoIncrementSubscriber, SaleInvoiceAutoIncrementSubscriber,
@@ -159,6 +165,7 @@ export const susbcribers = () => {
// # Receipts // # Receipts
SaleReceiptCostGLEntriesSubscriber, SaleReceiptCostGLEntriesSubscriber,
SaleReceiptMarkClosedOnMailSentSubcriber,
// Transaction locking. // Transaction locking.
SalesTransactionLockingGuardSubscriber, SalesTransactionLockingGuardSubscriber,
@@ -201,6 +208,6 @@ export const susbcribers = () => {
BillTaxRateValidateSubscriber, BillTaxRateValidateSubscriber,
WriteBillTaxTransactionsSubscriber, WriteBillTaxTransactionsSubscriber,
SyncItemTaxRateOnEditTaxSubscriber SyncItemTaxRateOnEditTaxSubscriber,
]; ];
}; };

View File

@@ -1,6 +1,5 @@
import { IAccountTransaction } from '@/interfaces'; import { IAccountTransaction } from '@/interfaces';
import { Transformer } from '@/lib/Transformer/Transformer'; import { Transformer } from '@/lib/Transformer/Transformer';
import { transaction } from 'objection';
export default class AccountTransactionTransformer extends Transformer { export default class AccountTransactionTransformer extends Transformer {
/** /**

View File

@@ -5,7 +5,6 @@ import { IAccountEventActivatedPayload } from '@/interfaces';
import events from '@/subscribers/events'; import events from '@/subscribers/events';
import UnitOfWork from '@/services/UnitOfWork'; import UnitOfWork from '@/services/UnitOfWork';
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher'; import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
import { CommandAccountValidators } from './CommandAccountValidators';
@Service() @Service()
export class ActivateAccount { export class ActivateAccount {
@@ -18,9 +17,6 @@ export class ActivateAccount {
@Inject() @Inject()
private uow: UnitOfWork; private uow: UnitOfWork;
@Inject()
private validator: CommandAccountValidators;
/** /**
* Activates/Inactivates the given account. * Activates/Inactivates the given account.
* @param {number} tenantId * @param {number} tenantId

View File

@@ -8,11 +8,14 @@ import {
import { SaleEstimatesPdf } from './SaleEstimatesPdf'; import { SaleEstimatesPdf } from './SaleEstimatesPdf';
import { GetSaleEstimate } from './GetSaleEstimate'; import { GetSaleEstimate } from './GetSaleEstimate';
import { import {
ISaleEstimateMailPresendEvent,
SaleEstimateMailOptions, SaleEstimateMailOptions,
SaleEstimateMailOptionsDTO, SaleEstimateMailOptionsDTO,
} from '@/interfaces'; } from '@/interfaces';
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification'; import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
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 SendSaleEstimateMail { export class SendSaleEstimateMail {
@@ -31,6 +34,9 @@ export class SendSaleEstimateMail {
@Inject('agenda') @Inject('agenda')
private agenda: any; private agenda: any;
@Inject()
private eventPublisher: EventPublisher;
/** /**
* Triggers the reminder mail of the given sale estimate. * Triggers the reminder mail of the given sale estimate.
* @param {number} tenantId - * @param {number} tenantId -
@@ -49,6 +55,13 @@ export class SendSaleEstimateMail {
messageOptions, messageOptions,
}; };
await this.agenda.now('sale-estimate-mail-send', payload); 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 { return {
...mailOptions, ...mailOptions,
data: formatterData, data: formatterData,
attachEstimate: true attachEstimate: true,
}; };
}; };

View File

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

View File

@@ -2,6 +2,7 @@ import { Inject, Service } from 'typedi';
import { import {
PaymentReceiveMailOpts, PaymentReceiveMailOpts,
PaymentReceiveMailOptsDTO, PaymentReceiveMailOptsDTO,
PaymentReceiveMailPresendEvent,
SendInvoiceMailDTO, SendInvoiceMailDTO,
} from '@/interfaces'; } from '@/interfaces';
import Mail from '@/lib/Mail'; import Mail from '@/lib/Mail';
@@ -13,6 +14,8 @@ import {
import { GetPaymentReceive } from './GetPaymentReceive'; import { GetPaymentReceive } from './GetPaymentReceive';
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification'; import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
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 SendPaymentReceiveMailNotification { export class SendPaymentReceiveMailNotification {
@@ -28,6 +31,9 @@ export class SendPaymentReceiveMailNotification {
@Inject('agenda') @Inject('agenda')
private agenda: any; private agenda: any;
@Inject()
private eventPublisher: EventPublisher;
/** /**
* Sends the mail of the given payment receive. * Sends the mail of the given payment receive.
* @param {number} tenantId * @param {number} tenantId
@@ -46,6 +52,13 @@ export class SendPaymentReceiveMailNotification {
messageDTO, messageDTO,
}; };
await this.agenda.now('payment-receive-mail-send', payload); 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);
} }
/** /**

View File

@@ -7,9 +7,15 @@ import {
DEFAULT_RECEIPT_MAIL_CONTENT, DEFAULT_RECEIPT_MAIL_CONTENT,
DEFAULT_RECEIPT_MAIL_SUBJECT, DEFAULT_RECEIPT_MAIL_SUBJECT,
} from './constants'; } from './constants';
import { SaleReceiptMailOpts, SaleReceiptMailOptsDTO } from '@/interfaces'; import {
ISaleReceiptMailPresend,
SaleReceiptMailOpts,
SaleReceiptMailOptsDTO,
} from '@/interfaces';
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification'; import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
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 SaleReceiptMailNotification { export class SaleReceiptMailNotification {
@@ -25,6 +31,9 @@ export class SaleReceiptMailNotification {
@Inject() @Inject()
private contactMailNotification: ContactMailNotification; private contactMailNotification: ContactMailNotification;
@Inject()
private eventPublisher: EventPublisher;
@Inject('agenda') @Inject('agenda')
private agenda: any; private agenda: any;
@@ -37,14 +46,21 @@ export class SaleReceiptMailNotification {
public async triggerMail( public async triggerMail(
tenantId: number, tenantId: number,
saleReceiptId: number, saleReceiptId: number,
messageOpts: SaleReceiptMailOptsDTO messageOptions: SaleReceiptMailOptsDTO
) { ) {
const payload = { const payload = {
tenantId, tenantId,
saleReceiptId, saleReceiptId,
messageOpts, messageOpts: messageOptions,
}; };
await this.agenda.now('sale-receipt-mail-send', payload); 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);
} }
/** /**

View File

@@ -6,7 +6,7 @@ import { SaleReceiptCostGLEntries } from '../SaleReceiptCostGLEntries';
@Service() @Service()
export class SaleReceiptCostGLEntriesSubscriber { export class SaleReceiptCostGLEntriesSubscriber {
@Inject() @Inject()
saleReceiptCostEntries: SaleReceiptCostGLEntries; private saleReceiptCostEntries: SaleReceiptCostGLEntries;
/** /**
* Attaches events. * Attaches events.

View File

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

View File

@@ -172,6 +172,10 @@ export default {
onRejected: 'onSaleEstimateRejected', onRejected: 'onSaleEstimateRejected',
onNotifyMail: 'onSaleEstimateNotifyMail', onNotifyMail: 'onSaleEstimateNotifyMail',
onPreMailSend: 'onSaleEstimatePreMailSend',
onMailSend: 'onSaleEstimateMailSend',
onMailSent: 'onSaleEstimateMailSend',
}, },
/** /**
@@ -195,6 +199,10 @@ export default {
onNotifySms: 'onSaleReceiptNotifySms', onNotifySms: 'onSaleReceiptNotifySms',
onNotifiedSms: 'onSaleReceiptNotifiedSms', onNotifiedSms: 'onSaleReceiptNotifiedSms',
onPreMailSend: 'onSaleReceiptPreMailSend',
onMailSend: 'onSaleReceiptMailSend',
onMailSent: 'onSaleReceiptMailSent',
}, },
/** /**
@@ -215,6 +223,10 @@ export default {
onNotifySms: 'onPaymentReceiveNotifySms', onNotifySms: 'onPaymentReceiveNotifySms',
onNotifiedSms: 'onPaymentReceiveNotifiedSms', onNotifiedSms: 'onPaymentReceiveNotifiedSms',
onPreMailSend: 'onPaymentReceivePreMailSend',
onMailSend: 'onPaymentReceiveMailSend',
onMailSent: 'onPaymentReceiveMailSent',
}, },
/** /**