refactor: settings module

This commit is contained in:
Ahmed Bouhuolia
2025-03-07 04:05:24 +02:00
parent b7d0b6c24a
commit 40b7daa2e3
44 changed files with 325 additions and 259 deletions

View File

@@ -1,23 +1,31 @@
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { SettingsStore } from '../Settings/SettingsStore';
import { SETTINGS_PROVIDER } from '../Settings/Settings.types';
import { transactionIncrement } from '@/utils/transaction-increment';
/**
* Auto increment orders service.
*/
@Injectable()
export class AutoIncrementOrdersService {
constructor(
@Inject(SETTINGS_PROVIDER)
private readonly settingsStore: () => SettingsStore,
) {}
/**
* Check if the auto increment is enabled for the given settings group.
* @param {string} settingsGroup - Settings group.
* @returns {boolean}
* @returns {Promise<boolean>}
*/
public autoIncrementEnabled = (settingsGroup: string): boolean => {
// const settings = this.tenancy.settings(tenantId);
// const group = settingsGroup;
public autoIncrementEnabled = async (
settingsGroup: string,
): Promise<boolean> => {
const settingsStore = await this.settingsStore();
const group = settingsGroup;
// // Settings service transaction number and prefix.
// return settings.get({ group, key: 'auto_increment' }, false);
return true;
// Settings service transaction number and prefix.
return settingsStore.get({ group, key: 'auto_increment' }, false);
};
/**
@@ -26,18 +34,18 @@ export class AutoIncrementOrdersService {
* @param {Function} getMaxTransactionNo
* @return {Promise<string>}
*/
getNextTransactionNumber(group: string): string {
// const settings = this.tenancy.settings(tenantId);
async getNextTransactionNumber(group: string): Promise<string> {
const settingsStore = await this.settingsStore();
// // Settings service transaction number and prefix.
// const autoIncrement = this.autoIncrementEnabled(tenantId, group);
// Settings service transaction number and prefix.
const autoIncrement = await this.autoIncrementEnabled(group);
// const settingNo = settings.get({ group, key: 'next_number' }, '');
// const settingPrefix = settings.get({ group, key: 'number_prefix' }, '');
// return autoIncrement ? `${settingPrefix}${settingNo}` : '';
return '1';
const settingNo = settingsStore.get({ group, key: 'next_number' }, '');
const settingPrefix = settingsStore.get(
{ group, key: 'number_prefix' },
'',
);
return autoIncrement ? `${settingPrefix}${settingNo}` : '';
}
/**
@@ -46,17 +54,19 @@ export class AutoIncrementOrdersService {
* @param {string} orderNumber -Order number.
*/
async incrementSettingsNextNumber(group: string) {
// const settings = this.tenancy.settings(tenantId);
// const settingNo = settings.get({ group, key: 'next_number' });
// const autoIncrement = settings.get({ group, key: 'auto_increment' });
const settingsStore = await this.settingsStore();
const settingNo = settingsStore.get({ group, key: 'next_number' });
const autoIncrement = settingsStore.get({ group, key: 'auto_increment' });
// // Can't continue if the auto-increment of the service was disabled.
// if (!autoIncrement) {
// return;
// }
// settings.set(
// { group, key: 'next_number' },
// transactionIncrement(settingNo)
// );
// await settings.save();
if (!autoIncrement) {
return;
}
settingsStore.set(
{ group, key: 'next_number' },
transactionIncrement(settingNo),
);
await settingsStore.save();
}
}

View File

@@ -11,7 +11,7 @@ export class BankTransactionAutoIncrement {
* Retrieve the next unique invoice number.
* @return {string}
*/
public getNextTransactionNumber = (): string => {
public getNextTransactionNumber = (): Promise<string> => {
return this.autoIncrementOrdersService.getNextTransactionNumber('cashflow');
};

View File

@@ -61,11 +61,11 @@ export class CreateBankTransactionService {
* @param {ICashflowNewCommandDTO} newCashflowTransactionDTO - New transaction DTO.
* @returns {ICashflowTransactionInput} - Cashflow transaction object.
*/
private transformCashflowTransactionDTO = (
private transformCashflowTransactionDTO = async (
newCashflowTransactionDTO: ICashflowNewCommandDTO,
cashflowAccount: Account,
userId: number,
): BankTransaction => {
): Promise<BankTransaction> => {
const amount = newCashflowTransactionDTO.amount;
const fromDTO = pick(newCashflowTransactionDTO, [
@@ -81,7 +81,7 @@ export class CreateBankTransactionService {
'uncategorizedTransactionId',
]);
// Retreive the next invoice number.
const autoNextNumber = this.autoIncrement.getNextTransactionNumber();
const autoNextNumber = await this.autoIncrement.getNextTransactionNumber();
// Retrieve the transaction number.
const transactionNumber =
@@ -134,7 +134,7 @@ export class CreateBankTransactionService {
await this.authorize(newTransactionDTO, creditAccount);
// Transformes owner contribution DTO to cashflow transaction.
const cashflowTransactionObj = this.transformCashflowTransactionDTO(
const cashflowTransactionObj = await this.transformCashflowTransactionDTO(
newTransactionDTO,
cashflowAccount,
userId,

View File

@@ -27,8 +27,14 @@ import { PaymentMadeBranchValidateSubscriber } from './subscribers/Validators/Pa
import { PaymentReceiveBranchValidateSubscriber } from './subscribers/Validators/PaymentReceiveBranchSubscriber';
import { SaleReceiptBranchValidateSubscriber } from './subscribers/Validators/SaleReceiptBranchesSubscriber';
import { VendorCreditBranchValidateSubscriber } from './subscribers/Validators/VendorCreditBranchSubscriber';
import { ValidateBranchExistance } from './Integrations/ValidateBranchExistance';
import { ManualJournalBranchesValidator } from './Integrations/ManualJournals/ManualJournalsBranchesValidator';
import { CashflowTransactionsActivateBranches } from './integrations/Cashflow/CashflowActivateBranches';
import { ExpensesActivateBranches } from './integrations/Expense/ExpensesActivateBranches';
import { FeaturesModule } from '../Features/Features.module';
@Module({
imports: [TenancyDatabaseModule],
imports: [TenancyDatabaseModule, FeaturesModule],
controllers: [BranchesController],
providers: [
CreateBranchService,
@@ -45,18 +51,22 @@ import { VendorCreditBranchValidateSubscriber } from './subscribers/Validators/V
BranchCommandValidator,
BranchTransactionDTOTransformer,
ManualJournalBranchesDTOTransformer,
BillBranchValidateSubscriber,
CreditNoteBranchValidateSubscriber,
CreditNoteRefundBranchValidateSubscriber,
ContactBranchValidateSubscriber,
ExpenseBranchValidateSubscriber,
InventoryAdjustmentBranchValidateSubscriber,
ManualJournalBranchValidateSubscriber,
PaymentMadeBranchValidateSubscriber,
PaymentReceiveBranchValidateSubscriber,
SaleEstimateBranchValidateSubscriber,
SaleReceiptBranchValidateSubscriber,
VendorCreditBranchValidateSubscriber,
// BillBranchValidateSubscriber,
// CreditNoteBranchValidateSubscriber,
// CreditNoteRefundBranchValidateSubscriber,
// ContactBranchValidateSubscriber,
// ExpenseBranchValidateSubscriber,
// InventoryAdjustmentBranchValidateSubscriber,
// ManualJournalBranchValidateSubscriber,
// PaymentMadeBranchValidateSubscriber,
// PaymentReceiveBranchValidateSubscriber,
// SaleEstimateBranchValidateSubscriber,
// SaleReceiptBranchValidateSubscriber,
// VendorCreditBranchValidateSubscriber,
// ValidateBranchExistance,
// ManualJournalBranchesValidator,
// CashflowTransactionsActivateBranches,
// ExpensesActivateBranches
],
exports: [
BranchesSettingsService,

View File

@@ -23,9 +23,6 @@ export class ActivateBranches {
private readonly createBranch: CreateBranchService,
private readonly branchesSettings: BranchesSettingsService,
private readonly i18n: I18nService,
@Inject(Branch.name)
private readonly branchModel: TenantModelProxy<typeof Branch>,
) {}
/**

View File

@@ -12,7 +12,7 @@ export class GetBranchesService {
/**
* Retrieves branches list.
* @returns
*/
*/
public getBranches = async () => {
const branches = await this.branch().query().orderBy('name', 'DESC');

View File

@@ -11,7 +11,7 @@ export class CreditNoteAutoIncrementService {
* Retrieve the next unique credit number.
* @return {string}
*/
public getNextCreditNumber(): string {
public getNextCreditNumber(): Promise<string> {
return this.autoIncrementOrdersService.getNextTransactionNumber(
'credit_note',
);

View File

@@ -2,12 +2,14 @@ import { Module } from '@nestjs/common';
import { FeaturesConfigureManager } from './FeaturesConfigureManager';
import { FeaturesManager } from './FeaturesManager';
import { FeaturesSettingsDriver } from './FeaturesSettingsDriver';
import { FeaturesConfigure } from './FeaturesConfigure';
@Module({
providers: [
FeaturesManager,
FeaturesSettingsDriver,
FeaturesConfigureManager,
FeaturesConfigure
],
exports: [FeaturesManager],
})

View File

@@ -8,7 +8,8 @@ export class FeaturesConfigure {
constructor(private readonly configService: ConfigService) {}
/**
*
* Get the feature configure.
* @returns {IFeatureConfiugration[]}
*/
getConfigure(): IFeatureConfiugration[] {

View File

@@ -9,10 +9,10 @@ import { FeaturesConfigure } from './FeaturesConfigure';
export class FeaturesSettingsDriver {
constructor(
private readonly configure: FeaturesConfigureManager,
private readonly featuresConfigure: FeaturesConfigure
private readonly featuresConfigure: FeaturesConfigure,
@Inject(SETTINGS_PROVIDER)
private readonly settings: SettingsStore,
private readonly settings: () => SettingsStore,
) {}
/**
@@ -21,7 +21,7 @@ export class FeaturesSettingsDriver {
* @returns {Promise<void>}
*/
async turnOn(feature: string) {
this.settings.set({ group: 'features', key: feature, value: true });
this.settings().set({ group: 'features', key: feature, value: true });
}
/**
@@ -30,7 +30,7 @@ export class FeaturesSettingsDriver {
* @returns {Promise<void>}
*/
async turnOff(feature: string) {
this.settings.set({ group: 'features', key: feature, value: false });
this.settings().set({ group: 'features', key: feature, value: false });
}
/**
@@ -43,7 +43,7 @@ export class FeaturesSettingsDriver {
feature,
'defaultValue',
);
const settingValue = this.settings.get(
const settingValue = this.settings().get(
{ group: 'features', key: feature },
defaultValue,
);

View File

@@ -27,7 +27,6 @@ export class ItemCategoryApplication {
/**
* Creates a new item category.
* @param {number} tenantId - The tenant id.
* @param {IItemCategoryOTD} itemCategoryDTO - The item category data.
* @returns {Promise<ItemCategory>} The created item category.
*/

View File

@@ -23,8 +23,9 @@ export class AutoIncrementManualJournal {
/**
* Retrieve the next journal number.
* @returns {Promise<string>}
*/
public getNextJournalNumber = (): string => {
public getNextJournalNumber = (): Promise<string> => {
return this.autoIncrementOrdersService.getNextTransactionNumber(
'manual_journals'
);

View File

@@ -46,7 +46,7 @@ export class PaymentReceiveDTOTransformer {
sumBy(paymentReceiveDTO.entries, 'paymentAmount');
// Retreive the next invoice number.
const autoNextNumber = this.increments.getNextPaymentReceiveNumber();
const autoNextNumber = await this.increments.getNextPaymentReceiveNumber();
// Retrieve the next payment receive number.
const paymentReceiveNo =

View File

@@ -12,9 +12,9 @@ export class PaymentReceivedIncrement {
/**
* Retrieve the next unique payment receive number.
* @return {string}
* @return {Promise<string>}
*/
public getNextPaymentReceiveNumber(): string {
public getNextPaymentReceiveNumber(): Promise<string> {
return this.autoIncrementOrdersService.getNextTransactionNumber(
'payment_receives',
);

View File

@@ -50,7 +50,7 @@ export class SaleEstimateDTOTransformer {
this.itemEntryModel().calcAmount(e),
);
// Retrieve the next invoice number.
const autoNextNumber = this.estimateIncrement.getNextEstimateNumber();
const autoNextNumber = await this.estimateIncrement.getNextEstimateNumber();
// Retrieve the next estimate number.
const estimateNumber =
@@ -103,11 +103,11 @@ export class SaleEstimateDTOTransformer {
* @param {ISaleEstimateDTO} saleEstimateDTO
* @param {ISaleEstimate} oldSaleEstimate
*/
public transformEstimateNumberToModel(
public async transformEstimateNumberToModel(
saleEstimateDTO: ISaleEstimateDTO,
oldSaleEstimate?: SaleEstimate,
): string {
const autoNextNumber = this.estimateIncrement.getNextEstimateNumber();
): Promise<string> {
const autoNextNumber = await this.estimateIncrement.getNextEstimateNumber();
if (saleEstimateDTO.estimateNumber) {
return saleEstimateDTO.estimateNumber;

View File

@@ -9,9 +9,9 @@ export class SaleEstimateIncrement {
/**
* Retrieve the next unique estimate number.
* @return {string}
* @return {Promise<string>}
*/
public getNextEstimateNumber(): string {
public getNextEstimateNumber(): Promise<string> {
return this.autoIncrementOrdersService.getNextTransactionNumber(
'sales_estimates',
);

View File

@@ -1,78 +1,73 @@
// import { Inject, Service } from 'typedi';
// import { Knex } from 'knex';
// import { ISaleInvoice } from '@/interfaces';
// import ItemsEntriesService from '@/services/Items/ItemsEntriesService';
// import InventoryService from '@/services/Inventory/Inventory';
import { Knex } from 'knex';
import { Injectable } from '@nestjs/common';
import { ItemsEntriesService } from '../Items/ItemsEntries.service';
import { ModelObject } from 'objection';
import { SaleInvoice } from './models/SaleInvoice';
// @Service()
// export class InvoiceInventoryTransactions {
// @Inject()
// private itemsEntriesService: ItemsEntriesService;
@Injectable()
export class InvoiceInventoryTransactions {
constructor(
private readonly itemsEntriesService: ItemsEntriesService,
// private readonly inventoryService: InventoryService,
) {}
// @Inject()
// private inventoryService: InventoryService;
/**
* Records the inventory transactions of the given sale invoice in case
* the invoice has inventory entries only.
*
* @param {number} tenantId - Tenant id.
* @param {SaleInvoice} saleInvoice - Sale invoice DTO.
* @param {number} saleInvoiceId - Sale invoice id.
* @param {boolean} override - Allow to override old transactions.
* @return {Promise<void>}
*/
public async recordInventoryTranscactions(
saleInvoice: ModelObject<SaleInvoice>,
override?: boolean,
trx?: Knex.Transaction,
): Promise<void> {
// Loads the inventory items entries of the given sale invoice.
const inventoryEntries =
await this.itemsEntriesService.filterInventoryEntries(
saleInvoice.entries,
trx,
);
const transaction = {
transactionId: saleInvoice.id,
transactionType: 'SaleInvoice',
transactionNumber: saleInvoice.invoiceNo,
// /**
// * Records the inventory transactions of the given sale invoice in case
// * the invoice has inventory entries only.
// *
// * @param {number} tenantId - Tenant id.
// * @param {SaleInvoice} saleInvoice - Sale invoice DTO.
// * @param {number} saleInvoiceId - Sale invoice id.
// * @param {boolean} override - Allow to override old transactions.
// * @return {Promise<void>}
// */
// public async recordInventoryTranscactions(
// tenantId: number,
// saleInvoice: ISaleInvoice,
// override?: boolean,
// trx?: Knex.Transaction
// ): Promise<void> {
// // Loads the inventory items entries of the given sale invoice.
// const inventoryEntries =
// await this.itemsEntriesService.filterInventoryEntries(
// tenantId,
// saleInvoice.entries,
// trx
// );
// const transaction = {
// transactionId: saleInvoice.id,
// transactionType: 'SaleInvoice',
// transactionNumber: saleInvoice.invoiceNo,
exchangeRate: saleInvoice.exchangeRate,
warehouseId: saleInvoice.warehouseId,
// exchangeRate: saleInvoice.exchangeRate,
// warehouseId: saleInvoice.warehouseId,
// date: saleInvoice.invoiceDate,
// direction: 'OUT',
// entries: inventoryEntries,
// createdAt: saleInvoice.createdAt,
// };
// await this.inventoryService.recordInventoryTransactionsFromItemsEntries(
// tenantId,
// transaction,
// override,
// trx
// );
// }
// /**
// * Reverting the inventory transactions once the invoice deleted.
// * @param {number} tenantId - Tenant id.
// * @param {number} billId - Bill id.
// * @return {Promise<void>}
// */
// public async revertInventoryTransactions(
// tenantId: number,
// saleInvoiceId: number,
// trx?: Knex.Transaction
// ): Promise<void> {
// // Delete the inventory transaction of the given sale invoice.
// const { oldInventoryTransactions } =
// await this.inventoryService.deleteInventoryTransactions(
// tenantId,
// saleInvoiceId,
// 'SaleInvoice',
// trx
// );
// }
// }
date: saleInvoice.invoiceDate,
direction: 'OUT',
entries: inventoryEntries,
createdAt: saleInvoice.createdAt,
};
// await this.inventoryService.recordInventoryTransactionsFromItemsEntries(
// transaction,
// override,
// trx,
// );
}
/**
* Reverting the inventory transactions once the invoice deleted.
* @param {number} tenantId - Tenant id.
* @param {number} billId - Bill id.
* @return {Promise<void>}
*/
public async revertInventoryTransactions(
tenantId: number,
saleInvoiceId: number,
trx?: Knex.Transaction,
): Promise<void> {
// Delete the inventory transaction of the given sale invoice.
// const { oldInventoryTransactions } =
// await this.inventoryService.deleteInventoryTransactions(
// saleInvoiceId,
// 'SaleInvoice',
// trx,
// );
}
}

View File

@@ -43,7 +43,7 @@ export class CommandSaleInvoiceDTOTransformer {
private invoiceIncrement: SaleInvoiceIncrement,
private taxDTOTransformer: ItemEntriesTaxTransactions,
private brandingTemplatesTransformer: BrandingTemplateDTOTransformer,
private tenancyContext: TenancyContext
private tenancyContext: TenancyContext,
) {}
/**
@@ -61,7 +61,7 @@ export class CommandSaleInvoiceDTOTransformer {
const amount = this.getDueBalanceItemEntries(entriesModels);
// Retreive the next invoice number.
const autoNextNumber = this.invoiceIncrement.getNextInvoiceNumber();
const autoNextNumber = await this.invoiceIncrement.getNextInvoiceNumber();
// Retrieve the authorized user.
const authorizedUser = await this.tenancyContext.getSystemUser();

View File

@@ -10,9 +10,9 @@ export class SaleInvoiceIncrement {
/**
* Retrieves the next unique invoice number.
* @param {number} tenantId - Tenant id.
* @return {string}
* @return {Promise<string>}
*/
public getNextInvoiceNumber(): string {
public getNextInvoiceNumber(): Promise<string> {
return this.autoIncrementOrdersService.getNextTransactionNumber(
'sales_invoices',
);

View File

@@ -12,7 +12,7 @@ export class SaleReceiptIncrement {
* @param {number} tenantId - Tenant id.
* @return {string}
*/
public getNextReceiptNumber(): string {
public getNextReceiptNumber(): Promise<string> {
return this.autoIncrementOrdersService.getNextTransactionNumber(
'sales_receipts',
);

View File

@@ -1,4 +1,4 @@
import { Module } from '@nestjs/common';
import { Global, Module } from '@nestjs/common';
import { SettingRepository } from './repositories/Setting.repository';
import { SettingsStore } from './SettingsStore';
import { SettingsApplicationService } from './SettingsApplication.service';
@@ -6,13 +6,15 @@ import { SaveSettingsService } from './commands/SaveSettings.service';
import { SettingsController } from './Settings.controller';
import { SETTINGS_PROVIDER } from './Settings.types';
import { GetSettingsService } from './queries/GetSettings.service';
import { ClsModule } from 'nestjs-cls';
@Global()
@Module({
providers: [
SettingRepository,
{
imports: [
ClsModule.forFeatureAsync({
provide: SETTINGS_PROVIDER,
useFactory: async (settingRepository: SettingRepository) => {
inject: [SettingRepository],
useFactory: (settingRepository: SettingRepository) => async () => {
const settings = new SettingsStore(settingRepository);
// Load settings from database.
@@ -20,13 +22,18 @@ import { GetSettingsService } from './queries/GetSettings.service';
return settings;
},
inject: [SettingRepository],
},
global: true,
strict: true,
type: 'function',
}),
],
providers: [
SettingRepository,
GetSettingsService,
SettingsApplicationService,
SaveSettingsService,
],
exports: [SettingRepository],
controllers: [SettingsController],
exports: [SETTINGS_PROVIDER],
})
export class SettingsModule {}

View File

@@ -7,7 +7,7 @@ import { IOptionDTO, ISettingsDTO, SETTINGS_PROVIDER } from '../Settings.types';
export class SaveSettingsService {
constructor(
@Inject(SETTINGS_PROVIDER)
private readonly settingsStore: SettingsStore,
private readonly settingsStore: () => SettingsStore,
) {}
/**
@@ -15,6 +15,7 @@ export class SaveSettingsService {
* @param {ISettingsDTO} settingsDTO
*/
public async saveSettings(settingsDTO: ISettingsDTO) {
const settingsStore = await this.settingsStore();
const notDefinedOptions = this.validateNotDefinedSettings(
settingsDTO.options,
);
@@ -30,9 +31,9 @@ export class SaveSettingsService {
throw new Error(JSON.stringify(errorReasons));
}
settingsDTO.options.forEach((option: IOptionDTO) => {
this.settingsStore.set({ ...option });
settingsStore.set({ ...option });
});
await this.settingsStore.save();
await settingsStore.save();
}
/**
@@ -44,7 +45,7 @@ export class SaveSettingsService {
const notDefined = [];
options.forEach((option) => {
const setting = this.settingsStore.config.getMetaConfig(
const setting = this.settingsStore().config.getMetaConfig(
option.key,
option.group,
);

View File

@@ -5,10 +5,11 @@ import { SETTINGS_PROVIDER } from '../Settings.types';
@Injectable()
export class GetSettingsService {
constructor(
@Inject(SETTINGS_PROVIDER) private readonly settingsStore: SettingsStore,
@Inject(SETTINGS_PROVIDER)
private readonly settingsStore: () => SettingsStore,
) {}
public async execute() {
return this.settingsStore.all();
return (await this.settingsStore()).all();
}
}

View File

@@ -1,13 +1,14 @@
import { Knex } from 'knex';
import { Inject } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { TenantRepository } from '@/common/repository/TenantRepository';
import { TENANCY_DB_CONNECTION } from '@/modules/Tenancy/TenancyDB/TenancyDB.constants';
import { Setting } from '../models/Setting';
@Injectable()
export class SettingRepository extends TenantRepository {
constructor(
@Inject(TENANCY_DB_CONNECTION)
private readonly tenantKnex: Knex,
private readonly tenantKnex: () => Knex,
) {
super();
}
@@ -16,6 +17,6 @@ export class SettingRepository extends TenantRepository {
* Gets the repository's model.
*/
get model(): typeof Setting {
return Setting.bindKnex(this.tenantKnex);
return Setting.bindKnex(this.tenantKnex());
}
}

View File

@@ -85,8 +85,6 @@ const models = [
* @param model The model class to register
*/
export function RegisterTenancyModel(model: typeof Model) {
console.log(model.name);
return ClsModule.forFeatureAsync({
provide: model.name,
inject: [TENANCY_DB_CONNECTION],

View File

@@ -8,11 +8,13 @@ import {
import { Inject, Injectable } from '@nestjs/common';
import { SettingsStore } from '../Settings/SettingsStore';
import { SETTINGS_PROVIDER } from '../Settings/Settings.types';
import { SettingsApplicationService } from '../Settings/SettingsApplication.service';
@Injectable()
export class TransactionsLockingRepository {
constructor(
@Inject(SETTINGS_PROVIDER) private readonly settingsStore: SettingsStore,
@Inject(SETTINGS_PROVIDER)
private readonly settingsStore: () => SettingsStore,
) {}
/**
@@ -25,57 +27,58 @@ export class TransactionsLockingRepository {
transactionlocking,
) {
const group = `transactions-locking`;
const settingsStore = await this.settingsStore();
if (!isUndefined(transactionlocking.active)) {
this.settingsStore.set({
settingsStore.set({
group,
key: `${lockingGroup}.active`,
value: transactionlocking.active,
});
}
if (!isUndefined(transactionlocking.lockToDate)) {
this.settingsStore.set({
settingsStore.set({
group,
key: `${lockingGroup}.lock_to_date`,
value: parseDate(transactionlocking.lockToDate),
});
}
if (!isUndefined(transactionlocking.unlockFromDate)) {
this.settingsStore.set({
settingsStore.set({
group,
key: `${lockingGroup}.unlock_from_date`,
value: parseDate(transactionlocking.unlockFromDate),
});
}
if (!isUndefined(transactionlocking.unlockToDate)) {
this.settingsStore.set({
settingsStore.set({
group,
key: `${lockingGroup}.unlock_to_date`,
value: parseDate(transactionlocking.unlockToDate),
});
}
if (!isUndefined(transactionlocking.lockReason)) {
this.settingsStore.set({
settingsStore.set({
group,
key: `${lockingGroup}.lock_reason`,
value: transactionlocking.lockReason,
});
}
if (!isUndefined(transactionlocking.unlockReason)) {
this.settingsStore.set({
settingsStore.set({
group,
key: `${lockingGroup}.unlock_reason`,
value: transactionlocking.unlockReason,
});
}
if (!isUndefined(transactionlocking.partialUnlockReason)) {
this.settingsStore.set({
settingsStore.set({
group,
key: `${lockingGroup}.partial_unlock_reason`,
value: transactionlocking.partialUnlockReason,
});
}
await this.settingsStore.save();
await settingsStore.save();
}
/**
@@ -83,40 +86,41 @@ export class TransactionsLockingRepository {
* @param {string} lockingGroup - The group of the transactions locking
* @returns {ITransactionMeta} - The transactions locking settings
*/
public getTransactionsLocking(
public async getTransactionsLocking(
lockingGroup: string = TransactionsLockingGroup.All,
): ITransactionMeta {
): Promise<ITransactionMeta> {
const group = `transactions-locking`;
const settingsStore = await this.settingsStore();
const isEnabled = this.settingsStore.get({
const isEnabled = settingsStore.get({
group,
key: `${lockingGroup}.active`,
});
const lockFromDate = this.settingsStore.get({
const lockFromDate = settingsStore.get({
group,
key: `${lockingGroup}.lock_from_date`,
});
const lockToDate = this.settingsStore.get({
const lockToDate = settingsStore.get({
group,
key: `${lockingGroup}.lock_to_date`,
});
const unlockFromDate = this.settingsStore.get({
const unlockFromDate = settingsStore.get({
group,
key: `${lockingGroup}.unlock_from_date`,
});
const unlockToDate = this.settingsStore.get({
const unlockToDate = settingsStore.get({
group,
key: `${lockingGroup}.unlock_to_date`,
});
const lockReason = this.settingsStore.get({
const lockReason = settingsStore.get({
group,
key: `${lockingGroup}.lock_reason`,
});
const unlockReason = this.settingsStore.get({
const unlockReason = settingsStore.get({
group,
key: `${lockingGroup}.unlock_reason`,
});
const partialUnlockReason = this.settingsStore.get({
const partialUnlockReason = settingsStore.get({
group,
key: `${lockingGroup}.partial_unlock_reason`,
});
@@ -137,8 +141,10 @@ export class TransactionsLockingRepository {
* Get transactions locking type
* @returns {string} - The transactions locking type
*/
public getTransactionsLockingType() {
const lockingType = this.settingsStore.get({
public async getTransactionsLockingType() {
const settingsStore = await this.settingsStore();
const lockingType = settingsStore.get({
group: 'transactions-locking',
key: 'locking-type',
});
@@ -149,14 +155,17 @@ export class TransactionsLockingRepository {
* Flag transactions locking type
* @param {TransactionsLockingType} transactionsType - The transactions locking type
*/
public flagTransactionsLockingType(
public async flagTransactionsLockingType(
transactionsType: TransactionsLockingType,
) {
this.settingsStore.set({
const settingsStore = await this.settingsStore();
settingsStore.set({
group: 'transactions-locking',
key: 'locking-type',
value: transactionsType,
});
await settingsStore.save();
}
}

View File

@@ -27,8 +27,8 @@ export class TransactionsLockingService {
/**
* Enable/disable all transacations locking.
* @param {TransactionsLockingGroup} module - The transaction locking module.
* @param {Partial<ITransactionsLockingAllDTO>} allLockingDTO
* @param {TransactionsLockingGroup} module - The transaction locking module.
* @param {Partial<ITransactionsLockingAllDTO>} allLockingDTO
* @returns {Promise<ITransactionMeta>}
*/
public commandTransactionsLocking = async (
@@ -64,8 +64,8 @@ export class TransactionsLockingService {
/**
* Cancels the full transactions locking.
* @param {TransactionsLockingGroup} module - The transaction locking module.
* @param {ICancelTransactionsLockingDTO} cancelLockingDTO
* @param {TransactionsLockingGroup} module - The transaction locking module.
* @param {ICancelTransactionsLockingDTO} cancelLockingDTO
* @returns {Promise<ITransactionMeta>}
*/
public cancelTransactionLocking = async (
@@ -112,7 +112,7 @@ export class TransactionsLockingService {
// Retrieve the current transactions locking type.
const lockingType =
this.transactionsLockingRepo.getTransactionsLockingType();
await this.transactionsLockingRepo.getTransactionsLockingType();
if (moduleGroup !== TransactionsLockingGroup.All) {
this.validateLockingTypeNotAll(lockingType);

View File

@@ -13,8 +13,8 @@ export class FinancialTransactionLocking {
* @param {Date} transactionDate - The transaction date.
* @throws {ServiceError(TRANSACTIONS_DATE_LOCKED)}
*/
public transactionLockingGuard = (transactionDate: Date) => {
this.transactionLockingGuardService.transactionsLockingGuard(
public transactionLockingGuard = async (transactionDate: Date) => {
await this.transactionLockingGuardService.transactionsLockingGuard(
transactionDate,
TransactionsLockingGroup.Financial,
);

View File

@@ -16,7 +16,7 @@ export class PurchasesTransactionLockingGuard {
public transactionLockingGuard = async (
transactionDate: MomentInput
) => {
this.transactionLockingGuardService.transactionsLockingGuard(
await this.transactionLockingGuardService.transactionsLockingGuard(
transactionDate,
TransactionsLockingGroup.Purchases
);

View File

@@ -18,14 +18,12 @@ export class TransactionsLockingGuard {
* @param {TransactionsLockingGroup} lockingGroup - The transaction group.
* @returns {boolean}
*/
public isTransactionsLocking = (
public isTransactionsLocking = async (
transactionDate: MomentInput,
lockingGroup: string = TransactionsLockingGroup.All
): boolean => {
lockingGroup: string = TransactionsLockingGroup.All,
): Promise<boolean> => {
const { isEnabled, unlockFromDate, unlockToDate, lockToDate } =
this.transactionsLockingRepo.getTransactionsLocking(
lockingGroup
);
await this.transactionsLockingRepo.getTransactionsLocking(lockingGroup);
// Returns false anyway in case if the transaction locking is disabled.
if (!isEnabled) return false;
@@ -49,14 +47,15 @@ export class TransactionsLockingGuard {
*
* @throws {ServiceError}
*/
public validateTransactionsLocking = (
public validateTransactionsLocking = async (
transactionDate: MomentInput,
lockingGroup: TransactionsLockingGroup
lockingGroup: TransactionsLockingGroup,
) => {
const isLocked = this.isTransactionsLocking(
const isLocked = await this.isTransactionsLocking(
transactionDate,
lockingGroup
lockingGroup,
);
if (isLocked) {
this.throwTransactionsLockError(lockingGroup);
}
@@ -66,12 +65,11 @@ export class TransactionsLockingGuard {
* Throws transactions locking error.
* @param {TransactionsLockingGroup} lockingGroup - The transaction group.
*/
public throwTransactionsLockError = (
lockingGroup: TransactionsLockingGroup
public throwTransactionsLockError = async (
lockingGroup: TransactionsLockingGroup,
) => {
const { lockToDate } = this.transactionsLockingRepo.getTransactionsLocking(
lockingGroup
);
const { lockToDate } =
await this.transactionsLockingRepo.getTransactionsLocking(lockingGroup);
throw new ServiceError(ERRORS.TRANSACTIONS_DATE_LOCKED, null, {
lockedToDate: lockToDate,
formattedLockedToDate: moment(lockToDate).format('YYYY/MM/DD'),
@@ -83,24 +81,21 @@ export class TransactionsLockingGuard {
* @param {TransactionsLockingGroup} lockingGroup - The transaction group.
* @param {Date} transactionDate - The transaction date.
*/
public transactionsLockingGuard = (
public transactionsLockingGuard = async (
transactionDate: MomentInput,
moduleType: TransactionsLockingGroup
moduleType: TransactionsLockingGroup,
) => {
const lockingType =
this.transactionsLockingRepo.getTransactionsLockingType();
await this.transactionsLockingRepo.getTransactionsLockingType();
//
if (lockingType === TransactionsLockingGroup.All) {
return this.validateTransactionsLocking(
transactionDate,
TransactionsLockingGroup.All
TransactionsLockingGroup.All,
);
}
//
return this.validateTransactionsLocking(
transactionDate,
moduleType
);
return this.validateTransactionsLocking(transactionDate, moduleType);
};
}

View File

@@ -21,7 +21,7 @@ export class QueryTransactionsLocking {
* Retrieve transactions locking modules.
* @returns {ITransactionLockingMetaPOJO[]}
*/
public getTransactionsLockingModules = (): Promise<
public getTransactionsLockingModules = async (): Promise<
ITransactionLockingMetaPOJO[]
> => {
const modules = TRANSACTIONS_LOCKING_SCHEMA.map(
@@ -47,10 +47,12 @@ export class QueryTransactionsLocking {
* @param {TransactionsLockingGroup} module -
* @returns {ITransactionLockingMetaPOJO}
*/
public getTransactionsLockingModuleMeta = (
public getTransactionsLockingModuleMeta = async (
module: TransactionsLockingGroup,
): Promise<ITransactionLockingMetaPOJO> => {
const meta = this.transactionsLockingRepo.getTransactionsLocking(module);
const meta =
await this.transactionsLockingRepo.getTransactionsLocking(module);
return this.transformer.transform(
meta,
new TransactionsLockingMetaTransformer(),
@@ -66,7 +68,7 @@ export class QueryTransactionsLocking {
async (): Promise<ITransactionsLockingListPOJO> => {
// Retrieve the current transactions locking type.
const lockingType =
this.transactionsLockingRepo.getTransactionsLockingType();
await this.transactionsLockingRepo.getTransactionsLockingType();
const all = await this.getTransactionsLockingAll();
const modules = await this.getTransactionsLockingModules();

View File

@@ -61,7 +61,7 @@ export class CreateVendorCreditService {
);
// Transforms the credit DTO to storage layer.
const vendorCreditModel =
this.vendorCreditDTOTransformService.transformCreateEditDTOToModel(
await this.vendorCreditDTOTransformService.transformCreateEditDTOToModel(
vendorCreditCreateDTO,
vendor.currencyCode,
);

View File

@@ -74,7 +74,7 @@ export class EditVendorCreditService {
);
// Transformes edit DTO to model storage layer.
const vendorCreditModel =
this.vendorCreditDTOTransform.transformCreateEditDTOToModel(
await this.vendorCreditDTOTransform.transformCreateEditDTOToModel(
vendorCreditDTO,
vendor.currencyCode,
oldVendorCredit,

View File

@@ -14,7 +14,7 @@ export class VendorCreditAutoIncrementService {
* @param {number} tenantId - Tenant id.
* @return {string}
*/
public getNextCreditNumber = (): string => {
public getNextCreditNumber = (): Promise<string> => {
return this.autoIncrementOrdersService.getNextTransactionNumber(
'vendor_credit',
);
@@ -22,7 +22,6 @@ export class VendorCreditAutoIncrementService {
/**
* Increment the vendor credit serial next number.
* @param {number} tenantId -
*/
public incrementSerialNumber = () => {
return this.autoIncrementOrdersService.incrementSettingsNextNumber(

View File

@@ -38,11 +38,11 @@ export class VendorCreditDTOTransformService {
* @param {IVendorCredit} oldVendorCredit -
* @returns {VendorCredit}
*/
public transformCreateEditDTOToModel = (
public transformCreateEditDTOToModel = async (
vendorCreditDTO: IVendorCreditCreateDTO | IVendorCreditEditDTO,
vendorCurrencyCode: string,
oldVendorCredit?: VendorCredit,
): VendorCredit => {
): Promise<VendorCredit> => {
// Calculates the total amount of items entries.
const amount = this.itemsEntriesService.getTotalItemsEntries(
vendorCreditDTO.entries,
@@ -59,7 +59,8 @@ export class VendorCreditDTOTransformService {
)(vendorCreditDTO.entries);
// Retreive the next vendor credit number.
const autoNextNumber = this.vendorCreditAutoIncrement.getNextCreditNumber();
const autoNextNumber =
await this.vendorCreditAutoIncrement.getNextCreditNumber();
// Detarmines the credit note number.
const vendorCreditNumber =

View File

@@ -1,11 +1,12 @@
import { Knex } from 'knex';
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { AccountTransaction } from '../Accounts/models/AccountTransaction.model';
import { TenantModelProxy } from '../System/models/TenantBaseModel';
@Injectable()
export class InventoryTransactionsWarehouses {
constructor(
@Inject(AccountTransaction.name)
private readonly accountTransactionModel: TenantModelProxy<typeof AccountTransaction>,
) {}

View File

@@ -1,13 +1,16 @@
import { Injectable } from "@nestjs/common";
import { Warehouse } from "../models/Warehouse.model";
import { TenantModelProxy } from "@/modules/System/models/TenantBaseModel";
import { Bill } from "@/modules/Bills/models/Bill";
import { ItemEntry } from "@/modules/TransactionItemEntry/models/ItemEntry";
import { Inject, Injectable } from '@nestjs/common';
import { Warehouse } from '../models/Warehouse.model';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { Bill } from '@/modules/Bills/models/Bill';
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
@Injectable()
export class BillActivateWarehouses {
constructor(
@Inject(Bill.name)
private readonly billModel: TenantModelProxy<typeof Bill>,
@Inject(ItemEntry.name)
private readonly itemEntryModel: TenantModelProxy<typeof ItemEntry>,
) {}
@@ -17,18 +20,15 @@ export class BillActivateWarehouses {
* @returns {Promise<void>}
*/
public updateBillsWithWarehouse = async (
primaryWarehouse: Warehouse
primaryWarehouse: Warehouse,
): Promise<void> => {
// Updates the sale estimates with primary warehouse.
await this.billModel().query().update({
warehouseId: primaryWarehouse.id,
});
// Update the sale estimates entries with primary warehouse.
await this.itemEntryModel()
.query()
.where('referenceType', 'Bill')
.update({
warehouseId: primaryWarehouse.id,
});
await this.itemEntryModel().query().where('referenceType', 'Bill').update({
warehouseId: primaryWarehouse.id,
});
};
}

View File

@@ -1,13 +1,16 @@
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
import { CreditNote } from '@/modules/CreditNotes/models/CreditNote';
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { Warehouse } from '../models/Warehouse.model';
@Injectable()
export class CreditNotesActivateWarehouses {
constructor(
@Inject(CreditNote.name)
private readonly creditNoteModel: TenantModelProxy<typeof CreditNote>,
@Inject(ItemEntry.name)
private readonly itemEntryModel: TenantModelProxy<typeof ItemEntry>,
) {}

View File

@@ -1,16 +1,18 @@
import { Injectable } from "@nestjs/common";
import { Warehouse } from "../models/Warehouse.model";
import { SaleInvoice } from "@/modules/SaleInvoices/models/SaleInvoice";
import { ItemEntry } from "@/modules/TransactionItemEntry/models/ItemEntry";
import { TenantModelProxy } from "@/modules/System/models/TenantBaseModel";
import { Inject, Injectable } from '@nestjs/common';
import { Warehouse } from '../models/Warehouse.model';
import { SaleInvoice } from '@/modules/SaleInvoices/models/SaleInvoice';
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable()
export class InvoicesActivateWarehouses {
constructor(
@Inject(SaleInvoice.name)
private readonly saleInvoiceModel: TenantModelProxy<typeof SaleInvoice>,
@Inject(ItemEntry.name)
private readonly itemEntryModel: TenantModelProxy<typeof ItemEntry>,
) {}
/**
* Updates all inventory transactions with the primary warehouse.
@@ -18,7 +20,7 @@ export class InvoicesActivateWarehouses {
* @returns {Promise<void>}
*/
updateInvoicesWithWarehouse = async (
primaryWarehouse: Warehouse
primaryWarehouse: Warehouse,
): Promise<void> => {
// Updates the sale invoices with primary warehouse.
await this.saleInvoiceModel().query().update({

View File

@@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
import { Warehouse } from '../models/Warehouse.model';
@@ -7,7 +7,10 @@ import { SaleReceipt } from '@/modules/SaleReceipts/models/SaleReceipt';
@Injectable()
export class ReceiptActivateWarehouses {
constructor(
@Inject(SaleReceipt.name)
private readonly saleReceiptModel: TenantModelProxy<typeof SaleReceipt>,
@Inject(ItemEntry.name)
private readonly itemEntryModel: TenantModelProxy<typeof ItemEntry>,
) {}

View File

@@ -2,12 +2,15 @@ import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { VendorCredit } from '@/modules/VendorCredit/models/VendorCredit';
import { ItemEntry } from '@/modules/TransactionItemEntry/models/ItemEntry';
import { Warehouse } from '../models/Warehouse.model';
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
@Injectable()
export class VendorCreditActivateWarehouses {
constructor(
@Inject(VendorCredit.name)
private readonly vendorCreditModel: TenantModelProxy<typeof VendorCredit>,
@Inject(ItemEntry.name)
private readonly itemEntryModel: TenantModelProxy<typeof ItemEntry>,
) {}

View File

@@ -1,5 +1,5 @@
import { chain, difference } from 'lodash';
import { Injectable } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { ERRORS } from './constants';
import { ServiceError } from '@/modules/Items/ServiceError';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@@ -11,6 +11,7 @@ export class ValidateWarehouseExistance {
* @param {TenantModelProxy<typeof Warehouse>} warehouseModel - Warehouse model.
*/
constructor(
@Inject(Warehouse.name)
private readonly warehouseModel: TenantModelProxy<typeof Warehouse>,
) {}

View File

@@ -31,9 +31,22 @@ import { SaleReceiptWarehousesValidateSubscriber } from './subscribers/Validator
import { CreditNoteWarehousesValidateSubscriber } from './subscribers/Validators/Sales/CreditNoteWarehousesSubscriber';
import { BillWarehousesValidateSubscriber } from './subscribers/Validators/Purchases/BillWarehousesSubscriber';
import { AccountsTransactionsWarehousesSubscribe } from './AccountsTransactionsWarehousesSubscribe';
import { BillActivateWarehouses } from './Activate/BillWarehousesActivate';
import { CreditNotesActivateWarehouses } from './Activate/CreditNoteWarehousesActivate';
import { VendorCreditActivateWarehouses } from './Activate/VendorCreditWarehousesActivate';
import { InvoicesActivateWarehouses } from './Activate/InvoiceWarehousesActivate';
import { ReceiptActivateWarehouses } from './Activate/ReceiptWarehousesActivate';
import { WarehousesDTOValidators } from './Integrations/WarehousesDTOValidators';
import { DeleteItemWarehousesQuantity } from './commands/DeleteItemWarehousesQuantity';
import { InventoryTransactionsWarehouses } from './AccountsTransactionsWarehouses';
import { RegisterTenancyModel } from '../Tenancy/TenancyModels/Tenancy.module';
import { Warehouse } from './models/Warehouse.model';
import { ValidateWarehouseExistance } from './Integrations/ValidateWarehouseExistance';
const models = [RegisterTenancyModel(Warehouse)];
@Module({
imports: [TenancyDatabaseModule],
imports: [TenancyDatabaseModule, ...models],
controllers: [WarehousesController],
providers: [
CreateWarehouse,
@@ -66,7 +79,17 @@ import { AccountsTransactionsWarehousesSubscribe } from './AccountsTransactionsW
SaleInvoicesWarehousesValidateSubscriber,
VendorCreditWarehousesValidateSubscriber,
AccountsTransactionsWarehousesSubscribe,
BillActivateWarehouses,
CreditNotesActivateWarehouses,
VendorCreditActivateWarehouses,
CreditNotesActivateWarehouses,
InvoicesActivateWarehouses,
ReceiptActivateWarehouses,
WarehousesDTOValidators,
DeleteItemWarehousesQuantity,
InventoryTransactionsWarehouses,
ValidateWarehouseExistance
],
exports: [WarehouseTransactionDTOTransform],
exports: [WarehouseTransactionDTOTransform, ...models],
})
export class WarehousesModule {}