mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 12:50:38 +00:00
feat(server): change estimate and receipts status once delivering mail
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -132,4 +132,10 @@ export interface SaleEstimateMailOptions extends CommonMailOptions {
|
||||
|
||||
export interface SaleEstimateMailOptionsDTO extends CommonMailOptionsDTO {
|
||||
attachEstimate?: boolean;
|
||||
}
|
||||
}
|
||||
|
||||
export interface ISaleEstimateMailPresendEvent {
|
||||
tenantId: number;
|
||||
saleEstimateId: number;
|
||||
messageOptions: SaleEstimateMailOptionsDTO;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
];
|
||||
};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { IAccountTransaction } from '@/interfaces';
|
||||
import { Transformer } from '@/lib/Transformer/Transformer';
|
||||
import { transaction } from 'objection';
|
||||
|
||||
export default class AccountTransactionTransformer extends Transformer {
|
||||
/**
|
||||
|
||||
@@ -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 => {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,7 +6,7 @@ import { SaleReceiptCostGLEntries } from '../SaleReceiptCostGLEntries';
|
||||
@Service()
|
||||
export class SaleReceiptCostGLEntriesSubscriber {
|
||||
@Inject()
|
||||
saleReceiptCostEntries: SaleReceiptCostGLEntries;
|
||||
private saleReceiptCostEntries: SaleReceiptCostGLEntries;
|
||||
|
||||
/**
|
||||
* Attaches events.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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',
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user