From 616ce9b630330f54c4b31009ffec16aa2512ba80 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 2 Jul 2025 09:58:44 +0300 Subject: [PATCH 1/5] timer picker end date selection fixed. --- lib/controllers/api_routes/urls.dart | 8 +-- .../components/assistant_employee_card.dart | 39 ++++++-------- .../components/external_request.dart | 53 ++++++++++++------- .../update_ppm/ppm_external_details_form.dart | 43 ++++++++------- .../ppm_wo/update_ppm/wo_info_form.dart | 26 ++++----- .../tasks_wo/update_task_request_view.dart | 51 +++++++++++------- .../update_device_transfer.dart | 29 +++++++--- lib/views/widgets/timer/app_timer.dart | 26 +++++---- 8 files changed, 158 insertions(+), 117 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index ff04c64b..a3c52227 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -3,14 +3,14 @@ class URLs { static const String appReleaseBuildNumber = "17"; - static const host1 = "https://atomsm.hmg.com"; // production url + // 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 = "https://atomsmuat.hmg.com"; // local UAT url - // static String _baseUrl = "$_host/mobile"; + static String _baseUrl = "$_host/mobile"; // static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis // static final String _baseUrl = "$_host/mobile"; // host local UAT - static final String _baseUrl = "$_host/v3/mobile"; // v3 for new CM,PM,TM + // static final String _baseUrl = "$_host/v3/mobile"; // v3 for new CM,PM,TM static String _host = host1; 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 cd265105..6002b7e7 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 @@ -107,7 +107,7 @@ class _AssistantEmployeeCardState extends State { label: context.translation.startTime, hideShadow: true, backgroundColor: AppColor.neutral100, - from:requestDetailProvider.currentWorkOrder?.data?.requestedDate, + from: requestDetailProvider.currentWorkOrder?.data?.requestedDate, date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate, formatDateWithTime: true, onDatePicker: (selectedDate) { @@ -117,13 +117,13 @@ class _AssistantEmployeeCardState extends State { ).then((selectedTime) { // Handle the selected date and time here. if (selectedTime != null) { - DateTime selectedDateTime = DateTime( - selectedDate.year, - selectedDate.month, - selectedDate.day, - selectedTime.hour, - selectedTime.minute, - ); + DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + if (selectedDateTime.isAfter(DateTime.now())) { + "Start time is after than current time".showToast; + selectedTime = null; + return; + } + requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate = selectedDateTime; requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); ServiceRequestUtils.calculateAndAssignWorkingHours( @@ -141,8 +141,9 @@ class _AssistantEmployeeCardState extends State { ADatePicker( label: context.translation.endTime, hideShadow: true, - from:requestDetailProvider.currentWorkOrder?.data?.requestedDate, + from: requestDetailProvider.currentWorkOrder?.data?.requestedDate, backgroundColor: AppColor.neutral100, + enable: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate != null, date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate, formatDateWithTime: true, to: DateTime.now(), @@ -154,25 +155,19 @@ class _AssistantEmployeeCardState extends State { // Handle the selected date and time here. if (selectedTime != null) { - final TimeOfDay now = TimeOfDay.now(); - final bool isBeforeNow = Utils.isBeforeOrEqualCurrentTime(selectedTime, now); - if (!isBeforeNow) { + selectedDate = selectedDate.add(Duration(hours: selectedTime.hour, minutes: selectedTime.minute)); + bool isBeforeCurrentTime = selectedDate.isBefore(DateTime.now()); + bool isAfterStartTime = selectedDate.isAfter(requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.startDate!); + if (!isBeforeCurrentTime) { "Please select a time before the current time.".showToast; return; } - DateTime selectedDateTime = DateTime( - selectedDate.year, - selectedDate.month, - selectedDate.day, - selectedTime.hour, - selectedTime.minute, - ); - if (requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate != null && - selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.startDate!)) { + if (!isAfterStartTime) { "End Date time must be greater then start date".showToast; return; } - requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate = selectedDateTime; + + requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate = selectedDate; requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); ServiceRequestUtils.calculateAndAssignWorkingHours( startTime: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate, 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 310c91dd..9284610d 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 @@ -146,13 +146,12 @@ class _ExternalMaintenanceRequestState extends State ).then((selectedTime) { // Handle the selected date and time here. if (selectedTime != null) { - DateTime selectedDateTime = DateTime( - selectedDate.year, - selectedDate.month, - selectedDate.day, - selectedTime.hour, - selectedTime.minute, - ); + DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + if (selectedDateTime.isAfter(DateTime.now())) { + "Start time is after than current time".showToast; + selectedTime = null; + return; + } requestDetailProvider.activityMaintenanceHelperModel?.supplierStartTime = selectedDateTime; requestDetailProvider.activityMaintenanceHelperModel?.supplierEndTime = null; requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); @@ -176,6 +175,7 @@ class _ExternalMaintenanceRequestState extends State backgroundColor: AppColor.neutral100, from: requestDetailProvider.currentWorkOrder?.data?.requestedDate, to: DateTime.now(), + enable: requestDetailProvider.activityMaintenanceHelperModel?.supplierStartTime != null, date: requestDetailProvider.activityMaintenanceHelperModel?.supplierEndTime, formatDateWithTime: true, onDatePicker: (selectedDate) { @@ -185,25 +185,38 @@ class _ExternalMaintenanceRequestState extends State ).then((selectedTime) { // Handle the selected date and time here. if (selectedTime != null) { - final TimeOfDay now = TimeOfDay.now(); - final bool isBeforeNow = Utils.isBeforeOrEqualCurrentTime(selectedTime, now); - if (!isBeforeNow) { + // final TimeOfDay now = TimeOfDay.now(); + // final bool isBeforeNow = Utils.isBeforeOrEqualCurrentTime(selectedTime, now); + // if (!isBeforeNow) { + // "Please select a time before the current time.".showToast; + // return; + // } + + + + selectedDate = selectedDate.add(Duration(hours: selectedTime.hour, minutes: selectedTime.minute)); + bool isBeforeCurrentTime = selectedDate.isBefore(DateTime.now()); + bool isAfterStartTime = selectedDate.isAfter(requestDetailProvider.activityMaintenanceHelperModel!.supplierStartTime!); + if (!isBeforeCurrentTime) { "Please select a time before the current time.".showToast; return; } - DateTime selectedDateTime = DateTime( - selectedDate.year, - selectedDate.month, - selectedDate.day, - selectedTime.hour, - selectedTime.minute, - ); - if (requestDetailProvider.activityMaintenanceHelperModel!.supplierStartTime != null && - selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.supplierStartTime!)) { + if (!isAfterStartTime) { "End Date time must be greater then start date".showToast; return; } - requestDetailProvider.activityMaintenanceHelperModel?.supplierEndTime = selectedDateTime; + + // if (requestDetailProvider.activityMaintenanceHelperModel!.supplierStartTime != null && + // selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.supplierStartTime!)) { + // "End Date time must be greater then start date".showToast; + // return; + // } + + + + + + requestDetailProvider.activityMaintenanceHelperModel?.supplierEndTime = selectedDate; requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); ServiceRequestUtils.calculateAndAssignWorkingHours( startTime: requestDetailProvider.activityMaintenanceHelperModel!.supplierStartTime, 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 456206f0..504562a3 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 @@ -1,5 +1,3 @@ -import 'dart:developer'; - import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/providers/api/ppm_provider.dart'; @@ -91,7 +89,7 @@ class ExternalDetailItem extends StatefulWidget { final PreventiveVisitSuppliers model; final VoidCallback onRemove; final int index; - final String ?createdDate; + final String? createdDate; const ExternalDetailItem({ Key? key, @@ -187,20 +185,19 @@ class _ExternalDetailItemState extends State { backgroundColor: AppColor.neutral100, date: widget.model.startDateTime, formatDateWithTime: true, - from:DateTime.tryParse(_ppmProvider?.planPreventiveVisit?.creationDate??'') , + from: DateTime.tryParse(_ppmProvider?.planPreventiveVisit?.creationDate ?? ''), onDatePicker: (selectedDate) { showTimePicker( context: context, initialTime: TimeOfDay.now(), ).then((selectedTime) { if (selectedTime != null) { - DateTime selectedDateTime = DateTime( - selectedDate.year, - selectedDate.month, - selectedDate.day, - selectedTime.hour, - selectedTime.minute, - ); + DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + if (selectedDateTime.isAfter(DateTime.now())) { + "Start time is after than current time".showToast; + selectedTime = null; + return; + } setState(() { widget.model.startDateTime = selectedDateTime; }); @@ -224,27 +221,29 @@ class _ExternalDetailItemState extends State { hideShadow: true, backgroundColor: AppColor.neutral100, date: widget.model.endDateTime, + enable: widget.model.startDateTime != null, formatDateWithTime: true, - from:DateTime.tryParse(_ppmProvider?.planPreventiveVisit?.creationDate??'') , + from: DateTime.tryParse(_ppmProvider?.planPreventiveVisit?.creationDate ?? ''), onDatePicker: (selectedDate) { showTimePicker( context: context, initialTime: TimeOfDay.now(), ).then((selectedTime) { if (selectedTime != null) { - DateTime selectedDateTime = DateTime( - selectedDate.year, - selectedDate.month, - selectedDate.day, - selectedTime.hour, - selectedTime.minute, - ); - if (widget.model.startDateTime != null && selectedDateTime.isBefore(widget.model.startDateTime!)) { - "End Date time must be greater than start date".showToast; + selectedDate = selectedDate.add(Duration(hours: selectedTime.hour, minutes: selectedTime.minute)); + bool isBeforeCurrentTime = selectedDate.isBefore(DateTime.now()); + bool isAfterStartTime = selectedDate.isAfter(widget.model.startDateTime!); + if (!isBeforeCurrentTime) { + "Please select a time before the current time.".showToast; + return; + } + if (!isAfterStartTime) { + "End Date time must be greater then start date".showToast; return; } + setState(() { - widget.model.endDateTime = selectedDateTime; + widget.model.endDateTime = selectedDate; }); ServiceRequestUtils.calculateAndAssignWorkingHours( startTime: widget.model.startDateTime, 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 1f82daa6..03fbb0d2 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 @@ -185,7 +185,7 @@ class _WoInfoFormState extends State { hideShadow: true, backgroundColor: AppColor.neutral100, date: widget.planPreventiveVisit.acutalDateOfVisit, - from: DateTime.tryParse(widget.planPreventiveVisit.creationDate??''), + from: DateTime.tryParse(widget.planPreventiveVisit.creationDate ?? ''), formatDateWithTime: true, onDatePicker: (selectedDate) { showTimePicker( @@ -193,19 +193,19 @@ class _WoInfoFormState extends State { initialTime: TimeOfDay.now(), ).then((selectedTime) { if (selectedTime != null) { - final TimeOfDay now = TimeOfDay.now(); - final bool isBeforeNow = Utils.isBeforeOrEqualCurrentTime(selectedTime, now); - if (!isBeforeNow) { - "Please select a time before the current time.".showToast; + // final TimeOfDay now = TimeOfDay.now(); + // final bool isBeforeNow = Utils.isBeforeOrEqualCurrentTime(selectedTime, now); + // if (!isBeforeNow) { + // "Please select a time before the current time.".showToast; + // return; + // } + + DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + if (selectedDateTime.isAfter(DateTime.now())) { + "Start time is after than current time".showToast; + selectedTime = null; return; } - DateTime selectedDateTime = DateTime( - selectedDate.year, - selectedDate.month, - selectedDate.day, - selectedTime.hour, - selectedTime.minute, - ); setState(() { widget.planPreventiveVisit.acutalDateOfVisit = selectedDateTime; }); @@ -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.creationDate ?? ''), 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 a41d4e94..813cb39a 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 @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; @@ -7,11 +8,11 @@ import 'package:test_sa/controllers/providers/api/all_requests_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/models/new_models/building.dart'; -import 'package:test_sa/models/new_models/department.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; 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/task_request/task_request_model.dart'; import 'package:test_sa/modules/cm_module/utilities/service_request_utils.dart'; @@ -33,6 +34,7 @@ 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/status/report/service_report_assistant_employee_menu.dart'; import 'package:test_sa/views/widgets/timer/app_timer.dart'; + import '../../../../models/new_models/site.dart'; import '../../../../models/new_models/work_order_detail_model.dart'; @@ -654,13 +656,12 @@ class _AssistantEmployeeCardState extends State { ).then((selectedTime) { // Handle the selected date and time here. if (selectedTime != null) { - DateTime selectedDateTime = DateTime( - selectedDate.year, - selectedDate.month, - selectedDate.day, - selectedTime.hour, - selectedTime.minute, - ); + DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + if (selectedDateTime.isAfter(DateTime.now())) { + "Start time is after than current time".showToast; + selectedTime = null; + return; + } taskModel?.modelAssistantEmployees?.startDate = selectedDateTime; taskRequestProvider.updateTaskModel(taskModel); ServiceRequestUtils.calculateAndAssignWorkingHours( @@ -680,6 +681,7 @@ class _AssistantEmployeeCardState extends State { hideShadow: true, backgroundColor: AppColor.neutral100, date: taskModel?.modelAssistantEmployees?.endDate, + enable: taskModel?.modelAssistantEmployees?.startDate != null, formatDateWithTime: true, onDatePicker: (selectedDate) { showTimePicker( @@ -688,19 +690,32 @@ class _AssistantEmployeeCardState extends State { ).then((selectedTime) { // Handle the selected date and time here. if (selectedTime != null) { - DateTime selectedDateTime = DateTime( - selectedDate.year, - selectedDate.month, - selectedDate.day, - selectedTime.hour, - selectedTime.minute, - ); + // DateTime selectedDateTime = DateTime( + // selectedDate.year, + // selectedDate.month, + // selectedDate.day, + // selectedTime.hour, + // selectedTime.minute, + // ); + // + // if (taskModel?.modelAssistantEmployees?.startDate != null && selectedDateTime.isBefore(taskModel!.modelAssistantEmployees!.startDate!)) { + // "End Date time must be greater then start date".showToast; + // return; + // } - if (taskModel?.modelAssistantEmployees?.startDate != null && selectedDateTime.isBefore(taskModel!.modelAssistantEmployees!.startDate!)) { + selectedDate = selectedDate.add(Duration(hours: selectedTime.hour, minutes: selectedTime.minute)); + bool isBeforeCurrentTime = selectedDate.isBefore(DateTime.now()); + bool isAfterStartTime = selectedDate.isAfter(taskModel!.modelAssistantEmployees!.startDate!); + if (!isBeforeCurrentTime) { + "Please select a time before the current time.".showToast; + return; + } + if (!isAfterStartTime) { "End Date time must be greater then start date".showToast; return; } - taskModel?.modelAssistantEmployees?.endDate = selectedDateTime; + + taskModel?.modelAssistantEmployees?.endDate = selectedDate; taskRequestProvider.updateTaskModel(taskModel); ServiceRequestUtils.calculateAndAssignWorkingHours( startTime: taskModel?.modelAssistantEmployees?.startDate, diff --git a/lib/views/pages/device_transfer/update_device_transfer.dart b/lib/views/pages/device_transfer/update_device_transfer.dart index 70d85626..7e038575 100644 --- a/lib/views/pages/device_transfer/update_device_transfer.dart +++ b/lib/views/pages/device_transfer/update_device_transfer.dart @@ -457,13 +457,12 @@ class _AssistantEmployeeCardState extends State { ).then((selectedTime) { // Handle the selected date and time here. if (selectedTime != null) { - DateTime selectedDateTime = DateTime( - selectedDate.year, - selectedDate.month, - selectedDate.day, - selectedTime.hour, - selectedTime.minute, - ); + DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); + if (selectedDateTime.isAfter(DateTime.now())) { + "Start time is after than current time".showToast; + selectedTime = null; + return; + } widget.formModel?.modelAssistantEmployees?.startDate = selectedDateTime; ServiceRequestUtils.calculateAndAssignWorkingHours( startTime: widget.formModel?.modelAssistantEmployees?.startDate, @@ -501,6 +500,22 @@ class _AssistantEmployeeCardState extends State { "End Date time must be greater then start date".showToast; return; } + + selectedDate = selectedDate.add(Duration(hours: selectedTime.hour, minutes: selectedTime.minute)); + bool isBeforeCurrentTime = selectedDate.isBefore(DateTime.now()); + bool isAfterStartTime = selectedDate.isAfter(widget.formModel!.modelAssistantEmployees!.startDate!); + if (!isBeforeCurrentTime) { + "Please select a time before the current time.".showToast; + return; + } + if (!isAfterStartTime) { + "End Date time must be greater then start date".showToast; + return; + } + + + + widget.formModel?.modelAssistantEmployees?.endDate = selectedDateTime; ServiceRequestUtils.calculateAndAssignWorkingHours( startTime: widget.formModel?.modelAssistantEmployees?.startDate, diff --git a/lib/views/widgets/timer/app_timer.dart b/lib/views/widgets/timer/app_timer.dart index e72757ca..9583cc5b 100644 --- a/lib/views/widgets/timer/app_timer.dart +++ b/lib/views/widgets/timer/app_timer.dart @@ -7,7 +7,6 @@ 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/timer_model.dart'; import 'package:test_sa/modules/cm_module/utilities/service_request_utils.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; @@ -166,7 +165,7 @@ class _AppTimerState extends State { backgroundColor: AppColor.neutral100, date: _pickerStartAt, from: widget.pickerFromDate, - enable: widget.enabled ? _tempPickerTimer == null:false, + enable: widget.enabled ? _tempPickerTimer == null : false, formatDateWithTime: true, onDatePicker: (selectedDate) { showTimePicker( @@ -175,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 (_pickerStartAt!.isAfter(DateTime.now())) { + "Start time is after than current time".showToast; + _pickerStartAt = null; + selectedTime = null; + return; + } setState(() {}); } }); @@ -185,8 +190,8 @@ class _AppTimerState extends State { label: context.translation.endTime, hideShadow: true, backgroundColor: AppColor.neutral100, - enable: widget.enabled? _pickerStartAt != null:false, - from:_pickerStartAt, + enable: widget.enabled ? _pickerStartAt != null : false, + from: _pickerStartAt, date: _pickerEndAt, to: DateTime.now(), formatDateWithTime: true, @@ -195,20 +200,19 @@ class _AppTimerState extends State { context: context, initialTime: TimeOfDay.now(), ).then((selectedTime) { - if (selectedTime != null) { - final TimeOfDay now = TimeOfDay.now(); - final bool isBeforeNow = Utils.isBeforeOrEqualCurrentTime(selectedTime, now); - if (!isBeforeNow) { + selectedDate = selectedDate.add(Duration(hours: selectedTime.hour, minutes: selectedTime.minute)); + bool isBeforeCurrentTime = selectedDate.isBefore(DateTime.now()); + bool isAfterStartTime = selectedDate.isAfter(_pickerStartAt!); + if (!isBeforeCurrentTime) { "Please select a time before the current time.".showToast; return; } - DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); - if (_pickerStartAt != null && selectedDateTime.isBefore(_pickerStartAt!)) { + if (!isAfterStartTime) { "End Date time must be greater then start date".showToast; return; } - _pickerEndAt = selectedDateTime; + _pickerEndAt = selectedDate; setPickerTime(); } }); From a2e5a8a5882be80907405446082b09b61a0873d7 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 2 Jul 2025 13:56:03 +0300 Subject: [PATCH 2/5] otp verification improved, serial no added --- lib/models/new_models/work_order_detail_model.dart | 4 ++++ .../views/components/service_request_detail_view.dart | 8 ++++---- .../cm_module/views/components/verify_arrival_view.dart | 2 +- .../cm_module/views/components/verify_otp_view.dart | 3 ++- .../land_page/requests/service_request_item_view.dart | 1 + 5 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/models/new_models/work_order_detail_model.dart b/lib/models/new_models/work_order_detail_model.dart index 10be7e76..166ed9b6 100644 --- a/lib/models/new_models/work_order_detail_model.dart +++ b/lib/models/new_models/work_order_detail_model.dart @@ -289,21 +289,25 @@ class WorkOrderAsset { WorkOrderAsset({ required this.id, required this.assetNumber, + required this.assetSerialNo, }); int? id; String? assetNumber; + String? assetSerialNo; factory WorkOrderAsset.fromJson(Map json) { return WorkOrderAsset( id: json["id"], assetNumber: json["assetNumber"], + assetSerialNo: json["assetSerialNo"], ); } Map toJson() => { "id": id, "assetNumber": assetNumber, + "assetSerialNo": assetSerialNo, }; } 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 ecb1c39f..0215b6ad 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 @@ -189,10 +189,10 @@ class _ServiceRequestDetailViewState extends State { '${context.translation.assetNumber}: ${workOrder.asset!.assetNumber}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), ), - // Text( - // '${context.translation.equipmentStatus}: ${workOrder.defectType?.name}', // todo ask ahmed - // style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20), - // ), + Text( + '${context.translation.serialNo}: ${workOrder.asset!.assetSerialNo}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), + ), Text( '${context.translation.manufacture}: ${workOrder.manufacturer?.name?.cleanupWhitespace?.capitalizeFirstOfEach}', style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral120), diff --git a/lib/modules/cm_module/views/components/verify_arrival_view.dart b/lib/modules/cm_module/views/components/verify_arrival_view.dart index 6c55c953..73d171a2 100644 --- a/lib/modules/cm_module/views/components/verify_arrival_view.dart +++ b/lib/modules/cm_module/views/components/verify_arrival_view.dart @@ -148,7 +148,7 @@ class _VerifyArrivalViewState extends State { break; case 3: await requestDetailProvider.sendOtp(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!); - Navigator.pushReplacement( + Navigator.push( context, MaterialPageRoute(builder: (context) => const VerifyOtpView()), ); diff --git a/lib/modules/cm_module/views/components/verify_otp_view.dart b/lib/modules/cm_module/views/components/verify_otp_view.dart index 63346dcf..25705f96 100644 --- a/lib/modules/cm_module/views/components/verify_otp_view.dart +++ b/lib/modules/cm_module/views/components/verify_otp_view.dart @@ -56,6 +56,7 @@ class VerifyOtpView extends StatelessWidget { await requestDetailProvider.engineerConfirmArrival( workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: 3, photoInfo: '', otp: pin, assetNo: ''); Navigator.pop(context); + Navigator.pop(context); requestDetailProvider.startTimer(); Navigator.pop(context); } else { @@ -109,7 +110,7 @@ class VerifyOtpView extends StatelessWidget { 3.height, InkWell( onTap: () { - //other method check.. + Navigator.pop(context); }, child: Text( context.translation.checkOutOtherMethods, diff --git a/lib/new_views/pages/land_page/requests/service_request_item_view.dart b/lib/new_views/pages/land_page/requests/service_request_item_view.dart index 7d18b013..0fac59f4 100644 --- a/lib/new_views/pages/land_page/requests/service_request_item_view.dart +++ b/lib/new_views/pages/land_page/requests/service_request_item_view.dart @@ -119,6 +119,7 @@ class ServiceRequestItemView extends StatelessWidget { // '${context.translation.requestType}: ${requestDetails!.requestType}'.bodyText(context), 'CM Number: ${requestDetails!.requestNo}'.bodyText(context), '${context.translation.assetNumber}: ${requestDetails!.assetNo}'.bodyText(context), + '${context.translation.serialNo}: ${requestDetails!.assetSN}'.bodyText(context), '${context.translation.assetName}: ${requestDetails!.assetName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), 8.height, Row( From 3881b69963c1ae4e9f5f742d445d33c992775ec7 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Wed, 2 Jul 2025 13:56:34 +0300 Subject: [PATCH 3/5] target sdk updated to 35. --- android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 61ac68e0..8be014cb 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -47,7 +47,7 @@ android { // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. minSdkVersion 21 - targetSdkVersion 34 + targetSdkVersion 35 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } From bf44e5cbec7ad8fa86e625e242ed6a87b94e680c Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 3 Jul 2025 09:52:20 +0300 Subject: [PATCH 4/5] 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; From 9b9ce8c4b23b6a04b80c47d8d36e78ba2aaa3d56 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 3 Jul 2025 11:58:28 +0300 Subject: [PATCH 5/5] 1.3.2+21 uploaded on stores. --- lib/controllers/api_routes/urls.dart | 11 ++++++----- pubspec.yaml | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 5fe6560a..ac68fd50 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -1,16 +1,16 @@ class URLs { URLs._(); - static const String appReleaseBuildNumber = "17"; + static const String appReleaseBuildNumber = "18"; - // static const host1 = "https://atomsm.hmg.com"; // production url + 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 = "https://atomsmuat.hmg.com"; // local UAT url - static String _baseUrl = "$_host/mobile"; + // static String _baseUrl = "$_host/mobile"; // static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis // static final String _baseUrl = "$_host/mobile"; // host local UAT - // static final String _baseUrl = "$_host/v3/mobile"; // v3 for new CM,PM,TM + static final String _baseUrl = "$_host/v3/mobile"; // v3 for new CM,PM,TM static String _host = host1; @@ -90,6 +90,7 @@ class URLs { static get engineerConfirmArriveUrl => '$_baseUrl/ServiceRequest/EngineerConfirmArrive'; static get engineerUpdateWorkOrderUrl => '$_baseUrl/ServiceRequest/EngineerUpdateWorkOrder'; + static get engineerUpdateCost => '$_baseUrl/ServiceRequest/EngineerUpdateCost'; static get engineerSetReminderUrl => '$_baseUrl/ServiceRequest/EngineerSetReminder'; diff --git a/pubspec.yaml b/pubspec.yaml index 80503ddb..6ecb3c07 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.1+20 +version: 1.3.2+21 environment: sdk: ">=3.5.0 <4.0.0"