ppm task supplier ui completed and save and update api implemented

design_3.0_latest
WaseemAbbasi22 9 months ago
parent b67e6dea11
commit 7df18179a1

@ -1,5 +1,6 @@
import 'dart:convert';
import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
@ -18,7 +19,33 @@ class PpmProvider extends ChangeNotifier {
// number of items call in each request
final pageItemNumber = 12;
//reset provider data
PlanPreventiveVisit? _planPreventiveVisit;
late int _totalTabs = 4;
TabController? tabController;
int get totalTabs => _totalTabs;
set totalTabs(int value) {
_totalTabs = value;
notifyListeners();
}
List<File> _ppmPlanAttachments = [];
List<File> get ppmPlanAttachments => _ppmPlanAttachments;
set ppmPlanAttachments(List<File> value) {
_ppmPlanAttachments = value;
notifyListeners();
}
PlanPreventiveVisit? get planPreventiveVisit => _planPreventiveVisit;
set planPreventiveVisit(PlanPreventiveVisit? value) {
_planPreventiveVisit = value;
notifyListeners();
} //reset provider data
void reset() {
ppms = null;
nextPage = true;
@ -122,22 +149,32 @@ class PpmProvider extends ChangeNotifier {
// }
Future<PlanPreventiveVisit?> getPlanPreventiveVisitById(int id) async {
// try {
Response response = await ApiManager.instance.get(URLs.getPlanPreventiveVisitById + "?planPreventiveVisitId=$id");
if (response.statusCode >= 200 && response.statusCode < 300) {
return PlanPreventiveVisit.fromJson(json.decode(response.body)["data"]);
}
return null;
// try {
isLoading = true;
Response response = await ApiManager.instance.get(URLs.getPlanPreventiveVisitById + "?planPreventiveVisitId=$id");
if (response.statusCode >= 200 && response.statusCode < 300) {
planPreventiveVisit = PlanPreventiveVisit.fromJson(json.decode(response.body)["data"]);
print('data i got is ${planPreventiveVisit?.toJson(status: 0)}');
isLoading = false;
notifyListeners();
return planPreventiveVisit;
}
isLoading = false;
notifyListeners();
return null;
// } catch (error) {
// isLoading= false;
// notifyListeners();
// return null;
// }
}
Future<int> updateRecurrentWo({required int status,required PlanPreventiveVisit planPreventiveVisit}) async {
Future<int> updateVisitByEngineer({required int status}) async {
isLoading = true;
Response response;
try {
response = await ApiManager.instance.post(URLs.updateRecurrentPlanUrl, body: planPreventiveVisit.toJson(status: status));
response = await ApiManager.instance.post(URLs.updateVisitByEngineer, body: planPreventiveVisit!.toJson(status: status));
print('response i got is ${response.body}');
stateCode = response.statusCode;
isLoading = false;
notifyListeners();
@ -150,34 +187,34 @@ class PpmProvider extends ChangeNotifier {
}
}
Future<int> updateVisitByEngineer(BuildContext context, {required User user, required Ppm ppm}) async {
try {
ppm.visitTimers?.add(
VisitTimers(
id: 0,
startDateTime: ppm.tbsTimer?.startAt!.toIso8601String(), // Handle potential null
endDateTime: ppm.tbsTimer?.endAt?.toIso8601String(), // Handle potential null
workingHours: ((ppm.tbsTimer?.durationInSecond ?? 0) / 60 / 60),
),
);
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
late Response response; // Using 'late' for initialization later
Map<String, dynamic> body = ppm.copyWith(assignedEmployeeId: user.userName, tbsTimer: ppm.tbsTimer).toJson();
response = await ApiManager.instance.put(URLs.updateVisitByEngineer, body: body);
if (response.statusCode >= 200 && response.statusCode < 300) {
reset(); //visit.status = pentry.ppmVisitStatus;
notifyListeners();
Fluttertoast.showToast(msg: context.translation.successfulRequestMessage);
Navigator.of(context).pop();
} else {
Fluttertoast.showToast(msg: "${context.translation.failedToCompleteRequest} ${jsonDecode(response.body)["message"]}");
}
Navigator.of(context).pop();
return response.statusCode;
} catch (error) {
return -1;
}
}
// Future<int> updateVisitByEngineer(BuildContext context, {required User user, required Ppm ppm}) async {
// try {
// ppm.visitTimers?.add(
// VisitTimers(
// id: 0,
// startDateTime: ppm.tbsTimer?.startAt!.toIso8601String(), // Handle potential null
// endDateTime: ppm.tbsTimer?.endAt?.toIso8601String(), // Handle potential null
// workingHours: ((ppm.tbsTimer?.durationInSecond ?? 0) / 60 / 60),
// ),
// );
// showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
// late Response response; // Using 'late' for initialization later
// Map<String, dynamic> body = ppm.copyWith(assignedEmployeeId: user.userName, tbsTimer: ppm.tbsTimer).toJson();
// response = await ApiManager.instance.put(URLs.updateVisitByEngineer, body: body);
// if (response.statusCode >= 200 && response.statusCode < 300) {
// reset(); //visit.status = pentry.ppmVisitStatus;
// notifyListeners();
// Fluttertoast.showToast(msg: context.translation.successfulRequestMessage);
// Navigator.of(context).pop();
// } else {
// Fluttertoast.showToast(msg: "${context.translation.failedToCompleteRequest} ${jsonDecode(response.body)["message"]}");
// }
// Navigator.of(context).pop();
// return response.statusCode;
// } catch (error) {
// return -1;
// }
// }
/// return -2 if request in progress
/// return -1 if error happen when sending request

@ -544,6 +544,11 @@
"executionTimeFrame": "إطار زمني للتنفيذ",
"pmTestResult": "نتيجة اختبار الصيانة الوقائية",
"actualVisit": "الزيارة الفعلية",
"typeOfPm": "نوع الصيانة الوقائية"
"typeOfPm": "نوع الصيانة الوقائية",
"totalWorkingTime": "إجمالي وقت العمل",
"attachments": "المرفقات",
"supplierName": "اسم المورد",
"externalEngineerName": "اسم المهندس الخارجي",
"telephone": "الهاتف"
}

@ -547,5 +547,10 @@
"executionTimeFrame": "Execution Time Frame",
"pmTestResult": "PM Test Result",
"actualVisit": "Actual Visit",
"typeOfPm": "Type of PM"
"totalWorkingTime": "Total Working Time",
"typeOfPm": "Type of PM",
"attachments": "Attachments",
"supplierName": "Supplier Name",
"externalEngineerName": "External Engineer Name",
"telephone": "Telephone"
}

@ -1,9 +1,13 @@
import 'dart:convert';
import 'dart:io';
import 'package:flutter/widgets.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/service_request/supplier_details.dart';
import 'package:test_sa/models/timer_model.dart';
import 'package:test_sa/service_request_latest/utilities/service_request_utils.dart';
class PlanPreventiveVisit {
String? id;
@ -24,7 +28,7 @@ class PlanPreventiveVisit {
String? fromDate;
String? toDate;
AssignedEmployee? assignedEmployee;
String? acutalDateOfVisit;
DateTime? acutalDateOfVisit;
Lookup? typeOfService;
Lookup? visitStatus;
num? travelingHours;
@ -32,11 +36,12 @@ class PlanPreventiveVisit {
int? executionTimeFrame;
Lookup? taskStatus;
Lookup? deviceStatus;
Lookup? assetAvailability;
Lookup? assetAvailability = Lookup();
Lookup? safety;
String? engSignature;
String? nurseSignature;
List<PreventiveVisitAttachments>? preventiveVisitAttachments;
List<File>? attachments = [];
List<PreventiveVisitCalibrations>? preventiveVisitCalibrations;
List<PreventiveVisitChecklists>? preventiveVisitChecklists;
List<PreventiveVisitKits>? preventiveVisitKits;
@ -76,6 +81,7 @@ class PlanPreventiveVisit {
this.engSignature,
this.nurseSignature,
this.preventiveVisitAttachments,
this.attachments,
this.preventiveVisitCalibrations,
this.preventiveVisitChecklists,
this.preventiveVisitKits,
@ -85,7 +91,7 @@ class PlanPreventiveVisit {
PlanPreventiveVisit.fromJson(Map<String, dynamic> json) {
id = json['id'];
visitNo = json['visitNo'];
asset = json['asset'] != null ? new Asset.fromJson(json['asset']) : null;
asset = json['asset'] != null ? Asset.fromJson(json['asset']) : null;
planNo = json['planNo'];
planName = json['planName'];
nextPMDate = json['nextPMDate'];
@ -100,53 +106,54 @@ class PlanPreventiveVisit {
roomName = json['roomName'];
fromDate = json['fromDate'];
toDate = json['toDate'];
assignedEmployee = json['assignedEmployee'] != null ? new AssignedEmployee.fromJson(json['assignedEmployee']) : null;
acutalDateOfVisit = json['acutalDateOfVisit'];
typeOfService = json['typeOfService'] != null ? new Lookup.fromJson(json['typeOfService']) : null;
visitStatus = json['visitStatus'] != null ? new Lookup.fromJson(json['visitStatus']) : null;
assignedEmployee = json['assignedEmployee'] != null ? AssignedEmployee.fromJson(json['assignedEmployee']) : null;
acutalDateOfVisit = json['acutalDateOfVisit'] != null ? DateTime.parse(json['acutalDateOfVisit']) : null;
typeOfService = json['typeOfService'] != null ? Lookup.fromJson(json['typeOfService']) : null;
visitStatus = json['visitStatus'] != null ? Lookup.fromJson(json['visitStatus']) : null;
travelingHours = json['travelingHours'];
comments = json['comments'];
executionTimeFrame = json['executionTimeFrame'];
taskStatus = json['taskStatus'] != null ? new Lookup.fromJson(json['taskStatus']) : null;
deviceStatus = json['deviceStatus'] != null ? new Lookup.fromJson(json['deviceStatus']) : null;
assetAvailability = json['assetAvailability'];
safety = json['safety'] != null ? new Lookup.fromJson(json['safety']) : null;
taskStatus = json['taskStatus'] != null ? Lookup.fromJson(json['taskStatus']) : null;
deviceStatus = json['deviceStatus'] != null ? Lookup.fromJson(json['deviceStatus']) : null;
assetAvailability = json['assetAvailability'] != null ? Lookup.fromJson(json['assetAvailability']) : null;
safety = json['safety'] != null ? Lookup.fromJson(json['safety']) : null;
engSignature = json['engSignature'];
nurseSignature = json['nurseSignature'];
if (json['preventiveVisitAttachments'] != null) {
preventiveVisitAttachments = <PreventiveVisitAttachments>[];
json['preventiveVisitAttachments'].forEach((v) {
preventiveVisitAttachments!.add(new PreventiveVisitAttachments.fromJson(v));
preventiveVisitAttachments!.add(PreventiveVisitAttachments.fromJson(v));
});
}
if (json['preventiveVisitCalibrations'] != null) {
preventiveVisitCalibrations = <PreventiveVisitCalibrations>[];
json['preventiveVisitCalibrations'].forEach((v) {
preventiveVisitCalibrations!.add(new PreventiveVisitCalibrations.fromJson(v));
preventiveVisitCalibrations!.add(PreventiveVisitCalibrations.fromJson(v));
});
}
if (json['preventiveVisitChecklists'] != null) {
preventiveVisitChecklists = <PreventiveVisitChecklists>[];
json['preventiveVisitChecklists'].forEach((v) {
preventiveVisitChecklists!.add(new PreventiveVisitChecklists.fromJson(v));
preventiveVisitChecklists!.add(PreventiveVisitChecklists.fromJson(v));
});
}
if (json['preventiveVisitKits'] != null) {
preventiveVisitKits = <PreventiveVisitKits>[];
json['preventiveVisitKits'].forEach((v) {
preventiveVisitKits!.add(new PreventiveVisitKits.fromJson(v));
preventiveVisitKits!.add(PreventiveVisitKits.fromJson(v));
});
}
if (json['preventiveVisitTimers'] != null) {
preventiveVisitTimers = <PreventiveVisitTimers>[];
json['preventiveVisitTimers'].forEach((v) {
preventiveVisitTimers!.add(new PreventiveVisitTimers.fromJson(v));
preventiveVisitTimers!.add(PreventiveVisitTimers.fromJson(v));
});
}
if (json['preventiveVisitSuppliers'] != null) {
preventiveVisitSuppliers = <PreventiveVisitSuppliers>[];
json['preventiveVisitSuppliers'].forEach((v) {
preventiveVisitSuppliers!.add( PreventiveVisitSuppliers.fromJson(v));
preventiveVisitSuppliers!.add(PreventiveVisitSuppliers.fromJson(v));
});
}
}
@ -154,10 +161,9 @@ class PlanPreventiveVisit {
Map<String, dynamic> toJson({required int status}) {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['acutalDateOfVisit'] = acutalDateOfVisit;
data['statusValue'] = status;
data['acutalDateOfVisit'] = acutalDateOfVisit?.toIso8601String();
data['typeOfServiceId'] = typeOfService?.id;
data['visitStatusValue'] = visitStatus?.value;
data['visitStatusValue'] = status;
data['travelingHours'] = travelingHours;
data['comments'] = comments;
data['taskStatusId'] = taskStatus?.id;
@ -211,8 +217,8 @@ class PlanPreventiveVisit {
// data['engSignature'] = engSignature;
// data['nurseSignature'] = nurseSignature;
if (preventiveVisitAttachments != null) {
data['preventiveVisitAttachments'] = preventiveVisitAttachments!.map((v) => v.toJson()).toList();
}
if (preventiveVisitCalibrations != null) {
@ -354,7 +360,7 @@ class PlanPreventiveVisit {
// PlanPreventiveVisit.fromJson(Map<String, dynamic> json) {
// id = json['id'];
// visitNo = json['visitNo'];
// asset = json['asset'] != null ? new Asset.fromJson(json['asset']) : null;
// asset = json['asset'] != null ? Asset.fromJson(json['asset']) : null;
// planNo = json['planNo'];
// planName = json['planName'];
// nextPMDate = json['nextPMDate'];
@ -369,10 +375,10 @@ class PlanPreventiveVisit {
// roomName = json['roomName'];
// fromDate = json['fromDate'];
// toDate = json['toDate'];
// assignedEmployee = json['assignedEmployee'] != null ? new AssignedEmployee.fromJson(json['assignedEmployee']) : null;
// assignedEmployee = json['assignedEmployee'] != null ? AssignedEmployee.fromJson(json['assignedEmployee']) : null;
// acutalDateOfVisit = json['acutalDateOfVisit'];
// typeOfService = json['typeOfService'] != null ? new TypeOfService.fromJson(json['typeOfService']) : null;
// visitStatus = json['visitStatus'] != null ? new VisitStatus.fromJson(json['visitStatus']) : null;
// typeOfService = json['typeOfService'] != null ? TypeOfService.fromJson(json['typeOfService']) : null;
// visitStatus = json['visitStatus'] != null ? VisitStatus.fromJson(json['visitStatus']) : null;
// travelingHours = json['travelingHours'];
// comments = json['comments'];
// executionTimeFrame = json['executionTimeFrame'];
@ -391,37 +397,37 @@ class PlanPreventiveVisit {
// if (json['preventiveVisitCalibrations'] != null) {
// preventiveVisitCalibrations = <PreventiveVisitChecklists>[];
// json['preventiveVisitCalibrations'].forEach((v) {
// preventiveVisitCalibrations!.add(new PreventiveVisitChecklists.fromJson(v));
// preventiveVisitCalibrations!.add( PreventiveVisitChecklists.fromJson(v));
// });
// }
// if (json['preventiveVisitChecklists'] != null) {
// preventiveVisitChecklists = <PreventiveVisitChecklists>[];
// json['preventiveVisitChecklists'].forEach((v) {
// preventiveVisitChecklists!.add(new PreventiveVisitChecklists.fromJson(v));
// preventiveVisitChecklists!.add( PreventiveVisitChecklists.fromJson(v));
// });
// }
// if (json['preventiveVisitKits'] != null) {
// preventiveVisitKits = <PreventiveVisitChecklists>[];
// json['preventiveVisitKits'].forEach((v) {
// preventiveVisitKits!.add(new PreventiveVisitChecklists.fromJson(v));
// preventiveVisitKits!.add( PreventiveVisitChecklists.fromJson(v));
// });
// }
// if (json['preventiveVisitTimers'] != null) {
// preventiveVisitTimers = <PreventiveVisitTimers>[];
// json['preventiveVisitTimers'].forEach((v) {
// preventiveVisitTimers!.add(new PreventiveVisitTimers.fromJson(v));
// preventiveVisitTimers!.add( PreventiveVisitTimers.fromJson(v));
// });
// }
// if (json['preventiveVisitSuppliers'] != null) {
// preventiveVisitSuppliers = <PreventiveVisitChecklists>[];
// json['preventiveVisitSuppliers'].forEach((v) {
// preventiveVisitSuppliers!.add(new PreventiveVisitChecklists.fromJson(v));
// preventiveVisitSuppliers!.add( PreventiveVisitChecklists.fromJson(v));
// });
// }
// }
//
// Map<String, dynamic> toJson() {
// final Map<String, dynamic> data = new Map<String, dynamic>();
// final Map<String, dynamic> data = Map<String, dynamic>();
// data['id'] = this.id;
// data['visitNo'] = this.visitNo;
// if (this.asset != null) {
@ -536,7 +542,7 @@ class Asset {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
final Map<String, dynamic> data = Map<String, dynamic>();
data['id'] = this.id;
data['assetNumber'] = this.assetNumber;
data['assetSerialNo'] = this.assetSerialNo;
@ -562,7 +568,7 @@ class AssignedEmployee {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
final Map<String, dynamic> data = Map<String, dynamic>();
data['userId'] = this.userId;
data['userName'] = this.userName;
data['email'] = this.email;
@ -586,7 +592,7 @@ class AssignedEmployee {
// }
//
// Map<String, dynamic> toJson() {
// final Map<String, dynamic> data = new Map<String, dynamic>();
// final Map<String, dynamic> data = Map<String, dynamic>();
// data['id'] = this.id;
// data['name'] = this.name;
// data['value'] = this.value;
@ -608,7 +614,7 @@ class AssignedEmployee {
// }
//
// Map<String, dynamic> toJson() {
// final Map<String, dynamic> data = new Map<String, dynamic>();
// final Map<String, dynamic> data = Map<String, dynamic>();
// data['id'] = this.id;
// data['name'] = this.name;
// data['value'] = this.value;
@ -627,21 +633,21 @@ class PreventiveVisitChecklists {
PreventiveVisitChecklists.fromJson(Map<String, dynamic> json) {
id = json['id'];
taskStatus = json['taskStatus'] != null ? Lookup.fromJson(json['taskStatus']) : null;
taskStatus = json['taskStatus'] != null ? Lookup.fromJson(json['taskStatus']) : null;
taskComment = json['taskComment'];
measuredValue = json['measuredValue'];
instructionText = json['instructionText'] != null ? InstructionText.fromJson(json['instructionText']) : null;
instructionText = json['instructionText'] != null ? InstructionText.fromJson(json['instructionText']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['taskStatus'] = this.taskStatus?.toJson();
data['taskComment'] = this.taskComment;
data['measuredValue'] = this.measuredValue;
if (this.instructionText != null) {
data['instructionText'] = this.instructionText!.toJson();
}
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['taskStatusId'] = taskStatus?.id;
data['taskComment'] = taskComment;
data['measuredValue'] = measuredValue;
// if (instructionText != null) {
// data['instructionText'] = instructionText!.toJson();
// }
return data;
}
}
@ -658,9 +664,9 @@ class InstructionText {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['text'] = this.text;
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['text'] = text;
return data;
}
}
@ -702,7 +708,7 @@ class PreventiveVisitAttachments {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['attachmentName'] = attachmentName;
return data;
@ -718,15 +724,16 @@ class PreventiveVisitCalibrations {
PreventiveVisitCalibrations.fromJson(Map<String, dynamic> json) {
id = json['id'];
asset = json['asset'] != null ? Asset.fromJson(json['asset']) : null;
asset = json['asset'] != null ? Asset.fromJson(json['asset']) : null;
calibrationDateOfTesters = json['calibrationDateOfTesters'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
if (asset != null) {
data['asset'] = asset!.toJson();
// data['asset'] = asset!.toJson();
data['assetId'] = asset?.id;
}
data['calibrationDateOfTesters'] = calibrationDateOfTesters;
return data;
@ -737,18 +744,19 @@ class PreventiveVisitSuppliers {
int? id;
SupplierDetails? supplier;
SuppPersons? suppPerson;
String? startDateTime;
String? endDateTime;
DateTime? startDateTime;
DateTime? endDateTime;
TextEditingController? workingHoursController;
num? workingHours;
PreventiveVisitSuppliers({this.id, this.supplier, this.suppPerson, this.startDateTime, this.endDateTime, this.workingHours});
PreventiveVisitSuppliers({this.id, this.supplier, this.suppPerson, this.startDateTime, this.endDateTime, this.workingHours, this.workingHoursController});
PreventiveVisitSuppliers.fromJson(Map<String, dynamic> json) {
id = json['id'];
supplier = json['supplier'] != null ? SupplierDetails.fromJson(json['supplier']) : null;
suppPerson = json['suppPerson'] != null ? SuppPersons.fromJson(json['suppPerson']) : null;
startDateTime = json['startDateTime'];
endDateTime = json['endDateTime'];
supplier = json['supplier'] != null ? SupplierDetails.fromJson(json['supplier']) : null;
suppPerson = json['suppPerson'] != null ? SuppPersons.fromJson(json['suppPerson']) : null;
startDateTime = json['startDateTime'] != null ? DateTime.parse(json['startDateTime']) : null;
endDateTime = json['endDateTime'] != null ? DateTime.parse(json['endDateTime']) : null;
workingHours = json['workingHours'];
}
@ -756,13 +764,15 @@ class PreventiveVisitSuppliers {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
if (supplier != null) {
data['supplier'] = supplier!.toJson();
// data['supplier'] = supplier!.toJson();
data['supplierId'] = supplier?.id;
}
if (suppPerson != null) {
data['suppPerson'] = suppPerson!.toJson();
// data['suppPerson'] = suppPerson!.toJson();
data['suppPersonId'] = suppPerson?.id;
}
data['startDateTime'] = startDateTime;
data['endDateTime'] = endDateTime;
data['startDateTime'] = startDateTime?.toIso8601String();
data['endDateTime'] = endDateTime?.toIso8601String();
data['workingHours'] = workingHours;
return data;
}
@ -851,7 +861,7 @@ class Supplier {
if (json['suppPersons'] != null) {
suppPersons = <SuppPersons>[];
json['suppPersons'].forEach((v) {
suppPersons!.add(new SuppPersons.fromJson(v));
suppPersons!.add(SuppPersons.fromJson(v));
});
}
if (json['suppTCodes'] != null) {
@ -863,7 +873,7 @@ class Supplier {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['suppliername'] = suppliername;
data['name'] = name;
@ -921,7 +931,7 @@ class Supplier {
// }
//
// Map<String, dynamic> toJson() {
// final Map<String, dynamic> data = new Map<String, dynamic>();
// final Map<String, dynamic> data = Map<String, dynamic>();
// data['id'] = this.id;
// data['supplierId'] = this.supplierId;
// data['personName'] = this.personName;
@ -941,14 +951,15 @@ class PreventiveVisitKits {
PreventiveVisitKits.fromJson(Map<String, dynamic> json) {
id = json['id'];
partCatalogItem = json['partCatalogItem'] != null ? new PartCatalogItem.fromJson(json['partCatalogItem']) : null;
partCatalogItem = json['partCatalogItem'] != null ? PartCatalogItem.fromJson(json['partCatalogItem']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
final Map<String, dynamic> data = Map<String, dynamic>();
data['id'] = id;
if (partCatalogItem != null) {
data['partCatalogItem'] = partCatalogItem!.toJson();
// data['partCatalogItem'] = partCatalogItem!.toJson();
data['partCatalogItemId'] = partCatalogItem?.id;
}
return data;
}
@ -970,7 +981,7 @@ class PartCatalogItem {
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['partName'] = partName;
data['partNumber'] = partNumber;

@ -37,6 +37,10 @@ class ServiceRequestUtils {
return -1; // Indicating invalid input
}
}
static bool isLocalUrl(String url) {
if (url.isEmpty != false) return false;
return url.startsWith("/") || url.startsWith("file://") || url.substring(1).startsWith(':\\');
}
static String calculateTimeDifference(DateTime startDate, DateTime endDate) {
try {

@ -38,6 +38,7 @@ class _PpmDetailsPageState extends State<PpmDetailsPage> {
@override
void initState() {
getVisitData();
super.initState();
}
@ -46,22 +47,24 @@ class _PpmDetailsPageState extends State<PpmDetailsPage> {
super.dispose();
}
Future<void> getVisitData() async {
ppmProvider = Provider.of<PpmProvider>(context, listen: false);
await ppmProvider?.getPlanPreventiveVisitById(widget.request.id!);
}
@override
Widget build(BuildContext context) {
userProvider ??= Provider.of<UserProvider>(context, listen: false);
ppmProvider ??= Provider.of<PpmProvider>(context, listen: false);
ppmProvider!.getPlanPreventiveVisitById(widget.request.id!);
// ppmProvider ??= Provider.of<PpmProvider>(context, listen: false);
// ppmProvider!.getPlanPreventiveVisitById(widget.request.id!);
return Scaffold(
appBar: DefaultAppBar(title: context.translation.preventiveMaintenance),
body: SafeArea(
child: FutureBuilder(
future: ppmProvider!.getPlanPreventiveVisitById(widget.request.id!),
builder: (context, snap) {
if (snap.connectionState == ConnectionState.waiting) {
return const ALoading();
} else if (snap.hasData) {
PlanPreventiveVisit planPreventiveVisit = snap.data as PlanPreventiveVisit;
return Column(children: [
child: Consumer<PpmProvider>(builder: (context, ppmProvider, child) {
PlanPreventiveVisit? planPreventiveVisit = ppmProvider.planPreventiveVisit;
return ppmProvider.isLoading
? const ALoading()
: Column(children: [
SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
@ -76,8 +79,8 @@ class _PpmDetailsPageState extends State<PpmDetailsPage> {
),
if (widget.request.priority != null) 8.width,
StatusLabel(
label: planPreventiveVisit.visitStatus!.name!,
id: planPreventiveVisit.visitStatus!.id!,
label: planPreventiveVisit?.visitStatus!.name!,
id: planPreventiveVisit!.visitStatus!.id!,
textColor: AppColor.getRequestStatusTextColorByName(context, planPreventiveVisit.visitStatus!.name!),
backgroundColor: AppColor.getRequestStatusColorByName(context, planPreventiveVisit.visitStatus!.name!),
),
@ -92,7 +95,7 @@ class _PpmDetailsPageState extends State<PpmDetailsPage> {
'${context.translation.requestNo}: ${planPreventiveVisit.visitNo}'.bodyText(context),
const Divider().defaultStyle(context),
// '${context.translation.expectDate}: ${planPreventiveVisit.expectedDate?.toAssetDetailsFormat ?? ""}'.bodyText(context), //todo @baha,
'${context.translation.actualDate}: ${planPreventiveVisit.acutalDateOfVisit?.toAssetDetailsFormat ?? ""}'.bodyText(context), //todo @baha,
'${context.translation.actualDate}: ${planPreventiveVisit.acutalDateOfVisit?.toIso8601String().toAssetDetailsFormat ?? ""}'.bodyText(context), //todo @baha,
const Divider().defaultStyle(context),
'${context.translation.engineerName}: ${planPreventiveVisit.assignedEmployee?.userName ?? ""}'.bodyText(context), //todo @baha,
'${context.translation.site}: ${planPreventiveVisit.siteName?.cleanupWhitespace.capitalizeFirstOfEach}'.bodyText(context), //todo @baha,
@ -106,17 +109,12 @@ class _PpmDetailsPageState extends State<PpmDetailsPage> {
if (userProvider!.user!.type == UsersTypes.engineer && (planPreventiveVisit.visitStatus!.id! != 270 && planPreventiveVisit.visitStatus!.id! != 269))
AppFilledButton(
onPressed: () async {
//TODO remove after testing..
await Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdatePpm(ppm: null, planPreventiveVisit: planPreventiveVisit, details: widget.request)));
// setState(() {});
},
label: context.translation.updateRequest,
).paddingAll(16)
]);
}
return NoDataFound(message: context.translation.noDataFound).center;
}),
}),
),
);
}

@ -1,36 +1,297 @@
// 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/string_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/plan_preventive_visit/plan_preventive_visit_model.dart';
// import 'package:test_sa/models/ppm/ppm_calibration_tools.dart';
// import 'package:test_sa/models/service_request/supplier_details.dart';
// import 'package:test_sa/new_views/common_widgets/app_filled_button.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/loading_list_notifier.dart';
// import 'package:test_sa/providers/ppm_service_provider.dart';
// import 'package:test_sa/providers/work_order/vendor_provider.dart';
// import 'package:test_sa/service_request_latest/utilities/service_request_utils.dart';
// import 'package:test_sa/views/widgets/pentry/calibration_tool_asset_picker.dart';
//
// import '../../../../../new_views/app_style/app_color.dart';
// import '../../../../widgets/date_and_time/date_picker.dart';
//
// class PpmExternalDetailsForm extends StatefulWidget {
// final List<PreventiveVisitSuppliers>? models;
//
// const PpmExternalDetailsForm({Key? key, this.models = const <PreventiveVisitSuppliers>[]}) : super(key: key);
//
// @override
// State<PpmExternalDetailsForm> createState() => _PpmExternalDetailsFormState();
// }
//
// class _PpmExternalDetailsFormState extends State<PpmExternalDetailsForm> {
// final TextEditingController _workingHoursController = TextEditingController();
//
// @override
// Widget build(BuildContext context) {
// return ListView.builder(
// itemCount: widget.models!.length + 1,
// padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 16),
// itemBuilder: (context, index) {
// if (index == widget.models!.length) {
// return AppFilledButton(
// label: "Add More External Details".addTranslation,
// maxWidth: true,
// textColor: AppColor.black10,
// buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10,
// icon: Icon(Icons.add_circle, color: AppColor.blueStatus(context)),
// showIcon: true,
// 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(() {});
// },
// );
// }
// final model = widget.models![index];
// // _workingHoursController.text = model.workingHours != null ? model.workingHours.toString() : '';
// return Container(
// padding: const EdgeInsets.all(16),
// margin: EdgeInsets.only(bottom: 16.toScreenHeight),
// decoration: BoxDecoration(
// color: AppColor.background(context),
// borderRadius: BorderRadius.circular(20),
// boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)],
// ),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// (index == 0 ? "1 /4 . External Details" : "").heading5(context),
// "trash".toSvgAsset(height: 20, width: 15).onPress(() {
// widget.models!.remove(model);
//
// setState(() {});
// }),
// ],
// ),
// 16.height,
// SingleItemDropDownMenu<SupplierDetails, VendorProvider>(
// context: context,
// title: context.translation.supplier,
// initialValue: model.supplier,
// backgroundColor: AppColor.neutral100,
// showAsBottomSheet: true,
// onSelect: (supplier) {
// if (supplier != null) {
// model.supplier = supplier;
// print('supplier dtails is ${supplier.toJson()}');
// setState(() {});
// }
// },
// ),
// 8.height,
// SingleItemDropDownMenu<SuppPersons, NullableLoadingProvider>(
// context: context,
// title: context.translation.supplierEngineer,
// enabled: model.suppPerson != null,
// backgroundColor: AppColor.neutral100,
// initialValue: model.suppPerson,
// staticData: model.supplier?.suppPersons,
// showAsBottomSheet: true,
// onSelect: (suppPerson) {
// if (suppPerson != null) {
// model.suppPerson = suppPerson;
// print('supply person is ${model.suppPerson?.toJson()}');
// }
// },
// ),
// 8.height,
// AppTextFormField(
// labelText: "Telephone",
// initialValue: model.supplier?.telephones != null && model.supplier!.telephones!.isNotEmpty ? (model.supplier?.telephones?[0].telephone ?? "").toString() : '',
// textAlign: TextAlign.center,
// backgroundColor: AppColor.neutral100,
// style: Theme.of(context).textTheme.titleMedium,
// textInputType: TextInputType.number,
// onChange: (value) {
// model.supplier?.telephones?[0].telephone = value;
// },
// ),
// 8.height,
// Row(
// mainAxisSize: MainAxisSize.min,
// children: [
// ADatePicker(
// label: context.translation.startTime,
// hideShadow: true,
// backgroundColor: AppColor.neutral100,
// date: model.startDateTime,
// formatDateWithTime: true,
// onDatePicker: (selectedDate) {
// showTimePicker(
// context: context,
// initialTime: TimeOfDay.now(),
// ).then((selectedTime) {
// // Handle the selected date and time here.
// if (selectedTime != null) {
// DateTime selectedDateTime = DateTime(
// selectedDate.year,
// selectedDate.month,
// selectedDate.day,
// selectedTime.hour,
// selectedTime.minute,
// );
// setState(() {
// model.startDateTime = selectedDateTime;
// });
// model.endDateTime = null;
// _workingHoursController.clear();
// ServiceRequestUtils.calculateAndAssignWorkingHours(
// startTime: model.startDateTime,
// endTime: model.endDateTime,
// workingHoursController: _workingHoursController,
// updateModel: (hours) {
// model.workingHours = hours;
// },
// );
// }
// });
// },
// ).expanded,
// 8.width,
// ADatePicker(
// label: context.translation.endTime,
// hideShadow: true,
// backgroundColor: AppColor.neutral100,
// date: model.endDateTime,
// formatDateWithTime: true,
// onDatePicker: (selectedDate) {
// showTimePicker(
// context: context,
// initialTime: TimeOfDay.now(),
// ).then((selectedTime) {
// // Handle the selected date and time here.
// if (selectedTime != null) {
// DateTime selectedDateTime = DateTime(
// selectedDate.year,
// selectedDate.month,
// selectedDate.day,
// selectedTime.hour,
// selectedTime.minute,
// );
// if (model.startDateTime != null && selectedDateTime.isBefore(model.startDateTime!)) {
// "End Date time must be greater then start date".showToast;
// return;
// }
// model.endDateTime = selectedDateTime;
// setState(() {});
// ServiceRequestUtils.calculateAndAssignWorkingHours(
// startTime: model.startDateTime,
// endTime: model.endDateTime,
// workingHoursController: _workingHoursController,
// updateModel: (hours) {
// model.workingHours = hours;
// },
// );
// }
// });
// },
// ).expanded,
// ],
// ),
// 8.height,
// AppTextFormField(
// labelText: context.translation.workingHours,
// backgroundColor: AppColor.neutral80,
// controller: _workingHoursController,
// suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
// // initialValue: model.workingHours != null ? model.workingHours.toString() : '',
// textAlign: TextAlign.center,
// labelStyle: AppTextStyles.textFieldLabelStyle,
// enable: false,
// showShadow: false,
// style: Theme.of(context).textTheme.titleMedium,
// ),
// 8.height,
// ],
// ),
// );
// },
// );
// }
// }
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/string_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/ppm/ppm_calibration_tools.dart';
import 'package:test_sa/models/plan_preventive_visit/plan_preventive_visit_model.dart';
import 'package:test_sa/models/service_request/supplier_details.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/views/widgets/pentry/calibration_tool_asset_picker.dart';
import '../../../../../new_views/app_style/app_color.dart';
import '../../../../widgets/date_and_time/date_picker.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/loading_list_notifier.dart';
import 'package:test_sa/providers/work_order/vendor_provider.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/service_request_latest/utilities/service_request_utils.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/loaders/app_loading.dart';
class PpmExternalDetailsForm extends StatefulWidget {
final List<PpmCalibrationTools>? models;
final List<PreventiveVisitSuppliers>? models;
const PpmExternalDetailsForm({Key? key, this.models = const <PpmCalibrationTools>[]}) : super(key: key);
const PpmExternalDetailsForm({Key? key, this.models = const <PreventiveVisitSuppliers>[]}) : super(key: key);
@override
State<PpmExternalDetailsForm> createState() => _PpmExternalDetailsFormState();
}
class _PpmExternalDetailsFormState extends State<PpmExternalDetailsForm> {
bool isLoading = false;
//TODO add loader when adding or deleting item..
void _addNewEntry() {
setState(() {
// isLoading = true;
widget.models!.add(PreventiveVisitSuppliers(id: 0));
// Future.delayed(Duration(seconds: 1)).whenComplete(() {
// setState(() {
// isLoading = false;
// });
// });
});
}
void _removeEntry(int index) {
setState(() {
isLoading = true;
widget.models!.removeAt(index);
// isLoading = false;
});
}
@override
Widget build(BuildContext context) {
final userProvider = Provider.of<UserProvider>(context);
return ListView.builder(
itemCount: widget.models!.length + 1,
padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 16),
padding: const EdgeInsets.all(16),
itemBuilder: (context, index) {
if (index == widget.models!.length) {
return AppFilledButton(
@ -40,70 +301,193 @@ class _PpmExternalDetailsFormState extends State<PpmExternalDetailsForm> {
buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10,
icon: Icon(Icons.add_circle, color: AppColor.blueStatus(context)),
showIcon: true,
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(() {});
},
onPressed: _addNewEntry,
);
}
final model = widget.models![index];
return Container(
padding: const EdgeInsets.all(16),
margin: EdgeInsets.only(bottom: 16.toScreenHeight),
decoration: BoxDecoration(
color: AppColor.background(context),
borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)],
// return !isLoading
// ?
return ExternalDetailItem(
model: widget.models![index],
index: index,
onRemove: () => _removeEntry(index),
);
// : const ALoading();
},
);
}
}
class ExternalDetailItem extends StatefulWidget {
final PreventiveVisitSuppliers model;
final VoidCallback onRemove;
final int index;
const ExternalDetailItem({
Key? key,
required this.model,
required this.onRemove,
required this.index,
}) : super(key: key);
@override
State<ExternalDetailItem> createState() => _ExternalDetailItemState();
}
class _ExternalDetailItemState extends State<ExternalDetailItem> {
TextEditingController? controller;
@override
void initState() {
controller = TextEditingController(text: widget.model.workingHours != null ? widget.model.workingHours.toString() : '');
super.initState();
}
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(16),
margin: EdgeInsets.only(bottom: 16.toScreenHeight),
decoration: BoxDecoration(
color: AppColor.background(context),
borderRadius: BorderRadius.circular(20),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.03), blurRadius: 14)],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
(widget.index == 0 ? "1 /4 . External Details" : "").heading5(context),
"trash".toSvgAsset(height: 20, width: 15).onPress(() {
widget.onRemove();
}),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
16.height,
SingleItemDropDownMenu<SupplierDetails, VendorProvider>(
context: context,
title: context.translation.supplier,
initialValue: widget.model.supplier,
backgroundColor: AppColor.neutral100,
showAsBottomSheet: true,
onSelect: (supplier) {
if (supplier != null) {
setState(() {
widget.model.supplier = supplier;
});
}
},
),
8.height,
SingleItemDropDownMenu<SuppPersons, NullableLoadingProvider>(
context: context,
title: context.translation.supplierEngineer,
enabled: widget.model.supplier != null,
backgroundColor: AppColor.neutral100,
initialValue: widget.model.suppPerson,
staticData: widget.model.supplier?.suppPersons,
showAsBottomSheet: true,
onSelect: (suppPerson) {
if (suppPerson != null) {
widget.model.suppPerson = suppPerson;
}
},
),
8.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
(index == 0 ? "1 /4 . External Details" : "").heading5(context),
"trash".toSvgAsset(height: 20, width: 15).onPress(() {
widget.models!.remove(model);
setState(() {});
}),
],
),
16.height,
CalibrationToolAssetPicker(
initialValue: model.assetId == null ? null : Lookup(id: model.assetId?.toInt(), name: model.assetNumber ?? ""),
hospitalId: userProvider.user!.clientId,
onPick: (number) {
model.assetNumber = number.assetNumber;
model.assetId = number.id;
setState(() {});
ADatePicker(
label: context.translation.startTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: widget.model.startDateTime,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
setState(() {
widget.model.startDateTime = selectedDateTime;
});
widget.model.endDateTime = null;
controller?.clear();
ServiceRequestUtils.calculateAndAssignWorkingHours(
startTime: widget.model.startDateTime,
endTime: widget.model.endDateTime,
workingHoursController: controller!,
updateModel: (hours) {
widget.model.workingHours = hours;
},
);
}
});
},
),
8.height,
).expanded,
8.width,
ADatePicker(
label: context.translation.calibrationDate,
date: DateTime.tryParse(model.calibrationDateOfTesters ?? ""),
from: DateTime.now().subtract(const Duration(days: 90)),
backgroundColor: context.isDark ? AppColor.neutral50 : AppColor.background(context),
withBorder: false,
onDatePicker: (date) {
model.calibrationDateOfTesters = date.toIso8601String();
setState(() {});
label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: widget.model.endDateTime,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
if (widget.model.startDateTime != null && selectedDateTime.isBefore(widget.model.startDateTime!)) {
"End Date time must be greater than start date".showToast;
return;
}
setState(() {
widget.model.endDateTime = selectedDateTime;
});
ServiceRequestUtils.calculateAndAssignWorkingHours(
startTime: widget.model.startDateTime,
endTime: widget.model.endDateTime,
workingHoursController: controller!,
updateModel: (hours) {
widget.model.workingHours = hours;
},
);
}
});
},
),
).expanded,
],
),
);
},
8.height,
AppTextFormField(
labelText: context.translation.workingHours,
backgroundColor: AppColor.neutral80,
controller: controller,
textAlign: TextAlign.center,
enable: false,
showShadow: false,
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
],
),
);
}
}

@ -1,7 +1,9 @@
import 'dart:convert';
import 'dart:developer';
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/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart';
@ -11,7 +13,9 @@ import 'package:test_sa/models/plan_preventive_visit/plan_preventive_visit_model
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/app_lazy_loading.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/service_request_latest/utilities/service_request_utils.dart';
import 'package:test_sa/views/pages/user/ppm/update_ppm/ppm_external_details_form.dart';
import '../../../../../extensions/text_extensions.dart';
@ -32,30 +36,37 @@ class UpdatePpm extends StatefulWidget {
}
class _UpdatePpmState extends State<UpdatePpm> with SingleTickerProviderStateMixin {
late UserProvider _userProvider;
late PpmProvider _regularVisitsProvider;
Ppm? _ppm;
late PlanPreventiveVisit _planPreventiveVisit;
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
late TabController _tabController;
late PpmProvider ppmProvider;
_onSubmit({required int status}) async {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
ppmProvider.planPreventiveVisit?.preventiveVisitAttachments = [];
for (var item in ppmProvider.ppmPlanAttachments) {
ppmProvider.planPreventiveVisit?.preventiveVisitAttachments
?.add(PreventiveVisitAttachments(id: 0, attachmentName: ServiceRequestUtils.isLocalUrl(item.path) ? "${item.path.split("/").last}|${base64Encode(item.readAsBytesSync())}" : item.path));
}
log('data i got is ${ppmProvider.planPreventiveVisit?.toJson(status: status)}');
_onSubmit() async {
// if (!(await _ppm.validate(context))) {
// setState(() {});
// return;
// }
// _ppm.removeEmptyObjects();
// await _regularVisitsProvider.updatePentry(context, user: _userProvider.user!, ppm: widget.ppm);
await ppmProvider.updateVisitByEngineer(status: status).whenComplete((){
// if(status==1){// when click complete then this request remove from the list and status changes to closed..
//
// }
// allRequestsProvider.recurrentWoData?.recurrentWoTimerModel=null;
Navigator.pop(context);
Navigator.pop(context);
});
}
@override
void initState() {
_ppm = widget.ppm;
ppmProvider = Provider.of<PpmProvider>(context, listen: false);
_planPreventiveVisit = widget.planPreventiveVisit;
_tabController = TabController(length: 3, vsync: this);
_tabController = TabController(length: ppmProvider.totalTabs, vsync: this);
super.initState();
}
@ -69,8 +80,6 @@ class _UpdatePpmState extends State<UpdatePpm> with SingleTickerProviderStateMix
@override
Widget build(BuildContext context) {
_userProvider = Provider.of<UserProvider>(context, listen: false);
_regularVisitsProvider = Provider.of<PpmProvider>(context, listen: false);
return Scaffold(
backgroundColor: AppColor.neutral110,
appBar: DefaultAppBar(title: context.translation.preventiveMaintenance),
@ -122,13 +131,11 @@ class _UpdatePpmState extends State<UpdatePpm> with SingleTickerProviderStateMix
physics: const NeverScrollableScrollPhysics(),
controller: _tabController,
children: [
// PpmExternalDetailsForm(models: []),
if (ppmProvider.totalTabs == 4) ...[
PpmExternalDetailsForm(models: _planPreventiveVisit.preventiveVisitSuppliers),
],
PpmCalibrationToolsForm(models: _planPreventiveVisit.preventiveVisitCalibrations),
PpmPMKitsForm(models: _planPreventiveVisit.preventiveVisitKits,assetId: _planPreventiveVisit.asset?.id),
// PpmExternalDetailsForm(models: _ppm.vCalibrationTools),
// PpmCalibrationToolsForm(models: _ppm.vCalibrationTools),
// PpmPMKitsForm(models: _ppm.vKits, assetId: widget.ppm.assetId),
PpmPMKitsForm(models: _planPreventiveVisit.preventiveVisitKits, assetId: _planPreventiveVisit.asset?.id),
PpmPmChecklistForm(checkList: _planPreventiveVisit.preventiveVisitChecklists),
],
)
@ -143,18 +150,20 @@ class _UpdatePpmState extends State<UpdatePpm> with SingleTickerProviderStateMix
buttonColor: AppColor.white60,
textColor: AppColor.neutral50,
onPressed: () {
_onSubmit();
_onSubmit(status: 0);
},
label: context.translation.save,
).expanded,
16.width,
AppFilledButton(
onPressed: () {
if (tabIndex == 0) {
_onSubmit(status: 1);
return;
}
if (_tabController.index == 3) {
_onSubmit();
_onSubmit(status: 1);
} else {
_tabController.animateTo(_tabController.index + 1);
setState(() {});

@ -1,25 +1,27 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:provider/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/plan_preventive_visit/plan_preventive_visit_model.dart';
import 'package:test_sa/models/service_request/supplier_details.dart';
import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/providers/ppm_asset_availability_provider.dart';
import 'package:test_sa/providers/ppm_electrical_safety_provider.dart';
import 'package:test_sa/providers/ppm_service_provider.dart';
import 'package:test_sa/providers/ppm_task_status_provider.dart';
import 'package:test_sa/providers/work_order/vendor_provider.dart';
import 'package:test_sa/service_request_latest/utilities/service_request_utils.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/e_signature/e_signature.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/requests/request_status.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_visit_status_provider.dart';
import '../../../../widgets/date_and_time/date_picker.dart';
import '../../../../widgets/timer/app_timer.dart';
class WoInfoForm extends StatefulWidget {
@ -33,383 +35,331 @@ class WoInfoForm extends StatefulWidget {
}
class _WoInfoFormState extends State<WoInfoForm> {
SupplierDetails? initialSupplier;
SuppPersons? _suppPerson;
//TODO need to move this to provider ...
@override
void initState() {
// TODO need to use model attributes directly no need to assign to new variable. when confirm from backend we need one or multiple suppliers.
if (widget.planPreventiveVisit.preventiveVisitSuppliers != null && widget.planPreventiveVisit.preventiveVisitSuppliers!.isNotEmpty) {
initialSupplier = SupplierDetails.fromJson(widget.planPreventiveVisit.preventiveVisitSuppliers?[0].supplier?.toJson());
_suppPerson = SuppPersons.fromJson(widget.planPreventiveVisit.preventiveVisitSuppliers?[0].suppPerson?.toJson());
}
WidgetsBinding.instance.addPostFrameCallback((_) async {
PpmProvider ppmProvider = Provider.of<PpmProvider>(context, listen: false);
if (widget.planPreventiveVisit.preventiveVisitAttachments != null && widget.planPreventiveVisit.preventiveVisitAttachments!.isNotEmpty) {
ppmProvider.ppmPlanAttachments = [];
ppmProvider.ppmPlanAttachments.addAll(widget.planPreventiveVisit.preventiveVisitAttachments!.map((e) => File(e.attachmentName!)).toList());
}
});
super.initState();
}
@override
Widget build(BuildContext context) {
// widget.planPreventiveVisit ??= [];
// widget.planPreventiveVisit.files = (widget.model.files ?? []).where((element) => element.attachmentName?.isNotEmpty ?? false).toList();
double totalWorkingHours =
widget.planPreventiveVisit.preventiveVisitTimers?.fold(0.0, (sum, item) => (sum ?? 0) + DateTime.parse(item.endDateTime!).difference(DateTime.parse(item.startDateTime!)).inSeconds) ?? 0;
totalWorkingHours = totalWorkingHours;
return ListView(
padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 16),
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (widget.planPreventiveVisit.visitStatus != null)
StatusLabel(
label: widget.planPreventiveVisit.visitStatus?.name,
textColor: AppColor.getRequestStatusTextColorByName(context, widget.planPreventiveVisit.visitStatus?.name),
backgroundColor: AppColor.getRequestStatusColorByName(context, widget.planPreventiveVisit.visitStatus?.name),
return Consumer<PpmProvider>(builder: (context, ppmProvider, child) {
return ListView(
padding: const EdgeInsets.only(left: 16, right: 16, top: 8, bottom: 16),
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (widget.planPreventiveVisit.visitStatus != null)
StatusLabel(
label: widget.planPreventiveVisit.visitStatus?.name,
textColor: AppColor.getRequestStatusTextColorByName(context, widget.planPreventiveVisit.visitStatus?.name),
backgroundColor: AppColor.getRequestStatusColorByName(context, widget.planPreventiveVisit.visitStatus?.name),
),
8.height,
widget.planPreventiveVisit.planName!.bodyText(context).custom(color: AppColor.black10),
2.height,
'${context.translation.pmPlanNo}: ${widget.planPreventiveVisit.planNo}'.bodyText2(context).custom(color: AppColor.neutral120),
//need to add in translation it's suggestion from ahmed..
'Work Order Number: ${widget.planPreventiveVisit.visitNo}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.from}: ${widget.planPreventiveVisit.fromDate?.toMonthYearFormat}'
.bodyText2(context)
.custom(color: AppColor.neutral120),
'${context.translation.to}: ${widget.planPreventiveVisit.toDate?.toMonthYearFormat}'
.bodyText2(context)
.custom(color: AppColor.neutral120),
'${context.translation.nextPmDate}: ${widget.planPreventiveVisit.nextPMDate != null ? widget.planPreventiveVisit.nextPMDate!.toMonthYearFormat : '-'}'
.bodyText2(context)
.custom(color: AppColor.neutral120),
'${context.translation.assignEngineer}: ${widget.planPreventiveVisit.assignedEmployee?.userName ?? ""}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.executionTimeFrame}: ${widget.planPreventiveVisit.executionTimeFrame ?? ""} days'.bodyText2(context).custom(color: AppColor.neutral120),
],
).toShadowContainer(context),
12.height,
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
widget.planPreventiveVisit.assetName!.bodyText(context).custom(color: AppColor.black10),
"info_icon".toSvgAsset(height: 17, width: 17),
],
),
8.height,
widget.planPreventiveVisit.planName!.bodyText(context).custom(color: AppColor.black10),
2.height,
'${context.translation.pmPlanNo}: ${widget.planPreventiveVisit.planNo}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.nextPmDate}: ${widget.planPreventiveVisit.nextPMDate?.toMonthYearFormat}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.assignEngineer}: ${widget.planPreventiveVisit.assignedEmployee?.userName ?? ""}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.executionTimeFrame}: ${widget.planPreventiveVisit.executionTimeFrame ?? ""}'.bodyText2(context).custom(color: AppColor.neutral120),
],
).toShadowContainer(context),
12.height,
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
widget.planPreventiveVisit.assetName!.bodyText(context).custom(color: AppColor.black10),
"info_icon".toSvgAsset(height: 17, width: 17),
],
),
2.height,
'${context.translation.assetNo}: ${widget.planPreventiveVisit.asset?.assetNumber}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.model}: ${widget.planPreventiveVisit.model}'.bodyText2(context).custom(color: AppColor.neutral120),
],
).toShadowContainer(context),
2.height,
'${context.translation.assetNo}: ${widget.planPreventiveVisit.asset?.assetNumber}'.bodyText2(context).custom(color: AppColor.neutral120),
'${context.translation.model}: ${widget.planPreventiveVisit.model}'.bodyText2(context).custom(color: AppColor.neutral120),
],
).toShadowContainer(context),
// SingleItemDropDownMenu<Lookup, PPMVisitStatusProvider>(
// context: context,
// initialValue:
// widget.planPreventiveVisit.visitStatus?.id == null ? null : Lookup(name: widget.planPreventiveVisit.visitStatus?.name ?? "", id: widget.planPreventiveVisit.visitStatus?.id?.toInt()),
// title: context.translation.ppmVisit,
// onSelect: (value) {
// if (value?.value == 4) {
// "Status cannot be change to ${value?.name}.".addTranslation.showToast;
// setState(() {});
// return;
// }
//
// if (value != null) {
// widget.planPreventiveVisit.visitStatus?.name = value.name;
// widget.planPreventiveVisit.visitStatus?.id = value.id;
// }
// },
// ),
// SingleItemDropDownMenu<Lookup, PPMVisitStatusProvider>(
// context: context,
// initialValue:
// widget.planPreventiveVisit.visitStatus?.id == null ? null : Lookup(name: widget.planPreventiveVisit.visitStatus?.name ?? "", id: widget.planPreventiveVisit.visitStatus?.id?.toInt()),
// title: context.translation.ppmVisit,
// onSelect: (value) {
// if (value?.value == 4) {
// "Status cannot be change to ${value?.name}.".addTranslation.showToast;
// setState(() {});
// return;
// }
//
// if (value != null) {
// widget.planPreventiveVisit.visitStatus?.name = value.name;
// widget.planPreventiveVisit.visitStatus?.id = value.id;
// }
// },
// ),
// SingleItemDropDownMenu<Lookup, PPMDeviceStatusProvider>(
// context: context,
// initialValue: widget.planPreventiveVisit.deviceStatusId == null ? null : Lookup(name: widget.model.deviceStatusName ?? "", id: widget.model.deviceStatusId?.toInt()),
// title: context.translation.deviceStatus,
// onSelect: (value) {
// if (value != null) {
// widget.planPreventiveVisit.deviceStatusId = value.id;
// widget.planPreventiveVisit.deviceStatusName = value.name;
// }
// },
// ),
8.height,
SingleItemDropDownMenu<Lookup, PpmTaskStatusProvider>(
context: context,
initialValue: widget.planPreventiveVisit.taskStatus == null ? null : Lookup(name: widget.planPreventiveVisit.taskStatus?.name ?? "", id: widget.planPreventiveVisit.taskStatus?.id),
title: context.translation.taskStatus,
onSelect: (value) {
if (value != null) {
widget.planPreventiveVisit.taskStatus?.id = value.id;
widget.planPreventiveVisit.taskStatus?.name = value.name;
}
},
),
8.height,
SingleItemDropDownMenu<Lookup, PpmAssetAvailabilityProvider>(
context: context,
initialValue: widget.planPreventiveVisit.assetAvailability == null
? null
: Lookup(name: widget.planPreventiveVisit.assetAvailability?.name ?? "", id: widget.planPreventiveVisit.assetAvailability?.id),
title: "Asset Availability",
onSelect: (value) {
if (value != null) {
widget.planPreventiveVisit.assetAvailability?.id = value.id;
widget.planPreventiveVisit.assetAvailability?.name = value.name;
}
},
),
// SingleItemDropDownMenu<Lookup, PPMDeviceStatusProvider>(
// context: context,
// initialValue: widget.planPreventiveVisit.deviceStatusId == null ? null : Lookup(name: widget.model.deviceStatusName ?? "", id: widget.model.deviceStatusId?.toInt()),
// title: context.translation.deviceStatus,
// onSelect: (value) {
// if (value != null) {
// widget.planPreventiveVisit.deviceStatusId = value.id;
// widget.planPreventiveVisit.deviceStatusName = value.name;
// }
// },
// ),
8.height,
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
//TODO Ahmed need to provide look up value....
8.height,
SingleItemDropDownMenu<Lookup, PpmElectricalSafetyProvider>(
context: context,
initialValue: widget.planPreventiveVisit.safety?.id == null ? null : Lookup(name: widget.planPreventiveVisit.safety?.name ?? "", id: widget.planPreventiveVisit.safety?.id),
title: "Electrical Safety",
onSelect: (value) {
if (value != null) {
widget.planPreventiveVisit.safety?.id = value.id;
widget.planPreventiveVisit.safety?.name = value.name;
}
},
),
8.height,
SingleItemDropDownMenu<Lookup, PpmServiceProvider>(
context: context,
initialValue:
widget.planPreventiveVisit.typeOfService == null ? null : Lookup(name: widget.planPreventiveVisit.typeOfService?.name ?? "", id: widget.planPreventiveVisit.typeOfService?.id?.toInt()),
title: context.translation.serviceType,
onSelect: (value) {
if (value != null) {
widget.planPreventiveVisit.typeOfService?.id = value.id;
widget.planPreventiveVisit.typeOfService?.name = value.name;
//TODO check this why make all values null..
SingleItemDropDownMenu<Lookup, PpmTaskStatusProvider>(
context: context,
initialValue: widget.planPreventiveVisit.taskStatus == null ? null : Lookup(name: widget.planPreventiveVisit.taskStatus?.name ?? "", id: widget.planPreventiveVisit.taskStatus?.id),
title: context.translation.pmTestResult,
backgroundColor: AppColor.neutral100,
onSelect: (value) {
if (value != null) {
widget.planPreventiveVisit.taskStatus = value;
}
},
),
8.height,
ADatePicker(
label: context.translation.actualVisit,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: widget.planPreventiveVisit.acutalDateOfVisit,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
if (selectedTime != null) {
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
setState(() {
widget.planPreventiveVisit.acutalDateOfVisit = selectedDate;
});
// widget.planPreventiveVisit?.preventiveVisitSuppliers?. = null;
// widget.model.supplierName = null;
// initialSupplier = null;
// _suppPerson = null;
// widget.model.suppPersonId = null;
// widget.model.suppPerson = null;
}
});
},
),
// SingleItemDropDownMenu<Lookup, PpmElectricalSafetyProvider>(
// context: context,
// backgroundColor: AppColor.neutral100,
// initialValue: widget.planPreventiveVisit.safety?.id == null ? null : Lookup(name: widget.planPreventiveVisit.safety?.name ?? "", id: widget.planPreventiveVisit.safety?.id),
// title: context.translation.actualVisit,
// onSelect: (value) {
// if (value != null) {
// widget.planPreventiveVisit.safety = value;
// // widget.planPreventiveVisit.safety?.id = value.id;
// // widget.planPreventiveVisit.safety?.name = value.name;
// }
// },
// ),
setState(() {});
}
},
),
8.height,
8.height,
SingleItemDropDownMenu<Lookup, PpmElectricalSafetyProvider>(
context: context,
backgroundColor: AppColor.neutral100,
initialValue: widget.planPreventiveVisit.safety?.id == null ? null : Lookup(name: widget.planPreventiveVisit.safety?.name ?? "", id: widget.planPreventiveVisit.safety?.id),
title: "Electrical Safety",
onSelect: (value) {
if (value != null) {
widget.planPreventiveVisit.safety = value;
}
},
),
8.height,
SingleItemDropDownMenu<Lookup, PpmAssetAvailabilityProvider>(
context: context,
backgroundColor: AppColor.neutral100,
initialValue: widget.planPreventiveVisit.assetAvailability == null
? null
: Lookup(name: widget.planPreventiveVisit.assetAvailability?.name ?? "", id: widget.planPreventiveVisit.assetAvailability?.id),
title: "Asset Availability",
onSelect: (value) {
if (value != null) {
widget.planPreventiveVisit.assetAvailability = value;
}
},
),
8.height,
SingleItemDropDownMenu<Lookup, PpmServiceProvider>(
context: context,
backgroundColor: AppColor.neutral100,
initialValue: widget.planPreventiveVisit.typeOfService == null
? null
: Lookup(name: widget.planPreventiveVisit.typeOfService?.name ?? "", id: widget.planPreventiveVisit.typeOfService?.id?.toInt()),
title: context.translation.typeOfPm,
onSelect: (value) {
if (value != null) {
widget.planPreventiveVisit.typeOfService = value;
if (widget.planPreventiveVisit.typeOfService?.id == 66) {
ppmProvider.totalTabs = 4;
} else {
ppmProvider.totalTabs = 3;
}
}
},
),
8.height,
_timerWidget(context, totalWorkingHours),
8.height,
AppTextFormField(
labelText: context.translation.callComments,
backgroundColor: AppColor.neutral100,
initialValue: (widget.planPreventiveVisit.comments ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
onChange: (value) {
widget.planPreventiveVisit.comments = value;
},
),
8.height,
MultiFilesPicker(
label: context.translation.attachments,
files: ppmProvider.ppmPlanAttachments,
buttonColor: AppColor.black10,
onlyImages: false,
buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120),
),
],
).toShadowContainer(context),
//TODO need to check this also...
// ESignature(
// title: context.translation.nurseSignature,
// oldSignature: widget.planPreventiveVisit.nurseSignature,
// newSignature: widget.planPreventiveVisit.localNurseSignature,
// onChange: (signature) {
// widget.planPreventiveVisit.localNurseSignature = signature;
// widget.planPreventiveVisit.nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
// },
// ),
// ESignature(
// title: context.translation.engSign,
// oldSignature: widget.planPreventiveVisit.engSignature,
// newSignature: widget.planPreventiveVisit.localEngineerSignature,
// onChange: (signature) {
// widget.planPreventiveVisit.localEngineerSignature = signature;
// widget.planPreventiveVisit.engSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
// },
// ),
],
);
});
}
Widget _timerWidget(BuildContext context, double totalWorkingHours) {
return Column(
children: [
AppTimer(
label: context.translation.timer,
label: context.translation.workingHours,
decoration: BoxDecoration(color: AppColor.neutral100, borderRadius: BorderRadius.circular(10)),
width: double.infinity,
timer: widget.planPreventiveVisit.tbsTimer,
enabled: widget.planPreventiveVisit.tbsTimer?.endAt == null,
timerProgress: (isRunning) {
print("timerProgress:$isRunning");
},
// enabled: widget.planPreventiveVisit.tbsTimer?.endAt == null,
timerProgress: (isRunning) {},
onChange: (timer) async {
widget.planPreventiveVisit.tbsTimer = timer;
return true;
},
),
8.height,
11.height,
if (totalWorkingHours > 0.0) ...[
Container(
height: 56.toScreenHeight,
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth),
alignment: Alignment.centerLeft,
decoration: BoxDecoration(
color: context.isDark ? AppColor.neutral40 : AppColor.background(context),
borderRadius: BorderRadius.circular(10),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Total Working Time",
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: context.isDark ? null : AppColor.neutral20, fontWeight: FontWeight.w500),
),
Text(
" ${formatDuration(totalWorkingHours.round())}",
style: Theme.of(context).textTheme.bodyMedium,
),
],
),
),
8.height,
],
if (widget.planPreventiveVisit.typeOfService?.id == 66) ...[
SingleItemDropDownMenu<SupplierDetails, VendorProvider>(
context: context,
title: context.translation.supplier,
initialValue: initialSupplier,
showAsBottomSheet: true,
onSelect: (supplier) {
if (supplier != null) {
initialSupplier = supplier;
print('supplier dtails is ${supplier.toJson()}');
// widget.planPreventiveVisit.preventiveVisitSuppliers?[0].supplier=supplier;
// widget.model.supplierId = supplier.id;
// widget.model.supplierName = supplier.name;
// initialSupplier = supplier;
// _suppPerson = null;
// widget.model.suppPersonId = null;
// widget.model.suppPerson = null;
// setState(() {});
}
},
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
context.translation.totalWorkingTime.bodyText2(context),
" ${ServiceRequestUtils.formatTimerDuration(totalWorkingHours.round())}".bodyText(context).custom(color: AppColor.black20),
],
),
8.height,
SingleItemDropDownMenu<SuppPersons, NullableLoadingProvider>(
context: context,
title: context.translation.supplierEngineer,
enabled: initialSupplier?.suppPersons?.isNotEmpty ?? false,
initialValue: _suppPerson,
staticData: initialSupplier?.suppPersons,
showAsBottomSheet: true,
onSelect: (suppPerson) {
if (suppPerson != null) {
// _suppPerson = suppPerson;
// widget.model.suppPersonId = suppPerson.id;
// widget.model.suppPerson = suppPerson.name;
// setState(() {});
}
},
),
8.height,
// AppTextFormField(
// labelText: "Telephone",
// initialValue: (initialSupplier?.telephones?[0].telephone ?? "").toString(),
// textAlign: TextAlign.center,
// style: Theme.of(context).textTheme.titleMedium,
// textInputType: TextInputType.number,
// onChange: (value) {
// initialSupplier?.telephones?[0].telephone = value;
// },
// ),
8.height,
//TODO implement this after feedback from backend.
// AppTimer(
// label: "External Supplier Timer",
// timer: widget.model.externalEngineerTimer,
// enabled: widget.model.externalEngineerTimer?.endAt == null,
// timerProgress: (isRunning) {
// print("timerProgress:$isRunning");
// },
// onChange: (timer) async {
// widget.model.externalEngineerTimer = timer;
// return true;
// },
// ),
// 8.height,
],
ADatePicker(
label: context.translation.actualVisitDate,
date: DateTime.tryParse(widget.planPreventiveVisit.acutalDateOfVisit ?? ""),
from: DateTime.now().subtract(const Duration(days: 30)),
onDatePicker: (date) {
// if (date.isBefore(DateTime.parse(widget.planPreventiveVisit.expectedDate!))) {
// "Actual visit date must be greater then expected date".showToast;
// return;
// }
//
// widget.model.actualDate = date.toIso8601String();
// setState(() {});
},
),
8.height,
// ADatePicker(
// label: context.translation.expectedVisitDate,
// date: DateTime.tryParse(widget.model.nextDate ?? ""),
// from: DateTime.now().subtract(const Duration(days: 30)),
// enable: false,
// onDatePicker: (date) {
// widget.model.nextDate = date.toIso8601String();
// setState(() {});
// },
// ),
8.height,
AppTextFormField(
labelText: context.translation.travelingHours,
initialValue: (widget.planPreventiveVisit.travelingHours ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
textInputType: TextInputType.number,
onChange: (value) {
widget.planPreventiveVisit.travelingHours = int.parse(value);
},
),
8.height,
// 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,
AppTextFormField(
labelText: context.translation.comments,
initialValue: (widget.planPreventiveVisit.comments ?? "").toString(),
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleMedium,
onChange: (value) {
widget.planPreventiveVisit.comments = value;
},
),
8.height,
// ESignature(
// title: context.translation.nurseSignature,
// oldSignature: widget.planPreventiveVisit.nurseSignature,
// newSignature: widget.planPreventiveVisit.localNurseSignature,
// onChange: (signature) {
// widget.planPreventiveVisit.localNurseSignature = signature;
// widget.planPreventiveVisit.nurseSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
// },
// ),
8.height,
// ESignature(
// title: context.translation.engSign,
// oldSignature: widget.planPreventiveVisit.engSignature,
// newSignature: widget.planPreventiveVisit.localEngineerSignature,
// onChange: (signature) {
// widget.planPreventiveVisit.localEngineerSignature = signature;
// widget.planPreventiveVisit.engSignature = "${DateTime.now().toIso8601String()}.png|${base64Encode(signature)}";
// },
// ),
],
);
}
String formatDuration1(int seconds) {
int hours = seconds ~/ 3600;
int minutes = (seconds % 3600) ~/ 60;
String formattedDuration = '';
if (hours > 0) {
formattedDuration += '$hours hour${hours > 1 ? 's' : ''} ';
}
if (minutes > 0) {
formattedDuration += '$minutes minute${minutes > 1 ? 's' : ''} ';
}
if (formattedDuration.isEmpty) {
formattedDuration = 'Less than a minute';
}
return formattedDuration.trim();
}
String formatDuration(int seconds) {
int hours = seconds ~/ 3600;
int minutes = (seconds % 3600) ~/ 60;
int remainingSeconds = seconds % 60;
String formattedDuration = '';
if (hours > 0) {
formattedDuration += '$hours hour${hours > 1 ? 's' : ''} ';
}
if (minutes > 0) {
formattedDuration += '$minutes minute${minutes > 1 ? 's' : ''} ';
}
if (remainingSeconds > 0) {
formattedDuration += '$remainingSeconds second${remainingSeconds > 1 ? 's' : ''} ';
}
if (formattedDuration.isEmpty) {
formattedDuration = 'Less than a second';
}
return formattedDuration.trim();
}
// String formatDuration1(int seconds) {
// int hours = seconds ~/ 3600;
// int minutes = (seconds % 3600) ~/ 60;
//
// String formattedDuration = '';
// if (hours > 0) {
// formattedDuration += '$hours hour${hours > 1 ? 's' : ''} ';
// }
// if (minutes > 0) {
// formattedDuration += '$minutes minute${minutes > 1 ? 's' : ''} ';
// }
// if (formattedDuration.isEmpty) {
// formattedDuration = 'Less than a minute';
// }
//
// return formattedDuration.trim();
// }
//
// String formatDuration(int seconds) {
// int hours = seconds ~/ 3600;
// int minutes = (seconds % 3600) ~/ 60;
// int remainingSeconds = seconds % 60;
//
// String formattedDuration = '';
// if (hours > 0) {
// formattedDuration += '$hours hour${hours > 1 ? 's' : ''} ';
// }
// if (minutes > 0) {
// formattedDuration += '$minutes minute${minutes > 1 ? 's' : ''} ';
// }
// if (remainingSeconds > 0) {
// formattedDuration += '$remainingSeconds second${remainingSeconds > 1 ? 's' : ''} ';
// }
// if (formattedDuration.isEmpty) {
// formattedDuration = 'Less than a second';
// }
//
// return formattedDuration.trim();
// }
}

Loading…
Cancel
Save