2
0
mirror of https://github.com/frappe/books.git synced 2024-09-20 03:29:00 +00:00

feat: batchwise filters in stock ledger and stock balance

This commit is contained in:
18alantom 2023-02-27 19:41:39 +05:30
parent 9a8e423b72
commit b3e4073bb7
3 changed files with 63 additions and 13 deletions

View File

@ -25,9 +25,11 @@ export class StockBalance extends StockLedger {
const filters = { const filters = {
item: this.item, item: this.item,
location: this.location, location: this.location,
batch: this.batch,
fromDate: this.fromDate, fromDate: this.fromDate,
toDate: this.toDate, toDate: this.toDate,
}; };
const rawData = getStockBalanceEntries(this._rawData ?? [], filters); const rawData = getStockBalanceEntries(this._rawData ?? [], filters);
return rawData.map((sbe, i) => { return rawData.map((sbe, i) => {
@ -41,7 +43,7 @@ export class StockBalance extends StockLedger {
} }
getFilters(): Field[] { getFilters(): Field[] {
return [ const filters = [
{ {
fieldtype: 'Link', fieldtype: 'Link',
target: 'Item', target: 'Item',
@ -56,6 +58,17 @@ export class StockBalance extends StockLedger {
label: t`Location`, label: t`Location`,
fieldname: 'location', fieldname: 'location',
}, },
...(this.hasBatches
? [
{
fieldtype: 'Link',
target: 'BatchNumber',
placeholder: t`Batch`,
label: t`Batch`,
fieldname: 'batch',
},
]
: []),
{ {
fieldtype: 'Date', fieldtype: 'Date',
placeholder: t`From Date`, placeholder: t`From Date`,
@ -69,6 +82,8 @@ export class StockBalance extends StockLedger {
fieldname: 'toDate', fieldname: 'toDate',
}, },
] as Field[]; ] as Field[];
return filters;
} }
getColumns(): ColumnField[] { getColumns(): ColumnField[] {
@ -89,6 +104,11 @@ export class StockBalance extends StockLedger {
label: 'Location', label: 'Location',
fieldtype: 'Link', fieldtype: 'Link',
}, },
...(this.hasBatches
? ([
{ fieldname: 'batch', label: 'Batch', fieldtype: 'Link' },
] as ColumnField[])
: []),
{ {
fieldname: 'balanceQuantity', fieldname: 'balanceQuantity',
label: 'Balance Qty.', label: 'Balance Qty.',

View File

@ -3,6 +3,7 @@ import { RawValueMap } from 'fyo/core/types';
import { Action } from 'fyo/model/types'; import { Action } from 'fyo/model/types';
import { cloneDeep } from 'lodash'; import { cloneDeep } from 'lodash';
import { DateTime } from 'luxon'; import { DateTime } from 'luxon';
import { InventorySettings } from 'models/inventory/InventorySettings';
import { ValuationMethod } from 'models/inventory/types'; import { ValuationMethod } from 'models/inventory/types';
import { ModelNameEnum } from 'models/types'; import { ModelNameEnum } from 'models/types';
import getCommonExportActions from 'reports/commonExporter'; import getCommonExportActions from 'reports/commonExporter';
@ -26,6 +27,7 @@ export class StockLedger extends Report {
item?: string; item?: string;
location?: string; location?: string;
batch?: string;
fromDate?: string; fromDate?: string;
toDate?: string; toDate?: string;
ascending?: boolean; ascending?: boolean;
@ -34,6 +36,11 @@ export class StockLedger extends Report {
groupBy: 'none' | 'item' | 'location' = 'none'; groupBy: 'none' | 'item' | 'location' = 'none';
get hasBatches(): boolean {
return !!(this.fyo.singles.InventorySettings as InventorySettings)
.enableBatches;
}
constructor(fyo: Fyo) { constructor(fyo: Fyo) {
super(fyo); super(fyo);
this._setObservers(); this._setObservers();
@ -110,6 +117,10 @@ export class StockLedger extends Report {
continue; continue;
} }
if (this.batch && row.batchNumber !== this.batch) {
continue;
}
const date = row.date.valueOf(); const date = row.date.valueOf();
if (toDate && date > toDate) { if (toDate && date > toDate) {
continue; continue;
@ -260,11 +271,11 @@ export class StockLedger extends Report {
label: 'Location', label: 'Location',
fieldtype: 'Link', fieldtype: 'Link',
}, },
{ ...(this.hasBatches
fieldname: 'batchNumber', ? ([
label: 'Batch No.', { fieldname: 'batch', label: 'Batch', fieldtype: 'Link' },
fieldtype: 'Link', ] as ColumnField[])
}, : []),
{ {
fieldname: 'quantity', fieldname: 'quantity',
label: 'Quantity', label: 'Quantity',
@ -344,6 +355,17 @@ export class StockLedger extends Report {
label: t`Location`, label: t`Location`,
fieldname: 'location', fieldname: 'location',
}, },
...(this.hasBatches
? ([
{
fieldtype: 'Link',
target: 'BatchNumber',
placeholder: t`Batch`,
label: t`Batch`,
fieldname: 'batch',
},
] as Field[])
: []),
{ {
fieldtype: 'Date', fieldtype: 'Date',
placeholder: t`From Date`, placeholder: t`From Date`,

View File

@ -117,7 +117,10 @@ export function getStockBalanceEntries(
toDate?: string; toDate?: string;
} }
): StockBalanceEntry[] { ): StockBalanceEntry[] {
const sbeMap: Record<Item, Record<Location, StockBalanceEntry>> = {}; const sbeMap: Record<
Item,
Record<Location, Record<BatchNo, StockBalanceEntry>>
> = {};
const fromDate = filters.fromDate ? Date.parse(filters.fromDate) : null; const fromDate = filters.fromDate ? Date.parse(filters.fromDate) : null;
const toDate = filters.toDate ? Date.parse(filters.toDate) : null; const toDate = filters.toDate ? Date.parse(filters.toDate) : null;
@ -131,16 +134,19 @@ export function getStockBalanceEntries(
continue; continue;
} }
const batchNumber = sle.batchNumber || '';
sbeMap[sle.item] ??= {}; sbeMap[sle.item] ??= {};
sbeMap[sle.item][sle.location] ??= getSBE( sbeMap[sle.item][sle.location] ??= {};
sbeMap[sle.item][sle.location][batchNumber] ??= getSBE(
sle.item, sle.item,
sle.location, sle.location,
sle.batchNumber batchNumber
); );
const date = sle.date.valueOf(); const date = sle.date.valueOf();
if (fromDate && date < fromDate) { if (fromDate && date < fromDate) {
const sbe = sbeMap[sle.item][sle.location]!; const sbe = sbeMap[sle.item][sle.location][batchNumber];
updateOpeningBalances(sbe, sle); updateOpeningBalances(sbe, sle);
continue; continue;
} }
@ -149,13 +155,15 @@ export function getStockBalanceEntries(
continue; continue;
} }
const sbe = sbeMap[sle.item][sle.location]!; const sbe = sbeMap[sle.item][sle.location][batchNumber];
updateCurrentBalances(sbe, sle); updateCurrentBalances(sbe, sle);
} }
return Object.values(sbeMap) return Object.values(sbeMap)
.map((sbes) => Object.values(sbes)) .map((sbeBatched) =>
.flat(); Object.values(sbeBatched).map((sbes) => Object.values(sbes))
)
.flat(2);
} }
function getSBE( function getSBE(