recall and alert type request added

design_3.0_TM_Module_snagsFix
WaseemAbbasi22 2 months ago
parent 630c1533e7
commit ccef98860f

@ -3,14 +3,14 @@ class URLs {
static const String appReleaseBuildNumber = "24"; static const String appReleaseBuildNumber = "24";
static const host1 = "https://atomsm.hmg.com"; // production url // static const host1 = "https://atomsm.hmg.com"; // production url
// static const host1 = "https://atomsmdev.hmg.com"; // local DEV url // static const host1 = "https://atomsmdev.hmg.com"; // local DEV url
// static const host1 = "https://atomsmuat.hmg.com"; // local UAT url static const host1 = "https://atomsmuat.hmg.com"; // local UAT url
// static String _baseUrl = "$_host/mobile"; // static String _baseUrl = "$_host/mobile";
// static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis // static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis
// static final String _baseUrl = "$_host/mobile"; // host local UAT static final String _baseUrl = "$_host/mobile"; // host local UAT
static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM // static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM
static String _host = host1; static String _host = host1;

@ -143,7 +143,7 @@ class AllRequestsProvider extends ChangeNotifier {
} }
final type = typeTransaction == null final type = typeTransaction == null
? search?.typeTransaction == null || (search?.typeTransaction?.isEmpty ?? false) ? search?.typeTransaction == null || (search?.typeTransaction?.isEmpty ?? false)
? [1, 2, 3, 4, 5, 6] //added 6 to get task request ... ? [1, 2, 3, 4, 5, 6,7]
: search!.typeTransaction : search!.typeTransaction
: [typeTransaction]; : [typeTransaction];
List<int> status = (search?.statuses == null || (search?.statuses?.isEmpty ?? false)) ? (((search?.isArchived ?? false) ? [3] : [1, 2, 4])) : search!.statuses!; List<int> status = (search?.statuses == null || (search?.statuses?.isEmpty ?? false)) ? (((search?.isArchived ?? false) ? [3] : [1, 2, 4])) : search!.statuses!;

@ -63,7 +63,7 @@ class TaskData {
String? callComment; String? callComment;
List<TaskJobAttachment>? taskJobAttachments; List<TaskJobAttachment>? taskJobAttachments;
TaskContactUser? assignedEngineer; TaskContactUser? assignedEngineer;
List<TaskJobAssistantEmployees>? taskJobAssistantEmployees; List<TaskJobAssistantEmployees>? taskJobAssistantEmployees = [];
TaskJobAssistantEmployees? modelAssistantEmployees; TaskJobAssistantEmployees? modelAssistantEmployees;
List<AssistantEmployees>? assistantEmployees; List<AssistantEmployees>? assistantEmployees;
List<TaskJobHistory>? taskJobHistories; List<TaskJobHistory>? taskJobHistories;
@ -164,19 +164,6 @@ class TaskData {
json['taskJobAssistantEmployees'].forEach((v) { json['taskJobAssistantEmployees'].forEach((v) {
taskJobAssistantEmployees!.add(TaskJobAssistantEmployees.fromJson(v)); taskJobAssistantEmployees!.add(TaskJobAssistantEmployees.fromJson(v));
}); });
if (taskJobAssistantEmployees != null && taskJobAssistantEmployees!.isNotEmpty) {
assistantEmployees = [
AssistantEmployees.fromJson({
'id': null,
'user': {
'id': taskJobAssistantEmployees?[0].assistantEngineer?.userId,
'name': taskJobAssistantEmployees?[0].assistantEngineer?.userName,
}
})
];
}
modelAssistantEmployees = taskJobAssistantEmployees!.isNotEmpty ? taskJobAssistantEmployees!.first : TaskJobAssistantEmployees();
} }
if (json['taskJobActivityEngineerTimers'] != null) { if (json['taskJobActivityEngineerTimers'] != null) {
taskJobActivityEngineerTimers = <TaskJobActivityEngineerTimer>[]; taskJobActivityEngineerTimers = <TaskJobActivityEngineerTimer>[];
@ -293,11 +280,12 @@ class TaskData {
final Map<String, dynamic> data = <String, dynamic>{}; final Map<String, dynamic> data = <String, dynamic>{};
data['id'] = id; data['id'] = id;
data['statusValue'] = statusValue; data['statusValue'] = statusValue;
if (assistantEmployees != null && assistantEmployees!.isNotEmpty) { if (taskJobAssistantEmployees != null && taskJobAssistantEmployees!.isNotEmpty) {
data['taskJobAssistantEmployees'] = [modelAssistantEmployees?.toJson()]; data['taskJobAssistantEmployees'] = taskJobAssistantEmployees;
} else { } else {
data['taskJobAssistantEmployees'] = []; data['taskJobAssistantEmployees'] = [];
} }
if (taskJobActivityEngineerTimers != null) { if (taskJobActivityEngineerTimers != null) {
data['taskJobActivityEngineerTimers'] = taskJobActivityEngineerTimers!.map((v) => v.toJson()).toList(); data['taskJobActivityEngineerTimers'] = taskJobActivityEngineerTimers!.map((v) => v.toJson()).toList();
} }
@ -520,10 +508,12 @@ class TaskJobAssistantEmployees {
String? comment; String? comment;
AssignedEmployee? user; AssignedEmployee? user;
AssistantEngineer? assistantEngineer; AssistantEngineer? assistantEngineer;
AssistantEmployees? employee;
TaskJobAssistantEmployees({this.startDate, this.endDate, this.workingHours, this.comment, this.assistantEnginerId, this.user, this.id, this.assistantEngineer}); TaskJobAssistantEmployees({this.startDate, this.endDate, this.workingHours, this.comment, this.assistantEnginerId, this.user, this.id, this.assistantEngineer});
TaskJobAssistantEmployees.fromJson(Map<String, dynamic> json) { TaskJobAssistantEmployees.fromJson(Map<String, dynamic> json) {
Map<String, dynamic> assistEmpData = {};
id = json['id']; id = json['id'];
startDate = json['startDate'] != null ? DateTime.parse(json['startDate']) : null; startDate = json['startDate'] != null ? DateTime.parse(json['startDate']) : null;
endDate = json['endDate'] != null ? DateTime.parse(json['endDate']) : null; endDate = json['endDate'] != null ? DateTime.parse(json['endDate']) : null;
@ -532,8 +522,19 @@ class TaskJobAssistantEmployees {
} else { } else {
workingHours = null; workingHours = null;
} }
comment = json['comment']; comment = json['comment'];
user = json['assistantEnginer'] != null ? AssignedEmployee.fromJson(json['assistantEnginer']) : null; user = json['assistantEnginer'] != null ? AssignedEmployee.fromJson(json['assistantEnginer']) : null;
if (json['assistantEnginer'] != null) {
assistEmpData = {
'id': null,
'user': {
'id': user?.userId,
'name': user?.userName,
},
};
}
employee = AssistantEmployees.fromJson(assistEmpData);
assistantEngineer = json['assistantEnginer'] != null ? AssistantEngineer.fromJson(json['assistantEnginer']) : null; assistantEngineer = json['assistantEnginer'] != null ? AssistantEngineer.fromJson(json['assistantEnginer']) : null;
} }

@ -61,6 +61,7 @@ class _TaskRequestDetailsViewState extends State<TaskRequestDetailsView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
userProvider ??= Provider.of<UserProvider>(context, listen: false); userProvider ??= Provider.of<UserProvider>(context, listen: false);
return Scaffold( return Scaffold(
// appBar: DefaultAppBar(title:taskProvider?.taskRequestModel?.taskType?.id==7?'Recall and Alert Details': context.translation.taskRequest),
appBar: DefaultAppBar(title: context.translation.taskRequest), appBar: DefaultAppBar(title: context.translation.taskRequest),
body: Consumer<TaskRequestProvider>(builder: (context, taskProvider, child) { body: Consumer<TaskRequestProvider>(builder: (context, taskProvider, child) {
TaskData? taskModel = taskProvider.taskRequestModel; TaskData? taskModel = taskProvider.taskRequestModel;
@ -152,7 +153,7 @@ class _TaskRequestDetailsViewState extends State<TaskRequestDetailsView> {
if (taskProvider.taskRequestModel?.taskType?.isInstallation == true) { if (taskProvider.taskRequestModel?.taskType?.isInstallation == true) {
taskProvider.getSiteData(siteId: taskProvider.taskRequestModel?.asset?.siteId); taskProvider.getSiteData(siteId: taskProvider.taskRequestModel?.asset?.siteId);
} }
Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateTaskRequest(taskId: widget.taskId))); Navigator.of(context).push(MaterialPageRoute(builder: (_) => UpdateTaskRequest(taskId: widget.taskId,createdDate: widget.requestDetails?.date,)));
}, },
label: context.translation.updateRequest, label: context.translation.updateRequest,
), ),

@ -12,6 +12,7 @@ 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/helper/utils.dart';
import 'package:test_sa/models/generic_attachment_model.dart'; import 'package:test_sa/models/generic_attachment_model.dart';
import 'package:test_sa/models/lookup.dart'; import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/building.dart'; import 'package:test_sa/models/new_models/building.dart';
@ -37,14 +38,14 @@ import 'package:test_sa/views/widgets/loaders/app_loading.dart';
import 'package:test_sa/views/widgets/loaders/no_data_found.dart'; import 'package:test_sa/views/widgets/loaders/no_data_found.dart';
import 'package:test_sa/views/widgets/status/report/service_report_assistant_employee_menu.dart'; import 'package:test_sa/views/widgets/status/report/service_report_assistant_employee_menu.dart';
import 'package:test_sa/views/widgets/timer/app_timer.dart'; import 'package:test_sa/views/widgets/timer/app_timer.dart';
import '../../../../models/new_models/site.dart'; import '../../../../models/new_models/site.dart';
import '../../../../models/new_models/work_order_detail_model.dart'; import '../../../models/new_models/work_order_detail_model.dart';
class UpdateTaskRequest extends StatefulWidget { class UpdateTaskRequest extends StatefulWidget {
final int taskId; final int taskId;
final String? createdDate;
const UpdateTaskRequest({Key? key, required this.taskId}) : super(key: key); const UpdateTaskRequest({Key? key, required this.taskId, this.createdDate}) : super(key: key);
@override @override
State<UpdateTaskRequest> createState() => _UpdateTaskRequestState(); State<UpdateTaskRequest> createState() => _UpdateTaskRequestState();
@ -58,8 +59,6 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
List<GenericAttachmentModel> attachments = []; List<GenericAttachmentModel> attachments = [];
bool installationType = true; bool installationType = true;
String comments = ''; String comments = '';
List<File> _userAttachments = [];
List<TaskJobAttachment> _readOnlyAttachments = [];
@override @override
void initState() { void initState() {
@ -71,19 +70,15 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
} }
Future<void> assignData() async { Future<void> assignData() async {
//may need to pass model in class parameters.
_taskProvider = Provider.of<TaskRequestProvider>(context, listen: false); _taskProvider = Provider.of<TaskRequestProvider>(context, listen: false);
UserProvider _userProvider = Provider.of<UserProvider>(context, listen: false); UserProvider _userProvider = Provider.of<UserProvider>(context, listen: false);
TaskData? taskModel = _taskProvider?.taskRequestModel;
TaskData? taskModel = _taskProvider!.taskRequestModel; _taskProvider?.refresh();
_userAttachments = _taskProvider?.taskRequestModel?.taskJobAttachments?.where((e) => e.createdBy == _userProvider.user?.userID).map((e) => File(e.name ?? '')).toList() ?? []; if (taskModel?.taskJobAttachments != null) {
_readOnlyAttachments = _taskProvider?.taskRequestModel?.taskJobAttachments?.where((e) => e.createdBy != _userProvider.user?.userID).toList() ?? []; attachments.addAll(
taskModel!.taskJobAttachments!.where((e) => e.createdBy == _userProvider.user?.userID).map((e) => GenericAttachmentModel(id: e.id, name: e.name ?? '')).toList(),
_taskProvider?.updateTaskModel(taskModel); );
if (taskModel != null) {
attachments.addAll(taskModel.taskJobAttachments!.map((e) => GenericAttachmentModel(id:e.id,name:e.name ?? '')).toList());
// if (taskModel.taskType?.isInstallation == true) {
// await _taskProvider!.getSiteData(siteId: taskModel.asset?.siteId);
// }
} }
} }
@ -108,78 +103,90 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
? const ALoading() ? const ALoading()
: taskProvider.taskRequestModel != null : taskProvider.taskRequestModel != null
? Form( ? Form(
key: _formKey, key: _formKey,
child: Column( child: Column(
children: [ children: [
SingleChildScrollView( SingleChildScrollView(
padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)), padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)),
child: Column( child: Column(
children: [ children: [
Column( Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
_timerWidget(context, true, taskProvider), _timerWidget(context, true, taskProvider),
8.height, 8.height,
if (taskProvider.taskRequestModel?.taskType?.isInstallation == true) ...[installationWidget(taskModel: taskProvider.taskRequestModel!)], if (taskProvider.taskRequestModel?.taskType?.isInstallation == true) ...[installationWidget(taskModel: taskProvider.taskRequestModel!)],
if (taskProvider.taskRequestModel?.taskType?.isRecallAndAlert == true) ...[ if (taskProvider.taskRequestModel?.taskType?.isRecallAndAlert == true) ...[
recallAlertTypeWidget(taskModel: taskProvider.taskRequestModel!), recallAlertTypeWidget(taskModel: taskProvider.taskRequestModel!),
],
// if (previousComments.isNotEmpty) ...[
// 'Previous Comments'.bodyText2(context).custom(color: AppColor.neutral50),
// 8.height,
buildPreviousComments(taskProvider: taskProvider),
// 8.height,
// ],
AppTextFormField(
initialValue: "",
labelText: context.translation.technicalComment,
textInputType: TextInputType.multiline,
backgroundColor: AppColor.fieldBgColor(context),
labelStyle: TextStyle(color: AppColor.textColor(context)),
showShadow: false,
alignLabelWithHint: true,
onChange: (value) {
comments = value;
setState(() {});
},
onSaved: (value) {},
),
20.height,
AttachmentPicker(
label: context.translation.attachFiles,
attachment: attachments,
buttonColor: AppColor.black10,
onlyImages: false,
buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120),
),
], ],
).toShadowContainer(context), // if (previousComments.isNotEmpty) ...[
16.height, // 'Previous Comments'.bodyText2(context).custom(color: AppColor.neutral50),
const AssistantEmployeeCard().toShadowContainer(context, paddingObject: const EdgeInsets.symmetric(horizontal: 16)), // 8.height,
], buildPreviousComments(taskProvider: taskProvider),
), // 8.height,
).expanded, // ],
FooterActionButton.footerContainer( AppTextFormField(
context: context, initialValue: "",
child: Row( labelText: context.translation.technicalComment,
mainAxisAlignment: MainAxisAlignment.spaceAround, textInputType: TextInputType.multiline,
children: [ backgroundColor: AppColor.fieldBgColor(context),
AppFilledButton( labelStyle: TextStyle(color: AppColor.textColor(context)),
label: context.translation.save, showShadow: false,
buttonColor: AppColor.white60, alignLabelWithHint: true,
textColor: AppColor.black10, onChange: (value) {
onPressed: () => _updateTask(context: context, status: 0), comments = value;
).expanded, setState(() {});
12.width, },
AppFilledButton( onSaved: (value) {},
label: context.translation.complete, ),
buttonColor: AppColor.primary10, 20.height,
onPressed: () => _updateTask(context: context, status: 1), AttachmentPicker(
).expanded, label: context.translation.attachFiles,
], attachment: attachments,
), buttonColor: AppColor.black10,
onlyImages: false,
buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120),
),
],
).toShadowContainer(context),
16.height,
TaskRequestAssistantEmployeeList(
assetId: taskProvider.taskRequestModel?.asset?.id,
createdDate: widget.createdDate ?? '',
//widget.requestDetails?.date
assistantEmployeeList: taskProvider.taskRequestModel?.taskJobAssistantEmployees,
cardPadding: 0,
onListChanged: (updatedList) {
setState(() {
taskProvider.taskRequestModel?.taskJobAssistantEmployees = updatedList;
});
},
),
// const AssistantEmployeeCard().toShadowContainer(context, paddingObject: const EdgeInsets.symmetric(horizontal: 16)),
],
), ),
], ).expanded,
FooterActionButton.footerContainer(
context: context,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
AppFilledButton(
label: context.translation.save,
buttonColor: AppColor.white60,
textColor: AppColor.black10,
onPressed: () => _updateTask(context: context, status: 0),
).expanded,
12.width,
AppFilledButton(
label: context.translation.complete,
buttonColor: AppColor.primary10,
onPressed: () => _updateTask(context: context, status: 1),
).expanded,
],
),
),
],
), ),
) )
: NoDataFound(message: context.translation.noDataFound).center, : NoDataFound(message: context.translation.noDataFound).center,
@ -199,7 +206,7 @@ class _UpdateTaskRequestState extends State<UpdateTaskRequest> {
showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading()); showDialog(context: context, barrierDismissible: false, builder: (context) => const AppLazyLoading());
List<TaskJobAttachment> attachment = []; List<TaskJobAttachment> attachment = [];
for (var item in attachments) { for (var item in attachments) {
String fileName = ServiceRequestUtils.isLocalUrl(item.name??'') ? ("${item.name??''.split("/").last}|${base64Encode(File(item.name??'').readAsBytesSync())}") :item.name??''; String fileName = ServiceRequestUtils.isLocalUrl(item.name ?? '') ? ("${item.name ?? ''.split("/").last}|${base64Encode(File(item.name ?? '').readAsBytesSync())}") : item.name ?? '';
attachment.add(TaskJobAttachment(id: item.id, name: fileName)); attachment.add(TaskJobAttachment(id: item.id, name: fileName));
} }
taskModel?.taskJobAttachments = attachment; taskModel?.taskJobAttachments = attachment;
@ -608,218 +615,509 @@ bool validate({TaskData? model}) {
} }
} }
if (model?.assistantEmployees != null) { if (model!.taskJobAssistantEmployees?.isNotEmpty ?? false) {
if (model?.modelAssistantEmployees?.startDate == null) { for (int i = 0; i < model.taskJobAssistantEmployees!.length; i++) {
Fluttertoast.showToast(msg: "Please Select Assistant Employee Start Time"); final employee = model.taskJobAssistantEmployees![i];
return false; final position = Utils.getOrdinal(i + 1);
}
if (model?.modelAssistantEmployees?.endDate == null) { if (employee.user == null) {
Fluttertoast.showToast(msg: "Please Select Assistant Employee End Time"); Fluttertoast.showToast(
return false; msg: "Please select the $position assistant employee",
);
return false;
}
if (employee.user?.userId != null) {
if (employee.startDate == null) {
Fluttertoast.showToast(
msg: "Please select start time for assistant employee ${employee.user?.userName}",
);
return false;
}
if (employee.endDate == null) {
Fluttertoast.showToast(
msg: "Please select end time for assistant employee ${employee.user?.userName}",
);
return false;
}
}
} }
} }
return true; return true;
} }
class AssistantEmployeeCard extends StatefulWidget { class TaskRequestAssistantEmployeeList extends StatefulWidget {
const AssistantEmployeeCard({super.key}); final List<TaskJobAssistantEmployees>? assistantEmployeeList;
final ValueChanged<List<TaskJobAssistantEmployees>>? onListChanged;
final double? cardPadding;
final dynamic assetId;
final String createdDate;
const TaskRequestAssistantEmployeeList({
super.key,
this.assistantEmployeeList,
this.onListChanged,
required this.assetId,
this.cardPadding,
required this.createdDate,
});
@override @override
State<AssistantEmployeeCard> createState() => _AssistantEmployeeCardState(); State<TaskRequestAssistantEmployeeList> createState() => _TaskRequestAssistantEmployeeListState();
} }
class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> { class _TaskRequestAssistantEmployeeListState extends State<TaskRequestAssistantEmployeeList> {
bool status = false; late List<TaskJobAssistantEmployees> _list;
final TextEditingController _workingHoursController = TextEditingController(text: ''); late List<TextEditingController> _controllers;
bool isExpanded = false;
TaskData? taskModel;
@override @override
void initState() { void initState() {
TaskRequestProvider taskRequestProvider = Provider.of<TaskRequestProvider>(context, listen: false);
taskModel = taskRequestProvider.taskRequestModel;
super.initState(); super.initState();
_list = List<TaskJobAssistantEmployees>.from(widget.assistantEmployeeList ?? []);
_controllers = _list.map((e) => TextEditingController(text: e.workingHours?.toString() ?? '')).toList();
} }
@override void _addNewEntry() {
void dispose() { setState(() {
// TODO: implement dispose _list.add(TaskJobAssistantEmployees());
_controllers.add(TextEditingController());
});
widget.onListChanged?.call(_list);
}
_workingHoursController.dispose(); void _removeEntry(int index) {
super.dispose(); setState(() {
_list.removeAt(index);
_controllers.removeAt(index);
});
widget.onListChanged?.call(_list);
}
void _updateModel(int index, void Function(TaskJobAssistantEmployees model) updateList, {bool updateController = false}) {
setState(() {
updateList(_list[index]);
});
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Consumer<TaskRequestProvider>(builder: (context, taskRequestProvider, child) { return ListView.builder(
return Column( itemCount: _list.length + 1,
children: [ shrinkWrap: true,
SizedBox( physics: const NeverScrollableScrollPhysics(),
height: 56.toScreenHeight, padding: EdgeInsets.all(widget.cardPadding ?? 16),
child: Row( itemBuilder: (context, index) {
mainAxisAlignment: MainAxisAlignment.spaceBetween, if (index == _list.length) {
return AppFilledButton(
label: "Add Assistant Employee".addTranslation,
maxWidth: true,
textColor: AppColor.textColor(context),
buttonColor: context.isDark ? AppColor.neutral60 : AppColor.white10,
icon: Icon(Icons.add_circle, color: AppColor.blueStatus(context)),
showIcon: true,
onPressed: _addNewEntry,
);
}
return EmployeeCard(
model: _list[index],
assetId: widget.assetId,
index: index,
createdDate: widget.createdDate,
// selectedEmployee: selectedEmployee,
onUpdate: (updateList) => _updateModel(index, updateList),
onRemove: () => _removeEntry(index),
workingHoursController: _controllers[index],
);
},
);
}
}
class EmployeeCard extends StatelessWidget {
final TaskJobAssistantEmployees model;
final int index;
final dynamic assetId;
final String? createdDate;
final void Function(void Function(TaskJobAssistantEmployees model)) onUpdate;
final VoidCallback onRemove;
final TextEditingController workingHoursController;
EmployeeCard({
super.key,
required this.model,
required this.assetId,
required this.index,
required this.onUpdate,
this.createdDate,
required this.onRemove,
required this.workingHoursController,
});
// AssistantEmployees selectedEmployee = AssistantEmployees();
@override
Widget build(BuildContext context) {
return Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
context.translation.assistantEmployee.bodyText(context).custom(color: AppColor.textColor(context)),
Container(
height: 32,
width: 32,
padding: const EdgeInsets.all(6),
child: "trash".toSvgAsset(height: 20, width: 20),
).onPress(onRemove),
],
),
8.height,
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
ServiceReportAssistantEmployeeMenu(
title: context.translation.select,
backgroundColor: AppColor.fieldBgColor(context),
assetId: assetId,
initialValue: model.employee,
onSelect: (employee) {
if (employee != null) {
onUpdate((model) {
model.employee = employee.copyWith(id: 0);
model.user = AssignedEmployee(
userId: employee.user?.id,
userName: employee.user?.name,
);
});
}
},
),
8.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [ children: [
context.translation.assistantEmployee.heading6(context).custom(color: AppColor.textColor(context)), ADatePicker(
Icon(isExpanded ? Icons.keyboard_arrow_up_rounded : Icons.keyboard_arrow_down_rounded), label: context.translation.startTime,
hideShadow: true,
backgroundColor: AppColor.fieldBgColor(context),
date: model.startDate,
formatDateWithTime: true,
from: DateTime.tryParse(createdDate ?? ''),
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
if (selectedTime != null) {
final selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
if (createdDate != null && selectedDateTime.isBefore(DateTime.tryParse(createdDate ?? '')!)) {
"Start time is before the request time.".showToast;
return;
}
if (selectedDateTime.isAfter(DateTime.now())) {
"Start time is after the current time".showToast;
return;
}
onUpdate((model) {
model.startDate = selectedDateTime;
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.fieldBgColor(context),
date: model.endDate,
formatDateWithTime: true,
from: DateTime.tryParse(createdDate ?? ''),
onDatePicker: (selectedDate) {
showTimePicker(
context: context,
initialTime: TimeOfDay.now(),
).then((selectedTime) {
if (selectedTime != null) {
final endDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
selectedTime.hour,
selectedTime.minute,
);
if (!endDateTime.isBefore(DateTime.now())) {
"Please select a time before the current time.".showToast;
return;
}
if (model.startDate == null || !endDateTime.isAfter(model.startDate!)) {
"End date must be after start date".showToast;
return;
}
onUpdate((model) {
model.endDate = endDateTime;
ServiceRequestUtils.calculateAndAssignWorkingHours(
startTime: model.startDate,
endTime: model.endDate,
workingHoursController: workingHoursController,
updateModel: (hours) => model.workingHours = hours,
);
});
}
});
},
).expanded,
], ],
), ),
).onPress(() { 8.height,
setState(() { AppTextFormField(
isExpanded = !isExpanded; labelText: context.translation.workingHours,
}); backgroundColor: AppColor.fieldBgColor(context),
}), controller: workingHoursController,
isExpanded suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
? Column( textAlign: TextAlign.center,
crossAxisAlignment: CrossAxisAlignment.stretch, enable: false,
children: [ showShadow: false,
ServiceReportAssistantEmployeeMenu( labelStyle: AppTextStyles.textFieldLabelStyle,
title: context.translation.select, style: Theme.of(context).textTheme.titleMedium,
backgroundColor: AppColor.fieldBgColor(context), ),
initialValue: (taskModel?.assistantEmployees?.isNotEmpty ?? false) ? taskModel?.assistantEmployees?.first : null, 8.height,
onSelect: (employee) { AppTextFormField(
if (employee == null) { initialValue: model.comment,
taskModel?.assistantEmployees = []; labelText: context.translation.technicalComment,
} else { backgroundColor: AppColor.fieldBgColor(context),
taskModel?.assistantEmployees = [employee.copyWith(id: 0)]; showShadow: false,
taskModel?.modelAssistantEmployees?.user = AssignedEmployee(userId: employee.user?.id, userName: employee.user?.name); labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: context.isDark ? AppColor.white10 : AppColor.black10),
} alignLabelWithHint: true,
}, textInputType: TextInputType.multiline,
), onChange: (value) => onUpdate((model) => model.comment = value),
8.height, // onSaved: (value) => onUpdate((model) => model.technicalComment = value),
Row( ),
mainAxisSize: MainAxisSize.min, 8.height,
children: [ ],
ADatePicker( )
label: context.translation.startTime, ],
hideShadow: true, ).toShadowContainer(context, paddingObject: const EdgeInsets.symmetric(horizontal: 16, vertical: 12)).paddingOnly(bottom: 12);
backgroundColor: AppColor.fieldBgColor(context),
date: taskModel?.modelAssistantEmployees?.startDate,
// from: taskModel?.d,
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 (widget.pickerFromDate != null && selectedDateTime.isBefore(widget.pickerFromDate!)) {
// "Start time is before the request time.".showToast;
// _pickerStartAt = null;
// selectedTime = null;
// return;
// }
if (selectedDateTime.isAfter(DateTime.now())) {
"Start time is after than current time".showToast;
selectedTime = null;
return;
}
taskModel?.modelAssistantEmployees?.startDate = selectedDateTime;
taskRequestProvider.updateTaskModel(taskModel);
ServiceRequestUtils.calculateAndAssignWorkingHours(
startTime: taskModel?.modelAssistantEmployees?.startDate,
endTime: taskModel?.modelAssistantEmployees?.startDate,
workingHoursController: _workingHoursController,
updateModel: (hours) {
taskModel!.modelAssistantEmployees!.workingHours = hours;
});
}
});
},
).expanded,
8.width,
ADatePicker(
label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.fieldBgColor(context),
date: taskModel?.modelAssistantEmployees?.endDate,
enable: taskModel?.modelAssistantEmployees?.startDate != null,
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 (taskModel?.modelAssistantEmployees?.startDate != null && selectedDateTime.isBefore(taskModel!.modelAssistantEmployees!.startDate!)) {
// "End Date time must be greater then start date".showToast;
// return;
// }
selectedDate = selectedDate.add(Duration(hours: selectedTime.hour, minutes: selectedTime.minute));
bool isBeforeCurrentTime = selectedDate.isBefore(DateTime.now());
bool isAfterStartTime = selectedDate.isAfter(taskModel!.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;
}
taskModel?.modelAssistantEmployees?.endDate = selectedDate;
taskRequestProvider.updateTaskModel(taskModel);
ServiceRequestUtils.calculateAndAssignWorkingHours(
startTime: taskModel?.modelAssistantEmployees?.startDate,
endTime: taskModel?.modelAssistantEmployees?.endDate,
workingHoursController: _workingHoursController,
updateModel: (hours) {
taskModel!.modelAssistantEmployees!.workingHours = hours;
});
}
});
},
).expanded,
],
),
8.height,
AppTextFormField(
labelText: context.translation.workingHours,
backgroundColor: AppColor.fieldBgColor(context),
controller: _workingHoursController,
suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
initialValue: taskModel?.modelAssistantEmployees?.workingHours != null ? taskModel!.modelAssistantEmployees!.workingHours?.toStringAsFixed(2) : '',
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)),
enable: false,
showShadow: false,
style: Theme.of(context).textTheme.titleMedium,
),
8.height,
AppTextFormField(
initialValue: taskModel?.modelAssistantEmployees?.comment,
labelText: context.translation.comment,
backgroundColor: AppColor.fieldBgColor(context),
showShadow: false,
labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)),
alignLabelWithHint: true,
textInputType: TextInputType.multiline,
onChange: (value) {
taskModel?.modelAssistantEmployees?.comment = value;
},
onSaved: (value) {
taskModel?.modelAssistantEmployees?.comment = value;
},
),
16.height,
],
)
: const SizedBox(),
],
);
});
} }
} }
// class AssistantEmployeeCard extends StatefulWidget {
// const AssistantEmployeeCard({super.key});
//
// @override
// State<AssistantEmployeeCard> createState() => _AssistantEmployeeCardState();
// }
//
// class _AssistantEmployeeCardState extends State<AssistantEmployeeCard> {
// bool status = false;
// final TextEditingController _workingHoursController = TextEditingController(text: '');
// bool isExpanded = false;
// TaskData? taskModel;
//
// @override
// void initState() {
// TaskRequestProvider taskRequestProvider = Provider.of<TaskRequestProvider>(context, listen: false);
// taskModel = taskRequestProvider.taskRequestModel;
//
// super.initState();
// }
//
// @override
// void dispose() {
// // TODO: implement dispose
//
// _workingHoursController.dispose();
// super.dispose();
// }
//
// @override
// Widget build(BuildContext context) {
// return Consumer<TaskRequestProvider>(builder: (context, taskRequestProvider, child) {
// return Column(
// children: [
// SizedBox(
// height: 56.toScreenHeight,
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// context.translation.assistantEmployee.heading6(context).custom(color: AppColor.textColor(context)),
// Icon(isExpanded ? Icons.keyboard_arrow_up_rounded : Icons.keyboard_arrow_down_rounded),
// ],
// ),
// ).onPress(() {
// setState(() {
// isExpanded = !isExpanded;
// });
// }),
// isExpanded
// ? Column(
// crossAxisAlignment: CrossAxisAlignment.stretch,
// children: [
// ServiceReportAssistantEmployeeMenu(
// title: context.translation.select,
// backgroundColor: AppColor.fieldBgColor(context),
// initialValue: (taskModel?.assistantEmployees?.isNotEmpty ?? false) ? taskModel?.assistantEmployees?.first : null,
// onSelect: (employee) {
// if (employee == null) {
// taskModel?.assistantEmployees = [];
// } else {
// taskModel?.assistantEmployees = [employee.copyWith(id: 0)];
// taskModel?.modelAssistantEmployees?.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.fieldBgColor(context),
// date: taskModel?.modelAssistantEmployees?.startDate,
// // from: taskModel?.d,
// 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 (widget.pickerFromDate != null && selectedDateTime.isBefore(widget.pickerFromDate!)) {
// // "Start time is before the request time.".showToast;
// // _pickerStartAt = null;
// // selectedTime = null;
// // return;
// // }
// if (selectedDateTime.isAfter(DateTime.now())) {
// "Start time is after than current time".showToast;
// selectedTime = null;
// return;
// }
// taskModel?.modelAssistantEmployees?.startDate = selectedDateTime;
// taskRequestProvider.updateTaskModel(taskModel);
// ServiceRequestUtils.calculateAndAssignWorkingHours(
// startTime: taskModel?.modelAssistantEmployees?.startDate,
// endTime: taskModel?.modelAssistantEmployees?.startDate,
// workingHoursController: _workingHoursController,
// updateModel: (hours) {
// taskModel!.modelAssistantEmployees!.workingHours = hours;
// });
// }
// });
// },
// ).expanded,
// 8.width,
// ADatePicker(
// label: context.translation.endTime,
// hideShadow: true,
// backgroundColor: AppColor.fieldBgColor(context),
// date: taskModel?.modelAssistantEmployees?.endDate,
// enable: taskModel?.modelAssistantEmployees?.startDate != null,
// 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 (taskModel?.modelAssistantEmployees?.startDate != null && selectedDateTime.isBefore(taskModel!.modelAssistantEmployees!.startDate!)) {
// // "End Date time must be greater then start date".showToast;
// // return;
// // }
//
// selectedDate = selectedDate.add(Duration(hours: selectedTime.hour, minutes: selectedTime.minute));
// bool isBeforeCurrentTime = selectedDate.isBefore(DateTime.now());
// bool isAfterStartTime = selectedDate.isAfter(taskModel!.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;
// }
//
// taskModel?.modelAssistantEmployees?.endDate = selectedDate;
// taskRequestProvider.updateTaskModel(taskModel);
// ServiceRequestUtils.calculateAndAssignWorkingHours(
// startTime: taskModel?.modelAssistantEmployees?.startDate,
// endTime: taskModel?.modelAssistantEmployees?.endDate,
// workingHoursController: _workingHoursController,
// updateModel: (hours) {
// taskModel!.modelAssistantEmployees!.workingHours = hours;
// });
// }
// });
// },
// ).expanded,
// ],
// ),
// 8.height,
// AppTextFormField(
// labelText: context.translation.workingHours,
// backgroundColor: AppColor.fieldBgColor(context),
// controller: _workingHoursController,
// suffixIcon: "clock".toSvgAsset(width: 20, color: context.isDark ? AppColor.neutral10 : null).paddingOnly(end: 16),
// initialValue: taskModel?.modelAssistantEmployees?.workingHours != null ? taskModel!.modelAssistantEmployees!.workingHours?.toStringAsFixed(2) : '',
// textAlign: TextAlign.center,
// labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)),
// enable: false,
// showShadow: false,
// style: Theme.of(context).textTheme.titleMedium,
// ),
// 8.height,
// AppTextFormField(
// initialValue: taskModel?.modelAssistantEmployees?.comment,
// labelText: context.translation.comment,
// backgroundColor: AppColor.fieldBgColor(context),
// showShadow: false,
// labelStyle: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)),
// alignLabelWithHint: true,
// textInputType: TextInputType.multiline,
// onChange: (value) {
// taskModel?.modelAssistantEmployees?.comment = value;
// },
// onSaved: (value) {
// taskModel?.modelAssistantEmployees?.comment = value;
// },
// ),
// 16.height,
// ],
// )
// : const SizedBox(),
// ],
// );
// });
// }
// }

@ -22,7 +22,8 @@ class AppBottomNavigationBar extends StatelessWidget {
List<NavItemModel> navItems = [ List<NavItemModel> navItems = [
NavItemModel(0, "overview", context.translation.overview), NavItemModel(0, "overview", context.translation.overview),
NavItemModel(1, "request_icon", context.translation.workOrder), NavItemModel(1, "request_icon", context.translation.workOrder),
if (!isEngineer||isUserFMS) //TODO unCommit this to disable task
// if (!isEngineer||isUserFMS)
NavItemModel(2, "add_icon", context.translation.calendar, showLabel: false), NavItemModel(2, "add_icon", context.translation.calendar, showLabel: false),
NavItemModel(3, "assets", context.translation.assets), NavItemModel(3, "assets", context.translation.assets),
NavItemModel(4, "contact", context.translation.contact), NavItemModel(4, "contact", context.translation.contact),

@ -92,13 +92,13 @@ class CreateRequestModel {
list.add(CreateRequestModel(context.translation.correctiveMaintenance, "add_icon", CreateNewRequest.id)); list.add(CreateRequestModel(context.translation.correctiveMaintenance, "add_icon", CreateNewRequest.id));
} }
//TODO uncommit this to enable task. //TODO uncommit this to enable task.
// list.add(CreateRequestModel(context.translation.task, "add_icon", CreateTaskView.id)); list.add(CreateRequestModel(context.translation.task, "add_icon", CreateTaskView.id));
} else { } else {
list.add(CreateRequestModel(context.translation.correctiveMaintenance, "add_icon", CreateNewRequest.id)); list.add(CreateRequestModel(context.translation.correctiveMaintenance, "add_icon", CreateNewRequest.id));
list.add(CreateRequestModel(context.translation.gasRefill, "add_icon", GasRefillRequestForm.routeName)); list.add(CreateRequestModel(context.translation.gasRefill, "add_icon", GasRefillRequestForm.routeName));
list.add(CreateRequestModel(context.translation.transferAsset, "add_icon", CreateDeviceTransferRequest.id)); list.add(CreateRequestModel(context.translation.transferAsset, "add_icon", CreateDeviceTransferRequest.id));
//TODO uncommit this to enable task. //TODO uncommit this to enable task.
// list.add(CreateRequestModel(context.translation.task, "add_icon", CreateTaskView.id)); list.add(CreateRequestModel(context.translation.task, "add_icon", CreateTaskView.id));
} }
return list; return list;
} }

@ -1,6 +1,7 @@
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/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/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';
@ -47,6 +48,7 @@ class _AllRequestsFilterPageState extends State<AllRequestsFilterPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool isEngineer = (Provider.of<UserProvider>(context, listen: false).user?.type) == UsersTypes.engineer; bool isEngineer = (Provider.of<UserProvider>(context, listen: false).user?.type) == UsersTypes.engineer;
bool isUserFMS = Provider.of<SettingProvider>(context, listen: false).isUserFMS;
if (search == null) { if (search == null) {
search = SearchAllRequestsModel( search = SearchAllRequestsModel(
requestNumber: SearchByRequestNumberModel(context, controller: TextEditingController()), requestNumber: SearchByRequestNumberModel(context, controller: TextEditingController()),
@ -64,10 +66,16 @@ class _AllRequestsFilterPageState extends State<AllRequestsFilterPage> {
context.translation.transferAsset: 3, context.translation.transferAsset: 3,
context.translation.preventiveMaintenance: 4, context.translation.preventiveMaintenance: 4,
//TODO unCommit this to enable task. //TODO unCommit this to enable task.
// context.translation.task: 6, context.translation.task: 6,
}; };
if (isEngineer) { if (isEngineer) {
types.addAll({context.translation.recurrentWo: 5}); types[context.translation.recurrentWo] = 5;
}
if (!isUserFMS) {
// replace with translation
types['Recall and Alert'] = 7;
} }
final statuses = { final statuses = {
"All WO": 0, "All WO": 0,

@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:test_sa/controllers/providers/api/all_requests_provider.dart'; import 'package:test_sa/controllers/providers/api/all_requests_provider.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart'; import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/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';
@ -33,6 +34,7 @@ class _MyRequestsPageState extends State<MyRequestsPage> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (_provider == null) { if (_provider == null) {
bool isUserFMS = Provider.of<SettingProvider>(context, listen: false).isUserFMS;
requestsList = [ requestsList = [
Request(null, context.translation.allWorkOrder), Request(null, context.translation.allWorkOrder),
Request(1, context.translation.correctiveMaintenance), Request(1, context.translation.correctiveMaintenance),
@ -44,7 +46,11 @@ class _MyRequestsPageState extends State<MyRequestsPage> {
requestsList.add(Request(5, context.translation.recurrentWo)); requestsList.add(Request(5, context.translation.recurrentWo));
} }
//TODO unCommit this to enable task //TODO unCommit this to enable task
// requestsList.add(Request(6, context.translation.taskRequest)); requestsList.add(Request(6, context.translation.taskRequest));
//after confirm name add this to translation...
if (!isUserFMS) {
requestsList.add(Request(7, 'Recall and Alert'));
}
_provider = Provider.of<AllRequestsProvider>(context, listen: false); _provider = Provider.of<AllRequestsProvider>(context, listen: false);
_provider!.reset(); _provider!.reset();

@ -40,6 +40,8 @@ class RequestItemViewList extends StatelessWidget {
return RecurrentWoItemView(requestDetails: list[index]); return RecurrentWoItemView(requestDetails: list[index]);
case 6: case 6:
return TaskRequestItemView(requestDetails: list[index]); return TaskRequestItemView(requestDetails: list[index]);
case 7:
return TaskRequestItemView(requestDetails: list[index]);
default: default:
Container( Container(
height: 100, height: 100,

@ -43,6 +43,10 @@ class TaskRequestProvider extends ChangeNotifier {
notifyListeners(); notifyListeners();
} }
void refresh() {
notifyListeners();
}
Future<void> addTask({ Future<void> addTask({
required BuildContext context, required BuildContext context,
required AddTaskModel task, required AddTaskModel task,

Loading…
Cancel
Save