mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-19 22:30:31 +00:00
feat: payment received mail preview
This commit is contained in:
@@ -130,9 +130,18 @@ export default class PaymentReceivesController extends BaseController {
|
|||||||
[
|
[
|
||||||
...this.paymentReceiveValidation,
|
...this.paymentReceiveValidation,
|
||||||
body('subject').isString().optional(),
|
body('subject').isString().optional(),
|
||||||
|
|
||||||
body('from').isString().optional(),
|
body('from').isString().optional(),
|
||||||
body('to').isString().optional(),
|
|
||||||
body('body').isString().optional(),
|
body('to').isArray().exists(),
|
||||||
|
body('to.*').isString().isEmail().optional(),
|
||||||
|
|
||||||
|
body('cc').isArray().optional({ nullable: true }),
|
||||||
|
body('cc.*').isString().isEmail().optional(),
|
||||||
|
|
||||||
|
body('bcc').isArray().optional({ nullable: true }),
|
||||||
|
body('bcc.*').isString().isEmail().optional(),
|
||||||
|
|
||||||
body('attach_invoice').optional().isBoolean().toBoolean(),
|
body('attach_invoice').optional().isBoolean().toBoolean(),
|
||||||
],
|
],
|
||||||
this.sendPaymentReceiveByMail.bind(this),
|
this.sendPaymentReceiveByMail.bind(this),
|
||||||
|
|||||||
@@ -130,8 +130,18 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
[
|
[
|
||||||
...this.validateSpecificEstimateSchema,
|
...this.validateSpecificEstimateSchema,
|
||||||
body('subject').isString().optional(),
|
body('subject').isString().optional(),
|
||||||
|
|
||||||
body('from').isString().optional(),
|
body('from').isString().optional(),
|
||||||
body('to').isString().optional(),
|
|
||||||
|
body('to').isArray().exists(),
|
||||||
|
body('to.*').isString().isEmail().optional(),
|
||||||
|
|
||||||
|
body('cc').isArray().optional({ nullable: true }),
|
||||||
|
body('cc.*').isString().isEmail().optional(),
|
||||||
|
|
||||||
|
body('bcc').isArray().optional({ nullable: true }),
|
||||||
|
body('bcc.*').isString().isEmail().optional(),
|
||||||
|
|
||||||
body('body').isString().optional(),
|
body('body').isString().optional(),
|
||||||
body('attach_invoice').optional().isBoolean().toBoolean(),
|
body('attach_invoice').optional().isBoolean().toBoolean(),
|
||||||
],
|
],
|
||||||
@@ -567,8 +577,9 @@ export default class SalesEstimatesController extends BaseController {
|
|||||||
const { tenantId } = req;
|
const { tenantId } = req;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const data =
|
const data = await this.saleEstimatesApplication.getSaleEstimateState(
|
||||||
await this.saleEstimatesApplication.getSaleEstimateState(tenantId);
|
tenantId
|
||||||
|
);
|
||||||
return res.status(200).send({ data });
|
return res.status(200).send({ data });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
|
|||||||
@@ -56,8 +56,18 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
[
|
[
|
||||||
...this.specificReceiptValidationSchema,
|
...this.specificReceiptValidationSchema,
|
||||||
body('subject').isString().optional(),
|
body('subject').isString().optional(),
|
||||||
|
|
||||||
body('from').isString().optional(),
|
body('from').isString().optional(),
|
||||||
body('to').isString().optional(),
|
|
||||||
|
body('to').isArray().exists(),
|
||||||
|
body('to.*').isString().isEmail().optional(),
|
||||||
|
|
||||||
|
body('cc').isArray().optional({ nullable: true }),
|
||||||
|
body('cc.*').isString().isEmail().optional(),
|
||||||
|
|
||||||
|
body('bcc').isArray().optional({ nullable: true }),
|
||||||
|
body('bcc.*').isString().isEmail().optional(),
|
||||||
|
|
||||||
body('body').isString().optional(),
|
body('body').isString().optional(),
|
||||||
body('attach_receipt').optional().isBoolean().toBoolean(),
|
body('attach_receipt').optional().isBoolean().toBoolean(),
|
||||||
],
|
],
|
||||||
@@ -399,8 +409,9 @@ export default class SalesReceiptsController extends BaseController {
|
|||||||
|
|
||||||
// Retrieves receipt in pdf format.
|
// Retrieves receipt in pdf format.
|
||||||
try {
|
try {
|
||||||
const data =
|
const data = await this.saleReceiptsApplication.getSaleReceiptState(
|
||||||
await this.saleReceiptsApplication.getSaleReceiptState(tenantId);
|
tenantId
|
||||||
|
);
|
||||||
return res.status(200).send({ data });
|
return res.status(200).send({ data });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
next(error);
|
next(error);
|
||||||
|
|||||||
@@ -177,7 +177,9 @@ export type IPaymentReceiveGLCommonEntry = Pick<
|
|||||||
| 'branchId'
|
| 'branchId'
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export interface PaymentReceiveMailOpts extends CommonMailOptions {}
|
export interface PaymentReceiveMailOpts extends CommonMailOptions {
|
||||||
|
attachPdf?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export interface PaymentReceiveMailOptsDTO extends CommonMailOptionsDTO {}
|
export interface PaymentReceiveMailOptsDTO extends CommonMailOptionsDTO {}
|
||||||
|
|
||||||
@@ -239,7 +241,6 @@ export interface PaymentReceivedPdfTemplateAttributes {
|
|||||||
paymentReceivedDateLabel: string;
|
paymentReceivedDateLabel: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export interface IPaymentReceivedState {
|
export interface IPaymentReceivedState {
|
||||||
defaultTemplateId: number;
|
defaultTemplateId: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import {
|
||||||
|
renderEstimateEmailTemplate,
|
||||||
|
EstimatePaymentEmailProps,
|
||||||
|
} from '@bigcapital/email-components';
|
||||||
|
import { GetSaleEstimate } from './GetSaleEstimate';
|
||||||
|
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
||||||
|
import { GetEstimateMailTemplateAttributesTransformer } from './GetEstimateMailTemplateAttributesTransformer';
|
||||||
|
import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class GetEstimateMailTemplate {
|
||||||
|
@Inject()
|
||||||
|
private getEstimateService: GetSaleEstimate;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private transformer: TransformerInjectable;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getBrandingTemplate: GetPdfTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the mail template attributes of the given estimate.
|
||||||
|
* Estimate template attributes are composed of the estimate and branding template attributes.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} estimateId - Estimate id.
|
||||||
|
* @returns {Promise<EstimatePaymentEmailProps>}
|
||||||
|
*/
|
||||||
|
public async getMailTemplateAttributes(
|
||||||
|
tenantId: number,
|
||||||
|
estimateId: number
|
||||||
|
): Promise<EstimatePaymentEmailProps> {
|
||||||
|
const estimate = await this.getEstimateService.getEstimate(
|
||||||
|
tenantId,
|
||||||
|
estimateId
|
||||||
|
);
|
||||||
|
const brandingTemplate = await this.getBrandingTemplate.getPdfTemplate(
|
||||||
|
tenantId,
|
||||||
|
estimate.pdfTemplateId
|
||||||
|
);
|
||||||
|
const mailTemplateAttributes = await this.transformer.transform(
|
||||||
|
tenantId,
|
||||||
|
estimate,
|
||||||
|
new GetEstimateMailTemplateAttributesTransformer(),
|
||||||
|
{
|
||||||
|
estimate,
|
||||||
|
brandingTemplate,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return mailTemplateAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rertieves the mail template html content.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} estimateId
|
||||||
|
* @param overrideAttributes
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public async getMailTemplate(
|
||||||
|
tenantId: number,
|
||||||
|
estimateId: number,
|
||||||
|
overrideAttributes?: Partial<any>
|
||||||
|
): Promise<string> {
|
||||||
|
const attributes = await this.getMailTemplateAttributes(
|
||||||
|
tenantId,
|
||||||
|
estimateId
|
||||||
|
);
|
||||||
|
const mergedAttributes = {
|
||||||
|
...attributes,
|
||||||
|
...overrideAttributes,
|
||||||
|
};
|
||||||
|
return renderEstimateEmailTemplate(mergedAttributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import { Transformer } from '@/lib/Transformer/Transformer';
|
||||||
|
|
||||||
|
export class GetEstimateMailTemplateAttributesTransformer extends Transformer {}
|
||||||
@@ -17,6 +17,7 @@ import { mergeAndValidateMailOptions } from '@/services/MailNotification/utils';
|
|||||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
import events from '@/subscribers/events';
|
import events from '@/subscribers/events';
|
||||||
import { transformEstimateToMailDataArgs } from './utils';
|
import { transformEstimateToMailDataArgs } from './utils';
|
||||||
|
import { GetEstimateMailTemplate } from './GetEstimateMailTemplate';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SendSaleEstimateMail {
|
export class SendSaleEstimateMail {
|
||||||
@@ -32,12 +33,15 @@ export class SendSaleEstimateMail {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private contactMailNotification: ContactMailNotification;
|
private contactMailNotification: ContactMailNotification;
|
||||||
|
|
||||||
@Inject('agenda')
|
@Inject()
|
||||||
private agenda: any;
|
private getEstimateMailTemplate: GetEstimateMailTemplate;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
private eventPublisher: EventPublisher;
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
|
@Inject('agenda')
|
||||||
|
private agenda: any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Triggers the reminder mail of the given sale estimate.
|
* Triggers the reminder mail of the given sale estimate.
|
||||||
* @param {number} tenantId -
|
* @param {number} tenantId -
|
||||||
@@ -132,9 +136,45 @@ export class SendSaleEstimateMail {
|
|||||||
mailOptions,
|
mailOptions,
|
||||||
formatterArgs
|
formatterArgs
|
||||||
);
|
);
|
||||||
return { ...formattedOptions };
|
// Retrieves the estimate mail template.
|
||||||
|
const message = await this.getEstimateMailTemplate.getMailTemplate(
|
||||||
|
tenantId,
|
||||||
|
saleEstimateId,
|
||||||
|
{
|
||||||
|
message: formattedOptions.message,
|
||||||
|
preview: formattedOptions.message,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return { ...formattedOptions, message };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the formatted mail options.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} saleEstimateId
|
||||||
|
* @param {SaleEstimateMailOptionsDTO} messageOptions
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public async getFormattedMailOptions(
|
||||||
|
tenantId: number,
|
||||||
|
saleEstimateId: number,
|
||||||
|
messageOptions: SaleEstimateMailOptionsDTO
|
||||||
|
): Promise<SaleEstimateMailOptions> {
|
||||||
|
const defaultMessageOptions = await this.getMailOptions(
|
||||||
|
tenantId,
|
||||||
|
saleEstimateId
|
||||||
|
);
|
||||||
|
const parsedMessageOptions = mergeAndValidateMailOptions(
|
||||||
|
defaultMessageOptions,
|
||||||
|
messageOptions
|
||||||
|
);
|
||||||
|
return this.formatMailOptions(
|
||||||
|
tenantId,
|
||||||
|
saleEstimateId,
|
||||||
|
parsedMessageOptions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the mail notification of the given sale estimate.
|
* Sends the mail notification of the given sale estimate.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -147,20 +187,10 @@ export class SendSaleEstimateMail {
|
|||||||
saleEstimateId: number,
|
saleEstimateId: number,
|
||||||
messageOptions: SaleEstimateMailOptionsDTO
|
messageOptions: SaleEstimateMailOptionsDTO
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const localMessageOpts = await this.getMailOptions(
|
const formattedOptions = await this.getFormattedMailOptions(
|
||||||
tenantId,
|
|
||||||
saleEstimateId
|
|
||||||
);
|
|
||||||
// Overrides and validates the given mail options.
|
|
||||||
const parsedMessageOptions = mergeAndValidateMailOptions(
|
|
||||||
localMessageOpts,
|
|
||||||
messageOptions
|
|
||||||
) as SaleEstimateMailOptions;
|
|
||||||
|
|
||||||
const formattedOptions = await this.formatMailOptions(
|
|
||||||
tenantId,
|
tenantId,
|
||||||
saleEstimateId,
|
saleEstimateId,
|
||||||
parsedMessageOptions
|
messageOptions
|
||||||
);
|
);
|
||||||
const mail = new Mail()
|
const mail = new Mail()
|
||||||
.setSubject(formattedOptions.subject)
|
.setSubject(formattedOptions.subject)
|
||||||
@@ -182,7 +212,6 @@ export class SendSaleEstimateMail {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const eventPayload = {
|
const eventPayload = {
|
||||||
tenantId,
|
tenantId,
|
||||||
saleEstimateId,
|
saleEstimateId,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { GetPaymentReceivedMailStateTransformer } from './GetPaymentReceivedMail
|
|||||||
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
||||||
import { Inject, Service } from 'typedi';
|
import { Inject, Service } from 'typedi';
|
||||||
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
|
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
|
||||||
|
import { SendPaymentReceiveMailNotification } from './PaymentReceivedMailNotification';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class GetPaymentReceivedMailState {
|
export class GetPaymentReceivedMailState {
|
||||||
@@ -11,7 +12,7 @@ export class GetPaymentReceivedMailState {
|
|||||||
private tenancy: HasTenancyService;
|
private tenancy: HasTenancyService;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
private contactMailNotification: ContactMailNotification;
|
private paymentReceivedMail: SendPaymentReceiveMailNotification;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
private transformer: TransformerInjectable;
|
private transformer: TransformerInjectable;
|
||||||
@@ -35,12 +36,10 @@ export class GetPaymentReceivedMailState {
|
|||||||
.withGraphFetched('pdfTemplate')
|
.withGraphFetched('pdfTemplate')
|
||||||
.throwIfNotFound();
|
.throwIfNotFound();
|
||||||
|
|
||||||
const mailOptions =
|
const mailOptions = await this.paymentReceivedMail.getMailOptions(
|
||||||
await this.contactMailNotification.getDefaultMailOptions(
|
tenantId,
|
||||||
tenantId,
|
paymentId
|
||||||
paymentReceive.customerId
|
);
|
||||||
);
|
|
||||||
|
|
||||||
const transformed = await this.transformer.transform(
|
const transformed = await this.transformer.transform(
|
||||||
tenantId,
|
tenantId,
|
||||||
paymentReceive,
|
paymentReceive,
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
||||||
|
import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate';
|
||||||
|
import { GetPaymentReceived } from './GetPaymentReceived';
|
||||||
|
import { GetPaymentReceivedMailTemplateAttrsTransformer } from './GetPaymentReceivedMailTemplateAttrsTransformer';
|
||||||
|
import {
|
||||||
|
PaymentReceivedEmailTemplateProps,
|
||||||
|
renderPaymentReceivedEmailTemplate,
|
||||||
|
} from '@bigcapital/email-components';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class GetPaymentReceivedMailTemplate {
|
||||||
|
@Inject()
|
||||||
|
private getPaymentReceivedService: GetPaymentReceived;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getBrandingTemplate: GetPdfTemplate;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private transformer: TransformerInjectable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the mail template attributes of the given payment received.
|
||||||
|
* @param {number} tenantId - Tenant id.
|
||||||
|
* @param {number} paymentReceivedId - Payment received id.
|
||||||
|
* @returns {Promise<PaymentReceivedEmailTemplateProps>}
|
||||||
|
*/
|
||||||
|
public async getMailTemplateAttributes(
|
||||||
|
tenantId: number,
|
||||||
|
paymentReceivedId: number
|
||||||
|
): Promise<PaymentReceivedEmailTemplateProps> {
|
||||||
|
const paymentReceived =
|
||||||
|
await this.getPaymentReceivedService.getPaymentReceive(
|
||||||
|
tenantId,
|
||||||
|
paymentReceivedId
|
||||||
|
);
|
||||||
|
const brandingTemplate = await this.getBrandingTemplate.getPdfTemplate(
|
||||||
|
tenantId,
|
||||||
|
paymentReceived.pdfTemplateId
|
||||||
|
);
|
||||||
|
const mailTemplateAttributes = await this.transformer.transform(
|
||||||
|
tenantId,
|
||||||
|
paymentReceived,
|
||||||
|
new GetPaymentReceivedMailTemplateAttrsTransformer(),
|
||||||
|
{
|
||||||
|
paymentReceived,
|
||||||
|
brandingTemplate,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return mailTemplateAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the mail template html content.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} paymentReceivedId
|
||||||
|
* @param {Partial<PaymentReceivedEmailTemplateProps>} overrideAttributes
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public async getMailTemplate(
|
||||||
|
tenantId: number,
|
||||||
|
paymentReceivedId: number,
|
||||||
|
overrideAttributes?: Partial<PaymentReceivedEmailTemplateProps>
|
||||||
|
): Promise<string> {
|
||||||
|
const mailTemplateAttributes = await this.getMailTemplateAttributes(
|
||||||
|
tenantId,
|
||||||
|
paymentReceivedId
|
||||||
|
);
|
||||||
|
const mergedAttributes = {
|
||||||
|
...mailTemplateAttributes,
|
||||||
|
...overrideAttributes,
|
||||||
|
};
|
||||||
|
return renderPaymentReceivedEmailTemplate(mergedAttributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import { Transformer } from '@/lib/Transformer/Transformer';
|
||||||
|
|
||||||
|
export class GetPaymentReceivedMailTemplateAttrsTransformer extends Transformer {}
|
||||||
@@ -15,8 +15,9 @@ import { GetPaymentReceived } from './GetPaymentReceived';
|
|||||||
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
|
import { ContactMailNotification } from '@/services/MailNotification/ContactMailNotification';
|
||||||
import { mergeAndValidateMailOptions } from '@/services/MailNotification/utils';
|
import { mergeAndValidateMailOptions } from '@/services/MailNotification/utils';
|
||||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
import events from '@/subscribers/events';
|
|
||||||
import { transformPaymentReceivedToMailDataArgs } from './utils';
|
import { transformPaymentReceivedToMailDataArgs } from './utils';
|
||||||
|
import { GetPaymentReceivedMailTemplate } from './GetPaymentReceivedMailTemplate';
|
||||||
|
import events from '@/subscribers/events';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SendPaymentReceiveMailNotification {
|
export class SendPaymentReceiveMailNotification {
|
||||||
@@ -29,12 +30,15 @@ export class SendPaymentReceiveMailNotification {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private contactMailNotification: ContactMailNotification;
|
private contactMailNotification: ContactMailNotification;
|
||||||
|
|
||||||
@Inject('agenda')
|
|
||||||
private agenda: any;
|
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
private eventPublisher: EventPublisher;
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private paymentMailTemplate: GetPaymentReceivedMailTemplate;
|
||||||
|
|
||||||
|
@Inject('agenda')
|
||||||
|
private agenda: any;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends the mail of the given payment receive.
|
* Sends the mail of the given payment receive.
|
||||||
* @param {number} tenantId
|
* @param {number} tenantId
|
||||||
@@ -77,7 +81,82 @@ export class SendPaymentReceiveMailNotification {
|
|||||||
tenantId,
|
tenantId,
|
||||||
invoiceId
|
invoiceId
|
||||||
);
|
);
|
||||||
return transformPaymentReceivedToMailDataArgs(payment);
|
const commonArgs = await this.contactMailNotification.getCommonFormatArgs(
|
||||||
|
tenantId
|
||||||
|
);
|
||||||
|
const paymentArgs = transformPaymentReceivedToMailDataArgs(payment);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...commonArgs,
|
||||||
|
...paymentArgs,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the mail options of the given payment received.
|
||||||
|
* @param {number} tenantId - Tenant id.
|
||||||
|
* @param {number} paymentReceivedId - Payment received id.
|
||||||
|
* @param {string} defaultSubject - Default subject of the mail.
|
||||||
|
* @param {string} defaultContent - Default content of the mail.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public getMailOptions = async (
|
||||||
|
tenantId: number,
|
||||||
|
paymentReceivedId: number,
|
||||||
|
defaultSubject: string = DEFAULT_PAYMENT_MAIL_SUBJECT,
|
||||||
|
defaultContent: string = DEFAULT_PAYMENT_MAIL_CONTENT
|
||||||
|
): Promise<PaymentReceiveMailOpts> => {
|
||||||
|
const { PaymentReceive } = this.tenancy.models(tenantId);
|
||||||
|
|
||||||
|
const paymentReceived = await PaymentReceive.query().findById(
|
||||||
|
paymentReceivedId
|
||||||
|
);
|
||||||
|
const formatArgs = await this.textFormatter(tenantId, paymentReceivedId);
|
||||||
|
|
||||||
|
// Retrieves the default mail options.
|
||||||
|
const mailOptions =
|
||||||
|
await this.contactMailNotification.getDefaultMailOptions(
|
||||||
|
tenantId,
|
||||||
|
paymentReceived.customerId
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
...mailOptions,
|
||||||
|
message: defaultContent,
|
||||||
|
subject: defaultSubject,
|
||||||
|
attachPdf: true,
|
||||||
|
formatArgs,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the mail options of the given payment receive.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} paymentReceiveId
|
||||||
|
* @param {PaymentReceiveMailOpts} mailOptions
|
||||||
|
* @returns {Promise<PaymentReceiveMailOpts>}
|
||||||
|
*/
|
||||||
|
public formattedMailOptions = async (
|
||||||
|
tenantId: number,
|
||||||
|
paymentReceiveId: number,
|
||||||
|
mailOptions: PaymentReceiveMailOpts
|
||||||
|
): Promise<PaymentReceiveMailOpts> => {
|
||||||
|
const formatterArgs = await this.textFormatter(tenantId, paymentReceiveId);
|
||||||
|
const formattedOptions =
|
||||||
|
await this.contactMailNotification.formatMailOptions(
|
||||||
|
tenantId,
|
||||||
|
mailOptions,
|
||||||
|
formatterArgs
|
||||||
|
);
|
||||||
|
// Retrieves the mail template.
|
||||||
|
const message = await this.paymentMailTemplate.getMailTemplate(
|
||||||
|
tenantId,
|
||||||
|
paymentReceiveId,
|
||||||
|
{
|
||||||
|
message: formattedOptions.message,
|
||||||
|
preview: formattedOptions.message,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return { ...formattedOptions, message };
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -105,10 +184,10 @@ export class SendPaymentReceiveMailNotification {
|
|||||||
messageDTO
|
messageDTO
|
||||||
);
|
);
|
||||||
// Formats the message options.
|
// Formats the message options.
|
||||||
return this.contactMailNotification.formatMailOptions(
|
return this.formattedMailOptions(
|
||||||
tenantId,
|
tenantId,
|
||||||
parsedMessageOpts,
|
paymentReceiveId,
|
||||||
formatterArgs
|
parsedMessageOpts
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
import {
|
||||||
|
ReceiptEmailTemplateProps,
|
||||||
|
renderReceiptEmailTemplate,
|
||||||
|
} from '@bigcapital/email-components';
|
||||||
|
import { Inject, Service } from 'typedi';
|
||||||
|
import { GetSaleReceipt } from './GetSaleReceipt';
|
||||||
|
import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate';
|
||||||
|
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
||||||
|
import { GetSaleReceiptMailTemplateAttributesTransformer } from './GetSaleReceiptMailTemplateAttributesTransformer';
|
||||||
|
|
||||||
|
@Service()
|
||||||
|
export class GetSaleReceiptMailTemplate {
|
||||||
|
@Inject()
|
||||||
|
private getReceiptService: GetSaleReceipt;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private transformer: TransformerInjectable;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getBrandingTemplate: GetPdfTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the mail template attributes of the given estimate.
|
||||||
|
* Estimate template attributes are composed of the estimate and branding template attributes.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} receiptId - Receipt id.
|
||||||
|
* @returns {Promise<EstimatePaymentEmailProps>}
|
||||||
|
*/
|
||||||
|
public async getMailTemplateAttributes(
|
||||||
|
tenantId: number,
|
||||||
|
receiptId: number
|
||||||
|
): Promise<ReceiptEmailTemplateProps> {
|
||||||
|
const receipt = await this.getReceiptService.getSaleReceipt(
|
||||||
|
tenantId,
|
||||||
|
receiptId
|
||||||
|
);
|
||||||
|
const brandingTemplate = await this.getBrandingTemplate.getPdfTemplate(
|
||||||
|
tenantId,
|
||||||
|
receipt.pdfTemplateId
|
||||||
|
);
|
||||||
|
const mailTemplateAttributes = await this.transformer.transform(
|
||||||
|
tenantId,
|
||||||
|
receipt,
|
||||||
|
new GetSaleReceiptMailTemplateAttributesTransformer(),
|
||||||
|
{
|
||||||
|
receipt,
|
||||||
|
brandingTemplate,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return mailTemplateAttributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the mail template html content.
|
||||||
|
* @param {number} tenantId
|
||||||
|
* @param {number} estimateId
|
||||||
|
* @param overrideAttributes
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
public async getMailTemplate(
|
||||||
|
tenantId: number,
|
||||||
|
estimateId: number,
|
||||||
|
overrideAttributes?: Partial<any>
|
||||||
|
): Promise<string> {
|
||||||
|
const attributes = await this.getMailTemplateAttributes(
|
||||||
|
tenantId,
|
||||||
|
estimateId
|
||||||
|
);
|
||||||
|
const mergedAttributes = {
|
||||||
|
...attributes,
|
||||||
|
...overrideAttributes,
|
||||||
|
};
|
||||||
|
return renderReceiptEmailTemplate(mergedAttributes);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import { Transformer } from '@/lib/Transformer/Transformer';
|
||||||
|
|
||||||
|
export class GetSaleReceiptMailTemplateAttributesTransformer extends Transformer {}
|
||||||
@@ -17,6 +17,7 @@ import { mergeAndValidateMailOptions } from '@/services/MailNotification/utils';
|
|||||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||||
import events from '@/subscribers/events';
|
import events from '@/subscribers/events';
|
||||||
import { transformReceiptToMailDataArgs } from './utils';
|
import { transformReceiptToMailDataArgs } from './utils';
|
||||||
|
import { GetSaleReceiptMailTemplate } from './GetSaleReceiptMailTemplate';
|
||||||
|
|
||||||
@Service()
|
@Service()
|
||||||
export class SaleReceiptMailNotification {
|
export class SaleReceiptMailNotification {
|
||||||
@@ -32,6 +33,9 @@ export class SaleReceiptMailNotification {
|
|||||||
@Inject()
|
@Inject()
|
||||||
private contactMailNotification: ContactMailNotification;
|
private contactMailNotification: ContactMailNotification;
|
||||||
|
|
||||||
|
@Inject()
|
||||||
|
private getReceiptMailTemplate: GetSaleReceiptMailTemplate;
|
||||||
|
|
||||||
@Inject()
|
@Inject()
|
||||||
private eventPublisher: EventPublisher;
|
private eventPublisher: EventPublisher;
|
||||||
|
|
||||||
@@ -133,7 +137,15 @@ export class SaleReceiptMailNotification {
|
|||||||
mailOptions,
|
mailOptions,
|
||||||
formatterArgs
|
formatterArgs
|
||||||
)) as SaleReceiptMailOpts;
|
)) as SaleReceiptMailOpts;
|
||||||
return formattedOptions;
|
|
||||||
|
const message = await this.getReceiptMailTemplate.getMailTemplate(
|
||||||
|
tenantId,
|
||||||
|
receiptId,
|
||||||
|
{
|
||||||
|
message: formattedOptions.message,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return { ...formattedOptions, message };
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export function EstimateSendMailForm({ children }: EstimateSendMailFormProps) {
|
|||||||
{ setSubmitting }: FormikHelpers<EstimateSendMailFormValues>,
|
{ setSubmitting }: FormikHelpers<EstimateSendMailFormValues>,
|
||||||
) => {
|
) => {
|
||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
sendEstimateMail({ id: estimateId, values: { ...values } })
|
sendEstimateMail([estimateId, values])
|
||||||
.then(() => {
|
.then(() => {
|
||||||
AppToaster.show({
|
AppToaster.show({
|
||||||
message: 'The invoice mail has been sent to the customer.',
|
message: 'The invoice mail has been sent to the customer.',
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { css } from '@emotion/css';
|
|||||||
import { Intent } from '@blueprintjs/core';
|
import { Intent } from '@blueprintjs/core';
|
||||||
import { PaymentReceivedSendMailFormSchema } from './_types';
|
import { PaymentReceivedSendMailFormSchema } from './_types';
|
||||||
import { AppToaster } from '@/components';
|
import { AppToaster } from '@/components';
|
||||||
import { useSendSaleInvoiceMail } from '@/hooks/query';
|
import { useSendPaymentReceiveMail, } from '@/hooks/query';
|
||||||
import { usePaymentReceivedSendMailBoot } from './PaymentReceivedMailBoot';
|
import { usePaymentReceivedSendMailBoot } from './PaymentReceivedMailBoot';
|
||||||
import { useDrawerActions } from '@/hooks/state';
|
import { useDrawerActions } from '@/hooks/state';
|
||||||
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
import { useDrawerContext } from '@/components/Drawer/DrawerProvider';
|
||||||
@@ -27,7 +27,7 @@ interface PaymentReceivedSendMailFormProps {
|
|||||||
export function PaymentReceivedSendMailForm({
|
export function PaymentReceivedSendMailForm({
|
||||||
children,
|
children,
|
||||||
}: PaymentReceivedSendMailFormProps) {
|
}: PaymentReceivedSendMailFormProps) {
|
||||||
const { mutateAsync: sendInvoiceMail } = useSendSaleInvoiceMail();
|
const { mutateAsync: sendPaymentMail } = useSendPaymentReceiveMail();
|
||||||
const { paymentReceivedId, paymentReceivedMailState } =
|
const { paymentReceivedId, paymentReceivedMailState } =
|
||||||
usePaymentReceivedSendMailBoot();
|
usePaymentReceivedSendMailBoot();
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ export function PaymentReceivedSendMailForm({
|
|||||||
{ setSubmitting }: FormikHelpers<PaymentReceivedSendMailFormValues>,
|
{ setSubmitting }: FormikHelpers<PaymentReceivedSendMailFormValues>,
|
||||||
) => {
|
) => {
|
||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
sendInvoiceMail({ id: paymentReceivedId, values: { ...values } })
|
sendPaymentMail([paymentReceivedId, values])
|
||||||
.then(() => {
|
.then(() => {
|
||||||
AppToaster.show({
|
AppToaster.show({
|
||||||
message: 'The invoice mail has been sent to the customer.',
|
message: 'The invoice mail has been sent to the customer.',
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export function ReceiptSendMailForm({ children }: ReceiptSendMailFormProps) {
|
|||||||
{ setSubmitting }: FormikHelpers<ReceiptSendMailFormValues>,
|
{ setSubmitting }: FormikHelpers<ReceiptSendMailFormValues>,
|
||||||
) => {
|
) => {
|
||||||
setSubmitting(true);
|
setSubmitting(true);
|
||||||
sendReceiptMail({ id: receiptId, values: { ...values } })
|
sendReceiptMail([receiptId, values])
|
||||||
.then(() => {
|
.then(() => {
|
||||||
AppToaster.show({
|
AppToaster.show({
|
||||||
message: 'The receipt mail has been sent to the customer.',
|
message: 'The receipt mail has been sent to the customer.',
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ export function usePdfPaymentReceive(paymentReceiveId) {
|
|||||||
return useRequestPdf({ url: `sales/payment_receives/${paymentReceiveId}` });
|
return useRequestPdf({ url: `sales/payment_receives/${paymentReceiveId}` });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function useSendPaymentReceiveMail(props) {
|
export function useSendPaymentReceiveMail(props?: any) {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const apiRequest = useApiRequest();
|
const apiRequest = useApiRequest();
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,5 @@
|
|||||||
export * from './InvoicePaymentEmail';
|
export * from './InvoicePaymentEmail';
|
||||||
|
export * from './EstimatePaymentEmail';
|
||||||
|
export * from './ReceiptPaymentEmail';
|
||||||
|
export * from './CreditNoteEmailTemplate';
|
||||||
|
export * from './PaymentReceivedEmailTemplate';
|
||||||
|
|||||||
Reference in New Issue
Block a user