refactor: tenant proxy providers

This commit is contained in:
Ahmed Bouhuolia
2025-02-15 23:52:12 +02:00
parent 36851d3209
commit 5c0bb52b59
302 changed files with 2396 additions and 1677 deletions

View File

@@ -6,6 +6,7 @@ import { ModelObject } from 'objection';
import { ICashFlowStatementQuery } from './Cashflow.types';
import { Account } from '@/modules/Accounts/models/Account.model';
import { AccountTransaction } from '@/modules/Accounts/models/AccountTransaction.model';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable()
export class CashFlowRepository {
@@ -15,10 +16,12 @@ export class CashFlowRepository {
*/
constructor(
@Inject(Account.name)
private readonly accountModel: typeof Account,
private readonly accountModel: TenantModelProxy<typeof Account>,
@Inject(AccountTransaction.name)
private readonly accountTransactionModel: typeof AccountTransaction,
private readonly accountTransactionModel: TenantModelProxy<
typeof AccountTransaction
>,
) {}
/**
@@ -42,7 +45,7 @@ export class CashFlowRepository {
* @returns {Promise<IAccount[]>}
*/
public async cashFlowAccounts(): Promise<Account[]> {
const accounts = await this.accountModel.query();
const accounts = await this.accountModel().query();
return accounts;
}
@@ -58,7 +61,7 @@ export class CashFlowRepository {
.subtract(1, 'day')
.toDate();
const transactions = await this.accountTransactionModel
const transactions = await this.accountTransactionModel()
.query()
.onBuild((query) => {
query.modify('creditDebitSummation');
@@ -85,19 +88,21 @@ export class CashFlowRepository {
const groupByDateType = this.getGroupTypeFromPeriodsType(
filter.displayColumnsBy,
);
return await this.accountTransactionModel.query().onBuild((query) => {
query.modify('creditDebitSummation');
query.modify('groupByDateFormat', groupByDateType);
return await this.accountTransactionModel()
.query()
.onBuild((query) => {
query.modify('creditDebitSummation');
query.modify('groupByDateFormat', groupByDateType);
query.select('accountId');
query.select('accountId');
query.groupBy('accountId');
query.withGraphFetched('account');
query.groupBy('accountId');
query.withGraphFetched('account');
query.modify('filterDateRange', filter.fromDate, filter.toDate);
query.modify('filterDateRange', filter.fromDate, filter.toDate);
this.commonFilterBranchesQuery(filter, query);
});
this.commonFilterBranchesQuery(filter, query);
});
}
/**
@@ -112,18 +117,20 @@ export class CashFlowRepository {
const groupByDateType = this.getGroupTypeFromPeriodsType(
filter.displayColumnsBy,
);
return await this.accountTransactionModel.query().onBuild((query) => {
query.modify('creditDebitSummation');
query.modify('groupByDateFormat', groupByDateType);
return await this.accountTransactionModel()
.query()
.onBuild((query) => {
query.modify('creditDebitSummation');
query.modify('groupByDateFormat', groupByDateType);
query.select('accountId');
query.groupBy('accountId');
query.select('accountId');
query.groupBy('accountId');
query.withGraphFetched('account');
query.modify('filterDateRange', filter.fromDate, filter.toDate);
query.withGraphFetched('account');
query.modify('filterDateRange', filter.fromDate, filter.toDate);
this.commonFilterBranchesQuery(filter, query);
});
this.commonFilterBranchesQuery(filter, query);
});
}
/**
@@ -138,18 +145,20 @@ export class CashFlowRepository {
filter.displayColumnsBy,
);
return await this.accountTransactionModel.query().onBuild((query) => {
query.modify('creditDebitSummation');
query.modify('groupByDateFormat', groupByDateType);
return await this.accountTransactionModel()
.query()
.onBuild((query) => {
query.modify('creditDebitSummation');
query.modify('groupByDateFormat', groupByDateType);
query.select('accountId');
query.groupBy('accountId');
query.select('accountId');
query.groupBy('accountId');
query.withGraphFetched('account');
query.modify('filterDateRange', filter.fromDate, filter.toDate);
query.withGraphFetched('account');
query.modify('filterDateRange', filter.fromDate, filter.toDate);
this.commonFilterBranchesQuery(filter, query);
});
this.commonFilterBranchesQuery(filter, query);
});
}
/**

View File

@@ -239,7 +239,7 @@ export class CashFlowTable {
): ICashFlowStatementSection => {
const label = section.footerLabel
? section.footerLabel
: this.i18n.__('Total {{accountName}}', { accountName: section.label });
: this.i18n.t('Total {{accountName}}', { accountName: section.label });
section.children.push({
sectionType: ICashFlowStatementSectionType.TOTAL,
@@ -300,7 +300,7 @@ export class CashFlowTable {
* @returns {ITableColumn}
*/
private totalColumns = (): ITableColumn[] => {
return [{ key: 'total', label: this.i18n.__('Total') }];
return [{ key: 'total', label: this.i18n.t('Total') }];
};
/**

View File

@@ -5,18 +5,21 @@ import { AccountTransaction } from '@/modules/Accounts/models/AccountTransaction
import { Customer } from '@/modules/Customers/models/Customer';
import { ModelObject } from 'objection';
import { ACCOUNT_TYPE } from '@/constants/accounts';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable()
export class CustomerBalanceSummaryRepository {
constructor(
@Inject(Account.name)
private readonly accountModel: typeof Account,
private readonly accountModel: TenantModelProxy<typeof Account>,
@Inject(AccountTransaction.name)
private readonly accountTransactionModel: typeof AccountTransaction,
private readonly accountTransactionModel: TenantModelProxy<
typeof AccountTransaction
>,
@Inject(Customer.name)
private readonly customerModel: typeof Customer,
private readonly customerModel: TenantModelProxy<typeof Customer>,
) {}
/**
@@ -27,7 +30,7 @@ export class CustomerBalanceSummaryRepository {
public async getCustomers(
customersIds: number[],
): Promise<ModelObject<Customer>[]> {
return await this.customerModel
return await this.customerModel()
.query()
.orderBy('displayName')
.onBuild((query) => {
@@ -42,7 +45,7 @@ export class CustomerBalanceSummaryRepository {
* @returns {Promise<IAccount[]>}
*/
public async getReceivableAccounts(): Promise<ModelObject<Account>[]> {
return await this.accountModel
return await this.accountModel()
.query()
.where('accountType', ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE);
}
@@ -59,7 +62,7 @@ export class CustomerBalanceSummaryRepository {
const receivableAccountsIds = map(receivableAccounts, 'id');
// Retrieve the customers transactions of A/R accounts.
const customersTranasctions = await this.accountTransactionModel
const customersTranasctions = await this.accountTransactionModel()
.query()
.onBuild((query) => {
query.whereIn('accountId', receivableAccountsIds);

View File

@@ -11,6 +11,7 @@ import { Item } from '@/modules/Items/models/Item';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { events } from '@/common/events/events';
import { getPurchasesByItemsDefaultQuery } from './utils';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable()
export class PurchasesByItemsService {
@@ -27,10 +28,12 @@ export class PurchasesByItemsService {
private readonly tenancyContext: TenancyContext,
@Inject(InventoryTransaction.name)
private readonly inventoryTransactionModel: typeof InventoryTransaction,
private readonly inventoryTransactionModel: TenantModelProxy<
typeof InventoryTransaction
>,
@Inject(Item.name)
private readonly itemModel: typeof Item,
private readonly itemModel: TenantModelProxy<typeof Item>,
) {}
/**
@@ -46,17 +49,19 @@ export class PurchasesByItemsService {
...getPurchasesByItemsDefaultQuery(),
...query,
};
const inventoryItems = await this.itemModel.query().onBuild((q) => {
q.where('type', 'inventory');
const inventoryItems = await this.itemModel()
.query()
.onBuild((q) => {
q.where('type', 'inventory');
if (filter.itemsIds.length > 0) {
q.whereIn('id', filter.itemsIds);
}
});
if (filter.itemsIds.length > 0) {
q.whereIn('id', filter.itemsIds);
}
});
const inventoryItemsIds = inventoryItems.map((item) => item.id);
// Calculates the total inventory total quantity and rate `IN` transactions.
const inventoryTransactions = await this.inventoryTransactionModel
const inventoryTransactions = await this.inventoryTransactionModel()
.query()
.onBuild((builder: any) => {
builder.modify('itemsTotals');

View File

@@ -11,6 +11,7 @@ import { InventoryTransaction } from '@/modules/InventoryCost/models/InventoryTr
import { events } from '@/common/events/events';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { SalesByItemsReport } from './SalesByItems';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable()
export class SalesByItemsReportService {
@@ -20,10 +21,12 @@ export class SalesByItemsReportService {
private readonly tenancyContext: TenancyContext,
@Inject(Item.name)
private readonly itemModel: typeof Item,
private readonly itemModel: TenantModelProxy<typeof Item>,
@Inject(InventoryTransaction.name)
private readonly inventoryTransactionModel: typeof InventoryTransaction,
private readonly inventoryTransactionModel: TenantModelProxy<
typeof InventoryTransaction
>,
) {}
/**
@@ -41,18 +44,21 @@ export class SalesByItemsReportService {
const tenantMetadata = await this.tenancyContext.getTenantMetadata();
// Inventory items for sales report.
const inventoryItems = await this.itemModel.query().onBuild((q) => {
q.where('type', 'inventory');
const inventoryItems = await this.itemModel()
.query()
.onBuild((q) => {
q.where('type', 'inventory');
if (filter.itemsIds.length > 0) {
q.whereIn('id', filter.itemsIds);
}
});
if (filter.itemsIds.length > 0) {
q.whereIn('id', filter.itemsIds);
}
});
const inventoryItemsIds = inventoryItems.map((item) => item.id);
// Calculates the total inventory total quantity and rate `IN` transactions.
const inventoryTransactions = await this.inventoryTransactionModel.query().onBuild(
(builder: any) => {
const inventoryTransactions = await this.inventoryTransactionModel()
.query()
.onBuild((builder: any) => {
builder.modify('itemsTotals');
builder.modify('OUTDirection');
@@ -61,8 +67,7 @@ export class SalesByItemsReportService {
// Filter the date range of the sheet.
builder.modify('filterDateRange', filter.fromDate, filter.toDate);
},
);
});
const sheet = new SalesByItemsReport(
filter,
inventoryItems,

View File

@@ -14,17 +14,20 @@ import { ITransactionsByCustomersFilter } from './TransactionsByCustomer.types';
import { TenancyContext } from '@/modules/Tenancy/TenancyContext.service';
import { TransactionsByContactRepository } from '../TransactionsByContact/TransactionsByContactRepository';
import { DateInput } from '@/common/types/Date';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable({ scope: Scope.TRANSIENT })
export class TransactionsByCustomersRepository extends TransactionsByContactRepository {
@Inject(Customer.name)
private readonly customerModel: typeof Customer;
private readonly customerModel: TenantModelProxy<typeof Customer>;
@Inject(Account.name)
private readonly accountModel: typeof Account;
private readonly accountModel: TenantModelProxy<typeof Account>;
@Inject(AccountTransaction.name)
private readonly accountTransactionModel: typeof AccountTransaction;
private readonly accountTransactionModel: TenantModelProxy<
typeof AccountTransaction
>;
@Inject(AccountRepository)
private readonly accountRepository: AccountRepository;
@@ -168,11 +171,10 @@ export class TransactionsByCustomersRepository extends TransactionsByContactRepo
fromDate: DateInput,
toDate: DateInput,
): Promise<ILedgerEntry[]> {
const transactions =
await this.getCustomersPeriodTransactions(
fromDate,
toDate,
);
const transactions = await this.getCustomersPeriodTransactions(
fromDate,
toDate,
);
// @ts-ignore
return R.pipe(
@@ -192,13 +194,15 @@ export class TransactionsByCustomersRepository extends TransactionsByContactRepo
* @returns {Promise<ICustomer[]>}
*/
public async getCustomers(customersIds?: number[]) {
return this.customerModel.query().onBuild((q) => {
q.orderBy('displayName');
return this.customerModel()
.query()
.onBuild((q) => {
q.orderBy('displayName');
if (!isEmpty(customersIds)) {
q.whereIn('id', customersIds);
}
});
if (!isEmpty(customersIds)) {
q.whereIn('id', customersIds);
}
});
}
/**
@@ -206,7 +210,7 @@ export class TransactionsByCustomersRepository extends TransactionsByContactRepo
* @returns {Promise<IAccount[]>}
*/
public async getReceivableAccounts(): Promise<Account[]> {
const accounts = await this.accountModel
const accounts = await this.accountModel()
.query()
.where('accountType', ACCOUNT_TYPE.ACCOUNTS_RECEIVABLE);
return accounts;
@@ -225,7 +229,7 @@ export class TransactionsByCustomersRepository extends TransactionsByContactRepo
const receivableAccounts = await this.getReceivableAccounts();
const receivableAccountsIds = map(receivableAccounts, 'id');
const openingTransactions = await this.accountTransactionModel
const openingTransactions = await this.accountTransactionModel()
.query()
.modify(
'contactsOpeningBalance',
@@ -249,7 +253,7 @@ export class TransactionsByCustomersRepository extends TransactionsByContactRepo
const receivableAccounts = await this.getReceivableAccounts();
const receivableAccountsIds = map(receivableAccounts, 'id');
const transactions = await this.accountTransactionModel
const transactions = await this.accountTransactionModel()
.query()
.onBuild((query) => {
// Filter by date.

View File

@@ -1,4 +1,5 @@
import { AccountTransaction } from '@/modules/Accounts/models/AccountTransaction.model';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
import { Inject, Injectable } from '@nestjs/common';
import { ModelObject } from 'objection';
@@ -6,12 +7,13 @@ import { ModelObject } from 'objection';
export class TransactionsByReferenceRepository {
constructor(
@Inject(AccountTransaction.name)
private readonly accountTransactionModel: typeof AccountTransaction,
private readonly accountTransactionModel: TenantModelProxy<
typeof AccountTransaction
>,
) {}
/**
* Retrieve the accounts transactions of the givne reference id and type.
* @param {number} tenantId -
* @param {number} referenceId - Reference id.
* @param {string} referenceType - Reference type.
* @return {Promise<IAccountTransaction[]>}
@@ -20,7 +22,8 @@ export class TransactionsByReferenceRepository {
referenceId: number,
referenceType: string,
): Promise<Array<ModelObject<AccountTransaction>>> {
return this.accountTransactionModel.query()
return this.accountTransactionModel()
.query()
.where('reference_id', referenceId)
.where('reference_type', referenceType)
.withGraphFetched('account');

View File

@@ -14,6 +14,7 @@ import { Ledger } from '@/modules/Ledger/Ledger';
import { ModelObject } from 'objection';
import { ITransactionsByVendorsFilter } from './TransactionsByVendor.types';
import { DateInput } from '@/common/types/Date';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable()
export class TransactionsByVendorRepository extends TransactionsByContactRepository {
@@ -24,13 +25,15 @@ export class TransactionsByVendorRepository extends TransactionsByContactReposit
public readonly accountRepository: AccountRepository;
@Inject(Vendor.name)
public readonly vendorModel: typeof Vendor;
public readonly vendorModel: TenantModelProxy<typeof Vendor>;
@Inject(Account.name)
public readonly accountModel: typeof Account;
public readonly accountModel: TenantModelProxy<typeof Account>;
@Inject(AccountTransaction.name)
public readonly accountTransactionModel: typeof AccountTransaction;
public readonly accountTransactionModel: TenantModelProxy<
typeof AccountTransaction
>;
/**
* Ledger.
@@ -197,13 +200,15 @@ export class TransactionsByVendorRepository extends TransactionsByContactReposit
* @returns {Promise<IVendor[]>}
*/
public async getVendors(vendorsIds?: number[]): Promise<Vendor[]> {
return await this.vendorModel.query().onBuild((q) => {
q.orderBy('displayName');
return await this.vendorModel()
.query()
.onBuild((q) => {
q.orderBy('displayName');
if (!isEmpty(vendorsIds)) {
q.whereIn('id', vendorsIds);
}
});
if (!isEmpty(vendorsIds)) {
q.whereIn('id', vendorsIds);
}
});
}
/**
@@ -211,7 +216,7 @@ export class TransactionsByVendorRepository extends TransactionsByContactReposit
* @returns {Promise<IAccount[]>}
*/
public async getPayableAccounts(): Promise<Account[]> {
const accounts = await this.accountModel
const accounts = await this.accountModel()
.query()
.where('accountType', ACCOUNT_TYPE.ACCOUNTS_PAYABLE);
return accounts;
@@ -230,7 +235,7 @@ export class TransactionsByVendorRepository extends TransactionsByContactReposit
const payableAccounts = await this.getPayableAccounts();
const payableAccountsIds = map(payableAccounts, 'id');
const openingTransactions = await this.accountTransactionModel
const openingTransactions = await this.accountTransactionModel()
.query()
.modify(
'contactsOpeningBalance',
@@ -254,7 +259,7 @@ export class TransactionsByVendorRepository extends TransactionsByContactReposit
const receivableAccounts = await this.getPayableAccounts();
const receivableAccountsIds = map(receivableAccounts, 'id');
const transactions = await this.accountTransactionModel
const transactions = await this.accountTransactionModel()
.query()
.onBuild((query) => {
// Filter by date.

View File

@@ -7,16 +7,17 @@ import { Inject, Injectable, Scope } from '@nestjs/common';
import { ITrialBalanceSheetQuery } from './TrialBalanceSheet.types';
import { Ledger } from '@/modules/Ledger/Ledger';
import { AccountRepository } from '@/modules/Accounts/repositories/Account.repository';
import { TenantModelProxy } from '@/modules/System/models/TenantBaseModel';
@Injectable({ scope: Scope.TRANSIENT })
export class TrialBalanceSheetRepository {
private query: ITrialBalanceSheetQuery;
@Inject(Account.name)
private accountModel: typeof Account;
private accountModel: TenantModelProxy<typeof Account>;
@Inject(AccountTransaction.name)
private accountTransactionModel: typeof AccountTransaction;
private accountTransactionModel: TenantModelProxy<typeof AccountTransaction>;
@Inject(AccountRepository)
private accountRepository: AccountRepository;
@@ -77,7 +78,7 @@ export class TrialBalanceSheetRepository {
* @return {Promise<IAccount[]>}
*/
private getAccounts = () => {
return this.accountModel.query();
return this.accountModel().query();
};
/**
@@ -85,18 +86,20 @@ export class TrialBalanceSheetRepository {
* @param {Date|string} openingDate -
*/
public closingAccountsTotal = async (openingDate: Date | string) => {
return this.accountTransactionModel.query().onBuild((query) => {
query.sum('credit as credit');
query.sum('debit as debit');
query.groupBy('accountId');
query.select(['accountId']);
return this.accountTransactionModel()
.query()
.onBuild((query) => {
query.sum('credit as credit');
query.sum('debit as debit');
query.groupBy('accountId');
query.select(['accountId']);
query.modify('filterDateRange', null, openingDate);
query.withGraphFetched('account');
query.modify('filterDateRange', null, openingDate);
query.withGraphFetched('account');
// @ts-ignore
this.commonFilterBranchesQuery(query);
});
// @ts-ignore
this.commonFilterBranchesQuery(query);
});
};
/**