fix low count of items scanned

This commit is contained in:
davmar
2026-09-01 17:52:52 +02:00
parent cdf46bb12a
commit d532af6111
2 changed files with 59 additions and 11 deletions
+26 -7
View File
@@ -136,12 +136,21 @@ class ReceiptParser {
} else { } else {
run = 0; run = 0;
if (_parseQty(stripped, config) == null && if (_parseQty(stripped, config) == null &&
!_isIgnorable(stripped, config)) { !_isIgnorable(stripped, config) &&
!config.matchesAny(stripped, [
...config.grandTotalKeywords,
...config.subtotalKeywords,
...config.taxInclusiveTotalKeywords,
...config.totalDiscountKeywords,
]) &&
_trailingPrice(stripped, config) == null) {
names++; names++;
} }
} }
} }
return maxRun >= 4 && prices >= 4 && names >= 4; if (maxRun >= 4 && prices >= 4 && names >= 4) return true;
// ML Kit sometimes splits a short receipt into names, then prices (2–3 items).
return maxRun >= 2 && prices >= 2 && names >= prices && maxRun >= prices;
} }
static ReceiptParseResult _parseSequential( static ReceiptParseResult _parseSequential(
@@ -235,11 +244,17 @@ class ReceiptParser {
} }
case _Kind.priceOnly: case _Kind.priceOnly:
final amount = classified.amount!; final amount = classified.amount!;
if (amount < 0 && pending != null) { if (pending != null) {
if (amount < 0) {
pending!.discount += amount; pending!.discount += amount;
pending!.lineTotal = roundMoney( pending!.lineTotal = roundMoney(
(pending!.lineTotal ?? pending!.unitPrice ?? 0) + amount, (pending!.lineTotal ?? pending!.unitPrice ?? 0) + amount,
); );
} else if (pending!.lineTotal == null &&
pending!.unitPrice == null) {
pending!.lineTotal = amount;
flush();
}
} }
} }
} }
@@ -307,19 +322,23 @@ class ReceiptParser {
} }
final count = names.length < prices.length ? names.length : prices.length; final count = names.length < prices.length ? names.length : prices.length;
final pairedNames = names.length > count
? names.sublist(names.length - count)
: names;
final nameOffset = names.length - pairedNames.length;
final items = <LineItem>[ final items = <LineItem>[
for (var i = 0; i < count; i++) for (var i = 0; i < count; i++)
LineItem( LineItem(
id: _id(), id: _id(),
name: names[i].name, name: pairedNames[i].name,
price: prices[i], price: prices[i],
quantity: names[i].quantity, quantity: pairedNames[i].quantity,
unitPrice: names[i].unitPrice, unitPrice: pairedNames[i].unitPrice,
), ),
]; ];
for (var i = 0; i < discountSlots.length && i < discounts.length; i++) { for (var i = 0; i < discountSlots.length && i < discounts.length; i++) {
final index = discountSlots[i]; final index = discountSlots[i] - nameOffset;
if (index < 0 || index >= items.length) continue; if (index < 0 || index >= items.length) continue;
final item = items[index]; final item = items[index];
final discount = discounts[i]; final discount = discounts[i];
+29
View File
@@ -15,6 +15,35 @@ CHANGE 1.50
expect(items.map((item) => item.price), [1.50, 2.00]); expect(items.map((item) => item.price), [1.50, 2.00]);
}); });
test('parses name on one line and price on the next', () {
final items = ReceiptParser.parse('''
MILK
1,50
BREAD
2,00
Totaal 3,50
''');
expect(items, hasLength(2));
expect(items.map((item) => item.name), ['MILK', 'BREAD']);
expect(items.map((item) => item.price), [1.50, 2.00]);
});
test('pairs two name lines with two price lines from short column OCR', () {
final items = ReceiptParser.parse('''
Jumbo
MILK
BREAD
1,50
2,00
Totaal 3,50
''');
expect(items, hasLength(2));
expect(items.map((item) => item.name), ['MILK', 'BREAD']);
expect(items.map((item) => item.price), [1.50, 2.00]);
});
test('uses the next line when quantity and total are split', () { test('uses the next line when quantity and total are split', () {
final items = ReceiptParser.parse(''' final items = ReceiptParser.parse('''
EGGS EGGS