ppm issues fixed & code formatting

design_3.0_demo_module
zaid_daoud 2 years ago
parent df9fa59f1b
commit 7200efcbca

@ -69,7 +69,7 @@ class AllRequestsProvider extends ChangeNotifier {
allRequestsAndCount = AllRequestsAndCount.fromJson(json.decode(response.body)["data"]); allRequestsAndCount = AllRequestsAndCount.fromJson(json.decode(response.body)["data"]);
notifyListeners(); notifyListeners();
} else { } else {
allRequestsAndCount =null; allRequestsAndCount = null;
} }
isAllLoading = false; isAllLoading = false;
notifyListeners(); notifyListeners();
@ -91,7 +91,7 @@ class AllRequestsProvider extends ChangeNotifier {
try { try {
Map<String, dynamic> body = { Map<String, dynamic> body = {
"typeTransaction": [1, 2, 3, 4], "typeTransaction": [1, 2, 3, 4],
"statusTransaction": [1, 2, 3,4], "statusTransaction": [1, 2, 3, 4],
"priority": [0, 1], "priority": [0, 1],
"displayData": [], "displayData": [],
"from": from.toIso8601String(), "from": from.toIso8601String(),

@ -153,7 +153,7 @@ class GasRefillProvider extends ChangeNotifier {
if (newModel.timer?.endAt != null) "endDate": newModel.timer.endAt.toIso8601String(), if (newModel.timer?.endAt != null) "endDate": newModel.timer.endAt.toIso8601String(),
if (newModel.timer?.endAt != null) "endTime": newModel.timer.endAt.toIso8601String(), if (newModel.timer?.endAt != null) "endTime": newModel.timer.endAt.toIso8601String(),
// "workingHours": ((endDate?.difference(startDate)?.inMinutes ?? 0) / 60), // "workingHours": ((endDate?.difference(startDate)?.inMinutes ?? 0) / 60),
'workingHours': newModel.timer.durationInSecond != null ? newModel.timer.durationInSecond / 60 / 60 : newModel.workingHours, 'workingHours': newModel.timer?.durationInSecond != null ? newModel.timer.durationInSecond / 60 / 60 : newModel.workingHours,
"assignedEmployee": oldModel?.assignedEmployee?.id == null ? null : oldModel?.assignedEmployee?.toJson(), "assignedEmployee": oldModel?.assignedEmployee?.id == null ? null : oldModel?.assignedEmployee?.toJson(),
"site": hospital?.toMap(), "site": hospital?.toMap(),
"building": building?.toJson(includeFloors: false), "building": building?.toJson(includeFloors: false),

@ -88,13 +88,13 @@ class PartsProvider 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<List<SparePart>> getPartsList({num assetId, String title}) async { Future<List<SparePart>> getPartsList({num assetId, String partNo, String partName}) async {
Response response; Response response;
try { try {
if (int.tryParse(title ?? "") != null) { if (partNo != null) {
response = await ApiManager.instance.post(URLs.getPartNumber, body: {if (title != null && title.isNotEmpty) "partNo": title, "assetId": assetId}); response = await ApiManager.instance.post(URLs.getPartNumber, body: {"partNo": partNo, "assetId": assetId});
} else { } else {
response = await ApiManager.instance.post(URLs.getPartNumber, body: {if (title != null && title.isNotEmpty) "partName": title, "assetId": assetId}); response = await ApiManager.instance.post(URLs.getPartNumber, body: {"partName": partName, "assetId": assetId});
} }
List<SparePart> page = []; List<SparePart> page = [];
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {

@ -1,27 +1,25 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:logger/logger.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart'; import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/pantry/pentry.dart'; import 'package:test_sa/models/ppm/ppm.dart';
import 'package:test_sa/models/ppm/ppm_search.dart';
import 'package:test_sa/models/user.dart'; import 'package:test_sa/models/user.dart';
import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/models/visits/visits_group.dart';
import 'package:test_sa/models/visits/visits_search.dart';
import '../../../new_views/common_widgets/app_lazy_loading.dart'; import '../../../new_views/common_widgets/app_lazy_loading.dart';
class RegularVisitsProvider extends ChangeNotifier { class PpmProvider extends ChangeNotifier {
// number of items call in each request // number of items call in each request
final pageItemNumber = 12; final pageItemNumber = 12;
//reset provider data //reset provider data
void reset() { void reset() {
visits = null; ppms = null;
nextPage = true; nextPage = true;
stateCode = null; stateCode = null;
} }
@ -35,14 +33,14 @@ class RegularVisitsProvider extends ChangeNotifier {
bool nextPage = true; bool nextPage = true;
// list of user requests // list of user requests
List<Visit> visits; List<Ppm> ppms;
// when requests in-process _loading = true // when requests in-process _loading = true
// done _loading = true // done _loading = true
// failed _loading = false // failed _loading = false
bool isLoading; bool isLoading;
VisitsSearch visitsSearch = VisitsSearch(); PpmSearch visitsSearch = PpmSearch();
/// 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
@ -56,14 +54,14 @@ class RegularVisitsProvider extends ChangeNotifier {
}) async { }) async {
if (isLoading == true) return -2; if (isLoading == true) return -2;
isLoading = true; isLoading = true;
if (visits?.isEmpty ?? true) notifyListeners(); if (ppms?.isEmpty ?? true) notifyListeners();
Response response; Response response;
//userId = 397.toString(); // testing id to view data //userId = 397.toString(); // testing id to view data
try { try {
Map<String, dynamic> body = {}; Map<String, dynamic> body = {};
body.addAll(visitsSearch.toMap()); body.addAll(visitsSearch.toJson());
body["pageNumber"] = (visits?.length ?? 0) ~/ pageItemNumber + 1; body["pageNumber"] = (ppms?.length ?? 0) ~/ pageItemNumber + 1;
body["pageSize"] = pageItemNumber; body["pageSize"] = pageItemNumber;
response = await ApiManager.instance.post( response = await ApiManager.instance.post(
@ -81,9 +79,9 @@ class RegularVisitsProvider extends ChangeNotifier {
// client's request was successfully received // client's request was successfully received
try { try {
List requestsListJson = json.decode(response.body)["data"]; List requestsListJson = json.decode(response.body)["data"];
List<Visit> visits = requestsListJson.map((request) => Visit.fromJson(request)).toList(); List<Ppm> visits = requestsListJson.map((request) => Ppm.fromJson(request)).toList();
this.visits ??= []; ppms ??= [];
this.visits.addAll(visits); ppms.addAll(visits);
notifyListeners(); notifyListeners();
if (visits.length == pageItemNumber) { if (visits.length == pageItemNumber) {
nextPage = true; nextPage = true;
@ -91,7 +89,7 @@ class RegularVisitsProvider extends ChangeNotifier {
nextPage = false; nextPage = false;
} }
} catch (error) { } catch (error) {
Logger().e(error); log(error ?? "");
isLoading = false; isLoading = false;
stateCode = -1; stateCode = -1;
notifyListeners(); notifyListeners();
@ -103,26 +101,19 @@ class RegularVisitsProvider extends ChangeNotifier {
return response.statusCode; return response.statusCode;
} }
Future<Visit> getVisitObjectById(num id) async { Future<Ppm> getPpmById(num id) async {
try { try {
Map<String, dynamic> body = {}; visitsSearch.id = id;
body.addAll(visitsSearch.toMap()); visitsSearch.pageNumber = 1;
body["pageNumber"] = 1; visitsSearch.pageSize = 3;
body["pageSize"] = 3; Response response = await ApiManager.instance.post(URLs.getRegularVisits, body: visitsSearch.toJson());
body["id"] = id;
Response response = await ApiManager.instance.post(
URLs.getRegularVisits,
body: body,
);
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
List requestsListJson = json.decode(response.body)["data"]; List requestsListJson = json.decode(response.body)["data"];
List<Visit> visits = requestsListJson.map((request) => Visit.fromJson(request)).toList(); List<Ppm> visits = requestsListJson.map((request) => Ppm.fromJson(request)).toList();
return visits?.first; return visits?.firstWhere((element) => id == element.id, orElse: () => null);
} else {
return null;
} }
return null;
} catch (error) { } catch (error) {
return null; return null;
} }
@ -136,12 +127,12 @@ class RegularVisitsProvider extends ChangeNotifier {
Future<int> updateGroupOfVisits({ Future<int> updateGroupOfVisits({
@required String host, @required String host,
@required User user, @required User user,
VisitsGroup group, // VisitsGroup group,
}) async { }) async {
Response response; Response response;
try { try {
Map<String, dynamic> body = group.toJson(); Map<String, dynamic> body = {} /*group.toJson()*/;
response = await ApiManager.instance.post( response = await ApiManager.instance.post(
URLs.getRegularVisits, URLs.getRegularVisits,
@ -163,12 +154,12 @@ class RegularVisitsProvider extends ChangeNotifier {
} }
} }
Future<Pentry> getPentry({String host, User user, int id}) async { Future<Ppm> getPentry({String host, User user, int id}) async {
Response response; Response response;
response = await ApiManager.instance.get("${URLs.getPentry}/$id"); response = await ApiManager.instance.get("${URLs.getPentry}/$id");
Pentry pantry; Ppm pantry;
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
pantry = Pentry.fromMap(json.decode(utf8.decode(response.bodyBytes))); pantry = Ppm.fromJson(json.decode(utf8.decode(response.bodyBytes)));
} }
return pantry; return pantry;
} }
@ -176,27 +167,13 @@ class RegularVisitsProvider extends ChangeNotifier {
Future<int> updatePentry( Future<int> updatePentry(
BuildContext context, { BuildContext context, {
@required User user, @required User user,
@required Pentry pentry, @required Ppm ppm,
@required Visit visit,
}) async { }) async {
try { try {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
Response response; Response response;
Map<String, dynamic> body = pentry.toMap(visit.id); Map<String, dynamic> body = ppm.copyWith(assignedEmployeeId: user.userName, tbsTimer: ppm.tbsTimer).toJson();
body["id"] = visit.id;
body["assetId"] = visit.deviceId;
body["ppmScheduleId"] = visit.ppmScheduleId;
body["assignedEmployeeId"] = user.userName;
// body["token"] = user.token;
// body["vChecklists"]?.addAll({});
// body["vCalibrationTools"]?.addAll({"visitId": visit.id,});
// body["vKits"]?.add({"visitId": visit.id,});
response = await ApiManager.instance.put(URLs.updatePentry, body: body); response = await ApiManager.instance.put(URLs.updatePentry, body: body);
// response = await post(
// Uri.parse(host+URLs.updatePentry + "/${visit.id}"),
// body: body,
// );
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
reset(); //visit.status = pentry.ppmVisitStatus; reset(); //visit.status = pentry.ppmVisitStatus;
notifyListeners(); notifyListeners();

@ -1,122 +1,122 @@
import 'dart:convert'; // import 'dart:convert';
//
import 'package:flutter/cupertino.dart'; // import 'package:flutter/cupertino.dart';
import 'package:http/http.dart'; // import 'package:http/http.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart'; // import 'package:test_sa/controllers/api_routes/api_manager.dart';
import 'package:test_sa/controllers/api_routes/urls.dart'; // import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/user.dart'; // import 'package:test_sa/models/user.dart';
import 'package:test_sa/models/visits/visit.dart'; // import 'package:test_sa/models/visits/ppm.dart';
import 'package:test_sa/models/visits/visits_group.dart'; // import 'package:test_sa/models/visits/ppm_search.dart';
import 'package:test_sa/models/visits/visits_search.dart'; // import 'package:test_sa/models/visits/visits_group.dart';
//
class PreventiveMaintenanceVisitsProvider extends ChangeNotifier { // class PreventiveMaintenanceVisitsProvider extends ChangeNotifier {
// number of items call in each request // // number of items call in each request
final pageItemNumber = 10; // final pageItemNumber = 10;
//
//reset provider data // //reset provider data
void reset() { // void reset() {
visits = null; // visits = null;
nextPage = true; // nextPage = true;
stateCode = null; // stateCode = null;
} // }
//
// state code of current request to defied error message // // state code of current request to defied error message
// like 400 customer request failed // // like 400 customer request failed
// 500 service not available // // 500 service not available
int stateCode; // int stateCode;
//
// true if there is next page in product list and false if not // // true if there is next page in product list and false if not
bool nextPage = true; // bool nextPage = true;
//
// list of user requests // // list of user requests
List<Visit> visits; // List<Visit> visits;
//
// when requests in-process _loading = true // // when requests in-process _loading = true
// done _loading = true // // done _loading = true
// failed _loading = false // // failed _loading = false
bool isLoading; // bool isLoading;
//
VisitsSearch visitsSearch = VisitsSearch(); // VisitsSearch visitsSearch = VisitsSearch();
//
/// 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<int> getVisits({ // Future<int> getVisits({
@required String host, // @required String host,
@required User user, // @required User user,
// VisitsSearch visitsSearch, // // VisitsSearch visitsSearch,
}) async { // }) async {
if (isLoading == true) return -2; // if (isLoading == true) return -2;
isLoading = true; // isLoading = true;
Response response; // Response response;
//userId = 397.toString(); // testing id to view data // //userId = 397.toString(); // testing id to view data
try { // try {
response = await get( // response = await get(
Uri.parse( // Uri.parse(
"${host + URLs.getPreventiveMaintenanceVisits}?uid=${user.id}&token=${user.token}&page=${(visits?.length ?? 0) ~/ pageItemNumber}${visitsSearch?.toMap()}", // "${host + URLs.getPreventiveMaintenanceVisits}?uid=${user.id}&token=${user.token}&page=${(visits?.length ?? 0) ~/ pageItemNumber}${visitsSearch?.toMap()}",
), // ),
headers: {"Content-Type": "application/json; charset=utf-8"}); // headers: {"Content-Type": "application/json; charset=utf-8"});
} catch (error) { // } catch (error) {
isLoading = false; // isLoading = false;
stateCode = -1; // stateCode = -1;
notifyListeners(); // notifyListeners();
return -1; // return -1;
} // }
stateCode = response.statusCode; // stateCode = response.statusCode;
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 requestsListJson = json.decode(utf8.decode(response.bodyBytes)); // List requestsListJson = json.decode(utf8.decode(response.bodyBytes));
List<Visit> _visits = requestsListJson.map((request) => Visit.fromJson(request)).toList(); // List<Visit> _visits = requestsListJson.map((request) => Visit.fromJson(request)).toList();
visits ??= []; // visits ??= [];
visits.addAll(_visits); // visits.addAll(_visits);
if (_visits.length == pageItemNumber) { // if (_visits.length == pageItemNumber) {
nextPage = true; // nextPage = true;
} else { // } else {
nextPage = false; // nextPage = false;
} // }
} // }
isLoading = false; // isLoading = false;
notifyListeners(); // notifyListeners();
return response.statusCode; // return response.statusCode;
} // }
//
/// 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<int> updateGroupOfVisits({ // Future<int> updateGroupOfVisits({
@required String host, // @required String host,
@required User user, // @required User user,
VisitsGroup group, // VisitsGroup group,
}) async { // }) async {
Response response; // Response response;
Map<String, String> body = group.toJson(); // Map<String, String> body = group.toJson();
// body["token"] = user.token ?? ""; // // body["token"] = user.token ?? "";
// body["uid"] = user.id; // // body["uid"] = user.id;
//userId = 397.toString(); // testing id to view data // //userId = 397.toString(); // testing id to view data
try { // try {
response = await ApiManager.instance.put(URLs.updatePreventiveMaintenanceVisits, body: body); // response = await ApiManager.instance.put(URLs.updatePreventiveMaintenanceVisits, body: body);
//
stateCode = response.statusCode; // stateCode = response.statusCode;
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
// group.visits.forEach((visit) { // // group.visits.forEach((visit) {
// visit.status = group.status; // // visit.status = group.status;
// visit.actualDate = group.date.toString().split(" ").first; // // visit.actualDate = group.date.toString().split(" ").first;
// }); // // });
group.visits.clear(); // group.ppms.clear();
notifyListeners(); // notifyListeners();
} // }
//
return response.statusCode; // return response.statusCode;
} catch (error) { // } catch (error) {
isLoading = false; // isLoading = false;
stateCode = -1; // stateCode = -1;
notifyListeners(); // notifyListeners();
return -1; // return -1;
} // }
} // }
} // }

@ -168,7 +168,7 @@
"newServiceReport": "تقرير خدمة جديد", "newServiceReport": "تقرير خدمة جديد",
"number": "رقم", "number": "رقم",
"operatingHours": "ساعات العمل", "operatingHours": "ساعات العمل",
"partNumberName": "رقم/اسم القطعة", "partName": "اسم القطعة",
"quantity": "كمية", "quantity": "كمية",
"reasons": "الاسباب", "reasons": "الاسباب",
"reason": "السبب", "reason": "السبب",
@ -303,6 +303,7 @@
"assistantEmployee" : "موظف مساعد", "assistantEmployee" : "موظف مساعد",
"assignAssistant" : "تعيين مساعد", "assignAssistant" : "تعيين مساعد",
"partNo" : "الجزء رقم", "partNo" : "الجزء رقم",
"partNumber" : "الجزء رقم",
"engSign" : "توقيع المهندس", "engSign" : "توقيع المهندس",
"requesterName" : "اسم الطالب", "requesterName" : "اسم الطالب",
"updateWorkOrder" : "تعديل طلب العمل", "updateWorkOrder" : "تعديل طلب العمل",

@ -170,7 +170,7 @@
"newServiceReport": "New Work Order", "newServiceReport": "New Work Order",
"number": "Number", "number": "Number",
"operatingHours": "Operating Hours", "operatingHours": "Operating Hours",
"partNumberName": "Part Number/Name", "partName": "Part Name",
"quantity": "Quantity", "quantity": "Quantity",
"reasons": "Reasons", "reasons": "Reasons",
"reason": "Reason", "reason": "Reason",
@ -308,6 +308,7 @@
"assistantEmployee" : "Assistant Employee", "assistantEmployee" : "Assistant Employee",
"assignAssistant" : "Assign Assistant", "assignAssistant" : "Assign Assistant",
"partNo" : "Part No.", "partNo" : "Part No.",
"partNumber" : "Part Number",
"engSign" : "Engineer Signature", "engSign" : "Engineer Signature",
"requesterName" : "Requester Name", "requesterName" : "Requester Name",
"updateWorkOrder" : "Update Work Order", "updateWorkOrder" : "Update Work Order",

@ -15,8 +15,7 @@ import 'package:test_sa/controllers/providers/api/gas_refill_provider.dart';
import 'package:test_sa/controllers/providers/api/hospitals_provider.dart'; import 'package:test_sa/controllers/providers/api/hospitals_provider.dart';
import 'package:test_sa/controllers/providers/api/notifications_provider.dart'; import 'package:test_sa/controllers/providers/api/notifications_provider.dart';
import 'package:test_sa/controllers/providers/api/parts_provider.dart'; import 'package:test_sa/controllers/providers/api/parts_provider.dart';
import 'package:test_sa/controllers/providers/api/preventive_maintenance_visits_provider.dart'; import 'package:test_sa/controllers/providers/api/ppm_provider.dart';
import 'package:test_sa/controllers/providers/api/regular_visits_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/employee/assigned_to_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/employee/assigned_to_provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/employee/engineers_provider.dart'; import 'package:test_sa/controllers/providers/api/status_drop_down/employee/engineers_provider.dart';
@ -58,6 +57,7 @@ import 'package:test_sa/providers/gas_request_providers/gas_status_provider.dart
import 'package:test_sa/providers/gas_request_providers/gas_types_provider.dart'; import 'package:test_sa/providers/gas_request_providers/gas_types_provider.dart';
import 'package:test_sa/providers/gas_request_providers/site_provider.dart'; import 'package:test_sa/providers/gas_request_providers/site_provider.dart';
import 'package:test_sa/providers/loading_list_notifier.dart'; import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/providers/ppm_checklist_status_provider.dart';
import 'package:test_sa/providers/ppm_device_status_provider.dart'; import 'package:test_sa/providers/ppm_device_status_provider.dart';
import 'package:test_sa/providers/ppm_visit_status_provider.dart'; import 'package:test_sa/providers/ppm_visit_status_provider.dart';
import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart'; import 'package:test_sa/providers/service_request_providers/equipment_status_provider.dart';
@ -81,6 +81,7 @@ import 'package:test_sa/views/pages/user/gas_refill/request_gas_refill.dart';
import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart'; import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart';
import 'package:test_sa/views/pages/user/land_page.dart' as old; import 'package:test_sa/views/pages/user/land_page.dart' as old;
import 'package:test_sa/views/pages/user/notifications/notifications_page.dart'; import 'package:test_sa/views/pages/user/notifications/notifications_page.dart';
import 'package:test_sa/views/pages/user/ppm/ppm_page.dart';
import 'package:test_sa/views/pages/user/profile_page.dart'; import 'package:test_sa/views/pages/user/profile_page.dart';
import 'package:test_sa/views/pages/user/report_issues_page.dart'; import 'package:test_sa/views/pages/user/report_issues_page.dart';
import 'package:test_sa/views/pages/user/requests/create_service_request_page.dart'; import 'package:test_sa/views/pages/user/requests/create_service_request_page.dart';
@ -89,8 +90,6 @@ import 'package:test_sa/views/pages/user/requests/requests_page.dart';
import 'package:test_sa/views/pages/user/requests/update_service_request_page.dart'; import 'package:test_sa/views/pages/user/requests/update_service_request_page.dart';
import 'package:test_sa/views/pages/user/requests/work_order/work_order_details_page.dart'; import 'package:test_sa/views/pages/user/requests/work_order/work_order_details_page.dart';
import 'package:test_sa/views/pages/user/requests/work_order/work_orders_list_page.dart'; import 'package:test_sa/views/pages/user/requests/work_order/work_orders_list_page.dart';
import 'package:test_sa/views/pages/user/visits/preventive_maintenance_visits_page.dart';
import 'package:test_sa/views/pages/user/visits/regular_visits_page.dart';
import 'package:test_sa/views/widgets/departments/single_department_picker.dart'; import 'package:test_sa/views/widgets/departments/single_department_picker.dart';
import 'package:test_sa/views/widgets/equipment/asset_detail_page.dart'; import 'package:test_sa/views/widgets/equipment/asset_detail_page.dart';
import 'package:test_sa/views/widgets/equipment/single_device_picker.dart'; import 'package:test_sa/views/widgets/equipment/single_device_picker.dart';
@ -147,8 +146,8 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => ServiceRequestsProvider()), ChangeNotifierProvider(create: (_) => ServiceRequestsProvider()),
ChangeNotifierProvider(create: (_) => DepartmentsProvider()), ChangeNotifierProvider(create: (_) => DepartmentsProvider()),
ChangeNotifierProvider(create: (_) => NotificationsProvider()), ChangeNotifierProvider(create: (_) => NotificationsProvider()),
ChangeNotifierProvider(create: (_) => PreventiveMaintenanceVisitsProvider()), // ChangeNotifierProvider(create: (_) => PreventiveMaintenanceVisitsProvider()),
ChangeNotifierProvider(create: (_) => RegularVisitsProvider()), ChangeNotifierProvider(create: (_) => PpmProvider()),
ChangeNotifierProvider(create: (_) => PartsProvider()), ChangeNotifierProvider(create: (_) => PartsProvider()),
ChangeNotifierProvider(create: (_) => ServiceReportReasonsProvider()), ChangeNotifierProvider(create: (_) => ServiceReportReasonsProvider()),
ChangeNotifierProvider(create: (_) => ServiceReportStatusProvider()), ChangeNotifierProvider(create: (_) => ServiceReportStatusProvider()),
@ -195,6 +194,7 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => CommentsProvider()), ChangeNotifierProvider(create: (_) => CommentsProvider()),
ChangeNotifierProvider(create: (_) => RequestStatusProvider()), ChangeNotifierProvider(create: (_) => RequestStatusProvider()),
ChangeNotifierProvider(create: (_) => VendorProvider()), ChangeNotifierProvider(create: (_) => VendorProvider()),
ChangeNotifierProvider(create: (_) => PpmChecklistStatusProvider()),
], ],
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
@ -226,8 +226,8 @@ class MyApp extends StatelessWidget {
SingleDepartmentPicker.id: (_) => SingleDepartmentPicker(), SingleDepartmentPicker.id: (_) => SingleDepartmentPicker(),
NotificationsPage.id: (_) => NotificationsPage(), NotificationsPage.id: (_) => NotificationsPage(),
FutureRequestServiceDetails.id: (_) => FutureRequestServiceDetails(), FutureRequestServiceDetails.id: (_) => FutureRequestServiceDetails(),
PreventiveMaintenanceVisitsPage.id: (_) => PreventiveMaintenanceVisitsPage(), // PreventiveMaintenanceVisitsPage.id: (_) => PreventiveMaintenanceVisitsPage(),
RegularVisitsPage.id: (_) => RegularVisitsPage(), PpmPage.id: (_) => const PpmPage(),
TrackGasRefillPage.id: (_) => const TrackGasRefillPage(), TrackGasRefillPage.id: (_) => const TrackGasRefillPage(),
RequestDeviceTransfer.id: (_) => const RequestDeviceTransfer(), RequestDeviceTransfer.id: (_) => const RequestDeviceTransfer(),
TrackDeviceTransferPage.id: (_) => const TrackDeviceTransferPage(), TrackDeviceTransferPage.id: (_) => const TrackDeviceTransferPage(),

@ -45,6 +45,7 @@ class GasRefillModel {
startTime = json['startTime']; startTime = json['startTime'];
endDate = json['endDate']; endDate = json['endDate'];
endTime = json['endTime']; endTime = json['endTime'];
workingHours = json['workingHours'];
try { try {
final sd = DateTime.tryParse(startDate ?? ""); final sd = DateTime.tryParse(startDate ?? "");
final st = DateTime.tryParse(startTime ?? ""); final st = DateTime.tryParse(startTime ?? "");
@ -63,7 +64,6 @@ class GasRefillModel {
} }
engSignature = json['engSignature']; engSignature = json['engSignature'];
nurseSignature = json['nurseSignature']; nurseSignature = json['nurseSignature'];
workingHours = json['workingHours'];
site = json['site'] != null ? Site.fromJson(json['site']) : null; site = json['site'] != null ? Site.fromJson(json['site']) : null;
building = json['building'] != null ? Building.fromJson(json['building']) : null; building = json['building'] != null ? Building.fromJson(json['building']) : null;
floor = json['floor'] != null ? Floor.fromJson(json['floor']) : null; floor = json['floor'] != null ? Floor.fromJson(json['floor']) : null;

@ -1,40 +0,0 @@
import 'package:test_sa/models/lookup.dart';
class CalibrationTool {
int id;
Lookup assetsNumber;
DateTime dataOfTesting;
CalibrationTool({
this.id,
this.assetsNumber,
this.dataOfTesting,
});
Map<String, dynamic> toMap(int visitId) {
return {
"id": id ?? 0,
"visitId": visitId,
if (assetsNumber != null) 'assetId': (assetsNumber?.id).toString(),
if (dataOfTesting != null) 'calibrationDateOfTesters': dataOfTesting.toIso8601String(),
};
}
factory CalibrationTool.fromMap(Map<String, dynamic> map) {
return CalibrationTool(
assetsNumber: Lookup(id: map["assetId"], name: map['assetNumber']),
dataOfTesting: DateTime.tryParse(map['calibrationDateOfTesters'] ?? ""),
);
}
CalibrationTool copyWith({
Lookup assetsNumber,
DateTime dataOfTesting,
}) {
return CalibrationTool(
id: id,
assetsNumber: assetsNumber ?? this.assetsNumber,
dataOfTesting: dataOfTesting ?? this.dataOfTesting,
);
}
}

@ -1,34 +0,0 @@
import 'package:test_sa/models/lookup.dart';
class Contact {
Lookup title;
Lookup contactPerson;
String job;
String email;
String telephone;
String landLine;
Contact({this.title, this.contactPerson, this.job, this.email, this.telephone, this.landLine});
Map<String, String> toMap() {
return {
if (title != null) 'title': title.id.toString(),
if (contactPerson != null) 'contactPerson': contactPerson.id.toString(),
if (job != null) 'job': job,
if (email != null) 'email': email,
if (telephone != null) 'telephone': telephone,
if (landLine != null) 'landLine': landLine,
};
}
factory Contact.fromMap(Map<String, dynamic> map) {
return Contact(
title: map['title'] as Lookup,
contactPerson: map['contactPerson'] as Lookup,
job: map['job'] as String,
email: map['email'] as String,
telephone: map['telephone'] as String,
landLine: map['landLine'] as String,
);
}
}

@ -1,12 +0,0 @@
import 'package:test_sa/models/lookup.dart';
class ContactTitle extends Lookup {
ContactTitle({int id, String label}) : super(id: id, name: label);
factory ContactTitle.fromMap(Map<String, dynamic> parsedJson) {
return ContactTitle(
label: parsedJson["value"],
id: parsedJson["id"],
);
}
}

@ -1,12 +0,0 @@
import 'package:test_sa/models/lookup.dart';
class ContactTitle extends Lookup {
ContactTitle({int id, String label}) : super(id: id, name: label);
factory ContactTitle.fromMap(Map<String, dynamic> parsedJson) {
return ContactTitle(
label: parsedJson["value"],
id: parsedJson["id"],
);
}
}

@ -1,203 +0,0 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/pantry/calibration_tools.dart';
import 'package:test_sa/models/pantry/pm_kit.dart';
import 'package:test_sa/models/pantry/ppm_check_list.dart';
import 'package:test_sa/models/timer_model.dart';
class Pentry {
Lookup ppmVisitStatus;
Lookup status;
TimerModel timer;
DateTime actualVisitDate;
DateTime expectedVisitDate;
String travelingHours;
String image;
List<File> files = [];
// List<Contact> contacts;
List<PPMCheckList> ppmCheckLists;
List<CalibrationTool> calibrationTools;
List<PMKit> pmKits;
String signatureNurse;
String signatureEngineer;
Uint8List localNurseSignature;
Uint8List localEngineerSignature;
Pentry(
{this.travelingHours,
this.timer,
this.status,
this.ppmVisitStatus,
this.actualVisitDate,
this.expectedVisitDate,
this.image,
this.files,
// this.contacts,
this.ppmCheckLists,
this.calibrationTools,
this.pmKits,
this.signatureNurse,
this.signatureEngineer,
this.localNurseSignature,
this.localEngineerSignature});
Future<bool> validate() async {
if (ppmVisitStatus == null) {
await Fluttertoast.showToast(msg: "PPM Visit Status is Required");
return false;
}
if (actualVisitDate == null) {
await Fluttertoast.showToast(msg: "Actual visit date is Required");
return false;
}
if (expectedVisitDate == null) {
await Fluttertoast.showToast(msg: "Expected visit date is Required");
return false;
}
if (timer?.startAt == null) {
await Fluttertoast.showToast(msg: "Working Hours Required");
return false;
}
if (timer?.endAt == null) {
await Fluttertoast.showToast(msg: "Please Stop The Timer");
return false;
}
if (status?.id == null) {
await Fluttertoast.showToast(msg: "Device Status is Required");
return false;
}
return true;
}
Map<String, dynamic> toMap(int visitId) {
Map<String, dynamic> map = {};
map["visitStatusId"] = ppmVisitStatus?.id;
if (status != null) map["deviceStatusId"] = status?.id;
if (travelingHours != null) map["travelingHours"] = travelingHours;
//if(imageFile != null) map["file_attachement"] = base64Encode(imageFile.readAsBytesSync());
map["actualDate"] = actualVisitDate.toIso8601String();
map["expectedDate"] = expectedVisitDate.toIso8601String();
if (timer != null) {
map["startDate"] = timer.startAt.toIso8601String();
map["endDate"] = timer.endAt?.toIso8601String() ?? DateTime.now().toIso8601String();
map["workingHours"] = (timer.durationInSecond / 60 / 60).toStringAsFixed(5);
}
if (files?.isNotEmpty ?? false) {
map["vAttachments"] = files.map((file) => {"attachmentName": _isLocalUrl(file.path) ? (file.path.split("/").last + "|" + base64Encode(file.readAsBytesSync())) : file.path}).toList();
}
map["travelingHours"] = travelingHours;
// if(contacts?.isNotEmpty == true) {
// for(int i = 0;i<contacts.length;i++){
// contacts[i].toMap().forEach((key, value) {
// body["contacts[$i].$key"] = value;
// });
// }
// }
map["vChecklists"] = ppmCheckLists.map((e) => e.toMap(visitId)).toList();
map["vCalibrationTools"] = calibrationTools.map((e) => e.toMap(visitId)).toList();
map["vKits"] = pmKits.map((e) => e.toMap(visitId)).toList();
map["nurseSignature"] = signatureNurse; //"${DateTime.now().toIso8601String()}.png|$signatureNurse";
map["engSignature"] = signatureEngineer; //"${DateTime.now().toIso8601String()}.png|$signatureEngineer";
return map;
}
bool _isLocalUrl(String url) {
if (url?.isEmpty != false) return false;
return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\');
}
factory Pentry.fromMap(Map<String, dynamic> map) {
// List<Contact> contacts = [];
// if(map['contacts'] != null){
// contacts =(map['contacts'] as List<dynamic>)
// .map((e) => Contact.fromMap(e as Map<String, dynamic>))
// .toList();
// }
List<PMKit> pmKits = [];
if (map['vKits'] != null) {
pmKits = (map['vKits'] as List<dynamic>).map((e) => PMKit.fromMap(e as Map<String, dynamic>)).toList();
}
List<String> files = [];
if (map["vAttachments"] != null) if (map["vAttachments"] is List) {
List list = map["vAttachments"];
list.removeWhere((element) => (element["attachmentURL"]?.toString() ?? "").isEmpty);
files = list.map((e) => URLs.getFileUrl(e["attachmentName"])).toList();
}
List<PPMCheckList> ppmCheckLists = [];
if (map['vChecklists'] != null) {
ppmCheckLists = (map['vChecklists'] as List<dynamic>).map((e) => PPMCheckList.fromMap(e as Map<String, dynamic>)).toList();
}
List<CalibrationTool> calibrationTools = [];
if (map['vCalibrationTools'] != null) {
calibrationTools = (map['vCalibrationTools'] as List<dynamic>).map((e) => CalibrationTool.fromMap(e as Map<String, dynamic>)).toList();
}
return Pentry(
status: Lookup(id: map["deviceStatusId"], name: map["deviceStatusName"]),
ppmVisitStatus: Lookup(id: map["visitStatusId"], name: map["visitStatusName"]),
actualVisitDate: DateTime.tryParse(map["actualDate"] ?? ""),
expectedVisitDate: DateTime.tryParse(map["expectedDate"] ?? ""),
travelingHours: map["travelingHours"],
timer: TimerModel(
startAt: DateTime.tryParse(map["startDate"] ?? ""),
endAt: DateTime.tryParse(map["endDate"] ?? ""),
durationInSecond: (int.tryParse(map["workingHours"] ?? "") ?? 0) * 60 * 60,
),
// contacts: contacts,
ppmCheckLists: ppmCheckLists,
calibrationTools: calibrationTools,
pmKits: pmKits,
files: files?.map((e) {
return File(e);
})?.toList() ??
[],
signatureNurse: URLs.getFileUrl(map["nurseSignature"]),
signatureEngineer: URLs.getFileUrl(map["engSignature"]),
);
}
Pentry copyWith({
Lookup ppmVisitStatus,
Lookup status,
TimerModel timer,
DateTime actualVisitDate,
DateTime expectedVisitDate,
String travelingHours,
String image,
List<File> files,
List<PPMCheckList> ppmCheckLists,
List<CalibrationTool> calibrationTools,
List<PMKit> pmKits,
String signatureNurse,
String signatureEngineer,
}) {
return Pentry(
ppmVisitStatus: ppmVisitStatus ?? this.ppmVisitStatus,
status: status ?? this.status,
timer: timer ?? this.timer,
actualVisitDate: actualVisitDate ?? this.actualVisitDate,
expectedVisitDate: expectedVisitDate ?? this.expectedVisitDate,
travelingHours: travelingHours ?? this.travelingHours,
image: image ?? this.image,
files: files ?? this.files,
ppmCheckLists: ppmCheckLists ?? this.ppmCheckLists?.map((e) => e.copyWith())?.toList(),
calibrationTools: calibrationTools ?? this.calibrationTools?.map((e) => e.copyWith())?.toList(),
pmKits: pmKits ?? this.pmKits.map((e) => e.copyWith()).toList(),
signatureNurse: signatureNurse ?? this.signatureNurse,
signatureEngineer: signatureEngineer ?? this.signatureEngineer);
}
void clearEmptyObjects() {
ppmCheckLists.removeWhere((element) => (element?.title?.isEmpty ?? true) && (element?.comment?.isEmpty ?? true) && (element?.measuredValue?.isEmpty ?? true) && element.status == null);
calibrationTools.removeWhere((element) => (element?.assetsNumber == null) && (element?.dataOfTesting == null));
pmKits.removeWhere((element) => (element?.itemCode == null));
}
}

@ -1,63 +0,0 @@
import 'package:test_sa/models/lookup.dart';
class PMKit {
int id;
Lookup itemCode;
String itemName;
String preparationTimeFrame;
String kitFrequencyDemand;
String availability;
String quantityNeeded;
String quantityReserved;
PMKit({this.id, this.itemCode, this.itemName, this.preparationTimeFrame, this.kitFrequencyDemand, this.availability, this.quantityNeeded, this.quantityReserved});
Map<String, dynamic> toMap(int visitId) {
return {
"id": id ?? 0,
"visitId": visitId,
if (itemCode != null) 'partCatalogItemId': (itemCode?.id),
if (itemName != null) 'itemName': itemName,
// if(preparationTimeFrame != null) 'preparationTimeFrame': preparationTimeFrame,
// if(kitFrequencyDemand != null) 'kitFrequencyDemand': kitFrequencyDemand,
// if(availability != null) 'availability': availability,
if (quantityNeeded != null) 'quantityNeeded': quantityNeeded,
// if(quantityReserved != null) 'quantityReserved': quantityReserved,
};
}
factory PMKit.fromMap(Map<String, dynamic> map) {
return PMKit(
id: map['id'],
itemCode: Lookup(id: map['partCatalogItemId'], name: map["partNumber"]),
itemName: map['itemName'] as String,
preparationTimeFrame: map['preparationTimeFrame'] as String,
kitFrequencyDemand: map['kitFrequencyDemand'] as String,
availability: map['availability'] as String,
quantityNeeded: map['quantityNeeded'] as String,
quantityReserved: map['quantityReserved'] as String,
);
}
PMKit copyWith({
int id,
Lookup itemCode,
String itemName,
String preparationTimeFrame,
String kitFrequencyDemand,
String availability,
String quantityNeeded,
String quantityReserved,
}) {
return PMKit(
id: id ?? this.id,
itemCode: itemCode ?? this.itemCode,
itemName: itemName ?? this.itemName,
preparationTimeFrame: preparationTimeFrame ?? this.preparationTimeFrame,
kitFrequencyDemand: kitFrequencyDemand ?? this.kitFrequencyDemand,
availability: availability ?? this.availability,
quantityNeeded: quantityNeeded ?? this.quantityNeeded,
quantityReserved: quantityReserved ?? this.quantityReserved,
);
}
}

@ -1,54 +0,0 @@
import 'package:test_sa/models/lookup.dart';
class PPMCheckList {
int id;
Lookup status;
String title;
String comment;
String measuredValue;
PPMCheckList({
this.id,
this.title,
this.status,
this.comment,
this.measuredValue,
});
Map<String, dynamic> toMap(int visitId) {
return {
'id': id ?? 0,
"visitId": visitId,
if (status != null) 'taskStatusId': status?.id,
if (title != null) 'task': title,
if (comment != null) 'taskComment': comment,
if (measuredValue != null) 'measuredValue': measuredValue,
};
}
factory PPMCheckList.fromMap(Map<String, dynamic> map) {
return PPMCheckList(
id: map['id'] as int,
status: Lookup(id: map["taskStatusId"], name: map["taskStatusName"]),
title: map['task'] as String,
comment: map['taskComment'] as String,
measuredValue: map['measuredValue'] as String,
);
}
PPMCheckList copyWith({
int id,
Lookup status,
String title,
String comment,
String measuredValue,
}) {
return PPMCheckList(
id: id ?? this.id,
status: status ?? this.status,
title: title ?? this.title,
comment: comment ?? this.comment,
measuredValue: measuredValue ?? this.measuredValue,
);
}
}

@ -0,0 +1,603 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/cupertino.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/ppm/ppm_attachment.dart';
import 'package:test_sa/models/ppm/ppm_calibration_tools.dart';
import 'package:test_sa/models/ppm/ppm_check_list.dart';
import 'package:test_sa/models/ppm/ppm_contacts.dart';
import 'package:test_sa/models/ppm/ppm_kit.dart';
import 'package:test_sa/models/timer_model.dart';
class Ppm {
Ppm({
this.id,
this.ppmScheduleId,
this.assetId,
this.jobSheetNo,
this.assignedEmployeeId,
this.expectedDate,
this.actualDate,
this.nextDate,
this.forwardToId,
this.maintenanceContractId,
this.typeOfServiceId,
this.executionTimeFrameId,
this.externalEngineer,
this.telephone,
this.groupLeaderReviewId,
this.timePeriodId,
this.assignedToId,
this.vCalibrationTools,
this.vKits,
this.vContacts,
this.vChecklists,
this.files,
this.visitStatusId,
this.startDate,
this.endDate,
this.workingHours,
this.travelingHours,
this.deviceStatusId,
this.comments,
this.workPerformed,
this.supplierId,
this.suppPersonId,
this.suppStartDate,
this.suppEndDate,
this.suppWorkingHours,
this.taskStatusId,
this.engSignature,
this.nurseSignature,
this.safetyId,
this.assetAvailabilityId,
this.assetAvailabilityName,
this.assetName,
this.assetNumber,
this.assetSerialNo,
this.assetSupplierId,
this.assetSupplierName,
this.assignedEmployeeName,
this.assignedToName,
this.contractNumber,
this.createdOn,
this.departmentId,
this.departmentName,
this.deviceStatusName,
this.dueDate,
this.executionTimeFrameName,
this.forwardToName,
this.groupLeaderReviewName,
this.manufacturerId,
this.manufacturerName,
this.modelId,
this.modelName,
this.modifiedOn,
bool notified,
this.planCode,
this.planNo,
this.ppmId,
this.ppmScheduleCode,
this.ppmScheduleNo,
this.ppmSupplierId,
this.ppmSupplierName,
this.safetyName,
this.siteId,
this.siteName,
this.supplierName,
this.suppPerson,
this.taskStatusName,
this.timePeriodName,
this.timePeriodValue,
this.typeOfServiceName,
this.visitCode,
this.visitNo,
this.visitStatusName,
this.warrantyEndDate,
});
Ppm.fromJson(dynamic json) {
id = json['id'];
ppmScheduleId = json['ppmScheduleId'];
assetId = json['assetId'];
jobSheetNo = json['jobSheetNo'];
assignedEmployeeId = json['assignedEmployeeId'];
expectedDate = json['expectedDate'];
actualDate = json['actualDate'];
nextDate = json['nextDate'];
forwardToId = json['forwardToId'];
maintenanceContractId = json['maintenanceContractId'];
typeOfServiceId = json['typeOfServiceId'];
executionTimeFrameId = json['executionTimeFrameId'];
externalEngineer = json['externalEngineer'];
telephone = json['telephone'];
groupLeaderReviewId = json['groupLeaderReviewId'];
timePeriodId = json['timePeriodId'];
assignedToId = json['assignedToId'];
if (json['vCalibrationTools'] != null) {
vCalibrationTools = [];
json['vCalibrationTools'].forEach((v) {
vCalibrationTools.add(PpmCalibrationTools.fromJson(v));
});
}
if (json['vKits'] != null) {
vKits = [];
json['vKits'].forEach((v) {
vKits.add(PpmKits.fromJson(v));
});
}
if (json['vContacts'] != null) {
vContacts = [];
json['vContacts'].forEach((v) {
vContacts.add(PpmContacts.fromJson(v));
});
}
if (json['vChecklists'] != null) {
vChecklists = [];
json['vChecklists'].forEach((v) {
vChecklists.add(PpmChecklists.fromJson(v));
});
}
if (json['vAttachments'] != null) {
files = [];
json['vAttachments'].forEach((v) {
files.add(PpmAttachments.fromJson(v));
});
}
visitStatusId = json['visitStatusId'];
startDate = json['startDate'];
endDate = json['endDate'];
workingHours = json['workingHours'];
try {
tbsTimer = TimerModel(startAt: DateTime.tryParse(startDate ?? ""), endAt: DateTime.tryParse(endDate ?? ""));
if (tbsTimer.endAt != null && tbsTimer.startAt != null) {
tbsTimer.durationInSecond = (tbsTimer.endAt.difference(tbsTimer.startAt))?.inSeconds;
workingHours = (((tbsTimer.durationInSecond ?? 0) / 60) / 60).toStringAsFixed(2);
}
} catch (e) {
print(e.toString());
}
travelingHours = json['travelingHours'];
deviceStatusId = json['deviceStatusId'];
comments = json['comments'];
workPerformed = json['workPerformed'];
supplierId = json['supplierId'];
suppPersonId = json['suppPersonId'];
suppStartDate = json['suppStartDate'];
suppEndDate = json['suppEndDate'];
suppWorkingHours = json['suppWorkingHours'];
taskStatusId = json['taskStatusId'];
engSignature = json['engSignature'];
nurseSignature = json['nurseSignature'];
safetyId = json['safetyId'];
assetAvailabilityId = json['assetAvailabilityId'];
assetAvailabilityName = json['assetAvailabilityName'];
assetName = json['assetName'];
assetNumber = json['assetNumber'];
assetSerialNo = json['assetSerialNo'];
assetSupplierId = json['assetSupplierId'];
assetSupplierName = json['assetSupplierName'];
assignedEmployeeName = json['assignedEmployeeName'];
assignedToName = json['assignedToName'];
createdOn = json['createdOn'];
departmentId = json['departmentId'];
departmentName = json['departmentName'];
deviceStatusName = json['deviceStatusName'];
dueDate = json['dueDate'];
executionTimeFrameName = json['executionTimeFrameName'];
forwardToName = json['forwardToName'];
manufacturerId = json['manufacturerId'];
manufacturerName = json['manufacturerName'];
modifiedOn = json['modifiedOn'];
notified = json['notified'];
planCode = json['planCode'];
planNo = json['planNo'];
ppmId = json['ppmId'];
ppmScheduleCode = json['ppmScheduleCode'];
ppmScheduleNo = json['ppmScheduleNo'];
ppmSupplierId = json['ppmSupplierId'];
ppmSupplierName = json['ppmSupplierName'];
safetyName = json['safetyName'];
siteId = json['siteId'];
siteName = json['siteName'];
supplierName = json['supplierName'];
suppPerson = json['suppPerson'];
taskStatusName = json['taskStatusName'];
timePeriodName = json['timePeriodName'];
timePeriodValue = json['timePeriodValue'];
typeOfServiceName = json['typeOfServiceName'];
visitCode = json['visitCode'];
visitNo = json['visitNo'];
visitStatusName = json['visitStatusName'];
warrantyEndDate = json['warrantyEndDate'];
}
num id;
num ppmScheduleId;
num assetId;
String jobSheetNo;
String assignedEmployeeId;
String expectedDate;
String actualDate;
String nextDate;
String forwardToId;
num maintenanceContractId;
num typeOfServiceId;
num executionTimeFrameId;
String externalEngineer;
String telephone;
num groupLeaderReviewId;
num timePeriodId;
num assignedToId;
List<PpmCalibrationTools> vCalibrationTools;
List<PpmKits> vKits;
List<PpmContacts> vContacts;
List<PpmChecklists> vChecklists;
List<PpmAttachments> files;
num visitStatusId;
String startDate;
String endDate;
String workingHours;
String travelingHours;
num deviceStatusId;
String comments;
String workPerformed;
num supplierId;
num suppPersonId;
String suppStartDate;
String suppEndDate;
String suppWorkingHours;
num taskStatusId;
String engSignature;
String nurseSignature;
num safetyId;
num assetAvailabilityId;
String assetAvailabilityName;
String assetName;
String assetNumber;
String assetSerialNo;
num assetSupplierId;
String assetSupplierName;
String assignedEmployeeName;
String assignedToName;
String contractNumber;
String createdOn;
num departmentId;
String departmentName;
String deviceStatusName;
String dueDate;
String executionTimeFrameName;
String forwardToName;
String groupLeaderReviewName;
num manufacturerId;
String manufacturerName;
num modelId;
String modelName;
String modifiedOn;
bool notified;
String planCode;
num planNo;
num ppmId;
String ppmScheduleCode;
num ppmScheduleNo;
num ppmSupplierId;
String ppmSupplierName;
String safetyName;
num siteId;
String siteName;
String supplierName;
String suppPerson;
String taskStatusName;
String timePeriodName;
num timePeriodValue;
String typeOfServiceName;
String visitCode;
num visitNo;
String visitStatusName;
String warrantyEndDate;
TimerModel tbsTimer = TimerModel();
Uint8List localNurseSignature;
Uint8List localEngineerSignature;
Ppm copyWith({
num id,
num ppmScheduleId,
num assetId,
String jobSheetNo,
String assignedEmployeeId,
String expectedDate,
String actualDate,
String nextDate,
String forwardToId,
num maintenanceContractId,
num typeOfServiceId,
num executionTimeFrameId,
String externalEngineer,
String telephone,
num groupLeaderReviewId,
num timePeriodId,
num assignedToId,
List<PpmCalibrationTools> vCalibrationTools,
List<PpmKits> vKits,
List<PpmContacts> vContacts,
List<PpmChecklists> vChecklists,
List<PpmAttachments> files,
num visitStatusId,
String startDate,
String endDate,
String workingHours,
String travelingHours,
num deviceStatusId,
String comments,
String workPerformed,
num supplierId,
num suppPersonId,
String suppStartDate,
String suppEndDate,
String suppWorkingHours,
num taskStatusId,
String engSignature,
String nurseSignature,
num safetyId,
num assetAvailabilityId,
String assetAvailabilityName,
String assetName,
String assetNumber,
String assetSerialNo,
num assetSupplierId,
String assetSupplierName,
String assignedEmployeeName,
String assignedToName,
String contractNumber,
String createdOn,
num departmentId,
String departmentName,
String deviceStatusName,
String dueDate,
String executionTimeFrameName,
String forwardToName,
String groupLeaderReviewName,
num manufacturerId,
String manufacturerName,
num modelId,
String modelName,
String modifiedOn,
bool notified,
String planCode,
num planNo,
num ppmId,
String ppmScheduleCode,
num ppmScheduleNo,
num ppmSupplierId,
String ppmSupplierName,
String safetyName,
num siteId,
String siteName,
String supplierName,
String suppPerson,
String taskStatusName,
String timePeriodName,
num timePeriodValue,
String typeOfServiceName,
String visitCode,
num visitNo,
String visitStatusName,
String warrantyEndDate,
TimerModel tbsTimer,
}) =>
Ppm(
id: id ?? this.id,
ppmScheduleId: ppmScheduleId ?? this.ppmScheduleId,
assetId: assetId ?? this.assetId,
jobSheetNo: jobSheetNo ?? this.jobSheetNo,
assignedEmployeeId: assignedEmployeeId ?? this.assignedEmployeeId,
expectedDate: expectedDate ?? this.expectedDate,
actualDate: actualDate ?? this.actualDate,
nextDate: nextDate ?? this.nextDate,
forwardToId: forwardToId ?? this.forwardToId,
maintenanceContractId: maintenanceContractId ?? this.maintenanceContractId,
typeOfServiceId: typeOfServiceId ?? this.typeOfServiceId,
executionTimeFrameId: executionTimeFrameId ?? this.executionTimeFrameId,
externalEngineer: externalEngineer ?? this.externalEngineer,
telephone: telephone ?? this.telephone,
groupLeaderReviewId: groupLeaderReviewId ?? this.groupLeaderReviewId,
timePeriodId: timePeriodId ?? this.timePeriodId,
assignedToId: assignedToId ?? this.assignedToId,
vCalibrationTools: vCalibrationTools ?? this.vCalibrationTools,
vKits: vKits ?? this.vKits,
vContacts: vContacts ?? this.vContacts,
vChecklists: vChecklists ?? this.vChecklists,
files: files ?? this.files,
visitStatusId: visitStatusId ?? this.visitStatusId,
startDate: startDate ?? this.startDate,
endDate: endDate ?? this.endDate,
workingHours: workingHours ?? this.workingHours,
travelingHours: travelingHours ?? this.travelingHours,
deviceStatusId: deviceStatusId ?? this.deviceStatusId,
comments: comments ?? this.comments,
workPerformed: workPerformed ?? this.workPerformed,
supplierId: supplierId ?? this.supplierId,
suppPersonId: suppPersonId ?? this.suppPersonId,
suppStartDate: suppStartDate ?? this.suppStartDate,
suppEndDate: suppEndDate ?? this.suppEndDate,
suppWorkingHours: suppWorkingHours ?? this.suppWorkingHours,
taskStatusId: taskStatusId ?? this.taskStatusId,
engSignature: engSignature ?? this.engSignature,
nurseSignature: nurseSignature ?? this.nurseSignature,
safetyId: safetyId ?? this.safetyId,
assetAvailabilityId: assetAvailabilityId ?? this.assetAvailabilityId,
assetAvailabilityName: assetAvailabilityName ?? this.assetAvailabilityName,
assetName: assetName ?? this.assetName,
assetNumber: assetNumber ?? this.assetNumber,
assetSerialNo: assetSerialNo ?? this.assetSerialNo,
assetSupplierId: assetSupplierId ?? this.assetSupplierId,
assetSupplierName: assetSupplierName ?? this.assetSupplierName,
assignedEmployeeName: assignedEmployeeName ?? this.assignedEmployeeName,
assignedToName: assignedToName ?? this.assignedToName,
createdOn: createdOn ?? this.createdOn,
departmentId: departmentId ?? this.departmentId,
departmentName: departmentName ?? this.departmentName,
deviceStatusName: deviceStatusName ?? this.deviceStatusName,
dueDate: dueDate ?? this.dueDate,
executionTimeFrameName: executionTimeFrameName ?? this.executionTimeFrameName,
forwardToName: forwardToName ?? this.forwardToName,
manufacturerId: manufacturerId ?? this.manufacturerId,
manufacturerName: manufacturerName ?? this.manufacturerName,
modifiedOn: modifiedOn ?? this.modifiedOn,
notified: notified ?? this.notified,
planCode: planCode ?? this.planCode,
planNo: planNo ?? this.planNo,
ppmId: ppmId ?? this.ppmId,
ppmScheduleCode: ppmScheduleCode ?? this.ppmScheduleCode,
ppmScheduleNo: ppmScheduleNo ?? this.ppmScheduleNo,
ppmSupplierId: ppmSupplierId ?? this.ppmSupplierId,
ppmSupplierName: ppmSupplierName ?? this.ppmSupplierName,
safetyName: safetyName ?? this.safetyName,
siteId: siteId ?? this.siteId,
siteName: siteName ?? this.siteName,
supplierName: supplierName ?? this.supplierName,
suppPerson: suppPerson ?? this.suppPerson,
taskStatusName: taskStatusName ?? this.taskStatusName,
timePeriodName: timePeriodName ?? this.timePeriodName,
timePeriodValue: timePeriodValue ?? this.timePeriodValue,
typeOfServiceName: typeOfServiceName ?? this.typeOfServiceName,
visitCode: visitCode ?? this.visitCode,
visitNo: visitNo ?? this.visitNo,
visitStatusName: visitStatusName ?? this.visitStatusName,
warrantyEndDate: warrantyEndDate ?? this.warrantyEndDate,
)..tbsTimer = tbsTimer ?? this.tbsTimer;
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['ppmScheduleId'] = ppmScheduleId;
map['assetId'] = assetId;
map['jobSheetNo'] = jobSheetNo;
map['assignedEmployeeId'] = assignedEmployeeId;
map['expectedDate'] = expectedDate;
map['actualDate'] = actualDate;
map['nextDate'] = nextDate;
map['forwardToId'] = forwardToId;
map['maintenanceContractId'] = maintenanceContractId;
map['typeOfServiceId'] = typeOfServiceId;
map['executionTimeFrameId'] = executionTimeFrameId;
map['externalEngineer'] = externalEngineer;
map['telephone'] = telephone;
map['groupLeaderReviewId'] = groupLeaderReviewId;
map['timePeriodId'] = timePeriodId;
map['assignedToId'] = assignedToId;
if (vCalibrationTools != null) {
map['vCalibrationTools'] = vCalibrationTools.map((v) => v.copyWith(visitId: id).toJson()).toList();
}
if (vKits != null) {
map['vKits'] = vKits.map((v) => v.copyWith(visitId: id).toJson()).toList();
}
if (vContacts != null) {
map['vContacts'] = vContacts.map((v) => v.toJson()).toList();
}
if (vChecklists != null) {
map['vChecklists'] = vChecklists.map((v) => v.toJson()).toList();
}
if (files?.isNotEmpty ?? false) {
map["vAttachments"] = files
.map((file) =>
{"attachmentName": _isLocalUrl(file.attachmentName) ? ("${file.attachmentName.split("/").last}|${base64Encode(File(file.attachmentName).readAsBytesSync())}") : file.attachmentName})
.toList();
}
map['visitStatusId'] = visitStatusId;
map['startDate'] = tbsTimer?.startAt?.toIso8601String();
map['endDate'] = tbsTimer?.endAt?.toIso8601String();
map['workingHours'] = ((tbsTimer?.durationInSecond ?? 0) / 60 / 60).toStringAsFixed(5);
map['travelingHours'] = travelingHours;
map['deviceStatusId'] = deviceStatusId;
map['comments'] = comments;
map['workPerformed'] = workPerformed;
map['supplierId'] = supplierId;
map['suppPersonId'] = suppPersonId;
map['suppStartDate'] = suppStartDate;
map['suppEndDate'] = suppEndDate;
map['suppWorkingHours'] = suppWorkingHours;
map['taskStatusId'] = taskStatusId;
map['engSignature'] = engSignature;
map['nurseSignature'] = nurseSignature;
map['safetyId'] = safetyId;
map['assetAvailabilityId'] = assetAvailabilityId;
map['assetAvailabilityName'] = assetAvailabilityName;
map['assetName'] = assetName;
map['assetNumber'] = assetNumber;
map['assetSerialNo'] = assetSerialNo;
map['assetSupplierId'] = assetSupplierId;
map['assetSupplierName'] = assetSupplierName;
map['assignedEmployeeName'] = assignedEmployeeName;
map['assignedToName'] = assignedToName;
map['createdOn'] = createdOn;
map['departmentId'] = departmentId;
map['departmentName'] = departmentName;
map['deviceStatusName'] = deviceStatusName;
map['dueDate'] = dueDate;
map['executionTimeFrameName'] = executionTimeFrameName;
map['forwardToName'] = forwardToName;
map['manufacturerId'] = manufacturerId;
map['manufacturerName'] = manufacturerName;
map['modifiedOn'] = modifiedOn;
map['notified'] = notified;
map['planCode'] = planCode;
map['planNo'] = planNo;
map['ppmId'] = ppmId;
map['ppmScheduleCode'] = ppmScheduleCode;
map['ppmScheduleNo'] = ppmScheduleNo;
map['ppmSupplierId'] = ppmSupplierId;
map['ppmSupplierName'] = ppmSupplierName;
map['safetyName'] = safetyName;
map['siteId'] = siteId;
map['siteName'] = siteName;
map['supplierName'] = supplierName;
map['suppPerson'] = suppPerson;
map['taskStatusName'] = taskStatusName;
map['timePeriodName'] = timePeriodName;
map['timePeriodValue'] = timePeriodValue;
map['typeOfServiceName'] = typeOfServiceName;
map['visitCode'] = visitCode;
map['visitNo'] = visitNo;
map['visitStatusName'] = visitStatusName;
map['warrantyEndDate'] = warrantyEndDate;
return map;
}
bool _isLocalUrl(String url) {
if (url?.isEmpty != false) return false;
return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\');
}
Future<bool> validate(BuildContext context) async {
if (deviceStatusId == null || visitStatusId == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.status}");
return false;
}
if (actualDate == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.actualDate}");
return false;
}
if (expectedDate == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.visitDate}");
return false;
}
if (tbsTimer?.startAt == null) {
await Fluttertoast.showToast(msg: "Working Hours Required");
return false;
}
if (tbsTimer?.endAt == null) {
await Fluttertoast.showToast(msg: "Please Stop The Timer");
return false;
}
return true;
}
void removeEmptyObjects() {
if (vCalibrationTools?.isNotEmpty ?? false) vCalibrationTools.removeWhere((element) => element.assetId == null && element.calibrationDateOfTesters == null);
if (vKits?.isNotEmpty ?? false) vKits.removeWhere((element) => element.partName == null && element.partNumber == null);
}
}

@ -0,0 +1,42 @@
class PpmAttachments {
PpmAttachments({
this.id,
this.visitId,
this.attachmentName,
this.attachmentURL,
});
PpmAttachments.fromJson(dynamic json) {
id = json['id'];
visitId = json['visitId'];
attachmentName = json['attachmentName'];
attachmentName = json['attachmentURL'];
}
num id;
num visitId;
String attachmentName;
String attachmentURL;
PpmAttachments copyWith({
num id,
num visitId,
String attachmentName,
String attachmentURL,
}) =>
PpmAttachments(
id: id ?? this.id,
visitId: visitId ?? this.visitId,
attachmentName: attachmentName ?? this.attachmentName,
attachmentURL: attachmentURL ?? this.attachmentURL,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['visitId'] = visitId;
map['attachmentName'] = attachmentName;
map['attachmentURL'] = attachmentURL;
return map;
}
}

@ -0,0 +1,60 @@
class PpmCalibrationTools {
PpmCalibrationTools({
this.id,
this.visitId,
this.assetId,
this.calibrationDateOfTesters,
this.assetSerialNo,
this.assetName,
this.assetNumber,
});
PpmCalibrationTools.fromJson(dynamic json) {
id = json['id'];
visitId = json['visitId'];
assetId = json['assetId'];
calibrationDateOfTesters = json['calibrationDateOfTesters'];
assetSerialNo = json['assetSerialNo'];
assetName = json['assetName'];
assetNumber = json['assetNumber'];
}
num id;
num visitId;
num assetId;
String calibrationDateOfTesters;
String assetSerialNo;
String assetName;
String assetNumber;
PpmCalibrationTools copyWith({
num id,
num visitId,
num assetId,
String calibrationDateOfTesters,
String assetSerialNo,
String assetName,
String assetNumber,
}) =>
PpmCalibrationTools(
id: id ?? this.id,
visitId: visitId ?? this.visitId,
assetId: assetId ?? this.assetId,
calibrationDateOfTesters: calibrationDateOfTesters ?? this.calibrationDateOfTesters,
assetSerialNo: assetSerialNo ?? this.assetSerialNo,
assetName: assetName ?? this.assetName,
assetNumber: assetNumber ?? this.assetNumber,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['visitId'] = visitId;
map['assetId'] = assetId;
map['calibrationDateOfTesters'] = calibrationDateOfTesters;
map['assetSerialNo'] = assetSerialNo;
map['assetName'] = assetName;
map['assetNumber'] = assetNumber;
return map;
}
}

@ -0,0 +1,60 @@
class PpmChecklists {
PpmChecklists({
this.id,
this.visitId,
this.task,
this.taskStatusId,
this.taskComment,
this.measuredValue,
this.taskStatusName,
});
PpmChecklists.fromJson(dynamic json) {
id = json['id'];
visitId = json['visitId'];
task = json['task'];
taskStatusId = json['taskStatusId'];
taskStatusName = json['taskStatusName'];
taskComment = json['taskComment'];
measuredValue = json['measuredValue'];
}
num id;
num visitId;
String task;
num taskStatusId;
String taskComment;
String measuredValue;
String taskStatusName;
PpmChecklists copyWith({
num id,
num visitId,
String task,
num taskStatusId,
String taskComment,
String measuredValue,
String taskStatusName,
}) =>
PpmChecklists(
id: id ?? this.id,
visitId: visitId ?? this.visitId,
task: task ?? this.task,
taskStatusId: taskStatusId ?? this.taskStatusId,
taskComment: taskComment ?? this.taskComment,
measuredValue: measuredValue ?? this.measuredValue,
taskStatusName: taskStatusName ?? this.taskStatusName,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['visitId'] = visitId;
map['task'] = task;
map['taskStatusId'] = taskStatusId;
map['taskComment'] = taskComment;
map['measuredValue'] = measuredValue;
map['taskStatusName'] = taskStatusName;
return map;
}
}

@ -0,0 +1,66 @@
class PpmContacts {
PpmContacts({
this.id,
this.visitId,
this.title,
this.person,
this.job,
this.email,
this.telephone,
this.landLine,
});
PpmContacts.fromJson(dynamic json) {
id = json['id'];
visitId = json['visitId'];
title = json['title'];
person = json['person'];
job = json['job'];
email = json['email'];
telephone = json['telephone'];
landLine = json['landLine'];
}
num id;
num visitId;
String title;
String person;
String job;
String email;
String telephone;
String landLine;
PpmContacts copyWith({
num id,
num visitId,
String title,
String person,
String job,
String email,
String telephone,
String landLine,
}) =>
PpmContacts(
id: id ?? this.id,
visitId: visitId ?? this.visitId,
title: title ?? this.title,
person: person ?? this.person,
job: job ?? this.job,
email: email ?? this.email,
telephone: telephone ?? this.telephone,
landLine: landLine ?? this.landLine,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['visitId'] = visitId;
map['title'] = title;
map['person'] = person;
map['job'] = job;
map['email'] = email;
map['telephone'] = telephone;
map['landLine'] = landLine;
return map;
}
}

@ -0,0 +1,60 @@
class PpmKits {
PpmKits({
this.id,
this.visitId,
this.partCatalogItemId,
this.partNumber,
this.oracleCode,
this.partName,
this.partName2,
});
PpmKits.fromJson(dynamic json) {
id = json['id'];
visitId = json['visitId'];
partCatalogItemId = json['partCatalogItemId'];
partNumber = json['partNumber'];
oracleCode = json['oracleCode'];
partName = json['partName'];
partName2 = json['partName2'];
}
num id;
num visitId;
num partCatalogItemId;
String partNumber;
String oracleCode;
String partName;
String partName2;
PpmKits copyWith({
num id,
num visitId,
num partCatalogItemId,
String partNumber,
String oracleCode,
String partName,
String partName2,
}) =>
PpmKits(
id: id ?? this.id,
visitId: visitId ?? this.visitId,
partCatalogItemId: partCatalogItemId ?? this.partCatalogItemId,
partNumber: partNumber ?? this.partNumber,
oracleCode: oracleCode ?? this.oracleCode,
partName: partName ?? this.partName,
partName2: partName2 ?? this.partName2,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['id'] = id;
map['visitId'] = visitId;
map['partCatalogItemId'] = partCatalogItemId;
map['partNumber'] = partNumber;
map['oracleCode'] = oracleCode;
map['partName'] = partName;
map['partName2'] = partName2;
return map;
}
}

@ -0,0 +1,202 @@
import '../device/asset_by_id_model.dart';
class PpmSearch {
PpmSearch({
this.pageSize,
this.pageNumber,
this.id,
this.assetId,
this.modelId,
this.ppmId,
this.ppmScheduleId,
this.classification,
this.visitStatusId,
this.deviceStatusId,
this.groupLeaderReviewId,
this.assignedEmployeeId,
this.hasAssignedEmployee,
this.assignedToId,
this.expectedDateFrom,
this.expectedDateTo,
this.actualDateFrom,
this.actualDateTo,
this.siteId,
this.jobSheetNo,
this.typeOfServiceId,
this.planNumber,
this.notified,
this.mostRecent,
this.assetGroup,
this.buildingId,
this.floorId,
this.roomId,
this.departmentId,
this.assetName,
});
PpmSearch.fromJson(dynamic json) {
pageSize = json['pageSize'];
pageNumber = json['pageNumber'];
id = json['id'];
assetId = json['assetId'];
modelId = json['modelId'];
ppmId = json['ppmId'];
ppmScheduleId = json['ppmScheduleId'];
classification = json['classification'];
visitStatusId = json['visitStatusId'];
deviceStatusId = json['deviceStatusId'];
groupLeaderReviewId = json['groupLeaderReviewId'];
assignedEmployeeId = json['assignedEmployeeId'];
hasAssignedEmployee = json['hasAssignedEmployee'];
assignedToId = json['assignedToId'];
expectedDateFrom = json['expectedDateFrom'];
expectedDateTo = json['expectedDateTo'];
actualDateFrom = json['actualDateFrom'];
actualDateTo = json['actualDateTo'];
siteId = json['siteId'];
jobSheetNo = json['jobSheetNo'];
typeOfServiceId = json['typeOfServiceId'];
planNumber = json['planNumber'];
notified = json['notified'];
mostRecent = json['mostRecent'];
assetGroup = json['assetGroup'] != null ? AssetGroup.fromJson(json['assetGroup']) : null;
buildingId = json['buildingId'];
floorId = json['floorId'];
roomId = json['roomId'];
departmentId = json['departmentId'];
assetName = json['assetName'];
}
num pageSize;
num pageNumber;
num id;
num assetId;
num modelId;
num ppmId;
num ppmScheduleId;
num classification;
num visitStatusId;
num deviceStatusId;
num groupLeaderReviewId;
String assignedEmployeeId;
bool hasAssignedEmployee;
num assignedToId;
String expectedDateFrom;
String expectedDateTo;
String actualDateFrom;
String actualDateTo;
num siteId;
String jobSheetNo;
num typeOfServiceId;
num planNumber;
bool notified;
bool mostRecent;
AssetGroup assetGroup;
num buildingId;
num floorId;
num roomId;
num departmentId;
String assetName;
PpmSearch copyWith({
num pageSize,
num pageNumber,
num id,
num assetId,
num modelId,
num ppmId,
num ppmScheduleId,
num classification,
num visitStatusId,
num deviceStatusId,
num groupLeaderReviewId,
String assignedEmployeeId,
bool hasAssignedEmployee,
num assignedToId,
String expectedDateFrom,
String expectedDateTo,
String actualDateFrom,
String actualDateTo,
num siteId,
String jobSheetNo,
num typeOfServiceId,
num planNumber,
bool notified,
bool mostRecent,
AssetGroup assetGroup,
num buildingId,
num floorId,
num roomId,
num departmentId,
String assetName,
}) =>
PpmSearch(
pageSize: pageSize ?? this.pageSize,
pageNumber: pageNumber ?? this.pageNumber,
id: id ?? this.id,
assetId: assetId ?? this.assetId,
modelId: modelId ?? this.modelId,
ppmId: ppmId ?? this.ppmId,
ppmScheduleId: ppmScheduleId ?? this.ppmScheduleId,
classification: classification ?? this.classification,
visitStatusId: visitStatusId ?? this.visitStatusId,
deviceStatusId: deviceStatusId ?? this.deviceStatusId,
groupLeaderReviewId: groupLeaderReviewId ?? this.groupLeaderReviewId,
assignedEmployeeId: assignedEmployeeId ?? this.assignedEmployeeId,
hasAssignedEmployee: hasAssignedEmployee ?? this.hasAssignedEmployee,
assignedToId: assignedToId ?? this.assignedToId,
expectedDateFrom: expectedDateFrom ?? this.expectedDateFrom,
expectedDateTo: expectedDateTo ?? this.expectedDateTo,
actualDateFrom: actualDateFrom ?? this.actualDateFrom,
actualDateTo: actualDateTo ?? this.actualDateTo,
siteId: siteId ?? this.siteId,
jobSheetNo: jobSheetNo ?? this.jobSheetNo,
typeOfServiceId: typeOfServiceId ?? this.typeOfServiceId,
planNumber: planNumber ?? this.planNumber,
notified: notified ?? this.notified,
mostRecent: mostRecent ?? this.mostRecent,
assetGroup: assetGroup ?? this.assetGroup,
buildingId: buildingId ?? this.buildingId,
floorId: floorId ?? this.floorId,
roomId: roomId ?? this.roomId,
departmentId: departmentId ?? this.departmentId,
assetName: assetName ?? this.assetName,
);
Map<String, dynamic> toJson() {
final map = <String, dynamic>{};
map['pageSize'] = pageSize;
map['pageNumber'] = pageNumber;
map['id'] = id;
map['assetId'] = assetId;
map['modelId'] = modelId;
map['ppmId'] = ppmId;
map['ppmScheduleId'] = ppmScheduleId;
map['classification'] = classification;
map['visitStatusId'] = visitStatusId;
map['deviceStatusId'] = deviceStatusId;
map['groupLeaderReviewId'] = groupLeaderReviewId;
map['assignedEmployeeId'] = assignedEmployeeId;
map['hasAssignedEmployee'] = hasAssignedEmployee;
map['assignedToId'] = assignedToId;
map['expectedDateFrom'] = expectedDateFrom;
map['expectedDateTo'] = expectedDateTo;
map['actualDateFrom'] = actualDateFrom;
map['actualDateTo'] = actualDateTo;
map['siteId'] = siteId;
map['jobSheetNo'] = jobSheetNo;
map['typeOfServiceId'] = typeOfServiceId;
map['planNumber'] = planNumber;
map['notified'] = notified;
map['mostRecent'] = mostRecent;
if (assetGroup != null) {
map['assetGroup'] = assetGroup.toJson();
}
map['buildingId'] = buildingId;
map['floorId'] = floorId;
map['roomId'] = roomId;
map['departmentId'] = departmentId;
map['assetName'] = assetName;
return map;
}
}

@ -91,7 +91,7 @@ class ServiceReport {
endofWorkTime = json['endofWorkTime']; endofWorkTime = json['endofWorkTime'];
workingHours = json['workingHours']; workingHours = json['workingHours'];
try { try {
timer = TimerModel(startAt: DateTime.tryParse(startofWorkTime ?? ""), endAt: DateTime.tryParse(endofWorkTime)); timer = TimerModel(startAt: DateTime.tryParse(startofWorkTime ?? ""), endAt: DateTime.tryParse(endofWorkTime ?? ""));
if (timer.endAt != null && timer.startAt != null) { if (timer.endAt != null && timer.startAt != null) {
timer.durationInSecond = (timer.endAt.difference(timer.startAt))?.inSeconds; timer.durationInSecond = (timer.endAt.difference(timer.startAt))?.inSeconds;
workingHours = (((timer.durationInSecond ?? 0) / 60) / 60); workingHours = (((timer.durationInSecond ?? 0) / 60) / 60);

@ -1,85 +0,0 @@
import 'package:test_sa/controllers/api_routes/urls.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/pantry/pentry.dart';
class Visit {
int id;
String serialNumber;
String expectDate;
String actualDate;
String createdOn;
int hospitalId;
String hospitalName;
int deviceId;
int ppmScheduleId;
String deviceSerialNumber;
String deviceArabicName;
String deviceEnglishName;
String employId;
String employName;
String modelAndBrand;
Pentry pentry;
Lookup status;
String assignTo;
String deviceNumber;
List<String> images;
Visit({
this.id,
this.ppmScheduleId,
this.serialNumber,
this.hospitalId,
this.hospitalName,
this.deviceId,
this.deviceSerialNumber,
this.deviceArabicName,
this.deviceEnglishName,
this.employId,
this.employName,
this.expectDate,
this.actualDate,
this.status,
this.modelAndBrand,
this.pentry,
this.images,
this.assignTo,
this.deviceNumber,
this.createdOn,
});
factory Visit.fromJson(Map<String, dynamic> parsedJson) {
List<String> images = [];
if (parsedJson["vAttachments"] is List) {
List list = parsedJson["vAttachments"];
images = list.map((e) {
return URLs.getFileUrl(e["attachmentURL"].toString());
}).toList();
}
return Visit(
id: parsedJson["id"],
serialNumber: parsedJson["visitCode"],
ppmScheduleId: parsedJson["ppmScheduleId"],
hospitalId: parsedJson["siteId"],
deviceNumber: parsedJson["assetNumber"],
hospitalName: parsedJson["siteName"],
deviceId: parsedJson["assetId"],
deviceSerialNumber: parsedJson["assetSerialNo"],
deviceEnglishName: parsedJson["assetName"],
deviceArabicName: parsedJson["assetName"],
employId: parsedJson["assignedEmployeeId"].toString(),
employName: parsedJson["assignedEmployeeName"],
expectDate: parsedJson["expectedDate"].toString().split("T").first,
actualDate: parsedJson["actualDate"].toString().split("T").first,
modelAndBrand: "${parsedJson["modelName"]} / ${parsedJson["manufacturerName"]}",
// contactStatus: parsedJson["contactStatus"],
images: images,
status: Lookup(
id: parsedJson["visitStatusId"], // actual value (0,1,2)
name: parsedJson["visitStatusName"] // text value
),
assignTo: parsedJson["assignedToName"],
pentry: Pentry.fromMap(parsedJson),
createdOn: parsedJson['createdOn'],
);
}
}

@ -1,45 +0,0 @@
import 'package:test_sa/models/engineer.dart';
import 'package:test_sa/models/visits/visit.dart';
class VisitsGroup {
// String userId;
// String workingHours;
// String travelingHours;
// String jobSheetNumber;
// String image;
// Lookup status;
// Lookup taskStatus;
// DateTime date;
Engineer engineer;
List<Visit> visits;
VisitsGroup({
// this.userId,
// this.status,
// this.date,
// this.jobSheetNumber,
// this.travelingHours,
// this.workingHours,
this.visits,
this.engineer,
// this.image,
// this.taskStatus,
});
Map<String, dynamic> toJson() {
Map<String, dynamic> jsonObject = {};
jsonObject["ids"] = visits.map((e) => e.id).toList();
jsonObject["assignedEmployeeId"] = engineer?.id;
// if(status != null) jsonObject["taskStatusId"] = status.id.toString();
// if(date != null) jsonObject["actualDate"] = date.toIso8601String();
// if(jobSheetNumber != null && jobSheetNumber.isNotEmpty)
// jsonObject["jobSheetNo"] = jobSheetNumber;
// if(travelingHours != null && travelingHours.isNotEmpty)
// jsonObject["travelingHours"] = travelingHours;
// if(workingHours != null && workingHours.isNotEmpty)
// jsonObject["workingHours"] = workingHours;
// if(image != null) jsonObject["image"] = image;
// if(taskStatus != null) jsonObject["task_status"] = taskStatus.id.toString();
return jsonObject;
}
}

@ -1,99 +0,0 @@
import 'package:test_sa/models/hospital.dart';
import 'package:test_sa/models/lookup.dart';
class VisitsSearch {
String deviceSerialNumber;
String deviceName;
String deviceNumber;
Hospital hospital;
String brand;
Lookup model;
Lookup contactStatus;
DateTime expectedDateFrom;
DateTime expectedDateTo;
DateTime actualDateFrom;
DateTime actualDateTo;
Lookup statusValue;
bool mostRecent;
VisitsSearch({
this.deviceSerialNumber,
this.statusValue,
this.brand,
this.hospital,
this.actualDateTo,
this.actualDateFrom,
this.model,
this.contactStatus,
this.expectedDateFrom,
this.expectedDateTo,
this.deviceNumber,
this.deviceName,
this.mostRecent = true,
});
fromSearch(VisitsSearch newSearch) {
deviceSerialNumber = newSearch.deviceSerialNumber;
brand = newSearch.brand;
hospital = newSearch.hospital;
actualDateTo = newSearch.actualDateTo;
actualDateFrom = newSearch.actualDateFrom;
model = newSearch.model;
contactStatus = newSearch.contactStatus;
expectedDateFrom = newSearch.expectedDateFrom;
expectedDateTo = newSearch.expectedDateTo;
statusValue = newSearch.statusValue;
mostRecent = newSearch.mostRecent;
deviceNumber = newSearch.deviceNumber;
deviceName = newSearch.deviceName;
}
Map<String, dynamic> toMap() {
Map<String, dynamic> _search = {};
if (deviceSerialNumber != null && deviceSerialNumber.isNotEmpty) {
_search["assetId"] = deviceSerialNumber;
}
if (hospital != null) {
_search["siteId"] = hospital.id;
}
if (mostRecent != null) {
_search["mostRecent"] = mostRecent;
}
if (brand != null && brand.isNotEmpty) {
// todo get new key
_search[""] = brand;
}
if (model != null) {
_search["modelId"] = model.id;
}
if (expectedDateFrom != null) {
_search["expectedDateFrom"] = expectedDateFrom.toIso8601String();
}
if (expectedDateTo != null) {
_search["expectedDateTo"] = expectedDateTo.toIso8601String();
}
if (actualDateFrom != null) {
_search["actualDateFrom"] = actualDateFrom.toIso8601String();
}
if (actualDateTo != null) {
_search["actualDateTo"] = actualDateTo.toIso8601String();
}
if (statusValue != null) {
_search["visitStatusId"] = statusValue.id;
}
if (contactStatus != null) {
_search["assignedToId"] = contactStatus.id;
}
return _search;
}
}

@ -40,12 +40,19 @@ class AppColor {
static const Color orange60 = Color(0xff886400); static const Color orange60 = Color(0xff886400);
static Color greenStatus(BuildContext context) => context.isDark ? const Color(0xff1FA269) : green50; static Color greenStatus(BuildContext context) => context.isDark ? const Color(0xff1FA269) : green50;
static Color blueStatus(BuildContext context) => context.isDark ? primary40 : primary50; static Color blueStatus(BuildContext context) => context.isDark ? primary40 : primary50;
static Color redStatus(BuildContext context) => context.isDark ? const Color(0xffFFB6B8) : red40; static Color redStatus(BuildContext context) => context.isDark ? const Color(0xffFFB6B8) : red40;
static Color yellowStatus(BuildContext context) => context.isDark ? const Color(0xffFFDA76) : orange40; static Color yellowStatus(BuildContext context) => context.isDark ? const Color(0xffFFDA76) : orange40;
static Color background(BuildContext context) => context.isDark ? neutral60 : Colors.white; static Color background(BuildContext context) => context.isDark ? neutral60 : Colors.white;
static Color selectedButtonColor(BuildContext context) => context.isDark ? neutral60 : neutral30; static Color selectedButtonColor(BuildContext context) => context.isDark ? neutral60 : neutral30;
static Color unSelectedButtonColor(BuildContext context) => context.isDark ? neutral60 : Colors.white; static Color unSelectedButtonColor(BuildContext context) => context.isDark ? neutral60 : Colors.white;
static Color filterButtonTextColor(BuildContext context) => context.isDark ? neutral30 : neutral50; static Color filterButtonTextColor(BuildContext context) => context.isDark ? neutral30 : neutral50;
static Color getRequestStatusTextColorByName(BuildContext context, String status) { static Color getRequestStatusTextColorByName(BuildContext context, String status) {

@ -28,6 +28,7 @@ class AppTextFormField extends StatefulWidget {
final Color backgroundColor; final Color backgroundColor;
final bool alignLabelWithHint; final bool alignLabelWithHint;
final bool showShadow; final bool showShadow;
final void Function() onTap;
const AppTextFormField({ const AppTextFormField({
Key key, Key key,
@ -54,6 +55,7 @@ class AppTextFormField extends StatefulWidget {
this.backgroundColor, this.backgroundColor,
this.showShadow = true, this.showShadow = true,
this.alignLabelWithHint, this.alignLabelWithHint,
this.onTap,
}) : super(key: key); }) : super(key: key);
@override @override
@ -90,6 +92,7 @@ class _AppTextFormFieldState extends State<AppTextFormField> {
textInputAction: widget.textInputType == TextInputType.multiline ? null : widget.textInputAction ?? TextInputAction.next, textInputAction: widget.textInputType == TextInputType.multiline ? null : widget.textInputAction ?? TextInputAction.next,
onEditingComplete: widget.onAction ?? () => FocusScope.of(context).nextFocus(), onEditingComplete: widget.onAction ?? () => FocusScope.of(context).nextFocus(),
style: AppTextStyle.body1?.copyWith(fontWeight: FontWeight.w500), style: AppTextStyle.body1?.copyWith(fontWeight: FontWeight.w500),
onTap: widget.onTap,
decoration: InputDecoration( decoration: InputDecoration(
alignLabelWithHint: widget.alignLabelWithHint, alignLabelWithHint: widget.alignLabelWithHint,
border: border, border: border,

@ -1,5 +1,4 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
@ -8,7 +7,6 @@ import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/pages/land_page/calender_fragments/daily_fragment.dart'; import 'package:test_sa/new_views/pages/land_page/calender_fragments/daily_fragment.dart';
import 'package:test_sa/new_views/pages/land_page/calender_fragments/weekly_fragment.dart'; import 'package:test_sa/new_views/pages/land_page/calender_fragments/weekly_fragment.dart';
import '../../../controllers/providers/api/all_requests_provider.dart';
import 'calender_fragments/monthly_fragment.dart'; import 'calender_fragments/monthly_fragment.dart';
class CalendarPage extends StatefulWidget { class CalendarPage extends StatefulWidget {
@ -24,7 +22,10 @@ class _CalendarPageState extends State<CalendarPage> with SingleTickerProviderSt
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_tabController = TabController(length: 3, vsync: this)..addListener(() {setState(() {});}); _tabController = TabController(length: 3, vsync: this)
..addListener(() {
setState(() {});
});
} }
@override @override

@ -7,7 +7,6 @@ import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import '../../../../controllers/providers/api/all_requests_provider.dart'; import '../../../../controllers/providers/api/all_requests_provider.dart';
import '../../../../views/widgets/loaders/no_item_found.dart';
import '../../../app_style/app_color.dart'; import '../../../app_style/app_color.dart';
import '../requests/asset_item_view.dart'; import '../requests/asset_item_view.dart';
import '../requests/gas_refill_item_view.dart'; import '../requests/gas_refill_item_view.dart';
@ -41,8 +40,11 @@ class _DailyFragmentState extends State<DailyFragment> {
children: [ children: [
DateFormat("EEEE, d MMMM, yyyy", context.isAr ? "ar" : "en").format(DateTime.now()).heading5(context), DateFormat("EEEE, d MMMM, yyyy", context.isAr ? "ar" : "en").format(DateTime.now()).heading5(context),
const Divider().defaultStyle(context), const Divider().defaultStyle(context),
if (snapshot.calendarRequests?.requestsDetails?.isEmpty ?? true) Center(child: context.translation.noDataFound.heading5(context).custom(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50),).paddingOnly(top: 16,bottom: 16), if (snapshot.calendarRequests?.requestsDetails?.isEmpty ?? true)
ListView.separated( Center(
child: context.translation.noDataFound.heading5(context).custom(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50),
).paddingOnly(top: 16, bottom: 16),
ListView.separated(
shrinkWrap: true, shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
itemBuilder: (cxt, index) { itemBuilder: (cxt, index) {

@ -53,7 +53,7 @@ class _WeeklyFragmentState extends State<WeeklyFragment> {
weekendDays: const [], weekendDays: const [],
onCalendarCreated: (controller) {}, onCalendarCreated: (controller) {},
onPageChanged: (date) { onPageChanged: (date) {
if(!snapshot.isCalendarLoading){ if (!snapshot.isCalendarLoading) {
_initialDate = date; _initialDate = date;
Provider.of<AllRequestsProvider>(context, listen: false) Provider.of<AllRequestsProvider>(context, listen: false)
@ -90,8 +90,8 @@ class _WeeklyFragmentState extends State<WeeklyFragment> {
day: day, day: day,
fill: snapshot.calendarRequests.requestsDetails?.firstWhere( fill: snapshot.calendarRequests.requestsDetails?.firstWhere(
(element) => (element.date != null) && (DateTime.tryParse(element.date).day == (dateTime)?.day), (element) => (element.date != null) && (DateTime.tryParse(element.date).day == (dateTime)?.day),
orElse: () => null, orElse: () => null,
) != ) !=
null, null,
).toShimmer(isShow: snapshot.isCalendarLoading); ).toShimmer(isShow: snapshot.isCalendarLoading);
}, },

@ -5,10 +5,9 @@ import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/all_requests_and_count_model.dart'; import 'package:test_sa/models/all_requests_and_count_model.dart';
import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/views/pages/user/visits/visit_details.dart';
import '../../../../views/pages/user/ppm/ppm_details_page.dart';
import '../../../../views/widgets/requests/request_status.dart'; import '../../../../views/widgets/requests/request_status.dart';
class PpmItemView extends StatelessWidget { class PpmItemView extends StatelessWidget {
@ -47,8 +46,8 @@ class PpmItemView extends StatelessWidget {
8.height, 8.height,
context.translation.ppmRequest.heading5(context), context.translation.ppmRequest.heading5(context),
8.height, 8.height,
'${context.translation.assetNumber}: ${request.assetName}'.bodyText(context), '${context.translation.assetNumber}: ${request.assetNo}'.bodyText(context),
'${context.translation.assetSN}: ${request.assetNo}'.bodyText(context), '${context.translation.assetSN}: ${request.assetSN}'.bodyText(context),
'${context.translation.code}: ${request.code}'.bodyText(context), '${context.translation.code}: ${request.code}'.bodyText(context),
16.height, 16.height,
Row( Row(
@ -64,11 +63,7 @@ class PpmItemView extends StatelessWidget {
), ),
], ],
).toShadowContainer(context, showShadow: showShadow).onPress(() { ).toShadowContainer(context, showShadow: showShadow).onPress(() {
Navigator.of(context).push( Navigator.of(context).push(MaterialPageRoute(builder: (_) => PpmDetailsPage(request: request)));
MaterialPageRoute(
builder: (_) => VisitDetailsPage(visit: Visit(id: request.id), priority: request.priority),
),
);
}); });
} }
} }

@ -0,0 +1,35 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:test_sa/models/lookup.dart';
import '../../controllers/api_routes/api_manager.dart';
import '../../controllers/api_routes/urls.dart';
import 'loading_list_notifier.dart';
class PpmChecklistStatusProvider extends LoadingListNotifier<Lookup> {
@override
Future getDate() async {
if (loading ?? false) return -2;
loading = true;
notifyListeners();
Response response;
try {
response = await ApiManager.instance.get(URLs.getPentryTaskStatus);
} catch (error) {
loading = false;
stateCode = -1;
notifyListeners();
return -1;
}
stateCode = response.statusCode;
if (response.statusCode >= 200 && response.statusCode < 300) {
// client's request was successfully received
List listJson = json.decode(response.body)["data"];
items = listJson.map((department) => Lookup.fromJson(department)).toList();
}
loading = false;
notifyListeners();
return response.statusCode;
}
}

@ -86,7 +86,7 @@ class _SparePartsBottomSheetState extends State<SparePartsBottomSheet> {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
ASubTitle(context.translation.partNumberName), ASubTitle(context.translation.partNumber),
_validate && _workOrder.sparePartsWorkOrders == null _validate && _workOrder.sparePartsWorkOrders == null
? ASubTitle( ? ASubTitle(
context.translation.requiredWord, context.translation.requiredWord,

@ -12,8 +12,8 @@ import 'package:test_sa/new_views/pages/new_gas_refill_request_page.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/pages/device_transfer/track_device_transfer.dart'; import 'package:test_sa/views/pages/device_transfer/track_device_transfer.dart';
import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart'; import 'package:test_sa/views/pages/user/gas_refill/track_gas_refill.dart';
import 'package:test_sa/views/pages/user/ppm/ppm_page.dart';
import 'package:test_sa/views/pages/user/requests/create_service_request_page.dart'; import 'package:test_sa/views/pages/user/requests/create_service_request_page.dart';
import 'package:test_sa/views/pages/user/visits/regular_visits_page.dart';
import 'package:test_sa/views/widgets/dialogs/dialog.dart'; import 'package:test_sa/views/widgets/dialogs/dialog.dart';
import '../../../models/enums/user_types.dart'; import '../../../models/enums/user_types.dart';
@ -164,7 +164,7 @@ class _LandPageState extends State<LandPage> {
text: context.translation.preventiveMaintenance, text: context.translation.preventiveMaintenance,
icon: FontAwesomeIcons.personWalking, icon: FontAwesomeIcons.personWalking,
onPressed: () { onPressed: () {
Navigator.of(context).pushNamed(RegularVisitsPage.id); Navigator.of(context).pushNamed(PpmPage.id);
}, },
), ),
//if (_userProvider.user.type == UsersTypes.engineer) //if (_userProvider.user.type == UsersTypes.engineer)

@ -1,46 +1,45 @@
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/providers/api/regular_visits_provider.dart'; import 'package:test_sa/controllers/providers/api/ppm_provider.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/visits/visit.dart'; import 'package:test_sa/models/all_requests_and_count_model.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/pages/user/visits/pantry/edit_pentry.dart'; import 'package:test_sa/views/pages/user/ppm/update_ppm/edit_ppm.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart'; import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_item_found.dart'; import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
import '../../../../controllers/providers/api/user_provider.dart'; import '../../../../controllers/providers/api/user_provider.dart';
import '../../../../models/enums/user_types.dart'; import '../../../../models/enums/user_types.dart';
import '../../../../models/ppm/ppm.dart';
import '../../../../new_views/app_style/app_color.dart'; import '../../../../new_views/app_style/app_color.dart';
import '../../../../new_views/common_widgets/app_filled_button.dart'; import '../../../../new_views/common_widgets/app_filled_button.dart';
import '../../../widgets/requests/request_status.dart'; import '../../../widgets/requests/request_status.dart';
class VisitDetailsPage extends StatelessWidget { class PpmDetailsPage extends StatelessWidget {
static const String id = "/visit-details"; static const String id = "/visit-details";
final Visit visit; final RequestsDetails request;
final String priority;
const VisitDetailsPage({Key key, this.visit, this.priority}) : super(key: key); const PpmDetailsPage({Key key, this.request}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
UserProvider userProvider = Provider.of<UserProvider>(context); UserProvider userProvider = Provider.of<UserProvider>(context);
PpmProvider ppmProvider = Provider.of<PpmProvider>(context);
RegularVisitsProvider _visitsProvider = Provider.of<RegularVisitsProvider>(context);
return Scaffold( return Scaffold(
appBar: DefaultAppBar(title: context.translation.preventiveMaintenance), appBar: DefaultAppBar(title: context.translation.preventiveMaintenance),
body: SafeArea( body: SafeArea(
child: FutureBuilder( child: FutureBuilder(
future: _visitsProvider.getVisitObjectById(visit.id), future: ppmProvider.getPpmById(request.id),
builder: (context, snap) { builder: (context, snap) {
if (snap.connectionState == ConnectionState.waiting) { if (snap.connectionState == ConnectionState.waiting) {
return const ALoading(); return const ALoading();
} else if (snap.hasData) { } else if (snap.hasData) {
Visit visit = snap.data; Ppm ppm = snap.data;
return Column(children: [ return Column(children: [
SingleChildScrollView( SingleChildScrollView(
@ -49,42 +48,42 @@ class VisitDetailsPage extends StatelessWidget {
children: [ children: [
Row( Row(
children: [ children: [
if (priority != null) if (request.priority != null)
StatusLabel( StatusLabel(
label: priority, label: request.priority,
textColor: AppColor.getRequestStatusTextColorByName(context, priority), textColor: AppColor.getRequestStatusTextColorByName(context, request.priority),
backgroundColor: AppColor.getRequestStatusColorByName(context, priority), backgroundColor: AppColor.getRequestStatusColorByName(context, request.priority),
), ),
if (priority != null) 8.width, if (request.priority != null) 8.width,
StatusLabel( StatusLabel(
label: visit.status.name, label: ppm.visitStatusName,
id: visit.status.id, id: ppm.deviceStatusId,
textColor: AppColor.getRequestStatusTextColorByName(context, visit.status.name), textColor: AppColor.getRequestStatusTextColorByName(context, ppm.visitStatusName),
backgroundColor: AppColor.getRequestStatusColorByName(context, visit.status.name), backgroundColor: AppColor.getRequestStatusColorByName(context, ppm.visitStatusName),
), ),
1.width.expanded, 1.width.expanded,
], ],
), ),
8.height, 8.height,
visit.deviceEnglishName.heading5(context), ppm.assetName.heading5(context),
8.height, 8.height,
'${context.translation.assetNumber}: ${visit.deviceNumber}'.bodyText(context), '${context.translation.assetNumber}: ${ppm.assetNumber}'.bodyText(context),
'${context.translation.assetSN}: ${visit.deviceSerialNumber}'.bodyText(context), '${context.translation.assetSN}: ${ppm.assetSerialNo}'.bodyText(context),
'${context.translation.code}: ${visit.serialNumber}'.bodyText(context), '${context.translation.code}: ${ppm.visitCode}'.bodyText(context),
const Divider().defaultStyle(context), const Divider().defaultStyle(context),
'${context.translation.expectDate}: ${visit.expectDate?.toServiceRequestDetailsFormat}'.bodyText(context), '${context.translation.expectDate}: ${ppm.expectedDate?.toServiceRequestDetailsFormat}'.bodyText(context),
'${context.translation.actualDate}: ${visit.actualDate?.toServiceRequestDetailsFormat}'.bodyText(context), '${context.translation.actualDate}: ${ppm.actualDate?.toServiceRequestDetailsFormat}'.bodyText(context),
const Divider().defaultStyle(context), const Divider().defaultStyle(context),
'${context.translation.assignedTo}: ${visit.assignTo}'.bodyText(context), '${context.translation.assignedTo}: ${ppm.assignedToName}'.bodyText(context),
'${context.translation.engineerName}: ${visit.employName}'.bodyText(context), '${context.translation.engineerName}: ${ppm.assignedEmployeeName}'.bodyText(context),
'${context.translation.site}: ${visit.hospitalName}'.bodyText(context), '${context.translation.site}: ${ppm.siteName}'.bodyText(context),
], ],
).toShadowContainer(context).paddingAll(16), ).toShadowContainer(context).paddingAll(16),
).expanded, ).expanded,
if (userProvider.user.type == UsersTypes.engineer && (visit.status.id != 270 || visit.status.id != 269)) if (userProvider.user.type == UsersTypes.engineer && (ppm.visitStatusId != 270 || ppm.visitStatusId != 269))
AppFilledButton( AppFilledButton(
onPressed: () { onPressed: () {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => EditPentry(visit: visit, pentry: visit.pentry))); Navigator.of(context).push(MaterialPageRoute(builder: (_) => EditPpm(ppm: ppm, details: request)));
}, },
label: context.translation.updateRequest, label: context.translation.updateRequest,
).paddingAll(16) ).paddingAll(16)

@ -0,0 +1,69 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/ppm_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/extensions/context_extension.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import '../../../../models/ppm/ppm.dart';
import '../../../widgets/loaders/lazy_loading.dart';
import '../../../widgets/loaders/no_item_found.dart';
import '../../../widgets/ppm/ppm_item.dart';
class PpmPage extends StatefulWidget {
static const String id = "/ppm_page";
const PpmPage({Key key}) : super(key: key);
@override
_PpmPageState createState() => _PpmPageState();
}
class _PpmPageState extends State<PpmPage> with TickerProviderStateMixin {
PpmProvider _visitsProvider;
UserProvider _userProvider;
SettingProvider _settingProvider;
@override
Widget build(BuildContext context) {
_visitsProvider = Provider.of<PpmProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
return Scaffold(
appBar: DefaultAppBar(title: context.translation.preventiveMaintenance),
body: SafeArea(
child: LoadingManager(
isLoading: _visitsProvider.isLoading,
isFailedLoading: _visitsProvider.ppms == null,
stateCode: _visitsProvider.stateCode,
onRefresh: () async {
_visitsProvider.reset();
await _visitsProvider.getVisits(
user: _userProvider.user,
host: _settingProvider.host,
);
},
child: _visitsProvider.ppms.isEmpty
? NoItemFound(message: context.translation.noVisitsFound)
: LazyLoading(
nextPage: _visitsProvider.nextPage,
onLazyLoad: () async {
await _visitsProvider.getVisits(user: _userProvider.user, host: _settingProvider.host);
},
child: ListView.builder(
itemCount: _visitsProvider.ppms.length,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
itemBuilder: (context, itemIndex) {
Ppm ppm = _visitsProvider.ppms[itemIndex];
return Padding(padding: const EdgeInsets.only(bottom: 8.0), child: PpmItem(ppm: ppm));
},
),
),
),
),
);
}
}

@ -1,65 +1,53 @@
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/providers/api/regular_visits_provider.dart'; import 'package:test_sa/controllers/providers/api/ppm_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/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/pantry/calibration_tools.dart'; import 'package:test_sa/models/all_requests_and_count_model.dart';
import 'package:test_sa/models/pantry/pentry.dart'; import 'package:test_sa/models/ppm/ppm.dart';
import 'package:test_sa/models/pantry/pm_kit.dart';
import 'package:test_sa/models/pantry/ppm_check_list.dart';
import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.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_pm_kit_form.dart';
import 'package:test_sa/views/widgets/pentry/pentry_ppm_check_list_form.dart';
import '../../../../../extensions/text_extensions.dart';
import '../../../../widgets/pentry/pentry_calibration_tool_form.dart';
import '../../../../widgets/pentry/pentry_pm_kit_form.dart';
import '../../../../widgets/pentry/pentry_ppm_check_list_form.dart';
import '../../../../widgets/pentry/pentry_tbs_form.dart'; import '../../../../widgets/pentry/pentry_tbs_form.dart';
class EditPentry extends StatefulWidget { class EditPpm extends StatefulWidget {
final Pentry pentry; final Ppm ppm;
final Visit visit; final RequestsDetails details;
const EditPentry({Key key, this.pentry, this.visit}) : super(key: key); const EditPpm({Key key, this.ppm, this.details}) : super(key: key);
@override @override
State<EditPentry> createState() => _EditPentryState(); State<EditPpm> createState() => _EditPpmState();
} }
class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateMixin { class _EditPpmState extends State<EditPpm> with SingleTickerProviderStateMixin {
bool _isLoading = false;
bool _validate = false;
UserProvider _userProvider; UserProvider _userProvider;
SettingProvider _settingProvider; PpmProvider _regularVisitsProvider;
RegularVisitsProvider _regularVisitsProvider; Ppm _ppm;
Pentry _pentry;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TabController _tabController; TabController _tabController;
_onSubmit() async { _onSubmit() async {
_validate = true; if (!(await _ppm.validate(context))) {
if (!(await _pentry.validate())) {
setState(() {}); setState(() {});
return; return;
} }
_ppm.removeEmptyObjects();
_pentry.clearEmptyObjects(); await _regularVisitsProvider.updatePentry(context, user: _userProvider.user, ppm: widget.ppm);
await _regularVisitsProvider.updatePentry(context, user: _userProvider.user, pentry: _pentry, visit: widget.visit);
} }
@override @override
void initState() { void initState() {
_pentry = widget.pentry.copyWith(); _ppm = widget.ppm;
if (_pentry.pmKits.isEmpty) _pentry.pmKits.add(PMKit());
if (_pentry.calibrationTools.isEmpty) _pentry.calibrationTools.add(CalibrationTool());
if (_pentry.ppmCheckLists.isEmpty) _pentry.ppmCheckLists.add(PPMCheckList());
_tabController = TabController(length: 4, vsync: this); _tabController = TabController(length: 4, vsync: this);
super.initState(); super.initState();
} }
@ -73,29 +61,30 @@ class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateM
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context); _regularVisitsProvider = Provider.of<PpmProvider>(context);
_regularVisitsProvider = Provider.of<RegularVisitsProvider>(context);
return Scaffold( return Scaffold(
appBar: DefaultAppBar(title: context.translation.preventiveMaintenance), appBar: DefaultAppBar(title: context.translation.preventiveMaintenance),
key: _scaffoldKey, key: _scaffoldKey,
body: SafeArea( body: SafeArea(
child: LoadingManager( child: LoadingManager(
isLoading: _isLoading, isLoading: false,
isFailedLoading: false, isFailedLoading: false,
stateCode: 200, stateCode: 200,
onRefresh: () async {}, onRefresh: () async {},
child: Column( child: Column(
children: [ children: [
Container( Container(
decoration: BoxDecoration(color: context.isDark ? AppColor.neutral10 : AppColor.neutral30, borderRadius: BorderRadius.circular(16)), decoration: BoxDecoration(color: context.isDark ? AppColor.neutral50 : AppColor.neutral30, borderRadius: BorderRadius.circular(16)),
child: TabBar( child: TabBar(
controller: _tabController, controller: _tabController,
isScrollable: true, isScrollable: true,
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
labelColor: context.isDark ? AppColor.neutral10 : AppColor.neutral60, labelColor: context.isDark ? AppColor.neutral30 : AppColor.neutral60,
unselectedLabelColor: AppColor.neutral20, unselectedLabelColor: context.isDark ? AppColor.neutral10 : AppColor.neutral20,
unselectedLabelStyle: AppTextStyles.bodyText,
labelStyle: AppTextStyles.bodyText,
indicatorPadding: const EdgeInsets.all(4), indicatorPadding: const EdgeInsets.all(4),
indicator: BoxDecoration(color: Theme.of(context).cardColor, borderRadius: BorderRadius.circular(13)), indicator: BoxDecoration(color: context.isDark ? AppColor.neutral60 : Theme.of(context).cardColor, borderRadius: BorderRadius.circular(13)),
onTap: (index) { onTap: (index) {
setState(() {}); setState(() {});
}, },
@ -111,10 +100,10 @@ class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateM
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
controller: _tabController, controller: _tabController,
children: [ children: [
PentryTBSForm(model: _pentry, enableValidate: _validate), PentryTBSForm(model: _ppm),
PentryCalibrationToolForm(models: _pentry.calibrationTools, enableValidate: _validate), PentryCalibrationToolForm(models: _ppm.vCalibrationTools),
PentryPMKitForm(models: _pentry.pmKits, enableValidate: _validate, assetId: widget.visit?.deviceId), PentryPMKitForm(models: _ppm.vKits, assetId: widget.ppm?.assetId),
PentryPMChecklistForm(models: _pentry.ppmCheckLists, enableValidate: _validate), PentryPMChecklistForm(models: _ppm.vChecklists),
], ],
).expanded, ).expanded,
AppFilledButton( AppFilledButton(

@ -0,0 +1,49 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/models/ppm/ppm.dart';
class FutureEditPpm extends StatefulWidget {
final Ppm ppm;
const FutureEditPpm({Key key, this.ppm}) : super(key: key);
@override
State<FutureEditPpm> createState() => _FutureEditPpmState();
}
class _FutureEditPpmState extends State<FutureEditPpm> {
UserProvider _userProvider;
SettingProvider _settingProvider;
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
//String requestId = ModalRoute.of(context).settings.arguments;
// return Scaffold(
// body: FutureBuilder<Pentry>(
// future: RegularVisitsProvider().getPentry(user: _userProvider.user, host: _settingProvider.host, id: widget.ppm.id),
// builder: (BuildContext context, AsyncSnapshot<Pentry> snapshot) {
// if (snapshot.hasError) {
// return FailedLoading(
// message: context.translation.failedToCompleteRequest,
// onReload: () {
// setState(() {});
// },
// );
// }
// if (snapshot.hasData) {
// return EditPentry(
// pentry: snapshot.data,
// ppm: widget.ppm,
// );
// }
// return const Center(child: ALoading());
// },
// ),
// );
}
}

@ -112,7 +112,7 @@ class _ProfilePageState extends State<ProfilePage> {
if (croppedFile != null) { if (croppedFile != null) {
await snapshot.uploadProfileImage(_user.userID, File(croppedFile.path)); await snapshot.uploadProfileImage(_user.userID, File(croppedFile.path));
Provider.of<SettingProvider>(context,listen: false).setUser(_userProvider.user); Provider.of<SettingProvider>(context, listen: false).setUser(_userProvider.user);
} }
} }
}), }),

@ -36,6 +36,7 @@ class ServiceRequestDetailsPage extends StatefulWidget {
class _ServiceRequestDetailsPageState extends State<ServiceRequestDetailsPage> { class _ServiceRequestDetailsPageState extends State<ServiceRequestDetailsPage> {
bool loading = false; bool loading = false;
ServiceRequest serviceRequest; ServiceRequest serviceRequest;
@override @override
void initState() { void initState() {
super.initState(); super.initState();

@ -17,6 +17,7 @@ class PartNoButton extends StatefulWidget {
final List<SparePartsWorkOrders> initialList; final List<SparePartsWorkOrders> initialList;
final TextEditingController controller; final TextEditingController controller;
final Function(List<SparePartsWorkOrders> sparePart) onChange; final Function(List<SparePartsWorkOrders> sparePart) onChange;
const PartNoButton({@required this.spareParts, @required this.controller, this.initialList, this.onChange, Key key}) : super(key: key); const PartNoButton({@required this.spareParts, @required this.controller, this.initialList, this.onChange, Key key}) : super(key: key);
@override @override
@ -56,6 +57,8 @@ class _PartNoButtonState extends State<PartNoButton> {
childrenPadding: const EdgeInsets.symmetric(horizontal: 16), childrenPadding: const EdgeInsets.symmetric(horizontal: 16),
backgroundColor: AppColor.background(context), backgroundColor: AppColor.background(context),
collapsedBackgroundColor: AppColor.background(context), collapsedBackgroundColor: AppColor.background(context),
iconColor: context.isDark ? AppColor.neutral30 : AppColor.neutral50,
collapsedIconColor: context.isDark ? AppColor.neutral30 : AppColor.neutral50,
children: [ children: [
SingleItemDropDownMenu<SparePart, NullableLoadingProvider>( SingleItemDropDownMenu<SparePart, NullableLoadingProvider>(
context: context, context: context,

@ -1,55 +0,0 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/regular_visits_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/extensions/context_extension.dart';
import 'package:test_sa/models/pantry/pentry.dart';
import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/views/pages/user/visits/pantry/edit_pentry.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/failed_loading.dart';
class FutureEditPentry extends StatefulWidget {
final Visit visit;
const FutureEditPentry({Key key, this.visit}) : super(key: key);
@override
State<FutureEditPentry> createState() => _FutureEditPentryState();
}
class _FutureEditPentryState extends State<FutureEditPentry> {
UserProvider _userProvider;
SettingProvider _settingProvider;
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
//String requestId = ModalRoute.of(context).settings.arguments;
return Scaffold(
body: FutureBuilder<Pentry>(
future: RegularVisitsProvider().getPentry(user: _userProvider.user, host: _settingProvider.host, id: widget.visit.id),
builder: (BuildContext context, AsyncSnapshot<Pentry> snapshot) {
if (snapshot.hasError) {
return FailedLoading(
message: context.translation.failedToCompleteRequest,
onReload: () {
setState(() {});
},
);
}
if (snapshot.hasData) {
return EditPentry(
pentry: snapshot.data,
visit: widget.visit,
);
}
return const Center(child: ALoading());
},
),
);
}
}

@ -1,181 +0,0 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/providers/api/preventive_maintenance_visits_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/extensions/context_extension.dart';
import 'package:test_sa/models/visits/visits_group.dart';
import 'package:test_sa/models/visits/visits_search.dart';
import 'package:test_sa/views/pages/user/visits/update_visits_group_sheet.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_icon_button.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/search/visits_search_bar.dart';
import 'package:test_sa/views/widgets/visits/visits_list.dart';
class PreventiveMaintenanceVisitsPage extends StatefulWidget {
static final String id = "/preventive-maintenance-visits";
@override
_PreventiveMaintenanceVisitsPageState createState() => _PreventiveMaintenanceVisitsPageState();
}
class _PreventiveMaintenanceVisitsPageState extends State<PreventiveMaintenanceVisitsPage> with TickerProviderStateMixin {
PreventiveMaintenanceVisitsProvider _visitsProvider;
UserProvider _userProvider;
SettingProvider _settingProvider;
@override
Widget build(BuildContext context) {
_visitsProvider = Provider.of<PreventiveMaintenanceVisitsProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
return Scaffold(
body: SafeArea(
child: LoadingManager(
isLoading: _visitsProvider.isLoading,
isFailedLoading: _visitsProvider.visits == null,
stateCode: _visitsProvider.stateCode,
onRefresh: () async {
//_visitsProvider.visitsSearch = VisitsSearch();
_visitsProvider.reset();
await _visitsProvider.getVisits(
user: _userProvider.user,
host: _settingProvider.host,
//visitsSearch: _visitsSearch
);
},
child: Stack(
children: [
Column(
children: [
Container(
// color: AColors.primaryColor,
padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
child: Column(
children: [
Row(
children: [
ABackButton(),
Expanded(
child: Center(
child: Text(
context.translation.preventiveMaintenance,
// style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
),
),
),
AIconButton(
iconData: Icons.search,
// color: AColors.secondaryColor,
buttonSize: 42,
// backgroundColor: AColors.white,
onPressed: () async {
VisitsSearch _temp = await showModalBottomSheet(
context: context,
isScrollControlled: true,
builder: (context) {
return VisitsSearchDialog(
initialSearchValue: _visitsProvider.visitsSearch,
);
});
if (_temp != null) {
_visitsProvider.visitsSearch = _temp;
_visitsProvider.reset();
setState(() {});
await _visitsProvider.getVisits(
user: _userProvider.user,
host: _settingProvider.host,
//visitsSearch: _visitsSearch
);
}
},
),
SizedBox(
width: 16,
)
],
),
],
),
),
Visibility(
visible: _visitsProvider.visitsSearch.toMap().isNotEmpty,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: AButton(
text: context.translation.clearSearch,
onPressed: () {
_visitsProvider.visitsSearch = VisitsSearch();
_visitsProvider.reset();
setState(() {});
},
),
),
),
Expanded(
child: VisitsList(
nextPage: _visitsProvider.nextPage,
onLazyLoad: () async {
await _visitsProvider.getVisits(
user: _userProvider.user,
host: _settingProvider.host,
//visitsSearch: _visitsSearch
);
},
onEditGroup: (visits) async {
VisitsGroup _group = await showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) {
return UpdateVisitsGroupSheet(
visits: visits,
title: context.translation.updatePreventiveMaintenance,
);
},
) as VisitsGroup;
if (_group != null) {
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return CupertinoAlertDialog(
title: Text(context.translation.updatingDots),
content: Center(child: CircularProgressIndicator()),
);
},
);
int status = await _visitsProvider.updateGroupOfVisits(user: _userProvider.user, host: _settingProvider.host, group: _group);
Navigator.of(context).pop();
if (status >= 200 && status < 300) {
Fluttertoast.showToast(
msg: context.translation.preventiveMaintenanceUpdatedSuccessfully,
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
);
} else {
Fluttertoast.showToast(
msg: HttpStatusManger.getStatusMessage(status: status, subtitle: context.translation),
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
);
}
}
},
visits: _visitsProvider.visits,
),
),
],
),
],
),
),
),
);
}
}

@ -1,225 +0,0 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/api_routes/http_status_manger.dart';
import 'package:test_sa/controllers/providers/api/regular_visits_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/extensions/context_extension.dart';
import 'package:test_sa/models/visits/visits_group.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/views/pages/user/visits/update_visits_group_sheet.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
import 'package:test_sa/views/widgets/visits/visits_list.dart';
class RegularVisitsPage extends StatefulWidget {
static final String id = "/Regular-visits";
@override
_RegularVisitsPageState createState() => _RegularVisitsPageState();
}
class _RegularVisitsPageState extends State<RegularVisitsPage> with TickerProviderStateMixin {
RegularVisitsProvider _visitsProvider;
UserProvider _userProvider;
SettingProvider _settingProvider;
bool _expandedSearch = false;
@override
Widget build(BuildContext context) {
_visitsProvider = Provider.of<RegularVisitsProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
return Scaffold(
appBar: DefaultAppBar(title: context.translation.preventiveMaintenance),
body: SafeArea(
child: LoadingManager(
isLoading: _visitsProvider.isLoading,
isFailedLoading: _visitsProvider.visits == null,
stateCode: _visitsProvider.stateCode,
onRefresh: () async {
_visitsProvider.reset();
//_visitsProvider.visitsSearch = VisitsSearch();
await _visitsProvider.getVisits(
user: _userProvider.user,
host: _settingProvider.host,
);
},
child: VisitsList(
nextPage: _visitsProvider.nextPage,
onLazyLoad: () async {
await _visitsProvider.getVisits(
user: _userProvider.user,
host: _settingProvider.host,
);
},
onEditGroup: (visits) async {
VisitsGroup group = await showModalBottomSheet(
isScrollControlled: true,
context: context,
builder: (context) {
return UpdateVisitsGroupSheet(
visits: visits,
title: context.translation.updateRegularVisits,
);
},
) as VisitsGroup;
if (group != null) {
showDialog<void>(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return CupertinoAlertDialog(
title: Text(context.translation.updatingDots),
content: Center(child: CircularProgressIndicator()),
);
},
);
int status = await _visitsProvider.updateGroupOfVisits(user: _userProvider.user, host: _settingProvider.host, group: group);
Navigator.of(context).pop();
if (status >= 200 && status < 300) {
Fluttertoast.showToast(
msg: context.translation.preventiveMaintenanceUpdatedSuccessfully,
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
);
} else {
Fluttertoast.showToast(
msg: HttpStatusManger.getStatusMessage(status: status, subtitle: context.translation),
toastLength: Toast.LENGTH_LONG,
gravity: ToastGravity.BOTTOM,
);
}
}
},
visits: _visitsProvider.visits,
),
// child: Stack(
// children: [
// Column(
// children: [
// Container(
// color: AColors.primaryColor,
// padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 4),
// child: Column(
// children: [
// Row(
// children: [
// ABackButton(),
// Expanded(
// child: Center(
// child: Text(
// context.translation.preventiveMaintenance,
// style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontStyle: FontStyle.italic),
// ),
// ),
// ),
// AnimatedSwitcher(
// duration: Duration(milliseconds: 400),
// child: AIconButton(
// key: ValueKey(_expandedSearch),
// iconData: _expandedSearch ? Icons.keyboard_arrow_up : Icons.search,
// color: AColors.secondaryColor,
// buttonSize: 42,
// backgroundColor: AColors.white,
// onPressed: () async {
// VisitsSearch _temp = await showModalBottomSheet(
// context: context,
// isScrollControlled: true,
// builder: (context) {
// return VisitsSearchDialog(
// initialSearchValue: _visitsProvider.visitsSearch,
// );
// });
// if (_temp != null) {
// _visitsProvider.visitsSearch.fromSearch(_temp);
// _visitsProvider.reset();
// setState(() {});
// }
// },
// ),
// ),
// SizedBox(
// width: 16,
// )
// ],
// ),
// ],
// ),
// ),
// Visibility(
// visible: (_visitsProvider.visitsSearch.toMap()..remove("mostRecent")).isNotEmpty,
// child: Padding(
// padding: const EdgeInsets.all(8.0),
// child: AButton(
// text: context.translation.clearSearch,
// onPressed: () {
// _visitsProvider.visitsSearch = VisitsSearch();
// _visitsProvider.reset();
// setState(() {});
// },
// ),
// ),
// ),
// Expanded(
// child: VisitsList(
// nextPage: _visitsProvider.nextPage,
// onLazyLoad: () async {
// await _visitsProvider.getVisits(
// user: _userProvider.user,
// host: _settingProvider.host,
// );
// },
// onEditGroup: (visits) async {
// VisitsGroup _group = await showModalBottomSheet(
// isScrollControlled: true,
// context: context,
// builder: (context) {
// return UpdateVisitsGroupSheet(
// visits: visits,
// title: context.translation.updateRegularVisits,
// );
// },
// ) as VisitsGroup;
// if (_group != null) {
// showDialog<void>(
// context: context,
// barrierDismissible: false,
// builder: (BuildContext context) {
// return CupertinoAlertDialog(
// title: Text(context.translation.updatingDots),
// content: Center(child: CircularProgressIndicator()),
// );
// },
// );
// int status = await _visitsProvider.updateGroupOfVisits(user: _userProvider.user, host: _settingProvider.host, group: _group);
// Navigator.of(context).pop();
// if (status >= 200 && status < 300) {
// Fluttertoast.showToast(
// msg: context.translation.preventiveMaintenanceUpdatedSuccessfully,
// toastLength: Toast.LENGTH_LONG,
// gravity: ToastGravity.BOTTOM,
// );
// } else {
// Fluttertoast.showToast(
// msg: HttpStatusManger.getStatusMessage(status: status, subtitle: context.translation),
// toastLength: Toast.LENGTH_LONG,
// gravity: ToastGravity.BOTTOM,
// );
// }
// }
// },
// visits: _visitsProvider.visits,
// ),
// ),
// ],
// ),
// ],
// ),
),
),
);
}
}

@ -1,242 +0,0 @@
import 'package:flutter/material.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/models/visits/visits_group.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/status/employee/engineers_mune.dart';
import 'package:test_sa/views/widgets/visits/visit_status.dart';
class UpdateVisitsGroupSheet extends StatefulWidget {
final List<Visit> visits;
final String title;
const UpdateVisitsGroupSheet({Key key, this.visits, this.title}) : super(key: key);
@override
_UpdateVisitsGroupSheetState createState() => _UpdateVisitsGroupSheetState();
}
class _UpdateVisitsGroupSheetState extends State<UpdateVisitsGroupSheet> {
// List<Lookup> status = [
// Lookup(name: "Done", id: 0,),
// Lookup(name: "Not Yet", id: 1),
// Lookup(name: "On Hold", id: 2,),
// ];
//
// List<Lookup> taskStatus = [
// Lookup(name: "Passed", id: 0,),
// Lookup(name: "Failed", id: 1),
// ];
VisitsGroup _group = VisitsGroup();
// File _image;
@override
void initState() {
super.initState();
_group.visits = widget.visits;
//_group.date = DateTime.now();
}
@override
Widget build(BuildContext context) {
return Container(
height: MediaQuery.of(context).size.height / 1.3,
padding: EdgeInsets.symmetric(
horizontal: 16.0 * AppStyle.getScaleFactor(context),
vertical: 8.0 * AppStyle.getScaleFactor(context),
),
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Expanded(
child: Text(
widget.title ?? context.translation.updateVisitsGroup,
style: Theme.of(context).textTheme.subtitle1,
textScaleFactor: AppStyle.getScaleFactor(context),
),
),
ASmallButton(
text: context.translation.cancel,
onPressed: () {
Navigator.of(context).pop();
},
),
],
),
SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
),
EngineersMenu(
initialValue: _group.engineer,
onSelect: (engineer) {
_group.engineer = engineer;
},
),
SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
),
// AOneImagePicker(
// image: _image,
// onPick: (image){
// _image =image;
// _group.image = base64Encode(image.readAsBytesSync());
// },
// ),
// SizedBox(height: 12 * AppStyle.getScaleFactor(context),),
// ATextFormField(
// initialValue: _group.jobSheetNumber,
// hintText: _subtitle.jobSheetNumber,
// style: Theme.of(context).textTheme.headline6,
// onSaved: (value){
// _group.jobSheetNumber = value;
// },
// ),
// SizedBox(height: 8 * AppStyle.getScaleFactor(context),),
// ATextFormField(
// initialValue: _group.workingHours,
// hintText: _subtitle.workingHours,
// style: Theme.of(context).textTheme.headline6,
// onSaved: (value){
// _group.workingHours = value;
// },
// ),
// SizedBox(height: 8 * AppStyle.getScaleFactor(context),),
// ATextFormField(
// initialValue: _group.travelingHours,
// hintText: _subtitle.travelingHours,
// style: Theme.of(context).textTheme.headline6,
// onSaved: (value){
// _group.travelingHours = value;
// },
// ),
// SizedBox(height: 8 * AppStyle.getScaleFactor(context),),
// Row(
// children: [
// Expanded(
// child: Text(
// "${_subtitle.date} :",
// style: Theme.of(context).textTheme.subtitle1,
// textScaleFactor: AppStyle.getScaleFactor(context),
// ),
// ),
// ADatePicker(
// date: _group.date ?? DateTime.now(),
// onDatePicker: (date){
// _group.date = date;
// setState(() {});
// },
// ),
// ],
// ),
// // SizedBox(height: 8 * AStyling.getScaleFactor(context),),
// Text(
// "${_subtitle.status} :",
// style: Theme.of(context).textTheme.subtitle1,
// textScaleFactor: AppStyle.getScaleFactor(context),
// ),
// SizedBox(height: 8 * AppStyle.getScaleFactor(context),),
// Center(
// child: Wrap(
// spacing: 10,
// runSpacing: 10,
// children: List.generate(
// status.length,
// (index) {
// bool isSelected = _group.status == status[index];
// return FilterItem(
// isSelected: isSelected,
// onSelected: (){
// if(isSelected)
// _group.status = null;
// else
// _group.status = status[index];
//
// setState(() {});
// },
// status: status[index],
// );
// }
//
// ),
// ),
// ),
// Text(
// "${_subtitle.taskStatus} :",
// style: Theme.of(context).textTheme.subtitle1,
// textScaleFactor: AppStyle.getScaleFactor(context),
// ),
// SizedBox(height: 8 * AppStyle.getScaleFactor(context),),
// Center(
// child: Wrap(
// spacing: 10,
// runSpacing: 10,
// children: List.generate(
// taskStatus.length,
// (index) {
// bool isSelected = _group.taskStatus == taskStatus[index];
// return FilterItem(
// isSelected: isSelected,
// onSelected: (){
// if(isSelected)
// _group.taskStatus = null;
// else
// _group.taskStatus = taskStatus[index];
//
// setState(() {});
// },
// status: taskStatus[index],
// );
// }
//
// ),
// ),
// ),
SizedBox(
height: 8 * AppStyle.getScaleFactor(context),
),
Expanded(
child: ListView.builder(
itemCount: widget.visits.length,
itemBuilder: (context, index) {
Visit visit = widget.visits[index];
return Container(
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 8),
margin: EdgeInsets.symmetric(vertical: 4),
// decoration: BoxDecoration(color: AColors.primaryColor, borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [AppStyle.boxShadow]),
child: Row(
children: [
Expanded(
child: Text(
"${context.translation.sn}: " + visit.deviceSerialNumber ?? context.translation.noSerialNumberFound,
// style: Theme.of(context).textTheme.headline6.copyWith(color: AColors.white, fontSize: 16, fontWeight: FontWeight.bold),
),
),
VisitStatusLabel(
visit: visit,
)
],
),
);
},
),
),
AButton(
text: context.translation.update,
onPressed: () {
Navigator.of(context).pop(_group);
},
),
],
),
],
),
);
}
}

@ -11,21 +11,33 @@ class ADatePicker extends StatelessWidget {
final DateTime to; final DateTime to;
final String label; final String label;
final Function(DateTime) onDatePicker; final Function(DateTime) onDatePicker;
final bool enable; final bool enable, withBorder;
final Color backgroundColor;
const ADatePicker({Key key, @required this.label, this.date, this.onDatePicker, this.from, this.to, this.enable = true}) : super(key: key); const ADatePicker({
Key key,
@required this.label,
this.withBorder = true,
this.backgroundColor,
this.date,
this.onDatePicker,
this.from,
this.to,
this.enable = true,
}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Container( return Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: context.isDark && (enable == false) color: backgroundColor ??
? AppColor.neutral50 (context.isDark && (enable == false)
: (enable == false) ? AppColor.neutral50
? AppColor.neutral40 : (enable == false)
: AppColor.background(context), ? AppColor.neutral40
: AppColor.background(context)),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
border: Border.all(width: 1, color: Theme.of(context).scaffoldBackgroundColor), border: withBorder ? Border.all(width: 1, color: Theme.of(context).scaffoldBackgroundColor) : const Border(),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
), ),
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight), padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight),
@ -37,7 +49,7 @@ class ADatePicker extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
label.tinyFont(context), label.tinyFont(context),
((date?.toIso8601String()?.split("T")?.first) ?? context.translation.pickADate).bodyText(context).custom(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50), ((date?.toIso8601String()?.split("T")?.first) ?? context.translation.pickADate).bodyText(context).custom(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
], ],
).expanded ).expanded
: label.bodyText(context).paddingOnly(top: 8, bottom: 8), : label.bodyText(context).paddingOnly(top: 8, bottom: 8),

@ -16,8 +16,9 @@ class MultiFilesPicker extends StatefulWidget {
final bool error; final bool error;
final List<File> files; final List<File> files;
final bool enabled, onlyImages; final bool enabled, onlyImages;
final Function(List<File>) onChange;
const MultiFilesPicker({Key key, this.files, this.label, this.error = false, this.enabled = true, this.onlyImages = false}) : super(key: key); const MultiFilesPicker({Key key, this.files, this.label, this.error = false, this.enabled = true, this.onlyImages = false, this.onChange}) : super(key: key);
@override @override
State<MultiFilesPicker> createState() => _MultiFilesPickerState(); State<MultiFilesPicker> createState() => _MultiFilesPickerState();
@ -46,6 +47,9 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
return; return;
} }
widget.files.remove(image); widget.files.remove(image);
if (widget.onChange != null) {
widget.onChange(widget.files);
}
setState(() {}); setState(() {});
}, },
); );
@ -109,6 +113,9 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
File fileImage = File(pickedFile.path); File fileImage = File(pickedFile.path);
if (fileImage != null) { if (fileImage != null) {
widget.files.add(fileImage); widget.files.add(fileImage);
if (widget.onChange != null) {
widget.onChange(widget.files);
}
setState(() {}); setState(() {});
} }
} }

@ -5,18 +5,21 @@ import 'package:test_sa/controllers/providers/api/parts_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/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/views/app_style/sizing.dart'; import 'package:test_sa/views/app_style/sizing.dart';
import '../../../extensions/text_extensions.dart'; import '../../../extensions/text_extensions.dart';
import '../../../models/service_request/spare_parts.dart'; import '../../../models/service_request/spare_parts.dart';
import '../../../new_views/app_style/app_text_style.dart';
class AutoCompletePartsField extends StatefulWidget { class AutoCompletePartsField extends StatefulWidget {
final String initialValue; final String initialValue;
final num assetId; final num assetId;
final bool clearAfterPick; final bool clearAfterPick, byName;
final Function(SparePartsWorkOrders) onPick; final Function(SparePartsWorkOrders) onPick;
const AutoCompletePartsField({Key key, this.initialValue, this.assetId, this.onPick, this.clearAfterPick = true}) : super(key: key); const AutoCompletePartsField({Key key, this.byName, this.initialValue, this.assetId, this.onPick, this.clearAfterPick = true}) : super(key: key);
@override @override
_AutoCompletePartsFieldState createState() => _AutoCompletePartsFieldState(); _AutoCompletePartsFieldState createState() => _AutoCompletePartsFieldState();
@ -53,30 +56,41 @@ class _AutoCompletePartsFieldState extends State<AutoCompletePartsField> {
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_partsProvider = Provider.of<PartsProvider>(context); _partsProvider = Provider.of<PartsProvider>(context);
final border = UnderlineInputBorder(borderSide: BorderSide.none, borderRadius: BorderRadius.circular(10));
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: AppColor.background(context),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
), ),
child: TypeAheadField<SparePartsWorkOrders>( child: TypeAheadField<SparePartsWorkOrders>(
minCharsForSuggestions: 1,
textFieldConfiguration: TextFieldConfiguration( textFieldConfiguration: TextFieldConfiguration(
style: AppTextStyles.bodyText, style: AppTextStyles.bodyText,
controller: _controller, controller: _controller,
textAlign: TextAlign.start, textAlign: TextAlign.start,
decoration: InputDecoration( decoration: InputDecoration(
label: context.translation.partNumberName.tinyFont(context), border: border,
border: InputBorder.none, disabledBorder: border,
disabledBorder: InputBorder.none, focusedBorder: border,
focusedBorder: InputBorder.none, enabledBorder: border,
enabledBorder: InputBorder.none, errorBorder: border,
contentPadding: EdgeInsets.symmetric(vertical: 8.toScreenHeight, horizontal: 16.toScreenWidth),
constraints: const BoxConstraints(),
suffixIconConstraints: const BoxConstraints(minWidth: 0),
filled: true,
fillColor: (context.isDark ? AppColor.neutral50 : AppColor.background(context)),
errorStyle: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.red50 : AppColor.red60),
floatingLabelStyle: AppTextStyle.body1?.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? null : AppColor.neutral20),
labelText: widget.byName ? context.translation.partName : context.translation.partNumber,
), ),
textInputAction: TextInputAction.search, textInputAction: TextInputAction.search,
), ),
suggestionsCallback: (vale) async { suggestionsCallback: (value) async {
return (await _partsProvider.getPartsList(title: vale, assetId: widget.assetId)).map((e) => SparePartsWorkOrders(sparePart: e)).toList(); return (await _partsProvider.getPartsList(partName: widget.byName ? value : null, partNo: widget.byName ? null : value, assetId: widget.assetId))
.map((e) => SparePartsWorkOrders(sparePart: e))
.toList();
}, },
itemBuilder: (context, part) { itemBuilder: (context, part) {
return ListTile( return ListTile(
@ -91,7 +105,7 @@ class _AutoCompletePartsFieldState extends State<AutoCompletePartsField> {
if (widget.clearAfterPick) { if (widget.clearAfterPick) {
_controller.clear(); _controller.clear();
} else { } else {
_controller.text = part?.sparePart?.partNo; _controller.text = widget.byName ? (part?.sparePart?.partName ?? "") : (part?.sparePart?.partNo ?? "");
} }
widget.onPick(part); widget.onPick(part);
}, },

@ -5,12 +5,16 @@ import 'package:test_sa/controllers/providers/api/devices_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/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import '../../../../extensions/text_extensions.dart';
import '../../../../models/device/asset.dart'; import '../../../../models/device/asset.dart';
import '../../../../models/device/asset_search.dart';
import '../../../../new_views/app_style/app_color.dart';
import '../../../../new_views/app_style/app_text_style.dart';
import '../../../app_style/sizing.dart';
class AutoCompleteDeviceNumberField extends StatefulWidget { class AutoCompleteDeviceNumberField extends StatefulWidget {
final Lookup initialValue; final Lookup initialValue;
@ -54,30 +58,44 @@ class _AutoCompleteDeviceNumberFieldState extends State<AutoCompleteDeviceNumber
_settingProvider = Provider.of<SettingProvider>(context); _settingProvider = Provider.of<SettingProvider>(context);
_userProvider = Provider.of<UserProvider>(context); _userProvider = Provider.of<UserProvider>(context);
_devicesProvider = Provider.of<AssetProvider>(context); _devicesProvider = Provider.of<AssetProvider>(context);
final border = UnderlineInputBorder(borderSide: BorderSide.none, borderRadius: BorderRadius.circular(10));
return Container( return Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.white, color: AppColor.background(context),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)), borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
), ),
child: TypeAheadField<Asset>( child: TypeAheadField<Asset>(
minCharsForSuggestions: 1,
textFieldConfiguration: TextFieldConfiguration( textFieldConfiguration: TextFieldConfiguration(
style: AppTextStyles.bodyText, style: AppTextStyles.bodyText,
controller: _controller, controller: _controller,
textAlign: TextAlign.start, textAlign: TextAlign.start,
textInputAction: TextInputAction.search,
decoration: InputDecoration( decoration: InputDecoration(
label: context.translation.assetNumber.tinyFont(context), border: border,
border: InputBorder.none, disabledBorder: border,
disabledBorder: InputBorder.none, focusedBorder: border,
focusedBorder: InputBorder.none, enabledBorder: border,
enabledBorder: InputBorder.none, errorBorder: border,
contentPadding: EdgeInsets.symmetric(vertical: 8.toScreenHeight, horizontal: 16.toScreenWidth),
constraints: const BoxConstraints(),
suffixIconConstraints: const BoxConstraints(minWidth: 0),
filled: true,
fillColor: (context.isDark ? AppColor.neutral50 : AppColor.background(context)),
errorStyle: AppTextStyle.tiny.copyWith(color: context.isDark ? AppColor.red50 : AppColor.red60),
floatingLabelStyle: AppTextStyle.body1?.copyWith(fontWeight: FontWeight.w500, color: context.isDark ? null : AppColor.neutral20),
labelText: context.translation.assetNumber,
), ),
textInputAction: TextInputAction.search,
), ),
suggestionsCallback: (vale) async { suggestionsCallback: (value) async {
return await _devicesProvider.getDevicesList(host: _settingProvider.host, user: _userProvider.user, hospitalId: widget.hospitalId, /* number: vale,*/ addPagination: false); return await _devicesProvider.getDevicesList(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: widget.hospitalId,
addPagination: false,
search: AssetSearch(assetNo: value),
);
}, },
itemBuilder: (context, device) { itemBuilder: (context, device) {
return device.assetNumber.bodyText(context).paddingOnly(bottom: 16, start: 16); return device.assetNumber.bodyText(context).paddingOnly(bottom: 16, start: 16);

@ -1,22 +1,23 @@
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/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/pantry/calibration_tools.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/ppm/ppm_calibration_tools.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart'; import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/pentry/auto_complete_fields/auto_complete_devices_field.dart';
import '../../../new_views/app_style/app_color.dart'; import '../../../new_views/app_style/app_color.dart';
import '../date_and_time/date_picker.dart';
import 'auto_complete_fields/auto_complete_devices_field.dart';
class PentryCalibrationToolForm extends StatefulWidget { class PentryCalibrationToolForm extends StatefulWidget {
final List<CalibrationTool> models; final List<PpmCalibrationTools> models;
final bool enableValidate;
const PentryCalibrationToolForm({Key key, this.models, this.enableValidate}) : super(key: key); const PentryCalibrationToolForm({Key key, this.models}) : super(key: key);
@override @override
State<PentryCalibrationToolForm> createState() => _PentryCalibrationToolFormState(); State<PentryCalibrationToolForm> createState() => _PentryCalibrationToolFormState();
@ -36,8 +37,18 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
maxWidth: true, maxWidth: true,
textColor: Colors.white, textColor: Colors.white,
buttonColor: context.isDark ? AppColor.neutral60 : AppColor.neutral50, buttonColor: context.isDark ? AppColor.neutral60 : AppColor.neutral50,
onPressed: () { onPressed: () async {
widget.models.add(CalibrationTool()); if (widget.models?.isNotEmpty ?? false) {
if (widget.models.last.assetId == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.assetNumber}");
return;
}
if (widget.models.last.calibrationDateOfTesters == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.date}");
return;
}
}
widget.models.add(PpmCalibrationTools(id: 0));
setState(() {}); setState(() {});
}, },
); );
@ -47,7 +58,7 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
margin: EdgeInsets.only(bottom: 16.toScreenHeight), margin: EdgeInsets.only(bottom: 16.toScreenHeight),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).cardColor, color: AppColor.background(context),
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)], boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)],
), ),
@ -66,18 +77,22 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
), ),
16.height, 16.height,
AutoCompleteDeviceNumberField( AutoCompleteDeviceNumberField(
initialValue: model.assetsNumber, initialValue: model.assetId == null ? null : Lookup(id: model.assetId, name: model.assetNumber ?? ""),
hospitalId: userProvider.user.clientId, hospitalId: userProvider.user.clientId,
onPick: (number) { onPick: (number) {
model.assetsNumber = number; model.assetNumber = number.name;
model.assetId = number.id;
setState(() {});
}, },
), ),
8.height, 8.height,
ADatePicker( ADatePicker(
label: context.translation.calibrationDate, label: context.translation.calibrationDate,
date: model.dataOfTesting, date: DateTime.tryParse(model.calibrationDateOfTesters ?? ""),
backgroundColor: context.isDark ? AppColor.neutral50 : AppColor.background(context),
withBorder: false,
onDatePicker: (date) { onDatePicker: (date) {
model.dataOfTesting = date; model.calibrationDateOfTesters = date?.toIso8601String();
setState(() {}); setState(() {});
}, },
), ),

@ -1,27 +1,20 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/ppm/ppm_kit.dart';
import 'package:test_sa/models/pantry/pm_kit.dart';
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
import 'package:test_sa/views/widgets/parts/auto_complete_parts_field.dart';
import '../../../new_views/app_style/app_color.dart'; import '../../../new_views/app_style/app_color.dart';
import '../../../new_views/common_widgets/app_filled_button.dart'; import '../../../new_views/common_widgets/app_filled_button.dart';
import '../parts/auto_complete_parts_field.dart';
class PentryPMKitForm extends StatefulWidget { class PentryPMKitForm extends StatefulWidget {
final List<PMKit> models; final List<PpmKits> models;
final bool enableValidate;
final num assetId; final num assetId;
const PentryPMKitForm({ const PentryPMKitForm({Key key, this.models, this.assetId}) : super(key: key);
Key key,
this.models,
this.assetId,
this.enableValidate,
}) : super(key: key);
@override @override
State<PentryPMKitForm> createState() => _PentryPMKitFormState(); State<PentryPMKitForm> createState() => _PentryPMKitFormState();
@ -41,19 +34,28 @@ class _PentryPMKitFormState extends State<PentryPMKitForm> {
maxWidth: true, maxWidth: true,
textColor: Colors.white, textColor: Colors.white,
buttonColor: context.isDark ? AppColor.neutral60 : AppColor.neutral50, buttonColor: context.isDark ? AppColor.neutral60 : AppColor.neutral50,
onPressed: () { onPressed: () async {
widget.models.add(PMKit()); if (widget.models?.isNotEmpty ?? false) {
if (widget.models.last.partNumber == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.partNumber}");
return;
}
if (widget.models.last.partName == null) {
await Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.partName}");
return;
}
}
widget.models.add(PpmKits(id: 0));
setState(() {}); setState(() {});
}, },
); );
} }
final model = widget.models[index]; final model = widget.models[index];
final TextEditingController controller = TextEditingController(text: model.quantityNeeded);
return Container( return Container(
padding: const EdgeInsets.all(16), padding: const EdgeInsets.all(16),
margin: EdgeInsets.only(bottom: 16.toScreenHeight), margin: EdgeInsets.only(bottom: 16.toScreenHeight),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Theme.of(context).cardColor, color: AppColor.background(context),
borderRadius: BorderRadius.circular(20), borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)], boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)],
), ),
@ -74,19 +76,26 @@ class _PentryPMKitFormState extends State<PentryPMKitForm> {
AutoCompletePartsField( AutoCompletePartsField(
assetId: widget.assetId, assetId: widget.assetId,
clearAfterPick: false, clearAfterPick: false,
initialValue: (model.itemCode?.name ?? "").toString(), byName: true,
initialValue: model.partName ?? "",
onPick: (part) { onPick: (part) {
model.itemCode = Lookup(id: part.id, name: part?.sparePart?.partNo); model.partCatalogItemId = part?.sparePart?.id;
model.itemName = part?.sparePart?.partName; model.partNumber = part?.sparePart?.partNo;
model.partName = part?.sparePart?.partName;
setState(() {});
}, },
), ),
8.height, 8.height,
AppTextFormField( AutoCompletePartsField(
controller: controller, assetId: widget.assetId,
labelText: context.translation.quantity, clearAfterPick: false,
textInputType: TextInputType.number, byName: false,
onChange: (text) { initialValue: model.partNumber ?? "",
model.quantityNeeded = num.tryParse(text ?? "")?.toString(); onPick: (part) {
model.partCatalogItemId = part?.sparePart?.id;
model.partNumber = part?.sparePart?.partNo;
model.partName = part?.sparePart?.partName;
setState(() {});
}, },
), ),
], ],

@ -3,26 +3,29 @@ import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/pantry/ppm_check_list.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/ppm/ppm_check_list.dart';
import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart';
import 'package:test_sa/providers/ppm_checklist_status_provider.dart';
class PentryPMChecklistForm extends StatefulWidget { class PentryPMChecklistForm extends StatefulWidget {
final List<PPMCheckList> models; final List<PpmChecklists> models;
final bool enableValidate;
const PentryPMChecklistForm({Key key, this.models, this.enableValidate}) : super(key: key); const PentryPMChecklistForm({Key key, this.models}) : super(key: key);
@override @override
State<PentryPMChecklistForm> createState() => _PentryPMChecklistFormState(); State<PentryPMChecklistForm> createState() => _PentryPMChecklistFormState();
} }
class _PentryPMChecklistFormState extends State<PentryPMChecklistForm> { class _PentryPMChecklistFormState extends State<PentryPMChecklistForm> {
PPMCheckList item = PPMCheckList(); PpmChecklists item = PpmChecklists();
List<int> showLabel = [];
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final list = widget.models?.where((element) => element.title != null)?.toList(); final list = widget.models?.where((element) => element.task != null)?.toList();
return (list?.isEmpty ?? true) return (list?.isEmpty ?? true)
? context.translation.noDataFound.heading5(context).center ? context.translation.noDataFound.heading5(context).center
: ListView.builder( : ListView.builder(
@ -33,16 +36,53 @@ class _PentryPMChecklistFormState extends State<PentryPMChecklistForm> {
return Card( return Card(
child: ExpansionTile( child: ExpansionTile(
shape: const Border(), shape: const Border(),
title: (list[index].title ?? "").heading5(context), title: (list[index].task ?? "").heading5(context),
subtitle: "${context.translation.status} ${list[index].status?.name}".bodyText(context), onExpansionChanged: (value) {
initiallyExpanded: index == 0, if (!value) {
iconColor: AppColor.neutral50, showLabel.remove(index);
collapsedIconColor: AppColor.neutral50, } else {
showLabel.add(index);
}
setState(() {});
},
subtitle: showLabel.isNotEmpty && showLabel.contains(index) ? null : "${context.translation.status} ${list[index].taskStatusName}".bodyText(context),
iconColor: context.isDark ? AppColor.neutral30 : AppColor.neutral50,
collapsedIconColor: context.isDark ? AppColor.neutral30 : AppColor.neutral50,
childrenPadding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight), childrenPadding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight),
children: [ children: [
AppTextFormField(labelText: context.translation.measuredValue, initialValue: list[index].measuredValue, enable: false), if (showLabel.isNotEmpty && showLabel.contains(index))
SingleItemDropDownMenu<Lookup, PpmChecklistStatusProvider>(
context: context,
backgroundColor: context.isDark ? AppColor.neutral50 : null,
initialValue: list[index].taskStatusId == null ? null : Lookup(id: list[index].taskStatusId, name: list[index].taskStatusName),
title: context.translation.status,
onSelect: (value) {
list[index].taskStatusId = value.id;
list[index].taskStatusName = value.name;
},
),
if (showLabel.isNotEmpty && showLabel.contains(index)) 8.height,
AppTextFormField(
labelText: context.translation.measuredValue,
initialValue: list[index].measuredValue,
enable: false,
backgroundColor: context.isDark ? AppColor.neutral20 : null,
// backgroundColor: context.isDark ? AppColor.neutral50 : null,
// onChange: (text) {
// list[index].measuredValue = text;
// },
),
8.height, 8.height,
AppTextFormField(labelText: context.translation.comment, initialValue: list[index].comment, enable: false), AppTextFormField(
labelText: context.translation.comment,
initialValue: list[index].taskComment,
enable: false,
backgroundColor: context.isDark ? AppColor.neutral20 : null,
// backgroundColor: context.isDark ? AppColor.neutral50 : null,
// onChange: (text) {
// list[index].taskComment = text;
// },
),
8.height, 8.height,
], ],
), ),

@ -1,28 +1,26 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/ppm/ppm.dart';
import 'package:test_sa/models/pantry/pentry.dart'; import 'package:test_sa/models/ppm/ppm_attachment.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart';
import 'package:test_sa/providers/ppm_device_status_provider.dart';
import 'package:test_sa/providers/ppm_visit_status_provider.dart';
import 'package:test_sa/views/widgets/e_signature/e_signature.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart';
import '../../../models/lookup.dart';
import '../../../new_views/common_widgets/app_text_form_field.dart';
import '../../../new_views/common_widgets/single_item_drop_down_menu.dart';
import '../../../providers/ppm_device_status_provider.dart';
import '../../../providers/ppm_visit_status_provider.dart';
import '../date_and_time/date_picker.dart'; import '../date_and_time/date_picker.dart';
import '../e_signature/e_signature.dart';
import '../images/multi_image_picker.dart'; import '../images/multi_image_picker.dart';
import '../timer/app_timer.dart';
class PentryTBSForm extends StatefulWidget { class PentryTBSForm extends StatefulWidget {
final Pentry model; final Ppm model;
final bool enableValidate;
const PentryTBSForm({ const PentryTBSForm({Key key, this.model}) : super(key: key);
Key key,
this.model,
this.enableValidate,
}) : super(key: key);
@override @override
State<PentryTBSForm> createState() => _PentryTBSFormState(); State<PentryTBSForm> createState() => _PentryTBSFormState();
@ -32,6 +30,7 @@ class _PentryTBSFormState extends State<PentryTBSForm> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
widget.model?.files ??= []; widget.model?.files ??= [];
widget.model?.files = (widget.model.files ?? []).where((element) => element.attachmentName != null && element.attachmentName.isNotEmpty).toList();
return SingleChildScrollView( return SingleChildScrollView(
child: Column( child: Column(
@ -40,104 +39,96 @@ class _PentryTBSFormState extends State<PentryTBSForm> {
8.height, 8.height,
SingleItemDropDownMenu<Lookup, PPMVisitStatusProvider>( SingleItemDropDownMenu<Lookup, PPMVisitStatusProvider>(
context: context, context: context,
initialValue: widget.model.ppmVisitStatus, initialValue: widget.model.visitStatusId == null ? null : Lookup(name: widget.model.visitStatusName ?? "", id: widget.model.visitStatusId),
title: context.translation.ppmVisit, title: context.translation.ppmVisit,
onSelect: (value) { onSelect: (value) {
if (value != null) { if (value != null) {
widget.model.ppmVisitStatus = value; widget.model.visitStatusName = value.name;
widget.model.visitStatusId = value.id;
} }
}, },
), ),
8.height, 8.height,
AppTimer( AppTimer(
label: context.translation.timer, label: context.translation.timer,
timer: widget.model.timer, timer: widget.model.tbsTimer,
enabled: widget.model.timer.endAt == null, enabled: widget.model.tbsTimer.endAt == null,
onChange: (timer) async { onChange: (timer) async {
widget.model.timer = timer; widget.model.tbsTimer = timer;
return true; return true;
}, },
), ),
8.height, 8.height,
SingleItemDropDownMenu<Lookup, PPMDeviceStatusProvider>( SingleItemDropDownMenu<Lookup, PPMDeviceStatusProvider>(
context: context, context: context,
initialValue: widget.model.status, initialValue: widget.model.deviceStatusId == null ? null : Lookup(name: widget.model.deviceStatusName ?? "", id: widget.model.deviceStatusId),
title: context.translation.deviceStatus, title: context.translation.deviceStatus,
onSelect: (value) { onSelect: (value) {
if (value != null) { if (value != null) {
widget.model.status = value; widget.model.deviceStatusId = value.id;
widget.model.deviceStatusName = value.name;
} }
}, },
), ),
8.height, 8.height,
ADatePicker( ADatePicker(
label: context.translation.actualVisitDate, label: context.translation.actualVisitDate,
date: widget.model.actualVisitDate, date: DateTime.tryParse(widget.model.actualDate ?? ""),
from: DateTime.now().subtract(const Duration(days: 30)), from: DateTime.now().subtract(const Duration(days: 30)),
onDatePicker: (date) { onDatePicker: (date) {
if (date == null) return; if (date == null) return;
widget.model.actualVisitDate = date; widget.model.actualDate = date?.toIso8601String();
setState(() {}); setState(() {});
}, },
), ),
8.height, 8.height,
ADatePicker( ADatePicker(
label: context.translation.expectedVisitDate, label: context.translation.expectedVisitDate,
date: widget.model.expectedVisitDate, date: DateTime.tryParse(widget.model.expectedDate ?? ""),
from: DateTime.now().subtract(const Duration(days: 30)), from: DateTime.now().subtract(const Duration(days: 30)),
onDatePicker: (date) { onDatePicker: (date) {
if (date == null) return; if (date == null) return;
widget.model.expectedVisitDate = date; widget.model.expectedDate = date?.toIso8601String();
setState(() {}); setState(() {});
}, },
), ),
8.height, 8.height,
// const ASubTitle("Traveling Hours"), AppTextFormField(
// const SizedBox( labelText: context.translation.travelingHours,
// height: 4, initialValue: (widget.model.travelingHours ?? "").toString(),
// ), textAlign: TextAlign.center,
// ATextFormField( style: Theme.of(context).textTheme.titleMedium,
// initialValue: (widget.model.travelingHours ?? "").toString(), textInputType: TextInputType.number,
// textAlign: TextAlign.center, onChange: (value) {
// style: Theme.of(context).textTheme.titleMedium, widget.model.travelingHours = value;
// textInputType: TextInputType.number, },
// onChange: (value) { ),
// widget.model.travelingHours = value;
// },
// ),
8.height, 8.height,
MultiFilesPicker(label: context.translation.attachImage, files: widget.model.files), MultiFilesPicker(
// AMiniOneFilePicker( label: context.translation.attachImage,
// //error: _validate && _serviceReport.image == null, files: widget.model.files.map((e) => File(e.attachmentName)).toList(),
// file: widget.model.file, onChange: (files) {
// onPick: (file) { widget.model.files = files.map((e) => PpmAttachments(attachmentName: e.path)).toList();
// widget.model.file = file; },
// }, ),
// ),
8.height, 8.height,
ESignature( ESignature(
title: context.translation.nurseSignature, title: context.translation.nurseSignature,
oldSignature: widget.model.signatureNurse, oldSignature: widget.model.nurseSignature,
newSignature: widget.model.localNurseSignature, newSignature: widget.model.localNurseSignature,
onChange: (signature) { onChange: (signature) {
// if (signature == null || signature.isEmpty) {
// return;
// }
widget.model.localNurseSignature = signature; widget.model.localNurseSignature = signature;
widget.model.signatureNurse = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; widget.model.nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
}, },
), ),
8.height, 8.height,
ESignature( ESignature(
title: context.translation.engSign, title: context.translation.engSign,
oldSignature: widget.model.signatureEngineer, oldSignature: widget.model.engSignature,
newSignature: widget.model.localEngineerSignature, newSignature: widget.model.localEngineerSignature,
onChange: (signature) { onChange: (signature) {
// if (signature == null || signature.isEmpty) {
// return;
// }
widget.model.localEngineerSignature = signature; widget.model.localEngineerSignature = signature;
widget.model.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}"; widget.model.engSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
}, },
), ),
8.height, 8.height,

@ -4,22 +4,22 @@ import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/all_requests_and_count_model.dart';
import 'package:test_sa/models/enums/user_types.dart'; import 'package:test_sa/models/enums/user_types.dart';
import 'package:test_sa/models/visits/visit.dart'; import 'package:test_sa/models/ppm/ppm.dart';
import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/views/pages/user/visits/visit_details.dart'; import 'package:test_sa/views/pages/user/ppm/ppm_details_page.dart';
import 'package:test_sa/views/pages/user/ppm/update_ppm/edit_ppm.dart';
import '../../../controllers/providers/api/user_provider.dart'; import '../../../controllers/providers/api/user_provider.dart';
import '../../../extensions/text_extensions.dart'; import '../../../extensions/text_extensions.dart';
import '../../../models/lookup.dart';
import '../../pages/user/visits/pantry/edit_pentry.dart';
import '../requests/request_status.dart'; import '../requests/request_status.dart';
class VisitItem extends StatelessWidget { class PpmItem extends StatelessWidget {
final Visit visit; final Ppm ppm;
final Lookup priority; final RequestsDetails request;
const VisitItem({Key key, this.visit, this.priority}) : super(key: key); const PpmItem({Key key, this.ppm, this.request}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -32,29 +32,28 @@ class VisitItem extends StatelessWidget {
children: [ children: [
Row( Row(
children: [ children: [
if (priority != null) if (request.priority != null)
StatusLabel( StatusLabel(
label: priority.name, label: request.priority,
id: priority.id, textColor: AppColor.getRequestStatusTextColorByName(context, request.priority),
textColor: AppColor.getPriorityStatusTextColor(context, priority.id), backgroundColor: AppColor.getRequestStatusColorByName(context, request.priority),
backgroundColor: AppColor.getPriorityStatusColor(context, priority.id),
), ),
if (priority != null) 8.width, if (request.priority != null) 8.width,
StatusLabel( StatusLabel(
label: visit.status.name, label: ppm.visitStatusName,
id: visit.status.id, id: ppm.deviceStatusId,
textColor: AppColor.getRequestStatusTextColorByName(context, visit.status.name), textColor: AppColor.getRequestStatusTextColorByName(context, ppm.visitStatusName),
backgroundColor: AppColor.getRequestStatusColorByName(context, visit.status.name), backgroundColor: AppColor.getRequestStatusColorByName(context, ppm.visitStatusName),
), ),
1.width.expanded, 1.width.expanded,
], ],
), ),
8.height, 8.height,
visit.deviceEnglishName.heading5(context), ppm.assetName.heading5(context),
8.height, 8.height,
'${context.translation.assetNumber}: ${visit.deviceNumber}'.bodyText(context), '${context.translation.assetNumber}: ${ppm.assetNumber}'.bodyText(context),
'${context.translation.assetSN}: ${visit.deviceSerialNumber}'.bodyText(context), '${context.translation.assetSN}: ${ppm.assetSerialNo}'.bodyText(context),
'${context.translation.code}: ${visit.serialNumber}'.bodyText(context), '${context.translation.code}: ${ppm.visitCode}'.bodyText(context),
16.height, 16.height,
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
@ -67,7 +66,7 @@ class VisitItem extends StatelessWidget {
Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14) Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14)
], ],
).onPress(() { ).onPress(() {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => VisitDetailsPage(visit: visit))); Navigator.of(context).push(MaterialPageRoute(builder: (_) => PpmDetailsPage(request: RequestsDetails(id: ppm.id))));
}), }),
], ],
).expanded, ).expanded,
@ -75,13 +74,13 @@ class VisitItem extends StatelessWidget {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
if (userProvider.user.type == UsersTypes.engineer && (visit.status.id != 270 || visit.status.id != 269)) if (userProvider.user.type == UsersTypes.engineer && (ppm.deviceStatusId != 270 || ppm.deviceStatusId != 269))
"edit".toSvgAsset(height: 48, width: 48).onPress(() { "edit".toSvgAsset(height: 48, width: 48).onPress(() {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => EditPentry(visit: visit, pentry: visit.pentry))); Navigator.of(context).push(MaterialPageRoute(builder: (_) => EditPpm(ppm: ppm, details: request)));
}), }),
if (userProvider.user.type == UsersTypes.engineer && (visit.status.id != 270 || visit.status.id != 269)) 8.height, if (userProvider.user.type == UsersTypes.engineer && (ppm.deviceStatusId != 270 || ppm.deviceStatusId != 269)) 8.height,
Text( Text(
visit.createdOn != null ? visit.createdOn.toServiceRequestCardFormat : "", ppm.createdOn != null ? ppm.createdOn.toServiceRequestCardFormat : "",
textAlign: TextAlign.end, textAlign: TextAlign.end,
style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50), style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
), ),

@ -33,76 +33,76 @@ class StatusLabel extends StatelessWidget {
); );
} }
// Color getRequestStatusColor1(String status) { // Color getRequestStatusColor1(String status) {
// switch (status) { // switch (status) {
// case "in progress": // case "in progress":
// return AColors.statusYellowLight; // return AColors.statusYellowLight;
// case "completed": // case "completed":
// return AColors.statusGreenLight; // return AColors.statusGreenLight;
// case "high priority": // case "high priority":
// return AColors.statusRedLight; // return AColors.statusRedLight;
// case "low priority": // case "low priority":
// return AColors.statusGreenLight; // return AColors.statusGreenLight;
// case "open": // case "open":
// return AColors.statusBlue; // return AColors.statusBlue;
// default: // default:
// return AColors.statusDefault; // return AColors.statusDefault;
// } // }
// } // }
// //
// Color getRequestStatusTextColor(String status) { // Color getRequestStatusTextColor(String status) {
// switch (status) { // switch (status) {
// case "in progress": // case "in progress":
// return AColors.statusYellow; // return AColors.statusYellow;
// case "completed": // case "completed":
// return AColors.statusGreen; // return AColors.statusGreen;
// case "high priority": // case "high priority":
// return AColors.statusRed; // return AColors.statusRed;
// case "low priority": // case "low priority":
// return AColors.statusGreen; // return AColors.statusGreen;
// case "open": // case "open":
// return AColors.statusBlue; // return AColors.statusBlue;
// default: // default:
// return Colors.white; // return Colors.white;
// } // }
// } // }
// //
// static Color getRequestStatusColor(int id) { // static Color getRequestStatusColor(int id) {
// switch (id) { // switch (id) {
// case 4: // case 4:
// return AColors.deepRed; // return AColors.deepRed;
// case 6: // case 6:
// return AColors.green; // return AColors.green;
// case 5: // case 5:
// return AColors.orange; // return AColors.orange;
// case 8: // case 8:
// return AColors.green; // return AColors.green;
// case 9: // case 9:
// return AColors.orange; // return AColors.orange;
// default: // default:
// return AColors.grey; // return AColors.grey;
// } // }
// } // }
// //
// static Color getGasStatusColor(int id) { // static Color getGasStatusColor(int id) {
// switch (id) { // switch (id) {
// case 0: // case 0:
// return AColors.orange; // return AColors.orange;
// case 1: // case 1:
// return AColors.green; // return AColors.green;
// default: // default:
// return AColors.grey; // return AColors.grey;
// } // }
// } // }
// //
// static Color getPriorityStatusColor(int id) { // static Color getPriorityStatusColor(int id) {
// switch (id) { // switch (id) {
// case 0: // case 0:
// return AColors.orange; // return AColors.orange;
// case 1: // case 1:
// return AColors.green; // return AColors.green;
// default: // default:
// return AColors.grey; // return AColors.grey;
// } // }
// } // }
} }

@ -8,6 +8,7 @@ class FilterItem extends StatelessWidget {
final VoidCallback onSelected; final VoidCallback onSelected;
const FilterItem({Key key, this.status, this.isSelected, this.onSelected}) : super(key: key); const FilterItem({Key key, this.status, this.isSelected, this.onSelected}) : super(key: key);
// //
// Color getStatusColor() { // Color getStatusColor() {
// switch (status.id) { // switch (status.id) {

@ -0,0 +1,334 @@
import 'package:flutter/material.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/ppm/ppm_search.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../switch_button.dart';
class PpmSearchDialog extends StatefulWidget {
final PpmSearch initialSearchValue;
final bool expandedSearch;
final Function(PpmSearch) onSearch;
const PpmSearchDialog({Key key, this.initialSearchValue, this.expandedSearch, this.onSearch}) : super(key: key);
@override
_PpmSearchDialogState createState() => _PpmSearchDialogState();
}
class _PpmSearchDialogState extends State<PpmSearchDialog> with TickerProviderStateMixin {
PpmSearch _search;
List<Lookup> status = [
Lookup(
name: "Done",
id: 0,
),
Lookup(name: "Not Yet", id: 1),
Lookup(
name: "On Hold",
id: 2,
),
];
List<Lookup> contactStatus = [
// Lookup(name: "Hospital Employee", value: "H",),
// Lookup(name: "Under Warranty", value: "CW"),
// Lookup(name: "Under Maintenance Contract", value: "CC",),
];
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
void initState() {
super.initState();
_search = PpmSearch();
/// todo : working
// _search.fromSearch(widget.initialSearchValue);
}
@override
Widget build(BuildContext context) {
DateTime today = DateTime.now();
return SizedBox(
height: MediaQuery.of(context).size.height / 1.3,
child: Form(
key: _formKey,
child: ListView(
// shrinkWrap: true,
// physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ASmallButton(
text: context.translation.cancel,
onPressed: () {
Navigator.of(context).pop();
},
),
ASmallButton(
text: context.translation.search,
onPressed: () {
if (!_formKey.currentState.validate()) {
return;
}
_formKey.currentState.save();
Navigator.of(context).pop(_search);
},
)
],
),
ASwitchButton(
title: "Most Recent",
value: _search.mostRecent ?? false,
onChange: (value) {
_search.mostRecent = value;
setState(() {});
},
),
SizedBox(
height: 8.0 * AppStyle.getScaleFactor(context),
),
// ATextFormField(
// initialValue: _search.deviceNumber,
// hintText: context.translation.assetNumber,
// style: Theme.of(context).textTheme.headline6,
// textInputAction: TextInputAction.search,
// onAction: () {
// if (!_formKey.currentState.validate()) {
// return;
// }
// _formKey.currentState.save();
// Navigator.of(context).pop(_search);
// },
// onSaved: (value) {
// _search.deviceNumber = value;
// },
// ),
// SizedBox(
// height: 8.0 * AppStyle.getScaleFactor(context),
// ),
// ATextFormField(
// initialValue: _search.deviceName,
// hintText: context.translation.assetName,
// style: Theme.of(context).textTheme.headline6,
// textInputAction: TextInputAction.search,
// onAction: () {
// if (!_formKey.currentState.validate()) {
// return;
// }
// _formKey.currentState.save();
// Navigator.of(context).pop(_search);
// },
// onSaved: (value) {
// _search.deviceName = value;
// },
// ),
// SizedBox(
// height: 8.0 * AppStyle.getScaleFactor(context),
// ),
// ATextFormField(
// initialValue: _search.deviceSerialNumber,
// hintText: context.translation.serialNumber,
// style: Theme.of(context).textTheme.headline6,
// textInputAction: TextInputAction.search,
// onAction: () {
// if (!_formKey.currentState.validate()) {
// return;
// }
// _formKey.currentState.save();
// Navigator.of(context).pop(_search);
// },
// onSaved: (value) {
// _search.deviceSerialNumber = value;
// },
// ),
// SizedBox(
// height: 8.0 * AppStyle.getScaleFactor(context),
// ),
// HospitalAutoCompleteField(
// initialValue: _search.hospital?.name,
// // onSave: (value){
// // _search.hospital = value;
// // },
// onSearch: (value) {
// _search.hospital = value;
// Navigator.of(context).pop(_search);
// },
// ),
// // SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
// // ATextFormField(
// // initialValue: _search.brand,
// // hintText: _subtitle.brand,
// // style: Theme.of(context).textTheme.headline6,
// // textInputAction: TextInputAction.search,
// // onAction: (){
// // if(!_formKey.currentState.validate()) {
// // return;
// // }
// // _formKey.currentState.save();
// // Navigator.of(context).pop(_search);
// // },
// // onSaved: (value){
// // _search.brand = value;
// // },
// // ),
// SizedBox(
// height: 8.0 * AppStyle.getScaleFactor(context),
// ),
// AutoCompleteModelField(
// initialValue: _search.model,
// onPick: (lookup) {
// _search.model = lookup;
// Navigator.of(context).pop(_search);
// },
// ),
// // ATextFormField(
// // initialValue: _search.model,
// // hintText: _subtitle.model,
// // style: Theme.of(context).textTheme.headline6,
// // textInputAction: TextInputAction.search,
// // onAction: (){
// // if(!_formKey.currentState.validate()) {
// // return;
// // }
// // _formKey.currentState.save();
// // Navigator.of(context).pop(_search);
// // },
// // onSaved: (value){
// // _search.model = value;
// // },
// // ),
// SizedBox(
// height: 8.0 * AppStyle.getScaleFactor(context),
// ),
// ASubTitle(context.translation.status),
// SizedBox(
// height: 4.0 * AppStyle.getScaleFactor(context),
// ),
// PentryVisitsStatusMenu(
// initialValue: _search.statusValue,
// onSelect: (status) {
// _search.statusValue = status;
// },
// ),
// Wrap(
// spacing: 10,
// runSpacing: 10,
// children: List.generate(
// status.length,
// (index) {
// bool isSelected = _search.statusValue == status[index].id;
// return FilterItem(
// isSelected: isSelected,
// onSelected: (){
// if(isSelected) {
// _search.statusValue = null;
// } else {
// _search.statusValue = status[index].id;
// }
//
// setState(() {});
// },
// status: status[index],
// );
// }
//
// ),
// ),
SizedBox(
height: 8.0 * AppStyle.getScaleFactor(context),
),
ASubTitle(context.translation.contactStatus),
SizedBox(
height: 4.0 * AppStyle.getScaleFactor(context),
),
// AssignedToMenu(
// initialValue: _search.contactStatus,
// onSelect: (status) {
// _search.contactStatus = status;
// },
// ),
// Wrap(
// spacing: 10,
// runSpacing: 10,
// children: List.generate(
// contactStatus.length,
// (index) {
// bool isSelected = _search.contactStatus == contactStatus[index];
// return FilterItem(
// isSelected: isSelected,
// onSelected: (){
// if(isSelected) {
// _search.contactStatus = null;
// } else {
// _search.contactStatus = contactStatus[index];
// }
//
// setState(() {});
// },
// status: contactStatus[index],
// );
// }
//
// ),
// ),
SizedBox(
height: 8.0 * AppStyle.getScaleFactor(context),
),
ASubTitle(context.translation.actualDate),
SizedBox(
height: 4.0 * AppStyle.getScaleFactor(context),
),
// FromToDateBar(
// from: _search.actualDateFrom,
// to: _search.actualDateTo,
// onPickFrom: (date) {
// _search.actualDateFrom = date;
// },
// onPickTo: (date) {
// _search.actualDateTo = date;
// },
// ),
// SizedBox(
// height: 8.0 * AppStyle.getScaleFactor(context),
// ),
// ASubTitle(context.translation.expectDate),
// SizedBox(
// height: 4.0 * AppStyle.getScaleFactor(context),
// ),
// FromToDateBar(
// from: _search.expectedDateFrom ?? DateTime(today.year, today.month, 1),
// to: _search.expectedDateTo ?? DateTime(today.year, (today.month + 1).clamp(1, 12), today.month == 12 ? 31 : 0),
// onPickFrom: (date) {
// _search.expectedDateFrom = date;
// },
// onPickTo: (date) {
// _search.expectedDateTo = date;
// },
// ),
// Visibility(
// visible: _search.toMap().isNotEmpty,
// child: Padding(
// padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
// child: AButton(
// padding: EdgeInsets.zero,
// text: context.translation.clearSearch,
// onPressed: () {
// _search = VisitsSearch();
// Navigator.of(context).pop(_search);
// },
// ),
// ),
// ),
],
),
),
);
}
}

@ -1,339 +0,0 @@
import 'package:flutter/material.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/visits/visits_search.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/buttons/app_button.dart';
import 'package:test_sa/views/widgets/buttons/app_small_button.dart';
import 'package:test_sa/views/widgets/date_and_time/from_to_date_bar.dart';
import 'package:test_sa/views/widgets/equipment/auto_complete_models_field.dart';
import 'package:test_sa/views/widgets/hospitals/hospital_auto_complete_field.dart';
import 'package:test_sa/views/widgets/status/employee/assigned_to_mune.dart';
import 'package:test_sa/views/widgets/status/pentry/pentry_visit_status_mune.dart';
import 'package:test_sa/views/widgets/titles/app_sub_title.dart';
import '../app_text_form_field.dart';
import '../switch_button.dart';
class VisitsSearchDialog extends StatefulWidget {
final VisitsSearch initialSearchValue;
final bool expandedSearch;
final Function(VisitsSearch) onSearch;
const VisitsSearchDialog({Key key, this.initialSearchValue, this.expandedSearch, this.onSearch}) : super(key: key);
@override
_VisitsSearchDialogState createState() => _VisitsSearchDialogState();
}
class _VisitsSearchDialogState extends State<VisitsSearchDialog> with TickerProviderStateMixin {
VisitsSearch _search;
List<Lookup> status = [
Lookup(
name: "Done",
id: 0,
),
Lookup(name: "Not Yet", id: 1),
Lookup(
name: "On Hold",
id: 2,
),
];
List<Lookup> contactStatus = [
// Lookup(name: "Hospital Employee", value: "H",),
// Lookup(name: "Under Warranty", value: "CW"),
// Lookup(name: "Under Maintenance Contract", value: "CC",),
];
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
@override
void initState() {
super.initState();
_search = VisitsSearch();
_search.fromSearch(widget.initialSearchValue);
}
@override
Widget build(BuildContext context) {
DateTime today = DateTime.now();
return SizedBox(
height: MediaQuery.of(context).size.height / 1.3,
child: Form(
key: _formKey,
child: ListView(
// shrinkWrap: true,
// physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
ASmallButton(
text: context.translation.cancel,
onPressed: () {
Navigator.of(context).pop();
},
),
ASmallButton(
text: context.translation.search,
onPressed: () {
if (!_formKey.currentState.validate()) {
return;
}
_formKey.currentState.save();
Navigator.of(context).pop(_search);
},
)
],
),
ASwitchButton(
title: "Most Recent",
value: _search.mostRecent ?? false,
onChange: (value) {
_search.mostRecent = value;
setState(() {});
},
),
SizedBox(
height: 8.0 * AppStyle.getScaleFactor(context),
),
ATextFormField(
initialValue: _search.deviceNumber,
hintText: context.translation.assetNumber,
style: Theme.of(context).textTheme.headline6,
textInputAction: TextInputAction.search,
onAction: () {
if (!_formKey.currentState.validate()) {
return;
}
_formKey.currentState.save();
Navigator.of(context).pop(_search);
},
onSaved: (value) {
_search.deviceNumber = value;
},
),
SizedBox(
height: 8.0 * AppStyle.getScaleFactor(context),
),
ATextFormField(
initialValue: _search.deviceName,
hintText: context.translation.assetName,
style: Theme.of(context).textTheme.headline6,
textInputAction: TextInputAction.search,
onAction: () {
if (!_formKey.currentState.validate()) {
return;
}
_formKey.currentState.save();
Navigator.of(context).pop(_search);
},
onSaved: (value) {
_search.deviceName = value;
},
),
SizedBox(
height: 8.0 * AppStyle.getScaleFactor(context),
),
ATextFormField(
initialValue: _search.deviceSerialNumber,
hintText: context.translation.serialNumber,
style: Theme.of(context).textTheme.headline6,
textInputAction: TextInputAction.search,
onAction: () {
if (!_formKey.currentState.validate()) {
return;
}
_formKey.currentState.save();
Navigator.of(context).pop(_search);
},
onSaved: (value) {
_search.deviceSerialNumber = value;
},
),
SizedBox(
height: 8.0 * AppStyle.getScaleFactor(context),
),
HospitalAutoCompleteField(
initialValue: _search.hospital?.name,
// onSave: (value){
// _search.hospital = value;
// },
onSearch: (value) {
_search.hospital = value;
Navigator.of(context).pop(_search);
},
),
// SizedBox(height: 8.0 * AppStyle.getScaleFactor(context),),
// ATextFormField(
// initialValue: _search.brand,
// hintText: _subtitle.brand,
// style: Theme.of(context).textTheme.headline6,
// textInputAction: TextInputAction.search,
// onAction: (){
// if(!_formKey.currentState.validate()) {
// return;
// }
// _formKey.currentState.save();
// Navigator.of(context).pop(_search);
// },
// onSaved: (value){
// _search.brand = value;
// },
// ),
SizedBox(
height: 8.0 * AppStyle.getScaleFactor(context),
),
AutoCompleteModelField(
initialValue: _search.model,
onPick: (lookup) {
_search.model = lookup;
Navigator.of(context).pop(_search);
},
),
// ATextFormField(
// initialValue: _search.model,
// hintText: _subtitle.model,
// style: Theme.of(context).textTheme.headline6,
// textInputAction: TextInputAction.search,
// onAction: (){
// if(!_formKey.currentState.validate()) {
// return;
// }
// _formKey.currentState.save();
// Navigator.of(context).pop(_search);
// },
// onSaved: (value){
// _search.model = value;
// },
// ),
SizedBox(
height: 8.0 * AppStyle.getScaleFactor(context),
),
ASubTitle(context.translation.status),
SizedBox(
height: 4.0 * AppStyle.getScaleFactor(context),
),
PentryVisitsStatusMenu(
initialValue: _search.statusValue,
onSelect: (status) {
_search.statusValue = status;
},
),
// Wrap(
// spacing: 10,
// runSpacing: 10,
// children: List.generate(
// status.length,
// (index) {
// bool isSelected = _search.statusValue == status[index].id;
// return FilterItem(
// isSelected: isSelected,
// onSelected: (){
// if(isSelected) {
// _search.statusValue = null;
// } else {
// _search.statusValue = status[index].id;
// }
//
// setState(() {});
// },
// status: status[index],
// );
// }
//
// ),
// ),
SizedBox(
height: 8.0 * AppStyle.getScaleFactor(context),
),
ASubTitle(context.translation.contactStatus),
SizedBox(
height: 4.0 * AppStyle.getScaleFactor(context),
),
AssignedToMenu(
initialValue: _search.contactStatus,
onSelect: (status) {
_search.contactStatus = status;
},
),
// Wrap(
// spacing: 10,
// runSpacing: 10,
// children: List.generate(
// contactStatus.length,
// (index) {
// bool isSelected = _search.contactStatus == contactStatus[index];
// return FilterItem(
// isSelected: isSelected,
// onSelected: (){
// if(isSelected) {
// _search.contactStatus = null;
// } else {
// _search.contactStatus = contactStatus[index];
// }
//
// setState(() {});
// },
// status: contactStatus[index],
// );
// }
//
// ),
// ),
SizedBox(
height: 8.0 * AppStyle.getScaleFactor(context),
),
ASubTitle(context.translation.actualDate),
SizedBox(
height: 4.0 * AppStyle.getScaleFactor(context),
),
FromToDateBar(
from: _search.actualDateFrom,
to: _search.actualDateTo,
onPickFrom: (date) {
_search.actualDateFrom = date;
},
onPickTo: (date) {
_search.actualDateTo = date;
},
),
SizedBox(
height: 8.0 * AppStyle.getScaleFactor(context),
),
ASubTitle(context.translation.expectDate),
SizedBox(
height: 4.0 * AppStyle.getScaleFactor(context),
),
FromToDateBar(
from: _search.expectedDateFrom ?? DateTime(today.year, today.month, 1),
to: _search.expectedDateTo ?? DateTime(today.year, (today.month + 1).clamp(1, 12), today.month == 12 ? 31 : 0),
onPickFrom: (date) {
_search.expectedDateFrom = date;
},
onPickTo: (date) {
_search.expectedDateTo = date;
},
),
Visibility(
visible: _search.toMap().isNotEmpty,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
child: AButton(
padding: EdgeInsets.zero,
text: context.translation.clearSearch,
onPressed: () {
_search = VisitsSearch();
Navigator.of(context).pop(_search);
},
),
),
),
],
),
),
);
}
}

@ -22,6 +22,7 @@ class ServiceReportFaultDescription extends StatefulWidget {
class _ServiceReportFaultDescriptionState extends State<ServiceReportFaultDescription> { class _ServiceReportFaultDescriptionState extends State<ServiceReportFaultDescription> {
FaultDescription initialValue; FaultDescription initialValue;
@override @override
void initState() { void initState() {
super.initState(); super.initState();

@ -89,7 +89,7 @@ class _AppTimerState extends State<AppTimer> {
_running = _startAt != null && _endAt == null; _running = _startAt != null && _endAt == null;
_delay = (widget.timer?.durationInSecond ?? 0); _delay = (widget.timer?.durationInSecond ?? 0);
final difference = _startAt == null ? 0 : (_endAt ?? DateTime.now())?.difference(_startAt)?.inSeconds ?? 0; final difference = _startAt == null ? 0 : (_endAt ?? DateTime.now())?.difference(_startAt)?.inSeconds ?? 0;
_period.value = Duration(seconds: _running ? difference : _delay + difference).toString().split(".").first; _period.value = Duration(seconds: _running ? difference : (difference != 0 ? difference : _delay)).toString().split(".").first;
super.initState(); super.initState();
if (_running) { if (_running) {
_startTimer(); _startTimer();

@ -1,36 +0,0 @@
import 'package:flutter/material.dart';
import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/views/app_style/sizing.dart';
class VisitStatusLabel extends StatelessWidget {
final Visit visit;
const VisitStatusLabel({Key key, this.visit}) : super(key: key);
// Color getStatusColor() {
// switch (visit.status.id) {
// case 0:
// return AColors.green;
// case 1:
// return AColors.grey;
// case 2:
// return AColors.grey;
// default:
// return AColors.grey;
// }
// }
@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.symmetric(vertical: 2, horizontal: 8),
alignment: Alignment.center,
decoration: BoxDecoration(/*color: getStatusColor(),*/ borderRadius: BorderRadius.circular(AppStyle.getBorderRadius(context)), boxShadow: [AppStyle.boxShadow]),
child: Text(
visit.status.name == null || visit.status.name.isEmpty ? "no status" : visit.status.name,
style: Theme.of(context).textTheme.subtitle2.copyWith(
// color: getStatusColor().computeLuminance() > 0.5 ? AColors.black : Colors.white,
),
));
}
}

@ -1,98 +0,0 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/visits/visit.dart';
import 'package:test_sa/views/widgets/loaders/lazy_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_item_found.dart';
import 'package:test_sa/views/widgets/visits/visit_item.dart';
import '../../../controllers/providers/api/user_provider.dart';
class VisitsList extends StatefulWidget {
final List<Visit> visits;
final bool nextPage;
final Future<void> Function() onLazyLoad;
final Function(List<Visit>) onEditGroup;
const VisitsList({Key key, this.visits, this.nextPage, this.onLazyLoad, this.onEditGroup}) : super(key: key);
@override
_VisitsListState createState() => _VisitsListState();
}
class _VisitsListState extends State<VisitsList> {
final List<Visit> _selectedVisits = [];
@override
void initState() {
_selectedVisits.clear();
super.initState();
}
@override
Widget build(BuildContext context) {
UserProvider userProvider = Provider.of<UserProvider>(context);
if (widget.visits.isEmpty) {
return NoItemFound(message: context.translation.noVisitsFound);
}
return Stack(
children: [
LazyLoading(
nextPage: widget.nextPage,
onLazyLoad: widget.onLazyLoad,
child: ListView.builder(
itemCount: widget.visits.length,
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
itemBuilder: (context, itemIndex) {
Visit visit = widget.visits[itemIndex];
// bool isSelected = _selectedVisits.contains(visit);
return Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: VisitItem(visit: visit),
);
},
),
),
// Align(
// alignment: Alignment.bottomLeft,
// child: Padding(
// padding: EdgeInsets.all(8.0 * AppStyle.getScaleFactor(context)),
// child: AnimatedSwitcher(
// duration: const Duration(milliseconds: 400),
// child: Visibility(
// key: ValueKey(_selectedVisits.isNotEmpty),
// visible: _selectedVisits.isNotEmpty,
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// FloatingActionButton(
// heroTag: "cancel",
// child: const Icon(Icons.cancel),
// onPressed: () {
// _selectedVisits.clear();
// setState(() {});
// },
// ),
// FloatingActionButton(
// heroTag: "edit",
// child: const Icon(Icons.edit),
// onPressed: () {
// if (!widget.visits.contains(_selectedVisits.first)) {
// _selectedVisits.clear();
// setState(() {});
// return;
// }
// widget.onEditGroup(_selectedVisits);
// //_selectedVisits.clear();
// },
// ),
// ],
// ),
// ),
// ),
// ),
// )
],
);
}
}
Loading…
Cancel
Save