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/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 'controller/ChangeFieldInForm.dart'; import 'controller/ChangeSupplyUsing.dart'; import 'controller/ChangeWorker.dart'; import 'dung/widget_dung_supply.dart'; import 'nursery/widget_worker.dart'; import 'plant/widget_plant_supply.dart'; import 'spraying/widget_spraying_supply.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 activityType; final String title; final int activityId; ActionScreen( {@required this.isEdit, @required this.cropId, @required this.idAction, @required this.title, @required this.activityType, @required this.activityId}); @override _ActionScreenState createState() => _ActionScreenState(); } class _ActionScreenState extends State { var _formKey = GlobalKey(); var pref = LocalPref(); final _executeByController = TextEditingController(); DateTime executeTime = DateTime.now(); List filePaths = []; 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); _executeByController.text = currentFullName ?? ""; } @override void initState() { super.initState(); getSharedPrefs(); changeFileController.initValue(); } _submitForm() async { switch (widget.activityType) { case 'ACTIVE_TYPE_NURSERY': if (Get.find().isChanged) { 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(); } break; case 'ACTIVE_TYPE_PLANTING': case 'ACTIVE_TYPE_FERTILIZE': case 'ACTIVE_TYPE_SPRAYING_PESTICIDES': if (Get.find().isChanged) { Utils.showDialogConfirmSupply(onConfirm: () { Get.back(); _validateInputs(); }); } else { _validateInputs(); } break; default: _validateInputs(); break; } } _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) { print(textFieldControllers[key].text); 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; } //CHECK NURSERY if (widget.activityType == 'ACTIVE_TYPE_NURSERY') { _requestActivity.tbNurseryDetailsDTOList = _nurseryDetails; } else if (widget.activityType == 'ACTIVE_TYPE_PLANTING' || widget.activityType == 'ACTIVE_TYPE_FERTILIZE' || widget.activityType == 'ACTIVE_TYPE_SPRAYING_PESTICIDES') { _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)); }, activityType: widget.activityType, 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)); }, activityType: widget.activityType, 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 ? '${field.description} *' : '${field.description}', hintText: field.description), controller: textFieldControllers[field.id.toString()], onSaved: (newValue) {}, validator: field.isMandatory ? (String value) { return Validators.validateNotNullOrEmpty( value, 'Vui lòng nhập ${field.description}'); } : null, ), ], ); } else if (field.tbControlTypeName == 'number') { return Column( children: [ groupName(field.groupName), WidgetTextFormFieldNumber( hintValue: field.description, labelText: field.isMandatory ? '${field.description} *' : '${field.description}', textController: textFieldControllers[field.id.toString()], onSaved: (newValue) {}, validator: field.isMandatory ? (String value) { return Validators.validNumberOrEmpty( value, 'Vui lòng nhập ${field.description}'); } : null, ), ], ); } else if (field.tbControlTypeName == 'textarea') { return Column( children: [ groupName(field.groupName), TextFieldAreaWidget( hint: field.description, labelText: field.isMandatory ? '${field.description} *' : '${field.description}', controller: textFieldControllers[field.id.toString()], onSaved: (newValue) {}, validator: field.isMandatory ? (String value) { return Validators.validateNotNullOrEmpty( value, 'Vui lòng nhập ${field.description}'); } : null, ), ], ); } else if (field.tbControlTypeName == 'dropdown') { return Column( children: [ groupName(field.groupName), DropdownSupplyWidget( titleName: field.description ?? '', tbSupply: field.tbActivityExtendTypeExternalTable ?? '', tag: field.name, value: field.description, hint: '${field.description} ${field.isMandatory ? '*' : ''}', 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.description, hint: '${field.description} ${field.isMandatory ? '*' : ''}', onPressed: (selectedDate) { valueObjects[field.id.toString()] = selectedDate .convertLocalDateTimeToStringUtcDateTime(); }, validator: field.isMandatory ? (String value) { return Validators.validateNotNullOrEmpty( value, 'Vui lòng nhập ${field.description}'); } : null, ), ], ); } else { return Container(); } }) ], ); } // // GENERATE SUPPLY // Widget generateSupply(String activityType) { switch (activityType) { case 'ACTIVE_TYPE_NURSERY': return WidgetWorker(onChangeWorkers: (nurseryDetails) { _nurseryDetails = nurseryDetails; }); break; case 'ACTIVE_TYPE_PLANTING': return Column( children: [ Container( width: double.infinity, height: 16, color: Colors.grey[200], ), WidgetPlantSupply( currentItems: [], onChangeSupplies: (value) { _supplyUsings = value; }), ], ); break; case 'ACTIVE_TYPE_FERTILIZE': return Column( children: [ Container( width: double.infinity, height: 16, color: Colors.grey[200], ), WidgetDungSupply( currentItems: [], onChangeSupplies: (value) { _supplyUsings = value; }), ], ); break; case 'ACTIVE_TYPE_SPRAYING_PESTICIDES': return Column( children: [ Container( width: double.infinity, height: 16, color: Colors.grey[200], ), WidgetSprayingSupply( currentItems: [], onChangeSupplies: (value) { _supplyUsings = value; }), ], ); break; default: return Container(); break; } } 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((_) { if (widget.activityType == 'ACTIVE_TYPE_PLANTING' || widget.activityType == 'ACTIVE_TYPE_FERTILIZE' || widget.activityType == 'ACTIVE_TYPE_SPRAYING_PESTICIDES') { //list supply Get.find() .changeInitList(_requestActivity.tbSuppliesUsingDetailsDTOs); } else if (widget.activityType == 'ACTIVE_TYPE_NURSERY') { //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)) { dropdownValueName = dropdownData.name; } }); } var commonData = CommonData() ..id = int.tryParse(element.index) ..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()); } }); } }); } 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, actionType: widget.activityType, 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; _requestActivity = state.activityDetail; //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(widget.activityType), 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(); } }