diff --git a/packages/server-nest/src/modules/BankRules/commands/CreateBankRule.service.ts b/packages/server-nest/src/modules/BankRules/commands/CreateBankRule.service.ts index 2ccbb103c..a7bf7c584 100644 --- a/packages/server-nest/src/modules/BankRules/commands/CreateBankRule.service.ts +++ b/packages/server-nest/src/modules/BankRules/commands/CreateBankRule.service.ts @@ -11,6 +11,7 @@ import { EventEmitter2 } from '@nestjs/event-emitter'; import { events } from '@/common/events/events'; import { BankRule } from '../models/BankRule'; import { CreateBankRuleDto } from '../dtos/BankRule.dto'; +import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; @Injectable() export class CreateBankRuleService { @@ -18,7 +19,8 @@ export class CreateBankRuleService { private readonly uow: UnitOfWork, private readonly eventPublisher: EventEmitter2, - @Inject(BankRule.name) private readonly bankRuleModel: typeof BankRule, + @Inject(BankRule.name) + private readonly bankRuleModel: TenantModelProxy, ) {} /** @@ -48,9 +50,11 @@ export class CreateBankRuleService { trx, } as IBankRuleEventCreatingPayload); - const bankRule = await this.bankRuleModel.query(trx).upsertGraphAndFetch({ - ...transformDTO, - }); + const bankRule = await this.bankRuleModel() + .query(trx) + .upsertGraphAndFetch({ + ...transformDTO, + }); // Triggers `onBankRuleCreated` event. await this.eventPublisher.emitAsync(events.bankRules.onCreated, { createRuleDTO, diff --git a/packages/server-nest/src/modules/BankingTranasctionsRegonize/commands/RevertRecognizedTransactions.service.ts b/packages/server-nest/src/modules/BankingTranasctionsRegonize/commands/RevertRecognizedTransactions.service.ts index b322dad49..f0bfc3922 100644 --- a/packages/server-nest/src/modules/BankingTranasctionsRegonize/commands/RevertRecognizedTransactions.service.ts +++ b/packages/server-nest/src/modules/BankingTranasctionsRegonize/commands/RevertRecognizedTransactions.service.ts @@ -5,6 +5,7 @@ import { RevertRecognizedTransactionsCriteria } from '../_types'; import { RecognizedBankTransaction } from '../models/RecognizedBankTransaction'; import { UncategorizedBankTransaction } from '@/modules/BankingTransactions/models/UncategorizedBankTransaction'; import { UnitOfWork } from '@/modules/Tenancy/TenancyDB/UnitOfWork.service'; +import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; @Injectable() export class RevertRecognizedTransactionsService { @@ -12,10 +13,14 @@ export class RevertRecognizedTransactionsService { private readonly uow: UnitOfWork, @Inject(RecognizedBankTransaction.name) - private readonly recognizedBankTransactionModel: typeof RecognizedBankTransaction, + private readonly recognizedBankTransactionModel: TenantModelProxy< + typeof RecognizedBankTransaction + >, @Inject(UncategorizedBankTransaction.name) - private readonly uncategorizedBankTransactionModel: typeof UncategorizedBankTransaction, + private readonly uncategorizedBankTransactionModel: TenantModelProxy< + typeof UncategorizedBankTransaction + >, ) {} /** @@ -36,32 +41,34 @@ export class RevertRecognizedTransactionsService { return this.uow.withTransaction(async (trx: Knex.Transaction) => { // Retrieves all the recognized transactions of the banbk rule. const uncategorizedTransactions = - await this.uncategorizedBankTransactionModel.query(trx).onBuild((q) => { - q.withGraphJoined('recognizedTransaction'); - q.whereNotNull('recognizedTransaction.id'); + await this.uncategorizedBankTransactionModel() + .query(trx) + .onBuild((q) => { + q.withGraphJoined('recognizedTransaction'); + q.whereNotNull('recognizedTransaction.id'); - if (rulesIds.length > 0) { - q.whereIn('recognizedTransaction.bankRuleId', rulesIds); - } - if (transactionsCriteria?.accountId) { - q.where('accountId', transactionsCriteria.accountId); - } - if (transactionsCriteria?.batch) { - q.where('batch', transactionsCriteria.batch); - } - }); + if (rulesIds.length > 0) { + q.whereIn('recognizedTransaction.bankRuleId', rulesIds); + } + if (transactionsCriteria?.accountId) { + q.where('accountId', transactionsCriteria.accountId); + } + if (transactionsCriteria?.batch) { + q.where('batch', transactionsCriteria.batch); + } + }); const uncategorizedTransactionIds = uncategorizedTransactions.map( (r) => r.id, ); - // Unlink the recongized transactions out of uncategorized transactions. - await this.uncategorizedBankTransactionModel + // Unlink the recognized transactions out of un-categorized transactions. + await this.uncategorizedBankTransactionModel() .query(trx) .whereIn('id', uncategorizedTransactionIds) .patch({ recognizedTransactionId: null, }); - // Delete the recognized bank transactions that assocaited to bank rule. - await this.recognizedBankTransactionModel + // Delete the recognized bank transactions that associated to bank rule. + await this.recognizedBankTransactionModel() .query(trx) .whereIn('uncategorizedTransactionId', uncategorizedTransactionIds) .delete(); diff --git a/packages/server-nest/src/modules/Features/FeaturesSettingsDriver.ts b/packages/server-nest/src/modules/Features/FeaturesSettingsDriver.ts index 68ababc77..306eece9a 100644 --- a/packages/server-nest/src/modules/Features/FeaturesSettingsDriver.ts +++ b/packages/server-nest/src/modules/Features/FeaturesSettingsDriver.ts @@ -21,7 +21,9 @@ export class FeaturesSettingsDriver { * @returns {Promise} */ async turnOn(feature: string) { - this.settings().set({ group: 'features', key: feature, value: true }); + const settingsStore = await this.settings(); + + settingsStore.set({ group: 'features', key: feature, value: true }); } /** @@ -30,24 +32,24 @@ export class FeaturesSettingsDriver { * @returns {Promise} */ async turnOff(feature: string) { - this.settings().set({ group: 'features', key: feature, value: false }); + const settingsStore = await this.settings(); + + settingsStore.set({ group: 'features', key: feature, value: false }); } /** - * Detarmines the given feature name is accessible. + * Determines the given feature name is accessible. * @param {string} feature - The feature name. * @returns {Promise} */ async accessible(feature: string) { + const settingsStore = await this.settings(); + const defaultValue = this.configure.getFeatureConfigure( feature, 'defaultValue', ); - const settingValue = this.settings().get( - { group: 'features', key: feature }, - defaultValue, - ); - return settingValue; + return settingsStore.get({ group: 'features', key: feature }, defaultValue); } /** @@ -55,11 +57,13 @@ export class FeaturesSettingsDriver { * @returns {Promise} */ async all(): Promise { - const mappedOpers = this.featuresConfigure.getConfigure().map(async (featureConfigure) => { - const { name, defaultValue } = featureConfigure; - const isAccessible = await this.accessible(featureConfigure.name); - return { name, isAccessible, defaultAccessible: defaultValue }; - }); + const mappedOpers = this.featuresConfigure + .getConfigure() + .map(async (featureConfigure) => { + const { name, defaultValue } = featureConfigure; + const isAccessible = await this.accessible(featureConfigure.name); + return { name, isAccessible, defaultAccessible: defaultValue }; + }); return Promise.all(mappedOpers); } } diff --git a/packages/server-nest/src/modules/InventoryCost/commands/InventoryTransactions.service.ts b/packages/server-nest/src/modules/InventoryCost/commands/InventoryTransactions.service.ts index 8880c9e60..d84af1520 100644 --- a/packages/server-nest/src/modules/InventoryCost/commands/InventoryTransactions.service.ts +++ b/packages/server-nest/src/modules/InventoryCost/commands/InventoryTransactions.service.ts @@ -1,6 +1,6 @@ // @ts-nocheck import { Knex } from 'knex'; -import { Inject } from '@nestjs/common'; +import { Inject, Injectable } from '@nestjs/common'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { IInventoryTransactionsDeletedPayload, @@ -14,6 +14,7 @@ import { transformItemEntriesToInventory } from '../utils'; import { IItemEntryTransactionType } from '../../TransactionItemEntry/ItemEntry.types'; import { ItemEntry } from '../../TransactionItemEntry/models/ItemEntry'; +@Injectable() export class InventoryTransactionsService { /** * @param {EventEmitter2} eventEmitter - Event emitter. @@ -143,7 +144,7 @@ export class InventoryTransactionsService { trx?: Knex.Transaction, ): Promise<{ oldInventoryTransactions: InventoryTransaction[] }> { // Retrieve the inventory transactions of the given sale invoice. - const oldInventoryTransactions = await this.inventoryTransactionModel + const oldInventoryTransactions = await this.inventoryTransactionModel() .query(trx) .where({ transactionId, transactionType }); diff --git a/packages/server-nest/src/modules/MailNotification/ContactMailNotification.ts b/packages/server-nest/src/modules/MailNotification/ContactMailNotification.ts index 9fab1a595..618c739dd 100644 --- a/packages/server-nest/src/modules/MailNotification/ContactMailNotification.ts +++ b/packages/server-nest/src/modules/MailNotification/ContactMailNotification.ts @@ -5,6 +5,7 @@ import { TenancyContext } from '../Tenancy/TenancyContext.service'; import { Customer } from '../Customers/models/Customer'; import { CommonMailOptions } from './MailNotification.types'; import { formatMessage } from '@/utils/format-message'; +import { TenantModelProxy } from '../System/models/TenantBaseModel'; @Injectable() export class ContactMailNotification { @@ -13,7 +14,7 @@ export class ContactMailNotification { private readonly tenantContext: TenancyContext, @Inject(Customer.name) - private readonly customerModel: typeof Customer, + private readonly customerModel: TenantModelProxy, ) {} /** @@ -26,7 +27,7 @@ export class ContactMailNotification { ): Promise< Pick > { - const customer = await this.customerModel + const customer = await this.customerModel() .query() .findById(customerId) .throwIfNotFound(); diff --git a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedGLEntries.ts b/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedGLEntries.ts index 401228102..908cfdcaa 100644 --- a/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedGLEntries.ts +++ b/packages/server-nest/src/modules/PaymentReceived/commands/PaymentReceivedGLEntries.ts @@ -8,6 +8,7 @@ import { Injectable } from '@nestjs/common'; import { Inject } from '@nestjs/common'; import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service'; import { Account } from '@/modules/Accounts/models/Account.model'; +import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel'; @Injectable() export class PaymentReceivedGLEntries { @@ -17,7 +18,9 @@ export class PaymentReceivedGLEntries { private readonly tenancyContext: TenancyContext, @Inject(PaymentReceived.name) - private readonly paymentReceivedModel: typeof PaymentReceived, + private readonly paymentReceivedModel: TenantModelProxy< + typeof PaymentReceived + >, ) {} /** @@ -28,13 +31,13 @@ export class PaymentReceivedGLEntries { */ public writePaymentGLEntries = async ( paymentReceiveId: number, - trx?: Knex.Transaction + trx?: Knex.Transaction, ): Promise => { // Retrieves the given tenant metadata. const tenantMeta = await this.tenancyContext.getTenantMetadata(); // Retrieves the payment receive with associated entries. - const paymentReceive = await this.paymentReceivedModel + const paymentReceive = await this.paymentReceivedModel() .query(trx) .findById(paymentReceiveId) .withGraphFetched('entries.invoice'); @@ -55,12 +58,12 @@ export class PaymentReceivedGLEntries { */ public revertPaymentGLEntries = async ( paymentReceiveId: number, - trx?: Knex.Transaction + trx?: Knex.Transaction, ) => { await this.ledgerStorage.deleteByReference( paymentReceiveId, 'PaymentReceive', - trx + trx, ); }; @@ -71,7 +74,7 @@ export class PaymentReceivedGLEntries { */ public rewritePaymentGLEntries = async ( paymentReceiveId: number, - trx?: Knex.Transaction + trx?: Knex.Transaction, ) => { // Reverts the payment GL entries. await this.revertPaymentGLEntries(paymentReceiveId, trx); @@ -94,12 +97,12 @@ export class PaymentReceivedGLEntries { // Retrieve the A/R account of the given currency. const receivableAccount = await this.accountRepository.findOrCreateAccountReceivable( - paymentReceive.currencyCode + paymentReceive.currencyCode, ); // Exchange gain/loss account. - const exGainLossAccount = await this.accountRepository.findBySlug( - 'exchange-grain-loss' - ) as Account; + const exGainLossAccount = (await this.accountRepository.findBySlug( + 'exchange-grain-loss', + )) as Account; const paymentReceivedGL = new PaymentReceivedGL(paymentReceive) .setARAccountId(receivableAccount.id) @@ -108,5 +111,4 @@ export class PaymentReceivedGLEntries { return paymentReceivedGL.getLedger(); }; - } diff --git a/packages/server-nest/src/modules/PdfTemplate/models/PdfTemplate.ts b/packages/server-nest/src/modules/PdfTemplate/models/PdfTemplate.ts index 9c315aedd..718208934 100644 --- a/packages/server-nest/src/modules/PdfTemplate/models/PdfTemplate.ts +++ b/packages/server-nest/src/modules/PdfTemplate/models/PdfTemplate.ts @@ -1,8 +1,6 @@ -// import { getUploadedObjectUri } from '@/services/Attachments/utils'; -import { BaseModel } from '@/models/Model'; -// import TenantModel from 'models/TenantModel'; +import { TenantBaseModel } from '@/modules/System/models/TenantBaseModel'; -export class PdfTemplateModel extends BaseModel { +export class PdfTemplateModel extends TenantBaseModel { public resource!: string; public templateName!: string; public predefined!: boolean; diff --git a/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.controller.ts b/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.controller.ts index fc9452f29..ae86afc0d 100644 --- a/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.controller.ts +++ b/packages/server-nest/src/modules/SaleInvoices/SaleInvoices.controller.ts @@ -151,7 +151,7 @@ export class SaleInvoicesController { return this.saleInvoiceApplication.getSaleInvoiceState(); } - @Post(':id/deliver') + @Put(':id/deliver') @ApiOperation({ summary: 'Deliver the given sale invoice.' }) @ApiResponse({ status: 200, diff --git a/packages/server-nest/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts b/packages/server-nest/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts index 6b1a052a6..7516e58cd 100644 --- a/packages/server-nest/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts +++ b/packages/server-nest/src/modules/SaleInvoices/dtos/SaleInvoice.dto.ts @@ -2,6 +2,7 @@ import { ItemEntryDto } from '@/modules/TransactionItemEntry/dto/ItemEntry.dto'; import { ApiProperty } from '@nestjs/swagger'; import { Type } from 'class-transformer'; import { + ArrayMinSize, IsArray, IsBoolean, IsDate, @@ -12,7 +13,6 @@ import { IsOptional, IsString, Min, - MinLength, ValidateNested, } from 'class-validator'; @@ -130,7 +130,7 @@ class CommandSaleInvoiceDto { @IsArray() @ValidateNested({ each: true }) @Type(() => ItemEntryDto) - @MinLength(1) + @ArrayMinSize(1) @ApiProperty({ description: 'Invoice line items', type: [ItemEntryDto], diff --git a/packages/server-nest/src/modules/Settings/commands/SaveSettings.service.ts b/packages/server-nest/src/modules/Settings/commands/SaveSettings.service.ts index 709f1a0f1..55b37b78e 100644 --- a/packages/server-nest/src/modules/Settings/commands/SaveSettings.service.ts +++ b/packages/server-nest/src/modules/Settings/commands/SaveSettings.service.ts @@ -16,7 +16,7 @@ export class SaveSettingsService { */ public async saveSettings(settingsDTO: ISettingsDTO) { const settingsStore = await this.settingsStore(); - const notDefinedOptions = this.validateNotDefinedSettings( + const notDefinedOptions = await this.validateNotDefinedSettings( settingsDTO.options, ); const errorReasons: { type: string; code: number; keys: any[] }[] = []; @@ -41,11 +41,12 @@ export class SaveSettingsService { * @param {Array} options * @return {Boolean} */ - private validateNotDefinedSettings(options) { + private async validateNotDefinedSettings(options) { const notDefined = []; + const settingStore = await this.settingsStore(); options.forEach((option) => { - const setting = this.settingsStore().config.getMetaConfig( + const setting = settingStore.config.getMetaConfig( option.key, option.group, ); diff --git a/packages/server-nest/src/modules/TaxRates/TaxRate.module.ts b/packages/server-nest/src/modules/TaxRates/TaxRate.module.ts index 57ccfc427..97d62856f 100644 --- a/packages/server-nest/src/modules/TaxRates/TaxRate.module.ts +++ b/packages/server-nest/src/modules/TaxRates/TaxRate.module.ts @@ -19,9 +19,13 @@ import { SaleInvoiceTaxRateValidateSubscriber } from './subscribers/SaleInvoiceT import { SyncItemTaxRateOnEditTaxSubscriber } from './subscribers/SyncItemTaxRateOnEditTaxSubscriber'; import { WriteTaxTransactionsItemEntries } from './WriteTaxTransactionsItemEntries'; import { SyncItemTaxRateOnEditTaxRate } from './SyncItemTaxRateOnEditTaxRate'; +import { RegisterTenancyModel } from '../Tenancy/TenancyModels/Tenancy.module'; +import { TaxRateTransaction } from './models/TaxRateTransaction.model'; + +const models = [RegisterTenancyModel(TaxRateTransaction)]; @Module({ - imports: [], + imports: [...models], controllers: [TaxRatesController], providers: [ CreateTaxRate, @@ -42,8 +46,8 @@ import { SyncItemTaxRateOnEditTaxRate } from './SyncItemTaxRateOnEditTaxRate'; SaleInvoiceTaxRateValidateSubscriber, SyncItemTaxRateOnEditTaxSubscriber, WriteTaxTransactionsItemEntries, - SyncItemTaxRateOnEditTaxRate + SyncItemTaxRateOnEditTaxRate, ], - exports: [ItemEntriesTaxTransactions], + exports: [ItemEntriesTaxTransactions, ...models], }) export class TaxRatesModule {} diff --git a/packages/server-nest/src/modules/TaxRates/WriteTaxTransactionsItemEntries.ts b/packages/server-nest/src/modules/TaxRates/WriteTaxTransactionsItemEntries.ts index a5eaeae45..1bbd403ce 100644 --- a/packages/server-nest/src/modules/TaxRates/WriteTaxTransactionsItemEntries.ts +++ b/packages/server-nest/src/modules/TaxRates/WriteTaxTransactionsItemEntries.ts @@ -1,19 +1,18 @@ import { sumBy, chain, keyBy } from 'lodash'; import { Knex } from 'knex'; -import { SaleInvoice } from '../SaleInvoices/models/SaleInvoice'; +import { ModelObject } from 'objection'; import { TenantModelProxy } from '../System/models/TenantBaseModel'; import { TaxRateModel } from './models/TaxRate.model'; import { Inject, Injectable } from '@nestjs/common'; -import { ModelObject } from 'objection'; import { ItemEntry } from '../TransactionItemEntry/models/ItemEntry'; import { TaxRateTransaction } from './models/TaxRateTransaction.model'; @Injectable() export class WriteTaxTransactionsItemEntries { constructor( - @Inject(SaleInvoice.name) + @Inject(TaxRateTransaction.name) private readonly taxRateTransactionModel: TenantModelProxy< - typeof SaleInvoice + typeof TaxRateTransaction >, @Inject(TaxRateModel.name) diff --git a/packages/server-nest/test/init-app-test.ts b/packages/server-nest/test/init-app-test.ts index 886566b36..443bdb77c 100644 --- a/packages/server-nest/test/init-app-test.ts +++ b/packages/server-nest/test/init-app-test.ts @@ -4,8 +4,9 @@ import { AppModule } from '../src/modules/App/App.module'; let app: INestApplication; -let orgainzationId = 'fxdo7u419m5ryy4tb'; -let authenticationToken = ''; +let orgainzationId = 'hpgpqhanm8s4921m'; +let authenticationToken = + 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiZXhwIjoxNzQ4MzExOTc5LjIzOCwiaWF0IjoxNzQzMTI3OTc5fQ.h3xvmuNjeyFeshEZRVRLCsARgTpx4xeZQHQuZzESm2U'; beforeAll(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({