diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 6d04a2a4..edbf0bd9 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -469,8 +469,6 @@ "-framework", "\"nanopb\"", "-framework", - "\"qr_code_scanner\"", - "-framework", "\"speech_to_text\"", "-framework", "\"sqflite\"", @@ -689,8 +687,6 @@ "-framework", "\"nanopb\"", "-framework", - "\"qr_code_scanner\"", - "-framework", "\"speech_to_text\"", "-framework", "\"sqflite\"", @@ -795,8 +791,6 @@ "-framework", "\"nanopb\"", "-framework", - "\"qr_code_scanner\"", - "-framework", "\"speech_to_text\"", "-framework", "\"sqflite\"", diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index aac9b8b5..bacf721a 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -1,7 +1,7 @@ class URLs { URLs._(); - static const String appReleaseBuildNumber = "28"; + static const String appReleaseBuildNumber = "31"; // static const host1 = "https://atomsm.hmg.com"; // production url static const host1 = "https://atomsmdev.hmg.com"; // local DEV url @@ -67,8 +67,10 @@ class URLs { //service request new flow urls. static get nurseDashboardCountUrl => '$_baseUrl/ServiceRequest/GetDashboardNurseCount'; + static get qaAuditorCount => '$_baseUrl/ServiceRequest/GetDashboardQAAuditorCount'; static get nurseDashboardDetailsUrl => '$_baseUrl/ServiceRequest/GetDashboardNurseDetails'; + static get qaAuditorDetails => '$_baseUrl/ServiceRequest/GetDashboardQAAuditorDetails'; static get nurseRejectUrl => '$_baseUrl/ServiceRequest/NurseReject'; diff --git a/lib/controllers/notification/firebase_notification_manger.dart b/lib/controllers/notification/firebase_notification_manger.dart index c01d9965..bc011827 100644 --- a/lib/controllers/notification/firebase_notification_manger.dart +++ b/lib/controllers/notification/firebase_notification_manger.dart @@ -110,12 +110,13 @@ class FirebaseNotificationManger { serviceClass = CMDetailPage(requestId: int.parse(messageData["requestNumber"].toString())); break; case "7": - serviceClass = DeviceTransferDetails(model: DeviceTransfer(id: int.parse(messageData["requestNumber"].toString()))); + serviceClass = DeviceTransferDetails(model: DeviceTransfer(id: int.parse(messageData["requestNumber"].toString())), moduleId: 3); break; case "9": serviceClass = GasRefillDetailsPage( priority: messageData["priority"], date: messageData["createdOn"], + moduleId: 2, model: GasRefillModel(id: int.parse(messageData["requestNumber"].toString())), ); break; diff --git a/lib/controllers/providers/api/all_requests_provider.dart b/lib/controllers/providers/api/all_requests_provider.dart index 29dca48b..5036ea9c 100644 --- a/lib/controllers/providers/api/all_requests_provider.dart +++ b/lib/controllers/providers/api/all_requests_provider.dart @@ -140,6 +140,7 @@ class AllRequestsProvider extends ChangeNotifier { } if (context.userProvider.isQualityUser) { list = [10, 11]; + if (context.settingProvider.isUserFlowMedical) list.insert(0, 7); return list; } diff --git a/lib/dashboard_latest/dashboard_provider.dart b/lib/dashboard_latest/dashboard_provider.dart index c09cb621..f1a92f54 100644 --- a/lib/dashboard_latest/dashboard_provider.dart +++ b/lib/dashboard_latest/dashboard_provider.dart @@ -106,7 +106,9 @@ class DashBoardProvider extends ChangeNotifier { isAllCountLoading = true; notifyListeners(); String url = ''; - if (usersType == UsersTypes.engineer || usersType == UsersTypes.assessor || usersType == UsersTypes.assessorTl) { + if (usersType == UsersTypes.qualityUser) { + url = URLs.qaAuditorCount; + } else if (usersType == UsersTypes.engineer || usersType == UsersTypes.assessor || usersType == UsersTypes.assessorTl) { url = URLs.engineerDashboardCountUrl; } else { url = URLs.nurseDashboardCountUrl; @@ -241,7 +243,10 @@ class DashBoardProvider extends ChangeNotifier { Response response; String url = ''; - if (usersType == UsersTypes.engineer || usersType == UsersTypes.assessor || usersType == UsersTypes.assessorTl) { + + if (usersType == UsersTypes.qualityUser) { + url = URLs.qaAuditorDetails; + } else if (usersType == UsersTypes.engineer || usersType == UsersTypes.assessor || usersType == UsersTypes.assessorTl) { //need to check pagination for not assigned task @waseem. //these checks are to call different apis for dashboard for engineer... @@ -372,6 +377,13 @@ class CategoryTabs { return tabs; } + if (userType == UsersTypes.qualityUser) { + tabs.add(CategoryTabs(label: 'Open', tag: 1, id: 2)); + tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 3)); + tabs.add(CategoryTabs(label: 'Closed', tag: 3, id: 4)); + return tabs; + } + tabs.add(CategoryTabs(label: 'Open', tag: 1, id: 2)); tabs.add(CategoryTabs(label: 'In Progress', tag: 2, id: 3)); tabs.add(CategoryTabs(label: 'Pending Acknowledgement', tag: 3, id: 1)); diff --git a/lib/dashboard_latest/widgets/progress_fragment.dart b/lib/dashboard_latest/widgets/progress_fragment.dart index a56f54e6..4ab32aab 100644 --- a/lib/dashboard_latest/widgets/progress_fragment.dart +++ b/lib/dashboard_latest/widgets/progress_fragment.dart @@ -182,6 +182,13 @@ class ProgressFragment extends StatelessWidget { ChartData('Open', snapshot.dashboardCount?.data?.countOpen?.toDouble() ?? 0.0, AppColor.blueStatus(context)), ChartData('In Progress', snapshot.dashboardCount?.data?.countInprogress?.toDouble() ?? 0.0, AppColor.orange70), ]; + } else if (_userProvider.isQualityUser) { + total = (snapshot.dashboardCount?.data?.countComplete ?? 0) + (snapshot.dashboardCount?.data?.countInprogress ?? 0) + (snapshot.dashboardCount?.data?.countOpen ?? 0); + chartData = [ + ChartData('Closed', snapshot.dashboardCount?.data?.countComplete?.toDouble() ?? 0.0, AppColor.green70), + ChartData('Open', snapshot.dashboardCount?.data?.countOpen?.toDouble() ?? 0.0, AppColor.blueStatus(context)), + ChartData('In Progress', snapshot.dashboardCount?.data?.countInprogress?.toDouble() ?? 0.0, AppColor.orange70), + ]; } else { total = (snapshot.dashboardCount?.data?.countComplete ?? 0) + (snapshot.dashboardCount?.data?.countInprogress ?? 0) + (snapshot.dashboardCount?.data?.countOpen ?? 0); chartData = [ @@ -248,7 +255,7 @@ class ProgressFragment extends StatelessWidget { showChartValuesOutside: false, decimalPlaces: 1, ), - ).toShimmer(isShow: snapshot.isAllCountLoading, radius: 250,context: context).paddingAll(0).toShadowContainer(context), + ).toShimmer(isShow: snapshot.isAllCountLoading, radius: 250, context: context).paddingAll(0).toShadowContainer(context), ], ), ), diff --git a/lib/models/device/device_transfer.dart b/lib/models/device/device_transfer.dart index c8620eaf..67b7d465 100644 --- a/lib/models/device/device_transfer.dart +++ b/lib/models/device/device_transfer.dart @@ -38,6 +38,7 @@ class DeviceTransfer { this.senderEngSignature, this.senderAttachments, this.receiverAssignedEmployeeId, + this.receiverAssignedEmployeeNumber, this.receiverMachineStatusId, this.senderMachineStatusValue, this.receiverComment, @@ -74,6 +75,7 @@ class DeviceTransfer { this.receiverMachineStatusValue, this.receiverMachineStatusName, this.senderAssignedEmployeeName, + this.senderAssignedEmployeeNumber, this.senderBuildingName, this.senderDepartmentName, this.senderEngSignatureUrl, @@ -144,6 +146,7 @@ class DeviceTransfer { }); } receiverAssignedEmployeeId = json['receiverAssignedEmployeeId']; + receiverAssignedEmployeeNumber = json['receiverAssignedEmployeeNumber']; receiverMachineStatusId = json['receiverMachineStatusId']; receiverMachineStatusValue = json['receiverMachineStatusValue']; receiverComment = json['receiverComment']; @@ -220,6 +223,7 @@ class DeviceTransfer { receiverEngSignatureUrl = json['receiverEngSignatureUrl']; receiverMachineStatusName = json['receiverMachineStatusName']; senderAssignedEmployeeName = json['senderAssignedEmployeeName']; + senderAssignedEmployeeNumber = json['senderAssignedEmployeeNumber']; senderBuildingName = json['senderBuildingName']; senderDepartmentName = json['senderDepartmentName']; senderEngSignatureUrl = json['senderEngSignatureUrl']; @@ -270,6 +274,7 @@ class DeviceTransfer { List? attachments; List? assetTransferAttachments; String? receiverAssignedEmployeeId; + String? receiverAssignedEmployeeNumber; num? receiverMachineStatusId; int? receiverMachineStatusValue; String? receiverComment; @@ -290,6 +295,7 @@ class DeviceTransfer { String? senderFloorName; String? senderDepartmentName; String? senderAssignedEmployeeName; + String? senderAssignedEmployeeNumber; String? senderMachineStatusName; String? senderEngSignatureUrl; String? receiverAssignedEmployeeName; @@ -345,6 +351,7 @@ class DeviceTransfer { String? senderEngSignature, List? senderAttachments, String? receiverAssignedEmployeeId, + String? receiverAssignedEmployeeNumber, num? receiverMachineStatusId, String? receiverComment, String? receiverStartDate, @@ -364,6 +371,7 @@ class DeviceTransfer { String? senderFloorName, String? senderDepartmentName, String? senderAssignedEmployeeName, + String? senderAssignedEmployeeNumber, String? senderMachineStatusName, String? senderEngSignatureUrl, String? receiverAssignedEmployeeName, @@ -420,6 +428,7 @@ class DeviceTransfer { senderEngSignature: senderEngSignature ?? this.senderEngSignature, senderAttachments: senderAttachments ?? this.senderAttachments, receiverAssignedEmployeeId: receiverAssignedEmployeeId ?? this.receiverAssignedEmployeeId, + receiverAssignedEmployeeNumber: receiverAssignedEmployeeNumber ?? this.receiverAssignedEmployeeNumber, receiverMachineStatusId: receiverMachineStatusId ?? this.receiverMachineStatusId, receiverComment: receiverComment ?? this.receiverComment, receiverStartDate: receiverStartDate ?? this.receiverStartDate, @@ -439,6 +448,7 @@ class DeviceTransfer { senderFloorName: senderFloorName ?? this.senderFloorName, senderDepartmentName: senderDepartmentName ?? this.senderDepartmentName, senderAssignedEmployeeName: senderAssignedEmployeeName ?? this.senderAssignedEmployeeName, + senderAssignedEmployeeNumber: senderAssignedEmployeeNumber ?? this.senderAssignedEmployeeNumber, senderMachineStatusName: senderMachineStatusName ?? this.senderMachineStatusName, senderMachineStatusValue: senderMachineStatusValue ?? this.senderMachineStatusValue, senderEngSignatureUrl: senderEngSignatureUrl ?? this.senderEngSignatureUrl, @@ -503,6 +513,7 @@ class DeviceTransfer { map['senderAttachments'] = senderAttachments!.map((v) => v.toJson()).toList(); } map['receiverAssignedEmployeeId'] = receiverAssignedEmployeeId; + map['receiverAssignedEmployeeNumber'] = receiverAssignedEmployeeNumber; map['receiverMachineStatusId'] = receiverMachineStatusId; map['receiverComment'] = receiverComment; map['receiverStartDate'] = receiverStartDate; @@ -524,6 +535,7 @@ class DeviceTransfer { map["senderFloorName"] = senderFloorName; map["senderDepartmentName"] = senderDepartmentName; map["senderAssignedEmployeeName"] = senderAssignedEmployeeName; + map["senderAssignedEmployeeNumber"] = senderAssignedEmployeeNumber; map["senderMachineStatusName"] = senderMachineStatusName; map["senderEngSignatureUrl"] = senderEngSignatureUrl; map["receiverAssignedEmployeeName"] = receiverAssignedEmployeeName; @@ -631,6 +643,7 @@ class DeviceTransfer { map['assetTransferReceiverTimers'] = receiverVisitTimers!.map((v) => v.toJson()).toList(); } map['receiverAssignedEmployeeId'] = receiverAssignedEmployeeId; + map['receiverAssignedEmployeeNumber'] = receiverAssignedEmployeeNumber; map['receiverMachineStatusId'] = receiverMachineStatusId; map['receiverComment'] = receiverComment; map['receiverStartDate'] = receiverStartDate; @@ -674,6 +687,7 @@ class DeviceTransfer { senderEngSignature = assetTransfer.senderEngSignature; senderAttachments = assetTransfer.senderAttachments; receiverAssignedEmployeeId = assetTransfer.receiverAssignedEmployeeId; + receiverAssignedEmployeeNumber = assetTransfer.receiverAssignedEmployeeNumber; receiverMachineStatusId = assetTransfer.receiverMachineStatusId; receiverComment = assetTransfer.receiverComment; receiverStartDate = assetTransfer.receiverStartDate; @@ -693,6 +707,7 @@ class DeviceTransfer { senderFloorName = assetTransfer.senderFloorName; senderDepartmentName = assetTransfer.senderDepartmentName; senderAssignedEmployeeName = assetTransfer.senderAssignedEmployeeName; + senderAssignedEmployeeNumber = assetTransfer.senderAssignedEmployeeNumber; senderMachineStatusName = assetTransfer.senderMachineStatusName; senderEngSignatureUrl = assetTransfer.senderEngSignatureUrl; receiverAssignedEmployeeName = assetTransfer.receiverAssignedEmployeeName; diff --git a/lib/models/new_models/gas_refill_model.dart b/lib/models/new_models/gas_refill_model.dart index e9e873f3..a50373df 100644 --- a/lib/models/new_models/gas_refill_model.dart +++ b/lib/models/new_models/gas_refill_model.dart @@ -523,3 +523,55 @@ class GasRefillContactPerson { }; } } +class AssignedEmployee { + String? id; + String? name; + String? email; + String? employeeId; + int? languageId; + String? extensionNo; + String? phoneNumber; + String? positionName; + String? position; + bool? isActive; + + AssignedEmployee( + {this.id, + this.name, + this.email, + this.employeeId, + this.languageId, + this.extensionNo, + this.phoneNumber, + this.positionName, + this.position, + this.isActive}); + + AssignedEmployee.fromJson(Map json) { + id = json['id']; + name = json['name']; + email = json['email']; + employeeId = json['employeeId']; + languageId = json['languageId']; + extensionNo = json['extensionNo']; + phoneNumber = json['phoneNumber']; + positionName = json['positionName']; + position = json['position']; + isActive = json['isActive']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['name'] = this.name; + data['email'] = this.email; + data['employeeId'] = this.employeeId; + data['languageId'] = this.languageId; + data['extensionNo'] = this.extensionNo; + data['phoneNumber'] = this.phoneNumber; + data['positionName'] = this.positionName; + data['position'] = this.position; + data['isActive'] = this.isActive; + return data; + } +} diff --git a/lib/models/user.dart b/lib/models/user.dart index 2fd42598..5eac8486 100644 --- a/lib/models/user.dart +++ b/lib/models/user.dart @@ -110,6 +110,8 @@ class User { return UsersTypes.assessorTl; case "R-3": // Quality User return UsersTypes.qualityUser; + case "R-58": // Quality User + return UsersTypes.qualityUser; default: return null; } diff --git a/lib/modules/cm_module/cm_detail_page.dart b/lib/modules/cm_module/cm_detail_page.dart index cbf729ca..d396e598 100644 --- a/lib/modules/cm_module/cm_detail_page.dart +++ b/lib/modules/cm_module/cm_detail_page.dart @@ -153,7 +153,8 @@ class _CMDetailPageState extends State { ], ), ).onPress(() { - Navigator.push(context, MaterialPageRoute(builder: (context) => CreateLoanRequestPage(workOrderId: widget.requestId))); + CMDetailProvider provider = Provider.of(context, listen: false); + Navigator.push(context, MaterialPageRoute(builder: (context) => CreateLoanRequestPage(workOrderId: widget.requestId, workOrder: provider.currentWorkOrder!.data))); }); } return const SizedBox(); diff --git a/lib/modules/cm_module/views/components/service_request_detail_view.dart b/lib/modules/cm_module/views/components/service_request_detail_view.dart index 6aae9abf..f8c4f320 100644 --- a/lib/modules/cm_module/views/components/service_request_detail_view.dart +++ b/lib/modules/cm_module/views/components/service_request_detail_view.dart @@ -199,8 +199,6 @@ class _ServiceRequestDetailViewState extends State { '${context.translation.assetName}: ${workOrder.assetNdModel!.name?.cleanupWhitespace?.capitalizeFirstOfEach}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), - - // 8.height, Text( '${context.translation.assetNumber}: ${workOrder.asset!.assetNumber}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), diff --git a/lib/modules/cx_module/chat/chat_widget.dart b/lib/modules/cx_module/chat/chat_widget.dart index a137245e..4d28bd1b 100644 --- a/lib/modules/cx_module/chat/chat_widget.dart +++ b/lib/modules/cx_module/chat/chat_widget.dart @@ -73,25 +73,26 @@ class _ChatWidgetState extends State { @override Widget build(BuildContext context) { - return Consumer(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); - }); - ; + return widget.isShow + ? Consumer(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); + }) + : const SizedBox(); } } diff --git a/lib/modules/cx_module/chat/helper/chat_file_viewer.dart b/lib/modules/cx_module/chat/helper/chat_file_viewer.dart index fbd53eec..04fba4a1 100644 --- a/lib/modules/cx_module/chat/helper/chat_file_viewer.dart +++ b/lib/modules/cx_module/chat/helper/chat_file_viewer.dart @@ -127,8 +127,9 @@ class ChatFileViewer extends StatelessWidget { Future downloadFile() async { try { + // print("downloadUrl:$downloadUrl"); return await ChatApiClient() - .downloadFileWithHttp(downloadUrl, fileName: fileTypeResponse.fileName, fileTypeDescription: fileTypeResponse.fileTypeDescription, fileSource: fileTypeResponse.fileTypeId!); + .downloadFileWithHttp(downloadUrl, fileName: fileTypeResponse.fileName, fileTypeDescription: fileTypeResponse.fileTypeDescription ?? "", fileSource: fileTypeResponse.fileTypeId!); } catch (ex) { print("downloadFile:$ex"); return null; diff --git a/lib/modules/internal_audit_module/models/equipment_internal_audit_data_model.dart b/lib/modules/internal_audit_module/models/equipment_internal_audit_data_model.dart index 92f41bab..1e62dd1d 100644 --- a/lib/modules/internal_audit_module/models/equipment_internal_audit_data_model.dart +++ b/lib/modules/internal_audit_module/models/equipment_internal_audit_data_model.dart @@ -170,6 +170,8 @@ class Asset { String? siteName; int? siteId; String? modelDefinition; + int? departmentId; + String? departmentName; Asset({ this.id, @@ -181,6 +183,8 @@ class Asset { this.siteName, this.siteId, this.modelDefinition, + this.departmentId, + this.departmentName, }); Asset.fromJson(Map json) { @@ -193,6 +197,8 @@ class Asset { siteName = json['siteName']; siteId = json['siteId']; modelDefinition = json['modelDefinition']; + departmentId = json['departmentId']; + departmentName = json['departmentName']; } Map toJson() { @@ -206,6 +212,8 @@ class Asset { data['siteName'] = siteName; data['siteId'] = siteId; data['modelDefinition'] = modelDefinition; + data['departmentId'] = departmentId; + data['departmentName'] = departmentName; return data; } } diff --git a/lib/modules/internal_audit_module/pages/equipment_internal_audit/create_equipment_internal_audit_form.dart b/lib/modules/internal_audit_module/pages/equipment_internal_audit/create_equipment_internal_audit_form.dart index 83ddb00c..638b7189 100644 --- a/lib/modules/internal_audit_module/pages/equipment_internal_audit/create_equipment_internal_audit_form.dart +++ b/lib/modules/internal_audit_module/pages/equipment_internal_audit/create_equipment_internal_audit_form.dart @@ -42,6 +42,8 @@ class _CreateEquipmentInternalAuditFormState extends State _scaffoldKey = GlobalKey(); FocusNode auditCheckListNode = FocusNode(); + int noFindingValue = 4; + @override void initState() { super.initState(); @@ -78,7 +80,6 @@ class _CreateEquipmentInternalAuditFormState extends State( context: context, showAsBottomSheet: true, @@ -89,6 +90,15 @@ class _CreateEquipmentInternalAuditFormState extends State element.value == noFindingValue); + } catch (ex) {} + if (noFindingElement != null) { + value!.removeWhere((element) => element.value != noFindingElement!.value); + } + } _equipmentinternalAuditModel.findings = value ?? []; }, ), @@ -137,9 +147,9 @@ class _CreateEquipmentInternalAuditFormState extends State const AppLazyLoading()); _equipmentinternalAuditModel.auditorId = context.userProvider.user?.userID; - bool status = await internalAuditProvider.addEquipmentInternalAudit(context: context, request: _equipmentinternalAuditModel); + bool status = await internalAuditProvider.addEquipmentInternalAudit(context: context, request: _equipmentinternalAuditModel); Navigator.pop(context); - if(status){ + if (status) { Navigator.pop(context); } } diff --git a/lib/modules/internal_audit_module/pages/equipment_internal_audit/equipment_internal_audit_detail_page.dart b/lib/modules/internal_audit_module/pages/equipment_internal_audit/equipment_internal_audit_detail_page.dart index 84999bcb..74903c92 100644 --- a/lib/modules/internal_audit_module/pages/equipment_internal_audit/equipment_internal_audit_detail_page.dart +++ b/lib/modules/internal_audit_module/pages/equipment_internal_audit/equipment_internal_audit_detail_page.dart @@ -19,6 +19,7 @@ import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/images/files_list.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; +import 'package:test_sa/views/widgets/requests/request_status.dart'; class EquipmentInternalAuditDetailPage extends StatefulWidget { static const String id = "/details-internal-audit"; @@ -51,12 +52,10 @@ class _EquipmentInternalAuditDetailPageState extends State getAuditData() async { model = await _internalAuditProvider.getEquipmentInternalAuditById(widget.auditId); allAttachments.clear(); - allAttachments = [ + allAttachments = [ ...(model?.attachments ?? []), ...(model?.engineerData?.attachments ?? []), ]; - - } @override @@ -82,12 +81,43 @@ class _EquipmentInternalAuditDetailPageState extends State EquipmentInternalAuditDetailPage(auditId: requestDetails!.id!))); + Navigator.push(context, MaterialPageRoute(builder: (context) => EquipmentInternalAuditDetailPage(auditId: requestData!.id!))); }); } return Column( @@ -85,9 +84,11 @@ class EquipmentInternalAuditItemView extends StatelessWidget { 8.height, (requestDetails?.nameOfType ?? "Internal Audit Request").heading5(context), 8.height, + infoWidget(label: context.translation.requestNo, value: requestDetails!.requestNo, context: context), infoWidget(label: context.translation.assetNumber, value: requestDetails!.assetNo, context: context), infoWidget(label: context.translation.assetSN, value: requestDetails!.assetSN, context: context), infoWidget(label: context.translation.model, value: requestDetails!.model, context: context), + infoWidget(label: context.translation.site, value: requestDetails!.site, context: context), 8.height, Row( mainAxisSize: MainAxisSize.min, diff --git a/lib/modules/internal_audit_module/pages/system_internal_audit/system_internal_audit_detail_page.dart b/lib/modules/internal_audit_module/pages/system_internal_audit/system_internal_audit_detail_page.dart index 9f3804e4..848b5dcf 100644 --- a/lib/modules/internal_audit_module/pages/system_internal_audit/system_internal_audit_detail_page.dart +++ b/lib/modules/internal_audit_module/pages/system_internal_audit/system_internal_audit_detail_page.dart @@ -20,6 +20,7 @@ import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/views/widgets/images/files_list.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart'; +import 'package:test_sa/views/widgets/requests/request_status.dart'; class SystemInternalAuditDetailPage extends StatefulWidget { static const String id = "/details-system-internal-audit"; @@ -79,17 +80,45 @@ class _SystemInternalAuditDetailPageState extends State SystemInternalAuditDetailPage(auditId: requestDetails!.id!))); + Navigator.push(context, MaterialPageRoute(builder: (context) => SystemInternalAuditDetailPage(auditId: requestData!.id!))); }); } return Column( @@ -85,9 +85,12 @@ class SystemInternalAuditItemView extends StatelessWidget { ), 8.height, (requestDetails?.nameOfType ?? "Internal Audit Request").heading5(context), + + infoWidget(label: context.translation.requestNo, value: requestDetails!.requestNo, context: context), infoWidget(label: context.translation.assetNumber, value: requestDetails!.assetNo, context: context), infoWidget(label: context.translation.assetSN, value: requestDetails!.assetSN, context: context), infoWidget(label: context.translation.model, value: requestDetails!.model, context: context), + infoWidget(label: context.translation.site, value: requestDetails!.site, context: context), 8.height, // infoWidget(label: context.translation.site, value: requestDetails!.site, context: context), 8.height, diff --git a/lib/modules/loan_module/models/medical_department_model.dart b/lib/modules/loan_module/models/medical_department_model.dart index 08a6b200..1b0bbcb9 100644 --- a/lib/modules/loan_module/models/medical_department_model.dart +++ b/lib/modules/loan_module/models/medical_department_model.dart @@ -1,18 +1,20 @@ import 'package:test_sa/models/base.dart'; class MedicalDepartmentModel extends Base { - MedicalDepartmentModel({ - this.departmentName, this.departmentCode, this.ntCode, this.costCenterNumber, this.costCenterName, this.name, this.id, this.createdBy, this.createdDate, this.modifiedBy, this.modifiedDate - }) : super(identifier: id?.toString() ?? '', name: departmentName); // Handle potential null id + MedicalDepartmentModel( + {this.departmentName, this.departmentCode, this.ntCode, this.costCenterNumber, this.costCenterName, this.name, this.id, this.createdBy, this.createdDate, this.modifiedBy, this.modifiedDate}) + : super(identifier: id?.toString() ?? '', name: departmentName); // Handle potential null id MedicalDepartmentModel.fromJson(Map json) { + id = json['id']; + identifier = id?.toString() ?? ''; + name = json['departmentName'] ?? json['name']; departmentName = json['departmentName'] ?? json['name']; departmentCode = json['departmentCode']; ntCode = json['ntCode']; costCenterNumber = json['costCenterNumber']; costCenterName = json['costCenterName']; name = json['name']; - id = json['id']; createdBy = json['createdBy']; createdDate = json['createdDate']; modifiedBy = json['modifiedBy']; @@ -30,6 +32,4 @@ class MedicalDepartmentModel extends Base { String? createdDate; String? modifiedBy; String? modifiedDate; - - } diff --git a/lib/modules/loan_module/pages/create_loan_request_page.dart b/lib/modules/loan_module/pages/create_loan_request_page.dart index 9590a9f4..fe76e39b 100644 --- a/lib/modules/loan_module/pages/create_loan_request_page.dart +++ b/lib/modules/loan_module/pages/create_loan_request_page.dart @@ -16,14 +16,9 @@ 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/building.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/room_model.dart'; import 'package:test_sa/models/new_models/site.dart'; -import 'package:test_sa/models/new_models/task_request/task_request_model.dart'; import 'package:test_sa/models/new_models/task_request/task_type_model.dart'; -import 'package:test_sa/models/service_request/pending_service_request_model.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'; @@ -39,20 +34,15 @@ 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/task_request_provider/task_job_provider.dart'; -import 'package:test_sa/providers/task_request_provider/task_request_provider.dart'; -import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; -import 'package:test_sa/views/widgets/equipment/asset_picker.dart'; import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; - import '../../../../../../new_views/common_widgets/default_app_bar.dart'; -import '../../../models/new_models/department.dart'; class CreateLoanRequestPage extends StatefulWidget { static const String id = "/create-loan"; int? workOrderId; + WorkOrderData? workOrder; - CreateLoanRequestPage({Key? key, this.workOrderId}) : super(key: key); + CreateLoanRequestPage({Key? key, this.workOrderId, this.workOrder}) : super(key: key); @override _CreateLoanRequestPageState createState() => _CreateLoanRequestPageState(); @@ -62,7 +52,6 @@ class _CreateLoanRequestPageState extends State with Tick final List attachments = []; final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); - Asset? device; TaskType? selectedType; final LoanFormModel _loanFormModel = LoanFormModel(); @@ -70,11 +59,14 @@ class _CreateLoanRequestPageState extends State with Tick bool get isBackUpRequest => widget.workOrderId != null; + List loanTypes = []; + @override void initState() { super.initState(); Provider.of(context, listen: false).reset(); Provider.of(context, listen: false).reset(); + loanTypes = [Lookup(id: 0, name: "Standard", value: 1), Lookup(id: 1, name: "Backup", value: 2)]; } @override @@ -92,23 +84,55 @@ class _CreateLoanRequestPageState extends State with Tick crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ + SingleItemDropDownMenu( + context: context, + title: "Loan Type", + enabled: false, + staticData: loanTypes, + initialValue: isBackUpRequest ? loanTypes[1] : loanTypes[0], + showShadow: false, + backgroundColor: AppColor.fieldBgColor(context), + showAsBottomSheet: true, + onSelect: (value) {}, + ), + 16.height, if (isBackUpRequest) ...[ - scanAssetButton(), + 'Asset Information'.addTranslation.bodyText(context).custom(color: AppColor.black10), + 8.height, + Text( + '${context.translation.assetName}: ${widget.workOrder!.assetNdModel!.name?.cleanupWhitespace?.capitalizeFirstOfEach}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + '${context.translation.assetNumber}: ${widget.workOrder!.asset!.assetNumber}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + '${context.translation.serialNo}: ${widget.workOrder!.asset!.assetSerialNo}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + '${context.translation.model}: ${widget.workOrder!.model?.name!.cleanupWhitespace?.capitalizeFirstOfEach}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), + Text( + '${context.translation.manufacture}: ${widget.workOrder!.manufacturer?.name?.cleanupWhitespace?.capitalizeFirstOfEach}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), 16.height, ], + ...doctorInfoSection(), // ...contactInfoSection(), - // 16.height, - ...itemDetailsSection(), 16.height, - ...doctorInfoSection(), + ...itemDetailsSection(), 16.height, ...vendorDetailsSection(), 16.height, AttachmentPicker( label: context.translation.attachments, attachment: attachments, - buttonColor: AppColor.black10, onlyImages: false, + showAsListView: true, buttonIcon: 'image-plus'.toSvgAsset(color: context.isDark ? AppColor.primary10 : AppColor.neutral120), onChange: (attachments) { attachments = attachments; @@ -473,24 +497,8 @@ class _CreateLoanRequestPageState extends State with Tick ]; } - Widget scanAssetButton() { - return AssetPicker( - device: device, - showLoading: false, - borderColor: AppColor.black20, - onPick: (asset) async { - device = asset; - setState(() {}); - }, - ); - } - Future _submit() async { FocusScope.of(context).unfocus(); - if (isBackUpRequest && device == null) { - "Please scan or pick asset".showToast; - return; - } if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); @@ -507,7 +515,12 @@ class _CreateLoanRequestPageState extends State with Tick body["requestorUserID"] = context.userProvider.user!.userID; if (isBackUpRequest) { - body["assetId"] = device!.id; + body["assetId"] = widget.workOrder!.asset!.id; + body["assetName"] = widget.workOrder!.assetNdModel!.name; + body["assetNumber"] = widget.workOrder!.asset!.assetNumber; + body["assetSerialNumber"] = widget.workOrder!.asset!.assetSerialNo; + body["model"] = widget.workOrder!.model?.name; + body["manufacturer"] = widget.workOrder!.manufacturer?.name; body["cMWOItemId"] = widget.workOrderId; } bool isSuccess = await loanProvider.addLoanRequest(body); diff --git a/lib/modules/loan_module/provider/loan_provider.dart b/lib/modules/loan_module/provider/loan_provider.dart index b5cb0093..b2a3a5e3 100644 --- a/lib/modules/loan_module/provider/loan_provider.dart +++ b/lib/modules/loan_module/provider/loan_provider.dart @@ -1,4 +1,5 @@ import 'package:flutter/cupertino.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:http/http.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; @@ -8,9 +9,10 @@ import 'dart:convert'; class LoanProvider extends ChangeNotifier { Future addLoanRequest(Map body) async { try { - Response response = await ApiManager.instance.post(URLs.addLoan, body: body); + Response response = await ApiManager.instance.post(URLs.addLoan, body: body, showToast: false); if (response.statusCode >= 200 && response.statusCode < 300) { - // trafRequestDataModel = TrafRequestDataModel.fromJson(json.decode(response.body)["data"]); + String message = (jsonDecode(response.body)["data"] ?? "") + " " + (jsonDecode(response.body)["message"] ?? ""); + Fluttertoast.showToast(msg: message ?? "", toastLength: Toast.LENGTH_LONG); return true; } return false; diff --git a/lib/modules/tm_module/device_transfer/device_transfer_details.dart b/lib/modules/tm_module/device_transfer/device_transfer_details.dart index b5761a69..e249bd35 100644 --- a/lib/modules/tm_module/device_transfer/device_transfer_details.dart +++ b/lib/modules/tm_module/device_transfer/device_transfer_details.dart @@ -9,6 +9,7 @@ import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/device/device_transfer.dart'; +import 'package:test_sa/modules/cx_module/chat/chat_widget.dart'; import 'package:test_sa/views/widgets/images/files_list.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; @@ -22,8 +23,9 @@ import 'update_device_transfer.dart'; class DeviceTransferDetails extends StatefulWidget { final DeviceTransfer model; + final int moduleId; - const DeviceTransferDetails({Key? key, required this.model}) : super(key: key); + const DeviceTransferDetails({Key? key, required this.model, required this.moduleId}) : super(key: key); @override State createState() => _DeviceTransferDetailsState(); @@ -131,6 +133,7 @@ class _DeviceTransferDetailsState extends State { ] else ...[ // sender card _buildCard( + _model!, isSender: true, site: _model?.senderSiteName?.cleanupWhitespace.capitalizeFirstOfEach ?? "", dept: _model?.senderDepartmentName?.cleanupWhitespace.capitalizeFirstOfEach ?? "", @@ -150,6 +153,7 @@ class _DeviceTransferDetailsState extends State { 8.height, // receiver card _buildCard( + _model!, isSender: false, site: _model?.destSiteName?.cleanupWhitespace.capitalizeFirstOfEach ?? "", dept: _model?.destDepartmentName?.cleanupWhitespace.capitalizeFirstOfEach ?? "", @@ -215,7 +219,17 @@ class _DeviceTransferDetailsState extends State { ], ), ], - ), + ).expanded, + if (context.userProvider.isEngineer || context.userProvider.isNurse) + ChatWidget( + moduleId: widget.moduleId, + isShow: _model!.senderMachineStatusValue! != 4, + isReadOnly: _model!.senderMachineStatusValue! != 1, + requestId: widget.model.id!.toInt(), + assigneeEmployeeNumber: _model!.senderAssignedEmployeeNumber, + myLoginUserID: context.userProvider.user!.username!, + contactEmployeeINumber: _model!.assetTransferContactPersons!.first.employeeNumber, + ), if ((_userProvider!.user?.type == UsersTypes.engineer)) if (isCurrentEngineerEligibleForEdit && isCurrentRequestEditAble) "edit".toSvgAsset(height: 40, width: 40).onPress(() async { @@ -248,7 +262,8 @@ class _DeviceTransferDetailsState extends State { ).toShadowContainer(context); } - _buildCard({required String site, String? building, String? dept, String? floor, required String comment, required bool isSender, StatusLabel? statusLabel, String? assignTo}) { + _buildCard(DeviceTransfer _deviceTransfer, + {required String site, String? building, String? dept, String? floor, required String comment, required bool isSender, StatusLabel? statusLabel, String? assignTo}) { bool isCurrentEngineerEligibleForEdit = isSender ? _model?.senderAssignedEmployeeId == _userProvider!.user?.userID : _model?.receiverAssignedEmployeeId == _userProvider!.user?.userID; bool isCurrentRequestClosed = isSender ? ((_model?.senderMachineStatusValue == 3)) : ((_model?.receiverMachineStatusValue == 3)); @@ -265,7 +280,17 @@ class _DeviceTransferDetailsState extends State { if (statusLabel != null) 8.height, isSender ? context.translation.senderDetails.heading5(context) : context.translation.receiverDetails.heading5(context), ], - ), + ).expanded, + if (context.userProvider.isEngineer || context.userProvider.isNurse) + ChatWidget( + moduleId: widget.moduleId, + isShow: (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!, + contactEmployeeINumber: _deviceTransfer.assetTransferContactPersons!.first.employeeNumber, + ), if ((_userProvider!.user?.type == UsersTypes.engineer)) if (isCurrentEngineerEligibleForEdit && !isCurrentRequestClosed) @@ -273,7 +298,7 @@ class _DeviceTransferDetailsState extends State { // ? (!(_model?.senderMachineStatusName?.toLowerCase()?.contains("close") ?? false) && !(_model?.senderMachineStatusName?.toLowerCase()?.contains("complete") ?? false)) // : (!(_model?.receiverMachineStatusName?.toLowerCase()?.contains("close") ?? false) && !(_model?.receiverMachineStatusName?.toLowerCase()?.contains("complete") ?? false))) // - "edit".toSvgAsset(height: 48, width: 48).onPress(() async { + "edit".toSvgAsset(height: 48, width: 48).onPress(() async { bool isReload = (await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateDeviceTransfer(model: _model!, isSender: isSender)))) as bool; if (isReload ?? false) { setState(() {}); diff --git a/lib/modules/tm_module/gas_refill/gas_refill_details.dart b/lib/modules/tm_module/gas_refill/gas_refill_details.dart index a6e60491..00ac17aa 100644 --- a/lib/modules/tm_module/gas_refill/gas_refill_details.dart +++ b/lib/modules/tm_module/gas_refill/gas_refill_details.dart @@ -28,8 +28,9 @@ import 'update_gas_refill_request.dart'; class GasRefillDetailsPage extends StatefulWidget { GasRefillModel model; String? priority, date; + final int moduleId; - GasRefillDetailsPage({Key? key, this.priority, this.date, required this.model}) : super(key: key); + GasRefillDetailsPage({Key? key, this.priority, this.date, required this.model, required this.moduleId}) : super(key: key); @override State createState() => _GasRefillDetailsPageState(); @@ -59,21 +60,22 @@ class _GasRefillDetailsPageState extends State { appBar: DefaultAppBar( title: context.translation.gasRefillDetails, actions: [ - // if (context.userProvider.isEngineer || context.userProvider.isNurse) - // Selector( - // selector: (_, myModel) => myModel.gasRefillModel, // Selects only the userName - // builder: (_, _gasRefillModel, __) { - // if (_gasRefillModel == null) return const SizedBox(); - // return ChatWidget( - // moduleId: 2, - // isShow: _gasRefillModel.status!.value! == 1, - // // isReadOnly: _gasRefillModel.status!.value! == 1, - // requestId: widget.model.id!.toInt(), - // assigneeEmployeeNumber: _gasRefillModel.assignedEmployee!.name!, - // myLoginUserID: context.userProvider.user!.username!, - // contactEmployeeINumber: _gasRefillModel.gasRefillContactPerson!.first.employeeCode!, - // ); - // }) + if (context.userProvider.isEngineer || context.userProvider.isNurse) + Selector( + selector: (_, myModel) => myModel.gasRefillModel, // Selects only the userName + builder: (_, _gasRefillModel, __) { + if (_gasRefillModel == null) return const SizedBox(); + + return ChatWidget( + moduleId: widget.moduleId, + isShow: _gasRefillModel.status!.value! != 0, + isReadOnly: _gasRefillModel.status!.value! != 1, + requestId: widget.model.id!.toInt(), + assigneeEmployeeNumber: _gasRefillModel.assignedEmployee?.employeeId!, + myLoginUserID: context.userProvider.user!.username!, + contactEmployeeINumber: _gasRefillModel.gasRefillContactPerson!.first.employeeCode!, + ); + }) ], ), key: _scaffoldKey, diff --git a/lib/modules/tm_module/tasks/task_request_detail_view.dart b/lib/modules/tm_module/tasks/task_request_detail_view.dart index e5b5bdb5..91a75fc7 100644 --- a/lib/modules/tm_module/tasks/task_request_detail_view.dart +++ b/lib/modules/tm_module/tasks/task_request_detail_view.dart @@ -11,6 +11,7 @@ import 'package:test_sa/models/all_requests_and_count_model.dart'; import 'package:test_sa/models/new_models/task_request/task_request_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/cx_module/chat/chat_widget.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/working_time_tile.dart'; import 'package:test_sa/providers/task_request_provider/task_request_provider.dart'; @@ -29,8 +30,9 @@ class TaskRequestDetailsView extends StatefulWidget { static const String id = "/task-request-detail"; final int taskId; final RequestsDetails? requestDetails; + final int moduleId; - const TaskRequestDetailsView({Key? key, required this.taskId, this.requestDetails}) : super(key: key); + const TaskRequestDetailsView({Key? key, required this.taskId, this.requestDetails, required this.moduleId}) : super(key: key); @override _TaskRequestDetailsViewState createState() { @@ -65,7 +67,27 @@ class _TaskRequestDetailsViewState extends State { Widget build(BuildContext context) { userProvider ??= Provider.of(context, listen: false); return Scaffold( - appBar: DefaultAppBar(title: context.translation.taskRequest), + appBar: DefaultAppBar( + title: context.translation.taskRequest, + actions: [ + if (context.userProvider.isEngineer || context.userProvider.isNurse) + Selector( + 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, + ); + }) + ], + ), body: Consumer(builder: (context, taskProvider, child) { TaskData? taskModel = taskProvider.taskRequestModel; return taskProvider.isLoading diff --git a/lib/modules/tm_module/tasks/task_request_item_view.dart b/lib/modules/tm_module/tasks/task_request_item_view.dart index 3cc6bd05..2c164df3 100644 --- a/lib/modules/tm_module/tasks/task_request_item_view.dart +++ b/lib/modules/tm_module/tasks/task_request_item_view.dart @@ -68,7 +68,8 @@ class TaskRequestItemView extends StatelessWidget { Navigator.of(context).push(MaterialPageRoute( builder: (_) => TaskRequestDetailsView( taskId: requestData!.id!, - requestDetails: RequestsDetails(nameOfType: requestData?.nameOfType, status: requestData?.statusName, priority: requestData?.priorityName, date: requestData?.transactionDate), + moduleId: requestData!.transactionNo!, + requestDetails: RequestsDetails(nameOfType: requestData?.nameOfType, status: requestData?.statusName, priority: requestData?.priorityName, date: requestData?.transactionDate, ), ))); }); } @@ -122,6 +123,7 @@ class TaskRequestItemView extends StatelessWidget { Navigator.of(context).push(MaterialPageRoute( builder: (_) => TaskRequestDetailsView( taskId: requestDetails!.id!, + moduleId: requestDetails!.transactionType!, requestDetails: requestDetails, ))); }); diff --git a/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart b/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart index 26076417..ea9963d2 100644 --- a/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart +++ b/lib/new_views/pages/land_page/my_request/all_requests_filter_page.dart @@ -102,7 +102,9 @@ class _AllRequestsFilterPageState extends State { types = {"TRAF": 9}; } if (context.userProvider.isQualityUser) { - types = {'Equipment Internal Audit': 10, 'System Internal Audit': 11}; + if (context.settingProvider.isUserFlowMedical) types = {'Recall and Alert': 7}; + types['Equipment Internal Audit'] = 10; + types['System Internal Audit'] = 11; } final statuses = { diff --git a/lib/new_views/pages/land_page/my_request/my_requests_page.dart b/lib/new_views/pages/land_page/my_request/my_requests_page.dart index d482356e..0a31b856 100644 --- a/lib/new_views/pages/land_page/my_request/my_requests_page.dart +++ b/lib/new_views/pages/land_page/my_request/my_requests_page.dart @@ -83,6 +83,7 @@ class _MyRequestsPageState extends State { if (context.userProvider.isQualityUser) { 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'), ]; diff --git a/lib/new_views/pages/land_page/requests/device_item_view.dart b/lib/new_views/pages/land_page/requests/device_item_view.dart index 008ce1e8..dfb12d40 100644 --- a/lib/new_views/pages/land_page/requests/device_item_view.dart +++ b/lib/new_views/pages/land_page/requests/device_item_view.dart @@ -77,7 +77,7 @@ class DeviceItemView extends StatelessWidget { ), ], ).toShadowContainer(context, withShadow: showShadow).onPress(() { - Navigator.of(context).push(MaterialPageRoute(builder: (_) => DeviceTransferDetails(model: DeviceTransfer(id: requestData!.id!)))); + Navigator.of(context).push(MaterialPageRoute(builder: (_) => DeviceTransferDetails(model: DeviceTransfer(id: requestData!.id!), moduleId: requestData!.transactionNo!))); }); } @@ -138,7 +138,11 @@ class DeviceItemView extends StatelessWidget { ), ], ).toShadowContainer(context, withShadow: showShadow).onPress(() { - Navigator.of(context).push(MaterialPageRoute(builder: (_) => DeviceTransferDetails(model: DeviceTransfer(id: requestDetails!.id!)))); + Navigator.of(context).push(MaterialPageRoute( + builder: (_) => DeviceTransferDetails( + model: DeviceTransfer(id: requestDetails!.id!), + moduleId: requestDetails!.transactionType!, + ))); }); } diff --git a/lib/new_views/pages/land_page/requests/gas_refill_item_view.dart b/lib/new_views/pages/land_page/requests/gas_refill_item_view.dart index 1143487a..bd6ac0a7 100644 --- a/lib/new_views/pages/land_page/requests/gas_refill_item_view.dart +++ b/lib/new_views/pages/land_page/requests/gas_refill_item_view.dart @@ -74,6 +74,7 @@ class GasRefillItemView extends StatelessWidget { builder: (_) => GasRefillDetailsPage( priority: requestData!.priorityName, date: requestData!.transactionDate!, + moduleId: requestData!.transactionNo!, model: GasRefillModel(id: requestData!.id), ), ), @@ -135,6 +136,7 @@ class GasRefillItemView extends StatelessWidget { builder: (_) => GasRefillDetailsPage( priority: requestDetails!.priority!, date: requestDetails!.date, + moduleId: requestDetails!.transactionType!, model: GasRefillModel(id: requestDetails!.id), ), ), diff --git a/lib/providers/task_request_provider/task_request_provider.dart b/lib/providers/task_request_provider/task_request_provider.dart index e3d38a4b..1a517d73 100644 --- a/lib/providers/task_request_provider/task_request_provider.dart +++ b/lib/providers/task_request_provider/task_request_provider.dart @@ -77,6 +77,7 @@ class TaskRequestProvider extends ChangeNotifier { Future getTaskById({required int id, bool? showLoading = true}) async { try { isLoading = showLoading ?? true; + taskRequestModel = null; notifyListeners(); final response = await ApiManager.instance.get(URLs.getTaskByIdUrl + "?taskJobId=$id"); stateCode = response.statusCode; @@ -129,7 +130,6 @@ class TaskRequestProvider extends ChangeNotifier { isLoading = false; notifyListeners(); if (stateCode == 200) { - return true; } return false; diff --git a/lib/views/widgets/images/files_list.dart b/lib/views/widgets/images/files_list.dart index 9a24e097..3c3a120c 100644 --- a/lib/views/widgets/images/files_list.dart +++ b/lib/views/widgets/images/files_list.dart @@ -1,10 +1,15 @@ import 'dart:io'; +import 'package:ellipsized_text/ellipsized_text.dart'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:open_file/open_file.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/extensions/int_extensions.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/loaders/image_loader.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -12,78 +17,180 @@ import 'package:url_launcher/url_launcher.dart'; class FilesList extends StatelessWidget { final List images; final EdgeInsets? padding; + final bool showAsListView; - const FilesList({Key? key, this.images = const [], this.padding}) : super(key: key); + const FilesList({Key? key, this.images = const [], this.padding, this.showAsListView = false}) : super(key: key); @override Widget build(BuildContext context) { - return GridView.builder( - padding: const EdgeInsets.only(top: 8, bottom: 8), - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 6, mainAxisSpacing: 8, crossAxisSpacing: 8), - itemCount: images.length, - itemBuilder: (context, itemIndex) { - if (!images[itemIndex].contains(".")) { - return const Text("Bad\nFile"); - } - var isImage = images[itemIndex].split(".").last.toLowerCase() == "png" || images[itemIndex].split(".").last.toLowerCase() == "jpg" || images[itemIndex].split(".").last.toLowerCase() == "jpeg"; - var isPdf = images[itemIndex].split(".").last.toLowerCase() == "pdf"; - var isExcel = images[itemIndex].split(".").last.toLowerCase() == "xlsx"; + return showAsListView + ? ListView.separated( + shrinkWrap: true, + padding: const EdgeInsets.only(top: 8), + physics: const NeverScrollableScrollPhysics(), + itemBuilder: (cxt, itemIndex) { + if (!images[itemIndex].contains(".")) { + return const Text("Bad\nFile"); + } + var isImage = + images[itemIndex].split(".").last.toLowerCase() == "png" || images[itemIndex].split(".").last.toLowerCase() == "jpg" || images[itemIndex].split(".").last.toLowerCase() == "jpeg"; + var isPdf = images[itemIndex].split(".").last.toLowerCase() == "pdf"; + var isExcel = images[itemIndex].split(".").last.toLowerCase() == "xlsx"; - return Container( - decoration: ShapeDecoration( - color: Colors.white, - shape: RoundedRectangleBorder( - side: const BorderSide(width: 1, color: Color(0xFFEAF1F4)), - borderRadius: BorderRadius.circular(8), - ), - ), - child: ClipRRect( - borderRadius: BorderRadius.circular(8), - child: (isImage - ? (_isLocalUrl(images[itemIndex]) - ? Image.file(File(images[itemIndex])) - : ImageLoader( - url: images[itemIndex], - boxFit: BoxFit.cover, - height: 48, - width: 48, - )) - : Image.asset("assets/images/${isPdf ? "pdf" : isExcel ? "excel" : "doc"}.png")), - ), - ).onPress(() async { - if (isImage) { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => Scaffold( - body: SafeArea( - child: Stack( - children: [ - // InteractiveViewer(child: Image(image: getImageObject(itemIndex))).center, - InteractiveViewer(child: getImageWidget(itemIndex)).center, - const ABackButton(), - ], + return Row( + children: [ + Container( + width: 48.toScreenWidth, + height: 48.toScreenWidth, + decoration: ShapeDecoration( + color: Colors.white, + shape: RoundedRectangleBorder( + side: const BorderSide(width: 1, color: Color(0xFFEAF1F4)), + borderRadius: BorderRadius.circular(8), + ), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: (isImage + ? (_isLocalUrl(images[itemIndex]) + ? Image.file(File(images[itemIndex])) + : ImageLoader( + url: images[itemIndex], + boxFit: BoxFit.cover, + height: 48, + width: 48, + )) + : Image.asset("assets/images/${isPdf ? "pdf" : isExcel ? "excel" : "doc"}.png")), ), ), - ), - ), - ); - } else if (_isLocalUrl(images[itemIndex])) { - OpenFile.open(images[itemIndex]); - } else { - try { - if (!await launchUrl(Uri.parse(images[itemIndex]), mode: LaunchMode.externalApplication)) { - Fluttertoast.showToast(msg: "UnExpected Error with file."); - throw Exception('Could not launch '); + 8.width, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + EllipsizedText( + images[itemIndex].split("/").last, + style: AppTextStyles.heading6.copyWith(color: AppColor.black10), + type: EllipsisType.start, // or EllipsisType.middle + ), + 4.height, + RichText( + text: TextSpan( + text: 'Asset Guide | ', + style: AppTextStyles.bodyText.copyWith(color: AppColor.neutral120), + children: [ + TextSpan( + text: 'View', + recognizer: TapGestureRecognizer() + ..onTap = () async { + if (isImage) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => Scaffold( + body: SafeArea( + child: Stack( + children: [ + // InteractiveViewer(child: Image(image: getImageObject(itemIndex))).center, + InteractiveViewer(child: getImageWidget(itemIndex)).center, + const ABackButton(), + ], + ), + ), + ), + ), + ); + } else if (_isLocalUrl(images[itemIndex])) { + OpenFile.open(images[itemIndex]); + } else { + try { + if (!await launchUrl(Uri.parse(images[itemIndex]), mode: LaunchMode.externalApplication)) { + Fluttertoast.showToast(msg: "UnExpected Error with file."); + throw Exception('Could not launch '); + } + } catch (ex) { + Fluttertoast.showToast(msg: "No Viewer found."); + } + } + }, + style: AppTextStyles.bodyText.copyWith(color: AppColor.primary10, decoration: TextDecoration.underline), + ), + ], + ), + ), + ], + ).expanded + ], + ); + }, + separatorBuilder: (cxt, index) => 8.height, + itemCount: images.length) + : GridView.builder( + padding: const EdgeInsets.only(top: 8, bottom: 8), + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 6, mainAxisSpacing: 8, crossAxisSpacing: 8), + itemCount: images.length, + itemBuilder: (context, itemIndex) { + if (!images[itemIndex].contains(".")) { + return const Text("Bad\nFile"); } - } catch (ex) { - Fluttertoast.showToast(msg: "No Viewer found."); - } - } - }); - }, - ); + var isImage = + images[itemIndex].split(".").last.toLowerCase() == "png" || images[itemIndex].split(".").last.toLowerCase() == "jpg" || images[itemIndex].split(".").last.toLowerCase() == "jpeg"; + var isPdf = images[itemIndex].split(".").last.toLowerCase() == "pdf"; + var isExcel = images[itemIndex].split(".").last.toLowerCase() == "xlsx"; + + return Container( + decoration: ShapeDecoration( + color: Colors.white, + shape: RoundedRectangleBorder( + side: const BorderSide(width: 1, color: Color(0xFFEAF1F4)), + borderRadius: BorderRadius.circular(8), + ), + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(8), + child: (isImage + ? (_isLocalUrl(images[itemIndex]) + ? Image.file(File(images[itemIndex])) + : ImageLoader( + url: images[itemIndex], + boxFit: BoxFit.cover, + height: 48, + width: 48, + )) + : Image.asset("assets/images/${isPdf ? "pdf" : isExcel ? "excel" : "doc"}.png")), + ), + ).onPress(() async { + if (isImage) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => Scaffold( + body: SafeArea( + child: Stack( + children: [ + // InteractiveViewer(child: Image(image: getImageObject(itemIndex))).center, + InteractiveViewer(child: getImageWidget(itemIndex)).center, + const ABackButton(), + ], + ), + ), + ), + ), + ); + } else if (_isLocalUrl(images[itemIndex])) { + OpenFile.open(images[itemIndex]); + } else { + try { + if (!await launchUrl(Uri.parse(images[itemIndex]), mode: LaunchMode.externalApplication)) { + Fluttertoast.showToast(msg: "UnExpected Error with file."); + throw Exception('Could not launch '); + } + } catch (ex) { + Fluttertoast.showToast(msg: "No Viewer found."); + } + } + }); + }, + ); // return ListView.separated( // padding: padding ?? EdgeInsets.symmetric(horizontal: 32 * AppStyle.getScaleFactor(context)), diff --git a/lib/views/widgets/images/multi_image_picker.dart b/lib/views/widgets/images/multi_image_picker.dart index fbeeb9ce..e2973118 100644 --- a/lib/views/widgets/images/multi_image_picker.dart +++ b/lib/views/widgets/images/multi_image_picker.dart @@ -320,6 +320,7 @@ class AttachmentPicker extends StatefulWidget { Color? buttonColor; final Function(List)? onChange; final bool showAsGrid; + final bool showAsListView; AttachmentPicker( {Key? key, @@ -332,6 +333,7 @@ class AttachmentPicker extends StatefulWidget { this.onlyImages = false, this.onChange, this.showAsGrid = false, + this.showAsListView = false, this.buttonColor}) : super(key: key); @@ -357,29 +359,54 @@ class _AttachmentPickerState extends State { : onFilePicker), 16.height, if (widget.attachment.isNotEmpty) - Wrap( - spacing: 8.toScreenWidth, - children: List.generate( - widget.attachment.length, - (index) { - File image = File(widget.attachment[index].name!); - return MultiFilesPickerItem( - file: image, - enabled: widget.enabled, - onRemoveTap: (image) { - if (!widget.enabled) { - return; - } - widget.attachment.removeAt(index); - if (widget.onChange != null) { - widget.onChange!(widget.attachment); - } - setState(() {}); + widget.showAsListView + ? ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + padding: EdgeInsets.zero, + itemBuilder: (cxt, index) { + File image = File(widget.attachment[index].name!); + return MultiFilesPickerItem( + file: image, + showAsListView: widget.showAsListView, + enabled: widget.enabled, + onRemoveTap: (image) { + if (!widget.enabled) { + return; + } + widget.attachment.removeAt(index); + if (widget.onChange != null) { + widget.onChange!(widget.attachment); + } + setState(() {}); + }, + ); }, - ); - }, - ), - ), + separatorBuilder: (cxt, index) => 8.height, + itemCount: widget.attachment.length) + : Wrap( + spacing: 8.toScreenWidth, + children: List.generate( + widget.attachment.length, + (index) { + File image = File(widget.attachment[index].name!); + return MultiFilesPickerItem( + file: image, + enabled: widget.enabled, + onRemoveTap: (image) { + if (!widget.enabled) { + return; + } + widget.attachment.removeAt(index); + if (widget.onChange != null) { + widget.onChange!(widget.attachment); + } + setState(() {}); + }, + ); + }, + ), + ), ], ); } @@ -402,11 +429,6 @@ class _AttachmentPickerState extends State { } void showFileSourceSheet() async { - // if (widget.attachment.length >= 5) { - // Fluttertoast.showToast(msg: context.translation.maxImagesNumberIs5); - // return; - // } - ImageSource source = (await showModalBottomSheet( context: context, shape: const RoundedRectangleBorder( @@ -475,11 +497,6 @@ class _AttachmentPickerState extends State { } onFilePicker() async { - //TODO removed on request by Backend as they don't have anyissue with large number of files - // if (widget.attachment.length >= 5) { - // Fluttertoast.showToast(msg: context.translation.maxImagesNumberIs5); - // return; - // } ImageSource? source = await showModalBottomSheet( context: context, builder: (BuildContext context) { diff --git a/lib/views/widgets/images/multi_image_picker_item.dart b/lib/views/widgets/images/multi_image_picker_item.dart index 4669440e..662e7e4e 100644 --- a/lib/views/widgets/images/multi_image_picker_item.dart +++ b/lib/views/widgets/images/multi_image_picker_item.dart @@ -1,5 +1,7 @@ import 'dart:io'; +import 'package:ellipsized_text/ellipsized_text.dart'; +import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:open_file/open_file.dart'; @@ -18,8 +20,16 @@ class MultiFilesPickerItem extends StatelessWidget { final bool enabled; final Function(File) onRemoveTap; final VoidCallback? onRemove; + final bool showAsListView; - const MultiFilesPickerItem({Key? key, required this.file, required this.enabled, required this.onRemoveTap, this.onRemove}) : super(key: key); + const MultiFilesPickerItem({ + Key? key, + required this.file, + required this.enabled, + required this.onRemoveTap, + this.onRemove, + this.showAsListView = false, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -27,6 +37,96 @@ class MultiFilesPickerItem extends StatelessWidget { bool isPdf = file.path.split(".").last.toLowerCase() == "pdf"; bool isExcel = file.path.split(".").last.toLowerCase() == "xlsx"; + if (showAsListView) { + return Row( + children: [ + Container( + width: 48.toScreenWidth, + height: 48.toScreenWidth, + decoration: BoxDecoration( + color: AppColor.neutral90, + border: Border.all(width: 1, color: context.isDark ? AppColor.neutral30 : AppColor.neutral30), + image: DecorationImage( + image: getImage(isImage, isPdf, isExcel, file), + fit: BoxFit.cover, + ), + borderRadius: BorderRadius.circular(8), + ), + ), + 8.width, + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Flexible( + child: EllipsizedText( + file.path.split("/").last, + style: AppTextStyles.bodyText.copyWith(color: AppColor.black10), + type: EllipsisType.start, // or EllipsisType.middle + ), + ), + 8.width, + if (enabled) + InkWell( + child: "remove".toSvgAsset(width: 16), + onTap: () { + onRemoveTap(file); + if (onRemove != null) { + onRemove!(); + } + }, + ) + ], + ), + 4.height, + RichText( + text: TextSpan( + text: 'Asset Guide | ', + style: AppTextStyles.bodyText.copyWith(color: AppColor.neutral120), + children: [ + TextSpan( + text: 'View', + recognizer: TapGestureRecognizer() + ..onTap = () async { + if (isImage) { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => Scaffold( + appBar: const DefaultAppBar(), + body: SafeArea( + child: InteractiveViewer( + child: _isLocalUrl(file.path) + ? Image.file(file) + : ImageLoader( + url: URLs.getFileUrl(file.path), + boxFit: BoxFit.cover, + ), + ).center, + ), + ), + ), + ); + } else if (_isLocalUrl(file.path)) { + OpenFile.open(file.path); + } else { + if (!await launchUrl(Uri.parse(URLs.getFileUrl(file.path)!), mode: LaunchMode.externalApplication)) { + Fluttertoast.showToast(msg: "UnExpected Error with file."); + throw Exception('Could not launch'); + } + } + }, + style: AppTextStyles.bodyText.copyWith(color: AppColor.primary10, decoration: TextDecoration.underline), + ), + ], + ), + ), + ], + ).expanded + ], + ); + } + return SizedBox( width: 60.toScreenWidth, height: 60.toScreenWidth, diff --git a/pubspec.lock b/pubspec.lock index 44813421..f09bc410 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -265,6 +265,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + ellipsized_text: + dependency: "direct main" + description: + name: ellipsized_text + sha256: d4d372c2baf8d4adfb2ca3728c1e5955d1683e75fae774b311d557ad13317105 + url: "https://pub.dev" + source: hosted + version: "1.2.0" fake_async: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a7689979..a7edc369 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -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.3.11+30 +version: 1.4.0+31 environment: sdk: ">=3.5.0 <4.0.0" @@ -98,6 +98,7 @@ dependencies: tree_view_flutter: ^1.0.2 audio_waveforms: ^1.3.0 signalr_netcore: ^1.4.4 + ellipsized_text: ^1.2.0 local_auth_darwin: any dev_dependencies: