mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 21:00:31 +00:00
fix(InventoryValuation): inventory valuation report.
This commit is contained in:
@@ -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<void> {
|
||||
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<void>}
|
||||
*/
|
||||
private async validateExchangeRatesIdsExistance(
|
||||
tenantId: number,
|
||||
exchangeRatesIds: number[]
|
||||
): Promise<void> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<number, IAccountTransaction>;
|
||||
readonly OUTInventoryCostLots: Map<number, IAccountTransaction>;
|
||||
readonly INInventoryCostLots: Map<number, InventoryCostLotTracker>;
|
||||
readonly OUTInventoryCostLots: Map<number, InventoryCostLotTracker>;
|
||||
readonly baseCurrency: string;
|
||||
|
||||
/**
|
||||
@@ -27,8 +28,8 @@ export default class InventoryValuationSheet extends FinancialSheet {
|
||||
constructor(
|
||||
query: IInventoryValuationReportQuery,
|
||||
items: IItem[],
|
||||
INInventoryCostLots: IAccountTransaction[],
|
||||
OUTInventoryCostLots: IAccountTransaction[],
|
||||
INInventoryCostLots: Map<number, InventoryCostLotTracker[]>,
|
||||
OUTInventoryCostLots: Map<number, InventoryCostLotTracker[]>,
|
||||
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<number, InventoryCostLotTracker[]>} transactionsMap
|
||||
* @param {number} itemId
|
||||
* @returns
|
||||
*/
|
||||
getItemTransaction(
|
||||
transactionsMap,
|
||||
transactionsMap: Map<number, InventoryCostLotTracker[]>,
|
||||
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);
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user