|
|
|
|
@ -471,33 +471,40 @@ class WalaPlusRetailerModel {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Resolves a single location's city using the same 3-pass priority this used to apply
|
|
|
|
|
// globally: specific city name first, then a non-generic-country city, then any city at all.
|
|
|
|
|
String? _resolveLocationCity(WalaPlusRetailerLocation loc, bool isAr) {
|
|
|
|
|
String? cName = isAr ? loc.cityNameAr : loc.cityNameEn;
|
|
|
|
|
if (cName != null && cName.trim().isNotEmpty && cName != "null") {
|
|
|
|
|
return cName.trim();
|
|
|
|
|
}
|
|
|
|
|
if (loc.city != null && loc.city!.trim().isNotEmpty && loc.city != "null") {
|
|
|
|
|
String c = loc.city!.trim();
|
|
|
|
|
if (c.toLowerCase() != 'saudi arabia' && c != 'المملكة العربية السعودية') {
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (loc.city != null && loc.city!.trim().isNotEmpty && loc.city != "null") {
|
|
|
|
|
return loc.city!.trim();
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Multiple distinct cities across this retailer's locations -> "Multiple Cities" instead of
|
|
|
|
|
// just picking the first one found, so the badge doesn't silently hide the other branches.
|
|
|
|
|
String getDisplayCity({bool isAr = false}) {
|
|
|
|
|
log("locations: ${locations?.map((e) => e.toJson()).toList()}");
|
|
|
|
|
if (locations != null && locations!.isNotEmpty) {
|
|
|
|
|
// 1. First pass: look for specific city name
|
|
|
|
|
for (var loc in locations!) {
|
|
|
|
|
String? cName = isAr ? loc.cityNameAr : loc.cityNameEn;
|
|
|
|
|
if (cName != null && cName.trim().isNotEmpty && cName != "null") {
|
|
|
|
|
return cName.trim();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 2. Second pass: fallback to city if not generic country
|
|
|
|
|
for (var loc in locations!) {
|
|
|
|
|
if (loc.city != null && loc.city!.trim().isNotEmpty && loc.city != "null") {
|
|
|
|
|
String c = loc.city!.trim();
|
|
|
|
|
if (c.toLowerCase() != 'saudi arabia' && c != 'المملكة العربية السعودية') {
|
|
|
|
|
return c;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 3. Third pass: any non-empty city
|
|
|
|
|
for (var loc in locations!) {
|
|
|
|
|
if (loc.city != null && loc.city!.trim().isNotEmpty && loc.city != "null") {
|
|
|
|
|
return loc.city!.trim();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (locations == null || locations!.isEmpty) return '';
|
|
|
|
|
|
|
|
|
|
Set<String> distinctCities = <String>{};
|
|
|
|
|
for (var loc in locations!) {
|
|
|
|
|
String? resolved = _resolveLocationCity(loc, isAr);
|
|
|
|
|
if (resolved != null) distinctCities.add(resolved);
|
|
|
|
|
}
|
|
|
|
|
return '';
|
|
|
|
|
|
|
|
|
|
if (distinctCities.isEmpty) return '';
|
|
|
|
|
if (distinctCities.length > 1) return LocaleKeys.multipleCities.tr();
|
|
|
|
|
return distinctCities.first;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String get displayCity => getDisplayCity(isAr: false);
|
|
|
|
|
@ -583,37 +590,62 @@ class WalaPlusRetailerModel {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool get isOnlineStore => (type?.trim().toLowerCase() == 'online');
|
|
|
|
|
|
|
|
|
|
bool get isInstore =>
|
|
|
|
|
(type?.trim().toLowerCase() == 'instore' ||
|
|
|
|
|
type?.trim().toLowerCase() == 'in_store' ||
|
|
|
|
|
type?.trim().toLowerCase() == 'in store' ||
|
|
|
|
|
type?.trim().toLowerCase() == 'store' ||
|
|
|
|
|
(type == null && locations != null && locations!.isNotEmpty));
|
|
|
|
|
|
|
|
|
|
String? get normalizedType {
|
|
|
|
|
// type can be a comma-separated combo (e.g. "online,instore") when a retailer offers both -
|
|
|
|
|
// this splits and normalizes every part instead of only ever matching a single exact value,
|
|
|
|
|
// so a combined retailer is correctly recognized as both rather than neither/just one.
|
|
|
|
|
List<String> get normalizedTypes {
|
|
|
|
|
if (type != null && type!.trim().isNotEmpty) {
|
|
|
|
|
String t = type!.trim().toLowerCase();
|
|
|
|
|
if (t == 'online') return 'online';
|
|
|
|
|
if (t == 'instore' || t == 'in_store' || t == 'in store' || t == 'store') return 'instore';
|
|
|
|
|
return t;
|
|
|
|
|
Set<String> result = <String>{};
|
|
|
|
|
for (String part in type!.split(',')) {
|
|
|
|
|
String t = part.trim().toLowerCase();
|
|
|
|
|
if (t.isEmpty) continue;
|
|
|
|
|
if (t == 'online') {
|
|
|
|
|
result.add('online');
|
|
|
|
|
} else if (t == 'instore' || t == 'in_store' || t == 'in store' || t == 'store') {
|
|
|
|
|
result.add('instore');
|
|
|
|
|
} else {
|
|
|
|
|
result.add(t);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (result.isNotEmpty) return result.toList();
|
|
|
|
|
}
|
|
|
|
|
if (locations != null && locations!.isNotEmpty) {
|
|
|
|
|
return 'instore';
|
|
|
|
|
return <String>['instore'];
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
return <String>[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String? getDisplayType() {
|
|
|
|
|
String? norm = normalizedType;
|
|
|
|
|
bool get isOnlineStore => normalizedTypes.contains('online');
|
|
|
|
|
|
|
|
|
|
bool get isInstore => normalizedTypes.contains('instore');
|
|
|
|
|
|
|
|
|
|
// Kept for any existing single-value callers - returns the first normalized type found.
|
|
|
|
|
String? get normalizedType {
|
|
|
|
|
List<String> types = normalizedTypes;
|
|
|
|
|
return types.isEmpty ? null : types.first;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String _displayTypeLabel(String norm) {
|
|
|
|
|
if (norm == 'online') return LocaleKeys.online.tr();
|
|
|
|
|
if (norm == 'instore') return LocaleKeys.inStore.tr();
|
|
|
|
|
if (type != null && type!.trim().isNotEmpty) {
|
|
|
|
|
return type!.trim();
|
|
|
|
|
}
|
|
|
|
|
return norm;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String? getDisplayType() {
|
|
|
|
|
List<String> types = normalizedTypes;
|
|
|
|
|
if (types.isNotEmpty) return _displayTypeLabel(types.first);
|
|
|
|
|
if (type != null && type!.trim().isNotEmpty) return type!.trim();
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// One label per distinct type (e.g. ["Online", "In Store"]) - used to render a separate chip
|
|
|
|
|
// for each, instead of collapsing a dual-type retailer down to a single badge.
|
|
|
|
|
List<String> getDisplayTypes() {
|
|
|
|
|
List<String> types = normalizedTypes;
|
|
|
|
|
if (types.isNotEmpty) return types.map(_displayTypeLabel).toList();
|
|
|
|
|
if (type != null && type!.trim().isNotEmpty) return <String>[type!.trim()];
|
|
|
|
|
return <String>[];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class WalaPlusRetailerContact {
|
|
|
|
|
|