From bf44e5cbec7ad8fa86e625e242ed6a87b94e680c Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 3 Jul 2025 09:52:20 +0300 Subject: [PATCH] verification method issue fixed, if requester not confirms arrival. --- lib/controllers/api_routes/urls.dart | 2 + .../plan_preventive_visit_model.dart | 9 ++-- .../service_request_detail_provider.dart | 30 +++++++++--- .../action_button/footer_action_button.dart | 47 +++++++++++++++++-- .../service_request_detail_view.dart | 19 +++++--- .../components/assistant_employee_card.dart | 5 ++ .../components/external_request.dart | 5 ++ .../update_ppm/ppm_external_details_form.dart | 9 +++- .../ppm_wo/update_ppm/wo_info_form.dart | 2 +- .../tasks_wo/update_task_request_view.dart | 7 +++ .../update_device_transfer.dart | 6 +++ lib/views/widgets/timer/app_timer.dart | 6 +++ 12 files changed, 122 insertions(+), 25 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index a3c52227..5fe6560a 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -75,6 +75,8 @@ class URLs { static get engineerRejectUrl => '$_baseUrl/ServiceRequest/EngineerReject'; + static get returnToIHaveArrive => '$_baseUrl/ServiceRequest/ReturnToIHaveArrive'; + static get engineerFixRemotlyUrl => '$_baseUrl/ServiceRequest/EngineerFixRemotly'; static get engineerNeedVisitUrl => '$_baseUrl/ServiceRequest/EngineerNeedVisit'; diff --git a/lib/models/plan_preventive_visit/plan_preventive_visit_model.dart b/lib/models/plan_preventive_visit/plan_preventive_visit_model.dart index e092074c..b8f5fd94 100644 --- a/lib/models/plan_preventive_visit/plan_preventive_visit_model.dart +++ b/lib/models/plan_preventive_visit/plan_preventive_visit_model.dart @@ -26,6 +26,7 @@ class PlanPreventiveVisit { String? roomName; String? fromDate; String? creationDate; + String? createdDate; String? closedDate; String? toDate; AssignedEmployee? assignedEmployee; @@ -69,8 +70,9 @@ class PlanPreventiveVisit { this.departmentName, this.roomName, this.fromDate, - this.creationDate, - this.closedDate, + this.creationDate, + this.createdDate, + this.closedDate, this.toDate, this.assignedEmployee, this.acutalDateOfVisit, @@ -92,7 +94,7 @@ class PlanPreventiveVisit { this.preventiveVisitKits, this.preventiveVisitTimers, this.timerModelList, - this.ppMTimePicker, + this.ppMTimePicker, this.preventiveVisitSuppliers}); PlanPreventiveVisit.fromJson(Map json) { @@ -113,6 +115,7 @@ class PlanPreventiveVisit { roomName = json['roomName']; fromDate = json['fromDate']; creationDate = json['creationDate']; + createdDate = json['createdDate']; closedDate = json['closedDate']; toDate = json['toDate']; assignedEmployee = json['assignedEmployee'] != null ? AssignedEmployee.fromJson(json['assignedEmployee']) : null; diff --git a/lib/modules/cm_module/service_request_detail_provider.dart b/lib/modules/cm_module/service_request_detail_provider.dart index 93ff9fd3..7820a381 100644 --- a/lib/modules/cm_module/service_request_detail_provider.dart +++ b/lib/modules/cm_module/service_request_detail_provider.dart @@ -243,8 +243,8 @@ class ServiceRequestDetailProvider extends ChangeNotifier { } else { isReadOnlyRequest = false; } - }else{ - currentWorkOrder =null; + } else { + currentWorkOrder = null; } isLoading = false; notifyListeners(); @@ -257,12 +257,12 @@ class ServiceRequestDetailProvider extends ChangeNotifier { } //upload workorder attachment by engineer.. - Future addWorkOrderAttachment({required int woId, required List attachments,required List otherAttachment}) async { + Future addWorkOrderAttachment({required int woId, required List attachments, required List otherAttachment}) async { try { List woAttachments = []; - if(otherAttachment.isNotEmpty){ - woAttachments.addAll(otherAttachment); - } + if (otherAttachment.isNotEmpty) { + woAttachments.addAll(otherAttachment); + } for (var file in attachments) { String fileName = ServiceRequestUtils.isLocalUrl(file.path) ? ("${file.path.split("/").last}|${base64Encode(File(file.path).readAsBytesSync())}") : file.path; woAttachments.add(WorkOrderAttachments(id: 0, name: fileName)); @@ -373,6 +373,22 @@ class ServiceRequestDetailProvider extends ChangeNotifier { } } + Future switchToIHaveArrived() async { + Response response; + try { + final body = {"workOrderId": currentWorkOrder?.data?.requestId}; + response = await ApiManager.instance.post(URLs.returnToIHaveArrive, body: body); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + currentWorkOrder = await WorkOrderDetail.fromJson(json.decode(response.body)); + return true; + } + return false; + } catch (e) { + return false; + } + } + //engineerRejectWorkOrder...... Future engineerRejectWorkOrder() async { Response response; @@ -948,7 +964,7 @@ class ServiceRequestDetailProvider extends ChangeNotifier { isLoading = true; notifyListeners(); try { - final response = await ApiManager.instance.post(URLs.sendOtpUrl + "$workOrderId", body: {},showToast: false); + final response = await ApiManager.instance.post(URLs.sendOtpUrl + "$workOrderId", body: {}, showToast: false); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) {} isLoading = false; diff --git a/lib/modules/cm_module/views/components/action_button/footer_action_button.dart b/lib/modules/cm_module/views/components/action_button/footer_action_button.dart index d89b29af..4853cf43 100644 --- a/lib/modules/cm_module/views/components/action_button/footer_action_button.dart +++ b/lib/modules/cm_module/views/components/action_button/footer_action_button.dart @@ -3,6 +3,7 @@ import 'package:provider/provider.dart'; import 'package:test_sa/controllers/providers/api/user_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/models/enums/user_types.dart'; @@ -17,6 +18,7 @@ import 'package:test_sa/modules/cm_module/views/components/verify_arrival_view.d import 'package:test_sa/modules/cm_module/views/forms/asset_retired/verify_asset_detail.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_lazy_loading.dart'; import 'package:test_sa/new_views/swipe_module/dialoge/acknowledge_work_dialog.dart'; import 'package:test_sa/providers/service_request_providers/reject_reason_provider.dart'; @@ -242,11 +244,46 @@ class FooterActionButton { )); case WorkOrderNextStepEnum.waitingForRequesterToConfirm: return footerContainer( - child: AppFilledButton( - label: 'Waiting for requester to verify', - buttonColor: AppColor.neutral140, - textColor: AppColor.neutral150, - fontSize: 12.toScreenWidth, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AppFilledButton( + label: 'Waiting for requester to verify', + buttonColor: AppColor.neutral140, + textColor: AppColor.neutral150, + fontSize: 12.toScreenWidth, + ), + 12.height, + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon(Icons.info_outline_rounded, size: 16, color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + 6.width, + Text( + "If you're experiencing issues with verification, please select another method to continue", + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ).expanded, + ], + ), + 12.height, + AppFilledButton( + label: "Switch Arrival Method", + showIcon: true, + buttonColor: AppColor.green70, + onPressed: () { + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + Provider.of(context, listen: false).switchToIHaveArrived().then((value) { + Navigator.pop(context); + if (value) { + Navigator.push(context, MaterialPageRoute(builder: (context) => const VerifyArrivalView())); + } else { + "Failed to switch, please try again".showToast; + } + }); + }, + ) + ], )); case WorkOrderNextStepEnum.eFixRemotely: return footerContainer( 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 0215b6ad..247b0af7 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 @@ -86,13 +86,18 @@ class _ServiceRequestDetailViewState extends State { ], ), ).expanded, - FooterActionButton.requestDetailsFooterWidget( - workOrderNextStepStatus: requestProvider.currentWorkOrder!.data!.nextStep!.workOrderNextStepEnum!, - status: requestProvider.currentWorkOrder?.data?.status, - isEmpIsAssigned: requestProvider.currentWorkOrder!.data!.assignedEmployee != null, - activities: requestProvider.currentWorkOrder!.data?.activities ?? [], - userProvider: _userProvider, - context: context), + SafeArea( + top: false, + right: false, + left: false, + child: FooterActionButton.requestDetailsFooterWidget( + workOrderNextStepStatus: requestProvider.currentWorkOrder!.data!.nextStep!.workOrderNextStepEnum!, + status: requestProvider.currentWorkOrder?.data?.status, + isEmpIsAssigned: requestProvider.currentWorkOrder!.data!.assignedEmployee != null, + activities: requestProvider.currentWorkOrder!.data?.activities ?? [], + userProvider: _userProvider, + context: context), + ).toShadowContainer(context, padding: 0, showShadow: false, borderRadius: 0), ], ), //no need to show timer as discussed with backend diff --git a/lib/modules/cm_module/views/forms/maintenance_request/components/assistant_employee_card.dart b/lib/modules/cm_module/views/forms/maintenance_request/components/assistant_employee_card.dart index 6002b7e7..09a02718 100644 --- a/lib/modules/cm_module/views/forms/maintenance_request/components/assistant_employee_card.dart +++ b/lib/modules/cm_module/views/forms/maintenance_request/components/assistant_employee_card.dart @@ -118,6 +118,11 @@ class _AssistantEmployeeCardState extends State { // Handle the selected date and time here. if (selectedTime != null) { DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + if (requestDetailProvider.currentWorkOrder?.data?.requestedDate != null && selectedDateTime.isBefore(requestDetailProvider.currentWorkOrder!.data!.requestedDate!)) { + "Start time is before the request time.".showToast; + selectedTime = null; + return; + } if (selectedDateTime.isAfter(DateTime.now())) { "Start time is after than current time".showToast; selectedTime = null; diff --git a/lib/modules/cm_module/views/forms/maintenance_request/components/external_request.dart b/lib/modules/cm_module/views/forms/maintenance_request/components/external_request.dart index 9284610d..b6843244 100644 --- a/lib/modules/cm_module/views/forms/maintenance_request/components/external_request.dart +++ b/lib/modules/cm_module/views/forms/maintenance_request/components/external_request.dart @@ -147,6 +147,11 @@ class _ExternalMaintenanceRequestState extends State // Handle the selected date and time here. if (selectedTime != null) { DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + if (requestDetailProvider.currentWorkOrder?.data?.requestedDate != null && selectedDateTime.isBefore(requestDetailProvider.currentWorkOrder!.data!.requestedDate!)) { + "Start time is before the request time.".showToast; + selectedTime = null; + return; + } if (selectedDateTime.isAfter(DateTime.now())) { "Start time is after than current time".showToast; selectedTime = null; diff --git a/lib/modules/pm_module/ppm_wo/update_ppm/ppm_external_details_form.dart b/lib/modules/pm_module/ppm_wo/update_ppm/ppm_external_details_form.dart index 504562a3..2ce95ea3 100644 --- a/lib/modules/pm_module/ppm_wo/update_ppm/ppm_external_details_form.dart +++ b/lib/modules/pm_module/ppm_wo/update_ppm/ppm_external_details_form.dart @@ -185,7 +185,7 @@ class _ExternalDetailItemState extends State { backgroundColor: AppColor.neutral100, date: widget.model.startDateTime, formatDateWithTime: true, - from: DateTime.tryParse(_ppmProvider?.planPreventiveVisit?.creationDate ?? ''), + from: DateTime.tryParse(_ppmProvider?.planPreventiveVisit?.createdDate ?? ''), onDatePicker: (selectedDate) { showTimePicker( context: context, @@ -193,6 +193,11 @@ class _ExternalDetailItemState extends State { ).then((selectedTime) { if (selectedTime != null) { DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + if (DateTime.tryParse(_ppmProvider?.planPreventiveVisit?.createdDate ?? '') != null && selectedDateTime.isBefore(DateTime.tryParse(_ppmProvider?.planPreventiveVisit?.createdDate ?? '')!)) { + "Start time is before the request time.".showToast; + selectedTime = null; + return; + } if (selectedDateTime.isAfter(DateTime.now())) { "Start time is after than current time".showToast; selectedTime = null; @@ -223,7 +228,7 @@ class _ExternalDetailItemState extends State { date: widget.model.endDateTime, enable: widget.model.startDateTime != null, formatDateWithTime: true, - from: DateTime.tryParse(_ppmProvider?.planPreventiveVisit?.creationDate ?? ''), + from: DateTime.tryParse(_ppmProvider?.planPreventiveVisit?.createdDate ?? ''), onDatePicker: (selectedDate) { showTimePicker( context: context, diff --git a/lib/modules/pm_module/ppm_wo/update_ppm/wo_info_form.dart b/lib/modules/pm_module/ppm_wo/update_ppm/wo_info_form.dart index 03fbb0d2..0e12c5dc 100644 --- a/lib/modules/pm_module/ppm_wo/update_ppm/wo_info_form.dart +++ b/lib/modules/pm_module/ppm_wo/update_ppm/wo_info_form.dart @@ -363,7 +363,7 @@ class _WoInfoFormState extends State { width: double.infinity, timer: widget.planPreventiveVisit.tbsTimer, pickerTimer: widget.planPreventiveVisit.ppMTimePicker, - pickerFromDate: DateTime.tryParse(widget.planPreventiveVisit.creationDate ?? ''), + pickerFromDate: DateTime.tryParse(widget.planPreventiveVisit.createdDate ?? ''), onPick: (time) { widget.planPreventiveVisit.ppMTimePicker = time; }, diff --git a/lib/modules/tm_module/tasks_wo/update_task_request_view.dart b/lib/modules/tm_module/tasks_wo/update_task_request_view.dart index 813cb39a..6bff192a 100644 --- a/lib/modules/tm_module/tasks_wo/update_task_request_view.dart +++ b/lib/modules/tm_module/tasks_wo/update_task_request_view.dart @@ -648,6 +648,7 @@ class _AssistantEmployeeCardState extends State { hideShadow: true, backgroundColor: AppColor.neutral100, date: taskModel?.modelAssistantEmployees?.startDate, + // from: taskModel?.d, formatDateWithTime: true, onDatePicker: (selectedDate) { showTimePicker( @@ -657,6 +658,12 @@ class _AssistantEmployeeCardState extends State { // Handle the selected date and time here. if (selectedTime != null) { DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + // if (widget.pickerFromDate != null && selectedDateTime.isBefore(widget.pickerFromDate!)) { + // "Start time is before the request time.".showToast; + // _pickerStartAt = null; + // selectedTime = null; + // return; + // } if (selectedDateTime.isAfter(DateTime.now())) { "Start time is after than current time".showToast; selectedTime = null; diff --git a/lib/views/pages/device_transfer/update_device_transfer.dart b/lib/views/pages/device_transfer/update_device_transfer.dart index 7e038575..5270c36e 100644 --- a/lib/views/pages/device_transfer/update_device_transfer.dart +++ b/lib/views/pages/device_transfer/update_device_transfer.dart @@ -449,6 +449,7 @@ class _AssistantEmployeeCardState extends State { hideShadow: true, backgroundColor: AppColor.neutral100, date: widget.formModel?.modelAssistantEmployees?.startDate, + from: DateTime.tryParse(widget.formModel?.createdDate ?? ''), formatDateWithTime: true, onDatePicker: (selectedDate) { showTimePicker( @@ -458,6 +459,11 @@ class _AssistantEmployeeCardState extends State { // Handle the selected date and time here. if (selectedTime != null) { DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + if (DateTime.tryParse(widget.formModel?.createdDate ?? '') != null && selectedDateTime.isBefore(DateTime.tryParse(widget.formModel?.createdDate ?? '')!)) { + "Start time is before the request time.".showToast; + selectedTime = null; + return; + } if (selectedDateTime.isAfter(DateTime.now())) { "Start time is after than current time".showToast; selectedTime = null; diff --git a/lib/views/widgets/timer/app_timer.dart b/lib/views/widgets/timer/app_timer.dart index 9583cc5b..090f6913 100644 --- a/lib/views/widgets/timer/app_timer.dart +++ b/lib/views/widgets/timer/app_timer.dart @@ -174,6 +174,12 @@ class _AppTimerState extends State { ).then((selectedTime) { if (selectedTime != null) { _pickerStartAt = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + if (widget.pickerFromDate != null && _pickerStartAt!.isBefore(widget.pickerFromDate!)) { + "Start time is before the request time.".showToast; + _pickerStartAt = null; + selectedTime = null; + return; + } if (_pickerStartAt!.isAfter(DateTime.now())) { "Start time is after than current time".showToast; _pickerStartAt = null;