Merge branch 'master' into development_aamir

# Conflicts:
#	android/app/src/main/AndroidManifest.xml
#	ios/Runner.xcodeproj/project.pbxproj
#	lib/api/chat/chat_api_client.dart
#	lib/classes/consts.dart
development_aamir
Aamir Muhammad 2 years ago
commit 2f62498c66

@ -1,4 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mohem_flutter_app">
<uses-permission android:name="android.permission.INTERNET" />
@ -8,6 +9,16 @@
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<!-- Required only if your app needs to access videos
that other apps created. -->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- Required only if your app needs to access audio files
that other apps created. -->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- Chat Web RTC Calling -->
@ -27,6 +38,17 @@
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
android:roundIcon="@mipmap/ic_launcher_round">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileProvider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths"
tools:replace="android:resource" />
</provider>
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<root-path name="root" path="."/>
<external-path name="external_storage_directory" path="." />
</resources>

@ -16,7 +16,7 @@
"projects": {
"id": "b1cd3fa3-bb27-422e-a4c1-08dac09254df",
"nameEn": "Cloud Solutions",
"nameAr": "333شركة حلول السحابة للاتصالات وتقنية المعلومات",
"nameAr": "شركة حلول السحابة للاتصالات وتقنية المعلومات",
"projectCode": "CS"
},
"sponsors": [
@ -42,5 +42,6 @@
"totalQuestions": 10,
"cancelReason": null,
"marathonBufferTime": 30,
"currentTime": "2022-12-28T08:03:24.3671803Z"
"currentTime": "2022-12-28T08:03:24.3671803Z",
"displayCorrectAnswer": true
}

@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
@ -144,7 +144,6 @@
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
C4CFBC4C5CAC00182015ACD5 /* [CP] Embed Pods Frameworks */,
1C704830960BB41251F31356 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@ -204,23 +203,6 @@
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
1C704830960BB41251F31356 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
);
name = "[CP] Copy Pods Resources";
outputFileListPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
showEnvVarsInLog = 0;
};
2D06B7AD3B87C9C9059E4168 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@ -245,6 +227,7 @@
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@ -259,6 +242,7 @@
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
@ -382,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.8;
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -519,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.8;
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@ -548,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.8;
PRODUCT_BUNDLE_IDENTIFIER = com.cloudsolutions.mohemm;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";

@ -1,7 +1,9 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart';
import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
@ -27,12 +29,14 @@ class ChatApiClient {
Future<user.UserAutoLoginModel> getUserLoginToken() async {
user.UserAutoLoginModel userLoginResponse = user.UserAutoLoginModel();
String? deviceToken = AppState().getIsHuawei ? AppState().getHuaweiPushToken : AppState().getDeviceToken;
Response response = await ApiClient().postJsonForResponse(
"${ApiConsts.chatLoginTokenUrl}externaluserlogin",
{
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER.toString(),
"password": "FxIu26rWIKoF8n6mpbOmAjDLphzFGmpG",
"isMobile": true,
"platform": Platform.isIOS ? "ios" : "android",
"deviceToken": AppState().getIsHuawei ? AppState().getHuaweiPushToken : AppState().getDeviceToken,
"isHuaweiDevice": AppState().getIsHuawei,
"platform": Platform.isIOS ? "ios" : "android", // ios, android

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:mohem_flutter_app/api/api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
import 'package:mohem_flutter_app/classes/consts.dart';
@ -10,6 +12,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/mowadhafhi/get_transaction_attachment_model.dart';
class MowadhafhiApiClient {
static final MowadhafhiApiClient _instance = MowadhafhiApiClient._internal();
@ -51,6 +54,18 @@ class MowadhafhiApiClient {
}, url, postParams);
}
Future<GetTransactionAttachmentModel> getTransactionAttachments(int? attachmentID) async {
String url = "${ApiConsts.cocRest}Mohemm_ITG_GetTicketAttachment";
Map<String, dynamic> postParams = {"EmployeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER, "ItgAttachmentId": attachmentID};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel? responseData = GenericResponseModel.fromJson(json);
var jsonDecodedData = jsonDecode(responseData.mohemmITGResponseItem!);
return GetTransactionAttachmentModel.fromJson(jsonDecodedData);
}, url, postParams);
}
Future<List<GetTicketTypes>> getTicketTypes() async {
String url = "${ApiConsts.cocRest}Mohemm_ITG_GetTicketTypes";
Map<String, dynamic> postParams = {"EmployeeNumber": AppState().memberInformationList?.eMPLOYEENUMBER};

@ -24,6 +24,7 @@ import 'package:mohem_flutter_app/models/get_user_item_type_list.dart';
import 'package:mohem_flutter_app/models/itg_forms_models/itg_request_model.dart';
import 'package:mohem_flutter_app/models/member_information_list_model.dart';
import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart';
import 'package:mohem_flutter_app/models/termination/termination_notification_body.dart';
import 'package:mohem_flutter_app/models/update_user_item_type_list.dart';
import 'package:mohem_flutter_app/models/worklist/GetRFCEmployeeList.dart';
import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart';
@ -550,6 +551,22 @@ class WorkListApiClient {
}, url, postParams);
}
Future<List<TerminationNotificationBody>?> getTerminationNotificationBodyList(int? notificationId) async {
String url = "${ApiConsts.erpRest}GET_TERM_NOTIFICATION_BODY";
Map<String, dynamic> postParams = {
"P_NOTIFICATION_ID": notificationId,
"P_PAGE_LIMIT": 100,
"P_PAGE_NUM": 1,
};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
GenericResponseModel responseData = GenericResponseModel.fromJson(json);
return responseData.getTermNotificationBodyList;
}, url, postParams);
}
Future<List<GetFavoriteReplacements>?> getFavoriteReplacementWithoutImage() async {
String url = "${ApiConsts.erpRest}Mohemm_GetFavoriteReplacementsWithoutImage";
Map<String, dynamic> postParams = {};

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

@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart';
class ApiConsts {
//static String baseUrl = "http://10.200.204.20:2801/"; // Local server
// static String baseUrl = "https://erptstapp.srca.org.sa"; // SRCA server
// static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server
static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrl = "https://uat.hmgwebservices.com"; // UAT ser343622ver
// static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrlServices = baseUrl + "/Services/"; // server
// static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server
static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/";
@ -55,7 +55,6 @@ class ApiConsts {
static String marathonGetMarathonersCount = marathonBaseUrl + "Participant/GetRemainingParticipants";
//DummyCards for the UI
static CardContent dummyQuestion = const CardContent();
static int tabletMinLength = 500;
}
@ -73,3 +72,5 @@ class SharedPrefsConsts {
static String mohemmWifiPassword = "mohemmWifiPassword";
static String editItemForSale = "editItemForSale";
}

@ -30,7 +30,6 @@ class MyDecorations {
return getContainersDecoration(MyColors.greenColor);
case QuestionsOptionStatus.wrong:
return getContainersDecoration(MyColors.redColor);
case QuestionsOptionStatus.selected:
return getContainersDecoration(MyColors.yellowColorII);
case QuestionsOptionStatus.unSelected:

@ -92,6 +92,7 @@ import 'package:mohem_flutter_app/models/submit_term_transaction_list_model.dart
import 'package:mohem_flutter_app/models/subordinates_on_leaves_model.dart';
import 'package:mohem_flutter_app/models/termination/get_term_cols_structure_list_model.dart';
import 'package:mohem_flutter_app/models/termination/get_term_dff_structure_list_model.dart';
import 'package:mohem_flutter_app/models/termination/termination_notification_body.dart';
import 'package:mohem_flutter_app/models/update_item_type_success_list.dart';
import 'package:mohem_flutter_app/models/update_user_item_type_list.dart';
import 'package:mohem_flutter_app/models/vacation_rule/create_vacation_rule_list_model.dart';
@ -223,7 +224,6 @@ class GenericResponseModel {
List<String>? getOrganizationsSalariesList;
List<GetPaymentInformationList>? getPaymentInformationList;
List<GetPayslipList>? getPayslipList;
// List<String>? getPendingReqDetailsList;
// List<String>? getPendingReqFunctionsList;
List<GetPerformanceAppraisalList>? getPerformanceAppraisalList;
@ -254,7 +254,7 @@ class GenericResponseModel {
List<String>? getSwipesList;
List<GetTermColsStructureList>? getTermColsStructureList;
List<GetTermDffStructureList>? getTermDffStructureList;
List<String>? getTermNotificationBodyList;
List<TerminationNotificationBody>? getTermNotificationBodyList;
List<GetTimeCardSummaryList>? getTimeCardSummaryList;
List<GetTicketsByEmployeeList>? getTicketsByEmployeeList;
List<GetTicketDetailsByEmployee>? getTicketDetailsByEmployee;
@ -680,6 +680,7 @@ class GenericResponseModel {
successMsg = json['SuccessMsg'];
successMsgN = json['SuccessMsgN'];
vidaUpdatedResponse = json['VidaUpdatedResponse'];
if (json['AddAttSuccessList'] != null) {
addAttSuccessList = <AddAttSuccessList>[];
json['AddAttSuccessList'].forEach((v) {
@ -693,6 +694,14 @@ class GenericResponseModel {
businessCardPrivilege = json['BusinessCardPrivilege'];
calculateAbsenceDuration = json['CalculateAbsenceDuration'] != null ? new CalculateAbsenceDuration.fromJson(json['CalculateAbsenceDuration']) : null;
cancelHRTransactionLIst = json['CancelHRTransactionLIst'] != null ? new CancelHRTransactionLIst.fromJson(json['CancelHRTransactionLIst']) : null;
if (json['GetTermNotificationBodyList'] != null) {
getTermNotificationBodyList = <TerminationNotificationBody>[];
json['GetTermNotificationBodyList'].forEach((v) {
getTermNotificationBodyList!.add(TerminationNotificationBody.fromJson(v));
});
}
chatEmployeeLoginList = json['Chat_EmployeeLoginList'];
companyBadge = json['CompanyBadge'];
companyImage = json['CompanyImage'];
@ -1090,7 +1099,7 @@ class GenericResponseModel {
});
}
getTermNotificationBodyList = json['GetTermNotificationBodyList'];
if (json['GetTimeCardSummaryList'] != null) {
getTimeCardSummaryList = <GetTimeCardSummaryList>[];
@ -1612,6 +1621,9 @@ class GenericResponseModel {
data['GetNotificationReassignModeList'] = getNotificationReassignModeList!.map((v) => v.toJson()).toList();
}
if(getTermNotificationBodyList !=null){
data['GetTermNotificationBodyList'] = getTermNotificationBodyList!.map((v) => v.toJson()).toList();
}
data['GetObjectValuesList'] = this.getObjectValuesList;
data['GetOpenMissingSwipesList'] = this.getOpenMissingSwipesList;
data['GetOpenNotificationsList'] = this.getOpenNotificationsList;
@ -1688,7 +1700,6 @@ class GenericResponseModel {
data['GetTermDffStructureList'] = this.getTermDffStructureList!.map((v) => v.toJson()).toList();
}
data['GetTermNotificationBodyList'] = this.getTermNotificationBodyList;
if (this.getTimeCardSummaryList != null) {
data['GetTimeCardSummaryList'] = this.getTimeCardSummaryList!.map((v) => v.toJson()).toList();
}

@ -1,6 +1,6 @@
class CalculateAbsenceDuration {
num? pABSENCEDAYS;
num? pABSENCEHOURS;
double? pABSENCEDAYS;
double? pABSENCEHOURS;
String? pRETURNMSG;
String? pRETURNSTATUS;

@ -1,3 +1,5 @@
import 'dart:developer';
class MarathonDetailModel {
String? id;
String? titleEn;
@ -17,6 +19,7 @@ class MarathonDetailModel {
List<Questions>? questions;
int? totalQuestions;
int? marathonBufferTime;
bool? displayCorrectAnswer;
MarathonDetailModel({
id,
@ -37,6 +40,7 @@ class MarathonDetailModel {
questions,
totalQuestions,
marathonBufferTime,
displayCorrectAnswer,
});
MarathonDetailModel.fromJson(Map<String, dynamic> json) {
@ -68,6 +72,7 @@ class MarathonDetailModel {
}
totalQuestions = json["totalQuestions"];
marathonBufferTime = json["marathonBufferTime"];
displayCorrectAnswer = json["displayCorrectAnswer"];
}
Map<String, dynamic> toJson() {

@ -1,24 +1,24 @@
class GetTicketTransactions {
String? actionBy;
String? actionDate;
List<Attachments>? attachments;
String? comments;
String? statusDisplayText;
String? statusName;
String? ticketId;
int? ticketTransactionId;
GetTicketTransactions(
{this.actionBy,
this.actionDate,
this.comments,
this.statusDisplayText,
this.statusName,
this.ticketId,
this.ticketTransactionId});
GetTicketTransactions({this.actionBy, this.actionDate, this.attachments, this.comments, this.statusDisplayText, this.statusName, this.ticketId, this.ticketTransactionId});
GetTicketTransactions.fromJson(Map<String, dynamic> json) {
actionBy = json['actionBy'];
actionDate = json['actionDate'];
if (json['attachments'] != null) {
attachments = <Attachments>[];
json['attachments'].forEach((v) {
attachments!.add(new Attachments.fromJson(v));
});
}
comments = json['comments'];
statusDisplayText = json['statusDisplayText'];
statusName = json['statusName'];
@ -27,9 +27,12 @@ class GetTicketTransactions {
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
Map<String, dynamic> data = Map<String, dynamic>();
data['actionBy'] = this.actionBy;
data['actionDate'] = this.actionDate;
if (this.attachments != null) {
data['attachments'] = this.attachments!.map((v) => v.toJson()).toList();
}
data['comments'] = this.comments;
data['statusDisplayText'] = this.statusDisplayText;
data['statusName'] = this.statusName;
@ -38,3 +41,22 @@ class GetTicketTransactions {
return data;
}
}
class Attachments {
int? attachmentId;
String? fileName;
Attachments({this.attachmentId, this.fileName});
Attachments.fromJson(Map<String, dynamic> json) {
attachmentId = json['attachmentId'];
fileName = json['fileName'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = Map<String, dynamic>();
data['attachmentId'] = this.attachmentId;
data['fileName'] = this.fileName;
return data;
}
}

@ -0,0 +1,52 @@
class GetTransactionAttachmentModel {
int? attachmentId;
String? fileName;
String? contentType;
dynamic attachFileStream;
String? base64String;
dynamic isActive;
dynamic referenceItemId;
dynamic content;
dynamic filePath;
int? languageId;
GetTransactionAttachmentModel(
{this.attachmentId,
this.fileName,
this.contentType,
this.attachFileStream,
this.base64String,
this.isActive,
this.referenceItemId,
this.content,
this.filePath,
this.languageId});
GetTransactionAttachmentModel.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'];
languageId = json['languageId'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = 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;
data['languageId'] = this.languageId;
return data;
}
}

@ -0,0 +1,18 @@
class TerminationNotificationBody {
String? sEGMENTPROMPT;
String? sEGMENTVALUEDSP;
TerminationNotificationBody({this.sEGMENTPROMPT, this.sEGMENTVALUEDSP});
TerminationNotificationBody.fromJson(Map<String, dynamic> json) {
sEGMENTPROMPT = json['SEGMENT_PROMPT'];
sEGMENTVALUEDSP = json['SEGMENT_VALUE_DSP'];
}
Map<String, dynamic> toJson() {
Map<String, dynamic> data = new Map<String, dynamic>();
data['SEGMENT_PROMPT'] = this.sEGMENTPROMPT;
data['SEGMENT_VALUE_DSP'] = this.sEGMENTVALUEDSP;
return data;
}
}

@ -40,7 +40,7 @@ class _AddLeaveBalanceScreenState extends State<AddLeaveBalanceScreen> {
GetAbsenceAttendanceTypesList? selectedAbsenceType;
DateTime? startDateTime;
DateTime? endDateTime;
int? totalDays;
double? totalDays;
String comment = "";
ReplacementList? selectedReplacementEmployee;
String? selectedEmp;
@ -90,7 +90,7 @@ class _AddLeaveBalanceScreenState extends State<AddLeaveBalanceScreen> {
Utils.showLoading(context);
CalculateAbsenceDuration duration = await LeaveBalanceApiClient()
.calculateAbsenceDuration(selectedAbsenceType!.aBSENCEATTENDANCETYPEID!, Utils.getMonthNamedFormat(startDateTime!), Utils.getMonthNamedFormat(endDateTime!), -999, empID: selectedEmp);
totalDays = duration.pABSENCEDAYS?.toInt();
totalDays = duration.pABSENCEDAYS?.toDouble();
Utils.hideLoading(context);
setState(() {});
} catch (ex) {
@ -232,7 +232,7 @@ class _AddLeaveBalanceScreenState extends State<AddLeaveBalanceScreen> {
isInputTypeNum: true,
isEnable: false,
onChange: (input) {
totalDays = int.parse(input);
totalDays = double.tryParse(input);
},
),
12.height,

@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:developer';
import 'package:appinio_swiper/appinio_swiper.dart';
import 'package:easy_localization/easy_localization.dart';
@ -414,13 +415,16 @@ class MarathonProvider extends ChangeNotifier {
notifyListeners();
}
void updateCurrentQuestionOptionStatus(QuestionsOptionStatus status, int index) {
void updateCurrentQuestionOptionStatus({required QuestionsOptionStatus status, required int selectedOptIndex, required int correctOptionIndex}) {
for (int i = 0; i < currentQuestion.questionOptions!.length; i++) {
currentQuestion.questionOptions![i].optionStatus = QuestionsOptionStatus.unSelected;
}
currentQuestion.questionOptions![index].optionStatus = status;
selectedOptionId = currentQuestion.questionOptions![index].id;
selectedOptionIndex = index;
if (status == QuestionsOptionStatus.wrong) {
currentQuestion.questionOptions![correctOptionIndex].optionStatus = QuestionsOptionStatus.correct; // if person's answer is wrong we have to show him the actual right answer
}
currentQuestion.questionOptions![selectedOptIndex].optionStatus = status;
selectedOptionId = currentQuestion.questionOptions![selectedOptIndex].id;
selectedOptionIndex = selectedOptIndex;
notifyListeners();
}
@ -435,22 +439,30 @@ class MarathonProvider extends ChangeNotifier {
}
void getCorrectAnswerAndUpdateAnswerColor() {
log("correctOptionIndex");
callCountThreshold = 1;
int correctOptionIndex = -1;
if (demoMarathonDetailModel.displayCorrectAnswer ?? false) {
correctOptionIndex = currentQuestion.questionOptions!.indexWhere((QuestionOptions element) => element.isCorrectOption ?? false);
log("correctOptionIndex: $correctOptionIndex");
}
if (selectedOptionIndex != null) {
scheduleMicrotask(() async {
if (AppState().getIsDemoMarathon) {
if (currentQuestion.questionOptions![selectedOptionIndex!].isCorrectOption!) {
updateCurrentQuestionOptionStatus(QuestionsOptionStatus.correct, selectedOptionIndex!);
updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.correct, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex);
} else {
updateCurrentQuestionOptionStatus(QuestionsOptionStatus.wrong, selectedOptionIndex!);
updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.wrong, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex);
}
} else {
await callSubmitOptionApi().then((bool value) async {
updateIsUserOutOfGame = !value;
if (value) {
updateCurrentQuestionOptionStatus(QuestionsOptionStatus.correct, selectedOptionIndex!);
updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.correct, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex);
} else {
updateCurrentQuestionOptionStatus(QuestionsOptionStatus.wrong, selectedOptionIndex!);
updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.wrong, selectedOptIndex: selectedOptionIndex!, correctOptionIndex: correctOptionIndex);
}
});
}
@ -551,7 +563,6 @@ class MarathonProvider extends ChangeNotifier {
notifyListeners();
isPrivilegedWithMarathon = checkIfPrivilegedForMarathon();
demoMarathonDetailModel = await DemoMarathonRepo().getDemoMarathonDetails();
if (isPrivilegedWithMarathon) {
marathonDetailModel = await MarathonApiClient().getMarathonDetails();
updateTotalSecondsToWaitForMarathon = marathonDetailModel.marathonBufferTime ?? 30;

@ -133,7 +133,7 @@ class AnswerContent extends StatelessWidget {
if (provider.totalCurrentQuestionTime - provider.currentGapTime <= 0) {
null;
} else {
provider.updateCurrentQuestionOptionStatus(QuestionsOptionStatus.selected, index);
provider.updateCurrentQuestionOptionStatus(status: QuestionsOptionStatus.selected, selectedOptIndex: index, correctOptionIndex: -1); //
}
},
);

@ -1,3 +1,8 @@
import 'dart:convert';
import 'dart:io';
import 'dart:io' as Io;
import 'dart:typed_data';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/api/mowadhafhi/mowadhafhi_api_client.dart';
@ -6,9 +11,14 @@ 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/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/main.dart';
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_transaction_attachment_model.dart';
import 'package:mohem_flutter_app/ui/screens/mowadhafhi/view_transaction_attachment.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
import 'package:open_file/open_file.dart';
import 'package:path_provider/path_provider.dart';
class MowadhafhiRequestDetails extends StatefulWidget {
const MowadhafhiRequestDetails({Key? key}) : super(key: key);
@ -21,6 +31,9 @@ class _RequestDetailsState extends State<MowadhafhiRequestDetails> {
String? itgTicketID;
List<GetTicketDetailsByEmployee> getTicketsByEmployeeList = [];
List<GetTicketTransactions> getTicketTransactionsList = [];
GetTransactionAttachmentModel? getTransactionAttachmentModel;
late File imageFile;
@override
void initState() {
@ -43,7 +56,7 @@ class _RequestDetailsState extends State<MowadhafhiRequestDetails> {
backgroundColor: Colors.white,
appBar: AppBarWidget(
context,
title: LocaleKeys.mowadhafhiRequest.tr(),
title: LocaleKeys.mowadhafhiRequest.tr(),
),
body: SingleChildScrollView(
child: getTicketsByEmployeeList.length != 0
@ -76,16 +89,16 @@ class _RequestDetailsState extends State<MowadhafhiRequestDetails> {
],
),
8.height,
LocaleKeys.ticketReference.tr().toText12(color: MyColors.grey98Color),
LocaleKeys.ticketReference.tr().toText12(color: MyColors.grey98Color),
getTicketsByEmployeeList![0].ticketReferenceNo!.toText14(color: MyColors.grey57Color),
8.height,
LocaleKeys.section.tr().toText12(color: MyColors.grey98Color),
LocaleKeys.section.tr().toText12(color: MyColors.grey98Color),
getTicketsByEmployeeList![0].sectionName!.toText14(color: MyColors.grey57Color),
8.height,
LocaleKeys.topic.tr().toText12(color: MyColors.grey98Color),
LocaleKeys.topic.tr().toText12(color: MyColors.grey98Color),
getTicketsByEmployeeList![0].topicName!.toText14(color: MyColors.grey57Color),
8.height,
LocaleKeys.description.tr().toText12(color: MyColors.grey98Color),
LocaleKeys.description.tr().toText12(color: MyColors.grey98Color),
getTicketsByEmployeeList![0].description!.toText14(color: MyColors.grey57Color),
],
),
@ -128,15 +141,31 @@ class _RequestDetailsState extends State<MowadhafhiRequestDetails> {
Row(
children: [
LocaleKeys.actionBy.tr().toText14(color: MyColors.grey57Color),
": ".toText14(),
getTicketTransactionsList![index].actionBy!.toText14(color: MyColors.grey57Color),
],
),
Row(
children: [
LocaleKeys.actions.tr().toText14(color: MyColors.grey57Color),
": ".toText14(),
getTicketTransactionsList![index].statusDisplayText!.toText14(color: MyColors.grey57Color),
],
),
getTicketTransactionsList![index].comments!.toText14(color: MyColors.grey98Color),
12.height,
if (getTicketTransactionsList[index].attachments != null)
InkWell(
onTap: () {
print(getTicketTransactionsList[index].attachments![0].attachmentId);
getTransactionAttachment(getTicketTransactionsList[index].attachments![0].attachmentId!);
},
child: LocaleKeys.attachments.tr().toText14(color: MyColors.gradiantEndColor, isUnderLine: true),
),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
getTicketTransactionsList![0].actionDate!.split(" ")[0].toText12(color: MyColors.grey70Color),
getTicketTransactionsList![index].actionDate!.split(" ")[0].toText12(color: MyColors.grey70Color),
],
),
],
@ -212,4 +241,42 @@ class _RequestDetailsState extends State<MowadhafhiRequestDetails> {
Utils.handleException(ex, context, null);
}
}
void getTransactionAttachment(int attachmentID) async {
try {
Utils.showLoading(context);
getTransactionAttachmentModel = await MowadhafhiApiClient().getTransactionAttachments(attachmentID);
Utils.hideLoading(context);
handleTransactionAttachment();
} catch (ex) {
Utils.hideLoading(context);
Utils.handleException(ex, context, null);
}
}
Future<String> _createFileFromString(String encodedStr, String ext) async {
Uint8List bytes = base64.decode(encodedStr);
String dir = (await getApplicationDocumentsDirectory()).path;
File file = File("$dir/" + DateTime.now().millisecondsSinceEpoch.toString() + "." + ext);
await file.writeAsBytes(bytes);
return file.path;
}
void handleTransactionAttachment() async {
String ext = '';
String? rFile = getTransactionAttachmentModel!.base64String;
String? rFileExt = getTransactionAttachmentModel!.fileName;
ext = rFileExt!.split(".").last.toLowerCase();
try {
String path = await _createFileFromString(rFile!.split("base64,").last ?? "", ext ?? "");
debugPrint(path);
print(" file here: ${File(path).existsSync()}");
await OpenFile.open(path);
} catch (ex) {
Utils.showToast("Cannot open file.");
}
}
}

@ -0,0 +1,34 @@
import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:mohem_flutter_app/extensions/int_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/widgets/app_bar_widget.dart';
class ViewTransactionAttachment extends StatelessWidget {
final File imageFile;
const ViewTransactionAttachment({Key? key, required this.imageFile}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBarWidget(
context,
title: LocaleKeys.mowadhafhiRequest.tr(),
),
body: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.file(imageFile),
50.height,
],
),
),
);
}
}

@ -44,6 +44,8 @@ import 'package:mohem_flutter_app/widgets/bottom_sheet.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/dialogs/accept_reject_input_dialog.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:mohem_flutter_app/models/termination/termination_notification_body.dart';
class WorkListDetailScreen extends StatefulWidget {
WorkListDetailScreen({Key? key}) : super(key: key);
@ -80,6 +82,8 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
List<GetAbsenceCollectionNotificationBodyList>? getAbsenceCollectionNotificationBodyList = [];
GetContactNotificationBodyList? getContactNotificationBodyList;
List<GetAddressNotificationBodyList>? getAddressNotificationBodyList = [];
List<TerminationNotificationBody>? getTerminationNotificationBodyList = [];
GenericResponseModel? getBasicNTFBody;
GenericResponseModel? getICBody;
@ -121,6 +125,7 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
getItemCreationNtfBody?.itemCreationHeader!.clear();
getPhonesNotificationBodyList!.clear();
getBasicDetNtfBodyList!.clear();
getTerminationNotificationBodyList!.clear();
getAbsenceCollectionNotificationBodyList!.clear();
getContactNotificationBodyList = null;
getAddressNotificationBodyList!.clear();
@ -147,6 +152,8 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
getContactNotificationBody();
} else if (workListData!.rEQUESTTYPE == "ADDRESS") {
getAddressNotificationBody();
} else if(workListData!.rEQUESTTYPE =='TERMINATION'){
getTerminationNotificationBody();
}
}
if (workListData!.iTEMTYPE == "STAMP") {
@ -257,6 +264,7 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
getAbsenceCollectionNotificationBodyList: getAbsenceCollectionNotificationBodyList,
getContactNotificationBodyList: getContactNotificationBodyList,
getPrNotificationBodyList: getPrNotificationBody,
getTerminationNotificationBodyList:getTerminationNotificationBodyList
),
(workListData!.iTEMTYPE == "HRSSA" || workListData!.iTEMTYPE == "STAMP")
? DetailFragment(workListData, memberInformationListModel)
@ -854,6 +862,25 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
Utils.handleException(ex, context, null);
}
}
void getTerminationNotificationBody() async {
try {
if (apiCallCount == 0)
apiCallCount++;
getTerminationNotificationBodyList = await WorkListApiClient().getTerminationNotificationBodyList(workListData!.nOTIFICATIONID);
Utils.hideLoading(context);
apiCallCount--;
if (apiCallCount == 0) {
setState(() {});
}
} catch (ex) {
apiCallCount--;
Utils.hideLoading(context);
Utils.handleException(ex, context, null);
}
}
void getStampNotificationBody() async {
try {

@ -167,10 +167,14 @@ class ActionsFragment extends StatelessWidget {
Duration duration = DateTime.now().difference(dateTimeFrom);
return "Action duration: " + DateUtil.formatDuration(duration);
} else {
DateTime dateTimeTo = DateUtil.convertSimpleStringDateToDate(actionHistoryList[index].nOTIFICATIONDATE!);
DateTime dateTimeFrom = DateUtil.convertSimpleStringDateToDate(actionHistoryList[index + 1].nOTIFICATIONDATE!);
Duration duration = dateTimeTo.difference(dateTimeFrom);
return "Action duration: " + DateUtil.formatDuration(duration);
if (actionHistoryList[index + 1].nOTIFICATIONDATE!.isEmpty) {
return "";
} else {
DateTime dateTimeTo = DateUtil.convertSimpleStringDateToDate(actionHistoryList[index].nOTIFICATIONDATE!);
DateTime dateTimeFrom = DateUtil.convertSimpleStringDateToDate(actionHistoryList[index + 1].nOTIFICATIONDATE!);
Duration duration = dateTimeTo.difference(dateTimeFrom);
return "Action duration: " + DateUtil.formatDuration(duration);
}
}
}

@ -20,6 +20,8 @@ import 'package:mohem_flutter_app/models/worklist/hr/get_phones_notification_bod
import 'package:mohem_flutter_app/models/worklist_response_model.dart';
import 'package:mohem_flutter_app/widgets/item_detail_view_widget.dart';
import 'package:mohem_flutter_app/models/termination/termination_notification_body.dart';
class InfoFragment extends StatelessWidget {
WorkListResponseModel? workListData;
List<POHeader> poHeaderList;
@ -33,7 +35,7 @@ class InfoFragment extends StatelessWidget {
GetContactNotificationBodyList? getContactNotificationBodyList;
GetPrNotificationBodyList? getPrNotificationBodyList;
List<GetAddressNotificationBodyList>? getAddressNotificationBodyList = [];
List<TerminationNotificationBody>? getTerminationNotificationBodyList =[];
InfoFragment(
{this.workListData,
this.poHeaderList = const <POHeader>[],
@ -46,7 +48,9 @@ class InfoFragment extends StatelessWidget {
this.getAbsenceCollectionNotificationBodyList,
this.getContactNotificationBodyList,
this.getPrNotificationBodyList,
this.getAddressNotificationBodyList});
this.getAddressNotificationBodyList,
this.getTerminationNotificationBodyList
});
double itemHeight = 0;
double itemWidth = 0;
@ -93,6 +97,7 @@ class InfoFragment extends StatelessWidget {
if (getAbsenceCollectionNotificationBodyList?.isNotEmpty ?? false) getAbsenceCollectionNotificationBodyListWidget(getAbsenceCollectionNotificationBodyList ?? []),
if (getContactNotificationBodyList != null) getContactNotificationBodyListWidget(getContactNotificationBodyList ?? GetContactNotificationBodyList()).objectContainerView(),
if (getAddressNotificationBodyList?.isNotEmpty ?? false) getAddressNotificationBodyListWidget(getAddressNotificationBodyList!),
if (getTerminationNotificationBodyList?.isNotEmpty ?? false) getTerminationNotificationBodyListWidget(getTerminationNotificationBodyList!),
];
return Container(
width: double.infinity,
@ -499,6 +504,39 @@ class InfoFragment extends StatelessWidget {
).objectContainerView();
}
Widget getTerminationNotificationBodyListWidget(List<TerminationNotificationBody> getterminationNotificationBodyList) {
bool isOdd = false;
try {
if (getterminationNotificationBodyList.length % 2 != 0) {
isOdd = true;
getterminationNotificationBodyList.add(TerminationNotificationBody(sEGMENTPROMPT: "--", sEGMENTVALUEDSP: "--"));
}
} catch (e) {}
return GridView.builder(
itemCount: getterminationNotificationBodyList!.length,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (context, index) => ItemDetailViewGridItem(
index,
getterminationNotificationBodyList[index].sEGMENTPROMPT,
getterminationNotificationBodyList[index].sEGMENTVALUEDSP,
isNeedToShowEmptyDivider: (getterminationNotificationBodyList.length == index + 1)
? isOdd
? true
: false
: false,
),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
childAspectRatio: (itemWidth / itemHeight),
),
).objectContainerView();
}
List<Widget> getPRHeaderValues() {
List<Widget> pRHeaders = [];
getPrNotificationBodyList!.pRHeader!.forEach((element) {

@ -8,6 +8,8 @@ import 'package:mohem_flutter_app/classes/colors.dart';
import 'package:mohem_flutter_app/extensions/string_extensions.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheet.dart';
import 'package:mohem_flutter_app/widgets/bottom_sheets/attachment_options.dart';
import 'package:mohem_flutter_app/widgets/dialogs/confirm_dialog.dart';
import 'package:permission_handler/permission_handler.dart';
class ImageOptions {
static void showImageOptionsNew(BuildContext context, bool showFilesOption, Function(String, File) image) {
@ -43,24 +45,42 @@ class ImageOptions {
}
},
onFilesTap: () async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: [
'jpg',
'jpeg ',
'pdf',
'txt',
'docx',
'doc',
'pptx',
'xlsx',
'png',
'rar',
'zip',
],
);
List<File> files = result!.paths.map((path) => File(path!)).toList();
image(result.files.first.path.toString(), files.first);
Permission.storage.isGranted.then((isGranted) {
if (!isGranted) {
Permission.manageExternalStorage.request().then((granted) async {
if (granted == PermissionStatus.granted) {
FilePickerResult? result = await FilePicker.platform.pickFiles(
type: FileType.custom,
allowedExtensions: [
'jpg',
'jpeg ',
'pdf',
'txt',
'docx',
'doc',
'pptx',
'xlsx',
'png',
'rar',
'zip',
],
);
List<File> files = result!.paths.map((path) => File(path!)).toList();
image(result.files.first.path.toString(), files.first);
} else {
showDialog(
context: context,
builder: (BuildContext cxt) => ConfirmDialog(
message: "You need to give storage permission to upload files.",
onTap: () {
Navigator.pop(context);
},
),
);
}
});
}
});
},
),
);

@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
#version: 3.3.01+300040
version: 3.7.7+1
version: 3.3.6+300046
environment:
sdk: ">=2.16.0 <3.0.0"
@ -60,7 +60,7 @@ dependencies:
# android_id: ^0.1.3+1
platform_device_id: ^1.0.1
image_picker: ^0.8.5+3
file_picker: ^4.6.1
file_picker: 5.2.5
geolocator: ^9.0.2
month_year_picker: any
month_picker_dialog: ^2.0.2
@ -128,6 +128,8 @@ dependencies:
in_app_update: 3.0.0
flutter_ios_voip_kit: ^0.1.0
# saf: ^1.0.3+4
dependency_overrides:
firebase_core_platform_interface: 4.5.1

Loading…
Cancel
Save