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 } diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index a3c52227..67b4bf48 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 = "17"; + static const String appReleaseBuildNumber = "18"; // static const host1 = "https://atomsm.hmg.com"; // production url // static const host1 = "https://atomsmdev.hmg.com"; // local DEV url @@ -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'; @@ -88,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/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/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 ecb1c39f..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 @@ -189,10 +194,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/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..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 @@ -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,18 @@ 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 (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; + return; + } + requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate = selectedDateTime; requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); ServiceRequestUtils.calculateAndAssignWorkingHours( @@ -141,8 +146,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 +160,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..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 @@ -146,13 +146,17 @@ 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 (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; + return; + } requestDetailProvider.activityMaintenanceHelperModel?.supplierStartTime = selectedDateTime; requestDetailProvider.activityMaintenanceHelperModel?.supplierEndTime = null; requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); @@ -176,6 +180,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 +190,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..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 @@ -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,24 @@ 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, 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 (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; + return; + } setState(() { widget.model.startDateTime = selectedDateTime; }); @@ -224,27 +226,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?.createdDate ?? ''), 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..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 @@ -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.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 a41d4e94..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 @@ -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'; @@ -646,6 +648,7 @@ class _AssistantEmployeeCardState extends State { hideShadow: true, backgroundColor: AppColor.neutral100, date: taskModel?.modelAssistantEmployees?.startDate, + // from: taskModel?.d, formatDateWithTime: true, onDatePicker: (selectedDate) { showTimePicker( @@ -654,13 +657,18 @@ 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 (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; + return; + } taskModel?.modelAssistantEmployees?.startDate = selectedDateTime; taskRequestProvider.updateTaskModel(taskModel); ServiceRequestUtils.calculateAndAssignWorkingHours( @@ -680,6 +688,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 +697,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/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( diff --git a/lib/views/pages/device_transfer/update_device_transfer.dart b/lib/views/pages/device_transfer/update_device_transfer.dart index 70d85626..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( @@ -457,13 +458,17 @@ 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 (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; + return; + } widget.formModel?.modelAssistantEmployees?.startDate = selectedDateTime; ServiceRequestUtils.calculateAndAssignWorkingHours( startTime: widget.formModel?.modelAssistantEmployees?.startDate, @@ -501,6 +506,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..090f6913 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,18 @@ 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; + selectedTime = null; + return; + } setState(() {}); } }); @@ -185,8 +196,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 +206,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(); } }); 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"