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"]);
notifyListeners();
} else {
allRequestsAndCount =null;
allRequestsAndCount = null;
}
isAllLoading = false;
notifyListeners();
@ -91,7 +91,7 @@ class AllRequestsProvider extends ChangeNotifier {
try {
Map<String, dynamic> body = {
"typeTransaction": [1, 2, 3, 4],
"statusTransaction": [1, 2, 3,4],
"statusTransaction": [1, 2, 3, 4],
"priority": [0, 1],
"displayData": [],
"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) "endTime": newModel.timer.endAt.toIso8601String(),
// "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(),
"site": hospital?.toMap(),
"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
/// for more details check http state manager
/// 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;
try {
if (int.tryParse(title ?? "") != null) {
response = await ApiManager.instance.post(URLs.getPartNumber, body: {if (title != null && title.isNotEmpty) "partNo": title, "assetId": assetId});
if (partNo != null) {
response = await ApiManager.instance.post(URLs.getPartNumber, body: {"partNo": partNo, "assetId": assetId});
} 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 = [];
if (response.statusCode >= 200 && response.statusCode < 300) {

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

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

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

@ -170,7 +170,7 @@
"newServiceReport": "New Work Order",
"number": "Number",
"operatingHours": "Operating Hours",
"partNumberName": "Part Number/Name",
"partName": "Part Name",
"quantity": "Quantity",
"reasons": "Reasons",
"reason": "Reason",
@ -308,6 +308,7 @@
"assistantEmployee" : "Assistant Employee",
"assignAssistant" : "Assign Assistant",
"partNo" : "Part No.",
"partNumber" : "Part Number",
"engSign" : "Engineer Signature",
"requesterName" : "Requester Name",
"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/notifications_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/regular_visits_provider.dart';
import 'package:test_sa/controllers/providers/api/ppm_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/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/site_provider.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_visit_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/land_page.dart' as old;
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/report_issues_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/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/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/equipment/asset_detail_page.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: (_) => DepartmentsProvider()),
ChangeNotifierProvider(create: (_) => NotificationsProvider()),
ChangeNotifierProvider(create: (_) => PreventiveMaintenanceVisitsProvider()),
ChangeNotifierProvider(create: (_) => RegularVisitsProvider()),
// ChangeNotifierProvider(create: (_) => PreventiveMaintenanceVisitsProvider()),
ChangeNotifierProvider(create: (_) => PpmProvider()),
ChangeNotifierProvider(create: (_) => PartsProvider()),
ChangeNotifierProvider(create: (_) => ServiceReportReasonsProvider()),
ChangeNotifierProvider(create: (_) => ServiceReportStatusProvider()),
@ -195,6 +194,7 @@ class MyApp extends StatelessWidget {
ChangeNotifierProvider(create: (_) => CommentsProvider()),
ChangeNotifierProvider(create: (_) => RequestStatusProvider()),
ChangeNotifierProvider(create: (_) => VendorProvider()),
ChangeNotifierProvider(create: (_) => PpmChecklistStatusProvider()),
],
child: GestureDetector(
onTap: () {
@ -226,8 +226,8 @@ class MyApp extends StatelessWidget {
SingleDepartmentPicker.id: (_) => SingleDepartmentPicker(),
NotificationsPage.id: (_) => NotificationsPage(),
FutureRequestServiceDetails.id: (_) => FutureRequestServiceDetails(),
PreventiveMaintenanceVisitsPage.id: (_) => PreventiveMaintenanceVisitsPage(),
RegularVisitsPage.id: (_) => RegularVisitsPage(),
// PreventiveMaintenanceVisitsPage.id: (_) => PreventiveMaintenanceVisitsPage(),
PpmPage.id: (_) => const PpmPage(),
TrackGasRefillPage.id: (_) => const TrackGasRefillPage(),
RequestDeviceTransfer.id: (_) => const RequestDeviceTransfer(),
TrackDeviceTransferPage.id: (_) => const TrackDeviceTransferPage(),

@ -45,6 +45,7 @@ class GasRefillModel {
startTime = json['startTime'];
endDate = json['endDate'];
endTime = json['endTime'];
workingHours = json['workingHours'];
try {
final sd = DateTime.tryParse(startDate ?? "");
final st = DateTime.tryParse(startTime ?? "");
@ -63,7 +64,6 @@ class GasRefillModel {
}
engSignature = json['engSignature'];
nurseSignature = json['nurseSignature'];
workingHours = json['workingHours'];
site = json['site'] != null ? Site.fromJson(json['site']) : null;
building = json['building'] != null ? Building.fromJson(json['building']) : 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'];
workingHours = json['workingHours'];
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) {
timer.durationInSecond = (timer.endAt.difference(timer.startAt))?.inSeconds;
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 Color greenStatus(BuildContext context) => context.isDark ? const Color(0xff1FA269) : green50;
static Color blueStatus(BuildContext context) => context.isDark ? primary40 : primary50;
static Color redStatus(BuildContext context) => context.isDark ? const Color(0xffFFB6B8) : red40;
static Color yellowStatus(BuildContext context) => context.isDark ? const Color(0xffFFDA76) : orange40;
static Color background(BuildContext context) => context.isDark ? neutral60 : Colors.white;
static Color selectedButtonColor(BuildContext context) => context.isDark ? neutral60 : neutral30;
static Color unSelectedButtonColor(BuildContext context) => context.isDark ? neutral60 : Colors.white;
static Color filterButtonTextColor(BuildContext context) => context.isDark ? neutral30 : neutral50;
static Color getRequestStatusTextColorByName(BuildContext context, String status) {

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

@ -1,5 +1,4 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_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/weekly_fragment.dart';
import '../../../controllers/providers/api/all_requests_provider.dart';
import 'calender_fragments/monthly_fragment.dart';
class CalendarPage extends StatefulWidget {
@ -24,7 +22,10 @@ class _CalendarPageState extends State<CalendarPage> with SingleTickerProviderSt
@override
void initState() {
super.initState();
_tabController = TabController(length: 3, vsync: this)..addListener(() {setState(() {});});
_tabController = TabController(length: 3, vsync: this)
..addListener(() {
setState(() {});
});
}
@override

@ -7,7 +7,6 @@ import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import '../../../../controllers/providers/api/all_requests_provider.dart';
import '../../../../views/widgets/loaders/no_item_found.dart';
import '../../../app_style/app_color.dart';
import '../requests/asset_item_view.dart';
import '../requests/gas_refill_item_view.dart';
@ -41,8 +40,11 @@ class _DailyFragmentState extends State<DailyFragment> {
children: [
DateFormat("EEEE, d MMMM, yyyy", context.isAr ? "ar" : "en").format(DateTime.now()).heading5(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),
ListView.separated(
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),
ListView.separated(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (cxt, index) {

@ -53,7 +53,7 @@ class _WeeklyFragmentState extends State<WeeklyFragment> {
weekendDays: const [],
onCalendarCreated: (controller) {},
onPageChanged: (date) {
if(!snapshot.isCalendarLoading){
if (!snapshot.isCalendarLoading) {
_initialDate = date;
Provider.of<AllRequestsProvider>(context, listen: false)
@ -90,8 +90,8 @@ class _WeeklyFragmentState extends State<WeeklyFragment> {
day: day,
fill: snapshot.calendarRequests.requestsDetails?.firstWhere(
(element) => (element.date != null) && (DateTime.tryParse(element.date).day == (dateTime)?.day),
orElse: () => null,
) !=
orElse: () => null,
) !=
null,
).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/widget_extensions.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/views/pages/user/visits/visit_details.dart';
import '../../../../views/pages/user/ppm/ppm_details_page.dart';
import '../../../../views/widgets/requests/request_status.dart';
class PpmItemView extends StatelessWidget {
@ -47,8 +46,8 @@ class PpmItemView extends StatelessWidget {
8.height,
context.translation.ppmRequest.heading5(context),
8.height,
'${context.translation.assetNumber}: ${request.assetName}'.bodyText(context),
'${context.translation.assetSN}: ${request.assetNo}'.bodyText(context),
'${context.translation.assetNumber}: ${request.assetNo}'.bodyText(context),
'${context.translation.assetSN}: ${request.assetSN}'.bodyText(context),
'${context.translation.code}: ${request.code}'.bodyText(context),
16.height,
Row(
@ -64,11 +63,7 @@ class PpmItemView extends StatelessWidget {
),
],
).toShadowContainer(context, showShadow: showShadow).onPress(() {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => VisitDetailsPage(visit: Visit(id: request.id), priority: request.priority),
),
);
Navigator.of(context).push(MaterialPageRoute(builder: (_) => PpmDetailsPage(request: request)));
});
}
}

@ -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(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ASubTitle(context.translation.partNumberName),
ASubTitle(context.translation.partNumber),
_validate && _workOrder.sparePartsWorkOrders == null
? ASubTitle(
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/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/ppm/ppm_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 '../../../models/enums/user_types.dart';
@ -164,7 +164,7 @@ class _LandPageState extends State<LandPage> {
text: context.translation.preventiveMaintenance,
icon: FontAwesomeIcons.personWalking,
onPressed: () {
Navigator.of(context).pushNamed(RegularVisitsPage.id);
Navigator.of(context).pushNamed(PpmPage.id);
},
),
//if (_userProvider.user.type == UsersTypes.engineer)

@ -1,46 +1,45 @@
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/ppm_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_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/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/no_item_found.dart';
import '../../../../controllers/providers/api/user_provider.dart';
import '../../../../models/enums/user_types.dart';
import '../../../../models/ppm/ppm.dart';
import '../../../../new_views/app_style/app_color.dart';
import '../../../../new_views/common_widgets/app_filled_button.dart';
import '../../../widgets/requests/request_status.dart';
class VisitDetailsPage extends StatelessWidget {
class PpmDetailsPage extends StatelessWidget {
static const String id = "/visit-details";
final Visit visit;
final String priority;
final RequestsDetails request;
const VisitDetailsPage({Key key, this.visit, this.priority}) : super(key: key);
const PpmDetailsPage({Key key, this.request}) : super(key: key);
@override
Widget build(BuildContext context) {
UserProvider userProvider = Provider.of<UserProvider>(context);
RegularVisitsProvider _visitsProvider = Provider.of<RegularVisitsProvider>(context);
PpmProvider ppmProvider = Provider.of<PpmProvider>(context);
return Scaffold(
appBar: DefaultAppBar(title: context.translation.preventiveMaintenance),
body: SafeArea(
child: FutureBuilder(
future: _visitsProvider.getVisitObjectById(visit.id),
future: ppmProvider.getPpmById(request.id),
builder: (context, snap) {
if (snap.connectionState == ConnectionState.waiting) {
return const ALoading();
} else if (snap.hasData) {
Visit visit = snap.data;
Ppm ppm = snap.data;
return Column(children: [
SingleChildScrollView(
@ -49,42 +48,42 @@ class VisitDetailsPage extends StatelessWidget {
children: [
Row(
children: [
if (priority != null)
if (request.priority != null)
StatusLabel(
label: priority,
textColor: AppColor.getRequestStatusTextColorByName(context, priority),
backgroundColor: AppColor.getRequestStatusColorByName(context, priority),
label: request.priority,
textColor: AppColor.getRequestStatusTextColorByName(context, request.priority),
backgroundColor: AppColor.getRequestStatusColorByName(context, request.priority),
),
if (priority != null) 8.width,
if (request.priority != null) 8.width,
StatusLabel(
label: visit.status.name,
id: visit.status.id,
textColor: AppColor.getRequestStatusTextColorByName(context, visit.status.name),
backgroundColor: AppColor.getRequestStatusColorByName(context, visit.status.name),
label: ppm.visitStatusName,
id: ppm.deviceStatusId,
textColor: AppColor.getRequestStatusTextColorByName(context, ppm.visitStatusName),
backgroundColor: AppColor.getRequestStatusColorByName(context, ppm.visitStatusName),
),
1.width.expanded,
],
),
8.height,
visit.deviceEnglishName.heading5(context),
ppm.assetName.heading5(context),
8.height,
'${context.translation.assetNumber}: ${visit.deviceNumber}'.bodyText(context),
'${context.translation.assetSN}: ${visit.deviceSerialNumber}'.bodyText(context),
'${context.translation.code}: ${visit.serialNumber}'.bodyText(context),
'${context.translation.assetNumber}: ${ppm.assetNumber}'.bodyText(context),
'${context.translation.assetSN}: ${ppm.assetSerialNo}'.bodyText(context),
'${context.translation.code}: ${ppm.visitCode}'.bodyText(context),
const Divider().defaultStyle(context),
'${context.translation.expectDate}: ${visit.expectDate?.toServiceRequestDetailsFormat}'.bodyText(context),
'${context.translation.actualDate}: ${visit.actualDate?.toServiceRequestDetailsFormat}'.bodyText(context),
'${context.translation.expectDate}: ${ppm.expectedDate?.toServiceRequestDetailsFormat}'.bodyText(context),
'${context.translation.actualDate}: ${ppm.actualDate?.toServiceRequestDetailsFormat}'.bodyText(context),
const Divider().defaultStyle(context),
'${context.translation.assignedTo}: ${visit.assignTo}'.bodyText(context),
'${context.translation.engineerName}: ${visit.employName}'.bodyText(context),
'${context.translation.site}: ${visit.hospitalName}'.bodyText(context),
'${context.translation.assignedTo}: ${ppm.assignedToName}'.bodyText(context),
'${context.translation.engineerName}: ${ppm.assignedEmployeeName}'.bodyText(context),
'${context.translation.site}: ${ppm.siteName}'.bodyText(context),
],
).toShadowContainer(context).paddingAll(16),
).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(
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,
).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: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/settings/setting_provider.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/pantry/calibration_tools.dart';
import 'package:test_sa/models/pantry/pentry.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/models/all_requests_and_count_model.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/common_widgets/app_filled_button.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/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';
class EditPentry extends StatefulWidget {
final Pentry pentry;
final Visit visit;
class EditPpm extends StatefulWidget {
final Ppm ppm;
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
State<EditPentry> createState() => _EditPentryState();
State<EditPpm> createState() => _EditPpmState();
}
class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateMixin {
bool _isLoading = false;
bool _validate = false;
class _EditPpmState extends State<EditPpm> with SingleTickerProviderStateMixin {
UserProvider _userProvider;
SettingProvider _settingProvider;
RegularVisitsProvider _regularVisitsProvider;
Pentry _pentry;
PpmProvider _regularVisitsProvider;
Ppm _ppm;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
TabController _tabController;
_onSubmit() async {
_validate = true;
if (!(await _pentry.validate())) {
if (!(await _ppm.validate(context))) {
setState(() {});
return;
}
_pentry.clearEmptyObjects();
await _regularVisitsProvider.updatePentry(context, user: _userProvider.user, pentry: _pentry, visit: widget.visit);
_ppm.removeEmptyObjects();
await _regularVisitsProvider.updatePentry(context, user: _userProvider.user, ppm: widget.ppm);
}
@override
void initState() {
_pentry = widget.pentry.copyWith();
if (_pentry.pmKits.isEmpty) _pentry.pmKits.add(PMKit());
if (_pentry.calibrationTools.isEmpty) _pentry.calibrationTools.add(CalibrationTool());
if (_pentry.ppmCheckLists.isEmpty) _pentry.ppmCheckLists.add(PPMCheckList());
_ppm = widget.ppm;
_tabController = TabController(length: 4, vsync: this);
super.initState();
}
@ -73,29 +61,30 @@ class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateM
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context);
_settingProvider = Provider.of<SettingProvider>(context);
_regularVisitsProvider = Provider.of<RegularVisitsProvider>(context);
_regularVisitsProvider = Provider.of<PpmProvider>(context);
return Scaffold(
appBar: DefaultAppBar(title: context.translation.preventiveMaintenance),
key: _scaffoldKey,
body: SafeArea(
child: LoadingManager(
isLoading: _isLoading,
isLoading: false,
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
child: Column(
children: [
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(
controller: _tabController,
isScrollable: true,
padding: EdgeInsets.zero,
labelColor: context.isDark ? AppColor.neutral10 : AppColor.neutral60,
unselectedLabelColor: AppColor.neutral20,
labelColor: context.isDark ? AppColor.neutral30 : AppColor.neutral60,
unselectedLabelColor: context.isDark ? AppColor.neutral10 : AppColor.neutral20,
unselectedLabelStyle: AppTextStyles.bodyText,
labelStyle: AppTextStyles.bodyText,
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) {
setState(() {});
},
@ -111,10 +100,10 @@ class _EditPentryState extends State<EditPentry> with SingleTickerProviderStateM
physics: const NeverScrollableScrollPhysics(),
controller: _tabController,
children: [
PentryTBSForm(model: _pentry, enableValidate: _validate),
PentryCalibrationToolForm(models: _pentry.calibrationTools, enableValidate: _validate),
PentryPMKitForm(models: _pentry.pmKits, enableValidate: _validate, assetId: widget.visit?.deviceId),
PentryPMChecklistForm(models: _pentry.ppmCheckLists, enableValidate: _validate),
PentryTBSForm(model: _ppm),
PentryCalibrationToolForm(models: _ppm.vCalibrationTools),
PentryPMKitForm(models: _ppm.vKits, assetId: widget.ppm?.assetId),
PentryPMChecklistForm(models: _ppm.vChecklists),
],
).expanded,
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) {
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> {
bool loading = false;
ServiceRequest serviceRequest;
@override
void initState() {
super.initState();

@ -17,6 +17,7 @@ class PartNoButton extends StatefulWidget {
final List<SparePartsWorkOrders> initialList;
final TextEditingController controller;
final Function(List<SparePartsWorkOrders> sparePart) onChange;
const PartNoButton({@required this.spareParts, @required this.controller, this.initialList, this.onChange, Key key}) : super(key: key);
@override
@ -56,6 +57,8 @@ class _PartNoButtonState extends State<PartNoButton> {
childrenPadding: const EdgeInsets.symmetric(horizontal: 16),
backgroundColor: AppColor.background(context),
collapsedBackgroundColor: AppColor.background(context),
iconColor: context.isDark ? AppColor.neutral30 : AppColor.neutral50,
collapsedIconColor: context.isDark ? AppColor.neutral30 : AppColor.neutral50,
children: [
SingleItemDropDownMenu<SparePart, NullableLoadingProvider>(
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 String label;
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
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: context.isDark && (enable == false)
? AppColor.neutral50
: (enable == false)
? AppColor.neutral40
: AppColor.background(context),
color: backgroundColor ??
(context.isDark && (enable == false)
? AppColor.neutral50
: (enable == false)
? AppColor.neutral40
: AppColor.background(context)),
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)],
),
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth, vertical: 8.toScreenHeight),
@ -37,7 +49,7 @@ class ADatePicker extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: [
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
: label.bodyText(context).paddingOnly(top: 8, bottom: 8),

@ -16,8 +16,9 @@ class MultiFilesPicker extends StatefulWidget {
final bool error;
final List<File> files;
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
State<MultiFilesPicker> createState() => _MultiFilesPickerState();
@ -46,6 +47,9 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
return;
}
widget.files.remove(image);
if (widget.onChange != null) {
widget.onChange(widget.files);
}
setState(() {});
},
);
@ -109,6 +113,9 @@ class _MultiFilesPickerState extends State<MultiFilesPicker> {
File fileImage = File(pickedFile.path);
if (fileImage != null) {
widget.files.add(fileImage);
if (widget.onChange != null) {
widget.onChange(widget.files);
}
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/settings/setting_provider.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 '../../../extensions/text_extensions.dart';
import '../../../models/service_request/spare_parts.dart';
import '../../../new_views/app_style/app_text_style.dart';
class AutoCompletePartsField extends StatefulWidget {
final String initialValue;
final num assetId;
final bool clearAfterPick;
final bool clearAfterPick, byName;
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
_AutoCompletePartsFieldState createState() => _AutoCompletePartsFieldState();
@ -53,30 +56,41 @@ class _AutoCompletePartsFieldState extends State<AutoCompletePartsField> {
_settingProvider = Provider.of<SettingProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
_partsProvider = Provider.of<PartsProvider>(context);
final border = UnderlineInputBorder(borderSide: BorderSide.none, borderRadius: BorderRadius.circular(10));
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Colors.white,
color: AppColor.background(context),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
),
child: TypeAheadField<SparePartsWorkOrders>(
minCharsForSuggestions: 1,
textFieldConfiguration: TextFieldConfiguration(
style: AppTextStyles.bodyText,
controller: _controller,
textAlign: TextAlign.start,
decoration: InputDecoration(
label: context.translation.partNumberName.tinyFont(context),
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
border: border,
disabledBorder: border,
focusedBorder: border,
enabledBorder: border,
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,
),
suggestionsCallback: (vale) async {
return (await _partsProvider.getPartsList(title: vale, assetId: widget.assetId)).map((e) => SparePartsWorkOrders(sparePart: e)).toList();
suggestionsCallback: (value) async {
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) {
return ListTile(
@ -91,7 +105,7 @@ class _AutoCompletePartsFieldState extends State<AutoCompletePartsField> {
if (widget.clearAfterPick) {
_controller.clear();
} else {
_controller.text = part?.sparePart?.partNo;
_controller.text = widget.byName ? (part?.sparePart?.partName ?? "") : (part?.sparePart?.partNo ?? "");
}
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/settings/setting_provider.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/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_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 {
final Lookup initialValue;
@ -54,30 +58,44 @@ class _AutoCompleteDeviceNumberFieldState extends State<AutoCompleteDeviceNumber
_settingProvider = Provider.of<SettingProvider>(context);
_userProvider = Provider.of<UserProvider>(context);
_devicesProvider = Provider.of<AssetProvider>(context);
final border = UnderlineInputBorder(borderSide: BorderSide.none, borderRadius: BorderRadius.circular(10));
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Colors.white,
color: AppColor.background(context),
borderRadius: BorderRadius.circular(AppStyle.borderRadius * AppStyle.getScaleFactor(context)),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
),
child: TypeAheadField<Asset>(
minCharsForSuggestions: 1,
textFieldConfiguration: TextFieldConfiguration(
style: AppTextStyles.bodyText,
controller: _controller,
textAlign: TextAlign.start,
textInputAction: TextInputAction.search,
decoration: InputDecoration(
label: context.translation.assetNumber.tinyFont(context),
border: InputBorder.none,
disabledBorder: InputBorder.none,
focusedBorder: InputBorder.none,
enabledBorder: InputBorder.none,
border: border,
disabledBorder: border,
focusedBorder: border,
enabledBorder: border,
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 {
return await _devicesProvider.getDevicesList(host: _settingProvider.host, user: _userProvider.user, hospitalId: widget.hospitalId, /* number: vale,*/ addPagination: false);
suggestionsCallback: (value) async {
return await _devicesProvider.getDevicesList(
host: _settingProvider.host,
user: _userProvider.user,
hospitalId: widget.hospitalId,
addPagination: false,
search: AssetSearch(assetNo: value),
);
},
itemBuilder: (context, device) {
return device.assetNumber.bodyText(context).paddingOnly(bottom: 16, start: 16);

@ -1,22 +1,23 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/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/int_extensions.dart';
import 'package:test_sa/extensions/text_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/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 '../date_and_time/date_picker.dart';
import 'auto_complete_fields/auto_complete_devices_field.dart';
class PentryCalibrationToolForm extends StatefulWidget {
final List<CalibrationTool> models;
final bool enableValidate;
final List<PpmCalibrationTools> models;
const PentryCalibrationToolForm({Key key, this.models, this.enableValidate}) : super(key: key);
const PentryCalibrationToolForm({Key key, this.models}) : super(key: key);
@override
State<PentryCalibrationToolForm> createState() => _PentryCalibrationToolFormState();
@ -36,8 +37,18 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
maxWidth: true,
textColor: Colors.white,
buttonColor: context.isDark ? AppColor.neutral60 : AppColor.neutral50,
onPressed: () {
widget.models.add(CalibrationTool());
onPressed: () async {
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(() {});
},
);
@ -47,7 +58,7 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
padding: const EdgeInsets.all(16),
margin: EdgeInsets.only(bottom: 16.toScreenHeight),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
color: AppColor.background(context),
borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)],
),
@ -66,18 +77,22 @@ class _PentryCalibrationToolFormState extends State<PentryCalibrationToolForm> {
),
16.height,
AutoCompleteDeviceNumberField(
initialValue: model.assetsNumber,
initialValue: model.assetId == null ? null : Lookup(id: model.assetId, name: model.assetNumber ?? ""),
hospitalId: userProvider.user.clientId,
onPick: (number) {
model.assetsNumber = number;
model.assetNumber = number.name;
model.assetId = number.id;
setState(() {});
},
),
8.height,
ADatePicker(
label: context.translation.calibrationDate,
date: model.dataOfTesting,
date: DateTime.tryParse(model.calibrationDateOfTesters ?? ""),
backgroundColor: context.isDark ? AppColor.neutral50 : AppColor.background(context),
withBorder: false,
onDatePicker: (date) {
model.dataOfTesting = date;
model.calibrationDateOfTesters = date?.toIso8601String();
setState(() {});
},
),

@ -1,27 +1,20 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/lookup.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 'package:test_sa/models/ppm/ppm_kit.dart';
import '../../../new_views/app_style/app_color.dart';
import '../../../new_views/common_widgets/app_filled_button.dart';
import '../parts/auto_complete_parts_field.dart';
class PentryPMKitForm extends StatefulWidget {
final List<PMKit> models;
final bool enableValidate;
final List<PpmKits> models;
final num assetId;
const PentryPMKitForm({
Key key,
this.models,
this.assetId,
this.enableValidate,
}) : super(key: key);
const PentryPMKitForm({Key key, this.models, this.assetId}) : super(key: key);
@override
State<PentryPMKitForm> createState() => _PentryPMKitFormState();
@ -41,19 +34,28 @@ class _PentryPMKitFormState extends State<PentryPMKitForm> {
maxWidth: true,
textColor: Colors.white,
buttonColor: context.isDark ? AppColor.neutral60 : AppColor.neutral50,
onPressed: () {
widget.models.add(PMKit());
onPressed: () async {
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(() {});
},
);
}
final model = widget.models[index];
final TextEditingController controller = TextEditingController(text: model.quantityNeeded);
return Container(
padding: const EdgeInsets.all(16),
margin: EdgeInsets.only(bottom: 16.toScreenHeight),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
color: AppColor.background(context),
borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)],
),
@ -74,19 +76,26 @@ class _PentryPMKitFormState extends State<PentryPMKitForm> {
AutoCompletePartsField(
assetId: widget.assetId,
clearAfterPick: false,
initialValue: (model.itemCode?.name ?? "").toString(),
byName: true,
initialValue: model.partName ?? "",
onPick: (part) {
model.itemCode = Lookup(id: part.id, name: part?.sparePart?.partNo);
model.itemName = part?.sparePart?.partName;
model.partCatalogItemId = part?.sparePart?.id;
model.partNumber = part?.sparePart?.partNo;
model.partName = part?.sparePart?.partName;
setState(() {});
},
),
8.height,
AppTextFormField(
controller: controller,
labelText: context.translation.quantity,
textInputType: TextInputType.number,
onChange: (text) {
model.quantityNeeded = num.tryParse(text ?? "")?.toString();
AutoCompletePartsField(
assetId: widget.assetId,
clearAfterPick: false,
byName: false,
initialValue: model.partNumber ?? "",
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/text_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/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 {
final List<PPMCheckList> models;
final bool enableValidate;
final List<PpmChecklists> models;
const PentryPMChecklistForm({Key key, this.models, this.enableValidate}) : super(key: key);
const PentryPMChecklistForm({Key key, this.models}) : super(key: key);
@override
State<PentryPMChecklistForm> createState() => _PentryPMChecklistFormState();
}
class _PentryPMChecklistFormState extends State<PentryPMChecklistForm> {
PPMCheckList item = PPMCheckList();
PpmChecklists item = PpmChecklists();
List<int> showLabel = [];
@override
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)
? context.translation.noDataFound.heading5(context).center
: ListView.builder(
@ -33,16 +36,53 @@ class _PentryPMChecklistFormState extends State<PentryPMChecklistForm> {
return Card(
child: ExpansionTile(
shape: const Border(),
title: (list[index].title ?? "").heading5(context),
subtitle: "${context.translation.status} ${list[index].status?.name}".bodyText(context),
initiallyExpanded: index == 0,
iconColor: AppColor.neutral50,
collapsedIconColor: AppColor.neutral50,
title: (list[index].task ?? "").heading5(context),
onExpansionChanged: (value) {
if (!value) {
showLabel.remove(index);
} 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),
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,
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,
],
),

@ -1,28 +1,26 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/pantry/pentry.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 'package:test_sa/models/ppm/ppm.dart';
import 'package:test_sa/models/ppm/ppm_attachment.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 '../e_signature/e_signature.dart';
import '../images/multi_image_picker.dart';
import '../timer/app_timer.dart';
class PentryTBSForm extends StatefulWidget {
final Pentry model;
final bool enableValidate;
final Ppm model;
const PentryTBSForm({
Key key,
this.model,
this.enableValidate,
}) : super(key: key);
const PentryTBSForm({Key key, this.model}) : super(key: key);
@override
State<PentryTBSForm> createState() => _PentryTBSFormState();
@ -32,6 +30,7 @@ class _PentryTBSFormState extends State<PentryTBSForm> {
@override
Widget build(BuildContext context) {
widget.model?.files ??= [];
widget.model?.files = (widget.model.files ?? []).where((element) => element.attachmentName != null && element.attachmentName.isNotEmpty).toList();
return SingleChildScrollView(
child: Column(
@ -40,104 +39,96 @@ class _PentryTBSFormState extends State<PentryTBSForm> {
8.height,
SingleItemDropDownMenu<Lookup, PPMVisitStatusProvider>(
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,
onSelect: (value) {
if (value != null) {
widget.model.ppmVisitStatus = value;
widget.model.visitStatusName = value.name;
widget.model.visitStatusId = value.id;
}
},
),
8.height,
AppTimer(
label: context.translation.timer,
timer: widget.model.timer,
enabled: widget.model.timer.endAt == null,
timer: widget.model.tbsTimer,
enabled: widget.model.tbsTimer.endAt == null,
onChange: (timer) async {
widget.model.timer = timer;
widget.model.tbsTimer = timer;
return true;
},
),
8.height,
SingleItemDropDownMenu<Lookup, PPMDeviceStatusProvider>(
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,
onSelect: (value) {
if (value != null) {
widget.model.status = value;
widget.model.deviceStatusId = value.id;
widget.model.deviceStatusName = value.name;
}
},
),
8.height,
ADatePicker(
label: context.translation.actualVisitDate,
date: widget.model.actualVisitDate,
date: DateTime.tryParse(widget.model.actualDate ?? ""),
from: DateTime.now().subtract(const Duration(days: 30)),
onDatePicker: (date) {
if (date == null) return;
widget.model.actualVisitDate = date;
widget.model.actualDate = date?.toIso8601String();
setState(() {});
},
),
8.height,
ADatePicker(
label: context.translation.expectedVisitDate,
date: widget.model.expectedVisitDate,
date: DateTime.tryParse(widget.model.expectedDate ?? ""),
from: DateTime.now().subtract(const Duration(days: 30)),
onDatePicker: (date) {
if (date == null) return;
widget.model.expectedVisitDate = date;
widget.model.expectedDate = date?.toIso8601String();
setState(() {});
},
),
8.height,
// const ASubTitle("Traveling Hours"),
// const SizedBox(
// height: 4,
// ),
// ATextFormField(
// initialValue: (widget.model.travelingHours ?? "").toString(),
// textAlign: TextAlign.center,
// style: Theme.of(context).textTheme.titleMedium,
// textInputType: TextInputType.number,
// onChange: (value) {
// widget.model.travelingHours = value;
// },
// ),
AppTextFormField(
labelText: context.translation.travelingHours,
initialValue: (widget.model.travelingHours ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
textInputType: TextInputType.number,
onChange: (value) {
widget.model.travelingHours = value;
},
),
8.height,
MultiFilesPicker(label: context.translation.attachImage, files: widget.model.files),
// AMiniOneFilePicker(
// //error: _validate && _serviceReport.image == null,
// file: widget.model.file,
// onPick: (file) {
// widget.model.file = file;
// },
// ),
MultiFilesPicker(
label: context.translation.attachImage,
files: widget.model.files.map((e) => File(e.attachmentName)).toList(),
onChange: (files) {
widget.model.files = files.map((e) => PpmAttachments(attachmentName: e.path)).toList();
},
),
8.height,
ESignature(
title: context.translation.nurseSignature,
oldSignature: widget.model.signatureNurse,
oldSignature: widget.model.nurseSignature,
newSignature: widget.model.localNurseSignature,
onChange: (signature) {
// if (signature == null || signature.isEmpty) {
// return;
// }
widget.model.localNurseSignature = signature;
widget.model.signatureNurse = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
widget.model.nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
},
),
8.height,
ESignature(
title: context.translation.engSign,
oldSignature: widget.model.signatureEngineer,
oldSignature: widget.model.engSignature,
newSignature: widget.model.localEngineerSignature,
onChange: (signature) {
// if (signature == null || signature.isEmpty) {
// return;
// }
widget.model.localEngineerSignature = signature;
widget.model.signatureEngineer = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
widget.model.engSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
},
),
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/string_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/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/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 '../../../extensions/text_extensions.dart';
import '../../../models/lookup.dart';
import '../../pages/user/visits/pantry/edit_pentry.dart';
import '../requests/request_status.dart';
class VisitItem extends StatelessWidget {
final Visit visit;
final Lookup priority;
class PpmItem extends StatelessWidget {
final Ppm ppm;
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
Widget build(BuildContext context) {
@ -32,29 +32,28 @@ class VisitItem extends StatelessWidget {
children: [
Row(
children: [
if (priority != null)
if (request.priority != null)
StatusLabel(
label: priority.name,
id: priority.id,
textColor: AppColor.getPriorityStatusTextColor(context, priority.id),
backgroundColor: AppColor.getPriorityStatusColor(context, priority.id),
label: request.priority,
textColor: AppColor.getRequestStatusTextColorByName(context, request.priority),
backgroundColor: AppColor.getRequestStatusColorByName(context, request.priority),
),
if (priority != null) 8.width,
if (request.priority != null) 8.width,
StatusLabel(
label: visit.status.name,
id: visit.status.id,
textColor: AppColor.getRequestStatusTextColorByName(context, visit.status.name),
backgroundColor: AppColor.getRequestStatusColorByName(context, visit.status.name),
label: ppm.visitStatusName,
id: ppm.deviceStatusId,
textColor: AppColor.getRequestStatusTextColorByName(context, ppm.visitStatusName),
backgroundColor: AppColor.getRequestStatusColorByName(context, ppm.visitStatusName),
),
1.width.expanded,
],
),
8.height,
visit.deviceEnglishName.heading5(context),
ppm.assetName.heading5(context),
8.height,
'${context.translation.assetNumber}: ${visit.deviceNumber}'.bodyText(context),
'${context.translation.assetSN}: ${visit.deviceSerialNumber}'.bodyText(context),
'${context.translation.code}: ${visit.serialNumber}'.bodyText(context),
'${context.translation.assetNumber}: ${ppm.assetNumber}'.bodyText(context),
'${context.translation.assetSN}: ${ppm.assetSerialNo}'.bodyText(context),
'${context.translation.code}: ${ppm.visitCode}'.bodyText(context),
16.height,
Row(
mainAxisSize: MainAxisSize.min,
@ -67,7 +66,7 @@ class VisitItem extends StatelessWidget {
Icon(Icons.arrow_forward, color: AppColor.blueStatus(context), size: 14)
],
).onPress(() {
Navigator.of(context).push(MaterialPageRoute(builder: (_) => VisitDetailsPage(visit: visit)));
Navigator.of(context).push(MaterialPageRoute(builder: (_) => PpmDetailsPage(request: RequestsDetails(id: ppm.id))));
}),
],
).expanded,
@ -75,13 +74,13 @@ class VisitItem extends StatelessWidget {
Column(
crossAxisAlignment: CrossAxisAlignment.end,
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(() {
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(
visit.createdOn != null ? visit.createdOn.toServiceRequestCardFormat : "",
ppm.createdOn != null ? ppm.createdOn.toServiceRequestCardFormat : "",
textAlign: TextAlign.end,
style: AppTextStyles.tinyFont.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50),
),

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

@ -8,6 +8,7 @@ class FilterItem extends StatelessWidget {
final VoidCallback onSelected;
const FilterItem({Key key, this.status, this.isSelected, this.onSelected}) : super(key: key);
//
// Color getStatusColor() {
// 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> {
FaultDescription initialValue;
@override
void initState() {
super.initState();

@ -89,7 +89,7 @@ class _AppTimerState extends State<AppTimer> {
_running = _startAt != null && _endAt == null;
_delay = (widget.timer?.durationInSecond ?? 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();
if (_running) {
_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