You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
hmg-mohemm-flutter-app/lib/api/offers_and_discounts_api_cl...

952 lines
34 KiB
Dart

3 weeks ago
import 'dart:async';
import 'dart:convert';
3 weeks ago
import 'dart:developer';
import 'package:flutter/material.dart';
3 weeks ago
import 'package:geolocator/geolocator.dart';
import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/offers_and_discounts/get_categories_list.dart';
import 'package:mohem_flutter_app/models/offers_and_discounts/get_offers_list.dart';
import 'package:mohem_flutter_app/models/offers_and_discounts/wala_plus_category_model.dart';
import 'package:mohem_flutter_app/models/offers_and_discounts/wala_plus_retailer_model.dart';
3 weeks ago
import 'package:mohem_flutter_app/widgets/location/Location.dart' as location;
class OffersAndDiscountsApiClient {
static final OffersAndDiscountsApiClient _instance =
OffersAndDiscountsApiClient._internal();
2 weeks ago
static List<WalaPlusCategoryModel>? cachedCategories;
OffersAndDiscountsApiClient._internal();
factory OffersAndDiscountsApiClient() => _instance;
Future<List<GetCategoriesList>> getSaleCategories() async {
List<GetCategoriesList> getSaleCategoriesList = [];
String url = "${ApiConsts.cocRest}Mohemm_ITG_GetCategories";
Map<String, dynamic> postParams = {
"EmployeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER,
"ItgPageSize": 100,
"ItgPageNo": 1,
"ItgIsActive": true,
};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject(
(response) {
var body = json.decode(response['Mohemm_ITG_ResponseItem']);
GetCategoriesList getSaleCategoriesListObj = GetCategoriesList();
getSaleCategoriesListObj.id = 0;
getSaleCategoriesListObj.categoryNameEn = "All";
getSaleCategoriesListObj.categoryNameAr = "الجميع";
getSaleCategoriesListObj.isActive = true;
getSaleCategoriesListObj.content =
4 years ago
'<svg xmlns="http://www.w3.org/2000/svg" width="26.213" height="26.213" viewBox="0 0 26.213 26.213"> <g id="More_Select" data-name="More Select" transform="translate(-1 -1)"> <path id="Path_4860" data-name="Path 4860" d="M26.844,1H5.874A.874.874,0,0,0,5,1.874v.874H23.349A2.621,2.621,0,0,1,25.97,5.369V23.718h.874a.874.874,0,0,0,.874-.874V1.874A.874.874,0,0,0,26.844,1Z" transform="translate(-0.505)" fill="#2bb8a6"/> <path id="Path_4861" data-name="Path 4861" d="M22.844,5H1.874A.874.874,0,0,0,1,5.874v20.97a.874.874,0,0,0,.874.874h20.97a.874.874,0,0,0,.874-.874V5.874A.874.874,0,0,0,22.844,5ZM18.7,13.164,11.07,20.789a.874.874,0,0,1-1.236,0L6.022,16.977a.874.874,0,1,1,1.236-1.236l3.2,3.195,7.008-7.007A.874.874,0,1,1,18.7,13.165Z" transform="translate(0 -0.505)" fill="#125765"/> </g> </svg>';
getSaleCategoriesList.add(getSaleCategoriesListObj);
body['result']['data'].forEach((v) {
getSaleCategoriesList.add(GetCategoriesList.fromJson(v));
});
return getSaleCategoriesList;
},
url,
postParams,
);
}
Future<List<OffersListModel>> getOffersList(
int categoryID,
int pageSize,
) async {
List<OffersListModel> getSaleCategoriesList = [];
String url = "${ApiConsts.cocRest}GetOfferDiscountsConfigData";
Map<String, dynamic> postParams = {
"EmployeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER,
"ItgPageSize": pageSize,
"ItgPageNo": 1,
"ItgCategoryID": categoryID,
};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject(
(response) {
var body = json.decode(response['Mohemm_ITG_ResponseItem']);
var bodyData = body['result']['data'];
if (bodyData != null) {
bodyData.forEach((v) {
getSaleCategoriesList.add(OffersListModel.fromJson(v));
});
}
return getSaleCategoriesList;
},
url,
postParams,
);
}
3 weeks ago
String _resolveUserName() {
String? pUserName = AppState().getUserName;
if (pUserName == null || pUserName.isEmpty) {
pUserName =
AppState().postParamsObject?.userName ??
AppState().postParamsObject?.pUserName ??
AppState().memberInformationList?.eMPLOYEENUMBER;
}
3 weeks ago
return pUserName ?? "";
}
3 weeks ago
// Same Location.isEnabled -> Location.havePermission -> Location.getCurrentLocation pattern
// used by mark_attendance_widget.dart (e.g. Wifi attendance), wrapped as a Future since this
// is a background enrichment of the request, not a blocking user action - any failure (service
// disabled, permission denied, error) just resolves to null so the retailer fetch still proceeds
// without WP_Geo_Location rather than showing permission dialogs here.
Future<Position?> _getCurrentPositionSilently(BuildContext context) async {
Completer<bool> enabledCompleter = Completer<bool>();
location.Location.isEnabled((bool isEnabled) {
if (!enabledCompleter.isCompleted) enabledCompleter.complete(isEnabled);
});
bool isEnabled = await enabledCompleter.future;
debugPrint(
"_getCurrentPositionSilently: location service isEnabled=$isEnabled",
);
3 weeks ago
if (!isEnabled) return null;
Completer<bool> permissionCompleter = Completer<bool>();
location.Location.havePermission((bool hasPermission) {
if (!permissionCompleter.isCompleted)
permissionCompleter.complete(hasPermission);
3 weeks ago
});
bool hasPermission = await permissionCompleter.future;
debugPrint("_getCurrentPositionSilently: havePermission=$hasPermission");
if (!hasPermission) return null;
Completer<Position?> positionCompleter = Completer<Position?>();
location.Location.getCurrentLocation(
(Position position, bool isMocked) {
debugPrint(
"_getCurrentPositionSilently: got position lat=${position.latitude}, lng=${position.longitude}, isMocked=$isMocked",
);
if (!positionCompleter.isCompleted)
positionCompleter.complete(position);
3 weeks ago
},
() {
debugPrint(
"_getCurrentPositionSilently: getCurrentLocation error callback fired",
);
3 weeks ago
if (!positionCompleter.isCompleted) positionCompleter.complete(null);
},
context,
);
return positionCompleter.future;
}
3 weeks ago
String _resolveDepNationalId() {
if (!ApiConsts.isDependetLogin) {
return "";
}
return AppState().getUserName ?? "";
}
String _resolveMobileNumber({String? overrideMobile}) {
if (overrideMobile != null && overrideMobile.trim().isNotEmpty) {
return overrideMobile.trim();
}
// postParamsObject.mobileNumber/memberInformationList/memberLoginList are only ever set by
// the employee login flow and never cleared on logout - for a dependent session, the only
// legitimate source is the sponsor's mobile captured at dependent login (walaplusDepInfoModel),
// same reasoning as _resolveUserReference above.
if (ApiConsts.isDependetLogin) {
String? depMobile = AppState().walaplusDepInfoModel?.pEmpMobileNumber;
if (depMobile != null && depMobile.trim().isNotEmpty) {
return depMobile.trim();
}
return "";
}
3 weeks ago
String? mobile = AppState().postParamsObject?.mobileNumber;
if (mobile != null && mobile.trim().isNotEmpty) {
return mobile.trim();
}
mobile = AppState().memberInformationList?.eMPLOYEEMOBILENUMBER;
if (mobile != null && mobile.trim().isNotEmpty) {
return mobile.trim();
}
mobile = AppState().walaplusDepInfoModel?.pEmpMobileNumber;
if (mobile != null && mobile.trim().isNotEmpty) {
return mobile.trim();
}
3 weeks ago
mobile = AppState().memberLoginList?.pMOBILENUMBER;
if (mobile != null && mobile.trim().isNotEmpty) {
return mobile.trim();
}
mobile = AppState().memberInformationList?.mobileNumberWithZipCode;
if (mobile != null && mobile.trim().isNotEmpty) {
return mobile.trim();
}
return "";
}
3 weeks ago
Map<String, dynamic> _getBaseWalaPlusParams() {
Map<String, dynamic> base = {};
base.addAll(AppState().postParamsJson);
if (ApiConsts.isDependetLogin) {
String? token =
AppState().postParamsObject?.tokenID ??
AppState().authenticationTokenID;
3 weeks ago
if (token != null && token.isNotEmpty) {
base["TokenID"] = token;
}
String? logInToken = AppState().postParamsObject?.logInTokenID;
if (logInToken != null && logInToken.isNotEmpty) {
base["LogInTokenID"] = logInToken;
}
}
3 weeks ago
_cleanWalaPlusParams(base);
return base;
}
3 weeks ago
void _cleanWalaPlusParams(Map<String, dynamic> map) {
map.remove("P_EMAIL_ADDRESS");
map.remove("P_SESSION_ID");
map.remove("PayrollCodeStr");
map.remove("LegislationCodeStr");
map.remove("P_SELECTED_EMPLOYEE_NUMBER");
map.removeWhere((key, value) => value == null);
}
// Pass parentId to fetch the subcategories under a given main category (WP_ParentId) -
// omit it (the default) to fetch the top-level main categories, same as before.
Future<List<WalaPlusCategoryModel>> getWalaPlusCategories({
BuildContext? context,
String? mobileNumber,
String? parentId,
}) async {
3 weeks ago
String url = ApiConsts.walaPlusCategories;
String pUserName = _resolveUserName();
String pMobileNumber = _resolveMobileNumber(overrideMobile: mobileNumber);
String pDepNationalId = _resolveDepNationalId();
Map<String, dynamic> postParams = _getBaseWalaPlusParams();
postParams["UserName"] = pUserName;
postParams["P_USER_NAME"] = pUserName;
postParams["P_DEP_NATIONAL_ID"] = pDepNationalId;
if (pMobileNumber.isNotEmpty) {
postParams["MobileNumber"] = pMobileNumber;
}
postParams["MemberType"] = ApiConsts.isDependetLogin ? 2 : 1;
postParams["CompanyID"] = 1;
if (parentId != null && parentId.trim().isNotEmpty) {
postParams["WP_Parent_Id"] = parentId.trim();
}
3 weeks ago
_cleanWalaPlusParams(postParams);
2 weeks ago
List<WalaPlusCategoryModel> list = await ApiClient().postJsonForObject(
(response) {
List<WalaPlusCategoryModel> categories = [];
3 weeks ago
if (response != null) {
dynamic cats =
response['WalaPlus_Categories'] ??
response['walaPlus_Categories'] ??
response['WalaPlusCategories'] ??
response['result'];
if (cats is String) {
3 weeks ago
try {
cats = json.decode(cats);
} catch (e) {
debugPrint("Error decoding WalaPlus_Categories: $e");
}
}
if (cats is List) {
cats.forEach((v) {
3 weeks ago
if (v is Map<String, dynamic>) {
categories.add(WalaPlusCategoryModel.fromJson(v));
} else if (v is Map) {
categories.add(
WalaPlusCategoryModel.fromJson(Map<String, dynamic>.from(v)),
);
3 weeks ago
}
});
}
}
return categories;
},
url,
postParams,
);
2 weeks ago
if ((parentId == null || parentId.trim().isEmpty) && list.isNotEmpty) {
cachedCategories = list;
}
return list;
}
3 weeks ago
// Confirmed with backend team: WP_Offer_Type accepts "online" and "store".
static const String walaPlusOfferTypeOnline = "online";
static const String walaPlusOfferTypeInStore = "store";
// Maps the screen's internal filter key ("online"/"instore"/"all") to the WP_Offer_Type value
// the backend expects. Returns null for "all" (or anything unrecognized) so callers can skip
// sending WP_Offer_Type entirely.
static String? mapOfferTypeFilter(String internalKey) {
switch (internalKey) {
case "online":
return walaPlusOfferTypeOnline;
case "instore":
return walaPlusOfferTypeInStore;
default:
return null;
}
}
Future<WalaPlusRetailersResponse?> getWalaPlusRetailers({
String? categoryId,
2 weeks ago
// Every existing caller passes categoryId (even "" for "all") and relies on WP_CategoryID
// always being present in the request - default true preserves that for everyone. Pass
// false only when the category filter must be fully omitted (e.g. a cross-category newest
// feed), not just set to empty.
bool includeCategoryId = true,
int page = 1,
int perPage = 10,
String? geoLocation,
3 weeks ago
String? offerType,
2 weeks ago
String? sortBy,
int? radius,
int? minDiscount,
BuildContext? context,
3 weeks ago
String? mobileNumber,
3 weeks ago
String? query,
String? userReference,
}) async {
String url = ApiConsts.walaPlusRetailers;
3 weeks ago
String pUserName = _resolveUserName();
String pMobileNumber = _resolveMobileNumber(overrideMobile: mobileNumber);
String pDepNationalId = _resolveDepNationalId();
String effectiveCatId =
(categoryId == "all" || categoryId == "0" || categoryId == null)
? ""
: categoryId;
3 weeks ago
Map<String, dynamic> postParams = _getBaseWalaPlusParams();
postParams["UserName"] = pUserName;
postParams["P_USER_NAME"] = pUserName;
postParams["P_DEP_NATIONAL_ID"] = pDepNationalId;
if (pMobileNumber.isNotEmpty) {
postParams["MobileNumber"] = pMobileNumber;
}
3 weeks ago
postParams["MemberType"] = ApiConsts.isDependetLogin ? 2 : 1;
postParams["CompanyID"] = 1;
2 weeks ago
if (includeCategoryId) {
postParams["WP_CategoryID"] = effectiveCatId;
}
3 weeks ago
if (offerType != null && offerType.trim().isNotEmpty) {
postParams["WP_Offer_Type"] = offerType.trim();
}
3 weeks ago
postParams["WP_Page"] = page;
postParams["WP_Per_page"] = perPage;
3 weeks ago
if (query != null && query.trim().isNotEmpty) {
postParams["WP_Query"] = query.trim();
}
2 weeks ago
if (sortBy != null && sortBy.trim().isNotEmpty) {
postParams["WP_Sort_By"] = sortBy.trim();
}
// Backend contract declares these as non-nullable int DataMembers, so "Any"/"All" (null
// here) must be sent as a concrete 0, not omitted.
postParams["WP_Radius"] = radius ?? 0;
postParams["WP_Min_Discount"] = minDiscount ?? 0;
if (geoLocation != null && geoLocation.isNotEmpty) {
postParams["WP_Geo_Location"] = geoLocation;
3 weeks ago
} else if (context != null) {
try {
Position? position = await _getCurrentPositionSilently(context);
if (position != null) {
postParams["WP_Geo_Location"] =
"${position.latitude},${position.longitude}";
3 weeks ago
}
} catch (e) {
debugPrint("getWalaPlusRetailers: unable to get current location: $e");
}
}
3 weeks ago
_cleanWalaPlusParams(postParams);
// Pass WP_User_Reference: if filled then user ID, else null value
if (userReference != null && userReference.trim().isNotEmpty) {
postParams["WP_User_Reference"] = userReference.trim();
} else {
postParams["WP_User_Reference"] = null;
}
return await ApiClient().postJsonForObject(
(response) {
3 weeks ago
if (response != null) {
dynamic val =
response['WalaPlus_Retailers'] ??
response['walaPlus_Retailers'] ??
response['WalaPlusRetailers'] ??
response['WP_Retailers'] ??
response['result'];
if (val is String) {
3 weeks ago
try {
val = json.decode(val);
} catch (e) {
debugPrint("Error decoding WalaPlus_Retailers: $e");
}
}
if (val is Map<String, dynamic>) {
return WalaPlusRetailersResponse.fromJson(val);
} else if (val is Map) {
return WalaPlusRetailersResponse.fromJson(
Map<String, dynamic>.from(val),
);
3 weeks ago
} else if (val is List) {
List<WalaPlusRetailerModel> retailers = [];
for (var v in val) {
if (v is Map<String, dynamic>) {
retailers.add(WalaPlusRetailerModel.fromJson(v));
} else if (v is Map) {
retailers.add(
WalaPlusRetailerModel.fromJson(Map<String, dynamic>.from(v)),
);
3 weeks ago
}
}
return WalaPlusRetailersResponse(
retailers: retailers,
page: 1,
pagesCount: 1,
perPage: retailers.length,
);
}
}
return null;
},
url,
postParams,
);
}
Future<WalaPlusRetailerModel?> getWalaPlusRetailerById({
required String retailerId,
BuildContext? context,
String? mobileNumber,
String? userReference,
}) async {
String url = ApiConsts.walaPlusRetailersByID;
3 weeks ago
String pUserName = _resolveUserName();
String pMobileNumber = _resolveMobileNumber(overrideMobile: mobileNumber);
String pDepNationalId = _resolveDepNationalId();
String pUserReference = _resolveUserReference(
overrideUserReference: userReference,
);
3 weeks ago
Map<String, dynamic> postParams = _getBaseWalaPlusParams();
postParams["WP_RetailerID"] = retailerId;
postParams["RetailerID"] = retailerId;
postParams["UserName"] = pUserName;
postParams["P_USER_NAME"] = pUserName;
postParams["P_DEP_NATIONAL_ID"] = pDepNationalId;
if (pMobileNumber.isNotEmpty) {
postParams["MobileNumber"] = pMobileNumber;
}
3 weeks ago
postParams["MemberType"] = ApiConsts.isDependetLogin ? 2 : 1;
postParams["CompanyID"] = 1;
3 weeks ago
if (context != null) {
postParams["LanguageID"] = AppState().getLanguageID(context);
3 weeks ago
try {
Position? position = await _getCurrentPositionSilently(context);
log("context position: $position");
if (position != null) {
postParams["WP_Geo_Location"] =
"${position.latitude},${position.longitude}";
3 weeks ago
}
} catch (e) {
debugPrint(
"getWalaPlusRetailerById: unable to get current location: $e",
);
3 weeks ago
}
}
3 weeks ago
_cleanWalaPlusParams(postParams);
// Pass WP_User_Reference: if filled then user ID, else null value
if (pUserReference.isNotEmpty) {
postParams["WP_User_Reference"] = pUserReference;
} else {
postParams["WP_User_Reference"] = null;
}
debugPrint(
"getWalaPlusRetailerById: calling $url with params: $postParams",
);
return await ApiClient().postJsonForObject(
(response) {
3 weeks ago
if (response != null) {
debugPrint(
"getWalaPlusRetailerById response keys: ${response is Map ? response.keys.toList() : 'non-map'}",
);
dynamic val =
response['WalaPlus_RetailersByID'] ??
response['walaPlus_RetailersByID'] ??
response['WalaPlusRetailersByID'] ??
response['WP_RetailersByID'] ??
response['result'];
if (val is String) {
3 weeks ago
try {
val = json.decode(val);
} catch (e) {
debugPrint(
"Error decoding WalaPlus_RetailersByID JSON string: $e",
);
3 weeks ago
}
}
3 weeks ago
WalaPlusRetailerModel? model;
if (val is List && val.isNotEmpty) {
var item = val.first;
if (item is Map<String, dynamic>) {
3 weeks ago
model = WalaPlusRetailerModel.fromJson(item);
} else if (item is Map) {
model = WalaPlusRetailerModel.fromJson(
Map<String, dynamic>.from(item),
);
3 weeks ago
}
} else if (val is Map) {
Map<String, dynamic> map =
(val is Map<String, dynamic>)
? val
: Map<String, dynamic>.from(val);
3 weeks ago
if (map.containsKey('retailer')) {
var byIdResponse = WalaPlusRetailersByIDResponse.fromJson(map);
model =
byIdResponse.primaryRetailer ??
WalaPlusRetailerModel.fromJson(map);
3 weeks ago
} else {
model = WalaPlusRetailerModel.fromJson(map);
}
if (model?.isFavorite == null) {
if (map.containsKey('isfavorite')) {
model?.isFavorite =
map['isfavorite'] == true ||
map['isfavorite'] == 1 ||
map['isfavorite'] == 'true' ||
map['isfavorite'] == '1';
} else if (map.containsKey('is_favorite')) {
model?.isFavorite =
map['is_favorite'] == true ||
map['is_favorite'] == 1 ||
map['is_favorite'] == 'true' ||
map['is_favorite'] == '1';
}
}
if ((model?.offers == null || model!.offers!.isEmpty) &&
(map.containsKey('offers') || map.containsKey('Offers'))) {
model?.offers = WalaPlusRetailerModel.parseOffersList(
map['offers'] ?? map['Offers'],
);
3 weeks ago
}
if ((model?.locations == null || model!.locations!.isEmpty) &&
(map.containsKey('locations') ||
map.containsKey('Locations') ||
map.containsKey('location') ||
map.containsKey('Location'))) {
model?.locations = WalaPlusRetailerModel.parseLocationsList(
map['locations'] ??
map['Locations'] ??
map['location'] ??
map['Location'],
);
}
if ((model?.website == null ||
model!.website!.isEmpty ||
model!.website == "null")) {
String? web =
(map['website'] ??
map['merchant_website'] ??
map['website_url'] ??
map['url'] ??
map['merchant_url'])
?.toString();
2 weeks ago
if (web != null && web.trim().isNotEmpty && web != "null") {
model?.website = web.trim();
}
}
if ((model?.categories == null || model!.categories!.isEmpty) &&
(map.containsKey('categories') ||
map.containsKey('Categories') ||
map.containsKey('category') ||
map.containsKey('Category'))) {
dynamic catData =
map['categories'] ??
map['Categories'] ??
map['category'] ??
map['Category'];
2 weeks ago
if (catData is List) {
model?.categories =
catData
.map(
(c) =>
c is Map
? WalaPlusCategoryModel.fromJson(
Map<String, dynamic>.from(c),
)
: WalaPlusCategoryModel(name: c.toString()),
)
.toList();
2 weeks ago
} else if (catData is Map) {
model?.categories = [
WalaPlusCategoryModel.fromJson(
Map<String, dynamic>.from(catData),
),
];
2 weeks ago
} else if (catData is String && catData.trim().isNotEmpty) {
model?.categories = [
WalaPlusCategoryModel(name: catData.trim()),
];
2 weeks ago
}
}
} else if (response is Map<String, dynamic> &&
response.containsKey('name')) {
3 weeks ago
model = WalaPlusRetailerModel.fromJson(response);
}
if (model != null) {
if (response is Map) {
if (model.isFavorite == null) {
if (response.containsKey('isfavorite')) {
model.isFavorite =
response['isfavorite'] == true ||
response['isfavorite'] == 1 ||
response['isfavorite'] == 'true' ||
response['isfavorite'] == '1';
} else if (response.containsKey('is_favorite')) {
model.isFavorite =
response['is_favorite'] == true ||
response['is_favorite'] == 1 ||
response['is_favorite'] == 'true' ||
response['is_favorite'] == '1';
}
}
if (model.website == null ||
model.website!.isEmpty ||
model.website == "null") {
String? web =
(response['website'] ??
response['merchant_website'] ??
response['website_url'] ??
response['url'] ??
response['merchant_url'])
?.toString();
2 weeks ago
if (web != null && web.trim().isNotEmpty && web != "null") {
model.website = web.trim();
}
}
if ((model.offers == null || model.offers!.isEmpty) &&
(response.containsKey('offers') ||
response.containsKey('Offers'))) {
model.offers = WalaPlusRetailerModel.parseOffersList(
response['offers'] ?? response['Offers'],
);
3 weeks ago
}
if ((model.locations == null || model.locations!.isEmpty) &&
(response.containsKey('locations') ||
response.containsKey('Locations') ||
response.containsKey('location') ||
response.containsKey('Location'))) {
model.locations = WalaPlusRetailerModel.parseLocationsList(
response['locations'] ??
response['Locations'] ??
response['location'] ??
response['Location'],
);
3 weeks ago
}
if ((model.categories == null || model.categories!.isEmpty) &&
(response.containsKey('categories') ||
response.containsKey('Categories') ||
response.containsKey('category') ||
response.containsKey('Category'))) {
dynamic catData =
response['categories'] ??
response['Categories'] ??
response['category'] ??
response['Category'];
2 weeks ago
if (catData is List) {
model.categories =
catData
.map(
(c) =>
c is Map
? WalaPlusCategoryModel.fromJson(
Map<String, dynamic>.from(c),
)
: WalaPlusCategoryModel(name: c.toString()),
)
.toList();
2 weeks ago
} else if (catData is Map) {
model.categories = [
WalaPlusCategoryModel.fromJson(
Map<String, dynamic>.from(catData),
),
];
2 weeks ago
} else if (catData is String && catData.trim().isNotEmpty) {
model.categories = [
WalaPlusCategoryModel(name: catData.trim()),
];
2 weeks ago
}
}
3 weeks ago
}
debugPrint(
"getWalaPlusRetailerById: parsed retailer '${model.name}', isFavorite: ${model.isFavorite}, offers: ${model.offers?.length ?? 0}, locations: ${model.locations?.length ?? 0}",
);
3 weeks ago
return model;
}
}
return null;
},
url,
postParams,
);
}
String resolveUserReference({String? overrideUserReference}) {
return _resolveUserReference(overrideUserReference: overrideUserReference);
}
3 weeks ago
String _resolveUserReference({String? overrideUserReference}) {
if (overrideUserReference != null &&
overrideUserReference.trim().isNotEmpty) {
3 weeks ago
return overrideUserReference.trim();
}
// AppState().memberInformationList is never cleared on logout, so after logging out of an
// employee session and logging back in as a dependent (without a full app restart) it can
// still be sitting there from the previous session. Checking the CURRENT session type first
// - rather than just whichever field happens to be non-empty - prevents a dependent session
// from ever resolving to the previous employee's number.
if (ApiConsts.isDependetLogin) {
String? depRef = AppState().getUserName;
if (depRef != null && depRef.trim().isNotEmpty) {
return depRef.trim();
}
return "";
}
3 weeks ago
String? ref = AppState().memberInformationList?.eMPLOYEENUMBER?.toString();
if (ref != null && ref.trim().isNotEmpty) {
return ref.trim();
}
String? pUserName = AppState().getUserName;
if (pUserName != null && pUserName.trim().isNotEmpty) {
return pUserName.trim();
}
return "";
}
Future<Map<String, dynamic>?> redeemWalaPlusOffer({
required String offerId,
String? offerType,
String? userReference,
BuildContext? context,
}) async {
3 weeks ago
String url = ApiConsts.walaPlusOfferRedeem;
String pUserName = _resolveUserName();
String pUserReference = _resolveUserReference(
overrideUserReference: userReference,
);
3 weeks ago
Map<String, dynamic> postParams = _getBaseWalaPlusParams();
postParams["WP_User_Reference"] = pUserReference;
postParams["WP_Offer_Id"] = offerId;
postParams["WP_Offer_Type"] =
(offerType != null && offerType.trim().isNotEmpty)
? offerType.trim()
: "promo";
3 weeks ago
postParams["UserName"] = pUserName;
postParams["P_USER_NAME"] = pUserName;
if (ApiConsts.isDependetLogin) {
String pDepNationalId = _resolveDepNationalId();
if (pDepNationalId.isNotEmpty) {
postParams["P_DEP_NATIONAL_ID"] = pDepNationalId;
}
postParams["MemberType"] = 2;
} else {
postParams["P_DEP_NATIONAL_ID"] = "";
postParams["MemberType"] = 1;
}
_cleanWalaPlusParams(postParams);
debugPrint("redeemWalaPlusOffer calling $url with params: $postParams");
return await ApiClient().postJsonForObject(
(response) {
if (response != null) {
debugPrint("redeemWalaPlusOffer response: $response");
dynamic val =
response['WalaPlus_OfferRedeem'] ??
response['walaPlus_OfferRedeem'] ??
response['WalaPlusOfferRedeem'] ??
response['result'];
3 weeks ago
if (val is String) {
try {
val = json.decode(val);
} catch (e) {
debugPrint("Error decoding WalaPlus_OfferRedeem: $e");
}
}
if (val is Map<String, dynamic>) {
return val;
} else if (val is Map) {
return Map<String, dynamic>.from(val);
}
}
return null;
},
url,
postParams,
);
}
Future<GenericResponseModel?> addWalaPlusFavorite({
Object? retailerId,
List<String>? retailerIds,
BuildContext? context,
String? mobileNumber,
String? userReference,
}) async {
String url = ApiConsts.walaPlusFavoritesAdd;
String pUserName = _resolveUserName();
String pMobileNumber = _resolveMobileNumber(overrideMobile: mobileNumber);
String pUserReference = _resolveUserReference(
overrideUserReference: userReference,
);
List<String> ids = [];
if (retailerIds != null && retailerIds.isNotEmpty) {
ids.addAll(retailerIds);
} else if (retailerId != null) {
if (retailerId is List) {
ids.addAll(retailerId.map((e) => e.toString()));
} else {
ids.add(retailerId.toString());
}
}
Map<String, dynamic> postParams = _getBaseWalaPlusParams();
postParams["P_USER_NAME"] = pUserName;
postParams["UserName"] = pUserName;
if (pMobileNumber.isNotEmpty) {
postParams["MobileNumber"] = pMobileNumber;
}
if (pUserReference.isNotEmpty) {
postParams["WP_User_Reference"] = pUserReference;
}
postParams["WP_Retailer_Ids"] = ids;
if (context != null) {
postParams["LanguageID"] = AppState().getLanguageID(context);
}
if (ApiConsts.isDependetLogin) {
String pDepNationalId = _resolveDepNationalId();
if (pDepNationalId.isNotEmpty) {
postParams["P_DEP_NATIONAL_ID"] = pDepNationalId;
}
postParams["MemberType"] = 2;
} else {
postParams["MemberType"] = 1;
}
_cleanWalaPlusParams(postParams);
debugPrint("addWalaPlusFavorite calling $url with params: $postParams");
return await ApiClient().postJsonForObject(
(response) {
if (response != null) {
debugPrint("addWalaPlusFavorite response: $response");
return GenericResponseModel.fromJson(response);
}
return null;
},
url,
postParams,
);
}
Future<GenericResponseModel?> removeWalaPlusFavorite({
Object? retailerId,
List<String>? retailerIds,
BuildContext? context,
String? mobileNumber,
String? userReference,
}) async {
String url = ApiConsts.walaPlusFavoritesRemove;
String pUserName = _resolveUserName();
String pMobileNumber = _resolveMobileNumber(overrideMobile: mobileNumber);
String pUserReference = _resolveUserReference(
overrideUserReference: userReference,
);
List<String> ids = [];
if (retailerIds != null && retailerIds.isNotEmpty) {
ids.addAll(retailerIds);
} else if (retailerId != null) {
if (retailerId is List) {
ids.addAll(retailerId.map((e) => e.toString()));
} else {
ids.add(retailerId.toString());
}
}
Map<String, dynamic> postParams = _getBaseWalaPlusParams();
postParams["P_USER_NAME"] = pUserName;
postParams["UserName"] = pUserName;
if (pMobileNumber.isNotEmpty) {
postParams["MobileNumber"] = pMobileNumber;
}
if (pUserReference.isNotEmpty) {
postParams["WP_User_Reference"] = pUserReference;
}
postParams["WP_Retailer_Ids"] = ids;
if (context != null) {
postParams["LanguageID"] = AppState().getLanguageID(context);
}
if (ApiConsts.isDependetLogin) {
String pDepNationalId = _resolveDepNationalId();
if (pDepNationalId.isNotEmpty) {
postParams["P_DEP_NATIONAL_ID"] = pDepNationalId;
}
postParams["MemberType"] = 2;
} else {
postParams["MemberType"] = 1;
}
_cleanWalaPlusParams(postParams);
debugPrint("removeWalaPlusFavorite calling $url with params: $postParams");
return await ApiClient().postJsonForObject(
(response) {
if (response != null) {
debugPrint("removeWalaPlusFavorite response: $response");
return GenericResponseModel.fromJson(response);
}
return null;
},
url,
postParams,
);
}
}