Merge branch 'master' of http://34.17.52.79/Haroon6138/mohemm-flutter-app into sultan-dev

master
Sultan khan 11 months ago
commit 6d92a78843

@ -0,0 +1,6 @@
-----BEGIN PRIVATE KEY-----
MIGTAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBHkwdwIBAQQg+oBl9YdOiMRXfQZe
nIe6tR1tojoOvvcohNJmJtH+SsagCgYIKoZIzj0DAQehRANCAATDY9E82MAgMI/g
bKF1t4zLHJ1Yt9uoOnedNYsfyZLhh3l3ZyXRj02uDXz04AsNbNFjkLJXPc4xY9ad
+A4rY70x
-----END PRIVATE KEY-----

@ -1,5 +1,5 @@
buildscript {
ext.kotlin_version = '1.6.0'
ext.kotlin_version = '1.7.20'
repositories {
google()
mavenCentral()

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip

@ -0,0 +1,9 @@
<svg xmlns="http://www.w3.org/2000/svg" width="22.015" height="22.015" viewBox="0 0 22.015 22.015">
<g id="Button" transform="translate(-75.66 64.04) rotate(-45)">
<rect id="Rectangle_5860" data-name="Rectangle 5860" width="15.567" height="15.567" rx="7.783" transform="translate(91 16)" fill="#d85323"/>
<g id="plus_1" data-name="plus 1" transform="translate(95.001 20.001)">
<path id="Vector" d="M0,0V7.756" transform="translate(3.878)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.2"/>
<path id="Vector-2" data-name="Vector" d="M0,0H7.756" transform="translate(0 3.878)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.2"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 757 B

@ -0,0 +1,4 @@
<svg id="google-docs" xmlns="http://www.w3.org/2000/svg" width="18.402" height="24.158" viewBox="0 0 18.402 24.158">
<path id="Path_4955" data-name="Path 4955" d="M63.123,24.158H77.278A2.126,2.126,0,0,0,79.4,22.035V7.078H74.447a2.126,2.126,0,0,1-2.123-2.123V0h-9.2A2.126,2.126,0,0,0,61,2.123V22.035A2.126,2.126,0,0,0,63.123,24.158Zm2.831-14.2h8.493a.708.708,0,0,1,0,1.416H65.954a.708.708,0,1,1,0-1.416Zm0,2.831h8.493a.708.708,0,0,1,0,1.416H65.954a.708.708,0,1,1,0-1.416Zm0,2.831h8.493a.708.708,0,0,1,0,1.416H65.954a.708.708,0,1,1,0-1.416Zm0,2.831h5.662a.708.708,0,0,1,0,1.416H65.954a.708.708,0,1,1,0-1.416Z" transform="translate(-61)" fill="#125765"/>
<path id="Path_4956" data-name="Path 4956" d="M331.708,14.036h4.54L331,8.789v4.54A.708.708,0,0,0,331.708,14.036Z" transform="translate(-318.26 -8.374)" fill="#2bb8a6"/>
</svg>

After

Width:  |  Height:  |  Size: 832 B

@ -532,5 +532,13 @@
"connectHmgWifi": "قم بتوصيل HMG WIFI",
"connectedHmgWifi": "اتصال HMG WIFI",
"itgForms": "نماذج (ITG)",
"resetAdPassword": "إعادة تعيين كلمة مرور AD"
"resetAdPassword": "إعادة تعيين كلمة مرور AD",
"myDocuments": "مستنداتي",
"requiredDocuments": "المستندات المطلوبة",
"optionalDocuments": "المستندات الاختيارية",
"allDocuments": "كافة المستندات",
"expiredDocuments": "المستندات منتهية الصلاحية",
"missingDocuments": "مستندات مفقودة",
"uploadedDocuments": "المستندات التي تم تحميلها",
"addAtLeastOneAttachment": "الرجاء إضافة مرفق واحد على الأقل."
}

@ -471,7 +471,7 @@
"gameTime": "Game Time:",
"joinMarathon": "Join Marathon",
"joinDemoMarathon": "Join Demo Marathon",
"demo":"Demo",
"demo": "Demo",
"minutes": "Minutes",
"seconds": "Seconds",
"note": "Note:",
@ -532,6 +532,14 @@
"connectHmgWifi": "Connect HMG WIFI",
"connectedHmgWifi": "Connected HMG WIFI",
"itgForms": "ITG Forms",
"resetAdPassword": "Reset AD Password",
"myDocuments": "My Documents",
"requiredDocuments": "Required Documents",
"optionalDocuments": "Optional Documents",
"allDocuments": "All\nDocuments",
"expiredDocuments": "Expired\nDocuments",
"missingDocuments": "Missing\nDocuments",
"uploadedDocuments": "Uploaded\nDocuments"
"resetAdPassword": "Reset AD Password"
"manage": "Manage",
"members": "Members",
@ -551,5 +559,6 @@
"searchByUserName": "Search By Username",
"userSearch": "User Search",
"userName": "User Name",
"userId": "UserID"
"userId": "UserID",
"addAtLeastOneAttachment": "Please add at least one attachment."
}

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
@ -227,6 +227,7 @@
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@ -241,6 +242,7 @@
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@ -364,17 +366,18 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 99Z3UD3LJM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Mohemm;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemmtest;
MARKETING_VERSION = 3.7.2;
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -501,17 +504,18 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 99Z3UD3LJM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Mohemm;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemmtest;
MARKETING_VERSION = 3.7.2;
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -530,17 +534,18 @@
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 99Z3UD3LJM;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Mohemm;
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemmtest;
MARKETING_VERSION = 3.7.2;
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";

@ -2,15 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsForMedia</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
@ -31,6 +22,10 @@
<string>????</string>
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>
<array>
<string>sms</string>
@ -41,6 +36,15 @@
<true/>
<key>NFCReaderUsageDescription</key>
<string>This App requires access to NFC to mark your attendance.</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
<key>NSAllowsArbitraryLoadsForMedia</key>
<true/>
<key>NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
<key>NSCameraUsageDescription</key>
<string>This app requires camera access to capture &amp; upload picture as profile image.</string>
<key>NSFaceIDUsageDescription</key>
@ -51,17 +55,17 @@
<string>This App requires access to your location to mark your attendance.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This App requires access to your location to mark your attendance.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to select image as document &amp; upload it.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app requires microphone access to for call.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>This app requires photo library access to select image as document &amp; upload it.</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
</array>
<key>FirebaseAppDelegateProxyEnabled</key>
<false/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
@ -85,8 +89,6 @@
<array>
<string>0000</string>
</array>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>TAG</string>

@ -201,13 +201,15 @@ class DashboardApiClient {
}, url, postParams);
}
Future setAdvertisementViewed(String masterID, int advertisementId) async {
Future setAdvertisementViewed(String masterID, int advertisementId, String? ackValue) async {
String url = "${ApiConsts.cocRest}Mohemm_ITG_UpdateAdvertisementAsViewed";
Map<String, dynamic> postParams = {
"ItgNotificationMasterId": masterID,
"EmployeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
"ItgAdvertisement": {"advertisementId": advertisementId, "acknowledgment": true} //Mobile Id
"ItgAdvertisementId": advertisementId,
"ItgAcknowledgment": ackValue,
// "ItgAdvertisement": {"ItgAdvertisementId": advertisementId, "ItgAcknowledgment": ackValue} //Mobile Id
};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {

@ -60,7 +60,7 @@ class MyRequestsApiClient {
}, url, postParams);
}
Future<SubmitCcpTransactionList?> getSubmitNewRequest(List<Map<String, dynamic>> list) async
Future<GenericResponseModel> getSubmitNewRequest(List<Map<String, dynamic>> list) async
{
String url = "${ApiConsts.erpRest}SUBMIT_CCP_TRANSACTION";
Map<String, dynamic> postParams = {
@ -73,7 +73,7 @@ class MyRequestsApiClient {
postParams["EITTransactionTBL"] = list;
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
return responseData.submitCcpTransactionList;
return responseData;
}, url, postParams);
}

@ -12,6 +12,7 @@ import 'package:mohem_flutter_app/models/get_employee_address_model.dart';
import 'package:mohem_flutter_app/models/get_employee_basic_details.model.dart';
import 'package:mohem_flutter_app/models/get_employee_contacts.model.dart';
import 'package:mohem_flutter_app/models/get_employee_phones_model.dart';
import 'package:mohem_flutter_app/models/my_documents/employee_documents_list_model.dart';
import 'package:mohem_flutter_app/models/performance.dart';
import 'package:mohem_flutter_app/models/profile/basic_details_dff_structure.dart';
import 'package:mohem_flutter_app/models/profile/get_contact_clos_structure_list.dart';
@ -84,6 +85,19 @@ class ProfileApiClient {
}, url, postParams);
}
Future<List<EmployeeDocumentsList>> getEmployeeDocuments() async {
String url = "${ApiConsts.erpRest}GET_EMPLOYEE_DOCUMENTS";
Map<String, dynamic> postParams = {
"P_MENU_TYPE": "E",
"P_SELECTED_RESP_ID": -999,
};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
return responseData.employeeDocumentsList ?? [];
}, url, postParams);
}
Future updateEmpImage(img) async {
String url = "${ApiConsts.erpRest}UPDATE_EMPLOYEE_IMAGE";
Map<String, dynamic> postParams = {"P_MENU_TYPE": "E", "P_SELECTED_RESP_ID": -999, "P_IMAGE": img};

@ -90,7 +90,7 @@ class AppState {
String get getHuaweiPushToken => _huaweiPushToken;
final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 4.8, mobileType: Platform.isAndroid ? "android" : "ios");
final PostParamsModel _postParamsInitConfig = PostParamsModel(channel: 31, versionID: 5.2, mobileType: Platform.isAndroid ? "android" : "ios");
void setPostParamsInitConfig() {
isAuthenticated = false;

@ -35,6 +35,7 @@ class MyColors {
static const Color orange = Color(0xFFCC9B14);
static const Color yellowFavColor = Color(0xffEAC321);
static const Color yellowColorII = Color(0xffEAA118);
static const Color yellowColor00 = Color(0xffE6AA00);
static const Color backgroundBlackColor = Color(0xff202529);
static const Color black = Color(0xff000000);
static const Color white = Color(0xffffffff);
@ -64,4 +65,5 @@ class MyColors {
static const Color grey71Color = Color(0xff717171);
static const Color darkGrey3BColor = Color(0xff3B3B3B);
static const Color lightGreyIconColor = Color(0xff919191);
static const Color selectedBorderColor = Color(0xff37A4BE);
}

@ -3,12 +3,16 @@ import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
// import 'package:huawei_hmsavailability/huawei_hmsavailability.dart';
import 'package:huawei_push/huawei_push.dart' as huawei_push;
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/date_uitl.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
import 'package:mohem_flutter_app/models/get_notifications_response_model.dart';
import 'package:mohem_flutter_app/ui/notifications/notification_details_page.dart';
import 'package:permission_handler/permission_handler.dart';
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
@ -24,6 +28,8 @@ class AppNotifications {
String _huaweiToken = '';
late BuildContext context;
Future<void> requestPermissions() async {
if (Platform.isIOS) {
await flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation<IOSFlutterLocalNotificationsPlugin>()?.requestPermissions(alert: true, badge: true, sound: true);
@ -40,11 +46,13 @@ class AppNotifications {
}
}
void init(String? firebaseToken) async {
void init(String? firebaseToken, BuildContext context) async {
// if (Platform.isAndroid) {
// hmsApiAvailability = HmsApiAvailability();
// }
this.context = context;
await requestPermissions();
AppState().setDeviceToken = firebaseToken;
await Permission.notification.isDenied.then((bool value) {
@ -101,7 +109,10 @@ class AppNotifications {
debugPrint("HUAWEI PUSH TOKEN: $_huaweiToken");
}
void _onTokenError(Object error) {}
void _onTokenError(Object error) {
debugPrint("HUAWEI PUSH TOKEN ERROR: $error");
Utils.hideLoading(context);
}
Future<void> initTokenStream(Function loginCallback) async {
huawei_push.Push.getTokenStream.listen(_onTokenEvent, onError: _onTokenError).onData((data) {
@ -113,12 +124,51 @@ class AppNotifications {
void _handleMessage(RemoteMessage message) {
Utils.saveStringFromPrefs("isAppOpendByChat", "false");
GetNotificationsResponseModel notification = GetNotificationsResponseModel();
notification.createdOn = DateUtil.getMonthDayYearDateFormatted(DateTime.now());
notification.messageTypeData = message.data['picture'];
notification.message = message.data['message'];
notification.notificationType = message.data["NotificationType"].toString();
if (message.data["NotificationType"] == "2") {
notification.videoURL = message.data["VideoUrl"];
}
Future.delayed(Duration(seconds: 5), () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => NotificationsDetailsPage(
notification: notification,
),
),
);
});
}
void _handleOpenApp(RemoteMessage message) {
if (message.data.isNotEmpty && message.data["type"] == 'chat') {
Utils.saveStringFromPrefs("isAppOpendByChat", "true");
Utils.saveStringFromPrefs("notificationData", message.data["user_chat_history_response"].toString());
} else {
GetNotificationsResponseModel notification = GetNotificationsResponseModel();
notification.createdOn = DateUtil.getMonthDayYearDateFormatted(DateTime.now());
notification.messageTypeData = message.data['picture'];
notification.message = message.data['message'];
notification.notificationType = message.data["NotificationType"].toString();
if (message.data["NotificationType"] == "2") {
notification.videoURL = message.data["VideoUrl"];
}
Future.delayed(Duration(seconds: 5), () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (BuildContext context) => NotificationsDetailsPage(
notification: notification,
),
),
);
});
}
}
}

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/models/my_documents/employee_documents_list_model.dart';
import 'package:mohem_flutter_app/ui/app_update_screen.dart';
import 'package:mohem_flutter_app/ui/attendance/add_vacation_rule_screen.dart';
import 'package:mohem_flutter_app/ui/attendance/monthly_attendance_screen.dart';
@ -62,6 +63,8 @@ import 'package:mohem_flutter_app/ui/screens/items_for_sale/items_for_sale_home.
import 'package:mohem_flutter_app/ui/screens/mowadhafhi/mowadhafhi_home.dart';
import 'package:mohem_flutter_app/ui/screens/mowadhafhi/mowadhafhi_hr_request.dart';
import 'package:mohem_flutter_app/ui/screens/mowadhafhi/request_details.dart';
import 'package:mohem_flutter_app/ui/screens/my_documents/my_document_detail_screen.dart';
import 'package:mohem_flutter_app/ui/screens/my_documents/my_documents_screen.dart';
import 'package:mohem_flutter_app/ui/screens/my_requests/my_requests.dart';
import 'package:mohem_flutter_app/ui/screens/my_requests/new_request.dart';
import 'package:mohem_flutter_app/ui/screens/offers_and_discounts/offers_and_discounts_details.dart';
@ -152,6 +155,8 @@ class AppRoutes {
// My Requests
static const String myRequests = "/myRequests";
static const String newRequest = "/newRequests";
static const String myDocuments = "/myDocuments";
static const String myDocumentDetail = "/myDocumentDetail";
// Items For Sale
static const String itemsForSale = "/itemsForSale";
@ -272,7 +277,7 @@ class AppRoutes {
//My Requests
myRequests: (BuildContext context) => MyRequests(),
newRequest: (BuildContext context) => NewRequest(),
myDocuments: (BuildContext context) => MyDocumentsScreen(),
// Items for sale
itemsForSale: (BuildContext context) => ItemsForSale(),
itemsForSaleDetail: (BuildContext context) => ItemForSaleDetailPage(),

@ -10,6 +10,4 @@ extension IntExtensions on int {
Widget get divider => Divider(height: toDouble(), thickness: toDouble(), color: MyColors.lightGreyEFColor);
Widget get makeItSquare => SizedBox(width: toDouble(), height: toDouble());
}

@ -548,7 +548,14 @@ class CodegenLoader extends AssetLoader{
"connectHmgWifi": "قم بتوصيل HMG WIFI",
"connectedHmgWifi": "اتصال HMG WIFI",
"itgForms": "نماذج (ITG)",
"resetAdPassword": "إعادة تعيين كلمة مرور AD"
"resetAdPassword": "إعادة تعيين كلمة مرور AD",
"myDocuments": "مستنداتي",
"requiredDocuments": "المستندات المطلوبة",
"optionalDocuments": "المستندات الاختيارية",
"allDocuments": "كافة المستندات",
"expiredDocuments": "المستندات منتهية الصلاحية",
"missingDocuments": "مستندات مفقودة",
"uploadedDocuments": "المستندات التي تم تحميلها"
};
static const Map<String,dynamic> en_US = {
"mohemm": "Mohemm",
@ -1085,6 +1092,13 @@ static const Map<String,dynamic> en_US = {
"connectedHmgWifi": "Connected HMG WIFI",
"itgForms": "ITG Forms",
"resetAdPassword": "Reset AD Password",
"myDocuments": "My Documents",
"requiredDocuments": "Required Documents",
"optionalDocuments": "Optional Documents",
"allDocuments": "All\nDocuments",
"expiredDocuments": "Expired\nDocuments",
"missingDocuments": "Missing\nDocuments",
"uploadedDocuments": "Uploaded\nDocuments",
"manage": "Manage",
"members": "Members",
"areYouSureWantTodelete": "Are you sure want to delete?",

@ -519,6 +519,13 @@ abstract class LocaleKeys {
static const connectedHmgWifi = 'connectedHmgWifi';
static const itgForms = 'itgForms';
static const resetAdPassword = 'resetAdPassword';
static const myDocuments = 'myDocuments';
static const requiredDocuments = 'requiredDocuments';
static const optionalDocuments = 'optionalDocuments';
static const allDocuments = 'allDocuments';
static const expiredDocuments = 'expiredDocuments';
static const missingDocuments = 'missingDocuments';
static const uploadedDocuments = 'uploadedDocuments';
static const manage = 'manage';
static const members = 'members';
@ -539,4 +546,5 @@ abstract class LocaleKeys {
static const userSearch ='userSearch';
static const userName ='userName';
static const userId ='userId';
static const addAtLeastOneAttachment ='addAtLeastOneAttachment';
}

@ -60,6 +60,7 @@ import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_details.dart';
import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_transactions.dart';
import 'package:mohem_flutter_app/models/mowadhafhi/get_ticket_types.dart';
import 'package:mohem_flutter_app/models/mowadhafhi/get_tickets_list.dart';
import 'package:mohem_flutter_app/models/my_documents/employee_documents_list_model.dart';
import 'package:mohem_flutter_app/models/my_requests/get_ccp_dff_structure_model.dart';
import 'package:mohem_flutter_app/models/my_requests/get_ccp_output_model.dart';
import 'package:mohem_flutter_app/models/my_requests/get_ccp_transactions_model.dart';
@ -160,6 +161,7 @@ class GenericResponseModel {
String? deleteVacationRuleList;
String? disableSessionList;
String? employeeQR;
List<EmployeeDocumentsList>? employeeDocumentsList;
String? forgetPasswordTokenID;
List<String>? getCcpTransactionsListNew;
List<String>? getConcurrentProgramsList;
@ -431,6 +433,7 @@ class GenericResponseModel {
this.deleteVacationRuleList,
this.disableSessionList,
this.employeeQR,
this.employeeDocumentsList,
this.forgetPasswordTokenID,
this.getAbsenceAttachmentsList,
this.getAbsenceAttendanceTypesList,
@ -709,6 +712,14 @@ class GenericResponseModel {
deleteVacationRuleList = json['DeleteVacationRuleList'];
disableSessionList = json['DisableSessionList'];
employeeQR = json['EmployeeQR'];
if (json['Employee_Documents_List'] != null) {
employeeDocumentsList = <EmployeeDocumentsList>[];
json['Employee_Documents_List'].forEach((v) {
employeeDocumentsList!.add(EmployeeDocumentsList.fromJson(v));
});
}
forgetPasswordTokenID = json['ForgetPasswordTokenID'];
getAbsenceAttachmentsList = json['GetAbsenceAttachmentsList'];
@ -1315,7 +1326,7 @@ class GenericResponseModel {
if (json['RespondRolesList'] != null) {
respondRolesList = <String>[];
json['RespondRolesList'].forEach((v) {
// respondRolesList!.add(v);
// respondRolesList!.add(v);
});
}
resubmitAbsenceTransactionList = json['ResubmitAbsenceTransactionList'];
@ -1341,10 +1352,7 @@ class GenericResponseModel {
submitAddressTransactionList = json['SubmitAddressTransactionList'] != null ? SubmitAddressTransaction.fromJson(json['SubmitAddressTransactionList']) : null;
submitBasicDetTransactionList = json['SubmitBasicDetTransactionList'] != null ? SubmitBasicDetailsTransactionList.fromJson(json['SubmitBasicDetTransactionList']) : null;
submitCEITransactionList = json['SubmitCEITransactionList'];
submitCcpTransactionList = json['SubmitCcpTransactionList'] != null
? new SubmitCcpTransactionList.fromJson(
json['SubmitCcpTransactionList'])
: null;
submitCcpTransactionList = json['SubmitCcpTransactionList'] != null ? new SubmitCcpTransactionList.fromJson(json['SubmitCcpTransactionList']) : null;
submitContactTransactionList = json['SubmitContactTransactionList'] != null ? SubmitContactTransactionList.fromJson(json['SubmitContactTransactionList']) : null;
submitEITTransactionList = json['SubmitEITTransactionList'] != null ? SubmitEITTransactionList.fromJson(json['SubmitEITTransactionList']) : null;
@ -1471,6 +1479,11 @@ class GenericResponseModel {
data['DeleteVacationRuleList'] = this.deleteVacationRuleList;
data['DisableSessionList'] = this.disableSessionList;
data['EmployeeQR'] = this.employeeQR;
if (this.employeeDocumentsList != null) {
data['Employee_Documents_List'] = this.employeeDocumentsList!.map((v) => v.toJson()).toList();
}
data['ForgetPasswordTokenID'] = this.forgetPasswordTokenID;
data['GetAbsenceAttachmentsList'] = this.getAbsenceAttachmentsList;
@ -1804,8 +1817,7 @@ class GenericResponseModel {
data['SubmitCEITransactionList'] = this.submitCEITransactionList;
if (this.submitCcpTransactionList != null) {
data['SubmitCcpTransactionList'] =
this.submitCcpTransactionList!.toJson();
data['SubmitCcpTransactionList'] = this.submitCcpTransactionList!.toJson();
}
data['SubmitContactTransactionList'] = this.submitContactTransactionList;

@ -0,0 +1,96 @@
class GetNotificationsResponseModel {
int? id;
int? recordId;
int? patientID;
bool? projectOutSA;
String? deviceType;
String? deviceToken;
String? message;
String? messageType;
String? messageTypeData;
dynamic videoURL;
bool? isQueue;
String? isQueueOn;
String? createdOn;
String? createdBy;
String? notificationType;
bool? isSent;
String? isSentOn;
bool? isRead;
String? isReadOn;
int? channelID;
int? projectID;
GetNotificationsResponseModel(
{this.id,
this.recordId,
this.patientID,
this.projectOutSA,
this.deviceType,
this.deviceToken,
this.message,
this.messageType,
this.messageTypeData,
this.videoURL,
this.isQueue,
this.isQueueOn,
this.createdOn,
this.createdBy,
this.notificationType,
this.isSent,
this.isSentOn,
this.isRead,
this.isReadOn,
this.channelID,
this.projectID});
GetNotificationsResponseModel.fromJson(Map<String, dynamic> json) {
id = json['Id'];
recordId = json['RecordId'];
patientID = json['PatientID'];
projectOutSA = json['ProjectOutSA'];
deviceType = json['DeviceType'];
deviceToken = json['DeviceToken'];
message = json['Message'];
messageType = json['MessageType'];
messageTypeData = json['MessageTypeData'];
videoURL = json['VideoURL'];
isQueue = json['IsQueue'];
isQueueOn = json['IsQueueOn'];
createdOn = json['CreatedOn'];
createdBy = json['CreatedBy'];
notificationType = json['NotificationType'];
isSent = json['IsSent'];
isSentOn = json['IsSentOn'];
isRead = json['IsRead'];
isReadOn = json['IsReadOn'];
channelID = json['ChannelID'];
projectID = json['ProjectID'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['Id'] = this.id;
data['RecordId'] = this.recordId;
data['PatientID'] = this.patientID;
data['ProjectOutSA'] = this.projectOutSA;
data['DeviceType'] = this.deviceType;
data['DeviceToken'] = this.deviceToken;
data['Message'] = this.message;
data['MessageType'] = this.messageType;
data['MessageTypeData'] = this.messageTypeData;
data['VideoURL'] = this.videoURL;
data['IsQueue'] = this.isQueue;
data['IsQueueOn'] = this.isQueueOn;
data['CreatedOn'] = this.createdOn;
data['CreatedBy'] = this.createdBy;
data['NotificationType'] = this.notificationType;
data['IsSent'] = this.isSent;
data['IsSentOn'] = this.isSentOn;
data['IsRead'] = this.isRead;
data['IsReadOn'] = this.isReadOn;
data['ChannelID'] = this.channelID;
data['ProjectID'] = this.projectID;
return data;
}
}

@ -1,99 +1,156 @@
class Advertisement {
int? advertisementId;
String? advertisementTitle;
int? durationInSeconds;
bool? showDelete;
dynamic acknowledgment;
late bool isOptional;
List<ViewAttachFileColl>? viewAttachFileColl;
int? skipButtonId;
List<ActionButtonsColl>? actionButtonsColl;
bool? isActive;
num? pageSize;
num? pageNo;
num? languageId;
Advertisement({
this.advertisementId,
this.advertisementTitle,
this.durationInSeconds,
this.showDelete,
this.acknowledgment,
required this.isOptional,
// this.skipBtnTextEn,
// this.skipBtnTextAr,
this.viewAttachFileColl,
this.skipButtonId,
this.actionButtonsColl,
this.isActive,
this.pageSize,
this.pageNo,
this.languageId,
});
final int? advertisementId;
final String? advertisementTitle;
final int? durationInSeconds;
final bool? showDelete;
final dynamic acknowledgment;
final List<ViewAttachFileColl>? viewAttachFileColl;
final bool? isActive;
final dynamic pageSize;
final dynamic pageNo;
final dynamic languageId;
factory Advertisement.fromJson(Map<String, dynamic> json) => Advertisement(
advertisementId: json["advertisementId"] == null ? null : json["advertisementId"],
advertisementTitle: json["advertisementTitle"] == null ? null : json["advertisementTitle"],
durationInSeconds: json["durationInSeconds"] == null ? null : json["durationInSeconds"],
showDelete: json["showDelete"] == null ? null : json["showDelete"],
acknowledgment: json["acknowledgment"],
viewAttachFileColl: json["viewAttachFileColl"] == null ? null : List<ViewAttachFileColl>.from(json["viewAttachFileColl"].map((x) => ViewAttachFileColl.fromJson(x))),
isActive: json["isActive"] == null ? null : json["isActive"],
pageSize: json["pageSize"],
pageNo: json["pageNo"],
languageId: json["languageId"],
);
Advertisement.fromJson(Map<String, dynamic> json) {
advertisementId = json['advertisementId'];
advertisementTitle = json['advertisementTitle'];
durationInSeconds = json['durationInSeconds'];
showDelete = json['showDelete'];
acknowledgment = json['acknowledgment'];
isOptional = json['isOptional'];
// skipBtnTextEn = json['skipBtnTextEn'];
// skipBtnTextAr = json['skipBtnTextAr'];
if (json['viewAttachFileColl'] != null) {
viewAttachFileColl = <ViewAttachFileColl>[];
json['viewAttachFileColl'].forEach((v) {
viewAttachFileColl!.add(ViewAttachFileColl.fromJson(v));
});
}
skipButtonId = json['skipButtonId'];
if (json['actionButtonsColl'] != null) {
actionButtonsColl = <ActionButtonsColl>[];
json['actionButtonsColl'].forEach((v) {
actionButtonsColl!.add(ActionButtonsColl.fromJson(v));
});
}
isActive = json['isActive'];
pageSize = json['pageSize'];
pageNo = json['pageNo'];
languageId = json['languageId'];
}
Map<String, dynamic> toJson() => {
"advertisementId": advertisementId == null ? null : advertisementId,
"advertisementTitle": advertisementTitle == null ? null : advertisementTitle,
"durationInSeconds": durationInSeconds == null ? null : durationInSeconds,
"showDelete": showDelete == null ? null : showDelete,
"acknowledgment": acknowledgment,
"viewAttachFileColl": viewAttachFileColl == null ? null : List<dynamic>.from(viewAttachFileColl!.map((x) => x.toJson())),
"isActive": isActive == null ? null : isActive,
"pageSize": pageSize,
"pageNo": pageNo,
"languageId": languageId,
};
Map<String, dynamic> toJson() {
Map<String, dynamic> data = Map<String, dynamic>();
data['advertisementId'] = this.advertisementId;
data['advertisementTitle'] = this.advertisementTitle;
data['durationInSeconds'] = this.durationInSeconds;
data['showDelete'] = this.showDelete;
data['acknowledgment'] = this.acknowledgment;
data['isOptional'] = this.isOptional;
// data['skipBtnTextEn'] = this.skipBtnTextEn;
// data['skipBtnTextAr'] = this.skipBtnTextAr;
if (this.viewAttachFileColl != null) {
data['viewAttachFileColl'] = this.viewAttachFileColl!.map((v) => v.toJson()).toList();
}
data['skipButtonId'] = this.skipButtonId;
if (this.actionButtonsColl != null) {
data['actionButtonsColl'] = this.actionButtonsColl!.map((v) => v.toJson()).toList();
}
data['isActive'] = this.isActive;
data['pageSize'] = this.pageSize;
data['pageNo'] = this.pageNo;
data['languageId'] = this.languageId;
return data;
}
}
class ViewAttachFileColl {
ViewAttachFileColl({
this.attachmentId,
this.fileName,
this.contentType,
this.attachFileStream,
this.base64String,
this.isActive,
this.referenceItemId,
this.content,
this.filePath,
});
dynamic attachmentId;
String? fileName;
String? contentType;
dynamic attachFileStream;
String? base64String;
dynamic isActive;
dynamic referenceItemId;
dynamic content;
dynamic filePath;
ViewAttachFileColl({this.attachmentId, this.fileName, this.contentType, this.attachFileStream, this.base64String, this.isActive, this.referenceItemId, this.content, this.filePath});
ViewAttachFileColl.fromJson(Map<String, dynamic> json) {
attachmentId = json['attachmentId'];
fileName = json['fileName'];
contentType = json['contentType'];
attachFileStream = json['attachFileStream'];
base64String = json['base64String'];
isActive = json['isActive'];
referenceItemId = json['referenceItemId'];
content = json['content'];
filePath = json['filePath'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['attachmentId'] = this.attachmentId;
data['fileName'] = this.fileName;
data['contentType'] = this.contentType;
data['attachFileStream'] = this.attachFileStream;
data['base64String'] = this.base64String;
data['isActive'] = this.isActive;
data['referenceItemId'] = this.referenceItemId;
data['content'] = this.content;
data['filePath'] = this.filePath;
return data;
}
}
class ActionButtonsColl {
late int actionButtonId;
late String btnTextEn;
late String btnTextAr;
late String actionValue;
late dynamic iconOrImage;
late int orderNo;
final dynamic attachmentId;
final String? fileName;
final String? contentType;
final dynamic attachFileStream;
final String? base64String;
final dynamic isActive;
final dynamic referenceItemId;
final dynamic content;
final dynamic filePath;
ActionButtonsColl({required this.actionButtonId, required this.btnTextEn, required this.btnTextAr, required this.actionValue, required this.iconOrImage, required this.orderNo});
factory ViewAttachFileColl.fromJson(Map<String, dynamic> json) => ViewAttachFileColl(
attachmentId: json["attachmentId"],
fileName: json["fileName"] == null ? null : json["fileName"],
contentType: json["contentType"] == null ? null : json["contentType"],
attachFileStream: json["attachFileStream"],
base64String: json["base64String"] == null ? null : json["base64String"],
isActive: json["isActive"],
referenceItemId: json["referenceItemId"],
content: json["content"],
filePath: json["filePath"],
);
ActionButtonsColl.fromJson(Map<String, dynamic> json) {
actionButtonId = json['actionButtonId'];
btnTextEn = json['btnTextEn'];
btnTextAr = json['btnTextAr'];
actionValue = json['actionValue'];
iconOrImage = json['iconOrImage'];
orderNo = json['orderNo'];
}
Map<String, dynamic> toJson() => {
"attachmentId": attachmentId,
"fileName": fileName == null ? null : fileName,
"contentType": contentType == null ? null : contentType,
"attachFileStream": attachFileStream,
"base64String": base64String == null ? null : base64String,
"isActive": isActive,
"referenceItemId": referenceItemId,
"content": content,
"filePath": filePath,
};
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['actionButtonId'] = this.actionButtonId;
data['btnTextEn'] = this.btnTextEn;
data['btnTextAr'] = this.btnTextAr;
data['actionValue'] = this.actionValue;
data['iconOrImage'] = this.iconOrImage;
data['orderNo'] = this.orderNo;
return data;
}
}

@ -5,9 +5,9 @@ class SurveyModel {
String? description;
List<Questions>? questions;
bool? isActive;
Null? pageSize;
Null? pageNo;
Null? languageId;
dynamic pageSize;
dynamic pageNo;
dynamic languageId;
SurveyModel({this.surveyId, this.referenceNo, this.title, this.description, this.questions, this.isActive, this.pageSize, this.pageNo, this.languageId});
@ -51,13 +51,13 @@ class Questions {
bool? isRequired;
String? type;
int? sequenceNo;
Null? surveyId;
dynamic surveyId;
List<Options>? options;
Null? rspPercentage;
Null? isActive;
Null? pageSize;
Null? pageNo;
Null? languageId;
dynamic rspPercentage;
dynamic isActive;
dynamic pageSize;
dynamic pageNo;
dynamic 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});
@ -107,12 +107,12 @@ class Options {
bool? isCommentsRequired;
int? sequenceNo;
int? questionId;
Null? rspPercentage;
Null? count;
Null? isActive;
Null? pageSize;
Null? pageNo;
Null? languageId;
dynamic rspPercentage;
dynamic count;
dynamic isActive;
dynamic pageSize;
dynamic pageNo;
dynamic languageId;
Options({this.optionId, this.title, this.isCommentsRequired, this.sequenceNo, this.questionId, this.rspPercentage, this.count, this.isActive, this.pageSize, this.pageNo, this.languageId});

@ -6,7 +6,7 @@ class ITGRequest {
List<AllowedActions>? allowedActions;
List<dynamic>? attachments;
List<FieldGoups>? fieldGoups;
Null? grantFields;
dynamic grantFields;
List<WFHistory>? wFHistory;
ITGRequest({this.allowedActions, this.attachments, this.fieldGoups, this.grantFields, this.wFHistory});

@ -0,0 +1,36 @@
class EmployeeDocumentsList {
String? dOCUMENTREQUIREDSTATUS;
String? dOCUMENTSTATUS;
String? dOCUMENTTYPE;
String? dOCUMENTTYPENAME;
String? eNTITLEDTOAPPLYFLAG;
String? fUNCTIONNAME;
EmployeeDocumentsList(
{this.dOCUMENTREQUIREDSTATUS,
this.dOCUMENTSTATUS,
this.dOCUMENTTYPE,
this.dOCUMENTTYPENAME,
this.eNTITLEDTOAPPLYFLAG,
this.fUNCTIONNAME});
EmployeeDocumentsList.fromJson(Map<String, dynamic> json) {
dOCUMENTREQUIREDSTATUS = json['DOCUMENT_REQUIRED_STATUS'];
dOCUMENTSTATUS = json['DOCUMENT_STATUS'];
dOCUMENTTYPE = json['DOCUMENT_TYPE'];
dOCUMENTTYPENAME = json['DOCUMENT_TYPE_NAME'];
eNTITLEDTOAPPLYFLAG = json['ENTITLED_TO_APPLY_FLAG'];
fUNCTIONNAME = json['FUNCTION_NAME'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['DOCUMENT_REQUIRED_STATUS'] = this.dOCUMENTREQUIREDSTATUS;
data['DOCUMENT_STATUS'] = this.dOCUMENTSTATUS;
data['DOCUMENT_TYPE'] = this.dOCUMENTTYPE;
data['DOCUMENT_TYPE_NAME'] = this.dOCUMENTTYPENAME;
data['ENTITLED_TO_APPLY_FLAG'] = this.eNTITLEDTOAPPLYFLAG;
data['FUNCTION_NAME'] = this.fUNCTIONNAME;
return data;
}
}

@ -168,7 +168,7 @@ class ChatProviderModel with ChangeNotifier, DiagnosticableTreeMixin {
Future<void> getUserRecentChats() async {
ChatUserModel recentChat = await ChatApiClient().getRecentChats();
ChatUserModel favUList = await ChatApiClient().getFavUsers();
userGroups = await ChatApiClient().getGroupsByUserId();
// userGroups = await ChatApiClient().getGroupsByUserId();
if (favUList.response != null && recentChat.response != null) {
favUsersList = favUList.response!;
favUsersList.sort((ChatUser a, ChatUser b) =>

@ -91,7 +91,7 @@ class _ChatHomeState extends State<ChatHome> {
child: Row(
children: <Widget>[
myTab(LocaleKeys.mychats.tr(), 0),
myTab(LocaleKeys.group.tr(), 1),
// myTab(LocaleKeys.group.tr(), 1),
myTab(LocaleKeys.favorite.tr(), 2),
AppState().getempStatusIsManager ? myTab(LocaleKeys.myTeam.tr(), 3) : const SizedBox(),
],
@ -107,7 +107,7 @@ class _ChatHomeState extends State<ChatHome> {
},
children: <Widget>[
ChatHomeScreen(),
GropChatHomeScreen(),
// GropChatHomeScreen(),
ChatFavoriteUsersScreen(),
AppState().getempStatusIsManager ? const MyTeamScreen() : const SizedBox(),
],

@ -163,7 +163,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
print("-------------------- Survey ----------------------------");
if (val.result!.data!.notificationType == "Survey") {
DashboardApiClient().getAdvertisementDetail(val.result!.data!.notificationMasterId ?? "").then(
(value) {
(value) {
if (value!.mohemmItgResponseItem!.statusCode == 200) {
if (value.mohemmItgResponseItem!.result!.data != null) {
// Navigator.pushNamed(context, AppRoutes.survey, arguments: val.result!.data);

@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_countdown_timer/index.dart';
import 'package:lottie/lottie.dart';
import 'package:mohem_flutter_app/api/dashboard_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/lottie_consts.dart';
import 'package:mohem_flutter_app/classes/utils.dart';
@ -15,6 +16,7 @@ import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/main.dart';
import 'package:mohem_flutter_app/models/itg/advertisement.dart' as ads;
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:path_provider/path_provider.dart';
import 'package:video_player/video_player.dart';
@ -39,6 +41,12 @@ class _ITGAdsScreenState extends State<ITGAdsScreen> {
String? masterID;
int videoDuration = 0;
bool hasTimerEndedBool = false;
final ValueNotifier<bool> hasTimerEnded = ValueNotifier(false);
late CountdownTimerController timerController;
void checkFileType() async {
String? rFile = advertisementData!.viewAttachFileColl!.first.base64String;
String? rFileExt = advertisementData!.viewAttachFileColl!.first.fileName;
@ -53,9 +61,25 @@ class _ITGAdsScreenState extends State<ITGAdsScreen> {
isVideo = true;
_futureController = createVideoPlayer(rFile!);
}
advertisementData?.actionButtonsColl!.forEach((element) {
advertisementData?.actionButtonsColl!.removeWhere((element1) => element1.actionButtonId == advertisementData?.skipButtonId);
});
setState(() {});
}
void changeTimer(bool isTimerEnd) {
hasTimerEndedBool = isTimerEnd;
hasTimerEnded.value = !hasTimerEnded.value;
}
void onTimerEnd() {
changeTimer(true);
timerController.disposeTimer();
timerController.dispose();
}
Future processImage(String encodedBytes) async {
try {
Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last);
@ -69,18 +93,15 @@ class _ITGAdsScreenState extends State<ITGAdsScreen> {
Future<VideoPlayerController> createVideoPlayer(String encodedBytes) async {
try {
Uint8List decodedBytes = base64Decode(encodedBytes.split("base64,").last);
Directory appDocumentsDirectory = await getApplicationDocumentsDirectory(); // 1
File file = Io.File("${appDocumentsDirectory.path}/myAdsVideo.mp4");
file.writeAsBytesSync(decodedBytes);
VideoPlayerController controller = VideoPlayerController.file(file);
VideoPlayerController controller = VideoPlayerController.network(advertisementData!.viewAttachFileColl!.first.base64String!);
await controller.initialize();
await controller.play();
await controller.setVolume(1.0);
await controller.setLooping(false);
return controller;
} catch (e) {
return VideoPlayerController.asset("dataSource");
print(e);
return VideoPlayerController.network("https://apimohemmweb.cloudsolutions.com.sa/ErmAttachment/compressedvideo.mp4");
}
}
@ -94,8 +115,6 @@ class _ITGAdsScreenState extends State<ITGAdsScreen> {
@override
void dispose() {
if (_controller != null) _controller.dispose();
// player.stop();
// player.dispose();
super.dispose();
}
@ -107,6 +126,7 @@ class _ITGAdsScreenState extends State<ITGAdsScreen> {
if (advertisementData != null) {
checkFileType();
videoDuration = advertisementData?.durationInSeconds ?? 0;
timerController = CountdownTimerController(endTime: DateTime.now().millisecondsSinceEpoch + 1000 * videoDuration, onEnd: onTimerEnd);
}
return Scaffold(
backgroundColor: Colors.black,
@ -131,38 +151,107 @@ class _ITGAdsScreenState extends State<ITGAdsScreen> {
),
30.height,
CountdownTimer(
controller: timerController,
endTime: DateTime.now().millisecondsSinceEpoch + 1000 * videoDuration,
onEnd: null,
endWidget: "00:00:00".toText14(color: Colors.white, isBold: true),
endWidget: "00:00:00".toText16(color: Colors.white, isBold: true),
textStyle: const TextStyle(color: Colors.white, fontSize: 16, letterSpacing: -0.48, fontWeight: FontWeight.bold),
),
50.height,
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) {
if (advertisementData?.isOptional ?? false)
DefaultButton(AppState().isArabic(context) ? "يتخطى" : "Skip", () async {
Navigator.pop(context);
DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Skip").then((value) {
logger.d(value);
Navigator.pop(context);
});
} catch (ex) {
logger.wtf(ex);
Utils.handleException(ex, context, null);
}
}),
// DefaultButton(LocaleKeys.home.tr(), () async {
// DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!).then((value) {
// logger.d(value);
// });
// }).paddingOnly(left: 50, right: 50)
// ElevatedButton(
// onPressed: () async {
// // DashboardApiClient().setAdvertisementViewed(widget.addMasterId, widget.advertisement!.advertisementId!).then((value) {
// // logger.d(value);
// // });
}).paddingOnly(left: 60.0, right: 60.0, top: 8, bottom: 8),
ValueListenableBuilder<bool>(
valueListenable: hasTimerEnded,
builder: (context, val, child) {
if (hasTimerEndedBool) {
return GridView.builder(
padding: EdgeInsets.zero,
itemCount: advertisementData?.actionButtonsColl!.length,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
String? btnText = AppState().isArabic(context) ? advertisementData?.actionButtonsColl![index].btnTextAr : advertisementData?.actionButtonsColl![index].btnTextEn;
return DefaultButton(btnText!, () async {
Navigator.pop(context);
DashboardApiClient()
.setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, advertisementData?.actionButtonsColl![index].actionValue)
.then((value) {
logger.d(value);
});
}).paddingOnly(left: 60.0, right: 60.0, top: 8, bottom: 8);
},
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
childAspectRatio: (7.0),
),
);
// Row(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Container(padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_up, color: MyColors.gradiantEndColor))
// .onPress(() {
// try {
// Navigator.pop(context);
// DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Like").then((value) {
// logger.d(value);
// });
// } catch (ex) {
// logger.wtf(ex);
// Utils.handleException(ex, context, null);
// }
// }),
// 20.width,
// Container(
// padding: const EdgeInsets.all(16), decoration: Utils.containerRadius(MyColors.white, 10), child: const Icon(Icons.thumb_down, color: MyColors.gradiantEndColor))
// .onPress(() {
// try {
// Navigator.pop(context);
// DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Dislike").then((value) {
// logger.d(value);
// });
// } catch (ex) {
// logger.wtf(ex);
// Utils.handleException(ex, context, null);
// }
// }),
// ],
// );
} else {
return Container();
}
},
),
20.height,
// if (advertisementData?.isOptional ?? false)
// GridView.builder(
// padding: EdgeInsets.zero,
// itemCount: advertisementData?.actionButtonsColl!.length,
// shrinkWrap: true,
// physics: const NeverScrollableScrollPhysics(),
// itemBuilder: (context, index) {
// String? btnText = AppState().isArabic(context) ? advertisementData?.actionButtonsColl![index].btnTextAr : advertisementData?.actionButtonsColl![index].btnTextEn;
// return DefaultButton(btnText!, () async {
// Navigator.pop(context);
// DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, advertisementData?.actionButtonsColl![index].actionValue).then((value) {
// logger.d(value);
// });
// }).paddingAll(8);
// },
// child: const Text("Go To Dashboard"),
// gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
// crossAxisCount: 2,
// childAspectRatio: (4.0),
// ),
// )
// DefaultButton(AppState().isArabic(context) ? advertisementData?.skipButtonTextAr ?? "Skip" : advertisementData?.skipButtonTextEn ?? "Skip", () async {
// Navigator.pop(context);
// DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Skip").then((value) {
// logger.d(value);
// });
// }).paddingOnly(left: 100, right: 100)
],
);
} else {
@ -182,9 +271,9 @@ class _ITGAdsScreenState extends State<ITGAdsScreen> {
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) {
Navigator.pop(context);
DashboardApiClient().setAdvertisementViewed(masterID!, advertisementData!.advertisementId!, "Like").then((value) {
logger.d(value);
Navigator.pop(context);
});
} catch (ex) {
logger.wtf(ex);

@ -69,7 +69,9 @@ class ServicesWidget extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
SvgPicture.asset(AppState().isArabic(context) ? getMenuIconAr(data.homeMenus![parentIndex].menuEntiesList[index].prompt!) : getMenuIconEn(data.homeMenus![parentIndex].menuEntiesList[index].prompt!)),
SvgPicture.asset(AppState().isArabic(context)
? getMenuIconAr(data.homeMenus![parentIndex].menuEntiesList[index].prompt!)
: getMenuIconEn(data.homeMenus![parentIndex].menuEntiesList[index].prompt!)),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
@ -138,6 +140,9 @@ class ServicesWidget extends StatelessWidget {
case "قاعدة الاجازات":
returnImage = "assets/images/services_icons/vacation_rule.svg";
break;
case "مستنداتي":
returnImage = "assets/images/document.svg";
break;
default:
returnImage = "assets/images/monthly_attendance.svg";
break;
@ -181,6 +186,9 @@ class ServicesWidget extends StatelessWidget {
case "Vacation Rule":
returnImage = "assets/images/services_icons/vacation_rule.svg";
break;
case "My Documents":
returnImage = "assets/images/document.svg";
break;
default:
returnImage = "assets/images/monthly_attendance.svg";
break;
@ -199,6 +207,9 @@ class ServicesWidget extends StatelessWidget {
} else if (menuEntry.menuName == "MBL_PERINFO_SS") {
Navigator.of(context).pushNamed(AppRoutes.profile);
return;
} else if (menuEntry.menuName!.substring(4, menuEntry.menuName!.length) == "MBL_EMPLOYEE_DOCUMENTS") {
Navigator.pushNamed(context, AppRoutes.myDocuments);
return;
}
List<GetMenuEntriesList> menuList = pro.getMenuEntriesList?.where((element) => element.parentMenuName == menuEntry.menuName && (element.menuEntryType == "FUNCTION")).toList() ?? [];
menuEntry.icon = "";

@ -27,7 +27,6 @@ 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';
@ -98,11 +97,13 @@ class _LoginScreenState extends State<LoginScreen> {
Future<void> checkFirebaseToken() async {
try {
await checkPrefs();
Utils.showLoading(context);
if (Platform.isAndroid) {
try {
if (!(await Utils.isGoogleServicesAvailable())) {
print("HUAWEI APPPP GALLERYYYY!!!!");
AppNotifications().init(firebaseToken, context);
AppState().setIsHuawei = true;
AppNotifications().initHuaweiPush(checkLoginInfo);
} else {
@ -110,7 +111,8 @@ class _LoginScreenState extends State<LoginScreen> {
await Firebase.initializeApp();
_firebaseMessaging = FirebaseMessaging.instance;
firebaseToken = await _firebaseMessaging.getToken();
AppNotifications().init(firebaseToken);
print(firebaseToken);
AppNotifications().init(firebaseToken, context);
checkLoginInfo();
await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
}
@ -120,7 +122,10 @@ class _LoginScreenState extends State<LoginScreen> {
await Firebase.initializeApp();
_firebaseMessaging = FirebaseMessaging.instance;
firebaseToken = await _firebaseMessaging.getToken();
AppNotifications().init(firebaseToken);
String? firebaseAPNSToken = await _firebaseMessaging.getAPNSToken();
print("Firebase Token: $firebaseToken");
print("Firebase APNS Token: $firebaseAPNSToken");
AppNotifications().init(firebaseToken, context);
checkLoginInfo();
await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
}
@ -132,17 +137,21 @@ class _LoginScreenState extends State<LoginScreen> {
}
void checkLoginInfo() async {
loginInfo = await LoginApiClient().getMobileLoginInfoNEW(AppState().getIsHuawei ? AppState().getHuaweiPushToken : firebaseToken ?? "", Platform.isAndroid ? "android" : "ios");
if (loginInfo == null) {
await checkPrefs();
_autoLogin = false;
Utils.hideLoading(context);
return;
} else {
loginInfo!.deviceToken = firebaseToken;
await checkPrefs();
try {
loginInfo = await LoginApiClient().getMobileLoginInfoNEW(AppState().getIsHuawei ? AppState().getHuaweiPushToken : firebaseToken ?? "", Platform.isAndroid ? "android" : "ios");
if (loginInfo == null) {
await checkPrefs();
_autoLogin = false;
Utils.hideLoading(context);
return;
} else {
loginInfo!.deviceToken = firebaseToken;
await checkPrefs();
Utils.hideLoading(context);
performLogin();
}
} catch (ex) {
Utils.hideLoading(context);
performLogin();
}
}

@ -81,8 +81,8 @@ class MarathonScreen extends StatelessWidget {
displayLocalizedContent(
isPhoneLangArabic: AppState().isArabic(context),
selectedLanguage: provider.demoMarathonDetailModel.selectedLanguage!,
arabicContent: AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr!,
englishContent: AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn!,
arabicContent: AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr ?? "",
englishContent: AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn ?? "",
).toText22(
color: MyColors.grey3AColor,
isCentered: true,

@ -31,8 +31,10 @@ class RequestSubmitScreenParams {
String pItemId;
String approvalFlag;
String? selectedEmployeeID;
String? popNavigateToSpecificRoute;
bool isAttachmentMandatory;
RequestSubmitScreenParams(this.title, this.transactionId, this.pItemId, this.approvalFlag, {this.selectedEmployeeID});
RequestSubmitScreenParams(this.title, this.transactionId, this.pItemId, this.approvalFlag, {this.selectedEmployeeID, this.popNavigateToSpecificRoute, this.isAttachmentMandatory = false});
}
class RequestSubmitScreen extends StatefulWidget {
@ -145,8 +147,13 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
Utils.hideLoading(context);
Utils.showToast(LocaleKeys.yourRequestHasBeenSubmittedForApprovals.tr(), longDuration: true);
AppState().cancelRequestTrancsection = false;
Navigator.of(context).popUntil((route) => route.settings.name == AppRoutes.dashboard);
Navigator.pushNamed(context, AppRoutes.workList);
if (params?.popNavigateToSpecificRoute == null) {
Navigator.of(context).popUntil((route) => route.settings.name == AppRoutes.dashboard);
Navigator.pushNamed(context, AppRoutes.workList);
} else {
Navigator.of(context).popUntil((route) => route.settings.name == params!.popNavigateToSpecificRoute);
}
} catch (ex) {
Utils.hideLoading(context);
Utils.handleException(ex, context, null);
@ -174,7 +181,7 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
physics: const BouncingScrollPhysics(),
children: [
attachmentView(
LocaleKeys.attachments.tr(),
LocaleKeys.attachments.tr() + (params!.isAttachmentMandatory ? "*" : ""),
),
14.height,
InputWidget(
@ -204,6 +211,11 @@ class _RequestSubmitScreenState extends State<RequestSubmitScreen> {
DefaultButton(
LocaleKeys.submit.tr(),
() {
if (params!.isAttachmentMandatory && attachmentFiles.isEmpty) {
Utils.showToast(LocaleKeys.addAtLeastOneAttachment.tr());
return;
}
showDialog(
context: context,
builder: (cxt) => ConfirmDialog(

@ -95,7 +95,7 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
SubmitEITTransactionList submitEITTransactionList = await MyAttendanceApiClient().submitEitTransaction(dESCFLEXCONTEXTCODE, dynamicParams!.dynamicId, values, empID: dynamicParams!.selectedEmp);
Utils.hideLoading(context);
await Navigator.pushNamed(context, AppRoutes.requestSubmitScreen,
arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit'));
arguments: RequestSubmitScreenParams(LocaleKeys.submit.tr(), submitEITTransactionList.pTRANSACTIONID!, submitEITTransactionList.pITEMKEY!, 'eit',isAttachmentMandatory: dynamicParams!.isAttachmentMandatory));
if (!AppState().cancelRequestTrancsection) {
return;
}
@ -339,13 +339,6 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
}
idColName = val;
// if (getEitDffStructureList![j].fORMATTYPE == "X") {
// idColName = Utils.formatDateDefault(idColName!);
// // commenting to test
// // DateTime date = DateFormat('yyyy-MM-dd').parse(idColName!);
// // idColName = DateFormat('yyyy-MM-dd HH:mm:ss').format(date);
//
// }
if (getEitDffStructureList![j].fORMATTYPE == "X") {
idColName = Utils.reverseFormatDate(idColName!);
if(Utils.isDate(Utils.reverseFormatDate(Utils.formatDateNew(idColName!)), "yyyy-MM-dd")){
@ -532,11 +525,6 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
isEnable: false,
onTap: () async {
if ((getEitDffStructureList![index].eSERVICESDV?.pVALUECOLUMNNAME != null)) {
// if (getEitDffStructureList![index].isDefaultTypeIsCDPS) {
// selectedDate = DateFormat("yyyy/MM/dd", "en_US").parse(getEitDffStructureList![index].eSERVICESDV!.pVALUECOLUMNNAME!.replaceAll('/"', '').replaceAll(" 00:00:00", ""));
// } else {
// selectedDate = DateTime.parse(getEitDffStructureList![index].eSERVICESDV!.pVALUECOLUMNNAME!);
// }
if (getEitDffStructureList![index].isDefaultTypeIsCDPS) {
if (displayText.contains(" 00:00:00")) {
displayText = displayText.replaceAll(" 00:00:00", "");
@ -545,7 +533,6 @@ class _DynamicInputScreenState extends State<DynamicInputScreen> {
displayText = DateFormat('yyyy-MM-dd', "en_US").format(DateFormat("yyyy/MM/dd", "en_US").parse(displayText));
}
}
}
DateTime date = await _selectDate(context);
String dateString = date.toString().split(' ').first;

@ -19,12 +19,24 @@ class DynamicListViewParams {
String requestID;
String colsURL;
bool isUpdate;
String? popUntilRoute;
bool isAttachmentMandatory;
List<CollectionNotificationEit>? collectionNotificationList;
final String? selectedEmp;
DynamicListViewParams(this.title, this.dynamicId,
{this.selectedEmp, this.uRL = 'GET_EIT_DFF_STRUCTURE', this.requestID = '', this.colsURL = '', this.isUpdate = false, this.collectionNotificationList});
DynamicListViewParams(
this.title,
this.dynamicId, {
this.selectedEmp,
this.uRL = 'GET_EIT_DFF_STRUCTURE',
this.requestID = '',
this.colsURL = '',
this.isUpdate = false,
this.collectionNotificationList,
this.popUntilRoute,
this.isAttachmentMandatory = false,
});
}
class DynamicListViewScreen extends StatefulWidget {

@ -0,0 +1,74 @@
import 'package:flutter/material.dart';
import 'package:lottie/lottie.dart';
import 'package:mohem_flutter_app/models/get_notifications_response_model.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
class NotificationsDetailsPage extends StatefulWidget {
final GetNotificationsResponseModel notification;
NotificationsDetailsPage({required this.notification});
@override
State<NotificationsDetailsPage> createState() => _NotificationsDetailsPageState();
}
class _NotificationsDetailsPageState extends State<NotificationsDetailsPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBarWidget(
context,
title: "Notification Details",
),
body: ListView(
physics: BouncingScrollPhysics(),
padding: EdgeInsets.all(21),
children: [
Text(
widget.notification.createdOn!,
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
color: Color(0xff2E303A),
letterSpacing: -0.64,
),
),
if (widget.notification.messageTypeData != null)
if (widget.notification.messageTypeData!.isNotEmpty && widget.notification.notificationType != "2")
Padding(
padding: const EdgeInsets.only(top: 18),
child: Image.network(widget.notification.messageTypeData!, loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) return child;
return Center(
child: SizedBox(
width: 40.0,
height: 40.0,
child: showLoadingAnimation(),
),
);
}, fit: BoxFit.fill),
),
SizedBox(height: 18),
Text(
widget.notification.message!.trim(),
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,
color: Color(0xff575757),
letterSpacing: -0.48,
),
),
],
),
);
}
Widget showLoadingAnimation() {
return Lottie.asset(
'assets/lottie/loading.json',
repeat: true,
reverse: false,
);
}
}

@ -0,0 +1,174 @@
import 'dart:io';
import 'package:dotted_border/dotted_border.dart';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:image_picker/image_picker.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/my_documents/employee_documents_list_model.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/dynamic_forms/dynamic_textfield_widget.dart';
import 'package:mohem_flutter_app/widgets/my_document_item.dart';
import 'package:sizer/sizer.dart';
class MyDocumentDetailScreen extends StatefulWidget {
EmployeeDocumentsList document;
final Color color;
MyDocumentDetailScreen(this.document, this.color, {Key? key}) : super(key: key);
@override
_MyDocumentDetailScreenState createState() {
return _MyDocumentDetailScreenState();
}
}
class _MyDocumentDetailScreenState extends State<MyDocumentDetailScreen> {
DateTime? expiryDate;
List<XFile> imagesList = [];
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBarWidget(context, title: widget.document.dOCUMENTTYPE!, showHomeButton: true),
body: Column(
children: [
ListView(
padding: const EdgeInsets.all(21),
children: [
MyDocumentItem(widget.document, widget.color,isNotInDetailView: false),
20.height,
DynamicTextFieldWidget(
LocaleKeys.employeeNumber.tr(),
AppState().getUserName!,
isInputTypeNum: true,
isReadOnly: true,
),
12.height,
PopupMenuButton(
child: DynamicTextFieldWidget(
"Document Type*",
"National ID",
isEnable: false,
isPopup: true,
isInputTypeNum: true,
// isReadOnly: true,
),
itemBuilder: (_) => <PopupMenuItem<int>>[],
onSelected: (int popipIndex) async {}),
12.height,
DynamicTextFieldWidget(
"Expiry Date",
expiryDate == null ? LocaleKeys.dateRequired.tr() : Utils.getMonthNamedFormat(expiryDate!).replaceAll("-", " "),
suffixIconData: Icons.calendar_today,
isEnable: false,
onTap: () async {
DateTime date = await Utils.selectDate(context, expiryDate ?? DateTime.now());
String dateString = date.toString().split(' ').first;
if (date != expiryDate) {
expiryDate = date;
setState(() {});
}
},
),
12.height,
DottedBorder(
borderType: BorderType.RRect,
radius: const Radius.circular(10),
padding: const EdgeInsets.all(12),
dashPattern: const <double>[2, 1],
color: MyColors.selectedBorderColor,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Transform.rotate(
angle: 45,
child: const Icon(Icons.attach_file_rounded, size: 16, color: MyColors.selectedBorderColor),
),
4.width,
"Attach Image".toText14(color: MyColors.selectedBorderColor),
],
).center,
).onPress(() async {
ImagePicker picker = ImagePicker();
List<XFile> list = await picker.pickMultiImage();
if (list.isNotEmpty) {
imagesList.addAll(list);
var seen = <String>{};
imagesList = imagesList.where((image) => seen.add(image.name)).toList();
setState(() {});
}
}),
12.height,
GridView.builder(
padding: EdgeInsets.zero,
itemCount: imagesList.length,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) {
return Stack(
alignment: Alignment.topRight,
children: [
AspectRatio(
aspectRatio: 1,
child: Image.file(
File(imagesList[index].path),
fit: BoxFit.cover,
errorBuilder: (BuildContext context, Object error, StackTrace? stackTrace) {
return const Center(child: Text('This image type is not supported'));
},
),
).paddingOnly(top: 6, right: 6),
Container(
height: 16,
width: 16,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Color(0xffd85323),
),
child: const Icon(Icons.clear, color: Colors.white, size: 12),
).onPress(() {
imagesList.removeAt(index);
setState(() {});
}),
],
);
},
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 4,
mainAxisSpacing: 8,
crossAxisSpacing: 8,
childAspectRatio: 1,
),
)
],
).expanded,
const Divider(height: 1, color: MyColors.lightGreyEFColor),
DefaultButton(
LocaleKeys.submit.tr(),
widget.document.dOCUMENTSTATUS == "Exist" ? null : () {},
).paddingOnly(left: 21, right: 21, bottom: 21, top: 14),
],
),
);
}
}

@ -0,0 +1,165 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/profile_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/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/my_documents/employee_documents_list_model.dart';
import 'package:mohem_flutter_app/ui/my_attendance/dynamic_screens/dynamic_listview_screen.dart';
import 'package:mohem_flutter_app/ui/screens/my_documents/my_document_detail_screen.dart';
import 'package:mohem_flutter_app/widgets/my_document_item.dart';
class MyDocumentsFragment extends StatefulWidget {
List<EmployeeDocumentsList>? list;
MyDocumentsFragment(this.list, {Key? key}) : super(key: key);
@override
_MyDocumentsFragmentState createState() {
return _MyDocumentsFragmentState();
}
}
class _MyDocumentsFragmentState extends State<MyDocumentsFragment> {
int selectedIndex = 0;
List<EmployeeDocumentsList>? documentsList;
@override
void initState() {
super.initState();
documentsList = widget.list;
}
@override
void dispose() {
super.dispose();
}
@override
void didUpdateWidget(covariant MyDocumentsFragment oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.list != widget.list) {
documentsList = widget.list;
}
}
@override
Widget build(BuildContext context) {
List<EmployeeDocumentsList> documentfilteredList = getTagBySelectedTab(selectedIndex);
return Column(
children: [
GridView.count(
crossAxisSpacing: 6,
crossAxisCount: 4,
childAspectRatio: 79 / 79,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: const EdgeInsets.only(left: 21, right: 21, bottom: 11, top: 21),
children: [
gridViewItem(LocaleKeys.allDocuments.tr(), getTagBySelectedTab(0).length.toString(), 0, MyColors.darkTextColor),
gridViewItem(LocaleKeys.expiredDocuments.tr(), getTagBySelectedTab(1).length.toString(), 1, MyColors.redA3Color),
gridViewItem(LocaleKeys.missingDocuments.tr(), getTagBySelectedTab(2).length.toString(), 2, MyColors.yellowColor00),
gridViewItem(LocaleKeys.uploadedDocuments.tr(), getTagBySelectedTab(3).length.toString(), 3, MyColors.greenColor),
],
),
documentsList == null
? const SizedBox()
: (documentfilteredList.isNotEmpty
? ListView.separated(
physics: const BouncingScrollPhysics(),
padding: const EdgeInsets.only(left: 21, right: 21, bottom: 21, top: 11),
itemBuilder: (cxt, index) {
return MyDocumentItem(documentfilteredList[index], getColorByDocumentStatus(documentfilteredList[index].dOCUMENTSTATUS!)).onPress(() {
if (documentfilteredList[index].eNTITLEDTOAPPLYFLAG != 'Y') return;
Navigator.pushNamed(
context,
AppRoutes.addDynamicInput,
arguments: DynamicListViewParams(documentfilteredList[index].dOCUMENTTYPE!, documentfilteredList[index].fUNCTIONNAME!,
selectedEmp: AppState().getUserName, isAttachmentMandatory: true),
);
});
},
separatorBuilder: (cxt, index) => 12.height,
itemCount: documentfilteredList.length)
: Utils.getNoDataWidget(context).center)
.expanded,
],
);
}
Widget gridViewItem(String title, String value, int index, Color color) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 8),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, 0),
),
],
border: Border.all(color: selectedIndex == index ? MyColors.selectedBorderColor : Colors.white, width: 2),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
title.toText10(),
value.toText18(isBold: true, color: color),
],
),
).onPress(() {
setState(() {
selectedIndex = index;
});
});
}
Color getColorByDocumentStatus(String status) {
Color _color;
switch (status) {
case "Expired":
_color = MyColors.redA3Color;
break;
case "Exist":
_color = MyColors.greenColor;
break;
case "Missing":
_color = MyColors.yellowColor00;
break;
case "Not Exist":
_color = MyColors.redA3Color;
break;
default:
_color = MyColors.darkTextColor;
break;
}
return _color;
}
List<EmployeeDocumentsList> getTagBySelectedTab(int index) {
List<EmployeeDocumentsList> list = [];
switch (index) {
case 1:
list = documentsList?.where((element) => element.dOCUMENTSTATUS == "Expired").toList() ?? [];
break;
case 2:
list = documentsList?.where((element) => element.dOCUMENTSTATUS == "Missing").toList() ?? [];
break;
case 3:
list = documentsList?.where((element) => element.dOCUMENTSTATUS == "Exist").toList() ?? [];
break;
default:
list = documentsList ?? [];
break;
}
return list;
}
}

@ -0,0 +1,132 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/profile_api_client.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/my_documents/employee_documents_list_model.dart';
import 'package:mohem_flutter_app/ui/screens/my_documents/my_documents_fragment.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
class MyDocumentsScreen extends StatefulWidget {
MyDocumentsScreen({Key? key}) : super(key: key);
@override
_MyDocumentsScreenState createState() {
return _MyDocumentsScreenState();
}
}
class _MyDocumentsScreenState extends State<MyDocumentsScreen> {
int tabIndex = 0;
PageController controller = PageController();
List<EmployeeDocumentsList>? documentsList;
@override
void initState() {
super.initState();
getDocuments();
}
@override
void dispose() {
super.dispose();
}
void getDocuments() async {
try {
documentsList?.clear();
Utils.showLoading(context);
documentsList = await ProfileApiClient().getEmployeeDocuments();
Utils.hideLoading(context);
setState(() {});
} catch (ex) {
Utils.hideLoading(context);
Utils.handleException(ex, context, null);
}
}
@override
Widget build(BuildContext context) {
var requiredDocumentsList;
var optionalDocumentsList;
if (documentsList?.isNotEmpty ?? false) {
requiredDocumentsList = <EmployeeDocumentsList>[];
optionalDocumentsList = <EmployeeDocumentsList>[];
documentsList!.forEach((element) {
if (element.dOCUMENTREQUIREDSTATUS == "Required") {
requiredDocumentsList.add(element);
} else {
optionalDocumentsList.add(element);
}
});
}
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBarWidget(context, title: LocaleKeys.myDocuments.tr(), showHomeButton: true),
body: 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.requiredDocuments.tr(), 0), myTab(LocaleKeys.optionalDocuments.tr(), 1)],
),
),
PageView(
controller: controller,
physics: const NeverScrollableScrollPhysics(),
onPageChanged: (int pageIndex) {
setState(() {
tabIndex = pageIndex;
});
},
children: [MyDocumentsFragment(requiredDocumentsList), MyDocumentsFragment(optionalDocumentsList)],
).expanded,
],
),
);
}
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(() {
controller.jumpToPage(index);
}).expanded;
}
}

@ -76,70 +76,72 @@ class _MyRequestsState extends State<MyRequests> {
}),
),
12.height,
getCCPTransactionsList.isNotEmpty ? Expanded(
child: ListView.separated(
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Container(
width: double.infinity,
padding: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 12),
margin: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
("Request ID: " + getCCPTransactionsList[index].rEQUESTID.toString()).toText12(color: MyColors.grey57Color),
DateUtil.formatDateToDate(DateUtil.convertStringToDate(getCCPTransactionsList[index].rEQUESTDATE!), false).toText12(color: MyColors.grey70Color),
],
),
Container(
padding: const EdgeInsets.only(top: 10.0),
child: ("Phase: " + getCCPTransactionsList[index].cCPPHASE!).toText12(color: MyColors.grey57Color, isBold: true),
),
Container(
padding: const EdgeInsets.only(top: 10.0),
child: "Program Name: ".toText12(color: MyColors.grey57Color, isBold: true),
),
getCCPTransactionsList[index].cONCURRENTPROGRAMNAME!.toText12(color: MyColors.gradiantEndColor),
Container(
padding: const EdgeInsets.only(top: 10.0),
child: InkWell(
onTap: () {
getCCPOutput(getCCPTransactionsList[index].rEQUESTID.toString());
},
child: Row(
children: [
"Output: ".toText12(color: MyColors.grey57Color),
8.width,
"Open PDF".toText12(color: MyColors.grey57Color),
6.width,
const Icon(Icons.launch, size: 16.0),
],
),
getCCPTransactionsList.isNotEmpty
? Expanded(
child: ListView.separated(
physics: const BouncingScrollPhysics(),
shrinkWrap: true,
itemBuilder: (BuildContext context, int index) {
return Container(
width: double.infinity,
padding: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 12),
margin: const EdgeInsets.only(left: 12, right: 12, top: 10, bottom: 0),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
),
],
),
);
},
separatorBuilder: (BuildContext context, int index) => 12.height,
itemCount: getCCPTransactionsList.length),
) : Container(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
("Request ID: " + getCCPTransactionsList[index].rEQUESTID.toString()).toText12(color: MyColors.grey57Color),
DateUtil.formatDateToDate(DateUtil.convertStringToDate(getCCPTransactionsList[index].rEQUESTDATE!), false).toText12(color: MyColors.grey70Color),
],
),
Container(
padding: const EdgeInsets.only(top: 10.0),
child: ("Phase: " + getCCPTransactionsList[index].cCPPHASE!).toText12(color: MyColors.grey57Color, isBold: true),
),
Container(
padding: const EdgeInsets.only(top: 10.0),
child: "Program Name: ".toText12(color: MyColors.grey57Color, isBold: true),
),
getCCPTransactionsList[index].cONCURRENTPROGRAMNAME!.toText12(color: MyColors.gradiantEndColor),
Container(
padding: const EdgeInsets.only(top: 10.0),
child: InkWell(
onTap: () {
getCCPOutput(getCCPTransactionsList[index].rEQUESTID.toString());
},
child: Row(
children: [
"Output: ".toText12(color: MyColors.grey57Color),
8.width,
"Open PDF".toText12(color: MyColors.grey57Color),
6.width,
const Icon(Icons.launch, size: 16.0),
],
),
),
),
],
),
);
},
separatorBuilder: (BuildContext context, int index) => 12.height,
itemCount: getCCPTransactionsList.length),
)
: Container(),
],
).expanded,
1.divider,
@ -153,7 +155,9 @@ class _MyRequestsState extends State<MyRequests> {
void openNewRequest() async {
await Navigator.pushNamed(context, AppRoutes.newRequest).then((value) {
// getOpenTickets();
if (value != null && value == "refresh") {
getCCPTransactions(selectedConcurrentProgramList?.cONCURRENTPROGRAMNAME);
}
});
}

@ -5,12 +5,12 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/my_requests_api_client.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/dyanmic_forms/validate_eit_transaction_model.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/get_eit_dff_structure_list_model.dart';
import 'package:mohem_flutter_app/models/my_requests/get_ccp_transactions_model.dart';
import 'package:mohem_flutter_app/models/my_requests/get_ccp_transations_list_model.dart';
@ -118,14 +118,14 @@ class _NewRequestState extends State<NewRequest> {
return ValidateEitTransactionModel(dATEVALUE: dateVal, nAME: e.aPPLICATIONCOLUMNNAME, nUMBERVALUE: numberVal, tRANSACTIONNUMBER: 1, vARCHAR2VALUE: vatcherVal.toString()).toJson();
}).toList();
Utils.showLoading(context);
submitCcpTransactionList = await MyRequestsApiClient().getSubmitNewRequest(values);
getCCPTransactionsList = await MyRequestsApiClient().getCcpTransactions(values);
GenericResponseModel responseModel = await MyRequestsApiClient().getSubmitNewRequest(values);
Utils.hideLoading(context);
Navigator.pushNamed(
context,
AppRoutes.myRequests,
);
setState(() {});
if (responseModel.messageStatus == 1) {
Navigator.pop(context, "refresh");
} else {
Utils.showToast(responseModel.errorEndUserMessage ?? "");
}
} catch (ex) {
Utils.hideLoading(context);
Utils.handleException(ex, context, null);
@ -214,13 +214,15 @@ class _NewRequestState extends State<NewRequest> {
pIDCOLUMNNAME: DateFormat('yyyy/MM/dd HH:MM:SS', "en_US").format(date1),
pRETURNMSG: "null",
pRETURNSTATUS: getCCPDFFStructureModelList![index].dEFAULTVALUE,
pVALUECOLUMNNAME: getCCPDFFStructureModelList![index].isDefaultTypeIsCDPS ? DateFormat('yyyy/MM/dd HH:MM:SS', "en_US").format(date) : DateFormat('yyyy-MM-ddThh:mm:ss.s').format(date));
pVALUECOLUMNNAME:
getCCPDFFStructureModelList![index].isDefaultTypeIsCDPS ? DateFormat('yyyy/MM/dd HH:MM:SS', "en_US").format(date) : DateFormat('yyyy-MM-ddThh:mm:ss.s').format(date));
} else {
eservicesdv = ESERVICESDV(
pIDCOLUMNNAME: DateFormat('yyyy-MM-dd', "en_US").format(date1),
pRETURNMSG: "null",
pRETURNSTATUS: getCCPDFFStructureModelList![index].dEFAULTVALUE,
pVALUECOLUMNNAME: getCCPDFFStructureModelList![index].isDefaultTypeIsCDPS ? DateFormat('yyyy-MM-dd hh:mm:ss', "en_US").format(date) : DateFormat('yyyy-MM-ddThh:mm:ss.s').format(date));
pVALUECOLUMNNAME:
getCCPDFFStructureModelList![index].isDefaultTypeIsCDPS ? DateFormat('yyyy-MM-dd hh:mm:ss', "en_US").format(date) : DateFormat('yyyy-MM-ddThh:mm:ss.s').format(date));
}
getCCPDFFStructureModelList![index].eSERVICESDV = eservicesdv;
setState(() {});

@ -58,6 +58,7 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
List<GetPRActionHistoryList> actionHistoryList = [];
List<GetAttachementList> getAttachmentList = [];
int tabIndex = 0;
PageController controller = PageController();
@override
void initState() {
@ -136,7 +137,7 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
backgroundColor: Colors.white,
body: ListView(
padding: _screenParams!.isPRInfo ? const EdgeInsets.all(0) : const EdgeInsets.all(21),
physics: const BouncingScrollPhysics(),
physics: const NeverScrollableScrollPhysics(),
children: [
if (_screenParams!.isPRInfo) prLinesDataView(),
if (moItemHistoryList.isNotEmpty) loadMoItemHistoryData(),
@ -150,6 +151,7 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
Widget prLinesDataView() {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
padding: const EdgeInsets.only(left: 21, right: 21, top: 16, bottom: 16),
@ -177,36 +179,54 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
),
),
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(),
SizedBox(
height: MediaQuery.of(context).size.height,
child: PageView(
controller: controller,
onPageChanged: (pageIndex) {
setState(() {
tabIndex = pageIndex;
if (pageIndex == 1) {
getActionsDataFromApi();
}
if (pageIndex == 2) {
getAttachmentsDataFromApi();
}
});
},
children: [
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),
getPRActionsHistory(), //"ACTIONS".toText14().paddingOnly(top: 20, right: 21, left: 21),
getPRAttachments(),
],
),
),
],
);
}
@ -550,7 +570,8 @@ class _ItemHistoryScreenState extends State<ItemHistoryScreen> {
if (index == 2) {
getAttachmentsDataFromApi();
}
tabIndex = index;
// tabIndex = index;
controller.jumpToPage(index);
});
}).expanded;
}

@ -164,7 +164,7 @@ class InfoFragment extends StatelessWidget {
),
ItemDetailGrid(
ItemDetailViewCol(LocaleKeys.otherCharges.tr(), poHeaderList[index].oTHERCHARGES?.toString() ?? ""),
ItemDetailViewCol(LocaleKeys.totalPOAmountWithVAT.tr(), poHeaderList[index].tOTPOAMT.toString() ?? ""),
ItemDetailViewCol(LocaleKeys.totalPOAmountWithVAT.tr(), poHeaderList[index].lOCCURTOTPOAMT.toString() ?? ""),
),
ItemDetailGrid(
ItemDetailViewCol(LocaleKeys.totalPOAmountInWords.tr(), poHeaderList[index].tOTPOAMTWORD ?? ""),

@ -8,7 +8,7 @@ import 'package:mohem_flutter_app/classes/utils.dart';
class Location {
static void havePermission(Function(bool) callback) {
Geolocator.checkPermission().then((value) async {
if (value == LocationPermission.denied) {
if (value == LocationPermission.denied || value == LocationPermission.deniedForever) {
value = await Geolocator.requestPermission();
callback(![LocationPermission.denied, LocationPermission.deniedForever].contains(value));
} else {
@ -47,15 +47,6 @@ class Location {
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
}

@ -1,13 +1,11 @@
import 'dart:async';
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:geolocator/geolocator.dart';
import 'package:huawei_location/location/fused_location_provider_client.dart';
import 'package:huawei_location/location/location_request.dart';
import 'package:huawei_location/location/location_settings_request.dart';
import 'package:huawei_location/permission/permission_handler.dart';
import 'package:huawei_location/huawei_location.dart';
import 'package:mohem_flutter_app/api/dashboard_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/colors.dart';
@ -21,7 +19,7 @@ import 'package:mohem_flutter_app/provider/dashboard_provider_model.dart';
import 'package:mohem_flutter_app/ui/dialogs/success_dialog.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:mohem_flutter_app/widgets/dialogs/dialogs.dart';
import 'package:mohem_flutter_app/widgets/location/Location.dart';
import 'package:mohem_flutter_app/widgets/location/Location.dart' as location;
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';
@ -54,8 +52,6 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
}
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) {
@ -77,26 +73,61 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
}
void checkHuaweiLocationPermission(String attendanceType) async {
PermissionHandler permissionHandler = PermissionHandler();
if (await permissionHandler.hasLocationPermission()) {
getHuaweiCurrentLocation(attendanceType);
} else {
bool has = await requestPermissions();
if (has) {
getHuaweiCurrentLocation(attendanceType);
// Permission_Handler permissionHandler = PermissionHandler();
location.Location.isEnabled((bool isEnabled) async {
if (isEnabled) {
location.Location.havePermission((bool permission) async {
if (permission) {
getHuaweiCurrentLocation(attendanceType);
} else {
bool has = await requestPermissions();
if (has) {
getHuaweiCurrentLocation(attendanceType);
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give location permission to mark attendance",
onTap: () {
Navigator.pop(context);
},
),
);
}
}
});
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give location permission to mark attendance",
onTap: () {
message: "You need to enable location services to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openLocationSettings();
},
),
);
}
}
});
// if (await permissionHandler.hasLocationPermission()) {
// getHuaweiCurrentLocation(attendanceType);
// } else {
// bool has = await requestPermissions();
// if (has) {
// getHuaweiCurrentLocation(attendanceType);
// } else {
// showDialog(
// context: context,
// builder: (BuildContext cxt) => ConfirmDialog(
// message: "You need to give location permission to mark attendance",
// onTap: () {
// Navigator.pop(context);
// },
// ),
// );
// }
// }
}
Future<bool> requestPermissions() async {
@ -124,7 +155,7 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
mainAxisSize: MainAxisSize.min,
children: [
LocaleKeys.markAttendance.tr().toSectionHeading(),
LocaleKeys.selectMethodOfAttendance.tr().tr().toText11(color: const Color(0xff535353)),
LocaleKeys.selectMethodOfAttendance.tr().toText11(color: const Color(0xff535353)),
GridView(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,
@ -132,60 +163,145 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: (MediaQuery.of(context).size.width < 550) ? 3 : 5, childAspectRatio: 1 / 1, crossAxisSpacing: 8, mainAxisSpacing: 8),
children: <Widget>[
// if (isNfcEnabled)
attendanceMethod("NFC", "assets/images/nfc.svg", isNfcEnabled, () {
// if (isNfcLocationEnabled) {
if (AppState().getIsHuawei) {
checkHuaweiLocationPermission("NFC");
} else {
location.Location.isEnabled((bool isEnabled) {
if (isEnabled) {
location.Location.havePermission((bool permission) {
if (permission) {
location.Location.getCurrentLocation(
(Position position, bool isMocked) {
if (isMocked) {
markFakeAttendance("NFC", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
} else {
performNfcAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? "");
}
},
context,
);
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give location permission to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openAppSettings();
},
),
);
}
});
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to enable location services to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openLocationSettings();
},
),
);
}
});
}
}),
if (isWifiEnabled)
attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () {
if (AppState().getIsHuawei) {
checkHuaweiLocationPermission("NFC");
checkHuaweiLocationPermission("WIFI");
} else {
Location.getCurrentLocation((Position position, bool isMocked) {
if (isMocked) {
markFakeAttendance("NFC", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
location.Location.isEnabled((bool isEnabled) {
if (isEnabled) {
location.Location.havePermission((bool permission) {
if (permission) {
location.Location.getCurrentLocation(
(Position position, bool isMocked) {
if (isMocked) {
markFakeAttendance("WIFI", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
} else {
performWifiAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? "");
}
},
context,
);
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give location permission to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openAppSettings();
},
),
);
}
});
} else {
performNfcAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? "");
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to enable location services to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openLocationSettings();
},
),
);
}
}, context);
});
}
// } else {
// performNfcAttendance(widget.model);
// }
}),
if (isWifiEnabled)
attendanceMethod("Wifi", "assets/images/wufu.svg", isWifiEnabled, () {
// if (isWifiLocationEnabled) {
if (AppState().getIsHuawei) {
checkHuaweiLocationPermission("WIFI");
} else {
Location.getCurrentLocation((Position position, bool isMocked) {
if (isMocked) {
markFakeAttendance("WIFI", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
} else {
performWifiAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? "");
}
}, context);
}
// } else {
// performWifiAttendance(widget.model);
// }
}),
if (isQrEnabled)
attendanceMethod("QR", "assets/images/ic_qr.svg", isQrEnabled, () async {
// if (isQrLocationEnabled) {
if (AppState().getIsHuawei) {
checkHuaweiLocationPermission("QR");
} else {
Location.getCurrentLocation((Position position, bool isMocked) {
if (isMocked) {
markFakeAttendance("QR", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
} else {
performQrCodeAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? "");
}
}, context);
}
// } else {
// performQrCodeAttendance(widget.model);
// }
// performQrCodeAttendance(model);
if (AppState().getIsHuawei) {
checkHuaweiLocationPermission("QR");
} else {
location.Location.isEnabled((bool isEnabled) {
if (isEnabled) {
location.Location.havePermission((bool permission) {
if (permission) {
location.Location.getCurrentLocation(
(Position position, bool isMocked) {
if (isMocked) {
markFakeAttendance("QR", position.latitude.toString() ?? "", position.longitude.toString() ?? "");
} else {
performQrCodeAttendance(widget.model, lat: position.latitude.toString() ?? "", lng: position.longitude.toString() ?? "");
}
},
context,
);
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give location permission to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openAppSettings();
},
),
);
}
});
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to enable location services to mark attendance",
onTap: () async {
Navigator.pop(context);
await Geolocator.openLocationSettings();
},
),
);
}
});
}
}),
],
)
@ -194,49 +310,70 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
);
}
void getHuaweiCurrentLocation(String attendanceType) {
void getHuaweiCurrentLocation(String attendanceType) async {
try {
Utils.showLoading(context);
FusedLocationProviderClient locationService = FusedLocationProviderClient();
LocationRequest locationRequest = LocationRequest();
locationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY;
locationRequest.interval = 1000;
locationRequest.interval = 500;
List<LocationRequest> locationRequestList = <LocationRequest>[locationRequest];
LocationSettingsRequest locationSettingsRequest = LocationSettingsRequest(requests: locationRequestList);
locationService.checkLocationSettings(locationSettingsRequest).then((settings) async {
await locationService.getLastLocation().then((value) {
if (value.latitude == null || value.longitude == null) {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "Unable to get your location, Please check your location settings & try again.",
onTap: () {
Navigator.pop(context);
},
),
);
} else {
if (attendanceType == "QR") {
performQrCodeAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
}
if (attendanceType == "WIFI") {
performWifiAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
}
if (attendanceType == "NFC") {
performNfcAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
}
late StreamSubscription<Location> _streamSubscription;
int requestCode = (await (locationService.requestLocationUpdates(locationRequest)))!;
_streamSubscription = locationService.onLocationData!.listen(
(Location location) async {
Utils.hideLoading(context);
await locationService.removeLocationUpdates(requestCode);
if (attendanceType == "QR") {
performQrCodeAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? "");
}
}).catchError((error) {
print("HUAWEI LOCATION getLastLocation ERROR!!!!!");
print(error);
});
}).catchError((error) {
print("HUAWEI LOCATION checkLocationSettings ERROR!!!!!");
print(error);
if (error.code == "LOCATION_SETTINGS_NOT_AVAILABLE") {
// Location service not enabled.
}
});
if (attendanceType == "WIFI") {
performWifiAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? "");
}
if (attendanceType == "NFC") {
performNfcAttendance(widget.model, lat: location.latitude.toString() ?? "", lng: location.longitude.toString() ?? "");
}
requestCode = 0;
},
);
// locationService.checkLocationSettings(locationSettingsRequest).then((settings) async {
// await locationService.getLastLocation().then((value) {
// if (value.latitude == null || value.longitude == null) {
// showDialog(
// context: context,
// builder: (BuildContext cxt) => ConfirmDialog(
// message: "Unable to get your location, Please check your location settings & try again.",
// onTap: () {
// Navigator.pop(context);
// },
// ),
// );
// } else {
// if (attendanceType == "QR") {
// performQrCodeAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
// }
// if (attendanceType == "WIFI") {
// performWifiAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
// }
// if (attendanceType == "NFC") {
// performNfcAttendance(widget.model, lat: value.latitude.toString() ?? "", lng: value.longitude.toString() ?? "");
// }
// }
// }).catchError((error) {
// print("HUAWEI LOCATION getLastLocation ERROR!!!!!");
// print(error);
// });
// }).catchError((error) {
// print("HUAWEI LOCATION checkLocationSettings ERROR!!!!!");
// print(error);
// if (error.code == "LOCATION_SETTINGS_NOT_AVAILABLE") {
// // Location service not enabled.
// }
// });
} catch (error) {
print("HUAWEI LOCATION ERROR!!!!!");
print(error);

@ -0,0 +1,76 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.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/models/my_documents/employee_documents_list_model.dart';
import 'package:sizer/sizer.dart';
class MyDocumentItem extends StatelessWidget {
EmployeeDocumentsList document;
final Color color;
final bool isNotInDetailView;
MyDocumentItem(this.document, this.color, {Key? key,this.isNotInDetailView = true}) : super(key: key);
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: document.eNTITLEDTOAPPLYFLAG != 'Y' ? Colors.grey.shade300 : Colors.white,
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
color: const Color(0xff000000).withOpacity(.05),
blurRadius: 26,
offset: const Offset(0, -3),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(10.0),
child: Stack(
children: [
Positioned(
top: -35,
child: Container(
width: 45,
height: 45,
transform: Matrix4.rotationZ(0.8),
color: color,
),
),
Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisSize: MainAxisSize.min,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
SvgPicture.asset('assets/images/document.svg').paddingOnly(top: 6),
12.width,
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
document.dOCUMENTTYPENAME!.toText16(),
document.dOCUMENTSTATUS!.toText10(color: color),
],
).expanded,
],
).expanded,
if (isNotInDetailView)
const Icon(
Icons.arrow_forward,
size: 20,
color: Color(0xff2E303A),
)
],
).paddingOnly(top: 14, bottom: 18, right: 14, left: 24),
],
),
),
);
}
}

@ -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.0+300020
version: 3.2.991+300039
environment:
sdk: ">=2.16.0 <3.0.0"
@ -46,7 +46,7 @@ dependencies:
local_auth: ^1.1.9
fluttertoast: ^8.0.8
syncfusion_flutter_calendar: ^19.4.48
flutter_calendar_carousel: ^2.1.0
# flutter_calendar_carousel: ^2.1.0
pie_chart: ^5.1.0
shared_preferences: ^2.0.12
firebase_messaging: ^13.0.4
@ -54,36 +54,33 @@ dependencies:
logger: ^1.1.0
flutter_countdown_timer: ^4.1.0
nfc_manager: ^3.2.0
uuid: ^3.0.6
# uuid: ^3.0.6
# device_info_plus: ^4.0.0
# android_id: ^0.1.3+1
platform_device_id: ^1.0.1
image_picker: ^0.8.5+3
file_picker: ^4.6.1
# maps
google_maps_flutter: ^2.0.2
google_maps_utils: ^1.4.0+1
google_directions_api: ^0.9.0
geolocator: ^9.0.2
# flutter_compass: ^0.6.1
google_maps_flutter_web: ^0.3.2
month_year_picker: ^0.2.0+1
month_picker_dialog_2: 0.5.5
open_file: ^3.2.1
wifi_iot: ^0.3.18
flutter_html: ^3.0.0-alpha.6
# flutter_barcode_scanner: ^2.0.0
qr_code_scanner: ^1.0.0
qr_flutter: ^4.0.0
# flutter_barcode_scanner: ^2.0.0
qr_code_scanner: ^1.0.1
# qr_flutter: ^4.0.0
url_launcher: ^6.0.15
share: 2.0.4
flutter_rating_bar: ^4.0.1
auto_size_text: ^3.0.0
pull_to_refresh: ^2.0.0
# lottie json animations
# lottie json animations
lottie: any
# Marathon Card Swipe
# Marathon Card Swipe
appinio_swiper: ^1.1.1
expandable: ^5.0.1
# networkImage
# networkImage
cached_network_image: ^3.2.2
#Chat
@ -91,9 +88,9 @@ dependencies:
logging: ^1.0.1
swipe_to: ^1.0.2
flutter_webrtc: ^0.9.16
camera: ^0.10.0+4
flutter_local_notifications: any
firebase_analytics: any
camera: ^0.10.3
flutter_local_notifications: ^10.0.0
#firebase_analytics: any
#Chat Voice Message Recoding & Play
audio_waveforms: ^0.1.5+1
@ -102,11 +99,28 @@ dependencies:
#Encryption
flutter_des: ^2.1.0
video_player: ^2.4.7
video_player: ^2.5.1
just_audio: ^0.9.30
safe_device: ^1.1.2
# safe_device: ^1.1.2
flutter_layout_grid: ^2.0.1
#Huawei Dependencies
# huawei_hmsavailability: ^6.6.0+300
# huawei_location: 6.0.0+302
huawei_location: ^6.11.0+301
huawei_push: ^6.7.0+300
firebase_crashlytics: ^2.9.0
#Items for sale Image Carousel Slider
carousel_slider: ^4.2.1
#Huawei Specified
# store_checker: ^1.1.0
google_api_availability: ^3.0.1
#todo its for temporary purpose, later will remove this.
dotted_border: ^2.0.0+3
dependency_overrides:
firebase_core_platform_interface: 4.5.1

Loading…
Cancel
Save