New Work Order Done (Unable to upload Engineer Signature)

merge-requests/30/head
zaid_daoud 1 year ago
parent 31c7c7376f
commit 5945756e60

@ -190,5 +190,9 @@
"duplicateAlertMessage": "هل أنت متأكد أنك تريد تكرار الطلب؟", "duplicateAlertMessage": "هل أنت متأكد أنك تريد تكرار الطلب؟",
"duplicateRequest": "تكرار الطلب", "duplicateRequest": "تكرار الطلب",
"comment" : "تعليق", "comment" : "تعليق",
"updateServiceRequest" : "تعديل طلب الخدمة" "updateServiceRequest" : "تعديل طلب الخدمة",
"repairLocation" : "موقع الإصلاح",
"travelingExpense" : "مصاريف التنقل",
"startDate" : "وقت البدء",
"endDate" : "وقت الانتهاء"
} }

@ -190,5 +190,9 @@
"duplicateAlertMessage": "Are you sure you want to duplicate request?", "duplicateAlertMessage": "Are you sure you want to duplicate request?",
"duplicateRequest": "Duplicate Request", "duplicateRequest": "Duplicate Request",
"comment" : "Comment", "comment" : "Comment",
"updateServiceRequest" : "Update Service Request" "updateServiceRequest" : "Update Service Request",
"repairLocation" : "Repair Location",
"travelingExpense": "Traveling Expense",
"startDate" : "Start Date",
"endDate" : "End Date"
} }

@ -29,6 +29,7 @@ class URLs {
static get getServiceFirstAction => "$_baseUrl/Lookups/GetLookup?lookupEnum=700"; // get static get getServiceFirstAction => "$_baseUrl/Lookups/GetLookup?lookupEnum=700"; // get
static get getServiceRequestTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=604"; // get static get getServiceRequestTypes => "$_baseUrl/Lookups/GetLookup?lookupEnum=604"; // get
static get getServiceRequestStatus => "$_baseUrl/Lookups/GetLookup?lookupEnum=503"; 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 getPreventiveMaintenanceVisits => "$_baseUrl/return/user/calibrations"; // get
static get updatePreventiveMaintenanceVisits => "$_baseUrl/Visit/UpdateVisits"; // get static get updatePreventiveMaintenanceVisits => "$_baseUrl/Visit/UpdateVisits"; // get

@ -281,7 +281,68 @@ class ServiceRequestsProvider extends ChangeNotifier {
}) async { }) async {
Response response; Response response;
try { try {
Map<String, dynamic> body = report.toMap(request); Map<String, dynamic> 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["uid"] = user.id;
// body["token"] = user.token; // body["token"] = user.token;
response = await ApiManager.instance.post(URLs.createServiceReport, body: body); response = await ApiManager.instance.post(URLs.createServiceReport, body: body);
@ -299,6 +360,7 @@ class ServiceRequestsProvider extends ChangeNotifier {
} }
return response.statusCode; return response.statusCode;
} catch (error) { } catch (error) {
print(error);
return -1; return -1;
} }
} }

@ -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<Lookup> _reasons;
List<Lookup> 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<int> 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;
}
}
}

@ -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/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_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_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_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_report_types_provider.dart';
import 'controllers/providers/api/status_drop_down/report/service_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: (_) => EngineersProvider()),
ChangeNotifierProvider(create: (_) => ServiceLoanAvailabilityProvider()), ChangeNotifierProvider(create: (_) => ServiceLoanAvailabilityProvider()),
ChangeNotifierProvider(create: (_) => ServiceFirstActionProvider()), ChangeNotifierProvider(create: (_) => ServiceFirstActionProvider()),
ChangeNotifierProvider(create: (_) => ServiceReportRepairLocationProvider()),
], ],
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {

@ -15,6 +15,7 @@ class ServiceReport {
DateTime endDate; DateTime endDate;
Lookup assetType; Lookup assetType;
Lookup callLastSituation; Lookup callLastSituation;
Lookup repairLocation;
Engineer engineer; Engineer engineer;
Lookup status; Lookup status;
Lookup type; Lookup type;
@ -33,36 +34,42 @@ class ServiceReport {
TimerModel timer; TimerModel timer;
String signatureNurse; String signatureNurse;
String signatureEngineer; String signatureEngineer;
String comment;
Uint8List localNurseSignature; Uint8List localNurseSignature;
Uint8List localEngineerSignature; Uint8List localEngineerSignature;
int travelingExpense;
ServiceReport( ServiceReport({
{this.id, this.id,
this.visitDate, this.visitDate,
this.endDate, this.endDate,
this.assetType, this.assetType,
this.status, this.status,
this.type, this.type,
this.faultDescriptionId, this.faultDescriptionId,
//this.workHours, //this.workHours,
this.travelingHours, this.travelingHours,
this.parts, this.parts,
this.engineer, this.engineer,
this.workPreformed, this.workPreformed,
this.reason, this.reason,
this.operatingHours, this.operatingHours,
this.callLastSituation, this.callLastSituation,
this.jobSheetNumber, this.jobSheetNumber,
this.image, this.image,
this.device, this.device,
this.invoiceCode, this.invoiceCode,
this.invoiceNumber, this.invoiceNumber,
this.quantity = "1", this.quantity = "1",
this.timer, this.timer,
this.signatureNurse, this.signatureNurse,
this.signatureEngineer, this.signatureEngineer,
this.localNurseSignature, this.localNurseSignature,
this.localEngineerSignature}); this.localEngineerSignature,
this.comment,
this.repairLocation,
this.travelingExpense,
});
Map<String, dynamic> toMap(ServiceRequest request) { Map<String, dynamic> toMap(ServiceRequest request) {
Map<String, dynamic> _map = {}; Map<String, dynamic> _map = {};
@ -98,6 +105,7 @@ class ServiceReport {
_map["callRequest"]["asset"]["invoiceNumber"] = invoiceNumber; _map["callRequest"]["asset"]["invoiceNumber"] = invoiceNumber;
} }
_map["AssignedEmployee"] = engineer?.toMap(); _map["AssignedEmployee"] = engineer?.toMap();
_map["repairLocation"] = repairLocation?.toMap();
//if(quantity != null && quantity.isNotEmpty) _map["qty"] = quantity; //if(quantity != null && quantity.isNotEmpty) _map["qty"] = quantity;
//if(endDate != null) _map["end_date"] = (endDate.millisecondsSinceEpoch ~/ 1000).toString(); //if(endDate != null) _map["end_date"] = (endDate.millisecondsSinceEpoch ~/ 1000).toString();
if (reason != null) _map["reason"] = reason.toMap(); if (reason != null) _map["reason"] = reason.toMap();
@ -113,6 +121,8 @@ class ServiceReport {
} }
_map["nurseSignature"] = signatureNurse; _map["nurseSignature"] = signatureNurse;
_map["engSignature"] = signatureEngineer; _map["engSignature"] = signatureEngineer;
_map["comment"] = comment;
_map["travelingExpense"] = travelingExpense;
return _map; return _map;
} }

@ -217,6 +217,10 @@ class Subtitle {
String alert; String alert;
String comment; String comment;
String updateServiceRequest; String updateServiceRequest;
String repairLocation;
String travelingExpense;
String startDate;
String endDate;
void setIssues(List<String> issues) { void setIssues(List<String> issues) {
issues.clear(); issues.clear();
@ -409,6 +413,10 @@ class Subtitle {
@required this.duplicateAlert, @required this.duplicateAlert,
@required this.duplicateAlertMessage, @required this.duplicateAlertMessage,
@required this.duplicateRequest, @required this.duplicateRequest,
@required this.repairLocation,
@required this.travelingExpense,
@required this.startDate,
@required this.endDate,
}); });
factory Subtitle.fromJson(Map<String, dynamic> parsedJson) { factory Subtitle.fromJson(Map<String, dynamic> parsedJson) {
@ -594,6 +602,10 @@ class Subtitle {
duplicateAlert: parsedJson["duplicateAlert"], duplicateAlert: parsedJson["duplicateAlert"],
duplicateAlertMessage: parsedJson["duplicateAlertMessage"], duplicateAlertMessage: parsedJson["duplicateAlertMessage"],
duplicateRequest: parsedJson["duplicateRequest"], duplicateRequest: parsedJson["duplicateRequest"],
repairLocation: parsedJson["repairLocation"],
travelingExpense: parsedJson["travelingExpense"],
startDate: parsedJson["startDate"],
endDate: parsedJson["endDate"],
); );
} }
} }

@ -2,7 +2,6 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/http_status_manger.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/part.dart';
import 'package:test_sa/models/service_report.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.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/app_style/sizing.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_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_reasons.dart';
import 'package:test_sa/views/widgets/status/report/service_report_status.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_status.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart'; import 'package:test_sa/views/widgets/timer/app_timer.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.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 { class CreateServiceReport extends StatefulWidget {
static final String id = "/create-service-report"; static final String id = "/create-service-report";
final ServiceRequest request ; final ServiceRequest request;
const CreateServiceReport({Key key, this.request}) : super(key: key); const CreateServiceReport({Key key, this.request}) : super(key: key);
@override @override
_CreateServiceReportState createState() => _CreateServiceReportState(); _CreateServiceReportState createState() => _CreateServiceReportState();
} }
class _CreateServiceReportState extends State<CreateServiceReport> with TickerProviderStateMixin{ class _CreateServiceReportState extends State<CreateServiceReport> with TickerProviderStateMixin {
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; SettingProvider _settingProvider;
ServiceRequestsProvider _serviceRequestsProvider; ServiceRequestsProvider _serviceRequestsProvider;
@ -67,11 +65,10 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
@override @override
void initState() { void initState() {
_serviceReport = ServiceReport( _serviceReport = ServiceReport(
visitDate: DateTime.now(), visitDate: DateTime.now(),
//type: const Lookup(value: 2), //type: const Lookup(value: 2),
device: widget.request.device, device: widget.request.device,
parts: [] parts: []);
);
super.initState(); super.initState();
} }
@ -81,6 +78,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
_workPreformedController.dispose(); _workPreformedController.dispose();
super.dispose(); super.dispose();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
@ -102,52 +100,54 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
ListView( ListView(
children: [ children: [
//AppNameBar(), //AppNameBar(),
const SizedBox(height: 16,), const SizedBox(
height: 16,
),
Center( Center(
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: Text( child: Text(
_subtitle.newServiceReport, _subtitle.newServiceReport,
style: Theme.of(context).textTheme.headline5.copyWith( style: Theme.of(context).textTheme.headline5.copyWith(color: AColors.cyan, fontSize: 28, fontWeight: FontWeight.bold),
color: AColors.cyan,
fontSize: 28,
fontWeight: FontWeight.bold
),
), ),
), ),
), ),
Container( Container(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
margin: const EdgeInsets.symmetric(horizontal: 16,vertical: 16), margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
decoration: BoxDecoration( decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [
const BoxShadow(
color: AColors.grey, color: AColors.grey,
borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), offset: Offset(0, -1),
boxShadow: [ )
const BoxShadow( ]),
color: AColors.grey,
offset: Offset(0,-1),
)
]
),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
Wrap( Wrap(
spacing: 10, spacing: 10,
children: [ children: [
ASubTitle("${_subtitle.callId}: ${widget.request.requestCode}",font: 14,), ASubTitle(
widget.request.deviceSerialNumber == null ? const SizedBox(): "${_subtitle.callId}: ${widget.request.requestCode}",
ASubTitle("${_subtitle.deviceSN}: ${widget.request.deviceSerialNumber}",font: 14,), font: 14,
),
widget.request.deviceSerialNumber == null
? const SizedBox()
: ASubTitle(
"${_subtitle.deviceSN}: ${widget.request.deviceSerialNumber}",
font: 14,
),
Text( Text(
"${_subtitle.customer}: ${widget.request.hospitalName}", "${_subtitle.customer}: ${widget.request.hospitalName}",
style: Theme.of(context).textTheme.subtitle1.copyWith( style: Theme.of(context).textTheme.subtitle1.copyWith(
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
fontSize: 12, fontSize: 12,
), ),
textScaleFactor: AppStyle.getScaleFactor(context), textScaleFactor: AppStyle.getScaleFactor(context),
) )
], ],
), ),
const Divider(), const Divider(),
@ -181,9 +181,12 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.visitDate), ASubTitle(_subtitle.visitDate),
_validate && _serviceReport.visitDate == null ? _validate && _serviceReport.visitDate == null
ASubTitle(_subtitle.requiredWord,color: Colors.red,): ? ASubTitle(
const SizedBox.shrink(), _subtitle.requiredWord,
color: Colors.red,
)
: const SizedBox.shrink(),
Row( Row(
children: [ children: [
Expanded( Expanded(
@ -191,7 +194,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
date: _serviceReport.visitDate, date: _serviceReport.visitDate,
from: DateTime.now().subtract(const Duration(days: 365)), from: DateTime.now().subtract(const Duration(days: 365)),
to: DateTime.now().add(const Duration(days: 365)), to: DateTime.now().add(const Duration(days: 365)),
onDatePicker: (date){ onDatePicker: (date) {
_serviceReport.visitDate = date; _serviceReport.visitDate = date;
setState(() {}); setState(() {});
}, },
@ -202,10 +205,11 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
], ],
), ),
), ),
], ],
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
// device sn // device sn
Visibility( Visibility(
visible: widget.request.deviceSerialNumber == null, visible: widget.request.deviceSerialNumber == null,
@ -213,33 +217,47 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.deviceSN), ASubTitle(_subtitle.deviceSN),
_validate && _serviceReport.device?.id == null ? _validate && _serviceReport.device?.id == null
ASubTitle(_subtitle.requiredWord,color: Colors.red,): ? ASubTitle(
const SizedBox.shrink(), _subtitle.requiredWord,
color: Colors.red,
)
: const SizedBox.shrink(),
AutoCompleteDeviceField( AutoCompleteDeviceField(
hospitalId: widget.request.hospitalId, hospitalId: widget.request.hospitalId,
initialValue: _serviceReport.device, initialValue: _serviceReport.device,
onPick: (id){ onPick: (id) {
_serviceReport.device.id = id; _serviceReport.device.id = id;
}, },
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
], ],
), ),
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
ASubTitle(_subtitle.serviceType), ASubTitle(_subtitle.serviceType),
_validate && _serviceReport.assetType == null ? _validate && _serviceReport.assetType == null
ASubTitle(_subtitle.requiredWord,color: Colors.red,): ? ASubTitle(
const SizedBox.shrink(), _subtitle.requiredWord,
const SizedBox(height: 4,), color: Colors.red,
)
: const SizedBox.shrink(),
const SizedBox(
height: 4,
),
ServiceAssetTypeMenu( ServiceAssetTypeMenu(
initialValue: _serviceReport.assetType, initialValue: _serviceReport.assetType,
onSelect: (status){ onSelect: (status) {
_serviceReport.assetType = status; _serviceReport.assetType = status;
}, },
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
// Report status and Service Type // Report status and Service Type
Row( Row(
children: [ children: [
@ -249,40 +267,51 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.reportStatus), ASubTitle(_subtitle.reportStatus),
_validate && _serviceReport.status == null ? _validate && _serviceReport.status == null
ASubTitle(_subtitle.requiredWord,color: Colors.red,): ? ASubTitle(
const SizedBox.shrink(), _subtitle.requiredWord,
const SizedBox(height: 4,), color: Colors.red,
)
: const SizedBox.shrink(),
const SizedBox(
height: 4,
),
ServiceReportStatusMenu( ServiceReportStatusMenu(
report: _serviceReport, report: _serviceReport,
onSelect: (status){ onSelect: (status) {
_serviceReport.status = status; _serviceReport.status = status;
}, },
), ),
], ],
), ),
), ),
const SizedBox(width: 8,), const SizedBox(
width: 8,
),
// Provider.of<ServiceReportLastCallsProvider>(context).isLoading == null // Provider.of<ServiceReportLastCallsProvider>(context).isLoading == null
// ? const SizedBox.shrink(): // ? const SizedBox.shrink():
// Call's last Situation // Call's last Situation
Consumer<ServiceReportLastCallsProvider>( Consumer<ServiceReportLastCallsProvider>(
builder: (_, provider, __) { builder: (_, provider, __) {
if(provider.isLoading == null) return const SizedBox.shrink(); if (provider.isLoading == null) return const SizedBox.shrink();
return Expanded( return Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.callLastSituation), ASubTitle(_subtitle.callLastSituation),
_validate && _serviceReport.callLastSituation == null ? _validate && _serviceReport.callLastSituation == null
ASubTitle(_subtitle.requiredWord,color: Colors.red,): ? ASubTitle(
const SizedBox.shrink(), _subtitle.requiredWord,
const SizedBox(height: 4,), color: Colors.red,
)
: const SizedBox.shrink(),
const SizedBox(
height: 4,
),
ServiceReportLastCallsMenu( ServiceReportLastCallsMenu(
report: _serviceReport, report: _serviceReport,
onSelect: (status){ onSelect: (status) {
if(status?.value == 12 if (status?.value == 12 || _serviceReport.callLastSituation?.value == 12) {
|| _serviceReport.callLastSituation?.value == 12){
_serviceReport.callLastSituation = status; _serviceReport.callLastSituation = status;
setState(() {}); setState(() {});
} else { } else {
@ -297,70 +326,83 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
), ),
], ],
), ),
SizedBox(height: 8 * AppStyle.getScaleFactor(context),), SizedBox(
const ASubTitle("Assign Employee"), height: 8 * AppStyle.getScaleFactor(context),
const SizedBox(height: 8,), ),
_validate && _serviceReport.engineer == null ? const ASubTitle("Assigned Employee"),
ASubTitle(_subtitle.requiredWord,color: Colors.red,): const SizedBox(
const SizedBox.shrink(), height: 8,
const SizedBox(height: 4,), ),
_validate && _serviceReport.engineer == null
? ASubTitle(
_subtitle.requiredWord,
color: Colors.red,
)
: const SizedBox.shrink(),
const SizedBox(
height: 4,
),
EngineersMenu( EngineersMenu(
initialValue: _serviceReport.engineer, initialValue: _serviceReport.engineer,
onSelect: (engineer){ onSelect: (engineer) {
_serviceReport.engineer = engineer; _serviceReport.engineer = engineer;
}, },
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
// invoice number & code // invoice number & code
_serviceReport.callLastSituation?.id != 12 ? const SizedBox.shrink(): _serviceReport.callLastSituation?.id != 12
Row( ? const SizedBox.shrink()
children: [ : Row(
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.invoiceNumber), Expanded(
const SizedBox(height: 8,), child: Column(
ATextFormField( crossAxisAlignment: CrossAxisAlignment.start,
initialValue: _serviceReport?.invoiceNumber, children: [
textAlign: TextAlign.center, ASubTitle(_subtitle.invoiceNumber),
style: Theme.of(context).textTheme.subtitle1, const SizedBox(
validator: (value) => height: 8,
Validator.hasValue(value) ),
? null : _subtitle.requiredWord, ATextFormField(
textInputType: TextInputType.number, initialValue: _serviceReport?.invoiceNumber,
onSaved: (value){ textAlign: TextAlign.center,
_serviceReport.invoiceNumber = value; 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,
), ),
const SizedBox(width: 8,), Expanded(
Expanded( child: Column(
child: Column( crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: [ ASubTitle(_subtitle.invoiceCode),
ASubTitle(_subtitle.invoiceCode), const SizedBox(
const SizedBox(height: 4,), height: 4,
ATextFormField( ),
initialValue: _serviceReport?.invoiceCode, ATextFormField(
textAlign: TextAlign.center, initialValue: _serviceReport?.invoiceCode,
style: Theme.of(context).textTheme.subtitle1, textAlign: TextAlign.center,
validator: (value) => style: Theme.of(context).textTheme.subtitle1,
Validator.hasValue(value) validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord,
? null : _subtitle.requiredWord, textInputType: TextInputType.text,
textInputType: TextInputType.text, onSaved: (value) {
onSaved: (value){ _serviceReport.invoiceCode = value;
_serviceReport.invoiceCode = value; },
}, ),
],
),
), ),
], ],
), ),
),
],
),
// const SizedBox(height: 8,), // const SizedBox(height: 8,),
// Row( // Row(
// children: [ // children: [
@ -421,7 +463,9 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
// ), // ),
// const SizedBox(height: 8,), // const SizedBox(height: 8,),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
Row( Row(
children: [ children: [
// reasons // reasons
@ -430,17 +474,21 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.reasons), ASubTitle(_subtitle.reasons),
const SizedBox(height: 4,), const SizedBox(
height: 4,
),
ServiceReportReasonsMenu( ServiceReportReasonsMenu(
initialValue: _serviceReport.reason, initialValue: _serviceReport.reason,
onSelect: (status){ onSelect: (status) {
_serviceReport.reason = status; _serviceReport.reason = status;
}, },
), ),
], ],
), ),
), ),
const SizedBox(width: 8,), const SizedBox(
width: 8,
),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -449,8 +497,8 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
AMiniOneImagePicker( AMiniOneImagePicker(
//error: _validate && _serviceReport.image == null, //error: _validate && _serviceReport.image == null,
image: _image, image: _image,
onPick: (image){ onPick: (image) {
_image =image; _image = image;
_serviceReport.image = "${image.path.split("/").last}|${base64Encode(image.readAsBytesSync())}"; _serviceReport.image = "${image.path.split("/").last}|${base64Encode(image.readAsBytesSync())}";
}, },
), ),
@ -459,7 +507,49 @@ class _CreateServiceReportState extends State<CreateServiceReport> 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 // Traveling Hours & Working Hours
Row( Row(
children: [ children: [
@ -468,13 +558,15 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.workingHours), ASubTitle(_subtitle.workingHours),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: AppTimer( child: AppTimer(
timer: _serviceReport.timer, timer: _serviceReport.timer,
onChange: (timer) async{ onChange: (timer) async {
_serviceReport.timer = timer; _serviceReport.timer = timer;
return true; return true;
}, },
@ -523,7 +615,9 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
// ), // ),
], ],
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
// Operating Hours and Job Sheet Number // Operating Hours and Job Sheet Number
// Row( // Row(
// children: [ // children: [
@ -570,30 +664,39 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
// ), // ),
// ], // ],
// ), // ),
//const SizedBox(height: 8,), const SizedBox(
const SizedBox(height: 8,), height: 8,
),
const ASubTitle("Nurse Signature"), const ASubTitle("Nurse Signature"),
ESignature( ESignature(
oldSignature: _serviceReport.signatureNurse, oldSignature: _serviceReport.signatureNurse,
newSignature: _serviceReport.localNurseSignature, newSignature: _serviceReport.localNurseSignature,
onSaved: (signature){ onSaved: (signature) {
if(signature == null || signature.isEmpty) {return;} if (signature == null || signature.isEmpty) {
return;
}
_serviceReport.localNurseSignature = signature; _serviceReport.localNurseSignature = signature;
_serviceReport.signatureNurse = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; _serviceReport.signatureNurse = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
}, },
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
const ASubTitle("Engineer Signature"), const ASubTitle("Engineer Signature"),
ESignature( ESignature(
oldSignature: _serviceReport.signatureEngineer, oldSignature: _serviceReport.signatureEngineer,
newSignature: _serviceReport.localNurseSignature, newSignature: _serviceReport.localNurseSignature,
onSaved: (signature){ onSaved: (signature) {
if(signature == null || signature.isEmpty) {return;} if (signature == null || signature.isEmpty) {
return;
}
_serviceReport.localNurseSignature = signature; _serviceReport.localNurseSignature = signature;
_serviceReport.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; _serviceReport.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
}, },
), ),
const SizedBox(height: 8,), const SizedBox(
height: 8,
),
// Part Number and Quantity // Part Number and Quantity
Row( Row(
children: [ children: [
@ -603,45 +706,49 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.partNumber), ASubTitle(_subtitle.partNumber),
_validate && _serviceReport.parts == null ? _validate && _serviceReport.parts == null
ASubTitle(_subtitle.requiredWord,color: Colors.red,): ? ASubTitle(
const SizedBox.shrink(), _subtitle.requiredWord,
const SizedBox(height: 4,), color: Colors.red,
)
: const SizedBox.shrink(),
const SizedBox(
height: 4,
),
AutoCompletePartsField( AutoCompletePartsField(
onPick: (part){ onPick: (part) {
_serviceReport.parts.add(part); _serviceReport.parts.add(part);
}, },
), ),
], ],
), ),
), ),
], ],
), ),
SizedBox(height: 8*AppStyle.getScaleFactor(context),), SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
),
Row( Row(
children: [ children: [
Expanded(flex:3,child: Text(_subtitle.number)), Expanded(flex: 3, child: Text(_subtitle.number)),
Expanded(flex: 1,child: Text(_subtitle.quantity)), Expanded(flex: 1, child: Text(_subtitle.quantity)),
], ],
), ),
Column( Column(
children: List.generate( children: List.generate(_serviceReport.parts.length, (index) {
_serviceReport.parts.length, Part _part = _serviceReport.parts[index];
(index) { return PartItem(
Part _part = _serviceReport.parts[index]; part: _part,
return PartItem( onDelete: (part) {
part: _part, _serviceReport.parts.remove(part);
onDelete: (part){ setState(() {});
_serviceReport.parts.remove(part); },
setState(() {}); );
}, }),
); ),
} const SizedBox(
), height: 16,
), ),
const SizedBox(height: 16,),
], ],
), ),
), ),
@ -651,47 +758,48 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
text: _subtitle.submit, text: _subtitle.submit,
onPressed: () async { onPressed: () async {
_validate = true; _validate = true;
if(!_formKey.currentState.validate()){ print(1);
if (!_formKey.currentState.validate()) {
print(2);
setState(() {}); setState(() {});
return; return;
} }
if(!_serviceReport.validate()) return; print(3);
if (!_serviceReport.validate()) return;
print(4);
_formKey.currentState.save(); _formKey.currentState.save();
print(5);
_isLoading =true; _isLoading = true;
setState(() {}); setState(() {});
int status = await _serviceRequestsProvider.createServiceReport( int status = await _serviceRequestsProvider.createServiceReport(
user: _userProvider.user, user: _userProvider.user,
host: _settingProvider.host, host: _settingProvider.host,
report: _serviceReport, report: _serviceReport,
request: widget.request request: widget.request,
); );
_isLoading =false; print(6);
print(status);
_isLoading = false;
setState(() {}); setState(() {});
if(status >= 200 && status < 300){ if (status >= 200 && status < 300) {
Fluttertoast.showToast( Fluttertoast.showToast(
msg: _subtitle.requestCompleteSuccessfully, msg: _subtitle.requestCompleteSuccessfully,
); );
Navigator.of(context).pop(); Navigator.of(context).pop();
Navigator.of(context).pop(); Navigator.of(context).pop();
}else{ } else {
String errorMessage = HttpStatusManger.getStatusMessage( String errorMessage = HttpStatusManger.getStatusMessage(status: status, subtitle: _subtitle);
status: status, subtitle: _subtitle); ScaffoldMessenger.of(context).showSnackBar(SnackBar(
ScaffoldMessenger.of(context).showSnackBar( content: Text(errorMessage),
SnackBar( ));
content: Text(
errorMessage
),
)
);
} }
}, },
), ),
), ),
const SizedBox(height: 300,) const SizedBox(
height: 300,
)
], ],
), ),
const ABackButton(), const ABackButton(),

@ -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<SettingProvider>(context);
UserProvider _userProvider = Provider.of<UserProvider>(context);
ServiceReportRepairLocationProvider _menuProvider = Provider.of<ServiceReportRepairLocationProvider>(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,
));
}
}
Loading…
Cancel
Save