|
|
|
|
@ -68,6 +68,23 @@ class WalaPlusRetailersByIDResponse {
|
|
|
|
|
factory WalaPlusRetailersByIDResponse.fromJson(Map<String, dynamic> json) {
|
|
|
|
|
List<WalaPlusRetailerLocation> locList = WalaPlusRetailerModel.parseLocationsList(json['locations'] ?? json['Locations'] ?? json['location'] ?? json['Location']);
|
|
|
|
|
List<WalaPlusOfferModel> offList = WalaPlusRetailerModel.parseOffersList(json['offers'] ?? json['Offers']);
|
|
|
|
|
List<WalaPlusCategoryModel> catList = [];
|
|
|
|
|
dynamic catData = json['categories'] ?? json['Categories'] ?? json['category'] ?? json['Category'];
|
|
|
|
|
if (catData is List) {
|
|
|
|
|
for (var c in catData) {
|
|
|
|
|
if (c is Map<String, dynamic>) {
|
|
|
|
|
catList.add(WalaPlusCategoryModel.fromJson(c));
|
|
|
|
|
} else if (c is Map) {
|
|
|
|
|
catList.add(WalaPlusCategoryModel.fromJson(Map<String, dynamic>.from(c)));
|
|
|
|
|
} else if (c is String && c.trim().isNotEmpty) {
|
|
|
|
|
catList.add(WalaPlusCategoryModel(name: c.trim()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (catData is Map) {
|
|
|
|
|
catList.add(WalaPlusCategoryModel.fromJson(Map<String, dynamic>.from(catData)));
|
|
|
|
|
} else if (catData is String && catData.trim().isNotEmpty) {
|
|
|
|
|
catList.add(WalaPlusCategoryModel(name: catData.trim()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
List<WalaPlusRetailerModel> retList = [];
|
|
|
|
|
dynamic retData = json['retailer'] ?? json['Retailer'];
|
|
|
|
|
@ -77,6 +94,7 @@ class WalaPlusRetailersByIDResponse {
|
|
|
|
|
var model = WalaPlusRetailerModel.fromJson(r);
|
|
|
|
|
if (model.locations == null || model.locations!.isEmpty) model.locations = locList;
|
|
|
|
|
if (model.offers == null || model.offers!.isEmpty) model.offers = offList;
|
|
|
|
|
if ((model.categories == null || model.categories!.isEmpty) && catList.isNotEmpty) model.categories = catList;
|
|
|
|
|
if ((model.website == null || model.website!.isEmpty || model.website == "null") && (json['website'] != null || json['merchant_website'] != null || json['url'] != null)) {
|
|
|
|
|
model.website = (json['website'] ?? json['merchant_website'] ?? json['url'])?.toString();
|
|
|
|
|
}
|
|
|
|
|
@ -89,6 +107,7 @@ class WalaPlusRetailersByIDResponse {
|
|
|
|
|
var model = WalaPlusRetailerModel.fromJson(Map<String, dynamic>.from(r));
|
|
|
|
|
if (model.locations == null || model.locations!.isEmpty) model.locations = locList;
|
|
|
|
|
if (model.offers == null || model.offers!.isEmpty) model.offers = offList;
|
|
|
|
|
if ((model.categories == null || model.categories!.isEmpty) && catList.isNotEmpty) model.categories = catList;
|
|
|
|
|
if ((model.website == null || model.website!.isEmpty || model.website == "null") && (json['website'] != null || json['merchant_website'] != null || json['url'] != null)) {
|
|
|
|
|
model.website = (json['website'] ?? json['merchant_website'] ?? json['url'])?.toString();
|
|
|
|
|
}
|
|
|
|
|
@ -103,6 +122,7 @@ class WalaPlusRetailersByIDResponse {
|
|
|
|
|
var model = WalaPlusRetailerModel.fromJson(Map<String, dynamic>.from(retData));
|
|
|
|
|
if (model.locations == null || model.locations!.isEmpty) model.locations = locList;
|
|
|
|
|
if (model.offers == null || model.offers!.isEmpty) model.offers = offList;
|
|
|
|
|
if ((model.categories == null || model.categories!.isEmpty) && catList.isNotEmpty) model.categories = catList;
|
|
|
|
|
if ((model.website == null || model.website!.isEmpty || model.website == "null") && (json['website'] != null || json['merchant_website'] != null || json['url'] != null)) {
|
|
|
|
|
model.website = (json['website'] ?? json['merchant_website'] ?? json['url'])?.toString();
|
|
|
|
|
}
|
|
|
|
|
@ -174,6 +194,8 @@ class WalaPlusRetailerModel {
|
|
|
|
|
List<WalaPlusOfferModel>? offers;
|
|
|
|
|
List<WalaPlusRetailerLocation>? locations;
|
|
|
|
|
List<WalaPlusCategoryModel>? categories;
|
|
|
|
|
String? categoryId;
|
|
|
|
|
String? categoryName;
|
|
|
|
|
String? validity;
|
|
|
|
|
String? validTo;
|
|
|
|
|
String? validUntil;
|
|
|
|
|
@ -213,6 +235,8 @@ class WalaPlusRetailerModel {
|
|
|
|
|
this.offers,
|
|
|
|
|
this.locations,
|
|
|
|
|
this.categories,
|
|
|
|
|
this.categoryId,
|
|
|
|
|
this.categoryName,
|
|
|
|
|
this.validity,
|
|
|
|
|
this.validTo,
|
|
|
|
|
this.validUntil,
|
|
|
|
|
@ -297,10 +321,79 @@ class WalaPlusRetailerModel {
|
|
|
|
|
List<WalaPlusRetailerLocation> locationsList = parseLocationsList(locationsSource ?? targetJson['locations'] ?? targetJson['Locations'] ?? targetJson['location'] ?? targetJson['Location']);
|
|
|
|
|
|
|
|
|
|
List<WalaPlusCategoryModel> categoriesList = [];
|
|
|
|
|
if (targetJson['categories'] != null && targetJson['categories'] is List) {
|
|
|
|
|
targetJson['categories'].forEach((v) {
|
|
|
|
|
categoriesList.add(WalaPlusCategoryModel.fromJson(v));
|
|
|
|
|
});
|
|
|
|
|
dynamic rawCats = targetJson['categories'] ?? targetJson['Categories'] ?? targetJson['category'] ?? targetJson['Category'];
|
|
|
|
|
if (rawCats != null && rawCats is List) {
|
|
|
|
|
for (var v in rawCats) {
|
|
|
|
|
if (v is Map<String, dynamic>) {
|
|
|
|
|
categoriesList.add(WalaPlusCategoryModel.fromJson(v));
|
|
|
|
|
} else if (v is Map) {
|
|
|
|
|
categoriesList.add(WalaPlusCategoryModel.fromJson(Map<String, dynamic>.from(v)));
|
|
|
|
|
} else if (v is String && v.trim().isNotEmpty) {
|
|
|
|
|
categoriesList.add(WalaPlusCategoryModel(name: v.trim()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (rawCats is Map) {
|
|
|
|
|
categoriesList.add(WalaPlusCategoryModel.fromJson(Map<String, dynamic>.from(rawCats)));
|
|
|
|
|
} else if (rawCats is String && rawCats.toString().trim().isNotEmpty && rawCats.toString().trim() != "null") {
|
|
|
|
|
categoriesList.add(WalaPlusCategoryModel(name: rawCats.toString().trim()));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String? singleCatName = (targetJson['category_name'] ??
|
|
|
|
|
targetJson['categoryName'] ??
|
|
|
|
|
targetJson['cat_name'] ??
|
|
|
|
|
targetJson['catName'] ??
|
|
|
|
|
targetJson['CategoryName'] ??
|
|
|
|
|
targetJson['Category_Name'] ??
|
|
|
|
|
targetJson['category_title'] ??
|
|
|
|
|
targetJson['categoryTitle'])?.toString().trim();
|
|
|
|
|
String? singleCatAr = (targetJson['category_name_ar'] ??
|
|
|
|
|
targetJson['categoryNameAr'] ??
|
|
|
|
|
targetJson['cat_name_ar'] ??
|
|
|
|
|
targetJson['catNameAr'] ??
|
|
|
|
|
targetJson['category_ar'] ??
|
|
|
|
|
targetJson['country_name_ar'] ??
|
|
|
|
|
targetJson['countryNameAr'])?.toString().trim();
|
|
|
|
|
String? singleCatEn = (targetJson['category_name_en'] ??
|
|
|
|
|
targetJson['categoryNameEn'] ??
|
|
|
|
|
targetJson['cat_name_en'] ??
|
|
|
|
|
targetJson['catNameEn'] ??
|
|
|
|
|
targetJson['category_en'] ??
|
|
|
|
|
targetJson['country_name_en'] ??
|
|
|
|
|
targetJson['countryNameEn'])?.toString().trim();
|
|
|
|
|
String? foundCategoryId = (targetJson['category_id'] ??
|
|
|
|
|
targetJson['categoryId'] ??
|
|
|
|
|
targetJson['cat_id'] ??
|
|
|
|
|
targetJson['catId'] ??
|
|
|
|
|
targetJson['WP_CategoryID'] ??
|
|
|
|
|
targetJson['WP_CategoryId'])?.toString().trim();
|
|
|
|
|
|
|
|
|
|
String? rawType = targetJson['type']?.toString().trim();
|
|
|
|
|
String? lowerType = rawType?.toLowerCase();
|
|
|
|
|
bool isTypeStoreKeyword = lowerType == null ||
|
|
|
|
|
lowerType.isEmpty ||
|
|
|
|
|
lowerType == 'online' ||
|
|
|
|
|
lowerType == 'instore' ||
|
|
|
|
|
lowerType == 'in_store' ||
|
|
|
|
|
lowerType == 'in store' ||
|
|
|
|
|
lowerType == 'store' ||
|
|
|
|
|
lowerType == 'online,instore' ||
|
|
|
|
|
lowerType == 'instore,online';
|
|
|
|
|
|
|
|
|
|
if ((singleCatName == null || singleCatName.isEmpty) && !isTypeStoreKeyword && rawType != null && rawType.isNotEmpty) {
|
|
|
|
|
singleCatName = rawType;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (categoriesList.isEmpty) {
|
|
|
|
|
if ((singleCatName != null && singleCatName.isNotEmpty && singleCatName != "null") ||
|
|
|
|
|
(singleCatAr != null && singleCatAr.isNotEmpty && singleCatAr != "null") ||
|
|
|
|
|
(singleCatEn != null && singleCatEn.isNotEmpty && singleCatEn != "null")) {
|
|
|
|
|
categoriesList.add(WalaPlusCategoryModel(
|
|
|
|
|
id: foundCategoryId,
|
|
|
|
|
name: singleCatName ?? singleCatEn ?? singleCatAr,
|
|
|
|
|
countryNameAr: singleCatAr ?? singleCatName,
|
|
|
|
|
countryNameEn: singleCatEn ?? singleCatName,
|
|
|
|
|
));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WalaPlusRetailerContact? contactObj;
|
|
|
|
|
@ -424,6 +517,8 @@ class WalaPlusRetailerModel {
|
|
|
|
|
offers: offersList,
|
|
|
|
|
locations: locationsList,
|
|
|
|
|
categories: categoriesList,
|
|
|
|
|
categoryId: foundCategoryId,
|
|
|
|
|
categoryName: singleCatName ?? singleCatEn ?? singleCatAr,
|
|
|
|
|
validity: foundValidity,
|
|
|
|
|
validTo: targetJson['valid_to']?.toString() ?? targetJson['validTo']?.toString(),
|
|
|
|
|
validUntil: targetJson['valid_until']?.toString() ?? targetJson['validUntil']?.toString(),
|
|
|
|
|
@ -528,9 +623,50 @@ class WalaPlusRetailerModel {
|
|
|
|
|
if (categories != null) {
|
|
|
|
|
data['categories'] = categories!.map((v) => v.toJson()).toList();
|
|
|
|
|
}
|
|
|
|
|
data['category_id'] = categoryId;
|
|
|
|
|
data['category_name'] = categoryName;
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String? getDisplayCategory({bool isAr = false, List<WalaPlusCategoryModel>? fallbackCategories}) {
|
|
|
|
|
if (categories != null && categories!.isNotEmpty) {
|
|
|
|
|
for (var cat in categories!) {
|
|
|
|
|
String? primary = isAr ? cat.countryNameAr : cat.countryNameEn;
|
|
|
|
|
String? secondary = isAr ? (cat.name ?? cat.countryNameEn) : (cat.name ?? cat.countryNameAr);
|
|
|
|
|
String? resolved = (primary != null && primary.trim().isNotEmpty && primary != "null")
|
|
|
|
|
? primary.trim()
|
|
|
|
|
: (secondary != null && secondary.trim().isNotEmpty && secondary != "null" ? secondary.trim() : null);
|
|
|
|
|
if (resolved != null && resolved.isNotEmpty) {
|
|
|
|
|
return resolved;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (categoryName != null && categoryName!.trim().isNotEmpty && categoryName != "null") {
|
|
|
|
|
return categoryName!.trim();
|
|
|
|
|
}
|
|
|
|
|
if (fallbackCategories != null && categoryId != null && categoryId!.trim().isNotEmpty) {
|
|
|
|
|
for (var cat in fallbackCategories) {
|
|
|
|
|
if (cat.id?.toString() == categoryId?.toString()) {
|
|
|
|
|
String? primary = isAr ? cat.countryNameAr : cat.countryNameEn;
|
|
|
|
|
String? secondary = isAr ? (cat.name ?? cat.countryNameEn) : (cat.name ?? cat.countryNameAr);
|
|
|
|
|
String? resolved = (primary != null && primary.trim().isNotEmpty && primary != "null")
|
|
|
|
|
? primary.trim()
|
|
|
|
|
: (secondary != null && secondary.trim().isNotEmpty && secondary != "null" ? secondary.trim() : null);
|
|
|
|
|
if (resolved != null && resolved.isNotEmpty) {
|
|
|
|
|
return resolved;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (type != null && type!.trim().isNotEmpty) {
|
|
|
|
|
String lt = type!.trim().toLowerCase();
|
|
|
|
|
if (lt != 'online' && lt != 'instore' && lt != 'store' && lt != 'in_store') {
|
|
|
|
|
return type!.trim();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String? get displayImage {
|
|
|
|
|
if (image != null && image!.trim().isNotEmpty && image != "null") return image!.trim();
|
|
|
|
|
if (imageThumb != null && imageThumb!.trim().isNotEmpty && imageThumb != "null") return imageThumb!.trim();
|
|
|
|
|
@ -688,8 +824,8 @@ class WalaPlusRetailerModel {
|
|
|
|
|
// 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 {
|
|
|
|
|
Set<String> result = <String>{};
|
|
|
|
|
if (type != null && type!.trim().isNotEmpty) {
|
|
|
|
|
Set<String> result = <String>{};
|
|
|
|
|
for (String part in type!.split(',')) {
|
|
|
|
|
String t = part.trim().toLowerCase();
|
|
|
|
|
if (t.isEmpty) continue;
|
|
|
|
|
@ -698,15 +834,19 @@ class WalaPlusRetailerModel {
|
|
|
|
|
} else if (t == 'instore' || t == 'in_store' || t == 'in store' || t == 'store') {
|
|
|
|
|
result.add('instore');
|
|
|
|
|
} else {
|
|
|
|
|
result.add(t);
|
|
|
|
|
// Non-online types (e.g. category names like "Physiotherapy") represent
|
|
|
|
|
// in-store merchants/services that require physical presence.
|
|
|
|
|
result.add('instore');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (result.isNotEmpty) return result.toList();
|
|
|
|
|
}
|
|
|
|
|
if (locations != null && locations!.isNotEmpty) {
|
|
|
|
|
return <String>['instore'];
|
|
|
|
|
result.add('instore');
|
|
|
|
|
}
|
|
|
|
|
return <String>[];
|
|
|
|
|
if (result.isEmpty && hasPhysicalLocation) {
|
|
|
|
|
result.add('instore');
|
|
|
|
|
}
|
|
|
|
|
return result.toList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool get isOnlineStore => normalizedTypes.contains('online');
|
|
|
|
|
@ -721,14 +861,12 @@ class WalaPlusRetailerModel {
|
|
|
|
|
|
|
|
|
|
String _displayTypeLabel(String norm) {
|
|
|
|
|
if (norm == 'online') return LocaleKeys.online.tr();
|
|
|
|
|
if (norm == 'instore') return LocaleKeys.inStore.tr();
|
|
|
|
|
return norm;
|
|
|
|
|
return LocaleKeys.inStore.tr();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
String? getDisplayType() {
|
|
|
|
|
List<String> types = normalizedTypes;
|
|
|
|
|
if (types.isNotEmpty) return _displayTypeLabel(types.first);
|
|
|
|
|
if (type != null && type!.trim().isNotEmpty) return type!.trim();
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -737,7 +875,6 @@ class WalaPlusRetailerModel {
|
|
|
|
|
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>[];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|