Files
bigcapital/packages/server/src/services/Sales/Receipts/SaleReceiptsPdfService.ts
2024-10-19 13:38:28 +02:00

120 lines
3.6 KiB
TypeScript

import { Inject, Service } from 'typedi';
import { TemplateInjectable } from '@/services/TemplateInjectable/TemplateInjectable';
import { ChromiumlyTenancy } from '@/services/ChromiumlyTenancy/ChromiumlyTenancy';
import { GetSaleReceipt } from './GetSaleReceipt';
import HasTenancyService from '@/services/Tenancy/TenancyService';
import { SaleReceiptBrandingTemplate } from './SaleReceiptBrandingTemplate';
import { transformReceiptToBrandingTemplateAttributes } from './utils';
import { ISaleReceiptBrandingTemplateAttributes } from '@/interfaces';
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
import events from '@/subscribers/events';
@Service()
export class SaleReceiptsPdf {
@Inject()
private tenancy: HasTenancyService;
@Inject()
private chromiumlyTenancy: ChromiumlyTenancy;
@Inject()
private templateInjectable: TemplateInjectable;
@Inject()
private getSaleReceiptService: GetSaleReceipt;
@Inject()
private saleReceiptBrandingTemplate: SaleReceiptBrandingTemplate;
@Inject()
private eventPublisher: EventPublisher;
/**
* Retrieves sale invoice pdf content.
* @param {number} tenantId -
* @param {number} saleInvoiceId -
* @returns {Promise<Buffer>}
*/
public async saleReceiptPdf(tenantId: number, saleReceiptId: number) {
const filename = await this.getSaleReceiptFilename(tenantId, saleReceiptId);
const brandingAttributes = await this.getReceiptBrandingAttributes(
tenantId,
saleReceiptId
);
// Converts the receipt template to html content.
const htmlContent = await this.templateInjectable.render(
tenantId,
'modules/receipt-regular',
brandingAttributes
);
// Renders the html content to pdf document.
const content = await this.chromiumlyTenancy.convertHtmlContent(
tenantId,
htmlContent
);
const eventPayload = { tenantId, saleReceiptId };
// Triggers the `onSaleReceiptPdfViewed` event.
await this.eventPublisher.emitAsync(
events.saleReceipt.onPdfViewed,
eventPayload
);
return [content, filename];
}
/**
* Retrieves the filename file document of the given sale receipt.
* @param {number} tenantId
* @param {number} receiptId
* @returns {Promise<string>}
*/
public async getSaleReceiptFilename(
tenantId: number,
receiptId: number
): Promise<string> {
const { SaleReceipt } = this.tenancy.models(tenantId);
const receipt = await SaleReceipt.query().findById(receiptId);
return `Receipt-${receipt.receiptNumber}`;
}
/**
* Retrieves receipt branding attributes.
* @param {number} tenantId
* @param {number} receiptId
* @returns {Promise<ISaleReceiptBrandingTemplateAttributes>}
*/
public async getReceiptBrandingAttributes(
tenantId: number,
receiptId: number
): Promise<ISaleReceiptBrandingTemplateAttributes> {
const { PdfTemplate } = this.tenancy.models(tenantId);
const saleReceipt = await this.getSaleReceiptService.getSaleReceipt(
tenantId,
receiptId
);
// Retrieve the invoice template id of not found get the default template id.
const templateId =
saleReceipt.pdfTemplateId ??
(
await PdfTemplate.query().findOne({
resource: 'SaleReceipt',
default: true,
})
)?.id;
// Retrieves the receipt branding template.
const brandingTemplate =
await this.saleReceiptBrandingTemplate.getSaleReceiptBrandingTemplate(
tenantId,
templateId
);
return {
...brandingTemplate.attributes,
...transformReceiptToBrandingTemplateAttributes(saleReceipt),
};
}
}