From 5f573c095ee7d15cfbae3a913887032ce6edc600 Mon Sep 17 00:00:00 2001 From: "a.bouhuolia" Date: Mon, 29 Mar 2021 15:19:35 +0200 Subject: [PATCH] fix(InventoryValuation): inventory valuation report. --- server/src/api/controllers/ExchangeRates.ts | 32 --------- .../ExchangeRates/ExchangeRatesService.ts | 53 --------------- .../InventoryValuationSheet.ts | 67 +++++++++++++++---- .../InventoryValuationSheetService.ts | 5 +- 4 files changed, 58 insertions(+), 99 deletions(-) diff --git a/server/src/api/controllers/ExchangeRates.ts b/server/src/api/controllers/ExchangeRates.ts index e1bf38503..157f1cfca 100644 --- a/server/src/api/controllers/ExchangeRates.ts +++ b/server/src/api/controllers/ExchangeRates.ts @@ -43,13 +43,6 @@ export default class ExchangeRatesController extends BaseController { asyncMiddleware(this.editExchangeRate.bind(this)), this.handleServiceError ); - router.delete( - '/bulk', - [...this.exchangeRatesIdsSchema], - this.validationResult, - asyncMiddleware(this.bulkDeleteExchangeRates.bind(this)), - this.handleServiceError - ); router.delete( '/:id', [...this.exchangeRateIdSchema], @@ -192,31 +185,6 @@ export default class ExchangeRatesController extends BaseController { } } - /** - * Deletes the given exchange rates in bulk. - * @param {Request} req - * @param {Response} res - * @param {NextFunction} next - */ - async bulkDeleteExchangeRates( - req: Request, - res: Response, - next: NextFunction - ) { - const { tenantId } = req; - const { ids: exchangeRateIds } = req.query; - - try { - await this.exchangeRatesService.deleteBulkExchangeRates( - tenantId, - exchangeRateIds - ); - return res.status(200).send(); - } catch (error) { - next(error); - } - } - /** * Handle service errors. * @param {Error} error diff --git a/server/src/services/ExchangeRates/ExchangeRatesService.ts b/server/src/services/ExchangeRates/ExchangeRatesService.ts index 1a2f5b946..07bf98400 100644 --- a/server/src/services/ExchangeRates/ExchangeRatesService.ts +++ b/server/src/services/ExchangeRates/ExchangeRatesService.ts @@ -135,30 +135,6 @@ export default class ExchangeRatesService implements IExchangeRatesService { return exchangeRates; } - /** - * Deletes exchange rates in bulk. - * @param {number} tenantId - * @param {number[]} exchangeRatesIds - */ - public async deleteBulkExchangeRates( - tenantId: number, - exchangeRatesIds: number[] - ): Promise { - const { ExchangeRate } = this.tenancy.models(tenantId); - - this.logger.info('[exchange_rates] trying delete in bulk.', { - tenantId, - exchangeRatesIds, - }); - await this.validateExchangeRatesIdsExistance(tenantId, exchangeRatesIds); - - await ExchangeRate.query().whereIn('id', exchangeRatesIds).delete(); - this.logger.info('[exchange_rates] deleted successfully.', { - tenantId, - exchangeRatesIds, - }); - } - /** * Validates period of the exchange rate existance. * @param {number} tenantId - Tenant id. @@ -214,33 +190,4 @@ export default class ExchangeRatesService implements IExchangeRatesService { throw new ServiceError(ERRORS.EXCHANGE_RATE_NOT_FOUND); } } - - /** - * Validates exchange rates ids existance. - * @param {number} tenantId - Tenant id. - * @param {number[]} exchangeRatesIds - Exchange rates ids. - * @returns {Promise} - */ - private async validateExchangeRatesIdsExistance( - tenantId: number, - exchangeRatesIds: number[] - ): Promise { - const { ExchangeRate } = this.tenancy.models(tenantId); - - const storedExchangeRates = await ExchangeRate.query().whereIn( - 'id', - exchangeRatesIds - ); - const storedExchangeRatesIds = storedExchangeRates.map( - (category) => category.id - ); - const notFoundExRates = difference( - exchangeRatesIds, - storedExchangeRatesIds - ); - - if (notFoundExRates.length > 0) { - throw new ServiceError(ERRORS.NOT_FOUND_EXCHANGE_RATES); - } - } } diff --git a/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheet.ts b/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheet.ts index e60d798fe..98e9b0823 100644 --- a/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheet.ts +++ b/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheet.ts @@ -4,7 +4,8 @@ import { IItem, IInventoryValuationReportQuery, IInventoryValuationItem, - IAccountTransaction, + InventoryCostLotTracker, + IInventoryValuationStatement, IInventoryValuationTotal } from 'interfaces'; import { transformToMap } from 'utils' @@ -12,8 +13,8 @@ import { transformToMap } from 'utils' export default class InventoryValuationSheet extends FinancialSheet { readonly query: IInventoryValuationReportQuery; readonly items: IItem[]; - readonly INInventoryCostLots: Map; - readonly OUTInventoryCostLots: Map; + readonly INInventoryCostLots: Map; + readonly OUTInventoryCostLots: Map; readonly baseCurrency: string; /** @@ -27,8 +28,8 @@ export default class InventoryValuationSheet extends FinancialSheet { constructor( query: IInventoryValuationReportQuery, items: IItem[], - INInventoryCostLots: IAccountTransaction[], - OUTInventoryCostLots: IAccountTransaction[], + INInventoryCostLots: Map, + OUTInventoryCostLots: Map, baseCurrency: string ) { super(); @@ -41,37 +42,59 @@ export default class InventoryValuationSheet extends FinancialSheet { this.numberFormat = this.query.numberFormat; } + /** + * Retrieve the item cost and quantity from the given transaction map. + * @param {Map} transactionsMap + * @param {number} itemId + * @returns + */ getItemTransaction( - transactionsMap, + transactionsMap: Map, itemId: number, ): { cost: number, quantity: number } { const meta = transactionsMap.get(itemId); const cost = get(meta, 'cost', 0); - const quantity = get(meta, 'cost', 0); + const quantity = get(meta, 'quantity', 0); return { cost, quantity }; } + /** + * Retrieve the cost and quantity of the givne item from `IN` transactions. + * @param {number} itemId - + */ getItemINTransaction( itemId: number, ): { cost: number, quantity: number } { return this.getItemTransaction(this.INInventoryCostLots, itemId); } + /** + * Retrieve the cost and quantity of the given item from `OUT` transactions. + * @param {number} itemId - + */ getItemOUTTransaction( itemId: number, ): { cost: number, quantity: number } { return this.getItemTransaction(this.OUTInventoryCostLots, itemId); } + /** + * Retrieve the item closing valuation. + * @param {number} itemId - Item id. + */ getItemValuation(itemId: number): number { const { cost: INValuation } = this.getItemINTransaction(itemId); const { cost: OUTValuation } = this.getItemOUTTransaction(itemId); - return INValuation - OUTValuation; + return Math.max(INValuation - OUTValuation, 0); } + /** + * Retrieve the item closing quantity. + * @param {number} itemId - Item id. + */ getItemQuantity(itemId: number): number { const { quantity: INQuantity } = this.getItemINTransaction(itemId); const { quantity: OUTQuantity } = this.getItemOUTTransaction(itemId); @@ -79,10 +102,21 @@ export default class InventoryValuationSheet extends FinancialSheet { return INQuantity - OUTQuantity; } + /** + * Calculates the item weighted average cost from the given valuation and quantity. + * @param {number} valuation + * @param {number} quantity + * @returns {number} + */ calcAverage(valuation: number, quantity: number): number { return quantity ? valuation / quantity : 0; } + /** + * Mapping the item model object to inventory valuation item + * @param {IItem} item + * @returns {IInventoryValuationItem} + */ itemMapper(item: IItem): IInventoryValuationItem { const valuation = this.getItemValuation(item.id); const quantity = this.getItemQuantity(item.id); @@ -103,13 +137,18 @@ export default class InventoryValuationSheet extends FinancialSheet { } /** - * - * @returns + * Retrieve the inventory valuation items. + * @returns {IInventoryValuationItem[]} */ - itemsSection() { + itemsSection(): IInventoryValuationItem[] { return this.items.map(this.itemMapper.bind(this)); } + /** + * Retrieve the inventory valuation total. + * @param {IInventoryValuationItem[]} items + * @returns {IInventoryValuationTotal} + */ totalSection(items: IInventoryValuationItem[]): IInventoryValuationTotal { const valuation = sumBy(items, item => item.valuation); const quantity = sumBy(items, item => item.quantity); @@ -122,7 +161,11 @@ export default class InventoryValuationSheet extends FinancialSheet { }; } - reportData() { + /** + * Retrieve the inventory valuation report data. + * @returns {IInventoryValuationStatement} + */ + reportData(): IInventoryValuationStatement { const items = this.itemsSection(); const total = this.totalSection(items); diff --git a/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetService.ts b/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetService.ts index ec7642c28..d9f833b58 100644 --- a/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetService.ts +++ b/server/src/services/FinancialStatements/InventoryValuationSheet/InventoryValuationSheetService.ts @@ -89,11 +89,12 @@ export default class InventoryValuationSheetService { builder.select('itemId'); builder.groupBy('itemId'); }; - + // Retrieve the inventory cost `IN` transactions. const INTransactions = await InventoryCostLotTracker.query() .onBuild(commonQuery) .where('direction', 'IN'); + // Retrieve the inventory cost `OUT` transactions. const OUTTransactions = await InventoryCostLotTracker.query() .onBuild(commonQuery) .where('direction', 'OUT'); @@ -105,7 +106,7 @@ export default class InventoryValuationSheetService { OUTTransactions, baseCurrency, ); - + // Retrieve the inventory valuation report data. const inventoryValuationData = inventoryValuationInstance.reportData(); return {