Merge branch 'master_mohemm_flutter' into development_haroon

merge-requests/3/head
haroon amjad 2 years ago
commit cc110df55e

@ -59,12 +59,6 @@ android {
}
signingConfigs {
debug {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']

@ -12,6 +12,7 @@ import 'package:mohem_flutter_app/models/dashboard/list_menu.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/itg/itg_main_response.dart';
import 'package:mohem_flutter_app/models/itg/itg_response_model.dart';
import 'package:platform_device_id/platform_device_id.dart';
import 'package:uuid/uuid.dart';
class DashboardApiClient {
@ -111,8 +112,8 @@ class DashboardApiClient {
// Generate a v4 (random) id
Map<String, dynamic> postParams = {
// "UID": await PlatformDeviceId.getDeviceId, //uuid.v4(), //Mobile Id
"UID": uuid.v4(), //Mobile Id
"UID": await PlatformDeviceId.getDeviceId, //uuid.v4(), //Mobile Id
// "UID": uuid.v4(), //Mobile Id
"Latitude": lat,
"Longitude": long,
"QRValue": QRValue,

@ -87,8 +87,8 @@ class MarathonApiClient {
Future<int?> joinMarathonAsParticipant() async {
Map<String, String> jsonObject = <String, String>{
"employeeNumber": AppState().memberInformationList!.eMPLOYEENUMBER ?? "",
"employeeNameAr": AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr ?? "",
"employeeNameEn": AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn ?? "",
"employeeNameAr": AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr ?? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn ?? "",
"employeeNameEn": AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEEn ?? AppState().memberInformationList!.eMPLOYEEDISPLAYNAMEAr ?? "",
"marathonId": AppState().getMarathonProjectId!,
};
@ -103,7 +103,6 @@ class MarathonApiClient {
);
}
Future<QuestionModel> getNextQuestion({required String? questionId, required String marathonId}) async {
Map<String, String?> jsonObject = <String, String?>{
"previousQuestionId": questionId,

@ -47,7 +47,7 @@ class WorkListApiClient {
Map<String, dynamic> postParams = {
"P_NOTIFICATION_TYPE": pNotificationType,
"P_PAGE_NUM": pPageNum,
"P_PAGE_LIMIT": 50,
"P_PAGE_LIMIT": 20,
"P_ITEM_TYPE": pItemType,
"P_SEARCH_FROM_USER": pSearchUser,
"P_SEARCH_ITEM_TYPE_DSP_NAME": pSearchItemType,
@ -414,7 +414,7 @@ class WorkListApiClient {
"EmployeeNumber": employeeNumber,
"Comments": "",
"AdditionalFields": null,
"NewUserEMPId":newUserEMPId
"NewUserEMPId": newUserEMPId
};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
@ -590,7 +590,8 @@ class WorkListApiClient {
}, url, postParams);
}
Future<GenericResponseModel> submitComment({String? comment, String? email, String? userId, int? notificationId, required String apiMode, int? approverIndex = null}) async {
Future<GenericResponseModel> submitComment(
{String? comment, String? email, String? userId, int? notificationId, required String apiMode, int? approverIndex = null, List<Map<String, dynamic>>? attributeData = const []}) async {
String url = "${ApiConsts.erpRest}NOTIFICATION_ACTIONS";
Map<String, dynamic> postParams = {
"P_COMMENTS": comment,
@ -599,7 +600,7 @@ class WorkListApiClient {
"P_FORWARD_TO_USER_NAME": userId,
"P_NOTIFICATION_ID": notificationId,
"P_APPROVER_INDEX": approverIndex,
"RespondAttributeList": []
"RespondAttributeList": attributeData
};
postParams.addAll(AppState().postParamsJson);
return await ApiClient().postJsonForObject((json) {
@ -641,5 +642,4 @@ class WorkListApiClient {
return responseData.getPRInformationList;
}, url, postParams);
}
}

@ -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 server
// static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrlServices = baseUrl + "/Services/"; // server
// static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server
static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/";

@ -440,7 +440,7 @@ class _DashboardScreenState extends State<DashboardScreen> with WidgetsBindingOb
tag: "ItemImage" + data.getOffersList[index].offersDiscountId.toString()!,
transitionOnUserGestures: true,
child: Image.network(
data.getOffersList[index].logo!,
data.getOffersList[index].logo ?? "",
fit: BoxFit.contain,
),
),

@ -8,6 +8,7 @@ import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
// import 'package:huawei_hmsavailability/huawei_hmsavailability.dart';
import 'package:mohem_flutter_app/api/login_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart';
@ -92,9 +93,6 @@ class _LoginScreenState extends State<LoginScreen> {
super.dispose();
}
String? firebaseToken;
GetMobileLoginInfoListModel? loginInfo;
@ -103,19 +101,19 @@ class _LoginScreenState extends State<LoginScreen> {
Utils.showLoading(context);
if (Platform.isAndroid) {
try {
if (!(await Utils.isGoogleServicesAvailable())) {
print("HUAWEI APPPP GALLERYYYY!!!!");
AppState().setIsHuawei = true;
AppNotifications().initHuaweiPush(checkLoginInfo);
} else {
print("GOOGLE PLAY STOREEEE!!!!");
await Firebase.initializeApp();
_firebaseMessaging = FirebaseMessaging.instance;
firebaseToken = await _firebaseMessaging.getToken();
AppNotifications().init(firebaseToken);
checkLoginInfo();
await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
}
if (!(await Utils.isGoogleServicesAvailable())) {
print("HUAWEI APPPP GALLERYYYY!!!!");
AppState().setIsHuawei = true;
AppNotifications().initHuaweiPush(checkLoginInfo);
} else {
print("GOOGLE PLAY STOREEEE!!!!");
await Firebase.initializeApp();
_firebaseMessaging = FirebaseMessaging.instance;
firebaseToken = await _firebaseMessaging.getToken();
AppNotifications().init(firebaseToken);
checkLoginInfo();
await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
}
// });
} catch (ex) {}
} else {

@ -13,6 +13,7 @@ import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/generic_response_model.dart';
import 'package:mohem_flutter_app/models/get_action_history_list_model.dart';
import 'package:mohem_flutter_app/models/itg_forms_models/wf_history_model.dart';
import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart';
import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart';
import 'package:mohem_flutter_app/models/worklist/replacement_list_model.dart';
import 'package:mohem_flutter_app/ui/work_list/sheets/search_options_sheet.dart';
@ -29,8 +30,10 @@ class DelegateSheet extends StatefulWidget {
List<GetActionHistoryList>? actionHistoryList;
List<WFHistory>? wFHistory;
VoidCallback callBackFunc;
List<NotificationGetRespondAttributesList> getNotificationRespondAttributes;
DelegateSheet({required this.title, required this.apiMode, this.notificationID, this.actionHistoryList, this.wFHistory, required this.callBackFunc});
DelegateSheet(
{required this.title, required this.apiMode, this.notificationID, this.actionHistoryList, this.wFHistory, required this.callBackFunc, this.getNotificationRespondAttributes = const []});
@override
State<DelegateSheet> createState() => _DelegateSheetState();
@ -415,6 +418,7 @@ class _DelegateSheetState extends State<DelegateSheet> {
actionHistoryList: actionHistory,
notificationID: widget.notificationID,
isITGRequest: widget.wFHistory != null,
getNotificationRespondAttributes: widget.getNotificationRespondAttributes,
));
},
child: Row(
@ -489,6 +493,7 @@ class _DelegateSheetState extends State<DelegateSheet> {
favoriteReplacements: actionHistory,
notificationID: widget.notificationID,
isITGRequest: widget.wFHistory != null,
getNotificationRespondAttributes: widget.getNotificationRespondAttributes,
));
},
child: Row(
@ -555,6 +560,7 @@ class _DelegateSheetState extends State<DelegateSheet> {
replacementList: actionHistory,
notificationID: widget.notificationID,
isITGRequest: widget.wFHistory != null,
getNotificationRespondAttributes: widget.getNotificationRespondAttributes,
));
},
child: Row(

@ -10,10 +10,12 @@ import 'package:mohem_flutter_app/extensions/widget_extensions.dart';
import 'package:mohem_flutter_app/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/get_action_history_list_model.dart';
import 'package:mohem_flutter_app/models/member_information_list_model.dart';
import 'package:mohem_flutter_app/models/notification_get_respond_attributes_list_model.dart';
import 'package:mohem_flutter_app/models/worklist/get_favorite_replacements_model.dart';
import 'package:mohem_flutter_app/models/worklist/replacement_list_model.dart';
import 'package:mohem_flutter_app/widgets/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.dart';
import 'package:mohem_flutter_app/widgets/dialogs/accept_reject_input_dialog.dart';
import 'package:mohem_flutter_app/widgets/input_widget.dart';
class SelectedItemSheet extends StatelessWidget {
@ -23,10 +25,18 @@ class SelectedItemSheet extends StatelessWidget {
GetFavoriteReplacements? favoriteReplacements;
ReplacementList? replacementList;
MemberInformationListModel? memberInformationListModel;
List<NotificationGetRespondAttributesList> getNotificationRespondAttributes;
bool isITGRequest;
SelectedItemSheet(this.title, {required this.apiMode, this.notificationID, this.actionHistoryList, this.favoriteReplacements, this.replacementList, this.isITGRequest = false});
SelectedItemSheet(this.title,
{required this.apiMode,
this.notificationID,
this.actionHistoryList,
this.favoriteReplacements,
this.replacementList,
this.isITGRequest = false,
this.getNotificationRespondAttributes = const []});
TextEditingController username = TextEditingController();
String comment = "";
@ -103,7 +113,7 @@ class SelectedItemSheet extends StatelessWidget {
email = replacementList!.emailAddress;
userId = replacementList!.userName;
}
isITGRequest ? performITGNetworkCall(context, email: email ?? "", userId: userId ?? "") : performNetworkCall(context, email: email ?? "", userId: userId ?? "");
isITGRequest ? performITGNetworkCall(context, email: email ?? "", userId: userId ?? "") : askForConfirmation(context, email: email ?? "", userId: userId ?? "");
} else {
Utils.showToast("Please enter comments");
}
@ -121,6 +131,41 @@ class SelectedItemSheet extends StatelessWidget {
);
}
void askForConfirmation(BuildContext context, {String? email, String? userId}) {
NotificationGetRespondAttributesList? notificationNoteInput;
NotificationGetRespondAttributesList? forwardToUser;
List<NotificationGetRespondAttributesList> filtered = getNotificationRespondAttributes.where((element) => element.attributeName == "NOTE" || element.attributeName == "WF_NOTE").toList();
if (filtered.isNotEmpty) {
notificationNoteInput = filtered.first;
}
filtered = getNotificationRespondAttributes.where((element) => element.attributeName == "FORWARD_TO_USERNAME_RESPONSE").toList();
if (filtered.isNotEmpty) {
forwardToUser = filtered.first;
}
showDialog(
context: context,
builder: (cxt) => AcceptRejectInputDialog(
message: title != null ? null : LocaleKeys.requestedItems.tr(),
// title: title,
notificationGetRespond: notificationNoteInput,
actionMode: apiMode,
onTap: (note) {
performNetworkCall(context, email: email ?? "", userId: userId ?? "", attributeData: [
if ((apiMode == "FORWARD" || apiMode == "APPROVE_AND_FORWARD") && forwardToUser != null)
{"ATTRIBUTE_NAME": "FORWARD_TO_USERNAME_RESPONSE", "ATTRIBUTE_TEXT_VALUE": actionHistoryList?.uSERNAME},
if (notificationNoteInput != null)
{
"ATTRIBUTE_NAME": notificationNoteInput.attributeName,
if (notificationNoteInput.attributeType == "number") "ATTRIBUTE_NUMBER_VALUE": note else if (notificationNoteInput.attributeType == "VARCHAR2") "ATTRIBUTE_TEXT_VALUE": note
}
]);
},
),
);
}
void getUserInformation(BuildContext context) async {
String? empID = "";
if (actionHistoryList != null) empID = actionHistoryList!.uSERNAME;
@ -137,10 +182,17 @@ class SelectedItemSheet extends StatelessWidget {
}
}
Future<void> performNetworkCall(BuildContext context, {String? email, String? userId}) async {
Future<void> performNetworkCall(BuildContext context, {String? email, String? userId, List<Map<String, dynamic>>? attributeData = const []}) async {
Utils.showLoading(context);
try {
await WorkListApiClient().submitComment(comment: comment, email: email, userId: userId, notificationId: notificationID, apiMode: apiMode, approverIndex: actionHistoryList != null ? actionHistoryList!.sEQUENCE : null);
await WorkListApiClient().submitComment(
comment: comment,
email: email,
userId: userId,
notificationId: notificationID,
apiMode: apiMode,
approverIndex: actionHistoryList != null ? actionHistoryList!.sEQUENCE : null,
attributeData: attributeData);
Utils.hideLoading(context);
// Navigator.pop(context);
// Navigator.pop(context);

@ -93,10 +93,12 @@ class _WorkListScreenState extends State<WorkListScreen> {
final ScrollController _controller = ScrollController();
int pNotificationType = 1;
ScrollController? _scrollController;
@override
void initState() {
super.initState();
_scrollController = ScrollController()..addListener(_scrollListener);
providerData = Provider.of<DashboardProviderModel>(context, listen: false);
calculateCounter();
if (workListItemIndex != null) getWorkList();
@ -154,7 +156,7 @@ class _WorkListScreenState extends State<WorkListScreen> {
ItgFormsModel? itgFormsModel;
int? itgRequestTypeIndex;
Future<void> getWorkList({bool showLoading = true}) async {
Future<void> getWorkList({bool showLoading = true, bool isCallingFromRefresh = false}) async {
try {
if (showLoading) Utils.showLoading(context);
if (workListItemTypes[workListItemIndex!].key == "ITG") {
@ -173,7 +175,12 @@ class _WorkListScreenState extends State<WorkListScreen> {
}
} else {
itgRequestTypeIndex = null;
workList = await WorkListApiClient().getWorkList(pageNumber, workListItemTypes[workListItemIndex!].key, pNotificationType.toString());
List<WorkListResponseModel>? _list = await WorkListApiClient().getWorkList(pageNumber, workListItemTypes[workListItemIndex!].key, pNotificationType.toString());
if (workList != null && _list != null && !isCallingFromRefresh) {
workList!.addAll(_list);
} else {
workList = _list;
}
AppState().setWorkList = workList;
}
if (showLoading) Utils.hideLoading(context);
@ -188,9 +195,10 @@ class _WorkListScreenState extends State<WorkListScreen> {
try {
_refreshController.refreshCompleted();
Utils.showLoading(context);
pageNumber = 1;
List dataOnRefresh = await Future.wait([
providerData.fetchWorkListCounter(context, showLoading: false),
getWorkList(showLoading: false),
getWorkList(showLoading: false, isCallingFromRefresh: true),
]);
calculateCounter();
Utils.hideLoading(context);
@ -203,9 +211,19 @@ class _WorkListScreenState extends State<WorkListScreen> {
@override
void dispose() {
_scrollController?.dispose();
super.dispose();
}
void _scrollListener() {
if (_scrollController!.position.pixels == _scrollController!.position.maxScrollExtent) {
pageNumber = pageNumber + 1;
if (itgRequestTypeIndex == null && workListItemTypes[workListItemIndex!].value != workList!.length) {
getWorkList();
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
@ -236,6 +254,7 @@ class _WorkListScreenState extends State<WorkListScreen> {
}
if (workListItemIndex != index && !workListItemTypes[index].disable) {
workListItemIndex = index;
pageNumber = 1;
if (workListItemTypes[index].value == 0) {
workList = [];
itgRequestTypeIndex = null;
@ -273,6 +292,7 @@ class _WorkListScreenState extends State<WorkListScreen> {
),
controller: _refreshController,
onRefresh: _onRefresh,
scrollController: _scrollController,
child: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: itgRequestTypeIndex != null
@ -354,7 +374,6 @@ class _WorkListScreenState extends State<WorkListScreen> {
setState(() {});
}
}
} else {
verifyWorkListCounter();
if (mounted) setState(() {});

@ -449,7 +449,6 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
}
void handleFabAction(GetNotificationButtonsList notificationButton) {
print("notificationButton:${notificationButton.bUTTONACTION}");
switch (notificationButton.bUTTONACTION) {
case "DELEGATE":
showMyBottomSheet(context,
@ -526,6 +525,7 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
notificationID: workListData!.nOTIFICATIONID,
actionHistoryList: actionHistoryList,
callBackFunc: reloadWorkList,
getNotificationRespondAttributes: getNotificationRespondAttributes,
));
break;
case "FORWARD":
@ -537,8 +537,12 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
notificationID: workListData!.nOTIFICATIONID,
actionHistoryList: actionHistoryList,
callBackFunc: reloadWorkList,
getNotificationRespondAttributes: getNotificationRespondAttributes,
));
break;
case "DEL":
performAction(notificationButton.bUTTONACTION!);
break;
case "REJECT":
performAction(notificationButton.bUTTONACTION!);
break;
@ -565,6 +569,7 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
actionHistoryList: actionHistoryList.last,
notificationID: workListData!.nOTIFICATIONID,
isITGRequest: false,
getNotificationRespondAttributes: getNotificationRespondAttributes,
));
setState(() {});
} catch (ex) {
@ -656,7 +661,6 @@ class _WorkListDetailScreenState extends State<WorkListDetailScreen> {
}
void performAction(String actionMode, {String? title}) {
print(actionMode);
showDialog(
context: context,
builder: (cxt) => AcceptRejectInputDialog(

@ -55,15 +55,16 @@ class DynamicTextFieldWidget extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
labelText,
style: const TextStyle(
fontSize: 11,
fontWeight: FontWeight.w600,
color: Color(0xff2B353E),
letterSpacing: -0.44,
if (labelText.isNotEmpty)
Text(
labelText,
style: const TextStyle(
fontSize: 11,
fontWeight: FontWeight.w600,
color: Color(0xff2B353E),
letterSpacing: -0.44,
),
),
),
TextField(
enabled: isEnable,
scrollPadding: EdgeInsets.zero,

@ -234,11 +234,10 @@ class _MarkAttendanceWidgetState extends State<MarkAttendanceWidget> {
// Location service not enabled.
}
});
} catch(error) {
} catch (error) {
print("HUAWEI LOCATION ERROR!!!!!");
print(error);
}
}
Future<void> performNfcAttendance(DashboardProviderModel model, {String lat = "0", String lng = "0"}) async {

@ -89,7 +89,7 @@ dependencies:
swipe_to: ^1.0.2
flutter_webrtc: ^0.9.16
camera: ^0.10.3
flutter_local_notifications: any
flutter_local_notifications: ^10.0.0
#firebase_analytics: any
#Chat Voice Message Recoding & Play

Loading…
Cancel
Save