2022-11-09 18:42:00 +00:00
|
|
|
import { Fyo } from 'fyo';
|
|
|
|
import { StockQueue } from 'models/inventory/stockQueue';
|
2022-11-21 09:57:59 +00:00
|
|
|
import { ValuationMethod } from 'models/inventory/types';
|
2022-11-09 18:42:00 +00:00
|
|
|
import { ModelNameEnum } from 'models/types';
|
|
|
|
import { safeParseFloat, safeParseInt } from 'utils/index';
|
|
|
|
import { ComputedStockLedgerEntry, RawStockLedgerEntry } from './types';
|
|
|
|
|
|
|
|
export async function getRawStockLedgerEntries(fyo: Fyo) {
|
|
|
|
const fieldnames = [
|
|
|
|
'name',
|
|
|
|
'date',
|
|
|
|
'item',
|
|
|
|
'rate',
|
|
|
|
'quantity',
|
|
|
|
'location',
|
|
|
|
'referenceName',
|
|
|
|
'referenceType',
|
|
|
|
];
|
|
|
|
|
|
|
|
return (await fyo.db.getAllRaw(ModelNameEnum.StockLedgerEntry, {
|
|
|
|
fields: fieldnames,
|
|
|
|
orderBy: 'date',
|
|
|
|
order: 'asc',
|
|
|
|
})) as RawStockLedgerEntry[];
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getStockLedgerEntries(
|
2022-11-21 09:57:59 +00:00
|
|
|
rawSLEs: RawStockLedgerEntry[],
|
|
|
|
valuationMethod: ValuationMethod
|
2022-11-09 18:42:00 +00:00
|
|
|
): ComputedStockLedgerEntry[] {
|
|
|
|
type Item = string;
|
|
|
|
type Location = string;
|
|
|
|
|
|
|
|
const computedSLEs: ComputedStockLedgerEntry[] = [];
|
|
|
|
const stockQueues: Record<Item, Record<Location, StockQueue>> = {};
|
|
|
|
|
|
|
|
for (const sle of rawSLEs) {
|
|
|
|
const name = safeParseInt(sle.name);
|
|
|
|
const date = new Date(sle.date);
|
|
|
|
const rate = safeParseFloat(sle.rate);
|
|
|
|
const { item, location, quantity, referenceName, referenceType } = sle;
|
|
|
|
|
|
|
|
if (quantity === 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
stockQueues[item] ??= {};
|
|
|
|
stockQueues[item][location] ??= new StockQueue();
|
|
|
|
|
|
|
|
const q = stockQueues[item][location];
|
|
|
|
const initialValue = q.value;
|
|
|
|
|
|
|
|
let incomingRate: number | null;
|
|
|
|
if (quantity > 0) {
|
|
|
|
incomingRate = q.inward(rate, quantity);
|
|
|
|
} else {
|
|
|
|
incomingRate = q.outward(-quantity);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (incomingRate === null) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const balanceQuantity = q.quantity;
|
2022-11-21 09:57:59 +00:00
|
|
|
let valuationRate = q.fifo;
|
|
|
|
if (valuationMethod === ValuationMethod.MovingAverage) {
|
|
|
|
valuationRate = q.movingAverage;
|
|
|
|
}
|
|
|
|
|
2022-11-09 18:42:00 +00:00
|
|
|
const balanceValue = q.value;
|
|
|
|
const valueChange = balanceValue - initialValue;
|
|
|
|
|
|
|
|
const csle: ComputedStockLedgerEntry = {
|
|
|
|
name,
|
|
|
|
date,
|
|
|
|
|
|
|
|
item,
|
|
|
|
location,
|
|
|
|
|
|
|
|
quantity,
|
|
|
|
balanceQuantity,
|
|
|
|
|
|
|
|
incomingRate,
|
|
|
|
valuationRate,
|
|
|
|
|
|
|
|
balanceValue,
|
|
|
|
valueChange,
|
|
|
|
|
|
|
|
referenceName,
|
|
|
|
referenceType,
|
|
|
|
};
|
|
|
|
|
|
|
|
computedSLEs.push(csle);
|
|
|
|
}
|
|
|
|
|
|
|
|
return computedSLEs;
|
|
|
|
}
|