mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-18 05:40:31 +00:00
feat(server): add pdf template crud endpoints
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { ICreateInvoicePdfTemplateDTO } from './types';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import UnitOfWork from '../UnitOfWork';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
import events from '@/subscribers/events';
|
||||
|
||||
@Service()
|
||||
export class CreatePdfTemplate {
|
||||
@Inject()
|
||||
private tennacy: HasTenancyService;
|
||||
|
||||
@Inject()
|
||||
private uow: UnitOfWork;
|
||||
|
||||
@Inject()
|
||||
private eventPublisher: EventPublisher;
|
||||
|
||||
/**
|
||||
* Creates a new pdf template.
|
||||
* @param {number} tenantId
|
||||
* @param {ICreateInvoicePdfTemplateDTO} invoiceTemplateDTO
|
||||
*/
|
||||
public createPdfTemplate(
|
||||
tenantId: number,
|
||||
templateName: string,
|
||||
invoiceTemplateDTO: ICreateInvoicePdfTemplateDTO
|
||||
) {
|
||||
const { PdfTemplate } = this.tennacy.models(tenantId);
|
||||
const resource = 'SaleInvoice';
|
||||
const attributes = invoiceTemplateDTO;
|
||||
|
||||
return this.uow.withTransaction(tenantId, async (trx) => {
|
||||
await PdfTemplate.query(trx).insert({
|
||||
templateName,
|
||||
resource,
|
||||
attributes,
|
||||
});
|
||||
|
||||
await this.eventPublisher.emitAsync(events.pdfTemplate.onInvoiceCreated, {
|
||||
tenantId,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import UnitOfWork from '../UnitOfWork';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
import events from '@/subscribers/events';
|
||||
|
||||
@Service()
|
||||
export class DeletePdfTemplate {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
@Inject()
|
||||
private uow: UnitOfWork;
|
||||
|
||||
@Inject()
|
||||
private eventPublisher: EventPublisher;
|
||||
|
||||
/**
|
||||
* Deletes a pdf template.
|
||||
* @param {number} tenantId
|
||||
* @param {number} templateId
|
||||
*/
|
||||
public deletePdfTemplate(tenantId: number, templateId: number) {
|
||||
const { PdfTemplate } = this.tenancy.models(tenantId);
|
||||
|
||||
return this.uow.withTransaction(tenantId, async (trx) => {
|
||||
await PdfTemplate.query(trx).deleteById(templateId);
|
||||
|
||||
await this.eventPublisher.emitAsync(events.pdfTemplate.onDeleted, {
|
||||
tenantId,
|
||||
templateId,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
45
packages/server/src/services/PdfTemplate/EditPdfTemplate.ts
Normal file
45
packages/server/src/services/PdfTemplate/EditPdfTemplate.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { IEditPdfTemplateDTO } from './types';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import UnitOfWork from '../UnitOfWork';
|
||||
import { EventPublisher } from '@/lib/EventPublisher/EventPublisher';
|
||||
import events from '@/subscribers/events';
|
||||
|
||||
@Service()
|
||||
export class EditPdfTemplate {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
@Inject()
|
||||
private uow: UnitOfWork;
|
||||
|
||||
@Inject()
|
||||
private eventPublisher: EventPublisher;
|
||||
|
||||
/**
|
||||
* Edits an existing pdf template.
|
||||
* @param {number} tenantId
|
||||
* @param {number} templateId
|
||||
* @param {IEditPdfTemplateDTO} editTemplateDTO
|
||||
*/
|
||||
public editPdfTemplate(
|
||||
tenantId: number,
|
||||
templateId: number,
|
||||
editTemplateDTO: IEditPdfTemplateDTO
|
||||
) {
|
||||
const { PdfTemplate } = this.tenancy.models(tenantId);
|
||||
|
||||
return this.uow.withTransaction(tenantId, async (trx) => {
|
||||
await PdfTemplate.query(trx)
|
||||
.patch({
|
||||
...editTemplateDTO,
|
||||
})
|
||||
.where('id', templateId);
|
||||
|
||||
await this.eventPublisher.emitAsync(events.pdfTemplate.onEdited, {
|
||||
tenantId,
|
||||
templateId,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
29
packages/server/src/services/PdfTemplate/GetPdfTemplate.ts
Normal file
29
packages/server/src/services/PdfTemplate/GetPdfTemplate.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Knex } from 'knex';
|
||||
import { Inject, Service } from 'typedi';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
|
||||
@Service()
|
||||
export class GetPdfTemplate {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
/**
|
||||
* Retrieves a pdf template by its ID.
|
||||
* @param {number} tenantId - The ID of the tenant.
|
||||
* @param {number} templateId - The ID of the pdf template to retrieve.
|
||||
* @return {Promise<any>} - The retrieved pdf template.
|
||||
*/
|
||||
async getPdfTemplate(
|
||||
tenantId: number,
|
||||
templateId: number,
|
||||
trx?: Knex.Transaction
|
||||
): Promise<any> {
|
||||
const { PdfTemplate } = this.tenancy.models(tenantId);
|
||||
|
||||
const template = await PdfTemplate.query(trx)
|
||||
.findById(templateId)
|
||||
.throwIfNotFound();
|
||||
|
||||
return template;
|
||||
}
|
||||
}
|
||||
37
packages/server/src/services/PdfTemplate/GetPdfTemplates.ts
Normal file
37
packages/server/src/services/PdfTemplate/GetPdfTemplates.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { TransformerInjectable } from '@/lib/Transformer/TransformerInjectable';
|
||||
import HasTenancyService from '../Tenancy/TenancyService';
|
||||
import { GetPdfTemplatesTransformer } from './GetPdfTemplatesTransformer';
|
||||
import { Inject, Service } from 'typedi';
|
||||
|
||||
@Service()
|
||||
export class GetPdfTemplates {
|
||||
@Inject()
|
||||
private tenancy: HasTenancyService;
|
||||
|
||||
@Inject()
|
||||
private transformInjectable: TransformerInjectable;
|
||||
|
||||
/**
|
||||
* Retrieves a list of PDF templates for a specified tenant.
|
||||
* @param {number} tenantId - The ID of the tenant for which to retrieve templates.
|
||||
* @param {Object} [query] - Optional query parameters to filter the templates.
|
||||
* @param {string} [query.resource] - The resource type to filter the templates by.
|
||||
* @returns {Promise<any>} - A promise that resolves to the transformed list of PDF templates.
|
||||
*/
|
||||
async getPdfTemplates(tenantId: number, query?: { resource?: string }) {
|
||||
const { PdfTemplate } = this.tenancy.models(tenantId);
|
||||
|
||||
const templates = await PdfTemplate.query().onBuild((q) => {
|
||||
if (query?.resource) {
|
||||
q.where('resource', query?.resource);
|
||||
}
|
||||
q.orderBy('createdAt', 'ASC');
|
||||
});
|
||||
|
||||
return this.transformInjectable.transform(
|
||||
tenantId,
|
||||
templates,
|
||||
new GetPdfTemplatesTransformer()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { Transformer } from '@/lib/Transformer/Transformer';
|
||||
|
||||
export class GetPdfTemplatesTransformer extends Transformer {
|
||||
// Empty transformer with no additional methods or attributes
|
||||
|
||||
/**
|
||||
* Exclude attributes.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public excludeAttributes = (): string[] => {
|
||||
return ['attributes'];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
import { Inject, Service } from 'typedi';
|
||||
import { ICreateInvoicePdfTemplateDTO } from './types';
|
||||
import { CreatePdfTemplate } from './CreatePdfTemplate';
|
||||
import { DeletePdfTemplate } from './DeletePdfTemplate';
|
||||
import { GetPdfTemplate } from './GetPdfTemplate';
|
||||
import { GetPdfTemplates } from './GetPdfTemplates';
|
||||
import { EditPdfTemplate } from './EditPdfTemplate';
|
||||
|
||||
@Service()
|
||||
export class PdfTemplateApplication {
|
||||
@Inject()
|
||||
private createPdfTemplateService: CreatePdfTemplate;
|
||||
|
||||
@Inject()
|
||||
private deletePdfTemplateService: DeletePdfTemplate;
|
||||
|
||||
@Inject()
|
||||
private getPdfTemplateService: GetPdfTemplate;
|
||||
|
||||
@Inject()
|
||||
private getPdfTemplatesService: GetPdfTemplates;
|
||||
|
||||
@Inject()
|
||||
private editPdfTemplateService: EditPdfTemplate;
|
||||
|
||||
public async createPdfTemplate(
|
||||
tenantId: number,
|
||||
templateName: string,
|
||||
invoiceTemplateDTO: ICreateInvoicePdfTemplateDTO
|
||||
) {
|
||||
return this.createPdfTemplateService.createPdfTemplate(
|
||||
tenantId,
|
||||
templateName,
|
||||
invoiceTemplateDTO
|
||||
);
|
||||
}
|
||||
|
||||
public async editPdfTemplate(
|
||||
tenantId: number,
|
||||
templateId: number,
|
||||
editTemplateDTO: IEditPdfTemplateDTO
|
||||
) {
|
||||
return this.editPdfTemplateService.editPdfTemplate(
|
||||
tenantId,
|
||||
templateId,
|
||||
editTemplateDTO
|
||||
);
|
||||
}
|
||||
|
||||
public async deletePdfTemplate(tenantId: number, templateId: number) {
|
||||
return this.deletePdfTemplateService.deletePdfTemplate(
|
||||
tenantId,
|
||||
templateId
|
||||
);
|
||||
}
|
||||
|
||||
public async getPdfTemplate(tenantId: number, templateId: number) {
|
||||
return this.getPdfTemplateService.getPdfTemplate(tenantId, templateId);
|
||||
}
|
||||
|
||||
public async getPdfTemplates(
|
||||
tenantId: number,
|
||||
query?: { resource?: string }
|
||||
) {
|
||||
return this.getPdfTemplatesService.getPdfTemplates(tenantId, query);
|
||||
}
|
||||
}
|
||||
58
packages/server/src/services/PdfTemplate/types.ts
Normal file
58
packages/server/src/services/PdfTemplate/types.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
export interface ICreateInvoicePdfTemplateDTO {
|
||||
// Colors
|
||||
primaryColor?: string;
|
||||
secondaryColor?: string;
|
||||
|
||||
// Company Logo
|
||||
showCompanyLogo?: boolean;
|
||||
companyLogo?: string;
|
||||
|
||||
// Top details.
|
||||
showInvoiceNumber?: boolean;
|
||||
invoiceNumberLabel?: string;
|
||||
|
||||
showDateIssue?: boolean;
|
||||
dateIssueLabel?: string;
|
||||
|
||||
showDueDate?: boolean;
|
||||
dueDateLabel?: string;
|
||||
|
||||
// Company name
|
||||
companyName?: string;
|
||||
|
||||
// Addresses
|
||||
showBilledFromAddress?: boolean;
|
||||
showBillingToAddress?: boolean;
|
||||
billedToLabel?: string;
|
||||
|
||||
// Entries
|
||||
itemNameLabel?: string;
|
||||
itemDescriptionLabel?: string;
|
||||
itemRateLabel?: string;
|
||||
itemTotalLabel?: string;
|
||||
|
||||
// Totals
|
||||
showSubtotal?: boolean;
|
||||
subtotalLabel?: string;
|
||||
|
||||
showDiscount?: boolean;
|
||||
discountLabel?: string;
|
||||
|
||||
showTaxes?: boolean;
|
||||
|
||||
showTotal?: boolean;
|
||||
totalLabel?: string;
|
||||
|
||||
paymentMadeLabel?: string;
|
||||
showPaymentMade?: boolean;
|
||||
|
||||
dueAmountLabel?: string;
|
||||
showDueAmount?: boolean;
|
||||
|
||||
// Footer paragraphs.
|
||||
termsConditionsLabel?: string;
|
||||
showTermsConditions?: boolean;
|
||||
|
||||
statementLabel?: string;
|
||||
showStatement?: boolean;
|
||||
}
|
||||
Reference in New Issue
Block a user