add maintenance request completed

design_3.0_latest
muhammad.abbasi 1 year ago
parent 9628a6408e
commit 77d18bd413

@ -48,6 +48,8 @@ class ServiceReportAssistantsEmployeeProvider extends ChangeNotifier {
/// return state code if request complete may be 200, 404 or 403 /// return state code if request complete may be 200, 404 or 403
/// for more details check http state manager /// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart /// lib\controllers\http_status_manger\http_status_manger.dart
///
Future<int> getAssistantEmployees(num assetId) async { Future<int> getAssistantEmployees(num assetId) async {
if (_loading) return -2; if (_loading) return -2;
_loading = true; _loading = true;

@ -5,6 +5,7 @@
"commentAdded": "تم إضافة التعليق", "commentAdded": "تم إضافة التعليق",
"requestLockMessage": "انتظر حتى إكمال الطلب", "requestLockMessage": "انتظر حتى إكمال الطلب",
"cancel": "إلغاء", "cancel": "إلغاء",
"addActivity": "إضافة نشاط",
"confirm": "تاكيد", "confirm": "تاكيد",
"done": "تم", "done": "تم",
"exit": "إغلاق", "exit": "إغلاق",

@ -101,6 +101,7 @@
"sparePartDetails": "Spare Part Details", "sparePartDetails": "Spare Part Details",
"attachQuotation": "Attach Quotation", "attachQuotation": "Attach Quotation",
"addSparePartActivity": "Add Spare Part Activity", "addSparePartActivity": "Add Spare Part Activity",
"addActivity": "Add Activity",
"updateSparePartActivity": "Update Spare Part Activity", "updateSparePartActivity": "Update Spare Part Activity",
"deviceName": "Asset Name", "deviceName": "Asset Name",
"deviceImages": "Asset Images", "deviceImages": "Asset Images",

@ -1,5 +1,9 @@
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/assigned_employee.dart'; import 'package:test_sa/models/new_models/assigned_employee.dart';
import 'package:test_sa/models/new_models/assistant_employee.dart';
import 'package:test_sa/models/new_models/work_order_detail_model.dart';
import 'package:test_sa/models/service_request/supp_engineer_work_orders.dart';
import 'package:test_sa/models/service_request/supplier_details.dart';
class ActivityMaintenanceHelperModel { class ActivityMaintenanceHelperModel {
int? workOrderId; int? workOrderId;
@ -10,6 +14,7 @@ class ActivityMaintenanceHelperModel {
int? workingHour; int? workingHour;
int? travelHours; int? travelHours;
Lookup? repairLocation; Lookup? repairLocation;
SupplierDetails? supplier;
String? assignedEmployeeId; String? assignedEmployeeId;
String? technicalComment; String? technicalComment;
int? supplierId; int? supplierId;
@ -17,13 +22,17 @@ class ActivityMaintenanceHelperModel {
DateTime? supplierStartTime; DateTime? supplierStartTime;
DateTime? supplierEndTime; DateTime? supplierEndTime;
int? supplierWorkingHour; int? supplierWorkingHour;
AssignedEmployee? assignedEmployee; // AssignedEmployee? assignedEmployee;
WorkOrderAssignedEmployee? assignedEmployee;
SuppEngineerWorkOrders? supEngineer;
MaintenanceActivityAssistantEmployees? modelAssistantEmployees;
List<AssistantEmployees>? assistantEmployees; List<AssistantEmployees>? assistantEmployees;
ActivityMaintenanceHelperModel( ActivityMaintenanceHelperModel(
{this.workOrderId, {this.workOrderId,
this.lastSituationId, this.lastSituationId,
this.startTime, this.startTime,
this.supplier,
this.endTime, this.endTime,
this.workingHour, this.workingHour,
this.travelHours, this.travelHours,
@ -35,8 +44,10 @@ class ActivityMaintenanceHelperModel {
this.supplierStartTime, this.supplierStartTime,
this.supplierEndTime, this.supplierEndTime,
this.supplierWorkingHour, this.supplierWorkingHour,
this.assistantEmployees,
this.supEngineer,
this.assignedEmployee, this.assignedEmployee,
this.assistantEmployees}); this.modelAssistantEmployees});
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
@ -49,22 +60,22 @@ class ActivityMaintenanceHelperModel {
data['workingHour'] = workingHour; data['workingHour'] = workingHour;
data['travelHours'] = travelHours; data['travelHours'] = travelHours;
data['repairLocationId'] = repairLocation?.id; data['repairLocationId'] = repairLocation?.id;
data['assignedEmployeeId'] = assignedEmployeeId; data['assignedEmployeeId'] = assignedEmployee?.userId;
data['technicalComment'] = technicalComment; data['technicalComment'] = technicalComment;
data['supplierId'] = supplierId; data['supplierId'] = supplier?.id;
data['supplierEngineerId'] = supplierEngineerId; data['supplierEngineerId'] = supEngineer?.id;
data['supplierStartTime'] = supplierStartTime?.toIso8601String(); data['supplierStartTime'] = supplierStartTime?.toIso8601String();
data['supplierEndTime'] = supplierEndTime?.toIso8601String(); data['supplierEndTime'] = supplierEndTime?.toIso8601String();
data['supplierWorkingHour'] = supplierWorkingHour; data['supplierWorkingHour'] = supplierWorkingHour;
if (assistantEmployees != null) { if (modelAssistantEmployees != null) {
data['assistantEmployees'] = data['assistantEmployees'] =[modelAssistantEmployees?.toJson()];
assistantEmployees!.map((v) => v.toJson()).toList(); // modelAssistantEmployees!.map((v) => v.toJson()).toList();
} }
return data; return data;
} }
} }
class AssistantEmployees { class MaintenanceActivityAssistantEmployees {
int? id; int? id;
String? userId; String? userId;
DateTime? startDate; DateTime? startDate;
@ -72,7 +83,7 @@ class AssistantEmployees {
int? workingHours; int? workingHours;
String? technicalComment; String? technicalComment;
AssistantEmployees( MaintenanceActivityAssistantEmployees(
{this.id, {this.id,
this.userId, this.userId,
this.startDate, this.startDate,
@ -82,7 +93,7 @@ class AssistantEmployees {
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{}; final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id; data['id'] = id??0;
data['userId'] = userId; data['userId'] = userId;
data['startDate'] = startDate?.toIso8601String(); data['startDate'] = startDate?.toIso8601String();
data['endDate'] = endDate?.toIso8601String(); data['endDate'] = endDate?.toIso8601String();

@ -88,7 +88,7 @@ class WorkOrderData {
}); });
int? requestId; int? requestId;
String? workOrderNo; String? workOrderNo;
AssignedEmployee? workOrderCreatedBy; WorkOrderAssignedEmployee? workOrderCreatedBy;
DateTime? requestedDate; DateTime? requestedDate;
WorkOrderAsset? asset; WorkOrderAsset? asset;
Lookup? assetGroup; Lookup? assetGroup;
@ -101,7 +101,7 @@ class WorkOrderData {
AssetGroup? department; AssetGroup? department;
int? room; int? room;
Lookup? assetType; Lookup? assetType;
AssignedEmployee? assignedEmployee; WorkOrderAssignedEmployee? assignedEmployee;
String? lastActivityStatus; String? lastActivityStatus;
Lookup? status; Lookup? status;
Lookup? nextStep; Lookup? nextStep;
@ -130,12 +130,10 @@ class WorkOrderData {
List<dynamic> activityAssetToBeRetireds; List<dynamic> activityAssetToBeRetireds;
factory WorkOrderData.fromJson(Map<String, dynamic> json) { factory WorkOrderData.fromJson(Map<String, dynamic> json) {
print('activities in json is ${json["activities"]}');
return WorkOrderData( return WorkOrderData(
requestId: json["id"], requestId: json["id"],
workOrderNo: json["workOrderNo"], workOrderNo: json["workOrderNo"],
workOrderCreatedBy: json["workOrderCreatedBy"] == null ? null : AssignedEmployee.fromJson(json["workOrderCreatedBy"]), workOrderCreatedBy: json["workOrderCreatedBy"] == null ? null : WorkOrderAssignedEmployee.fromJson(json["workOrderCreatedBy"]),
requestedDate: DateTime.tryParse(json["requestedDate"] ?? ""), requestedDate: DateTime.tryParse(json["requestedDate"] ?? ""),
asset: json["asset"] == null ? null : WorkOrderAsset.fromJson(json["asset"]), asset: json["asset"] == null ? null : WorkOrderAsset.fromJson(json["asset"]),
assetGroup: json["assetGroup"] == null ? null : Lookup.fromJson(json["assetGroup"]), assetGroup: json["assetGroup"] == null ? null : Lookup.fromJson(json["assetGroup"]),
@ -148,7 +146,7 @@ class WorkOrderData {
department: json["department"] == null ? null : AssetGroup.fromJson(json["department"]), department: json["department"] == null ? null : AssetGroup.fromJson(json["department"]),
room: json["room"], room: json["room"],
assetType: json["assetType"] == null ? null : Lookup.fromJson(json["assetType"]), assetType: json["assetType"] == null ? null : Lookup.fromJson(json["assetType"]),
assignedEmployee: json["assignedEmployee"] == null ? null : AssignedEmployee.fromJson(json["assignedEmployee"]), assignedEmployee: json["assignedEmployee"] == null ? null : WorkOrderAssignedEmployee.fromJson(json["assignedEmployee"]),
lastActivityStatus: json["lastActivityStatus"], lastActivityStatus: json["lastActivityStatus"],
status: json["status"] == null ? null : Lookup.fromJson(json["status"]), status: json["status"] == null ? null : Lookup.fromJson(json["status"]),
nextStep: json["nextStep"] == null ? null : Lookup.fromJson(json["nextStep"]), nextStep: json["nextStep"] == null ? null : Lookup.fromJson(json["nextStep"]),
@ -297,8 +295,8 @@ class AssetGroup {
}; };
} }
class AssignedEmployee { class WorkOrderAssignedEmployee {
AssignedEmployee({ WorkOrderAssignedEmployee({
required this.userId, required this.userId,
required this.userName, required this.userName,
required this.email, required this.email,
@ -310,8 +308,8 @@ class AssignedEmployee {
String? email; String? email;
int? languageId; int? languageId;
factory AssignedEmployee.fromJson(Map<String, dynamic> json) { factory WorkOrderAssignedEmployee.fromJson(Map<String, dynamic> json) {
return AssignedEmployee( return WorkOrderAssignedEmployee(
userId: json["userId"], userId: json["userId"],
userName: json["userName"], userName: json["userName"],
email: json["email"], email: json["email"],
@ -331,7 +329,7 @@ class Activities {
int? id; int? id;
int? orderNo; int? orderNo;
ActivityStatus? activityStatus; ActivityStatus? activityStatus;
dynamic activityMaintenance; ActivityMaintenance? activityMaintenance;
ActivitySparePart? activitySparePart; ActivitySparePart? activitySparePart;
String ?activityType; String ?activityType;
@ -349,7 +347,9 @@ class Activities {
activityStatus = json['activityStatus'] != null activityStatus = json['activityStatus'] != null
? ActivityStatus.fromJson(json['activityStatus']) ? ActivityStatus.fromJson(json['activityStatus'])
: null; : null;
activityMaintenance = json['activityMaintenance']; activityMaintenance = json['activityMaintenance'] != null
? ActivityMaintenance.fromJson(json['activityMaintenance'])
: null;
if(activityMaintenance!=null){ if(activityMaintenance!=null){
activityType='Maintenance Request'; activityType='Maintenance Request';
} }
@ -369,10 +369,12 @@ class Activities {
if (activityStatus != null) { if (activityStatus != null) {
data['activityStatus'] = activityStatus!.toJson(); data['activityStatus'] = activityStatus!.toJson();
} }
data['activityMaintenance'] = activityMaintenance;
if (activitySparePart != null) { if (activitySparePart != null) {
data['activitySparePart'] = activitySparePart!.toJson(); data['activitySparePart'] = activitySparePart!.toJson();
} }
if (activityMaintenance != null) {
data['activityMaintenance'] = activityMaintenance!.toJson();
}
return data; return data;
} }
} }
@ -391,7 +393,7 @@ class ActivityStatus {
} }
Map<String, dynamic> toJson() { 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['id'] = this.id;
data['name'] = this.name; data['name'] = this.name;
data['value'] = this.value; data['value'] = this.value;
@ -509,7 +511,7 @@ class WorkOrderContactPerson {
dynamic extension; dynamic extension;
String? email; String? email;
dynamic mobilePhone; dynamic mobilePhone;
AssignedEmployee? contactUser; WorkOrderAssignedEmployee? contactUser;
factory WorkOrderContactPerson.fromJson(Map<String, dynamic> json) { factory WorkOrderContactPerson.fromJson(Map<String, dynamic> json) {
return WorkOrderContactPerson( return WorkOrderContactPerson(
@ -520,7 +522,7 @@ class WorkOrderContactPerson {
extension: json["extension"], extension: json["extension"],
email: json["email"], email: json["email"],
mobilePhone: json["mobilePhone"], mobilePhone: json["mobilePhone"],
contactUser: json["contactUser"] == null ? null : AssignedEmployee.fromJson(json["contactUser"]), contactUser: json["contactUser"] == null ? null : WorkOrderAssignedEmployee.fromJson(json["contactUser"]),
); );
} }
@ -556,7 +558,7 @@ class WorkOrderHistory {
Lookup? workorderStatus; Lookup? workorderStatus;
dynamic activityStatus; dynamic activityStatus;
DateTime? date; DateTime? date;
AssignedEmployee? user; WorkOrderAssignedEmployee? user;
Lookup? step; Lookup? step;
DateTime? fixRemotlyStartTime; DateTime? fixRemotlyStartTime;
DateTime? fixRemotlyEndTime; DateTime? fixRemotlyEndTime;
@ -570,7 +572,7 @@ class WorkOrderHistory {
workorderStatus: json["workorderStatus"] == null ? null : Lookup.fromJson(json["workorderStatus"]), workorderStatus: json["workorderStatus"] == null ? null : Lookup.fromJson(json["workorderStatus"]),
activityStatus: json["activityStatus"], activityStatus: json["activityStatus"],
date: DateTime.tryParse(json["date"] ?? ""), date: DateTime.tryParse(json["date"] ?? ""),
user: json["user"] == null ? null : AssignedEmployee.fromJson(json["user"]), user: json["user"] == null ? null : WorkOrderAssignedEmployee.fromJson(json["user"]),
step: json["step"] == null ? null : Lookup.fromJson(json["step"]), step: json["step"] == null ? null : Lookup.fromJson(json["step"]),
fixRemotlyStartTime: DateTime.tryParse(json["fixRemotlyStartTime"] ?? ""), fixRemotlyStartTime: DateTime.tryParse(json["fixRemotlyStartTime"] ?? ""),
fixRemotlyEndTime: DateTime.tryParse(json["fixRemotlyEndTime"] ?? ""), fixRemotlyEndTime: DateTime.tryParse(json["fixRemotlyEndTime"] ?? ""),
@ -595,3 +597,176 @@ class WorkOrderHistory {
"needAVisitDateTime": needAVisitDateTime?.toIso8601String(), "needAVisitDateTime": needAVisitDateTime?.toIso8601String(),
}; };
} }
class ActivityMaintenance {
int? id;
int? activityStatus;
String? startTime;
String? endTime;
int? workingHours;
int? travelHours;
RepairLocation? repairLocation;
AssignedEmployee? assignedEmployee;
String? technicalComment;
int? supplier;
int? supplierEngineer;
String? supplierStartTime;
String? supplierEndTime;
int? supplierWorkingHours;
List<ActivityMaintenanceAssistantEmployees>? assistantEmployees;
ActivityMaintenance(
{this.id,
this.activityStatus,
this.startTime,
this.endTime,
this.workingHours,
this.travelHours,
this.repairLocation,
this.assignedEmployee,
this.technicalComment,
this.supplier,
this.supplierEngineer,
this.supplierStartTime,
this.supplierEndTime,
this.supplierWorkingHours,
this.assistantEmployees});
ActivityMaintenance.fromJson(Map<String, dynamic> json) {
id = json['id'];
activityStatus = json['activityStatus'];
startTime = json['startTime'];
endTime = json['endTime'];
workingHours = json['workingHours'];
travelHours = json['travelHours'];
repairLocation = json['repairLocation'] != null
? RepairLocation.fromJson(json['repairLocation'])
: null;
assignedEmployee = json['assignedEmployee'] != null
? AssignedEmployee.fromJson(json['assignedEmployee'])
: null;
technicalComment = json['technicalComment'];
supplier = json['supplier'];
supplierEngineer = json['supplierEngineer'];
supplierStartTime = json['supplierStartTime'];
supplierEndTime = json['supplierEndTime'];
supplierWorkingHours = json['supplierWorkingHours'];
if (json['assistantEmployees'] != null) {
assistantEmployees = <ActivityMaintenanceAssistantEmployees>[];
json['assistantEmployees'].forEach((v) {
assistantEmployees!.add( ActivityMaintenanceAssistantEmployees.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['activityStatus'] = activityStatus;
data['startTime'] = startTime;
data['endTime'] = endTime;
data['workingHours'] = workingHours;
data['travelHours'] = travelHours;
if (repairLocation != null) {
data['repairLocation'] = repairLocation!.toJson();
}
if (assignedEmployee != null) {
data['assignedEmployee'] = assignedEmployee!.toJson();
}
data['technicalComment'] = technicalComment;
data['supplier'] = supplier;
data['supplierEngineer'] = supplierEngineer;
data['supplierStartTime'] = supplierStartTime;
data['supplierEndTime'] = supplierEndTime;
data['supplierWorkingHours'] = supplierWorkingHours;
if (assistantEmployees != null) {
data['assistantEmployees'] =
assistantEmployees!.map((v) => v.toJson()).toList();
}
return data;
}
}
class RepairLocation {
int? id;
String? name;
int? value;
RepairLocation({this.id, this.name, this.value});
RepairLocation.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
value = json['value'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id;
data['name'] = name;
data['value'] = value;
return data;
}
}
class AssignedEmployee {
String? userId;
String? userName;
String? email;
int? languageId;
AssignedEmployee({this.userId, this.userName, this.email, this.languageId});
AssignedEmployee.fromJson(Map<String, dynamic> json) {
userId = json['userId'];
userName = json['userName'];
email = json['email'];
languageId = json['languageId'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['userId'] = userId;
data['userName'] = userName;
data['email'] = email;
data['languageId'] = languageId;
return data;
}
}
class ActivityMaintenanceAssistantEmployees {
String? startDate;
String? endDate;
int? workingHours;
String? technicalComment;
AssignedEmployee? user;
ActivityMaintenanceAssistantEmployees(
{this.startDate,
this.endDate,
this.workingHours,
this.technicalComment,
this.user});
ActivityMaintenanceAssistantEmployees.fromJson(Map<String, dynamic> json) {
startDate = json['startDate'];
endDate = json['endDate'];
workingHours = json['workingHours'];
technicalComment = json['technicalComment'];
user = json['user'] != null
? new AssignedEmployee.fromJson(json['user'])
: null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['startDate'] = startDate;
data['endDate'] = endDate;
data['workingHours'] = workingHours;
data['technicalComment'] = technicalComment;
if (user != null) {
data['user'] = user!.toJson();
}
return data;
}
}

@ -488,6 +488,28 @@ class RequestDetailProvider extends ChangeNotifier {
return -1; return -1;
} }
} }
Future<int> updateActivityMaintenance() async {
isLoading = true;
try {
final response = await ApiManager.instance.post(
URLs.updateActivityMaintenanceUrl,
body: activityMaintenanceHelperModel!.toJson(),
);
stateCode = response.statusCode;
print('update response i got is ${response.body}');
if (response.statusCode >= 200 && response.statusCode < 300) {
// request.engineerName = employee.name;
notifyListeners();
}
isLoading = false;
notifyListeners();
return response.statusCode;
} catch (error) {
isLoading = false;
notifyListeners();
return -1;
}
}
Future<int> deleteActivitySparePart({required int id, required int workOrderId}) async { Future<int> deleteActivitySparePart({required int id, required int workOrderId}) async {
isLoading = true; isLoading = true;
@ -555,7 +577,8 @@ class RequestDetailProvider extends ChangeNotifier {
stateCode = response.statusCode; stateCode = response.statusCode;
print('add sparepart activity response i got is ${response.body}'); print('add sparepart activity response i got is ${response.body}');
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body));
updateCurrentWorkOrder(currentWorkOrder);
notifyListeners(); notifyListeners();
} }
isLoading = false; isLoading = false;
@ -577,7 +600,8 @@ class RequestDetailProvider extends ChangeNotifier {
stateCode = response.statusCode; stateCode = response.statusCode;
print('add maintenance activity response i got is ${response.body}'); print('add maintenance activity response i got is ${response.body}');
if (response.statusCode >= 200 && response.statusCode < 300) { if (response.statusCode >= 200 && response.statusCode < 300) {
currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body));
updateCurrentWorkOrder(currentWorkOrder);
notifyListeners(); notifyListeners();
} }
isLoading = false; isLoading = false;

@ -170,10 +170,6 @@ class FooterActionButton {
buttonColor: AppColor.neutral140, buttonColor: AppColor.neutral140,
textColor: AppColor.neutral150, textColor: AppColor.neutral150,
fontSize: 12.toScreenWidth, fontSize: 12.toScreenWidth,
//TODO remove this after testing ....
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>const MaintenanceRequestForm()));
},
)); ));
} }
} else if (userProvider.user?.type == UsersTypes.nurse) { } else if (userProvider.user?.type == UsersTypes.nurse) {

@ -46,107 +46,10 @@ class ActivitiesListView extends StatelessWidget {
itemCount: activities.length, itemCount: activities.length,
separatorBuilder: (czt, index) => 16.height, separatorBuilder: (czt, index) => 16.height,
itemBuilder: (context, index) { itemBuilder: (context, index) {
return Column( if(activities[index].activityMaintenance!=null){
mainAxisSize: MainAxisSize.min, return maintenanceActivityCard(requestDetailProvider: requestDetailProvider, userProvider: userProvider, context: context, activity: activities[index]);
crossAxisAlignment: CrossAxisAlignment.start, }
children: [ return sparePartActivityCard(requestDetailProvider: requestDetailProvider, userProvider: userProvider, context: context, activity: activities[index]);
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
StatusLabel(
label: activities[index].activityStatus?.name,
textColor: AppColor.getHistoryLogStatusTextColorByName(activities[index].activityStatus!.name!),
backgroundColor: AppColor.getHistoryLogStatusColorByName(activities[index].activityStatus!.name!),
),
"drag_icon".toSvgAsset(height: 12, width: 23, color: AppColor.neutral160),
if (userProvider.user!.type == UsersTypes.engineer &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 3)
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"edit_icon".toSvgAsset(height: 21, width: 21).onPress(() {
requestDetailProvider.sparePartHelperModel = SparePartHelperModel(
id: activities[index].id,
workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId,
comment: activities[index].activitySparePart?.comment,
sparePartAttachments: activities[index].activitySparePart?.acitiySparePartAttachments ?? [],
sparePart: SparePart(
id: activities[index].activitySparePart?.partCatalogItem?.id,
partName: activities[index].activitySparePart?.partCatalogItem?.partName,
partNo: activities[index].activitySparePart?.partCatalogItem?.partNumber),
quantity: activities[index].activitySparePart?.quantity,
activityStatusId: activities[index].activityStatus?.id,
//TODO commets are missing in api response..
// comment: activities[index].activitySparePart?.description,
);
requestDetailProvider.updateSparePartHelperModel(requestDetailProvider.sparePartHelperModel);
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => const SparePartRequest(),
));
}),
24.width,
"delete_icon".toSvgAsset(height: 21, width: 21).onPress(() async {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
int status =
await requestDetailProvider.deleteActivitySparePart(id: activities[index].id!, workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!);
if (status == 200) {
await requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
Navigator.pop(context);
} else {
Navigator.pop(context);
}
}),
],
)
],
),
6.height,
//activity type...
Text(
'${activities[index].activityType?.cleanupWhitespace.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50),
),
3.height,
Text(
'${context.translation.partName}: ${activities[index].activitySparePart?.partCatalogItem?.partName}',
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
2.height,
Text(
'${context.translation.partNo}: ${activities[index].activitySparePart?.partCatalogItem?.partNumber}',
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
2.height,
//TODO description text not in api.
// Text(
// '${context.translation.date}: ${activities[index].currentSituation?.date}',
// style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
// ),
if (activities[index].activitySparePart?.comment?.isNotEmpty ?? false) ...[
const Divider().defaultStyle(context),
2.height,
Text(
activities[index].activitySparePart?.comment ?? "",
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
],
if (activities[index].activitySparePart?.acitiySparePartAttachments?.isNotEmpty ?? false) ...[
2.height,
const Divider().defaultStyle(context),
FilesList(images: activities[index].activitySparePart!.acitiySparePartAttachments!.map((toElement) => URLs.getFileUrl(toElement.name!)!).toList()),
],
],
).toShadowContainer(context, padding: 12, showShadow: false).onPress(() {
//TODO write onview detail method..
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => WorkOrderDetailsPage(workOrder: activities[index], serviceRequest: ServiceRequest())),
// );
});
}, },
).expanded, ).expanded,
if (userProvider.user!.type == UsersTypes.engineer && if (userProvider.user!.type == UsersTypes.engineer &&
@ -165,4 +68,211 @@ class ActivitiesListView extends StatelessWidget {
}), }),
); );
} }
Widget sparePartActivityCard({required RequestDetailProvider requestDetailProvider,required UserProvider userProvider,required BuildContext context,required Activities activity}){
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
StatusLabel(
label: activity.activityStatus?.name,
textColor: AppColor.getHistoryLogStatusTextColorByName(activity.activityStatus!.name!),
backgroundColor: AppColor.getHistoryLogStatusColorByName(activity.activityStatus!.name!),
),
"drag_icon".toSvgAsset(height: 12, width: 23, color: AppColor.neutral160),
if (userProvider.user!.type == UsersTypes.engineer &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 3)
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"edit_icon".toSvgAsset(height: 21, width: 21).onPress(() {
requestDetailProvider.sparePartHelperModel = SparePartHelperModel(
id: activity.id,
workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId,
comment: activity.activitySparePart?.comment,
sparePartAttachments: activity.activitySparePart?.acitiySparePartAttachments ?? [],
sparePart: SparePart(
id: activity.activitySparePart?.partCatalogItem?.id,
partName: activity.activitySparePart?.partCatalogItem?.partName,
partNo: activity.activitySparePart?.partCatalogItem?.partNumber),
quantity: activity.activitySparePart?.quantity,
activityStatusId: activity.activityStatus?.id,
//TODO commets are missing in api response..
// comment: activity.activitySparePart?.description,
);
requestDetailProvider.updateSparePartHelperModel(requestDetailProvider.sparePartHelperModel);
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => const SparePartRequest(),
));
}),
24.width,
"delete_icon".toSvgAsset(height: 21, width: 21).onPress(() async {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
int status =
await requestDetailProvider.deleteActivitySparePart(id: activity.id!, workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!);
if (status == 200) {
await requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
Navigator.pop(context);
} else {
Navigator.pop(context);
}
}),
],
)
],
),
6.height,
//activity type...
Text(
'${activity.activityType?.cleanupWhitespace.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50),
),
3.height,
Text(
'${context.translation.partName}: ${activity.activitySparePart?.partCatalogItem?.partName}',
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
2.height,
Text(
'${context.translation.partNo}: ${activity.activitySparePart?.partCatalogItem?.partNumber}',
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
2.height,
//TODO description text not in api.
// Text(
// '${context.translation.date}: ${activity.currentSituation?.date}',
// style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
// ),
if (activity.activitySparePart?.comment?.isNotEmpty ?? false) ...[
const Divider().defaultStyle(context),
2.height,
Text(
activity.activitySparePart?.comment ?? "",
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
],
if (activity.activitySparePart?.acitiySparePartAttachments?.isNotEmpty ?? false) ...[
2.height,
const Divider().defaultStyle(context),
FilesList(images: activity.activitySparePart!.acitiySparePartAttachments!.map((toElement) => URLs.getFileUrl(toElement.name!)!).toList()),
],
],
).toShadowContainer(context, padding: 12, showShadow: false).onPress(() {
//TODO write onview detail method..
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => WorkOrderDetailsPage(workOrder: activity, serviceRequest: ServiceRequest())),
// );
});
}
Widget maintenanceActivityCard({required RequestDetailProvider requestDetailProvider,required UserProvider userProvider,required BuildContext context,required Activities activity}){
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
StatusLabel(
label: activity.activityStatus?.name,
textColor: AppColor.getHistoryLogStatusTextColorByName(activity.activityStatus!.name!),
backgroundColor: AppColor.getHistoryLogStatusColorByName(activity.activityStatus!.name!),
),
"drag_icon".toSvgAsset(height: 12, width: 23, color: AppColor.neutral160),
if (userProvider.user!.type == UsersTypes.engineer &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 5 &&
requestDetailProvider.currentWorkOrder?.data?.status?.value != 3)
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
"edit_icon".toSvgAsset(height: 21, width: 21).onPress(() {
requestDetailProvider.sparePartHelperModel = SparePartHelperModel(
id: activity.id,
workOrderId: requestDetailProvider.currentWorkOrder?.data?.requestId,
comment: activity.activitySparePart?.comment,
sparePartAttachments: activity.activitySparePart?.acitiySparePartAttachments ?? [],
sparePart: SparePart(
id: activity.activitySparePart?.partCatalogItem?.id,
partName: activity.activitySparePart?.partCatalogItem?.partName,
partNo: activity.activitySparePart?.partCatalogItem?.partNumber),
quantity: activity.activitySparePart?.quantity,
activityStatusId: activity.activityStatus?.id,
//TODO commets are missing in api response..
// comment: activity.activitySparePart?.description,
);
requestDetailProvider.updateSparePartHelperModel(requestDetailProvider.sparePartHelperModel);
Navigator.of(context).push(MaterialPageRoute(
builder: (_) => const SparePartRequest(),
));
}),
24.width,
"delete_icon".toSvgAsset(height: 21, width: 21).onPress(() async {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
int status =
await requestDetailProvider.deleteActivitySparePart(id: activity.id!, workOrderId: requestDetailProvider.currentWorkOrder!.data!.requestId!);
if (status == 200) {
await requestDetailProvider.getWorkOrderById(id: requestDetailProvider.currentWorkOrder!.data!.requestId!);
Navigator.pop(context);
} else {
Navigator.pop(context);
}
}),
],
)
],
),
6.height,
//activity type...
Text(
'${activity.activityType?.cleanupWhitespace.capitalizeFirstOfEach}',
style: AppTextStyles.bodyText.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50),
),
3.height,
Text(
'${context.translation.partName}: ${activity.activitySparePart?.partCatalogItem?.partName}',
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
2.height,
Text(
'${context.translation.partNo}: ${activity.activitySparePart?.partCatalogItem?.partNumber}',
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
2.height,
//TODO description text not in api.
// Text(
// '${context.translation.date}: ${activity.currentSituation?.date}',
// style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
// ),
if (activity.activitySparePart?.comment?.isNotEmpty ?? false) ...[
const Divider().defaultStyle(context),
2.height,
Text(
activity.activitySparePart?.comment ?? "",
style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral120),
),
],
if (activity.activitySparePart?.acitiySparePartAttachments?.isNotEmpty ?? false) ...[
2.height,
const Divider().defaultStyle(context),
FilesList(images: activity.activitySparePart!.acitiySparePartAttachments!.map((toElement) => URLs.getFileUrl(toElement.name!)!).toList()),
],
],
).toShadowContainer(context, padding: 12, showShadow: false).onPress(() {
//TODO write onview detail method..
// Navigator.push(
// context,
// MaterialPageRoute(builder: (context) => WorkOrderDetailsPage(workOrder: activity, serviceRequest: ServiceRequest())),
// );
});
}
} }

@ -60,7 +60,7 @@ class WorkOrderDetailView extends StatelessWidget {
} }
Widget workOrderDetailCard(BuildContext context, WorkOrderData workOrder, UserProvider userProvider) { Widget workOrderDetailCard(BuildContext context, WorkOrderData workOrder, UserProvider userProvider) {
// print('callids i got is ${workOrder}') print('callids i got is ${workOrder.requestId}');
print('work order next step value is ${workOrder.nextStep?.toJson()}'); print('work order next step value is ${workOrder.nextStep?.toJson()}');
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,

@ -1,11 +1,12 @@
import 'package:expansion_tile_card/expansion_tile_card.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/string_extensions.dart'; import 'package:test_sa/extensions/string_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/helper_data_models/maintenance_request/activity_maintenance_model.dart';
import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart'; import 'package:test_sa/new_views/common_widgets/app_text_form_field.dart';
import 'package:test_sa/service_request_latest/request_detail_provider.dart'; import 'package:test_sa/service_request_latest/request_detail_provider.dart';
@ -20,9 +21,11 @@ class AssistantEmployeeCard extends StatefulWidget {
} }
class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> { class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
final GlobalKey<ExpansionTileCardState> cardA = GlobalKey();
bool status = false; bool status = false;
final TextEditingController _workingHoursController = TextEditingController(); final TextEditingController _workingHoursController = TextEditingController(text: '');
bool isCurrentUserIsAssistantEmp = false;
bool isExpanded = false;
@override @override
void initState() { void initState() {
@ -33,7 +36,14 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
super.initState(); super.initState();
} }
Future<void> getInitialData() async {} Future<void> getInitialData() async {
final user = Provider.of<UserProvider>(context, listen: false).user!;
RequestDetailProvider requestDetailProvider = Provider.of<RequestDetailProvider>(context, listen: false);
isCurrentUserIsAssistantEmp = (user.userID != requestDetailProvider.currentWorkOrder?.data?.assignedEmployee?.userId);
// if (isCurrentUserIsAssistantEmp) {
// // _subWorkOrders.assistantEmployees = [widget.workOrder.assistantEmployees?.first?.copyWith(id: 0)];
// }
}
@override @override
void dispose() { void dispose() {
@ -45,41 +55,44 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) { return Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) {
return ExpansionTileCard( return Column(
key: cardA, children: [
initialElevation: 0, SizedBox(
borderRadius: BorderRadius.circular(10), height: 56.toScreenHeight,
expandedTextColor: AppColor.black20, child: Row(
shadowColor: AppColor.white10, mainAxisAlignment: MainAxisAlignment.spaceBetween,
baseColor: AppColor.white10, children: [
contentPadding: const EdgeInsets.only(left: 16,right: 16), context.translation.assistantEmployee.bodyText(context).custom(color: AppColor.black20),
expandedColor: AppColor.white10, IconButton(onPressed: (){
duration: Duration.zero, setState(() {
elevation: 0, isExpanded=!isExpanded;
title: context.translation.assistantEmployee.bodyText(context).custom(color: AppColor.black20), });
children: <Widget>[ }, icon: Icon(isExpanded?Icons.arrow_drop_up_outlined:Icons.arrow_drop_down)),
Column( ],),
),
isExpanded? Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
// ServiceReportAssistantEmployeeMenu( ServiceReportAssistantEmployeeMenu(
// title: context.translation.assignAssistant, title: context.translation.select,
// assetId: widget.workOrder!.callRequest!.asset!.id!.toInt(), backgroundColor: AppColor.neutral100,
// assetId: requestDetailProvider.currentWorkOrder!.data!.asset!.id!,
// initialValue: (_subWorkOrders.assistantEmployees?.isNotEmpty ?? false) ? _subWorkOrders.assistantEmployees?.first : null, initialValue: (requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.isNotEmpty ?? false)
// // initialValue: !isCurrentAssigned ? requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.first
// // ? (widget.workOrder.assistantEmployees?.first) : null,
// // : (_subWorkOrders.assistantEmployees?.isNotEmpty ?? false) //TODO add check...
// // ? _subWorkOrders.assistantEmployees?.first // enable: !isCurrentUserIsAssistantEmp,
// // : null, onSelect: (employee) {
// enable: !isCurrentUserIsAssistantEmp, if (employee == null) {
// onSelect: (employee) { requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [];
// if (employee == null) { } else {
// _subWorkOrders.assistantEmployees = []; requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [employee.copyWith(id: 0)];
// } else { requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.userId = employee.user?.id;
// _subWorkOrders.assistantEmployees = [employee.copyWith(id: 0)];
// } }
// }, },
// ), ),
8.height,
Row( Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@ -87,7 +100,7 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
label: context.translation.startTime, label: context.translation.startTime,
hideShadow: true, hideShadow: true,
backgroundColor: AppColor.neutral100, backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.startTime, date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
formatDateWithTime: true, formatDateWithTime: true,
onDatePicker: (selectedDate) { onDatePicker: (selectedDate) {
showTimePicker( showTimePicker(
@ -103,7 +116,7 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
selectedTime.hour, selectedTime.hour,
selectedTime.minute, selectedTime.minute,
); );
requestDetailProvider.activityMaintenanceHelperModel?.startTime = selectedDateTime; requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider); assignWorkingHours(requestDetailProvider: requestDetailProvider);
} }
@ -115,7 +128,7 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
label: context.translation.endTime, label: context.translation.endTime,
hideShadow: true, hideShadow: true,
backgroundColor: AppColor.neutral100, backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.endTime, date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate,
formatDateWithTime: true, formatDateWithTime: true,
onDatePicker: (selectedDate) { onDatePicker: (selectedDate) {
showTimePicker( showTimePicker(
@ -131,11 +144,12 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
selectedTime.hour, selectedTime.hour,
selectedTime.minute, selectedTime.minute,
); );
if (requestDetailProvider.activityMaintenanceHelperModel!.startTime != null && selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.startTime!)) { if (requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate != null &&
selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.startDate!)) {
"End Date time must be greater then start date".showToast; "End Date time must be greater then start date".showToast;
return; return;
} }
requestDetailProvider.activityMaintenanceHelperModel?.endTime = selectedDateTime; requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider); assignWorkingHours(requestDetailProvider: requestDetailProvider);
} }
@ -150,7 +164,9 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
backgroundColor: AppColor.neutral80, backgroundColor: AppColor.neutral80,
controller: _workingHoursController, controller: _workingHoursController,
suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16), suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.workingHour.toString(), initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.workingHours != null
? requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.workingHours.toString()
: '',
textAlign: TextAlign.center, textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle, labelStyle: AppTextStyles.textFieldLabelStyle,
enable: false, enable: false,
@ -159,7 +175,7 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
), ),
8.height, 8.height,
AppTextFormField( AppTextFormField(
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.technicalComment, initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment,
labelText: context.translation.technicalComment, labelText: context.translation.technicalComment,
backgroundColor: AppColor.neutral100, backgroundColor: AppColor.neutral100,
showShadow: false, showShadow: false,
@ -167,19 +183,22 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
alignLabelWithHint: true, alignLabelWithHint: true,
textInputType: TextInputType.multiline, textInputType: TextInputType.multiline,
onChange: (value) { onChange: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.technicalComment = value; requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value;
}, },
onSaved: (value) { onSaved: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.technicalComment = value; requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value;
}, },
), ),
8.height,
], ],
), ):const SizedBox(),
], ],
); );
}); });
} }
//TODO move this to some common place....@waseem
int calculateWorkingHours(DateTime? startTime, DateTime? endTime) { int calculateWorkingHours(DateTime? startTime, DateTime? endTime) {
if (startTime != null && endTime != null) { if (startTime != null && endTime != null) {
Duration difference = endTime.difference(startTime); Duration difference = endTime.difference(startTime);
@ -192,16 +211,11 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
} }
assignWorkingHours({required RequestDetailProvider requestDetailProvider}) { assignWorkingHours({required RequestDetailProvider requestDetailProvider}) {
int hours = calculateWorkingHours(requestDetailProvider.activityMaintenanceHelperModel!.startTime, requestDetailProvider.activityMaintenanceHelperModel!.endTime); int hours = calculateWorkingHours(
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate, requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate);
if (hours != -1) { if (hours != -1) {
_workingHoursController.text = hours.toString(); _workingHoursController.text = hours.toString();
requestDetailProvider.activityMaintenanceHelperModel!.workingHour = hours; requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.workingHours = hours;
} }
} }
final ButtonStyle flatButtonStyle = TextButton.styleFrom(
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(4.0)),
),
);
} }

@ -22,6 +22,7 @@ import 'package:test_sa/providers/work_order/reason_provider.dart';
import 'package:test_sa/providers/work_order/vendor_provider.dart'; import 'package:test_sa/providers/work_order/vendor_provider.dart';
import 'package:test_sa/service_request_latest/request_detail_provider.dart'; import 'package:test_sa/service_request_latest/request_detail_provider.dart';
import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart'; import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/views/pages/user/requests/add_supplier_engineer_bottom_sheet.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart'; import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/date_and_time/time_picker.dart'; import 'package:test_sa/views/widgets/date_and_time/time_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.dart'; import 'package:test_sa/views/widgets/loaders/loading_manager.dart';
@ -42,262 +43,191 @@ class ExternalMaintenanceRequest extends StatefulWidget {
class _ExternalMaintenanceRequestState extends State<ExternalMaintenanceRequest> with TickerProviderStateMixin { class _ExternalMaintenanceRequestState extends State<ExternalMaintenanceRequest> with TickerProviderStateMixin {
ServiceRequest? _request;
ServiceRequestsProvider ?_serviceRequestsProvider;
ServiceStatusProvider? _assetTypeProvider;
ServiceReport ?_serviceReport; ServiceReport ?_serviceReport;
bool _isLoading = false;
int _selectedValue = 1;
final TextEditingController _workingHoursController = TextEditingController(); final TextEditingController _workingHoursController = TextEditingController();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _faultController = TextEditingController();
final TextEditingController _workPreformedController = TextEditingController();
final TextEditingController _partQtyController = TextEditingController();
@override @override
void initState() { void initState() {
_serviceReport = ServiceReport(
// returnToService: DateTime.now(),
// //type: const Lookup(value: 2),
// device: widget.request.device,
sparePartsWorkOrders: [],
);
super.initState(); super.initState();
if (context.mounted) {
_request = Provider.of<ServiceRequestsProvider>(context, listen: false).currentSelectedRequest;
Provider.of<ServiceReportLastCallsProvider>(context, listen: false).reset();
Provider.of<ReasonProvider>(context, listen: false).reset();
Provider.of<ReasonProvider>(context, listen: false).serviceRequestId = _request?.id;
}
// _isLoading = true;
}
@override
void dispose() {
_faultController.dispose();
_workPreformedController.dispose();
_partQtyController.dispose();
super.dispose();
} }
void getRequestForWorkOrder() async {
_isLoading = true;
setState(() {});
_serviceReport?.callRequest = await _serviceRequestsProvider?.getCallRequestForWorkOrder(callId: _request?.id??'0');
await _assetTypeProvider?.getTypes();
_serviceReport?.assignedEmployee = _serviceReport?.callRequest?.assignedEmployee;
_serviceReport?.equipmentStatus = _serviceReport?.callRequest?.defectType;
_serviceReport?.serviceType = Lookup(id: 65, name: "Interval", value: 1); // default value in service type as in web
_isLoading = false;
setState(() {});
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// _serviceRequestsProvider = Provider.of<ServiceRequestsProvider>(context);
// _assetTypeProvider = Provider.of<ServiceStatusProvider>(context);
// if (_serviceReport?.callRequest == null) {
// getRequestForWorkOrder();
// }
// _serviceReport?.assetType = _assetTypeProvider?.statuses?.firstWhere(
// (element) => element.value == _serviceReport?.callRequest?.assetType,
// orElse: () => Lookup(),
// );
return Consumer<RequestDetailProvider>( return Consumer<RequestDetailProvider>(
builder: (context, RequestDetailProvider requestDetailProvider,child) { builder: (context, RequestDetailProvider requestDetailProvider,child) {
return LoadingManager( return Column(
isLoading: _isLoading, children: [
isFailedLoading: false, Form(
stateCode: 200, key: _formKey,
onRefresh: () async {}, child: Column(
child: Stack( mainAxisSize: MainAxisSize.min,
children: [ children: [
SingleChildScrollView( SingleItemDropDownMenu<SupplierDetails, VendorProvider>(
child: Form( context: context,
key: _formKey, title: context.translation.supplier,
child: Column( backgroundColor: AppColor.neutral100,
crossAxisAlignment: CrossAxisAlignment.stretch, initialValue: requestDetailProvider.activityMaintenanceHelperModel?.supplier,
showAsBottomSheet: true,
onSelect: (supplier) {
if (supplier != null) {
requestDetailProvider.activityMaintenanceHelperModel?.supplier=supplier;
print('engineer is ${supplier.suppPersons?.length}');
// _subWorkOrders.supplier = supplier;
// log(_subWorkOrders.supplier?.suppPersons?.map((e) => e.personName)?.toString());
setState(() {});
}
},
),
8.height,
Row(
children: [ children: [
//TODO replace with correct component.. SingleItemDropDownMenu<SuppPersons, NullableLoadingProvider>(
SingleItemDropDownMenu<SupplierDetails, VendorProvider>(
context: context, context: context,
title: context.translation.supplier, backgroundColor: requestDetailProvider.activityMaintenanceHelperModel?.supplier?.suppliername == null ? AppColor.neutral40 : AppColor.neutral100,
initialValue: null, title: context.translation.supplierEngineer,
enabled: requestDetailProvider.activityMaintenanceHelperModel?.supplier?.suppPersons?.isNotEmpty ?? false,
staticData:requestDetailProvider.activityMaintenanceHelperModel?.supplier?.suppPersons,
showAsBottomSheet: true, showAsBottomSheet: true,
onSelect: (supplier) { initialValue: requestDetailProvider.activityMaintenanceHelperModel?.supEngineer == null ? null : SuppPersons.fromJson(requestDetailProvider.activityMaintenanceHelperModel?.supEngineer?.toJson()),
if (supplier != null) { onSelect: (suppPerson) {
// _subWorkOrders.supplier = supplier; print(suppPerson?.toJson());
// log(_subWorkOrders.supplier?.suppPersons?.map((e) => e.personName)?.toString()); if (suppPerson != null) {
requestDetailProvider.activityMaintenanceHelperModel?.supEngineer = SuppEngineerWorkOrders.fromJson(suppPerson.toJson());
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
// engineer = SuppEngineerWorkOrders(
// id: suppPerson?.supplierId,
// supplierContactId: suppPerson?.id,
// personName: suppPerson?.personName,
// contact: suppPerson?.contact,
// externalEngCode: suppPerson?.externalEngCode,
// email: suppPerson?.email,
// );
setState(() {}); setState(() {});
} }
}, },
), ).expanded,
SingleItemDropDownMenu<Lookup, NullableLoadingProvider>( 8.width,
context: context, Container(
height: 56.toScreenHeight, height: 56.toScreenHeight,
title: context.translation.supplier, width: 60.toScreenWidth,
showShadow: false, decoration: BoxDecoration(
color: requestDetailProvider.activityMaintenanceHelperModel?.supplier?.suppliername == null ? AppColor.neutral40 : AppColor.neutral100,
borderRadius: BorderRadius.circular(10),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
),
child: Icon(
Icons.add,
color: context.isDark ? null : AppColor.neutral60,
),
).onPress(requestDetailProvider.activityMaintenanceHelperModel?.supplier?.suppliername == null
? null
: () async {
SuppEngineerWorkOrders suppEngineer = (await showModalBottomSheet(
context: context,
useSafeArea: true,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder: (context) => AddSupplierEngineerBottomSheet(requestDetailProvider.activityMaintenanceHelperModel!.supplier!.id!.toInt()),
)) as SuppEngineerWorkOrders;
requestDetailProvider.activityMaintenanceHelperModel?.supplier?.suppPersons ??= [];
requestDetailProvider.activityMaintenanceHelperModel?.supplier?.suppPersons?.add(SuppPersons.fromJson(suppEngineer.toJson()));
requestDetailProvider.activityMaintenanceHelperModel?.supEngineer = suppEngineer;
setState(() {});
}),
],
),
8.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [
ADatePicker(
label: context.translation.startTime,
hideShadow: true,
backgroundColor: AppColor.neutral100, backgroundColor: AppColor.neutral100,
staticData: Provider.of<ServiceReportLastCallsProvider>(context).calls, date: requestDetailProvider.activityMaintenanceHelperModel?.supplierStartTime,
initialValue: _serviceReport?.calllastSituation, formatDateWithTime: true,
onSelect: (status) { onDatePicker: (selectedDate) {
_serviceReport?.calllastSituation = status; 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,
);
requestDetailProvider.activityMaintenanceHelperModel?.supplierStartTime = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider);
}
});
}, },
), ).expanded,
8.height, 8.width,
AppTextFormField( ADatePicker(
labelText: context.translation.engineerName, label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.neutral100, backgroundColor: AppColor.neutral100,
initialValue: _serviceReport?.assignedEmployee?.name.toString(), date: requestDetailProvider.activityMaintenanceHelperModel?.supplierEndTime,
textAlign: TextAlign.center, formatDateWithTime: true,
labelStyle: AppTextStyles.textFieldLabelStyle, onDatePicker: (selectedDate) {
showShadow: false, showTimePicker(
style: Theme.of(context).textTheme.titleMedium, context: context,
), initialTime: TimeOfDay.now(),
8.height, ).then((selectedTime) {
Row( // Handle the selected date and time here.
mainAxisSize: MainAxisSize.min, if (selectedTime != null) {
children: [ DateTime selectedDateTime = DateTime(
ADatePicker( selectedDate.year,
label: context.translation.startTime, selectedDate.month,
hideShadow: true, selectedDate.day,
backgroundColor: AppColor.neutral100, selectedTime.hour,
date: requestDetailProvider.activityMaintenanceHelperModel?.supplierStartTime, selectedTime.minute,
formatDateWithTime: true, );
onDatePicker: (selectedDate) { if (requestDetailProvider.activityMaintenanceHelperModel!.supplierStartTime!=null&&selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.supplierStartTime!)) {
showTimePicker( "End Date time must be greater then start date".showToast;
context: context, return;
initialTime: TimeOfDay.now(), }
).then((selectedTime) { requestDetailProvider.activityMaintenanceHelperModel?.supplierEndTime = selectedDateTime;
// Handle the selected date and time here. requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
if (selectedTime != null) { assignWorkingHours(requestDetailProvider: requestDetailProvider);
DateTime selectedDateTime = DateTime(
selectedDate.year, }
selectedDate.month, });
selectedDate.day, },
selectedTime.hour, ).expanded,
selectedTime.minute,
);
requestDetailProvider.activityMaintenanceHelperModel?.supplierStartTime = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider);
}
});
},
).expanded,
8.width,
ADatePicker(
label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.supplierEndTime,
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 (requestDetailProvider.activityMaintenanceHelperModel!.supplierStartTime!=null&&selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.supplierStartTime!)) {
"End Date time must be greater then start date".showToast;
return;
}
requestDetailProvider.activityMaintenanceHelperModel?.supplierEndTime = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider);
}
});
},
).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: requestDetailProvider.activityMaintenanceHelperModel?.supplierWorkingHour.toString(),
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
enable: false,
showShadow: false,
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
], ],
), ),
), 8.height,
).toShadowContainer(context).paddingOnly(start: 16, end: 16, top: 12), AppTextFormField(
FooterActionButton.footerContainer( labelText: context.translation.workingHours,
child: AppFilledButton( backgroundColor: AppColor.neutral80,
label:context.translation.addExternalActivity, // Use the dynamic label controller: _workingHoursController,
buttonColor: AppColor.primary10, suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
onPressed: () async { initialValue:requestDetailProvider.activityMaintenanceHelperModel?.supplierWorkingHour!=null? requestDetailProvider.activityMaintenanceHelperModel?.supplierWorkingHour.toString():'',
// Handle button press textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
enable: false,
showShadow: false,
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
}, ],
),
), ),
], ).toShadowContainer(context).paddingOnly(start: 16, end: 16, top: 12),
), ],
); );
} }
); );
} }
Widget repairLocationWidget(BuildContext context) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
radioButtonWidget(label: context.translation.remotely, value: 1),
radioButtonWidget(label: context.translation.workshop, value: 2),
radioButtonWidget(label: context.translation.abroad, value: 3),
],
);
}
Widget radioButtonWidget({required String label, required dynamic value}) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(
width: 20.toScreenWidth,
height: 40.toScreenHeight,
//TODO use the type required according data..
child: Radio<int>(
activeColor: AppColor.primary10,
value: value,
groupValue: _selectedValue,
onChanged: (int? value) {
setState(() {
_selectedValue = value!;
});
},
),
),
8.width,
Text(
label,
style: AppTextStyles.tinyFont.copyWith(color: AppColor.neutral120),
),
13.width,
],
);
}
int calculateWorkingHours(DateTime? startTime, DateTime? endTime) { int calculateWorkingHours(DateTime? startTime, DateTime? endTime) {
if(startTime!=null&&endTime!=null){ if(startTime!=null&&endTime!=null){
Duration difference = endTime.difference(startTime); Duration difference = endTime.difference(startTime);

@ -43,7 +43,6 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
ActivityStatusProvider? _activityStatusProvider; ActivityStatusProvider? _activityStatusProvider;
ServiceReport? _serviceReport; ServiceReport? _serviceReport;
bool _isLoading = false; bool _isLoading = false;
bool isCurrentUserIsAssignedEmployee = false;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>(); final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _workingHoursController = TextEditingController(); final TextEditingController _workingHoursController = TextEditingController();
@ -51,18 +50,15 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
@override @override
void initState() { void initState() {
_serviceReport = ServiceReport(
// returnToService: DateTime.now(),
// //type: const Lookup(value: 2),
// device: widget.request.device,
sparePartsWorkOrders: [],
);
_activityStatusProvider = Provider.of<ActivityStatusProvider>(context, listen: false); _activityStatusProvider = Provider.of<ActivityStatusProvider>(context, listen: false);
_requestDetailProvider = Provider.of<RequestDetailProvider>(context, listen: false); _requestDetailProvider = Provider.of<RequestDetailProvider>(context, listen: false);
_requestDetailProvider?.activityMaintenanceHelperModel?.assignedEmployee = _requestDetailProvider?.currentWorkOrder?.data?.assignedEmployee;
_requestDetailProvider?.activityMaintenanceHelperModel?.workOrderId = _requestDetailProvider?.currentWorkOrder?.data?.requestId;
_requestDetailProvider?.activityMaintenanceHelperModel?.lastSituationId = _requestDetailProvider?.currentWorkOrder?.data?.status?.id;
super.initState(); super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) { WidgetsBinding.instance.addPostFrameCallback((_) {
getInitialData();
}); });
// _isLoading = true; // _isLoading = true;
} }
@ -74,15 +70,7 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
super.dispose(); super.dispose();
} }
Future<void> getInitialData() async {
_activityStatusProvider?.getDate();
Provider.of<ServiceReportRepairLocationProvider>(context, listen: false).getTypes();
final user = Provider.of<UserProvider>(context).user!;
isCurrentUserIsAssignedEmployee = (user.userID != _requestDetailProvider?.currentWorkOrder?.data?.assignedEmployee?.userId);
if (isCurrentUserIsAssignedEmployee) {
// _subWorkOrders.assistantEmployees = [widget.workOrder.assistantEmployees?.first?.copyWith(id: 0)];
}
}
void getRequestForWorkOrder() async { void getRequestForWorkOrder() async {
_isLoading = true; _isLoading = true;
@ -99,168 +87,149 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) { return Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) {
return LoadingManager( return SingleChildScrollView(
isLoading: _isLoading, child: Column(
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
child: Stack(
children: [ children: [
SingleChildScrollView( Form(
key: _formKey,
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
Form( SingleItemDropDownMenu<Lookup, ActivityStatusProvider>(
key: _formKey, context: context,
child: Column( height: 56.toScreenHeight,
crossAxisAlignment: CrossAxisAlignment.stretch, title: context.translation.activityStatus,
children: [ showShadow: false,
SingleItemDropDownMenu<Lookup, ActivityStatusProvider>( backgroundColor: AppColor.neutral100,
context: context, initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus,
height: 56.toScreenHeight, onSelect: (status) {
title: context.translation.activityStatus, requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status;
showShadow: false, },
backgroundColor: AppColor.neutral100, ),
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus, 8.height,
onSelect: (status) { Row(
requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status; mainAxisSize: MainAxisSize.min,
}, children: [
), ADatePicker(
8.height, label: context.translation.startTime,
Row( hideShadow: true,
mainAxisSize: MainAxisSize.min, backgroundColor: AppColor.neutral100,
children: [ date: requestDetailProvider.activityMaintenanceHelperModel?.startTime,
ADatePicker( formatDateWithTime: true,
label: context.translation.startTime, onDatePicker: (selectedDate) {
hideShadow: true, showTimePicker(
backgroundColor: AppColor.neutral100, context: context,
date: requestDetailProvider.activityMaintenanceHelperModel?.startTime, initialTime: TimeOfDay.now(),
formatDateWithTime: true, ).then((selectedTime) {
onDatePicker: (selectedDate) { // Handle the selected date and time here.
showTimePicker( if (selectedTime != null) {
context: context, DateTime selectedDateTime = DateTime(
initialTime: TimeOfDay.now(), selectedDate.year,
).then((selectedTime) { selectedDate.month,
// Handle the selected date and time here. selectedDate.day,
if (selectedTime != null) { selectedTime.hour,
DateTime selectedDateTime = DateTime( selectedTime.minute,
selectedDate.year, );
selectedDate.month, requestDetailProvider.activityMaintenanceHelperModel?.startTime = selectedDateTime;
selectedDate.day, requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
selectedTime.hour, assignWorkingHours(requestDetailProvider: requestDetailProvider);
selectedTime.minute, }
); });
requestDetailProvider.activityMaintenanceHelperModel?.startTime = selectedDateTime; },
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); ).expanded,
assignWorkingHours(requestDetailProvider: requestDetailProvider); 8.width,
} ADatePicker(
}); label: context.translation.endTime,
}, hideShadow: true,
).expanded, backgroundColor: AppColor.neutral100,
8.width, date: requestDetailProvider.activityMaintenanceHelperModel?.endTime,
ADatePicker( formatDateWithTime: true,
label: context.translation.endTime, onDatePicker: (selectedDate) {
hideShadow: true, showTimePicker(
backgroundColor: AppColor.neutral100, context: context,
date: requestDetailProvider.activityMaintenanceHelperModel?.endTime, initialTime: TimeOfDay.now(),
formatDateWithTime: true, ).then((selectedTime) {
onDatePicker: (selectedDate) { // Handle the selected date and time here.
showTimePicker( if (selectedTime != null) {
context: context, DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute);
initialTime: TimeOfDay.now(), if (requestDetailProvider.activityMaintenanceHelperModel!.startTime != null &&
).then((selectedTime) { selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.startTime!)) {
// Handle the selected date and time here. "End Date time must be greater then start date".showToast;
if (selectedTime != null) { return;
DateTime selectedDateTime = DateTime(selectedDate.year, selectedDate.month, selectedDate.day, selectedTime.hour, selectedTime.minute); }
if (requestDetailProvider.activityMaintenanceHelperModel!.startTime != null && requestDetailProvider.activityMaintenanceHelperModel?.endTime = selectedDateTime;
selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.startTime!)) { requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
"End Date time must be greater then start date".showToast; assignWorkingHours(requestDetailProvider: requestDetailProvider);
return; }
} });
requestDetailProvider.activityMaintenanceHelperModel?.endTime = selectedDateTime; },
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel); ).expanded,
assignWorkingHours(requestDetailProvider: requestDetailProvider); ],
} ),
}); 8.height,
}, AppTextFormField(
).expanded, labelText: context.translation.workingHours,
], backgroundColor: AppColor.neutral80,
), controller: _workingHoursController,
8.height, suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
AppTextFormField( initialValue: requestDetailProvider.activityMaintenanceHelperModel?.workingHour != null ? requestDetailProvider.activityMaintenanceHelperModel?.workingHour.toString() : '',
labelText: context.translation.workingHours, textAlign: TextAlign.center,
backgroundColor: AppColor.neutral80, labelStyle: AppTextStyles.textFieldLabelStyle,
controller: _workingHoursController, enable: false,
suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16), showShadow: false,
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.workingHour.toString(), style: Theme.of(context).textTheme.titleMedium,
textAlign: TextAlign.center, ),
labelStyle: AppTextStyles.textFieldLabelStyle, 8.height,
enable: false, AppTextFormField(
showShadow: false, labelText: context.translation.travelingHours,
style: Theme.of(context).textTheme.titleMedium, backgroundColor: AppColor.neutral100,
), showShadow: false,
8.height, labelStyle: AppTextStyles.textFieldLabelStyle,
AppTextFormField( suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
labelText: context.translation.travelingHours, initialValue: requestDetailProvider.activityMaintenanceHelperModel?.travelHours?.toString(),
backgroundColor: AppColor.neutral100, textInputType: TextInputType.number,
showShadow: false, onChange: (value) {
labelStyle: AppTextStyles.textFieldLabelStyle, requestDetailProvider.activityMaintenanceHelperModel?.travelHours = int.tryParse(value);
suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16), },
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.travelHours?.toString(), // contentPadding: EdgeInsets.symmetric(vertical: 18.toScreenHeight, horizontal: 16.toScreenWidth),
textInputType: TextInputType.number, onSaved: (value) {
onChange: (value) { requestDetailProvider.activityMaintenanceHelperModel?.travelHours = value as int?;
requestDetailProvider.activityMaintenanceHelperModel?.travelHours = int.tryParse(value); },
}, ),
// contentPadding: EdgeInsets.symmetric(vertical: 18.toScreenHeight, horizontal: 16.toScreenWidth), 16.height,
onSaved: (value) { repairLocationWidget(context, requestDetailProvider),
requestDetailProvider.activityMaintenanceHelperModel?.travelHours = value as int?; 16.height,
}, AppTextFormField(
), labelText: context.translation.assignedEmployee,
16.height, backgroundColor: AppColor.neutral80,
repairLocationWidget(context, requestDetailProvider), initialValue: requestDetailProvider.activityMaintenanceHelperModel?.assignedEmployee?.userName,
16.height, textAlign: TextAlign.center,
AppTextFormField( labelStyle: AppTextStyles.textFieldLabelStyle,
labelText: context.translation.assignedEmployee, showShadow: false,
backgroundColor: AppColor.neutral80, enable: false,
initialValue: _serviceReport?.assignedEmployee?.name.toString(), style: Theme.of(context).textTheme.titleMedium,
textAlign: TextAlign.center, ),
labelStyle: AppTextStyles.textFieldLabelStyle, 8.height,
showShadow: false, AppTextFormField(
enable: false, initialValue: requestDetailProvider.activityMaintenanceHelperModel?.technicalComment,
style: Theme.of(context).textTheme.titleMedium, labelText: context.translation.technicalComment,
), backgroundColor: AppColor.neutral100,
8.height, showShadow: false,
AppTextFormField( labelStyle: AppTextStyles.textFieldLabelStyle,
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.technicalComment, alignLabelWithHint: true,
labelText: context.translation.technicalComment, textInputType: TextInputType.multiline,
backgroundColor: AppColor.neutral100, onChange: (value) {
showShadow: false, requestDetailProvider.activityMaintenanceHelperModel?.technicalComment = value;
labelStyle: AppTextStyles.textFieldLabelStyle, },
alignLabelWithHint: true, onSaved: (value) {
textInputType: TextInputType.multiline, requestDetailProvider.activityMaintenanceHelperModel?.technicalComment = value;
onChange: (value) { },
requestDetailProvider.activityMaintenanceHelperModel?.technicalComment = value; ),
},
onSaved: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.technicalComment = value;
},
),
],
),
).toShadowContainer(context).paddingOnly(start: 13, end: 14, top: 12),
const AssistantEmployeeCard().paddingOnly(start: 13, end: 14, top: 12),
100.height,
], ],
), ),
), ).toShadowContainer(context).paddingOnly(start: 13, end: 14, top: 12),
FooterActionButton.footerContainer( const AssistantEmployeeCard().toShadowContainer(context,paddingObject: const EdgeInsets.symmetric(horizontal: 16)).paddingOnly(start: 13, end: 14, top: 12),
child: AppFilledButton( 100.height,
label: context.translation.addInternalActivity, // Use the dynamic label
buttonColor: AppColor.primary10,
onPressed: () async {
// Handle button press
},
),
),
], ],
), ),
); );
@ -336,25 +305,5 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
} }
} }
Future<bool> validate({required ActivityMaintenanceHelperModel model}) async {
if (model.activityStatus == null) {
Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.activityStatus}");
return false;
} else if (model.startTime == null) {
Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.startTime}");
return false;
} else if (model.endTime == null) {
Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.endTime}");
return false;
} else if (model.travelHours == null) {
Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.travelingHours}");
return false;
} else if (model.repairLocation == null) {
Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.repairLocation}");
return false;
}
//write all other missing conditions..
return true;
}
} }

@ -1,10 +1,19 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/status_drop_down/report/service_report_repair_location_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import 'package:test_sa/extensions/int_extensions.dart'; import 'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart'; import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart'; import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/helper_data_models/maintenance_request/activity_maintenance_model.dart';
import 'package:test_sa/new_views/app_style/app_color.dart'; import 'package:test_sa/new_views/app_style/app_color.dart';
import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
import 'package:test_sa/new_views/common_widgets/app_lazy_loading.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart'; import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/service_request_latest/request_detail_provider.dart';
import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/service_request_latest/views/forms/maintenance_request/components/external_request.dart'; import 'package:test_sa/service_request_latest/views/forms/maintenance_request/components/external_request.dart';
import 'package:test_sa/service_request_latest/views/forms/maintenance_request/components/internal_request.dart'; import 'package:test_sa/service_request_latest/views/forms/maintenance_request/components/internal_request.dart';
@ -20,56 +29,132 @@ class _MaintenanceRequestFormState extends State<MaintenanceRequestForm> with Si
@override @override
void initState() { void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
getInitialData();
});
super.initState(); super.initState();
} }
Future<void> getInitialData() async {
Provider.of<ServiceReportRepairLocationProvider>(context, listen: false).getTypes();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Consumer<RequestDetailProvider>(
backgroundColor: AppColor.neutral110,
appBar: DefaultAppBar(title: context.translation.maintenanceRequest), builder: (context,RequestDetailProvider requestDetailProvider, child) {
body: DefaultTabController( return Scaffold(
length: 2, backgroundColor: AppColor.neutral110,
child: Column( appBar: DefaultAppBar(title: context.translation.maintenanceRequest),
mainAxisSize: MainAxisSize.min, body: Stack(
children: <Widget>[ children: [
Container( DefaultTabController(
margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight), length: 2,
decoration: BoxDecoration( child: Column(
color: context.isDark ? AppColor.neutral50 : AppColor.white10, mainAxisSize: MainAxisSize.min,
borderRadius: BorderRadius.circular(10), children: <Widget>[
), Container(
child: TabBar( margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight),
padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth), decoration: BoxDecoration(
labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, color: context.isDark ? AppColor.neutral50 : AppColor.white10,
unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20, borderRadius: BorderRadius.circular(10),
unselectedLabelStyle: AppTextStyles.bodyText, ),
labelStyle: AppTextStyles.bodyText, child: TabBar(
indicatorPadding: EdgeInsets.zero, padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth),
indicatorSize: TabBarIndicatorSize.tab, labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
dividerColor: Colors.transparent, unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
indicator: BoxDecoration( unselectedLabelStyle: AppTextStyles.bodyText,
color: context.isDark ? AppColor.neutral60 : AppColor.neutral110, labelStyle: AppTextStyles.bodyText,
borderRadius: BorderRadius.circular(7), indicatorPadding: EdgeInsets.zero,
indicatorSize: TabBarIndicatorSize.tab,
dividerColor: Colors.transparent,
indicator: BoxDecoration(
color: context.isDark ? AppColor.neutral60 : AppColor.neutral110,
borderRadius: BorderRadius.circular(7),
),
tabs: [
Tab(text: context.translation.internal, height: 57.toScreenHeight),
Tab(text: context.translation.external, height: 57.toScreenHeight),
],
),
),
// 12.height,
const TabBarView(
children: [
InternalMaintenanceRequest(),
ExternalMaintenanceRequest(),
],
).expanded,
],
), ),
tabs: [
Tab(text: context.translation.internal, height: 57.toScreenHeight),
Tab(text: context.translation.external, height: 57.toScreenHeight),
],
), ),
), FooterActionButton.footerContainer(
// 12.height, child: AppFilledButton(
const TabBarView( label: context.translation.addActivity, // Use the dynamic label
children: [ buttonColor: AppColor.primary10,
InternalMaintenanceRequest(), onPressed: () async {
ExternalMaintenanceRequest(), //TODO add this as dropdown not added in design yet Bhaa need to confirm with hussain then.
], requestDetailProvider.activityMaintenanceHelperModel?.lastSituationId=282;
).expanded,
print('model to add is ${requestDetailProvider.activityMaintenanceHelperModel?.toJson()}');
if(validate(model: requestDetailProvider.activityMaintenanceHelperModel!)){
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
int status = -1;
// if (requestDetailProvider.activityMaintenanceHelperModel?.id == 0) {
status = await requestDetailProvider.createActivityMaintenanceRequest();
// } else {
// //TODO update logic...
// status = await requestDetailProvider.updateActivityMaintenance();
// }
if (status == 200) {
//this is for hide the dialoge...
Navigator.pop(context);
Navigator.pop(context);
} else {
Navigator.pop(context);
}
}
],
), // Handle button press
), },
),
),
],
),
);
}
); );
} }
bool validate({required ActivityMaintenanceHelperModel model}) {
print('employee id is ${model.assignedEmployeeId}');
if (model.activityStatus == null) {
Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.activityStatus}");
return false;
} else if (model.startTime == null) {
Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.startTime}");
return false;
} else if (model.endTime == null) {
Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.endTime}");
return false;
}
// else if (model.travelHours == null) {
// Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.travelingHours}");
// return false;
// }
else if (model.repairLocation == null) {
Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.repairLocation}");
return false;
}
// else if (model.assignedEmployeeId == null) {
// Fluttertoast.showToast(msg: "${context.translation.youHaveToSelect} ${context.translation.assignedEmployee}");
// return false;
// }
//write all other missing conditions..
return true;
}
} }

@ -1,18 +1,20 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/context_extension.dart';
import'package:test_sa/extensions/int_extensions.dart'; import'package:test_sa/extensions/int_extensions.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import '../../../models/new_models/assistant_employee.dart'; import '../../../models/new_models/assistant_employee.dart';
import '../../../new_views/app_style/app_color.dart'; import '../../../new_views/app_style/app_color.dart';
class AssistantEmployeeMenu extends StatefulWidget { class AssistantEmployeeMenu extends StatefulWidget {
final List<AssistantEmployees> statuses; final List<AssistantEmployees> statuses;
Color? backgroundColor;
final AssistantEmployees? initialStatus; // Now nullable final AssistantEmployees? initialStatus; // Now nullable
final Function(AssistantEmployees?) onSelect; // Now accepts nullable values final Function(AssistantEmployees?) onSelect; // Now accepts nullable values
final String? title; // Now nullable final String? title; // Now nullable
final bool enable; final bool enable;
const AssistantEmployeeMenu({Key? key, required this.statuses, this.title, required this.onSelect, this.initialStatus, this.enable = true}) : super(key: key); AssistantEmployeeMenu({Key? key, required this.statuses, this.title, required this.onSelect, this.initialStatus,this.backgroundColor, this.enable = true}) : super(key: key);
@override @override
_SingleAssistantEmployeeMenuState createState() => _SingleAssistantEmployeeMenuState(); _SingleAssistantEmployeeMenuState createState() => _SingleAssistantEmployeeMenuState();
@ -63,7 +65,7 @@ Widget build(BuildContext context) {
height: 60.toScreenHeight, height: 60.toScreenHeight,
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth), padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth),
decoration: BoxDecoration( decoration: BoxDecoration(
color: context.isDark ? AppColor.neutral50 : Colors.white, color:widget.backgroundColor ?? (context.isDark ? AppColor.neutral50 : AppColor.neutral120),
borderRadius: BorderRadius.circular(10), borderRadius: BorderRadius.circular(10),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)], boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
), ),
@ -88,6 +90,7 @@ Widget build(BuildContext context) {
), ),
DropdownButton<AssistantEmployees>( DropdownButton<AssistantEmployees>(
value: _selectedStatus, value: _selectedStatus,
dropdownColor: AppColor.white10,
iconSize: 24, iconSize: 24,
isDense: true, isDense: true,
icon: const SizedBox.shrink(), icon: const SizedBox.shrink(),
@ -97,7 +100,7 @@ Widget build(BuildContext context) {
context.translation.select, context.translation.select,
style: Theme.of(context).textTheme.bodyLarge, style: Theme.of(context).textTheme.bodyLarge,
), ),
style: TextStyle(color: Theme.of(context).primaryColor), style: AppTextStyles.bodyText2.copyWith(color: AppColor.black20),
underline: const SizedBox.shrink(), underline: const SizedBox.shrink(),
onChanged: widget.enable onChanged: widget.enable
? (AssistantEmployees? newValue) { // Now accepts nullable values ? (AssistantEmployees? newValue) { // Now accepts nullable values
@ -113,9 +116,7 @@ Widget build(BuildContext context) {
value: value, value: value,
child: Text( child: Text(
value.user?.name ?? "NULL", // Use null-aware operator for user.name value.user?.name ?? "NULL", // Use null-aware operator for user.name
style: Theme.of(context).textTheme.bodyLarge?.copyWith( style: AppTextStyles.bodyText.copyWith(color: AppColor.black20),
color: widget.enable ? Theme.of(context).primaryColor : Colors.grey,
),
), ),
); );
}, },

@ -9,12 +9,13 @@ import '../../../../controllers/providers/api/status_drop_down/report/service_re
class ServiceReportAssistantEmployeeMenu extends StatelessWidget { class ServiceReportAssistantEmployeeMenu extends StatelessWidget {
final Function(AssistantEmployees?) onSelect; final Function(AssistantEmployees?) onSelect;
final AssistantEmployees? initialValue; // Now nullable final AssistantEmployees? initialValue; // Now nullable
Color? backgroundColor;
final String title; final String title;
final num assetId; final num assetId;
final bool enable; final bool enable;
const ServiceReportAssistantEmployeeMenu({Key? key, required this.onSelect, required this.title, required this.initialValue, required this.assetId, this.enable = true}) : super(key: key); ServiceReportAssistantEmployeeMenu({Key? key, required this.onSelect, required this.title, required this.initialValue, required this.assetId, this.backgroundColor, this.enable = true})
: super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -29,8 +30,11 @@ class ServiceReportAssistantEmployeeMenu extends StatelessWidget {
child: AssistantEmployeeMenu( child: AssistantEmployeeMenu(
initialStatus: initialValue, initialStatus: initialValue,
title: title, title: title,
statuses: menuProvider.assistantEmployees ?? [], // Provide an empty list if null statuses: menuProvider.assistantEmployees ?? [],
onSelect: onSelect, // Pass onSelect directly backgroundColor: backgroundColor,
// Provide an empty list if null
onSelect: onSelect,
// Pass onSelect directly
enable: enable, enable: enable,
), ),
); );

@ -225,14 +225,6 @@ packages:
url: "https://pub.dev" url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.1.0"
expansion_tile_card:
dependency: "direct main"
description:
name: expansion_tile_card
sha256: "27ce4cb518f00e21d0f2309aaa6462b26b148e93cee2029a73088cecf42b1eb0"
url: "https://pub.dev"
source: hosted
version: "3.0.0"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:

@ -60,7 +60,6 @@ dependencies:
permission_handler: ^11.3.1 permission_handler: ^11.3.1
rive: ^0.13.13 rive: ^0.13.13
another_flushbar: another_flushbar:
expansion_tile_card: ^3.0.0
pinput: pinput:
audioplayers: ^6.1.0 audioplayers: ^6.1.0
flare_flutter: ^3.0.2 flare_flutter: ^3.0.2

Loading…
Cancel
Save