multiple assistant employee structure added
parent
ffbe58b6c6
commit
705dff245d
@ -0,0 +1,246 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
import 'package:test_sa/extensions/context_extension.dart';
|
||||||
|
import 'package:test_sa/extensions/int_extensions.dart';
|
||||||
|
import 'package:test_sa/extensions/string_extensions.dart';
|
||||||
|
import 'package:test_sa/extensions/text_extensions.dart';
|
||||||
|
import 'package:test_sa/extensions/widget_extensions.dart';
|
||||||
|
import 'package:test_sa/models/new_models/work_order_detail_model.dart';
|
||||||
|
import 'package:test_sa/modules/cm_module/service_request_detail_provider.dart';
|
||||||
|
import 'package:test_sa/modules/cm_module/utilities/service_request_utils.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_text_form_field.dart';
|
||||||
|
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
|
||||||
|
import 'package:test_sa/views/widgets/status/report/service_report_assistant_employee_menu.dart';
|
||||||
|
|
||||||
|
class AssistantEmployeeList extends StatefulWidget {
|
||||||
|
List<ActivityMaintenanceAssistantEmployees>? assistantEmployeeList;
|
||||||
|
|
||||||
|
AssistantEmployeeList({super.key, this.assistantEmployeeList = const <ActivityMaintenanceAssistantEmployees>[]});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AssistantEmployeeList> createState() => _AssistantEmployeeListState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AssistantEmployeeListState extends State<AssistantEmployeeList> {
|
||||||
|
bool status = false;
|
||||||
|
final TextEditingController _workingHoursController = TextEditingController(text: '');
|
||||||
|
bool isCurrentUserIsAssistantEmp = false;
|
||||||
|
bool isExpanded = false;
|
||||||
|
|
||||||
|
void _addNewEntry() {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
setState(() {
|
||||||
|
widget.assistantEmployeeList!.add(ActivityMaintenanceAssistantEmployees());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _removeEntry(int index) {
|
||||||
|
setState(() {
|
||||||
|
setState(() {
|
||||||
|
widget.assistantEmployeeList!.removeAt(index);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_workingHoursController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Consumer<ServiceRequestDetailProvider>(builder: (context, requestDetailProvider, child) {
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: widget.assistantEmployeeList!.length + 1,
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
|
padding: const EdgeInsets.all(16),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
if (index == widget.assistantEmployeeList!.length) {
|
||||||
|
return Visibility(
|
||||||
|
visible: !requestDetailProvider.isReadOnlyRequest,
|
||||||
|
child: AppFilledButton(
|
||||||
|
label: "Add Assistant Employee".addTranslation,
|
||||||
|
maxWidth: true,
|
||||||
|
textColor: AppColor.black10,
|
||||||
|
buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10,
|
||||||
|
icon: Icon(Icons.add_circle, color: AppColor.blueStatus(context)),
|
||||||
|
showIcon: true,
|
||||||
|
onPressed: _addNewEntry,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ActivityMaintenanceAssistantEmployees model = widget.assistantEmployeeList![index];
|
||||||
|
return employeeCard(model: model, requestDetailProvider: requestDetailProvider, index: index)
|
||||||
|
.toShadowContainer(context, paddingObject: const EdgeInsets.symmetric(horizontal: 16, vertical: 12))
|
||||||
|
.paddingOnly(bottom: 12);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget employeeCard({required ActivityMaintenanceAssistantEmployees model, required ServiceRequestDetailProvider requestDetailProvider, required int index}) {
|
||||||
|
return Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
context.translation.assistantEmployee.bodyText(context).custom(color: AppColor.black20),
|
||||||
|
Container(
|
||||||
|
height: 32,
|
||||||
|
width: 32,
|
||||||
|
padding: const EdgeInsets.all(6),
|
||||||
|
child: "trash".toSvgAsset(height: 20, width: 20),
|
||||||
|
).onPress(() {
|
||||||
|
_removeEntry(index);
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
8.height,
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
children: [
|
||||||
|
ServiceReportAssistantEmployeeMenu(
|
||||||
|
title: context.translation.select,
|
||||||
|
backgroundColor: AppColor.neutral100,
|
||||||
|
assetId: requestDetailProvider.currentWorkOrder!.data!.asset!.id!,
|
||||||
|
initialValue: model.employee,
|
||||||
|
onSelect: (employee) {
|
||||||
|
if (employee != null) {
|
||||||
|
model.employee = employee.copyWith(id: 0);
|
||||||
|
model.user = AssignedEmployee(userId: employee.user?.id, userName: employee.user?.name);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
8.height,
|
||||||
|
Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
ADatePicker(
|
||||||
|
label: context.translation.startTime,
|
||||||
|
hideShadow: true,
|
||||||
|
backgroundColor: AppColor.neutral100,
|
||||||
|
date: model.startDate,
|
||||||
|
formatDateWithTime: true,
|
||||||
|
from: requestDetailProvider.currentWorkOrder?.data?.requestedDate,
|
||||||
|
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.currentWorkOrder?.data?.requestedDate != null && selectedDateTime.isBefore(requestDetailProvider.currentWorkOrder!.data!.requestedDate!)) {
|
||||||
|
"Start time is before the request time.".showToast;
|
||||||
|
selectedTime = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (selectedDateTime.isAfter(DateTime.now())) {
|
||||||
|
"Start time is after than current time".showToast;
|
||||||
|
selectedTime = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// DateTime selectedDateTime = DateTime(
|
||||||
|
// selectedDate.year,
|
||||||
|
// selectedDate.month,
|
||||||
|
// selectedDate.day,
|
||||||
|
// selectedTime.hour,
|
||||||
|
// selectedTime.minute,
|
||||||
|
// );
|
||||||
|
model.startDate = selectedDateTime;
|
||||||
|
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
|
||||||
|
ServiceRequestUtils.calculateAndAssignWorkingHours(
|
||||||
|
startTime: model.startDate,
|
||||||
|
endTime: model.endDate,
|
||||||
|
workingHoursController: _workingHoursController,
|
||||||
|
updateModel: (hours) {
|
||||||
|
model.workingHours = hours;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
).expanded,
|
||||||
|
8.width,
|
||||||
|
ADatePicker(
|
||||||
|
label: context.translation.endTime,
|
||||||
|
hideShadow: true,
|
||||||
|
backgroundColor: AppColor.neutral100,
|
||||||
|
date: model.endDate,
|
||||||
|
from: requestDetailProvider.currentWorkOrder?.data?.requestedDate,
|
||||||
|
formatDateWithTime: true,
|
||||||
|
onDatePicker: (selectedDate) {
|
||||||
|
showTimePicker(
|
||||||
|
context: context,
|
||||||
|
initialTime: TimeOfDay.now(),
|
||||||
|
).then((selectedTime) {
|
||||||
|
// Handle the selected date and time here.
|
||||||
|
if (selectedTime != null) {
|
||||||
|
selectedDate = selectedDate.add(Duration(hours: selectedTime.hour, minutes: selectedTime.minute));
|
||||||
|
bool isBeforeCurrentTime = selectedDate.isBefore(DateTime.now());
|
||||||
|
bool isAfterStartTime = selectedDate.isAfter(requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.startDate!);
|
||||||
|
if (!isBeforeCurrentTime) {
|
||||||
|
"Please select a time before the current time.".showToast;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isAfterStartTime) {
|
||||||
|
"End Date time must be greater then start date".showToast;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
model.endDate = selectedDate;
|
||||||
|
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
|
||||||
|
ServiceRequestUtils.calculateAndAssignWorkingHours(
|
||||||
|
startTime: model.startDate,
|
||||||
|
endTime: model.endDate,
|
||||||
|
workingHoursController: _workingHoursController,
|
||||||
|
updateModel: (hours) {
|
||||||
|
model.workingHours = hours;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
).expanded,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
8.height,
|
||||||
|
AppTextFormField(
|
||||||
|
labelText: context.translation.workingHours,
|
||||||
|
backgroundColor: AppColor.neutral80,
|
||||||
|
controller: _workingHoursController,
|
||||||
|
suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
|
||||||
|
initialValue: model.workingHours != null ? model.workingHours.toString() : '',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
labelStyle: AppTextStyles.textFieldLabelStyle,
|
||||||
|
enable: false,
|
||||||
|
showShadow: false,
|
||||||
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
),
|
||||||
|
8.height,
|
||||||
|
AppTextFormField(
|
||||||
|
initialValue: model.technicalComment,
|
||||||
|
labelText: context.translation.technicalComment,
|
||||||
|
backgroundColor: AppColor.neutral100,
|
||||||
|
showShadow: false,
|
||||||
|
labelStyle: AppTextStyles.textFieldLabelStyle,
|
||||||
|
alignLabelWithHint: true,
|
||||||
|
textInputType: TextInputType.multiline,
|
||||||
|
onChange: (value) {
|
||||||
|
model.technicalComment = value;
|
||||||
|
},
|
||||||
|
onSaved: (value) {
|
||||||
|
model.technicalComment = value;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
8.height,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
// : const SizedBox(),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue