diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index bed7f3cd..230aebdb 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -27,6 +27,7 @@ class URLs { static get getSiteAutoCompleteWithoutConditionSites => "$_baseUrl/Customer/GetCustomersAutoCompleteWithoutConditionSites"; // get static get getDepartments => "$_baseUrl/Customer/GetDepartmentLookup"; // get static get getAssets => "$_baseUrl/Asset/GetAssets"; // get + static get getFaultDescription => "$_baseUrl/Asset/GetDefectForModelDefinition"; // get static get getAssetById => "$_baseUrl/Asset/GetAssetById?assetId="; // get static get getModels => "$_baseUrl/ModelDefinition/GetModelDefinitionAsset"; // get ?client=2 static get getAllRequestsAndCount => "$_baseUrl/CallRequest/GetAllRequestsAndCount"; // get @@ -41,6 +42,7 @@ class URLs { static get engineerRejectUrl=> '$_baseUrl/ServiceRequest/EngineerReject'; static get engineerFixRemotlyUrl=> '$_baseUrl/ServiceRequest/EngineerFixRemotly'; static get engineerNeedVisitUrl=> '$_baseUrl/ServiceRequest/EngineerNeedVisit'; + static get engineerUpdateNeedVisitUrl=> '$_baseUrl/ServiceRequest/EngineerUpdateNeedVisit'; static get engineerMarkAsFixUrl=> '$_baseUrl/ServiceRequest/EngineerMarkAsFix'; static get engineerConfirmArriveUrl=> '$_baseUrl/ServiceRequest/EngineerConfirmArrive'; static get engineerUpdateWorkOrderUrl=> '$_baseUrl/ServiceRequest/EngineerUpdateWorkOrder'; @@ -107,8 +109,8 @@ class URLs { static get getPpmService => "$_baseUrl/Lookups/GetLookup?lookupEnum=34"; // get for ppm po reason, in mobile there is no use of it. static get getServiceReportReasons => "$_baseUrl/Lookups/GetLookupReason?lookupEnum=505"; - //TODO use this for testing ahmed create new apis for that - static get getServiceReportReasonsTest => "$_baseUrl/Lookups/GetLookup?lookupEnum=505"; + static get getServiceReportRejectionReasons => "$_baseUrl/Lookups/GetLookup?lookupEnum=1303"; + static get getServiceReportReasonsNew => "$_baseUrl/Lookups/GetLookupReasonNew?lookupEnum=505"; static get getServiceReportRetirementTypeTest => "$_baseUrl/Lookups/GetLookup?lookupEnum=415"; static get getServiceReportTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=501"; // get static get getServiceReportTypesForWO => "$_baseUrl/Lookups/GetLookup?lookupEnum=34"; // get @@ -120,7 +122,7 @@ class URLs { static get getServiceReportPriority => "$_baseUrl/Lookups/GetLookup?lookupEnum=4"; // get static get getServiceReportDefectTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=601"; // get static get getCallRequestForWorkOrder => "$_baseUrl/CallRequest/GetCallRequestForWorkOrder"; // get - + static get attachmentBaseUrl => "https://atomsmdev.hmg.com/v2/mobile/Files/DownloadFile?fileName="; //gas refill static get getGasTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=606"; // get // todo check edits with backend diff --git a/lib/extensions/widget_extensions.dart b/lib/extensions/widget_extensions.dart index 7ffe0f00..86e5f975 100644 --- a/lib/extensions/widget_extensions.dart +++ b/lib/extensions/widget_extensions.dart @@ -3,6 +3,8 @@ import 'package:flutter/material.dart'; import 'package:shimmer/shimmer.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/views/app_style/sizing.dart'; import '../new_views/app_style/app_color.dart'; @@ -30,7 +32,7 @@ extension WidgetExtensions on Widget { flushbarPosition: FlushbarPosition.TOP, backgroundColor: backgroundColor ?? AppColor.green70, title: title, - message: message, + messageText: Text(message,style: AppTextStyles.heading6.copyWith(color: AppColor.white10),), duration: Duration(seconds: duration ?? 3), flushbarStyle: FlushbarStyle.GROUNDED, reverseAnimationCurve: Curves.easeInOut, @@ -41,7 +43,7 @@ extension WidgetExtensions on Widget { icon: const Icon( Icons.close, color: AppColor.white20, - ), + ).paddingOnly(top: 25), ), )..show(context); diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index 74a29b4e..db53d276 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -11,6 +11,8 @@ "requestDetails": "تفاصيل الطلب", "retirementType": "نوع التقاعد", "assetRetiredPendingOpManagementApproval": "تم تقاعد الأصل. في انتظار موافقة إدارة العمليات", + "youMarkedThisIssueAsFixedWaitingForTheRequesterToConfirm": "لقد قمت بوضع علامة على هذه المشكلة على أنها تم إصلاحها. في انتظار تأكيد مقدم الطلب", + "assetRetirementRequestSubmittedSuccessfully": "تم تقديم طلب تقاعد الأصل بنجاح", "historyLogs": "سجلات التاريخ", "exitAlert": "هل انت متاكد من رغبتك في إغلاق التطبيق؟", "signOut": "تسجيل الخروج", @@ -30,6 +32,7 @@ "attachQuotation": "إرفاق العرض", "forgetPassword": "نسيت كلمة المرور", "addSparePartActivity": "إضافة نشاط قطع الغيار", + "updateSparePartActivity": "تحديث نشاط قطع غيار", "acceptTermsAndConditions": "موافقة علي الشروط والاحكام", "emailValidateMessage": "البريد الالكتروني غير صحيح", "nameValidateMessage": "الاسم مطلوب", diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 03f53b5b..2719d170 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -10,6 +10,8 @@ "exit": "Exit", "exitAlert": "Are you sure you want to exit?", "assetRetiredPendingOpManagementApproval": "Asset Retired. Pending OP Management Approval", + "assetRetirementRequestSubmittedSuccessfully": "Asset retirement request submitted successfully", + "youMarkedThisIssueAsFixedWaitingForTheRequesterToConfirm": "You marked this issue as fixed. Waiting for the requester to confirm", "signOut": "Sign Out", "logoutAlert": "Are you sure you want to Sign Out?", "language": "English", @@ -99,6 +101,7 @@ "sparePartDetails": "Spare Part Details", "attachQuotation": "Attach Quotation", "addSparePartActivity": "Add Spare Part Activity", + "updateSparePartActivity": "Update Spare Part Activity", "deviceName": "Asset Name", "deviceImages": "Asset Images", "deviceModel": "Asset Model", diff --git a/lib/main.dart b/lib/main.dart index 5648c4a8..4dcb198a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -51,6 +51,7 @@ import 'package:test_sa/providers/service_request_providers/first_action_provide import 'package:test_sa/providers/service_request_providers/priority_provider.dart'; import 'package:test_sa/providers/service_request_providers/requested_through_provider.dart'; import 'package:test_sa/providers/service_request_providers/type_of_request_provider.dart'; +import 'package:test_sa/providers/work_order/fault_description_provider.dart'; import 'package:test_sa/providers/work_order/reason_provider.dart'; import 'package:test_sa/providers/work_order/retirement_type_provider.dart'; import 'package:test_sa/providers/work_order/service_type_provider.dart'; @@ -82,6 +83,7 @@ import 'controllers/providers/settings/setting_provider.dart'; import 'dashboard_latest/dashboard_provider.dart'; import 'new_views/pages/new_gas_refill_request_page.dart'; import 'providers/service_request_providers/loan_availability_provider.dart'; +import 'providers/service_request_providers/reject_reason_provider.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -201,6 +203,8 @@ class MyApp extends StatelessWidget { /// Loan availability not required ChangeNotifierProvider(create: (_) => LoanAvailabilityProvider()), ChangeNotifierProvider(create: (_) => ReasonProvider()), + ChangeNotifierProvider(create: (_) => RejectReasonProvider()), + ChangeNotifierProvider(create: (_) => FaultDescriptionProvider()), ChangeNotifierProvider(create: (_) => RetirementTypeProvider()), ///todo deleted diff --git a/lib/models/helper_data_models/spare_part/activity_spare_part_model.dart b/lib/models/helper_data_models/spare_part/activity_spare_part_model.dart index 9ed71a79..82f616fa 100644 --- a/lib/models/helper_data_models/spare_part/activity_spare_part_model.dart +++ b/lib/models/helper_data_models/spare_part/activity_spare_part_model.dart @@ -4,6 +4,7 @@ class SparePartHelperModel { int? id; int? workOrderId; int? partCatalogItemId; + int? activityStatusId; SparePart? sparePart; num? quantity; String? comment; @@ -15,6 +16,7 @@ class SparePartHelperModel { this.partCatalogItemId, this.quantity, this.sparePart, + this.activityStatusId, this.comment,this.sparePartAttachments, }); @@ -25,6 +27,7 @@ class SparePartHelperModel { data['workOrderId'] = workOrderId; data['partCatalogItemId'] = sparePart?.id; data['quantity'] = quantity; + data['activityStatusId'] = activityStatusId; data['comment'] = comment; if (sparePartAttachments != null) { data['acitiySparePartAttachments'] = 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 bbd817dc..be919b55 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 @@ -1,4 +1,5 @@ +import 'package:test_sa/models/fault_description.dart'; import 'package:test_sa/models/lookup.dart'; import '../../new_models/work_order_detail_model.dart'; @@ -72,7 +73,7 @@ class EngineerUpdateWorkOrderHelperModel { num?loanAssetId; WorkOrderAsset? loanAsset; Lookup? failureReason; - Lookup? faultDescription; + FaultDescription? faultDescription; String? solution; EngineerUpdateWorkOrderHelperModel( @@ -97,10 +98,11 @@ class EngineerUpdateWorkOrderHelperModel { data['serviceTypeId'] = serviceType?.id; data['serviceTypeId'] = 65; data['loanAvailabilityId'] = loanAvailability?.id; - data['loanAssetId'] = loanAsset?.id; + data['loanAssetId'] = loanAssetId; data['failureReasonId'] = failureReason?.id; data['faultDescriptionId'] = faultDescription?.id; - data['solution'] = solution; + //TODO this cause issue with the return data + // data['solution'] = solution; return data; } } @@ -132,12 +134,11 @@ class NeedVisitHelperModel { class EngineerRejectHelperModel { int? workOrderId; String? feedback; - int? rejectReasonId; Lookup? rejectionReason; - EngineerRejectHelperModel({this.workOrderId, this.feedback, this.rejectReasonId,this.rejectionReason}); + EngineerRejectHelperModel({this.workOrderId, this.feedback,this.rejectionReason}); Map toJson() { - return {'workOrderId': workOrderId, 'feedback': feedback, 'rejectReasonId': rejectReasonId}; + return {'workOrderId': workOrderId, 'feedback': feedback, 'rejectReasonId': rejectionReason?.id}; } } \ No newline at end of file diff --git a/lib/models/new_models/work_order_detail_model.dart b/lib/models/new_models/work_order_detail_model.dart index 76449e23..d96c897f 100644 --- a/lib/models/new_models/work_order_detail_model.dart +++ b/lib/models/new_models/work_order_detail_model.dart @@ -1,3 +1,5 @@ +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'; class WorkOrderDetail { @@ -124,10 +126,12 @@ class WorkOrderData { DateTime? needAVisitDateTime; String?needAVisitComment; List workOrderHistory; - List activities; + List activities; List activityAssetToBeRetireds; factory WorkOrderData.fromJson(Map json) { + print('activities in json is ${json["activities"]}'); + return WorkOrderData( requestId: json["id"], workOrderNo: json["workOrderNo"], @@ -167,7 +171,7 @@ class WorkOrderData { 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))), - activities: json["activities"] == null ? [] : List.from(json["activities"]!.map((x) => x)), + activities: json["activities"] == null ? [] : List.from(json["activities"]!.map((x) => Activities.fromJson(x))), needAVisitDateTime: DateTime.tryParse(json["requestedDate"] ?? ""), needAVisitComment: json["needAVisitComment"], activityAssetToBeRetireds: json["activityAssetToBeRetireds"] == null ? [] : List.from(json["activityAssetToBeRetireds"]!.map((x) => x)), @@ -215,7 +219,7 @@ class WorkOrderData { "solution": solution?.toJson(), "totalWorkingHours": totalWorkingHours, "workOrderHistory": workOrderHistory.map((x) => x.toJson()).toList(), - "activities": activities.map((x) => x).toList(), + "activities": activities.map((x) => x.toJson()).toList(), "activityAssetToBeRetireds": activityAssetToBeRetireds.map((x) => x).toList(), }; Map toFixRemotelyJson() { @@ -323,6 +327,141 @@ class AssignedEmployee { "languageId": languageId, }; } +class Activities { + int? id; + int? orderNo; + ActivityStatus? activityStatus; + dynamic activityMaintenance; + ActivitySparePart? activitySparePart; + String ?activityType; + + Activities( + {this.id, + this.orderNo, + this.activityStatus, + this.activityMaintenance, + this.activityType, + this.activitySparePart}); + + Activities.fromJson(Map json) { + id = json['id']; + orderNo = json['orderNo']; + activityStatus = json['activityStatus'] != null + ? ActivityStatus.fromJson(json['activityStatus']) + : null; + activityMaintenance = json['activityMaintenance']; + if(activityMaintenance!=null){ + activityType='Maintenance Request'; + } + + activitySparePart = json['activitySparePart'] != null + ? ActivitySparePart.fromJson(json['activitySparePart']) + : null; + if(activitySparePart!=null){ + activityType='Spare Part Request'; + } + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + data['orderNo'] = orderNo; + if (activityStatus != null) { + data['activityStatus'] = activityStatus!.toJson(); + } + data['activityMaintenance'] = activityMaintenance; + if (activitySparePart != null) { + data['activitySparePart'] = activitySparePart!.toJson(); + } + return data; + } +} + +class ActivityStatus { + int? id; + String? name; + int? value; + + ActivityStatus({this.id, this.name, this.value}); + + ActivityStatus.fromJson(Map json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['name'] = this.name; + data['value'] = this.value; + return data; + } +} + +class ActivitySparePart { + int? id; + PartCatalogItem? partCatalogItem; + double? quantity; + List? acitiySparePartAttachments; + + ActivitySparePart( + {this.id, + this.partCatalogItem, + this.quantity, + this.acitiySparePartAttachments}); + + ActivitySparePart.fromJson(Map json) { + id = json['id']; + partCatalogItem = json['partCatalogItem'] != null + ? new PartCatalogItem.fromJson(json['partCatalogItem']) + : null; + quantity = json['quantity']; + if (json['acitiySparePartAttachments'] != null) { + acitiySparePartAttachments = []; + json['acitiySparePartAttachments'].forEach((v) { + acitiySparePartAttachments!.add(SparePartAttachments.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = {}; + data['id'] = id; + if (partCatalogItem != null) { + data['partCatalogItem'] = partCatalogItem!.toJson(); + } + data['quantity'] = quantity; + if (acitiySparePartAttachments != null) { + data['acitiySparePartAttachments'] = + acitiySparePartAttachments!.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class PartCatalogItem { + int? id; + String? partName; + String? partNumber; + + PartCatalogItem({this.id, this.partName, this.partNumber}); + + PartCatalogItem.fromJson(Map json) { + id = json['id']; + partName = json['partName']; + partNumber = json['partNumber']; + } + + Map toJson() { + final Map data = new Map(); + data['id'] = this.id; + data['partName'] = this.partName; + data['partNumber'] = this.partNumber; + return data; + } +} + class Site { Site({ diff --git a/lib/models/service_request/spare_parts.dart b/lib/models/service_request/spare_parts.dart index 3e064815..5571d179 100644 --- a/lib/models/service_request/spare_parts.dart +++ b/lib/models/service_request/spare_parts.dart @@ -7,6 +7,7 @@ class SparePartsWorkOrders extends Base { id = json['id']; sparePart = json['sparePart'] != null ? SparePart.fromJson(json['sparePart']) : null; qty = json['qty']; + returnQty = json['returnQty']; installQty = json['installQty']; } @@ -38,6 +39,7 @@ class SparePart extends Base { this.id, this.partNo, this.partName, + this.oracleCode, this.assetId, }) : super(identifier: id?.toString(), name: partName); @@ -46,6 +48,7 @@ class SparePart extends Base { identifier = id?.toString(); partNo = json['partNo']; partName = json['partName']; + oracleCode = json['oracleCode']; name = partName; assetId = json['assetId']; } @@ -53,16 +56,18 @@ class SparePart extends Base { num? id; String? partNo; String? partName; + String? oracleCode; num? assetId; - SparePart copyWith({num? id, String? partNo, String? partName, num? assetId}) => - SparePart(id: id ?? this.id, partNo: partNo ?? this.partNo, partName: partName ?? this.partName, assetId: assetId ?? this.assetId); + SparePart copyWith({num? id, String? partNo, String? partName, num? assetId,String?oracleCode}) => + SparePart(id: id ?? this.id,oracleCode: oracleCode?? this.oracleCode, partNo: partNo ?? this.partNo, partName: partName ?? this.partName, assetId: assetId ?? this.assetId); Map toJson() { final map = {}; map['id'] = id; map['partNo'] = partNo; map['partName'] = partName; + map['oracleCode'] = oracleCode; map['assetId'] = assetId; return map; } diff --git a/lib/new_views/app_style/app_color.dart b/lib/new_views/app_style/app_color.dart index dfc7c3a1..4fde35b4 100644 --- a/lib/new_views/app_style/app_color.dart +++ b/lib/new_views/app_style/app_color.dart @@ -30,6 +30,7 @@ class AppColor { static const Color neutral130 = Color(0xffE0E0E0); static const Color neutral140 = Color(0xffE6E6E6); static const Color neutral150 = Color(0xffA1A1A1); + static const Color neutral160 = Color(0xffE5E5E5); //background diff --git a/lib/new_views/common_widgets/app_drawer.dart b/lib/new_views/common_widgets/app_drawer.dart index 5ac57d57..48fc9e81 100644 --- a/lib/new_views/common_widgets/app_drawer.dart +++ b/lib/new_views/common_widgets/app_drawer.dart @@ -34,6 +34,7 @@ class AppDrawer extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Consumer(builder: (context, snapshot, _) { + print('profile photo i got is ${snapshot.user!.profilePhotoName!}'); return CircleAvatar( radius: 45, backgroundColor: context.isDark ? AppColor.neutral50 : AppColor.neutral40, diff --git a/lib/new_views/common_widgets/single_item_drop_down_menu.dart b/lib/new_views/common_widgets/single_item_drop_down_menu.dart index 3b5f4eda..8673277c 100644 --- a/lib/new_views/common_widgets/single_item_drop_down_menu.dart +++ b/lib/new_views/common_widgets/single_item_drop_down_menu.dart @@ -53,8 +53,10 @@ class _SingleItemDropDownMenuState(widget.context, listen: false); } + print('initial value i got is ${widget.initialValue?.identifier}'); if (widget.initialValue != null) { final result = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.where((element) => element.identifier == widget.initialValue?.identifier); + print('result value i got is ${result?.length}'); if (result?.isNotEmpty ?? false) _selectedItem = result!.first as T?; if (widget.onSelect != null && (widget.initialValue?.identifier ?? "") != (_selectedItem?.identifier ?? "")) { widget.onSelect!(_selectedItem); // Non-null assertion after null check @@ -70,6 +72,7 @@ class _SingleItemDropDownMenuState oldWidget) { + if (widget.initialValue != null) { final result = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.where((element) => element.identifier == widget.initialValue?.identifier); if (result?.isNotEmpty ?? false) { @@ -89,7 +92,6 @@ class _SingleItemDropDownMenuState(widget.context, listen: true); - final isEmpty = (X == NullableLoadingProvider ? widget.staticData : provider?.items)?.isEmpty ?? true; return AppLoadingManager( isLoading: widget.loading ?? ((X == NullableLoadingProvider) ? false : provider?.loading ?? false), diff --git a/lib/providers/service_request_providers/reject_reason_provider.dart b/lib/providers/service_request_providers/reject_reason_provider.dart new file mode 100644 index 00000000..9641ddc7 --- /dev/null +++ b/lib/providers/service_request_providers/reject_reason_provider.dart @@ -0,0 +1,38 @@ +import 'dart:convert'; + +import 'package:http/http.dart'; +import 'package:test_sa/providers/loading_list_notifier.dart'; + +import '../../controllers/api_routes/api_manager.dart'; +import '../../controllers/api_routes/urls.dart'; +import '../../models/lookup.dart'; + +class RejectReasonProvider extends LoadingListNotifier { + + + @override + Future getDate() async { + if (loading == true) return -2; + loading = true; + notifyListeners(); + loading = true; + notifyListeners(); + try { + Response response = await ApiManager.instance.get(URLs.getServiceReportRejectionReasons); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List categoriesListJson = json.decode(response.body)["data"]; + items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList(); + } + loading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + loading = false; + stateCode = -1; + notifyListeners(); + return -1; + } + } +} diff --git a/lib/providers/work_order/fault_description_provider.dart b/lib/providers/work_order/fault_description_provider.dart new file mode 100644 index 00000000..9c05109b --- /dev/null +++ b/lib/providers/work_order/fault_description_provider.dart @@ -0,0 +1,41 @@ +import 'dart:convert'; + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart'; +import 'package:test_sa/controllers/api_routes/api_manager.dart'; +import 'package:test_sa/controllers/api_routes/urls.dart'; +import 'package:test_sa/models/fault_description.dart'; +import 'package:test_sa/models/service_request/spare_parts.dart'; + +class FaultDescriptionProvider extends ChangeNotifier { + + int? _stateCode; + + int? get stateCode => _stateCode; + + bool _loading = false; + + bool get isLoading => _loading; + + set isLoading(bool isLoading) { + _loading = isLoading; + notifyListeners(); + } + Future> getFaultDescriptionList({num? assetId}) async { + late Response response; + try { + + response = await ApiManager.instance.get(URLs.getFaultDescription+"?assetId=$assetId",); + List list = []; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List faultListJson = json.decode(response.body)["data"]; + list = faultListJson.map((fault) => FaultDescription.fromJson(fault)).toList(); + } + return list; + } catch (error) { + return []; + } + } +} diff --git a/lib/providers/work_order/reason_provider.dart b/lib/providers/work_order/reason_provider.dart index 20004193..7176ad35 100644 --- a/lib/providers/work_order/reason_provider.dart +++ b/lib/providers/work_order/reason_provider.dart @@ -19,11 +19,9 @@ class ReasonProvider extends LoadingListNotifier { loading = true; notifyListeners(); try { - //TODO change this url only used for testing till ahmed make a new api.. getServiceReportReasonsTest replace with getServiceReportReasons - Response response = await ApiManager.instance.get(URLs.getServiceReportReasonsTest+"&serviceRequestId=$serviceRequestId"); + Response response = await ApiManager.instance.get(URLs.getServiceReportReasonsNew+"&serviceRequestId=$serviceRequestId"); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { - // client's request was successfully received List categoriesListJson = json.decode(response.body)["data"]; items = categoriesListJson.map((item) => Lookup.fromJson(item)).toList(); } diff --git a/lib/service_request_latest/request_detail_provider.dart b/lib/service_request_latest/request_detail_provider.dart index db335b29..03a3417f 100644 --- a/lib/service_request_latest/request_detail_provider.dart +++ b/lib/service_request_latest/request_detail_provider.dart @@ -3,6 +3,7 @@ import 'dart:convert'; import 'dart:developer'; import 'package:flutter/material.dart'; +import 'package:http/src/response.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/models/helper_data_models/asset_retired/asset_retired_model.dart'; @@ -63,11 +64,11 @@ class RequestDetailProvider extends ChangeNotifier { //UI models WorkOrderDetail? currentWorkOrder; AssetRetiredHelperModel? assetRetiredHelperModel=AssetRetiredHelperModel(); - SparePartHelperModel? sparePartHelperModel=SparePartHelperModel(); + SparePartHelperModel? sparePartHelperModel; FixRemotelyHelperModel? fixRemotelyHelperModel=FixRemotelyHelperModel(); NeedVisitHelperModel? needVisitHelperModel=NeedVisitHelperModel(); NurseActionHelperModel? nurseActionHelperModel; - EngineerRejectHelperModel? engineerRejectHelperModel; + EngineerRejectHelperModel? engineerRejectHelperModel=EngineerRejectHelperModel(); EngineerUpdateWorkOrderHelperModel? engineerUpdateWorkOrderHelperModel=EngineerUpdateWorkOrderHelperModel(); WorkOrderHelperModel? workOrderHelperModel; @@ -182,125 +183,157 @@ class RequestDetailProvider extends ChangeNotifier { } //engineerAcceptWorkOrder...... - Future engineerAcceptWorkOrder({required String id}) async { + Future engineerAcceptWorkOrder({required String id}) async { + Response response; try { final body = { "workOrderId": id, }; isLoading = true; - final response = await ApiManager.instance.post(URLs.engineerAcceptUrl, body: body); + response = await ApiManager.instance.post(URLs.engineerAcceptUrl, body: body); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { - CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); - print('response of Engineer accept workorder ${commonResponseModel.toJson()}'); + currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body)); + updateCurrentWorkOrder(currentWorkOrder); notifyListeners(); isLoading = false; - return commonResponseModel; + return response.statusCode; } isLoading = false; notifyListeners(); - return CommonResponseModel(); + return response.statusCode; } catch (e) { log("engineer accept [error] : $e"); isLoading = false; notifyListeners(); - return CommonResponseModel(); + return -1; } } //engineerRejectWorkOrder...... - Future engineerRejectWorkOrder() async { + Future engineerRejectWorkOrder() async { + Response response ; try { isLoading = true; - final response = await ApiManager.instance.post(URLs.engineerRejectUrl, body: engineerRejectHelperModel!.toJson()); + response = await ApiManager.instance.post(URLs.engineerRejectUrl, body: engineerRejectHelperModel!.toJson()); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { - CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); - print('response of Engineer reject workorder ${commonResponseModel.toJson()}'); + print('engineer reject workOrder response is ${response.body}'); + currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body)); + updateCurrentWorkOrder(currentWorkOrder); notifyListeners(); isLoading = false; - return commonResponseModel; + return response.statusCode; } isLoading = false; notifyListeners(); - return CommonResponseModel(); + return response.statusCode; } catch (e) { - log("engineer accept [error] : $e"); + log("engineer reject [error] : $e"); isLoading = false; notifyListeners(); - return CommonResponseModel(); + return -1; } } //engineerFixRemotelyWorkOrder...... - Future engineerFixRemotely() async { + Future engineerFixRemotely() async { + Response response; try { isLoading = true; - final response = await ApiManager.instance.post(URLs.engineerFixRemotlyUrl, body: fixRemotelyHelperModel!.toJson()); + response = await ApiManager.instance.post(URLs.engineerFixRemotlyUrl, body: fixRemotelyHelperModel!.toJson()); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { - CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); - print('response of Engineer fixremotely workorder ${commonResponseModel.toJson()}'); + updateCurrentWorkOrder(WorkOrderDetail.fromJson(json.decode(response.body))); notifyListeners(); isLoading = false; - return commonResponseModel; + return response.statusCode; } isLoading = false; notifyListeners(); - return CommonResponseModel(); + return response.statusCode; } catch (e) { - log("engineer accept [error] : $e"); + log("engineer fix remotely [error] : $e"); isLoading = false; notifyListeners(); - return CommonResponseModel(); + return -1; } } //engineerNeedAVisitWorkOrder...... - Future engineerNeedVisit() async { + Future engineerNeedVisit() async { + Response response; try { isLoading = true; - final response = await ApiManager.instance.post(URLs.engineerNeedVisitUrl, body: needVisitHelperModel!.toJson()); + response = await ApiManager.instance.post(URLs.engineerNeedVisitUrl, body: needVisitHelperModel!.toJson()); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { - CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); - print('response of Engineer fixremotely workorder ${commonResponseModel.toJson()}'); + currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body)); + updateCurrentWorkOrder(currentWorkOrder); notifyListeners(); isLoading = false; - return commonResponseModel; + return response.statusCode; } isLoading = false; notifyListeners(); - return CommonResponseModel(); + return response.statusCode; } catch (e) { log("engineer accept [error] : $e"); isLoading = false; notifyListeners(); - return CommonResponseModel(); + return -1; + } + } + //engineerUpdateNeedAVisitWorkOrder...... + Future engineerUpdateNeedVisit() async { + Response response; + try { + isLoading = true; + 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)); + updateCurrentWorkOrder(currentWorkOrder); + notifyListeners(); + isLoading = false; + return response.statusCode; + } + isLoading = false; + notifyListeners(); + return response.statusCode; + } catch (e) { + log("engineer accept [error] : $e"); + isLoading = false; + notifyListeners(); + return -1; } } //engineerMarkAsFixed...... - Future engineerMarkAsFixed({required int workOrderId,required String feedback}) async { + Future engineerMarkAsFixed({required int workOrderId,required String feedback}) async { + Response response ; try { Map body = {'workOrderId': workOrderId, 'feedback': feedback}; isLoading = true; - final response = await ApiManager.instance.post(URLs.engineerMarkAsFixUrl, body: body); + 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) { - CommonResponseModel commonResponseModel = CommonResponseModel.fromJson(json.decode(response.body)); + currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body)); notifyListeners(); isLoading = false; - return commonResponseModel; + return response.statusCode; } isLoading = false; notifyListeners(); - return CommonResponseModel(); + return response.statusCode; } catch (e) { - log("engineer accept [error] : $e"); + log("engineer mark as fixed [error] : $e"); isLoading = false; notifyListeners(); - return CommonResponseModel(); + return -1; } } @@ -358,13 +391,10 @@ class RequestDetailProvider extends ChangeNotifier { //engineerUpdateWorkOrder...... Future engineerUpdateWorkOrder() async { - try { + // try { isLoading = true; - print('body to update work order is ${engineerUpdateWorkOrderHelperModel!.toJson()}'); final response = await ApiManager.instance.post(URLs.engineerUpdateWorkOrderUrl, body: engineerUpdateWorkOrderHelperModel!.toJson()); stateCode = response.statusCode; - print('response of the verify Asset detail is ${response.body}'); - if (response.statusCode >= 200 && response.statusCode < 300) { currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body)); updateCurrentWorkOrder(currentWorkOrder); @@ -373,11 +403,12 @@ class RequestDetailProvider extends ChangeNotifier { } isLoading = false; notifyListeners(); - } catch (e) { - log("engineer accept [error] : $e"); - isLoading = false; - notifyListeners(); - } + // } + // catch (e) { + // log("engineer update workorder [error] : $e"); + // isLoading = false; + // notifyListeners(); + // } } //Nurse confirm reopen @@ -436,6 +467,7 @@ class RequestDetailProvider extends ChangeNotifier { 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; notifyListeners(); @@ -462,8 +494,10 @@ class RequestDetailProvider extends ChangeNotifier { 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... + notifyListeners(); } isLoading = false; @@ -506,7 +540,6 @@ class RequestDetailProvider extends ChangeNotifier { URLs.createActivityAssetToBeRetiredUrl, body: assetRetiredHelperModel!.toJson(), ); - print('response i got is ${response.body}'); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body)); @@ -524,7 +557,6 @@ class RequestDetailProvider extends ChangeNotifier { } //get Arrival type...... - //TODO create a model when there is data in api... Future getArrivalVerificationType() async { ArrivalVerificationTypeModel arrivalVerificationTypeModel= ArrivalVerificationTypeModel(); try { @@ -553,6 +585,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}'); 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 c28d6c96..81c0be08 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,16 +1,20 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_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/main.dart'; +import 'package:test_sa/models/enums/user_types.dart'; import 'package:test_sa/models/enums/work_order_next_step.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/providers/service_request_providers/reject_reason_provider.dart'; import 'package:test_sa/providers/work_order/reason_provider.dart'; import 'package:test_sa/service_request_latest/request_detail_provider.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'; import 'package:test_sa/service_request_latest/views/forms/asset_retired/verify_asset_detail.dart'; @@ -27,16 +31,148 @@ class FooterActionButton { ); } - static Widget requestDetailsFooterWidget({required WorkOrderNextStepEnum workOrderNextStepStatus, required BuildContext context}) { + static Widget requestDetailsFooterWidget({required WorkOrderNextStepEnum workOrderNextStepStatus, required BuildContext context, required UserProvider userProvider}) { RequestDetailProvider requestDetailProvider = Provider.of(context, listen: false); - switch (workOrderNextStepStatus) { - case WorkOrderNextStepEnum.onlyView: - return const SizedBox(); - // TODO: Handle this case. - case WorkOrderNextStepEnum.markedAsFixed: - // TODO: Handle this case. - case WorkOrderNextStepEnum.nTakeAction: + if (userProvider.user?.type == UsersTypes.engineer) { + switch (workOrderNextStepStatus) { + case WorkOrderNextStepEnum.onlyView: + return const SizedBox(); + // TODO: Handle this case. + case WorkOrderNextStepEnum.markedAsFixed: + // TODO: Handle this case. + case WorkOrderNextStepEnum.nTakeAction: + // const SizedBox().flushBar(context: context, title: context.translation.youMarkedThisIssueAsFixedWaitingForTheRequesterToConfirm, message: ''); + return footerContainer( + child: AppFilledButton( + label: context.translation.close, + // maxWidth: true, + buttonColor: AppColor.primary10, + onPressed: () async { + Navigator.pop(context); + }, + )); + case WorkOrderNextStepEnum.eRejectAccept: + return footerContainer( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, + children: [ + AppFilledButton( + label: context.translation.reject, + maxWidth: true, + buttonColor: Colors.white54, + textColor: AppColor.red30, + showBorder: true, + onPressed: () async { + //TODO need to discuss getData is not called by default... + if (context.mounted) { + RejectReasonProvider rejectionReasonProvider = Provider.of(context, listen: false); + rejectionReasonProvider.reset(); + rejectionReasonProvider.getDate(); + } + ServiceRequestBottomSheet.rejectRequestBottomSheet(context: context); + }, + ).expanded, + const SizedBox( + width: 20, + ), + AppFilledButton( + label: context.translation.accept, + maxWidth: true, + buttonColor: AppColor.green70, + onPressed: () async { + requestDetailProvider.engineerAcceptWorkOrder(id: requestDetailProvider.currentWorkOrder!.data!.requestId.toString()).whenComplete(() {}); + }, + ).expanded, + ], + )); + case WorkOrderNextStepEnum.eFixRemotelyNeedVisit: + return footerContainer( + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + mainAxisSize: MainAxisSize.min, + children: [ + AppFilledButton( + label: context.translation.needAVisit, + maxWidth: true, + buttonColor: AppColor.neutral50, + onPressed: () async { + ServiceRequestBottomSheet.initialVisitBottomSheet(context: context); + }, + ).expanded, + const SizedBox( + width: 20, + ), + AppFilledButton( + label: context.translation.fixedRemotely, + maxWidth: true, + buttonColor: AppColor.green70, + onPressed: () async { + ServiceRequestBottomSheet.fixRemotelyBottomSheet(context: context); + }, + ).expanded, + ], + )); + case WorkOrderNextStepEnum.eArrived: + return footerContainer( + child: AppFilledButton( + label: context.translation.iHaveArrived, + showIcon: true, + icon: 'arrived_icon'.toSvgAsset(), + buttonColor: AppColor.green70, + onPressed: () async { + Navigator.push(context, MaterialPageRoute(builder: (context) => const VerifyArrivalView())); + }, + )); + case WorkOrderNextStepEnum.verifyAssetDetail: + return footerContainer( + child: AppFilledButton( + label: context.translation.verify_asset_details, + // maxWidth: true, + buttonColor: AppColor.primary10, + onPressed: () async { + Navigator.push(context, MaterialPageRoute(builder: (context) => const VerifyAssetDetails())); + }, + )); + case WorkOrderNextStepEnum.activity: + return footerContainer( + child: Column( + children: [ + AppFilledButton( + label: context.translation.activities, + // maxWidth: true, + buttonColor: AppColor.neutral50, + onPressed: () async { + // ServiceRequestBottomSheet.activityTypeBottomSheet(context: context); + Navigator.push(context, MaterialPageRoute(builder: (context)=>const ActivitiesListView())); + }, + ), + 8.height, + AppFilledButton( + label: context.translation.markAsFixed, + // maxWidth: true, + buttonColor: AppColor.green70, + onPressed: () async { + ServiceRequestBottomSheet.feedBackBottomSheet(context: context); + }, + ), + ], + )); + case WorkOrderNextStepEnum.endWorkFlow: + return const SizedBox(); + + case WorkOrderNextStepEnum.assetRetirementManagementApproval: + return footerContainer( + child: AppFilledButton( + label: context.translation.assetRetiredPendingOpManagementApproval, + buttonColor: AppColor.neutral140, + textColor: AppColor.neutral150, + fontSize: 12.toScreenWidth, + )); + } + } else if (userProvider.user?.type == UsersTypes.nurse) { + if (workOrderNextStepStatus == WorkOrderNextStepEnum.nTakeAction) { return footerContainer( child: AppFilledButton( label: context.translation.takeAction, @@ -46,134 +182,8 @@ class FooterActionButton { ServiceRequestBottomSheet.nurseTakeActionBottomSheet(context: context); }, )); - case WorkOrderNextStepEnum.eRejectAccept: - return footerContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.min, - children: [ - AppFilledButton( - label: context.translation.reject, - maxWidth: true, - buttonColor: Colors.white54, - textColor: AppColor.red30, - showBorder: true, - onPressed: () async { - //TODO need to discuss getData is not called by default... - if (context.mounted) { - ReasonProvider reasonProvider = Provider.of(context, listen: false); - reasonProvider.reset(); - // reasonProvider.serviceRequestId = requestDetailProvider.currentServiceRequestId.toString(); - reasonProvider.serviceRequestId = '3'; - reasonProvider.getDate(); - } - ServiceRequestBottomSheet.rejectRequestBottomSheet(context: context); - }, - ).expanded, - const SizedBox( - width: 20, - ), - AppFilledButton( - label: context.translation.accept, - maxWidth: true, - buttonColor: AppColor.green70, - onPressed: () async { - requestDetailProvider.engineerAcceptWorkOrder(id: requestDetailProvider.currentWorkOrder!.data!.requestId.toString()).whenComplete(() { - requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); - }); - }, - ).expanded, - ], - )); - case WorkOrderNextStepEnum.eFixRemotelyNeedVisit: - return footerContainer( - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - mainAxisSize: MainAxisSize.min, - children: [ - AppFilledButton( - label: context.translation.needAVisit, - maxWidth: true, - buttonColor: AppColor.neutral50, - onPressed: () async { - ServiceRequestBottomSheet.initialVisitBottomSheet(context: context); - }, - ).expanded, - const SizedBox( - width: 20, - ), - AppFilledButton( - label: context.translation.fixedRemotely, - maxWidth: true, - buttonColor: AppColor.green70, - onPressed: () async { - ServiceRequestBottomSheet.fixRemotelyBottomSheet(context: context); - }, - ).expanded, - ], - )); - case WorkOrderNextStepEnum.eArrived: - return footerContainer( - child: AppFilledButton( - label: context.translation.iHaveArrived, - showIcon: true, - icon: 'arrived_icon'.toSvgAsset(), - buttonColor: AppColor.green70, - onPressed: () async { - Navigator.push(context, MaterialPageRoute(builder: (context) => const VerifyArrivalView())); - }, - )); - case WorkOrderNextStepEnum.verifyAssetDetail: - return footerContainer( - child: AppFilledButton( - label: context.translation.verify_asset_details, - // maxWidth: true, - buttonColor: AppColor.primary10, - onPressed: () async { - Navigator.push(context, MaterialPageRoute(builder: (context) => const VerifyAssetDetails())); - }, - )); - case WorkOrderNextStepEnum.activity: - return footerContainer( - child: Column( - children: [ - AppFilledButton( - label: context.translation.activities, - // maxWidth: true, - buttonColor: AppColor.neutral50, - onPressed: () async { - ServiceRequestBottomSheet.activityTypeBottomSheet(context: context); - }, - ), - 8.height, - AppFilledButton( - label: context.translation.markAsFixed, - // maxWidth: true, - buttonColor: AppColor.green70, - onPressed: () async { - ServiceRequestBottomSheet.feedBackBottomSheet(context: context); - }, - ), - ], - )); - case WorkOrderNextStepEnum.endWorkFlow: - return const SizedBox(); - // return footerContainer( - // child: AppFilledButton( - // label: context.translation.close, - // // maxWidth: true, - // buttonColor: AppColor.primary10, - // onPressed: () async {}, - // )); - case WorkOrderNextStepEnum.assetRetirementManagementApproval: - return footerContainer( - child: AppFilledButton( - label: context.translation.assetRetiredPendingOpManagementApproval, - buttonColor: AppColor.neutral140, - textColor: AppColor.neutral150, - fontSize: 12.toScreenWidth, - - )); + } } + 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 380cf357..c16fb9c4 100644 --- a/lib/service_request_latest/views/components/activities_list_view.dart +++ b/lib/service_request_latest/views/components/activities_list_view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/providers/api/service_requests_provider.dart'; @@ -8,13 +10,19 @@ 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'; +import 'package:test_sa/models/helper_data_models/spare_part/activity_spare_part_model.dart'; +import 'package:test_sa/models/new_models/work_order_detail_model.dart'; import 'package:test_sa/models/service_request/search_work_order.dart'; import 'package:test_sa/models/service_request/service_request.dart'; +import 'package:test_sa/models/service_request/spare_parts.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/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/action_button/footer_action_button.dart'; import 'package:test_sa/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart'; +import 'package:test_sa/service_request_latest/views/forms/spare_part/spare_part_request.dart'; import 'package:test_sa/views/pages/user/requests/work_order/update_service_report.dart'; import 'package:test_sa/views/pages/user/requests/work_order/work_order_details_page.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; @@ -27,102 +35,129 @@ class ActivitiesListView extends StatelessWidget { @override Widget build(BuildContext context) { - List activities = []; + //TODO add the check for type of activity after completing maintenance activity flow. + List activities = []; UserProvider userProvider = Provider.of(context); return Scaffold( appBar: DefaultAppBar(title: context.translation.activities), //backgroundColor: const Color(0xfff8f9fb), body: Consumer(builder: (context, RequestDetailProvider requestDetailProvider, child) { activities = requestDetailProvider.currentWorkOrder!.data!.activities; - return Column( + return Column( children: [ (activities.isEmpty) ? NoDataFound(message: context.translation.noDataFound).expanded : ListView.separated( - padding: const EdgeInsets.all(16), - itemCount: activities.length, - separatorBuilder: (czt, index) => 8.height, - itemBuilder: (context, index) { - return Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - StatusLabel( - label: activities[index].currentSituation!.name, - textColor: AppColor.getRequestStatusTextColorByName(context, activities[index].currentSituation!.name!), - backgroundColor: AppColor.getRequestStatusColorByName(context, activities[index].currentSituation!.name!), - ), - 8.height, - //activity type... - Text( - '${activities[index].callRequest!.asset!.modelDefinition!.assetName?.cleanupWhitespace.capitalizeFirstOfEach}', - style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), - ), - 2.height, - Text( - '${context.translation.workingHours}: ${activities[index].currentSituation?.workingHours}', - style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120), - ), - 2.height, - Text( - '${context.translation.date}: ${activities[index].currentSituation?.date}', - style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120), - ), - 2.height, - Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - context.translation.viewDetails, - style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context)), - ), - 4.width, - Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14) - ], - ), - ], - ).onPress(() { - Navigator.push( - context, - MaterialPageRoute(builder: (context) => WorkOrderDetailsPage(workOrder: activities[index], serviceRequest: ServiceRequest())), - ); - }).expanded, - Column( - crossAxisAlignment: CrossAxisAlignment.end, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - if (userProvider.user!.type == UsersTypes.engineer && - requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 && - requestDetailProvider.currentWorkOrder?.data?.status?.value != 3) - "edit".toSvgAsset(height: 48, width: 48).onPress(() { - Navigator.of(context).push( - MaterialPageRoute(builder: (_) => UpdateServiceReport(request: ServiceRequest(), workOrder: activities[index])), - ); - }), - if (userProvider.user!.type == UsersTypes.engineer && - requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 && - requestDetailProvider.currentWorkOrder?.data?.status?.value != 3) - 8.height, - Text(activities[index].visitDate?.toServiceRequestCardFormat ?? "", - textAlign: TextAlign.end, style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : const Color(0xFF3B3D4A))), - ], - ) - ], - ).toShadowContainer(context); - }, - ).expanded, + padding: const EdgeInsets.all(16), + itemCount: activities.length, + separatorBuilder: (czt, index) => 8.height, + itemBuilder: (context, index) { + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + StatusLabel( + label: activities[index].activityStatus?.name, + textColor: AppColor.getRequestStatusTextColorByName(context, activities[index].activityStatus?.name), + backgroundColor: AppColor.getRequestStatusColorByName(context, activities[index].activityStatus?.name), + ), + "drag_icon".toSvgAsset(height: 12, width: 23, color: AppColor.neutral160), + if (userProvider.user!.type == UsersTypes.engineer && + requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 && + requestDetailProvider.currentWorkOrder?.data?.status?.value != 3) + Row( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + "edit_icon".toSvgAsset(height: 21, width: 21).onPress(() { + print('attachments in activity model is ${activities[index].activitySparePart?.acitiySparePartAttachments}'); + requestDetailProvider.sparePartHelperModel=SparePartHelperModel( + id: activities[index].id, + workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId, + sparePartAttachments:activities[index].activitySparePart?.acitiySparePartAttachments??[], + sparePart:SparePart( + id: activities[index].activitySparePart?.partCatalogItem?.id, + partName: activities[index].activitySparePart?.partCatalogItem?.partName, + partNo: activities[index].activitySparePart?.partCatalogItem?.partNumber), + quantity: activities[index].activitySparePart?.quantity, + activityStatusId: activities[index].activityStatus?.id, + //TODO commets are missing in api response.. + // comment: activities[index].activitySparePart?.description, + ); + + requestDetailProvider.updateSparePartHelperModel(requestDetailProvider.sparePartHelperModel); + print('model in activity page is ${requestDetailProvider.sparePartHelperModel?.toJson()}'); + Navigator.of(context).push( + MaterialPageRoute(builder: (_) => const SparePartRequest (), + )); + }), + 24.width, + "delete_icon".toSvgAsset(height: 21, width: 21).onPress(()async { + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + int status = await requestDetailProvider.deleteActivitySparePart(id: activities[index].id!, workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!); + if (status == 200) { + await requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); + Navigator.pop(context); + } else { + Navigator.pop(context); + } + }), + ], + ) + ], + ), + 6.height, + //activity type... + Text( + '${activities[index].activityType?.cleanupWhitespace.capitalizeFirstOfEach}', + style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), + ), + 3.height, + Text( + '${context.translation.partName}: ${activities[index].activitySparePart?.partCatalogItem?.partName}', + style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120), + ), + 2.height, + Text( + '${context.translation.partNo}: ${activities[index].activitySparePart?.partCatalogItem?.partNumber}', + style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120), + ), + 2.height, + //TODO description text not in api. + // Text( + // '${context.translation.date}: ${activities[index].currentSituation?.date}', + // style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120), + // ), + 2.height, + ], + ).onPress(() { + //TODO write onview detail method.. + // Navigator.push( + // context, + // MaterialPageRoute(builder: (context) => WorkOrderDetailsPage(workOrder: activities[index], serviceRequest: ServiceRequest())), + // ); + }).expanded, + ], + ).toShadowContainer(context); + }, + ).expanded, if (userProvider.user!.type == UsersTypes.engineer && - (requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 && requestDetailProvider.currentWorkOrder?.data?.status?.value != 3)) - AppFilledButton( + (requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 && requestDetailProvider.currentWorkOrder?.data?.status?.value != 3)) + FooterActionButton.footerContainer( + child: AppFilledButton( label: context.translation.createNewActivity, maxWidth: true, + buttonColor: AppColor.primary10, onPressed: () async { ServiceRequestBottomSheet.activityTypeBottomSheet(context: context); }, - ).paddingOnly(start: 16, end: 16, bottom: 16) + )) ], ); }), 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 47a18e66..3f534873 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 @@ -10,11 +10,14 @@ 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/work_order_next_step.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'; import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart'; import 'package:test_sa/providers/service_request_providers/first_action_provider.dart'; +import 'package:test_sa/providers/service_request_providers/reject_reason_provider.dart'; import 'package:test_sa/providers/work_order/reason_provider.dart'; import 'package:test_sa/service_request_latest/request_detail_provider.dart'; import 'package:test_sa/service_request_latest/views/forms/maintenance_request/maintenance_request_main.dart'; @@ -174,8 +177,6 @@ class ServiceRequestBottomSheet { textColor: AppColor.black20, onPressed: () async { Navigator.pop(context); - // await snapshot.updateRequest(user: userProvider.user, request: serviceRequestProvider.serviceRequest); - // Navigator.pop(context, true); }, ), ), @@ -185,11 +186,14 @@ class ServiceRequestBottomSheet { label: context.translation.fixed, buttonColor: AppColor.green70, loading: false, - onPressed: () { + onPressed: () async { //TODO after confirm from backend call the api and reset the model. - // requestDetailProvider.engineerFixRemotely(); - // requestDetailProvider.fixRemotelyHelperModel = FixRemotelyHelperModel(); - print('model i got is ${requestDetailProvider.fixRemotelyHelperModel?.toJson()}'); + requestDetailProvider.fixRemotelyHelperModel?.workOrderId= requestDetailProvider.currentWorkOrder?.data?.requestId; + await requestDetailProvider.engineerFixRemotely(); + //TODO context issue to show message.. + // const SizedBox().flushBar(context: context, title: '', message: context.translation.youMarkedThisIssueAsFixedWaitingForTheRequesterToConfirm); + Navigator.pop(context); + }, ), ), @@ -332,10 +336,14 @@ class ServiceRequestBottomSheet { } static Future initialVisitBottomSheet({required BuildContext context}) { + TextEditingController _commentController = TextEditingController(); + return buildBottomSheetParent( context: context, childWidget: Consumer(builder: (context, requestDetailProvider, child) { - + if(requestDetailProvider.needVisitHelperModel?.comment!=null){ + _commentController.text = requestDetailProvider.needVisitHelperModel!.comment!; + } return Column( children: [ const SizedBox().indicatorWidget(), @@ -373,74 +381,10 @@ class ServiceRequestBottomSheet { } }, ), - // if (serviceRequestProvider.currentSelectedRequest?.firstAction?.id == 404 && Provider.of(context, listen: false).assetGroup?.id == 1) ...[ - // 8.height, - // Row( - // children: [ - // ADatePicker( - // label: context.translation.startDate, - // date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.startDate ?? ""), - // formatDateWithTime: true, - // onDatePicker: (selectedDate) { - // if (selectedDate != null) { - // showTimePicker( - // context: context, - // initialTime: TimeOfDay.now(), - // ).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, - // ); - // if (selectedDateTime != null) { - // serviceRequestProvider.currentSelectedRequest?.startDate = selectedDateTime?.toIso8601String(); - // } - // } - // }); - // } - // }, - // ).expanded, - // 8.width, - // ADatePicker( - // label: context.translation.endDate, - // date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.endDate ?? ""), - // formatDateWithTime: true, - // onDatePicker: (selectedDate) { - // showTimePicker( - // context: context, - // initialTime: TimeOfDay.now(), - // ).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, - // ); - // serviceRequestProvider.currentSelectedRequest?.endDate = selectedDateTime?.toIso8601String(); - // serviceRequestProvider.currentSelectedRequest?.workingHours = (((DateTime.parse(serviceRequestProvider.currentSelectedRequest!.endDate!) - // .difference(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.startDate!)) - // .inSeconds ?? - // 0) / - // 60) / - // 60) - // .toStringAsFixed(2); - // } - // }); - // }, - // ).expanded, - // ], - // ) - // ], 8.height, AppTextFormField( labelText: context.translation.comments, + controller: _commentController, backgroundColor: AppColor.neutral100, labelStyle: AppTextStyles.textFieldLabelStyle, showShadow: false, @@ -459,171 +403,28 @@ class ServiceRequestBottomSheet { buttonColor: AppColor.primary10, loading: false, onPressed: () async { - requestDetailProvider.needVisitHelperModel?.workOrderId= requestDetailProvider.currentWorkOrder!.data!.requestId; - print('payload to set initial visit ${requestDetailProvider.needVisitHelperModel?.toJson()}'); - //TODO reset model and call api after confirm form backend... - await requestDetailProvider.engineerNeedVisit().whenComplete((){ - Navigator.pop(context); - requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); - requestDetailProvider.needVisitHelperModel = NeedVisitHelperModel(); - }); - + if (requestDetailProvider.currentWorkOrder?.data?.nextStep!.workOrderNextStepEnum == WorkOrderNextStepEnum.eArrived) { + requestDetailProvider.updateNeedVisitHelperModel( + NeedVisitHelperModel( + workOrderId: requestDetailProvider.needVisitHelperModel?.workOrderId, + visitDate: requestDetailProvider.needVisitHelperModel?.visitDate, + comment: requestDetailProvider.needVisitHelperModel?.comment, + ) + ); + await requestDetailProvider.engineerUpdateNeedVisit(); + } + else { + requestDetailProvider.needVisitHelperModel?.workOrderId = requestDetailProvider.currentWorkOrder!.data!.requestId; + await requestDetailProvider.engineerNeedVisit(); + requestDetailProvider.needVisitHelperModel = NeedVisitHelperModel(); + } + Navigator.pop(context); }, ), 16.height, ], ); })); - - final GlobalKey _formKey = GlobalKey(); - return showModalBottomSheet( - context: context, - useSafeArea: true, - isScrollControlled: true, - backgroundColor: Colors.transparent, - builder: (context) => Consumer(builder: (context, serviceRequestProvider, child) { - return Form( - key: _formKey, - child: SingleChildScrollView( - child: Column( - children: [ - const SizedBox().indicatorWidget(), - 8.height, - Align( - alignment: AlignmentDirectional.centerStart, - child: context.translation.setVisitDate.bottomSheetHeadingTextStyle(context), - ), - 15.height, - ADatePicker( - label: context.translation.visitDate, - hideShadow: true, - backgroundColor: AppColor.neutral100, - date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.visitDate ?? ""), - formatDateWithTime: true, - onDatePicker: (selectedDate) { - if (selectedDate != null) { - showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - ).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, - ); - if (selectedDateTime.isBefore(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.date!))) { - "Visit Date time must be greater then request date".showToast; - return; - } - serviceRequestProvider.currentSelectedRequest?.visitDate = selectedDateTime?.toIso8601String(); - } - }); - } - }, - ), - if (serviceRequestProvider.currentSelectedRequest?.firstAction?.id == 404 && Provider.of(context, listen: false).assetGroup?.id == 1) ...[ - 8.height, - Row( - children: [ - ADatePicker( - label: context.translation.startDate, - date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.startDate ?? ""), - formatDateWithTime: true, - onDatePicker: (selectedDate) { - if (selectedDate != null) { - showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - ).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, - ); - if (selectedDateTime != null) { - serviceRequestProvider.currentSelectedRequest?.startDate = selectedDateTime?.toIso8601String(); - } - } - }); - } - }, - ).expanded, - 8.width, - ADatePicker( - label: context.translation.endDate, - date: DateTime.tryParse(serviceRequestProvider.currentSelectedRequest?.endDate ?? ""), - formatDateWithTime: true, - onDatePicker: (selectedDate) { - showTimePicker( - context: context, - initialTime: TimeOfDay.now(), - ).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, - ); - serviceRequestProvider.currentSelectedRequest?.endDate = selectedDateTime?.toIso8601String(); - serviceRequestProvider.currentSelectedRequest?.workingHours = (((DateTime.parse(serviceRequestProvider.currentSelectedRequest!.endDate!) - .difference(DateTime.parse(serviceRequestProvider.currentSelectedRequest!.startDate!)) - .inSeconds ?? - 0) / - 60) / - 60) - .toStringAsFixed(2); - } - }); - }, - ).expanded, - ], - ) - ], - 8.height, - AppTextFormField( - labelText: context.translation.comments, - backgroundColor: AppColor.neutral100, - labelStyle: AppTextStyles.textFieldLabelStyle, - showShadow: false, - textInputType: TextInputType.multiline, - alignLabelWithHint: true, - onChange: (text) { - serviceRequestProvider.currentSelectedRequest?.comments = text; - }, - onSaved: (text) { - serviceRequestProvider.currentSelectedRequest?.comments = text; - }, - ), - 12.height, - AppFilledButton( - label: context.translation.save, - buttonColor: AppColor.primary10, - loading: serviceRequestProvider.isLoading ?? false, - onPressed: () async { - _formKey.currentState?.save(); - - // await snapshot.updateRequest(user: userProvider.user, request: serviceRequestProvider.serviceRequest); - // Navigator.pop(context, true); - Navigator.of(context).push(MaterialPageRoute(builder: (_) => VerifyArrivalView())); - }, - ), - 16.height, - ], - ), - ), - ).bottomSheetContainer(context); - })); } static Future rejectRequestBottomSheet({required BuildContext context}) { @@ -639,14 +440,14 @@ class ServiceRequestBottomSheet { child: context.translation.rejectionReason.heading4(context).paddingOnly(top: 21), ), 15.height, - SingleItemDropDownMenu( + SingleItemDropDownMenu( context: context, title: context.translation.reason, + backgroundColor: AppColor.neutral100, initialValue: requestDetailProvider.engineerRejectHelperModel?.rejectionReason, onSelect: (value) { if (value != null) { requestDetailProvider.engineerRejectHelperModel?.rejectionReason = value; - requestDetailProvider.engineerRejectHelperModel?.rejectReasonId=value.id; requestDetailProvider.updateEngineerRejectHelperModel(requestDetailProvider.engineerRejectHelperModel); } }, @@ -675,11 +476,8 @@ class ServiceRequestBottomSheet { showBorder: true, loading: requestDetailProvider.isLoading, onPressed: () async { + requestDetailProvider.engineerRejectHelperModel?.workOrderId = requestDetailProvider.currentWorkOrder?.data?.requestId; requestDetailProvider.engineerRejectWorkOrder(); - - //Todo implement backend logic.. - // serviceRequestProvider.serviceRequest.device = asset; - // await snapshot.updateRequest(user: userProvider.user, request: serviceRequestProvider.currentSelectedRequest); Navigator.pop(context, true); }, ), @@ -745,6 +543,7 @@ class ServiceRequestBottomSheet { void onItemTap({required int index, required BuildContext context}) { switch (index) { case 0: + Provider.of(context,listen: false).sparePartHelperModel = SparePartHelperModel(); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const SparePartRequest()), @@ -914,65 +713,16 @@ class ServiceRequestBottomSheet { buttonColor: AppColor.green70, loading: false, onPressed: () { - print('feedback i got is ${feedback}'); - //TODO uncommit this after testing... - // requestDetailProvider.engineerMarkAsFixed(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, feedback:feedback); - + Navigator.pop(context); + requestDetailProvider.engineerMarkAsFixed(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, feedback:feedback); }, ), ], ); })); - - return showModalBottomSheet( - context: context, - useSafeArea: true, - isScrollControlled: true, - backgroundColor: Colors.transparent, - builder: (context) => Consumer(builder: (context, serviceRequestProvider, child) { - return Form( - // key: _formKey, - child: SingleChildScrollView( - child: StatefulBuilder(builder: (context, setState) { - return Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const SizedBox().indicatorWidget(), - 8.height, - Align( - alignment: AlignmentDirectional.centerStart, - child: context.translation.feedBack.bottomSheetHeadingTextStyle(context), - ), - 21.height, - AppTextFormField( - labelText: context.translation.comments, - textInputType: TextInputType.multiline, - labelStyle: AppTextStyles.textFieldLabelStyle, - showWithoutDecoration: true, - backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral100, - alignLabelWithHint: true, - onChange: (text) { - serviceRequestProvider.currentSelectedRequest?.comments = text; - }, - onSaved: (text) { - serviceRequestProvider.currentSelectedRequest?.comments = text; - }, - ), - 16.height, - AppFilledButton( - label: context.translation.fixed, - buttonColor: AppColor.green70, - loading: false, - onPressed: () {}, - ), - ], - ); - }), - ), - )..bottomSheetContainer(context); - })); } + static Future nurseTakeActionBottomSheet({required BuildContext context}) { bool acknowledge = false; Uint8List? newSignature; @@ -1037,7 +787,7 @@ class ServiceRequestBottomSheet { onPressed: () async { if (newSignature != null && acknowledge) { requestDetailProvider.nurseActionHelperModel=NurseActionHelperModel( - workOrderId: int.parse(requestDetailProvider.currentWorkOrder!.data!.workOrderNo!), + workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId, signatureNurse: nurseSignature, ); requestDetailProvider.nurseReject(); @@ -1056,7 +806,7 @@ class ServiceRequestBottomSheet { if (newSignature != null && acknowledge) { //TODO replace provider with new provider and also check workorder id is not correct. requestDetailProvider.nurseActionHelperModel=NurseActionHelperModel( - workOrderId: int.parse(requestDetailProvider.currentWorkOrder!.data!.workOrderNo!), + workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!, signatureNurse: nurseSignature, ); requestDetailProvider.nurseConfirm(); diff --git a/lib/service_request_latest/views/components/initial_visit_card.dart b/lib/service_request_latest/views/components/initial_visit_card.dart index 94705cea..265d79b7 100644 --- a/lib/service_request_latest/views/components/initial_visit_card.dart +++ b/lib/service_request_latest/views/components/initial_visit_card.dart @@ -1,42 +1,55 @@ import 'package:flutter/material.dart'; +import 'package:provider/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/helper_data_models/workorder/work_order_helper_models.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/service_request_latest/request_detail_provider.dart'; +import 'package:test_sa/service_request_latest/views/components/bottom_sheets/service_request_bottomsheet.dart'; class InitialVisitCard extends StatelessWidget { const InitialVisitCard({Key? key}) : super(key: key); @override Widget build(BuildContext context) { - return Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(14), - color: AppColor.white10, - ), - padding: EdgeInsets.symmetric(horizontal: 12.toScreenWidth, vertical: 14.toScreenHeight), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - DateTime.now().toString().toInitialVisitCardFormat, - textAlign: TextAlign.end, - style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), - ), - "edit_icon".toSvgAsset(height: 21, width: 21).onPress(() { - //open bottom sheet again with the informations added... - }), - ]), - 2.height, - context.translation.visitDateAndTime.heading6(context).custom(color: AppColor.neutral120), - 8.height, - 'Comments for the visit will be visible here for reference'.heading6(context).custom(color: AppColor.neutral120), + return Consumer(builder: (context, RequestDetailProvider requestDetailProvider, snapshot) { - ], - ), - ); + return Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(14), + color: AppColor.white10, + ), + padding: EdgeInsets.symmetric(horizontal: 12.toScreenWidth, vertical: 14.toScreenHeight), + margin: EdgeInsets.only(top: 10.toScreenHeight), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + Text( + requestDetailProvider.needVisitHelperModel!.visitDate.toString().toInitialVisitCardFormat, + textAlign: TextAlign.end, + style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.black10), + ), + "edit_icon".toSvgAsset(height: 21, width: 21).onPress(() { + + ServiceRequestBottomSheet.initialVisitBottomSheet(context: context); + }), + ]), + 2.height, + context.translation.visitDateAndTime.bodyText2(context).custom(color: AppColor.neutral120), + 8.height, + if (requestDetailProvider.needVisitHelperModel?.comment != null) ...[ + requestDetailProvider.needVisitHelperModel!.comment!.bodyText2(context).custom( + color: AppColor.neutral120, + ), + ] + ], + ), + ); + }); } } 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 dfd0d46e..2f2a4436 100644 --- a/lib/service_request_latest/views/components/request_detail_view.dart +++ b/lib/service_request_latest/views/components/request_detail_view.dart @@ -12,8 +12,10 @@ import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/models/enums/user_types.dart'; import 'package:test_sa/models/enums/work_order_next_step.dart'; import 'package:test_sa/models/helper_data_models/asset_retired/asset_retired_model.dart'; +import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_models.dart'; import 'package:test_sa/models/new_models/work_order_detail_model.dart'; import 'package:test_sa/models/service_request/service_request.dart'; +import 'package:test_sa/models/user.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/default_app_bar.dart'; @@ -41,34 +43,29 @@ class WorkOrderDetailView extends StatelessWidget { return requestProvider.isLoading ? const CircularProgressIndicator(color: AppColor.primary10).center : requestProvider.currentWorkOrder == null - ? const NoDataFound() - : Stack( + ? const NoDataFound() + : Stack( + children: [ + Column( + children: [ + SingleChildScrollView( + padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Column( - children: [ - SingleChildScrollView( - padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - workOrderDetailCard(context, requestProvider.currentWorkOrder!.data!, _userProvider), - - 40.height, - // skipForLater(serviceRequestsProvider.currentSelectedRequest), - // 20.height, - //TODO need to get data from api .. - // const InitialVisitCard(), - 20.height, - ], - ), - ).expanded, - FooterActionButton.requestDetailsFooterWidget(workOrderNextStepStatus: requestProvider.currentWorkOrder!.data!.nextStep!.workOrderNextStepEnum!, context: context), - ], - ), - // const TimerWidget(), + workOrderDetailCard(context, requestProvider.currentWorkOrder!.data!, _userProvider), + initialVisitCard(requestDetailProvider: requestProvider, userProvider: _userProvider), + 20.height, ], - ); + ), + ).expanded, + FooterActionButton.requestDetailsFooterWidget(workOrderNextStepStatus: requestProvider.currentWorkOrder!.data!.nextStep!.workOrderNextStepEnum!,userProvider: _userProvider, context: context), + ], + ), + // const TimerWidget(), + ], + ); }); } @@ -223,51 +220,51 @@ class WorkOrderDetailView extends StatelessWidget { ], ).paddingOnly(start: 16, end: 16, top: 16, bottom: 8), (userProvider.user!.type == UsersTypes.normal_user - ? Container( - height: 50, - padding: const EdgeInsets.only(left: 16, right: 16), - alignment: Alignment.center, - width: double.infinity, - decoration: ShapeDecoration( - color: context.isDark ? AppColor.neutral50 : AppColor.neutral30, - shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(20), - bottomRight: Radius.circular(20), - ), - ), - ), - child: Row( - children: [ - Text( - '${context.translation.commentHere}...', - style: AppTextStyles.heading6.copyWith( - color: (context.isDark ? AppColor.neutral30 : AppColor.neutral50).withOpacity(.6), - ), - ).expanded, - "comment_send".toSvgAsset(width: 24, color: context.isDark ? AppColor.primary50 : AppColor.primary70), - ], - ), - ) - : Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Divider().defaultStyle(context), - 16.height, - Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - context.translation.viewComments, - style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context)), - ), - 4.width, - Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14) - ], - ), - ], - ).paddingOnly(bottom: 16, start: 16, end: 16)) + ? Container( + height: 50, + padding: const EdgeInsets.only(left: 16, right: 16), + alignment: Alignment.center, + width: double.infinity, + decoration: ShapeDecoration( + color: context.isDark ? AppColor.neutral50 : AppColor.neutral30, + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only( + bottomLeft: Radius.circular(20), + bottomRight: Radius.circular(20), + ), + ), + ), + child: Row( + children: [ + Text( + '${context.translation.commentHere}...', + style: AppTextStyles.heading6.copyWith( + color: (context.isDark ? AppColor.neutral30 : AppColor.neutral50).withOpacity(.6), + ), + ).expanded, + "comment_send".toSvgAsset(width: 24, color: context.isDark ? AppColor.primary50 : AppColor.primary70), + ], + ), + ) + : Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Divider().defaultStyle(context), + 16.height, + Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + context.translation.viewComments, + style: AppTextStyles.bodyText.copyWith(color: AppColor.blueStatus(context)), + ), + 4.width, + Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14) + ], + ), + ], + ).paddingOnly(bottom: 16, start: 16, end: 16)) .onPress(() { // showModalBottomSheet( // context: context, @@ -279,12 +276,13 @@ class WorkOrderDetailView extends StatelessWidget { // ); }), //set condition for show asset detail button... - if (workOrder.nextStep!.workOrderNextStepEnum==WorkOrderNextStepEnum.verifyAssetDetail||workOrder.nextStep!.workOrderNextStepEnum==WorkOrderNextStepEnum.activity) ...[ + if (workOrder.nextStep!.workOrderNextStepEnum == WorkOrderNextStepEnum.verifyAssetDetail || workOrder.nextStep!.workOrderNextStepEnum == WorkOrderNextStepEnum.activity) ...[ assetRetiredButton(context: context), ] ], ).toShadowContainer(context, padding: 0); } + Widget assetRetiredButton({required BuildContext context}) { return Padding( padding: EdgeInsets.symmetric(horizontal: 16.toScreenHeight, vertical: 12.toScreenWidth), @@ -295,10 +293,35 @@ class WorkOrderDetailView extends StatelessWidget { textColor: AppColor.red30, showBorder: true, onPressed: () async { - Navigator.push(context, MaterialPageRoute(builder: (context) => const AssetRetired())); + Navigator.push(context, MaterialPageRoute(builder: (context) => const AssetRetired())); }), ); } + + Widget initialVisitCard({required RequestDetailProvider requestDetailProvider, required UserProvider userProvider}) { + if (requestDetailProvider.currentWorkOrder!.data!.needAVisitDateTime != null && + userProvider.user?.type == UsersTypes.engineer && + requestDetailProvider.currentWorkOrder?.data?.nextStep!.workOrderNextStepEnum == WorkOrderNextStepEnum.eArrived) { + requestDetailProvider.needVisitHelperModel = NeedVisitHelperModel( + workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId, + visitDate: requestDetailProvider.currentWorkOrder?.data?.needAVisitDateTime, + comment: requestDetailProvider.currentWorkOrder?.data?.needAVisitComment, + ); + // requestDetailProvider.updateNeedVisitHelperModel(requestDetailProvider.needVisitHelperModel); + return const InitialVisitCard(); + } else { + return const SizedBox(); + } + } + + void showToast({required UserProvider userProvider,required WorkOrderNextStepEnum nextStep,required BuildContext context}){ + if(userProvider.user?.type==UsersTypes.engineer){ + if(nextStep==WorkOrderNextStepEnum.nTakeAction){ + const SizedBox().flushBar(context: context, title: context.translation.youMarkedThisIssueAsFixedWaitingForTheRequesterToConfirm, message: ''); + } + } + + } } // class RequestDetailView extends StatefulWidget { 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 145a6111..50a0c2d2 100644 --- a/lib/service_request_latest/views/components/verify_arrival_view.dart +++ b/lib/service_request_latest/views/components/verify_arrival_view.dart @@ -137,7 +137,7 @@ class _VerifyArrivalViewState extends State { break; case 2: //TODO api has error need to fixed by ahmed... - // requestDetailProvider.sendOtp(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!); + requestDetailProvider.sendOtp(workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const VerifyOtpView()), 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 ec6d2106..b77bae96 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 @@ -9,13 +9,16 @@ 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/fault_description.dart'; import 'package:test_sa/models/helper_data_models/workorder/work_order_helper_models.dart'; 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/single_item_drop_down_menu.dart'; +import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart'; import 'package:test_sa/providers/service_request_providers/loan_availability_provider.dart'; +import 'package:test_sa/providers/work_order/fault_description_provider.dart'; import 'package:test_sa/providers/work_order/reason_provider.dart'; import 'package:test_sa/service_request_latest/request_detail_provider.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; @@ -42,6 +45,7 @@ class _VerifyAssetDetailsState extends State with TickerProv ReasonProvider? _reasonProvider; bool _isLoading = false; Asset? loanAvailabilityAsset; + List _faults = []; final GlobalKey _formKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); @@ -65,6 +69,7 @@ class _VerifyAssetDetailsState extends State with TickerProv _loanAvailabilityProvider = Provider.of(context, listen: false); _equipmentStatusProvider = Provider.of(context, listen: false); _reasonProvider?.serviceRequestId = _requestDetailProvider?.currentWorkOrder!.data!.requestId.toString(); + _faults = await Provider.of(context,listen: false).getFaultDescriptionList(assetId: _requestDetailProvider?.currentWorkOrder?.data?.asset?.id); _reasonProvider?.getDate(); _equipmentStatusProvider?.getDate(); _loanAvailabilityProvider?.getDate(); @@ -75,7 +80,7 @@ class _VerifyAssetDetailsState extends State with TickerProv equipmentStatus: currentWorkOrderData.equipmentStatus, loanAvailability: currentWorkOrderData.loanAvailablity, failureReason: currentWorkOrderData.failureReasone, - faultDescription: currentWorkOrderData.problemDescription, + // faultDescription: currentWorkOrderData.problemDescription, solution: currentWorkOrderData.solution?.name, returnToService: currentWorkOrderData.returnToService, serviceType: currentWorkOrderData.serviceType, @@ -184,19 +189,24 @@ class _VerifyAssetDetailsState extends State with TickerProv }, ), 8.height, - //TODO replace this with correct provider api will be provided by ahmed with solutions data as well... - // ServiceReportFaultDescription( - // requestId: requestDetailProvider.currentServiceRequestId?.toString(), - // initialValue: requestDetailProvider.engineerUpdateWorkOrderHelperModel.faultDescription, - // onSelect: (status) { - // requestDetailProvider.engineerUpdateWorkOrderHelperModel.faultDescription = status; - // _workPreformedController.text = _subWorkOrders.faultDescription?.workPerformed ?? ""; - // }, - // ), + SingleItemDropDownMenu( + context: context, + title: context.translation.faultDescription, + backgroundColor: AppColor.neutral100, + staticData: _faults, + showShadow: true, + initialValue: requestDetailProvider.engineerUpdateWorkOrderHelperModel?.faultDescription, + onSelect: (fault) { + requestDetailProvider.engineerUpdateWorkOrderHelperModel?.faultDescription = fault; + requestDetailProvider.engineerUpdateWorkOrderHelperModel?.solution = fault?.workPerformed; + if(mounted){ + requestDetailProvider.updateEngineerUpdateWorkOrderHelperModel(requestDetailProvider.engineerUpdateWorkOrderHelperModel); + } + }, + ), 11.height, context.translation.solutions.heading6(context).custom(color: AppColor.neutral50), 11.height, - //TODO solution from api... requestDetailProvider.engineerUpdateWorkOrderHelperModel?.solution != null ? requestDetailProvider.engineerUpdateWorkOrderHelperModel!.solution!.heading6(context).custom(color: AppColor.neutral50) : const SizedBox(), @@ -211,8 +221,6 @@ class _VerifyAssetDetailsState extends State with TickerProv label: context.translation.verify_asset_details, buttonColor: AppColor.primary10, onPressed: () async { - //TODO uncommit this when all informations are confirmed... - print('model is ${requestDetailProvider.engineerUpdateWorkOrderHelperModel?.toJson()}'); await requestDetailProvider.engineerUpdateWorkOrder(); Navigator.pop(context); }, diff --git a/lib/service_request_latest/views/forms/spare_part/spare_part_request.dart b/lib/service_request_latest/views/forms/spare_part/spare_part_request.dart index ca8c140f..81ace39b 100644 --- a/lib/service_request_latest/views/forms/spare_part/spare_part_request.dart +++ b/lib/service_request_latest/views/forms/spare_part/spare_part_request.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/providers/api/parts_provider.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; @@ -16,12 +17,15 @@ import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/service_request_latest/request_detail_provider.dart'; import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart'; +import 'package:test_sa/service_request_latest/views/components/activities_list_view.dart'; +import 'package:test_sa/service_request_latest/views/request_detail_main_view.dart'; import 'package:test_sa/views/widgets/images/multi_image_picker.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import '../../../../../../models/service_request/spare_parts.dart'; import '../../../../../../new_views/common_widgets/app_text_form_field.dart'; import '../../../../../../new_views/common_widgets/default_app_bar.dart'; import '../../../../controllers/validator/validator.dart'; +import '../../../../new_views/common_widgets/app_lazy_loading.dart'; class SparePartRequest extends StatefulWidget { static const String id = "/spare-part-request"; @@ -50,24 +54,33 @@ class _SparePartRequestState extends State with TickerProvider super.initState(); _partsProvider = Provider.of(context, listen: false); _requestDetailProvider = Provider.of(context, listen: false); + _requestDetailProvider?.sparePartHelperModel = SparePartHelperModel( + id: _requestDetailProvider?.sparePartHelperModel?.id??0, + workOrderId:_requestDetailProvider?.sparePartHelperModel?.workOrderId?? _requestDetailProvider?.currentWorkOrder?.data?.requestId, + sparePartAttachments:_requestDetailProvider?.sparePartHelperModel?.sparePartAttachments?? [], + sparePart:_requestDetailProvider?.sparePartHelperModel?.sparePart?? SparePart(), + quantity: _requestDetailProvider?.sparePartHelperModel?.quantity, + activityStatusId: _requestDetailProvider?.sparePartHelperModel?.activityStatusId, + comment: _requestDetailProvider?.sparePartHelperModel?.comment??'', + ); + _partQtyController.text =_requestDetailProvider?.sparePartHelperModel?.quantity!=null? _requestDetailProvider!.sparePartHelperModel!.quantity.toString():''; + _oracleNoController.text = _requestDetailProvider?.sparePartHelperModel?.sparePart?.oracleCode!=null?_requestDetailProvider!.sparePartHelperModel!.sparePart!.oracleCode!:''; + _descriptionController.text =_requestDetailProvider?.sparePartHelperModel?.comment!=null? _requestDetailProvider!.sparePartHelperModel!.comment!:''; + scheduleMicrotask(() async { _isLoading = true; + _files = _requestDetailProvider?.sparePartHelperModel?.sparePartAttachments?.map((e) => File(e.name!)).toList() ?? []; + setState(() {}); _spareParts = await _partsProvider!.getPartsList(assetId: _requestDetailProvider?.currentWorkOrder?.data?.asset?.id); - _requestDetailProvider?.sparePartHelperModel = SparePartHelperModel( - id: 0, - workOrderId: _requestDetailProvider?.currentWorkOrder?.data?.requestId, - sparePartAttachments: [], - sparePart: SparePart(), - ); + _isLoading = false; setState(() {}); }); - // _isLoading = true; } void restValues({required RequestDetailProvider requestDetailProvider}) { - requestDetailProvider.sparePartHelperModel = SparePartHelperModel(id: 0, workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId, sparePartAttachments: []); + requestDetailProvider.sparePartHelperModel = SparePartHelperModel(id: 0, workOrderId: _requestDetailProvider?.currentWorkOrder?.data?.requestId, sparePartAttachments: []); _partQtyController.clear(); _oracleNoController.clear(); _descriptionController.clear(); @@ -116,11 +129,11 @@ class _SparePartRequestState extends State with TickerProvider initialValue: requestDetailProvider.sparePartHelperModel?.sparePart, backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, onSelect: (part) { - if (part != requestDetailProvider.sparePartHelperModel?.sparePart) { - restValues(requestDetailProvider: requestDetailProvider); + if(part!=null){ + requestDetailProvider.sparePartHelperModel?.sparePart = part; + _oracleNoController.text = part.oracleCode??''; + requestDetailProvider.updateSparePartHelperModel(_requestDetailProvider?.sparePartHelperModel); } - requestDetailProvider.sparePartHelperModel?.sparePart = part; - requestDetailProvider.updateSparePartHelperModel(_requestDetailProvider?.sparePartHelperModel); }, ), 12.height, @@ -146,22 +159,13 @@ class _SparePartRequestState extends State with TickerProvider ), 12.height, AppTextFormField( - controller: _oracleNoController, labelStyle: AppTextStyles.textFieldLabelStyle, + controller: _oracleNoController, labelText: context.translation.oracleNo, textInputType: TextInputType.number, showWithoutDecoration: true, backgroundColor: context.isDark ? AppColor.neutral20 : AppColor.neutral90, - enable: requestDetailProvider.sparePartHelperModel?.sparePart?.id != null, - validator: (value) => value == null || value.isEmpty - ? context.translation.requiredField - : Validator.isNumeric(value) - ? null - : context.translation.onlyNumbers, - onSaved: (text) { - //TODO set the values... - // serviceRequestProvider.initialSelectedSparePart. = num.tryParse(text ?? ""); - }, + enable: false, ), 12.height, AppTextFormField( @@ -186,6 +190,11 @@ class _SparePartRequestState extends State with TickerProvider files: _files, buttonIcon: 'quotation_icon'.toSvgAsset(), buttonColor: AppColor.primary10, + onChange: (List file){ + for (var element in file) { + print('path is ${element.path}'); + } + }, ), ], ).paddingAll(16), @@ -196,16 +205,50 @@ class _SparePartRequestState extends State with TickerProvider ).paddingAll(12).expanded, FooterActionButton.footerContainer( child: AppFilledButton( - label: context.translation.addSparePartActivity, + label:_requestDetailProvider?.sparePartHelperModel?.id==0? context.translation.addSparePartActivity:context.translation.updateSparePartActivity, buttonColor: AppColor.green70, onPressed: () async { - for (var file in _files) { - requestDetailProvider.sparePartHelperModel?.sparePartAttachments - ?.add(SparePartAttachments(id: 0, name: "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}")); + // List attachmentList = []; + // List localFile = []; + // for (var file in _files) { + // print('loop executed..${file.path}'); + // if(_requestDetailProvider?.sparePartHelperModel?.sparePartAttachments!=null){ + // for (var attachment in _requestDetailProvider!.sparePartHelperModel!.sparePartAttachments!) { + // if(file.path==attachment.name){ + // print('name i got is ${attachment.name}'); + // attachmentList.add(attachment); + // } + // } + // } + // else{ + // print('file path i got is ${file.path}'); + // localFile.add(file); + // } + // attachmentList.add(SparePartAttachments(id: 0, name: "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}")); + // requestDetailProvider.sparePartHelperModel?.sparePartAttachments + // ?.add(SparePartAttachments(id: 0, name: "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}")); + // } + // for(var item in localFile){ + // attachmentList.add(SparePartAttachments(id: 0, name: "${item.path.split("/").last}|${base64Encode(item.readAsBytesSync())}")); + // } + + showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); + int status = -1; + if(_requestDetailProvider?.sparePartHelperModel?.id==0){ + status = await requestDetailProvider.createActivitySparePart(); + } + else{ + status = await requestDetailProvider.updateActivitySparePart(); + + } + if (status == 200) { + await requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!); + //this is for hide the dialoge... + Navigator.pop(context); + Navigator.pop(context); + } else { + Navigator.pop(context); } - print('model i got is ${requestDetailProvider.sparePartHelperModel?.toJson()}'); - // TODO Api has issue call this function when it's solved..... - // requestDetailProvider.createActivitySparePart(); }, )), ], diff --git a/lib/service_request_latest/views/nurse/create_new_request_view.dart b/lib/service_request_latest/views/nurse/create_new_request_view.dart index 631591c0..9aa685ac 100644 --- a/lib/service_request_latest/views/nurse/create_new_request_view.dart +++ b/lib/service_request_latest/views/nurse/create_new_request_view.dart @@ -1,6 +1,5 @@ import 'dart:convert'; import 'dart:io'; - import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -347,7 +346,7 @@ class _CreateNewRequestState extends State with TickerProvider // return; // } - _serviceRequest.devicePhotos = _deviceImages.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList(); + // _serviceRequest.devicePhotos = _deviceImages.map((e) => _isLocalUrl(e.path) ? "${e.path.split("/").last}|${base64Encode(e.readAsBytesSync())}" : e.path).toList(); if (_serviceRequest.audio != null) { if (_isLocalUrl(_serviceRequest.audio!)) { final File file = File(_serviceRequest.audio!); @@ -355,14 +354,18 @@ class _CreateNewRequestState extends State with TickerProvider } } List attachement = []; - for (var url in _deviceImages) { - + //for(var item in localFile){ + // attachmentList.add(SparePartAttachments(id: 0, name: "${item.path.split("/").last}|${base64Encode(item.readAsBytesSync())}")); + // } + for (var item in _deviceImages) { + attachement.add(WorkOrderAttachments(id: 0, name: "${item.path.split("/").last}|${base64Encode(item.readAsBytesSync())}")); } _requestDetailProvider.workOrderHelperModel = WorkOrderHelperModel( assetId: _serviceRequest.deviceId, priorityId: _serviceRequest.priority?.id, equipmentStatusId: _serviceRequest.defectType?.id, voiceNote: _serviceRequest.audio, + workOrderAttachments: attachement, comments: _serviceRequest.callComments, //add attachments also... );