Merge branch 'development_sikander' into 'master'

Development sikander

See merge request Cloud_Solution/mohemm-flutter-app!182
merge-requests/183/head
Sikander Saleem 3 years ago
commit 5bc20f84e2

@ -59,12 +59,6 @@ android {
} }
signingConfigs { signingConfigs {
debug {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword']
}
release { release {
keyAlias keystoreProperties['keyAlias'] keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword'] keyPassword keystoreProperties['keyPassword']
@ -73,6 +67,9 @@ android {
} }
} }
buildTypes { buildTypes {
debug {
signingConfig signingConfigs.debug
}
release { release {
signingConfig signingConfigs.release signingConfig signingConfigs.release
minifyEnabled true minifyEnabled true

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

@ -3,8 +3,8 @@ import 'package:mohem_flutter_app/ui/marathon/widgets/question_card.dart';
class ApiConsts { class ApiConsts {
//static String baseUrl = "http://10.200.204.20:2801/"; // Local server //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://erptstapp.srca.org.sa"; // SRCA server
// static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server static String baseUrl = "https://uat.hmgwebservices.com"; // UAT server
static String baseUrl = "https://hmgwebservices.com"; // Live server // static String baseUrl = "https://hmgwebservices.com"; // Live server
static String baseUrlServices = baseUrl + "/Services/"; // server static String baseUrlServices = baseUrl + "/Services/"; // server
// static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server // static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server
static String utilitiesRest = baseUrlServices + "Utilities.svc/REST/"; 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()!, tag: "ItemImage" + data.getOffersList[index].offersDiscountId.toString()!,
transitionOnUserGestures: true, transitionOnUserGestures: true,
child: Image.network( child: Image.network(
data.getOffersList[index].logo!, data.getOffersList[index].logo ?? "",
fit: BoxFit.contain, fit: BoxFit.contain,
), ),
), ),

@ -8,6 +8,7 @@ import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
// import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; // import 'package:huawei_hmsavailability/huawei_hmsavailability.dart';
import 'package:mohem_flutter_app/api/login_api_client.dart'; import 'package:mohem_flutter_app/api/login_api_client.dart';
import 'package:mohem_flutter_app/app_state/app_state.dart'; import 'package:mohem_flutter_app/app_state/app_state.dart';
@ -92,9 +93,6 @@ class _LoginScreenState extends State<LoginScreen> {
super.dispose(); super.dispose();
} }
String? firebaseToken; String? firebaseToken;
GetMobileLoginInfoListModel? loginInfo; GetMobileLoginInfoListModel? loginInfo;

@ -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/generic_response_model.dart';
import 'package:mohem_flutter_app/models/get_action_history_list_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/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/get_favorite_replacements_model.dart';
import 'package:mohem_flutter_app/models/worklist/replacement_list_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'; 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<GetActionHistoryList>? actionHistoryList;
List<WFHistory>? wFHistory; List<WFHistory>? wFHistory;
VoidCallback callBackFunc; 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 @override
State<DelegateSheet> createState() => _DelegateSheetState(); State<DelegateSheet> createState() => _DelegateSheetState();
@ -415,6 +418,7 @@ class _DelegateSheetState extends State<DelegateSheet> {
actionHistoryList: actionHistory, actionHistoryList: actionHistory,
notificationID: widget.notificationID, notificationID: widget.notificationID,
isITGRequest: widget.wFHistory != null, isITGRequest: widget.wFHistory != null,
getNotificationRespondAttributes: widget.getNotificationRespondAttributes,
)); ));
}, },
child: Row( child: Row(
@ -489,6 +493,7 @@ class _DelegateSheetState extends State<DelegateSheet> {
favoriteReplacements: actionHistory, favoriteReplacements: actionHistory,
notificationID: widget.notificationID, notificationID: widget.notificationID,
isITGRequest: widget.wFHistory != null, isITGRequest: widget.wFHistory != null,
getNotificationRespondAttributes: widget.getNotificationRespondAttributes,
)); ));
}, },
child: Row( child: Row(
@ -555,6 +560,7 @@ class _DelegateSheetState extends State<DelegateSheet> {
replacementList: actionHistory, replacementList: actionHistory,
notificationID: widget.notificationID, notificationID: widget.notificationID,
isITGRequest: widget.wFHistory != null, isITGRequest: widget.wFHistory != null,
getNotificationRespondAttributes: widget.getNotificationRespondAttributes,
)); ));
}, },
child: Row( 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/generated/locale_keys.g.dart';
import 'package:mohem_flutter_app/models/get_action_history_list_model.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/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/get_favorite_replacements_model.dart';
import 'package:mohem_flutter_app/models/worklist/replacement_list_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/button/default_button.dart';
import 'package:mohem_flutter_app/widgets/circular_avatar.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'; import 'package:mohem_flutter_app/widgets/input_widget.dart';
class SelectedItemSheet extends StatelessWidget { class SelectedItemSheet extends StatelessWidget {
@ -23,10 +25,18 @@ class SelectedItemSheet extends StatelessWidget {
GetFavoriteReplacements? favoriteReplacements; GetFavoriteReplacements? favoriteReplacements;
ReplacementList? replacementList; ReplacementList? replacementList;
MemberInformationListModel? memberInformationListModel; MemberInformationListModel? memberInformationListModel;
List<NotificationGetRespondAttributesList> getNotificationRespondAttributes;
bool isITGRequest; 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(); TextEditingController username = TextEditingController();
String comment = ""; String comment = "";
@ -103,7 +113,7 @@ class SelectedItemSheet extends StatelessWidget {
email = replacementList!.emailAddress; email = replacementList!.emailAddress;
userId = replacementList!.userName; 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 { } else {
Utils.showToast("Please enter comments"); 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").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 { void getUserInformation(BuildContext context) async {
String? empID = ""; String? empID = "";
if (actionHistoryList != null) empID = actionHistoryList!.uSERNAME; 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); Utils.showLoading(context);
try { 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); Utils.hideLoading(context);
// Navigator.pop(context); // Navigator.pop(context);
// Navigator.pop(context); // Navigator.pop(context);

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

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

@ -55,6 +55,7 @@ class DynamicTextFieldWidget extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (labelText.isNotEmpty)
Text( Text(
labelText, labelText,
style: const TextStyle( style: const TextStyle(

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

Loading…
Cancel
Save