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": "هل أنت متأكد أنك تريد تكرار الطلب؟",
"duplicateRequest": "تكرار الطلب",
"comment" : "تعليق",
"updateServiceRequest" : "تعديل طلب الخدمة"
"updateServiceRequest" : "تعديل طلب الخدمة",
"repairLocation" : "موقع الإصلاح",
"travelingExpense" : "مصاريف التنقل",
"startDate" : "وقت البدء",
"endDate" : "وقت الانتهاء"
}

@ -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"
}

@ -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

@ -281,7 +281,68 @@ class ServiceRequestsProvider extends ChangeNotifier {
}) async {
Response response;
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["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;
}
}

@ -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/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: () {

@ -15,6 +15,7 @@ class ServiceReport {
DateTime endDate;
Lookup assetType;
Lookup callLastSituation;
Lookup repairLocation;
Engineer engineer;
Lookup status;
Lookup type;
@ -33,11 +34,13 @@ class ServiceReport {
TimerModel timer;
String signatureNurse;
String signatureEngineer;
String comment;
Uint8List localNurseSignature;
Uint8List localEngineerSignature;
int travelingExpense;
ServiceReport(
{this.id,
ServiceReport({
this.id,
this.visitDate,
this.endDate,
this.assetType,
@ -62,7 +65,11 @@ class ServiceReport {
this.signatureNurse,
this.signatureEngineer,
this.localNurseSignature,
this.localEngineerSignature});
this.localEngineerSignature,
this.comment,
this.repairLocation,
this.travelingExpense,
});
Map<String, dynamic> toMap(ServiceRequest request) {
Map<String, dynamic> _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;
}

@ -217,6 +217,10 @@ class Subtitle {
String alert;
String comment;
String updateServiceRequest;
String repairLocation;
String travelingExpense;
String startDate;
String endDate;
void setIssues(List<String> 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<String, dynamic> 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"],
);
}
}

@ -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<CreateServiceReport> with TickerProviderStateMixin{
class _CreateServiceReportState extends State<CreateServiceReport> with TickerProviderStateMixin {
UserProvider _userProvider;
SettingProvider _settingProvider;
ServiceRequestsProvider _serviceRequestsProvider;
@ -70,8 +68,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
visitDate: DateTime.now(),
//type: const Lookup(value: 2),
device: widget.request.device,
parts: []
);
parts: []);
super.initState();
}
@ -81,6 +78,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
_workPreformedController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context);
@ -102,43 +100,46 @@ class _CreateServiceReportState extends State<CreateServiceReport> 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(
color: AColors.grey,
borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)),
boxShadow: [
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [
const BoxShadow(
color: AColors.grey,
offset: Offset(0,-1),
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(
@ -147,7 +148,6 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
),
textScaleFactor: AppStyle.getScaleFactor(context),
)
],
),
const Divider(),
@ -181,9 +181,12 @@ class _CreateServiceReportState extends State<CreateServiceReport> 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<CreateServiceReport> 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<CreateServiceReport> 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<CreateServiceReport> 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<CreateServiceReport> 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<ServiceReportLastCallsProvider>(context).isLoading == null
// ? const SizedBox.shrink():
// Call's last Situation
Consumer<ServiceReportLastCallsProvider>(
builder: (_, provider, __) {
if(provider.isLoading == null) return const SizedBox.shrink();
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,61 +326,75 @@ class _CreateServiceReportState extends State<CreateServiceReport> 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(
_serviceReport.callLastSituation?.id != 12
? const SizedBox.shrink()
: Row(
children: [
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.invoiceNumber),
const SizedBox(height: 8,),
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,
validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord,
textInputType: TextInputType.number,
onSaved: (value){
onSaved: (value) {
_serviceReport.invoiceNumber = value;
},
),
],
),
),
const SizedBox(width: 8,),
const SizedBox(
width: 8,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(_subtitle.invoiceCode),
const SizedBox(height: 4,),
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,
validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord,
textInputType: TextInputType.text,
onSaved: (value){
onSaved: (value) {
_serviceReport.invoiceCode = value;
},
),
@ -360,7 +403,6 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
),
],
),
// const SizedBox(height: 8,),
// Row(
// children: [
@ -421,7 +463,9 @@ class _CreateServiceReportState extends State<CreateServiceReport> 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<CreateServiceReport> 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<CreateServiceReport> 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<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
Row(
children: [
@ -468,13 +558,15 @@ class _CreateServiceReportState extends State<CreateServiceReport> 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<CreateServiceReport> 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<CreateServiceReport> 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<CreateServiceReport> 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) {
children: List.generate(_serviceReport.parts.length, (index) {
Part _part = _serviceReport.parts[index];
return PartItem(
part: _part,
onDelete: (part){
onDelete: (part) {
_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,
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,
);
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(),

@ -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