Merge remote-tracking branch 'origin/main_latest_merged' into majd_development_new

# Conflicts:
#	lib/views/pages/user/requests/report/edit_service_report.dart
#	lib/views/widgets/equipment/single_device_picker.dart
pull/2/head
nextwo 3 years ago
commit 3737c3b41c

@ -54,22 +54,25 @@ android {
} }
signingConfigs { signingConfigs {
release { // release {
keyAlias keystoreProperties['keyAlias'] // keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword'] // keyPassword keystoreProperties['keyPassword']
storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null // storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
storePassword keystoreProperties['storePassword'] // storePassword keystoreProperties['storePassword']
} // }
} }
buildTypes { buildTypes {
debug { debug {
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
} }
release { release {
minifyEnabled true signingConfig signingConfigs.debug
shrinkResources true
signingConfig signingConfigs.release
} }
// release {
// minifyEnabled true
// shrinkResources true
// signingConfig signingConfigs.release
// }
} }
} }

@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:developer'; import 'dart:developer';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:http/http.dart'; import 'package:http/http.dart';
@ -51,9 +52,12 @@ class ApiManager {
headers.addAll(_headers); headers.addAll(_headers);
Uri _url = Uri.parse(url); Uri _url = Uri.parse(url);
// print(_url); if (!kReleaseMode) {
// print(headers); print("URL:$_url");
// log(json.encode(body)); print("Headers:$headers");
print("Body:$body");
}
var request = http.Request('POST', _url); var request = http.Request('POST', _url);
request.body = json.encode(body); request.body = json.encode(body);
request.headers.addAll(headers); request.headers.addAll(headers);
@ -83,7 +87,7 @@ class ApiManager {
headers.addAll(_headers); headers.addAll(_headers);
Uri _url = Uri.parse(url); Uri _url = Uri.parse(url);
// print(_url); print(_url);
// print(headers); // print(headers);
// log(json.encode(body)); // log(json.encode(body));
var request = http.Request('PUT', _url); var request = http.Request('PUT', _url);

@ -23,7 +23,7 @@ class DeviceTransferProvider extends ChangeNotifier {
building = null; building = null;
floor = null; floor = null;
department = null; department = null;
room=""; room = "";
startDate = null; startDate = null;
endDate = null; endDate = null;
} }
@ -44,7 +44,6 @@ class DeviceTransferProvider extends ChangeNotifier {
// failed _loading = false // failed _loading = false
bool isLoading; bool isLoading;
Hospital hospital; Hospital hospital;
Buildings building; Buildings building;
Floors floor; Floors floor;
@ -179,8 +178,8 @@ class DeviceTransferProvider extends ChangeNotifier {
"senderMachineStatusId": newModel.status.id, "senderMachineStatusId": newModel.status.id,
"senderComment": newModel.comment, "senderComment": newModel.comment,
"senderWorkingHours": newModel.workingHours, "senderWorkingHours": newModel.workingHours,
"senderStartDate": newModel.startDate?.toIso8601String(), "senderStartDate": newModel.timer?.startAt?.toIso8601String(),
"senderEndDate": newModel.endDate?.toIso8601String(), "senderEndDate": newModel.timer?.endAt?.toIso8601String(),
"senderTravelingHours": newModel.travelingHours, "senderTravelingHours": newModel.travelingHours,
"senderAttachmentName": "${newModel.signature}.png", "senderAttachmentName": "${newModel.signature}.png",
"destSiteId": oldModel.receiver.client.id, "destSiteId": oldModel.receiver.client.id,
@ -189,8 +188,8 @@ class DeviceTransferProvider extends ChangeNotifier {
"receiverMachineStatusId": oldModel.receiver.status.id ?? "", "receiverMachineStatusId": oldModel.receiver.status.id ?? "",
"receiverComment": oldModel.receiver.comment, "receiverComment": oldModel.receiver.comment,
"receiverWorkingHours": oldModel.receiver.workingHours, "receiverWorkingHours": oldModel.receiver.workingHours,
"receiverStartDate": oldModel.receiver.startDate?.toIso8601String(), "receiverStartDate": oldModel.receiver.timer?.startAt?.toIso8601String(),
"receiverEndDate": oldModel.receiver.endDate?.toIso8601String(), "receiverEndDate": oldModel.receiver.timer?.endAt?.toIso8601String(),
"receiverTravelingHours": oldModel.receiver.travelingHours, "receiverTravelingHours": oldModel.receiver.travelingHours,
"receiverAttachmentName": "${oldModel.receiver.signature}.png", "receiverAttachmentName": "${oldModel.receiver.signature}.png",
}); });
@ -202,8 +201,8 @@ class DeviceTransferProvider extends ChangeNotifier {
"senderMachineStatusId": oldModel.sender.status.id, "senderMachineStatusId": oldModel.sender.status.id,
"senderComment": oldModel.sender.comment, "senderComment": oldModel.sender.comment,
"senderWorkingHours": oldModel.sender.workingHours, "senderWorkingHours": oldModel.sender.workingHours,
"senderStartDate": oldModel.sender.startDate?.toIso8601String(), "senderStartDate": oldModel.sender.timer?.startAt?.toIso8601String(),
"senderEndDate": oldModel.sender.endDate?.toIso8601String(), "senderEndDate": oldModel.sender.timer?.endAt?.toIso8601String(),
"senderTravelingHours": oldModel.sender.travelingHours, "senderTravelingHours": oldModel.sender.travelingHours,
"senderAttachmentName": "${oldModel.sender.signature}.png", "senderAttachmentName": "${oldModel.sender.signature}.png",
"destSiteId": newModel.client.id, "destSiteId": newModel.client.id,
@ -212,8 +211,8 @@ class DeviceTransferProvider extends ChangeNotifier {
"receiverMachineStatusId": newModel.status?.id ?? "", "receiverMachineStatusId": newModel.status?.id ?? "",
"receiverComment": newModel.comment, "receiverComment": newModel.comment,
"receiverWorkingHours": newModel.workingHours, "receiverWorkingHours": newModel.workingHours,
"receiverStartDate": newModel.startDate?.toIso8601String(), "receiverStartDate": newModel.timer?.startAt?.toIso8601String(),
"receiverEndDate": newModel.endDate?.toIso8601String(), "receiverEndDate": newModel.timer?.endAt?.toIso8601String(),
"receiverTravelingHours": newModel.travelingHours, "receiverTravelingHours": newModel.travelingHours,
"receiverAttachmentName": "${newModel.signature}.png", "receiverAttachmentName": "${newModel.signature}.png",
}); });
@ -247,5 +246,4 @@ class DeviceTransferProvider extends ChangeNotifier {
return -1; return -1;
} }
} }
} }

@ -147,31 +147,31 @@ class DevicesProvider extends ChangeNotifier {
} }
} }
/// return -2 if request in progress // /// return -2 if request in progress
/// return -1 if error happen when sending request // /// return -1 if error happen when sending request
/// return state code if request complete may be 200, 404 or 403 // /// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager // /// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart // /// lib\controllers\http_status_manger\http_status_manger.dart
Future<List<Device>> getDevicesListBySN({@required String host, @required User user, @required int hospitalId, @required String sn}) async { // Future<List<Device>> getDevicesListBySN({@required String host, @required User user, @required int hospitalId, @required String sn}) async {
Response response; // Response response;
try { // try {
response = await get( // response = await get(
Uri.parse(URLs.getEquipment + "?client=$hospitalId" + (sn == null || sn.isEmpty ? "" : "&serial_qr=$sn")), // Uri.parse(URLs.getEquipment + "?client=$hospitalId" + (sn == null || sn.isEmpty ? "" : "&serial_qr=$sn")),
); // );
//
_stateCode = response.statusCode; // _stateCode = response.statusCode;
List<Device> _page = []; // List<Device> _page = [];
if (response.statusCode >= 200 && response.statusCode < 300) { // if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // // client's request was successfully received
List categoriesListJson = json.decode(utf8.decode(response.bodyBytes)); // List categoriesListJson = json.decode(utf8.decode(response.bodyBytes));
_page = categoriesListJson.map((device) => Device.fromJson(device)).toList(); // _page = categoriesListJson.map((device) => Device.fromJson(device)).toList();
} // }
return _page; // return _page;
} catch (error) { // } catch (error) {
_loading = false; // _loading = false;
_stateCode = -1; // _stateCode = -1;
notifyListeners(); // notifyListeners();
return []; // return [];
} // }
} // }
} }

@ -158,6 +158,8 @@ class GasRefillProvider extends ChangeNotifier {
"building": building?.toJson(includeFloors: false), "building": building?.toJson(includeFloors: false),
"floor": floor?.toJson(includeDepartments: false), "floor": floor?.toJson(includeDepartments: false),
"department": department?.toJson(), "department": department?.toJson(),
"engSignature": newModel.signatureEngineer,
"nurseSignature": newModel.signatureNurse,
}; };
body["gazRefillDetails"] = newModel.details body["gazRefillDetails"] = newModel.details

@ -1,4 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
@ -235,6 +236,10 @@ class ServiceRequestsProvider extends ChangeNotifier {
"voiceNote": request.audio, "voiceNote": request.audio,
"assets": request.deviceId == null ? [] : [request.deviceId], "assets": request.deviceId == null ? [] : [request.deviceId],
"attachmentsCallRequest": request.devicePhotos?.map((e) => {"name": e})?.toList(), "attachmentsCallRequest": request.devicePhotos?.map((e) => {"name": e})?.toList(),
"assignedEmployee": {
"id": request.engineerId,
"name": request.engineerName,
},
"callSiteContactPerson": [ "callSiteContactPerson": [
{ {
"id": callSiteContactPerson['id'] ?? 0, "id": callSiteContactPerson['id'] ?? 0,
@ -316,9 +321,9 @@ class ServiceRequestsProvider extends ChangeNotifier {
"currentSituation": null, "currentSituation": null,
"repairLocation": report.repairLocation?.toMap(), "repairLocation": report.repairLocation?.toMap(),
"reason": report.reason?.toMap(), "reason": report.reason?.toMap(),
"startofWorkTime": report.startDate?.toIso8601String() ?? "", "startofWorkTime": report.timer?.startAt?.toIso8601String() ?? "",
"endofWorkTime": report.endDate?.toIso8601String() ?? "", "endofWorkTime": report.timer?.endAt?.toIso8601String() ?? "",
"workingHours": ((report?.endDate?.difference(report?.startDate)?.inMinutes ?? 0) / 60), "workingHours": report?.workingHours,
"travelingHours": report.travelingHours, "travelingHours": report.travelingHours,
"travelingExpenses": report.travelingExpense ?? 0, "travelingExpenses": report.travelingExpense ?? 0,
if (report.faultDescription != null) "faultDescription": report.faultDescription.toJson(), if (report.faultDescription != null) "faultDescription": report.faultDescription.toJson(),
@ -395,12 +400,14 @@ class ServiceRequestsProvider extends ChangeNotifier {
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received // client's request was successfully received
Map<String, dynamic> listJson = json.decode(response.body)["data"]; Map<String, dynamic> listJson = json.decode(response.body)["data"];
log(listJson?.toString());
callRequestForWorkOrder = CallRequestForWorkOrder.fromJson(listJson); callRequestForWorkOrder = CallRequestForWorkOrder.fromJson(listJson);
} }
notifyListeners(); notifyListeners();
return callRequestForWorkOrder; return callRequestForWorkOrder;
} catch (error) { } catch (error) {
print(error);
return null; return null;
} }
} }
@ -474,7 +481,7 @@ class ServiceRequestsProvider extends ChangeNotifier {
// body["token"] = user.token; // body["token"] = user.token;
// body["job_id"] = request.id; // body["job_id"] = request.id;
// body["report_id"] = request.reportID; // body["report_id"] = request.reportID;
try { // try {
Map<String, dynamic> body = report.toMap(request); Map<String, dynamic> body = report.toMap(request);
// body["uid"] = user.id; // body["uid"] = user.id;
// body["token"] = user.token; // body["token"] = user.token;
@ -491,9 +498,10 @@ class ServiceRequestsProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
return response.statusCode; return response.statusCode;
} catch (error) { // } catch (error) {
return -1; // print(error);
} // return -1;
// }
} }
Future<int> updateWorkOrderDetails({@required SearchWorkOrder workOrder}) async { Future<int> updateWorkOrderDetails({@required SearchWorkOrder workOrder}) async {
@ -619,6 +627,7 @@ class ServiceRequestsProvider extends ChangeNotifier {
"pageNumber": ((workOrders?.length ?? 0) ~/ pageItemNumber) + 1, "pageNumber": ((workOrders?.length ?? 0) ~/ pageItemNumber) + 1,
if (callerId?.isNotEmpty ?? false) "callId": callerId, if (callerId?.isNotEmpty ?? false) "callId": callerId,
if (search.assetType != null) "assetSerialNo": search.assetType?.name, if (search.assetType != null) "assetSerialNo": search.assetType?.name,
if (search.workOrderNo != null) "workOrderNo": search.workOrderNo,
if (search.id != null) "workOrderNo": search.id?.toString(), if (search.id != null) "workOrderNo": search.id?.toString(),
if (search.calllastSituation != null) "callslastSituationWO": search.calllastSituation.toMap(), if (search.calllastSituation != null) "callslastSituationWO": search.calllastSituation.toMap(),
if (search.assignedEmployee != null) if (search.assignedEmployee != null)

@ -41,14 +41,14 @@ class ServiceReportMaintenanceSituationProvider extends ChangeNotifier {
/// return state code if request complete may be 200, 404 or 403 /// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager /// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart /// lib\controllers\http_status_manger\http_status_manger.dart
Future<int> getOperators() async { Future<int> getOperators(String woId) async {
if (_loading == true) return -2; if (_loading == true) return -2;
_loading = true; _loading = true;
notifyListeners(); notifyListeners();
Response response; Response response;
try { try {
response = await ApiManager.instance.get( response = await ApiManager.instance.get(
"${URLs.getMaintenanceSituation}", woId == null ? "${URLs.getMaintenanceSituation}" : "${URLs.getServiceReportLastCalls}?parentWOId=$woId&isAdd=true&id=${0}&typeTransaction='Nothing'",
); );
// response = await get( // response = await get(
// Uri.parse( // Uri.parse(

@ -82,7 +82,7 @@ class Asset {
Department department; Department department;
String room; String room;
String testsDay; String testsDay;
String purchasingPrice; num purchasingPrice;
String nbv; String nbv;
String currency; String currency;
String poNo; String poNo;

@ -5,6 +5,8 @@ import 'package:test_sa/models/device/device_transfer_info.dart';
import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import '../timer_model.dart';
class DeviceTransfer { class DeviceTransfer {
int id; int id;
String userId; String userId;
@ -53,14 +55,19 @@ class DeviceTransfer {
destDepartmentName: parsedJson["destDepartmentName"], destDepartmentName: parsedJson["destDepartmentName"],
destFloor: parsedJson["destFloor"], destFloor: parsedJson["destFloor"],
destRoom: parsedJson["destRoom"], destRoom: parsedJson["destRoom"],
destSiteName: parsedJson["destSiteName"] destSiteName: parsedJson["destSiteName"]),
),
sender: DeviceTransferInfo( sender: DeviceTransferInfo(
travelingHours: parsedJson["senderTravelingHours"], travelingHours: parsedJson["senderTravelingHours"],
comment: parsedJson["senderComment"], comment: parsedJson["senderComment"],
workingHours: parsedJson["senderWorkingHours"], workingHours: parsedJson["senderWorkingHours"],
startDate: parsedJson["senderStartDate"]==null ? null:DateTime.parse(parsedJson["senderStartDate"]), timer: TimerModel(
endDate: parsedJson["senderEndDate"]==null ? null:DateTime.parse(parsedJson["senderEndDate"]), startAt: DateTime.tryParse(parsedJson["senderStartDate"] ?? ""),
endAt: DateTime.tryParse(parsedJson["senderEndDate"] ?? ""),
durationInSecond: ((parsedJson["workingHours"] ?? 0) * 60 * 60).toInt(),
stopped: parsedJson["workingHours"] == null ? null : true,
),
// startDate: parsedJson["senderStartDate"] == null ? null : DateTime.parse(parsedJson["senderStartDate"]),
// endDate: parsedJson["senderEndDate"] == null ? null : DateTime.parse(parsedJson["senderEndDate"]),
userId: parsedJson["senderAssignedEmployeeId"], userId: parsedJson["senderAssignedEmployeeId"],
userName: parsedJson["senderAssignedEmployeeName"], userName: parsedJson["senderAssignedEmployeeName"],
assignedEmployeeName: parsedJson["senderAssignedEmployeeName"], assignedEmployeeName: parsedJson["senderAssignedEmployeeName"],
@ -80,8 +87,11 @@ class DeviceTransfer {
travelingHours: parsedJson["receiverTravelingHours"], travelingHours: parsedJson["receiverTravelingHours"],
comment: parsedJson["receiverComment"], comment: parsedJson["receiverComment"],
workingHours: parsedJson["receiverWorkingHours"], workingHours: parsedJson["receiverWorkingHours"],
startDate: parsedJson["receiverStartDate"]==null ? null:DateTime.parse(parsedJson["receiverStartDate"]), timer: parsedJson["receiverStartDate"] != null || parsedJson["receiverEndDate"] != null
endDate: parsedJson["receiverEndDate"]==null ? null:DateTime.parse(parsedJson["receiverEndDate"]), ? TimerModel(startAt: DateTime.tryParse(parsedJson["receiverStartDate"] ?? ""), endAt: DateTime.tryParse(parsedJson["receiverEndDate"] ?? ""))
: null,
// startDate: parsedJson["receiverStartDate"] == null ? null : DateTime.parse(parsedJson["receiverStartDate"]),
// endDate: parsedJson["receiverEndDate"] == null ? null : DateTime.parse(parsedJson["receiverEndDate"]),
userId: parsedJson["receiverAssignedEmployeeId"], userId: parsedJson["receiverAssignedEmployeeId"],
userName: parsedJson["receiverAssignedEmployeeName"], userName: parsedJson["receiverAssignedEmployeeName"],
assignedEmployeeName: parsedJson["receiverAssignedEmployeeName"], assignedEmployeeName: parsedJson["receiverAssignedEmployeeName"],

@ -2,19 +2,22 @@ import 'package:test_sa/models/department.dart';
import 'package:test_sa/models/hospital.dart'; import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import '../timer_model.dart';
class DeviceTransferInfo { class DeviceTransferInfo {
String userId; String userId;
String comment; String comment;
Hospital client; Hospital client;
Department department; Department department;
String workingHours; String workingHours;
DateTime startDate; // DateTime startDate;
DateTime endDate; // DateTime endDate;
String travelingHours; String travelingHours;
String userName; String userName;
String signature; String signature;
String assignedEmployeeName; String assignedEmployeeName;
Lookup status; Lookup status;
TimerModel timer;
DeviceTransferInfo({ DeviceTransferInfo({
this.userId, this.userId,
@ -23,12 +26,13 @@ class DeviceTransferInfo {
this.client, this.client,
this.userName, this.userName,
this.travelingHours, this.travelingHours,
this.startDate, // this.startDate,
this.endDate, // this.endDate,
this.workingHours, this.workingHours,
this.signature, this.signature,
this.status, this.status,
this.assignedEmployeeName this.assignedEmployeeName,
this.timer,
}); });
Map<String, String> toJson(bool isSender) { Map<String, String> toJson(bool isSender) {
@ -37,8 +41,10 @@ class DeviceTransferInfo {
if (comment != null && comment.isNotEmpty) body["${baseKey}comment"] = comment; if (comment != null && comment.isNotEmpty) body["${baseKey}comment"] = comment;
if (workingHours != null && workingHours.isNotEmpty) body["${baseKey}working_hours"] = workingHours; if (workingHours != null && workingHours.isNotEmpty) body["${baseKey}working_hours"] = workingHours;
if (startDate != null) body["${baseKey}start_date"] = startDate?.toIso8601String(); // if (startDate != null) body["${baseKey}start_date"] = startDate?.toIso8601String();
if (endDate != null) body["${baseKey}end_date"] = endDate?.toIso8601String(); // if (endDate != null) body["${baseKey}end_date"] = endDate?.toIso8601String();
if (timer?.startAt != null) body["${baseKey}start_date"] = timer?.startAt?.toIso8601String();
if (timer?.endAt != null) body["${baseKey}end_date"] = timer?.endAt?.toIso8601String();
if (travelingHours != null && travelingHours.isNotEmpty) body["${baseKey}travel_hours"] = travelingHours; if (travelingHours != null && travelingHours.isNotEmpty) body["${baseKey}travel_hours"] = travelingHours;
if (status != null) body["${baseKey}status"] = status.id.toString(); if (status != null) body["${baseKey}status"] = status.id.toString();
if (signature != null && signature.isNotEmpty) body["${baseKey}image"] = signature; if (signature != null && signature.isNotEmpty) body["${baseKey}image"] = signature;
@ -57,8 +63,9 @@ class DeviceTransferInfo {
client = Hospital.fromHospital(old.client); client = Hospital.fromHospital(old.client);
department = Department.fromDepartment(old.department); department = Department.fromDepartment(old.department);
workingHours = old.workingHours; workingHours = old.workingHours;
startDate = old.startDate; // startDate = old.startDate;
endDate = old.endDate; // endDate = old.endDate;
timer = old.timer;
travelingHours = old.travelingHours; travelingHours = old.travelingHours;
comment = old.comment; comment = old.comment;
if (withSignature) signature = old.signature; if (withSignature) signature = old.signature;
@ -68,14 +75,20 @@ class DeviceTransferInfo {
factory DeviceTransferInfo.fromJson(Map<String, dynamic> parsedJson, String key) { factory DeviceTransferInfo.fromJson(Map<String, dynamic> parsedJson, String key) {
return DeviceTransferInfo( return DeviceTransferInfo(
workingHours: parsedJson["${key}working_hours"], workingHours: parsedJson["${key}working_hours"],
startDate: parsedJson["${key}start_date"], // startDate: parsedJson["${key}start_date"],
endDate: parsedJson["${key}end_date"], // endDate: parsedJson["${key}end_date"],
timer: TimerModel(
startAt: DateTime.tryParse(parsedJson["${key}start_date"] ?? ""),
endAt: DateTime.tryParse(parsedJson["${key}end_date"] ?? ""),
durationInSecond: ((parsedJson["${key}working_hours"] ?? 0) * 60 * 60).toInt(),
stopped: parsedJson["${key}working_hours"] == null || (parsedJson["${key}working_hours"] as String).isEmpty ? null : true,
),
travelingHours: parsedJson["${key}travel_hours"], travelingHours: parsedJson["${key}travel_hours"],
userName: parsedJson["${key}name"], userName: parsedJson["${key}name"],
signature: parsedJson["${key}image"], signature: parsedJson["${key}image"],
userId: parsedJson["${key}id"], userId: parsedJson["${key}id"],
comment: parsedJson["${key}comment"], comment: parsedJson["${key}comment"],
assignedEmployeeName:parsedJson["${key}AssignedEmployeeName"], assignedEmployeeName: parsedJson["${key}AssignedEmployeeName"],
client: Hospital(id: parsedJson["${key}SiteId"], name: parsedJson["${key}SiteName"]), client: Hospital(id: parsedJson["${key}SiteId"], name: parsedJson["${key}SiteName"]),
department: Department( department: Department(
id: parsedJson["${key}DepartmentId"], id: parsedJson["${key}DepartmentId"],

@ -1,6 +1,9 @@
import 'dart:typed_data';
import 'package:test_sa/models/gas_refill/gas_refill_details.dart'; import 'package:test_sa/models/gas_refill/gas_refill_details.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import '../../controllers/api_routes/urls.dart';
import '../call_request_for_work_order_model.dart'; import '../call_request_for_work_order_model.dart';
class GasRefillModel { class GasRefillModel {
@ -14,6 +17,10 @@ class GasRefillModel {
Department department; Department department;
List<GasRefillDetails> details; List<GasRefillDetails> details;
AssignedEmployee assignedEmployee; AssignedEmployee assignedEmployee;
String signatureNurse;
String signatureEngineer;
Uint8List localNurseSignature;
Uint8List localEngineerSignature;
DateTime startDate, endDate, expectedDate; DateTime startDate, endDate, expectedDate;
GasRefillModel({ GasRefillModel({
@ -30,6 +37,10 @@ class GasRefillModel {
this.expectedDate, this.expectedDate,
this.department, this.department,
this.assignedEmployee, this.assignedEmployee,
this.signatureNurse,
this.signatureEngineer,
this.localEngineerSignature,
this.localNurseSignature,
}); });
bool validate() { bool validate() {
@ -58,6 +69,10 @@ class GasRefillModel {
endDate = model.endDate; endDate = model.endDate;
expectedDate = model.expectedDate; expectedDate = model.expectedDate;
assignedEmployee = model.assignedEmployee; assignedEmployee = model.assignedEmployee;
localEngineerSignature = model.localEngineerSignature;
localNurseSignature = model.localNurseSignature;
signatureEngineer = model.signatureEngineer;
signatureNurse = model.signatureNurse;
} }
factory GasRefillModel.fromJson(Map<String, dynamic> parsedJson) { factory GasRefillModel.fromJson(Map<String, dynamic> parsedJson) {
@ -80,6 +95,8 @@ class GasRefillModel {
endDate: DateTime.tryParse(parsedJson['endDate'] ?? ""), endDate: DateTime.tryParse(parsedJson['endDate'] ?? ""),
expectedDate: DateTime.tryParse(parsedJson['expectedDate'] ?? ""), expectedDate: DateTime.tryParse(parsedJson['expectedDate'] ?? ""),
assignedEmployee: AssignedEmployee.fromJson(parsedJson['assignedEmployee'] ?? {}), assignedEmployee: AssignedEmployee.fromJson(parsedJson['assignedEmployee'] ?? {}),
signatureEngineer: URLs.getFileUrl(parsedJson["engSignature"]),
signatureNurse: URLs.getFileUrl(parsedJson["nurseSignature"]),
); );
} }
} }

@ -58,7 +58,7 @@ class Pentry {
Map<String, dynamic> toMap(int visitId) { Map<String, dynamic> toMap(int visitId) {
Map<String, dynamic> map = {}; Map<String, dynamic> map = {};
map["visitStatusId"] = ppmVisitStatus?.id.toString(); map["visitStatusId"] = ppmVisitStatus?.id.toString();
//if(status != null) map["visitStatusId"] = status?.id.toString(); if (status != null) map["deviceStatusId"] = status?.id.toString();
if (travelingHours != null) map["travelingHours"] = travelingHours; if (travelingHours != null) map["travelingHours"] = travelingHours;
//if(imageFile != null) map["file_attachement"] = base64Encode(imageFile.readAsBytesSync()); //if(imageFile != null) map["file_attachement"] = base64Encode(imageFile.readAsBytesSync());
map["actualDate"] = actualVisitDate.toIso8601String(); map["actualDate"] = actualVisitDate.toIso8601String();
@ -73,7 +73,7 @@ class Pentry {
{"attachmentName": (imageFile.path.split("/").last + base64Encode(imageFile.readAsBytesSync()))} {"attachmentName": (imageFile.path.split("/").last + base64Encode(imageFile.readAsBytesSync()))}
]; ];
} }
map["travelingHours"] = travelingHours;
// if(contacts?.isNotEmpty == true) { // if(contacts?.isNotEmpty == true) {
// for(int i = 0;i<contacts.length;i++){ // for(int i = 0;i<contacts.length;i++){
// contacts[i].toMap().forEach((key, value) { // contacts[i].toMap().forEach((key, value) {
@ -117,7 +117,12 @@ class Pentry {
actualVisitDate: DateTime.tryParse(map["actualDate"] ?? ""), actualVisitDate: DateTime.tryParse(map["actualDate"] ?? ""),
expectedVisitDate: DateTime.tryParse(map["expectedDate"] ?? ""), expectedVisitDate: DateTime.tryParse(map["expectedDate"] ?? ""),
travelingHours: map["travelingHours"], travelingHours: map["travelingHours"],
timer: TimerModel(startAt: DateTime.tryParse(map["startDate"] ?? ""), endAt: DateTime.tryParse(map["endDate"] ?? ""), durationInSecond: (int.tryParse(map["workingHours"] ?? "") ?? 0) * 60 * 60), timer: TimerModel(
startAt: DateTime.tryParse(map["startDate"] ?? ""),
endAt: DateTime.tryParse(map["endDate"] ?? ""),
durationInSecond: (int.tryParse(map["workingHours"] ?? "") ?? 0) * 60 * 60,
stopped: map["workingHours"] == null ? null : true,
),
// contacts: contacts, // contacts: contacts,
ppmCheckLists: ppmCheckLists, ppmCheckLists: ppmCheckLists,
calibrationTools: calibrationTools, calibrationTools: calibrationTools,

@ -1,5 +1,6 @@
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/device/device.dart'; import 'package:test_sa/models/device/device.dart';
import 'package:test_sa/models/engineer.dart'; import 'package:test_sa/models/engineer.dart';
@ -13,10 +14,11 @@ class ServiceReport {
int id; int id;
double operatingHours; double operatingHours;
DateTime visitDate; DateTime visitDate;
DateTime endDate; // DateTime endDate;
DateTime startDate; // DateTime startDate;
Lookup assetType; Lookup assetType;
Lookup callLastSituation; Lookup callLastSituation;
Lookup currentSituation;
Lookup repairLocation; Lookup repairLocation;
Engineer engineer; Engineer engineer;
Lookup equipmentStatus; Lookup equipmentStatus;
@ -25,7 +27,7 @@ class ServiceReport {
int faultDescriptionId; int faultDescriptionId;
String workPreformed; String workPreformed;
//String workHours; num workingHours;
double travelingHours; double travelingHours;
String invoiceNumber; String invoiceNumber;
String invoiceCode; String invoiceCode;
@ -40,19 +42,19 @@ class ServiceReport {
String comment; String comment;
Uint8List localNurseSignature; Uint8List localNurseSignature;
Uint8List localEngineerSignature; Uint8List localEngineerSignature;
int travelingExpense; num travelingExpense;
String reviewComment; String reviewComment;
FaultDescription faultDescription; FaultDescription faultDescription;
ServiceReport( ServiceReport({
{this.id, this.id,
this.visitDate, this.visitDate,
this.endDate, // this.endDate,
this.assetType, this.assetType,
this.equipmentStatus, this.equipmentStatus,
this.type, this.type,
this.faultDescriptionId, this.faultDescriptionId,
//this.workHours, this.workingHours,
this.travelingHours, this.travelingHours,
this.parts, this.parts,
this.engineer, this.engineer,
@ -60,6 +62,7 @@ class ServiceReport {
this.reason, this.reason,
this.operatingHours, this.operatingHours,
this.callLastSituation, this.callLastSituation,
this.currentSituation,
this.jobSheetNumber, this.jobSheetNumber,
this.image, this.image,
this.device, this.device,
@ -74,16 +77,17 @@ class ServiceReport {
this.comment, this.comment,
this.repairLocation, this.repairLocation,
this.travelingExpense, this.travelingExpense,
this.startDate, // this.startDate,
this.reviewComment, this.reviewComment,
this.faultDescription}); this.faultDescription,
});
Map<String, dynamic> toMap(ServiceRequest request) { Map<String, dynamic> toMap(ServiceRequest request) {
Map<String, dynamic> _map = {}; Map<String, dynamic> _map = {};
if (id != null) _map["id"] = id; if (id != null) _map["id"] = id;
if (visitDate != null) _map["visitDate"] = visitDate.toIso8601String(); if (visitDate != null) _map["visitDate"] = visitDate.toIso8601String();
//if(serviceType != null) _map["service_type"] = serviceType.id.toString(); //if(serviceType != null) _map["service_type"] = serviceType.id.toString();
if (equipmentStatus != null) _map["status"] = equipmentStatus?.toMap(); if (equipmentStatus != null) _map["equipmentStatus"] = equipmentStatus?.toMap();
if (type != null) _map["typeOfWO"] = type?.toMap(); if (type != null) _map["typeOfWO"] = type?.toMap();
if (assetType != null) _map["TypeOfWO"] = assetType?.toMap(); if (assetType != null) _map["TypeOfWO"] = assetType?.toMap();
//if(faultDescriptionId != null && faultDescriptionId.isNotEmpty) _map["fault_description"] = faultDescriptionId; //if(faultDescriptionId != null && faultDescriptionId.isNotEmpty) _map["fault_description"] = faultDescriptionId;
@ -93,17 +97,19 @@ class ServiceReport {
_map["endofWorkTime"] = (timer.endAt ?? DateTime.now()).toIso8601String(); _map["endofWorkTime"] = (timer.endAt ?? DateTime.now()).toIso8601String();
_map["workingHours"] = (timer.durationInSecond / 60 / 60).toStringAsFixed(5); _map["workingHours"] = (timer.durationInSecond / 60 / 60).toStringAsFixed(5);
} }
if (travelingHours != null && travelingHours.toString().isNotEmpty) _map["traveling_hours"] = travelingHours; if (travelingHours != null && travelingHours.toString().isNotEmpty) _map["travelingHours"] = travelingHours;
// if(workPreformed != null && workPreformed.isNotEmpty){ // if(workPreformed != null && workPreformed.isNotEmpty){
// _map["faultDescription"] = { // _map["faultDescription"] = {
// //"id":faultDescriptionId ?? 0, // "id":faultDescriptionId ?? 0,
// "workPerformed":workPreformed // "workPerformed":workPreformed
// }; // };
// } // }
if (travelingHours != null) _map["traveling_hours"] = travelingHours; _map["faultDescription"] = {"id": faultDescription?.id ?? 0, "workPerformed": faultDescription?.workPerformed};
if (workPreformed != null && workPreformed.isNotEmpty) { if (travelingHours != null) _map["travelingHours"] = travelingHours;
_map["faultDescription"] = faultDescription.toJson(); // if (workingHours != null) _map["workingHours"] = workingHours;
} // if (workPreformed != null && workPreformed.isNotEmpty) {
// _map["faultDescription"] = faultDescription.toJson();
// }
if (jobSheetNumber != null && jobSheetNumber.isNotEmpty) _map["job_sheet_no"] = jobSheetNumber; if (jobSheetNumber != null && jobSheetNumber.isNotEmpty) _map["job_sheet_no"] = jobSheetNumber;
if (parts != null && parts.isNotEmpty) { if (parts != null && parts.isNotEmpty) {
_map["sparePartsWorkOrders"] = parts.map((e) => e.toJson()).toList(); _map["sparePartsWorkOrders"] = parts.map((e) => e.toJson()).toList();
@ -122,6 +128,7 @@ class ServiceReport {
if (reason != null) _map["reason"] = reason.toMap(); if (reason != null) _map["reason"] = reason.toMap();
//if(operatingHours != null && operatingHours.isNotEmpty) _map["operation_hours"] = operatingHours; //if(operatingHours != null && operatingHours.isNotEmpty) _map["operation_hours"] = operatingHours;
if (callLastSituation != null) _map["calllastSituation"] = callLastSituation.toMap(); if (callLastSituation != null) _map["calllastSituation"] = callLastSituation.toMap();
if (currentSituation != null) _map["currentSituation"] = currentSituation.toMap();
//if(image != null) _map["image"] = image; //if(image != null) _map["image"] = image;
//if(invoiceCode != null) _map["invoice_no"] = invoiceCode; //if(invoiceCode != null) _map["invoice_no"] = invoiceCode;
//if(invoiceNumber != null) _map["invoice_code"] = invoiceNumber; //if(invoiceNumber != null) _map["invoice_code"] = invoiceNumber;
@ -133,16 +140,27 @@ class ServiceReport {
_map["nurseSignature"] = signatureNurse; _map["nurseSignature"] = signatureNurse;
_map["engSignature"] = signatureEngineer; _map["engSignature"] = signatureEngineer;
_map["comment"] = comment; _map["comment"] = comment;
_map["travelingExpense"] = travelingExpense; _map["travelingExpenses"] = travelingExpense;
_map["startofWorkTime"] = startDate; // _map["startofWorkTime"] = startDate.toIso8601String();
_map["endofWorkTime"] = endDate; // _map["endofWorkTime"] = endDate.toIso8601String();
_map["workingHours"] = endDate?.difference(startDate)?.inHours ?? 0; // _map["workingHours"] = endDate?.difference(startDate)?.inHours ?? 0;
if (timer?.startAt != null) _map["startofWorkTime"] = timer?.startAt?.toIso8601String();
if (timer?.endAt != null) _map["endofWorkTime"] = timer?.endAt?.toIso8601String();
_map["workingHours"] = workingHours;
_map["reviewComment"] = reviewComment; _map["reviewComment"] = reviewComment;
return _map; return _map;
} }
bool validate() { Future<bool> validate() async {
if (visitDate == null) return false; print("visitDate:$visitDate");
print("equipmentStatus:${equipmentStatus?.toMap()}");
print("callLastSituation:${callLastSituation?.toMap()}");
print("parts:$parts");
print("reason:${reason?.toMap()}");
if (visitDate == null) {
await Fluttertoast.showToast(msg: "Visit Date Required");
return false;
}
//if(serviceType == null) return false; //if(serviceType == null) return false;
if (equipmentStatus == null) return false; if (equipmentStatus == null) return false;
//if (type == null && assetType == null) return false; //if (type == null && assetType == null) return false;
@ -174,27 +192,38 @@ class ServiceReport {
id: id, id: id,
assetType: Lookup.fromJson(parsedJson["assetType"]), assetType: Lookup.fromJson(parsedJson["assetType"]),
callLastSituation: Lookup.fromJson(parsedJson["calllastSituation"]), callLastSituation: Lookup.fromJson(parsedJson["calllastSituation"]),
currentSituation: Lookup.fromJson(parsedJson["currentSituation"]),
repairLocation: Lookup.fromJson(parsedJson["repairLocation"]),
reason: Lookup.fromJson(parsedJson["reason"]), reason: Lookup.fromJson(parsedJson["reason"]),
equipmentStatus: Lookup.fromJson(parsedJson["status"]), equipmentStatus: Lookup.fromJson(parsedJson["equipmentStatus"]),
type: Lookup.fromJson(parsedJson["typeOfWO"]), type: Lookup.fromJson(parsedJson["typeOfWO"]),
faultDescriptionId: parsedJson["fault_description"], faultDescription: parsedJson['faultDescription'] != null ? FaultDescription.fromJson(parsedJson['faultDescription']) : null,
endDate: DateTime.tryParse(parsedJson["endofWorkTime"]),
// faultDescription: parsedJson["faultDescription"],
// startDate: DateTime.tryParse(parsedJson["startofWorkTime"] ?? ""),
// endDate: DateTime.tryParse(parsedJson["endofWorkTime"] ?? ""),
//invoiceCode: parsedJson["invoice_code"], //invoiceCode: parsedJson["invoice_code"],
//invoiceNumber: parsedJson["invoice_no"], //invoiceNumber: parsedJson["invoice_no"],
//jobSheetNumber: parsedJson["job_sheet_no"], //jobSheetNumber: parsedJson["job_sheet_no"],
operatingHours: parsedJson["workingHours"], // workingHours: parsedJson["workingHours"],
engineer: Engineer.fromJson(parsedJson["assignedEmployee"]), engineer: Engineer.fromJson(parsedJson["assignedEmployee"]),
parts: _parts, parts: _parts,
//quantity: parsedJson["nid"], //quantity: parsedJson["nid"],
travelingHours: parsedJson["traveling_hours"], travelingHours: parsedJson["travelingHours"],
travelingExpense: parsedJson["travelingExpenses"],
visitDate: DateTime.tryParse(parsedJson["visitDate"]), visitDate: DateTime.tryParse(parsedJson["visitDate"]),
//workHours: parsedJson["working_hours"], workingHours: parsedJson["workingHours"],
timer: TimerModel( timer: TimerModel(
startAt: DateTime.tryParse(parsedJson["startofWorkTime"]), endAt: DateTime.tryParse(parsedJson["endofWorkTime"]), durationInSecond: ((parsedJson["workingHours"] ?? 0) * 60 * 60).toInt()), startAt: DateTime.tryParse(parsedJson["startofWorkTime"] ?? ""),
endAt: DateTime.tryParse(parsedJson["endofWorkTime"] ?? ""),
durationInSecond: ((parsedJson["workingHours"] ?? 0) * 60 * 60).toInt(),
stopped: parsedJson["workingHours"] == null ? null : true,
),
//workPreformed: parsedJson["work_performed"], //workPreformed: parsedJson["work_performed"],
device: Device.fromJson(parsedJson["callRequest"]["asset"]), device: Device.fromJson(parsedJson["callRequest"]["asset"]),
signatureNurse: URLs.getFileUrl(parsedJson["nurseSignature"]), signatureNurse: URLs.getFileUrl(parsedJson["nurseSignature"]),
signatureEngineer: URLs.getFileUrl(parsedJson["engSignature"]), signatureEngineer: URLs.getFileUrl(parsedJson["engSignature"]),
comment: parsedJson['comment'],
reviewComment: parsedJson['reviewComment'], reviewComment: parsedJson['reviewComment'],
); );
} }

@ -1,4 +1,5 @@
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/timer_model.dart';
import '../fault_description.dart'; import '../fault_description.dart';
@ -21,8 +22,8 @@ class SearchWorkOrder {
this.currentSituation, this.currentSituation,
this.repairLocation, this.repairLocation,
this.reason, this.reason,
this.startofWorkTime, // this.startofWorkTime,
this.endofWorkTime, // this.endofWorkTime,
this.workingHours, this.workingHours,
this.travelingHours, this.travelingHours,
this.travelingExpenses, this.travelingExpenses,
@ -36,6 +37,7 @@ class SearchWorkOrder {
this.engSignature, this.engSignature,
this.nurseSignature, this.nurseSignature,
this.woParentDto, this.woParentDto,
this.timer,
}); });
SearchWorkOrder.fromJson(dynamic json) { SearchWorkOrder.fromJson(dynamic json) {
@ -66,8 +68,13 @@ class SearchWorkOrder {
currentSituation = json['currentSituation'] != null ? Lookup.fromJson(json['currentSituation']) : null; currentSituation = json['currentSituation'] != null ? Lookup.fromJson(json['currentSituation']) : null;
repairLocation = json['repairLocation'] != null ? Lookup.fromJson(json['repairLocation']) : null; repairLocation = json['repairLocation'] != null ? Lookup.fromJson(json['repairLocation']) : null;
reason = json['reason'] != null ? Lookup.fromJson(json['reason']) : null; reason = json['reason'] != null ? Lookup.fromJson(json['reason']) : null;
startofWorkTime = json['startofWorkTime']; // startofWorkTime = json['startofWorkTime'];
endofWorkTime = json['endofWorkTime']; // endofWorkTime = json['endofWorkTime'];
if (json['startofWorkTime'] != null || json['endofWorkTime'] != null) {
timer = TimerModel();
}
if (json['startofWorkTime'] != null) timer.startAt = DateTime.tryParse(json['startofWorkTime']);
if (json['endofWorkTime'] != null) timer.endAt = DateTime.tryParse(json['endofWorkTime']);
workingHours = json['workingHours']; workingHours = json['workingHours'];
travelingHours = json['travelingHours']; travelingHours = json['travelingHours'];
travelingExpenses = json['travelingExpenses']; travelingExpenses = json['travelingExpenses'];
@ -104,29 +111,36 @@ class SearchWorkOrder {
workOrderYear = wo.workOrderYear ?? workOrderYear; workOrderYear = wo.workOrderYear ?? workOrderYear;
workOrderSequennce = wo.workOrderSequennce ?? workOrderSequennce; workOrderSequennce = wo.workOrderSequennce ?? workOrderSequennce;
callRequest = wo.callRequest ?? callRequest; callRequest = wo.callRequest ?? callRequest;
assetType = wo.assetType ?? assetType; if (wo.assetType != null) assetType = Lookup.fromJson((wo.assetType)?.toMap() ?? {});
assignedEmployee = wo.assignedEmployee ?? assignedEmployee; if (wo.assignedEmployee != null) assignedEmployee = AssignedEmployee.fromJson((wo.assignedEmployee)?.toJson() ?? {});
visitDate = wo.visitDate ?? visitDate; visitDate = wo.visitDate ?? visitDate;
assistantEmployees = wo.assistantEmployees ?? assistantEmployees; assistantEmployees = (wo.assistantEmployees ?? assistantEmployees)
supplier = wo.supplier ?? supplier; ?.map((e) => AssistantEmployees.fromJson({
"id": e?.id,
"user": {"name": e?.user?.name, "id": (e?.user?.id) ?? "0"}
}))
?.toList() ??
[];
if (wo.supplier != null) supplier = SupplierModel.fromJson((wo.supplier)?.toJson() ?? {});
vendorTicketNumber = wo.vendorTicketNumber ?? vendorTicketNumber; vendorTicketNumber = wo.vendorTicketNumber ?? vendorTicketNumber;
contactPersonWorkOrders = wo.contactPersonWorkOrders ?? contactPersonWorkOrders; contactPersonWorkOrders = (wo.contactPersonWorkOrders ?? contactPersonWorkOrders)?.map((e) => ContactPersonWorkOrders.fromJson(e?.toJson() ?? {}))?.toList() ?? [];
calllastSituation = wo.calllastSituation ?? calllastSituation; calllastSituation = Lookup.fromJson((wo.calllastSituation ?? calllastSituation)?.toMap() ?? {});
currentSituation = wo.currentSituation ?? currentSituation; if (wo.currentSituation != null) currentSituation = Lookup.fromJson((wo.currentSituation)?.toMap() ?? {});
repairLocation = wo.repairLocation ?? repairLocation; repairLocation = Lookup.fromJson((wo.repairLocation ?? repairLocation)?.toMap() ?? {});
reason = wo.reason ?? reason; reason = Lookup.fromJson((wo.reason ?? reason)?.toMap() ?? {});
startofWorkTime = wo.startofWorkTime ?? startofWorkTime; // startofWorkTime = wo.startofWorkTime ?? startofWorkTime;
endofWorkTime = wo.endofWorkTime ?? endofWorkTime; // endofWorkTime = wo.endofWorkTime ?? endofWorkTime;
timer = wo.timer ?? timer;
workingHours = wo.workingHours ?? workingHours; workingHours = wo.workingHours ?? workingHours;
travelingHours = wo.travelingHours ?? travelingHours; travelingHours = wo.travelingHours ?? travelingHours;
travelingExpenses = wo.travelingExpenses ?? travelingExpenses; travelingExpenses = wo.travelingExpenses ?? travelingExpenses;
faultDescription = wo.faultDescription ?? faultDescription; faultDescription = FaultDescription.fromJson((wo.faultDescription ?? faultDescription)?.toJson() ?? {});
sparePartsWorkOrders = wo.sparePartsWorkOrders ?? sparePartsWorkOrders; sparePartsWorkOrders = (wo.sparePartsWorkOrders ?? sparePartsWorkOrders)?.map((e) => SparePartsWorkOrders.fromJson(e?.toJson() ?? {}))?.toList() ?? [];
reviewComment = wo.reviewComment ?? reviewComment; reviewComment = wo.reviewComment ?? reviewComment;
comment = wo.comment ?? comment; comment = wo.comment ?? comment;
attachmentsWorkOrder = wo.attachmentsWorkOrder ?? attachmentsWorkOrder; attachmentsWorkOrder = (wo.attachmentsWorkOrder ?? attachmentsWorkOrder)?.map((e) => AttachmentsWorkOrder.fromJson(e?.toJson() ?? {}))?.toList() ?? [];
equipmentStatus = wo.equipmentStatus ?? equipmentStatus; equipmentStatus = Lookup.fromJson((wo.equipmentStatus ?? equipmentStatus)?.toMap() ?? {});
suppEngineerWorkOrders = wo.suppEngineerWorkOrders ?? suppEngineerWorkOrders; suppEngineerWorkOrders = (wo.suppEngineerWorkOrders ?? suppEngineerWorkOrders)?.map((e) => SuppEngineerWorkOrders.fromJson(e?.toJson() ?? {}))?.toList() ?? [];
engSignature = wo.engSignature ?? engSignature; engSignature = wo.engSignature ?? engSignature;
nurseSignature = wo.nurseSignature ?? nurseSignature; nurseSignature = wo.nurseSignature ?? nurseSignature;
woParentDto = wo.woParentDto ?? woParentDto; woParentDto = wo.woParentDto ?? woParentDto;
@ -149,8 +163,8 @@ class SearchWorkOrder {
Lookup currentSituation; Lookup currentSituation;
Lookup repairLocation; Lookup repairLocation;
Lookup reason; Lookup reason;
String startofWorkTime; // String startofWorkTime;
String endofWorkTime; // String endofWorkTime;
num workingHours; num workingHours;
num travelingHours; num travelingHours;
num travelingExpenses; num travelingExpenses;
@ -164,6 +178,8 @@ class SearchWorkOrder {
String engSignature; String engSignature;
String nurseSignature; String nurseSignature;
WoParentDto woParentDto; WoParentDto woParentDto;
TimerModel timer;
SearchWorkOrder copyWith({ SearchWorkOrder copyWith({
num id, num id,
num parentWOId, num parentWOId,
@ -182,8 +198,8 @@ class SearchWorkOrder {
Lookup currentSituation, Lookup currentSituation,
Lookup repairLocation, Lookup repairLocation,
Lookup reason, Lookup reason,
String startofWorkTime, // String startofWorkTime,
String endofWorkTime, // String endofWorkTime,
num workingHours, num workingHours,
num travelingHours, num travelingHours,
num travelingExpenses, num travelingExpenses,
@ -197,6 +213,7 @@ class SearchWorkOrder {
String engSignature, String engSignature,
String nurseSignature, String nurseSignature,
WoParentDto woParentDto, WoParentDto woParentDto,
TimerModel timer,
}) => }) =>
SearchWorkOrder( SearchWorkOrder(
id: id ?? this.id, id: id ?? this.id,
@ -216,8 +233,8 @@ class SearchWorkOrder {
currentSituation: currentSituation ?? this.currentSituation, currentSituation: currentSituation ?? this.currentSituation,
repairLocation: repairLocation ?? this.repairLocation, repairLocation: repairLocation ?? this.repairLocation,
reason: reason ?? this.reason, reason: reason ?? this.reason,
startofWorkTime: startofWorkTime ?? this.startofWorkTime, // startofWorkTime: startofWorkTime ?? this.startofWorkTime,
endofWorkTime: endofWorkTime ?? this.endofWorkTime, // endofWorkTime: endofWorkTime ?? this.endofWorkTime,
workingHours: workingHours ?? this.workingHours, workingHours: workingHours ?? this.workingHours,
travelingHours: travelingHours ?? this.travelingHours, travelingHours: travelingHours ?? this.travelingHours,
travelingExpenses: travelingExpenses ?? this.travelingExpenses, travelingExpenses: travelingExpenses ?? this.travelingExpenses,
@ -231,6 +248,7 @@ class SearchWorkOrder {
engSignature: engSignature ?? this.engSignature, engSignature: engSignature ?? this.engSignature,
nurseSignature: nurseSignature ?? this.nurseSignature, nurseSignature: nurseSignature ?? this.nurseSignature,
woParentDto: woParentDto ?? this.woParentDto, woParentDto: woParentDto ?? this.woParentDto,
timer: timer ?? this.timer,
); );
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final map = <String, dynamic>{}; final map = <String, dynamic>{};
@ -262,21 +280,22 @@ class SearchWorkOrder {
if (calllastSituation != null) { if (calllastSituation != null) {
map['calllastSituation'] = calllastSituation.toMap(); map['calllastSituation'] = calllastSituation.toMap();
} }
if (currentSituation != null) { map['currentSituation'] = currentSituation?.toMap();
map['currentSituation'] = currentSituation.toMap(); if (repairLocation?.id != null) {
}
if (repairLocation != null) {
map['repairLocation'] = repairLocation.toMap(); map['repairLocation'] = repairLocation.toMap();
} }
if (reason != null) { if (reason != null) {
map['reason'] = reason.toMap(); map['reason'] = reason.toMap();
} }
map['startofWorkTime'] = startofWorkTime; // map['startofWorkTime'] = startofWorkTime;
map['endofWorkTime'] = endofWorkTime; // map['endofWorkTime'] = endofWorkTime;
map['startofWorkTime'] = timer?.startAt?.toIso8601String();
map['endofWorkTime'] = timer?.endAt?.toIso8601String();
map['workingHours'] = workingHours; map['workingHours'] = workingHours;
map['travelingHours'] = travelingHours; map['travelingHours'] = travelingHours;
map['travelingExpenses'] = travelingExpenses; map['travelingExpenses'] = travelingExpenses;
if (faultDescription != null) {
if (faultDescription?.id != null) {
map['faultDescription'] = faultDescription.toJson(); map['faultDescription'] = faultDescription.toJson();
} }
if (sparePartsWorkOrders != null) { if (sparePartsWorkOrders != null) {
@ -1722,11 +1741,8 @@ class Asset {
if (modelDefinition != null) { if (modelDefinition != null) {
map['modelDefinition'] = modelDefinition.toJson(); map['modelDefinition'] = modelDefinition.toJson();
} }
if (supplier != null) { map['supplier'] = supplier?.toJson();
map['supplier'] = supplier.toJson();
} else {
map['supplier'] = [];
}
map['ipAddress'] = ipAddress; map['ipAddress'] = ipAddress;
map['macAddress'] = macAddress; map['macAddress'] = macAddress;
map['portNumber'] = portNumber; map['portNumber'] = portNumber;
@ -1742,11 +1758,12 @@ class Asset {
if (parentAsset != null) { if (parentAsset != null) {
map['parentAsset'] = parentAsset.toJson(); map['parentAsset'] = parentAsset.toJson();
} }
if (assetType != null) {
map['assetType'] = assetType.toMap(); map['assetType'] = assetType?.toMap();
} else { print("supplier : ${supplier?.toJson()}");
map['assetType'] = []; print("supplier 2 : ${map['supplier']}");
} print("asset type : ${assetType?.toMap()}");
print("asset type 2: ${map['assetType']}");
if (site != null) { if (site != null) {
map['site'] = site.toJson(); map['site'] = site.toJson();
} }

@ -15,6 +15,7 @@ class ServiceRequest {
int hospitalId; int hospitalId;
String departmentName; String departmentName;
String engineerName; String engineerName;
String engineerId;
String date; String date;
String audio; String audio;
int statusValue; int statusValue;
@ -57,6 +58,7 @@ class ServiceRequest {
this.deviceId, this.deviceId,
this.audio, this.audio,
this.engineerName, this.engineerName,
this.engineerId,
this.viewReport = false, this.viewReport = false,
this.deviceModel, this.deviceModel,
this.engineerMobile, this.engineerMobile,
@ -102,6 +104,7 @@ class ServiceRequest {
statusValue: parsedJson["status"] == null ? null : parsedJson["status"]["value"], statusValue: parsedJson["status"] == null ? null : parsedJson["status"]["value"],
departmentName: parsedJson["asset"]["department"] != null ? parsedJson["asset"]["department"]["name"] : "", departmentName: parsedJson["asset"]["department"] != null ? parsedJson["asset"]["department"]["name"] : "",
engineerName: parsedJson["assignedEmployee"] == null ? null : parsedJson["assignedEmployee"]["name"], engineerName: parsedJson["assignedEmployee"] == null ? null : parsedJson["assignedEmployee"]["name"],
engineerId: parsedJson["assignedEmployee"] == null ? null : parsedJson["assignedEmployee"]["id"],
hospitalId: parsedJson["asset"]["site"]["id"], hospitalId: parsedJson["asset"]["site"]["id"],
reportID: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["workOrderId"] : null, reportID: parsedJson["workOrder"] != null ? parsedJson["workOrder"]["workOrderId"] : null,
viewReport: parsedJson["workOrder"] != null, viewReport: parsedJson["workOrder"] != null,

@ -2,6 +2,7 @@ class TimerModel {
DateTime startAt; DateTime startAt;
DateTime endAt; DateTime endAt;
int durationInSecond; int durationInSecond;
bool stopped;
TimerModel({this.startAt, this.endAt, this.durationInSecond}); TimerModel({this.startAt, this.endAt, this.durationInSecond, this.stopped});
} }

@ -86,11 +86,15 @@ class _DeviceTransferDetailsState extends State<DeviceTransferDetails> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
RequestInfoRow( RequestInfoRow(
title: _subtitle.title, title: "Id",
info: widget.model.id?.toString(),
),
RequestInfoRow(
title: _subtitle.assetName,
info: widget.model.title, info: widget.model.title,
), ),
RequestInfoRow( RequestInfoRow(
title: _subtitle.device, title: _subtitle.assetSN,
info: widget.model.device.serialNumber, info: widget.model.device.serialNumber,
), ),
RequestInfoRow( RequestInfoRow(

@ -19,8 +19,7 @@ import 'package:test_sa/views/widgets/status/gas_refill/gas_status.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/localization/localization.dart'; import '../../../../controllers/localization/localization.dart';
import '../../../controllers/validator/validator.dart'; import '../../widgets/timer/app_timer.dart';
import '../../widgets/date_and_time/time_picker.dart';
class UpdateDeviceTransfer extends StatefulWidget { class UpdateDeviceTransfer extends StatefulWidget {
final DeviceTransfer model; final DeviceTransfer model;
@ -46,6 +45,13 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
_update() async { _update() async {
if (_formModel?.workingHours == null || _formModel.workingHours.isEmpty) {
await Fluttertoast.showToast(msg: "Working Hours Timer Isn't Started");
return;
} else if ((_formModel?.timer?.stopped ?? false) == false) {
await Fluttertoast.showToast(msg: "Stop The Timer");
return;
}
_validate = true; _validate = true;
if (!_formKey.currentState.validate()) { if (!_formKey.currentState.validate()) {
setState(() {}); setState(() {});
@ -152,96 +158,23 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
const SizedBox( const SizedBox(
height: 16, height: 16,
), ),
ASubTitle(_subtitle.workingHours),
const SizedBox(height: 8),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: Column( child: AppTimer(
crossAxisAlignment: CrossAxisAlignment.stretch, timer: _formModel.timer,
children: [ onChange: (timer) async {
const ASubTitle("Start of Work"), _formModel.timer = timer;
SizedBox( _formModel.workingHours = (((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0";
height: 8 * AppStyle.getScaleFactor(context), return true;
),
ADateTimePicker(
date: _formModel.startDate,
from: DateTime.now().subtract(const Duration(days: 365)),
to: DateTime.now().add(const Duration(days: 365)),
onDateTimePicker: (date) {
_formModel.startDate = date;
_formModel.workingHours = ((_formModel.endDate?.difference(_formModel.startDate)?.inMinutes ?? 0) / 60)?.toStringAsFixed(2)?.toString() ?? 0;
setState(() {});
},
),
],
),
),
const SizedBox(width: 8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const ASubTitle("End of Work"),
SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
),
ADateTimePicker(
date: _formModel.endDate,
from: DateTime.now().subtract(const Duration(days: 365)),
to: DateTime.now().add(const Duration(days: 365)),
onDateTimePicker: (date) {
_formModel.endDate = date;
_formModel.workingHours = ((_formModel.endDate?.difference(_formModel.startDate)?.inMinutes ?? 0) / 60)?.toStringAsFixed(2)?.toString() ?? 0;
setState(() {});
}, },
), ),
],
),
), ),
], ],
), ),
const SizedBox(height: 4), const SizedBox(height: 16),
ASubTitle(_subtitle.workingHours),
const SizedBox(height: 4),
ATextFormField(
initialValue: null,
textAlign: TextAlign.center,
hintText: _formModel.startDate == null ? "0" : ((_formModel.endDate?.difference(_formModel.startDate)?.inMinutes ?? 0) / 60)?.toStringAsFixed(2)?.toString() ?? "0",
enable: false,
style: Theme.of(context).textTheme.subtitle1,
//validator: (value) => Validator.isNumeric(value) ? null : _subtitle.requiredWord,
textInputType: TextInputType.number,
onSaved: (value) {
// _serviceReport.workHours = value;
},
),
// ASubTitle(_subtitle.workingHours),
// const SizedBox(
// height: 4,
// ),
// ATextFormField(
// initialValue: _formModel?.workingHours,
// textAlign: TextAlign.center,
// style: Theme.of(context).textTheme.subtitle1,
// textInputType: TextInputType.number,
// onSaved: (value) {
// _formModel.workingHours = value;
// },
// ),
// const SizedBox(height: 8,),
// const ASubTitle("Sender Department"),
// if(_validate && _formModel.senderDepartment == null)
// ASubTitle(_subtitle.requiredWord,color: Colors.red,),
// const SizedBox(height: 4,),
// DepartmentButton(
// department: _formModel.senderDepartment,
// onDepartmentPick: (department){
// _formModel.senderDepartment = department;
// setState(() {});
// },
// ),
const SizedBox(
height: 8,
),
ASubTitle(_subtitle.status), ASubTitle(_subtitle.status),
const SizedBox( const SizedBox(
height: 4, height: 4,
@ -249,6 +182,7 @@ class _UpdateDeviceTransferState extends State<UpdateDeviceTransfer> {
GasStatusMenu( GasStatusMenu(
initialValue: _formModel.status, initialValue: _formModel.status,
onSelect: (status) { onSelect: (status) {
if (status == null) return;
_formModel.status = status; _formModel.status = status;
setState(() {}); setState(() {});
}, },

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.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';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
@ -114,9 +115,16 @@ class _LoginState extends State<Login> {
host: _settingProvider.host, host: _settingProvider.host,
); );
if (status >= 200 && status < 300) { if (status >= 200 && status < 300) {
if(_userProvider.user.isAuthenticated ?? false) {
_settingProvider.setUser(_userProvider.user); _settingProvider.setUser(_userProvider.user);
// if (_userProvider.user.isActive)
Navigator.of(context).pushNamed(LandPage.id); Navigator.of(context).pushNamed(LandPage.id);
} else {
Fluttertoast.showToast(msg: _userProvider.user.message);
}
// if (_userProvider.user.isActive)
// else // else
// Fluttertoast.showToast(msg: _subtitle.activationAlert); // Fluttertoast.showToast(msg: _subtitle.activationAlert);
} else { } else {

@ -6,6 +6,9 @@ import 'package:flutter/material.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/providers/api/service_requests_provider.dart'; import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_types_provider.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/call_request_for_work_order_model.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/service_report.dart'; import 'package:test_sa/models/service_report.dart';
import 'package:test_sa/models/service_request/search_work_order.dart'; import 'package:test_sa/models/service_request/search_work_order.dart';
@ -13,16 +16,18 @@ import 'package:test_sa/views/app_style/colors.dart';
import 'package:test_sa/views/pages/sub_workorder/spare_parts_details_bottom_sheet.dart'; import 'package:test_sa/views/pages/sub_workorder/spare_parts_details_bottom_sheet.dart';
import 'package:test_sa/views/pages/sub_workorder/work_order_details_bottom_sheet.dart'; import 'package:test_sa/views/pages/sub_workorder/work_order_details_bottom_sheet.dart';
import 'package:test_sa/views/pages/sub_workorder/workorder_details.dart'; import 'package:test_sa/views/pages/sub_workorder/workorder_details.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/status/service_request/service_request_defect_types_mune.dart';
import '../../../controllers/api_routes/http_status_manger.dart'; import '../../../controllers/api_routes/http_status_manger.dart';
import '../../../controllers/localization/localization.dart'; import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/status_drop_down/report/service_report_fault_description_provider.dart';
import '../../../models/subtitle.dart'; import '../../../models/subtitle.dart';
import '../../widgets/app_text_form_field.dart'; import '../../widgets/app_text_form_field.dart';
import '../../widgets/buttons/app_back_button.dart'; import '../../widgets/buttons/app_back_button.dart';
import '../../widgets/buttons/app_button.dart'; import '../../widgets/buttons/app_button.dart';
import '../../widgets/date_and_time/date_picker.dart'; import '../../widgets/date_and_time/date_picker.dart';
import '../../widgets/images/mini_one_image_picker.dart'; import '../../widgets/images/mini_one_image_picker.dart';
import '../../widgets/status/report/service_report_equipment_status.dart';
import '../../widgets/status/report/service_report_fault_description.dart'; import '../../widgets/status/report/service_report_fault_description.dart';
import '../../widgets/status/report/service_report_reasons.dart'; import '../../widgets/status/report/service_report_reasons.dart';
import '../../widgets/titles/app_sub_title.dart'; import '../../widgets/titles/app_sub_title.dart';
@ -30,6 +35,7 @@ import '../../widgets/titles/app_sub_title.dart';
class CreateSubWorkOrderPage extends StatefulWidget { class CreateSubWorkOrderPage extends StatefulWidget {
static const id = "/CreateSubWorkOrder"; static const id = "/CreateSubWorkOrder";
final SearchWorkOrder workOrder; final SearchWorkOrder workOrder;
const CreateSubWorkOrderPage({this.workOrder, Key key}) : super(key: key); const CreateSubWorkOrderPage({this.workOrder, Key key}) : super(key: key);
@override @override
@ -47,17 +53,50 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
@override @override
void initState() { void initState() {
_subWorkOrders = SearchWorkOrder(assignedEmployee: widget.workOrder.assignedEmployee, callRequest: CallRequest()); _subWorkOrders = SearchWorkOrder(
assignedEmployee: widget?.workOrder?.callRequest?.assignedEmployee,
callRequest: CallRequest(id: widget?.workOrder?.callRequest?.id),
currentSituation: null,
supplier: null,
);
_serviceReport = ServiceReport(id: widget.workOrder.id, type: widget.workOrder.assetType, equipmentStatus: widget.workOrder.equipmentStatus); _serviceReport = ServiceReport(id: widget.workOrder.id, type: widget.workOrder.assetType, equipmentStatus: widget.workOrder.equipmentStatus);
_isLoading = true;
super.initState(); super.initState();
} }
var assetTypesProvider;
CallRequestForWorkOrder _callRequestForWorkOrder;
Future getAssetType() async {
//if (assetTypesProvider == null) {
Provider.of<ServiceRequestFaultDescriptionProvider>(context, listen: false).reset();
assetTypesProvider = Provider.of<ServiceStatusProvider>(context, listen: false);
_callRequestForWorkOrder = await Provider.of<ServiceRequestsProvider>(context).getCallRequestForWorkOrder(callId: widget.workOrder.callRequest.id.toString());
await assetTypesProvider.getTypes();
_subWorkOrders?.assetType = assetTypesProvider.statuses?.firstWhere(
(element) => element.value == _callRequestForWorkOrder?.assetType,
orElse: () => null,
);
setState(() {
_isLoading = false;
});
//}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (_callRequestForWorkOrder == null) {
getAssetType();
}
final Subtitle subtitle = AppLocalization.of(context).subtitle; final Subtitle subtitle = AppLocalization.of(context).subtitle;
return Scaffold( return Scaffold(
body: SafeArea( body: SafeArea(
child: SingleChildScrollView( child: _isLoading
? const ALoading()
: Column(
children: [
SingleChildScrollView(
child: Form( child: Form(
key: _formKey, key: _formKey,
child: Column( child: Column(
@ -90,9 +129,7 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 16),
child: Column( child: Column(
children: [ children: [
WorkOrderDetails( WorkOrderDetails(item: widget.workOrder, assetType: _subWorkOrders?.assetType),
item: widget.workOrder,
),
const SizedBox(height: 8), const SizedBox(height: 8),
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -106,8 +143,8 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
const SizedBox( const SizedBox(
height: 4, height: 4,
), ),
ServiceReportEquipmentStatusMenu( ServiceRequestDefectTypesMenu(
report: _serviceReport, initialValue: _serviceReport.equipmentStatus,
onSelect: (status) { onSelect: (status) {
_subWorkOrders.equipmentStatus = status; _subWorkOrders.equipmentStatus = status;
_serviceReport.equipmentStatus = status; _serviceReport.equipmentStatus = status;
@ -182,11 +219,11 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
height: 4, height: 4,
), ),
ServiceReportFaultDescription( ServiceReportFaultDescription(
requestId: widget.workOrder?.id?.toString(), requestId: widget.workOrder?.callRequest?.id?.toString(),
initialValue: _subWorkOrders.faultDescription, initialValue: _subWorkOrders?.faultDescription,
onSelect: (status) { onSelect: (status) {
_subWorkOrders.faultDescription = status; _subWorkOrders.faultDescription = status;
setState(() {}); if (mounted) setState(() {});
}, },
), ),
], ],
@ -196,10 +233,8 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const ASubTitle("Solution"), const ASubTitle("Solution"),
const SizedBox( const SizedBox(height: 4),
height: 4, ATextFormField(labelText: _subWorkOrders?.faultDescription?.workPerformed ?? "", textInputType: TextInputType.multiline, enable: false),
),
ATextFormField(labelText: _subWorkOrders.faultDescription?.workPerformed ?? "", textInputType: TextInputType.multiline, enable: false),
], ],
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
@ -261,6 +296,7 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
image: _image, image: _image,
onPick: (image) { onPick: (image) {
_image = image; _image = image;
_subWorkOrders.attachmentsWorkOrder ??= [];
_subWorkOrders.attachmentsWorkOrder.add(AttachmentsWorkOrder(name: "${image.path.split("/").last}|${base64Encode(image.readAsBytesSync())}")); _subWorkOrders.attachmentsWorkOrder.add(AttachmentsWorkOrder(name: "${image.path.split("/").last}|${base64Encode(image.readAsBytesSync())}"));
}, },
), ),
@ -271,10 +307,8 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
], ],
), ),
), ),
), ).expanded,
), Padding(
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
floatingActionButton: Padding(
padding: const EdgeInsets.all(16.0), padding: const EdgeInsets.all(16.0),
child: AButton( child: AButton(
text: subtitle.create, text: subtitle.create,
@ -283,11 +317,8 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
_validate = true; _validate = true;
setState(() {}); setState(() {});
if (validate()) { if (validate()) {
if (_subWorkOrders.startofWorkTime == null) { if (_subWorkOrders.timer?.startAt == null || _subWorkOrders.timer?.endAt == null) {
Fluttertoast.showToast(msg: "${subtitle.startDate} required"); Fluttertoast.showToast(msg: "Working hours required");
return;
} else if (_subWorkOrders.endofWorkTime == null) {
Fluttertoast.showToast(msg: "${subtitle.endDate} required");
return; return;
} else if (_subWorkOrders.calllastSituation == null) { } else if (_subWorkOrders.calllastSituation == null) {
Fluttertoast.showToast(msg: "${subtitle.callLastSituation} required"); Fluttertoast.showToast(msg: "${subtitle.callLastSituation} required");
@ -316,6 +347,9 @@ class _CreateSubWorkOrderPageState extends State<CreateSubWorkOrderPage> {
}, },
), ),
), ),
],
),
),
); );
} }

@ -9,9 +9,11 @@ import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/pages/sub_workorder/workorder_list.dart'; import 'package:test_sa/views/pages/sub_workorder/workorder_list.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/hospitals/hospital_auto_complete_field_new.dart';
import '../../../controllers/api_routes/http_status_manger.dart'; import '../../../controllers/api_routes/http_status_manger.dart';
import '../../../controllers/localization/localization.dart'; import '../../../controllers/localization/localization.dart';
import '../../../controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart';
import '../../app_style/colors.dart'; import '../../app_style/colors.dart';
import '../../widgets/buttons/app_back_button.dart'; import '../../widgets/buttons/app_back_button.dart';
import '../../widgets/buttons/app_button.dart'; import '../../widgets/buttons/app_button.dart';
@ -35,6 +37,15 @@ class _SearchSubWorkOrderPageState extends State<SearchSubWorkOrderPage> {
bool _isLoading = false; bool _isLoading = false;
String _callerId = "", _site = ""; String _callerId = "", _site = "";
Lookup _dateOperator; Lookup _dateOperator;
@override
void initState() {
super.initState();
if (context.mounted) {
Provider.of<ServiceReportMaintenanceSituationProvider>(context, listen: false).reset();
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_subtitle = AppLocalization.of(context).subtitle; _subtitle = AppLocalization.of(context).subtitle;
@ -120,12 +131,16 @@ class _SearchSubWorkOrderPageState extends State<SearchSubWorkOrderPage> {
_searchWorkOrders.calllastSituation = status; _searchWorkOrders.calllastSituation = status;
} }
}, },
woId: _searchWorkOrders.id?.toString(),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
ATextFormField( HospitalAutoCompleteField(
labelText: "Site", initialValue:_site,
onSaved: (value) { onSearch: (value) {
_site = value; _site = value.name;
setState(() {
});
}, },
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
@ -183,7 +198,6 @@ class _SearchSubWorkOrderPageState extends State<SearchSubWorkOrderPage> {
_isLoading = false; _isLoading = false;
setState(() {}); setState(() {});
if (serviceRequestsProvider.stateCode >= 200 && serviceRequestsProvider.stateCode < 300) { if (serviceRequestsProvider.stateCode >= 200 && serviceRequestsProvider.stateCode < 300) {
Fluttertoast.showToast(msg: _subtitle.requestCompleteSuccessfully);
Navigator.push( Navigator.push(
context, context,
MaterialPageRoute( MaterialPageRoute(

@ -1,11 +1,14 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:test_sa/models/part.dart';
import 'package:test_sa/models/service_request/search_work_order.dart'; import 'package:test_sa/models/service_request/search_work_order.dart';
import 'package:test_sa/views/app_style/colors.dart'; import 'package:test_sa/views/app_style/colors.dart';
import '../../../controllers/localization/localization.dart'; import '../../../controllers/localization/localization.dart';
import '../../../models/subtitle.dart'; import '../../../models/subtitle.dart';
import '../../widgets/app_text_form_field.dart'; import '../../app_style/sizing.dart';
import '../../widgets/buttons/app_button.dart'; import '../../widgets/buttons/app_button.dart';
import '../../widgets/parts/auto_complete_parts_field.dart';
import '../../widgets/parts/part_item.dart';
import '../../widgets/titles/app_sub_title.dart'; import '../../widgets/titles/app_sub_title.dart';
class SparePartsBottomSheet extends StatefulWidget { class SparePartsBottomSheet extends StatefulWidget {
@ -19,6 +22,7 @@ class SparePartsBottomSheet extends StatefulWidget {
class _SparePartsBottomSheetState extends State<SparePartsBottomSheet> { class _SparePartsBottomSheetState extends State<SparePartsBottomSheet> {
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final SearchWorkOrder _workOrder = SearchWorkOrder(); final SearchWorkOrder _workOrder = SearchWorkOrder();
bool _validate = false;
@override @override
void initState() { void initState() {
@ -26,6 +30,12 @@ class _SparePartsBottomSheetState extends State<SparePartsBottomSheet> {
_workOrder.copyFrom(widget.subWorkOrder); _workOrder.copyFrom(widget.subWorkOrder);
} }
@override
void dispose() {
_workOrder.sparePartsWorkOrders = widget.subWorkOrder.sparePartsWorkOrders;
super.dispose();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final size = MediaQuery.of(context).size; final size = MediaQuery.of(context).size;
@ -52,93 +62,91 @@ class _SparePartsBottomSheetState extends State<SparePartsBottomSheet> {
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
child: SingleChildScrollView(
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const SizedBox(height: 8), Container(
if (_workOrder.sparePartsWorkOrders?.length != null) width: double.infinity,
ListView.builder( padding: const EdgeInsets.all(16),
itemCount: _workOrder.sparePartsWorkOrders?.length, margin: const EdgeInsets.symmetric(vertical: 16),
shrinkWrap: true, decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: const [
physics: const NeverScrollableScrollPhysics(), BoxShadow(
itemBuilder: (context, index) { color: AColors.grey,
final wo = _workOrder.sparePartsWorkOrders[index]; offset: Offset(0, -1),
return Column( )
]),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [ children: [
ATextFormField( Expanded(
labelText: _workOrder?.sparePartsWorkOrders[index]?.sparePart?.partNo ?? "Part No.", flex: 3,
onChange: (value) { child: Column(
_workOrder.sparePartsWorkOrders[index].sparePart = SparePart(partNo: value); crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(subtitle.partNumber),
_validate && _workOrder.sparePartsWorkOrders == null
? ASubTitle(
subtitle.requiredWord,
color: Colors.red,
)
: const SizedBox.shrink(),
const SizedBox(height: 4),
AutoCompletePartsField(
onPick: (part) {
_workOrder.sparePartsWorkOrders ??= [];
_workOrder.sparePartsWorkOrders.add(SparePartsWorkOrders(
id: part.reportPartID,
qty: part.quantity,
sparePart: SparePart(id: part.id, partName: part.name, partNo: part.code),
));
}, },
), ),
// const SizedBox(height: 8), ],
// ATextFormField(
// labelText: "Description",
// hintText: "Add Some Text",
// textInputType: TextInputType.multiline,
// onSaved: (value) {
// _workOrder.sparePartsWorkOrders[index].sparePart = value;
// },
// ),
const SizedBox(height: 8),
ATextFormField(
labelText: _workOrder?.sparePartsWorkOrders[index]?.qty?.toString() ?? "Quantity",
textInputType: TextInputType.number,
onSaved: (value) {
_workOrder.sparePartsWorkOrders[index].qty = double.tryParse(value ?? "");
},
), ),
const SizedBox(height: 8),
InkWell(
onTap: () {
_workOrder.sparePartsWorkOrders.removeWhere(
(element) => (element.sparePart?.partNo == wo.sparePart?.partNo && element.id == wo.id),
);
setState(() {});
},
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
const Icon(Icons.delete, color: Colors.red),
Text(
"Remove this part",
style: Theme.of(context).textTheme.bodySmall,
), ),
], ],
), ),
SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
), ),
const SizedBox(height: 8), if (_workOrder.sparePartsWorkOrders?.isNotEmpty ?? false)
Row(
children: [
Expanded(flex: 3, child: Text(subtitle.number)),
Expanded(flex: 1, child: Text(subtitle.quantity)),
], ],
),
if (_workOrder.sparePartsWorkOrders?.isNotEmpty ?? false)
Column(
children: List.generate(
_workOrder.sparePartsWorkOrders?.length,
(index) {
final spare = _workOrder.sparePartsWorkOrders[index];
Part part = Part(
id: spare.sparePart?.id,
reportPartID: spare.id,
code: spare.sparePart?.partNo,
name: spare.sparePart?.partName,
quantity: spare.qty,
); );
return PartItem(
part: part,
onEdit: (qty) {
spare.qty = qty;
}, },
), onDelete: (part) {
const Divider(), _workOrder.sparePartsWorkOrders.remove(spare);
const SizedBox(height: 8),
InkWell(
onTap: () {
_workOrder.sparePartsWorkOrders ??= [];
_workOrder.sparePartsWorkOrders.add(SparePartsWorkOrders());
setState(() {}); setState(() {});
}, },
child: Container( );
decoration: BoxDecoration( },
color: AColors.primaryColor.withOpacity(0.15),
borderRadius: BorderRadius.circular(10),
border: Border.all(color: AColors.primaryColor),
),
child: ListTile(
title: Text(
"Add Part",
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: AColors.primaryColor),
),
trailing: const Icon(
Icons.add_circle,
color: AColors.primaryColor,
size: 20,
), ),
), ),
const SizedBox(height: 16),
],
), ),
), ),
const SizedBox(height: 24), const SizedBox(height: 24),
@ -147,7 +155,6 @@ class _SparePartsBottomSheetState extends State<SparePartsBottomSheet> {
), ),
), ),
), ),
),
AButton( AButton(
text: subtitle.submit, text: subtitle.submit,
onPressed: () async { onPressed: () async {

@ -1,4 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/models/service_request/search_work_order.dart'; import 'package:test_sa/models/service_request/search_work_order.dart';
import 'package:test_sa/models/subtitle.dart'; import 'package:test_sa/models/subtitle.dart';
import 'package:test_sa/views/widgets/app_text_form_field.dart'; import 'package:test_sa/views/widgets/app_text_form_field.dart';
@ -8,8 +10,8 @@ import 'package:test_sa/views/widgets/status/report/service_report_maintenance_s
import 'package:test_sa/views/widgets/status/report/service_report_repair_location.dart'; import 'package:test_sa/views/widgets/status/report/service_report_repair_location.dart';
import '../../../controllers/localization/localization.dart'; import '../../../controllers/localization/localization.dart';
import '../../app_style/sizing.dart'; import '../../../controllers/providers/api/status_drop_down/report/service_report_maintenance_situation_provider.dart';
import '../../widgets/date_and_time/time_picker.dart'; import '../../widgets/timer/app_timer.dart';
import '../../widgets/titles/app_sub_title.dart'; import '../../widgets/titles/app_sub_title.dart';
class WorkOrderDetailsBottomSheet extends StatefulWidget { class WorkOrderDetailsBottomSheet extends StatefulWidget {
@ -27,7 +29,11 @@ class _WorkOrderDetailsBottomSheetState extends State<WorkOrderDetailsBottomShee
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_workOrder.copyFrom(widget.subWorkOrder); _workOrder.copyFrom(widget.subWorkOrder);
if (context.mounted) {
Provider.of<ServiceReportMaintenanceSituationProvider>(context, listen: false).reset();
}
} }
@override @override
@ -66,81 +72,29 @@ class _WorkOrderDetailsBottomSheetState extends State<WorkOrderDetailsBottomShee
const ASubTitle("Assistant Employee"), const ASubTitle("Assistant Employee"),
const SizedBox(height: 4), const SizedBox(height: 4),
ServiceReportAssistantEmployeeMenu( ServiceReportAssistantEmployeeMenu(
initialValue: (_workOrder.assistantEmployees?.isEmpty ?? false) ? null : _workOrder.assistantEmployees?.first, initialValue: (_workOrder.assistantEmployees?.isNotEmpty ?? false) ? _workOrder.assistantEmployees?.first : null,
onSelect: (assistantsEmployee) { onSelect: (assistantsEmployee) {
_workOrder.assistantEmployees = [assistantsEmployee]; _workOrder.assistantEmployees = [assistantsEmployee];
}, },
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
ASubTitle(subtitle.workingHours),
const SizedBox(height: 8),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: Column( child: AppTimer(
crossAxisAlignment: CrossAxisAlignment.stretch, timer: _workOrder.timer,
children: [ onChange: (timer) async {
const ASubTitle("Start of Work"), _workOrder.timer = timer;
SizedBox( _workOrder.workingHours = num.tryParse((((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0");
height: 8 * AppStyle.getScaleFactor(context), return true;
),
ADateTimePicker(
date: DateTime.tryParse(_workOrder.startofWorkTime ?? ""),
from: DateTime.now().subtract(const Duration(days: 365)),
to: DateTime.now(),
onDateTimePicker: (date) {
_workOrder.startofWorkTime = date?.toIso8601String();
setState(() {});
},
),
],
),
),
const SizedBox(width: 8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const ASubTitle("End of Work"),
SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
),
ADateTimePicker(
date: DateTime.tryParse(_workOrder.endofWorkTime ?? ""),
from: DateTime.now().subtract(const Duration(days: 365)),
to: DateTime.now(),
onDateTimePicker: (date) {
_workOrder.endofWorkTime = date?.toIso8601String();
setState(() {});
}, },
), ),
],
),
), ),
], ],
), ),
const SizedBox(height: 8), const SizedBox(height: 16),
ASubTitle(subtitle.workingHours),
const SizedBox(height: 4),
ATextFormField(
textAlign: TextAlign.center,
labelText: _workOrder.startofWorkTime == null
? "0"
: ((DateTime.tryParse(_workOrder.endofWorkTime ?? "")?.difference(DateTime.tryParse(_workOrder.startofWorkTime ?? ""))?.inMinutes ?? 0) / 60)
?.toStringAsFixed(2)
?.toString() ??
"0",
enable: false,
style: Theme.of(context).textTheme.titleMedium,
// validator: (value) => Validator.isNumeric(value) ? null : _subtitle.requiredWord,
textInputType: TextInputType.number,
onSaved: (value) {
_workOrder.workingHours = double.tryParse(
((DateTime.tryParse(_workOrder.endofWorkTime ?? "")?.difference(DateTime.tryParse(_workOrder.startofWorkTime ?? ""))?.inMinutes ?? 0) / 60)
?.toStringAsFixed(2)
?.toString() ??
"0");
},
),
const SizedBox(height: 8),
ATextFormField( ATextFormField(
labelText: "Travel Hours", labelText: "Travel Hours",
initialValue: _workOrder.travelingHours?.toString(), initialValue: _workOrder.travelingHours?.toString(),
@ -171,6 +125,7 @@ class _WorkOrderDetailsBottomSheetState extends State<WorkOrderDetailsBottomShee
_workOrder.calllastSituation = status; _workOrder.calllastSituation = status;
} }
}, },
woId: widget.subWorkOrder?.callRequest?.id?.toString(),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
const ASubTitle("Repair Location"), const ASubTitle("Repair Location"),
@ -199,6 +154,13 @@ class _WorkOrderDetailsBottomSheetState extends State<WorkOrderDetailsBottomShee
AButton( AButton(
text: subtitle.submit, text: subtitle.submit,
onPressed: () async { onPressed: () async {
if (_workOrder?.workingHours == null) {
await Fluttertoast.showToast(msg: "Working Hours Timer Isn't Started");
return;
} else if ((_workOrder?.timer?.stopped ?? false) == false) {
await Fluttertoast.showToast(msg: "Stop The Timer");
return;
}
_formKey.currentState.save(); _formKey.currentState.save();
widget.subWorkOrder.copyFrom(_workOrder); widget.subWorkOrder.copyFrom(_workOrder);
Navigator.pop(context); Navigator.pop(context);

@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:test_sa/models/lookup.dart';
import '../../../controllers/localization/localization.dart'; import '../../../controllers/localization/localization.dart';
import '../../../models/service_request/search_work_order.dart'; import '../../../models/service_request/search_work_order.dart';
@ -8,7 +9,9 @@ import '../../app_style/sizing.dart';
class WorkOrderDetails extends StatelessWidget { class WorkOrderDetails extends StatelessWidget {
final SearchWorkOrder item; final SearchWorkOrder item;
WorkOrderDetails({@required this.item,Key key}) : super(key: key); Lookup assetType;
WorkOrderDetails({@required this.item, this.assetType, Key key}) : super(key: key);
Subtitle _subtitle; Subtitle _subtitle;
@override @override
@ -30,15 +33,15 @@ class WorkOrderDetails extends StatelessWidget {
), ),
child: Column( child: Column(
children: [ children: [
_buildRow(_subtitle.callId, item.callRequest?.id?.toString()??"", context), _buildRow(_subtitle.callId, item.callRequest?.id?.toString() ?? "", context),
_buildRow(_subtitle.assetNumber, item.callRequest?.asset?.assetNumber??"", context), _buildRow(_subtitle.assetNumber, item.callRequest?.asset?.assetNumber ?? "", context),
_buildRow("WO No", item.workOrderNo, context), _buildRow("WO No", item.workOrderNo, context),
_buildRow(_subtitle.assetName, item.callRequest?.asset?.assetNumber??'', context), _buildRow(_subtitle.assetName, item.callRequest?.asset?.assetNumber ?? '', context),
_buildRow(_subtitle.department, item.callRequest?.asset?.department??'', context), _buildRow(_subtitle.department, item.callRequest?.asset?.department ?? '', context),
_buildRow(_subtitle.assetSN, item.callRequest?.asset?.assetSerialNo??'', context), _buildRow(_subtitle.assetSN, item.callRequest?.asset?.assetSerialNo ?? '', context),
_buildRow(_subtitle.model, item.callRequest?.asset?.modelDefinition?.modelName??"", context), _buildRow(_subtitle.model, item.callRequest?.asset?.modelDefinition?.modelName ?? "", context),
_buildRow("Manufacturer", item.callRequest?.asset?.modelDefinition?.manufacturerName??"", context), _buildRow("Manufacturer", item.callRequest?.asset?.modelDefinition?.manufacturerName ?? "", context),
_buildRow(_subtitle.site, item.callRequest?.asset?.site?.custName??"", context), _buildRow(_subtitle.site, item.callRequest?.asset?.site?.custName ?? "", context),
], ],
), ),
), ),
@ -53,16 +56,18 @@ class WorkOrderDetails extends StatelessWidget {
), ),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
), ),
child: _buildRow("Asset Type", item.assetType?.name??"", context),) child: _buildRow("Asset Type", assetType?.name ?? (item.assetType?.name ?? ""), context),
)
], ],
); );
} }
Widget _buildRow(String title, String value, BuildContext context){
Widget _buildRow(String title, String value, BuildContext context) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Text( Text(
title+" : ", title + " : ",
style: Theme.of(context).textTheme.subtitle2.copyWith(fontWeight: FontWeight.bold), style: Theme.of(context).textTheme.subtitle2.copyWith(fontWeight: FontWeight.bold),
), ),
//if (item.clientName != null) //if (item.clientName != null)

@ -1,3 +1,5 @@
import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -29,6 +31,7 @@ import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../controllers/localization/localization.dart'; import '../../../../controllers/localization/localization.dart';
import '../../../../controllers/providers/api/hospitals_provider.dart'; import '../../../../controllers/providers/api/hospitals_provider.dart';
import '../../../../models/enums/user_types.dart'; import '../../../../models/enums/user_types.dart';
import '../../../widgets/e_signature/e_signature.dart';
class RequestGasRefill extends StatefulWidget { class RequestGasRefill extends StatefulWidget {
static const String id = "/request-gas-refill"; static const String id = "/request-gas-refill";
@ -150,6 +153,7 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
} }
if (widget.gasRefillModel != null && _firstTime) { if (widget.gasRefillModel != null && _firstTime) {
_formModel = widget.gasRefillModel; _formModel = widget.gasRefillModel;
_formModel.status = const Lookup(value: 0);
HospitalsProvider().getHospitalsListByVal(searchVal: widget.gasRefillModel.clientName).then((value) { HospitalsProvider().getHospitalsListByVal(searchVal: widget.gasRefillModel.clientName).then((value) {
_gasRefillProvider.hospital = value?.firstWhere((element) => element.name == widget.gasRefillModel.clientName, orElse: () => null); _gasRefillProvider.hospital = value?.firstWhere((element) => element.name == widget.gasRefillModel.clientName, orElse: () => null);
print(_gasRefillProvider.hospital?.buildings?.length); print(_gasRefillProvider.hospital?.buildings?.length);
@ -212,7 +216,8 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
height: 4, height: 4,
), ),
GasStatusMenu( GasStatusMenu(
initialValue: _formModel.status ?? const Lookup(value: 1), initialValue: _formModel.status ?? const Lookup(value: 0),
enabled: false,
onSelect: (status) { onSelect: (status) {
_formModel.status = status; _formModel.status = status;
}, },
@ -288,73 +293,73 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
), ),
], ],
), ),
if (_userProvider.user?.type == UsersTypes.engineer) // if (_userProvider.user?.type == UsersTypes.engineer)
Column( // Column(
children: [ // children: [
Row( // Row(
children: [ // children: [
Expanded( // Expanded(
child: Column( // child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, // crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ // children: [
const ASubTitle("Start of Work"), // const ASubTitle("Start of Work"),
SizedBox( // SizedBox(
height: 8 * AppStyle.getScaleFactor(context), // height: 8 * AppStyle.getScaleFactor(context),
), // ),
ADateTimePicker( // ADateTimePicker(
date: _gasRefillProvider.startDate, // date: _gasRefillProvider.startDate,
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)),
onDateTimePicker: (date) { // onDateTimePicker: (date) {
_gasRefillProvider.startDate = date; // _gasRefillProvider.startDate = date;
setState(() {}); // setState(() {});
}, // },
), // ),
], // ],
), // ),
), // ),
const SizedBox(width: 8), // const SizedBox(width: 8),
Expanded( // Expanded(
child: Column( // child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch, // crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ // children: [
const ASubTitle("End of Work"), // const ASubTitle("End of Work"),
SizedBox( // SizedBox(
height: 8 * AppStyle.getScaleFactor(context), // height: 8 * AppStyle.getScaleFactor(context),
), // ),
ADateTimePicker( // ADateTimePicker(
date: _gasRefillProvider.endDate, // date: _gasRefillProvider.endDate,
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)),
onDateTimePicker: (date) { // onDateTimePicker: (date) {
_gasRefillProvider.endDate = date; // _gasRefillProvider.endDate = date;
setState(() {}); // setState(() {});
}, // },
), // ),
], // ],
), // ),
), // ),
], // ],
), // ),
const SizedBox(height: 8), // const SizedBox(height: 8),
ASubTitle(_subtitle.workingHours), // ASubTitle(_subtitle.workingHours),
const SizedBox(height: 4), // const SizedBox(height: 4),
ATextFormField( // ATextFormField(
initialValue: null, // initialValue: null,
textAlign: TextAlign.center, // textAlign: TextAlign.center,
hintText: _gasRefillProvider.startDate == null // hintText: _gasRefillProvider.startDate == null
? "0" // ? "0"
: ((_gasRefillProvider.endDate?.difference(_gasRefillProvider.startDate)?.inMinutes ?? 0) / 60)?.toStringAsFixed(2)?.toString() ?? "0", // : ((_gasRefillProvider.endDate?.difference(_gasRefillProvider.startDate)?.inMinutes ?? 0) / 60)?.toStringAsFixed(2)?.toString() ?? "0",
enable: false, // enable: false,
style: Theme.of(context).textTheme.subtitle1, // style: Theme.of(context).textTheme.subtitle1,
validator: (value) => Validator.isNumeric(value) ? null : _subtitle.requiredWord, // validator: (value) => Validator.isNumeric(value) ? null : _subtitle.requiredWord,
textInputType: TextInputType.number, // textInputType: TextInputType.number,
onSaved: (value) { // onSaved: (value) {
// _serviceReport.workHours = value; // // _serviceReport.workHours = value;
}, // },
), // ),
], // ],
), // ),
if (widget.gasRefillModel == null) if (widget.gasRefillModel == null)
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -481,14 +486,43 @@ class _RequestGasRefillState extends State<RequestGasRefill> {
}, },
); );
}), }),
if (widget.gasRefillModel != null) const SizedBox(height: 16),
if (widget.gasRefillModel != null) const ASubTitle("Nurse Signature"),
if (widget.gasRefillModel != null)
ESignature(
oldSignature: _formModel.signatureNurse,
newSignature: _formModel.localNurseSignature,
onChange: (signature) {
if (signature == null || signature.isEmpty) {
return;
}
_formModel.localNurseSignature = signature;
_formModel.signatureNurse = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
},
),
if (widget.gasRefillModel != null)
const SizedBox(
height: 8,
),
if (widget.gasRefillModel != null) const ASubTitle("Engineer Signature"),
if (widget.gasRefillModel != null)
ESignature(
oldSignature: _formModel.signatureEngineer,
newSignature: _formModel.localNurseSignature,
onChange: (signature) {
if (signature == null || signature.isEmpty) {
return;
}
_formModel.localNurseSignature = signature;
_formModel.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
},
),
const SizedBox(height: 16), const SizedBox(height: 16),
AButton( AButton(
text: widget.gasRefillModel == null ? _subtitle.submit : _subtitle.update, text: widget.gasRefillModel == null ? _subtitle.submit : _subtitle.update,
onPressed: _onSubmit, onPressed: _onSubmit,
), ),
const SizedBox( const SizedBox(height: 100)
height: 100,
)
], ],
), ),
), ),

@ -212,7 +212,7 @@ class _LandPageState extends State<LandPage> {
Navigator.of(context).pushNamed(TrackDeviceTransferPage.id); Navigator.of(context).pushNamed(TrackDeviceTransferPage.id);
}, },
), ),
// if (_userProvider?.user != null && _userProvider?.user?.type != UsersTypes.engineer) if (_userProvider?.user != null && _userProvider?.user?.type != UsersTypes.normal_user)
LandPageItem( LandPageItem(
text: "Search Work Order", text: "Search Work Order",
svgPath: "assets/images/sub_workorder_icon.svg", svgPath: "assets/images/sub_workorder_icon.svg",

@ -306,7 +306,7 @@ class CreateRequestPageState extends State<CreateRequestPage> {
Fluttertoast.showToast(msg: _subtitle.pickDevice); Fluttertoast.showToast(msg: _subtitle.pickDevice);
return; return;
} }
if (_serviceRequest.firstAction != null && _dateTime == null) { if (_serviceRequest.firstAction.name == "Need a visit" && _dateTime == null) {
Fluttertoast.showToast(msg: _subtitle.noDateFound); Fluttertoast.showToast(msg: _subtitle.noDateFound);
return; return;
} }

@ -23,24 +23,21 @@ import 'package:test_sa/views/widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/buttons/app_back_button.dart'; import 'package:test_sa/views/widgets/buttons/app_back_button.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart'; import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/date_and_time/time_picker.dart';
import 'package:test_sa/views/widgets/e_signature/e_signature.dart'; import 'package:test_sa/views/widgets/e_signature/e_signature.dart';
import 'package:test_sa/views/widgets/equipment/auto_complete_devices_field.dart'; import 'package:test_sa/views/widgets/equipment/auto_complete_devices_field.dart';
import 'package:test_sa/views/widgets/images/mini_one_image_picker.dart'; import 'package:test_sa/views/widgets/images/mini_one_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart'; import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart';
import 'package:test_sa/views/widgets/parts/part_item.dart'; import 'package:test_sa/views/widgets/parts/part_item.dart';
import 'package:test_sa/views/widgets/status/employee/engineers_mune.dart';
import 'package:test_sa/views/widgets/status/report/service_report_equipment_status.dart'; import 'package:test_sa/views/widgets/status/report/service_report_equipment_status.dart';
import 'package:test_sa/views/widgets/status/report/service_report_last_call.dart'; import 'package:test_sa/views/widgets/status/report/service_report_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/titles/app_sub_title.dart'; import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../../../../../controllers/providers/api/status_drop_down/report/service_types_provider.dart'; import '../../../../../controllers/providers/api/status_drop_down/report/service_types_provider.dart';
import '../../../../widgets/speech_to_text/speech_to_text.dart';
import '../../../../widgets/status/report/service_report_fault_description.dart'; import '../../../../widgets/status/report/service_report_fault_description.dart';
import '../../../../widgets/status/report/service_report_repair_location.dart'; import '../../../../widgets/status/report/service_report_repair_location.dart';
import '../../../../widgets/timer/app_timer.dart';
class CreateServiceReport extends StatefulWidget { class CreateServiceReport extends StatefulWidget {
static final String id = "/create-service-report"; static final String id = "/create-service-report";
@ -418,71 +415,23 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
SizedBox( SizedBox(
height: 8 * AppStyle.getScaleFactor(context), height: 8 * AppStyle.getScaleFactor(context),
), ),
ASubTitle(_subtitle.workingHours),
const SizedBox(height: 8),
Row( Row(
children: [ children: [
Expanded( Expanded(
child: Column( child: AppTimer(
crossAxisAlignment: CrossAxisAlignment.stretch, timer: _serviceReport.timer,
children: [ onChange: (timer) async {
const ASubTitle("Start of Work"), _serviceReport.timer = timer;
SizedBox( _serviceReport.workingHours = num.tryParse((((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0");
height: 8 * AppStyle.getScaleFactor(context), return true;
),
ADateTimePicker(
date: _serviceReport.startDate,
from: DateTime.now().subtract(const Duration(days: 365)),
to: DateTime.now().add(const Duration(days: 365)),
onDateTimePicker: (date) {
_serviceReport.startDate = date;
setState(() {});
}, },
), ),
],
),
),
const SizedBox(width: 8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const ASubTitle("End of Work"),
SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
),
ADateTimePicker(
date: _serviceReport.endDate,
from: DateTime.now().subtract(const Duration(days: 365)),
to: DateTime.now().add(const Duration(days: 365)),
onDateTimePicker: (date) {
_serviceReport.endDate = date;
setState(() {});
},
),
],
),
), ),
], ],
), ),
const SizedBox(height: 8), const SizedBox(height: 16),
ASubTitle(_subtitle.workingHours),
const SizedBox(height: 4),
ATextFormField(
initialValue: null,
textAlign: TextAlign.center,
hintText: _serviceReport.startDate == null
? "0"
: ((_serviceReport?.endDate?.difference(_serviceReport?.startDate)?.inMinutes ?? 0) / 60)?.toStringAsFixed(2)?.toString() ?? "0",
enable: false,
style: Theme.of(context).textTheme.subtitle1,
validator: (value) => Validator.isNumeric(value) ? null : _subtitle.requiredWord,
textInputType: TextInputType.number,
onSaved: (value) {
// _serviceReport.workHours = value;
},
),
const SizedBox(
height: 8,
),
// device sn // device sn
Visibility( Visibility(
visible: widget.request.deviceSerialNumber == null, visible: widget.request.deviceSerialNumber == null,
@ -636,7 +585,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
enable: false, enable: false,
hintText: _serviceReport.faultDescription?.workPerformed ?? "", hintText: _serviceReport.faultDescription?.workPerformed ?? "",
controller: _workPreformedController, controller: _workPreformedController,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.titleMedium,
validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord, validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord,
textInputType: TextInputType.multiline, textInputType: TextInputType.multiline,
onSaved: (value) { onSaved: (value) {
@ -656,6 +605,12 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.reasons), ASubTitle(_subtitle.reasons),
_validate && _serviceReport.reason?.id == null
? ASubTitle(
_subtitle.requiredWord,
color: Colors.red,
)
: const SizedBox.shrink(),
const SizedBox(height: 4), const SizedBox(height: 4),
ServiceReportReasonsMenu( ServiceReportReasonsMenu(
initialValue: _serviceReport.reason, initialValue: _serviceReport.reason,
@ -701,7 +656,7 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
), ),
ATextFormField( ATextFormField(
initialValue: _serviceReport?.travelingExpense?.toString(), initialValue: _serviceReport?.travelingExpense?.toString(),
hintText: _subtitle.travelingExpense, hintText: "i.e 3, 3.5, 4",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium, style: Theme.of(context).textTheme.titleMedium,
textInputType: TextInputType.number, textInputType: TextInputType.number,
@ -929,9 +884,9 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
), ),
Column( Column(
children: List.generate(_serviceReport.parts.length, (index) { children: List.generate(_serviceReport.parts.length, (index) {
Part _part = _serviceReport.parts[index]; Part part = _serviceReport.parts[index];
return PartItem( return PartItem(
part: _part, part: part,
onDelete: (part) { onDelete: (part) {
_serviceReport.parts.remove(part); _serviceReport.parts.remove(part);
setState(() {}); setState(() {});
@ -955,7 +910,10 @@ class _CreateServiceReportState extends State<CreateServiceReport> with TickerPr
// setState(() {}); // setState(() {});
// return; // return;
// } // }
if (!_serviceReport.validate()) return; if (!(await _serviceReport.validate())) {
setState(() {});
return;
}
_formKey.currentState.save(); _formKey.currentState.save();
_isLoading = true; _isLoading = true;

@ -8,9 +8,12 @@ import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/service_requests_provider.dart'; import 'package:test_sa/controllers/providers/api/service_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_last_calls_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_types_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart'; import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/controllers/validator/validator.dart'; import 'package:test_sa/controllers/validator/validator.dart';
import 'package:test_sa/models/call_request_for_work_order_model.dart';
import 'package:test_sa/models/engineer.dart';
import 'package:test_sa/models/part.dart'; import 'package:test_sa/models/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';
@ -27,12 +30,11 @@ import 'package:test_sa/views/widgets/images/mini_one_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart'; import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart';
import 'package:test_sa/views/widgets/parts/part_item.dart'; import 'package:test_sa/views/widgets/parts/part_item.dart';
import 'package:test_sa/views/widgets/status/employee/engineers_mune.dart'; import 'package:test_sa/views/widgets/status/report/service_report_equipment_status.dart';
import 'package:test_sa/views/widgets/status/report/service_report_fault_description.dart';
import 'package:test_sa/views/widgets/status/report/service_report_last_call.dart'; import 'package:test_sa/views/widgets/status/report/service_report_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_repair_location.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/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';
@ -42,6 +44,7 @@ class EditServiceReport extends StatefulWidget {
final ServiceReport report; final ServiceReport report;
const EditServiceReport({Key key, this.request, this.report}) : super(key: key); const EditServiceReport({Key key, this.request, this.report}) : super(key: key);
@override @override
_EditServiceReportState createState() => _EditServiceReportState(); _EditServiceReportState createState() => _EditServiceReportState();
} }
@ -54,6 +57,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
bool _validate = false; bool _validate = false;
ServiceReport _serviceReport; ServiceReport _serviceReport;
bool _isLoading = false; bool _isLoading = false;
bool _showCommentField = false;
Subtitle _subtitle; Subtitle _subtitle;
File _image; File _image;
@ -62,12 +66,26 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
TextEditingController _faultController = TextEditingController(); TextEditingController _faultController = TextEditingController();
TextEditingController _workPreformedController = TextEditingController(); TextEditingController _workPreformedController = TextEditingController();
ServiceStatusProvider _assetTypeProvider;
CallRequestForWorkOrder _callRequestForWorkOrder;
@override @override
void initState() { void initState() {
_serviceReport = widget.report; _serviceReport = widget.report;
super.initState(); super.initState();
} }
void getRequestForWorkOrder() async {
_isLoading = true;
setState(() {});
_callRequestForWorkOrder = await _serviceRequestsProvider.getCallRequestForWorkOrder(callId: widget.request.id);
_serviceReport.engineer = Engineer.fromJson(_callRequestForWorkOrder?.assignedEmployee?.toJson());
await _assetTypeProvider.getTypes(user: _userProvider.user, host: _settingProvider.host);
_isLoading = false;
setState(() {});
}
@override @override
void dispose() { void dispose() {
_faultController.dispose(); _faultController.dispose();
@ -80,6 +98,15 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
_serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context); _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
_assetTypeProvider = Provider.of<ServiceStatusProvider>(context);
if (_callRequestForWorkOrder == null) {
getRequestForWorkOrder();
}
_serviceReport.assetType = _assetTypeProvider.statuses?.firstWhere(
(element) => element.value == _callRequestForWorkOrder?.assetType,
orElse: () => null,
);
_subtitle = AppLocalization.of(context).subtitle; _subtitle = AppLocalization.of(context).subtitle;
return Scaffold( return Scaffold(
key: _scaffoldKey, key: _scaffoldKey,
@ -94,11 +121,9 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
child: Stack( child: Stack(
children: [ children: [
ListView( ListView(
padding: const EdgeInsets.all(16),
children: [ children: [
//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),
@ -108,22 +133,22 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
), ),
), ),
), ),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle("Caller Info"),
const SizedBox(height: 8),
Container( Container(
padding: const EdgeInsets.symmetric(horizontal: 16), width: double.infinity,
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 16), padding: const EdgeInsets.all(16),
decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [ margin: const EdgeInsets.symmetric(vertical: 16),
const BoxShadow( decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: const [
BoxShadow(
color: AColors.grey, color: AColors.grey,
offset: Offset(0, -1), offset: Offset(0, -1),
) )
]), ]),
child: Column( child: Wrap(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SizedBox(
height: 8,
),
Wrap(
spacing: 10, spacing: 10,
children: [ children: [
ASubTitle( ASubTitle(
@ -146,38 +171,53 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
) )
], ],
), ),
const Divider(), ),
const SizedBox(height: 8),
ASubTitle("Work Order Details"),
const SizedBox(height: 8),
Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.symmetric(vertical: 16),
decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [
const BoxShadow(
color: AColors.grey,
offset: Offset(0, -1),
)
]),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Report type and Reasons // Report type and Reasons
Row( Row(
children: [ children: [
// Report Status // Report Status
Expanded( // Expanded(
child: Column( // child: Column(
crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
children: [ // children: [
ASubTitle(_subtitle.reportType), // ASubTitle(_subtitle.reportType),
_validate && _serviceReport.type == null // _validate && _serviceReport.type == null
? ASubTitle( // ? ASubTitle(
_subtitle.requiredWord, // _subtitle.requiredWord,
color: Colors.red, // color: Colors.red,
) // )
: const SizedBox.shrink(), // : const SizedBox.shrink(),
const SizedBox( // const SizedBox(
height: 4, // height: 4,
), // ),
ServiceReportTypeMenu( // ServiceReportTypeMenu(
initialValue: _serviceReport.type, // initialValue: _serviceReport.type,
onSelect: (status) { // onSelect: (status) {
_serviceReport.type = status; // _serviceReport.type = status;
}, // },
), // ),
], // ],
), // ),
), // ),
const SizedBox( // const SizedBox(
width: 8, // width: 8,
), // ),
// visit date // visit date
Expanded( Expanded(
child: Column( child: Column(
@ -215,7 +255,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
), ),
// device sn // device sn
Visibility( Visibility(
visible: true, //widget.report.device == null, visible: widget.request.deviceSerialNumber == null,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
@ -233,15 +273,11 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
_serviceReport.device.id = id; _serviceReport.device.id = id;
}, },
), ),
const SizedBox( const SizedBox(height: 8),
height: 8,
),
], ],
), ),
), ),
const SizedBox( const SizedBox(height: 8),
height: 8,
),
ASubTitle(_subtitle.AssetType), ASubTitle(_subtitle.AssetType),
_validate && _serviceReport.assetType == null _validate && _serviceReport.assetType == null
? ASubTitle( ? ASubTitle(
@ -252,41 +288,34 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
const SizedBox( const SizedBox(
height: 4, height: 4,
), ),
ServiceAssetTypeMenu( LoadingManager(
initialValue: _serviceReport.assetType, isLoading: _assetTypeProvider.isLoading,
onSelect: (status) { isFailedLoading: _assetTypeProvider.statuses == null,
_serviceReport.assetType = status; stateCode: _assetTypeProvider.stateCode,
onRefresh: () async {
_assetTypeProvider.reset();
await _assetTypeProvider.getTypes(user: _userProvider.user, host: _settingProvider.host);
_serviceReport?.assetType = _assetTypeProvider.statuses?.firstWhere(
(element) => element.value == _callRequestForWorkOrder.assetType,
orElse: () => null,
);
}, },
child: ATextFormField(
initialValue: _serviceReport?.assetType?.name ?? "NULL",
textAlign: TextAlign.center,
enable: false,
style: Theme.of(context).textTheme.titleMedium,
), ),
const SizedBox(
height: 8,
),
SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
),
const ASubTitle("Assign Employee"),
const SizedBox(
height: 8,
),
_validate && _serviceReport.engineer == null
? ASubTitle(
_subtitle.requiredWord,
color: Colors.red,
)
: const SizedBox.shrink(),
const SizedBox(
height: 4,
),
EngineersMenu(
initialValue: _serviceReport.engineer,
onSelect: (engineer) {
_serviceReport.engineer = engineer;
},
), ),
// ServiceAssetTypeMenu(
// initialValue: _serviceReport.assetType,
// onSelect: (status) {
// _serviceReport.assetType = status;
// },
// ),
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
// Report status and Asset Type
Row( Row(
children: [ children: [
// report status // report status
@ -294,7 +323,8 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(_subtitle.reportStatus), // ASubTitle(_subtitle.reportStatus),
ASubTitle("Equipment Status"),
_validate && _serviceReport.equipmentStatus == null _validate && _serviceReport.equipmentStatus == null
? ASubTitle( ? ASubTitle(
_subtitle.requiredWord, _subtitle.requiredWord,
@ -304,19 +334,29 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
const SizedBox( const SizedBox(
height: 4, height: 4,
), ),
ServiceReportStatusMenu( // ServiceReportStatusMenu(
// report: _serviceReport,
// request: widget.request,
// onSelect: (status) {
// _serviceReport.status = status;
// },
// ),
ServiceReportEquipmentStatusMenu(
report: _serviceReport, report: _serviceReport,
request: widget.request, request: widget.request,
onSelect: (status) { onSelect: (status) {
_serviceReport.equipmentStatus = status; _serviceReport.equipmentStatus = status;
}, },
), )
], ],
), ),
), ),
const SizedBox( const SizedBox(
width: 8, width: 8,
), ),
// Provider.of<ServiceReportLastCallsProvider>(context).isLoading == null
// ? const SizedBox.shrink():
// 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();
@ -331,9 +371,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
color: Colors.red, color: Colors.red,
) )
: const SizedBox.shrink(), : const SizedBox.shrink(),
const SizedBox( const SizedBox(height: 4),
height: 4,
),
ServiceReportLastCallsMenu( ServiceReportLastCallsMenu(
report: _serviceReport, report: _serviceReport,
onSelect: (status) { onSelect: (status) {
@ -352,6 +390,113 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
), ),
], ],
), ),
if (_showCommentField)
const SizedBox(
height: 8,
),
if (_showCommentField)
ATextFormField(
initialValue: _serviceReport?.reviewComment,
hintText: "Review Comment",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
textInputType: TextInputType.multiline,
onSaved: (value) {
_serviceReport.reviewComment = value;
},
),
SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
),
// const ASubTitle("Assign Employee"),
// const SizedBox(
// height: 8,
// ),
// _validate && _serviceReport.engineer == null
// ? ASubTitle(
// _subtitle.requiredWord,
// color: Colors.red,
// )
// : const SizedBox.shrink(),
// const SizedBox(
// height: 4,
// ),
// EngineersMenu(
// initialValue: _serviceReport.engineer,
// onSelect: (engineer) {
// _serviceReport.engineer = engineer;
// },
// ),
// const SizedBox(
// height: 8,
// ),
// Report status and Service Type
// Row(
// children: [
// // report status
// Expanded(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// ASubTitle(_subtitle.reportStatus),
// _validate && _serviceReport.equipmentStatus == null
// ? ASubTitle(
// _subtitle.requiredWord,
// color: Colors.red,
// )
// : const SizedBox.shrink(),
// const SizedBox(
// height: 4,
// ),
// ServiceReportStatusMenu(
// report: _serviceReport,
// request: widget.request,
// onSelect: (status) {
// _serviceReport.equipmentStatus = status;
// },
// ),
// ],
// ),
// ),
// const SizedBox(
// width: 8,
// ),
// Consumer<ServiceReportLastCallsProvider>(
// builder: (_, provider, __) {
// if (provider.isLoading == null) return const SizedBox.shrink();
// return Expanded(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// ASubTitle(_subtitle.callLastSituation),
// _validate && _serviceReport.callLastSituation == null
// ? ASubTitle(
// _subtitle.requiredWord,
// color: Colors.red,
// )
// : const SizedBox.shrink(),
// const SizedBox(
// height: 4,
// ),
// ServiceReportLastCallsMenu(
// report: _serviceReport,
// onSelect: (status) {
// if (status?.value == 12 || _serviceReport.callLastSituation?.value == 12) {
// _serviceReport.callLastSituation = status;
// setState(() {});
// } else {
// _serviceReport.callLastSituation = status;
// }
// },
// ),
// ],
// ),
// );
// },
// ),
// ],
// ),
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
@ -467,10 +612,74 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
// }, // },
// ), // ),
// const SizedBox(height: 8,), // const SizedBox(height: 8,),
const SizedBox(height: 8),
ASubTitle(_subtitle.workingHours),
const SizedBox(height: 8),
Row(
children: [
Expanded(
child: AppTimer(
timer: _serviceReport.timer,
enabled: false,
// onChange: (timer) async {
// _serviceReport.timer = timer;
// _serviceReport.workingHours = num.tryParse((((timer?.durationInSecond ?? 0) / 60) / 60)?.toStringAsFixed(2) ?? "0");
// return true;
// },
),
),
],
),
const SizedBox(height: 16),
if (_showCommentField)
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
if (_showCommentField)
ATextFormField(
initialValue: _serviceReport?.reviewComment,
hintText: "Review Comment",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
textInputType: TextInputType.multiline,
onSaved: (value) {
_serviceReport.reviewComment = value;
},
),
SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
),
const SizedBox(height: 8),
ASubTitle(_subtitle.faultDescription),
const SizedBox(
height: 4,
),
ServiceReportFaultDescription(
requestId: widget.request?.id,
initialValue: _serviceReport.faultDescription,
onSelect: (status) {
print("faluttt:${status?.toJson()}");
_serviceReport.faultDescription = status;
if (mounted) setState(() {});
},
),
const SizedBox(height: 8),
ASubTitle(_subtitle.workPreformed),
const SizedBox(height: 4),
ATextFormField(
initialValue: _serviceReport?.workPreformed,
textAlign: TextAlign.center,
enable: false,
hintText: _serviceReport.faultDescription?.workPerformed ?? "",
controller: _workPreformedController,
style: Theme.of(context).textTheme.subtitle1,
validator: (value) => Validator.hasValue(value) ? null : _subtitle.requiredWord,
textInputType: TextInputType.multiline,
onSaved: (value) {
// _serviceReport.workPreformed = value;
},
),
const SizedBox(height: 4),
Row( Row(
children: [ children: [
// reasons // reasons
@ -515,74 +724,118 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
// Traveling Hours & Working Hours const SizedBox(height: 8),
Row( ASubTitle(_subtitle.repairLocation),
children: [ const SizedBox(height: 4),
Expanded( ServiceReportRepairLocation(
child: Column( initialValue: _serviceReport.repairLocation,
crossAxisAlignment: CrossAxisAlignment.start, onSelect: (status) {
children: [ _serviceReport.repairLocation = status;
ASubTitle(_subtitle.workingHours),
const SizedBox(
height: 8,
),
Row(
children: [
Expanded(
child: AppTimer(
timer: _serviceReport.timer,
onChange: (timer) async {
_serviceReport.timer = timer;
return true;
}, },
), ),
const SizedBox(height: 16),
ASubTitle(_subtitle.travelingExpense),
const SizedBox(
height: 4,
), ),
], ATextFormField(
initialValue: _serviceReport?.travelingExpense?.toString(),
hintText: _subtitle.travelingExpense,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
textInputType: TextInputType.number,
onSaved: (value) {
if (value != null && value.isEmpty) {
_serviceReport.travelingExpense = int.tryParse(_serviceReport?.travelingExpense?.toString() ?? "") ?? 0;
} else
_serviceReport.travelingExpense = int.tryParse(value) ?? 0;
},
), ),
// ATextFormField(
// initialValue: _serviceReport?.workHours, const SizedBox(height: 8),
// textAlign: TextAlign.center, ASubTitle(_subtitle.travelingHours),
// hintText: "i.e 3, 3.5, 4", const SizedBox(height: 4),
// style: Theme.of(context).textTheme.subtitle1, ATextFormField(
initialValue: _serviceReport?.travelingHours?.toString(),
textAlign: TextAlign.center,
hintText: "i.e 3, 3.5, 4",
style: Theme.of(context).textTheme.subtitle1,
// validator: (value) => // validator: (value) =>
// Validator.isNumeric(value) // Validator.isNumeric(value)
// ? null : _subtitle.requiredWord, // ? null : _subtitle.requiredWord,
// textInputType: TextInputType.number, textInputType: TextInputType.number,
// onSaved: (value){ onSaved: (value) {
// _serviceReport.workHours = value; _serviceReport.travelingHours = double.tryParse(value) ?? 0.0;
// }, },
// ),
],
),
), ),
// const SizedBox(width: 8,), // Traveling Hours & Working Hours
// Row(
// children: [
// Expanded( // Expanded(
// child: Column( // child: Column(
// crossAxisAlignment: CrossAxisAlignment.start, // crossAxisAlignment: CrossAxisAlignment.start,
// children: [ // children: [
// ASubTitle(_subtitle.travelingHours), // ASubTitle(_subtitle.workingHours),
// const SizedBox(height: 4,), // const SizedBox(
// ATextFormField( // height: 8,
// initialValue: _serviceReport?.travelingHours, // ),
// textAlign: TextAlign.center, // Row(
// hintText: "i.e 3, 3.5, 4", // children: [
// style: Theme.of(context).textTheme.subtitle1, // Expanded(
// validator: (value) => // child: AppTimer(
// Validator.isNumeric(value) // timer: _serviceReport.timer,
// ? null : _subtitle.requiredWord, // onChange: (timer) async {
// textInputType: TextInputType.number, // _serviceReport.timer = timer;
// onSaved: (value){ // return true;
// _serviceReport.travelingHours = value;
// }, // },
// ), // ),
// ),
// ], // ],
// ), // ),
// // ATextFormField(
// // initialValue: _serviceReport?.workHours,
// // textAlign: TextAlign.center,
// // hintText: "i.e 3, 3.5, 4",
// // style: Theme.of(context).textTheme.subtitle1,
// // validator: (value) =>
// // Validator.isNumeric(value)
// // ? null : _subtitle.requiredWord,
// // textInputType: TextInputType.number,
// // onSaved: (value){
// // _serviceReport.workHours = value;
// // },
// // ),
// ],
// ),
// ),
// // const SizedBox(width: 8,),
// // Expanded(
// // child: Column(
// // crossAxisAlignment: CrossAxisAlignment.start,
// // children: [
// // ASubTitle(_subtitle.travelingHours),
// // const SizedBox(height: 4,),
// // ATextFormField(
// // initialValue: _serviceReport?.travelingHours,
// // textAlign: TextAlign.center,
// // hintText: "i.e 3, 3.5, 4",
// // style: Theme.of(context).textTheme.subtitle1,
// // validator: (value) =>
// // Validator.isNumeric(value)
// // ? null : _subtitle.requiredWord,
// // textInputType: TextInputType.number,
// // onSaved: (value){
// // _serviceReport.travelingHours = value;
// // },
// // ),
// // ],
// // ),
// // ),
// ],
// ),
// const SizedBox(
// height: 8,
// ), // ),
],
),
const SizedBox(
height: 8,
),
// Operating Hours and Job Sheet Number // Operating Hours and Job Sheet Number
// Row( // Row(
// children: [ // children: [
@ -630,14 +883,26 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
// ], // ],
// ), // ),
//const SizedBox(height: 8,), //const SizedBox(height: 8,),
const SizedBox(
height: 8, const SizedBox(height: 8),
ASubTitle(_subtitle.comment),
const SizedBox(height: 4),
ATextFormField(
initialValue: _serviceReport?.comment,
hintText: "Technical Comment",
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
textInputType: TextInputType.multiline,
onSaved: (value) {
_serviceReport.comment = value;
},
), ),
const SizedBox(height: 8),
const ASubTitle("Nurse Signature"), const ASubTitle("Nurse Signature"),
ESignature( ESignature(
oldSignature: _serviceReport.signatureNurse, oldSignature: _serviceReport.signatureNurse,
newSignature: _serviceReport.localNurseSignature, newSignature: _serviceReport.localNurseSignature,
onChange: (signature) { onSaved: (signature) {
if (signature == null || signature.isEmpty) { if (signature == null || signature.isEmpty) {
return; return;
} }
@ -652,7 +917,7 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
ESignature( ESignature(
oldSignature: _serviceReport.signatureEngineer, oldSignature: _serviceReport.signatureEngineer,
newSignature: _serviceReport.localNurseSignature, newSignature: _serviceReport.localNurseSignature,
onChange: (signature) { onSaved: (signature) {
if (signature == null || signature.isEmpty) { if (signature == null || signature.isEmpty) {
return; return;
} }
@ -664,6 +929,25 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
height: 8, height: 8,
), ),
// Part Number and Quantity // Part Number and Quantity
],
),
),
],
),
ASubTitle("Spare Parts"),
Container(
width: double.infinity,
padding: const EdgeInsets.all(16),
margin: const EdgeInsets.symmetric(vertical: 16),
decoration: BoxDecoration(color: AColors.grey, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [
BoxShadow(
color: AColors.grey,
offset: Offset(0, -1),
)
]),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row( Row(
children: [ children: [
Expanded( Expanded(
@ -713,27 +997,34 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
); );
}), }),
), ),
const SizedBox( const SizedBox(
height: 16, height: 16,
), ),
], ],
), ),
), ),
Padding( AButton(
padding: const EdgeInsets.all(16.0),
child: AButton(
text: _subtitle.update, text: _subtitle.update,
onPressed: () async { onPressed: () async {
_validate = true; if (_serviceReport?.workingHours == null) {
if (!_formKey.currentState.validate()) { await Fluttertoast.showToast(msg: "Working Hours Timer Isn't Started");
setState(() {});
return; return;
} } else if ((_serviceReport?.timer?.stopped ?? false) == false) {
if (!_serviceReport.validate()) { await Fluttertoast.showToast(msg: "Stop The Timer");
setState(() {});
return; return;
} }
_validate = true;
print("jere1245");
// if (!_formKey.currentState.validate()) {
// setState(() {});
// return;
// }
// print("jere124");
// if (!_serviceReport.validate()) {
// setState(() {});
// return;
// }
// print("jere14");
_formKey.currentState.save(); _formKey.currentState.save();
_isLoading = true; _isLoading = true;
@ -756,10 +1047,6 @@ class _EditServiceReportState extends State<EditServiceReport> with TickerProvid
} }
}, },
), ),
),
const SizedBox(
height: 300,
)
], ],
), ),
const ABackButton(), const ABackButton(),

@ -31,6 +31,8 @@ class _FutureServiceReportState extends State<FutureServiceReport> {
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
Subtitle _subtitle = AppLocalization.of(context).subtitle; Subtitle _subtitle = AppLocalization.of(context).subtitle;
ServiceRequestsProvider().getSingleServiceReport(reportId: widget.workOrder.id, user: _userProvider.user, host: _settingProvider.host, subtitle: _subtitle)
;
return Scaffold( return Scaffold(
body: FutureBuilder<ServiceReport>( body: FutureBuilder<ServiceReport>(
future: ServiceRequestsProvider().getSingleServiceReport(reportId: widget.workOrder.id, user: _userProvider.user, host: _settingProvider.host, subtitle: _subtitle), future: ServiceRequestsProvider().getSingleServiceReport(reportId: widget.workOrder.id, user: _userProvider.user, host: _settingProvider.host, subtitle: _subtitle),

@ -345,7 +345,7 @@ class RequestDetailsPage extends StatelessWidget {
title: _subtitle.visitDate, title: _subtitle.visitDate,
info: workOrders[index].visitDate, info: workOrders[index].visitDate,
), ),
RequestInfoRow(title: _subtitle.assignedEmployee, info: workOrders[index].assignedEmployee.name), RequestInfoRow(title: _subtitle.assignedEmployee, info: workOrders[index].assignedEmployee?.name??""),
RequestInfoRow( RequestInfoRow(
title: _subtitle.assetSN, title: _subtitle.assetSN,
info: workOrders[index].callRequest.asset.assetSerialNo, info: workOrders[index].callRequest.asset.assetSerialNo,

@ -14,10 +14,11 @@ import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart'; import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/pentry/pentry_calibration_tool_form.dart'; import 'package:test_sa/views/widgets/pentry/pentry_calibration_tool_form.dart';
import 'package:test_sa/views/widgets/pentry/pentry_info_form.dart';
import 'package:test_sa/views/widgets/pentry/pentry_pm_kit_form.dart'; import 'package:test_sa/views/widgets/pentry/pentry_pm_kit_form.dart';
import 'package:test_sa/views/widgets/pentry/pentry_ppm_check_list_form.dart'; import 'package:test_sa/views/widgets/pentry/pentry_ppm_check_list_form.dart';
import '../../../../widgets/pentry/pentry_info_form.dart';
class EditPentry extends StatefulWidget { class EditPentry extends StatefulWidget {
final Pentry pentry; final Pentry pentry;
final Visit visit; final Visit visit;
@ -73,7 +74,7 @@ class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateM
if (_pentry.pmKits.isEmpty) _pentry.pmKits.add(PMKit()); if (_pentry.pmKits.isEmpty) _pentry.pmKits.add(PMKit());
if (_pentry.calibrationTools.isEmpty) _pentry.calibrationTools.add(CalibrationTool()); if (_pentry.calibrationTools.isEmpty) _pentry.calibrationTools.add(CalibrationTool());
if (_pentry.ppmCheckLists.isEmpty) _pentry.ppmCheckLists.add(PPMCheckList()); if (_pentry.ppmCheckLists.isEmpty) _pentry.ppmCheckLists.add(PPMCheckList());
_tabController = TabController(length: 3, vsync: this); _tabController = TabController(length: 4, vsync: this);
super.initState(); super.initState();
} }
@ -113,16 +114,17 @@ class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateM
Tab( Tab(
text: "PPM Check List", text: "PPM Check List",
), ),
// Tab(
// text: "Calibration Tools",
// ),
Tab( Tab(
text: "PK Kits", text: "Calibration Tools",
),
Tab(
text: "PM Kits",
), ),
Tab( Tab(
text: "Pentry", text: "PM Entry",
),
],
), ),
]),
), ),
), ),
Expanded( Expanded(
@ -147,7 +149,7 @@ class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateM
PentryInfoForm( PentryInfoForm(
model: _pentry, model: _pentry,
enableValidate: _validate, enableValidate: _validate,
) ),
], ],
), ),
Align( Align(

@ -21,7 +21,7 @@ class DeviceTransferInfoSection extends StatelessWidget {
info: info.client.name, info: info.client.name,
), ),
RequestInfoRow( RequestInfoRow(
title: subtitle.unite, title: subtitle.department,
info: info.department.name, info: info.department.name,
), ),
RequestInfoRow( RequestInfoRow(

@ -1,4 +1,3 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
@ -53,6 +52,13 @@ class DeviceTransferItem extends StatelessWidget {
Divider( Divider(
color: onItemColor, color: onItemColor,
), ),
Text(
item.device?.number ?? "-----",
style: Theme.of(context).textTheme.headline6.copyWith(color: onItemColor, fontSize: 16, fontWeight: FontWeight.bold),
),
Divider(
color: onItemColor,
),
Row( Row(
children: [ children: [
Expanded( Expanded(

@ -27,12 +27,19 @@ class DeviceItem extends StatelessWidget {
}, },
child: ListTile( child: ListTile(
title: Text( title: Text(
"${_subtitle.sn} : ${device.serialNumber}", "${_subtitle.assetName} : \n${device.modelDefinition.assetName}",
style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white), style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white),
), ),
subtitle: Column( subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Divider(
color: Theme.of(context).scaffoldBackgroundColor,
),
Text(
"${_subtitle.assetNumber} : ${device.number}",
style: Theme.of(context).textTheme.subtitle1.copyWith(color: AColors.white),
),
Divider( Divider(
color: Theme.of(context).scaffoldBackgroundColor, color: Theme.of(context).scaffoldBackgroundColor,
), ),

@ -33,20 +33,20 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
TextEditingController numberController = TextEditingController(); TextEditingController numberController = TextEditingController();
TextEditingController snController = TextEditingController(); TextEditingController snController = TextEditingController();
_getDevice(String result) async { _getDevice(String result) async {
print(result);
if (result == null) return; if (result == null) return;
showDialog( // List<Device> devices = await _devicesProvider.getDevicesListBySN(host: _settingProvider.host, user: _userProvider.user, hospitalId: _userProvider.user.clientId, sn: result);
barrierDismissible: false, _devicesProvider.reset();
context: context, await _devicesProvider.getEquipment(user: _userProvider.user, host: _settingProvider.host, hospitalId: _userProvider.user.clientId, serialNumber: "", number: result);
builder: (dialogContext) { _searchableList.clear();
return const Center(child: CircularProgressIndicator()); _searchableList.addAll(_devicesProvider.devices);
}); // Navigator.of(context).pop();
List<Device> devices = await _devicesProvider.getDevicesListBySN(host: _settingProvider.host, user: _userProvider.user, hospitalId: _userProvider.user.clientId, sn: result); // Navigator.of(context).pop();
Navigator.of(context).pop(); // if (devices.isEmpty) {
if (devices.isEmpty) { // Fluttertoast.showToast(msg: _subtitle.noDeviceFound);
Fluttertoast.showToast(msg: _subtitle.noDeviceFound); // return;
return; // }
} // Navigator.of(context).pop(devices.first);
Navigator.of(context).pop(devices.first);
} }
@override @override
@ -74,7 +74,8 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
_subtitle = AppLocalization.of(context).subtitle; _subtitle = AppLocalization.of(context).subtitle;
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false, resizeToAvoidBottomInset: false,
body: LoadingManager( body: SafeArea(
child: LoadingManager(
isLoading: _devicesProvider.isLoading, isLoading: _devicesProvider.isLoading,
stateCode: _devicesProvider.stateCode, stateCode: _devicesProvider.stateCode,
isFailedLoading: _devicesProvider.devices == null, isFailedLoading: _devicesProvider.devices == null,
@ -84,7 +85,7 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
}, },
child: Column( child: Column(
children: [ children: [
const SizedBox(height: 48), const SizedBox(height: 16),
Padding( Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16), padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: Column( child: Column(
@ -105,8 +106,7 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
), ),
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),ATextFormField(
ATextFormField(
hintText: _subtitle.searchBySn, hintText: _subtitle.searchBySn,
controller: snController, controller: snController,
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
@ -120,6 +120,7 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
_searchableList.addAll(_devicesProvider.devices); _searchableList.addAll(_devicesProvider.devices);
}, },
), ),
], ],
), ),
), ),
@ -151,6 +152,7 @@ class _SingleDevicePickerState extends State<SingleDevicePicker> {
], ],
), ),
), ),
),
floatingActionButton: FloatingActionButton( floatingActionButton: FloatingActionButton(
heroTag: "some tag 2", heroTag: "some tag 2",
child: const Icon(Icons.qr_code_scanner), child: const Icon(Icons.qr_code_scanner),

@ -6,8 +6,9 @@ import 'package:test_sa/views/widgets/buttons/app_icon_button2.dart';
class PartItem extends StatefulWidget { class PartItem extends StatefulWidget {
final Part part; final Part part;
final Function(Part) onDelete; final Function(Part) onDelete;
final Function(int qty) onEdit;
const PartItem({Key key, this.part, this.onDelete}) : super(key: key); const PartItem({Key key, this.part, this.onEdit, this.onDelete}) : super(key: key);
@override @override
_PartItemState createState() => _PartItemState(); _PartItemState createState() => _PartItemState();
@ -19,7 +20,7 @@ class _PartItemState extends State<PartItem> {
//final _subtitle = AppLocalization.of(context).subtitle; //final _subtitle = AppLocalization.of(context).subtitle;
return Column( return Column(
children: [ children: [
Divider(), const Divider(),
Row( Row(
children: [ children: [
Expanded( Expanded(
@ -30,7 +31,7 @@ class _PartItemState extends State<PartItem> {
children: [ children: [
Expanded( Expanded(
child: Text( child: Text(
widget.part.code, widget?.part?.code ?? "",
style: Theme.of(context).textTheme.bodyText1.copyWith(fontSize: 12, fontWeight: FontWeight.bold), style: Theme.of(context).textTheme.bodyText1.copyWith(fontSize: 12, fontWeight: FontWeight.bold),
), ),
), ),
@ -38,7 +39,11 @@ class _PartItemState extends State<PartItem> {
iconData: Icons.add, iconData: Icons.add,
color: Theme.of(context).primaryColor, color: Theme.of(context).primaryColor,
onPressed: () { onPressed: () {
widget.part.quantity++; if (widget.onEdit == null) {
++widget.part.quantity;
} else {
widget.onEdit(++widget.part.quantity);
}
setState(() {}); setState(() {});
}, },
), ),
@ -48,7 +53,11 @@ class _PartItemState extends State<PartItem> {
onPressed: widget.part.quantity < 2 onPressed: widget.part.quantity < 2
? null ? null
: () { : () {
widget.part.quantity--; if (widget.onEdit == null) {
--widget.part.quantity;
} else {
widget.onEdit(--widget.part.quantity);
}
setState(() {}); setState(() {});
}, },
), ),
@ -68,7 +77,7 @@ class _PartItemState extends State<PartItem> {
], ],
), ),
widget.part.name == null widget.part.name == null
? SizedBox.shrink() ? const SizedBox.shrink()
: Text( : Text(
widget.part.name, widget.part.name,
style: Theme.of(context).textTheme.caption.copyWith(fontSize: 11, fontWeight: FontWeight.bold), style: Theme.of(context).textTheme.caption.copyWith(fontSize: 11, fontWeight: FontWeight.bold),
@ -76,7 +85,8 @@ class _PartItemState extends State<PartItem> {
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
], ],
)), ),
),
AIconButton2( AIconButton2(
iconData: Icons.close, iconData: Icons.close,
color: Colors.red, color: Colors.red,

@ -43,9 +43,8 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
); );
} }
final model = widget.models[index]; final model = widget.models[index];
return ListView( return Column(
shrinkWrap: true, crossAxisAlignment: CrossAxisAlignment.start,
physics: const ClampingScrollPhysics(),
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,

@ -1,7 +1,6 @@
import 'dart:convert'; import 'dart:convert';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/localization/localization.dart'; import 'package:test_sa/controllers/localization/localization.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
@ -15,6 +14,8 @@ import 'package:test_sa/views/widgets/status/pentry/pentry_visit_status_mune.dar
import 'package:test_sa/views/widgets/timer/app_timer.dart'; import 'package:test_sa/views/widgets/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 '../status/pentry/pentry_status_mune.dart';
class PentryInfoForm extends StatefulWidget { class PentryInfoForm extends StatefulWidget {
final Pentry model; final Pentry model;
final bool enableValidate; final bool enableValidate;
@ -79,16 +80,21 @@ class _PentryInfoFormState extends State<PentryInfoForm> {
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
// const ASubTitle("Status"), const ASubTitle("Status"),
// // if(widget.enableValidate && widget.model.status == null) if (widget.enableValidate && widget.model.status == null)
// // ASubTitle(subtitle.requiredWord,color: Colors.red,), ASubTitle(
// const SizedBox(height: 4,), subtitle.requiredWord,
// PentryStatusMenu( color: Colors.red,
// initialValue: widget.model.status, ),
// onSelect: (status){ const SizedBox(
// widget.model.status = status; height: 4,
// }, ),
// ), PentryStatusMenu(
initialValue: widget.model.status,
onSelect: (status) {
widget.model.status = status;
},
),
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),

@ -27,8 +27,13 @@ class _PentryPMKitFormState extends State<PentryPMKitForm> {
final subtitle = AppLocalization.of(context).subtitle; final subtitle = AppLocalization.of(context).subtitle;
return ListView.builder( return ListView.builder(
padding: EdgeInsets.only( padding: EdgeInsets.only(
top: 12 * AppStyle.getScaleFactor(context), left: 12 * AppStyle.getScaleFactor(context), right: 12 * AppStyle.getScaleFactor(context), bottom: 80 * AppStyle.getScaleFactor(context)), top: 12 * AppStyle.getScaleFactor(context),
left: 12 * AppStyle.getScaleFactor(context),
right: 12 * AppStyle.getScaleFactor(context),
bottom: 100 * AppStyle.getScaleFactor(context) + MediaQuery.of(context).padding.bottom,
),
itemCount: widget.models.length + 1, itemCount: widget.models.length + 1,
shrinkWrap: true,
itemBuilder: (context, index) { itemBuilder: (context, index) {
if (index == widget.models.length) { if (index == widget.models.length) {
return AButton( return AButton(
@ -40,9 +45,8 @@ class _PentryPMKitFormState extends State<PentryPMKitForm> {
); );
} }
final model = widget.models[index]; final model = widget.models[index];
return ListView( return Column(
shrinkWrap: true, crossAxisAlignment: CrossAxisAlignment.start,
physics: const ClampingScrollPhysics(),
children: [ children: [
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -76,83 +80,12 @@ class _PentryPMKitFormState extends State<PentryPMKitForm> {
const SizedBox( const SizedBox(
height: 8, height: 8,
), ),
// const ASubTitle("Item Name"),
// const SizedBox(height: 4,),
// ATextFormField(
// initialValue: (model.itemName ?? "").toString(),
// textAlign: TextAlign.center,
// style: Theme.of(context).textTheme.subtitle1,
// textInputType: TextInputType.text,
// onChange: (value){
// model.itemName = value;
// },
// ),
// const SizedBox(height: 8,),
// const ASubTitle("Preparation Time Frame"),
// const SizedBox(height: 4,),
// ATextFormField(
// initialValue: (model.preparationTimeFrame ?? "").toString(),
// textAlign: TextAlign.center,
// style: Theme.of(context).textTheme.subtitle1,
// textInputType: TextInputType.text,
// onChange: (value){
// model.preparationTimeFrame = value;
// },
// ),
// const SizedBox(height: 8,),
// const ASubTitle("kit Frequency Demand"),
// const SizedBox(height: 4,),
// ATextFormField(
// initialValue: (model.kitFrequencyDemand ?? "").toString(),
// textAlign: TextAlign.center,
// style: Theme.of(context).textTheme.subtitle1,
// textInputType: TextInputType.text,
// onChange: (value){
// model.kitFrequencyDemand = value;
// },
// ),
// const SizedBox(height: 8,),
// const ASubTitle("Availability"),
// const SizedBox(height: 4,),
// ATextFormField(
// initialValue: (model.availability ?? "").toString(),
// textAlign: TextAlign.center,
// style: Theme.of(context).textTheme.subtitle1,
// textInputType: TextInputType.text,
// onChange: (value){
// model.availability = value;
// },
// ),
// const SizedBox(height: 8,),
// const ASubTitle("Quantity Needed"),
// const SizedBox(height: 4,),
// ATextFormField(
// initialValue: (model.quantityNeeded ?? "").toString(),
// textAlign: TextAlign.center,
// style: Theme.of(context).textTheme.subtitle1,
// textInputType: TextInputType.number,
// onChange: (value){
// model.quantityNeeded = value;
// },
// ),
// const SizedBox(height: 8,),
// const ASubTitle("Quantity Reserved"),
// const SizedBox(height: 4,),
// ATextFormField(
// initialValue: (model.quantityReserved ?? "").toString(),
// textAlign: TextAlign.center,
// style: Theme.of(context).textTheme.subtitle1,
// textInputType: TextInputType.number,
// onChange: (value){
// model.quantityReserved = value;
// },
// ),
// const SizedBox(height: 8,),
Divider( Divider(
color: Theme.of(context).textTheme.titleMedium.color, color: Theme.of(context).textTheme.titleMedium.color,
), ),
], ],
); );
}); },
);
} }
} }

@ -27,7 +27,7 @@ class _SingleAssistantEmployeeMenuState extends State<AssistantEmployeeMenu> {
void didUpdateWidget(covariant AssistantEmployeeMenu oldWidget) { void didUpdateWidget(covariant AssistantEmployeeMenu oldWidget) {
if (widget.initialStatus != null) { if (widget.initialStatus != null) {
final result = widget.statuses?.where((element) { final result = widget.statuses?.where((element) {
return element == widget.initialStatus; return element?.user?.id == widget.initialStatus?.user?.id;
}); });
if (result.isNotEmpty) { if (result.isNotEmpty) {
_selectedStatus = result.first; _selectedStatus = result.first;
@ -47,7 +47,7 @@ class _SingleAssistantEmployeeMenuState extends State<AssistantEmployeeMenu> {
void initState() { void initState() {
if (widget.initialStatus != null) { if (widget.initialStatus != null) {
final result = widget.statuses?.where((element) { final result = widget.statuses?.where((element) {
return element == widget.initialStatus; return element?.user?.id == widget.initialStatus?.user?.id;
}); });
if (result.isNotEmpty) _selectedStatus = result.first; if (result.isNotEmpty) _selectedStatus = result.first;
if (widget.initialStatus?.user?.id != _selectedStatus?.user?.id) { if (widget.initialStatus?.user?.id != _selectedStatus?.user?.id) {

@ -10,8 +10,9 @@ import 'package:test_sa/views/widgets/status/single_status_menu.dart';
class GasStatusMenu extends StatelessWidget { class GasStatusMenu extends StatelessWidget {
final Function(Lookup) onSelect; final Function(Lookup) onSelect;
final Lookup initialValue; final Lookup initialValue;
final bool enabled;
const GasStatusMenu({Key key, this.onSelect, this.initialValue}) : super(key: key); const GasStatusMenu({Key key, this.enabled = true, this.onSelect, this.initialValue}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final settingProvider = Provider.of<SettingProvider>(context); final settingProvider = Provider.of<SettingProvider>(context);
@ -29,6 +30,7 @@ class GasStatusMenu extends StatelessWidget {
initialStatus: initialValue, initialStatus: initialValue,
statuses: menuProvider.items, statuses: menuProvider.items,
onSelect: onSelect, onSelect: onSelect,
enabled: enabled,
)); ));
} }
} }

@ -26,7 +26,7 @@ class _SingleStatusMenuState extends State<FaultDescriptionMenu> {
void didUpdateWidget(covariant FaultDescriptionMenu oldWidget) { void didUpdateWidget(covariant FaultDescriptionMenu oldWidget) {
if (widget.initialStatus != null) { if (widget.initialStatus != null) {
final result = widget.statuses?.where((element) { final result = widget.statuses?.where((element) {
return element == widget.initialStatus; return element.id == widget.initialStatus.id;
}); });
if (result.isNotEmpty) { if (result.isNotEmpty) {
_selectedStatus = result.first; _selectedStatus = result.first;
@ -44,9 +44,11 @@ class _SingleStatusMenuState extends State<FaultDescriptionMenu> {
@override @override
void initState() { void initState() {
if (widget.initialStatus != null) { if (widget.initialStatus != null) {
final result = widget.statuses?.where((element) { final result = widget.statuses?.where((element) {
return element == widget.initialStatus;
return element.id == widget.initialStatus.id;
}); });
if (result.isNotEmpty) _selectedStatus = result.first; if (result.isNotEmpty) _selectedStatus = result.first;
if (widget.initialStatus.id != _selectedStatus?.id) { if (widget.initialStatus.id != _selectedStatus?.id) {

@ -63,7 +63,7 @@ class _ServiceReportEquipmentStatusMenuState extends State<ServiceReportEquipmen
callsLastSituationsProvider.getCalls( callsLastSituationsProvider.getCalls(
user: userProvider.user, user: userProvider.user,
host: settingProvider.host, host: settingProvider.host,
serviceStatus: status.id, serviceStatus: status?.id,
id: widget.report?.id, id: widget.report?.id,
woId: widget.request?.id, woId: widget.request?.id,
typeName: widget.report?.type?.name, typeName: widget.report?.type?.name,

@ -14,6 +14,7 @@ class ServiceReportLastCallsMenu extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
ServiceReportLastCallsProvider _menuProvider = Provider.of<ServiceReportLastCallsProvider>(context); ServiceReportLastCallsProvider _menuProvider = Provider.of<ServiceReportLastCallsProvider>(context);
print("report?.callLastSituation:${report?.callLastSituation?.toMap()}");
return LoadingManager( return LoadingManager(
isLoading: _menuProvider.isLoading, isLoading: _menuProvider.isLoading,
isFailedLoading: _menuProvider.calls == null, isFailedLoading: _menuProvider.calls == null,

@ -8,8 +8,14 @@ import 'package:test_sa/views/widgets/status/single_status_menu.dart';
class ServiceReportMaintenanceSituation extends StatelessWidget { class ServiceReportMaintenanceSituation extends StatelessWidget {
final Function(Lookup) onSelect; final Function(Lookup) onSelect;
final Lookup initialValue; final Lookup initialValue;
final String woId;
const ServiceReportMaintenanceSituation({Key key, @required this.onSelect, @required this.initialValue}) : super(key: key); const ServiceReportMaintenanceSituation({
Key key,
@required this.onSelect,
@required this.initialValue,
@required this.woId,
}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
ServiceReportMaintenanceSituationProvider menuProvider = Provider.of<ServiceReportMaintenanceSituationProvider>(context); ServiceReportMaintenanceSituationProvider menuProvider = Provider.of<ServiceReportMaintenanceSituationProvider>(context);
@ -18,7 +24,7 @@ class ServiceReportMaintenanceSituation extends StatelessWidget {
isFailedLoading: menuProvider.operators == null, isFailedLoading: menuProvider.operators == null,
stateCode: menuProvider.stateCode, stateCode: menuProvider.stateCode,
onRefresh: () async { onRefresh: () async {
menuProvider.getOperators(); menuProvider.getOperators(woId);
}, },
child: SingleStatusMenu( child: SingleStatusMenu(
initialStatus: initialValue, initialStatus: initialValue,

@ -7,8 +7,9 @@ class SingleStatusMenu extends StatefulWidget {
final List<Lookup> statuses; final List<Lookup> statuses;
final Lookup initialStatus; final Lookup initialStatus;
final Function(Lookup) onSelect; final Function(Lookup) onSelect;
final bool enabled;
const SingleStatusMenu({Key key, this.statuses, this.onSelect, this.initialStatus}) : super(key: key); const SingleStatusMenu({Key key, this.enabled = true, this.statuses, this.onSelect, this.initialStatus}) : super(key: key);
@override @override
_SingleStatusMenuState createState() => _SingleStatusMenuState(); _SingleStatusMenuState createState() => _SingleStatusMenuState();
@ -82,8 +83,10 @@ class _SingleStatusMenuState extends State<SingleStatusMenu> {
style: Theme.of(context).textTheme.subtitle1, style: Theme.of(context).textTheme.subtitle1,
), ),
style: TextStyle(color: Theme.of(context).primaryColor), style: TextStyle(color: Theme.of(context).primaryColor),
underline: SizedBox.shrink(), underline: const SizedBox.shrink(),
onChanged: (Lookup newValue) { onChanged: widget.enabled == false
? null
: (Lookup newValue) {
setState(() { setState(() {
_selectedStatus = newValue; _selectedStatus = newValue;
}); });
@ -95,7 +98,7 @@ class _SingleStatusMenuState extends State<SingleStatusMenu> {
child: Text( child: Text(
value.name, value.name,
style: Theme.of(context).textTheme.subtitle1.copyWith( style: Theme.of(context).textTheme.subtitle1.copyWith(
color: Theme.of(context).primaryColor, color: widget.enabled ? Theme.of(context).primaryColor : Colors.grey,
fontSize: 11, fontSize: 11,
//fontWeight: FontWeight.bold //fontWeight: FontWeight.bold
), ),

@ -9,11 +9,13 @@ class AppTimer extends StatefulWidget {
final TimerModel timer; final TimerModel timer;
final Future<bool> Function(TimerModel) onChange; final Future<bool> Function(TimerModel) onChange;
final TextStyle style; final TextStyle style;
final bool enabled;
const AppTimer({ const AppTimer({
Key key, Key key,
this.timer, this.timer,
this.onChange, this.onChange,
this.style, this.style,
this.enabled = true,
}) : super(key: key); }) : super(key: key);
@override @override
@ -32,7 +34,7 @@ class _AppTimerState extends State<AppTimer> {
_startTimer() async { _startTimer() async {
if (!_running) { if (!_running) {
final time = DateTime.now(); final time = DateTime.now();
bool result = await widget.onChange(TimerModel(startAt: time, endAt: null, durationInSecond: _delay)); bool result = await widget.onChange(TimerModel(startAt: time, endAt: null, durationInSecond: _delay, stopped: false));
if (!result) return; if (!result) return;
_running = true; _running = true;
@ -52,7 +54,7 @@ class _AppTimerState extends State<AppTimer> {
_stopTimer() async { _stopTimer() async {
final time = DateTime.now(); final time = DateTime.now();
final tempStartAt = _startAt.add(Duration(seconds: _delay)); final tempStartAt = _startAt.add(Duration(seconds: _delay));
bool result = await widget.onChange(TimerModel(startAt: tempStartAt, endAt: time, durationInSecond: _delay)); bool result = await widget.onChange(TimerModel(startAt: tempStartAt, endAt: time, durationInSecond: _delay, stopped: true));
if (!result) return; if (!result) return;
_running = false; _running = false;
_endAt = time; _endAt = time;
@ -99,7 +101,7 @@ class _AppTimerState extends State<AppTimer> {
child: ElevatedButton( child: ElevatedButton(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
minimumSize: const Size(1, 1), padding: EdgeInsets.all(4 * AppStyle.getScaleFactor(context)), backgroundColor: _running ? AColors.green[300] : AColors.grey, foregroundColor: Colors.black), minimumSize: const Size(1, 1), padding: EdgeInsets.all(4 * AppStyle.getScaleFactor(context)), backgroundColor: _running ? AColors.green[300] : AColors.grey, foregroundColor: Colors.black),
onPressed: _loading ? null : _onPressed, onPressed: _loading || widget.enabled == false ? null : _onPressed,
child: _loading child: _loading
? const SizedBox.square( ? const SizedBox.square(
dimension: 18, dimension: 18,
@ -108,7 +110,7 @@ class _AppTimerState extends State<AppTimer> {
)) ))
: Row( : Row(
children: [ children: [
Icon(_running ? Icons.pause : Icons.play_arrow), if (widget.enabled) Icon(_running ? Icons.pause : Icons.play_arrow),
Expanded( Expanded(
child: Center( child: Center(
child: ValueListenableBuilder<String>( child: ValueListenableBuilder<String>(
@ -116,7 +118,7 @@ class _AppTimerState extends State<AppTimer> {
builder: (context, value, _) { builder: (context, value, _) {
return Text( return Text(
value, value,
style: widget.style, style: widget.enabled ? widget.style : widget.style?.copyWith(color: Colors.black54),
); );
}), }),
), ),

Loading…
Cancel
Save