From 4f6ad2b29316c5263dc154178eb3b36cb099aa5f Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Sun, 4 May 2025 01:32:08 +0200 Subject: [PATCH] feat: apply credit note to invoice module --- packages/server/src/modules/App/App.module.ts | 2 + .../modules/Attachments/UnlinkAttachment.ts | 2 +- .../CreditNoteRefunds.module.ts | 7 +- .../commands/RefundCreditNoteGLEntries.ts | 284 +++++++------- .../models/RefundCreditNote.ts | 9 +- .../modules/CreditNotes/CreditNotes.module.ts | 16 +- .../CreditNoteBrandingTemplate.service.ts | 2 +- .../CreditNoteAutoSerialSubscriber.ts | 47 +-- .../DeleteCustomerLinkedCreditSubscriber.ts | 76 ++-- .../RefundCreditNoteGLEntriesSubscriber.ts | 102 +++-- .../RefundSyncCreditNoteBalanceSubscriber.ts | 103 +++-- .../CreditNotesApplyInvoice.module.ts | 27 ++ ...DeleteCreditNoteApplyToInvoices.service.ts | 2 +- .../CreditNoteApplySyncCreditSubscriber.ts | 111 +++--- .../CreditNoteApplySyncInvoicesSubscriber.ts | 102 +++-- .../types/CreditNoteApplyInvoice.types.ts | 5 +- .../EventsTracker/EventTracker.interfaces.ts | 3 + .../EventsTracker/EventTracker.module.ts | 3 +- .../events/ReportsEventsTracker.ts | 369 +++++++----------- .../PaymentsReceived.module.ts | 1 + ...PaymentReceivedBrandingTemplate.service.ts | 11 +- .../PdfTemplate/PdfTemplate.application.ts | 25 +- .../PdfTemplate/PdfTemplates.controller.ts | 2 +- .../PdfTemplate/PdfTemplates.module.ts | 4 + ...tOrganizationBrandingAttributes.service.ts | 2 +- .../GetPdfTemplateBrandingState.service.ts | 16 + .../SaleEstimatePdfTemplate.service.ts | 4 +- .../queries/SaleInvoicePdfTemplate.service.ts | 3 +- 28 files changed, 633 insertions(+), 707 deletions(-) create mode 100644 packages/server/src/modules/CreditNotesApplyInvoice/CreditNotesApplyInvoice.module.ts create mode 100644 packages/server/src/modules/EventsTracker/EventTracker.interfaces.ts create mode 100644 packages/server/src/modules/PdfTemplate/queries/GetPdfTemplateBrandingState.service.ts diff --git a/packages/server/src/modules/App/App.module.ts b/packages/server/src/modules/App/App.module.ts index 5ffc2ed98..c84084e81 100644 --- a/packages/server/src/modules/App/App.module.ts +++ b/packages/server/src/modules/App/App.module.ts @@ -82,6 +82,7 @@ import { AttachmentsModule } from '../Attachments/Attachment.module'; import { S3Module } from '../S3/S3.module'; import { ExportModule } from '../Export/Export.module'; import { ImportModule } from '../Import/Import.module'; +import { CreditNotesApplyInvoiceModule } from '../CreditNotesApplyInvoice/CreditNotesApplyInvoice.module'; @Module({ imports: [ @@ -169,6 +170,7 @@ import { ImportModule } from '../Import/Import.module'; VendorCreditApplyBillsModule, VendorCreditsRefundModule, CreditNoteRefundsModule, + CreditNotesApplyInvoiceModule, BillPaymentsModule, PaymentsReceivedModule, LedgerModule, diff --git a/packages/server/src/modules/Attachments/UnlinkAttachment.ts b/packages/server/src/modules/Attachments/UnlinkAttachment.ts index a345a998c..c52aa9a26 100644 --- a/packages/server/src/modules/Attachments/UnlinkAttachment.ts +++ b/packages/server/src/modules/Attachments/UnlinkAttachment.ts @@ -1,4 +1,4 @@ -import bluebird from 'bluebird'; +import * as bluebird from 'bluebird'; import { difference } from 'lodash'; import { validateLinkModelEntryExists, diff --git a/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts b/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts index eb96ec5dd..f09a95b65 100644 --- a/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts +++ b/packages/server/src/modules/CreditNoteRefunds/CreditNoteRefunds.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { forwardRef, Module } from '@nestjs/common'; import { CreateRefundCreditNoteService } from './commands/CreateRefundCreditNote.service'; import { DeleteRefundCreditNoteService } from './commands/DeleteRefundCreditNote.service'; import { RefundCreditNoteService } from './commands/RefundCreditNote.service'; @@ -8,7 +8,7 @@ import { CreditNoteRefundsController } from './CreditNoteRefunds.controller'; import { CreditNotesModule } from '../CreditNotes/CreditNotes.module'; @Module({ - imports: [CreditNotesModule], + imports: [forwardRef(() => CreditNotesModule)], providers: [ CreateRefundCreditNoteService, DeleteRefundCreditNoteService, @@ -16,6 +16,9 @@ import { CreditNotesModule } from '../CreditNotes/CreditNotes.module'; RefundSyncCreditNoteBalanceService, CreditNotesRefundsApplication, ], + exports: [ + RefundSyncCreditNoteBalanceService + ], controllers: [CreditNoteRefundsController], }) export class CreditNoteRefundsModule {} diff --git a/packages/server/src/modules/CreditNoteRefunds/commands/RefundCreditNoteGLEntries.ts b/packages/server/src/modules/CreditNoteRefunds/commands/RefundCreditNoteGLEntries.ts index da014b885..4027ac221 100644 --- a/packages/server/src/modules/CreditNoteRefunds/commands/RefundCreditNoteGLEntries.ts +++ b/packages/server/src/modules/CreditNoteRefunds/commands/RefundCreditNoteGLEntries.ts @@ -1,160 +1,162 @@ -// import { Inject, Service } from 'typedi'; -// import { Knex } from 'knex'; -// import { AccountNormal, ILedgerEntry, IRefundCreditNote } from '@/interfaces'; -// import HasTenancyService from '@/services/Tenancy/TenancyService'; -// import LedgerStorageService from '@/services/Accounting/LedgerStorageService'; -// import Ledger from '@/services/Accounting/Ledger'; +import { LedgerStorageService } from '@/modules/Ledger/LedgerStorage.service'; +import { Inject, Injectable } from '@nestjs/common'; +import { RefundCreditNote } from '../models/RefundCreditNote'; +import { Ledger } from '@/modules/Ledger/Ledger'; +import { Knex } from 'knex'; +import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; +import { Account } from '@/modules/Accounts/models/Account.model'; +import { ILedgerEntry } from '@/modules/Ledger/types/Ledger.types'; +import { AccountNormal } from '@/interfaces/Account'; -// @Service() -// export default class RefundCreditNoteGLEntries { -// @Inject() -// ledgerStorage: LedgerStorageService; +@Injectable() +export class RefundCreditNoteGLEntries { + constructor( + private readonly ledgerStorage: LedgerStorageService, -// @Inject() -// tenancy: HasTenancyService; + @Inject(Account.name) + private readonly accountModel: TenantModelProxy, -// /** -// * Retrieves the refund credit common GL entry. -// * @param {IRefundCreditNote} refundCreditNote -// * @returns -// */ -// private getRefundCreditCommonGLEntry = ( -// refundCreditNote: IRefundCreditNote -// ) => { -// return { -// currencyCode: refundCreditNote.currencyCode, -// exchangeRate: refundCreditNote.exchangeRate, + @Inject(RefundCreditNote.name) + private readonly refundCreditNoteModel: TenantModelProxy< + typeof RefundCreditNote + >, + ) {} -// transactionType: 'RefundCreditNote', -// transactionId: refundCreditNote.id, -// date: refundCreditNote.date, -// userId: refundCreditNote.userId, + /** + * Retrieves the refund credit common GL entry. + * @param {IRefundCreditNote} refundCreditNote + * @returns + */ + private getRefundCreditCommonGLEntry = ( + refundCreditNote: RefundCreditNote, + ) => { + return { + currencyCode: refundCreditNote.currencyCode, + exchangeRate: refundCreditNote.exchangeRate, -// referenceNumber: refundCreditNote.referenceNo, + transactionType: 'RefundCreditNote', + transactionId: refundCreditNote.id, + date: refundCreditNote.date, + userId: refundCreditNote.userId, -// createdAt: refundCreditNote.createdAt, -// indexGroup: 10, + referenceNumber: refundCreditNote.referenceNo, -// credit: 0, -// debit: 0, + createdAt: refundCreditNote.createdAt, + indexGroup: 10, -// note: refundCreditNote.description, -// branchId: refundCreditNote.branchId, -// }; -// }; + credit: 0, + debit: 0, -// /** -// * Retrieves the refudn credit receivable GL entry. -// * @param {IRefundCreditNote} refundCreditNote -// * @param {number} ARAccountId -// * @returns {ILedgerEntry} -// */ -// private getRefundCreditGLReceivableEntry = ( -// refundCreditNote: IRefundCreditNote, -// ARAccountId: number -// ): ILedgerEntry => { -// const commonEntry = this.getRefundCreditCommonGLEntry(refundCreditNote); + note: refundCreditNote.description, + branchId: refundCreditNote.branchId, + }; + }; -// return { -// ...commonEntry, -// debit: refundCreditNote.amount, -// accountId: ARAccountId, -// contactId: refundCreditNote.creditNote.customerId, -// index: 1, -// accountNormal: AccountNormal.DEBIT, -// }; -// }; + /** + * Retrieves the refudn credit receivable GL entry. + * @param {IRefundCreditNote} refundCreditNote + * @param {number} ARAccountId + * @returns {ILedgerEntry} + */ + private getRefundCreditGLReceivableEntry = ( + refundCreditNote: RefundCreditNote, + ARAccountId: number, + ): ILedgerEntry => { + const commonEntry = this.getRefundCreditCommonGLEntry(refundCreditNote); -// /** -// * Retrieves the refund credit withdrawal GL entry. -// * @param {number} refundCreditNote -// * @returns {ILedgerEntry} -// */ -// private getRefundCreditGLWithdrawalEntry = ( -// refundCreditNote: IRefundCreditNote -// ): ILedgerEntry => { -// const commonEntry = this.getRefundCreditCommonGLEntry(refundCreditNote); + return { + ...commonEntry, + debit: refundCreditNote.amount, + accountId: ARAccountId, + contactId: refundCreditNote.creditNote.customerId, + index: 1, + accountNormal: AccountNormal.DEBIT, + }; + }; -// return { -// ...commonEntry, -// credit: refundCreditNote.amount, -// accountId: refundCreditNote.fromAccountId, -// index: 2, -// accountNormal: AccountNormal.DEBIT, -// }; -// }; + /** + * Retrieves the refund credit withdrawal GL entry. + * @param {number} refundCreditNote + * @returns {ILedgerEntry} + */ + private getRefundCreditGLWithdrawalEntry = ( + refundCreditNote: RefundCreditNote, + ): ILedgerEntry => { + const commonEntry = this.getRefundCreditCommonGLEntry(refundCreditNote); -// /** -// * Retrieve the refund credit note GL entries. -// * @param {IRefundCreditNote} refundCreditNote -// * @param {number} receivableAccount -// * @returns {ILedgerEntry[]} -// */ -// public getRefundCreditGLEntries( -// refundCreditNote: IRefundCreditNote, -// ARAccountId: number -// ): ILedgerEntry[] { -// const receivableEntry = this.getRefundCreditGLReceivableEntry( -// refundCreditNote, -// ARAccountId -// ); -// const withdrawalEntry = -// this.getRefundCreditGLWithdrawalEntry(refundCreditNote); + return { + ...commonEntry, + credit: refundCreditNote.amount, + accountId: refundCreditNote.fromAccountId, + index: 2, + accountNormal: AccountNormal.DEBIT, + }; + }; -// return [receivableEntry, withdrawalEntry]; -// } + /** + * Retrieve the refund credit note GL entries. + * @param {IRefundCreditNote} refundCreditNote + * @param {number} receivableAccount + * @returns {ILedgerEntry[]} + */ + public getRefundCreditGLEntries( + refundCreditNote: RefundCreditNote, + ARAccountId: number, + ): ILedgerEntry[] { + const receivableEntry = this.getRefundCreditGLReceivableEntry( + refundCreditNote, + ARAccountId, + ); + const withdrawalEntry = + this.getRefundCreditGLWithdrawalEntry(refundCreditNote); -// /** -// * Creates refund credit GL entries. -// * @param {number} tenantId -// * @param {IRefundCreditNote} refundCreditNote -// * @param {Knex.Transaction} trx -// */ -// public createRefundCreditGLEntries = async ( -// tenantId: number, -// refundCreditNoteId: number, -// trx?: Knex.Transaction -// ) => { -// const { Account, RefundCreditNote } = this.tenancy.models(tenantId); + return [receivableEntry, withdrawalEntry]; + } -// // Retrieve the refund with associated credit note. -// const refundCreditNote = await RefundCreditNote.query(trx) -// .findById(refundCreditNoteId) -// .withGraphFetched('creditNote'); + /** + * Creates refund credit GL entries. + * @param {IRefundCreditNote} refundCreditNote + * @param {Knex.Transaction} trx + */ + public createRefundCreditGLEntries = async ( + refundCreditNoteId: number, + trx?: Knex.Transaction, + ) => { + // Retrieve the refund with associated credit note. + const refundCreditNote = await this.refundCreditNoteModel().query(trx) + .findById(refundCreditNoteId) + .withGraphFetched('creditNote'); -// // Receivable account A/R. -// const receivableAccount = await Account.query().findOne( -// 'slug', -// 'accounts-receivable' -// ); -// // Retrieve refund credit GL entries. -// const refundGLEntries = this.getRefundCreditGLEntries( -// refundCreditNote, -// receivableAccount.id -// ); -// const ledger = new Ledger(refundGLEntries); + // Receivable account A/R. + const receivableAccount = await this.accountModel().query().findOne( + 'slug', + 'accounts-receivable', + ); + // Retrieve refund credit GL entries. + const refundGLEntries = this.getRefundCreditGLEntries( + refundCreditNote, + receivableAccount.id, + ); + const ledger = new Ledger(refundGLEntries); -// // Saves refund ledger entries. -// await this.ledgerStorage.commit(tenantId, ledger, trx); -// }; + // Saves refund ledger entries. + await this.ledgerStorage.commit(ledger, trx); + }; -// /** -// * Reverts refund credit note GL entries. -// * @param {number} tenantId -// * @param {number} refundCreditNoteId -// * @param {number} receivableAccount -// * @param {Knex.Transaction} trx -// */ -// public revertRefundCreditGLEntries = async ( -// tenantId: number, -// refundCreditNoteId: number, -// trx?: Knex.Transaction -// ) => { -// await this.ledgerStorage.deleteByReference( -// tenantId, -// refundCreditNoteId, -// 'RefundCreditNote', -// trx -// ); -// }; -// } + /** + * Reverts refund credit note GL entries. + * @param {number} refundCreditNoteId + * @param {number} receivableAccount + * @param {Knex.Transaction} trx + */ + public revertRefundCreditGLEntries = async ( + refundCreditNoteId: number, + trx?: Knex.Transaction, + ) => { + await this.ledgerStorage.deleteByReference( + refundCreditNoteId, + 'RefundCreditNote', + trx, + ); + }; +} diff --git a/packages/server/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts b/packages/server/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts index 0d975d74d..3155d3683 100644 --- a/packages/server/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts +++ b/packages/server/src/modules/CreditNoteRefunds/models/RefundCreditNote.ts @@ -4,8 +4,9 @@ import { Model, mixin } from 'objection'; // import CustomViewBaseModel from './CustomViewBaseModel'; // import ModelSearchable from './ModelSearchable'; import { BaseModel } from '@/models/Model'; +import { CreditNote } from '@/modules/CreditNotes/models/CreditNote'; -export class RefundCreditNote extends BaseModel{ +export class RefundCreditNote extends BaseModel { date: Date; referenceNo: string; amount: number; @@ -14,12 +15,14 @@ export class RefundCreditNote extends BaseModel{ fromAccountId: number; description: string; creditNoteId: number; - + userId?: number; branchId?: number; - + createdAt?: Date | null; + creditNote!: CreditNote; + /** * Table name. */ diff --git a/packages/server/src/modules/CreditNotes/CreditNotes.module.ts b/packages/server/src/modules/CreditNotes/CreditNotes.module.ts index 6f6241adb..d5dfabaa9 100644 --- a/packages/server/src/modules/CreditNotes/CreditNotes.module.ts +++ b/packages/server/src/modules/CreditNotes/CreditNotes.module.ts @@ -1,4 +1,4 @@ -import { Module } from '@nestjs/common'; +import { forwardRef, Module } from '@nestjs/common'; import { CreateCreditNoteService } from './commands/CreateCreditNote.service'; import { CommandCreditNoteDTOTransform } from './commands/CommandCreditNoteDTOTransform.service'; import { EditCreditNoteService } from './commands/EditCreditNote.service'; @@ -26,6 +26,13 @@ import { GetCreditNotesService } from './queries/GetCreditNotes.service'; import { DynamicListModule } from '../DynamicListing/DynamicList.module'; import { CreditNotesExportable } from './commands/CreditNotesExportable'; import { CreditNotesImportable } from './commands/CreditNotesImportable'; +import { CreditNoteInventoryTransactionsSubscriber } from './subscribers/CreditNoteInventoryTransactionsSubscriber'; +import { RefundSyncCreditNoteBalanceSubscriber } from './subscribers/RefundSyncCreditNoteBalanceSubscriber'; +import { DeleteCustomerLinkedCreditSubscriber } from './subscribers/DeleteCustomerLinkedCreditSubscriber'; +import { CreditNoteInventoryTransactions } from './commands/CreditNotesInventoryTransactions'; +import { InventoryCostModule } from '../InventoryCost/InventoryCost.module'; +import { CreditNoteRefundsModule } from '../CreditNoteRefunds/CreditNoteRefunds.module'; +import { CreditNotesApplyInvoiceModule } from '../CreditNotesApplyInvoice/CreditNotesApplyInvoice.module'; @Module({ imports: [ @@ -39,6 +46,9 @@ import { CreditNotesImportable } from './commands/CreditNotesImportable'; LedgerModule, AccountsModule, DynamicListModule, + InventoryCostModule, + forwardRef(() => CreditNoteRefundsModule), + forwardRef(() => CreditNotesApplyInvoiceModule) ], providers: [ CreateCreditNoteService, @@ -57,6 +67,10 @@ import { CreditNotesImportable } from './commands/CreditNotesImportable'; CreditNoteGLEntriesSubscriber, CreditNotesExportable, CreditNotesImportable, + CreditNoteInventoryTransactions, + CreditNoteInventoryTransactionsSubscriber, + RefundSyncCreditNoteBalanceSubscriber, + DeleteCustomerLinkedCreditSubscriber, ], exports: [ CreateCreditNoteService, diff --git a/packages/server/src/modules/CreditNotes/queries/CreditNoteBrandingTemplate.service.ts b/packages/server/src/modules/CreditNotes/queries/CreditNoteBrandingTemplate.service.ts index 5d785d75c..ffb968296 100644 --- a/packages/server/src/modules/CreditNotes/queries/CreditNoteBrandingTemplate.service.ts +++ b/packages/server/src/modules/CreditNotes/queries/CreditNoteBrandingTemplate.service.ts @@ -22,7 +22,7 @@ export class CreditNoteBrandingTemplate { // Retrieves the organization branding attributes. const commonOrgBrandingAttrs = - await this.getOrgBrandingAttributes.getOrganizationBrandingAttributes(); + await this.getOrgBrandingAttributes.execute(); // Merges the default branding attributes with common organization branding attrs. const organizationBrandingAttrs = { diff --git a/packages/server/src/modules/CreditNotes/subscribers/CreditNoteAutoSerialSubscriber.ts b/packages/server/src/modules/CreditNotes/subscribers/CreditNoteAutoSerialSubscriber.ts index 0984b969b..25764ff07 100644 --- a/packages/server/src/modules/CreditNotes/subscribers/CreditNoteAutoSerialSubscriber.ts +++ b/packages/server/src/modules/CreditNotes/subscribers/CreditNoteAutoSerialSubscriber.ts @@ -1,30 +1,21 @@ -// import { Service, Inject } from 'typedi'; -// import events from '@/subscribers/events'; -// import BaseCreditNotes from '../commands/CommandCreditNoteDTOTransform.service'; -// import { ICreditNoteCreatedPayload } from '@/interfaces'; +import { Injectable } from '@nestjs/common'; +import { OnEvent } from '@nestjs/event-emitter'; +import { CreditNoteAutoIncrementService } from '../commands/CreditNoteAutoIncrement.service'; +import { ICreditNoteCreatedPayload } from '../types/CreditNotes.types'; +import { events } from '@/common/events/events'; -// @Service() -// export default class CreditNoteAutoSerialSubscriber { -// @Inject() -// creditNotesService: BaseCreditNotes; +@Injectable() +export default class CreditNoteAutoSerialSubscriber { + constructor( + private readonly creditNoteIncrementService: CreditNoteAutoIncrementService, + ) {} -// /** -// * Attaches events with handlers. -// */ -// public attach(bus) { -// bus.subscribe( -// events.creditNote.onCreated, -// this.autoSerialIncrementOnceCreated -// ); -// } - -// /** -// * Auto serial increment once credit note created. -// * @param {ICreditNoteCreatedPayload} payload - -// */ -// private autoSerialIncrementOnceCreated = async ({ -// tenantId, -// }: ICreditNoteCreatedPayload) => { -// await this.creditNotesService.incrementSerialNumber(tenantId); -// }; -// } + /** + * Auto serial increment once credit note created. + * @param {ICreditNoteCreatedPayload} payload - + */ + @OnEvent(events.creditNote.onCreated) + async autoSerialIncrementOnceCreated({}: ICreditNoteCreatedPayload) { + await this.creditNoteIncrementService.incrementSerialNumber(); + } +} diff --git a/packages/server/src/modules/CreditNotes/subscribers/DeleteCustomerLinkedCreditSubscriber.ts b/packages/server/src/modules/CreditNotes/subscribers/DeleteCustomerLinkedCreditSubscriber.ts index fee140d62..642ca7c59 100644 --- a/packages/server/src/modules/CreditNotes/subscribers/DeleteCustomerLinkedCreditSubscriber.ts +++ b/packages/server/src/modules/CreditNotes/subscribers/DeleteCustomerLinkedCreditSubscriber.ts @@ -1,48 +1,34 @@ -// import { Inject, Service } from 'typedi'; -// import { ServiceError } from '@/exceptions'; -// import TenancyService from '@/services/Tenancy/TenancyService'; -// import events from '@/subscribers/events'; -// import { ICustomerDeletingPayload } from '@/interfaces'; -// import DeleteCustomerLinkedCreidtNote from '../commands/DeleteCustomerLinkedCreditNote.service'; +import { OnEvent } from '@nestjs/event-emitter'; +import { Injectable } from '@nestjs/common'; +import { DeleteCustomerLinkedCreditNoteService } from '@/modules/CreditNotesApplyInvoice/commands/DeleteCustomerLinkedCreditNote.service'; +import { events } from '@/common/events/events'; +import { ICustomerDeletingPayload } from '@/modules/Customers/types/Customers.types'; +import { ServiceError } from '@/modules/Items/ServiceError'; -// const ERRORS = { -// CUSTOMER_HAS_TRANSACTIONS: 'CUSTOMER_HAS_TRANSACTIONS', -// }; +const ERRORS = { + CUSTOMER_HAS_TRANSACTIONS: 'CUSTOMER_HAS_TRANSACTIONS', +}; -// @Service() -// export default class DeleteCustomerLinkedCreditSubscriber { -// @Inject() -// tenancy: TenancyService; +@Injectable() +export class DeleteCustomerLinkedCreditSubscriber { + constructor( + private readonly deleteCustomerLinkedCredit: DeleteCustomerLinkedCreditNoteService, + ) {} -// @Inject() -// deleteCustomerLinkedCredit: DeleteCustomerLinkedCreidtNote; - -// /** -// * Attaches events with handlers. -// * @param bus -// */ -// public attach = (bus) => { -// bus.subscribe( -// events.customers.onDeleting, -// this.validateCustomerHasNoLinkedCreditsOnDeleting -// ); -// }; - -// /** -// * Validate vendor has no associated credit transaction once the vendor deleting. -// * @param {IVendorEventDeletingPayload} payload - -// */ -// public validateCustomerHasNoLinkedCreditsOnDeleting = async ({ -// tenantId, -// customerId, -// }: ICustomerDeletingPayload) => { -// try { -// await this.deleteCustomerLinkedCredit.validateCustomerHasNoCreditTransaction( -// tenantId, -// customerId -// ); -// } catch (error) { -// throw new ServiceError(ERRORS.CUSTOMER_HAS_TRANSACTIONS); -// } -// }; -// } + /** + * Validate vendor has no associated credit transaction once the vendor deleting. + * @param {IVendorEventDeletingPayload} payload - + */ + @OnEvent(events.customers.onDeleting) + public async validateCustomerHasNoLinkedCreditsOnDeleting({ + customerId, + }: ICustomerDeletingPayload) { + try { + await this.deleteCustomerLinkedCredit.validateCustomerHasNoCreditTransaction( + customerId, + ); + } catch (error) { + throw new ServiceError(ERRORS.CUSTOMER_HAS_TRANSACTIONS); + } + } +} diff --git a/packages/server/src/modules/CreditNotes/subscribers/RefundCreditNoteGLEntriesSubscriber.ts b/packages/server/src/modules/CreditNotes/subscribers/RefundCreditNoteGLEntriesSubscriber.ts index 8f5a4851c..666c1fdc9 100644 --- a/packages/server/src/modules/CreditNotes/subscribers/RefundCreditNoteGLEntriesSubscriber.ts +++ b/packages/server/src/modules/CreditNotes/subscribers/RefundCreditNoteGLEntriesSubscriber.ts @@ -1,61 +1,47 @@ -// import { Service, Inject } from 'typedi'; -// import events from '@/subscribers/events'; -// import RefundCreditNoteGLEntries from '../commands/RefundCreditNoteGLEntries'; -// import { -// IRefundCreditNoteCreatedPayload, -// IRefundCreditNoteDeletedPayload, -// } from '@/interfaces'; +import { events } from '@/common/events/events'; +import { RefundCreditNoteGLEntries } from '@/modules/CreditNoteRefunds/commands/RefundCreditNoteGLEntries'; +import { + IRefundCreditNoteCreatedPayload, + IRefundCreditNoteDeletedPayload, +} from '@/modules/CreditNoteRefunds/types/CreditNoteRefunds.types'; +import { Injectable } from '@nestjs/common'; +import { OnEvent } from '@nestjs/event-emitter'; -// @Service() -// export default class RefundCreditNoteGLEntriesSubscriber { -// @Inject() -// refundCreditGLEntries: RefundCreditNoteGLEntries; +@Injectable() +export class RefundCreditNoteGLEntriesSubscriber { + constructor( + private readonly refundCreditGLEntries: RefundCreditNoteGLEntries, + ) {} -// /** -// * Attaches events with handlers. -// */ -// public attach = (bus) => { -// bus.subscribe( -// events.creditNote.onRefundCreated, -// this.writeRefundCreditGLEntriesOnceCreated -// ); -// bus.subscribe( -// events.creditNote.onRefundDeleted, -// this.revertRefundCreditGLEntriesOnceDeleted -// ); -// }; + /** + * Writes refund credit note GL entries once the transaction created. + * @param {IRefundCreditNoteCreatedPayload} payload - + */ + @OnEvent(events.creditNote.onRefundCreated) + async writeRefundCreditGLEntriesOnceCreated({ + trx, + refundCreditNote, + creditNote, + }: IRefundCreditNoteCreatedPayload) { + await this.refundCreditGLEntries.createRefundCreditGLEntries( + refundCreditNote.id, + trx, + ); + } -// /** -// * Writes refund credit note GL entries once the transaction created. -// * @param {IRefundCreditNoteCreatedPayload} payload - -// */ -// private writeRefundCreditGLEntriesOnceCreated = async ({ -// trx, -// refundCreditNote, -// creditNote, -// tenantId, -// }: IRefundCreditNoteCreatedPayload) => { -// await this.refundCreditGLEntries.createRefundCreditGLEntries( -// tenantId, -// refundCreditNote.id, -// trx -// ); -// }; - -// /** -// * Reverts refund credit note GL entries once the transaction deleted. -// * @param {IRefundCreditNoteDeletedPayload} payload - -// */ -// private revertRefundCreditGLEntriesOnceDeleted = async ({ -// trx, -// refundCreditId, -// oldRefundCredit, -// tenantId, -// }: IRefundCreditNoteDeletedPayload) => { -// await this.refundCreditGLEntries.revertRefundCreditGLEntries( -// tenantId, -// refundCreditId, -// trx -// ); -// }; -// } + /** + * Reverts refund credit note GL entries once the transaction deleted. + * @param {IRefundCreditNoteDeletedPayload} payload - + */ + @OnEvent(events.creditNote.onRefundDeleted) + async revertRefundCreditGLEntriesOnceDeleted({ + trx, + refundCreditId, + oldRefundCredit, + }: IRefundCreditNoteDeletedPayload) { + await this.refundCreditGLEntries.revertRefundCreditGLEntries( + refundCreditId, + trx, + ); + } +} diff --git a/packages/server/src/modules/CreditNotes/subscribers/RefundSyncCreditNoteBalanceSubscriber.ts b/packages/server/src/modules/CreditNotes/subscribers/RefundSyncCreditNoteBalanceSubscriber.ts index 4f0cae69c..8d749b8d1 100644 --- a/packages/server/src/modules/CreditNotes/subscribers/RefundSyncCreditNoteBalanceSubscriber.ts +++ b/packages/server/src/modules/CreditNotes/subscribers/RefundSyncCreditNoteBalanceSubscriber.ts @@ -1,62 +1,47 @@ -// import { Inject, Service } from 'typedi'; -// import { -// IRefundCreditNoteCreatedPayload, -// IRefundCreditNoteDeletedPayload, -// } from '@/interfaces'; -// import events from '@/subscribers/events'; -// import RefundSyncCreditNoteBalance from '../commands/RefundSyncCreditNoteBalance'; +import { events } from '@/common/events/events'; +import { RefundSyncCreditNoteBalanceService } from '@/modules/CreditNoteRefunds/commands/RefundSyncCreditNoteBalance'; +import { + IRefundCreditNoteCreatedPayload, + IRefundCreditNoteDeletedPayload, +} from '@/modules/CreditNoteRefunds/types/CreditNoteRefunds.types'; +import { Injectable } from '@nestjs/common'; +import { OnEvent } from '@nestjs/event-emitter'; -// @Service() -// export default class RefundSyncCreditNoteBalanceSubscriber { -// @Inject() -// refundSyncCreditBalance: RefundSyncCreditNoteBalance; +@Injectable() +export class RefundSyncCreditNoteBalanceSubscriber { + constructor( + private readonly refundSyncCreditBalance: RefundSyncCreditNoteBalanceService, + ) {} -// /** -// * Attaches events with handlers. -// */ -// attach(bus) { -// bus.subscribe( -// events.creditNote.onRefundCreated, -// this.incrementRefundedAmountOnceRefundCreated -// ); -// bus.subscribe( -// events.creditNote.onRefundDeleted, -// this.decrementRefundedAmountOnceRefundDeleted -// ); -// return bus; -// } + /** + * Increment credit note refunded amount once associated refund transaction created. + * @param {IRefundCreditNoteCreatedPayload} payload - + */ + @OnEvent(events.creditNote.onRefundCreated) + async incrementRefundedAmountOnceRefundCreated({ + trx, + refundCreditNote, + }: IRefundCreditNoteCreatedPayload) { + await this.refundSyncCreditBalance.incrementCreditNoteRefundAmount( + refundCreditNote.creditNoteId, + refundCreditNote.amount, + trx, + ); + } -// /** -// * Increment credit note refunded amount once associated refund transaction created. -// * @param {IRefundCreditNoteCreatedPayload} payload - -// */ -// private incrementRefundedAmountOnceRefundCreated = async ({ -// trx, -// refundCreditNote, -// tenantId, -// }: IRefundCreditNoteCreatedPayload) => { -// await this.refundSyncCreditBalance.incrementCreditNoteRefundAmount( -// tenantId, -// refundCreditNote.creditNoteId, -// refundCreditNote.amount, -// trx -// ); -// }; - -// /** -// * Decrement credit note refunded amount once associated refuned transaction deleted. -// * @param {IRefundCreditNoteDeletedPayload} payload - -// */ -// private decrementRefundedAmountOnceRefundDeleted = async ({ -// trx, -// oldRefundCredit, -// tenantId, -// }: IRefundCreditNoteDeletedPayload) => { -// await this.refundSyncCreditBalance.decrementCreditNoteRefundAmount( -// tenantId, -// oldRefundCredit.creditNoteId, -// oldRefundCredit.amount, -// trx -// ); -// }; -// } + /** + * Decrement credit note refunded amount once associated refuned transaction deleted. + * @param {IRefundCreditNoteDeletedPayload} payload - + */ + @OnEvent(events.creditNote.onRefundDeleted) + async decrementRefundedAmountOnceRefundDeleted({ + trx, + oldRefundCredit, + }: IRefundCreditNoteDeletedPayload) { + await this.refundSyncCreditBalance.decrementCreditNoteRefundAmount( + oldRefundCredit.creditNoteId, + oldRefundCredit.amount, + trx, + ); + } +} diff --git a/packages/server/src/modules/CreditNotesApplyInvoice/CreditNotesApplyInvoice.module.ts b/packages/server/src/modules/CreditNotesApplyInvoice/CreditNotesApplyInvoice.module.ts new file mode 100644 index 000000000..65d363028 --- /dev/null +++ b/packages/server/src/modules/CreditNotesApplyInvoice/CreditNotesApplyInvoice.module.ts @@ -0,0 +1,27 @@ +import { forwardRef, Module } from '@nestjs/common'; +import { DeleteCustomerLinkedCreditNoteService } from './commands/DeleteCustomerLinkedCreditNote.service'; +import { DeleteCreditNoteApplyToInvoices } from './commands/DeleteCreditNoteApplyToInvoices.service'; +import { CreditNoteApplyToInvoices } from './commands/CreditNoteApplyToInvoices.service'; +import { CreditNoteApplySyncInvoicesCreditedAmount } from './commands/CreditNoteApplySyncInvoices.service'; +import { CreditNoteApplySyncCredit } from './commands/CreditNoteApplySyncCredit.service'; +import { PaymentsReceivedModule } from '../PaymentReceived/PaymentsReceived.module'; +import { CreditNotesModule } from '../CreditNotes/CreditNotes.module'; +import { GetCreditNoteAssociatedAppliedInvoices } from './queries/GetCreditNoteAssociatedAppliedInvoices.service'; +import { GetCreditNoteAssociatedInvoicesToApply } from './queries/GetCreditNoteAssociatedInvoicesToApply.service'; + +@Module({ + providers: [ + DeleteCustomerLinkedCreditNoteService, + DeleteCreditNoteApplyToInvoices, + CreditNoteApplyToInvoices, + CreditNoteApplySyncInvoicesCreditedAmount, + CreditNoteApplySyncCredit, + // GetCreditNoteAssociatedAppliedInvoices, + // GetCreditNoteAssociatedInvoicesToApply + ], + exports: [ + DeleteCustomerLinkedCreditNoteService, + ], + imports: [PaymentsReceivedModule, forwardRef(() => CreditNotesModule)], +}) +export class CreditNotesApplyInvoiceModule {} diff --git a/packages/server/src/modules/CreditNotesApplyInvoice/commands/DeleteCreditNoteApplyToInvoices.service.ts b/packages/server/src/modules/CreditNotesApplyInvoice/commands/DeleteCreditNoteApplyToInvoices.service.ts index c98ecd2ac..d52e2a3a8 100644 --- a/packages/server/src/modules/CreditNotesApplyInvoice/commands/DeleteCreditNoteApplyToInvoices.service.ts +++ b/packages/server/src/modules/CreditNotesApplyInvoice/commands/DeleteCreditNoteApplyToInvoices.service.ts @@ -11,7 +11,7 @@ import { ERRORS } from '../../CreditNotes/constants'; import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; @Injectable() -export default class DeleteCreditNoteApplyToInvoices { +export class DeleteCreditNoteApplyToInvoices { /** * @param {UnitOfWork} uow - Unit of work. * @param {EventEmitter2} eventPublisher - Event emitter. diff --git a/packages/server/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncCreditSubscriber.ts b/packages/server/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncCreditSubscriber.ts index 2b49ecb78..2693c6378 100644 --- a/packages/server/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncCreditSubscriber.ts +++ b/packages/server/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncCreditSubscriber.ts @@ -1,67 +1,52 @@ -// import { Service, Inject } from 'typedi'; -// import { sumBy } from 'lodash'; -// import events from '@/subscribers/events'; -// import { -// IApplyCreditToInvoicesCreatedPayload, -// IApplyCreditToInvoicesDeletedPayload, -// } from '@/interfaces'; -// import CreditNoteApplySyncCredit from '../commands/CreditNoteApplySyncCredit.service'; +import { sumBy } from 'lodash'; +import { Injectable } from '@nestjs/common'; +import { + IApplyCreditToInvoicesCreatedPayload, + IApplyCreditToInvoicesDeletedPayload, +} from '../types/CreditNoteApplyInvoice.types'; +import { CreditNoteApplySyncCredit } from '../commands/CreditNoteApplySyncCredit.service'; +import { OnEvent } from '@nestjs/event-emitter'; +import { events } from '@/common/events/events'; -// @Service() -// export default class CreditNoteApplySyncCreditSubscriber { -// @Inject() -// syncInvoicedAmountWithCredit: CreditNoteApplySyncCredit; +@Injectable() +export class CreditNoteApplySyncCreditSubscriber { + constructor( + private readonly syncInvoicedAmountWithCredit: CreditNoteApplySyncCredit, + ) {} -// /** -// * -// * @param bus -// */ -// attach(bus) { -// bus.subscribe( -// events.creditNote.onApplyToInvoicesCreated, -// this.incrementCreditedAmountOnceApplyToInvoicesCreated -// ); -// bus.subscribe( -// events.creditNote.onApplyToInvoicesDeleted, -// this.decrementCreditedAmountOnceApplyToInvoicesDeleted -// ); -// } + /** + * Increment credited amount of credit note transaction once the transaction created. + * @param {IApplyCreditToInvoicesCreatedPayload} payload - + */ + @OnEvent(events.creditNote.onApplyToInvoicesCreated) + async incrementCreditedAmountOnceApplyToInvoicesCreated({ + trx, + creditNote, + creditNoteAppliedInvoices, + }: IApplyCreditToInvoicesCreatedPayload) { + const totalCredited = sumBy(creditNoteAppliedInvoices, 'amount'); -// /** -// * Increment credited amount of credit note transaction once the transaction created. -// * @param {IApplyCreditToInvoicesCreatedPayload} payload - -// */ -// private incrementCreditedAmountOnceApplyToInvoicesCreated = async ({ -// trx, -// creditNote, -// tenantId, -// creditNoteAppliedInvoices, -// }: IApplyCreditToInvoicesCreatedPayload) => { -// const totalCredited = sumBy(creditNoteAppliedInvoices, 'amount'); + await this.syncInvoicedAmountWithCredit.incrementCreditNoteInvoicedAmount( + creditNote.id, + totalCredited, + trx, + ); + } -// await this.syncInvoicedAmountWithCredit.incrementCreditNoteInvoicedAmount( -// tenantId, -// creditNote.id, -// totalCredited, -// trx -// ); -// }; - -// /** -// * Decrement credited amount of credit note transaction once the transaction deleted. -// * @param {IApplyCreditToInvoicesDeletedPayload} payload - -// */ -// private decrementCreditedAmountOnceApplyToInvoicesDeleted = async ({ -// tenantId, -// creditNote, -// creditNoteAppliedToInvoice, -// trx, -// }: IApplyCreditToInvoicesDeletedPayload) => { -// await this.syncInvoicedAmountWithCredit.decrementCreditNoteInvoicedAmount( -// tenantId, -// creditNote.id, -// creditNoteAppliedToInvoice.amount, -// trx -// ); -// }; -// } + /** + * Decrement credited amount of credit note transaction once the transaction deleted. + * @param {IApplyCreditToInvoicesDeletedPayload} payload - + */ + @OnEvent(events.creditNote.onApplyToInvoicesDeleted) + async decrementCreditedAmountOnceApplyToInvoicesDeleted({ + creditNote, + creditNoteAppliedToInvoice, + trx, + }: IApplyCreditToInvoicesDeletedPayload) { + await this.syncInvoicedAmountWithCredit.decrementCreditNoteInvoicedAmount( + creditNote.id, + creditNoteAppliedToInvoice.amount, + trx, + ); + } +} diff --git a/packages/server/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncInvoicesSubscriber.ts b/packages/server/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncInvoicesSubscriber.ts index bcf0580d7..5169364a8 100644 --- a/packages/server/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncInvoicesSubscriber.ts +++ b/packages/server/src/modules/CreditNotesApplyInvoice/subscribers/CreditNoteApplySyncInvoicesSubscriber.ts @@ -1,61 +1,47 @@ -// import { Service, Inject } from 'typedi'; -// import events from '@/subscribers/events'; -// import { -// IApplyCreditToInvoicesCreatedPayload, -// IApplyCreditToInvoicesDeletedPayload, -// } from '@/interfaces'; -// import CreditNoteApplySyncInvoicesCreditedAmount from '../commands/CreditNoteApplySyncInvoices.service'; +import { OnEvent } from '@nestjs/event-emitter'; +import { Injectable } from '@nestjs/common'; +import { + IApplyCreditToInvoicesCreatedPayload, + IApplyCreditToInvoicesDeletedPayload, +} from '../types/CreditNoteApplyInvoice.types'; +import { CreditNoteApplySyncInvoicesCreditedAmount } from '../commands/CreditNoteApplySyncInvoices.service'; +import { events } from '@/common/events/events'; -// @Service() -// export default class CreditNoteApplySyncInvoicesCreditedAmountSubscriber { -// @Inject() -// private syncInvoicesWithCreditNote: CreditNoteApplySyncInvoicesCreditedAmount; +@Injectable() +export default class CreditNoteApplySyncInvoicesCreditedAmountSubscriber { + constructor( + private readonly syncInvoicesWithCreditNote: CreditNoteApplySyncInvoicesCreditedAmount, + ) {} -// /** -// * Attaches events with handlers. -// */ -// public attach(bus) { -// bus.subscribe( -// events.creditNote.onApplyToInvoicesCreated, -// this.incrementAppliedInvoicesOnceCreditCreated -// ); -// bus.subscribe( -// events.creditNote.onApplyToInvoicesDeleted, -// this.decrementAppliedInvoicesOnceCreditDeleted -// ); -// } + /** + * Increment invoices credited amount once the credit note apply to invoices transaction + * @param {IApplyCreditToInvoicesCreatedPayload} payload - + */ + @OnEvent(events.creditNote.onApplyToInvoicesCreated) + async incrementAppliedInvoicesOnceCreditCreated({ + trx, + creditNoteAppliedInvoices, + }: IApplyCreditToInvoicesCreatedPayload) { + await this.syncInvoicesWithCreditNote.incrementInvoicesCreditedAmount( + creditNoteAppliedInvoices, + trx, + ); + } -// /** -// * Increment invoices credited amount once the credit note apply to invoices transaction -// * @param {IApplyCreditToInvoicesCreatedPayload} payload - -// */ -// private incrementAppliedInvoicesOnceCreditCreated = async ({ -// trx, -// tenantId, -// creditNoteAppliedInvoices, -// }: IApplyCreditToInvoicesCreatedPayload) => { -// await this.syncInvoicesWithCreditNote.incrementInvoicesCreditedAmount( -// tenantId, -// creditNoteAppliedInvoices, -// trx -// ); -// }; - -// /** -// * -// * @param {IApplyCreditToInvoicesDeletedPayload} payload - -// */ -// private decrementAppliedInvoicesOnceCreditDeleted = async ({ -// trx, -// creditNoteAppliedToInvoice, -// tenantId, -// }: IApplyCreditToInvoicesDeletedPayload) => { -// // Decrement invoice credited amount. -// await this.syncInvoicesWithCreditNote.decrementInvoiceCreditedAmount( -// tenantId, -// creditNoteAppliedToInvoice.invoiceId, -// creditNoteAppliedToInvoice.amount, -// trx -// ); -// }; -// } + /** + * + * @param {IApplyCreditToInvoicesDeletedPayload} payload - + */ + @OnEvent(events.creditNote.onApplyToInvoicesDeleted) + async decrementAppliedInvoicesOnceCreditDeleted({ + trx, + creditNoteAppliedToInvoice, + }: IApplyCreditToInvoicesDeletedPayload) { + // Decrement invoice credited amount. + await this.syncInvoicesWithCreditNote.decrementInvoiceCreditedAmount( + creditNoteAppliedToInvoice.invoiceId, + creditNoteAppliedToInvoice.amount, + trx, + ); + } +} diff --git a/packages/server/src/modules/CreditNotesApplyInvoice/types/CreditNoteApplyInvoice.types.ts b/packages/server/src/modules/CreditNotesApplyInvoice/types/CreditNoteApplyInvoice.types.ts index 2d3bc633e..7172811ae 100644 --- a/packages/server/src/modules/CreditNotesApplyInvoice/types/CreditNoteApplyInvoice.types.ts +++ b/packages/server/src/modules/CreditNotesApplyInvoice/types/CreditNoteApplyInvoice.types.ts @@ -1,5 +1,6 @@ import { CreditNote } from '@/modules/CreditNotes/models/CreditNote'; import { Knex } from 'knex'; +import { CreditNoteAppliedInvoice } from '../models/CreditNoteAppliedInvoice'; export interface ICreditNoteApplyInvoiceDTO { entries: { invoiceId: number; amount: number }[]; @@ -17,12 +18,12 @@ export interface IApplyCreditToInvoicesDTO { export interface IApplyCreditToInvoicesCreatedPayload { trx: Knex.Transaction; creditNote: CreditNote; - creditNoteAppliedInvoices: ICreditNoteAppliedToInvoice[]; + creditNoteAppliedInvoices: CreditNoteAppliedInvoice[]; } export interface IApplyCreditToInvoicesDeletedPayload { trx: Knex.Transaction; creditNote: CreditNote; - creditNoteAppliedToInvoice: ICreditNoteAppliedToInvoice; + creditNoteAppliedToInvoice: CreditNoteAppliedInvoice; } export interface ICreditNoteAppliedToInvoice { diff --git a/packages/server/src/modules/EventsTracker/EventTracker.interfaces.ts b/packages/server/src/modules/EventsTracker/EventTracker.interfaces.ts new file mode 100644 index 000000000..d07e77df0 --- /dev/null +++ b/packages/server/src/modules/EventsTracker/EventTracker.interfaces.ts @@ -0,0 +1,3 @@ +interface ReportsEvents { + tenantId: number; +} \ No newline at end of file diff --git a/packages/server/src/modules/EventsTracker/EventTracker.module.ts b/packages/server/src/modules/EventsTracker/EventTracker.module.ts index a7210ad9c..ed4d077aa 100644 --- a/packages/server/src/modules/EventsTracker/EventTracker.module.ts +++ b/packages/server/src/modules/EventsTracker/EventTracker.module.ts @@ -18,6 +18,7 @@ import { PaymentMethodEventsTracker } from './events/PaymentMethodEventsTracker' import { PaymentLinkEventsTracker } from './events/PaymentLinkEventsTracker'; import { StripeIntegrationEventsTracker } from './events/StripeIntegrationEventsTracker'; import { PostHogModule } from './postHog.module'; +import { ReportsEventsTracker } from './events/ReportsEventsTracker'; @Module({ imports: [PostHogModule], @@ -40,7 +41,7 @@ import { PostHogModule } from './postHog.module'; PaymentMethodEventsTracker, PaymentLinkEventsTracker, StripeIntegrationEventsTracker, - // ReportsEventsTracker, + ReportsEventsTracker, ], }) export class EventTrackerModule {} diff --git a/packages/server/src/modules/EventsTracker/events/ReportsEventsTracker.ts b/packages/server/src/modules/EventsTracker/events/ReportsEventsTracker.ts index 2d4ed06e8..59f63fcff 100644 --- a/packages/server/src/modules/EventsTracker/events/ReportsEventsTracker.ts +++ b/packages/server/src/modules/EventsTracker/events/ReportsEventsTracker.ts @@ -1,240 +1,161 @@ -// import { Inject, Service } from 'typedi'; -// import { EventSubscriber } from '@/lib/EventPublisher/EventPublisher'; -// import { ReportsEvents } from '@/constants/event-tracker'; -// import { PosthogService } from '../EventTracker.service'; -// import events from '@/subscribers/events'; -// import { -// BALANCE_SHEET_VIEWED, -// TRIAL_BALANCE_SHEET_VIEWED, -// PROFIT_LOSS_SHEET_VIEWED, -// CASHFLOW_STATEMENT_VIEWED, -// GENERAL_LEDGER_VIEWED, -// JOURNAL_VIEWED, -// RECEIVABLE_AGING_VIEWED, -// PAYABLE_AGING_VIEWED, -// CUSTOMER_BALANCE_SUMMARY_VIEWED, -// VENDOR_BALANCE_SUMMARY_VIEWED, -// INVENTORY_VALUATION_VIEWED, -// CUSTOMER_TRANSACTIONS_VIEWED, -// VENDOR_TRANSACTIONS_VIEWED, -// SALES_BY_ITEM_VIEWED, -// PURCHASES_BY_ITEM_VIEWED, -// } from '@/constants/event-tracker'; +import { Inject, Injectable } from '@nestjs/common'; +import { OnEvent } from '@nestjs/event-emitter'; +import { + BALANCE_SHEET_VIEWED, + TRIAL_BALANCE_SHEET_VIEWED, + PROFIT_LOSS_SHEET_VIEWED, + CASHFLOW_STATEMENT_VIEWED, + GENERAL_LEDGER_VIEWED, + JOURNAL_VIEWED, + RECEIVABLE_AGING_VIEWED, + PAYABLE_AGING_VIEWED, + CUSTOMER_BALANCE_SUMMARY_VIEWED, + VENDOR_BALANCE_SUMMARY_VIEWED, + INVENTORY_VALUATION_VIEWED, + CUSTOMER_TRANSACTIONS_VIEWED, + VENDOR_TRANSACTIONS_VIEWED, + SALES_BY_ITEM_VIEWED, + PURCHASES_BY_ITEM_VIEWED, +} from '../event-tracker'; +import { events } from '@/common/events/events'; +import { POSTHOG_PROVIDER } from '../PostHog.constants'; -// @Service() -// export class ReportsEventsTracker extends EventSubscriber { -// @Inject() -// private posthog: PosthogService; +@Injectable() +export class ReportsEventsTracker { + constructor(@Inject(POSTHOG_PROVIDER) private readonly posthog: any) {} -// /** -// * Constructor method. -// */ -// public attach(bus) { -// bus.subscribe( -// events.reports.onBalanceSheetViewed, -// this.handleTrackBalanceSheetViewedEvent -// ); -// bus.subscribe( -// events.reports.onTrialBalanceSheetView, -// this.handleTrackTrialBalanceSheetViewedEvent -// ); -// bus.subscribe( -// events.reports.onProfitLossSheetViewed, -// this.handleTrackProfitLossSheetViewedEvent -// ); -// bus.subscribe( -// events.reports.onCashflowStatementViewed, -// this.handleTrackCashflowStatementViewedEvent -// ); -// bus.subscribe( -// events.reports.onGeneralLedgerViewed, -// this.handleTrackGeneralLedgerViewedEvent -// ); -// bus.subscribe( -// events.reports.onJournalViewed, -// this.handleTrackJournalViewedEvent -// ); -// bus.subscribe( -// events.reports.onReceivableAgingViewed, -// this.handleTrackReceivableAgingViewedEvent -// ); -// bus.subscribe( -// events.reports.onPayableAgingViewed, -// this.handleTrackPayableAgingViewedEvent -// ); -// bus.subscribe( -// events.reports.onCustomerBalanceSummaryViewed, -// this.handleTrackCustomerBalanceSummaryViewedEvent -// ); -// bus.subscribe( -// events.reports.onVendorBalanceSummaryViewed, -// this.handleTrackVendorBalanceSummaryViewedEvent -// ); -// bus.subscribe( -// events.reports.onInventoryValuationViewed, -// this.handleTrackInventoryValuationViewedEvent -// ); -// bus.subscribe( -// events.reports.onCustomerTransactionsViewed, -// this.handleTrackCustomerTransactionsViewedEvent -// ); -// bus.subscribe( -// events.reports.onVendorTransactionsViewed, -// this.handleTrackVendorTransactionsViewedEvent -// ); -// bus.subscribe( -// events.reports.onSalesByItemViewed, -// this.handleTrackSalesByItemViewedEvent -// ); -// bus.subscribe( -// events.reports.onPurchasesByItemViewed, -// this.handleTrackPurchasesByItemViewedEvent -// ); -// } + @OnEvent(events.reports.onBalanceSheetViewed) + handleTrackBalanceSheetViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: BALANCE_SHEET_VIEWED, + properties: {}, + }); + } -// private handleTrackBalanceSheetViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: BALANCE_SHEET_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onTrialBalanceSheetView) + handleTrackTrialBalanceSheetViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: TRIAL_BALANCE_SHEET_VIEWED, + properties: {}, + }); + } -// private handleTrackTrialBalanceSheetViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: TRIAL_BALANCE_SHEET_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onProfitLossSheetViewed) + handleTrackProfitLossSheetViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: PROFIT_LOSS_SHEET_VIEWED, + properties: {}, + }); + } -// private handleTrackProfitLossSheetViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: PROFIT_LOSS_SHEET_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onCashflowStatementViewed) + handleTrackCashflowStatementViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: CASHFLOW_STATEMENT_VIEWED, + properties: {}, + }); + } -// private handleTrackCashflowStatementViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: CASHFLOW_STATEMENT_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onGeneralLedgerViewed) + handleTrackGeneralLedgerViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: GENERAL_LEDGER_VIEWED, + properties: {}, + }); + } -// private handleTrackGeneralLedgerViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: GENERAL_LEDGER_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onJournalViewed) + handleTrackJournalViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: JOURNAL_VIEWED, + properties: {}, + }); + } -// private handleTrackJournalViewedEvent({ tenantId }: ReportsEvents) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: JOURNAL_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onReceivableAgingViewed) + handleTrackReceivableAgingViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: RECEIVABLE_AGING_VIEWED, + properties: {}, + }); + } -// private handleTrackReceivableAgingViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: RECEIVABLE_AGING_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onPayableAgingViewed) + handleTrackPayableAgingViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: PAYABLE_AGING_VIEWED, + properties: {}, + }); + } -// private handleTrackPayableAgingViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: PAYABLE_AGING_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onCustomerBalanceSummaryViewed) + handleTrackCustomerBalanceSummaryViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: CUSTOMER_BALANCE_SUMMARY_VIEWED, + properties: {}, + }); + } -// private handleTrackCustomerBalanceSummaryViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: CUSTOMER_BALANCE_SUMMARY_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onVendorBalanceSummaryViewed) + handleTrackVendorBalanceSummaryViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: VENDOR_BALANCE_SUMMARY_VIEWED, + properties: {}, + }); + } -// private handleTrackVendorBalanceSummaryViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: VENDOR_BALANCE_SUMMARY_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onInventoryValuationViewed) + handleTrackInventoryValuationViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: INVENTORY_VALUATION_VIEWED, + properties: {}, + }); + } -// private handleTrackInventoryValuationViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: INVENTORY_VALUATION_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onCustomerTransactionsViewed) + handleTrackCustomerTransactionsViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: CUSTOMER_TRANSACTIONS_VIEWED, + properties: {}, + }); + } -// private handleTrackCustomerTransactionsViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: CUSTOMER_TRANSACTIONS_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onVendorTransactionsViewed) + handleTrackVendorTransactionsViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: VENDOR_TRANSACTIONS_VIEWED, + properties: {}, + }); + } -// private handleTrackVendorTransactionsViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: VENDOR_TRANSACTIONS_VIEWED, -// properties: {}, -// }); -// } + @OnEvent(events.reports.onSalesByItemViewed) + handleTrackSalesByItemViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: SALES_BY_ITEM_VIEWED, + properties: {}, + }); + } -// private handleTrackSalesByItemViewedEvent({ tenantId }: ReportsEvents) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: SALES_BY_ITEM_VIEWED, -// properties: {}, -// }); -// } - -// private handleTrackPurchasesByItemViewedEvent( -// { tenantId }: ReportsEvents -// ) { -// this.posthog.trackEvent({ -// distinctId: `tenant-${tenantId}`, -// event: PURCHASES_BY_ITEM_VIEWED, -// properties: {}, -// }); -// } -// } + @OnEvent(events.reports.onPurchasesByItemViewed) + handleTrackPurchasesByItemViewedEvent({ tenantId }: ReportsEvents) { + this.posthog.trackEvent({ + distinctId: `tenant-${tenantId}`, + event: PURCHASES_BY_ITEM_VIEWED, + properties: {}, + }); + } +} diff --git a/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts b/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts index 8867d8b39..64b0343f4 100644 --- a/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts +++ b/packages/server/src/modules/PaymentReceived/PaymentsReceived.module.ts @@ -70,6 +70,7 @@ import { PaymentsReceivedImportable } from './commands/PaymentsReceivedImportabl PaymentReceivedGLEntries, PaymentsReceivedExportable, PaymentsReceivedImportable, + PaymentReceivedValidators ], imports: [ ChromiumlyTenancyModule, diff --git a/packages/server/src/modules/PaymentReceived/queries/PaymentReceivedBrandingTemplate.service.ts b/packages/server/src/modules/PaymentReceived/queries/PaymentReceivedBrandingTemplate.service.ts index 351240a94..2c5f8f800 100644 --- a/packages/server/src/modules/PaymentReceived/queries/PaymentReceivedBrandingTemplate.service.ts +++ b/packages/server/src/modules/PaymentReceived/queries/PaymentReceivedBrandingTemplate.service.ts @@ -14,15 +14,14 @@ export class PaymentReceivedBrandingTemplate { /** * Retrieves the payment received pdf template. * @param {number} paymentTemplateId - * @returns + * @returns */ public async getPaymentReceivedPdfTemplate(paymentTemplateId: number) { - const template = await this.getPdfTemplateService.getPdfTemplate( - paymentTemplateId - ); + const template = + await this.getPdfTemplateService.getPdfTemplate(paymentTemplateId); // Retrieves the organization branding attributes. const commonOrgBrandingAttrs = - await this.getOrgBrandingAttributes.getOrganizationBrandingAttributes(); + await this.getOrgBrandingAttributes.execute(); // Merges the default branding attributes with common organization branding attrs. const organizationBrandingAttrs = { @@ -35,7 +34,7 @@ export class PaymentReceivedBrandingTemplate { }; const attributes = mergePdfTemplateWithDefaultAttributes( brandingTemplateAttrs, - organizationBrandingAttrs + organizationBrandingAttrs, ); return { ...template, diff --git a/packages/server/src/modules/PdfTemplate/PdfTemplate.application.ts b/packages/server/src/modules/PdfTemplate/PdfTemplate.application.ts index 62be396bb..36684d286 100644 --- a/packages/server/src/modules/PdfTemplate/PdfTemplate.application.ts +++ b/packages/server/src/modules/PdfTemplate/PdfTemplate.application.ts @@ -6,6 +6,8 @@ import { GetPdfTemplateService } from './queries/GetPdfTemplate.service'; import { EditPdfTemplateService } from './commands/EditPdfTemplate.service'; import { AssignPdfTemplateDefaultService } from './commands/AssignPdfTemplateDefault.service'; import { GetOrganizationBrandingAttributesService } from './queries/GetOrganizationBrandingAttributes.service'; +import { GetPdfTemplates } from './queries/GetPdfTemplates.service'; +import { GetPdfTemplateBrandingState } from './queries/GetPdfTemplateBrandingState.service'; @Injectable() export class PdfTemplateApplication { @@ -13,11 +15,11 @@ export class PdfTemplateApplication { private readonly createPdfTemplateService: CreatePdfTemplateService, private readonly getPdfTemplateService: GetPdfTemplateService, private readonly deletePdfTemplateService: DeletePdfTemplateService, - // private readonly getPdfTemplatesService: GetPdfTemplatesService, + private readonly getPdfTemplatesService: GetPdfTemplates, private readonly editPdfTemplateService: EditPdfTemplateService, private readonly assignPdfTemplateDefaultService: AssignPdfTemplateDefaultService, - // private readonly getPdfTemplateBrandingStateService: GetPdfTemplateBrandingStateService, - // private readonly getOrganizationBrandingAttributesService: GetOrganizationBrandingAttributesService, + private readonly getPdfTemplateBrandingStateService: GetPdfTemplateBrandingState, + private readonly getOrganizationBrandingAttributesService: GetOrganizationBrandingAttributesService, ) {} /** @@ -59,8 +61,8 @@ export class PdfTemplateApplication { * Retrieves all PDF templates. * @param {string} resource - The resource type to filter templates. */ - public async getPdfTemplates(resource: string) { - // return this.getPdfTemplatesService.execute(resource); + public async getPdfTemplates(query?: { resource?: string }) { + return this.getPdfTemplatesService.getPdfTemplates(query); } /** @@ -77,10 +79,9 @@ export class PdfTemplateApplication { /** * Gets the PDF template branding state. - * @param {number} tenantId - The tenant ID. */ - public async getPdfTemplateBrandingState(tenantId: number) { - // return this.getPdfTemplateBrandingStateService.execute(tenantId); + public async getPdfTemplateBrandingState() { + return this.getPdfTemplateBrandingStateService.execute(); } /** @@ -93,4 +94,12 @@ export class PdfTemplateApplication { templateId, ); } + + /** + * Retrieves the organization branding attributes. + * @returns {Promise} The organization branding attributes. + */ + getOrganizationBrandingAttributes() { + return this.getOrganizationBrandingAttributesService.execute(); + } } diff --git a/packages/server/src/modules/PdfTemplate/PdfTemplates.controller.ts b/packages/server/src/modules/PdfTemplate/PdfTemplates.controller.ts index 58b19e08b..00f1ffc2b 100644 --- a/packages/server/src/modules/PdfTemplate/PdfTemplates.controller.ts +++ b/packages/server/src/modules/PdfTemplate/PdfTemplates.controller.ts @@ -65,7 +65,7 @@ export class PdfTemplatesController { description: 'The PDF templates have been successfully retrieved.', }) async getPdfTemplates(@Body('resource') resource: string) { - return this.pdfTemplateApplication.getPdfTemplates(resource); + return this.pdfTemplateApplication.getPdfTemplates({ resource }); } @Put(':id') diff --git a/packages/server/src/modules/PdfTemplate/PdfTemplates.module.ts b/packages/server/src/modules/PdfTemplate/PdfTemplates.module.ts index 75d0aa9ac..698daa646 100644 --- a/packages/server/src/modules/PdfTemplate/PdfTemplates.module.ts +++ b/packages/server/src/modules/PdfTemplate/PdfTemplates.module.ts @@ -11,6 +11,8 @@ import { PdfTemplatesController } from './PdfTemplates.controller'; import { GetPdfTemplateService } from './queries/GetPdfTemplate.service'; import { BrandingTemplateDTOTransformer } from './BrandingTemplateDTOTransformer'; import { GetOrganizationBrandingAttributesService } from './queries/GetOrganizationBrandingAttributes.service'; +import { GetPdfTemplates } from './queries/GetPdfTemplates.service'; +import { GetPdfTemplateBrandingState } from './queries/GetPdfTemplateBrandingState.service'; @Module({ exports: [ @@ -25,12 +27,14 @@ import { GetOrganizationBrandingAttributesService } from './queries/GetOrganizat CreatePdfTemplateService, DeletePdfTemplateService, GetPdfTemplateService, + GetPdfTemplates, EditPdfTemplateService, AssignPdfTemplateDefaultService, TenancyContext, TransformerInjectable, BrandingTemplateDTOTransformer, GetOrganizationBrandingAttributesService, + GetPdfTemplateBrandingState ], }) export class PdfTemplatesModule {} diff --git a/packages/server/src/modules/PdfTemplate/queries/GetOrganizationBrandingAttributes.service.ts b/packages/server/src/modules/PdfTemplate/queries/GetOrganizationBrandingAttributes.service.ts index 7722e3b41..36a282a2b 100644 --- a/packages/server/src/modules/PdfTemplate/queries/GetOrganizationBrandingAttributes.service.ts +++ b/packages/server/src/modules/PdfTemplate/queries/GetOrganizationBrandingAttributes.service.ts @@ -10,7 +10,7 @@ export class GetOrganizationBrandingAttributesService { * Retrieves the given organization branding attributes initial state. * @returns {Promise} */ - public async getOrganizationBrandingAttributes(): Promise { + public async execute(): Promise { const tenant = await this.tenancyContext.getTenant(true); const tenantMetadata = tenant.metadata; diff --git a/packages/server/src/modules/PdfTemplate/queries/GetPdfTemplateBrandingState.service.ts b/packages/server/src/modules/PdfTemplate/queries/GetPdfTemplateBrandingState.service.ts new file mode 100644 index 000000000..1ff7ef33e --- /dev/null +++ b/packages/server/src/modules/PdfTemplate/queries/GetPdfTemplateBrandingState.service.ts @@ -0,0 +1,16 @@ +import { Injectable } from '@nestjs/common'; +import { GetOrganizationBrandingAttributesService } from './GetOrganizationBrandingAttributes.service'; + +@Injectable() +export class GetPdfTemplateBrandingState { + constructor( + private readonly getOrgBrandingAttributes: GetOrganizationBrandingAttributesService, + ) {} + + async execute() { + const brandingAttributes = + await this.getOrgBrandingAttributes.execute(); + + return brandingAttributes; + } +} diff --git a/packages/server/src/modules/SaleInvoices/queries/SaleEstimatePdfTemplate.service.ts b/packages/server/src/modules/SaleInvoices/queries/SaleEstimatePdfTemplate.service.ts index c8e34fdb0..3655550e2 100644 --- a/packages/server/src/modules/SaleInvoices/queries/SaleEstimatePdfTemplate.service.ts +++ b/packages/server/src/modules/SaleInvoices/queries/SaleEstimatePdfTemplate.service.ts @@ -19,9 +19,9 @@ export class SaleEstimatePdfTemplate { public async getEstimatePdfTemplate(estimateTemplateId: number) { const template = await this.getPdfTemplateService.getPdfTemplate(estimateTemplateId); + // Retreives the organization branding attributes. - const commonOrgBrandingAttrs = - await this.getOrgBrandingAttrs.getOrganizationBrandingAttributes(); + const commonOrgBrandingAttrs = await this.getOrgBrandingAttrs.execute(); // Merge the default branding attributes with organization attrs. const orgainizationBrandingAttrs = { diff --git a/packages/server/src/modules/SaleInvoices/queries/SaleInvoicePdfTemplate.service.ts b/packages/server/src/modules/SaleInvoices/queries/SaleInvoicePdfTemplate.service.ts index 1a8960a5e..136f9f36b 100644 --- a/packages/server/src/modules/SaleInvoices/queries/SaleInvoicePdfTemplate.service.ts +++ b/packages/server/src/modules/SaleInvoices/queries/SaleInvoicePdfTemplate.service.ts @@ -19,9 +19,10 @@ export class SaleInvoicePdfTemplate { async getInvoicePdfTemplate(invoiceTemplateId: number) { const template = await this.getPdfTemplateService.getPdfTemplate(invoiceTemplateId); + // Retrieves the organization branding attributes. const commonOrgBrandingAttrs = - await this.getOrgBrandingAttributes.getOrganizationBrandingAttributes(); + await this.getOrgBrandingAttributes.execute(); const organizationBrandingAttrs = { ...defaultInvoicePdfTemplateAttributes,