Files
receipity/lib/utils/supermarkets.dart
T
2026-08-30 12:24:29 +02:00

109 lines
3.1 KiB
Dart

/// Known Dutch supermarket names, default colors, and OCR detection.
library;
import '../models/supermarket.dart';
const String kOtherSupermarket = 'Other';
final List<Supermarket> kDefaultSupermarkets = [
const Supermarket(name: 'Albert Heijn', colorValue: 0xFF00A0E2, sortOrder: 0),
const Supermarket(name: 'Jumbo', colorValue: 0xFFEEC21B, sortOrder: 1),
const Supermarket(name: 'Lidl', colorValue: 0xFF0050AA, sortOrder: 2),
const Supermarket(name: 'Aldi', colorValue: 0xFF00205B, sortOrder: 3),
const Supermarket(name: 'Plus', colorValue: 0xFF6EC31E, sortOrder: 4),
const Supermarket(name: 'Dirk', colorValue: 0xFFE30613, sortOrder: 5),
const Supermarket(name: 'Coop', colorValue: 0xFFE30613, sortOrder: 6),
const Supermarket(name: 'SPAR', colorValue: 0xFF009640, sortOrder: 7),
const Supermarket(name: 'Nettorama', colorValue: 0xFFE87722, sortOrder: 8),
const Supermarket(name: 'Hoogvliet', colorValue: 0xFFD32F2F, sortOrder: 9),
const Supermarket(name: 'Picnic', colorValue: 0xFFE31C5F, sortOrder: 10),
const Supermarket(
name: kOtherSupermarket,
colorValue: 0xFF78909C,
sortOrder: 11,
),
];
const Map<String, List<String>> kSupermarketAliases = {
'Albert Heijn': ['ALBERT HEIJN', 'AH TO GO', 'AH XL'],
'Jumbo': ['JUMBO'],
'Lidl': ['LIDL'],
'Kruidvat': ['KRUIDVAT'],
'Aldi': ['ALDI'],
'Plus': ['PLUS'],
'Dirk': ['DIRK'],
'Coop': ['COOP'],
'SPAR': ['SPAR'],
'Nettorama': ['NETTORAMA'],
'Hoogvliet': ['HOOGVLIET'],
'Ekoplaza': ['EKOPLAZA'],
'Action': ['ACTION'],
'Etos': ['ETOS'],
'World Toko': ['WORLD TOKO'],
'Picnic': ['PICNIC'],
};
/// Names used before settings were user-editable.
const List<String> kSupermarkets = [
'Albert Heijn',
'Jumbo',
'Lidl',
'Aldi',
'Plus',
'Dirk',
'Coop',
'SPAR',
'Nettorama',
'Hoogvliet',
'Picnic',
'Other',
];
/// Returns a supermarket name if it appears in [rawText].
String? detectSupermarket(String rawText, {Iterable<String> names = const []}) {
final upper = rawText.toUpperCase();
final extra =
names
.map((name) => name.trim())
.where((name) => name.isNotEmpty && name != kOtherSupermarket)
.toList()
..sort((a, b) => b.length.compareTo(a.length));
for (final name in extra) {
if (RegExp(
'\\b${RegExp.escape(name)}\\b',
caseSensitive: false,
).hasMatch(rawText)) {
return name;
}
}
for (final entry in kSupermarketAliases.entries) {
for (final alias in entry.value) {
if (RegExp('\\b${RegExp.escape(alias)}\\b').hasMatch(upper)) {
return _canonicalName(entry.key, extra);
}
}
}
if (RegExp(r'\bAH\b').hasMatch(upper)) {
return _canonicalName('Albert Heijn', extra);
}
return null;
}
String _canonicalName(String fallback, List<String> names) {
for (final name in names) {
if (name.toUpperCase() == fallback.toUpperCase()) return name;
}
return fallback;
}
Supermarket? supermarketByName(Iterable<Supermarket> stores, String? name) {
if (name == null || name.isEmpty) return null;
for (final store in stores) {
if (store.name.toLowerCase() == name.toLowerCase()) return store;
}
return null;
}