import 'dart:convert'; import 'package:farm_tpf/custom_model/SuppliesUsing.dart'; import 'package:farm_tpf/custom_model/action_form/ActionUIField.dart'; import 'package:farm_tpf/custom_model/action_form/ActionUIForm.dart'; import 'package:farm_tpf/custom_model/action_form/CommonData.dart'; import 'package:farm_tpf/custom_model/action_form/RequestActivity.dart'; import 'package:farm_tpf/data/api/app_exception.dart'; import 'package:farm_tpf/data/repository/repository.dart'; import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart'; import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart'; import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart'; import 'package:farm_tpf/presentation/custom_widgets/dropdown_supply_widget.dart'; import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_action_field_date.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_field_time_picker.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_radio_button.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_text_field_area.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_text_form_field.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart'; import 'package:farm_tpf/presentation/screens/actions/cubit/action_ui_cubit.dart'; import 'package:farm_tpf/presentation/screens/actions/supply_widget.dart'; import 'package:farm_tpf/utils/const_string.dart'; import 'package:farm_tpf/utils/pref.dart'; import 'package:farm_tpf/utils/validators.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:get/get.dart'; import 'package:keyboard_dismisser/keyboard_dismisser.dart'; import 'package:farm_tpf/utils/formatter.dart'; import '../../../utils/local_storage.dart'; import 'controller/ChangeFieldInForm.dart'; import 'controller/ChangeSupplyUsing.dart'; import 'controller/ChangeWorker.dart'; import 'nursery/widget_worker.dart'; import 'state_management_helper/change_dropdown_controller.dart'; import 'state_management_helper/change_file_controller.dart'; import 'util_action.dart'; class ActionScreen extends StatefulWidget { final bool isEdit; final int cropId; final int idAction; final String title; final int activityId; final DateTime? executeDate; ActionScreen({ required this.isEdit, required this.cropId, required this.idAction, required this.title, required this.activityId, this.executeDate, }); @override _ActionScreenState createState() => _ActionScreenState(); } class _ActionScreenState extends State { var _formKey = GlobalKey(); var pref = LocalPref(); final _executeByController = TextEditingController(); DateTime executeTime = DateTime.now(); List filePaths = []; var controller = Get.put(ChangeDropdownController()); var changeFileController = Get.put(ChangeFileController()); Map textFieldControllers = {}; Map valueObjects = {}; var _requestActivity = RequestActivity(); final _repository = Repository(); var _actionUIForm = ActionUIForm(); var _nurseryDetails = []; var _supplyUsings = []; var _previousGroupFieldName = ''; var isValidated = false; Future getSharedPrefs() async { // var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME); var currentFullName = LocalStorage.getString(LocalStorageKey.full_name); _executeByController.text = currentFullName ?? ""; } @override void initState() { super.initState(); getSharedPrefs(); changeFileController.initValue(); if (widget.executeDate != null) { executeTime = widget.executeDate!; } } _submitForm() async { final tbActivityType = _actionUIForm.tbActivityTypeDTO; final isUseSupply = tbActivityType?.isUseSupply ?? false; final isNursery = tbActivityType?.isStart == true && tbActivityType?.position == 1; if (isNursery) { if (Get.find().isChanged ?? false) { Utils.showDialog( title: 'Thông tin người thực hiện chưa cập nhật', message: 'Bạn có muốn cập nhật', textConfirm: 'Tiếp tục', textCancel: 'Xem lại', onConfirm: () { Get.back(); _validateInputs(); }); } else { _validateInputs(); } } else if (isUseSupply) { if (Get.find().isChanged ?? false) { Utils.showDialogConfirmSupply(onConfirm: () { Get.back(); _validateInputs(); }); } else { _validateInputs(); } } else { _validateInputs(); } } _validateInputs() async { if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); try { LoadingDialog.showLoadingDialog(context); filePaths = Get.find().newFiles ?? []; //Create request general model _requestActivity ..tbActivityTypeId = widget.idAction ..tbCropId = widget.cropId; if ((_actionUIForm.activityExtendTypeDTOList ?? []).isNotEmpty) { _requestActivity ..externalTable = _actionUIForm ?.activityExtendTypeDTOList?.first?.externalTable ?? ''; } filePaths = Get.find().newFiles ?? []; textFieldControllers.forEach((key, value) { valueObjects[key] = textFieldControllers[key]?.text ?? ''; }); //tbObjectUpdateDTOList var _objectPrameters = []; if (widget.isEdit) { // Edit if (_requestActivity.tbObjectUpdateDTOList != null) { _requestActivity.tbObjectUpdateDTOList?.forEach((element) { print(valueObjects[element.tbObjectParameterId.toString()]); var updateValue = ''; if (Validators.stringNotNullOrEmpty( valueObjects[element.tbObjectParameterId.toString()] ?? '')) { updateValue = valueObjects[element.tbObjectParameterId.toString()] ?? ''; } else { updateValue = element.index ?? ''; } var objectUpdate = TbObjectUpdateDTO() ..id = element.id ..tbObjectParameterId = element.tbObjectParameterId ..index = updateValue; _objectPrameters.add(objectUpdate); }); _requestActivity.tbObjectUpdateDTOList = _objectPrameters; } } else { //Add new valueObjects.forEach((key, value) { var objectUpdate = TbObjectUpdateDTO() ..tbObjectParameterId = int.tryParse(key) ..index = value; _objectPrameters.add(objectUpdate); }); _requestActivity.tbObjectUpdateDTOList = _objectPrameters; } final tbActivityType = _actionUIForm.tbActivityTypeDTO; final isUseSupply = tbActivityType?.isUseSupply ?? false; final isNursery = tbActivityType?.isStart == true && tbActivityType?.position == 1; //CHECK NURSERY if (isNursery) { _requestActivity.tbNurseryDetailsDTOList = _nurseryDetails; } else if ( // widget.activityType == 'ACTIVE_TYPE_PLANTING' || isUseSupply) { _requestActivity.tbSuppliesUsingDetailsDTOs = _supplyUsings; } //delete images _requestActivity.deletedImages = Get.find().deleteFiles; //convert data to json var activityCommonData = jsonEncode(_requestActivity.toJson()).toString(); print(activityCommonData); if (widget.activityId < 0) { //ADD New _repository.createActionCommon((data) { LoadingDialog.hideLoadingDialog(context); Get.back(result: 'ok'); Utils.showSnackBarSuccess(message: label_add_success); }, (error) { LoadingDialog.hideLoadingDialog(context); Utils.showSnackBarError(message: AppException.handleError(error)); }, activityData: activityCommonData, filePaths: filePaths); } else { //UPDATE _repository.updateActionCommon((data) { LoadingDialog.hideLoadingDialog(context); Get.back(result: 'ok'); Utils.showSnackBarSuccess(message: label_update_success); }, (error) { LoadingDialog.hideLoadingDialog(context); Utils.showSnackBarError(message: AppException.handleError(error)); }, activityData: activityCommonData, filePaths: filePaths); } //ADD NEW //Update } catch (e) { LoadingDialog.hideLoadingDialog(context); print(e.toString()); } } else { // setState(() { isValidated = true; }); } } Widget _btnExecuteTimePicker() { return WidgetFieldDateTimePicker( initDateTime: executeTime, onUpdateDateTime: (selectedDate) { _requestActivity.executeDate = selectedDate.convertLocalDateTimeToStringUtcDateTime(); }); } Widget _executeByField() { return TextFormField( keyboardType: TextInputType.text, decoration: InputDecoration(labelText: "Người thực hiện"), enabled: false, controller: _executeByController, onSaved: (newValue) {}, ); } // // GENERATE DYNAMIC FORM // Widget groupName(String name) { if (_previousGroupFieldName == name || !Validators.stringNotNullOrEmpty(name)) { return SizedBox(); } else { _previousGroupFieldName = name ?? ''; return Container( child: Row( children: [ Container( width: 24, height: 0.5, color: Colors.green, ), Text(' ${name ?? ''} '), Expanded( child: Container( width: 5, height: 0.5, color: Colors.green, ), ), ], ), ); } } Widget generateField(List fields) { return Wrap( children: [ ListView.separated( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: fields.length, separatorBuilder: (context, index) { return SizedBox( height: 8, ); }, itemBuilder: (context, index) { var field = fields[index]; if (field.tbControlTypeName == 'text') { return Column( children: [ groupName(field.groupName ?? ''), TextFormField( keyboardType: TextInputType.text, decoration: InputDecoration( labelText: ((field.isMandatory ?? false) ?? false) ? '${field.name} *' : '${field.name}', hintText: field.name), controller: textFieldControllers[field.id.toString()], onSaved: (newValue) {}, validator: ((field.isMandatory ?? false) ?? false) ? (String? value) { return Validators.validateNotNullOrEmpty( value ?? '', 'Vui lòng nhập ${field.name}', ); } : null, ), ], ); } else if (field.tbControlTypeName == 'number') { return Column( children: [ groupName(field.groupName ?? ''), WidgetTextFormFieldNumber( hintValue: field.name ?? '', labelText: ((field.isMandatory ?? false) ?? false) ? '${field.name} *' : '${field.name}', textController: textFieldControllers[field.id.toString()] ?? TextEditingController(), onSaved: (newValue) {}, validator: ((field.isMandatory ?? false) ?? false) ? (String? value) { return Validators.validNumberOrEmpty( value ?? '', 'Vui lòng nhập ${field.name}', ); } : null, ), ], ); } else if (field.tbControlTypeName == 'textarea') { return Column( children: [ groupName(field.groupName ?? ''), TextFieldAreaWidget( hint: field.name ?? '', labelText: (field.isMandatory ?? false) ? '${field.name} *' : '${field.name}', controller: textFieldControllers[field.id.toString()] ?? TextEditingController(), onSaved: (newValue) {}, validator: (field.isMandatory ?? false) ? (String? value) { return Validators.validateNotNullOrEmpty( value ?? '', 'Vui lòng nhập ${field.name}', ); } : null, ), ], ); } else if (field.tbControlTypeName == 'dropdown') { return Column( children: [ groupName(field.groupName ?? ''), DropdownSupplyWidget( titleName: field.name ?? '', tbSupply: field.tbActivityExtendTypeExternalTable ?? '', tag: field.name ?? '', value: field.name, hint: '${field.name} ${(field.isMandatory ?? false) ? '*' : ''}', condition: field.tbActivityExtendTypeCondition ?? '', invalidMessage: '', onPressed: (commonData) { valueObjects[field.id.toString()] = commonData.id.toString(); }, ), ], ); } else if (field.tbControlTypeName == 'radiobutton') { return Column( children: [ groupName(field.groupName ?? ''), RadioButtonWidget( tag: field.name ?? '', condition: field.tbActivityExtendTypeCondition ?? '', supply: field.tbActivityExtendTypeExternalTable ?? '', onPressed: (commonData) { valueObjects[field.id.toString()] = commonData.id.toString(); }, ), ], ); } else if (field.tbControlTypeName == 'date') { return Column( children: [ groupName(field.groupName ?? ''), FieldDateWidget( tag: field.name ?? '', isValidated: isValidated, value: field.name, hint: '${field.name} ${(field.isMandatory ?? false) ? '*' : ''}', onPressed: (selectedDate) { valueObjects[field.id.toString()] = selectedDate .convertLocalDateTimeToStringUtcDateTime(); }, validator: (field.isMandatory ?? false) ? (String? value) { return Validators.validateNotNullOrEmpty( value ?? '', 'Vui lòng nhập ${field.name}'); } : null, ), ], ); } else { return Container(); } }) ], ); } // // GENERATE SUPPLY // Widget generateSupply({ required String supplyGroup, bool isUseSupply = false, bool isStart = false, int position = 0, required String urlSupply, }) { if (isStart && position == 1) { return WidgetWorker(onChangeWorkers: (nurseryDetails) { _nurseryDetails = nurseryDetails; }); } if (isUseSupply) { return Column( children: [ Container( width: double.infinity, height: 16, color: Colors.grey[200], ), SupplyWidget( currentItems: [], urlSupply: urlSupply, supplyGroup: supplyGroup, onChangeSupplies: (value) { _supplyUsings = value; }), ], ); } return SizedBox.shrink(); } void showDataWhenEdit(BuildContext context) { //Show media try { if (Validators.stringNotNullOrEmpty(_requestActivity.media ?? '')) { BlocProvider.of(context).add( ChangeListMedia( items: UtilAction.convertFilePathToMedia( _requestActivity.media ?? '', ), ), ); } } catch (e) { print(e); } SchedulerBinding.instance.addPostFrameCallback((_) { final tbActivityType = _actionUIForm.tbActivityTypeDTO; final isUseSupply = tbActivityType?.isUseSupply ?? false; final isNursery = tbActivityType?.isStart == true && tbActivityType?.position == 1; if (isUseSupply) { //list supply Get.find() .changeInitList(_requestActivity.tbSuppliesUsingDetailsDTOs ?? []); } else if (isNursery) { //list nursery Get.find() .changeInitList(_requestActivity.tbNurseryDetailsDTOList ?? []); } }); //Show value textfield if (_requestActivity.tbObjectUpdateDTOList != null) { print(textFieldControllers.keys.toList()); _requestActivity.tbObjectUpdateDTOList?.forEach((element) { if (element.tbObjectParameterDTO?.tbControlTypeName == 'text' || element.tbObjectParameterDTO?.tbControlTypeName == 'textarea') { SchedulerBinding.instance.addPostFrameCallback((_) { textFieldControllers[element.tbObjectParameterId.toString()]?.text = element.index ?? ''; }); } else if (element.tbObjectParameterDTO?.tbControlTypeName == 'number') { SchedulerBinding.instance.addPostFrameCallback((_) { textFieldControllers[element.tbObjectParameterId.toString()]?.text = element.index?.formatStringToStringDecimal() ?? ''; }); } else { SchedulerBinding.instance.addPostFrameCallback((_) { if (element.tbObjectParameterDTO?.tbControlTypeName == 'dropdown' || element.tbObjectParameterDTO?.tbControlTypeName ?.toLowerCase() == 'radiobutton') { var dropdownValueName = ''; if ((element.tbObjectParameterDTO ?.tbActivityExtendTypeDropDownDTOList ?? []) .isNotEmpty || element.tbObjectParameterDTO ?.tbActivityExtendTypeDropDownDTOList != null) { element .tbObjectParameterDTO?.tbActivityExtendTypeDropDownDTOList ?.forEach((dropdownData) { if (dropdownData.id == int.tryParse(element.index ?? '-1')) { dropdownValueName = dropdownData.name ?? ''; } }); } var commonData = CommonData() ..id = int.tryParse(element.index ?? '-1') ..name = dropdownValueName; Get.find( tag: element.tbObjectParameterDTO?.name) .change(commonData); } else if (element.tbObjectParameterDTO?.tbControlTypeName == 'date') { Get.find( tag: element.tbObjectParameterDTO?.name) .change( element.index?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now(), ); } }); } }); } else { // } } @override Widget build(BuildContext context) => KeyboardDismisser( gestures: [ GestureType.onTap, GestureType.onPanUpdateDownDirection, ], child: Scaffold( backgroundColor: Colors.white, appBar: AppBarWidget( isBack: true, action: InkWell( child: Text( 'Lưu', style: TextStyle( color: Colors.red, fontWeight: FontWeight.normal), ), onTap: () { FocusScopeNode currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus) { currentFocus.unfocus(); } _submitForm(); }, ), ), body: MultiBlocProvider( providers: [ BlocProvider( create: (context) => ActionUiCubit(repository: Repository()) ..getActionUIForm( actionId: widget.idAction, isEdit: widget.isEdit, activityId: widget.activityId)), BlocProvider( create: (context) => MediaHelperBloc()..add(ChangeListMedia(items: [])), ) ], child: Form( key: _formKey, child: SafeArea( child: BlocBuilder( builder: (context, state) { if (state is ActionUiLoading) { print('loading...'); return Center( child: LoadingListPage(), ); } else if (state is ActionUiSuccess) { _actionUIForm = state.actionUIForm ?? ActionUIForm(); _requestActivity = state.activityDetail ?? RequestActivity(); //CREATE UI _actionUIForm.objectParameterDTOList ?.forEach((element) { //generate controller if (element.tbControlTypeName == 'text' || element.tbControlTypeName == 'number' || element.tbControlTypeName == 'textarea') { var textEditingController = new TextEditingController(); textFieldControllers.putIfAbsent( element.id.toString(), () => textEditingController); } // generate value each parameter valueObjects.putIfAbsent( element.id.toString(), () => ''); }); //SHOW EDIT DATA if (widget.isEdit) { showDataWhenEdit(context); } return SingleChildScrollView( child: Column( children: [ Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ Container( width: double.infinity, child: Text( "Ngày thực hiện *", style: TextStyle( color: Colors.black54, fontSize: 13.0), ), ), _btnExecuteTimePicker(), SizedBox( height: 8.0, ), generateField(_actionUIForm .objectParameterDTOList ?? []), _executeByField(), SizedBox( height: 8.0, ), ], ), ), generateSupply( supplyGroup: _actionUIForm .tbActivityTypeDTO?.supplyGroup ?? '', isUseSupply: _actionUIForm .tbActivityTypeDTO?.isUseSupply ?? false, isStart: _actionUIForm .tbActivityTypeDTO?.isStart ?? false, position: _actionUIForm .tbActivityTypeDTO?.position ?? 0, urlSupply: _actionUIForm .tbActivityTypeDTO?.urlSupply ?? '', ), Container( width: double.infinity, height: 16, color: Colors.grey[200], ), BlocBuilder( builder: (context, state) { if (state is MediaHelperSuccess) { return WidgetMediaPicker( currentItems: state.items, onChangeFiles: (newPathFiles, deletePathFiles) async { Get.find() .change(newPathFiles, deletePathFiles); }); } else { return Center( child: CircularProgressIndicator()); } }), Padding( padding: const EdgeInsets.all(8.0), child: ButtonWidget( title: 'CẬP NHẬT', onPressed: () { FocusScopeNode currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus) { currentFocus.unfocus(); } _submitForm(); }), ), ], ), ); } else if (state is ActionUiFailure) { return Center(child: Text(state.errorString)); } return Container(); }, ), )), ))); @override void dispose() { _executeByController.dispose(); textFieldControllers.forEach((key, value) { textFieldControllers[key]?.dispose(); }); super.dispose(); } }