feat: Add function to ignore non-item lines in receipt parsing

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Nils-Johan Gynther
2026-05-03 18:18:14 +02:00
parent a5f6ebe6ff
commit c8bfde346c
@@ -173,11 +173,29 @@ function hasAnyLetter(value: string): boolean {
return /[a-zåäö]/i.test(value); 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 { function normalizeParsedItem(input: any): ParsedReceiptItemRaw | null {
if (!input || typeof input !== 'object') return null; if (!input || typeof input !== 'object') return null;
const rawName = typeof input.rawName === 'string' ? input.rawName.trim() : ''; const rawName = typeof input.rawName === 'string' ? input.rawName.trim() : '';
if (!rawName || !hasAnyLetter(rawName)) return null; if (!rawName || !hasAnyLetter(rawName)) return null;
if (isIgnoredReceiptLine(rawName)) return null;
const quantity = Number(input.quantity); const quantity = Number(input.quantity);
if (!Number.isFinite(quantity) || quantity <= 0) return null; if (!Number.isFinite(quantity) || quantity <= 0) return null;
@@ -203,6 +221,10 @@ function ruleBasedParseLine(line: string): ParsedReceiptItemRaw | null {
const nameCandidate = extractNameCandidate(line); const nameCandidate = extractNameCandidate(line);
const rawName = nameCandidate ?? line; const rawName = nameCandidate ?? line;
if (isIgnoredReceiptLine(rawName)) {
return null;
}
// Multipack: "3x120g", "2 x 1.5l" // 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); const multiPack = /(\d+)\s*[x×]\s*(\d+(?:[\.,]\d+)?)\s*(ml|cl|dl|l|g|kg)\b/i.exec(normalized);
if (multiPack) { if (multiPack) {
@@ -272,6 +294,10 @@ export class ReceiptParsingService {
const needsAI: string[] = []; const needsAI: string[] = [];
for (const line of combinedLines) { for (const line of combinedLines) {
if (isIgnoredReceiptLine(line)) {
continue;
}
const item = ruleBasedParseLine(line); const item = ruleBasedParseLine(line);
if (item !== null) { if (item !== null) {
resolved.push(item); resolved.push(item);