mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 22:00:31 +00:00
refactor: notification mail services
This commit is contained in:
@@ -13,9 +13,10 @@ import {
|
||||
SaleEstimateMailOptionsDTO,
|
||||
} from '@/interfaces';
|
||||
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
|
||||
import { parseAndValidateMailOptions } from '@/services/MailNotification/utils';
|
||||
import { mergeAndValidateMailOptions } from '@/services/MailNotification/utils';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
import events from '@/subscribers/events';
|
||||
import { transformEstimateToMailDataArgs } from './utils';
|
||||
|
||||
@Service()
|
||||
export class SendSaleEstimateMail {
|
||||
@@ -65,23 +66,17 @@ export class SendSaleEstimateMail {
|
||||
}
|
||||
|
||||
/**
|
||||
* Formates the text of the mail.
|
||||
* Formate the text of the mail.
|
||||
* @param {number} tenantId - Tenant id.
|
||||
* @param {number} estimateId - Estimate id.
|
||||
* @returns {Promise<Record<string, any>>}
|
||||
*/
|
||||
public formatterData = async (tenantId: number, estimateId: number) => {
|
||||
public formatterArgs = async (tenantId: number, estimateId: number) => {
|
||||
const estimate = await this.getSaleEstimateService.getEstimate(
|
||||
tenantId,
|
||||
estimateId
|
||||
);
|
||||
return {
|
||||
CustomerName: estimate.customer.displayName,
|
||||
EstimateNumber: estimate.estimateNumber,
|
||||
EstimateDate: estimate.formattedEstimateDate,
|
||||
EstimateAmount: estimate.formattedAmount,
|
||||
EstimateExpirationDate: estimate.formattedExpirationDate,
|
||||
};
|
||||
return transformEstimateToMailDataArgs(estimate);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -92,7 +87,9 @@ export class SendSaleEstimateMail {
|
||||
*/
|
||||
public getMailOptions = async (
|
||||
tenantId: number,
|
||||
saleEstimateId: number
|
||||
saleEstimateId: number,
|
||||
defaultSubject: string = DEFAULT_ESTIMATE_REMINDER_MAIL_SUBJECT,
|
||||
defaultMessage: string = DEFAULT_ESTIMATE_REMINDER_MAIL_CONTENT
|
||||
): Promise<SaleEstimateMailOptions> => {
|
||||
const { SaleEstimate } = this.tenancy.models(tenantId);
|
||||
|
||||
@@ -100,22 +97,45 @@ export class SendSaleEstimateMail {
|
||||
.findById(saleEstimateId)
|
||||
.throwIfNotFound();
|
||||
|
||||
const formatterData = await this.formatterData(tenantId, saleEstimateId);
|
||||
const formatArgs = await this.formatterArgs(tenantId, saleEstimateId);
|
||||
|
||||
const mailOptions = await this.contactMailNotification.getMailOptions(
|
||||
tenantId,
|
||||
saleEstimate.customerId,
|
||||
DEFAULT_ESTIMATE_REMINDER_MAIL_SUBJECT,
|
||||
DEFAULT_ESTIMATE_REMINDER_MAIL_CONTENT,
|
||||
formatterData
|
||||
);
|
||||
const mailOptions =
|
||||
await this.contactMailNotification.getDefaultMailOptions(
|
||||
tenantId,
|
||||
saleEstimate.customerId
|
||||
);
|
||||
return {
|
||||
...mailOptions,
|
||||
data: formatterData,
|
||||
message: defaultMessage,
|
||||
subject: defaultSubject,
|
||||
attachEstimate: true,
|
||||
formatArgs,
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats the given mail options.
|
||||
* @param {number} tenantId
|
||||
* @param {number} saleEstimateId
|
||||
* @param {SaleEstimateMailOptions} mailOptions
|
||||
* @returns {Promise<SaleEstimateMailOptions>}
|
||||
*/
|
||||
public formatMailOptions = async (
|
||||
tenantId: number,
|
||||
saleEstimateId: number,
|
||||
mailOptions: SaleEstimateMailOptions
|
||||
): Promise<SaleEstimateMailOptions> => {
|
||||
const formatterArgs = await this.formatterArgs(tenantId, saleEstimateId);
|
||||
|
||||
const formattedOptions =
|
||||
await this.contactMailNotification.formatMailOptions(
|
||||
tenantId,
|
||||
mailOptions,
|
||||
formatterArgs
|
||||
);
|
||||
return { ...formattedOptions };
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends the mail notification of the given sale estimate.
|
||||
* @param {number} tenantId
|
||||
@@ -133,27 +153,52 @@ export class SendSaleEstimateMail {
|
||||
saleEstimateId
|
||||
);
|
||||
// Overrides and validates the given mail options.
|
||||
const messageOpts = parseAndValidateMailOptions(
|
||||
const parsedMessageOptions = mergeAndValidateMailOptions(
|
||||
localMessageOpts,
|
||||
messageOptions
|
||||
) as SaleEstimateMailOptions;
|
||||
|
||||
const formattedOptions = await this.formatMailOptions(
|
||||
tenantId,
|
||||
saleEstimateId,
|
||||
parsedMessageOptions
|
||||
);
|
||||
const mail = new Mail()
|
||||
.setSubject(messageOpts.subject)
|
||||
.setTo(messageOpts.to)
|
||||
.setContent(messageOpts.body);
|
||||
.setSubject(formattedOptions.subject)
|
||||
.setTo(formattedOptions.to)
|
||||
.setContent(formattedOptions.message);
|
||||
|
||||
// Attaches the estimate pdf to the mail.
|
||||
if (formattedOptions.attachEstimate) {
|
||||
// Retrieves the estimate pdf and attaches it to the mail.
|
||||
const [estimatePdfBuffer, estimateFilename] =
|
||||
await this.estimatePdf.getSaleEstimatePdf(tenantId, saleEstimateId);
|
||||
|
||||
if (messageOpts.attachEstimate) {
|
||||
const estimatePdfBuffer = await this.estimatePdf.getSaleEstimatePdf(
|
||||
tenantId,
|
||||
saleEstimateId
|
||||
);
|
||||
mail.setAttachments([
|
||||
{
|
||||
filename: messageOpts.data?.EstimateNumber || 'estimate.pdf',
|
||||
filename: `${estimateFilename}.pdf`,
|
||||
content: estimatePdfBuffer,
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
const eventPayload = {
|
||||
tenantId,
|
||||
saleEstimateId,
|
||||
messageOptions,
|
||||
formattedOptions,
|
||||
};
|
||||
// Triggers `onSaleEstimateMailSend` event.
|
||||
await this.eventPublisher.emitAsync(
|
||||
events.saleEstimate.onMailSend,
|
||||
eventPayload as ISaleEstimateMailPresendEvent
|
||||
);
|
||||
await mail.send();
|
||||
|
||||
// Triggers `onSaleEstimateMailSent` event.
|
||||
await this.eventPublisher.emitAsync(
|
||||
events.saleEstimate.onMailSent,
|
||||
eventPayload as ISaleEstimateMailPresendEvent
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
export const DEFAULT_ESTIMATE_REMINDER_MAIL_SUBJECT =
|
||||
'Estimate {EstimateNumber} is awaiting your approval';
|
||||
export const DEFAULT_ESTIMATE_REMINDER_MAIL_CONTENT = `<p>Dear {CustomerName}</p>
|
||||
'Estimate {Estimate Number} is awaiting your approval';
|
||||
export const DEFAULT_ESTIMATE_REMINDER_MAIL_CONTENT = `<p>Dear {Customer Name}</p>
|
||||
<p>Thank you for your business, You can view or print your estimate from attachements.</p>
|
||||
<p>
|
||||
Estimate <strong>#{EstimateNumber}</strong><br />
|
||||
Expiration Date : <strong>{EstimateExpirationDate}</strong><br />
|
||||
Amount : <strong>{EstimateAmount}</strong></br />
|
||||
Estimate <strong>#{Estimate Number}</strong><br />
|
||||
Expiration Date : <strong>{Estimate Expiration Date}</strong><br />
|
||||
Amount : <strong>{Estimate Amount}</strong></br />
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<i>Regards</i><br />
|
||||
<i>{CompanyName}</i>
|
||||
<i>{Company Name}</i>
|
||||
</p>
|
||||
`;
|
||||
|
||||
|
||||
@@ -22,3 +22,13 @@ export const transformEstimateToPdfTemplate = (
|
||||
customerAddress: contactAddressTextFormat(estimate.customer),
|
||||
};
|
||||
};
|
||||
|
||||
export const transformEstimateToMailDataArgs = (estimate: any) => {
|
||||
return {
|
||||
'Customer Name': estimate.customer.displayName,
|
||||
'Estimate Number': estimate.estimateNumber,
|
||||
'Estimate Date': estimate.formattedEstimateDate,
|
||||
'Estimate Amount': estimate.formattedAmount,
|
||||
'Estimate Expiration Date': estimate.formattedExpirationDate,
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user