From 5bf73172f602ff3e4b1258e8434cd3850e5575ca Mon Sep 17 00:00:00 2001 From: "zaid.daoud" Date: Wed, 15 Nov 2023 23:57:14 +0300 Subject: [PATCH] Previous Business Logic in Work order & sub work order --- ...ice_report_fault_description_provider.dart | 2 + lib/l10n/app_ar.arb | 4 +- lib/l10n/app_en.arb | 4 +- lib/main.dart | 2 + lib/models/fault_description.dart | 8 +- .../work_order/asset_types_provider.dart | 36 ++ .../create_sub_workorder_page.dart | 307 ++++++++++++++---- .../work_order/create_service_report.dart | 95 +++++- .../work_order/edit_service_report.dart | 91 ++++++ .../work_order/work_orders_list_page.dart | 2 +- .../service_report_fault_description.dart | 42 ++- .../service_report_repair_location.dart | 4 +- 12 files changed, 519 insertions(+), 78 deletions(-) create mode 100644 lib/providers/work_order/asset_types_provider.dart diff --git a/lib/controllers/providers/api/status_drop_down/report/service_report_fault_description_provider.dart b/lib/controllers/providers/api/status_drop_down/report/service_report_fault_description_provider.dart index bc47dfb8..57713c19 100644 --- a/lib/controllers/providers/api/status_drop_down/report/service_report_fault_description_provider.dart +++ b/lib/controllers/providers/api/status_drop_down/report/service_report_fault_description_provider.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -56,6 +57,7 @@ class ServiceRequestFaultDescriptionProvider extends ChangeNotifier { // client's request was successfully received List listJson = json.decode(response.body)["data"]['asset']['modelDefinition']['modelDefRelatedDefects']; _items = listJson?.map((type) => FaultDescription.fromJson(type))?.toList() ?? []; + log("${_items}Zaid"); } _loading = false; notifyListeners(); diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index d894cf50..ca6dd76f 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -368,5 +368,7 @@ "mrNumber" : "MR Number", "vendorEng" : "المهندس المزود", "vendorName" : "اسم المزود", - "reset" : "اعادة تعيين" + "reset" : "اعادة تعيين", + "solution" : "الحل", + "technicalComment" : "تعليق تقني" } \ No newline at end of file diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 310af1b1..508c199b 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -371,5 +371,7 @@ "mrNumber" : "MR Number", "vendorEng" : "Vendor Engineer", "vendorName" : "Vendor Name", - "reset" : "Reset" + "reset" : "Reset", + "solution" : "Solution", + "technicalComment" : "Technical Comment" } \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index d0f7cd08..ffdd4190 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -67,6 +67,7 @@ import 'package:test_sa/providers/service_request_providers/priority_provider.da import 'package:test_sa/providers/service_request_providers/request_status_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/asset_types_provider.dart'; import 'package:test_sa/providers/work_order/reason_provider.dart'; import 'package:test_sa/providers/work_order/service_type_provider.dart'; import 'package:test_sa/providers/work_order/vendor_provider.dart'; @@ -186,6 +187,7 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider(create: (_) => FirstActionStatusProvider()), ChangeNotifierProvider(create: (_) => LoanAvailabilityProvider()), ChangeNotifierProvider(create: (_) => ReasonProvider()), + ChangeNotifierProvider(create: (_) => AssetTypesProvider()), ChangeNotifierProvider(create: (_) => ServiceTypeProvider()), ChangeNotifierProvider(create: (_) => PPMVisitStatusProvider()), ChangeNotifierProvider(create: (_) => PentryTaskStatusProvider()), diff --git a/lib/models/fault_description.dart b/lib/models/fault_description.dart index 4858e55f..bc57b655 100644 --- a/lib/models/fault_description.dart +++ b/lib/models/fault_description.dart @@ -1,14 +1,18 @@ -class FaultDescription { +import 'package:test_sa/models/base.dart'; + +class FaultDescription extends Base { FaultDescription({ this.id, this.defectName, this.workPerformed, this.estimatedTime, - }); + }):super(name : defectName, identifier: id?.toString()); FaultDescription.fromJson(dynamic json) { id = json['id']; + identifier = id?.toString(); defectName = json['defectName']; + name = defectName; workPerformed = json['workPerformed']; estimatedTime = json['estimatedTime']; } diff --git a/lib/providers/work_order/asset_types_provider.dart b/lib/providers/work_order/asset_types_provider.dart new file mode 100644 index 00000000..3ce18020 --- /dev/null +++ b/lib/providers/work_order/asset_types_provider.dart @@ -0,0 +1,36 @@ +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 AssetTypesProvider 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.getAssetTypes); + 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/views/pages/sub_workorder/create_sub_workorder_page.dart b/lib/views/pages/sub_workorder/create_sub_workorder_page.dart index eafc914b..60d822d7 100644 --- a/lib/views/pages/sub_workorder/create_sub_workorder_page.dart +++ b/lib/views/pages/sub_workorder/create_sub_workorder_page.dart @@ -37,8 +37,11 @@ import '../../../providers/loading_list_notifier.dart'; import '../../../providers/work_order/reason_provider.dart'; import '../../widgets/date_and_time/date_picker.dart'; import '../../widgets/e_signature/e_signature.dart'; +import '../../widgets/loaders/loading_manager.dart'; import '../../widgets/status/report/service_report_assistant_employee_menu.dart'; +import '../../widgets/status/report/service_report_fault_description.dart'; import '../../widgets/status/report/service_report_last_call.dart'; +import '../../widgets/status/report/service_report_repair_location.dart'; import '../../widgets/timer/app_timer.dart'; class CreateSubWorkOrderPage extends StatefulWidget { @@ -60,6 +63,8 @@ class _CreateSubWorkOrderPageState extends State { bool _showVendorFields = false; SuppEngineerWorkOrders engineer; SupplierDetails initialSupplier; + final TextEditingController _workPreformedController = + TextEditingController(); @override void initState() { @@ -70,11 +75,16 @@ class _CreateSubWorkOrderPageState extends State { supplier: null, parentWOId: widget.workOrder.id, ); - _serviceReport = ServiceReport(id: widget.workOrder.id, assetType: widget.workOrder.assetType, equipmentStatus: widget.workOrder.equipmentStatus); + _serviceReport = ServiceReport( + id: widget.workOrder.id, + assetType: widget.workOrder.assetType, + equipmentStatus: widget.workOrder.equipmentStatus); _isLoading = true; super.initState(); if (context.mounted) { - Provider.of(context, listen: false).reset(); + Provider.of(context, + listen: false) + .reset(); } } @@ -83,12 +93,18 @@ class _CreateSubWorkOrderPageState extends State { Future getAssetType() async { Provider.of(context, listen: false).reset(); - final serviceRequestProvider = Provider.of(context); - Provider.of(context, listen: false).reset(); - assetTypesProvider = Provider.of(context, listen: false); - _callRequestForWorkOrder = await serviceRequestProvider.getCallRequestForWorkOrder(callId: widget.workOrder.callRequest.id.toString()); + final serviceRequestProvider = + Provider.of(context); + Provider.of(context, listen: false) + .reset(); + assetTypesProvider = + Provider.of(context, listen: false); + _callRequestForWorkOrder = + await serviceRequestProvider.getCallRequestForWorkOrder( + callId: widget.workOrder.callRequest.id.toString()); if (_subWorkOrders?.parentWOId != null) { - final subWoDetails = await serviceRequestProvider.getSubWorkOrderDetails(parentId: _subWorkOrders?.parentWOId.toString()); + final subWoDetails = await serviceRequestProvider.getSubWorkOrderDetails( + parentId: _subWorkOrders?.parentWOId.toString()); _subWorkOrders.copyDetails(subWoDetails); _serviceReport.equipmentStatus = subWoDetails.equipmentStatus; _serviceReport.reason = subWoDetails.reason; @@ -105,13 +121,20 @@ class _CreateSubWorkOrderPageState extends State { engineer = _subWorkOrders.suppEngineerWorkOrders?.last; engineer?.id = engineer?.supplierContactId; } - _subWorkOrders.supplier ??= SupplierDetails(id: _subWorkOrders?.supplier?.id); + _subWorkOrders.supplier ??= + SupplierDetails(id: _subWorkOrders?.supplier?.id); } setState(() { _isLoading = false; }); } + @override + void dispose() { + _workPreformedController?.dispose(); + super.dispose(); + } + @override Widget build(BuildContext context) { if (_callRequestForWorkOrder == null) { @@ -135,10 +158,15 @@ class _CreateSubWorkOrderPageState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - (widget.workOrder?.callRequest?.asset?.site?.name ?? "").heading5(context), + (widget.workOrder?.callRequest?.asset?.site + ?.name ?? + "") + .heading5(context), 8.height, - "${context.translation.assetNo}: ${widget.workOrder?.callRequest?.asset?.assetNumber ?? ""}".bodyText(context), - "${context.translation.callId}: ${widget.workOrder?.callRequest?.id}".bodyText(context), + "${context.translation.assetNo}: ${widget.workOrder?.callRequest?.asset?.assetNumber ?? ""}" + .bodyText(context), + "${context.translation.callId}: ${widget.workOrder?.callRequest?.id}" + .bodyText(context), ], ).paddingAll(16), ), @@ -146,9 +174,11 @@ class _CreateSubWorkOrderPageState extends State { 8.height, ADatePicker( label: context.translation.returnToService, - date: DateTime.tryParse(_subWorkOrders.visitDate ?? ""), + date: DateTime.tryParse( + _subWorkOrders.visitDate ?? ""), onDatePicker: (date) { - _subWorkOrders.visitDate = date?.toIso8601String(); + _subWorkOrders.visitDate = + date?.toIso8601String(); setState(() {}); }, ), @@ -163,6 +193,32 @@ class _CreateSubWorkOrderPageState extends State { }, ), 8.height, + LoadingManager( + isLoading: assetTypesProvider.isLoading, + isFailedLoading: + assetTypesProvider.statuses == null, + stateCode: assetTypesProvider.stateCode, + onRefresh: () async { + assetTypesProvider.reset(); + await assetTypesProvider.getTypes(); + _serviceReport?.assetType = + assetTypesProvider.statuses?.firstWhere( + (element) => + element.value == + _serviceReport.callRequest.assetType, + orElse: () => null, + ); + }, + child: AppTextFormField( + labelText: context.translation.assetType, + initialValue: + _serviceReport?.assetType?.name ?? "NULL", + textAlign: TextAlign.center, + enable: false, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + 8.height, SingleItemDropDownMenu( context: context, title: context.translation.reason, @@ -172,7 +228,8 @@ class _CreateSubWorkOrderPageState extends State { }, ), 8.height, - SingleItemDropDownMenu( + SingleItemDropDownMenu( context: context, title: context.translation.equipmentStatus, initialValue: _subWorkOrders.equipmentStatus, @@ -188,12 +245,15 @@ class _CreateSubWorkOrderPageState extends State { onSelect: (status) { _serviceReport.calllastSituation = status; if (checkVendorFieldsVisibility(status)) { - _subWorkOrders.supplier ??= SupplierDetails(id: _subWorkOrders?.supplier?.id); + _subWorkOrders.supplier ??= SupplierDetails( + id: _subWorkOrders?.supplier?.id); engineer = null; } else { _subWorkOrders.supplier = initialSupplier; } - if (status?.value == 12 || _subWorkOrders.calllastSituation?.value == 12) { + if (status?.value == 12 || + _subWorkOrders.calllastSituation?.value == + 12) { _subWorkOrders.calllastSituation = status; _subWorkOrders.mrNumber = null; } else { @@ -202,7 +262,8 @@ class _CreateSubWorkOrderPageState extends State { setState(() {}); }, ), - if (_subWorkOrders.calllastSituation?.value == 12) const SizedBox(height: 8), + if (_subWorkOrders.calllastSituation?.value == 12) + const SizedBox(height: 8), if (_subWorkOrders.calllastSituation?.value == 12) AppTextFormField( labelText: context.translation.mrNumber, @@ -213,24 +274,30 @@ class _CreateSubWorkOrderPageState extends State { ), if (_showVendorFields) const SizedBox(height: 8), if (_showVendorFields) - SingleItemDropDownMenu( + SingleItemDropDownMenu( context: context, title: context.translation.vendorEng, initialValue: _subWorkOrders.supplier, onSelect: (supplier) { if (supplier != null) { _subWorkOrders.supplier = supplier; - log(_subWorkOrders.supplier?.suppPersons?.map((e) => e.personName)?.toString()); + log(_subWorkOrders.supplier?.suppPersons + ?.map((e) => e.personName) + ?.toString()); setState(() {}); } }, ), if (_showVendorFields) const SizedBox(height: 8), if (_showVendorFields) - SingleItemDropDownMenu( + SingleItemDropDownMenu( context: context, title: context.translation.vendorName, - enabled: _subWorkOrders.supplier?.suppPersons?.isNotEmpty ?? false, + enabled: _subWorkOrders + .supplier?.suppPersons?.isNotEmpty ?? + false, staticData: _subWorkOrders.supplier.suppPersons, onSelect: (suppPerson) { if (suppPerson != null) { @@ -239,30 +306,66 @@ class _CreateSubWorkOrderPageState extends State { supplierContactId: suppPerson?.id, personName: suppPerson?.personName, contact: suppPerson?.contact, - externalEngCode: suppPerson?.externalEngCode, + externalEngCode: + suppPerson?.externalEngCode, email: suppPerson?.email, ); } }, ), 8.height, + ServiceReportFaultDescription( + requestId: widget.workOrder?.callRequest?.id?.toString(), + initialValue: _serviceReport.faultDescription, + onSelect: (status) { + _serviceReport.faultDescription = status; + _workPreformedController?.text = _serviceReport + .faultDescription?.workPerformed; + }, + ), + 8.height, + AppTextFormField( + labelText: context.translation.solution, + initialValue: + _serviceReport?.faultDescription?.workPerformed, + textAlign: TextAlign.center, + enable: false, + controller: _workPreformedController, + ), + 8.height, ServiceReportAssistantEmployeeMenu( title: context.translation.assignAssistant, assetId: widget.workOrder?.callRequest?.asset?.id, - initialValue: (_subWorkOrders.assistantEmployees?.isNotEmpty ?? false) ? _subWorkOrders.assistantEmployees?.first : null, + initialValue: (_subWorkOrders + .assistantEmployees?.isNotEmpty ?? + false) + ? _subWorkOrders.assistantEmployees?.first + : null, onSelect: (employee) { - _subWorkOrders.assistantEmployees = [employee.copyWith(id: 0)]; + _subWorkOrders.assistantEmployees = [ + employee.copyWith(id: 0) + ]; }, ), 8.height, - SingleItemDropDownMenu( + SingleItemDropDownMenu( context: context, title: context.translation.partNo, - staticData: _subWorkOrders.sparePartsWorkOrders.map((e) => e.sparePart).toList(), - initialValue: (_subWorkOrders.sparePartsWorkOrders?.isNotEmpty ?? false) ? _subWorkOrders.sparePartsWorkOrders.first.sparePart : null, + staticData: _subWorkOrders.sparePartsWorkOrders + .map((e) => e.sparePart) + .toList(), + initialValue: (_subWorkOrders + .sparePartsWorkOrders?.isNotEmpty ?? + false) + ? _subWorkOrders + .sparePartsWorkOrders.first.sparePart + : null, onSelect: (part) { _subWorkOrders.sparePartsWorkOrders.clear(); - _subWorkOrders.sparePartsWorkOrders.add(SparePartsWorkOrders(id: 0, sparePart: part, qty: 0)); + _subWorkOrders.sparePartsWorkOrders.add( + SparePartsWorkOrders( + id: 0, sparePart: part, qty: 0)); setState(() {}); }, ), @@ -270,28 +373,60 @@ class _CreateSubWorkOrderPageState extends State { AppTextFormField( labelText: context.translation.quantity, textInputType: TextInputType.number, - enable: _subWorkOrders?.sparePartsWorkOrders?.isNotEmpty, - initialValue: (_subWorkOrders.sparePartsWorkOrders?.isNotEmpty ?? false) ? _subWorkOrders.sparePartsWorkOrders.first.qty?.toString() : null, + enable: _subWorkOrders + ?.sparePartsWorkOrders?.isNotEmpty, + initialValue: (_subWorkOrders + .sparePartsWorkOrders?.isNotEmpty ?? + false) + ? _subWorkOrders.sparePartsWorkOrders.first.qty + ?.toString() + : null, onSaved: (text) { - if (_subWorkOrders.sparePartsWorkOrders?.isNotEmpty ?? false) { - _subWorkOrders.sparePartsWorkOrders.first.qty = num.tryParse(text ?? ""); + if (_subWorkOrders + .sparePartsWorkOrders?.isNotEmpty ?? + false) { + _subWorkOrders.sparePartsWorkOrders.first.qty = + num.tryParse(text ?? ""); } }, ), 8.height, - MultiFilesPicker(label: context.translation.attachImage, files: _files), + ServiceReportRepairLocation( + label: context.translation.repairLocation, + initialValue: _subWorkOrders.repairLocation, + onSelect: (status) { + _subWorkOrders.repairLocation = status; + }, + ), 8.height, - ESignature( - title: context.translation.engSign, - oldSignature: _subWorkOrders.engSignature, - newSignature: _subWorkOrders.localEngSignature, - onSaved: (signature) { - // if (signature == null || signature.isEmpty) { - // setState(() {}); - // return; - // } - _subWorkOrders.localEngSignature = signature; - _subWorkOrders.engSignature = signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}" : null; + MultiFilesPicker( + label: context.translation.attachImage, + files: _files), + AppTextFormField( + labelText: context.translation.travelingExpense, + initialValue: _serviceReport?.travelingExpenses?.toString(), + textInputType: TextInputType.number, + onSaved: (value) { + _serviceReport.travelingExpenses = int.tryParse(value) ?? 0; + }, + ), + 8.height, + AppTextFormField( + labelText: context.translation.travelingHours, + initialValue: _serviceReport?.travelingHours?.toString(), + textInputType: TextInputType.number, + onSaved: (value) { + _serviceReport.travelingHours = int.tryParse(value) ?? 0; + }, + ), + 8.height, + AppTextFormField( + initialValue: _serviceReport?.comment, + labelText: context.translation.technicalComment, + alignLabelWithHint: true, + textInputType: TextInputType.multiline, + onSaved: (value) { + _serviceReport.comment = value; }, ), ], @@ -303,29 +438,47 @@ class _CreateSubWorkOrderPageState extends State { onPressed: () async { setState(() {}); _subWorkOrders.suppEngineerWorkOrders ?? []; - if (engineer != null) _subWorkOrders.suppEngineerWorkOrders.add(engineer..id = 0); + if (engineer != null) + _subWorkOrders.suppEngineerWorkOrders + .add(engineer..id = 0); if (await validate()) { _subWorkOrders.attachmentsWorkOrder ??= []; for (var file in _files) { - _subWorkOrders.attachmentsWorkOrder.add(Attachment(id: 0, name: "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}")); + _subWorkOrders.attachmentsWorkOrder.add(Attachment( + id: 0, + name: + "${file.path.split("/").last}|${base64Encode(file.readAsBytesSync())}")); } if (_formKey.currentState?.validate() ?? false) {} _formKey.currentState?.save(); - final serviceRequestsProvider = Provider.of(context, listen: false); - for (var element in (_subWorkOrders?.suppEngineerWorkOrders ?? [])) { + final serviceRequestsProvider = + Provider.of(context, + listen: false); + for (var element + in (_subWorkOrders?.suppEngineerWorkOrders ?? [])) { if (element != null) { element.id = 0; } } - showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); - final status = await serviceRequestsProvider.createSubWorkOrder(workOrder: _subWorkOrders); + showDialog( + context: context, + barrierDismissible: false, + builder: (context) => const AppLazyLoading()); + final status = await serviceRequestsProvider + .createSubWorkOrder(workOrder: _subWorkOrders); Navigator.of(context).pop(); if (status >= 200 && status < 300) { - Fluttertoast.showToast(msg: context.translation.successfulRequestMessage); + Fluttertoast.showToast( + msg: + context.translation.successfulRequestMessage); Navigator.of(context).pop(); } else { - String errorMessage = HttpStatusManger.getStatusMessage(status: serviceRequestsProvider.stateCode, subtitle: context.translation); - ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage))); + String errorMessage = + HttpStatusManger.getStatusMessage( + status: serviceRequestsProvider.stateCode, + subtitle: context.translation); + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(errorMessage))); } } }, @@ -337,9 +490,16 @@ class _CreateSubWorkOrderPageState extends State { } bool checkVendorFieldsVisibility(Lookup callsLastSituation) { - bool result = (_subWorkOrders.supplier?.suppliername?.isNotEmpty ?? false) || - (callsLastSituation?.name?.toLowerCase()?.contains("under repair-vendor") ?? false) || - (callsLastSituation?.name?.toLowerCase()?.contains("waiting for vendor") ?? false); + bool result = + (_subWorkOrders.supplier?.suppliername?.isNotEmpty ?? false) || + (callsLastSituation?.name + ?.toLowerCase() + ?.contains("under repair-vendor") ?? + false) || + (callsLastSituation?.name + ?.toLowerCase() + ?.contains("waiting for vendor") ?? + false); setState(() { _showVendorFields = result; }); @@ -348,22 +508,39 @@ class _CreateSubWorkOrderPageState extends State { Future validate() async { if (_subWorkOrders.reason == null) { - Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.reason}"); + Fluttertoast.showToast( + msg: + "${context.translation.youHaveToSelect} ${context.translation.reason}"); return false; } else if (_subWorkOrders.equipmentStatus == null) { - Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.equipmentStatus}"); + Fluttertoast.showToast( + msg: + "${context.translation.youHaveToSelect} ${context.translation.equipmentStatus}"); return false; } else if (_subWorkOrders.calllastSituation == null) { - Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.callLastSituation}"); + Fluttertoast.showToast( + msg: + "${context.translation.youHaveToSelect} ${context.translation.callLastSituation}"); return false; - } else if (_showVendorFields && _subWorkOrders.suppEngineerWorkOrders == null) { - Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.vendorEng}"); + } else if (_showVendorFields && + _subWorkOrders.suppEngineerWorkOrders == null) { + Fluttertoast.showToast( + msg: + "${context.translation.youHaveToSelect} ${context.translation.vendorEng}"); return false; - } else if (_showVendorFields && (_subWorkOrders.supplier.suppliername == null || _subWorkOrders.supplier.suppliername.isEmpty)) { - Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.vendorName}"); + } else if (_showVendorFields && + (_subWorkOrders.supplier.suppliername == null || + _subWorkOrders.supplier.suppliername.isEmpty)) { + Fluttertoast.showToast( + msg: + "${context.translation.youHaveToSelect} ${context.translation.vendorName}"); return false; - } else if (_subWorkOrders.calllastSituation.value == 12 && (_subWorkOrders.sparePartsWorkOrders == null || _subWorkOrders.sparePartsWorkOrders.isEmpty)) { - Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.partNo}"); + } else if (_subWorkOrders.calllastSituation.value == 12 && + (_subWorkOrders.sparePartsWorkOrders == null || + _subWorkOrders.sparePartsWorkOrders.isEmpty)) { + Fluttertoast.showToast( + msg: + "${context.translation.youHaveToSelect} ${context.translation.partNo}"); return false; } else if (_subWorkOrders?.timer?.startAt == null) { await Fluttertoast.showToast(msg: "Working Hours Required"); diff --git a/lib/views/pages/user/requests/work_order/create_service_report.dart b/lib/views/pages/user/requests/work_order/create_service_report.dart index b48bdba4..bea0e287 100644 --- a/lib/views/pages/user/requests/work_order/create_service_report.dart +++ b/lib/views/pages/user/requests/work_order/create_service_report.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'dart:io'; import 'package:flutter/material.dart'; @@ -6,6 +7,7 @@ import 'package:provider/provider.dart'; import 'package:test_sa/attachment.dart'; import 'package:test_sa/controllers/providers/api/parts_provider.dart'; import 'package:test_sa/controllers/providers/api/service_requests_provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_fault_description_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'; @@ -16,6 +18,7 @@ import 'package:test_sa/models/service_request/service_report.dart'; import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.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/work_order/reason_provider.dart'; import 'package:test_sa/providers/work_order/service_type_provider.dart'; import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; @@ -30,13 +33,15 @@ 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 '../../../../../new_views/common_widgets/single_item_drop_down_menu.dart'; +import '../../../../../providers/work_order/asset_types_provider.dart'; import '../../../../widgets/date_and_time/date_picker.dart'; import '../../../../widgets/images/multi_image_picker.dart'; +import '../../../../widgets/status/report/service_report_fault_description.dart'; import '../../../../widgets/timer/app_timer.dart'; /// todo : TBD (compare with the design) class CreateServiceReport extends StatefulWidget { - static final String id = "/create-service-report"; + static const String id = "/create-service-report"; final ServiceRequest request; const CreateServiceReport({Key key, this.request}) : super(key: key); @@ -157,6 +162,36 @@ class _CreateServiceReportState extends State with TickerPr }, ), 8.height, + LoadingManager( + isLoading: _assetTypeProvider.isLoading, + isFailedLoading: _assetTypeProvider.statuses == null, + stateCode: _assetTypeProvider.stateCode, + onRefresh: () async { + _assetTypeProvider.reset(); + await _assetTypeProvider.getTypes(user: _userProvider.user, host: _settingProvider.host); + _serviceReport?.assetType = _assetTypeProvider.statuses?.firstWhere( + (element) => element.value == _serviceReport.callRequest.assetType, + orElse: () => null, + ); + }, + child: AppTextFormField( + labelText: context.translation.assetType, + initialValue: _serviceReport?.assetType?.name ?? "NULL", + textAlign: TextAlign.center, + enable: false, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: context.translation.equipmentStatus, + initialValue: _serviceReport.equipmentStatus, + onSelect: (value) { + _serviceReport.equipmentStatus = value; + }, + ), + 8.height, SingleItemDropDownMenu( context: context, title: context.translation.reason, @@ -181,6 +216,23 @@ class _CreateServiceReportState extends State with TickerPr }, ), 8.height, + ServiceReportFaultDescription( + requestId: widget.request?.id, + initialValue: _serviceReport.faultDescription, + onSelect: (status) { + _serviceReport.faultDescription = status; + _workPreformedController?.text = _serviceReport.faultDescription?.workPerformed; + }, + ), + 8.height, + AppTextFormField( + labelText: context.translation.solution, + initialValue: _serviceReport?.faultDescription?.workPerformed, + textAlign: TextAlign.center, + enable: false, + controller: _workPreformedController, + ), + 8.height, ServiceReportAssistantEmployeeMenu( title: context.translation.assignAssistant, assetId: _serviceReport.callRequest?.asset?.id, @@ -214,6 +266,34 @@ class _CreateServiceReportState extends State with TickerPr }, ), 8.height, + AppTextFormField( + labelText: context.translation.travelingExpense, + initialValue: _serviceReport?.travelingExpenses?.toString(), + textInputType: TextInputType.number, + onSaved: (value) { + _serviceReport.travelingExpenses = int.tryParse(value) ?? 0; + }, + ), + 8.height, + AppTextFormField( + labelText: context.translation.travelingHours, + initialValue: _serviceReport?.travelingHours?.toString(), + textInputType: TextInputType.number, + onSaved: (value) { + _serviceReport.travelingHours = int.tryParse(value) ?? 0; + }, + ), + 8.height, + AppTextFormField( + initialValue: _serviceReport?.comment, + labelText: context.translation.technicalComment, + alignLabelWithHint: true, + textInputType: TextInputType.multiline, + onSaved: (value) { + _serviceReport.comment = value; + }, + ), + 8.height, MultiFilesPicker(label: context.translation.attachImage, files: _files), 8.height, ESignature( @@ -228,6 +308,19 @@ class _CreateServiceReportState extends State with TickerPr _serviceReport.localEngSignature = signature; _serviceReport.engSignature = signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}" : null; }, + ), 8.height, + ESignature( + title: context.translation.nurseSignature, + oldSignature: _serviceReport.nurseSignature, + newSignature: _serviceReport.localNurseSignature, + onSaved: (signature) { + // if (signature == null || signature.isEmpty) { + // setState(() {}); + // return; + // } + _serviceReport.localNurseSignature = signature; + _serviceReport.nurseSignature = signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}" : null; + }, ), 24.height, ], diff --git a/lib/views/pages/user/requests/work_order/edit_service_report.dart b/lib/views/pages/user/requests/work_order/edit_service_report.dart index 0eb138c5..97f2e9c0 100644 --- a/lib/views/pages/user/requests/work_order/edit_service_report.dart +++ b/lib/views/pages/user/requests/work_order/edit_service_report.dart @@ -25,12 +25,14 @@ import '../../../../../new_views/common_widgets/app_text_form_field.dart'; import '../../../../../new_views/common_widgets/default_app_bar.dart'; import '../../../../../new_views/common_widgets/single_item_drop_down_menu.dart'; import '../../../../../providers/loading_list_notifier.dart'; +import '../../../../../providers/service_request_providers/equipment_status_provider.dart'; import '../../../../../providers/work_order/reason_provider.dart'; import '../../../../../providers/work_order/service_type_provider.dart'; import '../../../../widgets/date_and_time/date_picker.dart'; import '../../../../widgets/e_signature/e_signature.dart'; import '../../../../widgets/images/multi_image_picker.dart'; import '../../../../widgets/status/report/service_report_assistant_employee_menu.dart'; +import '../../../../widgets/status/report/service_report_fault_description.dart'; import '../../../../widgets/timer/app_timer.dart'; class EditServiceReport extends StatefulWidget { @@ -142,6 +144,36 @@ class _EditServiceReportState extends State with TickerProvid }, ), 8.height, + LoadingManager( + isLoading: _assetTypeProvider.isLoading, + isFailedLoading: _assetTypeProvider.statuses == null, + stateCode: _assetTypeProvider.stateCode, + onRefresh: () async { + _assetTypeProvider.reset(); + await _assetTypeProvider.getTypes(user: _userProvider.user, host: _settingProvider.host); + _serviceReport?.assetType = _assetTypeProvider.statuses?.firstWhere( + (element) => element.value == _serviceReport.callRequest.assetType, + orElse: () => null, + ); + }, + child: AppTextFormField( + labelText: context.translation.assetType, + initialValue: _serviceReport?.assetType?.name ?? "NULL", + textAlign: TextAlign.center, + enable: false, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + 8.height, + SingleItemDropDownMenu( + context: context, + title: context.translation.equipmentStatus, + initialValue: _serviceReport.equipmentStatus, + onSelect: (value) { + _serviceReport.equipmentStatus = value; + }, + ), + 8.height, SingleItemDropDownMenu( context: context, title: context.translation.reason, @@ -166,6 +198,23 @@ class _EditServiceReportState extends State with TickerProvid }, ), 8.height, + ServiceReportFaultDescription( + requestId: widget.request?.id, + initialValue: _serviceReport.faultDescription, + onSelect: (status) { + _serviceReport.faultDescription = status; + _workPreformedController?.text = _serviceReport.faultDescription?.workPerformed; + }, + ), + 8.height, + AppTextFormField( + labelText: context.translation.solution, + initialValue: _serviceReport?.faultDescription?.workPerformed, + textAlign: TextAlign.center, + enable: false, + controller: _workPreformedController, + ), + 8.height, ServiceReportAssistantEmployeeMenu( title: context.translation.assignAssistant, assetId: _serviceReport.callRequest?.asset?.id, @@ -199,6 +248,34 @@ class _EditServiceReportState extends State with TickerProvid }, ), 8.height, + AppTextFormField( + labelText: context.translation.travelingExpense, + initialValue: _serviceReport?.travelingExpenses?.toString(), + textInputType: TextInputType.number, + onSaved: (value) { + _serviceReport.travelingExpenses = int.tryParse(value) ?? 0; + }, + ), + 8.height, + AppTextFormField( + labelText: context.translation.travelingHours, + initialValue: _serviceReport?.travelingHours?.toString(), + textInputType: TextInputType.number, + onSaved: (value) { + _serviceReport.travelingHours = int.tryParse(value) ?? 0; + }, + ), + 8.height, + AppTextFormField( + initialValue: _serviceReport?.comment, + labelText: context.translation.technicalComment, + alignLabelWithHint: true, + textInputType: TextInputType.multiline, + onSaved: (value) { + _serviceReport.comment = value; + }, + ), + 8.height, MultiFilesPicker(label: context.translation.attachImage, files: _files), 8.height, ESignature( @@ -214,6 +291,20 @@ class _EditServiceReportState extends State with TickerProvid _serviceReport.engSignature = signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}" : null; }, ), + 8.height, + ESignature( + title: context.translation.nurseSignature, + oldSignature: _serviceReport.nurseSignature, + newSignature: _serviceReport.localNurseSignature, + onSaved: (signature) { + // if (signature == null || signature.isEmpty) { + // setState(() {}); + // return; + // } + _serviceReport.localNurseSignature = signature; + _serviceReport.nurseSignature = signature != null ? "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}" : null; + }, + ), 24.height, ], ), diff --git a/lib/views/pages/user/requests/work_order/work_orders_list_page.dart b/lib/views/pages/user/requests/work_order/work_orders_list_page.dart index ebcb56e2..3b0bc31c 100644 --- a/lib/views/pages/user/requests/work_order/work_orders_list_page.dart +++ b/lib/views/pages/user/requests/work_order/work_orders_list_page.dart @@ -78,7 +78,7 @@ class WorkOrderListPage extends StatelessWidget { ], ).expanded, if (_userProvider.user.type == UsersTypes.engineer && serviceRequest.statusValue != 5 && serviceRequest.statusValue != 3) - context.translation.edit.toSvgAsset(height: 48, width: 48).onPress(() { + "edit".toSvgAsset(height: 48, width: 48).onPress(() { Navigator.of(context).push( MaterialPageRoute(builder: (_) => UpdateServiceReport(request: serviceRequest, workOrder: workOrders[index])), ); diff --git a/lib/views/widgets/status/report/service_report_fault_description.dart b/lib/views/widgets/status/report/service_report_fault_description.dart index 0f2990bb..747327ea 100644 --- a/lib/views/widgets/status/report/service_report_fault_description.dart +++ b/lib/views/widgets/status/report/service_report_fault_description.dart @@ -3,17 +3,40 @@ import 'package:provider/provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_fault_description_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/models/fault_description.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/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/status/report/fault_desc_menu.dart'; -class ServiceReportFaultDescription extends StatelessWidget { +class ServiceReportFaultDescription extends StatefulWidget { final String requestId; final Function(FaultDescription) onSelect; final FaultDescription initialValue; const ServiceReportFaultDescription({Key key, this.requestId, this.onSelect, this.initialValue}) : super(key: key); + @override + State createState() => _ServiceReportFaultDescriptionState(); +} + +class _ServiceReportFaultDescriptionState extends State { + + @override + void initState() { + super.initState(); + if(widget.initialValue == null){ + WidgetsFlutterBinding.ensureInitialized() + .addPostFrameCallback((timeStamp) { + ServiceRequestFaultDescriptionProvider menuProvider = + Provider.of(context, + listen: false); + menuProvider.reset(); + menuProvider.getCallRequestForWorkOrder(requestId: widget.requestId); + }); + } + } @override Widget build(BuildContext context) { SettingProvider settingProvider = Provider.of(context); @@ -25,13 +48,20 @@ class ServiceReportFaultDescription extends StatelessWidget { stateCode: menuProvider.stateCode, onRefresh: () async { menuProvider.reset(); - await menuProvider.getCallRequestForWorkOrder(user: userProvider.user, host: settingProvider.host, requestId: requestId); + await menuProvider.getCallRequestForWorkOrder(user: userProvider.user, host: settingProvider.host, requestId: widget.requestId); }, - child: FaultDescriptionMenu( - initialStatus: initialValue, - statuses: menuProvider.items ?? [], - onSelect: onSelect, + child: SingleItemDropDownMenu( + context: context, + title: context.translation.faultDescription, + onSelect: widget.onSelect, + initialValue: widget.initialValue, + staticData: menuProvider.items ?? [], ), + // child: FaultDescriptionMenu( + // initialStatus: initialValue, + // statuses: menuProvider.items ?? [], + // onSelect: onSelect, + // ), ); } } diff --git a/lib/views/widgets/status/report/service_report_repair_location.dart b/lib/views/widgets/status/report/service_report_repair_location.dart index 52cb3038..1803b44d 100644 --- a/lib/views/widgets/status/report/service_report_repair_location.dart +++ b/lib/views/widgets/status/report/service_report_repair_location.dart @@ -8,10 +8,11 @@ import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/status/single_status_menu.dart'; class ServiceReportRepairLocation extends StatelessWidget { + final String label; final Lookup initialValue; final Function(Lookup) onSelect; - const ServiceReportRepairLocation({Key key, this.onSelect, this.initialValue}) : super(key: key); + const ServiceReportRepairLocation({Key key,this.label, this.onSelect, this.initialValue}) : super(key: key); @override Widget build(BuildContext context) { @@ -30,6 +31,7 @@ class ServiceReportRepairLocation extends StatelessWidget { ); }, child: SingleStatusMenu( + title: label, initialStatus: initialValue, statuses: _menuProvider.reasons, onSelect: onSelect,