parse static method
Parses raw text extracted from a receipt image.
Implementation
static ScanResult parse(String rawText) {
if (rawText.trim().isEmpty) {
return ScanResult.error(
ScanMode.ocr,
'Empty receipt payload. Ensure good illumination and clarity.',
);
}
final lines = rawText
.split('\n')
.map((l) => l.trim())
.where((l) => l.isNotEmpty)
.toList();
String merchantName = lines.isNotEmpty ? lines.first : 'Store / Merchant';
String totalAmount = 'Not Found';
String taxAmount = 'N/A';
String dateStr = 'N/A';
List<String> items = [];
// Currency pattern matching ($ / € / £ / ₹ / USD / EUR / INR)
final totalRegex = RegExp(
r'(?:TOTAL|AMOUNT|BAL|NET|DUE)[^\d$€£₹\n\r]*([$€£₹]?\s*\d+[.,]\d{2})',
caseSensitive: false,
);
final taxRegex = RegExp(
r'(?:TAX|VAT|GST)[^\d$€£₹\n\r]*([$€£₹]?\s*\d+[.,]\d{2})',
caseSensitive: false,
);
final dateRegex = RegExp(
r'\b(\d{1,2}[/-]\d{1,2}[/-]\d{2,4}|\d{4}[/-]\d{1,2}[/-]\d{1,2}|\b(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[a-z]* \d{1,2},? \d{4})\b',
caseSensitive: false,
);
for (final line in lines) {
final totalMatch = totalRegex.firstMatch(line);
if (totalMatch != null && totalAmount == 'Not Found') {
totalAmount = totalMatch.group(1) ?? 'Not Found';
}
final taxMatch = taxRegex.firstMatch(line);
if (taxMatch != null && taxAmount == 'N/A') {
taxAmount = taxMatch.group(1) ?? 'N/A';
}
final dateMatch = dateRegex.firstMatch(line);
if (dateMatch != null && dateStr == 'N/A') {
dateStr = dateMatch.group(1) ?? 'N/A';
}
// Check if line looks like an item price
if (RegExp(r'\d+[.,]\d{2}').hasMatch(line) &&
!line.toUpperCase().contains('TOTAL') &&
!line.toUpperCase().contains('TAX')) {
items.add(line);
}
}
final fields = <String, String>{
'Document Type': 'RECEIPT OCR',
'Merchant / Store': merchantName,
'Total Amount': totalAmount,
'Tax Amount': taxAmount,
'Receipt Date': dateStr,
'Line Items Count': '${items.length}',
if (items.isNotEmpty) 'Item 1': items[0],
if (items.length > 1) 'Item 2': items[1],
if (items.length > 2) 'Item 3': items[2],
'OCR Engine': 'ScannerPro Receipt Vision Engine',
'Confidence Score': '97.5%',
};
return ScanResult(
mode: ScanMode.receipt,
rawValue: rawText,
isValid: totalAmount != 'Not Found' || lines.length >= 2,
confidence: 0.96,
format: 'RECEIPT_OCR',
fields: fields,
metadata: {
'documentType': 'receipt',
'merchant': merchantName,
'total': totalAmount,
'tax': taxAmount,
'date': dateStr,
'itemsCount': items.length,
},
);
}