You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cloudsolutions-atoms/lib/views/pages/user/tasks_request/task_request_view.dart

503 lines
23 KiB
Dart

import 'dart:io';
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/models/new_models/department.dart';
import 'package:test_sa/extensions/text_extensions.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/models/device/asset_transfer.dart';
import 'package:test_sa/models/lookup.dart';
import 'package:test_sa/models/new_models/work_order_detail_model.dart';
import 'package:test_sa/models/timer_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_text_form_field.dart';
import 'package:test_sa/new_views/common_widgets/default_app_bar.dart';
import 'package:test_sa/new_views/common_widgets/single_item_drop_down_menu.dart';
import 'package:test_sa/providers/loading_list_notifier.dart';
import 'package:test_sa/providers/service_request_providers/last_situation_provider.dart';
import 'package:test_sa/service_request_latest/service_request_detail_provider.dart';
import 'package:test_sa/service_request_latest/utilities/service_request_utils.dart';
import 'package:test_sa/service_request_latest/views/components/action_button/footer_action_button.dart';
import 'package:test_sa/views/app_style/sizing.dart';
import 'package:test_sa/views/widgets/date_and_time/date_picker.dart';
import 'package:test_sa/views/widgets/images/multi_image_picker.dart';
import 'package:test_sa/views/widgets/loaders/loading_manager.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';
class TaskRequestForm extends StatefulWidget {
final AssetTransfer model;
const TaskRequestForm({Key? key, required this.model}) : super(key: key);
@override
State<TaskRequestForm> createState() => _TaskRequestFormState();
}
class _TaskRequestFormState extends State<TaskRequestForm> {
final bool _isLoading = false;
final TextEditingController _requestedQuantityController = TextEditingController();
final AssetTransfer _formModel = AssetTransfer();
final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
List<File> _files = [];
bool installationTye = false;
List<Lookup> completedActions = [
Lookup(value: 0, name: 'Physical Check'),
Lookup(value: 1, name: 'Software Update'),
Lookup(value: 0, name: 'Hardware Update'),
];
List<Lookup> impactStatus = [
Lookup(value: 0, name: 'Impacted'),
Lookup(value: 1, name: 'Not Impacted'),
];
Lookup selectedValue = Lookup(value: 0, name: 'Impacted');
@override
void initState() {
_formModel.fromDetails(widget.model);
_files = widget.model.receiverAttachments?.map((e) => File(e.attachmentName!)).toList() ?? [];
super.initState();
}
@override
void dispose() {
_requestedQuantityController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: DefaultAppBar(title: context.translation.taskRequest),
key: _scaffoldKey,
body: SafeArea(
child: LoadingManager(
isLoading: _isLoading,
isFailedLoading: false,
stateCode: 200,
onRefresh: () async {},
child: Form(
key: _formKey,
child: Column(
children: [
SingleChildScrollView(
padding: EdgeInsets.all(12 * AppStyle.getScaleFactor(context)),
child: Column(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
_timerWidget(context, 0, true),
12.height,
installationTye
? Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ADatePicker(
label: context.translation.installationDate,
hideShadow: true,
backgroundColor: AppColor.neutral90,
date: DateTime.now(),
formatDateWithTime: false,
onDatePicker: (selectedDate) {
// Handle the selected date and time here.
DateTime selectedDateTime = DateTime(
selectedDate.year,
selectedDate.month,
selectedDate.day,
);
},
),
12.height,
//TODO replace with provided lookup..
SingleItemDropDownMenu<Lookup, LastSituationProvider>(
context: context,
height: 56.toScreenHeight,
title: context.translation.serialNo,
showShadow: false,
backgroundColor: AppColor.neutral90,
showAsBottomSheet: true,
initialValue: null,
onSelect: (status) {
if (status != null) {
setState(() {});
}
},
),
12.height,
//TODO replace with provided lookup..
SingleItemDropDownMenu<Department, NullableLoadingProvider>(
context: context,
title: context.translation.department,
initialValue: Department(),
enabled: true,
backgroundColor: AppColor.neutral90,
showShadow: false,
staticData: [],
showAsBottomSheet: true,
onSelect: (value) {},
),
],
)
: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
context.translation.completedActions.bodyText(context).custom(color: AppColor.white936),
completedActionWidget(),
16.height,
context.translation.impactStatus.bodyText(context).custom(color: AppColor.white936),
impactStatusWidget(),
]),
12.height,
AppTextFormField(
initialValue: _formModel.receiverComment ?? "",
labelText: context.translation.technicalComment,
textInputType: TextInputType.multiline,
backgroundColor: AppColor.neutral90,
showShadow: false,
alignLabelWithHint: true,
onSaved: (value) {
_formModel.receiverComment = value;
},
),
20.height,
MultiFilesPicker(
label: context.translation.attachFiles,
files: _files,
buttonColor: AppColor.black10,
onlyImages: false,
buttonIcon: 'image-plus'.toSvgAsset(color: AppColor.neutral120),
),
],
).toShadowContainer(context),
16.height,
const AssistantEmployeeCard().toShadowContainer(context, paddingObject: const EdgeInsets.symmetric(horizontal: 16)),
],
),
).expanded,
FooterActionButton.footerContainer(
child: AppFilledButton(
buttonColor: AppColor.green70,
label: context.translation.markAsCompleted,
onPressed: () {},
// buttonColor: AppColor.primary10,
),
),
],
),
),
),
),
);
}
void updateTimer({TimerModel? timer}) {
_formModel.tbsTimer = timer;
// if (timer?.startAt != null && timer?.endAt != null) {
// _formModel.timerModelList = _formModel.timerModelList ?? [];
// _formModel.timerModelList!.add(timer!);
// }
// notifyListeners();
}
Widget completedActionWidget() {
return Column(
children: completedActions.asMap().entries.map((entry) {
int index = entry.key;
Lookup action = entry.value;
return Row(
children: [
Checkbox(
value: action.value == 1,
activeColor: AppColor.blueStatus(context),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
onChanged: (value) {
setState(() {
completedActions[index] = Lookup(value: value! ? 1 : 0, name: action.name);
});
},
),
action.name!
.bodyText(context)
.custom(
color: context.isDark ? AppColor.primary50 : AppColor.neutral50,
)
.expanded,
],
);
}).toList(),
);
}
Widget impactStatusWidget() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, // Aligns to the start
children: impactStatus.map((item) {
return Row(
mainAxisSize: MainAxisSize.min,
children: [
Radio<Lookup>(
value: item,
groupValue: selectedValue,
activeColor: AppColor.blueStatus(context),
visualDensity: VisualDensity.compact,
// Removes extra spacing
onChanged: (value) {
selectedValue = value!;
setState(() {});
},
),
Text(
item.name!,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
color: context.isDark ? AppColor.primary50 : AppColor.neutral50,
),
),
16.width, // Adds spacing between items
],
);
}).toList(),
);
}
Widget _timerWidget(BuildContext context, double totalWorkingHours, bool isTimerEnable) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
AppTimer(
label: context.translation.workingHours,
timer: _formModel.tbsTimer,
width: double.infinity,
enabled: isTimerEnable,
decoration: BoxDecoration(
color: AppColor.neutral90,
borderRadius: BorderRadius.circular(10),
),
timerProgress: (isRunning) {},
onChange: (timer) async {
updateTimer(timer: timer);
return true;
},
),
if (totalWorkingHours > 0.0) ...[
12.height,
Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
'Total Working Time:'.bodyText2(context).custom(color: AppColor.neutral90),
8.width,
Text(
ServiceRequestUtils.formatTimerDuration(totalWorkingHours.round()),
style: AppTextStyles.bodyText.copyWith(color: AppColor.neutral50, fontWeight: FontWeight.w600),
),
],
),
],
],
);
}
}
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 isCurrentUserIsAssistantEmp = false;
bool isExpanded = false;
@override
void initState() {
// TODO: implement initState
WidgetsBinding.instance.addPostFrameCallback((_) {
getInitialData();
});
super.initState();
}
Future<void> getInitialData() async {
final user = Provider.of<UserProvider>(context, listen: false).user!;
ServiceRequestDetailProvider requestDetailProvider = Provider.of<ServiceRequestDetailProvider>(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() {
// TODO: implement dispose
_workingHoursController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Consumer<ServiceRequestDetailProvider>(builder: (context, requestDetailProvider, child) {
return Column(
children: [
SizedBox(
height: 56.toScreenHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
context.translation.assistantEmployee.heading6(context).custom(color: AppColor.black10),
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.neutral100,
initialValue: null,
assetId: 23,
//TODO add check...
// enable: !isCurrentUserIsAssistantEmp,
onSelect: (employee) {
if (employee == null) {
requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [];
} else {
requestDetailProvider.activityMaintenanceHelperModel?.assistantEmployees = [employee.copyWith(id: 0)];
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.user = AssignedEmployee(userId: employee.user?.id, userName: employee.user?.name);
}
},
),
12.height,
Row(
mainAxisSize: MainAxisSize.min,
children: [
ADatePicker(
label: context.translation.startTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
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?.modelAssistantEmployees?.startDate = selectedDateTime;
requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
ServiceRequestUtils.calculateAndAssignWorkingHours(
startTime: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
endTime: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
workingHoursController: _workingHoursController,
updateModel: (hours) {
requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.workingHours = hours;
});
}
});
},
).expanded,
8.width,
ADatePicker(
label: context.translation.endTime,
hideShadow: true,
backgroundColor: AppColor.neutral100,
date: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate,
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,
);
//TODO need to replace with model attributes..
// 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?.modelAssistantEmployees?.endDate = selectedDateTime;
// requestDetailProvider.updateActivityMaintenanceHelperModel(requestDetailProvider.activityMaintenanceHelperModel);
// ServiceRequestUtils.calculateAndAssignWorkingHours(
// startTime: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.startDate,
// endTime: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.endDate,
// workingHoursController: _workingHoursController,
// updateModel: (hours) {
// requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.workingHours = hours;
// });
}
});
},
).expanded,
],
),
12.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?.modelAssistantEmployees?.workingHours != null
? requestDetailProvider.activityMaintenanceHelperModel!.modelAssistantEmployees!.workingHours.toString()
: '',
textAlign: TextAlign.center,
labelStyle: AppTextStyles.textFieldLabelStyle,
enable: false,
showShadow: false,
style: Theme.of(context).textTheme.titleMedium,
),
12.height,
AppTextFormField(
initialValue: requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment,
labelText: context.translation.technicalComment,
backgroundColor: AppColor.neutral100,
showShadow: false,
labelStyle: AppTextStyles.textFieldLabelStyle,
alignLabelWithHint: true,
textInputType: TextInputType.multiline,
onChange: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value;
},
onSaved: (value) {
requestDetailProvider.activityMaintenanceHelperModel?.modelAssistantEmployees?.technicalComment = value;
},
),
16.height,
],
)
: const SizedBox(),
],
);
});
}
}