mirror of
https://github.com/frappe/books.git
synced 2024-09-19 19:19:02 +00:00
fix: get return balance serial number & batches
This commit is contained in:
parent
9a3a14bd51
commit
1cd03aed34
@ -8,8 +8,8 @@ import {
|
|||||||
import { ModelNameEnum } from '../../models/types';
|
import { ModelNameEnum } from '../../models/types';
|
||||||
import DatabaseCore from './core';
|
import DatabaseCore from './core';
|
||||||
import { BespokeFunction } from './types';
|
import { BespokeFunction } from './types';
|
||||||
|
import { DocItem, ReturnDocItem } from 'models/inventory/types';
|
||||||
import { safeParseFloat } from 'utils/index';
|
import { safeParseFloat } from 'utils/index';
|
||||||
import { DocValueMap } from 'fyo/core/types';
|
|
||||||
|
|
||||||
export class BespokeQueries {
|
export class BespokeQueries {
|
||||||
[key: string]: BespokeFunction;
|
[key: string]: BespokeFunction;
|
||||||
@ -187,13 +187,7 @@ export class BespokeQueries {
|
|||||||
db: DatabaseCore,
|
db: DatabaseCore,
|
||||||
schemaName: string,
|
schemaName: string,
|
||||||
docName: string
|
docName: string
|
||||||
): Promise<DocValueMap[] | undefined> {
|
): Promise<Record<string, ReturnDocItem> | undefined> {
|
||||||
const docItems = (await db.knex!(`${schemaName}Item`)
|
|
||||||
.select('item')
|
|
||||||
.where('parent', docName)
|
|
||||||
.groupBy('item')
|
|
||||||
.sum({ quantity: 'quantity' })) as DocValueMap[];
|
|
||||||
|
|
||||||
const returnDocNames = (
|
const returnDocNames = (
|
||||||
await db.knex!(schemaName)
|
await db.knex!(schemaName)
|
||||||
.select('name')
|
.select('name')
|
||||||
@ -206,41 +200,175 @@ export class BespokeQueries {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const returnedItems = (await db.knex!(`${schemaName}Item`)
|
const returnedItems: DocItem[] = await db.knex!(`${schemaName}Item`)
|
||||||
.select('item')
|
.select('item', 'batch', 'serialNumber')
|
||||||
.sum({ quantity: 'quantity' })
|
.sum({ quantity: 'quantity' })
|
||||||
.whereIn('parent', returnDocNames)
|
.whereIn('parent', returnDocNames)
|
||||||
.groupBy('item')) as DocValueMap[];
|
.groupBy('item', 'batch', 'serialNumber');
|
||||||
|
|
||||||
if (!returnedItems.length) {
|
if (!returnedItems.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const returnBalanceItemQty = [];
|
const docItems: DocItem[] = await db.knex!(`${schemaName}Item`)
|
||||||
|
.select('name', 'item', 'batch', 'serialNumber')
|
||||||
|
.where('parent', docName)
|
||||||
|
.groupBy('item', 'batch', 'serialNumber')
|
||||||
|
.sum({ quantity: 'quantity' });
|
||||||
|
|
||||||
for (const item of returnedItems) {
|
const docItemsMap = BespokeQueries.#getDocItemMap(docItems);
|
||||||
const docItem = docItems.filter(
|
const returnedItemsMap = BespokeQueries.#getDocItemMap(returnedItems);
|
||||||
(invItem) => invItem.item === item.item
|
|
||||||
)[0];
|
|
||||||
|
|
||||||
if (!docItem) {
|
const returnBalanceItems = BespokeQueries.#getReturnBalanceItemQtyMap(
|
||||||
continue;
|
docItemsMap,
|
||||||
}
|
returnedItemsMap
|
||||||
|
|
||||||
let balanceQty = safeParseFloat(
|
|
||||||
(docItem.quantity as number) - Math.abs(item.quantity as number)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (balanceQty === 0) {
|
return returnBalanceItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
static #getDocItemMap(docItems: DocItem[]): Record<string, ReturnDocItem> {
|
||||||
|
const docItemsMap: Record<string, ReturnDocItem> = {};
|
||||||
|
const batchesMap:
|
||||||
|
| Record<
|
||||||
|
string,
|
||||||
|
{ quantity: number; serialNumbers?: string[] | undefined }
|
||||||
|
>
|
||||||
|
| undefined = {};
|
||||||
|
|
||||||
|
for (const item of docItems) {
|
||||||
|
if (!!docItemsMap[item.item]) {
|
||||||
|
if (item.batch) {
|
||||||
|
let serialNumbers: string[] | undefined;
|
||||||
|
|
||||||
|
if (item.serialNumber) {
|
||||||
|
serialNumbers = item.serialNumber.split('\n');
|
||||||
|
docItemsMap[item.item].batches![item.batch] = {
|
||||||
|
quantity: item.quantity,
|
||||||
|
serialNumbers,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
docItemsMap[item.item].batches![item.batch] = {
|
||||||
|
quantity: item.quantity,
|
||||||
|
serialNumbers,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
docItemsMap[item.item].quantity += item.quantity;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.serialNumber) {
|
||||||
|
const serialNumbers: string[] = [];
|
||||||
|
|
||||||
|
if (docItemsMap[item.item].serialNumbers) {
|
||||||
|
serialNumbers.push(...(docItemsMap[item.item].serialNumbers ?? []));
|
||||||
|
}
|
||||||
|
|
||||||
|
serialNumbers.push(...item.serialNumber.split('\n'));
|
||||||
|
docItemsMap[item.item].serialNumbers = serialNumbers;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (balanceQty > 0) {
|
if (item.batch) {
|
||||||
balanceQty *= -1;
|
let serialNumbers: string[] | undefined = undefined;
|
||||||
}
|
if (item.serialNumber) {
|
||||||
returnBalanceItemQty.push({ ...item, quantity: balanceQty });
|
serialNumbers = item.serialNumber.split('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnBalanceItemQty;
|
batchesMap[item.batch] = {
|
||||||
|
serialNumbers,
|
||||||
|
quantity: item.quantity,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let serialNumbers: string[] | undefined = undefined;
|
||||||
|
|
||||||
|
if (!item.batch && item.serialNumber) {
|
||||||
|
serialNumbers = item.serialNumber.split('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
docItemsMap[item.item] = {
|
||||||
|
serialNumbers,
|
||||||
|
batches: batchesMap,
|
||||||
|
quantity: item.quantity,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return docItemsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
static #getReturnBalanceItemQtyMap(
|
||||||
|
docItemsMap: Record<string, ReturnDocItem>,
|
||||||
|
returnedItemsMap: Record<string, ReturnDocItem>
|
||||||
|
): Record<string, ReturnDocItem> {
|
||||||
|
const returnBalanceItems: Record<string, ReturnDocItem> | undefined = {};
|
||||||
|
const balanceBatchQtyMap:
|
||||||
|
| Record<
|
||||||
|
string,
|
||||||
|
{ quantity: number; serialNumbers: string[] | undefined }
|
||||||
|
>
|
||||||
|
| undefined = {};
|
||||||
|
|
||||||
|
for (const row in returnedItemsMap) {
|
||||||
|
const balanceSerialNumbersMap: string[] | undefined = [];
|
||||||
|
|
||||||
|
if (!docItemsMap[row]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const returnedItem = returnedItemsMap[row];
|
||||||
|
const docItem = docItemsMap[row];
|
||||||
|
let balanceQty = 0;
|
||||||
|
|
||||||
|
const docItemHasBatch = !!Object.keys(docItem.batches ?? {}).length;
|
||||||
|
const returnedItemHasBatch = !!Object.keys(returnedItem.batches ?? {})
|
||||||
|
.length;
|
||||||
|
|
||||||
|
if (docItemHasBatch && returnedItemHasBatch && docItem.batches) {
|
||||||
|
for (const batch in returnedItem.batches) {
|
||||||
|
const returnedItemQty = Math.abs(
|
||||||
|
returnedItem.batches[batch].quantity
|
||||||
|
);
|
||||||
|
const docBatchItemQty = docItem.batches[batch].quantity;
|
||||||
|
const balanceQty = returnedItemQty - docBatchItemQty;
|
||||||
|
const docItemSerialNumbers = docItem.batches[batch].serialNumbers;
|
||||||
|
const returnItemSerialNumbers =
|
||||||
|
returnedItem.batches[batch].serialNumbers;
|
||||||
|
|
||||||
|
let balanceSerialNumbers: string[] | undefined;
|
||||||
|
|
||||||
|
if (docItemSerialNumbers && returnItemSerialNumbers) {
|
||||||
|
balanceSerialNumbers = docItemSerialNumbers.filter(
|
||||||
|
(serialNumber: string) =>
|
||||||
|
returnItemSerialNumbers.indexOf(serialNumber) == -1
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
balanceBatchQtyMap[batch] = {
|
||||||
|
quantity: balanceQty,
|
||||||
|
serialNumbers: balanceSerialNumbers,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (docItem.serialNumbers && returnedItem.serialNumbers) {
|
||||||
|
for (const serialNumber of docItem.serialNumbers) {
|
||||||
|
if (!returnedItem.serialNumbers.includes(serialNumber)) {
|
||||||
|
balanceSerialNumbersMap.push(serialNumber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
balanceQty = safeParseFloat(
|
||||||
|
Math.abs(returnedItem.quantity) - docItemsMap[row].quantity
|
||||||
|
);
|
||||||
|
|
||||||
|
returnBalanceItems[row] = {
|
||||||
|
quantity: balanceQty,
|
||||||
|
batches: balanceBatchQtyMap,
|
||||||
|
serialNumbers: balanceSerialNumbersMap,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return returnBalanceItems;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,6 +26,7 @@ import {
|
|||||||
DocValueMap,
|
DocValueMap,
|
||||||
RawValueMap,
|
RawValueMap,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
import { ReturnDocItem } from 'models/inventory/types';
|
||||||
|
|
||||||
type FieldMap = Record<string, Record<string, Field>>;
|
type FieldMap = Record<string, Record<string, Field>>;
|
||||||
|
|
||||||
@ -333,12 +334,12 @@ export class DatabaseHandler extends DatabaseBase {
|
|||||||
async getReturnBalanceItemsQty(
|
async getReturnBalanceItemsQty(
|
||||||
schemaName: string,
|
schemaName: string,
|
||||||
docName: string
|
docName: string
|
||||||
): Promise<DocValueMap[] | undefined> {
|
): Promise<Record<string, ReturnDocItem> | undefined> {
|
||||||
return (await this.#demux.callBespoke(
|
return (await this.#demux.callBespoke(
|
||||||
'getReturnBalanceItemsQty',
|
'getReturnBalanceItemsQty',
|
||||||
schemaName,
|
schemaName,
|
||||||
docName
|
docName
|
||||||
)) as DocValueMap[] | undefined;
|
)) as Promise<Record<string, ReturnDocItem> | undefined>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { t } from 'fyo';
|
import { t } from 'fyo';
|
||||||
import { Attachment } from 'fyo/core/types';
|
import { Attachment, DocValueMap } from 'fyo/core/types';
|
||||||
import { Doc } from 'fyo/model/doc';
|
import { Doc } from 'fyo/model/doc';
|
||||||
import {
|
import {
|
||||||
ChangeArg,
|
ChangeArg,
|
||||||
@ -26,7 +26,7 @@ import {
|
|||||||
validateBatch,
|
validateBatch,
|
||||||
validateSerialNumber,
|
validateSerialNumber,
|
||||||
} from './helpers';
|
} from './helpers';
|
||||||
import { safeParseFloat } from 'utils/index';
|
import { ReturnDocItem } from './types';
|
||||||
|
|
||||||
export abstract class StockTransfer extends Transfer {
|
export abstract class StockTransfer extends Transfer {
|
||||||
name?: string;
|
name?: string;
|
||||||
@ -37,14 +37,17 @@ export abstract class StockTransfer extends Transfer {
|
|||||||
grandTotal?: Money;
|
grandTotal?: Money;
|
||||||
backReference?: string;
|
backReference?: string;
|
||||||
items?: StockTransferItem[];
|
items?: StockTransferItem[];
|
||||||
isReturn?: boolean;
|
isReturned?: boolean;
|
||||||
returnAgainst?: string;
|
returnAgainst?: string;
|
||||||
isItemsReturned?: boolean;
|
|
||||||
|
|
||||||
get isSales() {
|
get isSales() {
|
||||||
return this.schemaName === ModelNameEnum.Shipment;
|
return this.schemaName === ModelNameEnum.Shipment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isReturn(): boolean {
|
||||||
|
return !!this.returnAgainst && this.returnAgainst.length > 1;
|
||||||
|
}
|
||||||
|
|
||||||
get invoiceSchemaName() {
|
get invoiceSchemaName() {
|
||||||
if (this.isSales) {
|
if (this.isSales) {
|
||||||
return ModelNameEnum.SalesInvoice;
|
return ModelNameEnum.SalesInvoice;
|
||||||
@ -65,8 +68,7 @@ export abstract class StockTransfer extends Transfer {
|
|||||||
terms: () => !(this.terms || !(this.isSubmitted || this.isCancelled)),
|
terms: () => !(this.terms || !(this.isSubmitted || this.isCancelled)),
|
||||||
attachment: () =>
|
attachment: () =>
|
||||||
!(this.attachment || !(this.isSubmitted || this.isCancelled)),
|
!(this.attachment || !(this.isSubmitted || this.isCancelled)),
|
||||||
isReturn: () => !this.fyo.singles.AccountingSettings?.enableStockReturns,
|
returnAgainst: () => this.isSubmitted && !this.returnAgainst,
|
||||||
returnAgainst: () => !this.isReturn,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaults: DefaultMap = {
|
static defaults: DefaultMap = {
|
||||||
@ -92,11 +94,6 @@ export abstract class StockTransfer extends Transfer {
|
|||||||
submitted: true,
|
submitted: true,
|
||||||
cancelled: false,
|
cancelled: false,
|
||||||
}),
|
}),
|
||||||
returnAgainst: () => ({
|
|
||||||
isReturn: false,
|
|
||||||
submitted: true,
|
|
||||||
cancelled: false,
|
|
||||||
}),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
override _getTransferDetails() {
|
override _getTransferDetails() {
|
||||||
@ -116,9 +113,9 @@ export abstract class StockTransfer extends Transfer {
|
|||||||
quantity: row.quantity!,
|
quantity: row.quantity!,
|
||||||
batch: row.batch!,
|
batch: row.batch!,
|
||||||
serialNumber: row.serialNumber!,
|
serialNumber: row.serialNumber!,
|
||||||
|
isReturn: row.isReturn,
|
||||||
fromLocation,
|
fromLocation,
|
||||||
toLocation,
|
toLocation,
|
||||||
isReturn: this.isReturn,
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -204,14 +201,14 @@ export abstract class StockTransfer extends Transfer {
|
|||||||
|
|
||||||
async afterSubmit() {
|
async afterSubmit() {
|
||||||
await super.afterSubmit();
|
await super.afterSubmit();
|
||||||
await updateSerialNumbers(this, false);
|
await updateSerialNumbers(this, false, this.isReturn);
|
||||||
await this._updateBackReference();
|
await this._updateBackReference();
|
||||||
await this._updateItemsReturned();
|
await this._updateItemsReturned();
|
||||||
}
|
}
|
||||||
|
|
||||||
async afterCancel(): Promise<void> {
|
async afterCancel(): Promise<void> {
|
||||||
await super.afterCancel();
|
await super.afterCancel();
|
||||||
await updateSerialNumbers(this, true);
|
await updateSerialNumbers(this, true, this.isReturn);
|
||||||
await this._updateBackReference();
|
await this._updateBackReference();
|
||||||
await this._updateItemsReturned();
|
await this._updateItemsReturned();
|
||||||
}
|
}
|
||||||
@ -271,27 +268,22 @@ export abstract class StockTransfer extends Transfer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async _updateItemsReturned() {
|
async _updateItemsReturned() {
|
||||||
if (!this.returnAgainst) {
|
if (!this.isSubmitted || !this.returnAgainst) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const returnDocs = await this.fyo.db.getAll(this.schema.name, {
|
const linkedReference = await this.loadAndGetLink('returnAgainst');
|
||||||
filters: {
|
if (!linkedReference) {
|
||||||
returnAgainst: this.returnAgainst,
|
return;
|
||||||
submitted: true,
|
}
|
||||||
cancelled: false,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const isItemsReturned = returnDocs.length;
|
|
||||||
|
|
||||||
const referenceDoc = await this.fyo.doc.getDoc(
|
const referenceDoc = await this.fyo.doc.getDoc(
|
||||||
this.schema.name,
|
this.schemaName,
|
||||||
this.returnAgainst
|
linkedReference.name
|
||||||
);
|
);
|
||||||
|
const isReturned = !!referenceDoc;
|
||||||
|
|
||||||
await referenceDoc.setAndSync({ isItemsReturned });
|
await referenceDoc.setAndSync({ isReturned });
|
||||||
await referenceDoc.submit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_getTransferMap() {
|
_getTransferMap() {
|
||||||
@ -422,62 +414,88 @@ export abstract class StockTransfer extends Transfer {
|
|||||||
return invoice;
|
return invoice;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getReturnDoc(): Promise<StockTransfer | null> {
|
async getReturnDoc(): Promise<StockTransfer | undefined> {
|
||||||
if (!this.items?.length) {
|
if (!this.name) {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const docData = this.getValidDict(true, true);
|
const docData = this.getValidDict(true, true);
|
||||||
const docItems = docData.items as StockTransferItem[];
|
const docItems = docData.items as DocValueMap[];
|
||||||
const returnDocItems: StockTransferItem[] = [];
|
|
||||||
|
if (!docItems) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let returnDocItems: DocValueMap[] = [];
|
||||||
|
|
||||||
const returnBalanceItemsQty = await this.fyo.db.getReturnBalanceItemsQty(
|
const returnBalanceItemsQty = await this.fyo.db.getReturnBalanceItemsQty(
|
||||||
this.schema.name,
|
this.schemaName,
|
||||||
this.name!
|
this.name
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const item of docItems) {
|
for (const item of docItems) {
|
||||||
if (!item.quantity) {
|
if (!returnBalanceItemsQty) {
|
||||||
|
returnDocItems = docItems;
|
||||||
|
returnDocItems.map((row) => {
|
||||||
|
row.name = undefined;
|
||||||
|
(row.quantity as number) *= -1;
|
||||||
|
return row;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const isItemExist = !!returnDocItems.filter(
|
||||||
|
(balanceItem) => balanceItem.item === item.item
|
||||||
|
).length;
|
||||||
|
|
||||||
|
if (isItemExist) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let quantity = -1 * item.quantity;
|
const returnedItem: ReturnDocItem | undefined =
|
||||||
|
returnBalanceItemsQty[item.item as string];
|
||||||
|
|
||||||
if (returnBalanceItemsQty) {
|
let quantity = returnedItem.quantity;
|
||||||
const balanceItemQty = returnBalanceItemsQty.filter(
|
let serialNumber: string | undefined =
|
||||||
(i) => i.item === item.item
|
returnedItem.serialNumbers?.join('\n');
|
||||||
)[0];
|
|
||||||
|
|
||||||
if (!balanceItemQty) {
|
if (
|
||||||
continue;
|
item.batch &&
|
||||||
|
returnedItem.batches &&
|
||||||
|
returnedItem.batches[item.batch as string]
|
||||||
|
) {
|
||||||
|
quantity = returnedItem.batches[item.batch as string].quantity;
|
||||||
|
|
||||||
|
if (returnedItem.batches[item.batch as string].serialNumbers) {
|
||||||
|
serialNumber =
|
||||||
|
returnedItem.batches[item.batch as string].serialNumbers?.join(
|
||||||
|
'\n'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
quantity = balanceItemQty.quantity as number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
item.quantity = safeParseFloat(quantity);
|
returnDocItems.push({
|
||||||
delete item.name;
|
...item,
|
||||||
returnDocItems.push(item);
|
serialNumber,
|
||||||
|
name: undefined,
|
||||||
|
quantity: quantity,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const returnDocData = {
|
const returnDocData = {
|
||||||
...docData,
|
...docData,
|
||||||
name: null,
|
name: undefined,
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
items: returnDocItems,
|
items: returnDocItems,
|
||||||
isReturn: true,
|
|
||||||
returnAgainst: docData.name,
|
returnAgainst: docData.name,
|
||||||
grandTotal: this.fyo.pesa(0),
|
} as DocValueMap;
|
||||||
};
|
|
||||||
|
|
||||||
const rawReturnDoc = this.fyo.doc.getNewDoc(
|
const newReturnDoc = this.fyo.doc.getNewDoc(
|
||||||
this.schema.name,
|
this.schema.name,
|
||||||
returnDocData
|
returnDocData
|
||||||
) as StockTransfer;
|
) as StockTransfer;
|
||||||
|
|
||||||
rawReturnDoc.once('beforeSync', async () => {
|
await newReturnDoc.runFormulas();
|
||||||
await rawReturnDoc.runFormulas();
|
return newReturnDoc;
|
||||||
});
|
|
||||||
return rawReturnDoc;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -502,6 +520,12 @@ async function validateSerialNumberStatus(doc: StockTransfer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const status = snDoc.status ?? 'Inactive';
|
const status = snDoc.status ?? 'Inactive';
|
||||||
|
const isSubmitted = !!doc.isSubmitted;
|
||||||
|
const isReturn = !!doc.returnAgainst;
|
||||||
|
|
||||||
|
if (isSubmitted || isReturn) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
doc.schemaName === ModelNameEnum.PurchaseReceipt &&
|
doc.schemaName === ModelNameEnum.PurchaseReceipt &&
|
||||||
|
@ -40,4 +40,24 @@ export interface SMTransferDetails {
|
|||||||
isReturn?: boolean;
|
isReturn?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ReturnBalanceItemQty {
|
||||||
|
item?: string;
|
||||||
|
quantity: number;
|
||||||
|
batch?: string | undefined;
|
||||||
|
serialNumber?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DocItem {
|
||||||
|
item: string;
|
||||||
|
quantity: number;
|
||||||
|
batch?: string | undefined;
|
||||||
|
serialNumber?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ReturnDocItem {
|
||||||
|
quantity: number;
|
||||||
|
batches?: Record<string, { quantity: number, serialNumbers?: string[] }> | undefined;
|
||||||
|
serialNumbers?: string[] | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
export interface SMIDetails extends SMDetails, SMTransferDetails {}
|
export interface SMIDetails extends SMDetails, SMTransferDetails {}
|
||||||
|
Loading…
Reference in New Issue
Block a user