From 3a27b9d6ca85f30ae0bed3ddbf04c8ceebbf21c4 Mon Sep 17 00:00:00 2001 From: WaseemAbbasi22 Date: Tue, 22 Oct 2024 17:04:54 +0300 Subject: [PATCH] implement scan qr code and ask requester to verify flow --- lib/controllers/api_routes/urls.dart | 4 + lib/dashboard_latest/dashboard_provider.dart | 54 ++++- lib/dashboard_latest/dashboard_view.dart | 2 +- lib/extensions/enum_extensions.dart | 32 ++- lib/models/enums/work_order_next_step.dart | 1 + .../activity_maintenance_model.dart | 13 +- .../workorder/work_order_helper_models.dart | 4 - .../arrival_verification_type_model.dart | 47 ++++- lib/models/new_models/dashboard_detail.dart | 3 + .../new_models/work_order_detail_model.dart | 4 + .../requests/request_paginated_listview.dart | 1 - .../requests/service_request_item_view.dart | 19 +- .../fault_description_provider.dart | 3 + .../request_detail_provider.dart | 134 +++++++++--- .../utilities/service_request_utils.dart | 42 ++++ .../action_button/footer_action_button.dart | 56 ++++- .../components/activities_list_view.dart | 4 +- .../service_request_bottomsheet.dart | 8 +- .../views/components/request_detail_view.dart | 10 +- .../views/components/verify_arrival_view.dart | 196 +++++++----------- .../asset_retired/verify_asset_detail.dart | 4 +- .../views/request_detail_main_view.dart | 24 ++- 22 files changed, 450 insertions(+), 215 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 780b7963..7c742eef 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -35,11 +35,14 @@ class URLs { static get nurseDashboardCountUrl=> '$_baseUrl/ServiceRequest/GetDashboardNurseCount'; static get nurseDashboardDetailsUrl=> '$_baseUrl/ServiceRequest/GetDashboardNurseDetails'; static get nurseRejectUrl=> '$_baseUrl/ServiceRequest/NurseReject'; + static get nurseAcceptUrl=> '$_baseUrl/ServiceRequest/NurseAccept'; static get engineerStopTimer=> '$_baseUrl/ServiceRequest/EngineerStopTimer'; static get nurseConfirmUrl=> '$_baseUrl/ServiceRequest/NurseConfirm'; static get engineerDashboardCountUrl=> '$_baseUrl/ServiceRequest/GetDashboardEngineerCount'; static get engineerDashboardDetailsUrl=> '$_baseUrl/ServiceRequest/GetDashboardEngineerDetails'; + static get engineerDashboardNotAssignDetails=> '$_baseUrl/ServiceRequest/GetDashboardEngineerNotAssignDetails'; static get engineerAcceptUrl=> '$_baseUrl/ServiceRequest/EngineerAccept'; + static get engineerAssignHimSelfUrl=> '$_baseUrl/ServiceRequest/AssignEngineerToHimself'; static get engineerRejectUrl=> '$_baseUrl/ServiceRequest/EngineerReject'; static get engineerFixRemotlyUrl=> '$_baseUrl/ServiceRequest/EngineerFixRemotly'; static get engineerNeedVisitUrl=> '$_baseUrl/ServiceRequest/EngineerNeedVisit'; @@ -49,6 +52,7 @@ class URLs { static get engineerConfirmArriveUrl=> '$_baseUrl/ServiceRequest/EngineerConfirmArrive'; static get engineerUpdateWorkOrderUrl=> '$_baseUrl/ServiceRequest/EngineerUpdateWorkOrder'; static get getWorkOrderByIdUrl=> '$_baseUrl/ServiceRequest/GetWorkOrderById'; + static get getQrCodeUrl=> '$_baseUrl/ServiceRequest/GetQRCode'; static get deleteActivitySparePartUrl=> '$_baseUrl/ServiceRequest/DeleteActivitySparePart'; static get deleteActivityMaintenanceUrl=> '$_baseUrl/ServiceRequest/DeleteActivityMaintenance'; static get createActivitySparePartUrl=> '$_baseUrl/ServiceRequest/CreateActivitySparePart'; diff --git a/lib/dashboard_latest/dashboard_provider.dart b/lib/dashboard_latest/dashboard_provider.dart index 89b03d22..b5d003e1 100644 --- a/lib/dashboard_latest/dashboard_provider.dart +++ b/lib/dashboard_latest/dashboard_provider.dart @@ -42,7 +42,6 @@ class DashBoardProvider extends ChangeNotifier { List tabs = []; void setTabs({required UsersTypes userType, required BuildContext context}) { - print('user type i got in method is ${userType}'); tabs = CategoryTabs.getTabs(userType: userType, context: context); } @@ -167,18 +166,21 @@ class DashBoardProvider extends ChangeNotifier { notifyListeners(); } - print('i am called...${usersType}'); - +print('status int got is $status'); Response response; String url = ''; if (usersType == UsersTypes.engineer) { - url = URLs.engineerDashboardDetailsUrl; + if(status==0){ + url = URLs.engineerDashboardNotAssignDetails; + }else{ + url = URLs.engineerDashboardDetailsUrl; + } } else { url = URLs.nurseDashboardDetailsUrl; } try { Map body = {"pageNumber": pageNum, "pageSize": pageItemNumber}; - if (status != null) body["statusValue"] = status; + if (status != null&&status!=0) body["statusValue"] = status; if (isHighPriority) body["isHighPriority"] = true; if (isOverdue) body["isOverdue"] = true; response = await ApiManager.instance.post(url, body: body); @@ -211,6 +213,47 @@ class DashBoardProvider extends ChangeNotifier { return -1; } } + Future getEngineerDashboardNotAssignedDetail({bool showLoader = true,}) async { + if (showLoader) { + isDetailLoading = showLoader; + notifyListeners(); + } + + + Response response; + + try { + Map body = {"pageNumber": pageNum, "pageSize": pageItemNumber}; + response = await ApiManager.instance.post(URLs.engineerDashboardNotAssignDetails, body: body); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + if (_requestDetailList == null) { + _requestDetailList = DD.DashboardDetail.fromJson(json.decode(response.body)); + } else { + _requestDetailList!.data!.addAll(DD.DashboardDetail.fromJson(json.decode(response.body)).data ?? []); + } + if (_requestDetailList!.data!.length >= pageItemNumber) { + nextPage = true; + } else { + nextPage = false; + } + } else { + requestDetailList = null; + } + if (showLoader) { + isDetailLoading = false; + } + notifyListeners(); + return response.statusCode; + } catch (error) { + if (showLoader) { + isDetailLoading = false; + } + stateCode = -1; + notifyListeners(); + return -1; + } + } bool get isDetailLoading => _isDetailLoading; @@ -229,6 +272,7 @@ class CategoryTabs { static List getTabs({required UsersTypes userType, required BuildContext context}) { List tabs = []; if (userType == UsersTypes.engineer) { + tabs.add(CategoryTabs('Not Assigned', 0)); tabs.add(CategoryTabs('Open Request', 1)); tabs.add(CategoryTabs('In Progress', 2)); tabs.add(CategoryTabs('Completed', 3)); diff --git a/lib/dashboard_latest/dashboard_view.dart b/lib/dashboard_latest/dashboard_view.dart index c1d4c403..1f490396 100644 --- a/lib/dashboard_latest/dashboard_view.dart +++ b/lib/dashboard_latest/dashboard_view.dart @@ -52,7 +52,7 @@ class _DashboardViewState extends State { _dashBoardProvider.setTabs(userType:userProvider.user!.type!,context: context); _dashBoardProvider.getDashBoardCount(usersType: userProvider.user!.type!); _dashBoardProvider.resetRequestDataList(); - _dashBoardProvider.getRequestDetail(usersType: userProvider.user!.type!, status: _dashBoardProvider.tabs[_dashBoardProvider.currentListIndex].tag); + _dashBoardProvider.getRequestDetail(usersType: userProvider.user!.type!, status: _dashBoardProvider.tabs[_dashBoardProvider.currentListIndex].tag); } void getInitialData() { diff --git a/lib/extensions/enum_extensions.dart b/lib/extensions/enum_extensions.dart index 0862957f..92f82118 100644 --- a/lib/extensions/enum_extensions.dart +++ b/lib/extensions/enum_extensions.dart @@ -1,3 +1,4 @@ +import 'package:test_sa/app_strings/app_asset.dart'; import 'package:test_sa/models/enums/work_order_next_step.dart'; extension EnumExtensionsWorkOrder on WorkOrderNextStepEnum { @@ -29,6 +30,9 @@ extension EnumExtensionsWorkOrder on WorkOrderNextStepEnum { return 22; case WorkOrderNextStepEnum.assetRetirementManagementApproval: return 26; + case WorkOrderNextStepEnum.waitingForRequesterToConfirm: + //replace with correct value... + return 31; } } } @@ -36,9 +40,12 @@ extension EnumExtensionsWorkOrder on WorkOrderNextStepEnum { extension IntExtensionsWorkOrder on int { WorkOrderNextStepEnum toWorkOrderNextStepEnum() { switch (this) { + //TODO add another case for engineer assign work order and + // case 2: + // return WorkOrderNextStepEnum.engineerAssignHimSelf; case 2: return WorkOrderNextStepEnum.onlyView; - case 3: + case 3: return WorkOrderNextStepEnum.markedAsFixed; case 5: return WorkOrderNextStepEnum.nTakeAction; @@ -52,12 +59,31 @@ extension IntExtensionsWorkOrder on int { return WorkOrderNextStepEnum.verifyAssetDetail; case 17: return WorkOrderNextStepEnum.activity; - case 22: + case 22: return WorkOrderNextStepEnum.endWorkFlow; - case 26: + case 26: return WorkOrderNextStepEnum.assetRetirementManagementApproval; + case 31: + return WorkOrderNextStepEnum.waitingForRequesterToConfirm; default: return WorkOrderNextStepEnum.onlyView; } } + + String getVerificationIconByValue() { + switch (this) { + case 1: + return AppAsset.scanQrIcon; + case 2: + return AppAsset.askRequesterIcon; + case 3: + return AppAsset.askOtpIcon; + case 4: + return AppAsset.takeDevicePhotoIcon; + case 5: + return AppAsset.scanQrIcon; + default: + return AppAsset.askRequesterIcon; + } + } } diff --git a/lib/models/enums/work_order_next_step.dart b/lib/models/enums/work_order_next_step.dart index 03643376..7c8bbcf7 100644 --- a/lib/models/enums/work_order_next_step.dart +++ b/lib/models/enums/work_order_next_step.dart @@ -8,5 +8,6 @@ enum WorkOrderNextStepEnum { verifyAssetDetail, // 16 activity, // 17 endWorkFlow, // 22 + waitingForRequesterToConfirm, // 31 . assetRetirementManagementApproval, //26 } diff --git a/lib/models/helper_data_models/maintenance_request/activity_maintenance_model.dart b/lib/models/helper_data_models/maintenance_request/activity_maintenance_model.dart index 94fd3d88..0bc584cf 100644 --- a/lib/models/helper_data_models/maintenance_request/activity_maintenance_model.dart +++ b/lib/models/helper_data_models/maintenance_request/activity_maintenance_model.dart @@ -8,8 +8,11 @@ import 'package:test_sa/models/service_request/supplier_details.dart'; class ActivityMaintenanceHelperModel { int? id; int? workOrderId; + //remove this int? lastSituationId; Lookup? lastSituation; + + Lookup? activityStatus; DateTime? startTime; DateTime? endTime; @@ -57,9 +60,9 @@ class ActivityMaintenanceHelperModel { Map toJson() { final Map data = {}; + data['id'] = id; data['workOrderId'] = workOrderId; - data['activityStatusId'] = activityStatus?.id; data['startTime'] = startTime?.toIso8601String(); data['endTime'] = endTime?.toIso8601String(); @@ -73,10 +76,10 @@ class ActivityMaintenanceHelperModel { data['supplierStartTime'] = supplierStartTime?.toIso8601String(); data['supplierEndTime'] = supplierEndTime?.toIso8601String(); data['supplierWorkingHour'] = supplierWorkingHour; - //TODO remove this when backend fix this on their side.. - if(activityStatus!=null){ - data['lastSituationId'] = activityStatus?.id; - } + // //TODO remove this when backend fix this on their side.. + // if(activityStatus!=null){ + // data['lastSituationId'] = activityStatus?.id; + // } if (assistantEmployees != null&&assistantEmployees!.isNotEmpty) { data['assistantEmployees'] = [modelAssistantEmployees?.toJson()]; } diff --git a/lib/models/helper_data_models/workorder/work_order_helper_models.dart b/lib/models/helper_data_models/workorder/work_order_helper_models.dart index 911f1b88..f851e5c3 100644 --- a/lib/models/helper_data_models/workorder/work_order_helper_models.dart +++ b/lib/models/helper_data_models/workorder/work_order_helper_models.dart @@ -92,14 +92,10 @@ class EngineerUpdateWorkOrderHelperModel { data['workOrderId'] = workOrderId; data['equipmentStatusId'] = equipmentStatus?.id; data['returnToService'] = returnToService; - //TODO Bhaa need to confirm about this for testing use internal id 65 - data['serviceTypeId'] = serviceType?.id; data['loanAvailabilityId'] = loanAvailability?.id; data['loanAssetId'] = loanAssetId; data['failureReasonId'] = failureReason?.id; data['faultDescriptionId'] = faultDescription?.id; - //TODO this cause issue with the return data - // data['solution'] = solution; return data; } } diff --git a/lib/models/new_models/arrival_verification_type_model.dart b/lib/models/new_models/arrival_verification_type_model.dart index b2fb7031..cec060d5 100644 --- a/lib/models/new_models/arrival_verification_type_model.dart +++ b/lib/models/new_models/arrival_verification_type_model.dart @@ -1,5 +1,7 @@ +import 'package:test_sa/extensions/enum_extensions.dart'; + class ArrivalVerificationTypeModel { - List? data; + List? data; String? message; String? title; String? innerMessage; @@ -16,9 +18,9 @@ class ArrivalVerificationTypeModel { ArrivalVerificationTypeModel.fromJson(Map json) { if (json['data'] != null) { - data = []; + data = []; json['data'].forEach((v) { - data!.add(Data.fromJson(v)); + data!.add(ArrivalTypeData.fromJson(v)); }); } message = json['message']; @@ -30,38 +32,57 @@ class ArrivalVerificationTypeModel { } -class Data { +class ArrivalTypeData { int? assetGroupId; int? verificationTypeId; VerificationTypes? verificationTypes; int? id; + + String? description; String? createdBy; String? createdDate; dynamic modifiedBy; dynamic modifiedDate; - Data( + ArrivalTypeData( {this.assetGroupId, this.verificationTypeId, this.verificationTypes, this.id, + this.description, this.createdBy, + this.createdDate, this.modifiedBy, this.modifiedDate}); - Data.fromJson(Map json) { + ArrivalTypeData.fromJson(Map json) { assetGroupId = json['assetGroupId']; verificationTypeId = json['verificationTypeId']; verificationTypes = json['verificationTypes'] != null ? VerificationTypes.fromJson(json['verificationTypes']) : null; id = json['id']; + description = json['description']; createdBy = json['createdBy']; createdDate = json['createdDate']; modifiedBy = json['modifiedBy']; modifiedDate = json['modifiedDate']; } + Map toJson() { + return { + 'assetGroupId': assetGroupId, + 'verificationTypeId': verificationTypeId, + 'verificationTypes': verificationTypes?.toJson(), + 'id': id, + 'createdBy': createdBy, + 'createdDate': createdDate, + 'description': description, + 'modifiedBy': modifiedBy, + 'modifiedDate': modifiedDate, + }; + } + } @@ -69,13 +90,23 @@ class VerificationTypes { int? id; String? name; int? value; + String?icon; - VerificationTypes({this.id, this.name, this.value}); + VerificationTypes({this.id, this.name, this.value,this.icon}); VerificationTypes.fromJson(Map json) { id = json['id']; name = json['name']; value = json['value']; + icon = (json['value'] as int).getVerificationIconByValue(); + } + Map toJson() { + return { + 'id': id, + 'name': name, + 'value': value, + }; } -} + +} \ No newline at end of file diff --git a/lib/models/new_models/dashboard_detail.dart b/lib/models/new_models/dashboard_detail.dart index 6142c90f..abc33163 100644 --- a/lib/models/new_models/dashboard_detail.dart +++ b/lib/models/new_models/dashboard_detail.dart @@ -47,6 +47,7 @@ class Data { String? priorityName; bool? isHighPriority; String? assetName; + String? rejectReason; String? assetNumber; String? requestTypeName; String? requestNo; @@ -66,6 +67,7 @@ class Data { assetNumber = json['assetNumber']; requestTypeName = json['requestTypeName']; requestNo = json['requestNo']; + rejectReason = json['rejectReason']; transactionNo = json['transactionNo']; nameOfType = json['nameOfType']; } @@ -82,6 +84,7 @@ class Data { data['assetNumber'] = assetNumber; data['requestTypeName'] = requestTypeName; data['requestNo'] = requestNo; + data['rejectReason'] = rejectReason; data['transactionNo'] = transactionNo; data['nameOfType'] = nameOfType; return data; diff --git a/lib/models/new_models/work_order_detail_model.dart b/lib/models/new_models/work_order_detail_model.dart index 03b3bbd5..62c7df7a 100644 --- a/lib/models/new_models/work_order_detail_model.dart +++ b/lib/models/new_models/work_order_detail_model.dart @@ -1,3 +1,4 @@ +import 'package:test_sa/models/fault_description.dart'; import 'package:test_sa/models/helper_data_models/spare_part/activity_spare_part_model.dart'; import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_models.dart'; import 'package:test_sa/models/lookup.dart'; @@ -71,6 +72,7 @@ class WorkOrderData { required this.assetLoan, required this.safety, required this.problemDescription, + required this.faultDescription, required this.comments, required this.voiceNote, required this.workOrderAttachments, @@ -121,6 +123,7 @@ class WorkOrderData { String? returnToService; Lookup? serviceType; Lookup? failureReasone; + FaultDescription? faultDescription; Lookup? solution; String? totalWorkingHours; DateTime? needAVisitDateTime; @@ -166,6 +169,7 @@ class WorkOrderData { returnToService: json["returnToService"], serviceType: json["serviceType"] == null ? null : Lookup.fromJson(json["serviceType"]), failureReasone: json["failureReasone"] == null ? null : Lookup.fromJson(json["failureReasone"]), + faultDescription: json["faultDescription"] == null ? null : FaultDescription.fromJson(json["faultDescription"]), solution: json["solution"] == null ? null : Lookup.fromJson(json["solution"]), totalWorkingHours: json["totalWorkingHours"], workOrderHistory: json["workOrderHistory"] == null ? [] : List.from(json["workOrderHistory"]!.map((x) => WorkOrderHistory.fromJson(x))), diff --git a/lib/new_views/pages/land_page/requests/request_paginated_listview.dart b/lib/new_views/pages/land_page/requests/request_paginated_listview.dart index e1bf7fc6..8665c755 100644 --- a/lib/new_views/pages/land_page/requests/request_paginated_listview.dart +++ b/lib/new_views/pages/land_page/requests/request_paginated_listview.dart @@ -17,7 +17,6 @@ class RequestPaginatedListview extends StatelessWidget { @override Widget build(BuildContext context) { - print('count i got is $totalCount'); return ListView.builder( itemCount: list.length < totalCount ? list.length + 1 : list.length, controller: scrollController, 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 07e7ebd3..de79ef30 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 @@ -1,11 +1,15 @@ //service request item page import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/user_provider.dart'; +import 'package:test_sa/dashboard_latest/dashboard_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/all_requests_and_count_model.dart'; +import 'package:test_sa/models/enums/user_types.dart'; import 'package:test_sa/models/new_models/dashboard_detail.dart'; import 'package:test_sa/service_request_latest/views/request_detail_main_view.dart'; @@ -37,8 +41,8 @@ class ServiceRequestItemView extends StatelessWidget { 8.width, StatusLabel( label: requestData!.statusName!, - textColor: AppColor.getHistoryLogStatusTextColorByName( requestData!.statusName!), - backgroundColor: AppColor.getHistoryLogStatusColorByName( requestData!.statusName!), + textColor: AppColor.getHistoryLogStatusTextColorByName(requestData!.statusName!), + backgroundColor: AppColor.getHistoryLogStatusColorByName(requestData!.statusName!), ), 1.width.expanded, Text(requestData!.transactionDate!.toServiceRequestCardFormat, @@ -51,6 +55,9 @@ class ServiceRequestItemView extends StatelessWidget { // '${context.translation.assetNumber}: ${request.assetNo}'.bodyText(context), // '${context.translation.requestType}: ${requestData!.requestTypeName}'.bodyText(context), '${context.translation.requestNo}: ${requestData!.requestNo}'.bodyText(context), + if (requestData?.statusName == 'Cancelled') ...[ + '${context.translation.rejectionReason}: ${requestData!.rejectReason}'.bodyText(context), + ], 8.height, Row( // mainAxisSize: MainAxisSize.min, @@ -69,8 +76,10 @@ class ServiceRequestItemView extends StatelessWidget { ], ), ], - ).toShadowContainer(context, withShadow: showShadow).onPress(() { - Navigator.of(context).push(MaterialPageRoute(builder: (_) => RequestDetailMain(requestId: requestData!.id!))); + ).toShadowContainer(context, withShadow: showShadow).onPress(() async { + await Navigator.of(context).push(MaterialPageRoute(builder: (_) => RequestDetailMain(requestId: requestData!.id!))); + UserProvider userProvider = Provider.of(context, listen: false); + Provider.of(context, listen: false).refreshDashboard(userType: userProvider.user!.type ?? UsersTypes.normal_user, context: context); }); } if (requestDetails != null) { @@ -98,7 +107,7 @@ class ServiceRequestItemView extends StatelessWidget { ), 8.height, (requestDetails!.nameOfType ?? context.translation.correctiveMaintenance).heading5(context), - '${context.translation.assetName}: ${requestDetails!.assetName?.cleanupWhitespace?.capitalizeFirstOfEach}'.bodyText(context), + '${context.translation.assetName}: ${requestDetails!.assetName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), '${context.translation.assetNumber}: ${requestDetails!.assetNo}'.bodyText(context), '${context.translation.requestType}: ${requestDetails!.requestType}'.bodyText(context), '${context.translation.requestNo}: ${requestDetails!.requestNo}'.bodyText(context), diff --git a/lib/providers/work_order/fault_description_provider.dart b/lib/providers/work_order/fault_description_provider.dart index 0c9c7a78..d5f27a3f 100644 --- a/lib/providers/work_order/fault_description_provider.dart +++ b/lib/providers/work_order/fault_description_provider.dart @@ -25,7 +25,10 @@ class FaultDescriptionProvider extends ChangeNotifier { Future> getFaultDescriptionList({num? assetId}) async { late Response response; try { + response = await ApiManager.instance.get(URLs.getFaultDescription+"?assetId=$assetId",); + print('url is ${URLs.getFaultDescription+"?assetId=$assetId"}'); + print('response of get fault is ${response.body}'); List list = []; if (response.statusCode >= 200 && response.statusCode < 300) { // client's request was successfully received diff --git a/lib/service_request_latest/request_detail_provider.dart b/lib/service_request_latest/request_detail_provider.dart index b7d65286..906bee33 100644 --- a/lib/service_request_latest/request_detail_provider.dart +++ b/lib/service_request_latest/request_detail_provider.dart @@ -65,6 +65,15 @@ class RequestDetailProvider extends ChangeNotifier { notifyListeners(); } + bool _isArrivalLoading = false; + + bool get isArrivalLoading => _isArrivalLoading; + + set isArrivalLoading(bool value) { + _isArrivalLoading = value; + notifyListeners(); + } + //UI models WorkOrderDetail? currentWorkOrder; AssetRetiredHelperModel? assetRetiredHelperModel = AssetRetiredHelperModel(); @@ -76,6 +85,7 @@ class RequestDetailProvider extends ChangeNotifier { EngineerRejectHelperModel? engineerRejectHelperModel = EngineerRejectHelperModel(); EngineerUpdateWorkOrderHelperModel? engineerUpdateWorkOrderHelperModel = EngineerUpdateWorkOrderHelperModel(); WorkOrderHelperModel? workOrderHelperModel; + List arrivalTypeList = []; void updateAssetRetiredHelperModel(AssetRetiredHelperModel? value) { assetRetiredHelperModel = value; @@ -193,6 +203,29 @@ class RequestDetailProvider extends ChangeNotifier { } } + //getQrCode...... + Future getQrCode({required int workOrderId}) async { + try { + notifyListeners(); + final response = await ApiManager.instance.get(URLs.getQrCodeUrl + "/$workOrderId"); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + String base64String = response.body.split(',').last; + + return base64String; + return response.body; + } + isLoading = false; + notifyListeners(); + } catch (e) { + log("getQrCode [error] : $e"); + isLoading = false; + notifyListeners(); + return null; + } + return null; + } + //engineerAcceptWorkOrder...... Future engineerAcceptWorkOrder({required String id}) async { Response response; @@ -214,7 +247,30 @@ class RequestDetailProvider extends ChangeNotifier { notifyListeners(); return -1; } - } //engineerAcceptWorkOrder...... + } //engineerAcceptWorkOrder...... + + Future engineerAssignWorkOrderToHimself({required String id}) async { + Response response; + try { + final body = {"workOrderId": id}; + isLoading = true; + notifyListeners(); + response = await ApiManager.instance.post(URLs.engineerAssignHimSelfUrl, body: body); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body)); + } + isLoading = false; + notifyListeners(); + return response.statusCode; + } catch (e) { + log("engineer accept [error] : $e"); + isLoading = false; + notifyListeners(); + return -1; + } + } //engineerAssignedHimself...... + Future engineerStopTimer() async { Response response; try { @@ -222,11 +278,8 @@ class RequestDetailProvider extends ChangeNotifier { isLoading = true; notifyListeners(); response = await ApiManager.instance.post(URLs.engineerStopTimer, body: body); - print('response of stop timer is ${response.body}'); stateCode = response.statusCode; - if (response.statusCode >= 200 && response.statusCode < 300) { - - } + if (response.statusCode >= 200 && response.statusCode < 300) {} isLoading = false; notifyListeners(); return response.statusCode; @@ -312,8 +365,6 @@ class RequestDetailProvider extends ChangeNotifier { notifyListeners(); response = await ApiManager.instance.post(URLs.engineerUpdateNeedVisitUrl, body: needVisitHelperModel!.toJson()); stateCode = response.statusCode; - print('body i got is ${needVisitHelperModel?.toJson()}'); - print('response i got is ${response.body}'); if (response.statusCode >= 200 && response.statusCode < 300) { currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body)); } @@ -335,10 +386,8 @@ class RequestDetailProvider extends ChangeNotifier { isLoading = true; notifyListeners(); Map body = {'workOrderId': workOrderId, 'feedback': feedback}; - response = await ApiManager.instance.post(URLs.engineerMarkAsFixUrl, body: body); stateCode = response.statusCode; - print('engineer mark as fixed response is ${response.body}'); if (response.statusCode >= 200 && response.statusCode < 300) { currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body)); } @@ -376,17 +425,23 @@ class RequestDetailProvider extends ChangeNotifier { } //engineer Confirm Arrive...... - Future engineerConfirmArrival({required int workOrderId, required int verificationTypeId, required String photoInfo, required String otp, String? assetNo}) async { + Future engineerConfirmArrival({required int workOrderId, required int verificationTypeId, String ?photoInfo, String ?otp, String? assetNo, String? workOrderCreatedById}) async { Response response; try { - Map body = {"workOrderId": workOrderId, "verificationTypeId": verificationTypeId, "photoInfo": photoInfo, "otp": otp, "assetNumber": assetNo}; + //"workOrderCreatedById": "string" + Map body = { + "workOrderId": workOrderId, + "verificationTypeId": verificationTypeId, + "photoInfo": photoInfo, + "otp": otp, + "assetNumber": assetNo, + "workOrderCreatedById": workOrderCreatedById + }; isLoading = true; notifyListeners(); response = await ApiManager.instance.post(URLs.engineerConfirmArriveUrl, body: body); stateCode = response.statusCode; - if (response.statusCode >= 200 && response.statusCode < 300) { - // print('response of Engineer confirm arrival ${response.body}'); - } + if (response.statusCode >= 200 && response.statusCode < 300) {} isLoading = false; notifyListeners(); return response.statusCode; @@ -440,8 +495,6 @@ class RequestDetailProvider extends ChangeNotifier { } } - - //Nurse confirm reopen Future nurseReject() async { try { @@ -452,7 +505,6 @@ class RequestDetailProvider extends ChangeNotifier { CommonResponseModel commonResponseModel = CommonResponseModel(); if (response.statusCode >= 200 && response.statusCode < 300) { - commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); } isLoading = false; @@ -466,6 +518,30 @@ class RequestDetailProvider extends ChangeNotifier { } } + //Nurse confirm arrival + Future nurseConfirmArrival({required int workOrderId}) async { + try { + Map body = { + "workOrderId": workOrderId + }; + isLoading = true; + notifyListeners(); + final response = await ApiManager.instance.post(URLs.nurseAcceptUrl, body: body); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body)); + } + isLoading = false; + notifyListeners(); + return stateCode; + } catch (e) { + log("nurse reject [error] : $e"); + isLoading = false; + notifyListeners(); + return -1; + } + } + //Nurse confirm close Future nurseConfirm() async { try { @@ -495,7 +571,6 @@ class RequestDetailProvider extends ChangeNotifier { try { final response = await ApiManager.instance.post(URLs.updateActivitySparePartUrl, body: sparePartHelperModel!.toJson()); stateCode = response.statusCode; - print('update response i got is ${response.body}'); if (response.statusCode >= 200 && response.statusCode < 300) { // request.engineerName = employee.name; } @@ -533,7 +608,6 @@ class RequestDetailProvider extends ChangeNotifier { try { Response response = await ApiManager.instance.get("${URLs.getSuppliersAutoComplete}?searchText=$supplierName"); stateCode = response.statusCode; - print('response i got is ${json.decode(response.body)["data"]}'); List persons = []; if (response.statusCode >= 200 && response.statusCode < 300) { List categoriesListJson = json.decode(response.body)["data"][0]['suppPersons']; @@ -555,7 +629,6 @@ class RequestDetailProvider extends ChangeNotifier { try { final response = await ApiManager.instance.post(URLs.deleteActivitySparePartUrl, body: body); stateCode = response.statusCode; - print('response of delete activity spare part is ${response.statusCode}'); if (response.statusCode >= 200 && response.statusCode < 300) { //map to the model... @@ -604,7 +677,6 @@ class RequestDetailProvider extends ChangeNotifier { body: sparePartHelperModel!.toJson(), ); stateCode = response.statusCode; - print('add sparepart activity response i got is ${response.body}'); if (response.statusCode >= 200 && response.statusCode < 300) { // currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body)); // // updateCurrentWorkOrder(currentWorkOrder); @@ -629,7 +701,6 @@ class RequestDetailProvider extends ChangeNotifier { body: activityMaintenanceHelperModel!.toJson(), ); stateCode = response.statusCode; - print('add maintenance activity response i got is ${response.body}'); if (response.statusCode >= 200 && response.statusCode < 300) { // currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body)); // updateCurrentWorkOrder(currentWorkOrder); @@ -668,24 +739,24 @@ class RequestDetailProvider extends ChangeNotifier { } //get Arrival type...... - Future getArrivalVerificationType() async { - ArrivalVerificationTypeModel arrivalVerificationTypeModel = ArrivalVerificationTypeModel(); + Future getArrivalVerificationType() async { try { - isLoading = true; + isArrivalLoading = true; notifyListeners(); final response = await ApiManager.instance.get(URLs.getArrivalVerificationTypeUrl); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { - arrivalVerificationTypeModel = ArrivalVerificationTypeModel.fromJson(json.decode(response.body)); + ArrivalVerificationTypeModel arrivalVerificationTypeModel = ArrivalVerificationTypeModel.fromJson(json.decode(response.body)); + arrivalTypeList = arrivalVerificationTypeModel.data ?? []; } - isLoading = false; + isArrivalLoading = false; notifyListeners(); - return arrivalVerificationTypeModel; + return response.statusCode; } catch (e) { log("getArrivalVerifaction [error] : $e"); - isLoading = false; + isArrivalLoading = false; notifyListeners(); - return arrivalVerificationTypeModel; + return -1; } } @@ -697,10 +768,7 @@ class RequestDetailProvider extends ChangeNotifier { final response = await ApiManager.instance.postWithOutBody( URLs.sendOtpUrl + "$workOrderId", ); - print('url for send otp is ${URLs.sendOtpUrl + "$workOrderId"}'); stateCode = response.statusCode; - print('response i got is ${response.body}'); - if (response.statusCode >= 200 && response.statusCode < 300) {} isLoading = false; notifyListeners(); diff --git a/lib/service_request_latest/utilities/service_request_utils.dart b/lib/service_request_latest/utilities/service_request_utils.dart index d634d13d..a19351ec 100644 --- a/lib/service_request_latest/utilities/service_request_utils.dart +++ b/lib/service_request_latest/utilities/service_request_utils.dart @@ -1,4 +1,13 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/extensions/context_extension.dart'; +import 'package:test_sa/extensions/text_extensions.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; +import 'package:test_sa/service_request_latest/request_detail_provider.dart'; class ServiceRequestUtils { static double calculateAndAssignWorkingHours({ @@ -20,4 +29,37 @@ class ServiceRequestUtils { } } + static void getQrCode({required BuildContext context }) async{ + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + RequestDetailProvider requestDetailProvider = Provider.of(context,listen:false); + String? base64String = await requestDetailProvider.getQrCode(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId ?? 0); + Navigator.pop(context); + if (base64String != null) { + // You have the base64 string, now you can display it + Uint8List bytes = base64Decode(base64String); + + showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + backgroundColor: Colors.white, + title:context.translation.scanQr.heading6(context).center, + content: Image.memory( + bytes, // Displaying the QR code from base64 + fit: BoxFit.contain, // Ensure the image fits well in the dialog + errorBuilder: (context, error, stackTrace) { + return const Icon(Icons.error, color: Colors.red); + }, + ), + + ); + }, + ); + } else { + print('Failed to get the QR code'); + } + + + } + } diff --git a/lib/service_request_latest/views/components/action_button/footer_action_button.dart b/lib/service_request_latest/views/components/action_button/footer_action_button.dart index aac26800..3cf87d74 100644 --- a/lib/service_request_latest/views/components/action_button/footer_action_button.dart +++ b/lib/service_request_latest/views/components/action_button/footer_action_button.dart @@ -1,3 +1,6 @@ +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart'; @@ -11,8 +14,10 @@ import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_mo import 'package:test_sa/models/new_models/work_order_detail_model.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/providers/service_request_providers/reject_reason_provider.dart'; import 'package:test_sa/service_request_latest/request_detail_provider.dart'; +import 'package:test_sa/service_request_latest/utilities/service_request_utils.dart'; import 'package:test_sa/service_request_latest/views/components/activities_list_view.dart'; import 'package:test_sa/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart'; import 'package:test_sa/service_request_latest/views/components/verify_arrival_view.dart'; @@ -37,10 +42,21 @@ class FooterActionButton { bool showMarkAsFixedButton = activities.isEmpty ? true : activities.every((object) => object.activityStatus!.name!.toLowerCase() == "completed"); if (userProvider.user?.type == UsersTypes.engineer) { + print('status i got is ${workOrderNextStepStatus}'); + switch (workOrderNextStepStatus) { case WorkOrderNextStepEnum.onlyView: - return const SizedBox(); - // TODO: Handle this case. + return footerContainer( + child: AppFilledButton( + label: 'Assign To Me', + // maxWidth: true, + buttonColor: AppColor.primary10, + onPressed: () async { + //TODO uncommit this after testing ... + requestDetailProvider.engineerAssignWorkOrderToHimself(id: requestDetailProvider.currentWorkOrder!.data!.requestId.toString()); + }, + fontSize: 12.toScreenWidth, + )); case WorkOrderNextStepEnum.markedAsFixed: break; // TODO: Handle this case. @@ -138,7 +154,12 @@ class FooterActionButton { // maxWidth: true, buttonColor: AppColor.primary10, onPressed: () async { - Navigator.push(context, MaterialPageRoute(builder: (context) => VerifyAssetDetails(isEdit: false,))); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => VerifyAssetDetails( + isEdit: false, + ))); }, )); case WorkOrderNextStepEnum.activity: @@ -178,13 +199,17 @@ class FooterActionButton { textColor: AppColor.neutral150, fontSize: 12.toScreenWidth, )); + case WorkOrderNextStepEnum.waitingForRequesterToConfirm: + return footerContainer( + child: AppFilledButton( + label: 'Waiting for requester to verify', + buttonColor: AppColor.neutral140, + textColor: AppColor.neutral150, + fontSize: 12.toScreenWidth, + )); } - } - else { - print('value is ${workOrderNextStepStatus}'); + } else { if (workOrderNextStepStatus == WorkOrderNextStepEnum.nTakeAction) { - print('i am here take action ..'); - return footerContainer( child: AppFilledButton( label: context.translation.takeAction, @@ -195,6 +220,21 @@ class FooterActionButton { }, )); } + if (workOrderNextStepStatus == WorkOrderNextStepEnum.waitingForRequesterToConfirm) { + return footerContainer( + child: AppFilledButton( + label: context.translation.confirm, + // maxWidth: true, + buttonColor: AppColor.green70, + onPressed: () async { + int ?status = await requestDetailProvider.nurseConfirmArrival(workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId??0); + if(status==200){ + + } + }, + )); + } + } return const SizedBox(); } diff --git a/lib/service_request_latest/views/components/activities_list_view.dart b/lib/service_request_latest/views/components/activities_list_view.dart index 3ddf45d5..890e0456 100644 --- a/lib/service_request_latest/views/components/activities_list_view.dart +++ b/lib/service_request_latest/views/components/activities_list_view.dart @@ -145,6 +145,8 @@ class _ActivitiesListViewState extends State { } Widget sparePartActivityCard({required RequestDetailProvider requestDetailProvider, required UserProvider userProvider, required BuildContext context, required Activities activity}) { + print('activity i got is ${activity?.toJson()}'); + print('activity status i got is ${activity.activityStatus?.toJson()}'); return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, @@ -340,7 +342,7 @@ class _ActivitiesListViewState extends State { workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId, startTime: activity.activityMaintenance?.startTime != null ? DateTime.parse(activity.activityMaintenance!.startTime!) : null, endTime: activity.activityMaintenance?.endTime != null ? DateTime.parse(activity.activityMaintenance!.endTime!) : null, - activityStatus: activity.activityMaintenance?.lastSituation, + activityStatus: activity.activityStatus, workingHour: activity.activityMaintenance?.workingHours ?? 0, travelHours: activity.activityMaintenance?.travelHours ?? 0, repairLocation: activity.activityMaintenance?.repairLocation, diff --git a/lib/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart b/lib/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart index 804e33be..52605aa2 100644 --- a/lib/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart +++ b/lib/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart @@ -175,9 +175,9 @@ class ServiceRequestBottomSheet { 16.height, Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, children: [ - SizedBox( - width: 200.toScreenHeight, + Expanded( child: AppFilledButton( label: context.translation.cancel, loading: false, @@ -189,8 +189,8 @@ class ServiceRequestBottomSheet { }, ), ), - SizedBox( - width: 200.toScreenHeight, + 10.width, + Expanded( child: AppFilledButton( label: context.translation.fixed, buttonColor: AppColor.green70, diff --git a/lib/service_request_latest/views/components/request_detail_view.dart b/lib/service_request_latest/views/components/request_detail_view.dart index 4982aac2..6b07b499 100644 --- a/lib/service_request_latest/views/components/request_detail_view.dart +++ b/lib/service_request_latest/views/components/request_detail_view.dart @@ -236,7 +236,7 @@ class WorkOrderDetailView extends StatelessWidget { if (workOrder.workOrderAttachments.isNotEmpty ?? false) ...[ 8.height, const Divider().defaultStyle(context), - FilesList(images: workOrder.workOrderAttachments.map((toElement) => URLs.getFileUrl(toElement.name!)!).toList()), + FilesList(images: workOrder.workOrderAttachments.map((toElement) => URLs.getFileUrl(toElement.name??'')??'').toList()), ], if (workOrder.voiceNote?.isNotEmpty ?? false) ...[ const Divider().defaultStyle(context), @@ -303,8 +303,8 @@ class WorkOrderDetailView extends StatelessWidget { // // ); // }), //set condition for show asset detail button... - if (workOrder.nextStep!.workOrderNextStepEnum == WorkOrderNextStepEnum.verifyAssetDetail || - workOrder.nextStep!.workOrderNextStepEnum == WorkOrderNextStepEnum.activity && userProvider.user?.type == UsersTypes.engineer) ...[ + if ((workOrder.nextStep!.workOrderNextStepEnum == WorkOrderNextStepEnum.verifyAssetDetail || + workOrder.nextStep!.workOrderNextStepEnum == WorkOrderNextStepEnum.activity) && userProvider.user?.type == UsersTypes.engineer) ...[ assetRetiredButton(context: context), ] ], @@ -359,8 +359,8 @@ class WorkOrderDetailView extends StatelessWidget { equipmentStatus: currentWorkOrderData.equipmentStatus, loanAvailability: currentWorkOrderData.loanAvailablity, failureReason: currentWorkOrderData.failureReasone, - // faultDescription: currentWorkOrderData.fa, - solution: currentWorkOrderData.solution?.name, + faultDescription: currentWorkOrderData.faultDescription, + solution: currentWorkOrderData.faultDescription?.workPerformed, returnToService: currentWorkOrderData.returnToService, serviceType: currentWorkOrderData.serviceType, ); diff --git a/lib/service_request_latest/views/components/verify_arrival_view.dart b/lib/service_request_latest/views/components/verify_arrival_view.dart index a4132de0..0baa10dd 100644 --- a/lib/service_request_latest/views/components/verify_arrival_view.dart +++ b/lib/service_request_latest/views/components/verify_arrival_view.dart @@ -1,30 +1,21 @@ import 'dart:convert'; import 'dart:io'; - import 'package:flutter/material.dart'; -import 'package:flutter_svg/svg.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:image_picker/image_picker.dart'; import 'package:provider/provider.dart'; -import 'package:test_sa/app_strings/app_asset.dart'; -import 'package:test_sa/controllers/providers/api/service_requests_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; -import 'package:test_sa/models/new_models/arrival_verification_type_model.dart'; -import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; +import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/service_request_latest/request_detail_provider.dart'; import 'package:test_sa/service_request_latest/views/components/verify_otp_view.dart'; -import 'package:test_sa/service_request_latest/views/forms/asset_retired/asset_retired.dart'; -import 'package:test_sa/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart'; -import 'package:test_sa/service_request_latest/views/request_detail_main_view.dart'; +import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import 'package:test_sa/views/widgets/qr/scan_qr.dart'; -import 'activities_list_view.dart'; - class VerifyArrivalView extends StatefulWidget { const VerifyArrivalView({Key? key}) : super(key: key); @@ -33,12 +24,8 @@ class VerifyArrivalView extends StatefulWidget { } class _VerifyArrivalViewState extends State { - ArrivalVerificationTypeModel? arrivalVerificationTypeModel; - @override void initState() { - //TODO call this when all data is confirmed - // getInitialData(); WidgetsBinding.instance.addPostFrameCallback((_) { getInitialData(); }); @@ -47,46 +34,40 @@ class _VerifyArrivalViewState extends State { Future getInitialData() async { RequestDetailProvider requestDetailProvider = Provider.of(context, listen: false); - arrivalVerificationTypeModel = await requestDetailProvider.getArrivalVerificationType(); - print('data i got is${arrivalVerificationTypeModel?.data?.first?.verificationTypeId}'); + await requestDetailProvider.getArrivalVerificationType(); } @override Widget build(BuildContext context) { - //TODO replace the list with Api... - final List> items = [ - {'heading': context.translation.scanQr, 'subHeading': context.translation.scanQrDetail, 'icon': AppAsset.scanQrIcon, 'id': 1}, - {'heading': context.translation.askRequester, 'subHeading': context.translation.askRequesterDetail, 'icon': AppAsset.askRequesterIcon, 'id': 2}, - {'heading': context.translation.askOtp, 'subHeading': context.translation.askOtpDetail, 'icon': AppAsset.askOtpIcon, 'id': 3}, - {'heading': context.translation.takeDevicePhoto, 'subHeading': context.translation.takeDevicePhotoDetail, 'icon': AppAsset.takeDevicePhotoIcon, 'id': 4}, - ]; return Scaffold( appBar: DefaultAppBar(title: context.translation.verifyArrival), //backgroundColor: const Color(0xfff8f9fb), body: Consumer(builder: (context, RequestDetailProvider requestDetailProvider, child) { return SafeArea( - child: ListView.builder( - padding: EdgeInsets.zero, - itemCount: items.length, - itemBuilder: (context, index) { - final item = items[index]; - return customListItem( - icon: item['icon']!, - heading: item['heading']!, - subHeading: item['subHeading']!, - context: context, - onTap: () { - onItemTap(requestDetailProvider: requestDetailProvider, index: index, context: context); - }); - }, - ).paddingOnly(start: 16, end: 16, top: 12, bottom: 12), + child: requestDetailProvider.isArrivalLoading + ? const CircularProgressIndicator(color: AppColor.primary10).center + : requestDetailProvider.arrivalTypeList.isEmpty + ? const NoDataFound().center + : ListView.builder( + padding: EdgeInsets.zero, + itemCount: requestDetailProvider.arrivalTypeList.length, + itemBuilder: (builderContext, index) { + final item = requestDetailProvider.arrivalTypeList[index]; + return customListItem( + icon: item.verificationTypes!.icon ?? '', + heading: item.verificationTypes!.name ?? '', + subHeading: item.description ?? '', + onTap: () { + onItemTap(requestDetailProvider: requestDetailProvider, index: index, context: context, verificationTypeId: item.verificationTypes?.value); + }); + }, + ).paddingOnly(start: 16, end: 16, top: 12, bottom: 12), ); }), ); } Widget customListItem({ - required BuildContext context, required String icon, required String heading, required String subHeading, @@ -133,7 +114,7 @@ class _VerifyArrivalViewState extends State { ); } - void onItemTap({required int index, required RequestDetailProvider requestDetailProvider, required BuildContext context}) async { + void onItemTap({required int index, required RequestDetailProvider requestDetailProvider, required BuildContext context, int? verificationTypeId}) async { switch (index) { case 0: int? status; @@ -143,34 +124,44 @@ class _VerifyArrivalViewState extends State { if (result != null) { try { //TODO show loader. - // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); - + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); status = await requestDetailProvider.engineerConfirmArrival( - workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: 1, photoInfo: '', otp: '', assetNo: result); + workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: verificationTypeId ?? 1, photoInfo: '', otp: '', assetNo: result); if (status == 200) { requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); - //Navigator.pop(context); + Navigator.pop(context); requestDetailProvider.startTimer(); - Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => RequestDetailMain(requestId: requestDetailProvider.currentWorkOrder!.data!.requestId!))); + Navigator.pop(context); } else { - // Navigator.pop(context); + Navigator.pop(context); //show some message. } } catch (e) { - // Navigator.pop(context); + Navigator.pop(context); print('error i got is $e'); } } break; case 1: - Fluttertoast.showToast(msg: 'Under process...' ?? "", toastLength: Toast.LENGTH_LONG); + try { + int? status; + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + status = await requestDetailProvider.engineerConfirmArrival( + workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: verificationTypeId ?? 1, photoInfo: '', otp: ''); + if (status == 200) { + Navigator.pop(context); + requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); + Navigator.pop(context); + requestDetailProvider.startTimer(); + } else { + Navigator.pop(context); + } + } catch (e) { + Navigator.pop(context); + } break; case 2: - //TODO add loader. - // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); - requestDetailProvider.sendOtp(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!); - //Navigator.pop(context); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const VerifyOtpView()), @@ -182,89 +173,54 @@ class _VerifyArrivalViewState extends State { var fileObj = ("${pickedFile.path.split("/").last}|${base64Encode(File(pickedFile.path).readAsBytesSync())}"); int? status; try { - //TODO add loader - // showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); - status = await requestDetailProvider.engineerConfirmArrival(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: 4, photoInfo: fileObj, otp: ''); - + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + status = await requestDetailProvider.engineerConfirmArrival( + workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, verificationTypeId: verificationTypeId ?? 4, photoInfo: fileObj, otp: ''); if (status == 200) { + Navigator.pop(context); requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); - // Navigator.pop(context); + Navigator.pop(context); + requestDetailProvider.startTimer(); + } else { + Navigator.pop(context); + } + } catch (e) { + Navigator.pop(context); + } + } + break; + case 4: + int? status; + String? result = await Navigator.of(context).push( + MaterialPageRoute(builder: (_) => const ScanQr()), + ) as String?; + if (result != null) { + try { + Map resultJson = jsonDecode(result); + print('result i got is ${resultJson}'); + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + status = await requestDetailProvider.engineerConfirmArrival( + workOrderId: resultJson['WorkOrderId'], verificationTypeId: 5, workOrderCreatedById: resultJson['WorkOrderCreatedById']); + if (status == 200) { + requestDetailProvider.getWorkOrderById(id: resultJson['WorkOrderId']); + Navigator.pop(context); requestDetailProvider.startTimer(); - Navigator.pushReplacement(context, MaterialPageRoute(builder: (context) => RequestDetailMain(requestId: requestDetailProvider.currentWorkOrder!.data!.requestId!))); + Navigator.pop(context); } else { + Navigator.pop(context); //show some message. - // Navigator.pop(context); } } catch (e) { + Navigator.pop(context); print('error i got is $e'); - // Navigator.pop(context); } } - - // Navigator.push( - // context, - // MaterialPageRoute(builder: (context) => const VerifyAssetDetails()), - // ); - //push to specific screen... - // Navigator.push( - // context, - // MaterialPageRoute(builder: (context) => const ScanQrView()), - // ); break; } // ScanQr } Future onFilePicker() async { - // ImageSource? source = await showModalBottomSheet( - // context: context, - // builder: (BuildContext context) { - // Widget listCard({required String icon, required String label, required VoidCallback onTap}) { - // return GestureDetector( - // onTap: onTap, - // child: Container( - // constraints: BoxConstraints(minWidth: 111.toScreenWidth, minHeight: 111.toScreenHeight), - // padding: EdgeInsets.symmetric(horizontal: 12.toScreenWidth, vertical: 12.toScreenHeight), - // decoration: BoxDecoration(borderRadius: BorderRadius.circular(12), border: Border.all(width: 1, color: AppColor.white70)), - // child: Column( - // mainAxisSize: MainAxisSize.min, - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // icon.toSvgAsset(), - // 24.height, - // label.bodyText2(context).custom(color: AppColor.black20), - // ], - // ), - // ), - // ); - // } - // - // return Container( - // padding: const EdgeInsets.all(16.0), - // child: Row( - // // mainAxisAlignment: MainAxisAlignment.spaceBetween, - // children: [ - // listCard( - // icon: 'camera_icon', - // label: '${context.translation.open}\n${context.translation.camera}', - // onTap: () { - // Navigator.of(context).pop(ImageSource.camera); - // }, - // ), - // 20.width, - // listCard( - // icon: 'gallery_icon', - // label: '${context.translation.open}\n${context.translation.gallery}', - // onTap: () { - // Navigator.of(context).pop(ImageSource.gallery); - // }, - // ), - // ], - // ), - // ); - // }, - // ); - // if (source == null) return null; File? fileImage; final pickedFile = await ImagePicker().pickImage(source: ImageSource.camera, imageQuality: 70, maxWidth: 800, maxHeight: 800); diff --git a/lib/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart b/lib/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart index afb6ebb8..a3bb6206 100644 --- a/lib/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart +++ b/lib/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart @@ -72,9 +72,9 @@ class _VerifyAssetDetailsState extends State with TickerProv equipmentStatus: currentWorkOrderData.equipmentStatus, loanAvailability: currentWorkOrderData.loanAvailablity, failureReason: currentWorkOrderData.failureReasone, - faultDescription: FaultDescription(), + faultDescription: currentWorkOrderData.faultDescription, loanAssetId: currentWorkOrderData.assetLoan?.id, - solution: currentWorkOrderData.solution?.name, + solution: currentWorkOrderData.faultDescription?.workPerformed, returnToService: currentWorkOrderData.returnToService, serviceType: currentWorkOrderData.serviceType, ); diff --git a/lib/service_request_latest/views/request_detail_main_view.dart b/lib/service_request_latest/views/request_detail_main_view.dart index 51b28766..b16ff023 100644 --- a/lib/service_request_latest/views/request_detail_main_view.dart +++ b/lib/service_request_latest/views/request_detail_main_view.dart @@ -1,12 +1,15 @@ import 'package:flutter/material.dart'; 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/text_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/models/enums/user_types.dart'; import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/service_request_latest/request_detail_provider.dart'; +import 'package:test_sa/service_request_latest/views/components/get_qr_code_view.dart'; import 'package:test_sa/service_request_latest/views/components/history_log_view.dart'; import 'components/request_detail_view.dart'; @@ -24,12 +27,14 @@ class RequestDetailMain extends StatefulWidget { class _RequestDetailMainState extends State { late RequestDetailProvider _requestProvider; + UserProvider? _userProvider; @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { _requestProvider = Provider.of(context, listen: false); + _userProvider = Provider.of(context, listen: false); _requestProvider.getWorkOrderById(id: widget.requestId); }); } @@ -41,33 +46,33 @@ class _RequestDetailMainState extends State { @override Widget build(BuildContext context) { + print('user type i got is ${_userProvider?.user?.type}'); return WillPopScope( onWillPop: () async { // Implement custom back button handling logic here - RequestDetailProvider requestDetailProvider = Provider.of(context,listen: false); - if(requestDetailProvider.timer!=null&&requestDetailProvider.timer!.isActive){ + RequestDetailProvider requestDetailProvider = Provider.of(context, listen: false); + if (requestDetailProvider.timer != null && requestDetailProvider.timer!.isActive) { requestDetailProvider.stopTimer(); } return true; // Return true if you want to allow popping the screen, false otherwise }, child: Scaffold( backgroundColor: AppColor.neutral100, - appBar:AppBar( + appBar: AppBar( automaticallyImplyLeading: false, titleSpacing: 16, title: Row( children: [ const Icon(Icons.arrow_back_ios).onPress(() { - RequestDetailProvider requestDetailProvider = Provider.of(context,listen: false); - if(requestDetailProvider.timer!=null&&requestDetailProvider.timer!.isActive){ - requestDetailProvider.stopTimer(); + RequestDetailProvider requestDetailProvider = Provider.of(context, listen: false); + if (requestDetailProvider.timer != null && requestDetailProvider.timer!.isActive) { + requestDetailProvider.stopTimer(); } Navigator.pop(context); - }), 10.width, Text( - context.translation.cmDetails , + context.translation.cmDetails, style: AppTextStyles.heading3.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), ).expanded, ], @@ -111,7 +116,6 @@ class _RequestDetailMainState extends State { ], ), ), - ), - ); + ),); } }