diff --git a/android/app/build.gradle b/android/app/build.gradle index 5590740..5279c1f 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -59,12 +59,6 @@ android { } signingConfigs { - debug { - keyAlias keystoreProperties['keyAlias'] - keyPassword keystoreProperties['keyPassword'] - storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null - storePassword keystoreProperties['storePassword'] - } release { keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] @@ -73,6 +67,9 @@ android { } } buildTypes { + debug { + signingConfig signingConfigs.debug + } release { signingConfig signingConfigs.release minifyEnabled true diff --git a/assets/langs/ar-SA.json b/assets/langs/ar-SA.json index 4178d17..4b7acc9 100644 --- a/assets/langs/ar-SA.json +++ b/assets/langs/ar-SA.json @@ -43,6 +43,7 @@ "newString": "جديد", "setTheNewPassword": "قم بتعيين كلمة المرور الجديدة", "typeYourNewPasswordBelow": "اكتب كلمة المرور الجديدة أدناه", + "typeYourNewActiveDirectoryPasswordBelow": "اكتب كلمة مرور الدليل النشط الجديدة أدناه", "confirmPassword": "تأكيد كلمة المرور", "update": "تحديث", "title": "عنوان", @@ -404,7 +405,8 @@ "stamp": "ختم", "addFavoriteList": "هل تريد اضافة {name} لقائمة المفضله", "feedbackUserExperience": "هذا للحصول على تعليقات حول تجربة المستخدم", - "rateUI": ".1 كيف تريد تقييم التطبيق", + "rateUI": "كيف تريد أن تقيم", + "rateUI2": "ما مدى رضائك عن هذا التطبيق", "submitSurvey": "ارسال الاستبيان", "typeHere": "اكتب هنا", "infoDetail": "تفاصيل المعلومات", @@ -424,7 +426,7 @@ "typeCurrentPasswordBelow": "اكتب كلمة المرور الحاليه", "currentPassword": "كلمة المرور الحاليه", "concurrentReports": "التقارير المتزامنه", - "EnterNewAddressMoved" : "أدخل عنوان جديد إذا كنت قد انتقلت", + "EnterNewAddressMoved": "أدخل عنوان جديد إذا كنت قد انتقلت", "CorrectAddress": "تصحيح أو تعديل هذا العنوان", "SelectChangeWantToMake": " حدد نوع التغيير الذي تريد القيام به.", "profile": { @@ -480,7 +482,7 @@ "gameTime": "وقت اللعب:", "joinMarathon": "انضم إلى ماراثون", "joinDemoMarathon": "انضم إلى الماراثون التجريبي", - "demo":"تجريبي", + "demo": "تجريبي", "minutes": "الدقائق", "seconds": "ثواني", "note": "ملحوظة:", @@ -517,12 +519,16 @@ "startingIn": "يبدأ في", "youAreOutOfContest": "أنت خارج المسابقة.", "winners": "الفائزين!!!", - "expireAfter":"تنتهي بعد", - "oneWeek":"أسبوع 1", - "twoWeek":"2 أسبوع", + "expireAfter": "تنتهي بعد", + "oneWeek": "أسبوع 1", + "twoWeek": "2 أسبوع", "noUpcoming": "لا يوجد قادم", "fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية", "noWinner": "حزين! لم يفز أحد اليوم.", - "myTeam" : "فريقي", - "youCanPlayDemo": "لكن يمكنك لعب العرض" + "myTeam": "فريقي", + "youCanPlayDemo": "لكن يمكنك لعب العرض", + "connectHmgWifi": "قم بتوصيل HMG WIFI", + "connectedHmgWifi": "اتصال HMG WIFI", + "itgForms": "نماذج (ITG)", + "resetAdPassword": "إعادة تعيين كلمة مرور AD" } \ No newline at end of file diff --git a/assets/langs/en-US.json b/assets/langs/en-US.json index e4a4266..3f460a1 100644 --- a/assets/langs/en-US.json +++ b/assets/langs/en-US.json @@ -43,6 +43,7 @@ "newString": "New", "setTheNewPassword": "Set the new password", "typeYourNewPasswordBelow": "Type your new password below", + "typeYourNewActiveDirectoryPasswordBelow": "Type new active directory password below", "confirmPassword": "Confirm Password", "update": "Update", "title": "Title", @@ -404,7 +405,8 @@ "stamp": "Stamp", "addFavoriteList": "Do you want to add {name} in your favorite list", "feedbackUserExperience": "This is to get the feedback about the user experience", - "rateUI": "1. How would you rate this UI?", + "rateUI": "How would you like to rate", + "rateUI2": "How do you satisfied with this application", "submitSurvey": "Submit Survey", "typeHere": "Type here", "infoDetail": "Info Detail", @@ -424,7 +426,7 @@ "typeCurrentPasswordBelow": "Type Your Current password below", "currentPassword": "Current password", "concurrentReports": "Concurrent Reports", - "EnterNewAddressMoved" : "Enter a new address if you have moved", + "EnterNewAddressMoved": "Enter a new address if you have moved", "CorrectAddress": "Correct or amend this address", "SelectChangeWantToMake": "Select the type of change you want to make", "profile": { @@ -469,7 +471,7 @@ "gameTime": "Game Time:", "joinMarathon": "Join Marathon", "joinDemoMarathon": "Join Demo Marathon", - "demo":"Demo", + "demo": "Demo", "minutes": "Minutes", "seconds": "Seconds", "note": "Note:", @@ -517,12 +519,16 @@ "startingIn": "Starting in", "youAreOutOfContest": "You are out of the contest.", "winners": "WINNERS!!!", - "expireAfter":"Expires After", - "oneWeek":"1 Week", - "twoWeek":"2 Week", + "expireAfter": "Expires After", + "oneWeek": "1 Week", + "twoWeek": "2 Week", "noUpcoming": "There is no upcoming", "fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.", "noWinner": "Sad! No one won today.", - "myTeam" : "My Team", - "youCanPlayDemo": "But you can play demo" + "myTeam": "My Team", + "youCanPlayDemo": "But you can play demo", + "connectHmgWifi": "Connect HMG WIFI", + "connectedHmgWifi": "Connected HMG WIFI", + "itgForms": "ITG Forms", + "resetAdPassword": "Reset AD Password" } \ No newline at end of file diff --git a/lib/api/dashboard_api_client.dart b/lib/api/dashboard_api_client.dart index 76b10ce..dfa4801 100644 --- a/lib/api/dashboard_api_client.dart +++ b/lib/api/dashboard_api_client.dart @@ -12,6 +12,7 @@ import 'package:mohem_flutter_app/models/dashboard/list_menu.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/itg/itg_main_response.dart'; import 'package:mohem_flutter_app/models/itg/itg_response_model.dart'; +import 'package:platform_device_id/platform_device_id.dart'; import 'package:uuid/uuid.dart'; class DashboardApiClient { @@ -111,8 +112,8 @@ class DashboardApiClient { // Generate a v4 (random) id Map postParams = { - // "UID": await PlatformDeviceId.getDeviceId, //uuid.v4(), //Mobile Id - "UID": uuid.v4(), //Mobile Id + "UID": await PlatformDeviceId.getDeviceId, //uuid.v4(), //Mobile Id + // "UID": uuid.v4(), //Mobile Id "Latitude": lat, "Longitude": long, "QRValue": QRValue, diff --git a/lib/api/login_api_client.dart b/lib/api/login_api_client.dart index 7da7754..1b6b19e 100644 --- a/lib/api/login_api_client.dart +++ b/lib/api/login_api_client.dart @@ -145,4 +145,15 @@ class LoginApiClient { return responseData; }, url, postParams); } + + Future changePasswordFromActiveDirectorySession(String password, String email) async { + String url = "${ApiConsts.authenticationRest}SetPassword"; + Map postParams = {"EmailAddress": email, "Password": password, "generalid": "Cs2020@2016\$2958"}; + postParams.addAll(AppState().postParamsJson); + postParams["LogInTokenID"] = "@acT!V3D!r3Ct0rY"; // hard code token for active directory + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData; + }, url, postParams); + } } diff --git a/lib/api/marathon/marathon_api_client.dart b/lib/api/marathon/marathon_api_client.dart index 9497b48..3d75d87 100644 --- a/lib/api/marathon/marathon_api_client.dart +++ b/lib/api/marathon/marathon_api_client.dart @@ -87,8 +87,8 @@ class MarathonApiClient { Future joinMarathonAsParticipant() async { Map jsonObject = { "employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER ?? "", - "employeeNameAr": AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr ?? "", - "employeeNameEn": AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn ?? "", + "employeeNameAr": AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr ?? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn ?? "", + "employeeNameEn": AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn ?? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr ?? "", "marathonId": AppState().getMarathonProjectId!, }; @@ -103,7 +103,6 @@ class MarathonApiClient { ); } - Future getNextQuestion({required String? questionId, required String marathonId}) async { Map jsonObject = { "previousQuestionId": questionId, diff --git a/lib/api/worklist/worklist_api_client.dart b/lib/api/worklist/worklist_api_client.dart index d55dc8d..628701f 100644 --- a/lib/api/worklist/worklist_api_client.dart +++ b/lib/api/worklist/worklist_api_client.dart @@ -14,6 +14,7 @@ import 'package:mohem_flutter_app/models/get_mo_notification_body_list_model.dar import 'package:mohem_flutter_app/models/get_notification_buttons_list_model.dart'; import 'package:mohem_flutter_app/models/get_po_Item_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_po_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_pr_action_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_pr_information_list.dart'; import 'package:mohem_flutter_app/models/get_pr_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_quotation_analysis_list_model.dart'; @@ -47,7 +48,7 @@ class WorkListApiClient { Map postParams = { "P_NOTIFICATION_TYPE": pNotificationType, "P_PAGE_NUM": pPageNum, - "P_PAGE_LIMIT": 25, + "P_PAGE_LIMIT": 20, "P_ITEM_TYPE": pItemType, "P_SEARCH_FROM_USER": pSearchUser, "P_SEARCH_ITEM_TYPE_DSP_NAME": pSearchItemType, @@ -91,6 +92,16 @@ class WorkListApiClient { }, url, postParams); } + Future> getPRAttachments(String pOLineID) async { + String url = "${ApiConsts.erpRest}GET_PR_ATTACHMENTS"; + Map postParams = {"P_PO_LINE_ID": pOLineID}; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getPRAttachmentList ?? []; + }, url, postParams); + } + Future> getRFCEmployeeeList(int pNotificationID) async { String url = "${ApiConsts.erpRest}GET_RFC_EMPLOYEE_LIST"; Map postParams = {"P_NOTIFICATION_ID": pNotificationID, "P_PAGE_NUM": 1, "P_PAGE_LIMIT": 10}; @@ -115,6 +126,20 @@ class WorkListApiClient { }, url, postParams); } + Future> getActionHistoryForPR(String pOLineID) async { + String url = "${ApiConsts.erpRest}GET_PR_ACTION_HISTORY"; + Map postParams = { + "P_PO_LINE_ID": pOLineID, + "P_PAGE_LIMIT": 100, + "P_PAGE_NUM": 1, + }; + postParams.addAll(AppState().postParamsJson); + return await ApiClient().postJsonForObject((json) { + GenericResponseModel responseData = GenericResponseModel.fromJson(json); + return responseData.getPRActionHistoryList?.reversed.toList() ?? []; + }, url, postParams); + } + Future> getNotificationButtons(int pNotificationID) async { String url = "${ApiConsts.erpRest}GET_NOTIFICATION_BUTTONS"; Map postParams = {"P_NOTIFICATION_ID": pNotificationID}; @@ -414,7 +439,7 @@ class WorkListApiClient { "EmployeeNumber": employeeNumber, "Comments": "", "AdditionalFields": null, - "NewUserEMPId":newUserEMPId + "NewUserEMPId": newUserEMPId }; postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject((json) { @@ -590,7 +615,8 @@ class WorkListApiClient { }, url, postParams); } - Future submitComment({String? comment, String? email, String? userId, int? notificationId, required String apiMode, int? approverIndex = null}) async { + Future submitComment( + {String? comment, String? email, String? userId, int? notificationId, required String apiMode, int? approverIndex = null, List>? attributeData = const []}) async { String url = "${ApiConsts.erpRest}NOTIFICATION_ACTIONS"; Map postParams = { "P_COMMENTS": comment, @@ -599,7 +625,7 @@ class WorkListApiClient { "P_FORWARD_TO_USER_NAME": userId, "P_NOTIFICATION_ID": notificationId, "P_APPROVER_INDEX": approverIndex, - "RespondAttributeList": [] + "RespondAttributeList": attributeData }; postParams.addAll(AppState().postParamsJson); return await ApiClient().postJsonForObject((json) { @@ -641,5 +667,4 @@ class WorkListApiClient { return responseData.getPRInformationList; }, url, postParams); } - } diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 5363feb..7ccdd4f 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -45,6 +45,8 @@ class AppState { String? get getForgetPasswordTokenID => forgetPasswordTokenID; + bool isConnectedToHMG = false; + //Wifi info String? _mohemmWifiSSID; @@ -88,7 +90,7 @@ class AppState { String get getHuaweiPushToken => _huaweiPushToken; - final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 10, mobileType: Platform.isAndroid ? "android" : "ios"); + final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.8, mobileType: Platform.isAndroid ? "android" : "ios"); void setPostParamsInitConfig() { isAuthenticated = false; diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index 688fd70..32b3fc7 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -3,11 +3,12 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart'; class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server // static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server - // static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server - static String baseUrl = "https://hmgwebservices.com"; // Live server + static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server + // static String baseUrl = "https://hmgwebservices.com"; // Live server static String baseUrlServices = baseUrl + "/Services/"; // server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; + static String authenticationRest = baseUrlServices + "Authentication.svc/REST/"; static String erpRest = baseUrlServices + "ERP.svc/REST/"; static String swpRest = baseUrlServices + "SWP.svc/REST/"; static String user = baseUrlServices + "api/User/"; diff --git a/lib/classes/notifications.dart b/lib/classes/notifications.dart index 29073e1..30736e3 100644 --- a/lib/classes/notifications.dart +++ b/lib/classes/notifications.dart @@ -127,17 +127,13 @@ class AppNotifications { } void _handleOpenApp(RemoteMessage message) { - logger.i("Open App Message:" + message.toMap().toString()); - if (message.data.isNotEmpty && message.data["messageType"] == 'chat') { + if (message.data.isNotEmpty && message.data["type"] == 'chat') { Utils.saveStringFromPrefs("isAppOpendByChat", "true"); Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString()); } } - -} - -AndroidNotificationChannel channel = AndroidNotificationChannel( +AndroidNotificationChannel channel = const AndroidNotificationChannel( "high_importance_channel", "High Importance Notifications", importance: Importance.high, @@ -153,4 +149,4 @@ Future backgroundMessageHandler(RemoteMessage message) async { ChatVoipCall().showCallkitIncoming(uuid: const Uuid().v4(), data: message, background: true); } } -} \ No newline at end of file +} diff --git a/lib/classes/utils.dart b/lib/classes/utils.dart index cc20f1b..34831c2 100644 --- a/lib/classes/utils.dart +++ b/lib/classes/utils.dart @@ -21,7 +21,6 @@ import 'package:mohem_flutter_app/widgets/loading_dialog.dart'; import 'package:nfc_manager/nfc_manager.dart'; import 'package:nfc_manager/platform_tags.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:store_checker/store_checker.dart'; // ignore_for_file: avoid_annotating_with_dynamic diff --git a/lib/config/routes.dart b/lib/config/routes.dart index d5bb898..d057be3 100644 --- a/lib/config/routes.dart +++ b/lib/config/routes.dart @@ -9,6 +9,7 @@ import 'package:mohem_flutter_app/ui/chat/chat_detailed_screen.dart'; import 'package:mohem_flutter_app/ui/chat/chat_home.dart'; import 'package:mohem_flutter_app/ui/chat/favorite_users_screen.dart'; import 'package:mohem_flutter_app/ui/landing/dashboard_screen.dart'; +import 'package:mohem_flutter_app/ui/landing/itg/change_itg_ad_password_screen.dart'; import 'package:mohem_flutter_app/ui/landing/itg/its_add_screen_video_image.dart'; import 'package:mohem_flutter_app/ui/landing/itg/survey_screen.dart'; import 'package:mohem_flutter_app/ui/landing/today_attendance_screen2.dart'; @@ -178,6 +179,7 @@ class AppRoutes { static const String subordinateLeave = "/subordinateLeave"; static const String changePassword = "/changePassword"; + static const String changeItgAdPasswordScreen = "/changeItgAdPasswordScreen"; //Chat static const String chat = "/chat"; @@ -291,7 +293,7 @@ class AppRoutes { subordinateLeave: (BuildContext context) => SubordinateLeave(), changePassword: (BuildContext context) => ChangePasswordScreen(), - + changeItgAdPasswordScreen: (BuildContext context) => ChangeItgAdPasswordScreen(), //Chat chat: (BuildContext context) => ChatHome(), chatDetailed: (BuildContext context) => ChatDetailScreen(), diff --git a/lib/generated/codegen_loader.g.dart b/lib/generated/codegen_loader.g.dart index f3497d3..ba21c29 100644 --- a/lib/generated/codegen_loader.g.dart +++ b/lib/generated/codegen_loader.g.dart @@ -59,6 +59,7 @@ class CodegenLoader extends AssetLoader{ "newString": "جديد", "setTheNewPassword": "قم بتعيين كلمة المرور الجديدة", "typeYourNewPasswordBelow": "اكتب كلمة المرور الجديدة أدناه", + "typeYourNewActiveDirectoryPasswordBelow": "اكتب كلمة مرور الدليل النشط الجديدة أدناه", "confirmPassword": "تأكيد كلمة المرور", "update": "تحديث", "title": "عنوان", @@ -420,7 +421,8 @@ class CodegenLoader extends AssetLoader{ "stamp": "ختم", "addFavoriteList": "هل تريد اضافة {name} لقائمة المفضله", "feedbackUserExperience": "هذا للحصول على تعليقات حول تجربة المستخدم", - "rateUI": ".1 كيف تريد تقييم التطبيق", + "rateUI": "كيف تريد أن تقيم", + "rateUI2": "ما مدى رضائك عن هذا التطبيق", "submitSurvey": "ارسال الاستبيان", "typeHere": "اكتب هنا", "infoDetail": "تفاصيل المعلومات", @@ -540,7 +542,11 @@ class CodegenLoader extends AssetLoader{ "fakeLocation": ".لقد تتبعنا أنك تحاول استخدام موقع مزيف! يعتبر هذا مخالفة وقد تم إخطار الموارد البشرية", "noWinner": "حزين! لم يفز أحد اليوم.", "myTeam": "فريقي", - "youCanPlayDemo": "لكن يمكنك لعب العرض" + "youCanPlayDemo": "لكن يمكنك لعب العرض", + "connectHmgWifi": "قم بتوصيل HMG WIFI", + "connectedHmgWifi": "اتصال HMG WIFI", + "itgForms": "نماذج (ITG)", + "resetAdPassword": "إعادة تعيين كلمة مرور AD" }; static const Map en_US = { "mohemm": "Mohemm", @@ -587,6 +593,7 @@ static const Map en_US = { "newString": "New", "setTheNewPassword": "Set the new password", "typeYourNewPasswordBelow": "Type your new password below", + "typeYourNewActiveDirectoryPasswordBelow": "Type new active directory password below", "confirmPassword": "Confirm Password", "update": "Update", "title": "Title", @@ -948,7 +955,8 @@ static const Map en_US = { "stamp": "Stamp", "addFavoriteList": "Do you want to add {name} in your favorite list", "feedbackUserExperience": "This is to get the feedback about the user experience", - "rateUI": "1. How would you rate this UI?", + "rateUI": "How would you like to rate", + "rateUI2": "How do you satisfied with this application", "submitSurvey": "Submit Survey", "typeHere": "Type here", "infoDetail": "Info Detail", @@ -1068,7 +1076,11 @@ static const Map en_US = { "fakeLocation": "We traced out that you try to use a fake location! This is considered a violation, and HR has been notified.", "noWinner": "Sad! No one won today.", "myTeam": "My Team", - "youCanPlayDemo": "But you can play demo" + "youCanPlayDemo": "But you can play demo", + "connectHmgWifi": "Connect HMG WIFI", + "connectedHmgWifi": "Connected HMG WIFI", + "itgForms": "ITG Forms", + "resetAdPassword": "Reset AD Password" }; static const Map> mapLocales = {"ar_SA": ar_SA, "en_US": en_US}; } diff --git a/lib/generated/locale_keys.g.dart b/lib/generated/locale_keys.g.dart index 4eb91c9..343bf38 100644 --- a/lib/generated/locale_keys.g.dart +++ b/lib/generated/locale_keys.g.dart @@ -44,6 +44,7 @@ abstract class LocaleKeys { static const newString = 'newString'; static const setTheNewPassword = 'setTheNewPassword'; static const typeYourNewPasswordBelow = 'typeYourNewPasswordBelow'; + static const typeYourNewActiveDirectoryPasswordBelow = 'typeYourNewActiveDirectoryPasswordBelow'; static const confirmPassword = 'confirmPassword'; static const update = 'update'; static const title = 'title'; @@ -406,6 +407,7 @@ abstract class LocaleKeys { static const addFavoriteList = 'addFavoriteList'; static const feedbackUserExperience = 'feedbackUserExperience'; static const rateUI = 'rateUI'; + static const rateUI2 = 'rateUI2'; static const submitSurvey = 'submitSurvey'; static const typeHere = 'typeHere'; static const infoDetail = 'infoDetail'; @@ -511,5 +513,9 @@ abstract class LocaleKeys { static const noWinner = 'noWinner'; static const myTeam = 'myTeam'; static const youCanPlayDemo = 'youCanPlayDemo'; + static const connectHmgWifi = 'connectHmgWifi'; + static const connectedHmgWifi = 'connectedHmgWifi'; + static const itgForms = 'itgForms'; + static const resetAdPassword = 'resetAdPassword'; } diff --git a/lib/models/generic_response_model.dart b/lib/models/generic_response_model.dart index a5677af..a9006eb 100644 --- a/lib/models/generic_response_model.dart +++ b/lib/models/generic_response_model.dart @@ -28,6 +28,7 @@ import 'package:mohem_flutter_app/models/get_mobile_login_info_list_model.dart'; import 'package:mohem_flutter_app/models/get_notification_buttons_list_model.dart'; import 'package:mohem_flutter_app/models/get_po_Item_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_po_notification_body_list_model.dart'; +import 'package:mohem_flutter_app/models/get_pr_action_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_pr_information_list.dart'; import 'package:mohem_flutter_app/models/get_pr_notification_body_list_model.dart'; import 'package:mohem_flutter_app/models/get_quotation_analysis_list_model.dart'; @@ -170,9 +171,11 @@ class GenericResponseModel { List? getAbsenceTransactionList; List? getAccrualBalancesList; List? getActionHistoryList; + List? getPRActionHistoryList; List? getAddressDffStructureList; List? getApprovesList; List? getAttachementList; + List? getPRAttachmentList; GetAttendanceTracking? getAttendanceTrackingList; List? getBasicDetColsStructureList; List? getBasicDetDffStructureList; @@ -436,10 +439,12 @@ class GenericResponseModel { this.getAbsenceTransactionList, this.getAccrualBalancesList, this.getActionHistoryList, + this.getPRActionHistoryList, this.getAddressDffStructureList, this.getAddressNotificationBodyList, this.getApprovesList, this.getAttachementList, + this.getPRAttachmentList, this.getAttendanceTrackingList, this.getBasicDetColsStructureList, this.getBasicDetDffStructureList, @@ -751,6 +756,13 @@ class GenericResponseModel { }); } + if (json['PR_Action_History_List'] != null) { + getPRActionHistoryList = []; + json['PR_Action_History_List'].forEach((v) { + getPRActionHistoryList!.add(GetPRActionHistoryList.fromJson(v)); + }); + } + if (json['GetAddressDffStructureList'] != null) { getAddressDffStructureList = []; json['GetAddressDffStructureList'].forEach((v) { @@ -772,6 +784,14 @@ class GenericResponseModel { getAttachementList!.add(GetAttachementList.fromJson(v)); }); } + + if (json['PR_Attachments_List'] != null) { + getPRAttachmentList = []; + json['PR_Attachments_List'].forEach((v) { + getPRAttachmentList!.add(GetAttachementList.fromJson(v)); + }); + } + getAttendanceTrackingList = json["GetAttendanceTrackingList"] == null ? null : GetAttendanceTracking.fromMap(json["GetAttendanceTrackingList"]); if (json['GetBasicDetColsStructureList'] != null) { getBasicDetColsStructureList = []; diff --git a/lib/models/get_pr_action_history_list_model.dart b/lib/models/get_pr_action_history_list_model.dart new file mode 100644 index 0000000..d57668d --- /dev/null +++ b/lib/models/get_pr_action_history_list_model.dart @@ -0,0 +1,68 @@ +class GetPRActionHistoryList { + String? aCTION; + String? aCTIONCODE; + String? aPPROVALDATE; + String? eMAILADDRESS; + String? eMPLOYEEIMAGE; + int? fROMROWNUM; + String? nAME; + String? nOTE; + int? nOOFROWS; + String? pOSITIONTITLE; + int? rOWNUM; + int? sEQUENCE; + int? tOROWNUM; + Null? uSERNAME; + + GetPRActionHistoryList( + {this.aCTION, + this.aCTIONCODE, + this.aPPROVALDATE, + this.eMAILADDRESS, + this.eMPLOYEEIMAGE, + this.fROMROWNUM, + this.nAME, + this.nOTE, + this.nOOFROWS, + this.pOSITIONTITLE, + this.rOWNUM, + this.sEQUENCE, + this.tOROWNUM, + this.uSERNAME}); + + GetPRActionHistoryList.fromJson(Map json) { + aCTION = json['ACTION']; + aCTIONCODE = json['ACTION_CODE']; + aPPROVALDATE = json['APPROVAL_DATE']; + eMAILADDRESS = json['EMAIL_ADDRESS']; + eMPLOYEEIMAGE = json['EMPLOYEE_IMAGE']; + fROMROWNUM = json['FROM_ROW_NUM']; + nAME = json['NAME']; + nOTE = json['NOTE']; + nOOFROWS = json['NO_OF_ROWS']; + pOSITIONTITLE = json['POSITION_TITLE']; + rOWNUM = json['ROW_NUM']; + sEQUENCE = json['SEQUENCE']; + tOROWNUM = json['TO_ROW_NUM']; + uSERNAME = json['USER_NAME']; + } + + Map toJson() { + Map data = new Map(); + data['ACTION'] = this.aCTION; + data['ACTION_CODE'] = this.aCTIONCODE; + data['APPROVAL_DATE'] = this.aPPROVALDATE; + data['EMAIL_ADDRESS'] = this.eMAILADDRESS; + data['EMPLOYEE_IMAGE'] = this.eMPLOYEEIMAGE; + data['FROM_ROW_NUM'] = this.fROMROWNUM; + data['NAME'] = this.nAME; + data['NOTE'] = this.nOTE; + data['NO_OF_ROWS'] = this.nOOFROWS; + data['POSITION_TITLE'] = this.pOSITIONTITLE; + data['ROW_NUM'] = this.rOWNUM; + data['SEQUENCE'] = this.sEQUENCE; + data['TO_ROW_NUM'] = this.tOROWNUM; + data['USER_NAME'] = this.uSERNAME; + return data; + } +} diff --git a/lib/models/itg/itg_response_model.dart b/lib/models/itg/itg_response_model.dart index 4dff106..dff7869 100644 --- a/lib/models/itg/itg_response_model.dart +++ b/lib/models/itg/itg_response_model.dart @@ -5,6 +5,7 @@ import 'dart:convert'; import 'package:mohem_flutter_app/models/itg/advertisement.dart'; +import 'package:mohem_flutter_app/models/itg/survey_model.dart'; MohemmItgResponseItem mohemmItgResponseItemFromJson(String str) => MohemmItgResponseItem.fromJson(json.decode(str)); @@ -103,7 +104,7 @@ class ItgResponseData { final bool? isDeleted; final bool? showDelete; final Advertisement? advertisement; - final dynamic survey; + final SurveyModel? survey; final dynamic isActive; final dynamic pageSize; final dynamic pageNo; @@ -126,7 +127,7 @@ class ItgResponseData { isDeleted: json["isDeleted"] == null ? null : json["isDeleted"], showDelete: json["showDelete"] == null ? null : json["showDelete"], advertisement: json["advertisement"] == null ? null : Advertisement.fromJson(json["advertisement"]), - survey: json["survey"], + survey: json["survey"] == null ? null : SurveyModel.fromJson(json["survey"]), isActive: json["isActive"], pageSize: json["pageSize"], pageNo: json["pageNo"], diff --git a/lib/models/itg/survey_model.dart b/lib/models/itg/survey_model.dart new file mode 100644 index 0000000..7cdbbdd --- /dev/null +++ b/lib/models/itg/survey_model.dart @@ -0,0 +1,148 @@ +class SurveyModel { + int? surveyId; + String? referenceNo; + String? title; + String? description; + List? questions; + bool? isActive; + Null? pageSize; + Null? pageNo; + Null? languageId; + + SurveyModel({this.surveyId, this.referenceNo, this.title, this.description, this.questions, this.isActive, this.pageSize, this.pageNo, this.languageId}); + + SurveyModel.fromJson(Map json) { + surveyId = json['surveyId']; + referenceNo = json['referenceNo']; + title = json['title']; + description = json['description']; + if (json['questions'] != null) { + questions = []; + json['questions'].forEach((v) { + questions!.add(new Questions.fromJson(v)); + }); + } + isActive = json['isActive']; + pageSize = json['pageSize']; + pageNo = json['pageNo']; + languageId = json['languageId']; + } + + Map toJson() { + Map data = new Map(); + data['surveyId'] = this.surveyId; + data['referenceNo'] = this.referenceNo; + data['title'] = this.title; + data['description'] = this.description; + if (this.questions != null) { + data['questions'] = this.questions!.map((v) => v.toJson()).toList(); + } + data['isActive'] = this.isActive; + data['pageSize'] = this.pageSize; + data['pageNo'] = this.pageNo; + data['languageId'] = this.languageId; + return data; + } +} + +class Questions { + int? questionId; + String? title; + bool? isRequired; + String? type; + int? sequenceNo; + Null? surveyId; + List? options; + Null? rspPercentage; + Null? isActive; + Null? pageSize; + Null? pageNo; + Null? languageId; + + Questions({this.questionId, this.title, this.isRequired, this.type, this.sequenceNo, this.surveyId, this.options, this.rspPercentage, this.isActive, this.pageSize, this.pageNo, this.languageId}); + + Questions.fromJson(Map json) { + questionId = json['questionId']; + title = json['title']; + isRequired = json['isRequired']; + type = json['type']; + sequenceNo = json['sequenceNo']; + surveyId = json['surveyId']; + if (json['options'] != null) { + options = []; + json['options'].forEach((v) { + options!.add(new Options.fromJson(v)); + }); + } + rspPercentage = json['rspPercentage']; + isActive = json['isActive']; + pageSize = json['pageSize']; + pageNo = json['pageNo']; + languageId = json['languageId']; + } + + Map toJson() { + Map data = new Map(); + data['questionId'] = this.questionId; + data['title'] = this.title; + data['isRequired'] = this.isRequired; + data['type'] = this.type; + data['sequenceNo'] = this.sequenceNo; + data['surveyId'] = this.surveyId; + if (this.options != null) { + data['options'] = this.options!.map((v) => v.toJson()).toList(); + } + data['rspPercentage'] = this.rspPercentage; + data['isActive'] = this.isActive; + data['pageSize'] = this.pageSize; + data['pageNo'] = this.pageNo; + data['languageId'] = this.languageId; + return data; + } +} + +class Options { + int? optionId; + String? title; + bool? isCommentsRequired; + int? sequenceNo; + int? questionId; + Null? rspPercentage; + Null? count; + Null? isActive; + Null? pageSize; + Null? pageNo; + Null? languageId; + + Options({this.optionId, this.title, this.isCommentsRequired, this.sequenceNo, this.questionId, this.rspPercentage, this.count, this.isActive, this.pageSize, this.pageNo, this.languageId}); + + Options.fromJson(Map json) { + optionId = json['optionId']; + title = json['title']; + isCommentsRequired = json['isCommentsRequired']; + sequenceNo = json['sequenceNo']; + questionId = json['questionId']; + rspPercentage = json['rspPercentage']; + count = json['count']; + isActive = json['isActive']; + pageSize = json['pageSize']; + pageNo = json['pageNo']; + languageId = json['languageId']; + } + + Map toJson() { + Map data = new Map(); + data['optionId'] = this.optionId; + data['title'] = this.title; + data['isCommentsRequired'] = this.isCommentsRequired; + data['sequenceNo'] = this.sequenceNo; + data['questionId'] = this.questionId; + data['rspPercentage'] = this.rspPercentage; + data['count'] = this.count; + data['isActive'] = this.isActive; + data['pageSize'] = this.pageSize; + data['pageNo'] = this.pageNo; + data['languageId'] = this.languageId; + return data; + } +} diff --git a/lib/provider/dashboard_provider_model.dart b/lib/provider/dashboard_provider_model.dart index d0f33df..0e18544 100644 --- a/lib/provider/dashboard_provider_model.dart +++ b/lib/provider/dashboard_provider_model.dart @@ -66,7 +66,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { if (attendanceTracking?.pSwipeIn != null) { isTimeRemainingInSeconds = calculateSeconds(attendanceTracking!.pRemainingHours ?? "00:00:00"); int totalShiftTimeInSeconds = calculateSeconds(attendanceTracking!.pScheduledHours ?? "00:00:00"); - if(isTimeRemainingInSeconds == 0 || totalShiftTimeInSeconds == 0) { + if (isTimeRemainingInSeconds == 0 || totalShiftTimeInSeconds == 0) { progress = 0; } else { progress = (isTimeRemainingInSeconds / totalShiftTimeInSeconds); @@ -245,7 +245,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { } } - void getCategoryOffersListAPI(BuildContext context) async { + void getCategoryOffersListAPI(BuildContext context) async { try { // Utils.showLoading(context); getOffersList = await OffersAndDiscountsApiClient().getOffersList(0, 10); @@ -262,7 +262,25 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { List menus = []; for (int i = 0; i < getMenuEntriesList.length; i++) { if (getMenuEntriesList[i].parentMenuName!.isEmpty) { - menus.add(Menus(getMenuEntriesList[i], getMenuEntriesList.where((element) => getMenuEntriesList[i].menuName == element.parentMenuName).toList())); + GetMenuEntriesList abc = GetMenuEntriesList(requestType: "itg_forms", prompt: LocaleKeys.itgForms.tr()); + List list = getMenuEntriesList.where((element) => getMenuEntriesList[i].menuName == element.parentMenuName).toList(); + + if (getMenuEntriesList[i].menuName == "MBL_E_PROFESSIONALS_01") { + // hard coding this check to add change password for Active Directory + + GetMenuEntriesList activeDirectoryEntry = GetMenuEntriesList( + requestType: "RESET_ITG_AD_PASSWORD", + prompt: LocaleKeys.resetAdPassword.tr(), + parentMenuName: 'ITG_FORMS', + menuName: LocaleKeys.itgForms.tr(), + menuEntryType: "FUNCTION", //Reset AD Password + ); + getMenuEntriesList.add(activeDirectoryEntry); + + list.add(GetMenuEntriesList(requestType: "ITG_FORMS", prompt: LocaleKeys.itgForms.tr(), menuName: 'ITG_FORMS')); + } + + menus.add(Menus(getMenuEntriesList[i], list)); } } return menus; @@ -272,6 +290,7 @@ class DashboardProviderModel with ChangeNotifier, DiagnosticableTreeMixin { MohemmItgResponseItem? res = await DashboardApiClient().getITGPageNotification(); return res; } + void notify() { notifyListeners(); } diff --git a/lib/provider/hmg_connection_provider.dart b/lib/provider/hmg_connection_provider.dart new file mode 100644 index 0000000..b19c1cc --- /dev/null +++ b/lib/provider/hmg_connection_provider.dart @@ -0,0 +1,46 @@ +import 'dart:io'; + +import 'package:flutter/cupertino.dart'; +import 'package:mohem_flutter_app/app_state/app_state.dart'; +import 'package:wifi_iot/wifi_iot.dart'; + +class HmgConnectionProvider extends ChangeNotifier { + bool isConnectedToHMG = false; + + Future checkHmgNetworkConnectivity() async { + if (await WiFiForIoTPlugin.getSSID() == AppState().getMohemmWifiSSID) { + isConnectedToHMG = true; + } else { + isConnectedToHMG = false; + } + AppState().isConnectedToHMG = isConnectedToHMG; + return isConnectedToHMG; + } + + void connectWithHmgNetwork() async { + try { + bool isConnected = await WiFiForIoTPlugin.connect("MOHEMM-CONNECT", password: "0987654321", joinOnce: Platform.isIOS ? false : true, security: NetworkSecurity.WPA, withInternet: false); + + if (isConnected) { + await WiFiForIoTPlugin.forceWifiUsage(true); + await Future.delayed(const Duration(seconds: 2)); + isConnectedToHMG=true; + + } + } catch (e) { + isConnectedToHMG = false; + AppState().isConnectedToHMG = isConnectedToHMG; + print("----------------o----"); + print(e); + } + } + + Future closeWifiRequest() async { + if (Platform.isAndroid) { + await WiFiForIoTPlugin.forceWifiUsage(false); + } + isConnectedToHMG = false; + AppState().isConnectedToHMG = isConnectedToHMG; + return await WiFiForIoTPlugin.disconnect(); + } +} diff --git a/lib/ui/landing/dashboard_screen.dart b/lib/ui/landing/dashboard_screen.dart index 989dbf9..840d118 100644 --- a/lib/ui/landing/dashboard_screen.dart +++ b/lib/ui/landing/dashboard_screen.dart @@ -27,7 +27,6 @@ import 'package:mohem_flutter_app/ui/landing/widget/services_widget.dart'; import 'package:mohem_flutter_app/ui/marathon/marathon_provider.dart'; import 'package:mohem_flutter_app/ui/marathon/widgets/marathon_banner.dart'; import 'package:mohem_flutter_app/widgets/bottom_sheet.dart'; -import 'package:mohem_flutter_app/widgets/dialogs/dialogs.dart'; import 'package:mohem_flutter_app/widgets/mark_attendance_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/dashboard_shimmer_widget.dart'; import 'package:mohem_flutter_app/widgets/shimmer/offers_shimmer_widget.dart'; @@ -166,7 +165,20 @@ class _DashboardScreenState extends State with WidgetsBindingOb if (val!.result!.data != null) { print("-------------------- Survey ----------------------------"); if (val.result!.data!.notificationType == "Survey") { - Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data); + DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then( + (value) { + if (value!.mohemmItgResponseItem!.statusCode == 200) { + if (value.mohemmItgResponseItem!.result!.data != null) { + // Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data); + Navigator.pushNamed(context, AppRoutes.survey, arguments: value.mohemmItgResponseItem!.result!.data); + // Navigator.pushNamed(context, AppRoutes.advertisement, arguments: { + // "masterId": val.result!.data!.notificationMasterId, + // "advertisement": value.mohemmItgResponseItem!.result!.data!.advertisement, + // }); + } + } + }, + ); } else { print("------------------------------------------- Ads --------------------"); DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then( @@ -497,7 +509,7 @@ class _DashboardScreenState extends State with WidgetsBindingOb tag: "ItemImage" + data.getOffersList[index].offersDiscountId.toString()!, transitionOnUserGestures: true, child: Image.network( - data.getOffersList[index].logo!, + data.getOffersList[index].logo ?? "", fit: BoxFit.contain, ), ), diff --git a/lib/ui/landing/itg/change_itg_ad_password_screen.dart b/lib/ui/landing/itg/change_itg_ad_password_screen.dart new file mode 100644 index 0000000..cc84f96 --- /dev/null +++ b/lib/ui/landing/itg/change_itg_ad_password_screen.dart @@ -0,0 +1,166 @@ +import 'package:easy_localization/src/public_ext.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/api/login_api_client.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/utils.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/generic_response_model.dart'; +import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/input_widget.dart'; + +class ChangeItgAdPasswordScreen extends StatefulWidget { + ChangeItgAdPasswordScreen({Key? key}) : super(key: key); + + @override + _ChangeItgAdPasswordScreenState createState() { + return _ChangeItgAdPasswordScreenState(); + } +} + +class _ChangeItgAdPasswordScreenState extends State { + TextEditingController password = TextEditingController(); + TextEditingController confirmPassword = TextEditingController(); + + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + void setNewPassword() async { + Utils.showLoading(context); + try { + GenericResponseModel response = await LoginApiClient().changePasswordFromActiveDirectorySession(password.text, AppState().memberInformationList!.eMPLOYEEEMAILADDRESS!); + Utils.hideLoading(context); + if ((response.messageStatus ?? 0) == 1) { + Utils.showToast(LocaleKeys.passwordChangedSuccessfully.tr()); + Navigator.pop(context); + } + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, (msg) { + Utils.confirmDialog(context, msg); + }); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: Colors.transparent, + leading: IconButton( + icon: const Icon(Icons.arrow_back_ios, color: MyColors.darkIconColor), + onPressed: () => Navigator.pop(context), + ), + ), + body: Column( + children: [ + ListView( + padding: const EdgeInsets.all(21), + children: [ + LocaleKeys.changePassword.tr().toText24(isBold: true), + LocaleKeys.typeYourNewActiveDirectoryPasswordBelow.tr().toText16(), + 16.height, + InputWidget( + LocaleKeys.password.tr(), + "**********", + password, + onChange: (value) { + setState(() {}); + }, + ), + 12.height, + InputWidget( + LocaleKeys.confirmPassword.tr(), + "**********", + confirmPassword, + isTextIsPassword: true, + onChange: (value) { + setState(() {}); + }, + ), + 16.height, + passwordConstraintsUI(LocaleKeys.doNotUseRecentPassword.tr(), true), + 8.height, + passwordConstraintsUI(LocaleKeys.atLeastOneLowercase.tr(), checkRegEx(r'[a-z]')), + // 8.height, + // passwordConstraintsUI(LocaleKeys.atLeastOneUppercase.tr(), checkRegEx(r'[A-Z]')), + 8.height, + passwordConstraintsUI(LocaleKeys.atLeastOneNumeric.tr(), checkRegEx(r'[0-9]')), + 8.height, + passwordConstraintsUI(LocaleKeys.minimum8Characters.tr(), password.text.length >= 8), + 8.height, + passwordConstraintsUI(LocaleKeys.doNotAddRepeatingLetters.tr(), checkRepeatedChars(password.text)), + // 8.height, + // passwordConstraintsUI(LocaleKeys.itShouldContainSpecialCharacter.tr(), checkRegEx(r'[!@#$%^&*(),.?":{}|<>]')), + 8.height, + passwordConstraintsUI(LocaleKeys.confirmPasswordMustMatch.tr(), password.text.isNotEmpty && password.text == confirmPassword.text), + ], + ).expanded, + DefaultButton(LocaleKeys.changePassword.tr(), (!isPasswordCompliant(password.text, 8)) ? null : setNewPassword).insideContainer + ], + ), + ); + } + + bool checkRegEx(String pattern) { + return RegExp(pattern).hasMatch(password.text); + } + + String recentPassword = ""; + + bool isPasswordCompliant(String? password, int minLength) { + if (password == null || password.isEmpty) { + return false; + } + + // bool hasUppercase = password.contains(RegExp(r'[A-Z]')); + bool hasDigits = password.contains(RegExp(r'[0-9]')); + bool hasLowercase = password.contains(RegExp(r'[a-z]')); + // bool hasSpecialCharacters = password.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]')); + bool hasMinLength = password.length >= minLength; + bool isMatched = password == confirmPassword.text; + + return hasDigits && hasLowercase && hasMinLength && isMatched && checkRepeatedChars(password); + } + + bool checkRepeatedChars(String password) { + bool isNonRepeatedLetters = true; + if (password.length > 2) { + for (int i = 0; i < password.length; i++) { + String char = password[i]; + try { + if (char == password[i + 1]) { + isNonRepeatedLetters = false; + break; + } + } catch (ex) {} + } + } + return isNonRepeatedLetters; + } + + Widget passwordConstraintsUI(String description, bool check) { + return Row( + children: [ + 4.width, + SizedBox( + width: 12, + height: 12, + child: Checkbox(fillColor: MaterialStateProperty.all(MyColors.gradiantEndColor), shape: const CircleBorder(), value: check, onChanged: null), + ), + 8.width, + description.toText14() + ], + ); + } +} diff --git a/lib/ui/landing/itg/its_add_screen_video_image.dart b/lib/ui/landing/itg/its_add_screen_video_image.dart index eb08898..61b2766 100644 --- a/lib/ui/landing/itg/its_add_screen_video_image.dart +++ b/lib/ui/landing/itg/its_add_screen_video_image.dart @@ -93,10 +93,7 @@ class _ITGAdsScreenState extends State { @override void dispose() { - if (_controller != null) { - _controller.dispose(); - } - + if (_controller != null) _controller.dispose(); // player.stop(); // player.dispose(); super.dispose(); @@ -182,14 +179,7 @@ class _ITGAdsScreenState extends State { children: [ Image.file(imageFile), 50.height, - Container( - padding: const EdgeInsets.all(16), - decoration: Utils.containerRadius(MyColors.white, 10), - child: const Icon( - Icons.thumb_up, - color: MyColors.gradiantEndColor, - ), - ).onPress( + Container(padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor)).onPress( () { try { DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) { diff --git a/lib/ui/landing/itg/survey_screen.dart b/lib/ui/landing/itg/survey_screen.dart index ec79d0f..59f3c14 100644 --- a/lib/ui/landing/itg/survey_screen.dart +++ b/lib/ui/landing/itg/survey_screen.dart @@ -1,5 +1,3 @@ -import 'dart:convert'; - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart'; @@ -7,15 +5,14 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/api/dashboard_api_client.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; -import 'package:mohem_flutter_app/config/routes.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/itg/itg_main_response.dart'; import 'package:mohem_flutter_app/models/itg/itg_response_model.dart'; +import 'package:mohem_flutter_app/models/itg/survey_model.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; -import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart'; class SurveyScreen extends StatefulWidget { const SurveyScreen({Key? key}) : super(key: key); @@ -27,78 +24,50 @@ class SurveyScreen extends StatefulWidget { class _SurveyScreenState extends State { String reviewText = ""; double starRating = 1; - int _selectedIndex = 5; + int _selectedIndex = 0; ItgResponseData? itgResponseData; + List answeredQuestions = []; + + @override + void initState() { + WidgetsBinding.instance.addPostFrameCallback( + (_) => initAnswersList(), + ); + super.initState(); + } + @override Widget build(BuildContext context) { - if (itgResponseData == null) itgResponseData = ModalRoute.of(context)!.settings.arguments as ItgResponseData; + itgResponseData ??= ModalRoute.of(context)!.settings.arguments as ItgResponseData; return Scaffold( backgroundColor: MyColors.backgroundColor, body: Column( children: [ Expanded( child: ListView( - scrollDirection: Axis.vertical, children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - 124.height, - LocaleKeys.feedbackUserExperience.tr().toText19(), - 27.height, - LocaleKeys.rateUI.tr().toText16(), - 22.height, - Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - RatingBar.builder( - initialRating: 3, - minRating: starRating, - direction: Axis.horizontal, - allowHalfRating: false, - itemCount: 5, - itemPadding: EdgeInsets.symmetric(horizontal: 8), - itemBuilder: (context, _) => Icon( - Icons.star, - color: Colors.amber, - ), - onRatingUpdate: (rating) { - starRating = rating; - }, - ) - ], - ).paddingOnly(left: 22, right: 22, top: 12, bottom: 12).objectContainerView(disablePadding: true), - 39.height, - LocaleKeys.rateUI.tr().toText16(), - 10.height, - GridView( - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 5, crossAxisSpacing: 7, mainAxisSpacing: 7), - physics: const NeverScrollableScrollPhysics(), - padding: const EdgeInsets.only(top: 0), - shrinkWrap: true, - children: [ - optionUI("poor.svg", 1), - optionUI("bad.svg", 2), - optionUI("normal.svg", 3), - optionUI("good.svg", 4), - optionUI("xcellent.svg", 5), - ], - ), - 27.height, - DynamicTextFieldWidget( - LocaleKeys.description.tr(), - LocaleKeys.typeHere.tr(), - lines: 3, - onChange: (v) { - reviewText = v; - }, - ), - 150.height - ], - ).paddingOnly(left: 21, right: 21), + Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + children: [ + 32.height, + itgResponseData?.survey?.title?.toText24() ?? const Text(""), + 8.height, + itgResponseData?.survey?.description?.toText16() ?? const Text(""), + ListView.builder( + padding: EdgeInsets.zero, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: itgResponseData?.survey?.questions?.length, + itemBuilder: (cxt, index) { + return answeredQuestions.isNotEmpty ? getSurveyWidget(itgResponseData?.survey?.questions![index], index) : Container(); + }, + ), + ], + ).paddingOnly(left: 21, right: 21), + ), ], )), DefaultButton( @@ -111,7 +80,7 @@ class _SurveyScreenState extends State { )); } - Widget optionUI(String icon, int index) { + Widget optionUI(String icon, int? index, int answerIndex) { return (_selectedIndex == index ? SvgPicture.asset( 'assets/images/' + icon, @@ -126,33 +95,129 @@ class _SurveyScreenState extends State { disablePadding: true, )) .onPress(() { - _selectedIndex = index; + _selectedIndex = index!; + answeredQuestions[answerIndex] = _selectedIndex.toString(); setState(() {}); }); } + void initAnswersList() { + answeredQuestions.clear(); + itgResponseData?.survey?.questions?.forEach((element) { + if (element.type != "Stars") { + if(element.type == "Faces") { + _selectedIndex = element.options![0].optionId!; + } + answeredQuestions.add(element.options![0].optionId.toString()); + } else { + answeredQuestions.add("4"); + } + }); + setState(() {}); + } + + Widget getSurveyWidget(Questions? question, int parentIndex) { + if (question?.type == "Expressions") { + // Expressions = radio buttons + return Column( + children: [ + 24.height, + question?.title?.toText18() ?? const Text(""), + 16.height, + GridView.builder( + padding: EdgeInsets.zero, + itemCount: question?.options?.length, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (context, index) { + return radioOption(question?.options?[index].title ?? "", question?.options?[index].optionId.toString() ?? "", answeredQuestions[parentIndex], parentIndex); + }, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: (4.0), + ), + ).paddingOnly(left: 22, right: 22, top: 12, bottom: 12).objectContainerView(disablePadding: true), + ], + ); + } else if (question?.type == "Stars") { + // Stars = star rating + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + 24.height, + question?.title?.toText18() ?? Text(""), + 16.height, + RatingBar.builder( + initialRating: 3, + minRating: starRating, + direction: Axis.horizontal, + allowHalfRating: false, + itemCount: 5, + itemPadding: const EdgeInsets.symmetric(horizontal: 8), + itemBuilder: (context, _) => const Icon( + Icons.star, + color: Colors.amber, + ), + onRatingUpdate: (rating) { + starRating = rating; + answeredQuestions[parentIndex] = rating.toInt().toString(); + }, + ).paddingOnly(left: 22, right: 22, top: 12, bottom: 12).objectContainerView(disablePadding: true), + ], + ); + } else if (question?.type == "Faces") { + // Faces = face rating + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + 24.height, + question?.title?.toText18() ?? Text("asdasdasdasd"), + 16.height, + GridView( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 5, crossAxisSpacing: 7, mainAxisSpacing: 7), + physics: const NeverScrollableScrollPhysics(), + padding: const EdgeInsets.only(top: 0), + shrinkWrap: true, + children: [ + optionUI("poor.svg", question?.options?[0].optionId, parentIndex), + optionUI("bad.svg", question?.options?[1].optionId, parentIndex), + optionUI("normal.svg", question?.options?[2].optionId, parentIndex), + optionUI("good.svg", question?.options?[3].optionId, parentIndex), + optionUI("xcellent.svg", question?.options?[4].optionId, parentIndex), + ], + ), + ], + ); + } else { + return Container(); + } + return Container(); + } + void performAPI() async { Utils.showLoading(context); + List> itgAnswersList = []; + int index = 0; try { - ItgMainRes? res= await DashboardApiClient().submitItgForm( - comment: reviewText, - masterId: itgResponseData!.notificationMasterId ?? "", - itgList: [ - {"questionId": "1", "optionId": null, "starRating": starRating}, - {"questionId": "2", "optionId": "4", "starRating": _selectedIndex} - ], - serviceId: itgResponseData!.serviceId ?? 0); - Utils.hideLoading(context); + answeredQuestions.forEach((element) { + itgAnswersList.add({ + "questionId": itgResponseData?.survey?.questions![index].questionId, + "optionId": itgResponseData?.survey?.questions![index].type != "Stars" ? answeredQuestions[index] : null, + "starRating": itgResponseData?.survey?.questions![index].type == "Stars" ? answeredQuestions[index] : null + }); + index++; + }); + ItgMainRes? res = await DashboardApiClient() + .submitItgForm(comment: reviewText, masterId: itgResponseData!.notificationMasterId ?? "", itgList: itgAnswersList, serviceId: itgResponseData!.survey!.surveyId ?? 0); + Utils.hideLoading(context); - - if(res!.mohemmItgResponseItem!.statusCode==200){ + if (res!.mohemmItgResponseItem!.statusCode == 200) { Utils.showToast("Survey has been submitted successfully"); Navigator.pop(context); - }else{ + } else { Utils.showToast(res.mohemmItgResponseItem!.message.toString()); } - } catch (ex) { Utils.hideLoading(context); Utils.handleException(ex, context, (msg) { @@ -160,4 +225,41 @@ class _SurveyScreenState extends State { }); } } + + Widget radioOption(String title, String value, String groupValue, int answerIndex) { + return Row( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Container( + width: 24, + height: 24, + decoration: BoxDecoration( + color: Colors.transparent, + border: Border.all(color: MyColors.borderColor, width: 1), + borderRadius: const BorderRadius.all( + Radius.circular(100), + ), + ), + padding: const EdgeInsets.all(4), + child: Container( + width: double.infinity, + height: double.infinity, + decoration: BoxDecoration( + color: value == answeredQuestions[answerIndex] ? MyColors.greenColor : Colors.transparent, + borderRadius: const BorderRadius.all( + Radius.circular(100), + ), + ), + ), + ), + 6.width, + title.toText12(color: MyColors.grey57Color), + 12.width + ], + ).onPress(() { + answeredQuestions[answerIndex] = value; + setState(() {}); + }); + } } diff --git a/lib/ui/login/login_screen.dart b/lib/ui/login/login_screen.dart index 0586bcc..e88cd2d 100644 --- a/lib/ui/login/login_screen.dart +++ b/lib/ui/login/login_screen.dart @@ -5,10 +5,11 @@ import 'package:easy_localization/src/public_ext.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; -import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; + +// import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; @@ -27,6 +28,7 @@ import 'package:mohem_flutter_app/models/member_information_list_model.dart'; import 'package:mohem_flutter_app/models/member_login_list_model.dart'; import 'package:mohem_flutter_app/models/privilege_list_model.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; +import 'package:mohem_flutter_app/widgets/button/hmg_connectivity_button.dart'; import 'package:mohem_flutter_app/widgets/input_widget.dart'; // import 'package:safe_device/safe_device.dart'; @@ -99,42 +101,37 @@ class _LoginScreenState extends State { GetMobileLoginInfoListModel? loginInfo; Future checkFirebaseToken() async { - if (await Utils.getStringFromPrefs("isIncomingCall") == "true") { - Utils.hideLoading(context); - Navigator.pushNamed(context, AppRoutes.chatStartCall); - } else { - try { - Utils.showLoading(context); - if (Platform.isAndroid) { - try { - if (!(await Utils.isGoogleServicesAvailable())) { - //print("HUAWEI APPPP GALLERYYYY!!!!"); - AppState().setIsHuawei = true; - AppNotifications().initHuaweiPush(checkLoginInfo); - } else { - print("GOOGLE PLAY STOREEEE!!!!"); - await Firebase.initializeApp(); - _firebaseMessaging = FirebaseMessaging.instance; - firebaseToken = await _firebaseMessaging.getToken(); - AppNotifications().init(firebaseToken); - checkLoginInfo(); - await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); - } - // }); - } catch (ex) {} - } else { - await Firebase.initializeApp(); - _firebaseMessaging = FirebaseMessaging.instance; - firebaseToken = await _firebaseMessaging.getToken(); - AppNotifications().init(firebaseToken); - checkLoginInfo(); - await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); - } - } catch (ex) { - Utils.hideLoading(context); - Utils.handleException(ex, context, null); + try { + Utils.showLoading(context); + if (Platform.isAndroid) { + try { + if (!(await Utils.isGoogleServicesAvailable())) { + print("HUAWEI APPPP GALLERYYYY!!!!"); + AppState().setIsHuawei = true; + AppNotifications().initHuaweiPush(checkLoginInfo); + } else { + print("GOOGLE PLAY STOREEEE!!!!"); + await Firebase.initializeApp(); + _firebaseMessaging = FirebaseMessaging.instance; + firebaseToken = await _firebaseMessaging.getToken(); + AppNotifications().init(firebaseToken); + checkLoginInfo(); + await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); + } + // }); + } catch (ex) {} + } else { + await Firebase.initializeApp(); + _firebaseMessaging = FirebaseMessaging.instance; + firebaseToken = await _firebaseMessaging.getToken(); + AppNotifications().init(firebaseToken); + checkLoginInfo(); await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); } + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); } } diff --git a/lib/ui/my_attendance/services_menu_list_screen.dart b/lib/ui/my_attendance/services_menu_list_screen.dart index 8e44324..44aac6a 100644 --- a/lib/ui/my_attendance/services_menu_list_screen.dart +++ b/lib/ui/my_attendance/services_menu_list_screen.dart @@ -57,6 +57,9 @@ class ServicesMenuListScreen extends StatelessWidget { } else if (servicesMenuData.list[index].requestType == "ABSENCE") { Navigator.pushNamed(context, AppRoutes.leaveBalance, arguments: servicesMenuData.selectedEmp); return; + } else if (servicesMenuData.list[index].requestType == "RESET_ITG_AD_PASSWORD") { + Navigator.pushNamed(context, AppRoutes.changeItgAdPasswordScreen); + return; } if (servicesMenuData.list[index].requestType == "EIT") { Navigator.pushNamed(context, AppRoutes.dynamicScreen, diff --git a/lib/ui/screens/items_for_sale/item_for_sale_detail.dart b/lib/ui/screens/items_for_sale/item_for_sale_detail.dart index fffcde9..a853e1a 100644 --- a/lib/ui/screens/items_for_sale/item_for_sale_detail.dart +++ b/lib/ui/screens/items_for_sale/item_for_sale_detail.dart @@ -1,5 +1,3 @@ -import 'dart:convert'; - import 'package:carousel_slider/carousel_slider.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -107,22 +105,34 @@ class _ItemForSaleDetailPageState extends State { ).expanded, Row( children: [ - DefaultButton("Email", () async { - Uri emailLaunchUri = Uri( - scheme: 'mailto', - path: getItemsForSaleList.emailAddress, - ); - launchUrl(emailLaunchUri); - }, iconData: Icons.email_sharp, isTextExpanded: false) + DefaultButton( + "Email", + getItemsForSaleList.status == 'Approved' + ? () async { + Uri emailLaunchUri = Uri( + scheme: 'mailto', + path: getItemsForSaleList.emailAddress, + ); + launchUrl(emailLaunchUri); + } + : null, + iconData: Icons.email_sharp, + isTextExpanded: false) .expanded, 8.width, - DefaultButton("Call", () async { - Uri callLaunchUri = Uri( - scheme: 'tel', - path: getItemsForSaleList.mobileNumber, - ); - launchUrl(callLaunchUri); - }, iconData: Icons.call_sharp, isTextExpanded: false) + DefaultButton( + "Call", + getItemsForSaleList.status == 'Approved' + ? () async { + Uri callLaunchUri = Uri( + scheme: 'tel', + path: getItemsForSaleList.mobileNumber, + ); + launchUrl(callLaunchUri); + } + : null, + iconData: Icons.call_sharp, + isTextExpanded: false) .expanded, ], ).insideContainer, @@ -132,6 +142,7 @@ class _ItemForSaleDetailPageState extends State { } List getItemImages() { + int index = 0; List itemImages = []; getItemsForSaleList.itemAttachments!.forEach((element) { itemImages.add( @@ -140,12 +151,13 @@ class _ItemForSaleDetailPageState extends State { child: ClipRRect( borderRadius: BorderRadius.circular(6), child: Image.network( - getItemsForSaleList.itemAttachments![0].filePath!, + getItemsForSaleList.itemAttachments![index].filePath!, fit: BoxFit.cover, ), ), ), ); + index++; }); return itemImages; } diff --git a/lib/ui/work_list/item_history_screen.dart b/lib/ui/work_list/item_history_screen.dart index 5aa18b3..88abf06 100644 --- a/lib/ui/work_list/item_history_screen.dart +++ b/lib/ui/work_list/item_history_screen.dart @@ -1,16 +1,29 @@ +import 'dart:convert'; +import 'dart:io'; +import 'dart:typed_data'; + import 'package:easy_localization/src/public_ext.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:mohem_flutter_app/api/worklist/worklist_api_client.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/classes/date_uitl.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/models/get_attachement_list_model.dart'; import 'package:mohem_flutter_app/models/get_mo_Item_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_po_Item_history_list_model.dart'; +import 'package:mohem_flutter_app/models/get_pr_action_history_list_model.dart'; import 'package:mohem_flutter_app/models/get_pr_information_list.dart'; import 'package:mohem_flutter_app/models/get_quotation_analysis_list_model.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; +import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart'; +import 'package:open_file/open_file.dart'; +import 'package:path_provider/path_provider.dart'; class ItemHistoryScreenParams { String? title; @@ -21,8 +34,10 @@ class ItemHistoryScreenParams { int? pOrgId; bool isPRInfo; GetPRInformationList? getPRInformationList; + String pOLineID; - ItemHistoryScreenParams({@required this.title, this.isItemHistory = true, this.isMO = true, this.isPRInfo = false, this.getPRInformationList, this.pItemId, this.pPoHeaderId, this.pOrgId}); + ItemHistoryScreenParams( + {@required this.title, this.isItemHistory = true, this.isMO = true, this.isPRInfo = false, this.getPRInformationList, this.pItemId, this.pPoHeaderId, this.pOrgId, this.pOLineID = ""}); } class ItemHistoryScreen extends StatefulWidget { @@ -40,6 +55,9 @@ class _ItemHistoryScreenState extends State { List moItemHistoryList = []; List poItemHistoryList = []; List quotationAnalysisList = []; + List actionHistoryList = []; + List getAttachmentList = []; + int tabIndex = 0; @override void initState() { @@ -49,6 +67,7 @@ class _ItemHistoryScreenState extends State { @override void dispose() { super.dispose(); + actionHistoryList.clear(); } void loadData() { @@ -60,6 +79,34 @@ class _ItemHistoryScreenState extends State { } } + void getActionsDataFromApi() async { + if (actionHistoryList.isEmpty) { + try { + Utils.showLoading(context); + actionHistoryList = await WorkListApiClient().getActionHistoryForPR(_screenParams!.pOLineID); + Utils.hideLoading(context); + setState(() {}); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } + } + } + + void getAttachmentsDataFromApi() async { + if (getAttachmentList.isEmpty) { + try { + Utils.showLoading(context); + getAttachmentList = await WorkListApiClient().getPRAttachments(_screenParams!.pOLineID!); + Utils.hideLoading(context); + setState(() {}); + } catch (ex) { + Utils.hideLoading(context); + Utils.handleException(ex, context, null); + } + } + } + void getDataFromApi() async { try { Utils.showLoading(context); @@ -88,7 +135,7 @@ class _ItemHistoryScreenState extends State { appBar: AppBarWidget(context, title: _screenParams?.title ?? ""), backgroundColor: Colors.white, body: ListView( - padding: const EdgeInsets.all(21), + padding: _screenParams!.isPRInfo ? const EdgeInsets.all(0) : const EdgeInsets.all(21), physics: const BouncingScrollPhysics(), children: [ if (_screenParams!.isPRInfo) prLinesDataView(), @@ -102,32 +149,243 @@ class _ItemHistoryScreenState extends State { } Widget prLinesDataView() { + return Column( + children: [ + Container( + padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16), + decoration: const BoxDecoration( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(25), + bottomRight: Radius.circular(25), + ), + gradient: LinearGradient( + transform: GradientRotation(.83), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ], + ), + ), + child: Row( + children: [ + myTab(LocaleKeys.info.tr(), 0), + myTab(LocaleKeys.actions.tr(), 1), + myTab(LocaleKeys.attachments.tr(), 2), + ], + ), + ), + if (tabIndex == 0) _screenParams!.getPRInformationList!.pRHeader![0].dESCRIPTION!.toText14().paddingOnly(top: 20, right: 21, left: 21), + if (tabIndex == 0) + ListView.separated( + padding: const EdgeInsets.all(21), + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, index) => Column( + children: [ + ItemDetailGrid( + ItemDetailViewCol("Cost Center", _screenParams!.getPRInformationList!.pRLines![index].cOSTCENTER ?? ""), + ItemDetailViewCol("Code", _screenParams!.getPRInformationList!.pRLines![index].iTEMCODE ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol("Unit", _screenParams!.getPRInformationList!.pRLines![index].uOM ?? ""), + ItemDetailViewCol("Price (SAR)", _screenParams!.getPRInformationList!.pRLines![index].uNITPRICE.toString() ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol("Amount (SAR)", _screenParams!.getPRInformationList!.pRLines![index].lINEAMOUNT.toString() ?? ""), + ItemDetailViewCol("Quantity", _screenParams!.getPRInformationList!.pRLines![index].qUANTITY.toString() ?? ""), + ), + ItemDetailGrid( + ItemDetailViewCol("AMU (Last 3 months)", _screenParams!.getPRInformationList!.pRLines![index].iTEMAMU.toString() ?? ""), + ItemDetailViewCol("PR Number", _screenParams!.getPRInformationList!.pRHeader![0].pRNUMBER!.toString() ?? ""), + isItLast: true, + ), + ], + ).objectContainerView(), + separatorBuilder: (cxt, index) => 12.height, + itemCount: _screenParams!.getPRInformationList!.pRLines!.length), + if (tabIndex == 1) getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21), + if (tabIndex == 2) getPRAttachments(), + ], + ); + } + + String determineFileIcon(String fileContentType) { + String icon = ""; + switch (fileContentType) { + case "pdf": + icon = "assets/images/pdf.svg"; + break; + case "xls": + icon = "assets/images/xls.svg"; + break; + case "xlsx": + icon = "assets/images/xls.svg"; + break; + case "png": + icon = "assets/images/png.svg"; + break; + case "jpg": + icon = "assets/images/jpg.svg"; + break; + case "jpeg": + icon = "assets/images/jpg.svg"; + break; + } + return icon; + } + + Future _createFileFromString(String encodedStr, String ext) async { + Uint8List bytes = base64.decode(encodedStr); + String dir = (await getApplicationDocumentsDirectory()).path; + File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext); + await file.writeAsBytes(bytes); + return file.path; + } + + Widget getPRAttachments() { return ListView.separated( + itemCount: getAttachmentList.length, + shrinkWrap: true, + itemBuilder: (context, index) { + return Row( + children: [ + SvgPicture.asset(determineFileIcon(getAttachmentList[index].fILECONTENTTYPE ?? "")), + 12.width, + (getAttachmentList[index].fILENAME ?? "").toText16().expanded, + ], + ).objectContainerView().onPress(() async { + try { + String path = await _createFileFromString(getAttachmentList[index].fILEDATA ?? "", getAttachmentList[index].fILECONTENTTYPE ?? ""); + OpenFile.open(path); + } catch (ex) { + Utils.showToast("Cannot open file."); + } + }); + }, + separatorBuilder: (BuildContext context, int index) => 12.height, + ).paddingAll(21); + } + + Widget getPRActionsHistory() { + return SingleChildScrollView( + child: ListView.separated( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), - itemBuilder: (cxt, index) => Column( - children: [ - ItemDetailGrid( - ItemDetailViewCol("Cost Center", _screenParams!.getPRInformationList!.pRLines![index].cOSTCENTER ?? ""), - ItemDetailViewCol("Code", _screenParams!.getPRInformationList!.pRLines![index].iTEMCODE ?? ""), - ), - ItemDetailGrid( - ItemDetailViewCol("Unit", _screenParams!.getPRInformationList!.pRLines![index].uOM ?? ""), - ItemDetailViewCol("Price (SAR)", _screenParams!.getPRInformationList!.pRLines![index].uNITPRICE.toString() ?? ""), - ), - ItemDetailGrid( - ItemDetailViewCol("Amount (SAR)", _screenParams!.getPRInformationList!.pRLines![index].lINEAMOUNT.toString() ?? ""), - ItemDetailViewCol("Quantity", _screenParams!.getPRInformationList!.pRLines![index].qUANTITY.toString() ?? ""), - ), - ItemDetailGrid( - ItemDetailViewCol("AMU (Last 3 months)", _screenParams!.getPRInformationList!.pRLines![index].iTEMAMU.toString() ?? ""), - Container(), - isItLast: true, - ), - ], - ).objectContainerView(), - separatorBuilder: (cxt, index) => 12.height, - itemCount: _screenParams!.getPRInformationList!.pRLines!.length); + itemCount: actionHistoryList.length, + padding: EdgeInsets.all(21), + itemBuilder: (context, index) { + return showItem(context, actionHistoryList[index], index); + }, + separatorBuilder: (BuildContext context, int index) { + return 12.height; + }, + ), + ); + } + + Widget showItem(BuildContext context, GetPRActionHistoryList actionHistory, int index) { + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: [ + BoxShadow( + color: const Color(0xff000000).withOpacity(.05), + blurRadius: 26, + offset: const Offset(0, -3), + ), + ], + ), + clipBehavior: Clip.antiAlias, + child: Stack( + clipBehavior: Clip.antiAlias, + children: [ + Positioned( + left: -20, + top: -10, + child: Transform.rotate( + angle: 15, + child: Container( + width: 50, + height: 30, + color: getStatusColor(actionHistory.aCTIONCODE!), + ), + ), + ), + Column( + children: [ + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + actionHistory.eMPLOYEEIMAGE != null + ? CircularAvatar(url: actionHistory.eMPLOYEEIMAGE ?? "", isImageBase64: true, height: 34, width: 34) + : CircularAvatar(url: "https://cdn4.iconfinder.com/data/icons/professions-2-2/151/89-512.png", isImageBase64: false, height: 34, width: 34), + 9.width, + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + actionHistory.nAME!.toText16(), + if ((actionHistory.nOTE ?? "").isNotEmpty) + SelectableText( + actionHistory.nOTE!, + style: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: MyColors.grey57Color, + letterSpacing: -0.72, + ), + ), + + // "Note: ${actionHistory.nOTE!}".toText12(color: MyColors.grey57Color), + 4.height, + Row( + children: [ + actionHistory.aCTION!.toText10(color: getStatusColor(actionHistory.aCTIONCODE!)), + 8.width, + if (actionHistory.aPPROVALDATE!.isNotEmpty) + DateUtil.formatDateToDate(DateUtil.convertSimpleStringDateToDateddMMyyyy(actionHistory.aPPROVALDATE!), false).toText12(color: MyColors.lightTextColor), + ], + ), + 10.height, + // getActionDuration(index).toText11(maxLine: 1, color: const Color(0xff1FA269)) + ], + ), + ) + ], + ).paddingOnly(top: 19, left: 16, right: 16, bottom: 12), + ], + ), + ], + ), + ); + } + + Color getStatusColor(String code) { + if (code == "SUBMIT") { + return const Color(0xff2E303A); + } else if (code == "REJECTED") { + return MyColors.redColor; + } else if (code == "REJECT") { + return MyColors.redColor; + } else if (code == "PENDING") { + return MyColors.orange; + } else if (code == "APPROVED" || code == "APPROVE" || code == "ANSWER_INFO") { + return const Color(0xff1FA269); + } else if (code == "REQUEST_INFO" || code == "FORWARD") { + return const Color(0xff2E303A); + } else if (code != "SUBMIT" && code != "REJECT" && code != "PENDING") { + return MyColors.orange; + } else { + return const Color(0xff2E303A); + } + } + + Widget getActionHistory() { + return Container(); } Widget loadMoItemHistoryData() { @@ -266,4 +524,34 @@ class _ItemHistoryScreenState extends State { separatorBuilder: (cxt, index) => 12.height, itemCount: quotationAnalysisList.length); } + + Widget myTab(String title, int index) { + bool isSelected = (index == tabIndex); + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + title.toText12(color: isSelected ? Colors.white : Colors.white.withOpacity(.74), isCenter: true), + 4.height, + Container( + height: 8, + width: 8, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: isSelected ? Colors.white : Colors.transparent, + ), + ) + ], + ).onPress(() { + setState(() { + if (index == 1) { + getActionsDataFromApi(); + } + if (index == 2) { + getAttachmentsDataFromApi(); + } + tabIndex = index; + }); + }).expanded; + } } diff --git a/lib/ui/work_list/sheets/delegate_sheet.dart b/lib/ui/work_list/sheets/delegate_sheet.dart index 2a5f453..d505099 100644 --- a/lib/ui/work_list/sheets/delegate_sheet.dart +++ b/lib/ui/work_list/sheets/delegate_sheet.dart @@ -13,6 +13,7 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/generic_response_model.dart'; import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; import 'package:mohem_flutter_app/models/itg_forms_models/wf_history_model.dart'; +import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart'; import 'package:mohem_flutter_app/models/worklist/replacement_list_model.dart'; import 'package:mohem_flutter_app/ui/work_list/sheets/search_options_sheet.dart'; @@ -29,8 +30,10 @@ class DelegateSheet extends StatefulWidget { List? actionHistoryList; List? wFHistory; VoidCallback callBackFunc; + List getNotificationRespondAttributes; - DelegateSheet({required this.title, required this.apiMode, this.notificationID, this.actionHistoryList, this.wFHistory, required this.callBackFunc}); + DelegateSheet( + {required this.title, required this.apiMode, this.notificationID, this.actionHistoryList, this.wFHistory, required this.callBackFunc, this.getNotificationRespondAttributes = const []}); @override State createState() => _DelegateSheetState(); @@ -415,6 +418,7 @@ class _DelegateSheetState extends State { actionHistoryList: actionHistory, notificationID: widget.notificationID, isITGRequest: widget.wFHistory != null, + getNotificationRespondAttributes: widget.getNotificationRespondAttributes, )); }, child: Row( @@ -489,6 +493,7 @@ class _DelegateSheetState extends State { favoriteReplacements: actionHistory, notificationID: widget.notificationID, isITGRequest: widget.wFHistory != null, + getNotificationRespondAttributes: widget.getNotificationRespondAttributes, )); }, child: Row( @@ -555,6 +560,7 @@ class _DelegateSheetState extends State { replacementList: actionHistory, notificationID: widget.notificationID, isITGRequest: widget.wFHistory != null, + getNotificationRespondAttributes: widget.getNotificationRespondAttributes, )); }, child: Row( diff --git a/lib/ui/work_list/sheets/selected_item_sheet.dart b/lib/ui/work_list/sheets/selected_item_sheet.dart index 54f87d0..85395a6 100644 --- a/lib/ui/work_list/sheets/selected_item_sheet.dart +++ b/lib/ui/work_list/sheets/selected_item_sheet.dart @@ -6,14 +6,15 @@ import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; -import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/get_action_history_list_model.dart'; import 'package:mohem_flutter_app/models/member_information_list_model.dart'; +import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart'; import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart'; import 'package:mohem_flutter_app/models/worklist/replacement_list_model.dart'; import 'package:mohem_flutter_app/widgets/button/default_button.dart'; import 'package:mohem_flutter_app/widgets/circular_avatar.dart'; +import 'package:mohem_flutter_app/widgets/dialogs/accept_reject_input_dialog.dart'; import 'package:mohem_flutter_app/widgets/input_widget.dart'; class SelectedItemSheet extends StatelessWidget { @@ -23,10 +24,18 @@ class SelectedItemSheet extends StatelessWidget { GetFavoriteReplacements? favoriteReplacements; ReplacementList? replacementList; MemberInformationListModel? memberInformationListModel; + List getNotificationRespondAttributes; bool isITGRequest; - SelectedItemSheet(this.title, {required this.apiMode, this.notificationID, this.actionHistoryList, this.favoriteReplacements, this.replacementList, this.isITGRequest = false}); + SelectedItemSheet(this.title, + {required this.apiMode, + this.notificationID, + this.actionHistoryList, + this.favoriteReplacements, + this.replacementList, + this.isITGRequest = false, + this.getNotificationRespondAttributes = const []}); TextEditingController username = TextEditingController(); String comment = ""; @@ -103,7 +112,7 @@ class SelectedItemSheet extends StatelessWidget { email = replacementList!.emailAddress; userId = replacementList!.userName; } - isITGRequest ? performITGNetworkCall(context, email: email ?? "", userId: userId ?? "") : performNetworkCall(context, email: email ?? "", userId: userId ?? ""); + isITGRequest ? performITGNetworkCall(context, email: email ?? "", userId: userId ?? "") : askForConfirmation(context, email: email ?? "", userId: userId ?? ""); } else { Utils.showToast("Please enter comments"); } @@ -121,6 +130,45 @@ class SelectedItemSheet extends StatelessWidget { ); } + void askForConfirmation(BuildContext context, {String? email, String? userId}) { + NotificationGetRespondAttributesList? notificationNoteInput; + NotificationGetRespondAttributesList? forwardToUser; + List filtered = getNotificationRespondAttributes.where((element) => element.attributeName == "NOTE" || element.attributeName == "WF_NOTE").toList(); + if (filtered.isNotEmpty) { + notificationNoteInput = filtered.first; + } + + filtered = getNotificationRespondAttributes.where((element) => element.attributeName == "FORWARD_TO_USERNAME_RESPONSE").toList(); + if (filtered.isNotEmpty) { + forwardToUser = filtered.first; + } + + if (notificationNoteInput == null) { + performNetworkCall(context, email: email ?? "", userId: userId ?? "", attributeData: []); + } else { + showDialog( + context: context, + builder: (cxt) => AcceptRejectInputDialog( + message: title != null ? null : LocaleKeys.requestedItems.tr(), + // title: title, + notificationGetRespond: notificationNoteInput, + actionMode: apiMode, + onTap: (note) { + performNetworkCall(context, email: email ?? "", userId: userId ?? "", attributeData: [ + if ((apiMode == "FORWARD" || apiMode == "APPROVE_AND_FORWARD") && forwardToUser != null) + {"ATTRIBUTE_NAME": "FORWARD_TO_USERNAME_RESPONSE", "ATTRIBUTE_TEXT_VALUE": actionHistoryList?.uSERNAME}, + if (notificationNoteInput != null) + { + "ATTRIBUTE_NAME": notificationNoteInput.attributeName, + if (notificationNoteInput.attributeType == "number") "ATTRIBUTE_NUMBER_VALUE": note else if (notificationNoteInput.attributeType == "VARCHAR2") "ATTRIBUTE_TEXT_VALUE": note + } + ]); + }, + ), + ); + } + } + void getUserInformation(BuildContext context) async { String? empID = ""; if (actionHistoryList != null) empID = actionHistoryList!.uSERNAME; @@ -137,10 +185,17 @@ class SelectedItemSheet extends StatelessWidget { } } - Future performNetworkCall(BuildContext context, {String? email, String? userId}) async { + Future performNetworkCall(BuildContext context, {String? email, String? userId, List>? attributeData = const []}) async { Utils.showLoading(context); try { - await WorkListApiClient().submitComment(comment: comment, email: email, userId: userId, notificationId: notificationID, apiMode: apiMode, approverIndex: actionHistoryList != null ? actionHistoryList!.sEQUENCE : null); + await WorkListApiClient().submitComment( + comment: comment, + email: email, + userId: userId, + notificationId: notificationID, + apiMode: apiMode, + approverIndex: actionHistoryList != null ? actionHistoryList!.sEQUENCE : null, + attributeData: attributeData); Utils.hideLoading(context); // Navigator.pop(context); // Navigator.pop(context); diff --git a/lib/ui/work_list/work_list_screen.dart b/lib/ui/work_list/work_list_screen.dart index 485921d..9dea0a1 100644 --- a/lib/ui/work_list/work_list_screen.dart +++ b/lib/ui/work_list/work_list_screen.dart @@ -93,10 +93,12 @@ class _WorkListScreenState extends State { final ScrollController _controller = ScrollController(); int pNotificationType = 1; + ScrollController? _scrollController; @override void initState() { super.initState(); + _scrollController = ScrollController()..addListener(_scrollListener); providerData = Provider.of(context, listen: false); calculateCounter(); if (workListItemIndex != null) getWorkList(); @@ -154,7 +156,7 @@ class _WorkListScreenState extends State { ItgFormsModel? itgFormsModel; int? itgRequestTypeIndex; - Future getWorkList({bool showLoading = true}) async { + Future getWorkList({bool showLoading = true, bool isCallingFromRefresh = false}) async { try { if (showLoading) Utils.showLoading(context); if (workListItemTypes[workListItemIndex!].key == "ITG") { @@ -173,7 +175,12 @@ class _WorkListScreenState extends State { } } else { itgRequestTypeIndex = null; - workList = await WorkListApiClient().getWorkList(pageNumber, workListItemTypes[workListItemIndex!].key, pNotificationType.toString()); + List? _list = await WorkListApiClient().getWorkList(pageNumber, workListItemTypes[workListItemIndex!].key, pNotificationType.toString()); + if (workList != null && _list != null && !isCallingFromRefresh) { + workList!.addAll(_list); + } else { + workList = _list; + } AppState().setWorkList = workList; } if (showLoading) Utils.hideLoading(context); @@ -188,9 +195,10 @@ class _WorkListScreenState extends State { try { _refreshController.refreshCompleted(); Utils.showLoading(context); + pageNumber = 1; List dataOnRefresh = await Future.wait([ providerData.fetchWorkListCounter(context, showLoading: false), - getWorkList(showLoading: false), + getWorkList(showLoading: false, isCallingFromRefresh: true), ]); calculateCounter(); Utils.hideLoading(context); @@ -203,9 +211,19 @@ class _WorkListScreenState extends State { @override void dispose() { + _scrollController?.dispose(); super.dispose(); } + void _scrollListener() { + if (_scrollController!.position.pixels == _scrollController!.position.maxScrollExtent) { + pageNumber = pageNumber + 1; + if (itgRequestTypeIndex == null && workListItemTypes[workListItemIndex!].value != workList!.length) { + getWorkList(); + } + } + } + @override Widget build(BuildContext context) { return Scaffold( @@ -236,6 +254,7 @@ class _WorkListScreenState extends State { } if (workListItemIndex != index && !workListItemTypes[index].disable) { workListItemIndex = index; + pageNumber = 1; if (workListItemTypes[index].value == 0) { workList = []; itgRequestTypeIndex = null; @@ -273,6 +292,7 @@ class _WorkListScreenState extends State { ), controller: _refreshController, onRefresh: _onRefresh, + scrollController: _scrollController, child: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: itgRequestTypeIndex != null @@ -354,7 +374,6 @@ class _WorkListScreenState extends State { setState(() {}); } } - } else { verifyWorkListCounter(); if (mounted) setState(() {}); diff --git a/lib/ui/work_list/worklist_detail_screen.dart b/lib/ui/work_list/worklist_detail_screen.dart index 7a489c3..0a4f8cc 100644 --- a/lib/ui/work_list/worklist_detail_screen.dart +++ b/lib/ui/work_list/worklist_detail_screen.dart @@ -148,9 +148,6 @@ class _WorkListDetailScreenState extends State { } else if (workListData!.rEQUESTTYPE == "ADDRESS") { getAddressNotificationBody(); } - // getBasicNTFBody = await WorkListApiClient().getBasicDetNTFBody(workListData!.nOTIFICATIONID!, -999); - // getAbsenceCollectionNotifications = await WorkListApiClient().getAbsenceNotificationBody(workListData!.nOTIFICATIONID!, -999); - // subordinatesLeavesModel = await WorkListApiClient().getSubordinatesLeaves("", ""); } if (workListData!.iTEMTYPE == "STAMP") { getStampNotificationBody(); @@ -449,7 +446,6 @@ class _WorkListDetailScreenState extends State { } void handleFabAction(GetNotificationButtonsList notificationButton) { - print("notificationButton:${notificationButton.bUTTONACTION}"); switch (notificationButton.bUTTONACTION) { case "DELEGATE": showMyBottomSheet(context, @@ -526,6 +522,7 @@ class _WorkListDetailScreenState extends State { notificationID: workListData!.nOTIFICATIONID, actionHistoryList: actionHistoryList, callBackFunc: reloadWorkList, + getNotificationRespondAttributes: getNotificationRespondAttributes, )); break; case "FORWARD": @@ -537,8 +534,12 @@ class _WorkListDetailScreenState extends State { notificationID: workListData!.nOTIFICATIONID, actionHistoryList: actionHistoryList, callBackFunc: reloadWorkList, + getNotificationRespondAttributes: getNotificationRespondAttributes, )); break; + case "DEL": + performAction(notificationButton.bUTTONACTION!); + break; case "REJECT": performAction(notificationButton.bUTTONACTION!); break; @@ -565,6 +566,7 @@ class _WorkListDetailScreenState extends State { actionHistoryList: actionHistoryList.last, notificationID: workListData!.nOTIFICATIONID, isITGRequest: false, + getNotificationRespondAttributes: getNotificationRespondAttributes, )); setState(() {}); } catch (ex) { @@ -656,7 +658,6 @@ class _WorkListDetailScreenState extends State { } void performAction(String actionMode, {String? title}) { - print(actionMode); showDialog( context: context, builder: (cxt) => AcceptRejectInputDialog( diff --git a/lib/ui/work_list/worklist_fragments/actions_fragment.dart b/lib/ui/work_list/worklist_fragments/actions_fragment.dart index 98b5b72..1d88129 100644 --- a/lib/ui/work_list/worklist_fragments/actions_fragment.dart +++ b/lib/ui/work_list/worklist_fragments/actions_fragment.dart @@ -82,7 +82,20 @@ class ActionsFragment extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ actionHistory.nAME!.toText16(), - if ((actionHistory.nOTE ?? "").isNotEmpty) "Note: ${actionHistory.nOTE!}".toText12(color: MyColors.grey57Color), + + if ((actionHistory.nOTE ?? "").isNotEmpty) + SelectableText( + actionHistory.nOTE!, + style: const TextStyle( + fontSize: 12, + fontWeight: FontWeight.w600, + color: MyColors.grey57Color, + letterSpacing: -0.72, + ), + ), + + // if ((actionHistory.nOTE ?? "").isNotEmpty) "Note: ${actionHistory.nOTE!}".toText12(color: MyColors.grey57Color), + 4.height, Row( children: [ diff --git a/lib/ui/work_list/worklist_fragments/attachments_fragment.dart b/lib/ui/work_list/worklist_fragments/attachments_fragment.dart index b351683..bc1bde6 100644 --- a/lib/ui/work_list/worklist_fragments/attachments_fragment.dart +++ b/lib/ui/work_list/worklist_fragments/attachments_fragment.dart @@ -22,7 +22,6 @@ class AttachmentsFragment extends StatelessWidget { return ListView.separated( itemCount: getAttachmentList.length, itemBuilder: (context, index) { - return Row( children: [ SvgPicture.asset(determineFileIcon(getAttachmentList[index].fILECONTENTTYPE ?? "")), diff --git a/lib/ui/work_list/worklist_fragments/request_fragment.dart b/lib/ui/work_list/worklist_fragments/request_fragment.dart index 5a77597..b2bc0b6 100644 --- a/lib/ui/work_list/worklist_fragments/request_fragment.dart +++ b/lib/ui/work_list/worklist_fragments/request_fragment.dart @@ -294,7 +294,7 @@ class RequestFragment extends StatelessWidget { context, AppRoutes.itemHistory, arguments: ItemHistoryScreenParams( - isItemHistory: false, isMO: false, isPRInfo: true, getPRInformationList: getPRInformationList, title: "PR Details", pItemId: 0, pPoHeaderId: 0), + isItemHistory: false, isMO: false, isPRInfo: true, getPRInformationList: getPRInformationList, title: "PR Details", pItemId: 0, pPoHeaderId: 0, pOLineID: poLineID), ); } catch (ex) { Utils.hideLoading(context); diff --git a/lib/widgets/button/hmg_connectivity_button.dart b/lib/widgets/button/hmg_connectivity_button.dart new file mode 100644 index 0000000..bc2b9df --- /dev/null +++ b/lib/widgets/button/hmg_connectivity_button.dart @@ -0,0 +1,50 @@ +import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/material.dart'; +import 'package:mohem_flutter_app/classes/colors.dart'; +import 'package:mohem_flutter_app/extensions/int_extensions.dart'; +import 'package:mohem_flutter_app/extensions/string_extensions.dart'; +import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; +import 'package:mohem_flutter_app/provider/hmg_connection_provider.dart'; +import 'package:provider/provider.dart'; + +class HmgConnectivityButton extends StatelessWidget { + @override + Widget build(BuildContext context) { + Provider.of(context, listen: false).checkHmgNetworkConnectivity(); + return Consumer( + builder: (_, HmgConnectionProvider foo, __) { + return Container( + height: 45, + padding: const EdgeInsets.only(left: 12, right: 12), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(200.0), + gradient: const LinearGradient( + transform: GradientRotation(.83), + begin: Alignment.topRight, + end: Alignment.bottomLeft, + colors: [ + MyColors.gradiantEndColor, + MyColors.gradiantStartColor, + ], + ), + ), + child: InkWell( + onTap: (){ + + }, + child: Row( + children: [ + const Icon( + Icons.wifi, + color: Colors.white, + ), + 12.width, + LocaleKeys.connectHmgWifi.tr().toText18(color: Colors.white), + ], + ), + ), + ); + }, + ); + } +} diff --git a/lib/widgets/dynamic_forms/dynamic_textfield_widget.dart b/lib/widgets/dynamic_forms/dynamic_textfield_widget.dart index cc710fe..0630e44 100644 --- a/lib/widgets/dynamic_forms/dynamic_textfield_widget.dart +++ b/lib/widgets/dynamic_forms/dynamic_textfield_widget.dart @@ -55,15 +55,16 @@ class DynamicTextFieldWidget extends StatelessWidget { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - labelText, - style: const TextStyle( - fontSize: 11, - fontWeight: FontWeight.w600, - color: Color(0xff2B353E), - letterSpacing: -0.44, + if (labelText.isNotEmpty) + Text( + labelText, + style: const TextStyle( + fontSize: 11, + fontWeight: FontWeight.w600, + color: Color(0xff2B353E), + letterSpacing: -0.44, + ), ), - ), TextField( enabled: isEnable, scrollPadding: EdgeInsets.zero, diff --git a/lib/widgets/location/Location.dart b/lib/widgets/location/Location.dart index 9329cb4..62bd016 100644 --- a/lib/widgets/location/Location.dart +++ b/lib/widgets/location/Location.dart @@ -44,15 +44,18 @@ class Location { AppPermissions.location((granted) { if (granted) { - Geolocator.getLastKnownPosition(forceAndroidLocationManager: true).then((value) { - if (value == null) { - Geolocator.getCurrentPosition().then((value) { - done(value); - }); - } else { - done(value); - } + Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.medium, timeLimit: const Duration(seconds: 5)).then((value) { + done(value); }); + // Geolocator.getLastKnownPosition(forceAndroidLocationManager: true).then((value) { + // if (value == null) { + // Geolocator.getCurrentPosition().then((value) { + // done(value); + // }); + // } else { + // done(value); + // } + // }); } else { // AppPermissions } diff --git a/lib/widgets/mark_attendance_widget.dart b/lib/widgets/mark_attendance_widget.dart index 2ffa961..f11fafe 100644 --- a/lib/widgets/mark_attendance_widget.dart +++ b/lib/widgets/mark_attendance_widget.dart @@ -26,6 +26,7 @@ import 'package:mohem_flutter_app/widgets/nfc/nfc_reader_sheet.dart'; import 'package:mohem_flutter_app/widgets/qr_scanner_dialog.dart'; import 'package:nfc_manager/nfc_manager.dart'; import 'package:permission_handler/permission_handler.dart'; +import 'package:platform_device_id/platform_device_id.dart'; import 'package:wifi_iot/wifi_iot.dart'; class MarkAttendanceWidget extends StatefulWidget { @@ -53,6 +54,8 @@ class _MarkAttendanceWidgetState extends State { } void checkAttendanceAvailability() async { + String? deviceID = await PlatformDeviceId.getDeviceId; + print("Platform Device ID: $deviceID"); bool isAvailable = await NfcManager.instance.isAvailable(); setState(() { AppState().privilegeListModel!.forEach((PrivilegeListModel element) { @@ -131,7 +134,7 @@ class _MarkAttendanceWidgetState extends State { children: [ // if (isNfcEnabled) attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () { - if (isNfcLocationEnabled) { + // if (isNfcLocationEnabled) { if (AppState().getIsHuawei) { checkHuaweiLocationPermission("NFC"); } else { @@ -143,13 +146,13 @@ class _MarkAttendanceWidgetState extends State { } }, context); } - } else { - performNfcAttendance(widget.model); - } + // } else { + // performNfcAttendance(widget.model); + // } }), if (isWifiEnabled) attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () { - if (isWifiLocationEnabled) { + // if (isWifiLocationEnabled) { if (AppState().getIsHuawei) { checkHuaweiLocationPermission("WIFI"); } else { @@ -161,13 +164,13 @@ class _MarkAttendanceWidgetState extends State { } }, context); } - } else { - performWifiAttendance(widget.model); - } + // } else { + // performWifiAttendance(widget.model); + // } }), if (isQrEnabled) attendanceMethod("QR", "assets/images/ic_qr.svg", isQrEnabled, () async { - if (isQrLocationEnabled) { + // if (isQrLocationEnabled) { if (AppState().getIsHuawei) { checkHuaweiLocationPermission("QR"); } else { @@ -179,9 +182,9 @@ class _MarkAttendanceWidgetState extends State { } }, context); } - } else { - performQrCodeAttendance(widget.model); - } + // } else { + // performQrCodeAttendance(widget.model); + // } // performQrCodeAttendance(model); }), ], @@ -234,11 +237,10 @@ class _MarkAttendanceWidgetState extends State { // Location service not enabled. } }); - } catch(error) { + } catch (error) { print("HUAWEI LOCATION ERROR!!!!!"); print(error); } - } Future performNfcAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async { diff --git a/pubspec.yaml b/pubspec.yaml index 5782482..2875f41 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 3.2.91+300030 +version: 3.2.93+300032 environment: sdk: ">=2.16.0 <3.0.0" @@ -96,6 +96,7 @@ dependencies: #Chat Voice Message Recoding & Play audio_waveforms: ^0.1.5+1 rxdart: ^0.27.7 + #Encryption flutter_des: ^2.1.0 @@ -119,7 +120,7 @@ dependencies: dependency_overrides: - #firebase_core_platform_interface: 4.5.3 + firebase_core_platform_interface: 4.5.1 dev_dependencies: