diff --git a/backend/src/receipt-import/receipt-import.service.ts b/backend/src/receipt-import/receipt-import.service.ts index ea8cfa30..0836f96e 100644 --- a/backend/src/receipt-import/receipt-import.service.ts +++ b/backend/src/receipt-import/receipt-import.service.ts @@ -60,6 +60,45 @@ function hasPorkLikeSignal(normalized: string): boolean { ); } +function inferPackageDebugFromRawName(rawName: string): { + packageCount: number; + packQuantity: number | null; + packUnit: string | null; +} { + const normalized = rawName.toLowerCase(); + + // e.g. "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) { + const count = Number.parseInt(multiPack[1], 10); + const qty = Number.parseFloat(multiPack[2].replace(',', '.')); + const unit = multiPack[3].toLowerCase(); + return { + packageCount: Number.isFinite(count) && count > 0 ? count : 1, + packQuantity: Number.isFinite(qty) ? qty : null, + packUnit: unit, + }; + } + + // e.g. "5dl", "1,5l" + const singlePack = /(\d+(?:[\.,]\d+)?)\s*(ml|cl|dl|l|g|kg)\b/i.exec(normalized); + if (singlePack) { + const qty = Number.parseFloat(singlePack[1].replace(',', '.')); + const unit = singlePack[2].toLowerCase(); + return { + packageCount: 1, + packQuantity: Number.isFinite(qty) ? qty : null, + packUnit: unit, + }; + } + + return { + packageCount: 1, + packQuantity: null, + packUnit: null, + }; +} + @Injectable() export class ReceiptImportService { private readonly logger = new Logger(ReceiptImportService.name); @@ -281,7 +320,11 @@ export class ReceiptImportService { if (traceEnabled) trace.push(msg); }; - pushTrace(`start raw="${item.rawName}" signal="${signalText || item.rawName}"`); + const pkg = inferPackageDebugFromRawName(item.rawName); + + pushTrace( + `start raw="${item.rawName}" signal="${signalText || item.rawName}" parsedQuantity=${item.quantity ?? 'null'} parsedUnit=${item.unit ?? 'null'} packageCount=${pkg.packageCount} packQuantity=${pkg.packQuantity ?? 'null'} packUnit=${pkg.packUnit ?? 'null'}`, + ); pushTrace( `match matchedProductId=${item.matchedProductId ?? 'null'} suggestedProductId=${item.suggestedProductId ?? 'null'}`, );