From c8bfde346c97629e651d0cd73f7d86cdeb659b8b Mon Sep 17 00:00:00 2001 From: Nils-Johan Gynther Date: Sun, 3 May 2026 18:18:14 +0200 Subject: [PATCH] feat: Add function to ignore non-item lines in receipt parsing Co-authored-by: Copilot --- .../receipt-parsing.service.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/backend/src/receipt-parsing/receipt-parsing.service.ts b/backend/src/receipt-parsing/receipt-parsing.service.ts index 734af91..194409c 100644 --- a/backend/src/receipt-parsing/receipt-parsing.service.ts +++ b/backend/src/receipt-parsing/receipt-parsing.service.ts @@ -173,11 +173,29 @@ function hasAnyLetter(value: string): boolean { return /[a-zåäö]/i.test(value); } +function isIgnoredReceiptLine(value: string): boolean { + const normalized = value.trim().toLowerCase(); + if (!normalized) return false; + + // Rabatt- och betalningsrader ska aldrig bli varuposter. + if (/^rabatt\b/.test(normalized)) return true; + if (/^summa\b/.test(normalized)) return true; + if (/^moms\b/.test(normalized)) return true; + if (/^pant\b/.test(normalized)) return true; + if (/^att\s+betala\b/.test(normalized)) return true; + if (/^totalt\b/.test(normalized)) return true; + if (/^kort\b/.test(normalized)) return true; + if (/^kontant\b/.test(normalized)) return true; + + return false; +} + function normalizeParsedItem(input: any): ParsedReceiptItemRaw | null { if (!input || typeof input !== 'object') return null; const rawName = typeof input.rawName === 'string' ? input.rawName.trim() : ''; if (!rawName || !hasAnyLetter(rawName)) return null; + if (isIgnoredReceiptLine(rawName)) return null; const quantity = Number(input.quantity); if (!Number.isFinite(quantity) || quantity <= 0) return null; @@ -203,6 +221,10 @@ function ruleBasedParseLine(line: string): ParsedReceiptItemRaw | null { const nameCandidate = extractNameCandidate(line); const rawName = nameCandidate ?? line; + if (isIgnoredReceiptLine(rawName)) { + return null; + } + // Multipack: "3x120g", "2 x 1.5l" const multiPack = /(\d+)\s*[x×]\s*(\d+(?:[\.,]\d+)?)\s*(ml|cl|dl|l|g|kg)\b/i.exec(normalized); if (multiPack) { @@ -272,6 +294,10 @@ export class ReceiptParsingService { const needsAI: string[] = []; for (const line of combinedLines) { + if (isIgnoredReceiptLine(line)) { + continue; + } + const item = ruleBasedParseLine(line); if (item !== null) { resolved.push(item);