import 'dart:convert'; import 'package:farm_tpf/custom_model/Spraying.dart'; import 'package:farm_tpf/custom_model/SuppliesUsing.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/widget_loading.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart'; import 'package:farm_tpf/presentation/custom_widgets/widget_text_field_description.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/bloc/action_detail_bloc.dart'; import 'package:farm_tpf/presentation/screens/actions/controller/ChangeFieldInForm.dart'; import 'package:farm_tpf/presentation/screens/actions/controller/ChangeSupplyUsing.dart'; import 'package:farm_tpf/presentation/screens/actions/spraying/widget_spraying_supply.dart'; import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_file_controller.dart'; import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_supply.dart'; import 'package:farm_tpf/utils/const_common.dart'; import 'package:farm_tpf/utils/const_string.dart'; import 'package:farm_tpf/utils/const_style.dart'; import 'package:farm_tpf/utils/pref.dart'; import 'package:farm_tpf/utils/validators.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_datetime_picker/flutter_datetime_picker.dart'; import 'package:get/get.dart'; import 'package:intl/intl.dart'; import 'package:keyboard_dismisser/keyboard_dismisser.dart'; import 'package:pattern_formatter/pattern_formatter.dart'; import 'package:farm_tpf/utils/formatter.dart'; import '../util_action.dart'; class EditActionSprayingScreen extends StatefulWidget { final int cropId; final bool isEdit; final int? activityId; EditActionSprayingScreen({required this.cropId, this.isEdit = false, this.activityId}); @override _EditActionSprayingScreenState createState() => _EditActionSprayingScreenState(); } class _EditActionSprayingScreenState extends State { final GlobalKey _scaffoldKey = GlobalKey(); final _repository = Repository(); GlobalKey _formKey = GlobalKey(); bool _autoValidate = false; Spraying _spraying = Spraying(); var pref = LocalPref(); final _descriptionController = TextEditingController(); final _purposeController = TextEditingController(); final _weatherController = TextEditingController(); final _executeByController = TextEditingController(); final _quarantinePeriodController = TextEditingController(); List suppliesUsing = []; String executeTimeView = ''; DateTime executeTime = DateTime.now(); String resultAtView = ''; DateTime resultAtTime = DateTime.now(); List filePaths = []; var changeFileController = Get.put(ChangeFileController()); Future getSharedPrefs() async { var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME); _executeByController.text = currentFullName ?? ""; } @override void initState() { super.initState(); getSharedPrefs(); changeFileController.initValue(); _spraying.suppliesUsing = []; _spraying.executeDate = executeTime.convertLocalDateTimeToStringUtcDateTime(); executeTimeView = executeTime.displayDateTime_DDMMYYYY_HHmm(); _spraying.cropId = widget.cropId; } _validateInputs() async { if (_formKey.currentState!.validate()) { _formKey.currentState!.save(); LoadingDialog.showLoadingDialog(context); filePaths = Get.find().newFiles; var newSups = []; suppliesUsing.forEach((sup) { var newSup = sup; newSup.suppliesInWarehouseId = sup.tbSuppliesInWarehouseId; newSup.equipmentOfCustomerId = sup.tbEquipmentOfCustomerId; newSups.add(newSup); }); _spraying.suppliesUsing = newSups; _spraying.mediaDel = Get.find().deleteFiles; var activitySpraying = jsonEncode(_spraying.toJson()).toString(); //ADD NEW if (_spraying.activityId == null) { _repository.createAction((value) { LoadingDialog.hideLoadingDialog(context); Get.back(result: value); Utils.showSnackBarSuccess(message: label_add_success); }, (error) { LoadingDialog.hideLoadingDialog(context); Utils.showSnackBarError(message: AppException.handleError(error)); }, apiAddAction: ConstCommon.apiAddSpraying, paramActivity: ConstCommon.paramsActionSpraying, activityAction: activitySpraying, filePaths: filePaths); } else { //UPDATE _repository.updateAction((value) { LoadingDialog.hideLoadingDialog(context); Get.back(result: value); Utils.showSnackBarSuccess(message: label_update_success); }, (error) { LoadingDialog.hideLoadingDialog(context); Utils.showSnackBarError(message: AppException.handleError(error)); }, apiUpdateAction: ConstCommon.apiUpdateSpraying, paramActivity: ConstCommon.paramsActionSpraying, activityAction: activitySpraying, filePaths: filePaths); } } else { _autoValidate = true; } } Widget _btnExecuteTimePicker() { return FlatButton( padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0), onPressed: () { DatePicker.showDateTimePicker(context, showTitleActions: true, onChanged: (date) {}, onConfirm: (date) { setState(() { if (resultAtTime != null && date.isAfter(resultAtTime)) { Utils.showSnackBarWarning(message: label_execute_date_must_after_result_time); } else { executeTime = date; _spraying.executeDate = executeTime.convertLocalDateTimeToStringUtcDateTime(); executeTimeView = executeTime.displayDateTime_DDMMYYYY_HHmm(); } }); }, currentTime: executeTime, locale: LocaleType.vi); }, child: Container( padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0), decoration: const BoxDecoration( border: kBorderTextField, ), child: Row( children: [ Expanded( child: Text( //TODO: check condition executeTimeView == null ? "$executeTime" : executeTimeView, style: const TextStyle(fontSize: 14.0, color: Colors.black87), )), const Icon( Icons.date_range, color: Colors.grey, ), ], ))); } Widget _btnResultAtTimePicker() { return FlatButton( padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0), onPressed: () { DatePicker.showDateTimePicker(context, showTitleActions: true, onChanged: (date) {}, onConfirm: (date) { setState(() { if (executeTime.isAfter(date)) { Utils.showSnackBarWarning(message: label_execute_date_must_after_result_time); } else { resultAtTime = date; _spraying.resultAt = resultAtTime.convertLocalDateTimeToStringUtcDateTime(); resultAtView = resultAtTime.displayDateTime_DDMMYYYY_HHmm(); } }); }, currentTime: resultAtTime, locale: LocaleType.vi); }, child: Container( padding: const EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0), decoration: const BoxDecoration( border: kBorderTextField, ), child: Row( children: [ Expanded( child: Text( resultAtView == null ? "" : resultAtView, style: const TextStyle(fontSize: 14.0, color: Colors.black87), )), const Icon( Icons.date_range, color: Colors.grey, ), ], ))); } Widget _purposeField() { return TextFormField( keyboardType: TextInputType.text, decoration: const InputDecoration(labelText: "Lý do sử dụng"), controller: _purposeController, onSaved: (newValue) { _spraying.purpose = newValue ?? ''; }, ); } Widget _quarantinePeriodField() { return WidgetTextFormFieldNumber( hintValue: "Thời gian cách ly", textController: _quarantinePeriodController, onSaved: (newValue) { _spraying.quarantinePeriod = (newValue ?? '0').parseDoubleThousand(); }, validator: (_) {}, onChanged: (_) {}, ); } Widget _weatherField() { return TextFormField( keyboardType: TextInputType.text, decoration: const InputDecoration(labelText: "Thời tiết"), controller: _weatherController, onSaved: (newValue) { _spraying.weatherConditions = newValue ?? ''; }, ); } Widget _desciptionField() { return TextFieldDescriptionWidget( controller: _descriptionController, onSaved: (newValue) { _spraying.description = newValue; }, ); } Widget _executeByField() { return TextFormField( keyboardType: TextInputType.text, decoration: const InputDecoration(labelText: "Người thực hiện"), enabled: false, controller: _executeByController, onSaved: (newValue) {}, ); } @override Widget build(BuildContext context) => KeyboardDismisser( gestures: [ GestureType.onTap, GestureType.onPanUpdateDownDirection, ], child: Scaffold( backgroundColor: Colors.white, key: _scaffoldKey, appBar: AppBarWidget( isBack: true, action: InkWell( child: const Text( 'Huỷ', style: TextStyle(color: Colors.red, fontWeight: FontWeight.normal), ), onTap: () { if (Get.isSnackbarOpen) Get.back(); Get.back(); }, ), ), body: KeyboardDismisser( child: MultiBlocProvider( providers: [ BlocProvider( create: (context) => ActionDetailBloc(repository: Repository()) ..add( FetchData( isNeedFetchData: widget.isEdit, apiActivity: ConstCommon.apiDetailSpraying, activityId: widget.activityId ?? -1, ), ), ), BlocProvider( create: (context) => MediaHelperBloc()..add(ChangeListMedia(items: [])), ) ], child: Form( key: _formKey, // autovalidate: _autoValidate, child: SafeArea( child: SingleChildScrollView( child: BlocConsumer( listener: (context, state) async { if (state is ActionDetailFailure) { LoadingDialog.hideLoadingDialog(context); } else if (state is ActionDetailSuccess) { LoadingDialog.hideLoadingDialog(context); _spraying = Spraying.fromJson(state.item); _spraying.activityId = widget.activityId ?? -1; _purposeController.text = _spraying.purpose ?? ""; _quarantinePeriodController.text = _spraying.quarantinePeriod?.formatNumtoStringDecimal() ?? ''; _weatherController.text = _spraying.weatherConditions ?? ""; _descriptionController.text = _spraying.description ?? ''; _executeByController.text = _spraying.executeBy ?? ''; executeTime = _spraying.executeDate?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now(); executeTimeView = executeTime.displayDateTime_DDMMYYYY_HHmm(); resultAtTime = _spraying.resultAt?.convertStringServerDateTimeToLocalDateTime() ?? DateTime.now(); resultAtView = resultAtTime.displayDateTime_DDMMYYYY_HHmm(); //Show media if (Validators.stringNotNullOrEmpty(_spraying.media ?? '')) { BlocProvider.of(context) .add(ChangeListMedia(items: UtilAction.convertFilePathToMedia(_spraying.media ?? ''))); } //list supply suppliesUsing = _spraying.suppliesUsing ?? []; Get.find().changeInitList(suppliesUsing); } else if (state is ActionDetailInitial) { print("init"); } else if (state is ActionDetailLoading) { print("loading"); LoadingDialog.showLoadingDialog(context); } }, builder: (context, state) { return Column( children: [ Padding( padding: const EdgeInsets.all(8.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( plot_action_spraying, style: TextStyle(fontWeight: FontWeight.w500, fontSize: 22), ), const SizedBox( height: 8.0, ), Container( width: double.infinity, child: const Text( "Ngày thực hiện *", style: TextStyle(color: Colors.black54, fontSize: 13.0), ), ), _btnExecuteTimePicker(), const SizedBox( height: 8.0, ), _purposeField(), const SizedBox( height: 8.0, ), _quarantinePeriodField(), const SizedBox( height: 8.0, ), Container( width: double.infinity, child: const Text( "Thời gian ghi nhận kết quả", style: TextStyle(color: Colors.black54, fontSize: 13.0), ), ), _btnResultAtTimePicker(), const SizedBox( height: 8.0, ), _weatherField(), const SizedBox( height: 8.0, ), _desciptionField(), const SizedBox( height: 8.0, ), _executeByField(), const SizedBox( height: 8.0, ), ], ), ), Container( width: double.infinity, height: 16, color: Colors.grey[200], ), WidgetSprayingSupply( currentItems: [], onChangeSupplies: (value) { suppliesUsing = value; }), Container( width: double.infinity, height: 16, color: Colors.grey[200], ), const SizedBox( height: 8.0, ), BlocBuilder(builder: (context, state) { if (state is MediaHelperSuccess) { return WidgetMediaPicker( currentItems: state.items, onChangeFiles: (newPathFiles, deletePathFiles) async { Get.find().change(newPathFiles, deletePathFiles); }); } else { return const Center(child: CircularProgressIndicator()); } }), Padding( padding: const EdgeInsets.all(8.0), child: ButtonWidget( title: 'CẬP NHẬT', onPressed: () { var currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus) { currentFocus.unfocus(); } if (Get.find().isChanged) { Utils.showDialogConfirmSupply(onConfirm: () { Get.back(); _validateInputs(); }); } else { _validateInputs(); } }), ), ], ); }, ), ), )))))); @override void dispose() { _quarantinePeriodController.dispose(); _purposeController.dispose(); _weatherController.dispose(); _descriptionController.dispose(); _executeByController.dispose(); super.dispose(); } }