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
/// for more details check http state manager
/// lib\controllers\http_status_manger\http_status_manger.dart
///
Future<int> getAssistantEmployees(num assetId) async {
if (_loading) return -2;
_loading = true;

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

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

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

@ -88,7 +88,7 @@ class WorkOrderData {
});
int? requestId;
String? workOrderNo;
AssignedEmployee? workOrderCreatedBy;
WorkOrderAssignedEmployee? workOrderCreatedBy;
DateTime? requestedDate;
WorkOrderAsset? asset;
Lookup? assetGroup;
@ -101,7 +101,7 @@ class WorkOrderData {
AssetGroup? department;
int? room;
Lookup? assetType;
AssignedEmployee? assignedEmployee;
WorkOrderAssignedEmployee? assignedEmployee;
String? lastActivityStatus;
Lookup? status;
Lookup? nextStep;
@ -130,12 +130,10 @@ class WorkOrderData {
List<dynamic> activityAssetToBeRetireds;
factory WorkOrderData.fromJson(Map<String, dynamic> json) {
print('activities in json is ${json["activities"]}');
return WorkOrderData(
requestId: json["id"],
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"] ?? ""),
asset: json["asset"] == null ? null : WorkOrderAsset.fromJson(json["asset"]),
assetGroup: json["assetGroup"] == null ? null : Lookup.fromJson(json["assetGroup"]),
@ -148,7 +146,7 @@ class WorkOrderData {
department: json["department"] == null ? null : AssetGroup.fromJson(json["department"]),
room: json["room"],
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"],
status: json["status"] == null ? null : Lookup.fromJson(json["status"]),
nextStep: json["nextStep"] == null ? null : Lookup.fromJson(json["nextStep"]),
@ -297,8 +295,8 @@ class AssetGroup {
};
}
class AssignedEmployee {
AssignedEmployee({
class WorkOrderAssignedEmployee {
WorkOrderAssignedEmployee({
required this.userId,
required this.userName,
required this.email,
@ -310,8 +308,8 @@ class AssignedEmployee {
String? email;
int? languageId;
factory AssignedEmployee.fromJson(Map<String, dynamic> json) {
return AssignedEmployee(
factory WorkOrderAssignedEmployee.fromJson(Map<String, dynamic> json) {
return WorkOrderAssignedEmployee(
userId: json["userId"],
userName: json["userName"],
email: json["email"],
@ -331,7 +329,7 @@ class Activities {
int? id;
int? orderNo;
ActivityStatus? activityStatus;
dynamic activityMaintenance;
ActivityMaintenance? activityMaintenance;
ActivitySparePart? activitySparePart;
String ?activityType;
@ -349,7 +347,9 @@ class Activities {
activityStatus = json['activityStatus'] != null
? ActivityStatus.fromJson(json['activityStatus'])
: null;
activityMaintenance = json['activityMaintenance'];
activityMaintenance = json['activityMaintenance'] != null
? ActivityMaintenance.fromJson(json['activityMaintenance'])
: null;
if(activityMaintenance!=null){
activityType='Maintenance Request';
}
@ -369,10 +369,12 @@ class Activities {
if (activityStatus != null) {
data['activityStatus'] = activityStatus!.toJson();
}
data['activityMaintenance'] = activityMaintenance;
if (activitySparePart != null) {
data['activitySparePart'] = activitySparePart!.toJson();
}
if (activityMaintenance != null) {
data['activityMaintenance'] = activityMaintenance!.toJson();
}
return data;
}
}
@ -391,7 +393,7 @@ class ActivityStatus {
}
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;
@ -509,7 +511,7 @@ class WorkOrderContactPerson {
dynamic extension;
String? email;
dynamic mobilePhone;
AssignedEmployee? contactUser;
WorkOrderAssignedEmployee? contactUser;
factory WorkOrderContactPerson.fromJson(Map<String, dynamic> json) {
return WorkOrderContactPerson(
@ -520,7 +522,7 @@ class WorkOrderContactPerson {
extension: json["extension"],
email: json["email"],
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;
dynamic activityStatus;
DateTime? date;
AssignedEmployee? user;
WorkOrderAssignedEmployee? user;
Lookup? step;
DateTime? fixRemotlyStartTime;
DateTime? fixRemotlyEndTime;
@ -570,7 +572,7 @@ class WorkOrderHistory {
workorderStatus: json["workorderStatus"] == null ? null : Lookup.fromJson(json["workorderStatus"]),
activityStatus: json["activityStatus"],
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"]),
fixRemotlyStartTime: DateTime.tryParse(json["fixRemotlyStartTime"] ?? ""),
fixRemotlyEndTime: DateTime.tryParse(json["fixRemotlyEndTime"] ?? ""),
@ -595,3 +597,176 @@ class WorkOrderHistory {
"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;
}
}
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 {
isLoading = true;
@ -555,7 +577,8 @@ class RequestDetailProvider extends ChangeNotifier {
stateCode = response.statusCode;
print('add sparepart activity response i got is ${response.body}');
if (response.statusCode >= 200 && response.statusCode < 300) {
currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body));
updateCurrentWorkOrder(currentWorkOrder);
notifyListeners();
}
isLoading = false;
@ -577,7 +600,8 @@ class RequestDetailProvider extends ChangeNotifier {
stateCode = response.statusCode;
print('add maintenance activity response i got is ${response.body}');
if (response.statusCode >= 200 && response.statusCode < 300) {
currentWorkOrder = WorkOrderDetail.fromJson(json.decode(response.body));
updateCurrentWorkOrder(currentWorkOrder);
notifyListeners();
}
isLoading = false;

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

@ -46,107 +46,10 @@ class ActivitiesListView extends StatelessWidget {
itemCount: activities.length,
separatorBuilder: (czt, index) => 16.height,
itemBuilder: (context, index) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
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())),
// );
});
if(activities[index].activityMaintenance!=null){
return maintenanceActivityCard(requestDetailProvider: requestDetailProvider, userProvider: userProvider, context: context, activity: activities[index]);
}
return sparePartActivityCard(requestDetailProvider: requestDetailProvider, userProvider: userProvider, context: context, activity: activities[index]);
},
).expanded,
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) {
// print('callids i got is ${workOrder}')
print('callids i got is ${workOrder.requestId}');
print('work order next step value is ${workOrder.nextStep?.toJson()}');
return Column(
crossAxisAlignment: CrossAxisAlignment.start,

@ -1,11 +1,12 @@
import 'package:expansion_tile_card/expansion_tile_card.dart';
import 'package:flutter/material.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/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/common_widgets/app_text_form_field.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> {
final GlobalKey<ExpansionTileCardState> cardA = GlobalKey();
bool status = false;
final TextEditingController _workingHoursController = TextEditingController();
final TextEditingController _workingHoursController = TextEditingController(text: '');
bool isCurrentUserIsAssistantEmp = false;
bool isExpanded = false;
@override
void initState() {
@ -33,7 +36,14 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
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
void dispose() {
@ -45,41 +55,44 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
@override
Widget build(BuildContext context) {
return Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) {
return ExpansionTileCard(
key: cardA,
initialElevation: 0,
borderRadius: BorderRadius.circular(10),
expandedTextColor: AppColor.black20,
shadowColor: AppColor.white10,
baseColor: AppColor.white10,
contentPadding: const EdgeInsets.only(left: 16,right: 16),
expandedColor: AppColor.white10,
duration: Duration.zero,
elevation: 0,
title: context.translation.assistantEmployee.bodyText(context).custom(color: AppColor.black20),
children: <Widget>[
Column(
return Column(
children: [
SizedBox(
height: 56.toScreenHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
context.translation.assistantEmployee.bodyText(context).custom(color: AppColor.black20),
IconButton(onPressed: (){
setState(() {
isExpanded=!isExpanded;
});
}, icon: Icon(isExpanded?Icons.arrow_drop_up_outlined:Icons.arrow_drop_down)),
],),
),
isExpanded? Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// ServiceReportAssistantEmployeeMenu(
// title: context.translation.assignAssistant,
// assetId: widget.workOrder!.callRequest!.asset!.id!.toInt(),
//
// initialValue: (_subWorkOrders.assistantEmployees?.isNotEmpty ?? false) ? _subWorkOrders.assistantEmployees?.first : null,
// // initialValue: !isCurrentAssigned
// // ? (widget.workOrder.assistantEmployees?.first)
// // : (_subWorkOrders.assistantEmployees?.isNotEmpty ?? false)
// // ? _subWorkOrders.assistantEmployees?.first
// // : null,
// enable: !isCurrentUserIsAssistantEmp,
// onSelect: (employee) {
// if (employee == null) {
// _subWorkOrders.assistantEmployees = [];
// } else {
// _subWorkOrders.assistantEmployees = [employee.copyWith(id: 0)];
// }
// },
// ),
ServiceReportAssistantEmployeeMenu(
title: context.translation.select,
backgroundColor: AppColor.neutral100,
assetId: requestDetailProvider.currentWorkOrder!.data!.asset!.id!,
initialValue: (requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.isNotEmpty ?? false)
? requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees?.first
: null,
//TODO add check...
// enable: !isCurrentUserIsAssistantEmp,
onSelect: (employee) {
if (employee == null) {
requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [];
} else {
requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [employee.copyWith(id: 0)];
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.userId = employee.user?.id;
}
},
),
8.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [
@ -87,7 +100,7 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
label: context.translation.startTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.startTime,
date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
@ -103,7 +116,7 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
selectedTime.hour,
selectedTime.minute,
);
requestDetailProvider.activityMaintenanceHelperModel?.startTime = selectedDateTime;
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider);
}
@ -115,7 +128,7 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.endTime,
date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate,
formatDateWithTime: true,
onDatePicker: (selectedDate) {
showTimePicker(
@ -131,11 +144,12 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
selectedTime.hour,
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;
return;
}
requestDetailProvider.activityMaintenanceHelperModel?.endTime = selectedDateTime;
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider);
}
@ -150,7 +164,9 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
backgroundColor: AppColor.neutral80,
controller: _workingHoursController,
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,
labelStyle: AppTextStyles.textFieldLabelStyle,
enable: false,
@ -159,7 +175,7 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
),
8.height,
AppTextFormField(
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.technicalComment,
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment,
labelText: context.translation.technicalComment,
backgroundColor: AppColor.neutral100,
showShadow: false,
@ -167,19 +183,22 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
alignLabelWithHint: true,
textInputType: TextInputType.multiline,
onChange: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.technicalComment = value;
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = 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) {
if (startTime != null && endTime != null) {
Duration difference = endTime.difference(startTime);
@ -192,16 +211,11 @@ class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
}
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) {
_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/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/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/time_picker.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 {
ServiceRequest? _request;
ServiceRequestsProvider ?_serviceRequestsProvider;
ServiceStatusProvider? _assetTypeProvider;
ServiceReport ?_serviceReport;
bool _isLoading = false;
int _selectedValue = 1;
final TextEditingController _workingHoursController = TextEditingController();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _faultController = TextEditingController();
final TextEditingController _workPreformedController = TextEditingController();
final TextEditingController _partQtyController = TextEditingController();
@override
void initState() {
_serviceReport = ServiceReport(
// returnToService: DateTime.now(),
// //type: const Lookup(value: 2),
// device: widget.request.device,
sparePartsWorkOrders: [],
);
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
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>(
builder: (context, RequestDetailProvider requestDetailProvider,child) {
return LoadingManager(
isLoading: _isLoading,
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
child: Stack(
children: [
SingleChildScrollView(
child: Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
return Column(
children: [
Form(
key: _formKey,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SingleItemDropDownMenu<SupplierDetails, VendorProvider>(
context: context,
title: context.translation.supplier,
backgroundColor: AppColor.neutral100,
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: [
//TODO replace with correct component..
SingleItemDropDownMenu<SupplierDetails, VendorProvider>(
SingleItemDropDownMenu<SuppPersons, NullableLoadingProvider>(
context: context,
title: context.translation.supplier,
initialValue: null,
backgroundColor: requestDetailProvider.activityMaintenanceHelperModel?.supplier?.suppliername == null ? AppColor.neutral40 : AppColor.neutral100,
title: context.translation.supplierEngineer,
enabled: requestDetailProvider.activityMaintenanceHelperModel?.supplier?.suppPersons?.isNotEmpty ?? false,
staticData:requestDetailProvider.activityMaintenanceHelperModel?.supplier?.suppPersons,
showAsBottomSheet: true,
onSelect: (supplier) {
if (supplier != null) {
// _subWorkOrders.supplier = supplier;
// log(_subWorkOrders.supplier?.suppPersons?.map((e) => e.personName)?.toString());
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.supEngineer == null ? null : SuppPersons.fromJson(requestDetailProvider.activityMaintenanceHelperModel?.supEngineer?.toJson()),
onSelect: (suppPerson) {
print(suppPerson?.toJson());
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(() {});
}
},
),
SingleItemDropDownMenu<Lookup, NullableLoadingProvider>(
context: context,
).expanded,
8.width,
Container(
height: 56.toScreenHeight,
title: context.translation.supplier,
showShadow: false,
width: 60.toScreenWidth,
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,
staticData: Provider.of<ServiceReportLastCallsProvider>(context).calls,
initialValue: _serviceReport?.calllastSituation,
onSelect: (status) {
_serviceReport?.calllastSituation = status;
date: requestDetailProvider.activityMaintenanceHelperModel?.supplierStartTime,
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,
);
requestDetailProvider.activityMaintenanceHelperModel?.supplierStartTime = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider);
}
});
},
),
8.height,
AppTextFormField(
labelText: context.translation.engineerName,
).expanded,
8.width,
ADatePicker(
label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
initialValue: _serviceReport?.assignedEmployee?.name.toString(),
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
showShadow: false,
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [
ADatePicker(
label: context.translation.startTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.supplierStartTime,
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,
);
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,
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,
],
),
),
).toShadowContainer(context).paddingOnly(start: 16, end: 16, top: 12),
FooterActionButton.footerContainer(
child: AppFilledButton(
label:context.translation.addExternalActivity, // Use the dynamic label
buttonColor: AppColor.primary10,
onPressed: () async {
// Handle button press
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!=null? requestDetailProvider.activityMaintenanceHelperModel?.supplierWorkingHour.toString():'',
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) {
if(startTime!=null&&endTime!=null){
Duration difference = endTime.difference(startTime);

@ -43,7 +43,6 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
ActivityStatusProvider? _activityStatusProvider;
ServiceReport? _serviceReport;
bool _isLoading = false;
bool isCurrentUserIsAssignedEmployee = false;
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final TextEditingController _workingHoursController = TextEditingController();
@ -51,18 +50,15 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
@override
void initState() {
_serviceReport = ServiceReport(
// returnToService: DateTime.now(),
// //type: const Lookup(value: 2),
// device: widget.request.device,
sparePartsWorkOrders: [],
);
_activityStatusProvider = Provider.of<ActivityStatusProvider>(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();
WidgetsBinding.instance.addPostFrameCallback((_) {
getInitialData();
});
// _isLoading = true;
}
@ -74,15 +70,7 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
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 {
_isLoading = true;
@ -99,168 +87,149 @@ class _InternalMaintenanceRequestState extends State<InternalMaintenanceRequest>
@override
Widget build(BuildContext context) {
return Consumer<RequestDetailProvider>(builder: (context, requestDetailProvider, child) {
return LoadingManager(
isLoading: _isLoading,
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
child: Stack(
return SingleChildScrollView(
child: Column(
children: [
SingleChildScrollView(
Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Form(
key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
SingleItemDropDownMenu<Lookup, ActivityStatusProvider>(
context: context,
height: 56.toScreenHeight,
title: context.translation.activityStatus,
showShadow: false,
backgroundColor: AppColor.neutral100,
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus,
onSelect: (status) {
requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status;
},
),
8.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [
ADatePicker(
label: context.translation.startTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.startTime,
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,
);
requestDetailProvider.activityMaintenanceHelperModel?.startTime = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider);
}
});
},
).expanded,
8.width,
ADatePicker(
label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.endTime,
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!.startTime != null &&
selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.startTime!)) {
"End Date time must be greater then start date".showToast;
return;
}
requestDetailProvider.activityMaintenanceHelperModel?.endTime = 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?.workingHour.toString(),
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
enable: false,
showShadow: false,
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
AppTextFormField(
labelText: context.translation.travelingHours,
backgroundColor: AppColor.neutral100,
showShadow: false,
labelStyle: AppTextStyles.textFieldLabelStyle,
suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.travelHours?.toString(),
textInputType: TextInputType.number,
onChange: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.travelHours = int.tryParse(value);
},
// contentPadding: EdgeInsets.symmetric(vertical: 18.toScreenHeight, horizontal: 16.toScreenWidth),
onSaved: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.travelHours = value as int?;
},
),
16.height,
repairLocationWidget(context, requestDetailProvider),
16.height,
AppTextFormField(
labelText: context.translation.assignedEmployee,
backgroundColor: AppColor.neutral80,
initialValue: _serviceReport?.assignedEmployee?.name.toString(),
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
showShadow: false,
enable: false,
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
AppTextFormField(
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.technicalComment,
labelText: context.translation.technicalComment,
backgroundColor: AppColor.neutral100,
showShadow: false,
labelStyle: AppTextStyles.textFieldLabelStyle,
alignLabelWithHint: true,
textInputType: TextInputType.multiline,
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,
SingleItemDropDownMenu<Lookup, ActivityStatusProvider>(
context: context,
height: 56.toScreenHeight,
title: context.translation.activityStatus,
showShadow: false,
backgroundColor: AppColor.neutral100,
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.activityStatus,
onSelect: (status) {
requestDetailProvider.activityMaintenanceHelperModel?.activityStatus = status;
},
),
8.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [
ADatePicker(
label: context.translation.startTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.startTime,
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,
);
requestDetailProvider.activityMaintenanceHelperModel?.startTime = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
assignWorkingHours(requestDetailProvider: requestDetailProvider);
}
});
},
).expanded,
8.width,
ADatePicker(
label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.endTime,
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!.startTime != null &&
selectedDateTime.isBefore(requestDetailProvider.activityMaintenanceHelperModel!.startTime!)) {
"End Date time must be greater then start date".showToast;
return;
}
requestDetailProvider.activityMaintenanceHelperModel?.endTime = 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?.workingHour != null ? requestDetailProvider.activityMaintenanceHelperModel?.workingHour.toString() : '',
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
enable: false,
showShadow: false,
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
AppTextFormField(
labelText: context.translation.travelingHours,
backgroundColor: AppColor.neutral100,
showShadow: false,
labelStyle: AppTextStyles.textFieldLabelStyle,
suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.travelHours?.toString(),
textInputType: TextInputType.number,
onChange: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.travelHours = int.tryParse(value);
},
// contentPadding: EdgeInsets.symmetric(vertical: 18.toScreenHeight, horizontal: 16.toScreenWidth),
onSaved: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.travelHours = value as int?;
},
),
16.height,
repairLocationWidget(context, requestDetailProvider),
16.height,
AppTextFormField(
labelText: context.translation.assignedEmployee,
backgroundColor: AppColor.neutral80,
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.assignedEmployee?.userName,
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
showShadow: false,
enable: false,
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
AppTextFormField(
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.technicalComment,
labelText: context.translation.technicalComment,
backgroundColor: AppColor.neutral100,
showShadow: false,
labelStyle: AppTextStyles.textFieldLabelStyle,
alignLabelWithHint: true,
textInputType: TextInputType.multiline,
onChange: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.technicalComment = value;
},
onSaved: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.technicalComment = value;
},
),
],
),
),
FooterActionButton.footerContainer(
child: AppFilledButton(
label: context.translation.addInternalActivity, // Use the dynamic label
buttonColor: AppColor.primary10,
onPressed: () async {
// Handle button press
},
),
),
).toShadowContainer(context).paddingOnly(start: 13, end: 14, top: 12),
const AssistantEmployeeCard().toShadowContainer(context,paddingObject: const EdgeInsets.symmetric(horizontal: 16)).paddingOnly(start: 13, end: 14, top: 12),
100.height,
],
),
);
@ -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: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/int_extensions.dart';
import 'package:test_sa/extensions/text_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/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/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/internal_request.dart';
@ -20,56 +29,132 @@ class _MaintenanceRequestFormState extends State<MaintenanceRequestForm> with Si
@override
void initState() {
WidgetsBinding.instance.addPostFrameCallback((_) {
getInitialData();
});
super.initState();
}
Future<void> getInitialData() async {
Provider.of<ServiceReportRepairLocationProvider>(context, listen: false).getTypes();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: AppColor.neutral110,
appBar: DefaultAppBar(title: context.translation.maintenanceRequest),
body: DefaultTabController(
length: 2,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight),
decoration: BoxDecoration(
color: context.isDark ? AppColor.neutral50 : AppColor.white10,
borderRadius: BorderRadius.circular(10),
),
child: TabBar(
padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth),
labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelStyle: AppTextStyles.bodyText,
labelStyle: AppTextStyles.bodyText,
indicatorPadding: EdgeInsets.zero,
indicatorSize: TabBarIndicatorSize.tab,
dividerColor: Colors.transparent,
indicator: BoxDecoration(
color: context.isDark ? AppColor.neutral60 : AppColor.neutral110,
borderRadius: BorderRadius.circular(7),
return Consumer<RequestDetailProvider>(
builder: (context,RequestDetailProvider requestDetailProvider, child) {
return Scaffold(
backgroundColor: AppColor.neutral110,
appBar: DefaultAppBar(title: context.translation.maintenanceRequest),
body: Stack(
children: [
DefaultTabController(
length: 2,
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(left: 16.toScreenWidth, right: 16.toScreenWidth, top: 12.toScreenHeight),
decoration: BoxDecoration(
color: context.isDark ? AppColor.neutral50 : AppColor.white10,
borderRadius: BorderRadius.circular(10),
),
child: TabBar(
padding: EdgeInsets.symmetric(vertical: 4.toScreenHeight, horizontal: 4.toScreenWidth),
labelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelColor: context.isDark ? AppColor.neutral30 : AppColor.black20,
unselectedLabelStyle: AppTextStyles.bodyText,
labelStyle: AppTextStyles.bodyText,
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),
],
),
),
// 12.height,
const TabBarView(
children: [
InternalMaintenanceRequest(),
ExternalMaintenanceRequest(),
],
).expanded,
FooterActionButton.footerContainer(
child: AppFilledButton(
label: context.translation.addActivity, // Use the dynamic label
buttonColor: AppColor.primary10,
onPressed: () async {
//TODO add this as dropdown not added in design yet Bhaa need to confirm with hussain then.
requestDetailProvider.activityMaintenanceHelperModel?.lastSituationId=282;
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:test_sa/extensions/context_extension.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 '../../../new_views/app_style/app_color.dart';
class AssistantEmployeeMenu extends StatefulWidget {
final List<AssistantEmployees> statuses;
Color? backgroundColor;
final AssistantEmployees? initialStatus; // Now nullable
final Function(AssistantEmployees?) onSelect; // Now accepts nullable values
final String? title; // Now nullable
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
_SingleAssistantEmployeeMenuState createState() => _SingleAssistantEmployeeMenuState();
@ -63,7 +65,7 @@ Widget build(BuildContext context) {
height: 60.toScreenHeight,
padding: EdgeInsets.symmetric(horizontal: 16.toScreenWidth),
decoration: BoxDecoration(
color: context.isDark ? AppColor.neutral50 : Colors.white,
color:widget.backgroundColor ?? (context.isDark ? AppColor.neutral50 : AppColor.neutral120),
borderRadius: BorderRadius.circular(10),
boxShadow: [BoxShadow(color: Colors.black.withOpacity(0.05), blurRadius: 10)],
),
@ -88,6 +90,7 @@ Widget build(BuildContext context) {
),
DropdownButton<AssistantEmployees>(
value: _selectedStatus,
dropdownColor: AppColor.white10,
iconSize: 24,
isDense: true,
icon: const SizedBox.shrink(),
@ -97,7 +100,7 @@ Widget build(BuildContext context) {
context.translation.select,
style: Theme.of(context).textTheme.bodyLarge,
),
style: TextStyle(color: Theme.of(context).primaryColor),
style: AppTextStyles.bodyText2.copyWith(color: AppColor.black20),
underline: const SizedBox.shrink(),
onChanged: widget.enable
? (AssistantEmployees? newValue) { // Now accepts nullable values
@ -113,9 +116,7 @@ Widget build(BuildContext context) {
value: value,
child: Text(
value.user?.name ?? "NULL", // Use null-aware operator for user.name
style: Theme.of(context).textTheme.bodyLarge?.copyWith(
color: widget.enable ? Theme.of(context).primaryColor : Colors.grey,
),
style: AppTextStyles.bodyText.copyWith(color: AppColor.black20),
),
);
},

@ -9,12 +9,13 @@ import '../../../../controllers/providers/api/status_drop_down/report/service_re
class ServiceReportAssistantEmployeeMenu extends StatelessWidget {
final Function(AssistantEmployees?) onSelect;
final AssistantEmployees? initialValue; // Now nullable
Color? backgroundColor;
final String title;
final num assetId;
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
Widget build(BuildContext context) {
@ -29,8 +30,11 @@ class ServiceReportAssistantEmployeeMenu extends StatelessWidget {
child: AssistantEmployeeMenu(
initialStatus: initialValue,
title: title,
statuses: menuProvider.assistantEmployees ?? [], // Provide an empty list if null
onSelect: onSelect, // Pass onSelect directly
statuses: menuProvider.assistantEmployees ?? [],
backgroundColor: backgroundColor,
// Provide an empty list if null
onSelect: onSelect,
// Pass onSelect directly
enable: enable,
),
);

@ -225,14 +225,6 @@ packages:
url: "https://pub.dev"
source: hosted
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:
dependency: transitive
description:

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

Loading…
Cancel
Save