refactor: dynamic list to nestjs

This commit is contained in:
Ahmed Bouhuolia
2025-01-14 22:57:54 +02:00
parent 081fdebee0
commit e7e7a95aa1
81 changed files with 596 additions and 742 deletions

View File

@@ -27,12 +27,8 @@ import InventoryCostMethod from './InventoryCostMethod';
export class InventoryService {
constructor(
private readonly eventEmitter: EventEmitter2,
private readonly itemsEntriesService: ItemsEntriesService,
private readonly uow: UnitOfWork,
@Inject(Item.name)
private readonly itemModel: typeof Item,
@Inject(InventoryTransaction.name)
private readonly inventoryTransactionModel: typeof InventoryTransaction,
@@ -340,7 +336,7 @@ export class InventoryService {
/**
* Mark item cost computing is running.
* @param {boolean} isRunning -
* @param {boolean} isRunning -
*/
async markItemsCostComputeRunning(isRunning: boolean = true) {
this.settings.set({

View File

@@ -1,9 +1,11 @@
import { Module } from '@nestjs/common';
import { InventoryCostGLBeforeWriteSubscriber } from './subscribers/InventoryCostGLBeforeWriteSubscriber';
import { InventoryCostGLStorage } from './InventoryCostGLStorage.service';
import { RegisterTenancyModel } from '../Tenancy/TenancyModels/Tenancy.module';
import { InventoryCostLotTracker } from './models/InventoryCostLotTracker';
import { InventoryTransaction } from './models/InventoryTransaction';
import { InventoryCostGLBeforeWriteSubscriber } from './subscribers/InventoryCostGLBeforeWriteSubscriber';
import { InventoryItemsQuantitySyncService } from './InventoryItemsQuantitySync.service';
import { InventoryCostMethod } from './InventoryCostMethod';
const models = [
RegisterTenancyModel(InventoryCostLotTracker),
@@ -15,6 +17,8 @@ const models = [
...models,
InventoryCostGLBeforeWriteSubscriber,
InventoryCostGLStorage,
InventoryItemsQuantitySyncService,
InventoryCostMethod,
],
exports: [...models],
})

View File

@@ -1,17 +1,17 @@
import { IInventoryItemCostMeta } from '@/interfaces';
import { Service, Inject } from 'typedi';
import { Injectable } from '@nestjs/common';
import { InventoryItemCostService } from './InventoryCosts.service';
import { IInventoryItemCostMeta } from './types/InventoryCost.types';
@Service()
@Injectable()
export class InventoryCostApplication {
@Inject()
inventoryCost: InventoryItemCostService;
constructor(
private readonly inventoryCost: InventoryItemCostService,
) {}
/**
* Retrieves the items inventory valuation list.
* @param {number} tenantId
* @param {number[]} itemsId
* @param {Date} date
* @param {number[]} itemsId
* @param {Date} date
* @returns {Promise<IInventoryItemCostMeta[]>}
*/
public getItemsInventoryValuationList = async (
@@ -19,7 +19,6 @@ export class InventoryCostApplication {
date: Date
): Promise<IInventoryItemCostMeta[]> => {
const itemsMap = await this.inventoryCost.getItemsInventoryValuation(
tenantId,
itemsId,
date
);

View File

@@ -1,21 +1,14 @@
import { omit } from 'lodash';
import { Container } from 'typedi';
import TenancyService from '@/services/Tenancy/TenancyService';
import { IInventoryLotCost } from '@/interfaces';
import { InventoryCostLotTracker } from './models/InventoryCostLotTracker';
import { Inject } from '@nestjs/common';
import { Knex } from 'knex';
export default class InventoryCostMethod {
tenancy: TenancyService;
tenantModels: any;
/**
* Constructor method.
* @param {number} tenantId - The given tenant id.
*/
constructor(tenantId: number, startingDate: Date, itemId: number) {
const tenancyService = Container.get(TenancyService);
this.tenantModels = tenancyService.models(tenantId);
}
export class InventoryCostMethod {
constructor(
@Inject(InventoryCostLotTracker.name)
private readonly inventoryCostLotTracker: typeof InventoryCostLotTracker
) {}
/**
* Stores the inventory lots costs transactions in bulk.
@@ -23,19 +16,19 @@ export default class InventoryCostMethod {
* @return {Promise[]}
*/
public storeInventoryLotsCost(
costLotsTransactions: IInventoryLotCost[]
costLotsTransactions: InventoryCostLotTracker[],
trx: Knex.Transaction
): Promise<object> {
const { InventoryCostLotTracker } = this.tenantModels;
const opers: any = [];
costLotsTransactions.forEach((transaction: any) => {
if (transaction.lotTransId && transaction.decrement) {
const decrementOper = InventoryCostLotTracker.query(this.trx)
const decrementOper = this.inventoryCostLotTracker.query(trx)
.where('id', transaction.lotTransId)
.decrement('remaining', transaction.decrement);
opers.push(decrementOper);
} else if (!transaction.lotTransId) {
const operation = InventoryCostLotTracker.query(this.trx).insert({
const operation = this.inventoryCostLotTracker.query(trx).insert({
...omit(transaction, ['decrement', 'invTransId', 'lotTransId']),
});
opers.push(operation);

View File

@@ -1,9 +1,10 @@
import { toSafeInteger } from 'lodash';
import { IInventoryTransaction, IItemsQuantityChanges } from '@/interfaces';
import { IItemsQuantityChanges } from './types/InventoryCost.types';
import { Knex } from 'knex';
import { Inject } from '@nestjs/common';
import { Item } from '../Items/models/Item';
import { Injectable } from '@nestjs/common';
import { InventoryTransaction } from './models/InventoryTransaction';
/**
* Syncs the inventory transactions with inventory items quantity.
@@ -11,8 +12,7 @@ import { Injectable } from '@nestjs/common';
@Injectable()
export class InventoryItemsQuantitySyncService {
constructor(
@Inject(Item.name)
private readonly itemModel: typeof Item,
@Inject(Item.name) private readonly itemModel: typeof Item,
) {}
/**
@@ -21,12 +21,14 @@ export class InventoryItemsQuantitySyncService {
* @return {IInventoryTransaction[]}
*/
public reverseInventoryTransactions(
inventroyTransactions: IInventoryTransaction[],
): IInventoryTransaction[] {
return inventroyTransactions.map((transaction) => ({
...transaction,
direction: transaction.direction === 'OUT' ? 'IN' : 'OUT',
}));
inventroyTransactions: InventoryTransaction[],
): InventoryTransaction[] {
return inventroyTransactions.map((transaction) => {
const cloned = transaction.$clone();
cloned.direction = cloned.direction === 'OUT' ? 'IN' : 'OUT';
return cloned;
});
}
/**
@@ -35,7 +37,7 @@ export class InventoryItemsQuantitySyncService {
* @return {IItemsQuantityChanges[]}
*/
public getReverseItemsQuantityChanges(
inventroyTransactions: IInventoryTransaction[],
inventroyTransactions: InventoryTransaction[],
): IItemsQuantityChanges[] {
const reversedTransactions = this.reverseInventoryTransactions(
inventroyTransactions,
@@ -49,12 +51,12 @@ export class InventoryItemsQuantitySyncService {
* @return {IItemsQuantityChanges[]}
*/
public getItemsQuantityChanges(
inventroyTransactions: IInventoryTransaction[],
inventroyTransactions: InventoryTransaction[],
): IItemsQuantityChanges[] {
const balanceMap: { [itemId: number]: number } = {};
inventroyTransactions.forEach(
(inventoryTransaction: IInventoryTransaction) => {
(inventoryTransaction: InventoryTransaction) => {
const { itemId, direction, quantity } = inventoryTransaction;
if (!balanceMap[itemId]) {

View File

@@ -55,7 +55,16 @@ export class InventoryCostLotTracker extends BaseModel {
query.groupBy('date');
query.groupBy('item_id');
},
filterDateRange(query, startDate, endDate, type: unitOfTime.StartOf = 'day') {
/**
* Filters transactions by the given date range.
*/
filterDateRange(
query,
startDate,
endDate,
type: unitOfTime.StartOf = 'day',
) {
const dateFormat = 'YYYY-MM-DD';
const fromDate = moment(startDate).startOf(type).format(dateFormat);
const toDate = moment(endDate).endOf(type).format(dateFormat);
@@ -71,7 +80,7 @@ export class InventoryCostLotTracker extends BaseModel {
/**
* Filters transactions by the given branches.
*/
filterByBranches(query, branchesIds) {
filterByBranches(query, branchesIds: number | Array<number>) {
const formattedBranchesIds = castArray(branchesIds);
query.whereIn('branchId', formattedBranchesIds);
@@ -80,7 +89,7 @@ export class InventoryCostLotTracker extends BaseModel {
/**
* Filters transactions by the given warehosues.
*/
filterByWarehouses(query, branchesIds) {
filterByWarehouses(query, branchesIds: number | Array<number>) {
const formattedWarehousesIds = castArray(branchesIds);
query.whereIn('warehouseId', formattedWarehousesIds);
@@ -92,15 +101,17 @@ export class InventoryCostLotTracker extends BaseModel {
* Relationship mapping.
*/
static get relationMappings() {
const Item = require('models/Item');
const SaleInvoice = require('models/SaleInvoice');
const ItemEntry = require('models/ItemEntry');
const SaleReceipt = require('models/SaleReceipt');
const { Item } = require('../../Items/models/Item');
const { SaleInvoice } = require('../../SaleInvoices/models/SaleInvoice');
const {
ItemEntry,
} = require('../../TransactionItemEntry/models/ItemEntry');
const { SaleReceipt } = require('../../SaleReceipts/models/SaleReceipt');
return {
item: {
relation: Model.BelongsToOneRelation,
modelClass: Item.default,
modelClass: Item,
join: {
from: 'inventory_cost_lot_tracker.itemId',
to: 'items.id',
@@ -108,7 +119,7 @@ export class InventoryCostLotTracker extends BaseModel {
},
invoice: {
relation: Model.BelongsToOneRelation,
modelClass: SaleInvoice.default,
modelClass: SaleInvoice,
join: {
from: 'inventory_cost_lot_tracker.transactionId',
to: 'sales_invoices.id',
@@ -116,7 +127,7 @@ export class InventoryCostLotTracker extends BaseModel {
},
itemEntry: {
relation: Model.BelongsToOneRelation,
modelClass: ItemEntry.default,
modelClass: ItemEntry,
join: {
from: 'inventory_cost_lot_tracker.entryId',
to: 'items_entries.id',
@@ -124,7 +135,7 @@ export class InventoryCostLotTracker extends BaseModel {
},
receipt: {
relation: Model.BelongsToOneRelation,
modelClass: SaleReceipt.default,
modelClass: SaleReceipt,
join: {
from: 'inventory_cost_lot_tracker.transactionId',
to: 'sales_receipts.id',

View File

@@ -106,10 +106,12 @@ export class InventoryTransaction extends BaseModel {
* Relationship mapping.
*/
static get relationMappings() {
const Item = require('models/Item');
const ItemEntry = require('models/ItemEntry');
const InventoryTransactionMeta = require('models/InventoryTransactionMeta');
const InventoryCostLots = require('models/InventoryCostLotTracker');
const { Item } = require('../../Items/models/Item');
const {
ItemEntry,
} = require('../../TransactionItemEntry/models/ItemEntry');
const { InventoryTransactionMeta } = require('./InventoryTransactionMeta');
const { InventoryCostLotTracker } = require('./InventoryCostLotTracker');
return {
// Transaction meta.
@@ -124,7 +126,7 @@ export class InventoryTransaction extends BaseModel {
// Item cost aggregated.
itemCostAggregated: {
relation: Model.HasOneRelation,
modelClass: InventoryCostLots.default,
modelClass: InventoryCostLotTracker,
join: {
from: 'inventory_transactions.itemId',
to: 'inventory_cost_lot_tracker.itemId',
@@ -138,7 +140,7 @@ export class InventoryTransaction extends BaseModel {
},
costLotAggregated: {
relation: Model.HasOneRelation,
modelClass: InventoryCostLots.default,
modelClass: InventoryCostLotTracker,
join: {
from: 'inventory_transactions.id',
to: 'inventory_cost_lot_tracker.inventoryTransactionId',
@@ -151,7 +153,7 @@ export class InventoryTransaction extends BaseModel {
},
item: {
relation: Model.BelongsToOneRelation,
modelClass: Item.default,
modelClass: Item,
join: {
from: 'inventory_transactions.itemId',
to: 'items.id',
@@ -159,7 +161,7 @@ export class InventoryTransaction extends BaseModel {
},
itemEntry: {
relation: Model.BelongsToOneRelation,
modelClass: ItemEntry.default,
modelClass: ItemEntry,
join: {
from: 'inventory_transactions.entryId',
to: 'items_entries.id',

View File

@@ -0,0 +1,29 @@
import { BaseModel } from '@/models/Model';
import { Model, raw } from 'objection';
export class InventoryTransactionMeta extends BaseModel {
/**
* Table name
*/
static get tableName() {
return 'inventory_transaction_meta';
}
/**
* Relationship mapping.
*/
static get relationMappings() {
const { InventoryTransaction } = require('./InventoryTransaction');
return {
inventoryTransaction: {
relation: Model.BelongsToOneRelation,
modelClass: InventoryTransaction,
join: {
from: 'inventory_transaction_meta.inventoryTransactionId',
to: 'inventory_transactions.inventoryTransactionId'
}
}
};
}
}