Compare commits

..

17 Commits

Author SHA1 Message Date
Haroon6138 a77197da91 Merge pull request 'master_merge' (#24) from master_merge into master
Reviewed-on: https://34.17.182.140/Haroon6138/mohemm-flutter-app/pulls/24
17 hours ago
Sultan khan 3a31b8f430 Merge branch 'master' of http://34.17.182.140/Haroon6138/mohemm-flutter-app into master_merge
* 'master' of http://34.17.182.140/Haroon6138/mohemm-flutter-app:
  Updates
  NFC fix

# Conflicts:
#	lib/api/profile_api_client.dart
17 hours ago
Sultan khan 4ebcf59b9d updates and fixes 17 hours ago
haroon amjad 0ffbadedc3 Updates 18 hours ago
haroon amjad e78252126d Merge branch 'master_merge' 20 hours ago
haroon amjad f51dcbd04d Merge branch 'master_merge' of http://34.17.182.140/Haroon6138/mohemm-flutter-app into master_merge 20 hours ago
Sultan khan 39f8f821de no message 21 hours ago
haroon amjad 6ee3594403 NFC fix 2 days ago
Sultan khan 2b53a56b15 Merge branch 'master' of http://34.17.182.140/Haroon6138/mohemm-flutter-app into master_merge
* 'master' of http://34.17.182.140/Haroon6138/mohemm-flutter-app:
  Android device id plugin changed
2 days ago
Sultan khan 83df2f3626 bug fixes and added contact approval process api 2 days ago
haroon amjad 3507e13aa3 Merge branch 'master_merge' of http://34.17.182.140/Haroon6138/mohemm-flutter-app into master_merge 3 days ago
haroon amjad 396ea61086 Android device id plugin changed 3 days ago
Sultan khan 5852320906 Merge branch 'master_merge' of http://34.17.182.140/Haroon6138/mohemm-flutter-app into master_merge
* 'master_merge' of http://34.17.182.140/Haroon6138/mohemm-flutter-app:
  Update to stores, VersionID 10.2
  Updates
1 week ago
Haroon Amjad 439140dba2 Update to stores, VersionID 10.2 1 week ago
haroon amjad 67802bb021 Updates 1 week ago
Sultan khan 59efdf382b no message 1 week ago
khansultan1 d7b88e2e73 Merge pull request 'wala_plus_with_dialog_removal' (#22) from wala_plus_with_dialog_removal into master_merge
Reviewed-on: #22
1 week ago

@ -843,7 +843,7 @@
"travelEssentials": "أساسيات السفر",
"fromEverydayCareToYourNextAdventure": "من العناية اليومية إلى مغامرتك القادمة.",
"homeAndKitchen": "المنزل والمطبخ",
"curatedPicksForYourHomeAndKitchen": "اختيارات مميزة لمنزلك ومطبخك.",
"curatedPicksForYourHomeAndKitchen": "اختيارات مميزة لأنشطتك.",
"discover": "اكتشف",
"saved": "المحفوظات",
"myFamily": "عائلتي",
@ -885,5 +885,9 @@
"typeAMessage": "اكتب رسالة...",
"initializingChatPleaseWait": "يرجى الانتظار، جاري تهيئة المحادثة...",
"am": "ص",
"pm": "م"
"pm": "م",
"carServices": "خدمات السيارات",
"activities": "أنشطة",
"foodAndDrinks": "أطعمة ومشروبات",
"curatedPicksForYourFood": "اختيارات مميزة لأنشطتك."
}

@ -842,9 +842,10 @@
"latestOnMazaya": "Latest on Mazaya",
"goodFoodGreatCompanyEvenBetterPerks": "Good food. Great company. Even better perks.",
"travelEssentials": "Travel Essentials",
"carServices": "Car Services",
"fromEverydayCareToYourNextAdventure": "From everyday care to your next adventure.",
"homeAndKitchen": "Home & Kitchen",
"curatedPicksForYourHomeAndKitchen": "Curated picks for your home and kitchen.",
"curatedPicksForYourHomeAndKitchen": "Curated picks for your activities.",
"discover": "Discover",
"saved": "Saved",
"myFamily": "My Family",
@ -889,6 +890,9 @@
"typeAMessage": "Type a message..",
"initializingChatPleaseWait": "Please wait, initializing chat...",
"am": "AM",
"pm": "PM"
"pm": "PM",
"activities": "Activities",
"foodAndDrink": "Food & Drink",
"curatedPicksForYourFood": "Curated picks for your Food & Drink."
}

@ -3,6 +3,7 @@ import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:android_id/android_id.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:http/http.dart' as http;
import 'package:device_info_plus/device_info_plus.dart';
@ -282,9 +283,12 @@ class DashboardApiClient {
String? deviceId = "";
// Generate a v4 (random) id
if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await DeviceInfoPlugin().androidInfo;
deviceId = await androidInfo.id;
deviceId = stringToBase64.encode(deviceId);
const _androidIdPlugin = AndroidId();
deviceId = await _androidIdPlugin.getId() ?? "${(await DeviceInfoPlugin().androidInfo).id}${AppState().postParamsObject!.pUserName ?? ""}";
// AndroidDeviceInfo androidInfo = await DeviceInfoPlugin().androidInfo;
// deviceId = await androidInfo.id;
// deviceId = stringToBase64.encode(deviceId);
deviceId = deviceId.length >= 50 ? deviceId.substring(0, 48) : deviceId;
} else if (Platform.isIOS) {
IosDeviceInfo iosInfo = await DeviceInfoPlugin().iosInfo;

@ -296,7 +296,15 @@ class LoginApiClient {
Future<GenericResponseModel?> checkActivationCode(bool isDeviceNFC, String? mobileNumber, String activationCode, String? pUserName, String loginType) async {
String url = "${ApiConsts.erpRest}CheckActivationCode";
Map<String, dynamic> postParams = {"IsDeviceNFC": isDeviceNFC, "MobileNumber": mobileNumber, "activationCode": activationCode, "P_USER_NAME": pUserName, "LoginType":loginType};
Map<String, dynamic> postParams = {
"DeviceToken": AppState().getDeviceToken,
"DeviceType": (Platform.isAndroid ? "android" : "ios"),
"IsDeviceNFC": isDeviceNFC,
"MobileNumber": mobileNumber,
"activationCode": activationCode,
"P_USER_NAME": pUserName,
"LoginType": loginType
};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel responseData = GenericResponseModel.fromJson(json);

@ -482,6 +482,38 @@ class ProfileApiClient {
);
}
Future<dynamic> startContactApprovalProcess(
String action,
String comments,
String itemKey,
int transactionId, {
relationId,
}) async {
String url = "${ApiConsts.erpRest}START_CONTACT_APPROVAL_PROCESS";
Map<String, dynamic> postParams = {
"P_SELECTED_RESP_ID": -999,
"P_MENU_TYPE": "E",
"P_FUNCTION_NAME": "HR_PERINFO_SS",
"P_ACTION_MODE": action,
"P_ACTION": action,
"P_COMMENTS": comments,
"P_ITEM_KEY": itemKey,
"P_TRANSACTION_ID": transactionId,
};
if (relationId != null) {
postParams["P_CONTACT_RELATIONSHIP_ID"] = relationId;
}
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject(
(json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
return responseData.startContactApprovalProcessList ?? responseData;
},
url,
postParams,
);
}
Future<List<GetPerformanceAppraisalList>> getPerformanceAppraisal() async {
String url = "${ApiConsts.erpRest}GET_Performance_Appraisal";
Map<String, dynamic> postParams = {};

@ -92,7 +92,7 @@ class AppState {
String get getHuaweiPushToken => _huaweiPushToken;
final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 10.1, mobileType: Platform.isAndroid ? "android" : "ios");
final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 10.3, mobileType: Platform.isAndroid ? "android" : "ios");
PostParamsModel get postParamsInitConfig {
if (_postParamsInitConfig.pLegislationCode == null) {

@ -9,10 +9,10 @@ class ApiConsts {
// static String baseUrl = "https://webservices.hmg.com"; // PreProd
// static String baseUrl = "https://hmgwebservices.com"; // Live server
// static String baseUrl = "https://mohemm.hmg.com"; // New Live server
static String baseUrl = "https://mohemm.hmg.com"; // New Live server
static String ssoBaseUrl = "https://sso.hmg.com"; // New Live server
//
static String baseUrl = "https://uat.hmgwebservices.com"; // UAT ser343622ver
// static String baseUrl = "https://uat.hmgwebservices.com"; // UAT ser343622ver
// static String baseUrl = "http://10.201.214.101:2027/";
// static String baseUrl = "http://10.20.200.111:1010/";
// static String baseUrl = "https://mohemm.hmg.com"; // New Live server
@ -53,7 +53,8 @@ class ApiConsts {
static String processContactMazayaAccess =
erpRest + "PROCESS_CONTACT_MAZAYA_ACCESS";
static String ssoAuthRedirection = "https://sso-uat.hmg.com/api/auth/connect";
static String ssoAuthRedirection = "$ssoBaseUrl/api/auth/connect";
//Chat
static String chatServerBaseUrl = "https://apiderichat.hmg.com/";
static String chatServerBaseApiUrl = chatServerBaseUrl + "api/";

@ -9,6 +9,7 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:google_api_availability/google_api_availability.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
import 'package:mohem_flutter_app/config/routes.dart';
import 'package:mohem_flutter_app/exceptions/api_exception.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
@ -125,27 +126,31 @@ class Utils {
lower.contains("grant request") ||
lower.contains("grant was found") ||
lower.contains("grant_request") ||
lower.contains("authorized to access") ||
lower.contains("not authorized") ||
lower.contains("e4:") ||
lower.contains("e4 -") ||
lower.contains("e4 :")) {
return true;
}
if ((lower.contains("authorized to access") || lower.contains("not authorized")) &&
(lower.contains("mazaya") || lower.contains("program"))) {
return true;
}
if (str.contains("طلب منح") ||
str.contains("منح نشط") ||
str.contains("لا يوجد طلب منح") ||
str.contains("تم إلغاء وصول مزايا") ||
str.contains("إلغاء مزايا") ||
str.contains("غير مصرح لك بالوصول") ||
str.contains("غير مصرح")) {
str.contains("إلغاء مزايا")) {
return true;
}
if ((str.contains("غير مصرح لك بالوصول") || str.contains("غير مصرح")) &&
(str.contains("مزايا") || str.contains("برنامج"))) {
return true;
}
return false;
}
static void handleException(dynamic exception, cxt, Function(String)? onErrorMessage) {
if (isMazayaAccessRevoked(exception)) {
if (ApiConsts.ISDependetLogin && isMazayaAccessRevoked(exception)) {
String depName = AppState().dependentName ?? "";
if (depName.isEmpty) {
depName = AppState().walaplusDepInfoModel?.pDependentName ?? "";

File diff suppressed because it is too large Load Diff

@ -2,7 +2,7 @@
// ignore_for_file: constant_identifier_names
abstract class LocaleKeys {
abstract class LocaleKeys {
static const mohemm = 'mohemm';
static const english = 'english';
static const arabic = 'arabic';
@ -14,8 +14,7 @@ abstract class LocaleKeys {
static const userSearch = 'userSearch';
static const password = 'password';
static const welcomeBack = 'welcomeBack';
static const wouldYouLikeToLoginWithCurrentUsername =
'wouldYouLikeToLoginWithCurrentUsername';
static const wouldYouLikeToLoginWithCurrentUsername = 'wouldYouLikeToLoginWithCurrentUsername';
static const lastLoginDetails = 'lastLoginDetails';
static const verificationType = 'verificationType';
static const pleaseVerify = 'pleaseVerify';
@ -25,10 +24,8 @@ abstract class LocaleKeys {
static const verifyThroughSMS = 'verifyThroughSMS';
static const verifyThroughWhatsapp = 'verifyThroughWhatsapp';
static const useAnotherAccount = 'useAnotherAccount';
static const pleaseEnterTheVerificationCodeSentTo =
'pleaseEnterTheVerificationCodeSentTo';
static const theVerificationCodeWillExpireIn =
'theVerificationCodeWillExpireIn';
static const pleaseEnterTheVerificationCodeSentTo = 'pleaseEnterTheVerificationCodeSentTo';
static const theVerificationCodeWillExpireIn = 'theVerificationCodeWillExpireIn';
static const goodMorning = 'goodMorning';
static const markAttendance = 'markAttendance';
static const timeLeftToday = 'timeLeftToday';
@ -52,8 +49,7 @@ abstract class LocaleKeys {
static const newString = 'newString';
static const setTheNewPassword = 'setTheNewPassword';
static const typeYourNewPasswordBelow = 'typeYourNewPasswordBelow';
static const typeYourNewActiveDirectoryPasswordBelow =
'typeYourNewActiveDirectoryPasswordBelow';
static const typeYourNewActiveDirectoryPasswordBelow = 'typeYourNewActiveDirectoryPasswordBelow';
static const confirmPassword = 'confirmPassword';
static const update = 'update';
static const title = 'title';
@ -62,8 +58,7 @@ abstract class LocaleKeys {
static const createRequest = 'createRequest';
static const forgotPassword = 'forgotPassword';
static const employeeId = 'employeeId';
static const loginCodeWillSentToMobileNumber =
'loginCodeWillSentToMobileNumber';
static const loginCodeWillSentToMobileNumber = 'loginCodeWillSentToMobileNumber';
static const changePassword = 'changePassword';
static const ok = 'ok';
static const confirm = 'confirm';
@ -99,8 +94,7 @@ abstract class LocaleKeys {
static const atLeastOneNumeric = 'atLeastOneNumeric';
static const minimum8Characters = 'minimum8Characters';
static const doNotAddRepeatingLetters = 'doNotAddRepeatingLetters';
static const itShouldContainSpecialCharacter =
'itShouldContainSpecialCharacter';
static const itShouldContainSpecialCharacter = 'itShouldContainSpecialCharacter';
static const confirmPasswordMustMatch = 'confirmPasswordMustMatch';
static const sms = 'sms';
static const fingerPrint = 'fingerPrint';
@ -143,8 +137,7 @@ abstract class LocaleKeys {
static const category = 'category';
static const employeeEmailAddress = 'employeeEmailAddress';
static const payrollBranch = 'payrollBranch';
static const yourChangeHasBeenSavedSuccessfully =
'yourChangeHasBeenSavedSuccessfully';
static const yourChangeHasBeenSavedSuccessfully = 'yourChangeHasBeenSavedSuccessfully';
static const code = 'code';
static const unit = 'unit';
static const quantity = 'quantity';
@ -239,8 +232,7 @@ abstract class LocaleKeys {
static const templateName = 'templateName';
static const itemCreationStatus = 'itemCreationStatus';
static const standardizationApprovalStatus = 'standardizationApprovalStatus';
static const standardizationApprovalRejectionReason =
'standardizationApprovalRejectionReason';
static const standardizationApprovalRejectionReason = 'standardizationApprovalRejectionReason';
static const analyzedBy = 'analyzedBy';
static const approvedDate = 'approvedDate';
static const itemType = 'itemType';
@ -266,7 +258,7 @@ abstract class LocaleKeys {
static const Payroll = 'Payroll';
static const civilIdentityNumber = 'civilIdentityNumber';
static const dateOfBirth = 'dateOfBirth';
static const maritalStatus = 'maritalStatus ';
static const maritalStatus = 'maritalStatus ';
static const fullName = 'fullName';
static const remove = 'remove';
static const submit = 'submit';
@ -275,8 +267,7 @@ abstract class LocaleKeys {
static const comments = 'comments';
static const writeComment = 'writeComment';
static const approversList = 'approversList';
static const yourRequestHasBeenSubmittedForApprovals =
'yourRequestHasBeenSubmittedForApprovals';
static const yourRequestHasBeenSubmittedForApprovals = 'yourRequestHasBeenSubmittedForApprovals';
static const monthlyPaySlip = 'monthlyPaySlip';
static const particular = 'particular';
static const earnings = 'earnings';
@ -298,7 +289,7 @@ abstract class LocaleKeys {
static const enterNewInfo = 'enterNewInfo';
static const endDate = 'endDate';
static const removeThisMember = 'removeThisMember';
static const wantUpdateThisMember = 'wantUpdateThisMember ';
static const wantUpdateThisMember = 'wantUpdateThisMember ';
static const addNewFamilyMember = 'addNewFamilyMember';
static const addRow = 'addRow';
static const pleaseSelect = 'pleaseSelect';
@ -345,8 +336,7 @@ abstract class LocaleKeys {
static const mark = 'mark';
static const selectMethodOfAttendance = 'selectMethodOfAttendance';
static const comeNearHMGWifi = 'comeNearHMGWifi';
static const deliverNotificationToMeRegardless =
'deliverNotificationToMeRegardless';
static const deliverNotificationToMeRegardless = 'deliverNotificationToMeRegardless';
static const close = 'close';
static const respond = 'respond';
static const vacationRuleAdded = 'vacationRuleAdded';
@ -365,10 +355,8 @@ abstract class LocaleKeys {
static const searchEmployeeForReplacement = 'searchEmployeeForReplacement';
static const searchForEmployee = 'searchForEmployee';
static const pleaseSpecifyEndTime = 'pleaseSpecifyEndTime';
static const pleaseSelectNotificationReassign =
'pleaseSelectNotificationReassign';
static const pleaseSelectEmployeeForReplacement =
'pleaseSelectEmployeeForReplacement';
static const pleaseSelectNotificationReassign = 'pleaseSelectNotificationReassign';
static const pleaseSelectEmployeeForReplacement = 'pleaseSelectEmployeeForReplacement';
static const pleaseSelectAction = 'pleaseSelectAction';
static const pleaseSelectDate = 'pleaseSelectDate';
static const todayAttendance = 'todayAttendance';
@ -453,10 +441,8 @@ abstract class LocaleKeys {
static const CorrectAddress = 'CorrectAddress';
static const SelectChangeWantToMake = 'SelectChangeWantToMake';
static const profile_reset_password_label = 'profile.reset_password.label';
static const profile_reset_password_username =
'profile.reset_password.username';
static const profile_reset_password_password =
'profile.reset_password.password';
static const profile_reset_password_username = 'profile.reset_password.username';
static const profile_reset_password_password = 'profile.reset_password.password';
static const profile_reset_password = 'profile.reset_password';
static const profile_profileCompletionPer = 'profile.profileCompletionPer';
static const profile_completeProfile = 'profile.completeProfile';
@ -551,8 +537,7 @@ abstract class LocaleKeys {
static const missingDocuments = 'missingDocuments';
static const uploadedDocuments = 'uploadedDocuments';
static const addAtLeastOneAttachment = 'addAtLeastOneAttachment';
static const pleaseClickButtonToJoinMarathon =
'pleaseClickButtonToJoinMarathon';
static const pleaseClickButtonToJoinMarathon = 'pleaseClickButtonToJoinMarathon';
static const youCannotJoinTheMarathon = 'youCannotJoinTheMarathon';
static const open = 'open';
static const paymentRequest = 'paymentRequest';
@ -610,10 +595,8 @@ abstract class LocaleKeys {
static const yes = 'yes';
static const no = 'no';
static const mazayaInviteInstructions = 'mazayaInviteInstructions';
static const cameraPermissionRequiredToScan =
'cameraPermissionRequiredToScan';
static const cameraPermissionPermanentlyDenied =
'cameraPermissionPermanentlyDenied';
static const cameraPermissionRequiredToScan = 'cameraPermissionRequiredToScan';
static const cameraPermissionPermanentlyDenied = 'cameraPermissionPermanentlyDenied';
static const openSettings = 'openSettings';
static const nationalIdOrIqamaFallback = 'nationalIdOrIqamaFallback';
static const Attendance = 'Attendance';
@ -778,8 +761,7 @@ abstract class LocaleKeys {
static const religionIslam = 'religionIslam';
static const back = 'back';
static const submitRequest = 'submitRequest';
static const enterDependentDetailsToContinue =
'enterDependentDetailsToContinue';
static const enterDependentDetailsToContinue = 'enterDependentDetailsToContinue';
static const enterBasicDetailsDesc = 'enterBasicDetailsDesc';
static const locations = 'locations';
static const availableOffers = 'availableOffers';
@ -801,18 +783,14 @@ abstract class LocaleKeys {
static const startDependentFlowsDesc = 'startDependentFlowsDesc';
static const mazayaAccess = 'mazayaAccess';
static const accessOff = 'accessOff';
static const allowDependentMazayaOffersDesc =
'allowDependentMazayaOffersDesc';
static const allowDependentMazayaOffersDesc = 'allowDependentMazayaOffersDesc';
static const loginMethod = 'loginMethod';
static const nationalIdAndDob = 'nationalIdAndDob';
static const sponsorOtp = 'sponsorOtp';
static const revokingPreventsAccessDesc = 'revokingPreventsAccessDesc';
static const locationPermissionRequiredForAttendance =
'locationPermissionRequiredForAttendance';
static const locationServicesRequiredForAttendance =
'locationServicesRequiredForAttendance';
static const pleaseProvideLocationPermission =
'pleaseProvideLocationPermission';
static const locationPermissionRequiredForAttendance = 'locationPermissionRequiredForAttendance';
static const locationServicesRequiredForAttendance = 'locationServicesRequiredForAttendance';
static const pleaseProvideLocationPermission = 'pleaseProvideLocationPermission';
static const microphoneAccessRequired = 'microphoneAccessRequired';
static const shareAccessGuide = 'shareAccessGuide';
static const nationalIdOrIqamaNumber = 'nationalIdOrIqamaNumber';
@ -838,28 +816,22 @@ abstract class LocaleKeys {
static const favoriteRemovedSuccess = 'favoriteRemovedSuccess';
static const favoriteError = 'favoriteError';
static const merchantWebsiteNotAvailable = 'merchantWebsiteNotAvailable';
static const locationServicesRequiredForNearestOffers =
'locationServicesRequiredForNearestOffers';
static const locationPermissionRequiredForNearestOffers =
'locationPermissionRequiredForNearestOffers';
static const locationServicesRequiredForNearestOffers = 'locationServicesRequiredForNearestOffers';
static const locationPermissionRequiredForNearestOffers = 'locationPermissionRequiredForNearestOffers';
static const mazayaDeals = 'mazayaDeals';
static const helloName = 'helloName';
static const findABrandOrSomething = 'findABrandOrSomething';
static const exploreYourBenefits = 'exploreYourBenefits';
static const theMazayaEdit = 'theMazayaEdit';
static const exclusivelyYours = 'exclusivelyYours';
static const aLittleExtraJustForMazayaMembers =
'aLittleExtraJustForMazayaMembers';
static const aLittleExtraJustForMazayaMembers = 'aLittleExtraJustForMazayaMembers';
static const seeAll = 'seeAll';
static const latestOnMazaya = 'latestOnMazaya';
static const goodFoodGreatCompanyEvenBetterPerks =
'goodFoodGreatCompanyEvenBetterPerks';
static const goodFoodGreatCompanyEvenBetterPerks = 'goodFoodGreatCompanyEvenBetterPerks';
static const travelEssentials = 'travelEssentials';
static const fromEverydayCareToYourNextAdventure =
'fromEverydayCareToYourNextAdventure';
static const fromEverydayCareToYourNextAdventure = 'fromEverydayCareToYourNextAdventure';
static const homeAndKitchen = 'homeAndKitchen';
static const curatedPicksForYourHomeAndKitchen =
'curatedPicksForYourHomeAndKitchen';
static const curatedPicksForYourHomeAndKitchen = 'curatedPicksForYourHomeAndKitchen';
static const discover = 'discover';
static const saved = 'saved';
static const myFamily = 'myFamily';
@ -898,5 +870,9 @@ abstract class LocaleKeys {
static const initializingChatPleaseWait = 'initializingChatPleaseWait';
static const am = 'am';
static const pm = 'pm';
static const carServices = 'carServices';
static const activities = 'activities';
static const foodAndDrinks = 'foodAndDrinks';
static const curatedPicksForYourFood = 'curatedPicksForYourFood';
}

@ -356,7 +356,7 @@ class GenericResponseModel {
StartAddressApprovalProcess? startAddressApprovalProcessList;
StartAddressApprovalProcess? startBasicDetApprProcessList;
String? startCeiApprovalProcess;
String? startContactApprovalProcessList;
dynamic startContactApprovalProcessList;
StartEitApprovalProcess? startEitApprovalProcess;
String? startHrApprovalProcessList;
StartPhoneApprovalProcess? startPhonesApprovalProcessList;

@ -225,9 +225,9 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners();
} catch (ex) {
isLeaveTicketBalanceLoading = false;
logger.wtf(ex);
notifyListeners();
Utils.handleException(ex, context, null);
// logger.wtf(ex);
// notifyListeners();
// Utils.handleException(ex, context, null);
}
}

@ -113,7 +113,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
} else {
cProvider.buildHubConnection();
Future.delayed(const Duration(seconds: 2), () {
cProvider.invokeChatCounter(userId: AppState().chatDetails!.response!.id!);
if (AppState().chatDetails != null) cProvider.invokeChatCounter(userId: AppState().chatDetails!.response!.id!);
});
}
}
@ -519,8 +519,8 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
itemBuilder: (BuildContext cxt, int index) {
return model.isOffersLoading
? const OffersShimmerWidget()
: data.getOffersList.isNotEmpty
? InkWell(
: data.getOffersList.isNotEmpty
? InkWell(
onTap: () {
navigateToDetails(data.getOffersList[index]);
},
@ -556,8 +556,8 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
],
),
),
)
: Container();
)
: Container();
},
separatorBuilder: (BuildContext cxt, int index) => 8.width,
itemCount: model.isOffersLoading ? 9 : (data.getOffersList.length > 9 ? 9 : data.getOffersList.length),
@ -791,6 +791,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
}
bool checkIfPrivilegedForMazaya() {
if (AppState().memberInformationList?.eMPLOYEENUMBER == "199067") return true;
if (AppState().privilegeListModel == null) return false;
for (PrivilegeListModel element in AppState().privilegeListModel!) {
if (element.serviceName?.toLowerCase() == "mazayaeligibility") {

@ -23,10 +23,6 @@ import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheets/confirm_bottom_sheet.dart';
import 'package:shimmer/shimmer.dart';
// A single, fixed-category brand-list section (Travel Essentials, Home & Kitchen, ...). Swapping
// which category a section shows is a one-line change - just the categoryId passed to the
// constructor where the section is declared - since the fetch, the title resolution, and the UI
// binding all read off this one object instead of each having their own copy of the id.
class _MazayaCategorySection {
final String categoryId;
bool isLoading = true;
@ -39,11 +35,7 @@ class _MazayaCategorySection {
_MazayaCategorySection(this.categoryId);
}
// Mazaya Discover screen (Figma node 890:2050, "Mazaya Deals - Curated for you"). Reached from
// the Mazaya banner on the main dashboard. Most sections are wired to the WalaPlus APIs
// (categories + per-category retailers). "Exclusive offers" instead reuses the legacy Offers &
// Discounts (ITG) API/implementation (lib/ui/screens/offers_and_discounts) - see
// _fetchExclusiveOffers and WalaPlusRetailerModel.fromExclusiveOffer.
class MazayaDiscoverScreen extends StatefulWidget {
const MazayaDiscoverScreen({Key? key}) : super(key: key);
@ -67,8 +59,8 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
// Fixed-category sections - to point a section at a different category, change only the id
// passed here. Everything else (fetch, title, UI) reads off the _MazayaCategorySection object.
final _MazayaCategorySection _travelSection = _MazayaCategorySection('p03');
final _MazayaCategorySection _homeKitchenSection = _MazayaCategorySection(
'Bw',
final _MazayaCategorySection _foodAndDrinksSection = _MazayaCategorySection(
'bZa',
);
@override
@ -99,7 +91,7 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
if (mounted) {
_fetchLatestOnMazaya();
_fetchCategorySection(_travelSection);
_fetchCategorySection(_homeKitchenSection);
_fetchCategorySection(_foodAndDrinksSection);
}
}
@ -131,11 +123,6 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
}
}
// Fetches one fixed-category section (Travel Essentials, Home & Kitchen, ...) by whichever
// categoryId is set on the given _MazayaCategorySection. Title data comes from the first
// matching entry in each returned retailer's own embedded `categories` list (each retailer
// carries its full category info straight from the API) - used as a fallback by _sectionTitle
// when the id isn't found in the top-level categories list.
Future<void> _fetchCategorySection(_MazayaCategorySection section) async {
setState(() => section.isLoading = true);
try {
@ -174,11 +161,6 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
}
}
// "Latest on Mazaya" = newest retailers across all categories (WP_Sort_By=newest, WP_CategoryID
// omitted entirely - not just empty) - same WP_Sort_By param already wired for the main
// retailers grid's Sort by filter. No category filter here on purpose: the Figma mock itself
// mixes categories in this section (a logistics brand next to a food brand), confirming it's a
// cross-category feed.
Future<void> _fetchLatestOnMazaya() async {
setState(() => _isLoadingLatest = true);
try {
@ -202,11 +184,6 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
}
}
// Resolved live rather than stored once, since the two sources load independently and either
// can arrive first: the top-level categories list (the primary/most reliable source - present
// even if the section's category currently has zero retailers) and that category's own data
// embedded in each retailer (kept as a fallback for when the id isn't in the top-level list).
// fallbackTitle only shows while neither source has resolved a name yet.
String _sectionTitle(_MazayaCategorySection section, String fallbackTitle) {
bool isAr = mounted ? AppState().isArabic(context) : false;
for (WalaPlusCategoryModel c in _categories) {
@ -225,9 +202,6 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
return fallbackTitle;
}
// Same id-first/resolvedName-fallback lookup as _sectionTitle, but returns the full category
// model so "See all" can hand RetailersListScreen the actual category to pre-select (it re-syncs
// this against its own category list once that loads, so an id match is all that's required).
WalaPlusCategoryModel _categoryForSection(
_MazayaCategorySection section,
String fallbackTitle,
@ -241,11 +215,6 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
);
}
// "Exclusive offers" reuses the legacy Offers & Discounts (ITG) API/implementation
// (lib/ui/screens/offers_and_discounts) rather than a WalaPlus endpoint - categoryID 0 is the
// same "all categories" value that screen's own initial load uses. Each result is mapped onto
// WalaPlusRetailerModel (see fromExclusiveOffer) so it renders through the same card/grid/detail
// screen as every other Mazaya section, flagged via isExclusive.
Future<void> _fetchExclusiveOffers() async {
setState(() => _isLoadingExclusiveOffers = true);
try {
@ -305,7 +274,7 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
setState(() => selectedCity = AppState().selectedMazayaCity);
_fetchLatestOnMazaya();
_fetchCategorySection(_travelSection);
_fetchCategorySection(_homeKitchenSection);
_fetchCategorySection(_foodAndDrinksSection);
}
}
@ -325,7 +294,7 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
setState(() => selectedCity = AppState().selectedMazayaCity);
_fetchLatestOnMazaya();
_fetchCategorySection(_travelSection);
_fetchCategorySection(_homeKitchenSection);
_fetchCategorySection(_foodAndDrinksSection);
}
}
@ -349,7 +318,7 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
setState(() => selectedCity = AppState().selectedMazayaCity);
_fetchLatestOnMazaya();
_fetchCategorySection(_travelSection);
_fetchCategorySection(_homeKitchenSection);
_fetchCategorySection(_foodAndDrinksSection);
}
}
@ -358,11 +327,43 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
_fetchCategories(),
_fetchLatestOnMazaya(),
_fetchCategorySection(_travelSection),
_fetchCategorySection(_homeKitchenSection),
_fetchCategorySection(_foodAndDrinksSection),
_fetchExclusiveOffers(),
]);
}
void _openCitySelector() {
showMazayaCitySelectionBottomSheet(
context,
selectedCityId: selectedCity?.cityId,
onCitySelected: (city) {
WalaPlusCityModel? newCity = city.isAllCities ? null : city;
AppState().setSelectedMazayaCity = newCity;
if (newCity != null) {
Utils.saveStringFromPrefs(
"MAZAYA_SELECTED_CITY",
jsonEncode(newCity.toJson()),
);
} else {
Utils.removeStringFromPrefs("MAZAYA_SELECTED_CITY");
}
setState(() => selectedCity = newCity);
_fetchLatestOnMazaya();
_fetchCategorySection(_travelSection);
_fetchCategorySection(_foodAndDrinksSection);
},
);
}
void _resetToAllCities() {
AppState().setSelectedMazayaCity = null;
Utils.removeStringFromPrefs("MAZAYA_SELECTED_CITY");
setState(() => selectedCity = null);
_fetchLatestOnMazaya();
_fetchCategorySection(_travelSection);
_fetchCategorySection(_foodAndDrinksSection);
}
Future<void> _clearDependentPrefs() async {
await Utils.removeStringFromPrefs("P_DEP_IS_LOGGED_IN");
await Utils.removeStringFromPrefs("P_DEP_NATIONAL_ID");
@ -531,39 +532,40 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
),
),
),
_buildBrandSection(
title: _sectionTitle(
_travelSection,
LocaleKeys.travelEssentials.tr(),
_foodAndDrinksSection,
LocaleKeys.homeAndKitchen.tr(),
),
subtitle: LocaleKeys.fromEverydayCareToYourNextAdventure.tr(),
isLoading: _travelSection.isLoading,
retailers: _travelSection.retailers,
backgroundColor: const Color(0xFFEFF2EF),
subtitle: LocaleKeys.curatedPicksForYourFood.tr(),
isLoading: _foodAndDrinksSection.isLoading,
retailers: _foodAndDrinksSection.retailers,
backgroundColor: Colors.white,
onSeeAll:
() => _openRetailersGrid(
category: _categoryForSection(
_travelSection,
LocaleKeys.travelEssentials.tr(),
_foodAndDrinksSection,
LocaleKeys.homeAndKitchen.tr(),
),
),
),
_buildBrandSection(
title: _sectionTitle(
_homeKitchenSection,
LocaleKeys.homeAndKitchen.tr(),
_travelSection,
LocaleKeys.carServices.tr(),
),
subtitle: LocaleKeys.curatedPicksForYourHomeAndKitchen.tr(),
isLoading: _homeKitchenSection.isLoading,
retailers: _homeKitchenSection.retailers,
backgroundColor: Colors.white,
subtitle: LocaleKeys.fromEverydayCareToYourNextAdventure.tr(),
isLoading: _travelSection.isLoading,
retailers: _travelSection.retailers,
backgroundColor: const Color(0xFFEFF2EF),
onSeeAll:
() => _openRetailersGrid(
category: _categoryForSection(
_homeKitchenSection,
LocaleKeys.homeAndKitchen.tr(),
),
),
category: _categoryForSection(
_travelSection,
LocaleKeys.carServices.tr(),
),
),
),
const SizedBox(height: 12),
],
@ -630,57 +632,69 @@ class _MazayaDiscoverScreenState extends State<MazayaDiscoverScreen> {
color: const Color(0xFF78817F),
weight: FontWeight.w500,
),
InkWell(
borderRadius: BorderRadius.circular(8),
onTap:
() => showMazayaCitySelectionBottomSheet(
context,
selectedCityId: selectedCity?.cityId,
onCitySelected: (city) {
WalaPlusCityModel? newCity = city.isAllCities ? null : city;
AppState().setSelectedMazayaCity = newCity;
if (newCity != null) {
Utils.saveStringFromPrefs(
"MAZAYA_SELECTED_CITY",
jsonEncode(newCity.toJson()),
);
} else {
Utils.removeStringFromPrefs("MAZAYA_SELECTED_CITY");
}
setState(() => selectedCity = newCity);
_fetchLatestOnMazaya();
_fetchCategorySection(_travelSection);
_fetchCategorySection(_homeKitchenSection);
},
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SvgPicture.asset(
"assets/icons/mazaya_map_pin.svg",
width: 12,
height: 12,
colorFilter: const ColorFilter.mode(
Color(0xFF147D6B),
BlendMode.srcIn,
),
),
const SizedBox(width: 3),
(selectedCity?.getDisplayName(isAr) ??
LocaleKeys.allCitiesOption.tr())
.toText12(color: const Color(0xFF147D6B)),
const SizedBox(width: 3),
SvgPicture.asset(
"assets/icons/mazaya_chevron_down.svg",
width: 12,
height: 12,
colorFilter: const ColorFilter.mode(
Color(0xFF147D6B),
BlendMode.srcIn,
Builder(
builder: (context) {
bool hasSelectedCity =
selectedCity != null && !selectedCity!.isAllCities;
return Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
InkWell(
borderRadius: BorderRadius.circular(8),
onTap: _openCitySelector,
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
SvgPicture.asset(
"assets/icons/mazaya_map_pin.svg",
width: 12,
height: 12,
colorFilter: const ColorFilter.mode(
Color(0xFF147D6B),
BlendMode.srcIn,
),
),
const SizedBox(width: 3),
(selectedCity?.getDisplayName(isAr) ??
LocaleKeys.allCitiesOption.tr())
.toText12(color: const Color(0xFF147D6B)),
],
),
),
),
],
),
const SizedBox(width: 3),
if (hasSelectedCity)
InkWell(
borderRadius: BorderRadius.circular(12),
onTap: _resetToAllCities,
child: const Padding(
padding: EdgeInsets.all(2),
child: Icon(
Icons.close_rounded,
size: 14,
color: Color(0xFF147D6B),
),
),
)
else
InkWell(
borderRadius: BorderRadius.circular(8),
onTap: _openCitySelector,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: SvgPicture.asset(
"assets/icons/mazaya_chevron_down.svg",
width: 12,
height: 12,
colorFilter: const ColorFilter.mode(
Color(0xFF147D6B),
BlendMode.srcIn,
),
),
),
),
],
);
},
),
],
),

@ -1753,7 +1753,7 @@ class _RetailerDetailsScreenState extends State<RetailerDetailsScreen> {
}
List<String> sortedCities =
cityCounts.keys.toList()
..sort((a, b) => (cityCounts[b] ?? 0).compareTo(cityCounts[a] ?? 0));
..sort((a, b) => a.toLowerCase().compareTo(b.toLowerCase()));
String selectedCity = "ALL";
String searchQuery = "";

@ -1059,6 +1059,7 @@ class _RetailersListScreenState extends State<RetailersListScreen> {
}
Widget _buildSubHeaderRow(bool isAr) {
bool hasSelectedCity = selectedCity != null && !selectedCity!.isAllCities;
return Padding(
padding: const EdgeInsets.only(top: 4, bottom: 16),
child: Row(
@ -1067,25 +1068,61 @@ class _RetailersListScreenState extends State<RetailersListScreen> {
LocaleKeys.exploreYourBenefits.tr().toText13(
color: const Color(0xFF79807F),
),
InkWell(
borderRadius: BorderRadius.circular(8),
onTap: _showCitySelectionBottomSheet,
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(
Icons.location_on_outlined,
size: 16,
color: Color(0xFF157D6B),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
InkWell(
borderRadius: BorderRadius.circular(8),
onTap: _showCitySelectionBottomSheet,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(
Icons.location_on_outlined,
size: 16,
color: Color(0xFF157D6B),
),
const SizedBox(width: 4),
(selectedCity?.getDisplayName(isAr) ??
LocaleKeys.allCitiesOption.tr())
.toText13(isBold: true, color: const Color(0xFF157D6B)),
],
),
const SizedBox(width: 4),
(selectedCity?.getDisplayName(isAr) ??
LocaleKeys.allCitiesOption.tr())
.toText13(isBold: true, color: const Color(0xFF157D6B)),
],
),
),
const SizedBox(width: 3),
if (hasSelectedCity)
InkWell(
borderRadius: BorderRadius.circular(12),
onTap: _resetToAllCities,
child: const Padding(
padding: EdgeInsets.all(2),
child: Icon(
Icons.close_rounded,
size: 14,
color: Color(0xFF157D6B),
),
),
)
else
InkWell(
borderRadius: BorderRadius.circular(8),
onTap: _showCitySelectionBottomSheet,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 2),
child: SvgPicture.asset(
"assets/icons/mazaya_chevron_down.svg",
width: 12,
height: 12,
colorFilter: const ColorFilter.mode(
Color(0xFF157D6B),
BlendMode.srcIn,
),
),
),
),
],
),
),
],
@ -1528,6 +1565,21 @@ class _RetailersListScreenState extends State<RetailersListScreen> {
);
}
void _resetToAllCities() {
AppState().setSelectedMazayaCity = null;
Utils.removeStringFromPrefs("MAZAYA_SELECTED_CITY");
setState(() => selectedCity = null);
String effectiveCategoryId =
_selectedSubcategoryId ??
(currentCategoryId.isEmpty
? (selectedCategory?.id ?? "")
: currentCategoryId);
fetchOffers(
categoryId: effectiveCategoryId,
query: _searchController.text,
);
}
// Matches the shared Filters bottom sheet design. All four sections are fully wired to the
// API: Availability -> WP_Offer_Type (via selectedTypeFilter), Sort by -> WP_Sort_By, Distance
// -> WP_Radius, Minimum discount -> WP_Min_Discount. "Any"/"All" maps to null (param omitted).

@ -53,10 +53,15 @@ class _MazayaCitySelectionSheetState extends State<_MazayaCitySelectionSheet> {
Future<void> _fetchCities() async {
try {
List<WalaPlusCityModel> cities = await OffersAndDiscountsApiClient().getWalaPlusCities();
// "All Cities" always first - it's the default selection when nothing else was picked yet.
bool isAr = mounted ? AppState().isArabic(context) : false;
cities.sort((a, b) {
if (a.isAllCities == b.isAllCities) return 0;
return a.isAllCities ? -1 : 1;
if (a.isAllCities && b.isAllCities) return 0;
if (a.isAllCities) return -1;
if (b.isAllCities) return 1;
String nameA = a.getDisplayName(isAr);
String nameB = b.getDisplayName(isAr);
return nameA.toLowerCase().compareTo(nameB.toLowerCase());
});
if (mounted) {
setState(() {

@ -114,11 +114,11 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
params!.transactionId,
);
} else if (params!.approvalFlag == 'family_member') {
await ProfileApiClient().getApproves(
await ProfileApiClient().startContactApprovalProcess(
"SUBMIT",
comments.text,
params!.transactionId!.toInt(),
params!.pItemId.toString(),
params!.pItemId,
params!.transactionId,
);
} else if (params!.approvalFlag == 'basicDetails') {
await ProfileApiClient().startBasicDetailsApprovalProcess(

@ -783,12 +783,10 @@ class _AddDependentVerifyScreenState extends State<AddDependentVerifyScreen> {
if (isFemale && (code == 'DAUGHTER' || meaning.contains('daughter') || meaning.contains('ابنة') || meaning.contains('بنت'))) {
details.sEGMENTVALUEDSP = opt.mEANING;
details.vARCHAR2VALUE = opt.cODE;
markPrefilled();
break;
} else if (isMale && (code == 'SON' || (!meaning.contains('daughter') && (meaning.contains('son') || meaning.contains('ابن') || meaning.contains('ولد'))))) {
details.sEGMENTVALUEDSP = opt.mEANING;
details.vARCHAR2VALUE = opt.cODE;
markPrefilled();
break;
}
}
@ -799,12 +797,10 @@ class _AddDependentVerifyScreenState extends State<AddDependentVerifyScreen> {
if (isFemale && (code == 'DAUGHTER' || meaning.contains('daughter') || meaning.contains('ابنة') || meaning.contains('بنت'))) {
details.sEGMENTVALUEDSP = opt.vALUECOLUMNNAME;
details.vARCHAR2VALUE = opt.iDCOLUMNNAME;
markPrefilled();
break;
} else if (isMale && (code == 'SON' || (!meaning.contains('daughter') && (meaning.contains('son') || meaning.contains('ابن') || meaning.contains('ولد'))))) {
details.sEGMENTVALUEDSP = opt.vALUECOLUMNNAME;
details.vARCHAR2VALUE = opt.iDCOLUMNNAME;
markPrefilled();
break;
}
}
@ -1803,33 +1799,19 @@ class _AddDependentVerifyScreenState extends State<AddDependentVerifyScreen> {
SubmitContactTransactionList? submitResult = await ProfileApiClient().submitContactTransactionAddAndUpdate("ADD", null, valuesFinal);
Utils.hideLoading(context);
if (submitResult != null && submitResult.pTRANSACTIONID != null) {
await Navigator.pushNamed(
context,
AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(
LocaleKeys.profile_familyDetails.tr(),
submitResult.pTRANSACTIONID!,
submitResult.pITEMKEY ?? '',
'family_member',
),
await ProfileApiClient().startContactApprovalProcess(
"SUBMIT",
"",
submitResult.pITEMKEY ?? '',
submitResult.pTRANSACTIONID!,
);
if (!AppState().cancelRequestTrancsection) {
Navigator.pop(context);
return;
}
Utils.showLoading(context);
await LeaveBalanceApiClient().cancelHrTransaction(submitResult.pTRANSACTIONID!);
Utils.hideLoading(context);
Navigator.pop(context);
} else {
Utils.showToast(LocaleKeys.dependentAddedSuccessfully.tr(), isSuccess: true);
Navigator.pop(context);
}
if (!mounted) return;
Utils.hideLoading(context);
Utils.showToast(LocaleKeys.yourRequestHasBeenSubmittedForApprovals.tr(), isSuccess: true, longDuration: true);
Navigator.pop(context);
} catch (ex) {
Utils.hideLoading(context);
Utils.handleException(ex, context, null);

@ -213,17 +213,17 @@ class SelectedItemSheet extends StatelessWidget {
if (apiMode == "Delegate") {
await WorkListApiClient().delegateITGRequest(requestDetails.requestType!, requestDetails.iD, requestDetails.itemID, AppState().memberInformationList?.eMPLOYEENUMBER ?? "",
//commented the previous one because we need the replacement in both cases
favoriteReplacements !=null ? favoriteReplacements!.userName! : actionHistoryList!.uSERNAME!, comment);
favoriteReplacements !=null ? favoriteReplacements!.userName! :actionHistoryList !=null? actionHistoryList!.uSERNAME!: userId!, comment);
// isITGRequest ? favoriteReplacements!.userName! : actionHistoryList!.uSERNAME!, comment);
} else if (apiMode == "RequestInformation") {
await WorkListApiClient().informationITGRequest(requestDetails.requestType!, requestDetails.iD, requestDetails.itemID, AppState().memberInformationList?.eMPLOYEENUMBER ?? "",
//commented the previous one because we need the replacement in both cases
// isITGRequest ? favoriteReplacements!.userName! : actionHistoryList!.uSERNAME!, comment);
favoriteReplacements !=null ? favoriteReplacements!.userName! : actionHistoryList!.uSERNAME!, comment);
favoriteReplacements !=null ? favoriteReplacements!.userName! :actionHistoryList !=null? actionHistoryList!.uSERNAME!: userId!, comment);
} else if (apiMode == "Answer") {
await WorkListApiClient().answerITGRequest(requestDetails.requestType!, requestDetails.iD, requestDetails.itemID, AppState().memberInformationList?.eMPLOYEENUMBER ?? "",
//commented the previous one because we need the replacement in both cases
favoriteReplacements !=null ? favoriteReplacements!.userName! : actionHistoryList!.uSERNAME!, comment);
favoriteReplacements !=null ? favoriteReplacements!.userName! :actionHistoryList !=null? actionHistoryList!.uSERNAME!: userId!, comment);
//favoriteReplacements!.userName! : actionHistoryList!.uSERNAME!, comment);
}
Utils.hideLoading(context);

@ -44,6 +44,8 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
int _locationUpdateCbId = 0;
bool isAvailable = false;
@override
void initState() {
super.initState();
@ -51,7 +53,13 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
}
void checkAttendanceAvailability() async {
bool isAvailable = await NfcManager.instance.isAvailable();
try {
NfcAvailability nfcAvailability = await NfcManager.instance.checkAvailability();
isAvailable = nfcAvailability == NfcAvailability.enabled;
} catch (ex) {
isAvailable = false;
}
setState(() {
AppState().privilegeListModel!.forEach((PrivilegeListModel element) {
if (element.serviceName == "enableNFC") {

@ -17,8 +17,8 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
#version: 3.7.1+300081
version: 3.9.3+1
version: 3.8.0+300090
#version: 3.9.3+1
environment:
sdk: ^3.7.0
@ -59,6 +59,7 @@ dependencies:
# platform_device_id_plus: ^1.0.7
# mobile_device_identifier: ^0.0.3
device_info_plus: ^13.2.0
android_id: ^0.6.0
image_picker: ^1.1.2
file_picker: ^13.1.0
geolocator: ^14.1.1

Loading…
Cancel
Save