From 5945756e6013fbf6a3e692d559ab0081cb497a02 Mon Sep 17 00:00:00 2001 From: zaid_daoud Date: Wed, 31 May 2023 11:27:48 +0300 Subject: [PATCH] New Work Order Done (Unable to upload Engineer Signature) --- assets/subtitles/ar_subtitle.json | 6 +- assets/subtitles/en_subtitle.json | 6 +- lib/controllers/api_routes/urls.dart | 1 + .../api/service_requests_provider.dart | 64 ++- ...rvice_report_repair_location_provider.dart | 69 +++ lib/main.dart | 2 + lib/models/service_report.dart | 64 ++- lib/models/subtitle.dart | 12 + .../report/create_service_report.dart | 478 +++++++++++------- .../service_report_repair_location.dart | 37 ++ 10 files changed, 524 insertions(+), 215 deletions(-) create mode 100644 lib/controllers/providers/api/status_drop_down/report/service_report_repair_location_provider.dart create mode 100644 lib/views/widgets/status/report/service_report_repair_location.dart diff --git a/assets/subtitles/ar_subtitle.json b/assets/subtitles/ar_subtitle.json index b4294845..6237d6c9 100644 --- a/assets/subtitles/ar_subtitle.json +++ b/assets/subtitles/ar_subtitle.json @@ -190,5 +190,9 @@ "duplicateAlertMessage": "هل أنت متأكد أنك تريد تكرار الطلب؟", "duplicateRequest": "تكرار الطلب", "comment" : "تعليق", - "updateServiceRequest" : "تعديل طلب الخدمة" + "updateServiceRequest" : "تعديل طلب الخدمة", + "repairLocation" : "موقع الإصلاح", + "travelingExpense" : "مصاريف التنقل", + "startDate" : "وقت البدء", + "endDate" : "وقت الانتهاء" } \ No newline at end of file diff --git a/assets/subtitles/en_subtitle.json b/assets/subtitles/en_subtitle.json index 3045e66e..3a88a991 100644 --- a/assets/subtitles/en_subtitle.json +++ b/assets/subtitles/en_subtitle.json @@ -190,5 +190,9 @@ "duplicateAlertMessage": "Are you sure you want to duplicate request?", "duplicateRequest": "Duplicate Request", "comment" : "Comment", - "updateServiceRequest" : "Update Service Request" + "updateServiceRequest" : "Update Service Request", + "repairLocation" : "Repair Location", + "travelingExpense": "Traveling Expense", + "startDate" : "Start Date", + "endDate" : "End Date" } \ No newline at end of file diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 36f430fd..d641e31f 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -29,6 +29,7 @@ class URLs { static get getServiceFirstAction => "$_baseUrl/Lookups/GetLookup?lookupEnum=700"; // get static get getServiceRequestTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=604"; // get static get getServiceRequestStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=503"; + static get getRepairLocation => "$_baseUrl/Lookups/GetLookup?lookupEnum=504"; static get getPreventiveMaintenanceVisits => "$_baseUrl/return/user/calibrations"; // get static get updatePreventiveMaintenanceVisits => "$_baseUrl/Visit/UpdateVisits"; // get diff --git a/lib/controllers/providers/api/service_requests_provider.dart b/lib/controllers/providers/api/service_requests_provider.dart index bde8b2cf..3d0569ba 100644 --- a/lib/controllers/providers/api/service_requests_provider.dart +++ b/lib/controllers/providers/api/service_requests_provider.dart @@ -281,7 +281,68 @@ class ServiceRequestsProvider extends ChangeNotifier { }) async { Response response; try { - Map body = report.toMap(request); + Map body = { + "id": 0, + "parentWOId": null, + "workOrderNo": "", + "workOrderYear": null, + "workOrderSequennce": null, + "callRequest": { + "id": request.id, + }, + "assetType": report.assetType?.toMap(), + "assignedEmployee": {"id": report.engineer.id, "name": report.engineer.name}, + "visitDate": report.visitDate?.toIso8601String() ?? "", + // "assistantEmployees": [ + // {"id": report.engineer.id, "name": report.engineer.name}, + // ], + "supplier": null, + "vendorTicketNumber": null, + "contactPersonWorkOrders": [ + { + "id": 0, + // "employeeCode": "", + "name": user.userName, + "telephone": user.phoneNumber, + // "job": "", + "email": user.email, + // "land": "", + "contactUserId": user.id, + } + ], + "calllastSituation": report.callLastSituation?.toMap(), + "currentSituation": null, + "repairLocation": report.repairLocation?.toMap(), + "reason": report.reason?.toMap(), + "startofWorkTime": report.timer?.startAt?.toIso8601String() ?? "", + "endofWorkTime": report.timer?.endAt?.toIso8601String() ?? "", + "workingHours": report.timer?.durationInSecond, + "travelingHours": report.travelingHours, + "travelingExpenses": report.travelingExpense ?? 0, + "faultDescription": { + "id": report.faultDescriptionId ?? 0, + "defectName": report.type?.name, + "workPerformed": report.workPreformed, + "estimatedTime": report.operatingHours, + }, + "sparePartsWorkOrders": report.parts + ?.map( + (p) => { + "id": p.id, + "sparePart": {"id": p.reportPartID ?? 0, "partNo": p.code, "partName": p.name}, + "qty": p.quantity + }, + ) + ?.toList(), + "reviewComment": "", + "comment": report.comment, + "attachmentsWorkOrder": request.devicePhotos?.map((e) => {"name": e})?.toList(), + "equipmentStatus": report.status?.toMap(), + "suppEngineerWorkOrders": null, + "engSignature": report.signatureEngineer, + "nurseSignature": report.signatureNurse, + "woParentDto": null, + }; // body["uid"] = user.id; // body["token"] = user.token; response = await ApiManager.instance.post(URLs.createServiceReport, body: body); @@ -299,6 +360,7 @@ class ServiceRequestsProvider extends ChangeNotifier { } return response.statusCode; } catch (error) { + print(error); return -1; } } diff --git a/lib/controllers/providers/api/status_drop_down/report/service_report_repair_location_provider.dart b/lib/controllers/providers/api/status_drop_down/report/service_report_repair_location_provider.dart new file mode 100644 index 00000000..c357a121 --- /dev/null +++ b/lib/controllers/providers/api/status_drop_down/report/service_report_repair_location_provider.dart @@ -0,0 +1,69 @@ +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'; +import 'package:test_sa/models/user.dart'; + +class ServiceReportRepairLocationProvider extends ChangeNotifier { + //reset provider data + void reset() { + _reasons = 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 _reasons; + List get reasons => _reasons; + + // 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 getTypes({String host, User user}) async { + if (_loading == true) return -2; + _loading = true; + notifyListeners(); + Response response; + try { + response = await ApiManager.instance.get( + URLs.getRepairLocation, + ); + _stateCode = response.statusCode; + if (response.statusCode >= 200 && response.statusCode < 300) { + // client's request was successfully received + List categoriesListJson = json.decode(response.body)["data"]; + _reasons = 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 60cea674..eef23138 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -51,6 +51,7 @@ 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_last_calls_provider.dart'; import 'controllers/providers/api/status_drop_down/report/service_report_reasons_provider.dart'; +import 'controllers/providers/api/status_drop_down/report/service_report_repair_location_provider.dart'; import 'controllers/providers/api/status_drop_down/report/service_report_status_provider.dart'; import 'controllers/providers/api/status_drop_down/report/service_report_types_provider.dart'; import 'controllers/providers/api/status_drop_down/report/service_types_provider.dart'; @@ -115,6 +116,7 @@ class MyApp extends StatelessWidget { ChangeNotifierProvider(create: (_) => EngineersProvider()), ChangeNotifierProvider(create: (_) => ServiceLoanAvailabilityProvider()), ChangeNotifierProvider(create: (_) => ServiceFirstActionProvider()), + ChangeNotifierProvider(create: (_) => ServiceReportRepairLocationProvider()), ], child: GestureDetector( onTap: () { diff --git a/lib/models/service_report.dart b/lib/models/service_report.dart index 8abb1303..3e471b7a 100644 --- a/lib/models/service_report.dart +++ b/lib/models/service_report.dart @@ -15,6 +15,7 @@ class ServiceReport { DateTime endDate; Lookup assetType; Lookup callLastSituation; + Lookup repairLocation; Engineer engineer; Lookup status; Lookup type; @@ -33,36 +34,42 @@ class ServiceReport { TimerModel timer; String signatureNurse; String signatureEngineer; + String comment; Uint8List localNurseSignature; Uint8List localEngineerSignature; + int travelingExpense; - ServiceReport( - {this.id, - this.visitDate, - this.endDate, - this.assetType, - this.status, - this.type, - this.faultDescriptionId, - //this.workHours, - this.travelingHours, - this.parts, - this.engineer, - this.workPreformed, - this.reason, - this.operatingHours, - this.callLastSituation, - this.jobSheetNumber, - this.image, - this.device, - this.invoiceCode, - this.invoiceNumber, - this.quantity = "1", - this.timer, - this.signatureNurse, - this.signatureEngineer, - this.localNurseSignature, - this.localEngineerSignature}); + ServiceReport({ + this.id, + this.visitDate, + this.endDate, + this.assetType, + this.status, + this.type, + this.faultDescriptionId, + //this.workHours, + this.travelingHours, + this.parts, + this.engineer, + this.workPreformed, + this.reason, + this.operatingHours, + this.callLastSituation, + this.jobSheetNumber, + this.image, + this.device, + this.invoiceCode, + this.invoiceNumber, + this.quantity = "1", + this.timer, + this.signatureNurse, + this.signatureEngineer, + this.localNurseSignature, + this.localEngineerSignature, + this.comment, + this.repairLocation, + this.travelingExpense, + }); Map toMap(ServiceRequest request) { Map _map = {}; @@ -98,6 +105,7 @@ class ServiceReport { _map["callRequest"]["asset"]["invoiceNumber"] = invoiceNumber; } _map["AssignedEmployee"] = engineer?.toMap(); + _map["repairLocation"] = repairLocation?.toMap(); //if(quantity != null && quantity.isNotEmpty) _map["qty"] = quantity; //if(endDate != null) _map["end_date"] = (endDate.millisecondsSinceEpoch ~/ 1000).toString(); if (reason != null) _map["reason"] = reason.toMap(); @@ -113,6 +121,8 @@ class ServiceReport { } _map["nurseSignature"] = signatureNurse; _map["engSignature"] = signatureEngineer; + _map["comment"] = comment; + _map["travelingExpense"] = travelingExpense; return _map; } diff --git a/lib/models/subtitle.dart b/lib/models/subtitle.dart index 1a05ab65..afbc42e2 100644 --- a/lib/models/subtitle.dart +++ b/lib/models/subtitle.dart @@ -217,6 +217,10 @@ class Subtitle { String alert; String comment; String updateServiceRequest; + String repairLocation; + String travelingExpense; + String startDate; + String endDate; void setIssues(List issues) { issues.clear(); @@ -409,6 +413,10 @@ class Subtitle { @required this.duplicateAlert, @required this.duplicateAlertMessage, @required this.duplicateRequest, + @required this.repairLocation, + @required this.travelingExpense, + @required this.startDate, + @required this.endDate, }); factory Subtitle.fromJson(Map parsedJson) { @@ -594,6 +602,10 @@ class Subtitle { duplicateAlert: parsedJson["duplicateAlert"], duplicateAlertMessage: parsedJson["duplicateAlertMessage"], duplicateRequest: parsedJson["duplicateRequest"], + repairLocation: parsedJson["repairLocation"], + travelingExpense: parsedJson["travelingExpense"], + startDate: parsedJson["startDate"], + endDate: parsedJson["endDate"], ); } } 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 f077fbd7..5bd983ab 100644 --- a/lib/views/pages/user/requests/report/create_service_report.dart +++ b/lib/views/pages/user/requests/report/create_service_report.dart @@ -2,7 +2,6 @@ import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:flutter/rendering.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:provider/provider.dart'; import 'package:test_sa/controllers/api_routes/http_status_manger.dart'; @@ -15,7 +14,6 @@ import 'package:test_sa/controllers/validator/validator.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'; -import 'package:test_sa/models/lookup.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'; @@ -33,22 +31,22 @@ import 'package:test_sa/views/widgets/status/employee/engineers_mune.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/timer/app_timer.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; + +import '../../../../widgets/status/report/service_report_repair_location.dart'; + class CreateServiceReport extends StatefulWidget { static final String id = "/create-service-report"; - final ServiceRequest request ; + final ServiceRequest request; const CreateServiceReport({Key key, this.request}) : super(key: key); @override _CreateServiceReportState createState() => _CreateServiceReportState(); } -class _CreateServiceReportState extends State with TickerProviderStateMixin{ - - +class _CreateServiceReportState extends State with TickerProviderStateMixin { UserProvider _userProvider; SettingProvider _settingProvider; ServiceRequestsProvider _serviceRequestsProvider; @@ -67,11 +65,10 @@ class _CreateServiceReportState extends State with TickerPr @override void initState() { _serviceReport = ServiceReport( - visitDate: DateTime.now(), - //type: const Lookup(value: 2), - device: widget.request.device, - parts: [] - ); + visitDate: DateTime.now(), + //type: const Lookup(value: 2), + device: widget.request.device, + parts: []); super.initState(); } @@ -81,6 +78,7 @@ class _CreateServiceReportState extends State with TickerPr _workPreformedController.dispose(); super.dispose(); } + @override Widget build(BuildContext context) { _userProvider = Provider.of(context); @@ -102,52 +100,54 @@ class _CreateServiceReportState extends State with TickerPr ListView( children: [ //AppNameBar(), - const SizedBox(height: 16,), + const SizedBox( + height: 16, + ), Center( child: Padding( padding: const EdgeInsets.all(8.0), child: Text( _subtitle.newServiceReport, - style: Theme.of(context).textTheme.headline5.copyWith( - color: AColors.cyan, - fontSize: 28, - fontWeight: FontWeight.bold - ), + style: Theme.of(context).textTheme.headline5.copyWith(color: AColors.cyan, fontSize: 28, fontWeight: FontWeight.bold), ), ), ), Container( padding: const EdgeInsets.symmetric(horizontal: 16), - margin: const EdgeInsets.symmetric(horizontal: 16,vertical: 16), - decoration: BoxDecoration( + 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, - borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), - boxShadow: [ - const BoxShadow( - color: AColors.grey, - offset: Offset(0,-1), - ) - ] - ), + offset: Offset(0, -1), + ) + ]), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), Wrap( spacing: 10, children: [ - ASubTitle("${_subtitle.callId}: ${widget.request.requestCode}",font: 14,), - widget.request.deviceSerialNumber == null ? const SizedBox(): - ASubTitle("${_subtitle.deviceSN}: ${widget.request.deviceSerialNumber}",font: 14,), + ASubTitle( + "${_subtitle.callId}: ${widget.request.requestCode}", + font: 14, + ), + widget.request.deviceSerialNumber == null + ? const SizedBox() + : ASubTitle( + "${_subtitle.deviceSN}: ${widget.request.deviceSerialNumber}", + font: 14, + ), Text( "${_subtitle.customer}: ${widget.request.hospitalName}", style: Theme.of(context).textTheme.subtitle1.copyWith( - fontWeight: FontWeight.bold, - fontSize: 12, - ), + fontWeight: FontWeight.bold, + fontSize: 12, + ), textScaleFactor: AppStyle.getScaleFactor(context), ) - ], ), const Divider(), @@ -181,9 +181,12 @@ class _CreateServiceReportState extends State with TickerPr crossAxisAlignment: CrossAxisAlignment.start, children: [ ASubTitle(_subtitle.visitDate), - _validate && _serviceReport.visitDate == null ? - ASubTitle(_subtitle.requiredWord,color: Colors.red,): - const SizedBox.shrink(), + _validate && _serviceReport.visitDate == null + ? ASubTitle( + _subtitle.requiredWord, + color: Colors.red, + ) + : const SizedBox.shrink(), Row( children: [ Expanded( @@ -191,7 +194,7 @@ class _CreateServiceReportState extends State with TickerPr date: _serviceReport.visitDate, from: DateTime.now().subtract(const Duration(days: 365)), to: DateTime.now().add(const Duration(days: 365)), - onDatePicker: (date){ + onDatePicker: (date) { _serviceReport.visitDate = date; setState(() {}); }, @@ -202,10 +205,11 @@ class _CreateServiceReportState extends State with TickerPr ], ), ), - ], ), - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), // device sn Visibility( visible: widget.request.deviceSerialNumber == null, @@ -213,33 +217,47 @@ class _CreateServiceReportState extends State with TickerPr crossAxisAlignment: CrossAxisAlignment.start, children: [ ASubTitle(_subtitle.deviceSN), - _validate && _serviceReport.device?.id == null ? - ASubTitle(_subtitle.requiredWord,color: Colors.red,): - const SizedBox.shrink(), + _validate && _serviceReport.device?.id == null + ? ASubTitle( + _subtitle.requiredWord, + color: Colors.red, + ) + : const SizedBox.shrink(), AutoCompleteDeviceField( hospitalId: widget.request.hospitalId, initialValue: _serviceReport.device, - onPick: (id){ + onPick: (id) { _serviceReport.device.id = id; }, ), - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), ], ), ), - 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,), + _validate && _serviceReport.assetType == null + ? ASubTitle( + _subtitle.requiredWord, + color: Colors.red, + ) + : const SizedBox.shrink(), + const SizedBox( + height: 4, + ), ServiceAssetTypeMenu( initialValue: _serviceReport.assetType, - onSelect: (status){ + onSelect: (status) { _serviceReport.assetType = status; }, ), - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), // Report status and Service Type Row( children: [ @@ -249,40 +267,51 @@ class _CreateServiceReportState extends State with TickerPr crossAxisAlignment: CrossAxisAlignment.start, children: [ ASubTitle(_subtitle.reportStatus), - _validate && _serviceReport.status == null ? - ASubTitle(_subtitle.requiredWord,color: Colors.red,): - const SizedBox.shrink(), - const SizedBox(height: 4,), + _validate && _serviceReport.status == null + ? ASubTitle( + _subtitle.requiredWord, + color: Colors.red, + ) + : const SizedBox.shrink(), + const SizedBox( + height: 4, + ), ServiceReportStatusMenu( report: _serviceReport, - onSelect: (status){ + onSelect: (status) { _serviceReport.status = status; }, ), ], ), ), - const SizedBox(width: 8,), + 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( + 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,), + _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){ + onSelect: (status) { + if (status?.value == 12 || _serviceReport.callLastSituation?.value == 12) { _serviceReport.callLastSituation = status; setState(() {}); } else { @@ -297,70 +326,83 @@ class _CreateServiceReportState extends State with TickerPr ), ], ), - 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,), + SizedBox( + height: 8 * AppStyle.getScaleFactor(context), + ), + const ASubTitle("Assigned 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){ + onSelect: (engineer) { _serviceReport.engineer = engineer; }, ), - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), // invoice number & code - _serviceReport.callLastSituation?.id != 12 ? const SizedBox.shrink(): - Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + _serviceReport.callLastSituation?.id != 12 + ? const SizedBox.shrink() + : Row( 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; - }, + 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,), - 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: [ @@ -421,7 +463,9 @@ class _CreateServiceReportState extends State with TickerPr // ), // const SizedBox(height: 8,), - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), Row( children: [ // reasons @@ -430,17 +474,21 @@ class _CreateServiceReportState extends State with TickerPr crossAxisAlignment: CrossAxisAlignment.start, children: [ ASubTitle(_subtitle.reasons), - const SizedBox(height: 4,), + const SizedBox( + height: 4, + ), ServiceReportReasonsMenu( initialValue: _serviceReport.reason, - onSelect: (status){ + onSelect: (status) { _serviceReport.reason = status; }, ), ], ), ), - const SizedBox(width: 8,), + const SizedBox( + width: 8, + ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -449,8 +497,8 @@ class _CreateServiceReportState extends State with TickerPr AMiniOneImagePicker( //error: _validate && _serviceReport.image == null, image: _image, - onPick: (image){ - _image =image; + onPick: (image) { + _image = image; _serviceReport.image = "${image.path.split("/").last}|${base64Encode(image.readAsBytesSync())}"; }, ), @@ -459,7 +507,49 @@ class _CreateServiceReportState extends State with TickerPr ), ], ), - 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, + ), + ATextFormField( + initialValue: _serviceReport?.travelingExpense?.toString(), + hintText: _subtitle.travelingExpense, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleMedium, + textInputType: TextInputType.number, + onSaved: (value) { + _serviceReport.travelingExpense = int.tryParse(value) ?? 0; + }, + ), + const SizedBox( + height: 8, + ), + ATextFormField( + initialValue: _serviceReport?.comment, + hintText: _subtitle.comment, + textAlign: TextAlign.center, + style: Theme.of(context).textTheme.titleMedium, + textInputType: TextInputType.multiline, + onSaved: (value) { + _serviceReport.comment = value; + }, + ), + + const SizedBox( + height: 8, + ), // Traveling Hours & Working Hours Row( children: [ @@ -468,13 +558,15 @@ class _CreateServiceReportState extends State with TickerPr crossAxisAlignment: CrossAxisAlignment.start, children: [ ASubTitle(_subtitle.workingHours), - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), Row( children: [ Expanded( child: AppTimer( timer: _serviceReport.timer, - onChange: (timer) async{ + onChange: (timer) async { _serviceReport.timer = timer; return true; }, @@ -523,7 +615,9 @@ class _CreateServiceReportState extends State with TickerPr // ), ], ), - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), // Operating Hours and Job Sheet Number // Row( // children: [ @@ -570,30 +664,39 @@ class _CreateServiceReportState extends State with TickerPr // ), // ], // ), - //const SizedBox(height: 8,), - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), const ASubTitle("Nurse Signature"), ESignature( oldSignature: _serviceReport.signatureNurse, newSignature: _serviceReport.localNurseSignature, - onSaved: (signature){ - if(signature == null || signature.isEmpty) {return;} + onSaved: (signature) { + if (signature == null || signature.isEmpty) { + return; + } _serviceReport.localNurseSignature = signature; _serviceReport.signatureNurse = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; }, ), - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), const ASubTitle("Engineer Signature"), ESignature( oldSignature: _serviceReport.signatureEngineer, newSignature: _serviceReport.localNurseSignature, - onSaved: (signature){ - if(signature == null || signature.isEmpty) {return;} + onSaved: (signature) { + if (signature == null || signature.isEmpty) { + return; + } _serviceReport.localNurseSignature = signature; _serviceReport.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; }, ), - const SizedBox(height: 8,), + const SizedBox( + height: 8, + ), // Part Number and Quantity Row( children: [ @@ -603,45 +706,49 @@ class _CreateServiceReportState extends State with TickerPr crossAxisAlignment: CrossAxisAlignment.start, children: [ ASubTitle(_subtitle.partNumber), - _validate && _serviceReport.parts == null ? - ASubTitle(_subtitle.requiredWord,color: Colors.red,): - const SizedBox.shrink(), - const SizedBox(height: 4,), + _validate && _serviceReport.parts == null + ? ASubTitle( + _subtitle.requiredWord, + color: Colors.red, + ) + : const SizedBox.shrink(), + const SizedBox( + height: 4, + ), AutoCompletePartsField( - onPick: (part){ + onPick: (part) { _serviceReport.parts.add(part); }, ), ], ), ), - ], ), - SizedBox(height: 8*AppStyle.getScaleFactor(context),), + SizedBox( + height: 8 * AppStyle.getScaleFactor(context), + ), Row( children: [ - Expanded(flex:3,child: Text(_subtitle.number)), - Expanded(flex: 1,child: Text(_subtitle.quantity)), + Expanded(flex: 3, child: Text(_subtitle.number)), + Expanded(flex: 1, child: Text(_subtitle.quantity)), ], ), Column( - children: List.generate( - _serviceReport.parts.length, - (index) { - Part _part = _serviceReport.parts[index]; - return PartItem( - part: _part, - onDelete: (part){ - _serviceReport.parts.remove(part); - setState(() {}); - }, - ); - } - ), + children: List.generate(_serviceReport.parts.length, (index) { + Part _part = _serviceReport.parts[index]; + return PartItem( + part: _part, + onDelete: (part) { + _serviceReport.parts.remove(part); + setState(() {}); + }, + ); + }), + ), + const SizedBox( + height: 16, ), - const SizedBox(height: 16,), - ], ), ), @@ -651,47 +758,48 @@ class _CreateServiceReportState extends State with TickerPr text: _subtitle.submit, onPressed: () async { _validate = true; - if(!_formKey.currentState.validate()){ + print(1); + if (!_formKey.currentState.validate()) { + print(2); setState(() {}); return; } - if(!_serviceReport.validate()) return; + print(3); + if (!_serviceReport.validate()) return; + print(4); _formKey.currentState.save(); - - _isLoading =true; + print(5); + _isLoading = true; setState(() {}); - - int status = await _serviceRequestsProvider.createServiceReport( user: _userProvider.user, host: _settingProvider.host, report: _serviceReport, - request: widget.request + request: widget.request, ); - _isLoading =false; + print(6); + print(status); + _isLoading = false; setState(() {}); - if(status >= 200 && status < 300){ + if (status >= 200 && status < 300) { Fluttertoast.showToast( - msg: _subtitle.requestCompleteSuccessfully, + 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 - ), - ) - ); + } else { + String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle); + ScaffoldMessenger.of(context).showSnackBar(SnackBar( + content: Text(errorMessage), + )); } }, ), ), - const SizedBox(height: 300,) + const SizedBox( + height: 300, + ) ], ), const ABackButton(), diff --git a/lib/views/widgets/status/report/service_report_repair_location.dart b/lib/views/widgets/status/report/service_report_repair_location.dart new file mode 100644 index 00000000..4892a3a7 --- /dev/null +++ b/lib/views/widgets/status/report/service_report_repair_location.dart @@ -0,0 +1,37 @@ +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; +import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_repair_location_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/lookup.dart'; +import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; +import 'package:test_sa/views/widgets/status/single_status_menu.dart'; + +class ServiceReportRepairLocation extends StatelessWidget { + final Lookup initialValue; + final Function(Lookup) onSelect; + + const ServiceReportRepairLocation({Key key, this.onSelect, this.initialValue}) : super(key: key); + @override + Widget build(BuildContext context) { + SettingProvider _settingProvider = Provider.of(context); + UserProvider _userProvider = Provider.of(context); + ServiceReportRepairLocationProvider _menuProvider = Provider.of(context); + return LoadingManager( + isLoading: _menuProvider.isLoading, + isFailedLoading: _menuProvider.reasons == null, + stateCode: _menuProvider.stateCode, + onRefresh: () async { + _menuProvider.reset(); + await _menuProvider.getTypes( + user: _userProvider.user, + host: _settingProvider.host, + ); + }, + child: SingleStatusMenu( + initialStatus: initialValue, + statuses: _menuProvider.reasons, + onSelect: onSelect, + )); + } +}