Merge remote-tracking branch 'origin/design_3.0_asset_delivery_module' into design_3.0_asset_delivery_module

design_3.0_asset_delivery_module
WaseemAbbasi22 2 days ago
commit bf4d2a3257

@ -1,12 +1,11 @@
class URLs {
URLs._();
static const String appReleaseBuildNumber = "31";
static const String appReleaseBuildNumber = "32";
// static const host1 = "https://atomsm.hmg.com"; // production url
// static const host1 = "https://atomsmdev.hmg.com"; // local DEV url
static const host1 = "https://atomsmuat.hmg.com"; // local UAT url
// static const host1 = "http://10.201.111.125:9495"; // temporary Server UAT url
// static String _baseUrl = "$_host/mobile";
@ -20,6 +19,7 @@ class URLs {
static const String chatHubUrlApi = "$chatHubUrl/api"; // new V2 apis
static const String chatHubUrlChat = "$chatHubUrl/hubs/chat"; // new V2 apis
static const String resetMessageCount = "$chatHubUrlApi/userChatHistory/AckMessages"; // new V2 apis
static const String chatApiKey = "f53a98286f82798d588f67a7f0db19f7aebc839e"; // new V2 apis
static String _host = host1;

@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
@ -13,6 +14,7 @@ import 'package:test_sa/modules/cx_module/survey/survey_page.dart';
import 'package:test_sa/modules/pm_module/ppm_wo/ppm_details_page.dart';
import 'package:test_sa/modules/pm_module/recurrent_wo/recurrent_work_order_view.dart';
import 'package:test_sa/modules/tm_module/device_transfer/device_transfer_details.dart';
import 'package:test_sa/modules/tm_module/tasks/task_request_detail_view.dart';
import 'package:test_sa/modules/tm_module/gas_refill/gas_refill_details.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
@ -88,6 +90,44 @@ class FirebaseNotificationManger {
String? transactionType = messageData["transactionType"]?.toString();
if (transactionType == null) {
return;
} else if (transactionType == "17" && messageData["requestType"] == "chat") {
int moduleId = int.parse(messageData["moduleId"].toString());
int requestNumber = int.parse(messageData["requestNumber"].toString());
switch (moduleId) {
case 1: // cm
serviceClass = CMDetailPage(requestId: requestNumber, moduleId: moduleId);
break;
case 2: // gas refill
serviceClass = GasRefillDetailsPage(
priority: messageData["priority"],
date: messageData["createdOn"],
moduleId: moduleId,
model: GasRefillModel(id: requestNumber),
);
break;
case 3: //transfer
serviceClass = DeviceTransferDetails(model: DeviceTransfer(id: requestNumber), moduleId: moduleId);
break;
case 6: // task
serviceClass = TaskRequestDetailsView(
taskId: requestNumber,
moduleId: moduleId,
// requestDetails: RequestsDetails(nameOfType: requestData?.nameOfType, status: requestData?.statusName, priority: requestData?.priorityName, date: requestData?.transactionDate, ),
);
// ServiceRequestDetailMain(requestId: int.parse(messageData["requestNumber"].toString()), moduleId: 1);
break;
default:
serviceClass = const Scaffold(body: Center(child: NoDataFound()));
}
Navigator.of(context).push(MaterialPageRoute(builder: (_) => serviceClass!));
return;
}
// PPM=1,
// ServiceRequestEngineer = 3,
// AssetTransfer=7,
@ -101,13 +141,13 @@ class FirebaseNotificationManger {
break;
//these three request are same corrective maintenance....
case "3":
serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString()));
serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString()), moduleId: 1);
break;
case "8":
serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString()));
serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString()), moduleId: 1);
break;
case "11":
serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString()));
serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString()), moduleId: 1);
break;
case "7":
serviceClass = DeviceTransferDetails(model: DeviceTransfer(id: int.parse(messageData["requestNumber"].toString())), moduleId: 3);

@ -73,14 +73,14 @@ class _DashboardViewState extends State<DashboardView> {
// await requestDetailProvider.engineerRejectWorkOrder(id: '3', feedBack: 'Abcdef');
// await dashBoardProvider.getDashBoardCount(usersType: user.type!);
// await getAllRequests();
if (isFCM) {
FirebaseNotificationManger.initialized(context);
NotificationManger.initialisation((notificationDetails) {
FirebaseNotificationManger.handleMessage(context, json.decode(notificationDetails.payload!));
}, (id, title, body, payload) async {});
isFCM = false;
}
// if (isFCM) {
// FirebaseNotificationManger.initialized(context);
// NotificationManger.initialisation((notificationDetails) {
// FirebaseNotificationManger.handleMessage(context, json.decode(notificationDetails.payload!));
// }, (id, title, body, payload) async {});
//
// isFCM = false;
// }
});
}

@ -136,6 +136,7 @@ import 'providers/service_request_providers/reject_reason_provider.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setEnabledSystemUIMode(SystemUiMode.edgeToEdge);
// HttpOverrides.global = MyHttpOverrides(); // for later use.
_configureLocalTimeZone();
NotificationManger.initialisation((notificationDetails) {}, (id, title, body, payload) async {});

@ -12,6 +12,7 @@ class User {
List<String>? departmentName;
String? message;
String? username;
String? employeeId;
String? userID;
String? email;
String? password;
@ -53,6 +54,7 @@ class User {
this.departmentName,
this.message,
this.username,
this.employeeId,
this.userID,
this.email,
this.password,
@ -151,6 +153,7 @@ class User {
map['message'] = message;
map['username'] = username;
map['userID'] = userID;
map['employeeId'] = employeeId;
map['email'] = email;
map['password'] = password;
map['token'] = token;
@ -212,6 +215,7 @@ class User {
message = json['message'];
username = json['username'];
userID = json['userID'];
employeeId = json['employeeId'];
email = json['email'];
password = json['password'];
token = json['token'];

@ -13,6 +13,7 @@ import 'package:test_sa/modules/cm_module/cm_detail_provider.dart';
import 'package:test_sa/modules/cm_module/views/components/bottom_sheets/service_request_bottomsheet.dart';
import 'package:test_sa/modules/cx_module/chat/chat_page.dart';
import 'package:test_sa/modules/cx_module/chat/chat_provider.dart';
import 'package:test_sa/modules/cx_module/chat/chat_widget.dart';
import 'package:test_sa/modules/cx_module/survey/survey_page.dart';
import 'package:test_sa/modules/loan_module/pages/create_loan_request_page.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
@ -23,8 +24,9 @@ import 'views/components/service_request_detail_view.dart';
class CMDetailPage extends StatefulWidget {
final int requestId;
final int moduleId;
CMDetailPage({Key? key, required this.requestId}) : super(key: key);
CMDetailPage({Key? key, required this.requestId, required this.moduleId}) : super(key: key);
@override
_CMDetailPageState createState() {
@ -40,6 +42,7 @@ class _CMDetailPageState extends State<CMDetailPage> {
@override
void initState() {
super.initState();
_requestProvider = Provider.of<CMDetailProvider>(context, listen: false);
WidgetsBinding.instance.addPostFrameCallback((_) {
Provider.of<ChatProvider>(context, listen: false).reset();
getInitialData();
@ -89,85 +92,46 @@ class _CMDetailPageState extends State<CMDetailPage> {
Navigator.pop(context);
},
actions: [
if (context.userProvider.isEngineer || context.userProvider.isNurse)
Selector<CMDetailProvider, bool>(
selector: (_, myModel) => myModel.isLoading, // Selects only the userName
builder: (_, isLoading, __) {
if (isLoading) {
return const SizedBox();
} else {
CMDetailProvider provider = Provider.of<CMDetailProvider>(context, listen: false);
int? statusValue = provider.currentWorkOrder?.data?.status?.value;
if (statusValue == 2 || statusValue == 3 || statusValue == 5 || statusValue == 6) {
getChatToken(moduleId, provider.currentWorkOrder?.data?.workOrderNo ?? "");
return Consumer<ChatProvider>(builder: (pContext, requestProvider, _) {
return IconButton(
icon: const Icon(Icons.chat_bubble),
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => ChatPage(
moduleId: moduleId,
requestId: widget.requestId,
title: _requestProvider.currentWorkOrder?.data?.workOrderNo ?? "",
readOnly: _requestProvider.isReadOnlyRequest,
)));
},
).toShimmer(context: context, isShow: requestProvider.chatLoginTokenLoading, radius: 30, height: 30, width: 30);
});
}
return const SizedBox();
}
}),
if (isNurse)
IconButton(
icon: 'qr'.toSvgAsset(height: 24, width: 24),
onPressed: () {
ServiceRequestBottomSheet.getQRCodeBottomSheet(context: context);
},
)
else ...[
Selector<CMDetailProvider, bool>(
selector: (_, myModel) => myModel.isLoading, // Selects only the userName
builder: (_, isLoading, __) {
if (isLoading) {
return const SizedBox();
} else {
CMDetailProvider provider = Provider.of<CMDetailProvider>(context, listen: false);
int? statusValue = provider.currentWorkOrder?.data?.status?.value;
if (statusValue == 2) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 6),
margin: const EdgeInsets.only(left: 2),
decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.neutral30, borderRadius: BorderRadius.circular(16)),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.add, size: 20, color: AppColor.black1E),
Text(
"Loan",
style: AppTextStyles.bodyText2.copyWith(color: AppColor.black1E),
),
4.width,
],
),
).onPress(() {
CMDetailProvider provider = Provider.of<CMDetailProvider>(context, listen: false);
Navigator.push(context, MaterialPageRoute(builder: (context) => CreateLoanRequestPage(workOrderId: widget.requestId, workOrder: provider.currentWorkOrder!.data)));
});
}
return const SizedBox();
Selector<CMDetailProvider, bool>(
selector: (_, myModel) => myModel.isLoading, // Selects only the userName
builder: (_, isLoading, __) {
if (isLoading) {
return const SizedBox();
} else {
CMDetailProvider provider = Provider.of<CMDetailProvider>(context, listen: false);
if ((context.userProvider.isEngineer || context.userProvider.isNurse) &&
provider.currentWorkOrder?.data?.assignedEmployee != null &&
(provider.currentWorkOrder?.data?.workOrderContactPerson?.isNotEmpty ?? false)) {
return ChatWidget(
moduleId: widget.moduleId,
isShow: context.settingProvider.isUserFlowMedical && (context.userProvider.isEngineer || context.userProvider.isNurse) && provider.currentWorkOrder?.data?.assignedEmployee != null,
isReadOnly: _requestProvider.isReadOnlyRequest,
requestId: widget.requestId.toInt(),
assigneeEmployeeNumber: provider.currentWorkOrder?.data?.assignedEmployee!.employeeId!,
myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!,
contactEmployeeINumber: provider.currentWorkOrder?.data?.workOrderContactPerson.first.employeeId,
);
}
}),
IconButton(
icon: const Icon(Icons.home),
onPressed: () {
// stopTimer();
Navigator.pop(context);
},
)
],
return const SizedBox();
}
}),
isNurse
? IconButton(
icon: 'qr'.toSvgAsset(
height: 24,
width: 24,
),
onPressed: () {
ServiceRequestBottomSheet.getQRCodeBottomSheet(context: context);
},
)
: IconButton(
icon: const Icon(Icons.home),
onPressed: () {
// stopTimer();
Navigator.pop(context);
},
),
],
),
body: DefaultTabController(

@ -300,7 +300,7 @@ class _CreateCMRequestState extends State<CreateCMRequest> with TickerProviderSt
bool checkPendingRequest = false;
void showPendingRequests() {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => PendingServiceRequestScreen(pendingAssetServiceRequest!)));
Navigator.of(context).push(MaterialPageRoute(builder: (_) => PendingServiceRequestScreen(pendingAssetServiceRequest!, 1)));
}
void showPendingRequestBottomSheet() async {

@ -35,6 +35,7 @@ import 'model/user_chat_history_model.dart';
// import 'package:mohem_flutter_app/models/chat/get_user_login_token_model.dart' as user;
// import 'package:mohem_flutter_app/models/chat/make_user_favotire_unfavorite_chat_model.dart' as fav;
//Need to refector this remove unused code.
class ChatApiClient {
static final ChatApiClient _instance = ChatApiClient._internal();
@ -81,8 +82,9 @@ class ChatApiClient {
}
Future<ChatParticipantModel?> loadParticipants(int moduleId, int referenceId, String? assigneeEmployeeNumber) async {
Response response =
await ApiClient().getJsonForResponse("${URLs.chatHubUrlApi}/chat/context/$moduleId/$referenceId?assigneeEmployeeNumber=$assigneeEmployeeNumber", token: chatLoginResponse!.token);
Response response = await ApiClient().getJsonForResponse(
"${URLs.chatHubUrlApi}/chat/context/$moduleId/$referenceId?assigneeEmployeeNumber=$assigneeEmployeeNumber&requestType=chat&transactionType=17",
token: chatLoginResponse!.token);
if (!kReleaseMode) {
// logger.i("login-res: " + response.body);
@ -94,6 +96,20 @@ class ChatApiClient {
}
}
Future<bool> resetCountApi(int moduleCode, int referenceNumber, String? employeeNumber) async {
final Map<String, dynamic> payload = {
'moduleCode': "$moduleCode",
'ReferenceNumber': "$referenceNumber",
};
final Response response = await ApiClient().postJsonForResponse(
URLs.resetMessageCount,
payload,
token: chatLoginResponse!.token,
);
return response.statusCode == 200;
}
Future<List<ChatAttachment>> viewAllDocuments(int moduleId, int referenceId) async {
Response response = await ApiClient().getJsonForResponse("${URLs.chatHubUrlApi}/attachments/conversation?referenceId=$referenceId&moduleCode=$moduleId", token: chatLoginResponse!.token);

@ -1,4 +1,5 @@
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:audio_waveforms/audio_waveforms.dart';
@ -29,6 +30,7 @@ import 'helper/chat_file_viewer.dart';
import 'model/get_single_user_chat_list_model.dart';
import 'model/user_chat_history_model.dart';
//Need to refactor this ...
enum ChatState { idle, voiceRecordingStarted, voiceRecordingCompleted }
class ChatPage extends StatefulWidget {
@ -66,7 +68,10 @@ class _ChatPageState extends State<ChatPage> {
@override
void initState() {
super.initState();
loadChatHistory();
WidgetsBinding.instance.addPostFrameCallback((_) {
loadChatHistory();
});
playerController.addListener(() async {
// if (playerController.playerState == PlayerState.playing && playerController.maxDuration == await playerController.getDuration()) {
// await playerController.stopPlayer();
@ -75,7 +80,7 @@ class _ChatPageState extends State<ChatPage> {
});
}
void loadChatHistory() {
void loadChatHistory() async {
// // String assigneeEmployeeNumber = Provider.of<ServiceRequestDetailProvider>(context, listen: false).currentWorkOrder?.data?.assignedEmployee?.employeeId ?? "";
// // String myEmployeeId = context.userProvider.user!.username!;
// //
@ -99,7 +104,14 @@ class _ChatPageState extends State<ChatPage> {
? Provider.of<CMDetailProvider>(context, listen: false).currentWorkOrder!.data!.workOrderCreatedBy!.employeeId!
: Provider.of<CMDetailProvider>(context, listen: false).currentWorkOrder!.data!.workOrderContactPerson.first.employeeId!))
: "");
Provider.of<ChatProvider>(context, listen: false).connectToHub(widget.moduleId, widget.requestId, myEmployeeId, receiver, widget.readOnly, isMounted: mounted);
final chatProvider = context.read<ChatProvider>();
// final chatProvider = Provider.of<C;
chatProvider.connectToHub(widget.moduleId, widget.requestId, myEmployeeId, receiver, widget.readOnly, isMounted: mounted);
bool readStatus = await chatProvider.resetCount(moduleId: widget.moduleId, referenceNo: widget.requestId, userId: context.userProvider.user?.id);
if (readStatus) {
chatProvider.chatParticipantModel?.unreadCount = 0;
}
}
@override
@ -231,7 +243,9 @@ class _ChatPageState extends State<ChatPage> {
}
return Column(mainAxisSize: MainAxisSize.min, children: [
if (showDateHeader) dateCard(currentMessage.createdDate?.toString().chatMsgDateWithYear ?? ""),
isSender ? senderMsgCard(showSenderName, chatProvider.chatResponseList[index]) : recipientMsgCard(showSenderName, chatProvider.chatResponseList[index])
isSender
? senderMsgCard(showSenderName, chatProvider.chatResponseList[index], index: index)
: recipientMsgCard(showSenderName, chatProvider.chatResponseList[index])
]);
},
itemCount: chatProvider.chatResponseList.length))
@ -607,7 +621,7 @@ class _ChatPageState extends State<ChatPage> {
.center;
}
Widget senderMsgCard(bool showHeader, SingleUserChatModel? chatResponse, {bool loading = false, String msg = ""}) {
Widget senderMsgCard(bool showHeader, SingleUserChatModel? chatResponse, {bool loading = false, String msg = "", int index = 0}) {
Widget senderHeader = Row(
mainAxisSize: MainAxisSize.min,
children: [

@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'dart:typed_data';
import 'package:audio_waveforms/audio_waveforms.dart';
@ -40,6 +41,7 @@ import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:signalr_netcore/hub_connection.dart';
import 'package:signalr_netcore/signalr_client.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/modules/cx_module/chat/model/chat_login_response_model.dart';
@ -54,6 +56,8 @@ import 'model/get_single_user_chat_list_model.dart';
import 'model/user_chat_history_model.dart';
// import 'get_single_user_chat_list_model.dart';
//Need to refactor this remove unused code.
HubConnection? chatHubConnection;
class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin {
@ -248,6 +252,9 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin {
chatHubConnection!.on("OnSubmitChatAsync", OnSubmitChatAsync);
chatHubConnection!.on("OnTypingAsync", OnTypingAsync);
chatHubConnection!.on("OnStopTypingAsync", OnStopTypingAsync);
//Need by Chat Backend for seen and un seen.
chatHubConnection!.on("OnSeenChatUserAsync", onSeenUserChatAsync);
chatHubConnection!.on("OnAckSeenAsync", onAckSeenAsync);
//group On message
@ -370,7 +377,19 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin {
// }
}
}
// notifyListeners();
}
Future<bool> resetCount({
required int moduleId,
required int referenceNo,
String? userId,
}) async {
try {
return await ChatApiClient().resetCountApi(moduleId, referenceNo, userId);
} catch (e, stack) {
debugPrint('resetCount error: $e');
rethrow;
}
}
void updateUserChatHistoryStatusAsync(List data) {
@ -453,6 +472,15 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin {
print(args);
}
Future<void> markMessageAsRead(int messageId) async {
final senderId = sender?.userId;
if (senderId == null) return;
chatHubConnection?.invoke(
"SendMessageReadAsync",
args: [messageId, senderId],
);
}
void onChatSeen(List<Object?>? args) {
dynamic items = args!.toList();
// for (var user in searchedChats!) {
@ -559,6 +587,57 @@ class ChatProvider with ChangeNotifier, DiagnosticableTreeMixin {
notifyListeners();
}
Future<void> onSeenUserChatAsync(List<Object?>? parameters) async {
try {
if (parameters == null || parameters.isEmpty) {
log('onSeenUserChatAsync: parameters are null or empty');
return;
}
final parm = parameters.first;
if (parm is! List || parm.isEmpty) {
log('onSeenUserChatAsync: parm is not a valid list');
return;
}
final firstItem = parm.first;
if (firstItem is! Map<String, dynamic>) {
log('onSeenUserChatAsync: firstItem is not a Map');
return;
}
await chatHubConnection!.invoke(
"AckSeenAsync",
args: [
firstItem['currentUserId'],
[firstItem['userChatHistoryId']],
],
);
} catch (e, stackTrace) {
log('onSeenUserChatAsync error: $e');
log('StackTrace: $stackTrace');
}
}
Future<void> onAckSeenAsync(List<Object?>? parameters) async {
try {
if (parameters == null || parameters.isEmpty) {
log('onAckSeenAsync: parameters are null or empty');
return;
}
final parm = parameters.first;
log('parm onAckSeenAsync $parm');
if (chatResponseList.isEmpty) {
log('onAckSeenAsync: chatResponseList is empty');
return;
}
log('last list item id ${chatResponseList.first.toJson()}');
chatResponseList.first.isSeen = true;
notifyListeners();
} catch (e, stackTrace) {
log('onAckSeenAsync error: $e');
log('StackTrace: $stackTrace');
}
}
// Future<void> OnSubmitChatAsync(List<Object?>? parameters) async {
// // List data = jsonDecode(parameters!.first!.toString());
//

@ -1,9 +1,12 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/modules/cm_module/cm_detail_provider.dart';
import 'package:test_sa/new_views/common_widgets/custom_badge.dart';
import 'chat_page.dart';
import 'chat_provider.dart';
@ -40,8 +43,10 @@ class _ChatWidgetState extends State<ChatWidget> {
@override
void initState() {
super.initState();
Provider.of<ChatProvider>(context, listen: false).reset();
getChatToken();
WidgetsBinding.instance.addPostFrameCallback((_) {
Provider.of<ChatProvider>(context, listen: false).reset();
getChatToken();
});
}
void getChatToken() {
@ -74,24 +79,31 @@ class _ChatWidgetState extends State<ChatWidget> {
@override
Widget build(BuildContext context) {
return widget.isShow
? Consumer<ChatProvider>(builder: (pContext, requestProvider, _) {
return IconButton(
icon: const Icon(Icons.chat_bubble),
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => ChatPage(
moduleId: widget.moduleId,
requestId: widget.requestId,
title: widget.title,
readOnly: widget.isReadOnly,
assigneeEmployeeNumber: widget.assigneeEmployeeNumber,
contactEmployeeINumber: widget.contactEmployeeINumber,
myLoginUserID: widget.myLoginUserID,
)));
},
).toShimmer(context: context, isShow: requestProvider.chatLoginTokenLoading, radius: 30, height: 30, width: 30);
? Consumer<ChatProvider>(builder: (pContext, chatProvider, _) {
final int unreadCount = (!chatProvider.chatLoginTokenLoading && (chatProvider.chatParticipantModel?.unreadCount ?? 0) > 0) ? chatProvider.chatParticipantModel!.unreadCount! : 0;
return CustomBadge2(
value: unreadCount,
top: 2,
right: 2,
minSize: 18,
child: IconButton(
icon: const Icon(Icons.chat_bubble),
onPressed: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (context) => ChatPage(
moduleId: widget.moduleId,
requestId: widget.requestId,
title: widget.title,
readOnly: widget.isReadOnly,
assigneeEmployeeNumber: widget.assigneeEmployeeNumber,
contactEmployeeINumber: widget.contactEmployeeINumber,
myLoginUserID: widget.myLoginUserID,
)));
},
).toShimmer(context: context, isShow: chatProvider.chatLoginTokenLoading, radius: 30, height: 30, width: 30),
);
})
: const SizedBox();
}

@ -46,6 +46,7 @@ class ChatFilePicker extends StatelessWidget {
fromMediaPicker(BuildContext context, ImageSource imageSource) async {
XFile? pickedFile = await ImagePicker().pickImage(source: imageSource, imageQuality: 70, maxWidth: 800, maxHeight: 800);
if (pickedFile != null) {
//Has UI issues here top buttons not clickable smoothly
CroppedFile? croppedFile = await ImageCropper().cropImage(
sourcePath: pickedFile.path,
// aspectRatio: CropAspectRatio(ratioX: 1, ratioY: 1),

@ -24,6 +24,7 @@ class ChatFileViewer extends StatelessWidget {
@override
Widget build(BuildContext context) {
return FutureBuilder<File?>(
future: checkFileInLocalStorage(),
builder: (BuildContext context, AsyncSnapshot<File?> snapshot) {

@ -1,12 +1,15 @@
import 'dart:developer';
class ChatParticipantModel {
int? id;
String? title;
String? conversationType;
List<Participants>? participants;
String? lastMessage;
dynamic lastMessage;
String? createdAt;
int? unreadCount;
ChatParticipantModel({this.id, this.title, this.conversationType, this.participants, this.lastMessage, this.createdAt});
ChatParticipantModel({this.id, this.title, this.conversationType, this.participants, this.createdAt, this.unreadCount});
ChatParticipantModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
@ -20,18 +23,20 @@ class ChatParticipantModel {
}
lastMessage = json['lastMessage'];
createdAt = json['createdAt'];
unreadCount = json['unreadCount'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['title'] = this.title;
data['conversationType'] = this.conversationType;
if (this.participants != null) {
data['participants'] = this.participants!.map((v) => v.toJson()).toList();
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['title'] = title;
data['conversationType'] = conversationType;
if (participants != null) {
data['participants'] = participants!.map((v) => v.toJson()).toList();
}
data['lastMessage'] = this.lastMessage;
data['createdAt'] = this.createdAt;
data['lastMessage'] = lastMessage;
data['createdAt'] = createdAt;
data['unreadCount'] = unreadCount;
return data;
}
}
@ -54,12 +59,12 @@ class Participants {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['userId'] = this.userId;
data['userName'] = this.userName;
data['employeeNumber'] = this.employeeNumber;
data['role'] = this.role;
data['userStatus'] = this.userStatus;
final Map<String, dynamic> data = <String, dynamic>{};
data['userId'] = userId;
data['userName'] = userName;
data['employeeNumber'] = employeeNumber;
data['role'] = role;
data['userStatus'] = userStatus;
return data;
}
}

@ -1,8 +1,7 @@
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/building.dart';
import 'package:test_sa/models/new_models/department.dart';
import 'package:test_sa/models/new_models/floor.dart';
import 'package:test_sa/models/new_models/mapped_sites.dart';
import 'package:test_sa/models/new_models/site.dart';
import 'package:test_sa/models/new_models/traf_department.dart';
import 'package:test_sa/modules/loan_module/models/medical_department_model.dart';
class LoanFormModel {
@ -21,6 +20,8 @@ class LoanFormModel {
Site? site;
MedicalDepartmentModel? department;
List<LoanAttachments>? loanAttachment;
MappedSite? mappedSite;
TrafDepartment? mappedDepartment;
LoanFormModel({
this.docName,
@ -38,6 +39,8 @@ class LoanFormModel {
this.loanAttachment,
this.site,
this.department,
this.mappedSite,
this.mappedDepartment,
});
//{
@ -91,8 +94,10 @@ class LoanFormModel {
"vendorNumber": vendorNumber,
"vendorContact": vendorNumber,
"vendorEmail": vendorEmail,
'siteId': site?.id,
'departmentId': department?.id,
// 'siteId': site?.id,
'siteId': mappedSite?.id,
// 'departmentId': department?.id,
'departmentId': mappedDepartment?.id,
"loanAttachments": loanAttachment != null ? loanAttachment!.map((v) => v.toJson()).toList() : [],
};
}

@ -1,39 +1,33 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/device_transfer_provider.dart';
import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/dashboard_latest/dashboard_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/helper/utils.dart';
import 'package:test_sa/models/device/asset.dart';
import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/site.dart';
import 'package:test_sa/models/new_models/mapped_sites.dart';
import 'package:test_sa/models/new_models/task_request/task_type_model.dart';
import 'package:test_sa/models/new_models/traf_department.dart';
import 'package:test_sa/models/new_models/work_order_detail_model.dart';
import 'package:test_sa/modules/cm_module/cm_request_utils.dart';
import 'package:test_sa/modules/cm_module/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/modules/loan_module/models/loan_form_model.dart';
import 'package:test_sa/modules/loan_module/models/medical_department_model.dart';
import 'package:test_sa/modules/loan_module/provider/loan_period_provider.dart';
import 'package:test_sa/modules/loan_module/provider/loan_provider.dart';
import 'package:test_sa/modules/loan_module/provider/loan_provider.dart';
import 'package:test_sa/modules/loan_module/provider/medical_department_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart';
import 'package:test_sa/providers/department_provider.dart';
import 'package:test_sa/providers/gas_request_providers/site_provider.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/providers/lookups/department_lookup_provider.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import '../../../../../../new_views/common_widgets/default_app_bar.dart';
@ -275,10 +269,10 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
return [
'Item Details'.addTranslation.bodyText(context).custom(color: AppColor.black10),
8.height,
SingleItemDropDownMenu<Site, SiteProvider>(
SingleItemDropDownMenu<MappedSite, MappedSiteProvider>(
context: context,
title: context.translation.site,
initialValue: _loanFormModel.site,
initialValue: _loanFormModel.mappedSite,
showShadow: false,
validator: (value) {
if (value == null) return "Please select a site";
@ -287,12 +281,17 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
backgroundColor: AppColor.fieldBgColor(context),
showAsBottomSheet: true,
onSelect: (value) {
_loanFormModel.site = value;
setState(() {});
if(value!=null){
_loanFormModel.mappedSite = value;
_loanFormModel.mappedDepartment = null;
Provider.of<DepartmentLookupProvider>(context,listen:false).getData(id:_loanFormModel.mappedSite?.id);
setState(() {});
}
},
),
8.height,
SingleItemDropDownMenu<MedicalDepartmentModel, MedicalDepartmentProvider>(
SingleItemDropDownMenu<TrafDepartment, DepartmentLookupProvider>(
context: context,
title: context.translation.department,
showShadow: false,
@ -301,11 +300,11 @@ class _CreateLoanRequestPageState extends State<CreateLoanRequestPage> with Tick
return null;
},
showAsBottomSheet: true,
initialValue: _loanFormModel.department,
initialValue: _loanFormModel.mappedDepartment,
requestById: context.userProvider.user?.clientId,
backgroundColor: AppColor.fieldBgColor(context),
onSelect: (value) {
_loanFormModel.department = value;
_loanFormModel.mappedDepartment = value;
setState(() {});
},
),

@ -62,10 +62,6 @@ class _CreateDeviceTransferRequestState extends State<CreateDeviceTransferReques
bool checkPendingRequest = false;
void showPendingRequests() {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => PendingServiceRequestScreen(pendingAssetServiceRequest!)));
}
void _onSubmit() async {
_transferModel.assetId = _pickedAsset?.id;
_transferModel.destSiteId = _assetDestination.site?.id;

@ -223,11 +223,11 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
if (context.userProvider.isEngineer || context.userProvider.isNurse)
ChatWidget(
moduleId: widget.moduleId,
isShow: _model!.senderMachineStatusValue! != 4,
isShow: context.settingProvider.isUserFlowMedical && _model!.senderMachineStatusValue! != 4,
isReadOnly: _model!.senderMachineStatusValue! != 1,
requestId: widget.model.id!.toInt(),
assigneeEmployeeNumber: _model!.senderAssignedEmployeeNumber,
myLoginUserID: context.userProvider.user!.username!,
myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!,
contactEmployeeINumber: _model!.assetTransferContactPersons!.first.employeeNumber,
),
if ((_userProvider!.user?.type == UsersTypes.engineer))
@ -284,11 +284,11 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
if (context.userProvider.isEngineer || context.userProvider.isNurse)
ChatWidget(
moduleId: widget.moduleId,
isShow: (isSender ? _deviceTransfer.senderMachineStatusValue! : _deviceTransfer.receiverMachineStatusValue!) != 0,
isShow: context.settingProvider.isUserFlowMedical && (isSender ? _deviceTransfer.senderMachineStatusValue! : _deviceTransfer.receiverMachineStatusValue!) != 0,
isReadOnly: (isSender ? _deviceTransfer.senderMachineStatusValue! : _deviceTransfer.receiverMachineStatusValue) != 1,
requestId: widget.model.id!.toInt(),
assigneeEmployeeNumber: isSender ? _deviceTransfer.senderAssignedEmployeeNumber! : _deviceTransfer.receiverAssignedEmployeeNumber!,
myLoginUserID: context.userProvider.user!.username!,
myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!,
contactEmployeeINumber: _deviceTransfer.assetTransferContactPersons!.first.employeeNumber,
),
if ((_userProvider!.user?.type == UsersTypes.engineer))

@ -68,11 +68,11 @@ class _GasRefillDetailsPageState extends State<GasRefillDetailsPage> {
return ChatWidget(
moduleId: widget.moduleId,
isShow: _gasRefillModel.status!.value! != 0,
isShow: context.settingProvider.isUserFlowMedical && _gasRefillModel.status!.value! != 0,
isReadOnly: _gasRefillModel.status!.value! != 1,
requestId: widget.model.id!.toInt(),
assigneeEmployeeNumber: _gasRefillModel.assignedEmployee?.employeeId!,
myLoginUserID: context.userProvider.user!.username!,
myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!,
contactEmployeeINumber: _gasRefillModel.gasRefillContactPerson!.first.employeeCode!,
);
})

@ -75,16 +75,20 @@ class _TaskRequestDetailsViewState extends State<TaskRequestDetailsView> {
selector: (_, myModel) => myModel.taskRequestModel, // Selects only the userName
builder: (_, _taskReqModel, __) {
if (_taskReqModel == null) return const SizedBox();
return ChatWidget(
moduleId: widget.moduleId,
isShow: _taskReqModel.taskJobStatus!.value! != 1,
isReadOnly: _taskReqModel.taskJobStatus!.value! != 2,
requestId: widget.taskId.toInt(),
assigneeEmployeeNumber: _taskReqModel.assignedEngineer?.employeeId!,
myLoginUserID: context.userProvider.user!.username!,
contactEmployeeINumber: _taskReqModel.taskJobContactPersons!.first.user?.employeeId,
);
if ((context.userProvider.isEngineer || context.userProvider.isNurse) &&
_taskReqModel.assignedEngineer?.employeeId != null &&
(_taskReqModel.taskJobContactPersons?.isNotEmpty ?? false)) {
return ChatWidget(
moduleId: widget.moduleId,
isShow: context.settingProvider.isUserFlowMedical && _taskReqModel.taskJobStatus!.value! != 1,
isReadOnly: _taskReqModel.taskJobStatus!.value! != 2,
requestId: widget.taskId.toInt(),
assigneeEmployeeNumber: _taskReqModel.assignedEngineer?.employeeId!,
myLoginUserID: context.userProvider.user!.employeeId ?? context.userProvider.user!.username!,
contactEmployeeINumber: _taskReqModel.taskJobContactPersons!.first.user?.employeeId,
);
} else
return const SizedBox();
})
],
),

@ -5,12 +5,20 @@ import 'package:test_sa/new_views/app_style/app_color.dart';
class CustomBadge extends StatelessWidget {
final Widget child; // The widget that the badge will be overlaid on.
final int value; // The value or text to be displayed in the badge.
final Color color; // The background color of the badge.
final Color color;
final double? positionR;
final double? positionT;
final double? height;
final double? width;
const CustomBadge({
CustomBadge({
Key? key,
required this.child,
required this.value,
this.height,
this.width,
this.positionR,
this.positionT,
this.color = AppColor.red30, // Default color is red
}) : super(key: key);
@ -22,13 +30,14 @@ class CustomBadge extends StatelessWidget {
child, // The main widget
// if (value > 0)
Positioned(
right: -6,
top: -6,
right: positionR ?? -6,
top: positionT ?? -6,
//Need to check why opacity he used here this is not correct need to make this total dynamic and responsive
child: Opacity(
opacity: value > 0 ? 1 : 0,
child: Container(
height: 23,
constraints: const BoxConstraints(minWidth: 23),
height: height ?? 23,
constraints: BoxConstraints(minWidth: width ?? 23),
padding: const EdgeInsets.all(3),
alignment: Alignment.center,
decoration: BoxDecoration(color: color, borderRadius: BorderRadius.circular(30)),
@ -43,3 +52,139 @@ class CustomBadge extends StatelessWidget {
);
}
}
//Need to use this badge every where..
class CustomBadge2 extends StatelessWidget {
final Widget child;
final int value;
final double top;
final double right;
final double left;
final double bottom;
final double minSize;
final Color backgroundColor;
final Color textColor;
final TextStyle? textStyle;
final int maxValue;
final Duration animationDuration;
const CustomBadge2({
super.key,
required this.child,
required this.value,
this.top = -6,
this.right = -6,
this.left = double.nan,
this.bottom = double.nan,
this.minSize = 18,
this.backgroundColor = AppColor.red30,
this.textColor = AppColor.white10,
this.textStyle,
this.maxValue = 99,
this.animationDuration = const Duration(milliseconds: 200),
});
bool get _isVisible => value > 0;
@override
Widget build(BuildContext context) {
return Stack(
clipBehavior: Clip.none,
children: [
child,
if (_isVisible)
Positioned(
top: top.isNaN ? null : top,
right: right.isNaN ? null : right,
left: left.isNaN ? null : left,
bottom: bottom.isNaN ? null : bottom,
child: AnimatedScale(
scale: _isVisible ? 1 : 0,
duration: animationDuration,
curve: Curves.easeOutBack,
child: AnimatedOpacity(
opacity: _isVisible ? 1 : 0,
duration: animationDuration,
child: _Badge(
value: value,
maxValue: maxValue,
minSize: minSize,
backgroundColor: backgroundColor,
textColor: textColor,
textStyle: textStyle ??
Theme.of(context).textTheme.labelSmall?.copyWith(
fontWeight: FontWeight.w700,
),
),
),
),
),
],
);
}
}
class _Badge extends StatelessWidget {
final int value;
final int maxValue;
final double minSize;
final Color backgroundColor;
final Color textColor;
final TextStyle? textStyle;
const _Badge({
required this.value,
required this.maxValue,
required this.minSize,
required this.backgroundColor,
required this.textColor,
this.textStyle,
});
bool get _isOverflow => value > maxValue;
@override
Widget build(BuildContext context) {
final TextStyle baseStyle = (textStyle ?? Theme.of(context).textTheme.labelMedium)!.copyWith(
color: textColor,
fontWeight: FontWeight.w700,
);
final double badgeSize = minSize;
return IgnorePointer(
child: SizedBox(
width: badgeSize,
height: badgeSize,
child: DecoratedBox(
decoration: const BoxDecoration(
shape: BoxShape.circle,
),
child: DecoratedBox(
decoration: BoxDecoration(
color: backgroundColor,
shape: BoxShape.circle,
),
child: Center(
child: _isOverflow
? FittedBox(
child: Text(
'$maxValue+',
style: baseStyle.copyWith(
fontSize: badgeSize * 0.45,
),
),
)
: CounterAnimatedText(
value: value,
style: baseStyle.copyWith(
fontSize: badgeSize * 0.6,
),
),
),
),
),
),
);
}
}

@ -112,12 +112,14 @@ class CreateRequestModel {
// list.add(CreateRequestModel(module.module!.name!, "add_icon", CreateTaskView.id));
// }
// });
if (context.userProvider.isQualityUser) {
if (context.userProvider.isQualityUser && context.settingProvider.isUserFlowMedical) {
list.add(CreateRequestModel("Equipment Internal Audit Checklist".addTranslation, "add_icon", CreateEquipmentInternalAuditForm.id));
list.add(CreateRequestModel("System Internal Audit Checklist".addTranslation, "add_icon", CreateSystemInternalAuditForm.id));
} else if (context.userProvider.isAssessor) {
list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id));
} else if (context.userProvider.isEngineer) {
}
// else if (context.userProvider.isAssessor) {
// list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id));
// }
else if (context.userProvider.isEngineer) {
if (Provider.of<SettingProvider>(context, listen: false).engineerCanCreateCM) {
list.add(CreateRequestModel(context.translation.correctiveMaintenance, "add_icon", CreateCMRequest.id));
}
@ -129,7 +131,7 @@ class CreateRequestModel {
list.add(CreateRequestModel(context.translation.transferAsset, "add_icon", CreateDeviceTransferRequest.id));
//TODO uncommit this to enable task.
list.add(CreateRequestModel(context.translation.task, "add_icon", CreateTaskView.id));
list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id));
// list.add(CreateRequestModel("TRAF".addTranslation, "add_icon", CreateTRAFRequestPage.id));
list.add(CreateRequestModel('Loan Equipment Request'.addTranslation, "add_icon", CreateLoanRequestPage.id));
}
return list;

@ -1,8 +1,11 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:test_sa/controllers/notification/firebase_notification_manger.dart';
import 'package:test_sa/controllers/notification/notification_manger.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/app_settings.dart';
import 'package:test_sa/dashboard_latest/dashboard_view.dart';
@ -42,7 +45,7 @@ class _LandPageState extends State<LandPage> {
bool showAppbar = true;
late List<Widget> _pages;
UserProvider? _userProvider;
bool isFCM = true;
@override
void initState() {
_pages = <Widget>[];
@ -123,7 +126,14 @@ class _LandPageState extends State<LandPage> {
// if (_userProvider!.user!.type != UsersTypes.engineer) const CalendarPage(),
const MyAssetsPage(fromBottomBar: true),
];
if (isFCM) {
FirebaseNotificationManger.initialized(context);
NotificationManger.initialisation((notificationDetails) {
FirebaseNotificationManger.handleMessage(context, json.decode(notificationDetails.payload!));
}, (id, title, body, payload) async {});
isFCM = false;
}
checkLocalAuth();
}

@ -79,8 +79,8 @@ class _AllRequestsFilterPageState extends State<AllRequestsFilterPage> {
if (isEngineer) {
types[context.translation.recurrentWo] = 5;
types["Equipment Internal Audit".addTranslation] = 10;
types["System Internal Audit".addTranslation] = 11;
if (context.settingProvider.isUserFlowMedical) types["Equipment Internal Audit".addTranslation] = 10;
if (context.settingProvider.isUserFlowMedical) types["System Internal Audit".addTranslation] = 11;
}
if (context.settingProvider.isUserFlowMedical && isEngineer) {
@ -93,18 +93,18 @@ class _AllRequestsFilterPageState extends State<AllRequestsFilterPage> {
types[module.module!.name!] = module.module!.value!;
}
});
//Hide traf
// if (!isEngineer) {
// types['TRAF'] = 9;
// }
if (!isEngineer) {
types['TRAF'] = 9;
}
if (context.userProvider.isAssessor) {
types = {"TRAF": 9};
}
// if (context.userProvider.isAssessor) {
// types = {"TRAF": 9};
// }
if (context.userProvider.isQualityUser) {
if (context.settingProvider.isUserFlowMedical) types = {'Recall and Alert': 7};
types['Equipment Internal Audit'] = 10;
types['System Internal Audit'] = 11;
if (context.settingProvider.isUserFlowMedical) types['Equipment Internal Audit'] = 10;
if (context.settingProvider.isUserFlowMedical) types['System Internal Audit'] = 11;
}
if (context.userProvider.isCommissioningEngineer) {
///TODO need to check what other requests type needed here.

@ -62,10 +62,11 @@ class _MyRequestsPageState extends State<MyRequestsPage> {
requestsList.add(Request(module.module!.value!, module.module!.name!.addTranslation));
}
});
if (context.userProvider.user!.type == UsersTypes.normal_user) {
requestsList.add(Request(9, 'TRAF'));
}
if (context.userProvider.isEngineer) {
//Hide TRAF.
// if (context.userProvider.user!.type == UsersTypes.normal_user) {
// requestsList.add(Request(9, 'TRAF'));
// }
if (context.userProvider.isEngineer &&context.settingProvider.isUserFlowMedical) {
requestsList.add(Request(10, 'Equipment Internal Audit'));
requestsList.add(Request(11, 'System Internal Audit'));
//Need to be added for new user role commissioning engineer
@ -77,7 +78,7 @@ class _MyRequestsPageState extends State<MyRequestsPage> {
if (context.userProvider.isAssessor) {
requestsList = [
Request(null, context.translation.allWorkOrder),
Request(9, 'TRAF'),
// Request(9, 'TRAF'),
];
}
if (context.userProvider.isCommissioningEngineer) {
@ -91,8 +92,8 @@ class _MyRequestsPageState extends State<MyRequestsPage> {
requestsList = [
Request(null, context.translation.allWorkOrder),
if (context.settingProvider.isUserFlowMedical) Request(7, 'Recall and Alert'),
Request(10, 'Equipment Internal Audit'),
Request(11, 'System Internal Audit'),
if (context.settingProvider.isUserFlowMedical) Request(10, 'Equipment Internal Audit'),
if (context.settingProvider.isUserFlowMedical) Request(11, 'System Internal Audit'),
];
}

@ -81,7 +81,7 @@ class ServiceRequestItemView extends StatelessWidget {
),
],
).toShadowContainer(context, withShadow: showShadow).onPress(() async {
await Navigator.of(context).push(MaterialPageRoute(builder: (_) => CMDetailPage(requestId: requestData!.id!)));
await Navigator.of(context).push(MaterialPageRoute(builder: (_) => CMDetailPage(requestId: requestData!.id!, moduleId: requestData!.transactionNo!)));
if (refreshData) {
Provider.of<DashBoardProvider>(context, listen: false).refreshDashboard(userType: Provider.of<SettingProvider>(context, listen: false).user!.type!, context: context);
}
@ -140,7 +140,7 @@ class ServiceRequestItemView extends StatelessWidget {
),
],
).toShadowContainer(context, withShadow: showShadow).onPress(() {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => CMDetailPage(requestId: requestDetails!.id!)));
Navigator.of(context).push(MaterialPageRoute(builder: (_) => CMDetailPage(requestId: requestDetails!.id!, moduleId: requestDetails!.transactionType!)));
});
}

@ -9,9 +9,10 @@ import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/widgets/sound/sound_player.dart';
class PendingServiceRequestScreen extends StatelessWidget {
final int moduleId;
final PendingAssetServiceRequest pendingAssetServiceRequest;
const PendingServiceRequestScreen(this.pendingAssetServiceRequest, {Key? key}) : super(key: key);
const PendingServiceRequestScreen(this.pendingAssetServiceRequest, this.moduleId, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
@ -63,7 +64,7 @@ class PendingServiceRequestScreen extends StatelessWidget {
],
),
).onPress(() {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => CMDetailPage(requestId: pendingAssetServiceRequest.details![index].id ?? 0)));
Navigator.of(context).push(MaterialPageRoute(builder: (_) => CMDetailPage(requestId: pendingAssetServiceRequest.details![index].id ?? 0, moduleId: moduleId)));
})));
}
}

@ -122,7 +122,7 @@ class _AssetDetailPageState extends State<AssetDetailPage> {
"${context.translation.building}: ${assetModel.building?.name?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context),
"${context.translation.floor}: ${assetModel.floor?.name?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context),
"${context.translation.md}: ${assetModel.department?.departmentName?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context),
"${context.translation.room}: ${assetModel.room?.value ?? "-"}".bodyText(context),
"${context.translation.room}: ${assetModel.room?.name?.cleanupWhitespace.capitalizeFirstOfEach ?? "-"}".bodyText(context),
],
).expanded,
],

@ -15,7 +15,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: 1.4.0+31
version: 1.5.0+32
environment:
sdk: ">=3.5.0 <4.0.0"

Loading…
Cancel
Save