import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.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/extensions/context_extension.dart'; import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/service_request/pending_service_request_model.dart'; import 'package:test_sa/models/service_request/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/service_request/spare_parts.dart'; import 'package:test_sa/models/service_request/supp_engineer_work_orders.dart'; import 'package:test_sa/models/service_request/supplier_engineer_model.dart'; import 'package:test_sa/models/timer_model.dart'; import '../../../models/service_request/search_work_order.dart'; import '../../../models/service_request/wo_call_request.dart'; import '../../../models/user.dart'; import '../../../new_views/common_widgets/app_lazy_loading.dart'; class ServiceRequestsProvider extends ChangeNotifier { // number of items call in each request final pageItemNumber = 10; //reset provider data void reset() { workOrders = []; serviceRequests = null; nextPage = true; stateCode = null; } // state code of current request to defied error message // like 400 customer request failed // 500 service not available int? stateCode; bool _isDetialLoading = false; bool get isDetialLoading => _isDetialLoading; set isDetialLoading(bool value) { _isDetialLoading = value; notifyListeners(); } // true if there is next page in product list and false if not bool nextPage = true; TimeOfDay? _selectedTime; TimeOfDay? get selectedTime => _selectedTime; set selectedTime(TimeOfDay? value) { _selectedTime = value; notifyListeners(); } // list of user requests List? serviceRequests; List workOrders = []; List _sparePartList = []; SparePartsWorkOrders _initialSelectedSparePart = SparePartsWorkOrders(); ServiceRequest? _currentSelectedRequest; int _selectedListIndex = 0; int get selectedListIndex => _selectedListIndex; set selectedListIndex(int value) { _selectedListIndex = value; notifyListeners(); } ServiceRequest? get currentSelectedRequest => _currentSelectedRequest; set currentSelectedRequest(ServiceRequest? value) { _currentSelectedRequest = value; notifyListeners(); } // when requests in-process _loading = true // done _loading = true // failed _loading = false bool isLoading = false; ServiceRequestSearch search = ServiceRequestSearch(); /// 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 getRequests({required int hospitalId}) async { if (isLoading == true) return -2; isLoading = true; if (serviceRequests?.isEmpty ?? false) notifyListeners(); Response response; try { Map body = {}; body.addAll(search.toMap()); body["pageNumber"] = (serviceRequests?.length ?? 0) ~/ pageItemNumber + 1; body["pageSize"] = pageItemNumber; response = await ApiManager.instance.post( URLs.getServiceRequests, body: body, ); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { // client's request was successfully received List requestsListJson = json.decode(response.body)["data"]; List serviceRequestsPage = requestsListJson.map((request) => ServiceRequest.fromJson(request)).toList(); serviceRequests ??= []; serviceRequests!.addAll(serviceRequestsPage); notifyListeners(); if (serviceRequestsPage.length == pageItemNumber) { nextPage = true; } else { nextPage = false; } } isLoading = false; notifyListeners(); return response.statusCode; } catch (error) { isLoading = false; stateCode = -1; notifyListeners(); return -1; } } // Future getSingleServiceRequest({ // required String requestId, // required String host, // required User user, // required AppLocalizations subtitle, // }) async { // String userData = ''; // if (user != null) { // userData += "&uid=" + user!.id!; // userData += "&token=" + user!.token!; // } // // Response response; // try { // response = await get(Uri.parse( // host + // URLs.getSingleServiceRequest + // '?call_nid=$requestId' // '$userData', // )); // } catch (error) { // throw (HttpStatusManger.getStatusMessage(status: -1, subtitle: subtitle)); // } // // // If the call to the server was successful, parse the JSON. // if (response.statusCode >= 200 && response.statusCode < 300) { // // If the call to the server was successful, parse the JSON. // List jsonList = json.decode(utf8.decode(response.bodyBytes).replaceAll("\\", "")); // List _requests = jsonList.map((i) => ServiceRequest.fromJson(i)).toList(); // return _requests[0]; // } else { // throw (HttpStatusManger.getStatusMessage(status: response.statusCode, subtitle: subtitle)); // } // } Future createRequest({ required BuildContext context, required String host, required User user, required ServiceRequest serviceRequest, }) async { var body = { "id": 0, "calNo": "", "callCreatedBy": {"id": user.userID, "name": user.userName ?? ""}, "assets": serviceRequest.device?.id == null ? [] : [serviceRequest.device?.id], "requestedDate": DateTime.now().toIso8601String(), "requestedTime": DateTime.now().toIso8601String(), "client": user.clientId, "callComments": serviceRequest.callComments, if (serviceRequest.devicePhotos?.isNotEmpty ?? false) "attachmentsCallRequest": serviceRequest.devicePhotos!.map((e) => {"name": e}).toList(), "priority": serviceRequest.priority?.toJson(), "defectType": serviceRequest.defectType?.toJson(), "typeofRequest": serviceRequest.type?.toJson(), "requestedThrough": serviceRequest.requestedThrough?.toJson(), "reviewComment": null, if (serviceRequest.audio != null) "voiceNote": serviceRequest.audio, "callSiteContactPerson": [ { "id": 0, // "employeeCode": user.email, "name": user.userName, "telephone": user.phoneNumber, // "job": "", "email": user.email, // "land": "", "contactUserId": user.userID, }, ], "noofFollowup": 0, "status": null, "callLastSituation": null, "firstAction": null, "loanAvailablity": null, "comments": null, "firstActionDate": null, "visitDate": null, "callReview": null, }; if (serviceRequest.audio != null) { body["voiceNote"] = serviceRequest.audio; } showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); Response response; try { response = await ApiManager.instance.post(URLs.createRequest, body: body); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { if (serviceRequests != null) { var data = json.decode(utf8.decode(response.bodyBytes)); if (data is List) { serviceRequests!.insert(0, ServiceRequest.fromJson(data[0])); } else { if (data["data"] != null && data["data"] == true) { // serviceRequests.insert(0, ServiceRequest.fromJson(data[0])); } } } notifyListeners(); Fluttertoast.showToast(msg: context.translation.successfulRequestMessage); Navigator.pop(context); } else { Fluttertoast.showToast(msg: "${context.translation.failedRequestMessage} :${json.decode(response.body)['message']}"); } Navigator.pop(context); } catch (error) { print(error); Navigator.pop(context); } } // Future createIssueReport({ // required String host, // required User user, // required Issue issue, // }) async { // Response response; // Map body = issue.toMap(); // body["uid"] = user.id; // body["token"] = user.token; // try { // response = await post( // Uri.parse(host + URLs.createReport), // body: body, // ); // // stateCode = response.statusCode; // if (response.statusCode >= 200 && response.statusCode < 300) {} // return response.statusCode; // } catch (error) { // return -1; // } // } Future checkAssetPendingRequest(int assetId) async { Response response; try { response = await ApiManager.instance.get(URLs.CheckIfAssetHasAnotherServiceRequest + "?assetId=$assetId"); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) {} return PendingAssetServiceRequest.fromJson(json.decode(response.body)["data"]); } catch (error) { "Please Try Again\n$error".addTranslation.showToast; return null; } } Future updateRequest({required User user, required ServiceRequest request}) async { isLoading = true; notifyListeners(); Map serviceRequest = await getServiceRequestById(requestId: request.id!); final List callSiteContacts = (serviceRequest['callSiteContactPerson'] as List); final Map callSiteContactPerson = callSiteContacts.isEmpty ? {} : callSiteContacts[0]; Response response; try { if ((request.audio ?? "").isNotEmpty) { request.audio = request.audio!.substring(request.audio!.indexOf("=") + 1, request.audio!.length); } } catch (ex) {} var body = { "id": request.id, "callNo": serviceRequest['callNo'], "callCreatedBy": serviceRequest['callCreatedBy'], "requestedDate": request.date ?? "", "requestedTime": request.date ?? "", "priority": request.priority?.toJson(), "defectType": request.defectType?.toJson(), "typeofRequest": request.type?.toJson(), "requestedThrough": request.requestedThrough?.toJson(), "voiceNote": request.audio, "assets": request.deviceId == null ? [] : [request.deviceId], "attachmentsCallRequest": (request.devicePhotos?.isNotEmpty ?? false) ? request.devicePhotos?.map((e) => {"name": e.getFileName}).toList() : [], "assignedEmployee": { "id": request.engineerId, "name": request.engineerName, }, "callSiteContactPerson": [ { "id": callSiteContactPerson['id'] ?? 0, "employeeCode": callSiteContactPerson['employeeCode'], "name": callSiteContactPerson['name'] ?? user.userName, "telephone": callSiteContactPerson['telephone'] ?? user.phoneNumber, "job": callSiteContactPerson['job'], "email": callSiteContactPerson['email'] ?? user.email, "land": callSiteContactPerson['land'], "contactUserId": user.userID, }, ], "callComments": request.callComments, "noofFollowup": 0, "status": request.statusId == null ? null : { "id": request.statusId, "name": request.statusLabel, "value": request.statusValue, }, "callLastSituation": null, "firstAction": request.firstAction?.toJson(), "loanAvailablity": request.loanAvailability?.toJson(), "comments": request.comments, "firstActionDate": request.visitDate, "visitDate": request.visitDate, "startDate": request.startDate, "endDate": request.endDate, "workingHours": request.workingHours, "callReview": null, "reviewComment": null, //"reviewComment": request.reviewComment, }; try { response = await ApiManager.instance.put( URLs.updateRequestDate, body: body, ); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { // request.engineerName = employee.name; notifyListeners(); } isLoading = false; notifyListeners(); return response.statusCode; } catch (error) { isLoading = false; notifyListeners(); return -1; } } Future createServiceReport(BuildContext context, {required ServiceReport report, required User user, required ServiceRequest request}) async { Response response; try { showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); final body = report.toJson(); final callRequest = CallRequest(id: num.tryParse(request.id ?? "")).toJson(); final contactPerson = [ { "id": 0, // "employeeCode": "", "name": user.userName, "telephone": user.phoneNumber, // "job": "", "email": user.email, // "land": "", "contactUserId": user.userID, } ]; body.update("contactPersonWorkOrders", (value) => contactPerson, ifAbsent: () => contactPerson); body.update("callRequest", (value) => callRequest, ifAbsent: () => callRequest); response = await ApiManager.instance.post(URLs.createServiceReport, body: body); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { reset(); notifyListeners(); Fluttertoast.showToast(msg: context.translation.successfulRequestMessage); Navigator.of(context).pop(); } else { Fluttertoast.showToast(msg: "${context.translation.failedToCompleteRequest}: ${json.decode(response.body)['message']}"); } Navigator.pop(context); return response.statusCode; } catch (error) { Navigator.pop(context); print(error); return -1; } } Future createSubWorkOrder({required SearchWorkOrder workOrder, bool makeSuppPersonsEmpty = false}) async { Response response; try { if (makeSuppPersonsEmpty) workOrder.supplier?.suppPersons = []; Map body = workOrder.toJson(); response = await ApiManager.instance.post(URLs.createServiceReport, body: body); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { reset(); notifyListeners(); } return response.statusCode; } catch (error) { print(error); return -1; } } CallRequest? callRequestForWorkOrder; Future getCallRequestForWorkOrder({required String callId}) async { Response response; try { response = await ApiManager.instance.get(URLs.getCallRequestForWorkOrder + "?callId=$callId"); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { // client's request was successfully received Map listJson = json.decode(response.body)["data"]; // log(listJson?.toString()); callRequestForWorkOrder = CallRequest.fromJson(listJson); } notifyListeners(); return callRequestForWorkOrder; } catch (error) { print(error); return null; } } Future> searchWorkOrders({required String callId}) async { Response response; try { var body = { "pageSize": pageItemNumber, "pageNumber": ((workOrders.length ?? 0) ~/ pageItemNumber) + 1, "callId": callId, }; 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"]; workOrders = workOrdersJson.map((request) => SearchWorkOrder.fromJson(request)).toList(); if (workOrders.length == pageItemNumber) { nextPage = true; } else { nextPage = false; } } return workOrders; } catch (e) { return []; } } Future getSubWorkOrderDetails({required String parentId}) async { Response response; try { response = await ApiManager.instance.get(URLs.getSubWorkerInfoAccordingToPreviousStep + "?parentId=$parentId"); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { // client's request was successfully received final workOrderJson = json.decode(response.body)["data"]; return ServiceReport.fromJson(workOrderJson); } return null; } catch (e) { print("getSubWorkOrderDetails [error] : $e"); return null; } } // Future createDuplicatedReport({ // required String host, // required User user, // required ServiceRequest request, // }) async { // Response response; // String userData = ''; // if (user != null) { // userData += "&uid=" + user.id; // userData += "&token=" + user.token; // } // // try { // response = await get( // Uri.parse(host + URLs.createDuplicatedReport + "?nid=${request.id}" + userData), // ); // // stateCode = response.statusCode; // // if (response.statusCode >= 200 && response.statusCode < 300) { // reset(); // notifyListeners(); // } // return response.statusCode; // } catch (error) { // return -1; // } // } Future updateServiceReport(BuildContext context, {required ServiceReport report}) async { Response response; report.callRequest = CallRequest(id: report.callRequest!.id!); Map body = report.toJson(); try { showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); response = await ApiManager.instance.put(URLs.updateServiceReport, body: body); if (response.statusCode >= 200 && response.statusCode < 300) { reset(); notifyListeners(); Fluttertoast.showToast(msg: context.translation.successfulRequestMessage); Navigator.of(context).pop(); } else { Fluttertoast.showToast(msg: context.translation.failedToCompleteRequest); } Navigator.of(context).pop(); return response.statusCode; } catch (e) { print(e); Navigator.of(context).pop(); return -1; } } Future updateWorkOrderDetails({required SearchWorkOrder workOrder}) 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 = workOrder.toJson(); // 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) { return -1; } } Future updateServiceReportTimer({required String host, required User user, required TimerModel timer, required ServiceRequest request}) async { Response response; Map body = {}; body["uid"] = user.id; body["token"] = user.token; body["job_id"] = request.id; body["start_time"] = (timer.startAt!.millisecondsSinceEpoch / 1000).toStringAsFixed(0); body["end_time"] = (timer.endAt!.millisecondsSinceEpoch / 1000).toStringAsFixed(0); body["working_hours"] = (timer.durationInSecond! / 60 / 60).toStringAsFixed(5); body["report_id"] = request.reportID; try { 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) { return -1; } } Future getSingleServiceReport(BuildContext context, {required int reportId}) async { Response response; try { response = await ApiManager.instance.get(URLs.getServiceReport + "?workOrderId=$reportId"); } catch (error) { throw (context.translation.failedToCompleteRequest); } // If the call to the server was successful, parse the JSON. if (response.statusCode >= 200 && response.statusCode < 300) { // If the call to the server was successful, parse the JSON. return ServiceReport.fromJson(json.decode(response.body)["data"]); } else { throw (("${context.translation.failedToCompleteRequest} ${jsonDecode(response.body)["message"]}")); } } Future getServiceRequestObjectById({required String requestId}) async { try { isDetialLoading = true; Response response = await ApiManager.instance.get(URLs.getServiceRequestById + "?callRequestId=$requestId"); if (response.statusCode >= 200 && response.statusCode < 300) { isDetialLoading = false; return ServiceRequest.fromJson(json.decode(response.body)["data"]); } else { isDetialLoading = false; return null; } } catch (error) { isDetialLoading = false; return null; } } Future> getServiceRequestById({required String requestId}) async { Response response; try { response = await ApiManager.instance.get(URLs.getServiceRequestById + "?callRequestId=$requestId"); } catch (error) { print(error); return {}; } // If the call to the server was successful, parse the JSON. if (response.statusCode >= 200 && response.statusCode < 300) { // If the call to the server was successful, parse the JSON. return { "callNo": json.decode(response.body)["data"]["callNo"], "callCreatedBy": json.decode(response.body)["data"]["callCreatedBy"], "callSiteContactPerson": json.decode(response.body)["data"]["callSiteContactPerson"], "firstActionDate": json.decode(response.body)["data"]["firstActionDate"], }; } else { 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!.toJson(), if (search.assignedEmployee != null) "assignedEmployees": [search.assignedEmployee!.id], // "statusWO": [], if (site.isNotEmpty ?? false) "site": site, if (search.visitDate != null) "visitDateSymbol": dateOperator.toJson(), if (search.visitDate != 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"]; 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 []; } } Future addSupplierEngineer(SupplierEngineer supplierEngineer) async { isLoading = true; notifyListeners(); Response response; SuppEngineerWorkOrders? res; try { response = await ApiManager.instance.post(URLs.addSupplierEngineer, body: supplierEngineer.toJson()); stateCode = response.statusCode; if (response.statusCode >= 200 && response.statusCode < 300) { res = SuppEngineerWorkOrders.fromJson(json.decode(response.body)["data"]); } isLoading = false; notifyListeners(); return res; } catch (error) { isLoading = false; notifyListeners(); return res; } } SparePartsWorkOrders get initialSelectedSparePart => _initialSelectedSparePart; set initialSelectedSparePart(SparePartsWorkOrders value) { _initialSelectedSparePart = value; notifyListeners(); } List get sparePartList => _sparePartList; set sparePartList(List value) { _sparePartList = value; notifyListeners(); } }