diff --git a/android/app/build.gradle b/android/app/build.gradle index e55e2b2..4f0659d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -54,22 +54,25 @@ android { } signingConfigs { - release { - keyAlias keystoreProperties['keyAlias'] - keyPassword keystoreProperties['keyPassword'] - storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null - storePassword keystoreProperties['storePassword'] - } +// release { +// keyAlias keystoreProperties['keyAlias'] +// keyPassword keystoreProperties['keyPassword'] +// storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null +// storePassword keystoreProperties['storePassword'] +// } } buildTypes { debug { signingConfig signingConfigs.debug } release { - minifyEnabled true - shrinkResources true - signingConfig signingConfigs.release + signingConfig signingConfigs.debug } +// release { +// minifyEnabled true +// shrinkResources true +// signingConfig signingConfigs.release +// } } } diff --git a/assets/images/sub_workorder_icon.svg b/assets/images/sub_workorder_icon.svg new file mode 100644 index 0000000..4400caa --- /dev/null +++ b/assets/images/sub_workorder_icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/subtitles/ar_subtitle.json b/assets/subtitles/ar_subtitle.json index 271c9c1..2ed3e57 100644 --- a/assets/subtitles/ar_subtitle.json +++ b/assets/subtitles/ar_subtitle.json @@ -201,6 +201,8 @@ "repairLocation" : "موقع الإصلاح", "travelingExpense" : "مصاريف التنقل", "startDate" : "وقت البدء", + "requestedQuantity" : "الكمية المطلوبة", + "deliveredQuantity" : "الكمية المسلّمة", "endDate" : "وقت الانتهاء", "destinationSite": "موقع الوجهه", "building": "بناء", diff --git a/assets/subtitles/en_subtitle.json b/assets/subtitles/en_subtitle.json index ee7b0c2..ed6f591 100644 --- a/assets/subtitles/en_subtitle.json +++ b/assets/subtitles/en_subtitle.json @@ -201,6 +201,8 @@ "repairLocation" : "Repair Location", "travelingExpense": "Traveling Expense", "startDate" : "Start Date", + "requestedQuantity" : "Requested Quantity", + "deliveredQuantity" : "Delivered Quantity", "endDate" : "End Date", "destinationSite": "Destination Site", "building": "Building", @@ -208,6 +210,4 @@ "department": "Department", "room": "Room", "actions": "Actions" - - } \ No newline at end of file diff --git a/lib/controllers/api_routes/api_manager.dart b/lib/controllers/api_routes/api_manager.dart index f40b309..3bbfed5 100644 --- a/lib/controllers/api_routes/api_manager.dart +++ b/lib/controllers/api_routes/api_manager.dart @@ -2,6 +2,7 @@ import 'dart:convert'; import 'dart:developer'; import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:http/http.dart' as http; import 'package:http/http.dart'; @@ -51,9 +52,12 @@ class ApiManager { headers.addAll(_headers); Uri _url = Uri.parse(url); - // print(_url); - // print(headers); - // log(json.encode(body)); + if (!kReleaseMode) { + print("URL:$_url"); + print("Headers:$headers"); + print("Body:$body"); + } + var request = http.Request('POST', _url); request.body = json.encode(body); request.headers.addAll(headers); @@ -83,7 +87,7 @@ class ApiManager { headers.addAll(_headers); Uri _url = Uri.parse(url); - // print(_url); + print(_url); // print(headers); // log(json.encode(body)); var request = http.Request('PUT', _url); diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 4dc9dc7..8679422 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -36,6 +36,9 @@ class URLs { static get getRepairLocation => "$_baseUrl/Lookups/GetLookup?lookupEnum=504"; static get equipmentStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=601"; + static get getDateOperators => "$_baseUrl/Lookups/GetLookup?lookupEnum=200"; + static get getMaintenanceSituation => "$_baseUrl/Lookups/GetLookup?lookupEnum=502"; + static get getAllUsers => "http://109.123.243.118:5000/api/Account/GetAllUsers"; static get getPreventiveMaintenanceVisits => "$_baseUrl/return/user/calibrations"; // get static get updatePreventiveMaintenanceVisits => "$_baseUrl/Visit/UpdateVisits"; // get diff --git a/lib/controllers/providers/api/device_transfer_provider.dart b/lib/controllers/providers/api/device_transfer_provider.dart index a534fbc..43c5ece 100644 --- a/lib/controllers/providers/api/device_transfer_provider.dart +++ b/lib/controllers/providers/api/device_transfer_provider.dart @@ -23,7 +23,7 @@ class DeviceTransferProvider extends ChangeNotifier { building = null; floor = null; department = null; - room=""; + room = ""; startDate = null; endDate = null; } @@ -44,7 +44,6 @@ class DeviceTransferProvider extends ChangeNotifier { // failed _loading = false bool isLoading; - Hospital hospital; Buildings building; Floors floor; @@ -115,7 +114,7 @@ class DeviceTransferProvider extends ChangeNotifier { // "transferCode": "string", "destBuildingId": building?.id, "destFloorId": floor.id, - "destRoom": room, + "destRoom": room, // "senderBuildingId": 0, // "senderFloorId": 0, // "senderDepartmentId": 0, @@ -179,8 +178,8 @@ class DeviceTransferProvider extends ChangeNotifier { "senderMachineStatusId": newModel.status.id, "senderComment": newModel.comment, "senderWorkingHours": newModel.workingHours, - "senderStartDate": newModel.startDate?.toIso8601String(), - "senderEndDate": newModel.endDate?.toIso8601String(), + "senderStartDate": newModel.timer?.startAt?.toIso8601String(), + "senderEndDate": newModel.timer?.endAt?.toIso8601String(), "senderTravelingHours": newModel.travelingHours, "senderAttachmentName": "${newModel.signature}.png", "destSiteId": oldModel.receiver.client.id, @@ -189,8 +188,8 @@ class DeviceTransferProvider extends ChangeNotifier { "receiverMachineStatusId": oldModel.receiver.status.id ?? "", "receiverComment": oldModel.receiver.comment, "receiverWorkingHours": oldModel.receiver.workingHours, - "receiverStartDate": oldModel.receiver.startDate?.toIso8601String(), - "receiverEndDate": oldModel.receiver.endDate?.toIso8601String(), + "receiverStartDate": oldModel.receiver.timer?.startAt?.toIso8601String(), + "receiverEndDate": oldModel.receiver.timer?.endAt?.toIso8601String(), "receiverTravelingHours": oldModel.receiver.travelingHours, "receiverAttachmentName": "${oldModel.receiver.signature}.png", }); @@ -202,8 +201,8 @@ class DeviceTransferProvider extends ChangeNotifier { "senderMachineStatusId": oldModel.sender.status.id, "senderComment": oldModel.sender.comment, "senderWorkingHours": oldModel.sender.workingHours, - "senderStartDate": oldModel.sender.startDate?.toIso8601String(), - "senderEndDate": oldModel.sender.endDate?.toIso8601String(), + "senderStartDate": oldModel.sender.timer?.startAt?.toIso8601String(), + "senderEndDate": oldModel.sender.timer?.endAt?.toIso8601String(), "senderTravelingHours": oldModel.sender.travelingHours, "senderAttachmentName": "${oldModel.sender.signature}.png", "destSiteId": newModel.client.id, @@ -212,8 +211,8 @@ class DeviceTransferProvider extends ChangeNotifier { "receiverMachineStatusId": newModel.status?.id ?? "", "receiverComment": newModel.comment, "receiverWorkingHours": newModel.workingHours, - "receiverStartDate": newModel.startDate?.toIso8601String(), - "receiverEndDate": newModel.endDate?.toIso8601String(), + "receiverStartDate": newModel.timer?.startAt?.toIso8601String(), + "receiverEndDate": newModel.timer?.endAt?.toIso8601String(), "receiverTravelingHours": newModel.travelingHours, "receiverAttachmentName": "${newModel.signature}.png", }); @@ -247,5 +246,4 @@ class DeviceTransferProvider extends ChangeNotifier { return -1; } } - } diff --git a/lib/controllers/providers/api/devices_provider.dart b/lib/controllers/providers/api/devices_provider.dart index 4bede20..2d55a2a 100644 --- a/lib/controllers/providers/api/devices_provider.dart +++ b/lib/controllers/providers/api/devices_provider.dart @@ -147,31 +147,31 @@ class DevicesProvider extends ChangeNotifier { } } - /// return -2 if request in progress - /// return -1 if error happen when sending request - /// return state code if request complete may be 200, 404 or 403 - /// for more details check http state manager - /// lib\controllers\http_status_manger\http_status_manger.dart - Future> getDevicesListBySN({@required String host, @required User user, @required int hospitalId, @required String sn}) async { - Response response; - try { - response = await get( - Uri.parse(URLs.getEquipment + "?client=$hospitalId" + (sn == null || sn.isEmpty ? "" : "&serial_qr=$sn")), - ); - - _stateCode = response.statusCode; - List _page = []; - if (response.statusCode >= 200 && response.statusCode < 300) { - // client's request was successfully received - List categoriesListJson = json.decode(utf8.decode(response.bodyBytes)); - _page = categoriesListJson.map((device) => Device.fromJson(device)).toList(); - } - return _page; - } catch (error) { - _loading = false; - _stateCode = -1; - notifyListeners(); - return []; - } - } + // /// return -2 if request in progress + // /// return -1 if error happen when sending request + // /// return state code if request complete may be 200, 404 or 403 + // /// for more details check http state manager + // /// lib\controllers\http_status_manger\http_status_manger.dart + // Future> getDevicesListBySN({@required String host, @required User user, @required int hospitalId, @required String sn}) async { + // Response response; + // try { + // response = await get( + // Uri.parse(URLs.getEquipment + "?client=$hospitalId" + (sn == null || sn.isEmpty ? "" : "&serial_qr=$sn")), + // ); + // + // _stateCode = response.statusCode; + // List _page = []; + // if (response.statusCode >= 200 && response.statusCode < 300) { + // // client's request was successfully received + // List categoriesListJson = json.decode(utf8.decode(response.bodyBytes)); + // _page = categoriesListJson.map((device) => Device.fromJson(device)).toList(); + // } + // return _page; + // } catch (error) { + // _loading = false; + // _stateCode = -1; + // notifyListeners(); + // return []; + // } + // } } diff --git a/lib/controllers/providers/api/gas_refill_provider.dart b/lib/controllers/providers/api/gas_refill_provider.dart index a229b07..faf84d6 100644 --- a/lib/controllers/providers/api/gas_refill_provider.dart +++ b/lib/controllers/providers/api/gas_refill_provider.dart @@ -91,22 +91,24 @@ class GasRefillProvider extends ChangeNotifier { @required User user, @required GasRefillModel model, }) async { + print("ss"); Map body = { "uid": user.id.toString(), "token": user.token ?? "", + "site": hospital?.toMap(), "building": {"id": building?.id, "name": building?.name, "value": building?.value}, - "floor": {"id": floor.id, "name": floor.name, "value": floor.value}, - if (expectedDateTime != null) "expectedDate": expectedDateTime, - if (expectedDateTime != null) "expectedTime": expectedDateTime, - if (startDate != null) "startDate": startDate, - if (startDate != null) "startTime": startDate, - if (endDate != null) "endDate": endDate, - if (endDate != null) "endTime": endDate, - "department": {"id": department.id, "departmentName": department.name, "departmentCode": "", "ntCode": ""}, + "floor": {"id": floor?.id, "name": floor?.name, "value": floor?.value}, + if (expectedDateTime != null) "expectedDate": expectedDateTime?.toIso8601String(), + if (expectedDateTime != null) "expectedTime": expectedDateTime?.toIso8601String(), + if (startDate != null) "startDate": startDate?.toIso8601String(), + if (startDate != null) "startTime": startDate?.toIso8601String(), + if (endDate != null) "endDate": endDate?.toIso8601String(), + if (endDate != null) "endTime": endDate?.toIso8601String(), + "department": {"id": department?.id, "departmentName": department?.name, "departmentCode": "", "ntCode": ""}, "GazRefillNo": "GR-${DateTime.now().toString().split(" ").first}", "status": model.status.toMap(), }; - + print("ss1"); body["gazRefillDetails"] = model.details .map((model) => { "gasType": model.type.toMap(), @@ -119,6 +121,7 @@ class GasRefillProvider extends ChangeNotifier { Response response; try { response = await ApiManager.instance.post(URLs.requestGasRefill, body: body); + print("ss2"); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { if (items != null) { @@ -128,6 +131,7 @@ class GasRefillProvider extends ChangeNotifier { } return response.statusCode; } catch (error) { + print(error); return -1; } } @@ -142,6 +146,20 @@ class GasRefillProvider extends ChangeNotifier { "id": newModel.id, "gazRefillNo": newModel.title ?? "", "status": newModel.status.toMap(), + "expectedDate": oldModel.expectedDate?.toIso8601String(), + "expectedTime": oldModel.expectedDate?.toIso8601String(), + "startDate": startDate?.toIso8601String(), + "startTime": startDate?.toIso8601String(), + "endDate": endDate?.toIso8601String(), + "endTime": endDate?.toIso8601String(), + "workingHours": ((endDate?.difference(startDate)?.inMinutes ?? 0) / 60), + "assignedEmployee": oldModel?.assignedEmployee?.id == null ? null : oldModel?.assignedEmployee?.toJson(), + "site": hospital?.toMap(), + "building": building?.toJson(includeFloors: false), + "floor": floor?.toJson(includeDepartments: false), + "department": department?.toJson(), + "engSignature": newModel.signatureEngineer, + "nurseSignature": newModel.signatureNurse, }; body["gazRefillDetails"] = newModel.details diff --git a/lib/controllers/providers/api/service_requests_provider.dart b/lib/controllers/providers/api/service_requests_provider.dart index a044543..edf5a74 100644 --- a/lib/controllers/providers/api/service_requests_provider.dart +++ b/lib/controllers/providers/api/service_requests_provider.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:developer'; import 'package:flutter/cupertino.dart'; import 'package:http/http.dart'; @@ -7,14 +8,15 @@ import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/models/call_request_for_work_order_model.dart'; import 'package:test_sa/models/issue.dart'; +import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/service_report.dart'; import 'package:test_sa/models/service_request/service_request.dart'; import 'package:test_sa/models/service_request/service_request_search.dart'; import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/timer_model.dart'; -import 'package:test_sa/models/user.dart'; import '../../../models/service_request/search_work_order.dart'; +import '../../../models/user.dart'; class ServiceRequestsProvider extends ChangeNotifier { // number of items call in each request @@ -22,6 +24,7 @@ class ServiceRequestsProvider extends ChangeNotifier { //reset provider data void reset() { + workOrders = []; serviceRequests = null; nextPage = true; stateCode = null; @@ -37,7 +40,7 @@ class ServiceRequestsProvider extends ChangeNotifier { // list of user requests List serviceRequests; - List workOrders = []; + List workOrders = []; // when requests in-process _loading = true // done _loading = true @@ -51,11 +54,7 @@ class ServiceRequestsProvider extends ChangeNotifier { /// return state code if request complete may be 200, 404 or 403 /// for more details check http state manager /// lib\controllers\http_status_manger\http_status_manger.dart - Future getRequests({ - @required String host, - @required User user, - @required int hospitalId, - }) async { + Future getRequests({@required int hospitalId}) async { if (isLoading == true) return -2; isLoading = true; if (serviceRequests == null) notifyListeners(); @@ -237,6 +236,10 @@ class ServiceRequestsProvider extends ChangeNotifier { "voiceNote": request.audio, "assets": request.deviceId == null ? [] : [request.deviceId], "attachmentsCallRequest": request.devicePhotos?.map((e) => {"name": e})?.toList(), + "assignedEmployee": { + "id": request.engineerId, + "name": request.engineerName, + }, "callSiteContactPerson": [ { "id": callSiteContactPerson['id'] ?? 0, @@ -318,9 +321,9 @@ class ServiceRequestsProvider extends ChangeNotifier { "currentSituation": null, "repairLocation": report.repairLocation?.toMap(), "reason": report.reason?.toMap(), - "startofWorkTime": report.startDate?.toIso8601String() ?? "", - "endofWorkTime": report.endDate?.toIso8601String() ?? "", - "workingHours": ((report?.endDate?.difference(report?.startDate)?.inMinutes ?? 0) / 60), + "startofWorkTime": report.timer?.startAt?.toIso8601String() ?? "", + "endofWorkTime": report.timer?.endAt?.toIso8601String() ?? "", + "workingHours": report?.workingHours, "travelingHours": report.travelingHours, "travelingExpenses": report.travelingExpense ?? 0, if (report.faultDescription != null) "faultDescription": report.faultDescription.toJson(), @@ -364,6 +367,27 @@ class ServiceRequestsProvider extends ChangeNotifier { } } + Future createSubWorkOrder({ + @required SearchWorkOrder workOrder, + }) async { + Response response; + try { + Map body = workOrder.toJson(); + response = await ApiManager.instance.post(URLs.createServiceReport, body: body); + print(response.body); + + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + reset(); + notifyListeners(); + } + return response.statusCode; + } catch (error) { + print(error); + return -1; + } + } + CallRequestForWorkOrder callRequestForWorkOrder; Future getCallRequestForWorkOrder({String callId}) async { @@ -376,17 +400,19 @@ class ServiceRequestsProvider extends ChangeNotifier { if (response.statusCode >= 200 && response.statusCode < 300) { // client's request was successfully received Map listJson = json.decode(response.body)["data"]; + log(listJson?.toString()); callRequestForWorkOrder = CallRequestForWorkOrder.fromJson(listJson); } notifyListeners(); return callRequestForWorkOrder; } catch (error) { + print(error); return null; } } - Future> searchWorkOrders({@required String callId}) async { + Future> searchWorkOrders({@required String callId}) async { Response response; try { @@ -401,7 +427,7 @@ class ServiceRequestsProvider extends ChangeNotifier { // client's request was successfully received List workOrdersJson = json.decode(response.body)["data"]; print(workOrdersJson); - workOrders = workOrdersJson.map((request) => SearchWorkOrders.fromJson(request)).toList(); + workOrders = workOrdersJson.map((request) => SearchWorkOrder.fromJson(request)).toList(); if (workOrders.length == pageItemNumber) { nextPage = true; } else { @@ -444,11 +470,41 @@ class ServiceRequestsProvider extends ChangeNotifier { } Future updateServiceReport({ - @required String host, - @required User user, @required ServiceReport report, - @required ServiceRequest request, + String host, + User user, + ServiceRequest request, }) async { + Response response; + //Map body = report.toMap(request); + // body["uid"] = user.id; + // body["token"] = user.token; + // body["job_id"] = request.id; + // body["report_id"] = request.reportID; + // try { + Map body = report.toMap(request); + // body["uid"] = user.id; + // body["token"] = user.token; + response = await ApiManager.instance.put(URLs.updateServiceReport, body: body); + // response = await post( + // Uri.parse( + // host+URLs.updateServiceReport), + // body: body, + // ); + // stateCode = response.statusCode; + + if (response.statusCode >= 200 && response.statusCode < 300) { + reset(); + notifyListeners(); + } + return response.statusCode; + // } catch (error) { + // print(error); + // return -1; + // } + } + + Future updateWorkOrderDetails({@required SearchWorkOrder workOrder}) async { Response response; //Map body = report.toMap(request); // body["uid"] = user.id; @@ -456,7 +512,7 @@ class ServiceRequestsProvider extends ChangeNotifier { // body["job_id"] = request.id; // body["report_id"] = request.reportID; try { - Map body = report.toMap(request); + Map body = workOrder.toJson(); // body["uid"] = user.id; // body["token"] = user.token; response = await ApiManager.instance.put(URLs.updateServiceReport, body: body); @@ -557,4 +613,51 @@ class ServiceRequestsProvider extends ChangeNotifier { return {}; } } + + Future> searchForWorkOrders( + SearchWorkOrder search, + String callerId, + Lookup dateOperator, + String site, + ) async { + Response response; + try { + var body = { + "pageSize": pageItemNumber, + "pageNumber": ((workOrders?.length ?? 0) ~/ pageItemNumber) + 1, + if (callerId?.isNotEmpty ?? false) "callId": callerId, + if (search.assetType != null) "assetSerialNo": search.assetType?.name, + if (search.workOrderNo != null) "workOrderNo": search.workOrderNo, + if (search.id != null) "workOrderNo": search.id?.toString(), + if (search.calllastSituation != null) "callslastSituationWO": search.calllastSituation.toMap(), + if (search.assignedEmployee != null) + "assignedEmployees": [ + search.assignedEmployee.id, + ], + // "statusWO": [], + if (site?.isNotEmpty ?? false) "site": site, + if (search.visitDate != null && dateOperator != null) "visitDateSymbol": dateOperator?.toMap(), + if (search.visitDate != null && dateOperator != null) "visitDateFrom": search.visitDate, + }; + print(body); + response = await ApiManager.instance.post(URLs.searchWorkOrders, body: body); + stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List workOrdersJson = json.decode(response.body)["data"]; + print(workOrdersJson); + workOrders ??= []; + workOrders.addAll(workOrdersJson.map((request) => SearchWorkOrder.fromJson(request)).toList()); + if (workOrders.length == pageItemNumber) { + nextPage = true; + } else { + nextPage = false; + } + } + return workOrders; + } catch (e) { + print(e); + return []; + } + } } diff --git a/lib/controllers/providers/api/status_drop_down/report/service_report_assistants_employee_provider.dart b/lib/controllers/providers/api/status_drop_down/report/service_report_assistants_employee_provider.dart new file mode 100644 index 0000000..922242a --- /dev/null +++ b/lib/controllers/providers/api/status_drop_down/report/service_report_assistants_employee_provider.dart @@ -0,0 +1,76 @@ +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/service_request/search_work_order.dart'; + +class ServiceReportAssistantsEmployeeProvider extends ChangeNotifier { + //reset provider data + void reset() { + _assistantEmployees = null; + _loading = null; + _stateCode = null; + } + + // state code of current request to defied error message + // like 400 customer request failed + // 500 service not available + int _stateCode; + int get stateCode => _stateCode; + + // contain user data + // when user not login or register _user = null + List _assistantEmployees; + List get assistantEmployees => _assistantEmployees; + + // when categories in-process _loading = true + // done _loading = true + // failed _loading = false + bool _loading; + bool get isLoading => _loading; + set isLoading(bool isLoading) { + _loading = isLoading; + notifyListeners(); + } + + /// return -2 if request in progress + /// return -1 if error happen when sending request + /// return state code if request complete may be 200, 404 or 403 + /// for more details check http state manager + /// lib\controllers\http_status_manger\http_status_manger.dart + Future getAssistantEmployees() async { + if (_loading == true) return -2; + _loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get( + "${URLs.getEngineers}", + ); + // response = await get( + // Uri.parse( + // URLs.getServiceReportLastCalls + // +(serviceStatus == null ? "" : "?service_status=$serviceStatus") + // ), + // ); + _stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List usersListJson = json.decode(response.body); + _assistantEmployees = []; + _assistantEmployees = usersListJson.map((type) => AssistantEmployees.fromJson(type ?? {})).toList(); + } + _loading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + _loading = false; + _stateCode = -1; + notifyListeners(); + return -1; + } + } +} 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 8946bd0..bc47dfb 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 @@ -55,7 +55,7 @@ class ServiceRequestFaultDescriptionProvider extends ChangeNotifier { if (response.statusCode >= 200 && response.statusCode < 300) { // client's request was successfully received List listJson = json.decode(response.body)["data"]['asset']['modelDefinition']['modelDefRelatedDefects']; - _items = listJson.map((type) => FaultDescription.fromJson(type)).toList(); + _items = listJson?.map((type) => FaultDescription.fromJson(type))?.toList() ?? []; } _loading = false; notifyListeners(); diff --git a/lib/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart b/lib/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart index a6f39ab..3e4741b 100644 --- a/lib/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart +++ b/lib/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart @@ -57,7 +57,7 @@ class ServiceReportLastCallsProvider extends ChangeNotifier { try { // todo request new api from backend to make filter work response = await ApiManager.instance.get( - "${URLs.getServiceReportLastCalls}?parentWOId=$woId&isAdd=true&id=${id ?? 0}&typeTransaction=$typeName", + "${URLs.getServiceReportLastCalls}?parentWOId=${woId??id}&isAdd=true&id=${id ?? 0}&typeTransaction=$typeName", ); // response = await get( // Uri.parse( diff --git a/lib/controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart b/lib/controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart new file mode 100644 index 0000000..1872058 --- /dev/null +++ b/lib/controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart @@ -0,0 +1,75 @@ +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/lookup.dart'; + +class ServiceReportMaintenanceSituationProvider extends ChangeNotifier { + //reset provider data + void reset() { + _calls = null; + _loading = null; + _stateCode = null; + } + + // state code of current request to defied error message + // like 400 customer request failed + // 500 service not available + int _stateCode; + int get stateCode => _stateCode; + + // contain user data + // when user not login or register _user = null + List _calls; + List get operators => _calls; + + // when categories in-process _loading = true + // done _loading = true + // failed _loading = false + bool _loading; + bool get isLoading => _loading; + set isLoading(bool isLoading) { + _loading = isLoading; + notifyListeners(); + } + + /// return -2 if request in progress + /// return -1 if error happen when sending request + /// return state code if request complete may be 200, 404 or 403 + /// for more details check http state manager + /// lib\controllers\http_status_manger\http_status_manger.dart + Future getOperators(String woId) async { + if (_loading == true) return -2; + _loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get( + woId == null ? "${URLs.getMaintenanceSituation}" : "${URLs.getServiceReportLastCalls}?parentWOId=$woId&isAdd=true&id=${0}&typeTransaction='Nothing'", + ); + // response = await get( + // Uri.parse( + // URLs.getServiceReportLastCalls + // +(serviceStatus == null ? "" : "?service_status=$serviceStatus") + // ), + // ); + _stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List categoriesListJson = json.decode(response.body)["data"]; + _calls = categoriesListJson.map((type) => Lookup.fromJson(type)).toList(); + } + _loading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + _loading = false; + _stateCode = -1; + notifyListeners(); + return -1; + } + } +} diff --git a/lib/controllers/providers/api/status_drop_down/report/service_report_users_provider.dart b/lib/controllers/providers/api/status_drop_down/report/service_report_users_provider.dart new file mode 100644 index 0000000..6fcd5f8 --- /dev/null +++ b/lib/controllers/providers/api/status_drop_down/report/service_report_users_provider.dart @@ -0,0 +1,75 @@ +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/engineer.dart'; + +class ServiceReportUsersProvider extends ChangeNotifier { + //reset provider data + void reset() { + _engineers = null; + _loading = null; + _stateCode = null; + } + + // state code of current request to defied error message + // like 400 customer request failed + // 500 service not available + int _stateCode; + int get stateCode => _stateCode; + + // contain user data + // when user not login or register _user = null + List _engineers; + List get engineers => _engineers; + + // when categories in-process _loading = true + // done _loading = true + // failed _loading = false + bool _loading; + bool get isLoading => _loading; + set isLoading(bool isLoading) { + _loading = isLoading; + notifyListeners(); + } + + /// return -2 if request in progress + /// return -1 if error happen when sending request + /// return state code if request complete may be 200, 404 or 403 + /// for more details check http state manager + /// lib\controllers\http_status_manger\http_status_manger.dart + Future getAllUsers() async { + if (_loading == true) return -2; + _loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get( + "${URLs.getAllUsers}", + ); + // response = await get( + // Uri.parse( + // URLs.getServiceReportLastCalls + // +(serviceStatus == null ? "" : "?service_status=$serviceStatus") + // ), + // ); + _stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List usersListJson = json.decode(response.body); + _engineers = usersListJson.map((type) => Engineer.fromJson(type)).toList(); + } + _loading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + _loading = false; + _stateCode = -1; + notifyListeners(); + return -1; + } + } +} diff --git a/lib/controllers/providers/api/status_drop_down/report/service_report_visit_date_operator_provider.dart b/lib/controllers/providers/api/status_drop_down/report/service_report_visit_date_operator_provider.dart new file mode 100644 index 0000000..dc8d785 --- /dev/null +++ b/lib/controllers/providers/api/status_drop_down/report/service_report_visit_date_operator_provider.dart @@ -0,0 +1,75 @@ +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/lookup.dart'; + +class ServiceReportVisitOperatorProvider extends ChangeNotifier { + //reset provider data + void reset() { + _calls = null; + _loading = null; + _stateCode = null; + } + + // state code of current request to defied error message + // like 400 customer request failed + // 500 service not available + int _stateCode; + int get stateCode => _stateCode; + + // contain user data + // when user not login or register _user = null + List _calls; + List get operators => _calls; + + // when categories in-process _loading = true + // done _loading = true + // failed _loading = false + bool _loading; + bool get isLoading => _loading; + set isLoading(bool isLoading) { + _loading = isLoading; + notifyListeners(); + } + + /// return -2 if request in progress + /// return -1 if error happen when sending request + /// return state code if request complete may be 200, 404 or 403 + /// for more details check http state manager + /// lib\controllers\http_status_manger\http_status_manger.dart + Future getOperators() async { + if (_loading == true) return -2; + _loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get( + "${URLs.getDateOperators}", + ); + // response = await get( + // Uri.parse( + // URLs.getServiceReportLastCalls + // +(serviceStatus == null ? "" : "?service_status=$serviceStatus") + // ), + // ); + _stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List categoriesListJson = json.decode(response.body)["data"]; + _calls = categoriesListJson.map((type) => Lookup.fromJson(type)).toList(); + } + _loading = false; + notifyListeners(); + return response.statusCode; + } catch (error) { + _loading = false; + _stateCode = -1; + notifyListeners(); + return -1; + } + } +} diff --git a/lib/main.dart b/lib/main.dart index 3d85f35..466e052 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -23,7 +23,10 @@ import 'package:test_sa/controllers/providers/api/status_drop_down/pentry/pentry import 'package:test_sa/controllers/providers/api/status_drop_down/pentry/pentry_visit_status_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_defect_types_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_equipment_status_provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_priority_provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_users_provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_visit_date_operator_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/service_reqest/service_request_first_action_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/service_reqest/service_request_loan_availability_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/service_reqest/service_request_status_provider.dart'; @@ -33,6 +36,8 @@ import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/pages/login.dart'; import 'package:test_sa/views/pages/register.dart'; import 'package:test_sa/views/pages/splash_screen.dart'; +import 'package:test_sa/views/pages/sub_workorder/create_sub_workorder_page.dart'; +import 'package:test_sa/views/pages/sub_workorder/search_sub_workorder_page.dart'; import 'package:test_sa/views/pages/user/gas_refill/request_gas_refill.dart'; import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart'; import 'package:test_sa/views/pages/user/land_page.dart'; @@ -50,6 +55,7 @@ import 'package:test_sa/views/widgets/equipment/single_device_picker.dart'; import 'controllers/providers/api/parts_provider.dart'; import 'controllers/providers/api/preventive_maintenance_visits_provider.dart'; import 'controllers/providers/api/status_drop_down/pentry/pentry_status_provider.dart'; +import 'controllers/providers/api/status_drop_down/report/service_report_assistants_employee_provider.dart'; import 'controllers/providers/api/status_drop_down/report/service_report_fault_description_provider.dart'; import 'controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart'; import 'controllers/providers/api/status_drop_down/report/service_report_reasons_provider.dart'; @@ -121,6 +127,10 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider(create: (_) => ServiceFirstActionProvider()), ChangeNotifierProvider(create: (_) => ServiceReportRepairLocationProvider()), ChangeNotifierProvider(create: (_) => ServiceRequestFaultDescriptionProvider()), + ChangeNotifierProvider(create: (_) => ServiceReportVisitOperatorProvider()), + ChangeNotifierProvider(create: (_) => ServiceReportMaintenanceSituationProvider()), + ChangeNotifierProvider(create: (_) => ServiceReportUsersProvider()), + ChangeNotifierProvider(create: (_) => ServiceReportAssistantsEmployeeProvider()), ], child: GestureDetector( onTap: () { @@ -172,6 +182,8 @@ class MyApp extends StatelessWidget { TrackGasRefillPage.id: (_) => const TrackGasRefillPage(), RequestDeviceTransfer.id: (_) => const RequestDeviceTransfer(), TrackDeviceTransferPage.id: (_) => const TrackDeviceTransferPage(), + SearchSubWorkOrderPage.id: (_) => const SearchSubWorkOrderPage(), + CreateSubWorkOrderPage.id: (_) => const CreateSubWorkOrderPage(), }, ), ), diff --git a/lib/models/call_request_for_work_order_model.dart b/lib/models/call_request_for_work_order_model.dart index dd0ac5a..188edce 100644 --- a/lib/models/call_request_for_work_order_model.dart +++ b/lib/models/call_request_for_work_order_model.dart @@ -82,7 +82,7 @@ class Asset { Department department; String room; String testsDay; - String purchasingPrice; + num purchasingPrice; String nbv; String currency; String poNo; @@ -328,7 +328,7 @@ class ModelDefinition { if (json['suppliers'] != null) { suppliers = []; json['suppliers'].forEach((v) { - // suppliers!.add(new Null.fromJson(v)); + // suppliers!.add(new Null.fromJson(v)); }); } } @@ -394,7 +394,7 @@ class Site { if (json['buildings'] != null) { buildings = []; json['buildings'].forEach((v) { - // buildings!.add(new Null.fromJson(v)); + // buildings!.add(new Null.fromJson(v)); }); } } @@ -427,11 +427,11 @@ class Department { } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['departmentName'] = this.departmentName; - data['departmentCode'] = this.departmentCode; - data['ntCode'] = this.ntCode; + final Map data = {}; + data['id'] = id; + data['departmentName'] = departmentName; + data['departmentCode'] = departmentCode; + data['ntCode'] = ntCode; return data; } } @@ -520,7 +520,7 @@ class Building { int value; var floor; - Building({this.id, this.name, this.value,this.floor}); + Building({this.id, this.name, this.value, this.floor}); Building.fromJson(Map json) { id = json['id']; @@ -538,4 +538,3 @@ class Building { return data; } } - diff --git a/lib/models/customer.dart b/lib/models/customer.dart index d075eff..5b0e1d8 100644 --- a/lib/models/customer.dart +++ b/lib/models/customer.dart @@ -46,7 +46,7 @@ class Data { customerCode = json['customerCode']; custName = json['custName']; if (json['buildings'] != null) { - buildings = new List(); + buildings = []; json['buildings'].forEach((v) { buildings.add(new Buildings.fromJson(v)); }); @@ -78,7 +78,7 @@ class Buildings { name = json['name']; value = json['value']; if (json['floors'] != null) { - floors = new List(); + floors = []; json['floors'].forEach((v) { floors.add(new Floors.fromJson(v)); }); @@ -110,7 +110,7 @@ class Floors { name = json['name']; value = json['value']; if (json['departments'] != null) { - departments = new List(); + departments = []; json['departments'].forEach((v) { departments.add(new Departments.fromJson(v)); }); diff --git a/lib/models/device/device_transfer.dart b/lib/models/device/device_transfer.dart index a8202f4..c585a8c 100644 --- a/lib/models/device/device_transfer.dart +++ b/lib/models/device/device_transfer.dart @@ -5,6 +5,8 @@ import 'package:test_sa/models/device/device_transfer_info.dart'; import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/lookup.dart'; +import '../timer_model.dart'; + class DeviceTransfer { int id; String userId; @@ -46,21 +48,26 @@ class DeviceTransfer { title: parsedJson["transferCode"], userId: parsedJson["uid"], device: Device( - id: parsedJson["assetId"], - number: parsedJson["assetNumber"], - serialNumber: parsedJson["assetSerialNo"], - destBuildingName: parsedJson["destBuildingName"], - destDepartmentName: parsedJson["destDepartmentName"], - destFloor: parsedJson["destFloor"], - destRoom: parsedJson["destRoom"], - destSiteName: parsedJson["destSiteName"] - ), + id: parsedJson["assetId"], + number: parsedJson["assetNumber"], + serialNumber: parsedJson["assetSerialNo"], + destBuildingName: parsedJson["destBuildingName"], + destDepartmentName: parsedJson["destDepartmentName"], + destFloor: parsedJson["destFloor"], + destRoom: parsedJson["destRoom"], + destSiteName: parsedJson["destSiteName"]), sender: DeviceTransferInfo( travelingHours: parsedJson["senderTravelingHours"], comment: parsedJson["senderComment"], workingHours: parsedJson["senderWorkingHours"], - startDate: parsedJson["senderStartDate"]==null ? null:DateTime.parse(parsedJson["senderStartDate"]), - endDate: parsedJson["senderEndDate"]==null ? null:DateTime.parse(parsedJson["senderEndDate"]), + timer: TimerModel( + startAt: DateTime.tryParse(parsedJson["senderStartDate"] ?? ""), + endAt: DateTime.tryParse(parsedJson["senderEndDate"] ?? ""), + durationInSecond: ((parsedJson["workingHours"] ?? 0) * 60 * 60).toInt(), + stopped: parsedJson["workingHours"] == null ? null : true, + ), + // startDate: parsedJson["senderStartDate"] == null ? null : DateTime.parse(parsedJson["senderStartDate"]), + // endDate: parsedJson["senderEndDate"] == null ? null : DateTime.parse(parsedJson["senderEndDate"]), userId: parsedJson["senderAssignedEmployeeId"], userName: parsedJson["senderAssignedEmployeeName"], assignedEmployeeName: parsedJson["senderAssignedEmployeeName"], @@ -80,8 +87,11 @@ class DeviceTransfer { travelingHours: parsedJson["receiverTravelingHours"], comment: parsedJson["receiverComment"], workingHours: parsedJson["receiverWorkingHours"], - startDate: parsedJson["receiverStartDate"]==null ? null:DateTime.parse(parsedJson["receiverStartDate"]), - endDate: parsedJson["receiverEndDate"]==null ? null:DateTime.parse(parsedJson["receiverEndDate"]), + timer: parsedJson["receiverStartDate"] != null || parsedJson["receiverEndDate"] != null + ? TimerModel(startAt: DateTime.tryParse(parsedJson["receiverStartDate"] ?? ""), endAt: DateTime.tryParse(parsedJson["receiverEndDate"] ?? "")) + : null, + // startDate: parsedJson["receiverStartDate"] == null ? null : DateTime.parse(parsedJson["receiverStartDate"]), + // endDate: parsedJson["receiverEndDate"] == null ? null : DateTime.parse(parsedJson["receiverEndDate"]), userId: parsedJson["receiverAssignedEmployeeId"], userName: parsedJson["receiverAssignedEmployeeName"], assignedEmployeeName: parsedJson["receiverAssignedEmployeeName"], diff --git a/lib/models/device/device_transfer_info.dart b/lib/models/device/device_transfer_info.dart index 41d0843..00e1d38 100644 --- a/lib/models/device/device_transfer_info.dart +++ b/lib/models/device/device_transfer_info.dart @@ -2,19 +2,22 @@ import 'package:test_sa/models/department.dart'; import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/lookup.dart'; +import '../timer_model.dart'; + class DeviceTransferInfo { String userId; String comment; Hospital client; Department department; String workingHours; - DateTime startDate; - DateTime endDate; + // DateTime startDate; + // DateTime endDate; String travelingHours; String userName; String signature; String assignedEmployeeName; Lookup status; + TimerModel timer; DeviceTransferInfo({ this.userId, @@ -23,12 +26,13 @@ class DeviceTransferInfo { this.client, this.userName, this.travelingHours, - this.startDate, - this.endDate, + // this.startDate, + // this.endDate, this.workingHours, this.signature, this.status, - this.assignedEmployeeName + this.assignedEmployeeName, + this.timer, }); Map toJson(bool isSender) { @@ -37,8 +41,10 @@ class DeviceTransferInfo { if (comment != null && comment.isNotEmpty) body["${baseKey}comment"] = comment; if (workingHours != null && workingHours.isNotEmpty) body["${baseKey}working_hours"] = workingHours; - if (startDate != null) body["${baseKey}start_date"] = startDate?.toIso8601String(); - if (endDate != null) body["${baseKey}end_date"] = endDate?.toIso8601String(); + // if (startDate != null) body["${baseKey}start_date"] = startDate?.toIso8601String(); + // if (endDate != null) body["${baseKey}end_date"] = endDate?.toIso8601String(); + if (timer?.startAt != null) body["${baseKey}start_date"] = timer?.startAt?.toIso8601String(); + if (timer?.endAt != null) body["${baseKey}end_date"] = timer?.endAt?.toIso8601String(); if (travelingHours != null && travelingHours.isNotEmpty) body["${baseKey}travel_hours"] = travelingHours; if (status != null) body["${baseKey}status"] = status.id.toString(); if (signature != null && signature.isNotEmpty) body["${baseKey}image"] = signature; @@ -57,8 +63,9 @@ class DeviceTransferInfo { client = Hospital.fromHospital(old.client); department = Department.fromDepartment(old.department); workingHours = old.workingHours; - startDate = old.startDate; - endDate = old.endDate; + // startDate = old.startDate; + // endDate = old.endDate; + timer = old.timer; travelingHours = old.travelingHours; comment = old.comment; if (withSignature) signature = old.signature; @@ -68,14 +75,20 @@ class DeviceTransferInfo { factory DeviceTransferInfo.fromJson(Map parsedJson, String key) { return DeviceTransferInfo( workingHours: parsedJson["${key}working_hours"], - startDate: parsedJson["${key}start_date"], - endDate: parsedJson["${key}end_date"], + // startDate: parsedJson["${key}start_date"], + // endDate: parsedJson["${key}end_date"], + timer: TimerModel( + startAt: DateTime.tryParse(parsedJson["${key}start_date"] ?? ""), + endAt: DateTime.tryParse(parsedJson["${key}end_date"] ?? ""), + durationInSecond: ((parsedJson["${key}working_hours"] ?? 0) * 60 * 60).toInt(), + stopped: parsedJson["${key}working_hours"] == null || (parsedJson["${key}working_hours"] as String).isEmpty ? null : true, + ), travelingHours: parsedJson["${key}travel_hours"], userName: parsedJson["${key}name"], signature: parsedJson["${key}image"], userId: parsedJson["${key}id"], comment: parsedJson["${key}comment"], - assignedEmployeeName:parsedJson["${key}AssignedEmployeeName"], + assignedEmployeeName: parsedJson["${key}AssignedEmployeeName"], client: Hospital(id: parsedJson["${key}SiteId"], name: parsedJson["${key}SiteName"]), department: Department( id: parsedJson["${key}DepartmentId"], diff --git a/lib/models/gas_refill/gas_refill_details.dart b/lib/models/gas_refill/gas_refill_details.dart index 02d31cf..0c9afe0 100644 --- a/lib/models/gas_refill/gas_refill_details.dart +++ b/lib/models/gas_refill/gas_refill_details.dart @@ -6,6 +6,7 @@ class GasRefillDetails { Lookup cylinderType; double requestedQuantity; double deliveredQuantity; + bool selectedForEditing; GasRefillDetails({ this.type, @@ -13,6 +14,7 @@ class GasRefillDetails { this.cylinderType, this.requestedQuantity, this.deliveredQuantity, + this.selectedForEditing, }); bool validate() { diff --git a/lib/models/gas_refill/gas_refill_model.dart b/lib/models/gas_refill/gas_refill_model.dart index f15dd4b..291ee5a 100644 --- a/lib/models/gas_refill/gas_refill_model.dart +++ b/lib/models/gas_refill/gas_refill_model.dart @@ -1,6 +1,11 @@ +import 'dart:typed_data'; + import 'package:test_sa/models/gas_refill/gas_refill_details.dart'; import 'package:test_sa/models/lookup.dart'; +import '../../controllers/api_routes/urls.dart'; +import '../call_request_for_work_order_model.dart'; + class GasRefillModel { int id; //String userId; @@ -9,8 +14,15 @@ class GasRefillModel { Lookup status; Lookup building; Lookup floor; + Department department; List details; + AssignedEmployee assignedEmployee; + String signatureNurse; + String signatureEngineer; + Uint8List localNurseSignature; + Uint8List localEngineerSignature; + DateTime startDate, endDate, expectedDate; GasRefillModel({ this.id, //this.userId, @@ -18,13 +30,27 @@ class GasRefillModel { this.title, this.status, this.details, + this.building, + this.floor, + this.startDate, + this.endDate, + this.expectedDate, + this.department, + this.assignedEmployee, + this.signatureNurse, + this.signatureEngineer, + this.localEngineerSignature, + this.localNurseSignature, }); bool validate() { if (title == null) return false; if (status == null) return false; - if (building == null) return false; - if (floor == null) return false; + // if (building == null) return false; + // if (floor == null) return false; + // if (department == null) return false; + // if (startDate == null) return false; + // if (endDate == null) return false; if (details == null && details.isEmpty) return false; return true; } @@ -36,6 +62,17 @@ class GasRefillModel { title = model.title; status = Lookup.fromStatus(model.status); details = model.details.map((e) => GasRefillDetails.fromDetails(e)).toList(); + building = model.building; + floor = model.floor; + department = model.department; + startDate = model.startDate; + endDate = model.endDate; + expectedDate = model.expectedDate; + assignedEmployee = model.assignedEmployee; + localEngineerSignature = model.localEngineerSignature; + localNurseSignature = model.localNurseSignature; + signatureEngineer = model.signatureEngineer; + signatureNurse = model.signatureNurse; } factory GasRefillModel.fromJson(Map parsedJson) { @@ -49,8 +86,17 @@ class GasRefillModel { //userId: parsedJson["uid"], title: parsedJson["gazRefillNo"], clientName: parsedJson["site"] == null ? null : parsedJson["site"]["custName"], - status: Lookup.fromJson(parsedJson["status"]), + status: Lookup.fromJson(parsedJson["status"] ?? {}), details: details, + building: Lookup.fromJson(parsedJson["building"] ?? {}), + floor: Lookup.fromJson(parsedJson["floor"] ?? {}), + department: Department.fromJson(parsedJson["department"] ?? {}), + startDate: DateTime.tryParse(parsedJson['startDate'] ?? ""), + endDate: DateTime.tryParse(parsedJson['endDate'] ?? ""), + expectedDate: DateTime.tryParse(parsedJson['expectedDate'] ?? ""), + assignedEmployee: AssignedEmployee.fromJson(parsedJson['assignedEmployee'] ?? {}), + signatureEngineer: URLs.getFileUrl(parsedJson["engSignature"]), + signatureNurse: URLs.getFileUrl(parsedJson["nurseSignature"]), ); } } diff --git a/lib/models/hospital.dart b/lib/models/hospital.dart index d9c5cd3..e0bf950 100644 --- a/lib/models/hospital.dart +++ b/lib/models/hospital.dart @@ -17,7 +17,7 @@ class Hospital { if (parsedJson['buildings'] != null) { buildings = []; parsedJson['buildings'].forEach((v) { - buildings.add(new Buildings.fromJson(v)); + buildings.add(Buildings.fromJson(v)); }); } @@ -78,20 +78,20 @@ class Buildings { name = json['name']; value = json['value']; if (json['floors'] != null) { - floors = new List(); + floors = []; json['floors'].forEach((v) { - floors.add(new Floors.fromJson(v)); + floors.add(Floors.fromJson(v)); }); } } - Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['name'] = this.name; - data['value'] = this.value; - if (this.floors != null) { - data['floors'] = this.floors.map((v) => v.toJson()).toList(); + Map toJson({bool includeFloors = true}) { + final Map data = {}; + data['id'] = id; + data['name'] = name; + data['value'] = value; + if (floors != null && includeFloors) { + data['floors'] = floors.map((v) => v.toJson()).toList(); } return data; } @@ -110,20 +110,20 @@ class Floors { name = json['name']; value = json['value']; if (json['departments'] != null) { - departments = new List(); + departments = []; json['departments'].forEach((v) { - departments.add(new Departments.fromJson(v)); + departments.add(Departments.fromJson(v)); }); } } - Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['name'] = this.name; - data['value'] = this.value; - if (this.departments != null) { - data['departments'] = this.departments.map((v) => v.toJson()).toList(); + Map toJson({bool includeDepartments = true}) { + final Map data = {}; + data['id'] = id; + data['name'] = name; + data['value'] = value; + if (departments != null && includeDepartments) { + data['departments'] = departments.map((v) => v.toJson()).toList(); } return data; } @@ -141,9 +141,9 @@ class Departments { } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['name'] = this.name; + final Map data = {}; + data['id'] = id; + data['name'] = name; return data; } } diff --git a/lib/models/pantry/pentry.dart b/lib/models/pantry/pentry.dart index 82ef9fd..40a9034 100644 --- a/lib/models/pantry/pentry.dart +++ b/lib/models/pantry/pentry.dart @@ -58,7 +58,7 @@ class Pentry { Map toMap(int visitId) { Map map = {}; map["visitStatusId"] = ppmVisitStatus?.id.toString(); - //if(status != null) map["visitStatusId"] = status?.id.toString(); + if (status != null) map["deviceStatusId"] = status?.id.toString(); if (travelingHours != null) map["travelingHours"] = travelingHours; //if(imageFile != null) map["file_attachement"] = base64Encode(imageFile.readAsBytesSync()); map["actualDate"] = actualVisitDate.toIso8601String(); @@ -73,7 +73,7 @@ class Pentry { {"attachmentName": (imageFile.path.split("/").last + base64Encode(imageFile.readAsBytesSync()))} ]; } - + map["travelingHours"] = travelingHours; // if(contacts?.isNotEmpty == true) { // for(int i = 0;i toMap(ServiceRequest request) { Map _map = {}; if (id != null) _map["id"] = id; if (visitDate != null) _map["visitDate"] = visitDate.toIso8601String(); //if(serviceType != null) _map["service_type"] = serviceType.id.toString(); - if (equipmentStatus != null) _map["status"] = equipmentStatus?.toMap(); + if (equipmentStatus != null) _map["equipmentStatus"] = equipmentStatus?.toMap(); if (type != null) _map["typeOfWO"] = type?.toMap(); if (assetType != null) _map["TypeOfWO"] = assetType?.toMap(); //if(faultDescriptionId != null && faultDescriptionId.isNotEmpty) _map["fault_description"] = faultDescriptionId; @@ -93,17 +97,19 @@ class ServiceReport { _map["endofWorkTime"] = (timer.endAt ?? DateTime.now()).toIso8601String(); _map["workingHours"] = (timer.durationInSecond / 60 / 60).toStringAsFixed(5); } - if (travelingHours != null && travelingHours.toString().isNotEmpty) _map["traveling_hours"] = travelingHours; + if (travelingHours != null && travelingHours.toString().isNotEmpty) _map["travelingHours"] = travelingHours; // if(workPreformed != null && workPreformed.isNotEmpty){ // _map["faultDescription"] = { - // //"id":faultDescriptionId ?? 0, + // "id":faultDescriptionId ?? 0, // "workPerformed":workPreformed // }; // } - if (travelingHours != null) _map["traveling_hours"] = travelingHours; - if (workPreformed != null && workPreformed.isNotEmpty) { - _map["faultDescription"] = faultDescription.toJson(); - } + _map["faultDescription"] = {"id": faultDescription?.id ?? 0, "workPerformed": faultDescription?.workPerformed}; + if (travelingHours != null) _map["travelingHours"] = travelingHours; + // if (workingHours != null) _map["workingHours"] = workingHours; + // if (workPreformed != null && workPreformed.isNotEmpty) { + // _map["faultDescription"] = faultDescription.toJson(); + // } if (jobSheetNumber != null && jobSheetNumber.isNotEmpty) _map["job_sheet_no"] = jobSheetNumber; if (parts != null && parts.isNotEmpty) { _map["sparePartsWorkOrders"] = parts.map((e) => e.toJson()).toList(); @@ -122,6 +128,7 @@ class ServiceReport { if (reason != null) _map["reason"] = reason.toMap(); //if(operatingHours != null && operatingHours.isNotEmpty) _map["operation_hours"] = operatingHours; if (callLastSituation != null) _map["calllastSituation"] = callLastSituation.toMap(); + if (currentSituation != null) _map["currentSituation"] = currentSituation.toMap(); //if(image != null) _map["image"] = image; //if(invoiceCode != null) _map["invoice_no"] = invoiceCode; //if(invoiceNumber != null) _map["invoice_code"] = invoiceNumber; @@ -133,16 +140,27 @@ class ServiceReport { _map["nurseSignature"] = signatureNurse; _map["engSignature"] = signatureEngineer; _map["comment"] = comment; - _map["travelingExpense"] = travelingExpense; - _map["startofWorkTime"] = startDate; - _map["endofWorkTime"] = endDate; - _map["workingHours"] = endDate?.difference(startDate)?.inHours ?? 0; + _map["travelingExpenses"] = travelingExpense; + // _map["startofWorkTime"] = startDate.toIso8601String(); + // _map["endofWorkTime"] = endDate.toIso8601String(); + // _map["workingHours"] = endDate?.difference(startDate)?.inHours ?? 0; + if (timer?.startAt != null) _map["startofWorkTime"] = timer?.startAt?.toIso8601String(); + if (timer?.endAt != null) _map["endofWorkTime"] = timer?.endAt?.toIso8601String(); + _map["workingHours"] = workingHours; _map["reviewComment"] = reviewComment; return _map; } - bool validate() { - if (visitDate == null) return false; + Future validate() async { + print("visitDate:$visitDate"); + print("equipmentStatus:${equipmentStatus?.toMap()}"); + print("callLastSituation:${callLastSituation?.toMap()}"); + print("parts:$parts"); + print("reason:${reason?.toMap()}"); + if (visitDate == null) { + await Fluttertoast.showToast(msg: "Visit Date Required"); + return false; + } //if(serviceType == null) return false; if (equipmentStatus == null) return false; //if (type == null && assetType == null) return false; @@ -174,27 +192,38 @@ class ServiceReport { id: id, assetType: Lookup.fromJson(parsedJson["assetType"]), callLastSituation: Lookup.fromJson(parsedJson["calllastSituation"]), + currentSituation: Lookup.fromJson(parsedJson["currentSituation"]), + repairLocation: Lookup.fromJson(parsedJson["repairLocation"]), reason: Lookup.fromJson(parsedJson["reason"]), - equipmentStatus: Lookup.fromJson(parsedJson["status"]), + equipmentStatus: Lookup.fromJson(parsedJson["equipmentStatus"]), type: Lookup.fromJson(parsedJson["typeOfWO"]), - faultDescriptionId: parsedJson["fault_description"], - endDate: DateTime.tryParse(parsedJson["endofWorkTime"]), + faultDescription: parsedJson['faultDescription'] != null ? FaultDescription.fromJson(parsedJson['faultDescription']) : null, + + // faultDescription: parsedJson["faultDescription"], + // startDate: DateTime.tryParse(parsedJson["startofWorkTime"] ?? ""), + // endDate: DateTime.tryParse(parsedJson["endofWorkTime"] ?? ""), //invoiceCode: parsedJson["invoice_code"], //invoiceNumber: parsedJson["invoice_no"], //jobSheetNumber: parsedJson["job_sheet_no"], - operatingHours: parsedJson["workingHours"], + // workingHours: parsedJson["workingHours"], engineer: Engineer.fromJson(parsedJson["assignedEmployee"]), parts: _parts, //quantity: parsedJson["nid"], - travelingHours: parsedJson["traveling_hours"], + travelingHours: parsedJson["travelingHours"], + travelingExpense: parsedJson["travelingExpenses"], visitDate: DateTime.tryParse(parsedJson["visitDate"]), - //workHours: parsedJson["working_hours"], + workingHours: parsedJson["workingHours"], timer: TimerModel( - startAt: DateTime.tryParse(parsedJson["startofWorkTime"]), endAt: DateTime.tryParse(parsedJson["endofWorkTime"]), durationInSecond: ((parsedJson["workingHours"] ?? 0) * 60 * 60).toInt()), + startAt: DateTime.tryParse(parsedJson["startofWorkTime"] ?? ""), + endAt: DateTime.tryParse(parsedJson["endofWorkTime"] ?? ""), + durationInSecond: ((parsedJson["workingHours"] ?? 0) * 60 * 60).toInt(), + stopped: parsedJson["workingHours"] == null ? null : true, + ), //workPreformed: parsedJson["work_performed"], device: Device.fromJson(parsedJson["callRequest"]["asset"]), signatureNurse: URLs.getFileUrl(parsedJson["nurseSignature"]), signatureEngineer: URLs.getFileUrl(parsedJson["engSignature"]), + comment: parsedJson['comment'], reviewComment: parsedJson['reviewComment'], ); } diff --git a/lib/models/service_request/search_work_order.dart b/lib/models/service_request/search_work_order.dart index 713e912..898fa0e 100644 --- a/lib/models/service_request/search_work_order.dart +++ b/lib/models/service_request/search_work_order.dart @@ -1,548 +1,2789 @@ import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/models/timer_model.dart'; -class SearchWorkOrders { - int id; - String parentWOId; - String workOrderNo; - int workOrderYear; - int workOrderSequennce; - CallRequest callRequest; - String assetType; - AssignedEmployee assignedEmployee; - String visitDate; - List assistantEmployees; - String supplier; - String vendorTicketNumber; - List contactPersonWorkOrders; - Lookup calllastSituation; - Lookup currentSituation; - String repairLocation; - String reason; - String startofWorkTime; - String endofWorkTime; - double workingHours; - num travelingHours; - num travelingExpenses; - ModelDefRelatedDefects faultDescription; - List sparePartsWorkOrders; - String reviewComment; - String comment; - String attachmentsWorkOrder; - String equipmentStatus; - List suppEngineerWorkOrders; - String engSignature; - String nurseSignature; - String woParentDto; - - SearchWorkOrders( - {this.id, - this.parentWOId, - this.workOrderNo, - this.workOrderYear, - this.workOrderSequennce, - this.callRequest, - this.assetType, - this.assignedEmployee, - this.visitDate, - this.assistantEmployees, - this.supplier, - this.vendorTicketNumber, - this.contactPersonWorkOrders, - this.calllastSituation, - this.currentSituation, - this.repairLocation, - this.reason, - this.startofWorkTime, - this.endofWorkTime, - this.workingHours, - this.travelingHours, - this.travelingExpenses, - this.faultDescription, - this.sparePartsWorkOrders, - this.reviewComment, - this.comment, - this.attachmentsWorkOrder, - this.equipmentStatus, - this.suppEngineerWorkOrders, - this.engSignature, - this.nurseSignature, - this.woParentDto}); - - SearchWorkOrders.fromJson(Map json) { - print(json['callRequest']); +import '../fault_description.dart'; + +class SearchWorkOrder { + SearchWorkOrder({ + this.id, + this.parentWOId, + this.workOrderNo, + this.workOrderYear, + this.workOrderSequennce, + this.callRequest, + this.assetType, + this.assignedEmployee, + this.visitDate, + this.assistantEmployees, + this.supplier, + this.vendorTicketNumber, + this.contactPersonWorkOrders, + this.calllastSituation, + this.currentSituation, + this.repairLocation, + this.reason, + // this.startofWorkTime, + // this.endofWorkTime, + this.workingHours, + this.travelingHours, + this.travelingExpenses, + this.faultDescription, + this.sparePartsWorkOrders, + this.reviewComment, + this.comment, + this.attachmentsWorkOrder, + this.equipmentStatus, + this.suppEngineerWorkOrders, + this.engSignature, + this.nurseSignature, + this.woParentDto, + this.timer, + }); + + SearchWorkOrder.fromJson(dynamic json) { id = json['id']; parentWOId = json['parentWOId']; workOrderNo = json['workOrderNo']; workOrderYear = json['workOrderYear']; workOrderSequennce = json['workOrderSequennce']; - callRequest = json['callRequest'] != null ? new CallRequest.fromJson(json['callRequest']) : CallRequest(); - assetType = json['assetType']; - assignedEmployee = json['assignedEmployee'] != null ? new AssignedEmployee.fromJson(json['assignedEmployee']) : AssignedEmployee(); + callRequest = json['callRequest'] != null ? CallRequest.fromJson(json['callRequest']) : null; + assetType = json['assetType'] != null ? Lookup.fromJson(json['assetType']) : null; + assignedEmployee = json['assignedEmployee'] != null ? AssignedEmployee.fromJson(json['assignedEmployee']) : null; visitDate = json['visitDate']; if (json['assistantEmployees'] != null) { - assistantEmployees = json['assistantEmployees']; + assistantEmployees = []; + json['assistantEmployees'].forEach((v) { + assistantEmployees.add(AssistantEmployees.fromJson(v)); + }); } - supplier = json['supplier']; + supplier = json['supplier'] != null ? SupplierModel.fromJson(json['supplier']) : null; vendorTicketNumber = json['vendorTicketNumber']; if (json['contactPersonWorkOrders'] != null) { - contactPersonWorkOrders = json['contactPersonWorkOrders']; - } - calllastSituation = json['calllastSituation'] != null ? new Lookup.fromJson(json['calllastSituation']) : Lookup(); - currentSituation = json['currentSituation'] != null ? new Lookup.fromJson(json['currentSituation']) : Lookup(); - repairLocation = json['repairLocation']; - reason = json['reason']; - startofWorkTime = json['startofWorkTime']; - endofWorkTime = json['endofWorkTime']; + contactPersonWorkOrders = []; + json['contactPersonWorkOrders'].forEach((v) { + contactPersonWorkOrders.add(ContactPersonWorkOrders.fromJson(v)); + }); + } + calllastSituation = json['calllastSituation'] != null ? Lookup.fromJson(json['calllastSituation']) : null; + currentSituation = json['currentSituation'] != null ? Lookup.fromJson(json['currentSituation']) : null; + repairLocation = json['repairLocation'] != null ? Lookup.fromJson(json['repairLocation']) : null; + reason = json['reason'] != null ? Lookup.fromJson(json['reason']) : null; + // startofWorkTime = json['startofWorkTime']; + // endofWorkTime = json['endofWorkTime']; + if (json['startofWorkTime'] != null || json['endofWorkTime'] != null) { + timer = TimerModel(); + } + if (json['startofWorkTime'] != null) timer.startAt = DateTime.tryParse(json['startofWorkTime']); + if (json['endofWorkTime'] != null) timer.endAt = DateTime.tryParse(json['endofWorkTime']); workingHours = json['workingHours']; travelingHours = json['travelingHours']; travelingExpenses = json['travelingExpenses']; - faultDescription = json['faultDescription'] != null ? new ModelDefRelatedDefects.fromJson(json['faultDescription']) : ModelDefRelatedDefects(); + faultDescription = json['faultDescription'] != null ? FaultDescription.fromJson(json['faultDescription']) : null; if (json['sparePartsWorkOrders'] != null) { - sparePartsWorkOrders = json['sparePartsWorkOrders']; + sparePartsWorkOrders = []; + json['sparePartsWorkOrders'].forEach((v) { + sparePartsWorkOrders.add(SparePartsWorkOrders.fromJson(v)); + }); } reviewComment = json['reviewComment']; comment = json['comment']; - attachmentsWorkOrder = json['attachmentsWorkOrder']; - equipmentStatus = json['equipmentStatus']; + if (json['attachmentsWorkOrder'] != null) { + attachmentsWorkOrder = []; + json['attachmentsWorkOrder'].forEach((v) { + attachmentsWorkOrder.add(AttachmentsWorkOrder.fromJson(v)); + }); + } + equipmentStatus = json['equipmentStatus'] != null ? Lookup.fromJson(json['equipmentStatus']) : null; if (json['suppEngineerWorkOrders'] != null) { - suppEngineerWorkOrders = json['suppEngineerWorkOrders']; + suppEngineerWorkOrders = []; + json['suppEngineerWorkOrders'].forEach((v) { + suppEngineerWorkOrders.add(SuppEngineerWorkOrders.fromJson(v)); + }); } engSignature = json['engSignature']; nurseSignature = json['nurseSignature']; - woParentDto = json['woParentDto']; + woParentDto = json['woParentDto'] != null ? WoParentDto.fromJson(json['woParentDto']) : null; } + void copyFrom(SearchWorkOrder wo) { + parentWOId = wo.parentWOId ?? parentWOId; + workOrderNo = wo.workOrderNo ?? workOrderNo; + workOrderYear = wo.workOrderYear ?? workOrderYear; + workOrderSequennce = wo.workOrderSequennce ?? workOrderSequennce; + callRequest = wo.callRequest ?? callRequest; + if (wo.assetType != null) assetType = Lookup.fromJson((wo.assetType)?.toMap() ?? {}); + if (wo.assignedEmployee != null) assignedEmployee = AssignedEmployee.fromJson((wo.assignedEmployee)?.toJson() ?? {}); + visitDate = wo.visitDate ?? visitDate; + assistantEmployees = (wo.assistantEmployees ?? assistantEmployees) + ?.map((e) => AssistantEmployees.fromJson({ + "id": e?.id, + "user": {"name": e?.user?.name, "id": (e?.user?.id) ?? "0"} + })) + ?.toList() ?? + []; + if (wo.supplier != null) supplier = SupplierModel.fromJson((wo.supplier)?.toJson() ?? {}); + vendorTicketNumber = wo.vendorTicketNumber ?? vendorTicketNumber; + contactPersonWorkOrders = (wo.contactPersonWorkOrders ?? contactPersonWorkOrders)?.map((e) => ContactPersonWorkOrders.fromJson(e?.toJson() ?? {}))?.toList() ?? []; + calllastSituation = Lookup.fromJson((wo.calllastSituation ?? calllastSituation)?.toMap() ?? {}); + if (wo.currentSituation != null) currentSituation = Lookup.fromJson((wo.currentSituation)?.toMap() ?? {}); + repairLocation = Lookup.fromJson((wo.repairLocation ?? repairLocation)?.toMap() ?? {}); + reason = Lookup.fromJson((wo.reason ?? reason)?.toMap() ?? {}); + // startofWorkTime = wo.startofWorkTime ?? startofWorkTime; + // endofWorkTime = wo.endofWorkTime ?? endofWorkTime; + timer = wo.timer ?? timer; + workingHours = wo.workingHours ?? workingHours; + travelingHours = wo.travelingHours ?? travelingHours; + travelingExpenses = wo.travelingExpenses ?? travelingExpenses; + faultDescription = FaultDescription.fromJson((wo.faultDescription ?? faultDescription)?.toJson() ?? {}); + sparePartsWorkOrders = (wo.sparePartsWorkOrders ?? sparePartsWorkOrders)?.map((e) => SparePartsWorkOrders.fromJson(e?.toJson() ?? {}))?.toList() ?? []; + reviewComment = wo.reviewComment ?? reviewComment; + comment = wo.comment ?? comment; + attachmentsWorkOrder = (wo.attachmentsWorkOrder ?? attachmentsWorkOrder)?.map((e) => AttachmentsWorkOrder.fromJson(e?.toJson() ?? {}))?.toList() ?? []; + equipmentStatus = Lookup.fromJson((wo.equipmentStatus ?? equipmentStatus)?.toMap() ?? {}); + suppEngineerWorkOrders = (wo.suppEngineerWorkOrders ?? suppEngineerWorkOrders)?.map((e) => SuppEngineerWorkOrders.fromJson(e?.toJson() ?? {}))?.toList() ?? []; + engSignature = wo.engSignature ?? engSignature; + nurseSignature = wo.nurseSignature ?? nurseSignature; + woParentDto = wo.woParentDto ?? woParentDto; + } + + num id; + num parentWOId; + String workOrderNo; + num workOrderYear; + num workOrderSequennce; + CallRequest callRequest; + Lookup assetType; + AssignedEmployee assignedEmployee; + String visitDate; + List assistantEmployees; + SupplierModel supplier; + String vendorTicketNumber; + List contactPersonWorkOrders; + Lookup calllastSituation; + Lookup currentSituation; + Lookup repairLocation; + Lookup reason; + // String startofWorkTime; + // String endofWorkTime; + num workingHours; + num travelingHours; + num travelingExpenses; + FaultDescription faultDescription; + List sparePartsWorkOrders; + String reviewComment; + String comment; + List attachmentsWorkOrder; + Lookup equipmentStatus; + List suppEngineerWorkOrders; + String engSignature; + String nurseSignature; + WoParentDto woParentDto; + TimerModel timer; + + SearchWorkOrder copyWith({ + num id, + num parentWOId, + String workOrderNo, + num workOrderYear, + num workOrderSequennce, + CallRequest callRequest, + Lookup assetType, + AssignedEmployee assignedEmployee, + String visitDate, + List assistantEmployees, + SupplierModel supplier, + String vendorTicketNumber, + List contactPersonWorkOrders, + Lookup calllastSituation, + Lookup currentSituation, + Lookup repairLocation, + Lookup reason, + // String startofWorkTime, + // String endofWorkTime, + num workingHours, + num travelingHours, + num travelingExpenses, + FaultDescription faultDescription, + List sparePartsWorkOrders, + String reviewComment, + String comment, + List attachmentsWorkOrder, + Lookup equipmentStatus, + List suppEngineerWorkOrders, + String engSignature, + String nurseSignature, + WoParentDto woParentDto, + TimerModel timer, + }) => + SearchWorkOrder( + id: id ?? this.id, + parentWOId: parentWOId ?? this.parentWOId, + workOrderNo: workOrderNo ?? this.workOrderNo, + workOrderYear: workOrderYear ?? this.workOrderYear, + workOrderSequennce: workOrderSequennce ?? this.workOrderSequennce, + callRequest: callRequest ?? this.callRequest, + assetType: assetType ?? this.assetType, + assignedEmployee: assignedEmployee ?? this.assignedEmployee, + visitDate: visitDate ?? this.visitDate, + assistantEmployees: assistantEmployees ?? this.assistantEmployees, + supplier: supplier ?? this.supplier, + vendorTicketNumber: vendorTicketNumber ?? this.vendorTicketNumber, + contactPersonWorkOrders: contactPersonWorkOrders ?? this.contactPersonWorkOrders, + calllastSituation: calllastSituation ?? this.calllastSituation, + currentSituation: currentSituation ?? this.currentSituation, + repairLocation: repairLocation ?? this.repairLocation, + reason: reason ?? this.reason, + // startofWorkTime: startofWorkTime ?? this.startofWorkTime, + // endofWorkTime: endofWorkTime ?? this.endofWorkTime, + workingHours: workingHours ?? this.workingHours, + travelingHours: travelingHours ?? this.travelingHours, + travelingExpenses: travelingExpenses ?? this.travelingExpenses, + faultDescription: faultDescription ?? this.faultDescription, + sparePartsWorkOrders: sparePartsWorkOrders ?? this.sparePartsWorkOrders, + reviewComment: reviewComment ?? this.reviewComment, + comment: comment ?? this.comment, + attachmentsWorkOrder: attachmentsWorkOrder ?? this.attachmentsWorkOrder, + equipmentStatus: equipmentStatus ?? this.equipmentStatus, + suppEngineerWorkOrders: suppEngineerWorkOrders ?? this.suppEngineerWorkOrders, + engSignature: engSignature ?? this.engSignature, + nurseSignature: nurseSignature ?? this.nurseSignature, + woParentDto: woParentDto ?? this.woParentDto, + timer: timer ?? this.timer, + ); Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['parentWOId'] = this.parentWOId; - data['workOrderNo'] = this.workOrderNo; - data['workOrderYear'] = this.workOrderYear; - data['workOrderSequennce'] = this.workOrderSequennce; - if (this.callRequest != null) { - data['callRequest'] = this.callRequest.toJson(); + final map = {}; + map['id'] = id ?? 0; + map['parentWOId'] = parentWOId; + map['workOrderNo'] = workOrderNo; + map['workOrderYear'] = workOrderYear; + map['workOrderSequennce'] = workOrderSequennce; + if (callRequest != null) { + map['callRequest'] = callRequest.toJson(); } - data['assetType'] = this.assetType; - if (this.assignedEmployee != null) { - data['assignedEmployee'] = this.assignedEmployee.toJson(); + if (assetType != null) { + map['assetType'] = assetType.toMap(); } - data['visitDate'] = this.visitDate; - if (this.assistantEmployees != null) { - data['assistantEmployees'] = this.assistantEmployees.map((v) => v.toJson()).toList(); + if (assignedEmployee != null) { + map['assignedEmployee'] = assignedEmployee.toJson(); } - data['supplier'] = this.supplier; - data['vendorTicketNumber'] = this.vendorTicketNumber; - if (this.contactPersonWorkOrders != null) { - data['contactPersonWorkOrders'] = this.contactPersonWorkOrders.map((v) => v.toJson()).toList(); + map['visitDate'] = visitDate; + if (assistantEmployees != null) { + map['assistantEmployees'] = assistantEmployees.map((v) => v?.toJson()).toList(); } - if (this.calllastSituation != null) { - data['calllastSituation'] = this.calllastSituation.toMap(); + if (supplier != null) { + map['supplier'] = supplier.toJson(); } - if (this.currentSituation != null) { - data['currentSituation'] = this.currentSituation.toMap(); + map['vendorTicketNumber'] = vendorTicketNumber; + if (contactPersonWorkOrders != null) { + map['contactPersonWorkOrders'] = contactPersonWorkOrders.map((v) => v.toJson()).toList(); } - data['repairLocation'] = this.repairLocation; - data['reason'] = this.reason; - data['startofWorkTime'] = this.startofWorkTime; - data['endofWorkTime'] = this.endofWorkTime; - data['workingHours'] = this.workingHours; - data['travelingHours'] = this.travelingHours; - data['travelingExpenses'] = this.travelingExpenses; - if (this.faultDescription != null) { - data['faultDescription'] = this.faultDescription.toJson(); + if (calllastSituation != null) { + map['calllastSituation'] = calllastSituation.toMap(); } - if (this.sparePartsWorkOrders != null) { - data['sparePartsWorkOrders'] = this.sparePartsWorkOrders.map((v) => v.toJson()).toList(); + map['currentSituation'] = currentSituation?.toMap(); + if (repairLocation?.id != null) { + map['repairLocation'] = repairLocation.toMap(); } - data['reviewComment'] = this.reviewComment; - data['comment'] = this.comment; - data['attachmentsWorkOrder'] = this.attachmentsWorkOrder; - data['equipmentStatus'] = this.equipmentStatus; - if (this.suppEngineerWorkOrders != null) { - data['suppEngineerWorkOrders'] = this.suppEngineerWorkOrders.map((v) => v.toJson()).toList(); + if (reason != null) { + map['reason'] = reason.toMap(); } - data['engSignature'] = this.engSignature; - data['nurseSignature'] = this.nurseSignature; - data['woParentDto'] = this.woParentDto; - return data; + // map['startofWorkTime'] = startofWorkTime; + // map['endofWorkTime'] = endofWorkTime; + map['startofWorkTime'] = timer?.startAt?.toIso8601String(); + map['endofWorkTime'] = timer?.endAt?.toIso8601String(); + map['workingHours'] = workingHours; + map['travelingHours'] = travelingHours; + map['travelingExpenses'] = travelingExpenses; + + if (faultDescription?.id != null) { + map['faultDescription'] = faultDescription.toJson(); + } + if (sparePartsWorkOrders != null) { + map['sparePartsWorkOrders'] = sparePartsWorkOrders.map((v) => v.toJson()).toList(); + } + map['reviewComment'] = reviewComment; + map['comment'] = comment; + if (attachmentsWorkOrder != null) { + map['attachmentsWorkOrder'] = attachmentsWorkOrder.map((v) => v.toJson()).toList(); + } + if (equipmentStatus != null) { + map['equipmentStatus'] = equipmentStatus.toMap(); + } + if (suppEngineerWorkOrders != null) { + map['suppEngineerWorkOrders'] = suppEngineerWorkOrders.map((v) => v.toJson()).toList(); + } + map['engSignature'] = engSignature; + map['nurseSignature'] = nurseSignature; + if (woParentDto != null) { + map['woParentDto'] = woParentDto.toJson(); + } + return map; } } -class CallRequest { - int id; - String callNo; - Asset asset; - AssignedEmployee assignedEmployee; - List callSiteContactPerson; - Lookup status; - Lookup callLastSituation; - String defectType; - String firstAction; - String assetType; - - CallRequest({this.id, this.callNo, this.asset, this.assignedEmployee, this.callSiteContactPerson, this.status, this.callLastSituation, this.defectType, this.firstAction, this.assetType}); +class WoParentDto { + WoParentDto({ + this.callLastSituation, + this.supplier, + this.assetType, + this.vendorTicketNumber, + this.callId, + this.id, + this.stepsWorkOrderDto, + this.suppEngineerWorkOrders, + this.equipmentStatus, + this.currentSituation, + }); - CallRequest.fromJson(Map json) { + WoParentDto.fromJson(dynamic json) { + callLastSituation = json['callLastSituation'] != null ? Lookup.fromJson(json['callLastSituation']) : null; + supplier = json['supplier'] != null ? SupplierModel.fromJson(json['supplier']) : null; + assetType = json['assetType'] != null ? Lookup.fromJson(json['assetType']) : null; + vendorTicketNumber = json['vendorTicketNumber']; + callId = json['callId']; id = json['id']; - callNo = json['callNo']; - asset = json['asset'] != null ? new Asset.fromJson(json['asset']) : Asset(); - assignedEmployee = json['assignedEmployee'] != null ? new AssignedEmployee.fromJson(json['assignedEmployee']) : AssignedEmployee(); - if (json['callSiteContactPerson'] != null) { - callSiteContactPerson = json['callSiteContactPerson']; + stepsWorkOrderDto = json['stepsWorkOrderDto'] != null ? StepsWorkOrderDto.fromJson(json['stepsWorkOrderDto']) : null; + if (json['suppEngineerWorkOrders'] != null) { + suppEngineerWorkOrders = []; + json['suppEngineerWorkOrders'].forEach((v) { + suppEngineerWorkOrders.add(SuppEngineerWorkOrders.fromJson(v)); + }); } - status = json['status'] != null ? new Lookup.fromJson(json['status']) : Lookup(); - callLastSituation = json['callLastSituation'] != null ? new Lookup.fromJson(json['callLastSituation']) : Lookup(); - defectType = json['defectType']; - firstAction = json['firstAction']; - assetType = json['assetType']; + equipmentStatus = json['equipmentStatus'] != null ? Lookup.fromJson(json['equipmentStatus']) : null; + currentSituation = json['currentSituation'] != null ? Lookup.fromJson(json['currentSituation']) : null; } - + Lookup callLastSituation; + SupplierModel supplier; + Lookup assetType; + String vendorTicketNumber; + num callId; + num id; + StepsWorkOrderDto stepsWorkOrderDto; + List suppEngineerWorkOrders; + Lookup equipmentStatus; + Lookup currentSituation; + WoParentDto copyWith({ + Lookup callLastSituation, + SupplierModel supplier, + Lookup assetType, + String vendorTicketNumber, + num callId, + num id, + StepsWorkOrderDto stepsWorkOrderDto, + List suppEngineerWorkOrders, + Lookup equipmentStatus, + Lookup currentSituation, + }) => + WoParentDto( + callLastSituation: callLastSituation ?? this.callLastSituation, + supplier: supplier ?? this.supplier, + assetType: assetType ?? this.assetType, + vendorTicketNumber: vendorTicketNumber ?? this.vendorTicketNumber, + callId: callId ?? this.callId, + id: id ?? this.id, + stepsWorkOrderDto: stepsWorkOrderDto ?? this.stepsWorkOrderDto, + suppEngineerWorkOrders: suppEngineerWorkOrders ?? this.suppEngineerWorkOrders, + equipmentStatus: equipmentStatus ?? this.equipmentStatus, + currentSituation: currentSituation ?? this.currentSituation, + ); Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['callNo'] = this.callNo; - if (this.asset != null) { - data['asset'] = this.asset.toJson(); + final map = {}; + if (callLastSituation != null) { + map['callLastSituation'] = callLastSituation.toMap(); + } + if (supplier != null) { + map['supplier'] = supplier.toJson(); } - if (this.assignedEmployee != null) { - data['assignedEmployee'] = this.assignedEmployee.toJson(); + if (assetType != null) { + map['assetType'] = assetType.toMap(); } - if (this.callSiteContactPerson != null) { - data['callSiteContactPerson'] = this.callSiteContactPerson.map((v) => v.toJson()).toList(); + map['vendorTicketNumber'] = vendorTicketNumber; + map['callId'] = callId ?? 0; + map['id'] = id ?? 0; + if (stepsWorkOrderDto != null) { + map['stepsWorkOrderDto'] = stepsWorkOrderDto.toJson(); } - if (this.status != null) { - data['status'] = this.status.toMap(); + if (suppEngineerWorkOrders != null) { + map['suppEngineerWorkOrders'] = suppEngineerWorkOrders.map((v) => v.toJson()).toList(); } - if (this.callLastSituation != null) { - data['callLastSituation'] = this.callLastSituation.toMap(); + if (equipmentStatus != null) { + map['equipmentStatus'] = equipmentStatus.toMap(); } - data['defectType'] = this.defectType; - data['firstAction'] = this.firstAction; - data['assetType'] = this.assetType; - return data; + if (currentSituation != null) { + map['currentSituation'] = currentSituation.toMap(); + } + return map; } } -class Asset { - int id; - String assetSerialNo; - String systemID; - String assetNumber; - ModelDefinition modelDefinition; - String supplier; - String ipAddress; - String macAddress; - String portNumber; - String assetReplace; - String oldAsset; - String isParent; - String parentAsset; - int assetType; - Site site; - String building; - String floor; - String department; - String room; - String testsDay; - String purchasingPrice; - String nbv; - String currency; - String poNo; - String invoiceNumber; - String invoiceDate; - String replacementDate; - String originDepartment; - Site originSite; - String budgetYear; - String lastPOPrice; - String commissioningStatus; - String productionDate; - String edd; - String technicalInspectionDate; - String deliveryInspectionDate; - String endUserAcceptanceDate; - String receivingCommittee; - String siteWarrantyMonths; - String extendedWarrantyMonths; - String remainderWarrantyMonths; - String eomWarrantyMonthsNo; - String warrantyValue; - String warrantyEndDate; - String warrantyContractConditions; - List technicalGuidanceBooks; - String comment; - String tagCode; +class SuppEngineerWorkOrders { + SuppEngineerWorkOrders({ + this.id, + this.supplierContactId, + this.personName, + this.personRoleName, + this.contact, + this.externalEngCode, + this.email, + }); - Asset( - {this.id, - this.assetSerialNo, - this.systemID, - this.assetNumber, - this.modelDefinition, - this.supplier, - this.ipAddress, - this.macAddress, - this.portNumber, - this.assetReplace, - this.oldAsset, - this.isParent, - this.parentAsset, - this.assetType, - this.site, - this.building, - this.floor, - this.department, - this.room, - this.testsDay, - this.purchasingPrice, - this.nbv, - this.currency, - this.poNo, - this.invoiceNumber, - this.invoiceDate, - this.replacementDate, - this.originDepartment, - this.originSite, - this.budgetYear, - this.lastPOPrice, - this.commissioningStatus, - this.productionDate, - this.edd, - this.technicalInspectionDate, - this.deliveryInspectionDate, - this.endUserAcceptanceDate, - this.receivingCommittee, - this.siteWarrantyMonths, - this.extendedWarrantyMonths, - this.remainderWarrantyMonths, - this.eomWarrantyMonthsNo, - this.warrantyValue, - this.warrantyEndDate, - this.warrantyContractConditions, - this.technicalGuidanceBooks, - this.comment, - this.tagCode}); - - Asset.fromJson(Map json) { + SuppEngineerWorkOrders.fromJson(dynamic json) { id = json['id']; - assetSerialNo = json['assetSerialNo']; - systemID = json['systemID']; - assetNumber = json['assetNumber']; - modelDefinition = json['modelDefinition'] != null ? new ModelDefinition.fromJson(json['modelDefinition']) : ModelDefinition(); - supplier = json['supplier']; - ipAddress = json['ipAddress']; - macAddress = json['macAddress']; - portNumber = json['portNumber']; - assetReplace = json['assetReplace']; - oldAsset = json['oldAsset']; - isParent = json['isParent']; - parentAsset = json['parentAsset']; - assetType = json['assetType']; - site = json['site'] != null ? new Site.fromJson(json['site']) : Site(); - building = json['building']; - floor = json['floor']; - department = json['department']; - } - - Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['assetSerialNo'] = this.assetSerialNo; - data['systemID'] = this.systemID; - data['assetNumber'] = this.assetNumber; - if (this.modelDefinition != null) { - data['modelDefinition'] = this.modelDefinition.toJson(); - } - data['supplier'] = this.supplier; - data['ipAddress'] = this.ipAddress; - data['macAddress'] = this.macAddress; - data['portNumber'] = this.portNumber; - data['assetReplace'] = this.assetReplace; - data['oldAsset'] = this.oldAsset; - data['isParent'] = this.isParent; - data['parentAsset'] = this.parentAsset; - data['assetType'] = this.assetType; - if (this.site != null) { - data['site'] = this.site.toJson(); - } - data['building'] = this.building; - data['floor'] = this.floor; - data['department'] = this.department; - data['room'] = this.room; - data['testsDay'] = this.testsDay; - data['purchasingPrice'] = this.purchasingPrice; - data['nbv'] = this.nbv; - data['currency'] = this.currency; - data['poNo'] = this.poNo; - data['invoiceNumber'] = this.invoiceNumber; - data['invoiceDate'] = this.invoiceDate; - data['replacementDate'] = this.replacementDate; - data['originDepartment'] = this.originDepartment; - if (this.originSite != null) { - data['originSite'] = this.originSite.toJson(); - } - data['budgetYear'] = this.budgetYear; - data['lastPOPrice'] = this.lastPOPrice; - data['commissioningStatus'] = this.commissioningStatus; - data['productionDate'] = this.productionDate; - data['edd'] = this.edd; - data['technicalInspectionDate'] = this.technicalInspectionDate; - data['deliveryInspectionDate'] = this.deliveryInspectionDate; - data['endUserAcceptanceDate'] = this.endUserAcceptanceDate; - data['receivingCommittee'] = this.receivingCommittee; - data['siteWarrantyMonths'] = this.siteWarrantyMonths; - data['extendedWarrantyMonths'] = this.extendedWarrantyMonths; - data['remainderWarrantyMonths'] = this.remainderWarrantyMonths; - data['eomWarrantyMonthsNo'] = this.eomWarrantyMonthsNo; - data['warrantyValue'] = this.warrantyValue; - data['warrantyEndDate'] = this.warrantyEndDate; - data['warrantyContractConditions'] = this.warrantyContractConditions; - if (this.technicalGuidanceBooks != null) { - data['technicalGuidanceBooks'] = this.technicalGuidanceBooks.map((v) => v.toJson()).toList(); - } - data['comment'] = this.comment; - data['tagCode'] = this.tagCode; - return data; + supplierContactId = json['supplierContactId']; + personName = json['personName']; + personRoleName = json['personRoleName']; + contact = json['contact']; + externalEngCode = json['externalEngCode']; + email = json['email']; + } + num id; + num supplierContactId; + String personName; + String personRoleName; + String contact; + String externalEngCode; + String email; + SuppEngineerWorkOrders copyWith({ + num id, + num supplierContactId, + String personName, + String personRoleName, + String contact, + String externalEngCode, + String email, + }) => + SuppEngineerWorkOrders( + id: id ?? this.id, + supplierContactId: supplierContactId ?? this.supplierContactId, + personName: personName ?? this.personName, + personRoleName: personRoleName ?? this.personRoleName, + contact: contact ?? this.contact, + externalEngCode: externalEngCode ?? this.externalEngCode, + email: email ?? this.email, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['supplierContactId'] = supplierContactId; + map['personName'] = personName; + map['personRoleName'] = personRoleName; + map['contact'] = contact; + map['externalEngCode'] = externalEngCode; + map['email'] = email; + return map; } } -class ModelDefinition { - int id; - String assetName; - String modelDefCode; - String modelName; - int manufacturerId; - String manufacturerName; - String supplierName; - String replacementDate; - int lifeSpan; - List modelDefRelatedDefects; - List suppliers; - - ModelDefinition( - {this.id, - this.assetName, - this.modelDefCode, - this.modelName, - this.manufacturerId, - this.manufacturerName, - this.supplierName, - this.replacementDate, - this.lifeSpan, - this.modelDefRelatedDefects, - this.suppliers}); - - ModelDefinition.fromJson(Map json) { +class StepsWorkOrderDto { + StepsWorkOrderDto({ + this.sequence, + this.id, + this.name, + this.statusValue, + this.typeTransaction, + this.processed, + this.parentWOId, + this.callId, + }); + + StepsWorkOrderDto.fromJson(dynamic json) { + sequence = json['sequence']; id = json['id']; - assetName = json['assetName']; - modelDefCode = json['modelDefCode']; - modelName = json['modelName']; - manufacturerId = json['manufacturerId']; - manufacturerName = json['manufacturerName']; - supplierName = json['supplierName']; - replacementDate = json['replacementDate']; - lifeSpan = json['lifeSpan']; - if (json['modelDefRelatedDefects'] != null) { - modelDefRelatedDefects = []; - json['modelDefRelatedDefects'].forEach((v) { - modelDefRelatedDefects.add(new ModelDefRelatedDefects.fromJson(v)); + name = json['name']; + statusValue = json['statusValue']; + typeTransaction = json['typeTransaction']; + processed = json['processed']; + parentWOId = json['parentWOId']; + callId = json['callId']; + } + num sequence; + num id; + String name; + num statusValue; + String typeTransaction; + bool processed; + num parentWOId; + num callId; + StepsWorkOrderDto copyWith({ + num sequence, + num id, + String name, + num statusValue, + String typeTransaction, + bool processed, + num parentWOId, + num callId, + }) => + StepsWorkOrderDto( + sequence: sequence ?? this.sequence, + id: id ?? this.id, + name: name ?? this.name, + statusValue: statusValue ?? this.statusValue, + typeTransaction: typeTransaction ?? this.typeTransaction, + processed: processed ?? this.processed, + parentWOId: parentWOId ?? this.parentWOId, + callId: callId ?? this.callId, + ); + Map toJson() { + final map = {}; + map['sequence'] = sequence; + map['id'] = id ?? 0; + map['name'] = name; + map['statusValue'] = statusValue; + map['typeTransaction'] = typeTransaction; + map['processed'] = processed; + map['parentWOId'] = parentWOId; + map['callId'] = callId; + return map; + } +} + +class SupplierModel { + SupplierModel({ + this.id, + this.suppliername, + this.name, + this.website, + this.email, + this.code, + this.suppNo, + this.suppStatusId, + this.cityId, + this.person, + this.comment, + this.zipcode, + this.contact, + this.telephones, + this.faxes, + this.addresses, + this.attachments, + this.suppPersons, + this.suppTCodes, + }); + + SupplierModel.fromJson(dynamic json) { + id = json['id'] ?? 0; + suppliername = json['suppliername']; + name = json['name']; + website = json['website']; + email = json['email']; + code = json['code']; + suppNo = json['suppNo']; + suppStatusId = json['suppStatusId']; + cityId = json['cityId']; + person = json['person']; + comment = json['comment']; + zipcode = json['zipcode']; + contact = json['contact']; + if (json['telephones'] != null) { + telephones = []; + json['telephones'].forEach((v) { + telephones.add(Telephones.fromJson(v)); }); } - if (json['suppliers'] != null) { - suppliers = json['suppliers']; + if (json['faxes'] != null) { + faxes = []; + json['faxes'].forEach((v) { + faxes.add(Faxes.fromJson(v)); + }); + } + if (json['addresses'] != null) { + addresses = []; + json['addresses'].forEach((v) { + addresses.add(Addresses.fromJson(v)); + }); + } + if (json['attachments'] != null) { + attachments = []; + json['attachments'].forEach((v) { + attachments.add(Attachments.fromJson(v)); + }); + } + if (json['suppPersons'] != null) { + suppPersons = []; + json['suppPersons'].forEach((v) { + suppPersons.add(SuppPersons.fromJson(v)); + }); + } + if (json['suppTCodes'] != null) { + suppTCodes = []; + json['suppTCodes'].forEach((v) { + suppTCodes.add(SuppTCodes.fromJson(v)); + }); } } - + num id; + String suppliername; + String name; + String website; + String email; + String code; + num suppNo; + num suppStatusId; + num cityId; + String person; + String comment; + num zipcode; + String contact; + List telephones; + List faxes; + List addresses; + List attachments; + List suppPersons; + List suppTCodes; + SupplierModel copyWith({ + num id, + String suppliername, + String name, + String website, + String email, + String code, + num suppNo, + num suppStatusId, + num cityId, + String person, + String comment, + num zipcode, + String contact, + List telephones, + List faxes, + List addresses, + List attachments, + List suppPersons, + List suppTCodes, + }) => + SupplierModel( + id: id ?? this.id ?? 0, + suppliername: suppliername ?? this.suppliername, + name: name ?? this.name, + website: website ?? this.website, + email: email ?? this.email, + code: code ?? this.code, + suppNo: suppNo ?? this.suppNo, + suppStatusId: suppStatusId ?? this.suppStatusId, + cityId: cityId ?? this.cityId, + person: person ?? this.person, + comment: comment ?? this.comment, + zipcode: zipcode ?? this.zipcode, + contact: contact ?? this.contact, + telephones: telephones ?? this.telephones, + faxes: faxes ?? this.faxes, + addresses: addresses ?? this.addresses, + attachments: attachments ?? this.attachments, + suppPersons: suppPersons ?? this.suppPersons, + suppTCodes: suppTCodes ?? this.suppTCodes, + ); Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['assetName'] = this.assetName; - data['modelDefCode'] = this.modelDefCode; - data['modelName'] = this.modelName; - data['manufacturerId'] = this.manufacturerId; - data['manufacturerName'] = this.manufacturerName; - data['supplierName'] = this.supplierName; - data['replacementDate'] = this.replacementDate; - data['lifeSpan'] = this.lifeSpan; - if (this.modelDefRelatedDefects != null) { - data['modelDefRelatedDefects'] = this.modelDefRelatedDefects.map((v) => v.toJson()).toList(); + final map = {}; + map['id'] = id ?? 0; + map['suppliername'] = suppliername; + map['name'] = name; + map['website'] = website; + map['email'] = email; + map['code'] = code; + map['suppNo'] = suppNo; + map['suppStatusId'] = suppStatusId; + map['cityId'] = cityId; + map['person'] = person; + map['comment'] = comment; + map['zipcode'] = zipcode; + map['contact'] = contact; + if (telephones != null) { + map['telephones'] = telephones.map((v) => v.toJson()).toList(); + } + if (faxes != null) { + map['faxes'] = faxes.map((v) => v.toJson()).toList(); + } + if (addresses != null) { + map['addresses'] = addresses.map((v) => v.toJson()).toList(); } - if (this.suppliers != null) { - data['suppliers'] = this.suppliers.map((v) => v.toJson()).toList(); + if (attachments != null) { + map['attachments'] = attachments.map((v) => v.toJson()).toList(); } - return data; + if (suppPersons != null) { + map['suppPersons'] = suppPersons.map((v) => v.toJson()).toList(); + } + if (suppTCodes != null) { + map['suppTCodes'] = suppTCodes.map((v) => v.toJson()).toList(); + } + return map; } } -class ModelDefRelatedDefects { - int id; - String defectName; - String workPerformed; - String estimatedTime; +class SuppTCodes { + SuppTCodes({ + this.id, + this.supplierId, + this.codeTypeId, + this.codeValue, + }); + + SuppTCodes.fromJson(dynamic json) { + id = json['id']; + supplierId = json['supplierId']; + codeTypeId = json['codeTypeId']; + codeValue = json['codeValue']; + } + num id; + num supplierId; + num codeTypeId; + String codeValue; + SuppTCodes copyWith({ + num id, + num supplierId, + num codeTypeId, + String codeValue, + }) => + SuppTCodes( + id: id ?? this.id ?? 0, + supplierId: supplierId ?? this.supplierId, + codeTypeId: codeTypeId ?? this.codeTypeId, + codeValue: codeValue ?? this.codeValue, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['supplierId'] = supplierId; + map['codeTypeId'] = codeTypeId; + map['codeValue'] = codeValue; + return map; + } +} - ModelDefRelatedDefects({this.id, this.defectName, this.workPerformed, this.estimatedTime}); +class SuppPersons { + SuppPersons({ + this.id, + this.supplierId, + this.personName, + this.personRoleId, + this.contact, + this.externalEngCode, + this.email, + }); - ModelDefRelatedDefects.fromJson(Map json) { + SuppPersons.fromJson(dynamic json) { id = json['id']; - defectName = json['defectName']; - workPerformed = json['workPerformed']; - estimatedTime = json['estimatedTime']; + supplierId = json['supplierId']; + personName = json['personName']; + personRoleId = json['personRoleId']; + contact = json['contact']; + externalEngCode = json['externalEngCode']; + email = json['email']; + } + num id; + num supplierId; + String personName; + num personRoleId; + String contact; + String externalEngCode; + String email; + SuppPersons copyWith({ + num id, + num supplierId, + String personName, + num personRoleId, + String contact, + String externalEngCode, + String email, + }) => + SuppPersons( + id: id ?? this.id, + supplierId: supplierId ?? this.supplierId, + personName: personName ?? this.personName, + personRoleId: personRoleId ?? this.personRoleId, + contact: contact ?? this.contact, + externalEngCode: externalEngCode ?? this.externalEngCode, + email: email ?? this.email, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['supplierId'] = supplierId; + map['personName'] = personName; + map['personRoleId'] = personRoleId; + map['contact'] = contact; + map['externalEngCode'] = externalEngCode; + map['email'] = email; + return map; } +} +class Attachments { + Attachments({ + this.id, + this.supplierId, + this.attachmentName, + this.attachmentURL, + }); + + Attachments.fromJson(dynamic json) { + id = json['id']; + supplierId = json['supplierId']; + attachmentName = json['attachmentName']; + attachmentURL = json['attachmentURL']; + } + num id; + num supplierId; + String attachmentName; + String attachmentURL; + Attachments copyWith({ + num id, + num supplierId, + String attachmentName, + String attachmentURL, + }) => + Attachments( + id: id ?? this.id, + supplierId: supplierId ?? this.supplierId, + attachmentName: attachmentName ?? this.attachmentName, + attachmentURL: attachmentURL ?? this.attachmentURL, + ); Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['defectName'] = this.defectName; - data['workPerformed'] = this.workPerformed; - data['estimatedTime'] = this.estimatedTime; - return data; + final map = {}; + map['id'] = id ?? 0; + map['supplierId'] = supplierId; + map['attachmentName'] = attachmentName; + map['attachmentURL'] = attachmentURL; + return map; } } -class Site { - int id; - int customerCode; - String custName; - List buildings; +class Addresses { + Addresses({ + this.id, + this.supplierId, + this.address, + }); + + Addresses.fromJson(dynamic json) { + id = json['id']; + supplierId = json['supplierId']; + address = json['address']; + } + num id; + num supplierId; + String address; + Addresses copyWith({ + num id, + num supplierId, + String address, + }) => + Addresses( + id: id ?? this.id, + supplierId: supplierId ?? this.supplierId, + address: address ?? this.address, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['supplierId'] = supplierId; + map['address'] = address; + return map; + } +} - Site({this.id, this.customerCode, this.custName, this.buildings}); +class Faxes { + Faxes({ + this.id, + this.supplierId, + this.fax, + }); - Site.fromJson(Map json) { + Faxes.fromJson(dynamic json) { id = json['id']; - customerCode = json['customerCode']; - custName = json['custName']; - if (json['buildings'] != null) { - buildings = json['buildings']; + supplierId = json['supplierId']; + fax = json['fax']; + } + num id; + num supplierId; + String fax; + Faxes copyWith({ + num id, + num supplierId, + String fax, + }) => + Faxes( + id: id ?? this.id, + supplierId: supplierId ?? this.supplierId, + fax: fax ?? this.fax, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['supplierId'] = supplierId; + map['fax'] = fax; + return map; + } +} + +class Telephones { + Telephones({ + this.id, + this.supplierId, + this.telephone, + }); + + Telephones.fromJson(dynamic json) { + id = json['id']; + supplierId = json['supplierId']; + telephone = json['telephone']; + } + num id; + num supplierId; + String telephone; + Telephones copyWith({ + num id, + num supplierId, + String telephone, + }) => + Telephones( + id: id ?? this.id, + supplierId: supplierId ?? this.supplierId, + telephone: telephone ?? this.telephone, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['supplierId'] = supplierId; + map['telephone'] = telephone; + return map; + } +} + +class AttachmentsWorkOrder { + AttachmentsWorkOrder({ + this.id, + this.name, + }); + + AttachmentsWorkOrder.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + } + num id; + String name; + AttachmentsWorkOrder copyWith({ + num id, + String name, + }) => + AttachmentsWorkOrder( + id: id ?? this.id, + name: name ?? this.name, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + return map; + } +} + +class SparePartsWorkOrders { + SparePartsWorkOrders({ + this.id, + this.sparePart, + this.qty, + this.returnQty, + this.installQty, + }); + + SparePartsWorkOrders.fromJson(dynamic json) { + id = json['id']; + sparePart = json['sparePart'] != null ? SparePart.fromJson(json['sparePart']) : null; + qty = json['qty']; + returnQty = json['returnQty']; + installQty = json['installQty']; + } + num id; + SparePart sparePart; + num qty; + num returnQty; + num installQty; + SparePartsWorkOrders copyWith({ + num id, + SparePart sparePart, + num qty, + num returnQty, + num installQty, + }) => + SparePartsWorkOrders( + id: id ?? this.id, + sparePart: sparePart ?? this.sparePart, + qty: qty ?? this.qty, + returnQty: returnQty ?? this.returnQty, + installQty: installQty ?? this.installQty, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + if (sparePart != null) { + map['sparePart'] = sparePart.toJson(); } + map['qty'] = qty; + map['returnQty'] = returnQty; + map['installQty'] = installQty; + return map; + } +} + +class SparePart { + SparePart({ + this.id, + this.partNo, + this.partName, + }); + + SparePart.fromJson(dynamic json) { + id = json['id']; + partNo = json['partNo']; + partName = json['partName']; + } + num id; + String partNo; + String partName; + SparePart copyWith({ + num id, + String partNo, + String partName, + }) => + SparePart( + id: id ?? this.id, + partNo: partNo ?? this.partNo, + partName: partName ?? this.partName, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['partNo'] = partNo; + map['partName'] = partName; + return map; } +} + +class ContactPersonWorkOrders { + ContactPersonWorkOrders({ + this.id, + this.employeeCode, + this.name, + this.telephone, + this.job, + this.email, + this.land, + this.contactUserId, + }); + + ContactPersonWorkOrders.fromJson(dynamic json) { + id = json['id']; + employeeCode = json['employeeCode']; + name = json['name']; + telephone = json['telephone']; + job = json['job']; + email = json['email']; + land = json['land']; + contactUserId = json['contactUserId']; + } + num id; + String employeeCode; + String name; + String telephone; + String job; + String email; + String land; + String contactUserId; + ContactPersonWorkOrders copyWith({ + num id, + String employeeCode, + String name, + String telephone, + String job, + String email, + String land, + String contactUserId, + }) => + ContactPersonWorkOrders( + id: id ?? this.id, + employeeCode: employeeCode ?? this.employeeCode, + name: name ?? this.name, + telephone: telephone ?? this.telephone, + job: job ?? this.job, + email: email ?? this.email, + land: land ?? this.land, + contactUserId: contactUserId ?? this.contactUserId, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['employeeCode'] = employeeCode; + map['name'] = name; + map['telephone'] = telephone; + map['job'] = job; + map['email'] = email; + map['land'] = land; + map['contactUserId'] = contactUserId; + return map; + } +} +class AssistantEmployees { + AssistantEmployees({ + this.id, + this.user, + }); + + AssistantEmployees.fromJson(dynamic json) { + id = json['id']; + user = json['user'] != null ? UserModel.fromJson(json['user']) : UserModel(name: json['userName'], id: json['userId']); + } + num id; + UserModel user; + AssistantEmployees copyWith({ + num id, + UserModel user, + }) => + AssistantEmployees( + id: id ?? this.id, + user: user ?? this.user, + ); Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['customerCode'] = this.customerCode; - data['custName'] = this.custName; - if (this.buildings != null) { - data['buildings'] = this.buildings.map((v) => v.toJson()).toList(); + final map = {}; + map['id'] = id ?? 0; + if (user != null) { + map['user'] = user.toJson(); } - return data; + return map; } } -class AssignedEmployee { +class UserModel { + UserModel({ + this.id, + this.name, + }); + + UserModel.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + } String id; String name; + UserModel copyWith({ + String id, + String name, + }) => + UserModel( + id: id ?? this.id, + name: name ?? this.name, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + return map; + } +} - AssignedEmployee({this.id, this.name}); +class AssignedEmployee { + AssignedEmployee({ + this.id, + this.name, + }); - AssignedEmployee.fromJson(Map json) { + AssignedEmployee.fromJson(dynamic json) { id = json['id']; name = json['name']; } + String id; + String name; + AssignedEmployee copyWith({ + String id, + String name, + }) => + AssignedEmployee( + id: id ?? this.id, + name: name ?? this.name, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + return map; + } +} + +class CallRequest { + CallRequest({ + this.id, + this.callNo, + this.callComments, + this.asset, + this.assignedEmployee, + this.callSiteContactPerson, + this.status, + this.callLastSituation, + this.defectType, + this.firstAction, + this.assetType, + }); + CallRequest.fromJson(dynamic json) { + id = json['id']; + callNo = json['callNo']; + callComments = json['callComments']; + asset = json['asset'] != null ? Asset.fromJson(json['asset']) : null; + assignedEmployee = json['assignedEmployee'] != null ? AssignedEmployee.fromJson(json['assignedEmployee']) : null; + if (json['callSiteContactPerson'] != null) { + callSiteContactPerson = []; + json['callSiteContactPerson'].forEach((v) { + callSiteContactPerson.add(CallSiteContactPerson.fromJson(v)); + }); + } + status = json['status'] != null ? Status.fromJson(json['status']) : null; + callLastSituation = json['callLastSituation'] != null ? Lookup.fromJson(json['callLastSituation']) : null; + defectType = json['defectType'] != null ? DefectType.fromJson(json['defectType']) : null; + firstAction = json['firstAction'] != null ? FirstAction.fromJson(json['firstAction']) : null; + assetType = json['assetType']; + } + num id; + String callNo; + String callComments; + Asset asset; + AssignedEmployee assignedEmployee; + List callSiteContactPerson; + Status status; + Lookup callLastSituation; + DefectType defectType; + FirstAction firstAction; + num assetType; + CallRequest copyWith({ + num id, + String callNo, + String callComments, + Asset asset, + AssignedEmployee assignedEmployee, + List callSiteContactPerson, + Status status, + Lookup callLastSituation, + DefectType defectType, + FirstAction firstAction, + num assetType, + }) => + CallRequest( + id: id ?? this.id, + callNo: callNo ?? this.callNo, + callComments: callComments ?? this.callComments, + asset: asset ?? this.asset, + assignedEmployee: assignedEmployee ?? this.assignedEmployee, + callSiteContactPerson: callSiteContactPerson ?? this.callSiteContactPerson, + status: status ?? this.status, + callLastSituation: callLastSituation ?? this.callLastSituation, + defectType: defectType ?? this.defectType, + firstAction: firstAction ?? this.firstAction, + assetType: assetType ?? this.assetType, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['callNo'] = callNo; + map['callComments'] = callComments; + if (asset != null) { + map['asset'] = asset.toJson(); + } + if (assignedEmployee != null) { + map['assignedEmployee'] = assignedEmployee.toJson(); + } + if (callSiteContactPerson != null) { + map['callSiteContactPerson'] = callSiteContactPerson.map((v) => v.toJson()).toList(); + } + if (status != null) { + map['status'] = status.toJson(); + } + if (callLastSituation != null) { + map['callLastSituation'] = callLastSituation.toMap(); + } + if (defectType != null) { + map['defectType'] = defectType.toJson(); + } + if (firstAction != null) { + map['firstAction'] = firstAction.toJson(); + } + map['assetType'] = assetType; + return map; + } +} + +class FirstAction { + FirstAction({ + this.id, + this.name, + this.value, + }); + + FirstAction.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + FirstAction copyWith({ + num id, + String name, + num value, + }) => + FirstAction( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class DefectType { + DefectType({ + this.id, + this.name, + this.value, + }); + + DefectType.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + DefectType copyWith({ + num id, + String name, + num value, + }) => + DefectType( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class Status { + Status({ + this.id, + this.name, + this.value, + }); + + Status.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + Status copyWith({ + num id, + String name, + num value, + }) => + Status( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class CallSiteContactPerson { + CallSiteContactPerson({ + this.id, + this.employeeCode, + this.name, + this.telephone, + this.job, + this.email, + this.land, + this.contactUserId, + }); + + CallSiteContactPerson.fromJson(dynamic json) { + id = json['id']; + employeeCode = json['employeeCode']; + name = json['name']; + telephone = json['telephone']; + job = json['job']; + email = json['email']; + land = json['land']; + contactUserId = json['contactUserId']; + } + num id; + String employeeCode; + String name; + String telephone; + String job; + String email; + String land; + String contactUserId; + CallSiteContactPerson copyWith({ + num id, + String employeeCode, + String name, + String telephone, + String job, + String email, + String land, + String contactUserId, + }) => + CallSiteContactPerson( + id: id ?? this.id, + employeeCode: employeeCode ?? this.employeeCode, + name: name ?? this.name, + telephone: telephone ?? this.telephone, + job: job ?? this.job, + email: email ?? this.email, + land: land ?? this.land, + contactUserId: contactUserId ?? this.contactUserId, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['employeeCode'] = employeeCode; + map['name'] = name; + map['telephone'] = telephone; + map['job'] = job; + map['email'] = email; + map['land'] = land; + map['contactUserId'] = contactUserId; + return map; + } +} + +class Asset { + Asset({ + this.id, + this.assetSerialNo, + this.systemID, + this.assetNumber, + this.modelDefinition, + this.supplier, + this.ipAddress, + this.macAddress, + this.portNumber, + this.assetReplace, + this.oldAsset, + this.isParent, + this.parentAsset, + this.assetType, + this.site, + this.building, + this.floor, + this.department, + this.room, + this.testsDay, + this.purchasingPrice, + this.nbv, + this.currency, + this.poNo, + this.invoiceNumber, + this.invoiceDate, + this.replacementDate, + this.originDepartment, + this.originSite, + this.budgetYear, + this.lastPOPrice, + this.commissioningStatus, + this.productionDate, + this.edd, + this.technicalInspectionDate, + this.deliveryInspectionDate, + this.endUserAcceptanceDate, + this.receivingCommittee, + this.siteWarrantyMonths, + this.extendedWarrantyMonths, + this.remainderWarrantyMonths, + this.eomWarrantyMonthsNo, + this.warrantyValue, + this.warrantyEndDate, + this.warrantyContractConditions, + this.technicalGuidanceBooks, + this.comment, + this.tagCode, + }); + + Asset.fromJson(dynamic json) { + id = json['id']; + assetSerialNo = json['assetSerialNo']; + systemID = json['systemID']; + assetNumber = json['assetNumber']; + modelDefinition = json['modelDefinition'] != null ? ModelDefinition.fromJson(json['modelDefinition']) : null; + supplier = json['supplier'] != null ? Supplier.fromJson(json['supplier']) : null; + ipAddress = json['ipAddress']; + macAddress = json['macAddress']; + portNumber = json['portNumber']; + assetReplace = json['assetReplace'] != null ? AssetReplace.fromJson(json['assetReplace']) : null; + oldAsset = json['oldAsset'] != null ? OldAsset.fromJson(json['oldAsset']) : null; + isParent = json['isParent'] != null ? IsParent.fromJson(json['isParent']) : null; + parentAsset = json['parentAsset'] != null ? ParentAsset.fromJson(json['parentAsset']) : null; + assetType = json['assetType'] != null ? Lookup.fromJson(json['assetType']) : null; + site = json['site'] != null ? Site.fromJson(json['site']) : null; + building = json['building'] != null ? Building.fromJson(json['building']) : null; + floor = json['floor'] != null ? Floor.fromJson(json['floor']) : null; + department = json['department'] != null ? Department.fromJson(json['department']) : null; + room = json['room']; + testsDay = json['testsDay']; + purchasingPrice = json['purchasingPrice']; + nbv = json['nbv']; + currency = json['currency'] != null ? Currency.fromJson(json['currency']) : null; + poNo = json['poNo']; + invoiceNumber = json['invoiceNumber']; + invoiceDate = json['invoiceDate']; + replacementDate = json['replacementDate']; + originDepartment = json['originDepartment'] != null ? OriginDepartment.fromJson(json['originDepartment']) : null; + originSite = json['originSite'] != null ? OriginSite.fromJson(json['originSite']) : null; + budgetYear = json['budgetYear']; + lastPOPrice = json['lastPOPrice']; + commissioningStatus = json['commissioningStatus'] != null ? CommissioningStatus.fromJson(json['commissioningStatus']) : null; + productionDate = json['productionDate']; + edd = json['edd']; + technicalInspectionDate = json['technicalInspectionDate']; + deliveryInspectionDate = json['deliveryInspectionDate']; + endUserAcceptanceDate = json['endUserAcceptanceDate']; + receivingCommittee = json['receivingCommittee']; + siteWarrantyMonths = json['siteWarrantyMonths'] != null ? SiteWarrantyMonths.fromJson(json['siteWarrantyMonths']) : null; + extendedWarrantyMonths = json['extendedWarrantyMonths'] != null ? ExtendedWarrantyMonths.fromJson(json['extendedWarrantyMonths']) : null; + remainderWarrantyMonths = json['remainderWarrantyMonths'] != null ? RemainderWarrantyMonths.fromJson(json['remainderWarrantyMonths']) : null; + eomWarrantyMonthsNo = json['eomWarrantyMonthsNo']; + warrantyValue = json['warrantyValue']; + warrantyEndDate = json['warrantyEndDate']; + warrantyContractConditions = json['warrantyContractConditions']; + if (json['technicalGuidanceBooks'] != null) { + technicalGuidanceBooks = []; + json['technicalGuidanceBooks'].forEach((v) { + technicalGuidanceBooks.add(TechnicalGuidanceBooks.fromJson(v)); + }); + } + comment = json['comment']; + tagCode = json['tagCode']; + } + num id; + String assetSerialNo; + String systemID; + String assetNumber; + ModelDefinition modelDefinition; + Supplier supplier; + String ipAddress; + String macAddress; + String portNumber; + AssetReplace assetReplace; + OldAsset oldAsset; + IsParent isParent; + ParentAsset parentAsset; + Lookup assetType; + Site site; + Building building; + Floor floor; + Department department; + String room; + num testsDay; + num purchasingPrice; + String nbv; + Currency currency; + String poNo; + String invoiceNumber; + String invoiceDate; + String replacementDate; + OriginDepartment originDepartment; + OriginSite originSite; + num budgetYear; + num lastPOPrice; + CommissioningStatus commissioningStatus; + String productionDate; + String edd; + String technicalInspectionDate; + String deliveryInspectionDate; + String endUserAcceptanceDate; + String receivingCommittee; + SiteWarrantyMonths siteWarrantyMonths; + ExtendedWarrantyMonths extendedWarrantyMonths; + RemainderWarrantyMonths remainderWarrantyMonths; + num eomWarrantyMonthsNo; + num warrantyValue; + String warrantyEndDate; + String warrantyContractConditions; + List technicalGuidanceBooks; + String comment; + String tagCode; + Asset copyWith({ + num id, + String assetSerialNo, + String systemID, + String assetNumber, + ModelDefinition modelDefinition, + SupplierModel supplier, + String ipAddress, + String macAddress, + String portNumber, + AssetReplace assetReplace, + OldAsset oldAsset, + IsParent isParent, + ParentAsset parentAsset, + Lookup assetType, + Site site, + Building building, + Floor floor, + Department department, + String room, + num testsDay, + num purchasingPrice, + String nbv, + Currency currency, + String poNo, + String invoiceNumber, + String invoiceDate, + String replacementDate, + OriginDepartment originDepartment, + OriginSite originSite, + num budgetYear, + num lastPOPrice, + CommissioningStatus commissioningStatus, + String productionDate, + String edd, + String technicalInspectionDate, + String deliveryInspectionDate, + String endUserAcceptanceDate, + String receivingCommittee, + SiteWarrantyMonths siteWarrantyMonths, + ExtendedWarrantyMonths extendedWarrantyMonths, + RemainderWarrantyMonths remainderWarrantyMonths, + num eomWarrantyMonthsNo, + num warrantyValue, + String warrantyEndDate, + String warrantyContractConditions, + List technicalGuidanceBooks, + String comment, + String tagCode, + }) => + Asset( + id: id ?? this.id, + assetSerialNo: assetSerialNo ?? this.assetSerialNo, + systemID: systemID ?? this.systemID, + assetNumber: assetNumber ?? this.assetNumber, + modelDefinition: modelDefinition ?? this.modelDefinition, + supplier: supplier ?? this.supplier, + ipAddress: ipAddress ?? this.ipAddress, + macAddress: macAddress ?? this.macAddress, + portNumber: portNumber ?? this.portNumber, + assetReplace: assetReplace ?? this.assetReplace, + oldAsset: oldAsset ?? this.oldAsset, + isParent: isParent ?? this.isParent, + parentAsset: parentAsset ?? this.parentAsset, + assetType: assetType ?? this.assetType, + site: site ?? this.site, + building: building ?? this.building, + floor: floor ?? this.floor, + department: department ?? this.department, + room: room ?? this.room, + testsDay: testsDay ?? this.testsDay, + purchasingPrice: purchasingPrice ?? this.purchasingPrice, + nbv: nbv ?? this.nbv, + currency: currency ?? this.currency, + poNo: poNo ?? this.poNo, + invoiceNumber: invoiceNumber ?? this.invoiceNumber, + invoiceDate: invoiceDate ?? this.invoiceDate, + replacementDate: replacementDate ?? this.replacementDate, + originDepartment: originDepartment ?? this.originDepartment, + originSite: originSite ?? this.originSite, + budgetYear: budgetYear ?? this.budgetYear, + lastPOPrice: lastPOPrice ?? this.lastPOPrice, + commissioningStatus: commissioningStatus ?? this.commissioningStatus, + productionDate: productionDate ?? this.productionDate, + edd: edd ?? this.edd, + technicalInspectionDate: technicalInspectionDate ?? this.technicalInspectionDate, + deliveryInspectionDate: deliveryInspectionDate ?? this.deliveryInspectionDate, + endUserAcceptanceDate: endUserAcceptanceDate ?? this.endUserAcceptanceDate, + receivingCommittee: receivingCommittee ?? this.receivingCommittee, + siteWarrantyMonths: siteWarrantyMonths ?? this.siteWarrantyMonths, + extendedWarrantyMonths: extendedWarrantyMonths ?? this.extendedWarrantyMonths, + remainderWarrantyMonths: remainderWarrantyMonths ?? this.remainderWarrantyMonths, + eomWarrantyMonthsNo: eomWarrantyMonthsNo ?? this.eomWarrantyMonthsNo, + warrantyValue: warrantyValue ?? this.warrantyValue, + warrantyEndDate: warrantyEndDate ?? this.warrantyEndDate, + warrantyContractConditions: warrantyContractConditions ?? this.warrantyContractConditions, + technicalGuidanceBooks: technicalGuidanceBooks ?? this.technicalGuidanceBooks, + comment: comment ?? this.comment, + tagCode: tagCode ?? this.tagCode, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['assetSerialNo'] = assetSerialNo; + map['systemID'] = systemID; + map['assetNumber'] = assetNumber; + if (modelDefinition != null) { + map['modelDefinition'] = modelDefinition.toJson(); + } + map['supplier'] = supplier?.toJson(); + + map['ipAddress'] = ipAddress; + map['macAddress'] = macAddress; + map['portNumber'] = portNumber; + if (assetReplace != null) { + map['assetReplace'] = assetReplace.toJson(); + } + if (oldAsset != null) { + map['oldAsset'] = oldAsset.toJson(); + } + if (isParent != null) { + map['isParent'] = isParent.toJson(); + } + if (parentAsset != null) { + map['parentAsset'] = parentAsset.toJson(); + } + + map['assetType'] = assetType?.toMap(); + print("supplier : ${supplier?.toJson()}"); + print("supplier 2 : ${map['supplier']}"); + print("asset type : ${assetType?.toMap()}"); + print("asset type 2: ${map['assetType']}"); + if (site != null) { + map['site'] = site.toJson(); + } + if (building != null) { + map['building'] = building.toJson(); + } + if (floor != null) { + map['floor'] = floor.toJson(); + } + if (department != null) { + map['department'] = department.toJson(); + } + map['room'] = room; + map['testsDay'] = testsDay; + map['purchasingPrice'] = purchasingPrice; + map['nbv'] = nbv; + if (currency != null) { + map['currency'] = currency.toJson(); + } + map['poNo'] = poNo; + map['invoiceNumber'] = invoiceNumber; + map['invoiceDate'] = invoiceDate; + map['replacementDate'] = replacementDate; + if (originDepartment != null) { + map['originDepartment'] = originDepartment.toJson(); + } + if (originSite != null) { + map['originSite'] = originSite.toJson(); + } + map['budgetYear'] = budgetYear; + map['lastPOPrice'] = lastPOPrice; + if (commissioningStatus != null) { + map['commissioningStatus'] = commissioningStatus.toJson(); + } + map['productionDate'] = productionDate; + map['edd'] = edd; + map['technicalInspectionDate'] = technicalInspectionDate; + map['deliveryInspectionDate'] = deliveryInspectionDate; + map['endUserAcceptanceDate'] = endUserAcceptanceDate; + map['receivingCommittee'] = receivingCommittee; + if (siteWarrantyMonths != null) { + map['siteWarrantyMonths'] = siteWarrantyMonths.toJson(); + } + if (extendedWarrantyMonths != null) { + map['extendedWarrantyMonths'] = extendedWarrantyMonths.toJson(); + } + if (remainderWarrantyMonths != null) { + map['remainderWarrantyMonths'] = remainderWarrantyMonths.toJson(); + } + map['eomWarrantyMonthsNo'] = eomWarrantyMonthsNo; + map['warrantyValue'] = warrantyValue; + map['warrantyEndDate'] = warrantyEndDate; + map['warrantyContractConditions'] = warrantyContractConditions; + if (technicalGuidanceBooks != null) { + map['technicalGuidanceBooks'] = technicalGuidanceBooks.map((v) => v.toJson()).toList(); + } + map['comment'] = comment; + map['tagCode'] = tagCode; + return map; + } +} + +class TechnicalGuidanceBooks { + TechnicalGuidanceBooks({ + this.id, + this.guidanceBook, + }); + + TechnicalGuidanceBooks.fromJson(dynamic json) { + id = json['id']; + guidanceBook = json['guidanceBook'] != null ? GuidanceBook.fromJson(json['guidanceBook']) : null; + } + num id; + GuidanceBook guidanceBook; + TechnicalGuidanceBooks copyWith({ + num id, + GuidanceBook guidanceBook, + }) => + TechnicalGuidanceBooks( + id: id ?? this.id, + guidanceBook: guidanceBook ?? this.guidanceBook, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + if (guidanceBook != null) { + map['guidanceBook'] = guidanceBook.toJson(); + } + return map; + } +} + +class GuidanceBook { + GuidanceBook({ + this.id, + this.name, + this.value, + }); + + GuidanceBook.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + GuidanceBook copyWith({ + num id, + String name, + num value, + }) => + GuidanceBook( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class RemainderWarrantyMonths { + RemainderWarrantyMonths({ + this.id, + this.name, + this.value, + }); + + RemainderWarrantyMonths.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + RemainderWarrantyMonths copyWith({ + num id, + String name, + num value, + }) => + RemainderWarrantyMonths( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class ExtendedWarrantyMonths { + ExtendedWarrantyMonths({ + this.id, + this.name, + this.value, + }); + + ExtendedWarrantyMonths.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + ExtendedWarrantyMonths copyWith({ + num id, + String name, + num value, + }) => + ExtendedWarrantyMonths( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class SiteWarrantyMonths { + SiteWarrantyMonths({ + this.id, + this.name, + this.value, + }); + + SiteWarrantyMonths.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + SiteWarrantyMonths copyWith({ + num id, + String name, + num value, + }) => + SiteWarrantyMonths( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class CommissioningStatus { + CommissioningStatus({ + this.id, + this.name, + this.value, + }); + + CommissioningStatus.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + CommissioningStatus copyWith({ + num id, + String name, + num value, + }) => + CommissioningStatus( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class OriginSite { + OriginSite({ + this.id, + this.customerCode, + this.custName, + this.buildings, + }); + + OriginSite.fromJson(dynamic json) { + id = json['id']; + customerCode = json['customerCode']; + custName = json['custName']; + if (json['buildings'] != null) { + buildings = []; + json['buildings'].forEach((v) { + buildings.add(Buildings.fromJson(v)); + }); + } + } + num id; + num customerCode; + String custName; + List buildings; + OriginSite copyWith({ + num id, + num customerCode, + String custName, + List buildings, + }) => + OriginSite( + id: id ?? this.id, + customerCode: customerCode ?? this.customerCode, + custName: custName ?? this.custName, + buildings: buildings ?? this.buildings, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['customerCode'] = customerCode; + map['custName'] = custName; + if (buildings != null) { + map['buildings'] = buildings.map((v) => v.toJson()).toList(); + } + return map; + } +} + +class Buildings { + Buildings({ + this.id, + this.name, + this.value, + this.floors, + }); + + Buildings.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + if (json['floors'] != null) { + floors = []; + json['floors'].forEach((v) { + floors.add(Floors.fromJson(v)); + }); + } + } + num id; + String name; + num value; + List floors; + Buildings copyWith({ + num id, + String name, + num value, + List floors, + }) => + Buildings( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + floors: floors ?? this.floors, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + if (floors != null) { + map['floors'] = floors.map((v) => v.toJson()).toList(); + } + return map; + } +} + +class Floors { + Floors({ + this.id, + this.name, + this.value, + this.departments, + }); + + Floors.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + if (json['departments'] != null) { + departments = []; + json['departments'].forEach((v) { + departments.add(Departments.fromJson(v)); + }); + } + } + num id; + String name; + num value; + List departments; + Floors copyWith({ + num id, + String name, + num value, + List departments, + }) => + Floors( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + departments: departments ?? this.departments, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + if (departments != null) { + map['departments'] = departments.map((v) => v.toJson()).toList(); + } + return map; + } +} + +class Departments { + Departments({ + this.id, + this.name, + }); + + Departments.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + } + num id; + String name; + Departments copyWith({ + num id, + String name, + }) => + Departments( + id: id ?? this.id, + name: name ?? this.name, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + return map; + } +} + +class OriginDepartment { + OriginDepartment({ + this.id, + this.departmentName, + this.departmentCode, + this.ntCode, + }); + + OriginDepartment.fromJson(dynamic json) { + id = json['id']; + departmentName = json['departmentName']; + departmentCode = json['departmentCode']; + ntCode = json['ntCode']; + } + num id; + String departmentName; + String departmentCode; + String ntCode; + OriginDepartment copyWith({ + num id, + String departmentName, + String departmentCode, + String ntCode, + }) => + OriginDepartment( + id: id ?? this.id ?? 0, + departmentName: departmentName ?? this.departmentName, + departmentCode: departmentCode ?? this.departmentCode, + ntCode: ntCode ?? this.ntCode, + ); + Map toJson() { + final map = {}; + map['id'] = id; + map['departmentName'] = departmentName; + map['departmentCode'] = departmentCode; + map['ntCode'] = ntCode; + return map; + } +} + +class Currency { + Currency({ + this.id, + this.name, + this.value, + }); + + Currency.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + Currency copyWith({ + num id, + String name, + num value, + }) => + Currency( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class Department { + Department({ + this.id, + this.departmentName, + this.departmentCode, + this.ntCode, + }); + + Department.fromJson(dynamic json) { + id = json['id']; + departmentName = json['departmentName']; + departmentCode = json['departmentCode']; + ntCode = json['ntCode']; + } + num id; + String departmentName; + String departmentCode; + String ntCode; + Department copyWith({ + num id, + String departmentName, + String departmentCode, + String ntCode, + }) => + Department( + id: id ?? this.id, + departmentName: departmentName ?? this.departmentName, + departmentCode: departmentCode ?? this.departmentCode, + ntCode: ntCode ?? this.ntCode, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['departmentName'] = departmentName; + map['departmentCode'] = departmentCode; + map['ntCode'] = ntCode; + return map; + } +} + +class Floor { + Floor({ + this.id, + this.name, + this.value, + }); + + Floor.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + Floor copyWith({ + num id, + String name, + num value, + }) => + Floor( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class Building { + Building({ + this.id, + this.name, + this.value, + }); + + Building.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + Building copyWith({ + num id, + String name, + num value, + }) => + Building( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class Site { + Site({ + this.id, + this.customerCode, + this.custName, + this.buildings, + }); + + Site.fromJson(dynamic json) { + id = json['id']; + customerCode = json['customerCode']; + custName = json['custName']; + if (json['buildings'] != null) { + buildings = []; + json['buildings'].forEach((v) { + buildings.add(Buildings.fromJson(v)); + }); + } + } + num id; + num customerCode; + String custName; + List buildings; + Site copyWith({ + num id, + num customerCode, + String custName, + List buildings, + }) => + Site( + id: id ?? this.id, + customerCode: customerCode ?? this.customerCode, + custName: custName ?? this.custName, + buildings: buildings ?? this.buildings, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['customerCode'] = customerCode; + map['custName'] = custName; + if (buildings != null) { + map['buildings'] = buildings.map((v) => v.toJson()).toList(); + } + return map; + } +} + +class ParentAsset { + ParentAsset({ + this.id, + this.assetSerialNo, + this.assetNumber, + this.tagCode, + this.systemId, + }); + + ParentAsset.fromJson(dynamic json) { + id = json['id']; + assetSerialNo = json['assetSerialNo']; + assetNumber = json['assetNumber']; + tagCode = json['tagCode']; + systemId = json['systemId']; + } + num id; + String assetSerialNo; + String assetNumber; + String tagCode; + String systemId; + ParentAsset copyWith({ + num id, + String assetSerialNo, + String assetNumber, + String tagCode, + String systemId, + }) => + ParentAsset( + id: id ?? this.id, + assetSerialNo: assetSerialNo ?? this.assetSerialNo, + assetNumber: assetNumber ?? this.assetNumber, + tagCode: tagCode ?? this.tagCode, + systemId: systemId ?? this.systemId, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['assetSerialNo'] = assetSerialNo; + map['assetNumber'] = assetNumber; + map['tagCode'] = tagCode; + map['systemId'] = systemId; + return map; + } +} + +class IsParent { + IsParent({ + this.id, + this.name, + this.value, + }); + + IsParent.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + IsParent copyWith({ + num id, + String name, + num value, + }) => + IsParent( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class OldAsset { + OldAsset({ + this.id, + this.assetSerialNo, + this.assetNumber, + this.tagCode, + this.systemId, + }); + + OldAsset.fromJson(dynamic json) { + id = json['id']; + assetSerialNo = json['assetSerialNo']; + assetNumber = json['assetNumber']; + tagCode = json['tagCode']; + systemId = json['systemId']; + } + num id; + String assetSerialNo; + String assetNumber; + String tagCode; + String systemId; + OldAsset copyWith({ + num id, + String assetSerialNo, + String assetNumber, + String tagCode, + String systemId, + }) => + OldAsset( + id: id ?? this.id ?? 0, + assetSerialNo: assetSerialNo ?? this.assetSerialNo, + assetNumber: assetNumber ?? this.assetNumber, + tagCode: tagCode ?? this.tagCode, + systemId: systemId ?? this.systemId, + ); + Map toJson() { + final map = {}; + map['id'] = id; + map['assetSerialNo'] = assetSerialNo; + map['assetNumber'] = assetNumber; + map['tagCode'] = tagCode; + map['systemId'] = systemId; + return map; + } +} + +class AssetReplace { + AssetReplace({ + this.id, + this.name, + this.value, + }); + + AssetReplace.fromJson(dynamic json) { + id = json['id']; + name = json['name']; + value = json['value']; + } + num id; + String name; + num value; + AssetReplace copyWith({ + num id, + String name, + num value, + }) => + AssetReplace( + id: id ?? this.id, + name: name ?? this.name, + value: value ?? this.value, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['name'] = name; + map['value'] = value; + return map; + } +} + +class Supplier { + Supplier({ + this.id, + this.suppliername, + }); + + Supplier.fromJson(dynamic json) { + id = json['id']; + suppliername = json['suppliername']; + } + num id; + String suppliername; + SupplierModel copyWith({ + num id, + String suppliername, + }) => + SupplierModel( + id: id ?? this.id, + suppliername: suppliername ?? this.suppliername, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['suppliername'] = suppliername; + return map; + } +} + +class ModelDefinition { + ModelDefinition({ + this.id, + this.assetName, + this.modelDefCode, + this.modelName, + this.manufacturerId, + this.manufacturerName, + this.supplierName, + this.replacementDate, + this.essentialEquipement, + this.businessCritical, + this.lifeSpan, + this.modelDefRelatedDefects, + this.suppliers, + }); + + ModelDefinition.fromJson(dynamic json) { + id = json['id']; + assetName = json['assetName']; + modelDefCode = json['modelDefCode']; + modelName = json['modelName']; + manufacturerId = json['manufacturerId']; + manufacturerName = json['manufacturerName']; + supplierName = json['supplierName']; + replacementDate = json['replacementDate']; + essentialEquipement = json['essentialEquipement']; + businessCritical = json['businessCritical']; + lifeSpan = json['lifeSpan']; + if (json['modelDefRelatedDefects'] != null) { + modelDefRelatedDefects = []; + json['modelDefRelatedDefects'].forEach((v) { + modelDefRelatedDefects.add(ModelDefRelatedDefects.fromJson(v)); + }); + } + if (json['suppliers'] != null) { + suppliers = []; + json['suppliers'].forEach((v) { + suppliers.add(Suppliers.fromJson(v)); + }); + } + } + num id; + String assetName; + String modelDefCode; + String modelName; + num manufacturerId; + String manufacturerName; + String supplierName; + String replacementDate; + String essentialEquipement; + String businessCritical; + num lifeSpan; + List modelDefRelatedDefects; + List suppliers; + ModelDefinition copyWith({ + num id, + String assetName, + String modelDefCode, + String modelName, + num manufacturerId, + String manufacturerName, + String supplierName, + String replacementDate, + String essentialEquipement, + String businessCritical, + num lifeSpan, + List modelDefRelatedDefects, + List suppliers, + }) => + ModelDefinition( + id: id ?? this.id, + assetName: assetName ?? this.assetName, + modelDefCode: modelDefCode ?? this.modelDefCode, + modelName: modelName ?? this.modelName, + manufacturerId: manufacturerId ?? this.manufacturerId, + manufacturerName: manufacturerName ?? this.manufacturerName, + supplierName: supplierName ?? this.supplierName, + replacementDate: replacementDate ?? this.replacementDate, + essentialEquipement: essentialEquipement ?? this.essentialEquipement, + businessCritical: businessCritical ?? this.businessCritical, + lifeSpan: lifeSpan ?? this.lifeSpan, + modelDefRelatedDefects: modelDefRelatedDefects ?? this.modelDefRelatedDefects, + suppliers: suppliers ?? this.suppliers, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['assetName'] = assetName; + map['modelDefCode'] = modelDefCode; + map['modelName'] = modelName; + map['manufacturerId'] = manufacturerId; + map['manufacturerName'] = manufacturerName; + map['supplierName'] = supplierName; + map['replacementDate'] = replacementDate; + map['essentialEquipement'] = essentialEquipement; + map['businessCritical'] = businessCritical; + map['lifeSpan'] = lifeSpan; + if (modelDefRelatedDefects != null) { + map['modelDefRelatedDefects'] = modelDefRelatedDefects.map((v) => v.toJson()).toList(); + } + if (suppliers != null) { + map['suppliers'] = suppliers.map((v) => v.toJson()).toList(); + } + return map; + } +} + +class Suppliers { + Suppliers({ + this.id, + this.suppliername, + }); + + Suppliers.fromJson(dynamic json) { + id = json['id']; + suppliername = json['suppliername']; + } + num id; + String suppliername; + Suppliers copyWith({ + num id, + String suppliername, + }) => + Suppliers( + id: id ?? this.id, + suppliername: suppliername ?? this.suppliername, + ); + Map toJson() { + final map = {}; + map['id'] = id ?? 0; + map['suppliername'] = suppliername; + return map; + } +} + +class ModelDefRelatedDefects { + ModelDefRelatedDefects({ + this.id, + this.defectName, + this.workPerformed, + this.estimatedTime, + }); + + ModelDefRelatedDefects.fromJson(dynamic json) { + id = json['id']; + defectName = json['defectName']; + workPerformed = json['workPerformed']; + estimatedTime = json['estimatedTime']; + } + num id; + String defectName; + String workPerformed; + String estimatedTime; + ModelDefRelatedDefects copyWith({ + num id, + String defectName, + String workPerformed, + String estimatedTime, + }) => + ModelDefRelatedDefects( + id: id ?? this.id ?? 0, + defectName: defectName ?? this.defectName, + workPerformed: workPerformed ?? this.workPerformed, + estimatedTime: estimatedTime ?? this.estimatedTime, + ); Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['name'] = this.name; - return data; + final map = {}; + map['id'] = id; + map['defectName'] = defectName; + map['workPerformed'] = workPerformed; + map['estimatedTime'] = estimatedTime; + return map; } } diff --git a/lib/models/service_request/service_request.dart b/lib/models/service_request/service_request.dart index a884da6..58fc280 100644 --- a/lib/models/service_request/service_request.dart +++ b/lib/models/service_request/service_request.dart @@ -15,6 +15,7 @@ class ServiceRequest { int hospitalId; String departmentName; String engineerName; + String engineerId; String date; String audio; int statusValue; @@ -57,6 +58,7 @@ class ServiceRequest { this.deviceId, this.audio, this.engineerName, + this.engineerId, this.viewReport = false, this.deviceModel, this.engineerMobile, @@ -102,6 +104,7 @@ class ServiceRequest { statusValue: parsedJson["status"] == null ? null : parsedJson["status"]["value"], departmentName: parsedJson["asset"]["department"] != null ? parsedJson["asset"]["department"]["name"] : "", engineerName: parsedJson["assignedEmployee"] == null ? null : parsedJson["assignedEmployee"]["name"], + engineerId: parsedJson["assignedEmployee"] == null ? null : parsedJson["assignedEmployee"]["id"], hospitalId: parsedJson["asset"]["site"]["id"], reportID: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["workOrderId"] : null, viewReport: parsedJson["workOrder"] != null, diff --git a/lib/models/subtitle.dart b/lib/models/subtitle.dart index 7b01517..b5b84e4 100644 --- a/lib/models/subtitle.dart +++ b/lib/models/subtitle.dart @@ -229,6 +229,8 @@ class Subtitle { String travelingExpense; String startDate; String endDate; + String requestedQuantity; + String deliveredQuantity; String destinationSite; String building; String floor; @@ -439,6 +441,8 @@ class Subtitle { @required this.travelingExpense, @required this.startDate, @required this.endDate, + @required this.requestedQuantity, + @required this.deliveredQuantity, @required this.assetNumber, @required this.destinationSite, @required this.building, @@ -643,6 +647,8 @@ class Subtitle { travelingExpense: parsedJson["travelingExpense"], startDate: parsedJson["startDate"], endDate: parsedJson["endDate"], + requestedQuantity: parsedJson["requestedQuantity"], + deliveredQuantity: parsedJson["deliveredQuantity"], destinationSite: parsedJson["destinationSite"], building: parsedJson["building"], floor: parsedJson["floor"], diff --git a/lib/models/timer_model.dart b/lib/models/timer_model.dart index c6434f9..907d006 100644 --- a/lib/models/timer_model.dart +++ b/lib/models/timer_model.dart @@ -2,6 +2,7 @@ class TimerModel { DateTime startAt; DateTime endAt; int durationInSecond; + bool stopped; - TimerModel({this.startAt, this.endAt, this.durationInSecond}); + TimerModel({this.startAt, this.endAt, this.durationInSecond, this.stopped}); } diff --git a/lib/views/pages/device_transfer/device_transfer_details.dart b/lib/views/pages/device_transfer/device_transfer_details.dart index b7726ff..74ff48e 100644 --- a/lib/views/pages/device_transfer/device_transfer_details.dart +++ b/lib/views/pages/device_transfer/device_transfer_details.dart @@ -86,11 +86,15 @@ class _DeviceTransferDetailsState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ RequestInfoRow( - title: _subtitle.title, + title: "Id", + info: widget.model.id?.toString(), + ), + RequestInfoRow( + title: _subtitle.assetName, info: widget.model.title, ), RequestInfoRow( - title: _subtitle.device, + title: _subtitle.assetSN, info: widget.model.device.serialNumber, ), RequestInfoRow( diff --git a/lib/views/pages/device_transfer/update_device_transfer.dart b/lib/views/pages/device_transfer/update_device_transfer.dart index 9b2c803..061b5d2 100644 --- a/lib/views/pages/device_transfer/update_device_transfer.dart +++ b/lib/views/pages/device_transfer/update_device_transfer.dart @@ -19,8 +19,7 @@ import 'package:test_sa/views/widgets/status/gas_refill/gas_status.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import '../../../../controllers/localization/localization.dart'; -import '../../../controllers/validator/validator.dart'; -import '../../widgets/date_and_time/time_picker.dart'; +import '../../widgets/timer/app_timer.dart'; class UpdateDeviceTransfer extends StatefulWidget { final DeviceTransfer model; @@ -46,6 +45,13 @@ class _UpdateDeviceTransferState extends State { final GlobalKey _scaffoldKey = GlobalKey(); _update() async { + if (_formModel?.workingHours == null || _formModel.workingHours.isEmpty) { + await Fluttertoast.showToast(msg: "Working Hours Timer Isn't Started"); + return; + } else if ((_formModel?.timer?.stopped ?? false) == false) { + await Fluttertoast.showToast(msg: "Stop The Timer"); + return; + } _validate = true; if (!_formKey.currentState.validate()) { setState(() {}); @@ -152,96 +158,23 @@ class _UpdateDeviceTransferState extends State { const SizedBox( height: 16, ), + ASubTitle(_subtitle.workingHours), + const SizedBox(height: 8), Row( children: [ Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const ASubTitle("Start of Work"), - SizedBox( - height: 8 * AppStyle.getScaleFactor(context), - ), - ADateTimePicker( - date: _formModel.startDate, - from: DateTime.now().subtract(const Duration(days: 365)), - to: DateTime.now().add(const Duration(days: 365)), - onDateTimePicker: (date) { - _formModel.startDate = date; - _formModel.workingHours = ((_formModel.endDate?.difference(_formModel.startDate)?.inMinutes ?? 0) / 60)?.toStringAsFixed(2)?.toString() ?? 0; - setState(() {}); - }, - ), - ], - ), - ), - const SizedBox(width: 8), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const ASubTitle("End of Work"), - SizedBox( - height: 8 * AppStyle.getScaleFactor(context), - ), - ADateTimePicker( - date: _formModel.endDate, - from: DateTime.now().subtract(const Duration(days: 365)), - to: DateTime.now().add(const Duration(days: 365)), - onDateTimePicker: (date) { - _formModel.endDate = date; - _formModel.workingHours = ((_formModel.endDate?.difference(_formModel.startDate)?.inMinutes ?? 0) / 60)?.toStringAsFixed(2)?.toString() ?? 0; - setState(() {}); - }, - ), - ], + child: AppTimer( + timer: _formModel.timer, + onChange: (timer) async { + _formModel.timer = timer; + _formModel.workingHours = (((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0"; + return true; + }, ), ), ], ), - const SizedBox(height: 4), - ASubTitle(_subtitle.workingHours), - const SizedBox(height: 4), - ATextFormField( - initialValue: null, - textAlign: TextAlign.center, - hintText: _formModel.startDate == null ? "0" : ((_formModel.endDate?.difference(_formModel.startDate)?.inMinutes ?? 0) / 60)?.toStringAsFixed(2)?.toString() ?? "0", - enable: false, - style: Theme.of(context).textTheme.subtitle1, - //validator: (value) => Validator.isNumeric(value) ? null : _subtitle.requiredWord, - textInputType: TextInputType.number, - onSaved: (value) { - // _serviceReport.workHours = value; - }, - ), - // ASubTitle(_subtitle.workingHours), - // const SizedBox( - // height: 4, - // ), - // ATextFormField( - // initialValue: _formModel?.workingHours, - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.number, - // onSaved: (value) { - // _formModel.workingHours = value; - // }, - // ), - // const SizedBox(height: 8,), - // const ASubTitle("Sender Department"), - // if(_validate && _formModel.senderDepartment == null) - // ASubTitle(_subtitle.requiredWord,color: Colors.red,), - // const SizedBox(height: 4,), - // DepartmentButton( - // department: _formModel.senderDepartment, - // onDepartmentPick: (department){ - // _formModel.senderDepartment = department; - // setState(() {}); - // }, - // ), - const SizedBox( - height: 8, - ), + const SizedBox(height: 16), ASubTitle(_subtitle.status), const SizedBox( height: 4, @@ -249,6 +182,7 @@ class _UpdateDeviceTransferState extends State { GasStatusMenu( initialValue: _formModel.status, onSelect: (status) { + if (status == null) return; _formModel.status = status; setState(() {}); }, diff --git a/lib/views/pages/login.dart b/lib/views/pages/login.dart index 65585b8..e77b67d 100644 --- a/lib/views/pages/login.dart +++ b/lib/views/pages/login.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/localization/localization.dart'; @@ -114,9 +115,16 @@ class _LoginState extends State { host: _settingProvider.host, ); if (status >= 200 && status < 300) { - _settingProvider.setUser(_userProvider.user); + if(_userProvider.user.isAuthenticated ?? false) { + _settingProvider.setUser(_userProvider.user); + Navigator.of(context).pushNamed(LandPage.id); + } else { + Fluttertoast.showToast(msg: _userProvider.user.message); + } + + // if (_userProvider.user.isActive) - Navigator.of(context).pushNamed(LandPage.id); + // else // Fluttertoast.showToast(msg: _subtitle.activationAlert); } else { diff --git a/lib/views/pages/sub_workorder/create_sub_workorder_page.dart b/lib/views/pages/sub_workorder/create_sub_workorder_page.dart new file mode 100644 index 0000000..fdfd67e --- /dev/null +++ b/lib/views/pages/sub_workorder/create_sub_workorder_page.dart @@ -0,0 +1,363 @@ +import 'dart:convert'; +import 'dart:developer'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:provider/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_types_provider.dart'; +import 'package:test_sa/extensions/widget_extensions.dart'; +import 'package:test_sa/models/call_request_for_work_order_model.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/models/service_report.dart'; +import 'package:test_sa/models/service_request/search_work_order.dart'; +import 'package:test_sa/views/app_style/colors.dart'; +import 'package:test_sa/views/pages/sub_workorder/spare_parts_details_bottom_sheet.dart'; +import 'package:test_sa/views/pages/sub_workorder/work_order_details_bottom_sheet.dart'; +import 'package:test_sa/views/pages/sub_workorder/workorder_details.dart'; +import 'package:test_sa/views/widgets/loaders/app_loading.dart'; +import 'package:test_sa/views/widgets/status/service_request/service_request_defect_types_mune.dart'; + +import '../../../controllers/api_routes/http_status_manger.dart'; +import '../../../controllers/localization/localization.dart'; +import '../../../controllers/providers/api/status_drop_down/report/service_report_fault_description_provider.dart'; +import '../../../models/subtitle.dart'; +import '../../widgets/app_text_form_field.dart'; +import '../../widgets/buttons/app_back_button.dart'; +import '../../widgets/buttons/app_button.dart'; +import '../../widgets/date_and_time/date_picker.dart'; +import '../../widgets/images/mini_one_image_picker.dart'; +import '../../widgets/status/report/service_report_fault_description.dart'; +import '../../widgets/status/report/service_report_reasons.dart'; +import '../../widgets/titles/app_sub_title.dart'; + +class CreateSubWorkOrderPage extends StatefulWidget { + static const id = "/CreateSubWorkOrder"; + final SearchWorkOrder workOrder; + + const CreateSubWorkOrderPage({this.workOrder, Key key}) : super(key: key); + + @override + State createState() => _CreateSubWorkOrderPageState(); +} + +class _CreateSubWorkOrderPageState extends State { + final GlobalKey _formKey = GlobalKey(); + SearchWorkOrder _subWorkOrders; + Lookup _serviceReportReason = const Lookup(); + ServiceReport _serviceReport; + File _image; + bool _isLoading = false; + bool _validate = false; + + @override + void initState() { + _subWorkOrders = SearchWorkOrder( + assignedEmployee: widget?.workOrder?.callRequest?.assignedEmployee, + callRequest: CallRequest(id: widget?.workOrder?.callRequest?.id), + currentSituation: null, + supplier: null, + ); + _serviceReport = ServiceReport(id: widget.workOrder.id, type: widget.workOrder.assetType, equipmentStatus: widget.workOrder.equipmentStatus); + _isLoading = true; + super.initState(); + } + + var assetTypesProvider; + CallRequestForWorkOrder _callRequestForWorkOrder; + + Future getAssetType() async { + //if (assetTypesProvider == null) { + Provider.of(context, listen: false).reset(); + assetTypesProvider = Provider.of(context, listen: false); + _callRequestForWorkOrder = await Provider.of(context).getCallRequestForWorkOrder(callId: widget.workOrder.callRequest.id.toString()); + await assetTypesProvider.getTypes(); + _subWorkOrders?.assetType = assetTypesProvider.statuses?.firstWhere( + (element) => element.value == _callRequestForWorkOrder?.assetType, + orElse: () => null, + ); + setState(() { + _isLoading = false; + }); + //} + } + + @override + Widget build(BuildContext context) { + if (_callRequestForWorkOrder == null) { + getAssetType(); + } + final Subtitle subtitle = AppLocalization.of(context).subtitle; + + return Scaffold( + body: SafeArea( + child: _isLoading + ? const ALoading() + : Column( + children: [ + SingleChildScrollView( + child: Form( + key: _formKey, + child: Column( + children: [ + Container( + color: AColors.primaryColor, + padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), + child: Column( + children: [ + Row( + children: [ + const ABackButton(), + Expanded( + child: Center( + child: Text( + "New Work Order", + style: Theme.of(context).textTheme.titleLarge.copyWith(color: AColors.white, fontStyle: FontStyle.italic), + ), + ), + ), + const SizedBox( + width: 48, + ) + ], + ), + ], + ), + ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16), + child: Column( + children: [ + WorkOrderDetails(item: widget.workOrder, assetType: _subWorkOrders?.assetType), + const SizedBox(height: 8), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const ASubTitle("Equipment status"), + if (_validate && _subWorkOrders?.equipmentStatus == null) + ASubTitle( + subtitle.requiredWord, + color: Colors.red, + ), + const SizedBox( + height: 4, + ), + ServiceRequestDefectTypesMenu( + initialValue: _serviceReport.equipmentStatus, + onSelect: (status) { + _subWorkOrders.equipmentStatus = status; + _serviceReport.equipmentStatus = status; + setState(() {}); + }, + ), + ], + ), + const SizedBox(height: 8), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const ASubTitle("Return to Service"), + if (_validate && _subWorkOrders.visitDate == null) + ASubTitle( + subtitle.requiredWord, + color: Colors.red, + ), + const SizedBox( + height: 4, + ), + Row( + children: [ + Expanded( + child: ADatePicker( + date: DateTime.tryParse(_subWorkOrders.visitDate ?? ""), + from: DateTime(1950), + onDatePicker: (date) { + _subWorkOrders.visitDate = date?.toIso8601String(); + setState(() {}); + }, + ), + ), + ], + ), + ], + ), + const SizedBox(height: 8), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ASubTitle("Failure ${subtitle.reasons}"), + if (_validate && _subWorkOrders.reason == null) + ASubTitle( + subtitle.requiredWord, + color: Colors.red, + ), + const SizedBox( + height: 4, + ), + ServiceReportReasonsMenu( + initialValue: _serviceReportReason, + onSelect: (status) { + _serviceReportReason = status; + _subWorkOrders.reason = status; + setState(() {}); + }, + ), + ], + ), + const SizedBox(height: 8), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ASubTitle(subtitle.faultDescription), + if (_validate && _subWorkOrders.faultDescription == null) + ASubTitle( + subtitle.requiredWord, + color: Colors.red, + ), + const SizedBox( + height: 4, + ), + ServiceReportFaultDescription( + requestId: widget.workOrder?.callRequest?.id?.toString(), + initialValue: _subWorkOrders?.faultDescription, + onSelect: (status) { + _subWorkOrders.faultDescription = status; + if (mounted) setState(() {}); + }, + ), + ], + ), + const SizedBox(height: 8), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const ASubTitle("Solution"), + const SizedBox(height: 4), + ATextFormField(labelText: _subWorkOrders?.faultDescription?.workPerformed ?? "", textInputType: TextInputType.multiline, enable: false), + ], + ), + const SizedBox(height: 8), + InkWell( + onTap: () async { + await showModalBottomSheet( + context: context, + useSafeArea: true, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (context) => WorkOrderDetailsBottomSheet(subWorkOrder: _subWorkOrders), + ); + log(_subWorkOrders?.toJson()?.toString()); + }, + child: Card( + child: ListTile( + title: Row( + children: [ + Text( + "WO Details", + style: Theme.of(context).textTheme.bodyMedium, + ), + const Text("*", style: TextStyle(color: Colors.red)), + ], + ), + trailing: const Icon(Icons.arrow_forward_ios, size: 14, color: AColors.primaryColor), + ), + ), + ), + const SizedBox(height: 8), + InkWell( + onTap: () async { + await showModalBottomSheet( + context: context, + useSafeArea: true, + isScrollControlled: true, + backgroundColor: Colors.transparent, + builder: (context) => SparePartsBottomSheet(subWorkOrder: _subWorkOrders), + ); + log(_subWorkOrders?.toJson()?.toString()); + }, + child: Card( + child: ListTile( + title: Row( + children: [ + Text( + "Spare Parts", + style: Theme.of(context).textTheme.bodyMedium, + ), + const Text("*", style: TextStyle(color: Colors.red)), + ], + ), + trailing: const Icon(Icons.arrow_forward_ios, size: 14, color: AColors.primaryColor), + ), + ), + ), + const SizedBox(height: 8), + AMiniOneImagePicker( + image: _image, + onPick: (image) { + _image = image; + _subWorkOrders.attachmentsWorkOrder ??= []; + _subWorkOrders.attachmentsWorkOrder.add(AttachmentsWorkOrder(name: "${image.path.split("/").last}|${base64Encode(image.readAsBytesSync())}")); + }, + ), + const SizedBox(height: 50), + ], + ), + ), + ], + ), + ), + ).expanded, + Padding( + padding: const EdgeInsets.all(16.0), + child: AButton( + text: subtitle.create, + onPressed: () async { + _subWorkOrders.parentWOId = widget.workOrder.id; + _validate = true; + setState(() {}); + if (validate()) { + if (_subWorkOrders.timer?.startAt == null || _subWorkOrders.timer?.endAt == null) { + Fluttertoast.showToast(msg: "Working hours required"); + return; + } else if (_subWorkOrders.calllastSituation == null) { + Fluttertoast.showToast(msg: "${subtitle.callLastSituation} required"); + return; + } + _validate = false; + _isLoading = true; + setState(() {}); + if (_formKey.currentState?.validate() ?? false) {} + _formKey.currentState?.save(); + final serviceRequestsProvider = Provider.of(context, listen: false); + final status = await serviceRequestsProvider.createSubWorkOrder(workOrder: _subWorkOrders); + _isLoading = false; + setState(() {}); + if (status >= 200 && status < 300) { + Fluttertoast.showToast(msg: subtitle.requestCompleteSuccessfully); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + } else { + String errorMessage = HttpStatusManger.getStatusMessage(status: serviceRequestsProvider.stateCode, subtitle: subtitle); + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text(errorMessage), + )); + } + } + }, + ), + ), + ], + ), + ), + ); + } + + bool validate() { + if (_subWorkOrders.faultDescription == null || _subWorkOrders.reason == null || _subWorkOrders.equipmentStatus == null || _subWorkOrders.visitDate == null) { + return false; + } else { + return true; + } + } +} diff --git a/lib/views/pages/sub_workorder/search_sub_workorder_page.dart b/lib/views/pages/sub_workorder/search_sub_workorder_page.dart new file mode 100644 index 0000000..952c831 --- /dev/null +++ b/lib/views/pages/sub_workorder/search_sub_workorder_page.dart @@ -0,0 +1,226 @@ +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/service_requests_provider.dart'; +import 'package:test_sa/models/engineer.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/models/service_request/search_work_order.dart'; +import 'package:test_sa/models/subtitle.dart'; +import 'package:test_sa/views/pages/sub_workorder/workorder_list.dart'; +import 'package:test_sa/views/widgets/app_text_form_field.dart'; +import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; +import 'package:test_sa/views/widgets/hospitals/hospital_auto_complete_field_new.dart'; + +import '../../../controllers/api_routes/http_status_manger.dart'; +import '../../../controllers/localization/localization.dart'; +import '../../../controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart'; +import '../../app_style/colors.dart'; +import '../../widgets/buttons/app_back_button.dart'; +import '../../widgets/buttons/app_button.dart'; +import '../../widgets/status/report/service_report_all_users.dart'; +import '../../widgets/status/report/service_report_maintenance_situation.dart'; +import '../../widgets/status/report/service_report_visit_date_operator.dart'; +import '../../widgets/titles/app_sub_title.dart'; + +class SearchSubWorkOrderPage extends StatefulWidget { + static String id = "/SubWorkOrderPage"; + const SearchSubWorkOrderPage({Key key}) : super(key: key); + + @override + State createState() => _SearchSubWorkOrderPageState(); +} + +class _SearchSubWorkOrderPageState extends State { + final GlobalKey _formKey = GlobalKey(); + final SearchWorkOrder _searchWorkOrders = SearchWorkOrder(); + Subtitle _subtitle; + bool _isLoading = false; + String _callerId = "", _site = ""; + Lookup _dateOperator; + + @override + void initState() { + super.initState(); + if (context.mounted) { + Provider.of(context, listen: false).reset(); + } + } + + @override + Widget build(BuildContext context) { + _subtitle = AppLocalization.of(context).subtitle; + return Scaffold( + body: SafeArea( + child: SingleChildScrollView( + child: Column( + children: [ + Container( + color: AColors.primaryColor, + padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), + child: Column( + children: [ + Row( + children: [ + const ABackButton(), + Expanded( + child: Center( + child: Text( + "Search Work Order", + style: Theme.of(context).textTheme.titleLarge.copyWith(color: AColors.white, fontStyle: FontStyle.italic), + ), + ), + ), + const SizedBox( + width: 48, + ) + ], + ), + ], + ), + ), + const SizedBox(height: 8), + Form( + key: _formKey, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ATextFormField( + labelText: "Caller ID", + onSaved: (value) { + _callerId = value; + }, + ), + const SizedBox(height: 16), + ATextFormField( + labelText: "Asset S.N.", + textInputType: TextInputType.number, + onSaved: (value) { + if (value != null) { + _searchWorkOrders.assetType = Lookup(name: value); + } + }, + ), + const SizedBox(height: 16), + ATextFormField( + labelText: "Work Order No.", + onSaved: (value) { + _searchWorkOrders.workOrderNo = value; + }, + ), + const SizedBox(height: 16), + ASubTitle(_subtitle.assignedEmployee), + const SizedBox(height: 4), + ServiceReportAllUsers( + initialValue: _searchWorkOrders.assignedEmployee == null ? null : Engineer(id: _searchWorkOrders.assignedEmployee.id, name: _searchWorkOrders.assignedEmployee.name), + onSelect: (engineer) { + _searchWorkOrders.assignedEmployee = AssignedEmployee(id: engineer.id, name: engineer.name); + }, + ), + const SizedBox(height: 16), + const ASubTitle("Maintenance Situation"), + const SizedBox(height: 4), + ServiceReportMaintenanceSituation( + initialValue: _searchWorkOrders.calllastSituation, + onSelect: (status) { + if (status?.value == 12 || _searchWorkOrders.calllastSituation?.value == 12) { + _searchWorkOrders.calllastSituation = status; + setState(() {}); + } else { + _searchWorkOrders.calllastSituation = status; + } + }, + woId: _searchWorkOrders.id?.toString(), + ), + const SizedBox(height: 16), + HospitalAutoCompleteField( + initialValue:_site, + onSearch: (value) { + _site = value.name; + setState(() { + + }); + }, + ), + const SizedBox(height: 16), + ASubTitle(_subtitle.visitDate), + const SizedBox(height: 4), + ServiceReportVisitDateOperator( + initialValue: _dateOperator, + onSelect: (status) { + _dateOperator = status; + }, + ), + Row( + children: [ + Expanded( + child: ADatePicker( + date: DateTime.tryParse(_searchWorkOrders.visitDate ?? ""), + from: DateTime(1950), + onDatePicker: (date) { + _searchWorkOrders.visitDate = date?.toIso8601String(); + setState(() {}); + }, + ), + ), + ], + ), + ], + ), + ), + ), + const SizedBox(height: 100), + ], + ), + ), + ), + floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat, + floatingActionButton: _isLoading + ? const CircularProgressIndicator() + : Padding( + padding: const EdgeInsets.symmetric(horizontal: 16), + child: AButton( + text: _subtitle.search, + onPressed: () async { + _isLoading = true; + setState(() {}); + if (_formKey.currentState?.validate() ?? false) {} + _formKey.currentState?.save(); + final serviceRequestsProvider = Provider.of(context, listen: false); + serviceRequestsProvider.reset(); + final List woList = await serviceRequestsProvider.searchForWorkOrders( + _searchWorkOrders, + _callerId, + _dateOperator, + _site, + ); + _isLoading = false; + setState(() {}); + if (serviceRequestsProvider.stateCode >= 200 && serviceRequestsProvider.stateCode < 300) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => WorkOrderList( + items: woList, + onLazyLoading: () async { + return await serviceRequestsProvider.searchForWorkOrders( + _searchWorkOrders, + _callerId, + _dateOperator, + _site, + ); + }, + ), + ), + ); + } else { + String errorMessage = HttpStatusManger.getStatusMessage(status: serviceRequestsProvider.stateCode, subtitle: _subtitle); + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(errorMessage))); + } + }, + ), + ), + ); + } +} diff --git a/lib/views/pages/sub_workorder/spare_parts_details_bottom_sheet.dart b/lib/views/pages/sub_workorder/spare_parts_details_bottom_sheet.dart new file mode 100644 index 0000000..e7d5fc9 --- /dev/null +++ b/lib/views/pages/sub_workorder/spare_parts_details_bottom_sheet.dart @@ -0,0 +1,173 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/models/part.dart'; +import 'package:test_sa/models/service_request/search_work_order.dart'; +import 'package:test_sa/views/app_style/colors.dart'; + +import '../../../controllers/localization/localization.dart'; +import '../../../models/subtitle.dart'; +import '../../app_style/sizing.dart'; +import '../../widgets/buttons/app_button.dart'; +import '../../widgets/parts/auto_complete_parts_field.dart'; +import '../../widgets/parts/part_item.dart'; +import '../../widgets/titles/app_sub_title.dart'; + +class SparePartsBottomSheet extends StatefulWidget { + final SearchWorkOrder subWorkOrder; + const SparePartsBottomSheet({this.subWorkOrder, Key key}) : super(key: key); + + @override + State createState() => _SparePartsBottomSheetState(); +} + +class _SparePartsBottomSheetState extends State { + final GlobalKey _formKey = GlobalKey(); + final SearchWorkOrder _workOrder = SearchWorkOrder(); + bool _validate = false; + + @override + void initState() { + super.initState(); + _workOrder.copyFrom(widget.subWorkOrder); + } + + @override + void dispose() { + _workOrder.sparePartsWorkOrders = widget.subWorkOrder.sparePartsWorkOrders; + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final size = MediaQuery.of(context).size; + final Subtitle subtitle = AppLocalization.of(context).subtitle; + return Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + child: ClipRRect( + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(15), + topRight: Radius.circular(15), + ), + clipBehavior: Clip.antiAliasWithSaveLayer, + child: Container( + color: Colors.white, + height: size.height * 0.9, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const ASubTitle("Spare Parts"), + const SizedBox(height: 8), + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + margin: const EdgeInsets.symmetric(vertical: 16), + decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: const [ + BoxShadow( + color: AColors.grey, + offset: Offset(0, -1), + ) + ]), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Expanded( + flex: 3, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ASubTitle(subtitle.partNumber), + _validate && _workOrder.sparePartsWorkOrders == null + ? ASubTitle( + subtitle.requiredWord, + color: Colors.red, + ) + : const SizedBox.shrink(), + const SizedBox(height: 4), + AutoCompletePartsField( + onPick: (part) { + _workOrder.sparePartsWorkOrders ??= []; + _workOrder.sparePartsWorkOrders.add(SparePartsWorkOrders( + id: part.reportPartID, + qty: part.quantity, + sparePart: SparePart(id: part.id, partName: part.name, partNo: part.code), + )); + }, + ), + ], + ), + ), + ], + ), + SizedBox( + height: 8 * AppStyle.getScaleFactor(context), + ), + if (_workOrder.sparePartsWorkOrders?.isNotEmpty ?? false) + Row( + children: [ + Expanded(flex: 3, child: Text(subtitle.number)), + Expanded(flex: 1, child: Text(subtitle.quantity)), + ], + ), + if (_workOrder.sparePartsWorkOrders?.isNotEmpty ?? false) + Column( + children: List.generate( + _workOrder.sparePartsWorkOrders?.length, + (index) { + final spare = _workOrder.sparePartsWorkOrders[index]; + Part part = Part( + id: spare.sparePart?.id, + reportPartID: spare.id, + code: spare.sparePart?.partNo, + name: spare.sparePart?.partName, + quantity: spare.qty, + ); + return PartItem( + part: part, + onEdit: (qty) { + spare.qty = qty; + }, + onDelete: (part) { + _workOrder.sparePartsWorkOrders.remove(spare); + setState(() {}); + }, + ); + }, + ), + ), + const SizedBox(height: 16), + ], + ), + ), + const SizedBox(height: 24), + ], + ), + ), + ), + ), + AButton( + text: subtitle.submit, + onPressed: () async { + _formKey.currentState.save(); + widget.subWorkOrder.copyFrom(_workOrder); + Navigator.pop(context); + }, + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/views/pages/sub_workorder/work_order_details_bottom_sheet.dart b/lib/views/pages/sub_workorder/work_order_details_bottom_sheet.dart new file mode 100644 index 0000000..df6e58f --- /dev/null +++ b/lib/views/pages/sub_workorder/work_order_details_bottom_sheet.dart @@ -0,0 +1,176 @@ +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/models/service_request/search_work_order.dart'; +import 'package:test_sa/models/subtitle.dart'; +import 'package:test_sa/views/widgets/app_text_form_field.dart'; +import 'package:test_sa/views/widgets/buttons/app_button.dart'; +import 'package:test_sa/views/widgets/status/report/service_report_assistant_employee_menu.dart'; +import 'package:test_sa/views/widgets/status/report/service_report_maintenance_situation.dart'; +import 'package:test_sa/views/widgets/status/report/service_report_repair_location.dart'; + +import '../../../controllers/localization/localization.dart'; +import '../../../controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart'; +import '../../widgets/timer/app_timer.dart'; +import '../../widgets/titles/app_sub_title.dart'; + +class WorkOrderDetailsBottomSheet extends StatefulWidget { + final SearchWorkOrder subWorkOrder; + const WorkOrderDetailsBottomSheet({this.subWorkOrder, Key key}) : super(key: key); + + @override + State createState() => _WorkOrderDetailsBottomSheetState(); +} + +class _WorkOrderDetailsBottomSheetState extends State { + final GlobalKey _formKey = GlobalKey(); + final SearchWorkOrder _workOrder = SearchWorkOrder(); + + @override + void initState() { + super.initState(); + + _workOrder.copyFrom(widget.subWorkOrder); + if (context.mounted) { + Provider.of(context, listen: false).reset(); + } + } + + @override + Widget build(BuildContext context) { + final size = MediaQuery.of(context).size; + final Subtitle subtitle = AppLocalization.of(context).subtitle; + return Padding( + padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), + child: ClipRRect( + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(15), + topRight: Radius.circular(15), + ), + clipBehavior: Clip.antiAliasWithSaveLayer, + child: Container( + color: Colors.white, + height: size.height * 0.9, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20), + child: Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const ASubTitle("WO Details"), + const SizedBox(height: 8), + Expanded( + child: Padding( + padding: const EdgeInsets.all(8.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: 8), + ATextFormField(enable: false, hintText: "Assigned Employee: ${_workOrder.assignedEmployee?.name}"), + const SizedBox(height: 8), + const ASubTitle("Assistant Employee"), + const SizedBox(height: 4), + ServiceReportAssistantEmployeeMenu( + initialValue: (_workOrder.assistantEmployees?.isNotEmpty ?? false) ? _workOrder.assistantEmployees?.first : null, + onSelect: (assistantsEmployee) { + _workOrder.assistantEmployees = [assistantsEmployee]; + }, + ), + const SizedBox(height: 8), + ASubTitle(subtitle.workingHours), + const SizedBox(height: 8), + Row( + children: [ + Expanded( + child: AppTimer( + timer: _workOrder.timer, + onChange: (timer) async { + _workOrder.timer = timer; + _workOrder.workingHours = num.tryParse((((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0"); + return true; + }, + ), + ), + ], + ), + const SizedBox(height: 16), + ATextFormField( + labelText: "Travel Hours", + initialValue: _workOrder.travelingHours?.toString(), + textInputType: TextInputType.number, + onSaved: (value) { + _workOrder.travelingHours = num.tryParse(value); + }, + ), + const SizedBox(height: 8), + ATextFormField( + labelText: "Travel Expense", + initialValue: _workOrder.travelingExpenses?.toString(), + textInputType: TextInputType.number, + onSaved: (value) { + _workOrder.travelingExpenses = num.tryParse(value); + }, + ), + const SizedBox(height: 8), + ASubTitle(subtitle.callLastSituation), + const SizedBox(height: 4), + ServiceReportMaintenanceSituation( + initialValue: _workOrder.calllastSituation, + onSelect: (status) { + if (status?.value == 12 || _workOrder.calllastSituation?.value == 12) { + _workOrder.calllastSituation = status; + setState(() {}); + } else { + _workOrder.calllastSituation = status; + } + }, + woId: widget.subWorkOrder?.callRequest?.id?.toString(), + ), + const SizedBox(height: 8), + const ASubTitle("Repair Location"), + const SizedBox(height: 4), + ServiceReportRepairLocation( + initialValue: _workOrder.repairLocation, + onSelect: (status) { + _workOrder.repairLocation = status; + }, + ), + const SizedBox(height: 8), + ATextFormField( + labelText: "Technical Comments", + initialValue: _workOrder.comment, + textInputType: TextInputType.multiline, + onSaved: (value) { + _workOrder.comment = value; + }, + ), + const SizedBox(height: 24), + ], + ), + ), + ), + ), + AButton( + text: subtitle.submit, + onPressed: () async { + if (_workOrder?.workingHours == null) { + await Fluttertoast.showToast(msg: "Working Hours Timer Isn't Started"); + return; + } else if ((_workOrder?.timer?.stopped ?? false) == false) { + await Fluttertoast.showToast(msg: "Stop The Timer"); + return; + } + _formKey.currentState.save(); + widget.subWorkOrder.copyFrom(_workOrder); + Navigator.pop(context); + }, + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/views/pages/sub_workorder/workorder_details.dart b/lib/views/pages/sub_workorder/workorder_details.dart new file mode 100644 index 0000000..6383f58 --- /dev/null +++ b/lib/views/pages/sub_workorder/workorder_details.dart @@ -0,0 +1,81 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/models/lookup.dart'; + +import '../../../controllers/localization/localization.dart'; +import '../../../models/service_request/search_work_order.dart'; +import '../../../models/subtitle.dart'; +import '../../app_style/colors.dart'; +import '../../app_style/sizing.dart'; + +class WorkOrderDetails extends StatelessWidget { + final SearchWorkOrder item; + Lookup assetType; + + WorkOrderDetails({@required this.item, this.assetType, Key key}) : super(key: key); + Subtitle _subtitle; + + @override + Widget build(BuildContext context) { + _subtitle = AppLocalization.of(context).subtitle; + return Column( + children: [ + Container( + padding: EdgeInsets.all(10), + decoration: BoxDecoration( + color: AColors.inputFieldBackgroundColor, + border: Border.all( + color: Color(0xffefefef), + ), + borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), + // boxShadow: const [ + // AppStyle.boxShadow + // ] + ), + child: Column( + children: [ + _buildRow(_subtitle.callId, item.callRequest?.id?.toString() ?? "", context), + _buildRow(_subtitle.assetNumber, item.callRequest?.asset?.assetNumber ?? "", context), + _buildRow("WO No", item.workOrderNo, context), + _buildRow(_subtitle.assetName, item.callRequest?.asset?.assetNumber ?? '', context), + _buildRow(_subtitle.department, item.callRequest?.asset?.department ?? '', context), + _buildRow(_subtitle.assetSN, item.callRequest?.asset?.assetSerialNo ?? '', context), + _buildRow(_subtitle.model, item.callRequest?.asset?.modelDefinition?.modelName ?? "", context), + _buildRow("Manufacturer", item.callRequest?.asset?.modelDefinition?.manufacturerName ?? "", context), + _buildRow(_subtitle.site, item.callRequest?.asset?.site?.custName ?? "", context), + ], + ), + ), + const SizedBox(height: 8), + Container( + padding: EdgeInsets.all(10), + height: 55, + decoration: BoxDecoration( + color: AColors.inputFieldBackgroundColor, + border: Border.all( + color: Color(0xffefefef), + ), + borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), + ), + child: _buildRow("Asset Type", assetType?.name ?? (item.assetType?.name ?? ""), context), + ) + ], + ); + } + + Widget _buildRow(String title, String value, BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Text( + title + " : ", + style: Theme.of(context).textTheme.subtitle2.copyWith(fontWeight: FontWeight.bold), + ), + //if (item.clientName != null) + Text( + value, + style: Theme.of(context).textTheme.subtitle2.copyWith(), + ), + ], + ); + } +} diff --git a/lib/views/pages/sub_workorder/workorder_item.dart b/lib/views/pages/sub_workorder/workorder_item.dart new file mode 100644 index 0000000..eae11ac --- /dev/null +++ b/lib/views/pages/sub_workorder/workorder_item.dart @@ -0,0 +1,105 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/controllers/localization/localization.dart'; +import 'package:test_sa/models/subtitle.dart'; +import 'package:test_sa/views/app_style/colors.dart'; +import 'package:test_sa/views/app_style/sizing.dart'; +import 'package:test_sa/views/widgets/requests/request_status.dart'; + +import '../../../models/service_request/search_work_order.dart'; + +class WorkOrderItem extends StatelessWidget { + final int index; + final SearchWorkOrder item; + final Function(SearchWorkOrder) onPressed; + const WorkOrderItem({Key key, this.item, this.onPressed, this.index}) : super(key: key); + + @override + Widget build(BuildContext context) { + Subtitle _subtitle = AppLocalization.of(context).subtitle; + Color itemColor = index % 2 == 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; + Color onItemColor = index % 2 != 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; + + return Padding( + padding: const EdgeInsets.symmetric(vertical: 4), + child: ElevatedButton( + style: ElevatedButton.styleFrom( + padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8), + backgroundColor: itemColor, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), + ), + ), + onPressed: () { + onPressed(item); + }, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + item.callRequest.callNo ?? "-----", + style: Theme.of(context).textTheme.headline6.copyWith(color: onItemColor, fontSize: 16, fontWeight: FontWeight.bold), + ), + Text( + item.callRequest.asset.id.toString(), + style: Theme.of(context).textTheme.subtitle2.copyWith( + color: onItemColor, + ), + ), + Row( + children: [ + Expanded( + child: Text( + _subtitle.assetName, + style: Theme.of(context).textTheme.subtitle2.copyWith( + color: onItemColor, + ), + ), + ), + //if (item.clientName != null) + Text( + item.callRequest.asset.assetNumber, + style: Theme.of(context).textTheme.subtitle2.copyWith( + color: onItemColor, + ), + ), + ], + ), + Text( + item.calllastSituation.name, + style: Theme.of(context).textTheme.subtitle2.copyWith( + color: onItemColor, + ), + ), + Divider( + color: onItemColor, + ), + Row( + children: [ + Expanded( + child: Text( + _subtitle.status, + style: Theme.of(context).textTheme.subtitle2.copyWith( + color: onItemColor, + ), + ), + ), + if (item.callRequest.status?.id != null) StatusLabel(label: item.callRequest.status.name, color: AColors.getGasStatusColor(item.callRequest.status.id)), + ], + ), + ], + ), + ), + ], + ), + ], + ), + ), + ); + } +} diff --git a/lib/views/pages/sub_workorder/workorder_list.dart b/lib/views/pages/sub_workorder/workorder_list.dart new file mode 100644 index 0000000..c78054a --- /dev/null +++ b/lib/views/pages/sub_workorder/workorder_list.dart @@ -0,0 +1,101 @@ +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/views/pages/sub_workorder/workorder_item.dart'; + +import '../../../controllers/localization/localization.dart'; +import '../../../controllers/providers/api/service_requests_provider.dart'; +import '../../../models/service_request/search_work_order.dart'; +import '../../../models/subtitle.dart'; +import '../../app_style/colors.dart'; +import '../../widgets/buttons/app_back_button.dart'; +import '../../widgets/loaders/lazy_loading.dart'; +import '../../widgets/loaders/no_item_found.dart'; +import 'create_sub_workorder_page.dart'; + +class WorkOrderList extends StatefulWidget { + List items; + final Future> Function() onLazyLoading; + WorkOrderList({Key key, this.items, this.onLazyLoading}) : super(key: key); + + @override + State createState() => _WorkOrderListState(); +} + +class _WorkOrderListState extends State { + List _items; + @override + void initState() { + super.initState(); + _items = widget.items; + } + + @override + Widget build(BuildContext context) { + final serviceRequestsProvider = Provider.of(context, listen: false); + Subtitle subtitle = AppLocalization.of(context).subtitle; + return Scaffold( + body: SafeArea( + child: Column( + children: [ + Container( + color: AColors.primaryColor, + padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), + child: Column( + children: [ + Row( + children: [ + const ABackButton(), + Expanded( + child: Center( + child: Text( + "Work Order List", + style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic), + ), + ), + ), + const SizedBox(width: 48), + ], + ), + ], + ), + ), + Expanded( + child: _items?.isEmpty ?? [] + ? NoItemFound( + message: subtitle.noServiceRequestFound, + ) + : LazyLoading( + nextPage: serviceRequestsProvider.nextPage, + onLazyLoad: () async { + _items = await widget.onLazyLoading(); + setState(() {}); + }, + child: ListView.builder( + itemCount: _items.length, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), + itemBuilder: (context, itemIndex) { + return WorkOrderItem( + index: itemIndex, + onPressed: (model) { + // Navigator.of(context).push(MaterialPageRoute( + // builder: (_) => WorkOrderUpdate(item: model,))); + log(model?.toJson()?.toString()); + Navigator.push( + context, + MaterialPageRoute(builder: (context) => CreateSubWorkOrderPage(workOrder: model)), + ); + }, + item: _items[itemIndex], + ); + }, + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/views/pages/sub_workorder/workorder_update.dart b/lib/views/pages/sub_workorder/workorder_update.dart new file mode 100644 index 0000000..9d9c5d6 --- /dev/null +++ b/lib/views/pages/sub_workorder/workorder_update.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/views/pages/sub_workorder/workorder_details.dart'; + +import '../../../controllers/localization/localization.dart'; +import '../../../models/service_request/search_work_order.dart'; +import '../../../models/subtitle.dart'; +import '../../app_style/colors.dart'; +import '../../widgets/buttons/app_back_button.dart'; +import '../../widgets/loaders/loading_manager.dart'; + +class WorkOrderUpdate extends StatefulWidget { + final SearchWorkOrder item; + + const WorkOrderUpdate({@required this.item, Key key}) : super(key: key); + + @override + State createState() => _WorkOrderUpdateState(); +} + +class _WorkOrderUpdateState extends State { + final GlobalKey _formKey = GlobalKey(); + Subtitle _subtitle; + bool _isLoading = false; + + @override + Widget build(BuildContext context) { + _subtitle = AppLocalization.of(context).subtitle; + + return Scaffold( + body: SafeArea( + child: Form( + key: _formKey, + child: LoadingManager( + isLoading: _isLoading, + isFailedLoading: false, + stateCode: 200, + onRefresh: () async {}, + child: Column( + children: [ + Container( + color: Theme.of(context).colorScheme.primary, + padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4), + child: Row( + children: [ + const ABackButton(), + Expanded( + child: Center( + child: Text( + "Work Order", + style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic), + ), + ), + ), + const SizedBox(width: 58), + ], + ), + ), + WorkOrderDetails(item: widget.item,) + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/views/pages/user/gas_refill/gas_refill_details.dart b/lib/views/pages/user/gas_refill/gas_refill_details.dart index 9171aea..c9d9a65 100644 --- a/lib/views/pages/user/gas_refill/gas_refill_details.dart +++ b/lib/views/pages/user/gas_refill/gas_refill_details.dart @@ -1,15 +1,16 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; +import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/providers/api/gas_refill_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/models/enums/user_types.dart'; import 'package:test_sa/models/gas_refill/gas_refill_model.dart'; import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/views/app_style/sizing.dart'; +import 'package:test_sa/views/pages/user/gas_refill/request_gas_refill.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_icon_button.dart'; @@ -20,6 +21,7 @@ import 'package:test_sa/views/widgets/requests/request_status.dart'; import 'package:test_sa/views/widgets/status/gas_refill/gas_status.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; +import '../../../../models/enums/user_types.dart'; import '../../../app_style/colors.dart'; class GasRefillDetails extends StatefulWidget { @@ -109,14 +111,24 @@ class _GasRefillDetailsState extends State { ), if (_userProvider.user.type == UsersTypes.engineer) AIconButton( - iconData: _enableEdit ? Icons.cancel : Icons.edit, + iconData: /*_enableEdit ? Icons.cancel :*/ Icons.edit, color: Theme.of(context).colorScheme.onPrimary, buttonSize: 42, backgroundColor: AColors.green, onPressed: () async { - _enableEdit = !_enableEdit; + // _enableEdit = !_enableEdit; + print(widget.model.startDate); _model.fromGasRefillModel(widget.model); - setState(() {}); + print(widget.model.startDate); + // setState(() {}); + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => RequestGasRefill( + gasRefillModel: widget.model, + ), + ), + ); }, ), const SizedBox( @@ -139,6 +151,22 @@ class _GasRefillDetailsState extends State { title: _subtitle.hospital, info: _model.clientName, ), + RequestInfoRow( + title: "Building", + info: _model.building?.name, + ), + RequestInfoRow( + title: "Floor", + info: _model.floor?.name, + ), + RequestInfoRow( + title: _subtitle.startDate, + info: _model.startDate == null ? null : DateFormat.yMd().format(_model.startDate), + ), + RequestInfoRow( + title: _subtitle.endDate, + info: _model.endDate == null ? null : DateFormat.yMd().format(_model.endDate), + ), _enableEdit ? Column( crossAxisAlignment: CrossAxisAlignment.start, diff --git a/lib/views/pages/user/gas_refill/request_gas_refill.dart b/lib/views/pages/user/gas_refill/request_gas_refill.dart index 716a7e6..cb18646 100644 --- a/lib/views/pages/user/gas_refill/request_gas_refill.dart +++ b/lib/views/pages/user/gas_refill/request_gas_refill.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; @@ -27,12 +29,14 @@ import 'package:test_sa/views/widgets/status/gas_refill/gas_type.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import '../../../../controllers/localization/localization.dart'; +import '../../../../controllers/providers/api/hospitals_provider.dart'; import '../../../../models/enums/user_types.dart'; +import '../../../widgets/e_signature/e_signature.dart'; class RequestGasRefill extends StatefulWidget { static const String id = "/request-gas-refill"; - - const RequestGasRefill({Key key}) : super(key: key); + final GasRefillModel gasRefillModel; + const RequestGasRefill({this.gasRefillModel, Key key}) : super(key: key); @override State createState() => _RequestGasRefillState(); @@ -47,10 +51,20 @@ class _RequestGasRefillState extends State { GasRefillProvider _gasRefillProvider; GasRefillDetails _currentDetails = GasRefillDetails(); final TextEditingController _requestedQuantityController = TextEditingController(); - final GasRefillModel _formModel = GasRefillModel(details: []); + final TextEditingController _deliveredQuantityController = TextEditingController(); + GasRefillModel _formModel = GasRefillModel(details: []); final GlobalKey _formKey = GlobalKey(); final GlobalKey _DetailsKey = GlobalKey(); final GlobalKey _scaffoldKey = GlobalKey(); + bool _firstTime = true; + + @override + void initState() { + super.initState(); + if (widget.gasRefillModel != null) { + _formModel = widget.gasRefillModel; + } + } @override void setState(VoidCallback fn) { @@ -64,12 +78,26 @@ class _RequestGasRefillState extends State { _isLoading = true; setState(() {}); + if (widget.gasRefillModel != null) { + if (!_formModel.validate()) { + _isLoading = false; + setState(() {}); + return; + } + } - int status = await _gasRefillProvider.createModel( - user: _userProvider.user, - host: _settingProvider.host, - model: _formModel, - ); + int status = widget.gasRefillModel == null + ? await _gasRefillProvider.createModel( + user: _userProvider.user, + host: _settingProvider.host, + model: _formModel, + ) + : await _gasRefillProvider.updateModel( + user: _userProvider.user, + host: _settingProvider.host, + oldModel: widget.gasRefillModel, + newModel: _formModel, + ); _isLoading = false; setState(() {}); if (status >= 200 && status < 300) { @@ -101,6 +129,7 @@ class _RequestGasRefillState extends State { _validate = false; Scrollable.ensureVisible(_DetailsKey.currentContext); _requestedQuantityController.clear(); + _deliveredQuantityController.clear(); _currentDetails = GasRefillDetails(); setState(() {}); return true; @@ -109,6 +138,7 @@ class _RequestGasRefillState extends State { @override void dispose() { _requestedQuantityController.dispose(); + _deliveredQuantityController.dispose(); super.dispose(); } @@ -121,7 +151,22 @@ class _RequestGasRefillState extends State { _gasRefillProvider = Provider.of(context, listen: false); _gasRefillProvider.reset(); } - + if (widget.gasRefillModel != null && _firstTime) { + _formModel = widget.gasRefillModel; + _formModel.status = const Lookup(value: 0); + HospitalsProvider().getHospitalsListByVal(searchVal: widget.gasRefillModel.clientName).then((value) { + _gasRefillProvider.hospital = value?.firstWhere((element) => element.name == widget.gasRefillModel.clientName, orElse: () => null); + print(_gasRefillProvider.hospital?.buildings?.length); + print(widget.gasRefillModel?.building?.name); + _gasRefillProvider.building = _gasRefillProvider.hospital?.buildings?.firstWhere((element) => element.name == widget.gasRefillModel?.building?.name, orElse: () => null); + _gasRefillProvider.floor = _gasRefillProvider.building?.floors?.firstWhere((element) => element.name == widget.gasRefillModel?.floor?.name, orElse: () => null); + _gasRefillProvider.department = _gasRefillProvider.floor?.departments?.firstWhere((element) => element.name == widget.gasRefillModel?.department?.departmentName, orElse: () => null); + _gasRefillProvider.startDate = widget.gasRefillModel?.startDate; + _gasRefillProvider.endDate = widget.gasRefillModel?.endDate; + _firstTime = false; + setState(() {}); + }); + } return Scaffold( key: _scaffoldKey, body: Form( @@ -141,7 +186,7 @@ class _RequestGasRefillState extends State { child: Padding( padding: const EdgeInsets.all(8.0), child: Text( - "Request Gas Refill", + "${widget.gasRefillModel == null ? "Request" : "Update"} Gas Refill", style: Theme.of(context).textTheme.headline5.copyWith(color: Theme.of(context).primaryColor, fontSize: 28, fontWeight: FontWeight.bold), ), ), @@ -171,7 +216,8 @@ class _RequestGasRefillState extends State { height: 4, ), GasStatusMenu( - initialValue: _formModel.status ?? const Lookup(value: 1), + initialValue: _formModel.status ?? const Lookup(value: 0), + enabled: false, onSelect: (status) { _formModel.status = status; }, @@ -247,149 +293,177 @@ class _RequestGasRefillState extends State { ), ], ), - if (_userProvider.user?.type == UsersTypes.engineer) - Row( + // if (_userProvider.user?.type == UsersTypes.engineer) + // Column( + // children: [ + // Row( + // children: [ + // Expanded( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.stretch, + // children: [ + // const ASubTitle("Start of Work"), + // SizedBox( + // height: 8 * AppStyle.getScaleFactor(context), + // ), + // ADateTimePicker( + // date: _gasRefillProvider.startDate, + // from: DateTime.now().subtract(const Duration(days: 365)), + // to: DateTime.now().add(const Duration(days: 365)), + // onDateTimePicker: (date) { + // _gasRefillProvider.startDate = date; + // setState(() {}); + // }, + // ), + // ], + // ), + // ), + // const SizedBox(width: 8), + // Expanded( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.stretch, + // children: [ + // const ASubTitle("End of Work"), + // SizedBox( + // height: 8 * AppStyle.getScaleFactor(context), + // ), + // ADateTimePicker( + // date: _gasRefillProvider.endDate, + // from: DateTime.now().subtract(const Duration(days: 365)), + // to: DateTime.now().add(const Duration(days: 365)), + // onDateTimePicker: (date) { + // _gasRefillProvider.endDate = date; + // setState(() {}); + // }, + // ), + // ], + // ), + // ), + // ], + // ), + // const SizedBox(height: 8), + // ASubTitle(_subtitle.workingHours), + // const SizedBox(height: 4), + // ATextFormField( + // initialValue: null, + // textAlign: TextAlign.center, + // hintText: _gasRefillProvider.startDate == null + // ? "0" + // : ((_gasRefillProvider.endDate?.difference(_gasRefillProvider.startDate)?.inMinutes ?? 0) / 60)?.toStringAsFixed(2)?.toString() ?? "0", + // enable: false, + // style: Theme.of(context).textTheme.subtitle1, + // validator: (value) => Validator.isNumeric(value) ? null : _subtitle.requiredWord, + // textInputType: TextInputType.number, + // onSaved: (value) { + // // _serviceReport.workHours = value; + // }, + // ), + // ], + // ), + if (widget.gasRefillModel == null) + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const ASubTitle("Start of Work"), - SizedBox( - height: 8 * AppStyle.getScaleFactor(context), - ), - ADateTimePicker( - date: _gasRefillProvider.startDate, - from: DateTime.now().subtract(const Duration(days: 365)), - to: DateTime.now().add(const Duration(days: 365)), - onDateTimePicker: (date) { - _gasRefillProvider.startDate = date; - setState(() {}); - }, - ), - ], + const SizedBox(height: 8), + Divider(color: Theme.of(context).colorScheme.primary), + const SizedBox(height: 4), + const ASubTitle("Type"), + if (_validate && _currentDetails.type == null) ASubTitle(_subtitle.requiredWord, color: Colors.red), + const SizedBox(height: 4), + GasTypeMenu( + initialValue: _currentDetails.type, + onSelect: (status) { + _currentDetails.type = status; + }, + ), + const SizedBox(height: 8), + const ASubTitle("Cylinder Size"), + if (_validate && _currentDetails.cylinderSize == null) + ASubTitle( + _subtitle.requiredWord, + color: Colors.red, ), + const SizedBox( + height: 4, + ), + GasCylinderSizeMenu( + initialValue: _currentDetails.cylinderSize, + onSelect: (status) { + _currentDetails.cylinderSize = status; + }, + ), + const SizedBox( + height: 8, ), - const SizedBox(width: 8), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const ASubTitle("End of Work"), - SizedBox( - height: 8 * AppStyle.getScaleFactor(context), - ), - ADateTimePicker( - date: _gasRefillProvider.endDate, - from: DateTime.now().subtract(const Duration(days: 365)), - to: DateTime.now().add(const Duration(days: 365)), - onDateTimePicker: (date) { - _gasRefillProvider.endDate = date; - setState(() {}); - }, - ), - ], + const SizedBox( + height: 8, + ), + const ASubTitle("Cylinder Type"), + if (_validate && _currentDetails.cylinderSize == null) + ASubTitle( + _subtitle.requiredWord, + color: Colors.red, ), + const SizedBox( + height: 4, + ), + GasCylinderTypesMenu( + initialValue: _currentDetails.cylinderType, + onSelect: (status) { + _currentDetails.cylinderType = status; + }, + ), + const SizedBox( + height: 8, + ), + ASubTitle(_subtitle.requestedQuantity), + if (_validate && _currentDetails?.requestedQuantity == null) + ASubTitle( + _subtitle.requiredWord, + color: Colors.red, + ), + SizedBox( + height: 4, + ), + ATextFormField( + initialValue: (_currentDetails?.requestedQuantity ?? "").toString(), + textAlign: TextAlign.center, + controller: _requestedQuantityController, + style: Theme.of(context).textTheme.subtitle1, + validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only", + textInputType: TextInputType.number, + onChange: (value) { + _currentDetails?.requestedQuantity = double.tryParse(value); + }, + ), + if (widget.gasRefillModel != null) const SizedBox(height: 16), + if (widget.gasRefillModel != null) ASubTitle(_subtitle.deliveredQuantity), + if (widget.gasRefillModel != null && _validate && _currentDetails?.deliveredQuantity == null) + ASubTitle( + _subtitle.requiredWord, + color: Colors.red, + ), + if (widget.gasRefillModel != null) const SizedBox(height: 4), + if (widget.gasRefillModel != null) + ATextFormField( + initialValue: (_currentDetails?.deliveredQuantity ?? "").toString(), + textAlign: TextAlign.center, + controller: _deliveredQuantityController, + style: Theme.of(context).textTheme.subtitle1, + validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only", + textInputType: TextInputType.number, + onChange: (value) { + _currentDetails?.deliveredQuantity = double.tryParse(value); + }, + ), + const SizedBox(height: 16), + AButton( + text: _subtitle.add, + onPressed: _addNewModel, ), ], ), - if (_userProvider.user?.type == UsersTypes.engineer) const SizedBox(height: 8), - if (_userProvider.user?.type == UsersTypes.engineer) ASubTitle(_subtitle.workingHours), - if (_userProvider.user?.type == UsersTypes.engineer) const SizedBox(height: 4), - if (_userProvider.user?.type == UsersTypes.engineer) - ATextFormField( - initialValue: null, - textAlign: TextAlign.center, - hintText: _gasRefillProvider.startDate == null - ? "0" - : ((_gasRefillProvider.endDate?.difference(_gasRefillProvider.startDate)?.inMinutes ?? 0) / 60)?.toStringAsFixed(2)?.toString() ?? "0", - enable: false, - style: Theme.of(context).textTheme.subtitle1, - validator: (value) => Validator.isNumeric(value) ? null : _subtitle.requiredWord, - textInputType: TextInputType.number, - onSaved: (value) { - // _serviceReport.workHours = value; - }, - ), - const SizedBox(height: 8), - Divider(color: Theme.of(context).colorScheme.primary), - const SizedBox(height: 4), - const ASubTitle("Type"), - if (_validate && _currentDetails.type == null) ASubTitle(_subtitle.requiredWord, color: Colors.red), - const SizedBox(height: 4), - GasTypeMenu( - initialValue: _currentDetails.type, - onSelect: (status) { - _currentDetails.type = status; - }, - ), - const SizedBox(height: 8), - const ASubTitle("Cylinder Size"), - if (_validate && _currentDetails.cylinderSize == null) - ASubTitle( - _subtitle.requiredWord, - color: Colors.red, - ), - const SizedBox( - height: 4, - ), - GasCylinderSizeMenu( - initialValue: _currentDetails.cylinderSize, - onSelect: (status) { - _currentDetails.cylinderSize = status; - }, - ), - const SizedBox( - height: 8, - ), - - const SizedBox( - height: 8, - ), - const ASubTitle("Cylinder Type"), - if (_validate && _currentDetails.cylinderSize == null) - ASubTitle( - _subtitle.requiredWord, - color: Colors.red, - ), - const SizedBox( - height: 4, - ), - GasCylinderTypesMenu( - initialValue: _currentDetails.cylinderType, - onSelect: (status) { - _currentDetails.cylinderType = status; - }, - ), - const SizedBox( - height: 8, - ), - ASubTitle(_subtitle.quantity), - if (_validate && _currentDetails.requestedQuantity == null) - ASubTitle( - _subtitle.requiredWord, - color: Colors.red, - ), - SizedBox( - height: 4, - ), - ATextFormField( - initialValue: (_currentDetails?.requestedQuantity ?? "").toString(), - textAlign: TextAlign.center, - controller: _requestedQuantityController, - style: Theme.of(context).textTheme.subtitle1, - validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only", - textInputType: TextInputType.number, - onSaved: (value) { - _currentDetails.requestedQuantity = double.tryParse(value); - }, - ), const SizedBox(height: 16), - AButton( - text: _subtitle.add, - onPressed: _addNewModel, - ), - if (_formModel.details.isNotEmpty) const ASubTitle("Gas Requests"), ListView.builder( key: _DetailsKey, @@ -399,21 +473,56 @@ class _RequestGasRefillState extends State { itemBuilder: (context, index) { final model = _formModel.details[index]; return GasRefillCreateDetailsItem( + isUpdate: widget.gasRefillModel != null, model: model, - onDelete: () { - _formModel.details.remove(model); + onPressed: () { + if (widget.gasRefillModel != null) { + model.selectedForEditing = !(model.selectedForEditing ?? false); + } + if (widget.gasRefillModel == null) { + _formModel.details.remove(model); + } setState(() {}); }, ); }), + if (widget.gasRefillModel != null) const SizedBox(height: 16), + if (widget.gasRefillModel != null) const ASubTitle("Nurse Signature"), + if (widget.gasRefillModel != null) + ESignature( + oldSignature: _formModel.signatureNurse, + newSignature: _formModel.localNurseSignature, + onChange: (signature) { + if (signature == null || signature.isEmpty) { + return; + } + _formModel.localNurseSignature = signature; + _formModel.signatureNurse = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + }, + ), + if (widget.gasRefillModel != null) + const SizedBox( + height: 8, + ), + if (widget.gasRefillModel != null) const ASubTitle("Engineer Signature"), + if (widget.gasRefillModel != null) + ESignature( + oldSignature: _formModel.signatureEngineer, + newSignature: _formModel.localNurseSignature, + onChange: (signature) { + if (signature == null || signature.isEmpty) { + return; + } + _formModel.localNurseSignature = signature; + _formModel.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + }, + ), const SizedBox(height: 16), AButton( - text: _subtitle.submit, + text: widget.gasRefillModel == null ? _subtitle.submit : _subtitle.update, onPressed: _onSubmit, ), - const SizedBox( - height: 100, - ) + const SizedBox(height: 100) ], ), ), diff --git a/lib/views/pages/user/gas_refill/track_gas_refill.dart b/lib/views/pages/user/gas_refill/track_gas_refill.dart index c016fd6..6dd1ca6 100644 --- a/lib/views/pages/user/gas_refill/track_gas_refill.dart +++ b/lib/views/pages/user/gas_refill/track_gas_refill.dart @@ -26,7 +26,11 @@ class _TrackGasRefillPageState extends State with TickerProv @override Widget build(BuildContext context) { - _gasRefillProvider = Provider.of(context); + if (_gasRefillProvider == null) { + _gasRefillProvider = Provider.of(context); + //_gasRefillProvider?.isLoading = false; + _gasRefillProvider.reset(); + } _userProvider = Provider.of(context); _settingProvider = Provider.of(context); Subtitle _subtitle = AppLocalization.of(context).subtitle; diff --git a/lib/views/pages/user/land_page.dart b/lib/views/pages/user/land_page.dart index ba49b91..e6e9d60 100644 --- a/lib/views/pages/user/land_page.dart +++ b/lib/views/pages/user/land_page.dart @@ -23,6 +23,7 @@ import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/pages/device_transfer/request_device_transfer.dart'; import 'package:test_sa/views/pages/device_transfer/track_device_transfer.dart'; +import 'package:test_sa/views/pages/sub_workorder/search_sub_workorder_page.dart'; import 'package:test_sa/views/pages/user/gas_refill/request_gas_refill.dart'; import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart'; import 'package:test_sa/views/pages/user/requests/create_request.dart'; @@ -211,6 +212,14 @@ class _LandPageState extends State { Navigator.of(context).pushNamed(TrackDeviceTransferPage.id); }, ), + if (_userProvider?.user != null && _userProvider?.user?.type != UsersTypes.normal_user) + LandPageItem( + text: "Search Work Order", + svgPath: "assets/images/sub_workorder_icon.svg", + onPressed: () { + Navigator.of(context).pushNamed(SearchSubWorkOrderPage.id); + }, + ), ], ), ], diff --git a/lib/views/pages/user/requests/create_request.dart b/lib/views/pages/user/requests/create_request.dart index 91b87be..bcd4520 100644 --- a/lib/views/pages/user/requests/create_request.dart +++ b/lib/views/pages/user/requests/create_request.dart @@ -306,7 +306,7 @@ class CreateRequestPageState extends State { Fluttertoast.showToast(msg: _subtitle.pickDevice); return; } - if (_serviceRequest.firstAction != null && _dateTime == null) { + if (_serviceRequest.firstAction.name == "Need a visit" && _dateTime == null) { Fluttertoast.showToast(msg: _subtitle.noDateFound); return; } diff --git a/lib/views/pages/user/requests/report/create_service_report.dart b/lib/views/pages/user/requests/report/create_service_report.dart index d94ddb6..23c96a7 100644 --- a/lib/views/pages/user/requests/report/create_service_report.dart +++ b/lib/views/pages/user/requests/report/create_service_report.dart @@ -23,24 +23,21 @@ import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; -import 'package:test_sa/views/widgets/date_and_time/time_picker.dart'; import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; import 'package:test_sa/views/widgets/equipment/auto_complete_devices_field.dart'; import 'package:test_sa/views/widgets/images/mini_one_image_picker.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart'; import 'package:test_sa/views/widgets/parts/part_item.dart'; -import 'package:test_sa/views/widgets/status/employee/engineers_mune.dart'; import 'package:test_sa/views/widgets/status/report/service_report_equipment_status.dart'; import 'package:test_sa/views/widgets/status/report/service_report_last_call.dart'; import 'package:test_sa/views/widgets/status/report/service_report_reasons.dart'; -import 'package:test_sa/views/widgets/status/report/service_report_status.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import '../../../../../controllers/providers/api/status_drop_down/report/service_types_provider.dart'; -import '../../../../widgets/speech_to_text/speech_to_text.dart'; import '../../../../widgets/status/report/service_report_fault_description.dart'; import '../../../../widgets/status/report/service_report_repair_location.dart'; +import '../../../../widgets/timer/app_timer.dart'; class CreateServiceReport extends StatefulWidget { static final String id = "/create-service-report"; @@ -331,7 +328,7 @@ class _CreateServiceReportState extends State with TickerPr child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // ASubTitle(_subtitle.reportStatus), + // ASubTitle(_subtitle.reportStatus), ASubTitle("Equipment Status"), _validate && _serviceReport.equipmentStatus == null ? ASubTitle( @@ -418,71 +415,23 @@ class _CreateServiceReportState extends State with TickerPr SizedBox( height: 8 * AppStyle.getScaleFactor(context), ), + ASubTitle(_subtitle.workingHours), + const SizedBox(height: 8), Row( children: [ Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const ASubTitle("Start of Work"), - SizedBox( - height: 8 * AppStyle.getScaleFactor(context), - ), - ADateTimePicker( - date: _serviceReport.startDate, - from: DateTime.now().subtract(const Duration(days: 365)), - to: DateTime.now().add(const Duration(days: 365)), - onDateTimePicker: (date) { - _serviceReport.startDate = date; - setState(() {}); - }, - ), - ], - ), - ), - const SizedBox(width: 8), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.stretch, - children: [ - const ASubTitle("End of Work"), - SizedBox( - height: 8 * AppStyle.getScaleFactor(context), - ), - ADateTimePicker( - date: _serviceReport.endDate, - from: DateTime.now().subtract(const Duration(days: 365)), - to: DateTime.now().add(const Duration(days: 365)), - onDateTimePicker: (date) { - _serviceReport.endDate = date; - setState(() {}); - }, - ), - ], + child: AppTimer( + timer: _serviceReport.timer, + onChange: (timer) async { + _serviceReport.timer = timer; + _serviceReport.workingHours = num.tryParse((((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0"); + return true; + }, ), ), ], ), - const SizedBox(height: 8), - ASubTitle(_subtitle.workingHours), - const SizedBox(height: 4), - ATextFormField( - initialValue: null, - textAlign: TextAlign.center, - hintText: _serviceReport.startDate == null - ? "0" - : ((_serviceReport?.endDate?.difference(_serviceReport?.startDate)?.inMinutes ?? 0) / 60)?.toStringAsFixed(2)?.toString() ?? "0", - enable: false, - style: Theme.of(context).textTheme.subtitle1, - validator: (value) => Validator.isNumeric(value) ? null : _subtitle.requiredWord, - textInputType: TextInputType.number, - onSaved: (value) { - // _serviceReport.workHours = value; - }, - ), - const SizedBox( - height: 8, - ), + const SizedBox(height: 16), // device sn Visibility( visible: widget.request.deviceSerialNumber == null, @@ -636,7 +585,7 @@ class _CreateServiceReportState extends State with TickerPr enable: false, hintText: _serviceReport.faultDescription?.workPerformed ?? "", controller: _workPreformedController, - style: Theme.of(context).textTheme.subtitle1, + style: Theme.of(context).textTheme.titleMedium, validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord, textInputType: TextInputType.multiline, onSaved: (value) { @@ -656,6 +605,12 @@ class _CreateServiceReportState extends State with TickerPr crossAxisAlignment: CrossAxisAlignment.start, children: [ ASubTitle(_subtitle.reasons), + _validate && _serviceReport.reason?.id == null + ? ASubTitle( + _subtitle.requiredWord, + color: Colors.red, + ) + : const SizedBox.shrink(), const SizedBox(height: 4), ServiceReportReasonsMenu( initialValue: _serviceReport.reason, @@ -701,7 +656,7 @@ class _CreateServiceReportState extends State with TickerPr ), ATextFormField( initialValue: _serviceReport?.travelingExpense?.toString(), - hintText: _subtitle.travelingExpense, + hintText: "i.e 3, 3.5, 4", textAlign: TextAlign.center, style: Theme.of(context).textTheme.titleMedium, textInputType: TextInputType.number, @@ -929,9 +884,9 @@ class _CreateServiceReportState extends State with TickerPr ), Column( children: List.generate(_serviceReport.parts.length, (index) { - Part _part = _serviceReport.parts[index]; + Part part = _serviceReport.parts[index]; return PartItem( - part: _part, + part: part, onDelete: (part) { _serviceReport.parts.remove(part); setState(() {}); @@ -955,7 +910,10 @@ class _CreateServiceReportState extends State with TickerPr // setState(() {}); // return; // } - if (!_serviceReport.validate()) return; + if (!(await _serviceReport.validate())) { + setState(() {}); + return; + } _formKey.currentState.save(); _isLoading = true; diff --git a/lib/views/pages/user/requests/report/edit_service_report.dart b/lib/views/pages/user/requests/report/edit_service_report.dart index 848fc4f..4a30278 100644 --- a/lib/views/pages/user/requests/report/edit_service_report.dart +++ b/lib/views/pages/user/requests/report/edit_service_report.dart @@ -8,9 +8,12 @@ import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; import 'package:test_sa/controllers/localization/localization.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_last_calls_provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_types_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/controllers/validator/validator.dart'; +import 'package:test_sa/models/call_request_for_work_order_model.dart'; +import 'package:test_sa/models/engineer.dart'; import 'package:test_sa/models/part.dart'; import 'package:test_sa/models/service_report.dart'; import 'package:test_sa/models/service_request/service_request.dart'; @@ -27,12 +30,11 @@ import 'package:test_sa/views/widgets/images/mini_one_image_picker.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart'; import 'package:test_sa/views/widgets/parts/part_item.dart'; -import 'package:test_sa/views/widgets/status/employee/engineers_mune.dart'; +import 'package:test_sa/views/widgets/status/report/service_report_equipment_status.dart'; +import 'package:test_sa/views/widgets/status/report/service_report_fault_description.dart'; import 'package:test_sa/views/widgets/status/report/service_report_last_call.dart'; import 'package:test_sa/views/widgets/status/report/service_report_reasons.dart'; -import 'package:test_sa/views/widgets/status/report/service_report_status.dart'; -import 'package:test_sa/views/widgets/status/report/service_report_type.dart'; -import 'package:test_sa/views/widgets/status/report/service_status.dart'; +import 'package:test_sa/views/widgets/status/report/service_report_repair_location.dart'; import 'package:test_sa/views/widgets/timer/app_timer.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; @@ -42,6 +44,7 @@ class EditServiceReport extends StatefulWidget { final ServiceReport report; const EditServiceReport({Key key, this.request, this.report}) : super(key: key); + @override _EditServiceReportState createState() => _EditServiceReportState(); } @@ -54,6 +57,7 @@ class _EditServiceReportState extends State with TickerProvid bool _validate = false; ServiceReport _serviceReport; bool _isLoading = false; + bool _showCommentField = false; Subtitle _subtitle; File _image; @@ -62,12 +66,26 @@ class _EditServiceReportState extends State with TickerProvid TextEditingController _faultController = TextEditingController(); TextEditingController _workPreformedController = TextEditingController(); + ServiceStatusProvider _assetTypeProvider; + + CallRequestForWorkOrder _callRequestForWorkOrder; + @override void initState() { _serviceReport = widget.report; super.initState(); } + void getRequestForWorkOrder() async { + _isLoading = true; + setState(() {}); + _callRequestForWorkOrder = await _serviceRequestsProvider.getCallRequestForWorkOrder(callId: widget.request.id); + _serviceReport.engineer = Engineer.fromJson(_callRequestForWorkOrder?.assignedEmployee?.toJson()); + await _assetTypeProvider.getTypes(user: _userProvider.user, host: _settingProvider.host); + _isLoading = false; + setState(() {}); + } + @override void dispose() { _faultController.dispose(); @@ -80,6 +98,15 @@ class _EditServiceReportState extends State with TickerProvid _userProvider = Provider.of(context); _settingProvider = Provider.of(context); _serviceRequestsProvider = Provider.of(context); + + _assetTypeProvider = Provider.of(context); + if (_callRequestForWorkOrder == null) { + getRequestForWorkOrder(); + } + _serviceReport.assetType = _assetTypeProvider.statuses?.firstWhere( + (element) => element.value == _callRequestForWorkOrder?.assetType, + orElse: () => null, + ); _subtitle = AppLocalization.of(context).subtitle; return Scaffold( key: _scaffoldKey, @@ -94,11 +121,9 @@ class _EditServiceReportState extends State with TickerProvid child: Stack( children: [ ListView( + padding: const EdgeInsets.all(16), children: [ - //AppNameBar(), - const SizedBox( - height: 16, - ), + const SizedBox(height: 16), Center( child: Padding( padding: const EdgeInsets.all(8.0), @@ -108,22 +133,22 @@ class _EditServiceReportState extends State with TickerProvid ), ), ), - Container( - padding: const EdgeInsets.symmetric(horizontal: 16), - margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), - decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [ - const BoxShadow( - color: AColors.grey, - offset: Offset(0, -1), - ) - ]), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox( - height: 8, - ), - Wrap( + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ASubTitle("Caller Info"), + const SizedBox(height: 8), + Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + margin: const EdgeInsets.symmetric(vertical: 16), + decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: const [ + BoxShadow( + color: AColors.grey, + offset: Offset(0, -1), + ) + ]), + child: Wrap( spacing: 10, children: [ ASubTitle( @@ -146,186 +171,161 @@ class _EditServiceReportState extends State with TickerProvid ) ], ), - const Divider(), - - // Report type and Reasons - Row( + ), + const SizedBox(height: 8), + ASubTitle("Work Order Details"), + const SizedBox(height: 8), + Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + margin: const EdgeInsets.symmetric(vertical: 16), + decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [ + const BoxShadow( + color: AColors.grey, + offset: Offset(0, -1), + ) + ]), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - // Report Status - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ASubTitle(_subtitle.reportType), - _validate && _serviceReport.type == null - ? ASubTitle( - _subtitle.requiredWord, - color: Colors.red, - ) - : const SizedBox.shrink(), - const SizedBox( - height: 4, - ), - ServiceReportTypeMenu( - initialValue: _serviceReport.type, - onSelect: (status) { - _serviceReport.type = status; - }, - ), - ], - ), - ), - const SizedBox( - width: 8, - ), - // visit date - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ASubTitle(_subtitle.visitDate), - _validate && _serviceReport.visitDate == null - ? ASubTitle( - _subtitle.requiredWord, - color: Colors.red, - ) - : const SizedBox.shrink(), - Row( + // Report type and Reasons + Row( + children: [ + // Report Status + // Expanded( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // ASubTitle(_subtitle.reportType), + // _validate && _serviceReport.type == null + // ? ASubTitle( + // _subtitle.requiredWord, + // color: Colors.red, + // ) + // : const SizedBox.shrink(), + // const SizedBox( + // height: 4, + // ), + // ServiceReportTypeMenu( + // initialValue: _serviceReport.type, + // onSelect: (status) { + // _serviceReport.type = status; + // }, + // ), + // ], + // ), + // ), + // const SizedBox( + // width: 8, + // ), + // visit date + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: ADatePicker( - date: _serviceReport.visitDate, - from: DateTime.now().subtract(const Duration(days: 365)), - to: DateTime.now().add(const Duration(days: 365)), - onDatePicker: (date) { - _serviceReport.visitDate = date; - setState(() {}); - }, - ), + ASubTitle(_subtitle.visitDate), + _validate && _serviceReport.visitDate == null + ? ASubTitle( + _subtitle.requiredWord, + color: Colors.red, + ) + : const SizedBox.shrink(), + Row( + children: [ + Expanded( + child: ADatePicker( + date: _serviceReport.visitDate, + from: DateTime.now().subtract(const Duration(days: 365)), + to: DateTime.now().add(const Duration(days: 365)), + onDatePicker: (date) { + _serviceReport.visitDate = date; + setState(() {}); + }, + ), + ), + ], ), ], ), - ], - ), + ), + ], ), - ], - ), - const SizedBox( - height: 8, - ), - // device sn - Visibility( - visible: true, //widget.report.device == null, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ASubTitle(_subtitle.deviceSN), - _validate && _serviceReport.device?.id == null - ? ASubTitle( - _subtitle.requiredWord, - color: Colors.red, - ) - : const SizedBox.shrink(), - AutoCompleteDeviceField( - hospitalId: widget.request.hospitalId, - initialValue: _serviceReport.device, - onPick: (id) { - _serviceReport.device.id = id; - }, - ), - const SizedBox( - height: 8, - ), - ], - ), - ), - const SizedBox( - height: 8, - ), - ASubTitle(_subtitle.serviceType), - _validate && _serviceReport.assetType == null - ? ASubTitle( - _subtitle.requiredWord, - color: Colors.red, - ) - : const SizedBox.shrink(), - const SizedBox( - height: 4, - ), - ServiceAssetTypeMenu( - initialValue: _serviceReport.assetType, - onSelect: (status) { - _serviceReport.assetType = status; - }, - ), - const SizedBox( - height: 8, - ), - SizedBox( - height: 8 * AppStyle.getScaleFactor(context), - ), - const ASubTitle("Assign Employee"), - const SizedBox( - height: 8, - ), - _validate && _serviceReport.engineer == null - ? ASubTitle( - _subtitle.requiredWord, - color: Colors.red, - ) - : const SizedBox.shrink(), - const SizedBox( - height: 4, - ), - EngineersMenu( - initialValue: _serviceReport.engineer, - onSelect: (engineer) { - _serviceReport.engineer = engineer; - }, - ), - const SizedBox( - height: 8, - ), - // Report status and Service Type - Row( - children: [ - // report status - Expanded( + const SizedBox( + height: 8, + ), + // device sn + Visibility( + visible: widget.request.deviceSerialNumber == null, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - ASubTitle(_subtitle.reportStatus), - _validate && _serviceReport.equipmentStatus == null + ASubTitle(_subtitle.deviceSN), + _validate && _serviceReport.device?.id == null ? ASubTitle( _subtitle.requiredWord, color: Colors.red, ) : const SizedBox.shrink(), - const SizedBox( - height: 4, - ), - ServiceReportStatusMenu( - report: _serviceReport, - request: widget.request, - onSelect: (status) { - _serviceReport.equipmentStatus = status; + AutoCompleteDeviceField( + hospitalId: widget.request.hospitalId, + initialValue: _serviceReport.device, + onPick: (id) { + _serviceReport.device.id = id; }, ), + const SizedBox(height: 8), ], ), ), + const SizedBox(height: 8), + ASubTitle(_subtitle.serviceType), + _validate && _serviceReport.assetType == null + ? ASubTitle( + _subtitle.requiredWord, + color: Colors.red, + ) + : const SizedBox.shrink(), const SizedBox( - width: 8, + height: 4, ), - Consumer( - builder: (_, provider, __) { - if (provider.isLoading == null) return const SizedBox.shrink(); - return Expanded( + 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 == _callRequestForWorkOrder.assetType, + orElse: () => null, + ); + }, + child: ATextFormField( + initialValue: _serviceReport?.assetType?.name ?? "NULL", + textAlign: TextAlign.center, + enable: false, + style: Theme.of(context).textTheme.titleMedium, + ), + ), + // ServiceAssetTypeMenu( + // initialValue: _serviceReport.assetType, + // onSelect: (status) { + // _serviceReport.assetType = status; + // }, + // ), + const SizedBox( + height: 8, + ), + Row( + children: [ + // report status + Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - ASubTitle(_subtitle.callLastSituation), - _validate && _serviceReport.callLastSituation == null + // ASubTitle(_subtitle.reportStatus), + ASubTitle("Equipment Status"), + _validate && _serviceReport.equipmentStatus == null ? ASubTitle( _subtitle.requiredWord, color: Colors.red, @@ -334,336 +334,620 @@ class _EditServiceReportState extends State with TickerProvid const SizedBox( height: 4, ), - ServiceReportLastCallsMenu( + // ServiceReportStatusMenu( + // report: _serviceReport, + // request: widget.request, + // onSelect: (status) { + // _serviceReport.status = status; + // }, + // ), + ServiceReportEquipmentStatusMenu( report: _serviceReport, + request: widget.request, onSelect: (status) { - if (status?.value == 12 || _serviceReport.callLastSituation?.value == 12) { - _serviceReport.callLastSituation = status; - setState(() {}); - } else { - _serviceReport.callLastSituation = status; - } + _serviceReport.equipmentStatus = status; }, - ), + ) ], ), - ); - }, + ), + const SizedBox( + width: 8, + ), + // Provider.of(context).isLoading == null + // ? const SizedBox.shrink(): + // Call's last Situation + Consumer( + builder: (_, provider, __) { + if (provider.isLoading == null) return const SizedBox.shrink(); + return Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ASubTitle(_subtitle.callLastSituation), + _validate && _serviceReport.callLastSituation == null + ? ASubTitle( + _subtitle.requiredWord, + color: Colors.red, + ) + : const SizedBox.shrink(), + const SizedBox(height: 4), + ServiceReportLastCallsMenu( + report: _serviceReport, + onSelect: (status) { + if (status?.value == 12 || _serviceReport.callLastSituation?.value == 12) { + _serviceReport.callLastSituation = status; + setState(() {}); + } else { + _serviceReport.callLastSituation = status; + } + }, + ), + ], + ), + ); + }, + ), + ], ), - ], - ), - const SizedBox( - height: 8, - ), - // invoice number & code - _serviceReport.callLastSituation?.value != 12 - ? const SizedBox.shrink() - : Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ASubTitle(_subtitle.invoiceNumber), - const SizedBox( - height: 8, - ), - ATextFormField( - initialValue: _serviceReport?.invoiceNumber, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.subtitle1, - validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord, - textInputType: TextInputType.number, - onSaved: (value) { - _serviceReport.invoiceNumber = value; - }, - ), - ], - ), - ), - const SizedBox( - width: 8, - ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ASubTitle(_subtitle.invoiceCode), - const SizedBox( - height: 4, + if (_showCommentField) + const SizedBox( + height: 8, + ), + if (_showCommentField) + ATextFormField( + initialValue: _serviceReport?.reviewComment, + hintText: "Review Comment", + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleMedium, + textInputType: TextInputType.multiline, + onSaved: (value) { + _serviceReport.reviewComment = value; + }, + ), + + SizedBox( + height: 8 * AppStyle.getScaleFactor(context), + ), + // const ASubTitle("Assign Employee"), + // const SizedBox( + // height: 8, + // ), + // _validate && _serviceReport.engineer == null + // ? ASubTitle( + // _subtitle.requiredWord, + // color: Colors.red, + // ) + // : const SizedBox.shrink(), + // const SizedBox( + // height: 4, + // ), + // EngineersMenu( + // initialValue: _serviceReport.engineer, + // onSelect: (engineer) { + // _serviceReport.engineer = engineer; + // }, + // ), + // const SizedBox( + // height: 8, + // ), + // Report status and Service Type + // Row( + // children: [ + // // report status + // Expanded( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // ASubTitle(_subtitle.reportStatus), + // _validate && _serviceReport.equipmentStatus == null + // ? ASubTitle( + // _subtitle.requiredWord, + // color: Colors.red, + // ) + // : const SizedBox.shrink(), + // const SizedBox( + // height: 4, + // ), + // ServiceReportStatusMenu( + // report: _serviceReport, + // request: widget.request, + // onSelect: (status) { + // _serviceReport.equipmentStatus = status; + // }, + // ), + // ], + // ), + // ), + // const SizedBox( + // width: 8, + // ), + // Consumer( + // builder: (_, provider, __) { + // if (provider.isLoading == null) return const SizedBox.shrink(); + // return Expanded( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // ASubTitle(_subtitle.callLastSituation), + // _validate && _serviceReport.callLastSituation == null + // ? ASubTitle( + // _subtitle.requiredWord, + // color: Colors.red, + // ) + // : const SizedBox.shrink(), + // const SizedBox( + // height: 4, + // ), + // ServiceReportLastCallsMenu( + // report: _serviceReport, + // onSelect: (status) { + // if (status?.value == 12 || _serviceReport.callLastSituation?.value == 12) { + // _serviceReport.callLastSituation = status; + // setState(() {}); + // } else { + // _serviceReport.callLastSituation = status; + // } + // }, + // ), + // ], + // ), + // ); + // }, + // ), + // ], + // ), + const SizedBox( + height: 8, + ), + // invoice number & code + _serviceReport.callLastSituation?.value != 12 + ? const SizedBox.shrink() + : Row( + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ASubTitle(_subtitle.invoiceNumber), + const SizedBox( + height: 8, + ), + ATextFormField( + initialValue: _serviceReport?.invoiceNumber, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.subtitle1, + validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord, + textInputType: TextInputType.number, + onSaved: (value) { + _serviceReport.invoiceNumber = value; + }, + ), + ], ), - ATextFormField( - initialValue: _serviceReport?.invoiceCode, - textAlign: TextAlign.center, - style: Theme.of(context).textTheme.subtitle1, - validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord, - textInputType: TextInputType.text, - onSaved: (value) { - _serviceReport.invoiceCode = value; - }, + ), + const SizedBox( + width: 8, + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ASubTitle(_subtitle.invoiceCode), + const SizedBox( + height: 4, + ), + ATextFormField( + initialValue: _serviceReport?.invoiceCode, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.subtitle1, + validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord, + textInputType: TextInputType.text, + onSaved: (value) { + _serviceReport.invoiceCode = value; + }, + ), + ], ), - ], - ), + ), + ], ), - ], - ), - // const SizedBox(height: 8,), - // Row( - // children: [ - // ASubTitle(_subtitle.faultDescription), - // Expanded( - // child: SizedBox( - // height: 32 * AppStyle.getScaleFactor(context), - // child: SpeechToTextButton( - // controller: _faultController, - // mini: true, - // ), - // ), - // ), - // ], - // ), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: _serviceReport?.faultDescriptionId, - // textAlign: TextAlign.center, - // controller: _faultController, - // style: Theme.of(context).textTheme.subtitle1, - // validator: (value) => - // Validator.hasValue(value) - // ? null : _subtitle.requiredWord, - // textInputType: TextInputType.multiline, - // onSaved: (value){ - // _serviceReport.faultDescriptionId = value; - // }, - // ), - // const SizedBox(height: 8,), - // Row( - // children: [ - // ASubTitle(_subtitle.workPreformed), - // Expanded( - // child: SizedBox( - // height: 32 * AppStyle.getScaleFactor(context), - // child: SpeechToTextButton( - // controller: _workPreformedController, - // mini: true, - // ), - // ), - // ), - // ], - // ), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: _serviceReport?.workPreformed, - // textAlign: TextAlign.center, - // controller: _workPreformedController, - // style: Theme.of(context).textTheme.subtitle1, - // validator: (value) => - // Validator.hasValue(value) - // ? null : _subtitle.requiredWord, - // textInputType: TextInputType.multiline, - // onSaved: (value){ - // _serviceReport.workPreformed = value; - // }, - // ), - // const SizedBox(height: 8,), - - const SizedBox( - height: 8, - ), - Row( - children: [ - // reasons - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ASubTitle(_subtitle.reasons), - const SizedBox( - height: 4, - ), - ServiceReportReasonsMenu( - initialValue: _serviceReport.reason, - onSelect: (status) { - _serviceReport.reason = status; - }, + // const SizedBox(height: 8,), + // Row( + // children: [ + // ASubTitle(_subtitle.faultDescription), + // Expanded( + // child: SizedBox( + // height: 32 * AppStyle.getScaleFactor(context), + // child: SpeechToTextButton( + // controller: _faultController, + // mini: true, + // ), + // ), + // ), + // ], + // ), + // const SizedBox(height: 4,), + // ATextFormField( + // initialValue: _serviceReport?.faultDescriptionId, + // textAlign: TextAlign.center, + // controller: _faultController, + // style: Theme.of(context).textTheme.subtitle1, + // validator: (value) => + // Validator.hasValue(value) + // ? null : _subtitle.requiredWord, + // textInputType: TextInputType.multiline, + // onSaved: (value){ + // _serviceReport.faultDescriptionId = value; + // }, + // ), + // const SizedBox(height: 8,), + // Row( + // children: [ + // ASubTitle(_subtitle.workPreformed), + // Expanded( + // child: SizedBox( + // height: 32 * AppStyle.getScaleFactor(context), + // child: SpeechToTextButton( + // controller: _workPreformedController, + // mini: true, + // ), + // ), + // ), + // ], + // ), + // const SizedBox(height: 4,), + // ATextFormField( + // initialValue: _serviceReport?.workPreformed, + // textAlign: TextAlign.center, + // controller: _workPreformedController, + // style: Theme.of(context).textTheme.subtitle1, + // validator: (value) => + // Validator.hasValue(value) + // ? null : _subtitle.requiredWord, + // textInputType: TextInputType.multiline, + // onSaved: (value){ + // _serviceReport.workPreformed = value; + // }, + // ), + // const SizedBox(height: 8,), + const SizedBox(height: 8), + ASubTitle(_subtitle.workingHours), + const SizedBox(height: 8), + Row( + children: [ + Expanded( + child: AppTimer( + timer: _serviceReport.timer, + enabled: false, + // onChange: (timer) async { + // _serviceReport.timer = timer; + // _serviceReport.workingHours = num.tryParse((((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0"); + // return true; + // }, ), - ], + ), + ], + ), + const SizedBox(height: 16), + if (_showCommentField) + const SizedBox( + height: 8, + ), + if (_showCommentField) + ATextFormField( + initialValue: _serviceReport?.reviewComment, + hintText: "Review Comment", + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleMedium, + textInputType: TextInputType.multiline, + onSaved: (value) { + _serviceReport.reviewComment = value; + }, ), + SizedBox( + height: 8 * AppStyle.getScaleFactor(context), ), + const SizedBox(height: 8), + ASubTitle(_subtitle.faultDescription), const SizedBox( - width: 8, + height: 4, ), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ASubTitle(_subtitle.attachImage), - AMiniOneImagePicker( - //error: _validate && _serviceReport.image == null, - image: _image, - onPick: (image) { - _image = image; - _serviceReport.image = base64Encode(image.readAsBytesSync()); - }, - ), - ], - ), + ServiceReportFaultDescription( + requestId: widget.request?.id, + initialValue: _serviceReport.faultDescription, + onSelect: (status) { + print("faluttt:${status?.toJson()}"); + _serviceReport.faultDescription = status; + if (mounted) setState(() {}); + }, ), - ], - ), - const SizedBox( - height: 8, - ), - // Traveling Hours & Working Hours - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - ASubTitle(_subtitle.workingHours), - const SizedBox( - height: 8, + const SizedBox(height: 8), + ASubTitle(_subtitle.workPreformed), + const SizedBox(height: 4), + ATextFormField( + initialValue: _serviceReport?.workPreformed, + textAlign: TextAlign.center, + enable: false, + hintText: _serviceReport.faultDescription?.workPerformed ?? "", + controller: _workPreformedController, + style: Theme.of(context).textTheme.subtitle1, + validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord, + textInputType: TextInputType.multiline, + onSaved: (value) { + // _serviceReport.workPreformed = value; + }, + ), + const SizedBox(height: 4), + Row( + children: [ + // reasons + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ASubTitle(_subtitle.reasons), + const SizedBox( + height: 4, + ), + ServiceReportReasonsMenu( + initialValue: _serviceReport.reason, + onSelect: (status) { + _serviceReport.reason = status; + }, + ), + ], ), - Row( + ), + const SizedBox( + width: 8, + ), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: AppTimer( - timer: _serviceReport.timer, - onChange: (timer) async { - _serviceReport.timer = timer; - return true; - }, - ), + ASubTitle(_subtitle.attachImage), + AMiniOneImagePicker( + //error: _validate && _serviceReport.image == null, + image: _image, + onPick: (image) { + _image = image; + _serviceReport.image = base64Encode(image.readAsBytesSync()); + }, ), ], ), - // ATextFormField( - // initialValue: _serviceReport?.workHours, - // textAlign: TextAlign.center, - // hintText: "i.e 3, 3.5, 4", - // style: Theme.of(context).textTheme.subtitle1, - // validator: (value) => - // Validator.isNumeric(value) - // ? null : _subtitle.requiredWord, - // textInputType: TextInputType.number, - // onSaved: (value){ - // _serviceReport.workHours = value; - // }, - // ), - ], - ), + ), + ], + ), + const SizedBox( + height: 8, + ), + const SizedBox(height: 8), + ASubTitle(_subtitle.repairLocation), + const SizedBox(height: 4), + ServiceReportRepairLocation( + initialValue: _serviceReport.repairLocation, + onSelect: (status) { + _serviceReport.repairLocation = status; + }, + ), + const SizedBox(height: 16), + ASubTitle(_subtitle.travelingExpense), + const SizedBox( + height: 4, + ), + ATextFormField( + initialValue: _serviceReport?.travelingExpense?.toString(), + hintText: _subtitle.travelingExpense, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleMedium, + textInputType: TextInputType.number, + onSaved: (value) { + if (value != null && value.isEmpty) { + _serviceReport.travelingExpense = int.tryParse(_serviceReport?.travelingExpense?.toString() ?? "") ?? 0; + } else + _serviceReport.travelingExpense = int.tryParse(value) ?? 0; + }, + ), + + const SizedBox(height: 8), + ASubTitle(_subtitle.travelingHours), + const SizedBox(height: 4), + ATextFormField( + initialValue: _serviceReport?.travelingHours?.toString(), + textAlign: TextAlign.center, + hintText: "i.e 3, 3.5, 4", + style: Theme.of(context).textTheme.subtitle1, + // validator: (value) => + // Validator.isNumeric(value) + // ? null : _subtitle.requiredWord, + textInputType: TextInputType.number, + onSaved: (value) { + _serviceReport.travelingHours = double.tryParse(value) ?? 0.0; + }, ), - // const SizedBox(width: 8,), - // Expanded( - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // ASubTitle(_subtitle.travelingHours), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: _serviceReport?.travelingHours, - // textAlign: TextAlign.center, - // hintText: "i.e 3, 3.5, 4", - // style: Theme.of(context).textTheme.subtitle1, - // validator: (value) => - // Validator.isNumeric(value) - // ? null : _subtitle.requiredWord, - // textInputType: TextInputType.number, - // onSaved: (value){ - // _serviceReport.travelingHours = value; - // }, + // Traveling Hours & Working Hours + // Row( + // children: [ + // Expanded( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // ASubTitle(_subtitle.workingHours), + // const SizedBox( + // height: 8, + // ), + // Row( + // children: [ + // Expanded( + // child: AppTimer( + // timer: _serviceReport.timer, + // onChange: (timer) async { + // _serviceReport.timer = timer; + // return true; + // }, + // ), + // ), + // ], + // ), + // // ATextFormField( + // // initialValue: _serviceReport?.workHours, + // // textAlign: TextAlign.center, + // // hintText: "i.e 3, 3.5, 4", + // // style: Theme.of(context).textTheme.subtitle1, + // // validator: (value) => + // // Validator.isNumeric(value) + // // ? null : _subtitle.requiredWord, + // // textInputType: TextInputType.number, + // // onSaved: (value){ + // // _serviceReport.workHours = value; + // // }, + // // ), + // ], + // ), + // ), + // // const SizedBox(width: 8,), + // // Expanded( + // // child: Column( + // // crossAxisAlignment: CrossAxisAlignment.start, + // // children: [ + // // ASubTitle(_subtitle.travelingHours), + // // const SizedBox(height: 4,), + // // ATextFormField( + // // initialValue: _serviceReport?.travelingHours, + // // textAlign: TextAlign.center, + // // hintText: "i.e 3, 3.5, 4", + // // style: Theme.of(context).textTheme.subtitle1, + // // validator: (value) => + // // Validator.isNumeric(value) + // // ? null : _subtitle.requiredWord, + // // textInputType: TextInputType.number, + // // onSaved: (value){ + // // _serviceReport.travelingHours = value; + // // }, + // // ), + // // ], + // // ), + // // ), + // ], + // ), + // const SizedBox( + // height: 8, + // ), + // Operating Hours and Job Sheet Number + // Row( + // children: [ + // Expanded( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // ASubTitle(_subtitle.operatingHours), + // const SizedBox(height: 4,), + // ATextFormField( + // initialValue: _serviceReport?.operatingHours, + // textAlign: TextAlign.center, + // hintText: "i.e 3, 3.5, 4", + // style: Theme.of(context).textTheme.subtitle1, + // validator: (value) => + // Validator.isNumeric(value) + // ? null : _subtitle.requiredWord, + // textInputType: TextInputType.number, + // onSaved: (value){ + // _serviceReport.operatingHours = value; + // }, + // ), + // ], + // ), + // ), + // const SizedBox(width: 8,), + // Expanded( + // child: Column( + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // ASubTitle(_subtitle.jobSheetNumber), + // const SizedBox(height: 4,), + // ATextFormField( + // initialValue: _serviceReport?.jobSheetNumber, + // textAlign: TextAlign.center, + // style: Theme.of(context).textTheme.subtitle1, + // textInputType: TextInputType.name, + // onSaved: (value){ + // _serviceReport.jobSheetNumber = value; + // }, + // ), + // ], // ), - // ], - // ), + // ), + // ], // ), + //const SizedBox(height: 8,), + + const SizedBox(height: 8), + ASubTitle(_subtitle.comment), + const SizedBox(height: 4), + ATextFormField( + initialValue: _serviceReport?.comment, + hintText: "Technical Comment", + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleMedium, + textInputType: TextInputType.multiline, + onSaved: (value) { + _serviceReport.comment = value; + }, + ), + const SizedBox(height: 8), + const ASubTitle("Nurse Signature"), + ESignature( + oldSignature: _serviceReport.signatureNurse, + newSignature: _serviceReport.localNurseSignature, + onSaved: (signature) { + if (signature == null || signature.isEmpty) { + return; + } + _serviceReport.localNurseSignature = signature; + _serviceReport.signatureNurse = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + }, + ), + const SizedBox( + height: 8, + ), + const ASubTitle("Engineer Signature"), + ESignature( + oldSignature: _serviceReport.signatureEngineer, + newSignature: _serviceReport.localNurseSignature, + onSaved: (signature) { + if (signature == null || signature.isEmpty) { + return; + } + _serviceReport.localNurseSignature = signature; + _serviceReport.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; + }, + ), + const SizedBox( + height: 8, + ), + // Part Number and Quantity ], ), - const SizedBox( - height: 8, - ), - // Operating Hours and Job Sheet Number - // Row( - // children: [ - // Expanded( - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // ASubTitle(_subtitle.operatingHours), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: _serviceReport?.operatingHours, - // textAlign: TextAlign.center, - // hintText: "i.e 3, 3.5, 4", - // style: Theme.of(context).textTheme.subtitle1, - // validator: (value) => - // Validator.isNumeric(value) - // ? null : _subtitle.requiredWord, - // textInputType: TextInputType.number, - // onSaved: (value){ - // _serviceReport.operatingHours = value; - // }, - // ), - // ], - // ), - // ), - // const SizedBox(width: 8,), - // Expanded( - // child: Column( - // crossAxisAlignment: CrossAxisAlignment.start, - // children: [ - // ASubTitle(_subtitle.jobSheetNumber), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: _serviceReport?.jobSheetNumber, - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.name, - // onSaved: (value){ - // _serviceReport.jobSheetNumber = value; - // }, - // ), - // ], - // ), - // ), - // ], - // ), - //const SizedBox(height: 8,), - const SizedBox( - height: 8, - ), - const ASubTitle("Nurse Signature"), - ESignature( - oldSignature: _serviceReport.signatureNurse, - newSignature: _serviceReport.localNurseSignature, - onChange: (signature) { - if (signature == null || signature.isEmpty) { - return; - } - _serviceReport.localNurseSignature = signature; - _serviceReport.signatureNurse = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - }, - ), - const SizedBox( - height: 8, - ), - const ASubTitle("Engineer Signature"), - ESignature( - oldSignature: _serviceReport.signatureEngineer, - newSignature: _serviceReport.localNurseSignature, - onChange: (signature) { - if (signature == null || signature.isEmpty) { - return; - } - _serviceReport.localNurseSignature = signature; - _serviceReport.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; - }, - ), - const SizedBox( - height: 8, - ), - // Part Number and Quantity + ), + ], + ), + ASubTitle("Spare Parts"), + Container( + width: double.infinity, + padding: const EdgeInsets.all(16), + margin: const EdgeInsets.symmetric(vertical: 16), + decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [ + BoxShadow( + color: AColors.grey, + offset: Offset(0, -1), + ) + ]), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ Row( children: [ Expanded( @@ -713,53 +997,56 @@ class _EditServiceReportState extends State with TickerProvid ); }), ), - const SizedBox( height: 16, ), ], ), ), - Padding( - padding: const EdgeInsets.all(16.0), - child: AButton( - text: _subtitle.update, - onPressed: () async { - _validate = true; - if (!_formKey.currentState.validate()) { - setState(() {}); - return; - } - if (!_serviceReport.validate()) { - setState(() {}); - return; - } - _formKey.currentState.save(); + AButton( + text: _subtitle.update, + onPressed: () async { + if (_serviceReport?.workingHours == null) { + await Fluttertoast.showToast(msg: "Working Hours Timer Isn't Started"); + return; + } else if ((_serviceReport?.timer?.stopped ?? false) == false) { + await Fluttertoast.showToast(msg: "Stop The Timer"); + return; + } + _validate = true; + print("jere1245"); + // if (!_formKey.currentState.validate()) { + // setState(() {}); + // return; + // } + // print("jere124"); + // if (!_serviceReport.validate()) { + // setState(() {}); + // return; + // } + // print("jere14"); + _formKey.currentState.save(); - _isLoading = true; - setState(() {}); + _isLoading = true; + setState(() {}); - int status = await _serviceRequestsProvider.updateServiceReport(user: _userProvider.user, host: _settingProvider.host, report: _serviceReport, request: widget.request); - _isLoading = false; - setState(() {}); - if (status >= 200 && status < 300) { - Fluttertoast.showToast( - msg: _subtitle.requestCompleteSuccessfully, - ); - Navigator.of(context).pop(); - Navigator.of(context).pop(); - } else { - String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle); - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text(errorMessage), - )); - } - }, - ), + int status = await _serviceRequestsProvider.updateServiceReport(user: _userProvider.user, host: _settingProvider.host, report: _serviceReport, request: widget.request); + _isLoading = false; + setState(() {}); + if (status >= 200 && status < 300) { + Fluttertoast.showToast( + msg: _subtitle.requestCompleteSuccessfully, + ); + Navigator.of(context).pop(); + Navigator.of(context).pop(); + } else { + String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle); + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text(errorMessage), + )); + } + }, ), - const SizedBox( - height: 300, - ) ], ), const ABackButton(), diff --git a/lib/views/pages/user/requests/report/future_service_report.dart b/lib/views/pages/user/requests/report/future_service_report.dart index 1a987b0..c391b66 100644 --- a/lib/views/pages/user/requests/report/future_service_report.dart +++ b/lib/views/pages/user/requests/report/future_service_report.dart @@ -15,7 +15,7 @@ import 'edit_service_report.dart'; class FutureServiceReport extends StatefulWidget { final ServiceRequest request; - final SearchWorkOrders workOrder; + final SearchWorkOrder workOrder; const FutureServiceReport({Key key, this.request, this.workOrder}) : super(key: key); @@ -31,6 +31,8 @@ class _FutureServiceReportState extends State { _userProvider = Provider.of(context); _settingProvider = Provider.of(context); Subtitle _subtitle = AppLocalization.of(context).subtitle; + ServiceRequestsProvider().getSingleServiceReport(reportId: widget.workOrder.id, user: _userProvider.user, host: _settingProvider.host, subtitle: _subtitle) + ; return Scaffold( body: FutureBuilder( future: ServiceRequestsProvider().getSingleServiceReport(reportId: widget.workOrder.id, user: _userProvider.user, host: _settingProvider.host, subtitle: _subtitle), diff --git a/lib/views/pages/user/requests/request_details.dart b/lib/views/pages/user/requests/request_details.dart index 36f3f94..03ef657 100644 --- a/lib/views/pages/user/requests/request_details.dart +++ b/lib/views/pages/user/requests/request_details.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; @@ -21,7 +20,6 @@ import 'package:test_sa/views/widgets/images/images_list.dart'; import 'package:test_sa/views/widgets/loaders/image_loader.dart'; import 'package:test_sa/views/widgets/requests/info_row.dart'; import 'package:test_sa/views/widgets/requests/request_status.dart'; -import 'package:test_sa/views/widgets/requests/service_request_update_dialog.dart'; import 'package:test_sa/views/widgets/sound/sound_player.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; @@ -39,7 +37,7 @@ class RequestDetailsPage extends StatelessWidget { Subtitle _subtitle = AppLocalization.of(context).subtitle; UserProvider _userProvider = Provider.of(context); SettingProvider _settingProvider = Provider.of(context); - List workOrders = []; + List workOrders = []; ServiceRequestsProvider _serviceRequestsProvider = Provider.of(context); return DefaultTabController( length: 2, @@ -305,114 +303,135 @@ class RequestDetailsPage extends StatelessWidget { FutureBuilder( future: _serviceRequestsProvider.searchWorkOrders(callId: serviceRequest.requestCode), builder: (context, snap) { - workOrders = snap.data as List; + workOrders = snap.data as List; if (snap.connectionState == ConnectionState.waiting) return Center(child: CircularProgressIndicator()); if (snap.connectionState == ConnectionState.done && (snap.data?.length ?? 0) != 0) { - return ListView.separated( - padding: EdgeInsets.all(21), - itemCount: workOrders.length, - separatorBuilder: (czt, index) => 21.height, - itemBuilder: (context, index) { - Color itemColor = index % 2 == 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; - Color onItemColor = index % 2 != 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; + return SingleChildScrollView( + child: Column( + children: [ + ListView.separated( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + padding: EdgeInsets.all(21), + itemCount: workOrders.length, + separatorBuilder: (czt, index) => 21.height, + itemBuilder: (context, index) { + Color itemColor = index % 2 == 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; + Color onItemColor = index % 2 != 0 ? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.onPrimary; - return ElevatedButton( - style: ElevatedButton.styleFrom( - padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8), - primary: itemColor.withOpacity(.7), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), - ), + return ElevatedButton( + style: ElevatedButton.styleFrom( + padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8), + primary: itemColor.withOpacity(.7), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), + ), + ), + //padding: EdgeInsets.symmetric(vertical: 8,horizontal: 8), + onPressed: () { + // onPressed(request); + }, + child: Column( + children: [ + RequestInfoRow( + title: _subtitle.callId, + content: serviceRequest.requestCode, + ), + RequestInfoRow( + title: _subtitle.orderWorkNumber, + info: workOrders[index].workOrderNo.toString(), + ), + RequestInfoRow( + title: _subtitle.visitDate, + info: workOrders[index].visitDate, + ), + RequestInfoRow(title: _subtitle.assignedEmployee, info: workOrders[index].assignedEmployee?.name??""), + RequestInfoRow( + title: _subtitle.assetSN, + info: workOrders[index].callRequest.asset.assetSerialNo, + ), + RequestInfoRow( + title: _subtitle.assetName, + info: workOrders[index].callRequest.asset.modelDefinition.assetName, + ), + RequestInfoRow( + title: _subtitle.model, + info: workOrders[index].callRequest.asset.modelDefinition.modelName, + ), + RequestInfoRow( + title: _subtitle.site, + info: workOrders[index].callRequest.asset.site.custName, + ), + RequestInfoRow( + title: _subtitle.maintenanceSituation, + info: workOrders[index].calllastSituation.name ?? '', + ), + RequestInfoRow( + title: _subtitle.currentSituation, + info: workOrders[index].currentSituation.name ?? '', + ), + _userProvider.user.type == UsersTypes.engineer && workOrders[index].workOrderNo != null + ? Padding( + padding: EdgeInsets.all(32), + child: AButton( + text: _subtitle.editServiceReport, + onPressed: () { + Navigator.of(context).push( + MaterialPageRoute( + builder: (_) => FutureServiceReport( + request: serviceRequest, + workOrder: workOrders[index], + )), + ); + }, + ), + ) + : SizedBox.shrink(), + ], + ), + ); + }, ), - //padding: EdgeInsets.symmetric(vertical: 8,horizontal: 8), - onPressed: () { - // onPressed(request); - }, - child: Column( - children: [ - RequestInfoRow( - title: _subtitle.callId, - content: serviceRequest.requestCode, - ), - RequestInfoRow( - title: _subtitle.orderWorkNumber, - info: workOrders[index].workOrderNo.toString(), - ), - RequestInfoRow( - title: _subtitle.visitDate, - info: workOrders[index].visitDate, - ), - RequestInfoRow(title: _subtitle.assignedEmployee, info: workOrders[index].assignedEmployee.name), - RequestInfoRow( - title: _subtitle.assetSN, - info: workOrders[index].callRequest.asset.assetSerialNo, - ), - RequestInfoRow( - title: _subtitle.assetName, - info: workOrders[index].callRequest.asset.modelDefinition.assetName, - ), - RequestInfoRow( - title: _subtitle.model, - info: workOrders[index].callRequest.asset.modelDefinition.modelName, - ), - RequestInfoRow( - title: _subtitle.site, - info: workOrders[index].callRequest.asset.site.custName, - ), - RequestInfoRow( - title: _subtitle.maintenanceSituation, - info: workOrders[index].calllastSituation.name ?? '', - ), - RequestInfoRow( - title: _subtitle.currentSituation, - info: workOrders[index].currentSituation.name ?? '', + if (_userProvider.user.type == UsersTypes.engineer) + Center( + child: Padding( + padding: const EdgeInsets.all(32), + child: AButton( + text: "Create Report", + onPressed: () { + Navigator.of(context).push(MaterialPageRoute(builder: (_) => CreateServiceReport(request: serviceRequest))); + }, + ), ), - _userProvider.user.type == UsersTypes.engineer && workOrders[index].workOrderNo != null - ? Padding( - padding: EdgeInsets.all(32), - child: AButton( - text: _subtitle.editServiceReport, - onPressed: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => FutureServiceReport( - request: serviceRequest, - workOrder: workOrders[index], - )), - ); - }, - ), - ) - : SizedBox.shrink(), - ], - ), - ); - }, + ), + ], + ), ); } else { - return _userProvider.user.type == UsersTypes.engineer - ? Center( + return Column( + children: [ + Expanded( + child: Center( + child: ASubTitle(_subtitle.dataNotFound), + ), + ), + if (_userProvider.user.type == UsersTypes.engineer) + Center( child: Padding( - padding: EdgeInsets.all(32), + padding: const EdgeInsets.all(32), child: AButton( text: "Create Report", onPressed: () { - Navigator.of(context).push( - MaterialPageRoute( - builder: (_) => CreateServiceReport( - request: serviceRequest, - )), - ); + Navigator.of(context).push(MaterialPageRoute(builder: (_) => CreateServiceReport(request: serviceRequest))); }, ), ), - ) - : Center( - child: ASubTitle(_subtitle.noDateFound), - ); + ), + ], + ); } }, - ) + ), ], ), ), diff --git a/lib/views/pages/user/requests/requests_page.dart b/lib/views/pages/user/requests/requests_page.dart index 0616033..a21debe 100644 --- a/lib/views/pages/user/requests/requests_page.dart +++ b/lib/views/pages/user/requests/requests_page.dart @@ -44,11 +44,7 @@ class _ServiceRequestsPageState extends State with TickerPr stateCode: _serviceRequestsProvider.stateCode, onRefresh: () async { _serviceRequestsProvider.reset(); - await _serviceRequestsProvider.getRequests( - user: _userProvider.user, - host: _settingProvider.host, - hospitalId: _userProvider.user.clientId, - ); + await _serviceRequestsProvider.getRequests(hospitalId: _userProvider.user.clientId); }, child: Stack( children: [ @@ -104,11 +100,7 @@ class _ServiceRequestsPageState extends State with TickerPr child: ServiceRequestsList( nextPage: _serviceRequestsProvider.nextPage, onLazyLoad: () async { - await _serviceRequestsProvider.getRequests( - user: _userProvider.user, - host: _settingProvider.host, - hospitalId: _userProvider.user.clientId, - ); + await _serviceRequestsProvider.getRequests(hospitalId: _userProvider.user.clientId); }, requests: _serviceRequestsProvider.serviceRequests, ), diff --git a/lib/views/pages/user/visits/pantry/edit_pentry.dart b/lib/views/pages/user/visits/pantry/edit_pentry.dart index 55d356b..d2d5205 100644 --- a/lib/views/pages/user/visits/pantry/edit_pentry.dart +++ b/lib/views/pages/user/visits/pantry/edit_pentry.dart @@ -14,10 +14,11 @@ import 'package:test_sa/models/visits/visit.dart'; import 'package:test_sa/views/widgets/buttons/app_small_button.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/pentry/pentry_calibration_tool_form.dart'; -import 'package:test_sa/views/widgets/pentry/pentry_info_form.dart'; import 'package:test_sa/views/widgets/pentry/pentry_pm_kit_form.dart'; import 'package:test_sa/views/widgets/pentry/pentry_ppm_check_list_form.dart'; +import '../../../../widgets/pentry/pentry_info_form.dart'; + class EditPentry extends StatefulWidget { final Pentry pentry; final Visit visit; @@ -73,7 +74,7 @@ class _EditPentryState extends State with SingleTickerProviderStateM if (_pentry.pmKits.isEmpty) _pentry.pmKits.add(PMKit()); if (_pentry.calibrationTools.isEmpty) _pentry.calibrationTools.add(CalibrationTool()); if (_pentry.ppmCheckLists.isEmpty) _pentry.ppmCheckLists.add(PPMCheckList()); - _tabController = TabController(length: 3, vsync: this); + _tabController = TabController(length: 4, vsync: this); super.initState(); } @@ -104,25 +105,26 @@ class _EditPentryState extends State with SingleTickerProviderStateM child: Padding( padding: const EdgeInsets.all(2.0), child: TabBar( - controller: _tabController, - isScrollable: true, - onTap: (index) { - setState(() {}); - }, - tabs: const [ - Tab( - text: "PPM Check List", - ), - // Tab( - // text: "Calibration Tools", - // ), - Tab( - text: "PK Kits", - ), - Tab( - text: "Pentry", - ), - ]), + controller: _tabController, + isScrollable: true, + onTap: (index) { + setState(() {}); + }, + tabs: const [ + Tab( + text: "PPM Check List", + ), + Tab( + text: "Calibration Tools", + ), + Tab( + text: "PM Kits", + ), + Tab( + text: "PM Entry", + ), + ], + ), ), ), Expanded( @@ -147,7 +149,7 @@ class _EditPentryState extends State with SingleTickerProviderStateM PentryInfoForm( model: _pentry, enableValidate: _validate, - ) + ), ], ), Align( diff --git a/lib/views/widgets/device_trancfer/device_transfer_info_section.dart b/lib/views/widgets/device_trancfer/device_transfer_info_section.dart index a311cb1..1a8da07 100644 --- a/lib/views/widgets/device_trancfer/device_transfer_info_section.dart +++ b/lib/views/widgets/device_trancfer/device_transfer_info_section.dart @@ -21,7 +21,7 @@ class DeviceTransferInfoSection extends StatelessWidget { info: info.client.name, ), RequestInfoRow( - title: subtitle.unite, + title: subtitle.department, info: info.department.name, ), RequestInfoRow( diff --git a/lib/views/widgets/device_trancfer/device_transfer_item.dart b/lib/views/widgets/device_trancfer/device_transfer_item.dart index 9da46fa..2039946 100644 --- a/lib/views/widgets/device_trancfer/device_transfer_item.dart +++ b/lib/views/widgets/device_trancfer/device_transfer_item.dart @@ -1,4 +1,3 @@ -import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/localization/localization.dart'; @@ -53,6 +52,13 @@ class DeviceTransferItem extends StatelessWidget { Divider( color: onItemColor, ), + Text( + item.device?.number ?? "-----", + style: Theme.of(context).textTheme.headline6.copyWith(color: onItemColor, fontSize: 16, fontWeight: FontWeight.bold), + ), + Divider( + color: onItemColor, + ), Row( children: [ Expanded( diff --git a/lib/views/widgets/equipment/device_item.dart b/lib/views/widgets/equipment/device_item.dart index e9fb904..0dd41e7 100644 --- a/lib/views/widgets/equipment/device_item.dart +++ b/lib/views/widgets/equipment/device_item.dart @@ -27,12 +27,19 @@ class DeviceItem extends StatelessWidget { }, child: ListTile( title: Text( - "${_subtitle.sn} : ${device.serialNumber}", + "${_subtitle.assetName} : \n${device.modelDefinition.assetName}", style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + Divider( + color: Theme.of(context).scaffoldBackgroundColor, + ), + Text( + "${_subtitle.assetNumber} : ${device.number}", + style: Theme.of(context).textTheme.subtitle1.copyWith(color: AColors.white), + ), Divider( color: Theme.of(context).scaffoldBackgroundColor, ), diff --git a/lib/views/widgets/equipment/single_device_picker.dart b/lib/views/widgets/equipment/single_device_picker.dart index ab36d5f..6166ea2 100644 --- a/lib/views/widgets/equipment/single_device_picker.dart +++ b/lib/views/widgets/equipment/single_device_picker.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/providers/api/devices_provider.dart'; @@ -13,6 +12,7 @@ import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/no_item_found.dart'; import '../app_text_form_field.dart'; +import '../qr/scan_qr.dart'; class SingleDevicePicker extends StatefulWidget { static final String id = "/single-device-Picker"; @@ -32,20 +32,20 @@ class _SingleDevicePickerState extends State { TextEditingController numberController = TextEditingController(); TextEditingController snController = TextEditingController(); _getDevice(String result) async { + print(result); if (result == null) return; - showDialog( - barrierDismissible: false, - context: context, - builder: (dialogContext) { - return const Center(child: CircularProgressIndicator()); - }); - List devices = await _devicesProvider.getDevicesListBySN(host: _settingProvider.host, user: _userProvider.user, hospitalId: _userProvider.user.clientId, sn: result); - Navigator.of(context).pop(); - if (devices.isEmpty) { - Fluttertoast.showToast(msg: _subtitle.noDeviceFound); - return; - } - Navigator.of(context).pop(devices.first); + // List devices = await _devicesProvider.getDevicesListBySN(host: _settingProvider.host, user: _userProvider.user, hospitalId: _userProvider.user.clientId, sn: result); + _devicesProvider.reset(); + await _devicesProvider.getEquipment(user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: "", number: result); + _searchableList.clear(); + _searchableList.addAll(_devicesProvider.devices); + // Navigator.of(context).pop(); + // Navigator.of(context).pop(); + // if (devices.isEmpty) { + // Fluttertoast.showToast(msg: _subtitle.noDeviceFound); + // return; + // } + // Navigator.of(context).pop(devices.first); } @override @@ -73,93 +73,95 @@ class _SingleDevicePickerState extends State { _subtitle = AppLocalization.of(context).subtitle; return Scaffold( resizeToAvoidBottomInset: false, - body: LoadingManager( - isLoading: _devicesProvider.isLoading, - stateCode: _devicesProvider.stateCode, - isFailedLoading: _devicesProvider.devices == null, - onRefresh: () async { - _devicesProvider.reset(); - await _devicesProvider.getEquipment(user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId); - }, - child: Column( - children: [ - const SizedBox(height: 48), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), - child: Column( - children: [ - ATextFormField( - hintText: _subtitle.searchBySn, - controller: snController, - style: Theme.of(context).textTheme.subtitle1, - suffixIcon: const Icon(Icons.search_rounded), - textInputAction: TextInputAction.search, - onAction: () async { - _devicesProvider.reset(); - await _devicesProvider.getEquipment( - user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text); - _searchableList.clear(); - _searchableList.addAll(_devicesProvider.devices); - }, - ), - const SizedBox( - height: 8, - ), - ATextFormField( - hintText: "Search by Number", - controller: numberController, - style: Theme.of(context).textTheme.subtitle1, - suffixIcon: const Icon(Icons.search_rounded), - textInputAction: TextInputAction.search, - onAction: () async { - _devicesProvider.reset(); - await _devicesProvider.getEquipment( - user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text); - _searchableList.clear(); - _searchableList.addAll(_devicesProvider.devices); - }, - ), - ], + body: SafeArea( + child: LoadingManager( + isLoading: _devicesProvider.isLoading, + stateCode: _devicesProvider.stateCode, + isFailedLoading: _devicesProvider.devices == null, + onRefresh: () async { + _devicesProvider.reset(); + await _devicesProvider.getEquipment(user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId); + }, + child: Column( + children: [ + const SizedBox(height: 16), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), + child: Column( + children: [ + ATextFormField( + hintText: _subtitle.searchBySn, + controller: snController, + style: Theme.of(context).textTheme.subtitle1, + suffixIcon: const Icon(Icons.search_rounded), + textInputAction: TextInputAction.search, + onAction: () async { + _devicesProvider.reset(); + await _devicesProvider.getEquipment( + user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text); + _searchableList.clear(); + _searchableList.addAll(_devicesProvider.devices); + }, + ), + const SizedBox( + height: 8, + ), + ATextFormField( + hintText: "Search by Number", + controller: numberController, + style: Theme.of(context).textTheme.subtitle1, + suffixIcon: const Icon(Icons.search_rounded), + textInputAction: TextInputAction.search, + onAction: () async { + _devicesProvider.reset(); + await _devicesProvider.getEquipment( + user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text); + _searchableList.clear(); + _searchableList.addAll(_devicesProvider.devices); + }, + ), + ], + ), ), - ), - Expanded( - child: _searchableList.isEmpty - ? NoItemFound( - message: _subtitle.noDeviceFound, - ) - : LazyLoading( - nextPage: _devicesProvider.nextPage, - onLazyLoad: () async { - await _devicesProvider.getDevicesList( - user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text); - }, - child: ListView.builder( - padding: EdgeInsets.zero, - shrinkWrap: true, - itemCount: _searchableList.length, - itemBuilder: (listContext, itemIndex) { - return DeviceItem( - device: _searchableList[itemIndex], - onPressed: (device) { - Navigator.of(context).pop(device); - }, - ); + Expanded( + child: _searchableList.isEmpty + ? NoItemFound( + message: _subtitle.noDeviceFound, + ) + : LazyLoading( + nextPage: _devicesProvider.nextPage, + onLazyLoad: () async { + await _devicesProvider.getDevicesList( + user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: snController.text, number: numberController.text); }, - ), - )), - ], + child: ListView.builder( + padding: EdgeInsets.zero, + shrinkWrap: true, + itemCount: _searchableList.length, + itemBuilder: (listContext, itemIndex) { + return DeviceItem( + device: _searchableList[itemIndex], + onPressed: (device) { + Navigator.of(context).pop(device); + }, + ); + }, + ), + )), + ], + ), ), ), - // floatingActionButton: FloatingActionButton( - // heroTag: "some tag 2", - // child: const Icon(Icons.qr_code_scanner), - // onPressed: () async { - // String result = await Navigator.of(context).push( - // MaterialPageRoute(builder: (_)=> const ScanQr()), - // ) as String; - // _getDevice(result); - // }, - // ), + floatingActionButton: FloatingActionButton( + heroTag: "some tag 2", + child: const Icon(Icons.qr_code_scanner), + onPressed: () async { + String result = await Navigator.of(context).push( + MaterialPageRoute(builder: (_) => const ScanQr()), + ) as String; + _getDevice(result); + }, + ), ); } } diff --git a/lib/views/widgets/gas_refill/building_type_menu.dart b/lib/views/widgets/gas_refill/building_type_menu.dart index 2cfb901..2043f15 100644 --- a/lib/views/widgets/gas_refill/building_type_menu.dart +++ b/lib/views/widgets/gas_refill/building_type_menu.dart @@ -1,15 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:provider/provider.dart'; -import 'package:test_sa/controllers/providers/api/status_drop_down/gas_refill/gas_types_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/models/hospital.dart'; -import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/sizing.dart'; -import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; -import 'package:test_sa/views/widgets/status/single_status_menu.dart'; class BuildingTypeMenu extends StatefulWidget { final Function(Buildings) onSelect; @@ -41,6 +33,9 @@ class _BuildingTypeMenuState extends State { _building = widget.building; _selectedBuilding = null; } + if (oldWidget.initialValue != widget.initialValue && widget.initialValue != null) { + _selectedBuilding = widget.initialValue; + } super.didUpdateWidget(oldWidget); } diff --git a/lib/views/widgets/gas_refill/department_type_menu.dart b/lib/views/widgets/gas_refill/department_type_menu.dart index 4014f57..1b58c20 100644 --- a/lib/views/widgets/gas_refill/department_type_menu.dart +++ b/lib/views/widgets/gas_refill/department_type_menu.dart @@ -1,15 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:provider/provider.dart'; -import 'package:test_sa/controllers/providers/api/status_drop_down/gas_refill/gas_types_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/models/hospital.dart'; -import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/sizing.dart'; -import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; -import 'package:test_sa/views/widgets/status/single_status_menu.dart'; class DepartmentTypeMenu extends StatefulWidget { final Function(Departments) onSelect; @@ -41,6 +33,9 @@ class _DepartmentTypeMenuState extends State { _departments = widget.departments; _selected = null; } + if (oldWidget.initialValue != widget.initialValue && widget.initialValue != null) { + _selected = widget.initialValue; + } super.didUpdateWidget(oldWidget); } diff --git a/lib/views/widgets/gas_refill/floor_type_menu.dart b/lib/views/widgets/gas_refill/floor_type_menu.dart index 9658b53..e8fe78f 100644 --- a/lib/views/widgets/gas_refill/floor_type_menu.dart +++ b/lib/views/widgets/gas_refill/floor_type_menu.dart @@ -1,15 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; -import 'package:provider/provider.dart'; -import 'package:test_sa/controllers/providers/api/status_drop_down/gas_refill/gas_types_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/models/hospital.dart'; -import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/sizing.dart'; -import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; -import 'package:test_sa/views/widgets/status/single_status_menu.dart'; class FloorTypeMenu extends StatefulWidget { final Function(Floors) onSelect; @@ -41,6 +33,9 @@ class _FloorTypeMenuState extends State { _floors = widget.floors; _selected = null; } + if (oldWidget.initialValue != widget.initialValue && widget.initialValue != null) { + _selected = widget.initialValue; + } super.didUpdateWidget(oldWidget); } diff --git a/lib/views/widgets/gas_refill/gas_refill_create_details_item.dart b/lib/views/widgets/gas_refill/gas_refill_create_details_item.dart index 41d0806..3d913f6 100644 --- a/lib/views/widgets/gas_refill/gas_refill_create_details_item.dart +++ b/lib/views/widgets/gas_refill/gas_refill_create_details_item.dart @@ -1,38 +1,92 @@ import 'package:flutter/material.dart'; import 'package:test_sa/models/gas_refill/gas_refill_details.dart'; import 'package:test_sa/views/app_style/colors.dart'; +import 'package:test_sa/views/widgets/app_text_form_field.dart'; -class GasRefillCreateDetailsItem extends StatelessWidget { +import '../../../controllers/localization/localization.dart'; +import '../buttons/app_button.dart'; +import '../titles/app_sub_title.dart'; + +class GasRefillCreateDetailsItem extends StatefulWidget { final GasRefillDetails model; - final VoidCallback onDelete; + final VoidCallback onPressed; + final bool isUpdate; + + const GasRefillCreateDetailsItem({Key key, this.isUpdate, this.model, this.onPressed}) : super(key: key); + + @override + State createState() => _GasRefillCreateDetailsItemState(); +} - const GasRefillCreateDetailsItem({Key key, this.model, this.onDelete}) : super(key: key); +class _GasRefillCreateDetailsItemState extends State { + GlobalKey _formKey; + + @override + void initState() { + super.initState(); + _formKey = GlobalKey(); + } @override Widget build(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [Expanded(child: Text(model.type.name)), IconButton(onPressed: onDelete, color: AColors.red, icon: const Icon(Icons.delete))], - ), - Wrap( - spacing: 10, - children: [ - Text("Quantity: ${model.requestedQuantity.toStringAsFixed(0)}"), - Text("Cylinder Size: ${model.cylinderSize.name}"), - Text("Cylinder Type: ${model.cylinderType.name}"), - ], - ), - if (model.deliveredQuantity != null) + final subtitle = AppLocalization.of(context).subtitle; + final startEditing = widget.isUpdate && (widget.model.selectedForEditing ?? false); + return Form( + key: _formKey, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ Row( children: [ - const Text("Delivered Quantity"), - Text(model.deliveredQuantity.toStringAsFixed(0)), + Expanded(child: Text(widget.model.type.name)), + IconButton(onPressed: widget.onPressed, color: widget.isUpdate ? AColors.cyan : AColors.red, icon: Icon(widget.isUpdate ? Icons.edit : Icons.delete)) + ], + ), + Wrap( + spacing: 10, + children: [ + Text("Quantity: ${widget.model.requestedQuantity.toStringAsFixed(0)}"), + Text("Cylinder Size: ${widget.model.cylinderSize.name}"), + Text("Cylinder Type: ${widget.model.cylinderType.name}"), ], ), - const Divider(), - ], + if (widget.model.deliveredQuantity != null) + Row( + children: [ + const Text("Delivered Quantity: "), + Text(widget.model.deliveredQuantity.toStringAsFixed(0)), + ], + ), + if (startEditing) const SizedBox(height: 16), + if (startEditing) ASubTitle(subtitle.deliveredQuantity), + if (startEditing) const SizedBox(height: 4), + if (startEditing) + ATextFormField( + initialValue: widget.model.deliveredQuantity?.toString() ?? "0", + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleMedium, + // validator: (value) => Validator.isNumeric(value) ? null : "allow numbers only", + textInputType: TextInputType.number, + onSaved: (value) { + if (value.isNotEmpty) { + widget.model.deliveredQuantity = double.tryParse(value); + } else { + widget.model.deliveredQuantity = 0; + } + }, + ), + if (startEditing) const SizedBox(height: 8), + if (startEditing) + AButton( + text: subtitle.edit, + onPressed: () { + _formKey.currentState?.save(); + widget.onPressed(); + }, + ), + const Divider(), + ], + ), ); } } diff --git a/lib/views/widgets/land_page/land_page_item.dart b/lib/views/widgets/land_page/land_page_item.dart index a3085e6..10b7ff0 100644 --- a/lib/views/widgets/land_page/land_page_item.dart +++ b/lib/views/widgets/land_page/land_page_item.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/sizing.dart'; @@ -6,8 +7,8 @@ class LandPageItem extends StatelessWidget { final String text; final IconData icon; final VoidCallback onPressed; - - const LandPageItem({Key key, this.text, this.icon, this.onPressed}) : super(key: key); + final String svgPath; + const LandPageItem({Key key, this.svgPath, this.text, this.icon, this.onPressed}) : super(key: key); @override Widget build(BuildContext context) { @@ -30,12 +31,20 @@ class LandPageItem extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Icon( - icon, - color: AColors.primaryColor, - size: 42 * AppStyle.getScaleFactor(context), - ), - Text(text, style: TextStyle(color: AColors.grey3A)), + if (icon != null) + Icon( + icon, + color: AColors.primaryColor, + size: 42 * AppStyle.getScaleFactor(context), + ), + if (svgPath != null) + SvgPicture.asset( + svgPath, + width: 42 * AppStyle.getScaleFactor(context), + height: 42 * AppStyle.getScaleFactor(context), + color: AColors.primaryColor, + ), + Text(text, style: const TextStyle(color: AColors.grey3A)), ], ), ), diff --git a/lib/views/widgets/parts/part_item.dart b/lib/views/widgets/parts/part_item.dart index 63d411e..c108d07 100644 --- a/lib/views/widgets/parts/part_item.dart +++ b/lib/views/widgets/parts/part_item.dart @@ -6,8 +6,9 @@ import 'package:test_sa/views/widgets/buttons/app_icon_button2.dart'; class PartItem extends StatefulWidget { final Part part; final Function(Part) onDelete; + final Function(int qty) onEdit; - const PartItem({Key key, this.part, this.onDelete}) : super(key: key); + const PartItem({Key key, this.part, this.onEdit, this.onDelete}) : super(key: key); @override _PartItemState createState() => _PartItemState(); @@ -19,64 +20,73 @@ class _PartItemState extends State { //final _subtitle = AppLocalization.of(context).subtitle; return Column( children: [ - Divider(), + const Divider(), Row( children: [ Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Row( - children: [ - Expanded( - child: Text( - widget.part.code, - style: Theme.of(context).textTheme.bodyText1.copyWith(fontSize: 12, fontWeight: FontWeight.bold), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Expanded( + child: Text( + widget?.part?.code ?? "", + style: Theme.of(context).textTheme.bodyText1.copyWith(fontSize: 12, fontWeight: FontWeight.bold), + ), ), - ), - AIconButton2( - iconData: Icons.add, - color: Theme.of(context).primaryColor, - onPressed: () { - widget.part.quantity++; - setState(() {}); - }, - ), - AIconButton2( - iconData: Icons.remove, - color: Theme.of(context).primaryColor, - onPressed: widget.part.quantity < 2 - ? null - : () { - widget.part.quantity--; - setState(() {}); - }, - ), - SizedBox( - width: 8 * AppStyle.getScaleFactor(context), - ), - Text( - widget.part.quantity.toString(), - style: Theme.of(context).textTheme.headline6.copyWith( - //fontSize: 12, - //fontWeight: FontWeight.bold - ), - ), - SizedBox( - width: 8 * AppStyle.getScaleFactor(context), - ), - ], - ), - widget.part.name == null - ? SizedBox.shrink() - : Text( - widget.part.name, - style: Theme.of(context).textTheme.caption.copyWith(fontSize: 11, fontWeight: FontWeight.bold), - maxLines: 1, - overflow: TextOverflow.ellipsis, + AIconButton2( + iconData: Icons.add, + color: Theme.of(context).primaryColor, + onPressed: () { + if (widget.onEdit == null) { + ++widget.part.quantity; + } else { + widget.onEdit(++widget.part.quantity); + } + setState(() {}); + }, ), - ], - )), + AIconButton2( + iconData: Icons.remove, + color: Theme.of(context).primaryColor, + onPressed: widget.part.quantity < 2 + ? null + : () { + if (widget.onEdit == null) { + --widget.part.quantity; + } else { + widget.onEdit(--widget.part.quantity); + } + setState(() {}); + }, + ), + SizedBox( + width: 8 * AppStyle.getScaleFactor(context), + ), + Text( + widget.part.quantity.toString(), + style: Theme.of(context).textTheme.headline6.copyWith( + //fontSize: 12, + //fontWeight: FontWeight.bold + ), + ), + SizedBox( + width: 8 * AppStyle.getScaleFactor(context), + ), + ], + ), + widget.part.name == null + ? const SizedBox.shrink() + : Text( + widget.part.name, + style: Theme.of(context).textTheme.caption.copyWith(fontSize: 11, fontWeight: FontWeight.bold), + maxLines: 1, + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), AIconButton2( iconData: Icons.close, color: Colors.red, diff --git a/lib/views/widgets/pentry/pentry_calibration_tool_form.dart b/lib/views/widgets/pentry/pentry_calibration_tool_form.dart index 048e113..27033ba 100644 --- a/lib/views/widgets/pentry/pentry_calibration_tool_form.dart +++ b/lib/views/widgets/pentry/pentry_calibration_tool_form.dart @@ -43,9 +43,8 @@ class _PentryCalibrationToolFormState extends State { ); } final model = widget.models[index]; - return ListView( - shrinkWrap: true, - physics: const ClampingScrollPhysics(), + return Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, diff --git a/lib/views/widgets/pentry/pentry_info_form.dart b/lib/views/widgets/pentry/pentry_info_form.dart index 290b873..33ccd2e 100644 --- a/lib/views/widgets/pentry/pentry_info_form.dart +++ b/lib/views/widgets/pentry/pentry_info_form.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart'; @@ -15,6 +14,8 @@ import 'package:test_sa/views/widgets/status/pentry/pentry_visit_status_mune.dar import 'package:test_sa/views/widgets/timer/app_timer.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; +import '../status/pentry/pentry_status_mune.dart'; + class PentryInfoForm extends StatefulWidget { final Pentry model; final bool enableValidate; @@ -79,16 +80,21 @@ class _PentryInfoFormState extends State { const SizedBox( height: 8, ), - // const ASubTitle("Status"), - // // if(widget.enableValidate && widget.model.status == null) - // // ASubTitle(subtitle.requiredWord,color: Colors.red,), - // const SizedBox(height: 4,), - // PentryStatusMenu( - // initialValue: widget.model.status, - // onSelect: (status){ - // widget.model.status = status; - // }, - // ), + const ASubTitle("Status"), + if (widget.enableValidate && widget.model.status == null) + ASubTitle( + subtitle.requiredWord, + color: Colors.red, + ), + const SizedBox( + height: 4, + ), + PentryStatusMenu( + initialValue: widget.model.status, + onSelect: (status) { + widget.model.status = status; + }, + ), const SizedBox( height: 8, ), diff --git a/lib/views/widgets/pentry/pentry_pm_kit_form.dart b/lib/views/widgets/pentry/pentry_pm_kit_form.dart index f6ac9b1..3fb154d 100644 --- a/lib/views/widgets/pentry/pentry_pm_kit_form.dart +++ b/lib/views/widgets/pentry/pentry_pm_kit_form.dart @@ -26,133 +26,66 @@ class _PentryPMKitFormState extends State { Widget build(BuildContext context) { final subtitle = AppLocalization.of(context).subtitle; return ListView.builder( - padding: EdgeInsets.only( - top: 12 * AppStyle.getScaleFactor(context), left: 12 * AppStyle.getScaleFactor(context), right: 12 * AppStyle.getScaleFactor(context), bottom: 80 * AppStyle.getScaleFactor(context)), - itemCount: widget.models.length + 1, - itemBuilder: (context, index) { - if (index == widget.models.length) { - return AButton( - text: subtitle.add, - onPressed: () { - widget.models.add(PMKit()); - setState(() {}); - }, - ); - } - final model = widget.models[index]; - return ListView( - shrinkWrap: true, - physics: const ClampingScrollPhysics(), - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - ASubTitle("#${index + 1}"), - if (index != 0) - ASmallButton( - color: Theme.of(context).colorScheme.error, - text: subtitle.delete, - onPressed: () { - widget.models.remove(model); - setState(() {}); - }, - ), - ], - ), - const SizedBox( - height: 8, - ), - const ASubTitle("Item Code"), - const SizedBox( - height: 4, - ), - AutoCompletePartsField( - clearAfterPick: false, - initialValue: (model.itemCode?.name ?? "").toString(), - onPick: (part) { - model.itemCode = Lookup(id: part.id, name: part.code); - }, - ), - const SizedBox( - height: 8, - ), - // const ASubTitle("Item Name"), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: (model.itemName ?? "").toString(), - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.text, - // onChange: (value){ - // model.itemName = value; - // }, - // ), - // const SizedBox(height: 8,), - // const ASubTitle("Preparation Time Frame"), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: (model.preparationTimeFrame ?? "").toString(), - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.text, - // onChange: (value){ - // model.preparationTimeFrame = value; - // }, - // ), - // const SizedBox(height: 8,), - // const ASubTitle("kit Frequency Demand"), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: (model.kitFrequencyDemand ?? "").toString(), - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.text, - // onChange: (value){ - // model.kitFrequencyDemand = value; - // }, - // ), - // const SizedBox(height: 8,), - // const ASubTitle("Availability"), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: (model.availability ?? "").toString(), - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.text, - // onChange: (value){ - // model.availability = value; - // }, - // ), - // const SizedBox(height: 8,), - // const ASubTitle("Quantity Needed"), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: (model.quantityNeeded ?? "").toString(), - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.number, - // onChange: (value){ - // model.quantityNeeded = value; - // }, - // ), - // const SizedBox(height: 8,), - // const ASubTitle("Quantity Reserved"), - // const SizedBox(height: 4,), - // ATextFormField( - // initialValue: (model.quantityReserved ?? "").toString(), - // textAlign: TextAlign.center, - // style: Theme.of(context).textTheme.subtitle1, - // textInputType: TextInputType.number, - // onChange: (value){ - // model.quantityReserved = value; - // }, - // ), - // const SizedBox(height: 8,), - Divider( - color: Theme.of(context).textTheme.titleMedium.color, - ), - ], + padding: EdgeInsets.only( + top: 12 * AppStyle.getScaleFactor(context), + left: 12 * AppStyle.getScaleFactor(context), + right: 12 * AppStyle.getScaleFactor(context), + bottom: 100 * AppStyle.getScaleFactor(context) + MediaQuery.of(context).padding.bottom, + ), + itemCount: widget.models.length + 1, + shrinkWrap: true, + itemBuilder: (context, index) { + if (index == widget.models.length) { + return AButton( + text: subtitle.add, + onPressed: () { + widget.models.add(PMKit()); + setState(() {}); + }, ); - }); + } + final model = widget.models[index]; + return Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + ASubTitle("#${index + 1}"), + if (index != 0) + ASmallButton( + color: Theme.of(context).colorScheme.error, + text: subtitle.delete, + onPressed: () { + widget.models.remove(model); + setState(() {}); + }, + ), + ], + ), + const SizedBox( + height: 8, + ), + const ASubTitle("Item Code"), + const SizedBox( + height: 4, + ), + AutoCompletePartsField( + clearAfterPick: false, + initialValue: (model.itemCode?.name ?? "").toString(), + onPick: (part) { + model.itemCode = Lookup(id: part.id, name: part.code); + }, + ), + const SizedBox( + height: 8, + ), + Divider( + color: Theme.of(context).textTheme.titleMedium.color, + ), + ], + ); + }, + ); } } diff --git a/lib/views/widgets/status/assistant_employee_menu.dart b/lib/views/widgets/status/assistant_employee_menu.dart new file mode 100644 index 0000000..45f2177 --- /dev/null +++ b/lib/views/widgets/status/assistant_employee_menu.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/views/app_style/colors.dart'; +import 'package:test_sa/views/app_style/sizing.dart'; + +import '../../../models/service_request/search_work_order.dart'; + +class AssistantEmployeeMenu extends StatefulWidget { + final List statuses; + final AssistantEmployees initialStatus; + final Function(AssistantEmployees) onSelect; + + const AssistantEmployeeMenu({Key key, this.statuses, this.onSelect, this.initialStatus}) : super(key: key); + + @override + _SingleAssistantEmployeeMenuState createState() => _SingleAssistantEmployeeMenuState(); +} + +class _SingleAssistantEmployeeMenuState extends State { + AssistantEmployees _selectedStatus; + + @override + void setState(VoidCallback fn) { + if (mounted) super.setState(fn); + } + + @override + void didUpdateWidget(covariant AssistantEmployeeMenu oldWidget) { + if (widget.initialStatus != null) { + final result = widget.statuses?.where((element) { + return element?.user?.id == widget.initialStatus?.user?.id; + }); + if (result.isNotEmpty) { + _selectedStatus = result.first; + } else { + _selectedStatus = null; + } + if ((widget.initialStatus?.user?.id ?? "") != (_selectedStatus?.user?.id ?? "")) { + widget.onSelect(_selectedStatus); + } + } else { + _selectedStatus = null; + } + super.didUpdateWidget(oldWidget); + } + + @override + void initState() { + if (widget.initialStatus != null) { + final result = widget.statuses?.where((element) { + return element?.user?.id == widget.initialStatus?.user?.id; + }); + if (result.isNotEmpty) _selectedStatus = result.first; + if (widget.initialStatus?.user?.id != _selectedStatus?.user?.id) { + widget.onSelect(_selectedStatus); + } + } + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: AColors.inputFieldBackgroundColor, + border: Border.all( + color: Color(0xffefefef), + ), + borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), + // boxShadow: const [ + // AppStyle.boxShadow + // ] + ), + child: DropdownButton( + value: _selectedStatus, + iconSize: 24, + icon: const Icon(Icons.keyboard_arrow_down_rounded), + elevation: 0, + isExpanded: true, + hint: Text( + "Select", + style: Theme.of(context).textTheme.subtitle1, + ), + style: TextStyle(color: Theme.of(context).primaryColor), + underline: const SizedBox.shrink(), + onChanged: (AssistantEmployees newValue) { + setState(() { + _selectedStatus = newValue; + }); + widget.onSelect(newValue); + }, + items: widget.statuses.map>((AssistantEmployees value) { + return DropdownMenuItem( + value: value, + child: Text( + value.user?.name ?? "NULL", + style: Theme.of(context).textTheme.titleMedium.copyWith( + color: Theme.of(context).primaryColor, + fontSize: 11, + //fontWeight: FontWeight.bold + ), + ), + ); + }).toList(), + ), + ); + } +} diff --git a/lib/views/widgets/status/gas_refill/gas_status.dart b/lib/views/widgets/status/gas_refill/gas_status.dart index c46e650..7e7cbac 100644 --- a/lib/views/widgets/status/gas_refill/gas_status.dart +++ b/lib/views/widgets/status/gas_refill/gas_status.dart @@ -10,8 +10,9 @@ import 'package:test_sa/views/widgets/status/single_status_menu.dart'; class GasStatusMenu extends StatelessWidget { final Function(Lookup) onSelect; final Lookup initialValue; + final bool enabled; - const GasStatusMenu({Key key, this.onSelect, this.initialValue}) : super(key: key); + const GasStatusMenu({Key key, this.enabled = true, this.onSelect, this.initialValue}) : super(key: key); @override Widget build(BuildContext context) { final settingProvider = Provider.of(context); @@ -29,6 +30,7 @@ class GasStatusMenu extends StatelessWidget { initialStatus: initialValue, statuses: menuProvider.items, onSelect: onSelect, + enabled: enabled, )); } } diff --git a/lib/views/widgets/status/report/fault_desc_menu.dart b/lib/views/widgets/status/report/fault_desc_menu.dart index 9250c7d..5229aff 100644 --- a/lib/views/widgets/status/report/fault_desc_menu.dart +++ b/lib/views/widgets/status/report/fault_desc_menu.dart @@ -26,7 +26,7 @@ class _SingleStatusMenuState extends State { void didUpdateWidget(covariant FaultDescriptionMenu oldWidget) { if (widget.initialStatus != null) { final result = widget.statuses?.where((element) { - return element == widget.initialStatus; + return element.id == widget.initialStatus.id; }); if (result.isNotEmpty) { _selectedStatus = result.first; @@ -44,9 +44,11 @@ class _SingleStatusMenuState extends State { @override void initState() { + if (widget.initialStatus != null) { final result = widget.statuses?.where((element) { - return element == widget.initialStatus; + + return element.id == widget.initialStatus.id; }); if (result.isNotEmpty) _selectedStatus = result.first; if (widget.initialStatus.id != _selectedStatus?.id) { diff --git a/lib/views/widgets/status/report/service_report_all_users.dart b/lib/views/widgets/status/report/service_report_all_users.dart new file mode 100644 index 0000000..c309809 --- /dev/null +++ b/lib/views/widgets/status/report/service_report_all_users.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_users_provider.dart'; +import 'package:test_sa/models/engineer.dart'; +import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; +import 'package:test_sa/views/widgets/status/users_menu.dart'; + +class ServiceReportAllUsers extends StatelessWidget { + final Function(Engineer) onSelect; + final Engineer initialValue; + const ServiceReportAllUsers({Key key, @required this.onSelect, this.initialValue}) : super(key: key); + @override + Widget build(BuildContext context) { + ServiceReportUsersProvider menuProvider = Provider.of(context); + return LoadingManager( + isLoading: menuProvider.isLoading, + isFailedLoading: menuProvider.engineers == null, + stateCode: menuProvider.stateCode, + onRefresh: () async { + menuProvider.getAllUsers(); + }, + child: UsersMenu( + initialStatus: initialValue, + statuses: menuProvider.engineers, + onSelect: onSelect, + ), + ); + } +} diff --git a/lib/views/widgets/status/report/service_report_assistant_employee_menu.dart b/lib/views/widgets/status/report/service_report_assistant_employee_menu.dart new file mode 100644 index 0000000..1bf2c49 --- /dev/null +++ b/lib/views/widgets/status/report/service_report_assistant_employee_menu.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/models/service_request/search_work_order.dart'; +import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; +import 'package:test_sa/views/widgets/status/assistant_employee_menu.dart'; + +import '../../../../controllers/providers/api/status_drop_down/report/service_report_assistants_employee_provider.dart'; + +class ServiceReportAssistantEmployeeMenu extends StatelessWidget { + final Function(AssistantEmployees) onSelect; + final AssistantEmployees initialValue; + const ServiceReportAssistantEmployeeMenu({Key key, @required this.onSelect, this.initialValue}) : super(key: key); + @override + Widget build(BuildContext context) { + ServiceReportAssistantsEmployeeProvider menuProvider = Provider.of(context); + return LoadingManager( + isLoading: menuProvider.isLoading, + isFailedLoading: menuProvider.assistantEmployees == null, + stateCode: menuProvider.stateCode, + onRefresh: () async { + await menuProvider.getAssistantEmployees(); + }, + child: AssistantEmployeeMenu( + initialStatus: initialValue, + statuses: menuProvider.assistantEmployees, + onSelect: onSelect, + ), + ); + } +} diff --git a/lib/views/widgets/status/report/service_report_equipment_status.dart b/lib/views/widgets/status/report/service_report_equipment_status.dart index 1a0382b..9518297 100644 --- a/lib/views/widgets/status/report/service_report_equipment_status.dart +++ b/lib/views/widgets/status/report/service_report_equipment_status.dart @@ -44,10 +44,10 @@ class _ServiceReportEquipmentStatusMenuState extends State(context); + print("report?.callLastSituation:${report?.callLastSituation?.toMap()}"); return LoadingManager( isLoading: _menuProvider.isLoading, isFailedLoading: _menuProvider.calls == null, diff --git a/lib/views/widgets/status/report/service_report_maintenance_situation.dart b/lib/views/widgets/status/report/service_report_maintenance_situation.dart new file mode 100644 index 0000000..311581a --- /dev/null +++ b/lib/views/widgets/status/report/service_report_maintenance_situation.dart @@ -0,0 +1,36 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; +import 'package:test_sa/views/widgets/status/single_status_menu.dart'; + +class ServiceReportMaintenanceSituation extends StatelessWidget { + final Function(Lookup) onSelect; + final Lookup initialValue; + final String woId; + + const ServiceReportMaintenanceSituation({ + Key key, + @required this.onSelect, + @required this.initialValue, + @required this.woId, + }) : super(key: key); + @override + Widget build(BuildContext context) { + ServiceReportMaintenanceSituationProvider menuProvider = Provider.of(context); + return LoadingManager( + isLoading: menuProvider.isLoading, + isFailedLoading: menuProvider.operators == null, + stateCode: menuProvider.stateCode, + onRefresh: () async { + menuProvider.getOperators(woId); + }, + child: SingleStatusMenu( + initialStatus: initialValue, + statuses: menuProvider.operators, + onSelect: onSelect, + ), + ); + } +} diff --git a/lib/views/widgets/status/report/service_report_visit_date_operator.dart b/lib/views/widgets/status/report/service_report_visit_date_operator.dart new file mode 100644 index 0000000..5148ffa --- /dev/null +++ b/lib/views/widgets/status/report/service_report_visit_date_operator.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_visit_date_operator_provider.dart'; +import 'package:test_sa/models/lookup.dart'; +import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; +import 'package:test_sa/views/widgets/status/single_status_menu.dart'; + +class ServiceReportVisitDateOperator extends StatelessWidget { + final Function(Lookup) onSelect; + final Lookup initialValue; + + const ServiceReportVisitDateOperator({Key key, @required this.onSelect, @required this.initialValue}) : super(key: key); + @override + Widget build(BuildContext context) { + ServiceReportVisitOperatorProvider menuProvider = Provider.of(context); + return LoadingManager( + isLoading: menuProvider.isLoading, + isFailedLoading: menuProvider.operators == null, + stateCode: menuProvider.stateCode, + onRefresh: () async { + menuProvider.getOperators(); + }, + child: SingleStatusMenu( + initialStatus: initialValue, + statuses: menuProvider.operators, + onSelect: onSelect, + ), + ); + } +} diff --git a/lib/views/widgets/status/single_status_menu.dart b/lib/views/widgets/status/single_status_menu.dart index dbd2eb7..6a9a990 100644 --- a/lib/views/widgets/status/single_status_menu.dart +++ b/lib/views/widgets/status/single_status_menu.dart @@ -7,8 +7,9 @@ class SingleStatusMenu extends StatefulWidget { final List statuses; final Lookup initialStatus; final Function(Lookup) onSelect; + final bool enabled; - const SingleStatusMenu({Key key, this.statuses, this.onSelect, this.initialStatus}) : super(key: key); + const SingleStatusMenu({Key key, this.enabled = true, this.statuses, this.onSelect, this.initialStatus}) : super(key: key); @override _SingleStatusMenuState createState() => _SingleStatusMenuState(); @@ -82,20 +83,22 @@ class _SingleStatusMenuState extends State { style: Theme.of(context).textTheme.subtitle1, ), style: TextStyle(color: Theme.of(context).primaryColor), - underline: SizedBox.shrink(), - onChanged: (Lookup newValue) { - setState(() { - _selectedStatus = newValue; - }); - widget.onSelect(newValue); - }, + underline: const SizedBox.shrink(), + onChanged: widget.enabled == false + ? null + : (Lookup newValue) { + setState(() { + _selectedStatus = newValue; + }); + widget.onSelect(newValue); + }, items: widget.statuses.map>((Lookup value) { return DropdownMenuItem( value: value, child: Text( value.name, style: Theme.of(context).textTheme.subtitle1.copyWith( - color: Theme.of(context).primaryColor, + color: widget.enabled ? Theme.of(context).primaryColor : Colors.grey, fontSize: 11, //fontWeight: FontWeight.bold ), diff --git a/lib/views/widgets/status/users_menu.dart b/lib/views/widgets/status/users_menu.dart new file mode 100644 index 0000000..8ffad74 --- /dev/null +++ b/lib/views/widgets/status/users_menu.dart @@ -0,0 +1,109 @@ +import 'package:flutter/material.dart'; +import 'package:test_sa/views/app_style/colors.dart'; +import 'package:test_sa/views/app_style/sizing.dart'; + +import '../../../models/engineer.dart'; + +class UsersMenu extends StatefulWidget { + final List statuses; + final Engineer initialStatus; + final Function(Engineer) onSelect; + + const UsersMenu({Key key, this.statuses, this.onSelect, this.initialStatus}) : super(key: key); + + @override + _SingleUsersMenuState createState() => _SingleUsersMenuState(); +} + +class _SingleUsersMenuState extends State { + Engineer _selectedStatus; + + @override + void setState(VoidCallback fn) { + if (mounted) super.setState(fn); + } + + @override + void didUpdateWidget(covariant UsersMenu oldWidget) { + if (widget.initialStatus != null) { + final result = widget.statuses?.where((element) { + return element == widget.initialStatus; + }); + if (result.isNotEmpty) { + _selectedStatus = result.first; + } else { + _selectedStatus = null; + } + if ((widget.initialStatus?.id ?? "") != (_selectedStatus?.id ?? "")) { + widget.onSelect(_selectedStatus); + } + } else { + _selectedStatus = null; + } + super.didUpdateWidget(oldWidget); + } + + @override + void initState() { + if (widget.initialStatus != null) { + final result = widget.statuses?.where((element) { + return element == widget.initialStatus; + }); + if (result.isNotEmpty) _selectedStatus = result.first; + if (widget.initialStatus.id != _selectedStatus?.id) { + widget.onSelect(_selectedStatus); + } + } + + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 16), + decoration: BoxDecoration( + color: AColors.inputFieldBackgroundColor, + border: Border.all( + color: Color(0xffefefef), + ), + borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), + // boxShadow: const [ + // AppStyle.boxShadow + // ] + ), + child: DropdownButton( + value: _selectedStatus, + iconSize: 24, + icon: const Icon(Icons.keyboard_arrow_down_rounded), + elevation: 0, + isExpanded: true, + hint: Text( + "Select", + style: Theme.of(context).textTheme.subtitle1, + ), + style: TextStyle(color: Theme.of(context).primaryColor), + underline: SizedBox.shrink(), + onChanged: (Engineer newValue) { + setState(() { + _selectedStatus = newValue; + }); + widget.onSelect(newValue); + }, + items: widget.statuses.map>((Engineer value) { + return DropdownMenuItem( + value: value, + child: Text( + value.name, + style: Theme.of(context).textTheme.subtitle1.copyWith( + color: Theme.of(context).primaryColor, + fontSize: 11, + //fontWeight: FontWeight.bold + ), + ), + ); + }).toList(), + ), + ); + } +} diff --git a/lib/views/widgets/timer/app_timer.dart b/lib/views/widgets/timer/app_timer.dart index 84c5e4e..9e88790 100644 --- a/lib/views/widgets/timer/app_timer.dart +++ b/lib/views/widgets/timer/app_timer.dart @@ -9,11 +9,13 @@ class AppTimer extends StatefulWidget { final TimerModel timer; final Future Function(TimerModel) onChange; final TextStyle style; + final bool enabled; const AppTimer({ Key key, this.timer, this.onChange, this.style, + this.enabled = true, }) : super(key: key); @override @@ -32,7 +34,7 @@ class _AppTimerState extends State { _startTimer() async { if (!_running) { final time = DateTime.now(); - bool result = await widget.onChange(TimerModel(startAt: time, endAt: null, durationInSecond: _delay)); + bool result = await widget.onChange(TimerModel(startAt: time, endAt: null, durationInSecond: _delay, stopped: false)); if (!result) return; _running = true; @@ -52,7 +54,7 @@ class _AppTimerState extends State { _stopTimer() async { final time = DateTime.now(); final tempStartAt = _startAt.add(Duration(seconds: _delay)); - bool result = await widget.onChange(TimerModel(startAt: tempStartAt, endAt: time, durationInSecond: _delay)); + bool result = await widget.onChange(TimerModel(startAt: tempStartAt, endAt: time, durationInSecond: _delay, stopped: true)); if (!result) return; _running = false; _endAt = time; @@ -99,7 +101,7 @@ class _AppTimerState extends State { child: ElevatedButton( style: ElevatedButton.styleFrom( minimumSize: const Size(1, 1), padding: EdgeInsets.all(4 * AppStyle.getScaleFactor(context)), backgroundColor: _running ? AColors.green[300] : AColors.grey, foregroundColor: Colors.black), - onPressed: _loading ? null : _onPressed, + onPressed: _loading || widget.enabled == false ? null : _onPressed, child: _loading ? const SizedBox.square( dimension: 18, @@ -108,7 +110,7 @@ class _AppTimerState extends State { )) : Row( children: [ - Icon(_running ? Icons.pause : Icons.play_arrow), + if (widget.enabled) Icon(_running ? Icons.pause : Icons.play_arrow), Expanded( child: Center( child: ValueListenableBuilder( @@ -116,7 +118,7 @@ class _AppTimerState extends State { builder: (context, value, _) { return Text( value, - style: widget.style, + style: widget.enabled ? widget.style : widget.style?.copyWith(color: Colors.black54), ); }), ), diff --git a/pubspec.yaml b/pubspec.yaml index 9988520..4f82161 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -60,6 +60,7 @@ dependencies: audioplayers: ^1.1.1 flare_flutter: ^3.0.2 signature: ^5.3.0 + flutter_svg: ^1.1.6 dev_dependencies: