mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-17 05:10:31 +00:00
feat: rendering pdf templates on the server-side
This commit is contained in:
@@ -2,9 +2,16 @@ import { Inject, Service } from 'typedi';
|
||||
import { ChromiumlyTenancy } from '@/services/ChromiumlyTenancy/ChromiumlyTenancy';
|
||||
import { TemplateInjectable } from '@/services/TemplateInjectable/TemplateInjectable';
|
||||
import { GetPaymentReceived } from './GetPaymentReceived';
|
||||
import HasTenancyService from '@/services/Tenancy/TenancyService';
|
||||
import { PaymentReceivedBrandingTemplate } from './PaymentReceivedBrandingTemplate';
|
||||
import { transformPaymentReceivedToPdfTemplate } from './utils';
|
||||
import { PaymentReceivedPdfTemplateAttributes } from '@/interfaces';
|
||||
|
||||
@Service()
|
||||
export default class GetPaymentReceivedPdf {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
@Inject()
|
||||
private chromiumlyTenancy: ChromiumlyTenancy;
|
||||
|
||||
@@ -14,6 +21,9 @@ export default class GetPaymentReceivedPdf {
|
||||
@Inject()
|
||||
private getPaymentService: GetPaymentReceived;
|
||||
|
||||
@Inject()
|
||||
private paymentBrandingTemplateService: PaymentReceivedBrandingTemplate;
|
||||
|
||||
/**
|
||||
* Retrieve sale invoice pdf content.
|
||||
* @param {number} tenantId -
|
||||
@@ -24,19 +34,52 @@ export default class GetPaymentReceivedPdf {
|
||||
tenantId: number,
|
||||
paymentReceiveId: number
|
||||
): Promise<Buffer> {
|
||||
const paymentReceive = await this.getPaymentService.getPaymentReceive(
|
||||
const brandingAttributes = await this.getPaymentBrandingAttributes(
|
||||
tenantId,
|
||||
paymentReceiveId
|
||||
);
|
||||
const htmlContent = await this.templateInjectable.render(
|
||||
tenantId,
|
||||
'modules/payment-receive-standard',
|
||||
{
|
||||
paymentReceive,
|
||||
}
|
||||
brandingAttributes
|
||||
);
|
||||
return this.chromiumlyTenancy.convertHtmlContent(tenantId, htmlContent, {
|
||||
margins: { top: 0, bottom: 0, left: 0, right: 0 },
|
||||
});
|
||||
// Converts the given html content to pdf document.
|
||||
return this.chromiumlyTenancy.convertHtmlContent(tenantId, htmlContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the given payment received branding attributes.
|
||||
* @param {number} tenantId
|
||||
* @param {number} paymentReceivedId
|
||||
* @returns {Promise<PaymentReceivedPdfTemplateAttributes>}
|
||||
*/
|
||||
async getPaymentBrandingAttributes(
|
||||
tenantId: number,
|
||||
paymentReceivedId: number
|
||||
): Promise<PaymentReceivedPdfTemplateAttributes> {
|
||||
const { PdfTemplate } = this.tenancy.models(tenantId);
|
||||
|
||||
const paymentReceived = await this.getPaymentService.getPaymentReceive(
|
||||
tenantId,
|
||||
paymentReceivedId
|
||||
);
|
||||
const templateId =
|
||||
paymentReceived?.pdfTemplateId ??
|
||||
(
|
||||
await PdfTemplate.query().findOne({
|
||||
resource: 'PaymentReceive',
|
||||
default: true,
|
||||
})
|
||||
)?.id;
|
||||
|
||||
const brandingTemplate =
|
||||
await this.paymentBrandingTemplateService.getPaymentReceivedPdfTemplate(
|
||||
tenantId,
|
||||
templateId
|
||||
);
|
||||
return {
|
||||
...brandingTemplate.attributes,
|
||||
...transformPaymentReceivedToPdfTemplate(paymentReceived),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { GetPdfTemplate } from '@/services/PdfTemplate/GetPdfTemplate';
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { mergePdfTemplateWithDefaultAttributes } from '../Invoices/utils';
|
||||
import { defaultPaymentReceivedPdfTemplateAttributes } from './constants';
|
||||
import { PdfTemplate } from '@/models/PdfTemplate';
|
||||
|
||||
@Service()
|
||||
export class PaymentReceivedBrandingTemplate {
|
||||
@Inject()
|
||||
private getPdfTemplateService: GetPdfTemplate;
|
||||
|
||||
/**
|
||||
* Retrieves the payment received pdf template.
|
||||
* @param {number} tenantId
|
||||
* @param {number} paymentTemplateId
|
||||
* @returns
|
||||
*/
|
||||
public async getPaymentReceivedPdfTemplate(
|
||||
tenantId: number,
|
||||
paymentTemplateId: number
|
||||
): Promise<PdfTemplate> {
|
||||
const template = await this.getPdfTemplateService.getPdfTemplate(
|
||||
tenantId,
|
||||
paymentTemplateId
|
||||
);
|
||||
const attributes = mergePdfTemplateWithDefaultAttributes(
|
||||
template.attributes,
|
||||
defaultPaymentReceivedPdfTemplateAttributes
|
||||
);
|
||||
return {
|
||||
...template,
|
||||
attributes,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import * as R from 'ramda';
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { omit, sumBy } from 'lodash';
|
||||
import composeAsync from 'async/compose';
|
||||
import {
|
||||
ICustomer,
|
||||
IPaymentReceived,
|
||||
@@ -12,6 +13,7 @@ import { PaymentReceivedIncrement } from './PaymentReceivedIncrement';
|
||||
import { BranchTransactionDTOTransform } from '@/services/Branches/Integrations/BranchTransactionDTOTransform';
|
||||
import { formatDateFields } from '@/utils';
|
||||
import { assocItemEntriesDefaultIndex } from '@/services/Items/utils';
|
||||
import { BrandingTemplateDTOTransformer } from '@/services/PdfTemplate/BrandingTemplateDTOTransformer';
|
||||
|
||||
@Service()
|
||||
export class PaymentReceiveDTOTransformer {
|
||||
@@ -24,6 +26,9 @@ export class PaymentReceiveDTOTransformer {
|
||||
@Inject()
|
||||
private branchDTOTransform: BranchTransactionDTOTransform;
|
||||
|
||||
@Inject()
|
||||
private brandingTemplatesTransformer: BrandingTemplateDTOTransformer;
|
||||
|
||||
/**
|
||||
* Transformes the create payment receive DTO to model object.
|
||||
* @param {number} tenantId
|
||||
@@ -68,8 +73,16 @@ export class PaymentReceiveDTOTransformer {
|
||||
exchangeRate: paymentReceiveDTO.exchangeRate || 1,
|
||||
entries,
|
||||
};
|
||||
const initialAsyncDTO = await composeAsync(
|
||||
// Assigns the default branding template id to the invoice DTO.
|
||||
this.brandingTemplatesTransformer.assocDefaultBrandingTemplate(
|
||||
tenantId,
|
||||
'SaleInvoice'
|
||||
)
|
||||
)(initialDTO);
|
||||
|
||||
return R.compose(
|
||||
this.branchDTOTransform.transformDTO<IPaymentReceived>(tenantId)
|
||||
)(initialDTO);
|
||||
)(initialAsyncDTO);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,3 +45,53 @@ export const PaymentsReceiveSampleData = [
|
||||
'Payment Amount': 850,
|
||||
},
|
||||
];
|
||||
|
||||
export const defaultPaymentReceivedPdfTemplateAttributes = {
|
||||
primaryColor: '#000',
|
||||
secondaryColor: '#000',
|
||||
showCompanyLogo: true,
|
||||
companyLogo: '',
|
||||
companyName: 'Bigcapital Technology, Inc.',
|
||||
|
||||
billedToAddress: [
|
||||
'Bigcapital Technology, Inc.',
|
||||
'131 Continental Dr Suite 305 Newark,',
|
||||
'Delaware 19713',
|
||||
'United States',
|
||||
'+1 762-339-5634',
|
||||
'ahmed@bigcapital.app',
|
||||
],
|
||||
billedFromAddress: [
|
||||
'131 Continental Dr Suite 305 Newark,',
|
||||
'Delaware 19713',
|
||||
'United States',
|
||||
'+1 762-339-5634',
|
||||
'ahmed@bigcapital.app',
|
||||
],
|
||||
showBilledFromAddress: true,
|
||||
showBillingToAddress: true,
|
||||
billedToLabel: 'Billed To',
|
||||
|
||||
total: '$1000.00',
|
||||
totalLabel: 'Total',
|
||||
showTotal: true,
|
||||
|
||||
subtotal: '1000/00',
|
||||
subtotalLabel: 'Subtotal',
|
||||
showSubtotal: true,
|
||||
|
||||
lines: [
|
||||
{
|
||||
invoiceNumber: 'INV-00001',
|
||||
invoiceAmount: '$1000.00',
|
||||
paidAmount: '$1000.00',
|
||||
},
|
||||
],
|
||||
showPaymentReceivedNumber: true,
|
||||
paymentReceivedNumberLabel: 'Payment Number',
|
||||
paymentReceivedNumebr: '346D3D40-0001',
|
||||
|
||||
paymentReceivedDate: 'September 3, 2024',
|
||||
showPaymentReceivedDate: true,
|
||||
paymentReceivedDateLabel: 'Payment Date',
|
||||
};
|
||||
|
||||
12
packages/server/src/services/Sales/PaymentReceived/utils.ts
Normal file
12
packages/server/src/services/Sales/PaymentReceived/utils.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import {
|
||||
IPaymentReceived,
|
||||
PaymentReceivedPdfTemplateAttributes,
|
||||
} from '@/interfaces';
|
||||
|
||||
export const transformPaymentReceivedToPdfTemplate = (
|
||||
payment: IPaymentReceived
|
||||
): Partial<PaymentReceivedPdfTemplateAttributes> => {
|
||||
return {
|
||||
// ...payment
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user