From 021ed39d5de23e07e5dd6b664de141b0cc317139 Mon Sep 17 00:00:00 2001 From: Gadha2311 Date: Fri, 30 Jan 2026 12:00:25 +0530 Subject: [PATCH] fix:added serial number fetch in salesinvoice --- models/baseModels/Item/Item.ts | 2 +- models/inventory/helpers.ts | 80 ++++++++++++++++------------------ 2 files changed, 38 insertions(+), 44 deletions(-) diff --git a/models/baseModels/Item/Item.ts b/models/baseModels/Item/Item.ts index dbf58b21..9971a1ba 100644 --- a/models/baseModels/Item/Item.ts +++ b/models/baseModels/Item/Item.ts @@ -120,7 +120,7 @@ export class Item extends Doc { name: seriesName, start: 1001, padZeros: 4, - current: 1000, + current: 1001, }) .sync(); } diff --git a/models/inventory/helpers.ts b/models/inventory/helpers.ts index 12f6f4a1..4bed96a5 100644 --- a/models/inventory/helpers.ts +++ b/models/inventory/helpers.ts @@ -479,55 +479,49 @@ export async function getExistingActiveSerialNumbersForItem( return ''; } - const activeSerialNumbers = await fyo.db.getAll(ModelNameEnum.SerialNumber, { - fields: ['name'], - filters: { item: item, status: 'Active' }, - orderBy: 'name', - order: 'asc', - }); + const stockLedgerEntries = (await fyo.db.getAllRaw( + ModelNameEnum.StockLedgerEntry, + { + fields: ['serialNumber', 'date', 'quantity'], + filters: { + item: item, + serialNumber: ['!=', ''], + }, + orderBy: ['date', 'created', 'name'], + order: 'asc', + } + )) as { serialNumber: string; date: string; quantity: number }[]; - if (!activeSerialNumbers || activeSerialNumbers.length === 0) { + if (!stockLedgerEntries || stockLedgerEntries.length === 0) { return ''; } - const usedInShipments = await fyo.db.getAll(ModelNameEnum.ShipmentItem, { - fields: ['serialNumber'], - filters: { - item: item, - }, - }); + const serialNumberStockMap: Record = {}; - const usedInPurchaseReceipts = await fyo.db.getAll( - ModelNameEnum.PurchaseReceiptItem, - { - fields: ['serialNumber'], - filters: { - item: item, - }, + for (const entry of stockLedgerEntries) { + const sn = entry.serialNumber.trim(); + if (!sn) continue; + + serialNumberStockMap[sn] = (serialNumberStockMap[sn] || 0) + entry.quantity; + } + + const availableSerialNumbers: string[] = []; + const seenSerialNumbers = new Set(); + + for (const entry of stockLedgerEntries) { + const sn = entry.serialNumber.trim(); + if (!sn) continue; + if (seenSerialNumbers.has(sn)) continue; + + if ((serialNumberStockMap[sn] || 0) > 0) { + availableSerialNumbers.push(sn); + seenSerialNumbers.add(sn); + + if (availableSerialNumbers.length >= quantity) { + break; + } } - ); - - const usedSerialNumbers = new Set(); - - usedInShipments.forEach((shipmentItem) => { - if (shipmentItem.serialNumber) { - const serialNumArray = getSerialNumbers( - String(shipmentItem.serialNumber) - ); - serialNumArray.forEach((sn) => usedSerialNumbers.add(sn)); - } - }); - - usedInPurchaseReceipts.forEach((receiptItem) => { - if (receiptItem.serialNumber) { - const serialNumArray = getSerialNumbers(String(receiptItem.serialNumber)); - serialNumArray.forEach((sn) => usedSerialNumbers.add(sn)); - } - }); - - const availableSerialNumbers = activeSerialNumbers - .map((sn) => String(sn.name)) - .filter((snName) => !usedSerialNumbers.has(snName)); + } if (availableSerialNumbers.length === 0) { return '';