mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-15 04:10:32 +00:00
feat(nestjs): migrate to NestJS
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { isNil } from 'lodash';
|
||||
import { PdfTemplateModel } from './models/PdfTemplate';
|
||||
import { TenantModelProxy } from '../System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class BrandingTemplateDTOTransformer {
|
||||
/**
|
||||
* @param {PdfTemplateModel} - Pdf template model.
|
||||
*/
|
||||
constructor(
|
||||
@Inject(PdfTemplateModel.name)
|
||||
private readonly pdfTemplate: TenantModelProxy<typeof PdfTemplateModel>,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Associates the default branding template id.
|
||||
* @param {string} resource - Resource name.
|
||||
* @param {Record<string, any>} object -
|
||||
* @param {string} attributeName
|
||||
* @returns
|
||||
*/
|
||||
public assocDefaultBrandingTemplate =
|
||||
(resource: string) => async (object: Record<string, any>) => {
|
||||
const attributeName = 'pdfTemplateId';
|
||||
|
||||
const defaultTemplate = await this.pdfTemplate()
|
||||
.query()
|
||||
.modify('default')
|
||||
.findOne({ resource });
|
||||
|
||||
// If the default template is not found OR the given object has no defined template id.
|
||||
if (!defaultTemplate || !isNil(object[attributeName])) {
|
||||
return object;
|
||||
}
|
||||
return {
|
||||
...object,
|
||||
[attributeName]: defaultTemplate.id,
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// import { Inject, Service } from 'typedi';
|
||||
// import { GetOrganizationBrandingAttributes } from './queries/GetOrganizationBrandingAttributes.service';
|
||||
|
||||
// @Service()
|
||||
// export class GetPdfTemplateBrandingState {
|
||||
// @Inject()
|
||||
// private getOrgBrandingAttributes: GetOrganizationBrandingAttributes;
|
||||
|
||||
// getBrandingState(tenantId: number) {
|
||||
// const brandingAttributes =
|
||||
// this.getOrgBrandingAttributes.getOrganizationBrandingAttributes(tenantId);
|
||||
|
||||
// return brandingAttributes;
|
||||
// }
|
||||
// }
|
||||
@@ -0,0 +1,96 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ICreateInvoicePdfTemplateDTO, IEditPdfTemplateDTO } from './types';
|
||||
import { CreatePdfTemplateService } from './commands/CreatePdfTemplate.service';
|
||||
import { DeletePdfTemplateService } from './commands/DeletePdfTemplate.service';
|
||||
import { GetPdfTemplateService } from './queries/GetPdfTemplate.service';
|
||||
import { EditPdfTemplateService } from './commands/EditPdfTemplate.service';
|
||||
import { AssignPdfTemplateDefaultService } from './commands/AssignPdfTemplateDefault.service';
|
||||
import { GetOrganizationBrandingAttributesService } from './queries/GetOrganizationBrandingAttributes.service';
|
||||
|
||||
@Injectable()
|
||||
export class PdfTemplateApplication {
|
||||
constructor(
|
||||
private readonly createPdfTemplateService: CreatePdfTemplateService,
|
||||
private readonly getPdfTemplateService: GetPdfTemplateService,
|
||||
private readonly deletePdfTemplateService: DeletePdfTemplateService,
|
||||
// private readonly getPdfTemplatesService: GetPdfTemplatesService,
|
||||
private readonly editPdfTemplateService: EditPdfTemplateService,
|
||||
private readonly assignPdfTemplateDefaultService: AssignPdfTemplateDefaultService,
|
||||
// private readonly getPdfTemplateBrandingStateService: GetPdfTemplateBrandingStateService,
|
||||
// private readonly getOrganizationBrandingAttributesService: GetOrganizationBrandingAttributesService,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Creates a new PDF template.
|
||||
* @param {string} templateName - The name of the PDF template to create.
|
||||
* @param {string} resource - The resource type associated with the PDF template.
|
||||
* @param {ICreateInvoicePdfTemplateDTO} invoiceTemplateDTO - The data transfer object containing the details for the new PDF template.
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
public async createPdfTemplate(
|
||||
templateName: string,
|
||||
resource: string,
|
||||
invoiceTemplateDTO: ICreateInvoicePdfTemplateDTO,
|
||||
) {
|
||||
return this.createPdfTemplateService.createPdfTemplate(
|
||||
templateName,
|
||||
resource,
|
||||
invoiceTemplateDTO,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a PDF template.
|
||||
* @param {number} templateId - The ID of the template to delete.
|
||||
*/
|
||||
public async deletePdfTemplate(templateId: number) {
|
||||
return this.deletePdfTemplateService.deletePdfTemplate(templateId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a specific PDF template.
|
||||
* @param {number} templateId - The ID of the template to retrieve.
|
||||
*/
|
||||
public async getPdfTemplate(templateId: number) {
|
||||
return this.getPdfTemplateService.getPdfTemplate(templateId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all PDF templates.
|
||||
* @param {string} resource - The resource type to filter templates.
|
||||
*/
|
||||
public async getPdfTemplates(resource: string) {
|
||||
// return this.getPdfTemplatesService.execute(resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits an existing PDF template.
|
||||
* @param {number} templateId - The ID of the template to edit.
|
||||
* @param {IEditPdfTemplateDTO} editDTO - The data transfer object containing the updates.
|
||||
*/
|
||||
public async editPdfTemplate(
|
||||
templateId: number,
|
||||
editDTO: IEditPdfTemplateDTO,
|
||||
) {
|
||||
return this.editPdfTemplateService.editPdfTemplate(templateId, editDTO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the PDF template branding state.
|
||||
* @param {number} tenantId - The tenant ID.
|
||||
*/
|
||||
public async getPdfTemplateBrandingState(tenantId: number) {
|
||||
// return this.getPdfTemplateBrandingStateService.execute(tenantId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns a PDF template as the default template.
|
||||
* @param {number} templateId - The ID of the PDF template to assign as default.
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
public async assignPdfTemplateAsDefault(templateId: number) {
|
||||
return this.assignPdfTemplateDefaultService.assignDefaultTemplate(
|
||||
templateId,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
|
||||
import {
|
||||
Body,
|
||||
Controller,
|
||||
Delete,
|
||||
Get,
|
||||
Param,
|
||||
Post,
|
||||
Put,
|
||||
} from '@nestjs/common';
|
||||
import { PdfTemplateApplication } from './PdfTemplate.application';
|
||||
import { ICreateInvoicePdfTemplateDTO, IEditPdfTemplateDTO } from './types';
|
||||
|
||||
@Controller('pdf-templates')
|
||||
@ApiTags('pdf-templates')
|
||||
export class PdfTemplatesController {
|
||||
constructor(
|
||||
private readonly pdfTemplateApplication: PdfTemplateApplication,
|
||||
) {}
|
||||
|
||||
@Post()
|
||||
@ApiOperation({ summary: 'Create a new PDF template.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'The PDF template has been successfully created.',
|
||||
})
|
||||
async createPdfTemplate(
|
||||
@Body('templateName') templateName: string,
|
||||
@Body('resource') resource: string,
|
||||
@Body() invoiceTemplateDTO: ICreateInvoicePdfTemplateDTO,
|
||||
) {
|
||||
return this.pdfTemplateApplication.createPdfTemplate(
|
||||
templateName,
|
||||
resource,
|
||||
invoiceTemplateDTO,
|
||||
);
|
||||
}
|
||||
|
||||
@Delete(':id')
|
||||
@ApiOperation({ summary: 'Delete the given PDF template.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'The PDF template has been successfully deleted.',
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'The PDF template not found.' })
|
||||
async deletePdfTemplate(@Param('id') templateId: number) {
|
||||
return this.pdfTemplateApplication.deletePdfTemplate(templateId);
|
||||
}
|
||||
|
||||
@Get(':id')
|
||||
@ApiOperation({ summary: 'Retrieves the PDF template details.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'The PDF template details have been successfully retrieved.',
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'The PDF template not found.' })
|
||||
async getPdfTemplate(@Param('id') templateId: number) {
|
||||
return this.pdfTemplateApplication.getPdfTemplate(templateId);
|
||||
}
|
||||
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'Retrieves the PDF templates.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'The PDF templates have been successfully retrieved.',
|
||||
})
|
||||
async getPdfTemplates(@Body('resource') resource: string) {
|
||||
return this.pdfTemplateApplication.getPdfTemplates(resource);
|
||||
}
|
||||
|
||||
@Put(':id')
|
||||
@ApiOperation({ summary: 'Edit the given PDF template.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'The PDF template has been successfully edited.',
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'The PDF template not found.' })
|
||||
async editPdfTemplate(
|
||||
@Param('id') templateId: number,
|
||||
@Body() editDTO: IEditPdfTemplateDTO,
|
||||
) {
|
||||
return this.pdfTemplateApplication.editPdfTemplate(templateId, editDTO);
|
||||
}
|
||||
|
||||
@Put(':id/assign-default')
|
||||
@ApiOperation({ summary: 'Assign the given PDF template as default.' })
|
||||
@ApiResponse({
|
||||
status: 200,
|
||||
description: 'The PDF template has been successfully assigned as default.',
|
||||
})
|
||||
@ApiResponse({ status: 404, description: 'The PDF template not found.' })
|
||||
async assignPdfTemplateAsDefault(@Param('id') templateId: number) {
|
||||
return this.pdfTemplateApplication.assignPdfTemplateAsDefault(templateId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TenancyContext } from '../Tenancy/TenancyContext.service';
|
||||
import { TenancyDatabaseModule } from '../Tenancy/TenancyDB/TenancyDB.module';
|
||||
import { TransformerInjectable } from '../Transformer/TransformerInjectable.service';
|
||||
import { AssignPdfTemplateDefaultService } from './commands/AssignPdfTemplateDefault.service';
|
||||
import { CreatePdfTemplateService } from './commands/CreatePdfTemplate.service';
|
||||
import { DeletePdfTemplateService } from './commands/DeletePdfTemplate.service';
|
||||
import { EditPdfTemplateService } from './commands/EditPdfTemplate.service';
|
||||
import { PdfTemplateApplication } from './PdfTemplate.application';
|
||||
import { PdfTemplatesController } from './PdfTemplates.controller';
|
||||
import { GetPdfTemplateService } from './queries/GetPdfTemplate.service';
|
||||
import { BrandingTemplateDTOTransformer } from './BrandingTemplateDTOTransformer';
|
||||
import { GetOrganizationBrandingAttributesService } from './queries/GetOrganizationBrandingAttributes.service';
|
||||
|
||||
@Module({
|
||||
exports: [
|
||||
GetPdfTemplateService,
|
||||
BrandingTemplateDTOTransformer,
|
||||
GetOrganizationBrandingAttributesService,
|
||||
],
|
||||
imports: [TenancyDatabaseModule],
|
||||
controllers: [PdfTemplatesController],
|
||||
providers: [
|
||||
PdfTemplateApplication,
|
||||
CreatePdfTemplateService,
|
||||
DeletePdfTemplateService,
|
||||
GetPdfTemplateService,
|
||||
EditPdfTemplateService,
|
||||
AssignPdfTemplateDefaultService,
|
||||
TenancyContext,
|
||||
TransformerInjectable,
|
||||
BrandingTemplateDTOTransformer,
|
||||
GetOrganizationBrandingAttributesService,
|
||||
],
|
||||
})
|
||||
export class PdfTemplatesModule {}
|
||||
@@ -0,0 +1,60 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Knex } from 'knex';
|
||||
import { UnitOfWork } from '../../Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { PdfTemplateModel } from '../models/PdfTemplate';
|
||||
import { events } from '@/common/events/events';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class AssignPdfTemplateDefaultService {
|
||||
constructor(
|
||||
private readonly uow: UnitOfWork,
|
||||
private readonly eventPublisher: EventEmitter2,
|
||||
|
||||
@Inject(PdfTemplateModel.name)
|
||||
private readonly pdfTemplateModel: TenantModelProxy<
|
||||
typeof PdfTemplateModel
|
||||
>,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Assigns a default PDF template.
|
||||
* @param {number} templateId - The ID of the template to be set as the default.
|
||||
* @returns {Promise<void>} A promise that resolves when the operation is complete.
|
||||
* @throws {Error} Throws an error if the specified template is not found.
|
||||
*/
|
||||
public async assignDefaultTemplate(templateId: number) {
|
||||
const oldPdfTemplate = await this.pdfTemplateModel()
|
||||
.query()
|
||||
.findById(templateId)
|
||||
.throwIfNotFound();
|
||||
|
||||
return this.uow.withTransaction(async (trx?: Knex.Transaction) => {
|
||||
// Triggers `onPdfTemplateAssigningDefault` event.
|
||||
await this.eventPublisher.emitAsync(
|
||||
events.pdfTemplate.onAssigningDefault,
|
||||
{
|
||||
templateId,
|
||||
},
|
||||
);
|
||||
await this.pdfTemplateModel()
|
||||
.query(trx)
|
||||
.where('resource', oldPdfTemplate.resource)
|
||||
.patch({ default: false });
|
||||
|
||||
await this.pdfTemplateModel()
|
||||
.query(trx)
|
||||
.findById(templateId)
|
||||
.patch({ default: true });
|
||||
|
||||
// Triggers `onPdfTemplateAssignedDefault` event.
|
||||
await this.eventPublisher.emitAsync(
|
||||
events.pdfTemplate.onAssignedDefault,
|
||||
{
|
||||
templateId,
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { events } from '@/common/events/events';
|
||||
import { ICreateInvoicePdfTemplateDTO } from '../types';
|
||||
import { UnitOfWork } from '../../Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { PdfTemplateModel } from '../models/PdfTemplate';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class CreatePdfTemplateService {
|
||||
constructor(
|
||||
private readonly uow: UnitOfWork,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
|
||||
@Inject(PdfTemplateModel.name)
|
||||
private readonly pdfTemplateModel: TenantModelProxy<
|
||||
typeof PdfTemplateModel
|
||||
>,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Creates a new pdf template.
|
||||
* @param {string} templateName - Pdf template name.
|
||||
* @param {string} resource - Pdf template resource.
|
||||
* @param {ICreateInvoicePdfTemplateDTO} invoiceTemplateDTO - Invoice template data.
|
||||
*/
|
||||
public createPdfTemplate(
|
||||
templateName: string,
|
||||
resource: string,
|
||||
invoiceTemplateDTO: ICreateInvoicePdfTemplateDTO,
|
||||
) {
|
||||
const attributes = invoiceTemplateDTO;
|
||||
|
||||
return this.uow.withTransaction(async (trx) => {
|
||||
// Triggers `onPdfTemplateCreating` event.
|
||||
await this.eventEmitter.emitAsync(events.pdfTemplate.onCreating, {});
|
||||
|
||||
const pdfTemplate = await this.pdfTemplateModel().query(trx).insert({
|
||||
templateName,
|
||||
resource,
|
||||
attributes,
|
||||
});
|
||||
|
||||
// Triggers `onPdfTemplateCreated` event.
|
||||
await this.eventEmitter.emitAsync(events.pdfTemplate.onCreated, {});
|
||||
|
||||
return pdfTemplate;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { ERRORS } from '../types';
|
||||
import { UnitOfWork } from '../../Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { events } from '@/common/events/events';
|
||||
import { ServiceError } from '../../Items/ServiceError';
|
||||
import { PdfTemplateModel } from '../models/PdfTemplate';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class DeletePdfTemplateService {
|
||||
constructor(
|
||||
@Inject(PdfTemplateModel.name)
|
||||
private readonly pdfTemplateModel: TenantModelProxy<
|
||||
typeof PdfTemplateModel
|
||||
>,
|
||||
private readonly uow: UnitOfWork,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Deletes a pdf template.
|
||||
* @param {number} templateId - Pdf template id.
|
||||
*/
|
||||
public async deletePdfTemplate(templateId: number) {
|
||||
const oldPdfTemplate = await this.pdfTemplateModel()
|
||||
.query()
|
||||
.findById(templateId)
|
||||
.throwIfNotFound();
|
||||
|
||||
// Cannot delete the predefined pdf templates.
|
||||
if (oldPdfTemplate.predefined) {
|
||||
throw new ServiceError(ERRORS.CANNOT_DELETE_PREDEFINED_PDF_TEMPLATE);
|
||||
}
|
||||
|
||||
return this.uow.withTransaction(async (trx) => {
|
||||
// Triggers `onPdfTemplateDeleting` event.
|
||||
await this.eventEmitter.emitAsync(events.pdfTemplate.onDeleting, {
|
||||
templateId,
|
||||
oldPdfTemplate,
|
||||
trx,
|
||||
});
|
||||
await this.pdfTemplateModel().query(trx).deleteById(templateId);
|
||||
|
||||
// Triggers `onPdfTemplateDeleted` event.
|
||||
await this.eventEmitter.emitAsync(events.pdfTemplate.onDeleted, {
|
||||
templateId,
|
||||
oldPdfTemplate,
|
||||
trx,
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Knex } from 'knex';
|
||||
import { IEditPdfTemplateDTO } from '../types';
|
||||
import { PdfTemplateModel } from '../models/PdfTemplate';
|
||||
import { UnitOfWork } from '../../Tenancy/TenancyDB/UnitOfWork.service';
|
||||
import { EventEmitter2 } from '@nestjs/event-emitter';
|
||||
import { events } from '@/common/events/events';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class EditPdfTemplateService {
|
||||
constructor(
|
||||
@Inject(PdfTemplateModel.name)
|
||||
private readonly pdfTemplateModel: TenantModelProxy<
|
||||
typeof PdfTemplateModel
|
||||
>,
|
||||
private readonly uow: UnitOfWork,
|
||||
private readonly eventEmitter: EventEmitter2,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Edits an existing pdf template.
|
||||
* @param {number} templateId - Template id.
|
||||
* @param {IEditPdfTemplateDTO} editTemplateDTO
|
||||
*/
|
||||
public async editPdfTemplate(
|
||||
templateId: number,
|
||||
editTemplateDTO: IEditPdfTemplateDTO,
|
||||
) {
|
||||
const oldPdfTemplate = await this.pdfTemplateModel()
|
||||
.query()
|
||||
.findById(templateId)
|
||||
.throwIfNotFound();
|
||||
|
||||
return this.uow.withTransaction(async (trx: Knex.Transaction) => {
|
||||
// Triggers `onPdfTemplateEditing` event.
|
||||
await this.eventEmitter.emitAsync(events.pdfTemplate.onEditing, {
|
||||
templateId,
|
||||
});
|
||||
|
||||
const pdfTemplate = await this.pdfTemplateModel()
|
||||
.query(trx)
|
||||
.where('id', templateId)
|
||||
.update({
|
||||
templateName: editTemplateDTO.templateName,
|
||||
attributes: editTemplateDTO.attributes,
|
||||
});
|
||||
|
||||
// Triggers `onPdfTemplatedEdited` event.
|
||||
await this.eventEmitter.emitAsync(events.pdfTemplate.onEdited, {
|
||||
templateId,
|
||||
});
|
||||
return pdfTemplate;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { IsObject, IsString } from 'class-validator';
|
||||
import { IsNotEmpty } from 'class-validator';
|
||||
|
||||
export class CreatePdfTemplateDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
templateName: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
resource: string;
|
||||
|
||||
@IsObject()
|
||||
@IsNotEmpty()
|
||||
attributes: Record<string, any>;
|
||||
}
|
||||
|
||||
export class EditPdfTemplateDto {
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
templateName: string;
|
||||
|
||||
@IsString()
|
||||
@IsNotEmpty()
|
||||
resource: string;
|
||||
|
||||
@IsObject()
|
||||
@IsNotEmpty()
|
||||
attributes: Record<string, any>;
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
export class PdfTemplateModel extends TenantBaseModel {
|
||||
public resource!: string;
|
||||
public templateName!: string;
|
||||
public predefined!: boolean;
|
||||
public default!: boolean;
|
||||
public attributes!: Record<string, any>;
|
||||
|
||||
/**
|
||||
* Table name.
|
||||
*/
|
||||
static get tableName() {
|
||||
return 'pdf_templates';
|
||||
}
|
||||
|
||||
/**
|
||||
* Timestamps columns.
|
||||
*/
|
||||
get timestamps() {
|
||||
return ['createdAt', 'updatedAt'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Json schema.
|
||||
*/
|
||||
static get jsonSchema() {
|
||||
return {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: { type: 'integer' },
|
||||
templateName: { type: 'string' },
|
||||
attributes: { type: 'object' }, // JSON field definition
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Model modifiers.
|
||||
*/
|
||||
static get modifiers() {
|
||||
return {
|
||||
/**
|
||||
* Filters the due invoices.
|
||||
*/
|
||||
default(query) {
|
||||
query.where('default', true);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Virtual attributes.
|
||||
*/
|
||||
static get virtualAttributes() {
|
||||
return ['companyLogoUri'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the company logo uri.
|
||||
* @returns {string}
|
||||
*/
|
||||
// get companyLogoUri() {
|
||||
// return this.attributes?.companyLogoKey
|
||||
// ? getUploadedObjectUri(this.attributes.companyLogoKey)
|
||||
// : '';
|
||||
// }
|
||||
|
||||
/**
|
||||
* Relationship mapping.
|
||||
*/
|
||||
static get relationMappings() {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { CommonOrganizationBrandingAttributes } from '../types';
|
||||
import { TenancyContext } from '../../Tenancy/TenancyContext.service';
|
||||
|
||||
@Injectable()
|
||||
export class GetOrganizationBrandingAttributesService {
|
||||
constructor(private readonly tenancyContext: TenancyContext) {}
|
||||
|
||||
/**
|
||||
* Retrieves the given organization branding attributes initial state.
|
||||
* @returns {Promise<CommonOrganizationBrandingAttributes>}
|
||||
*/
|
||||
public async getOrganizationBrandingAttributes(): Promise<CommonOrganizationBrandingAttributes> {
|
||||
const tenant = await this.tenancyContext.getTenant(true);
|
||||
const tenantMetadata = tenant.metadata;
|
||||
|
||||
const companyName = tenantMetadata?.name;
|
||||
const primaryColor = tenantMetadata?.primaryColor;
|
||||
const companyLogoKey = tenantMetadata?.logoKey;
|
||||
const companyLogoUri = tenantMetadata?.logoUri;
|
||||
const companyAddress = tenantMetadata?.addressTextFormatted;
|
||||
|
||||
return {
|
||||
companyName,
|
||||
companyAddress,
|
||||
companyLogoUri,
|
||||
companyLogoKey,
|
||||
primaryColor,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { Knex } from 'knex';
|
||||
import { GetPdfTemplateTransformer } from './GetPdfTemplate.transformer';
|
||||
import { PdfTemplateModel } from '../models/PdfTemplate';
|
||||
import { TransformerInjectable } from '../../Transformer/TransformerInjectable.service';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class GetPdfTemplateService {
|
||||
constructor(
|
||||
@Inject(PdfTemplateModel.name)
|
||||
private readonly pdfTemplateModel: TenantModelProxy<
|
||||
typeof PdfTemplateModel
|
||||
>,
|
||||
private readonly transformer: TransformerInjectable,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Retrieves a pdf template by its ID.
|
||||
* @param {number} templateId - The ID of the pdf template to retrieve.
|
||||
* @return {Promise<any>} - The retrieved pdf template.
|
||||
*/
|
||||
async getPdfTemplate(
|
||||
templateId: number,
|
||||
trx?: Knex.Transaction,
|
||||
): Promise<any> {
|
||||
const template = await this.pdfTemplateModel()
|
||||
.query(trx)
|
||||
.findById(templateId)
|
||||
.throwIfNotFound();
|
||||
|
||||
return this.transformer.transform(
|
||||
template,
|
||||
new GetPdfTemplateTransformer(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// import { getTransactionTypeLabel } from '@/utils/transactions-types';
|
||||
import { Transformer } from "../../Transformer/Transformer";
|
||||
|
||||
export class GetPdfTemplateTransformer extends Transformer {
|
||||
/**
|
||||
* Included attributes.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public includeAttributes = (): string[] => {
|
||||
return ['createdAtFormatted', 'resourceFormatted', 'attributes'];
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats the creation date of the PDF template.
|
||||
* @param {Object} template
|
||||
* @returns {string} A formatted string representing the creation date of the template.
|
||||
*/
|
||||
protected createdAtFormatted = (template) => {
|
||||
return this.formatDate(template.createdAt);
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats the creation date of the PDF template.
|
||||
* @param {Object} template -
|
||||
* @returns {string} A formatted string representing the creation date of the template.
|
||||
*/
|
||||
protected resourceFormatted = (template) => {
|
||||
// return getTransactionTypeLabel(template.resource);
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieves transformed brand attributes.
|
||||
* @param {} template
|
||||
* @returns
|
||||
*/
|
||||
protected attributes = (template) => {
|
||||
return this.item(
|
||||
template.attributes,
|
||||
new GetPdfTemplateAttributesTransformer()
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
class GetPdfTemplateAttributesTransformer extends Transformer {
|
||||
/**
|
||||
* Included attributes.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public includeAttributes = (): string[] => {
|
||||
return [];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { GetPdfTemplatesTransformer } from './GetPdfTemplates.transformer';
|
||||
import { PdfTemplateModel } from '../models/PdfTemplate';
|
||||
import { TransformerInjectable } from '../../Transformer/TransformerInjectable.service';
|
||||
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
|
||||
|
||||
@Injectable()
|
||||
export class GetPdfTemplates {
|
||||
constructor(
|
||||
private readonly transformInjectable: TransformerInjectable,
|
||||
|
||||
@Inject(PdfTemplateModel.name)
|
||||
private readonly pdfTemplateModel: TenantModelProxy<
|
||||
typeof PdfTemplateModel
|
||||
>,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Retrieves a list of PDF templates for a specified tenant.
|
||||
* @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(query?: { resource?: string }) {
|
||||
const templates = await this.pdfTemplateModel()
|
||||
.query()
|
||||
.onBuild((q) => {
|
||||
if (query?.resource) {
|
||||
q.where('resource', query?.resource);
|
||||
}
|
||||
q.orderBy('createdAt', 'ASC');
|
||||
});
|
||||
|
||||
return this.transformInjectable.transform(
|
||||
templates,
|
||||
new GetPdfTemplatesTransformer(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// import { getTransactionTypeLabel } from '@/utils/transactions-types';
|
||||
import { Transformer } from "../../Transformer/Transformer";
|
||||
|
||||
export class GetPdfTemplatesTransformer extends Transformer {
|
||||
/**
|
||||
* Exclude attributes.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public excludeAttributes = (): string[] => {
|
||||
return ['attributes'];
|
||||
};
|
||||
|
||||
/**
|
||||
* Includeded attributes.
|
||||
* @returns {string[]}
|
||||
*/
|
||||
public includeAttributes = (): string[] => {
|
||||
return ['createdAtFormatted', 'resourceFormatted'];
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats the creation date of the PDF template.
|
||||
* @param {Object} template
|
||||
* @returns {string} A formatted string representing the creation date of the template.
|
||||
*/
|
||||
protected createdAtFormatted = (template) => {
|
||||
return this.formatDate(template.createdAt);
|
||||
};
|
||||
|
||||
/**
|
||||
* Formats the creation date of the PDF template.
|
||||
* @param {Object} template -
|
||||
* @returns {string} A formatted string representing the creation date of the template.
|
||||
*/
|
||||
protected resourceFormatted = (template) => {
|
||||
// return getTransactionTypeLabel(template.resource);
|
||||
};
|
||||
}
|
||||
75
packages/server/src/modules/PdfTemplate/types.ts
Normal file
75
packages/server/src/modules/PdfTemplate/types.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
export enum ERRORS {
|
||||
CANNOT_DELETE_PREDEFINED_PDF_TEMPLATE = 'CANNOT_DELETE_PREDEFINED_PDF_TEMPLATE',
|
||||
}
|
||||
|
||||
export interface IEditPdfTemplateDTO {
|
||||
templateName: string;
|
||||
attributes: Record<string, any>;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
export interface CommonOrganizationBrandingAttributes {
|
||||
companyName?: string;
|
||||
primaryColor?: string;
|
||||
companyLogoKey?: string;
|
||||
companyLogoUri?: string;
|
||||
companyAddress?: string;
|
||||
}
|
||||
Reference in New Issue
Block a user