You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

334 lines
13KB

  1. import 'dart:convert';
  2. import 'package:farm_tpf/custom_model/Other.dart';
  3. import 'package:farm_tpf/data/api/app_exception.dart';
  4. import 'package:farm_tpf/data/repository/repository.dart';
  5. import 'package:farm_tpf/models/index.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart';
  7. import 'package:farm_tpf/presentation/custom_widgets/widget_field_time_picker.dart';
  8. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  9. import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart';
  10. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  11. import 'package:farm_tpf/presentation/screens/actions/bloc/action_detail_bloc.dart';
  12. import 'package:farm_tpf/presentation/screens/actions/other/bloc_get_action_type.dart';
  13. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_file_controller.dart';
  14. import 'package:farm_tpf/utils/const_common.dart';
  15. import 'package:farm_tpf/utils/const_string.dart';
  16. import 'package:farm_tpf/utils/const_style.dart';
  17. import 'package:farm_tpf/utils/pref.dart';
  18. import 'package:farm_tpf/utils/validators.dart';
  19. import 'package:flutter/material.dart';
  20. import 'package:flutter_bloc/flutter_bloc.dart';
  21. import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
  22. import 'package:get/get.dart';
  23. import 'package:intl/intl.dart';
  24. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  25. import 'package:farm_tpf/utils/formatter.dart';
  26. import '../util_action.dart';
  27. class EditActionOtherScreen extends StatefulWidget {
  28. final int cropId;
  29. final bool isEdit;
  30. final int activityId;
  31. EditActionOtherScreen(
  32. {@required this.cropId, this.isEdit = false, this.activityId});
  33. @override
  34. _EditActionOtherScreenState createState() => _EditActionOtherScreenState();
  35. }
  36. class _EditActionOtherScreenState extends State<EditActionOtherScreen> {
  37. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  38. final _repository = Repository();
  39. GlobalKey<FormState> _formKey = GlobalKey();
  40. bool _autoValidate = false;
  41. var pref = LocalPref();
  42. Other _other = Other();
  43. final _descriptionController = TextEditingController();
  44. final _executeByController = TextEditingController();
  45. List<ActionType> _actionTypes = List<ActionType>();
  46. ActionType _actionType;
  47. DateTime executeTime = DateTime.now();
  48. List<String> filePaths = List<String>();
  49. var changeFileController = Get.put(ChangeFileController());
  50. Future<Null> getSharedPrefs() async {
  51. var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  52. _executeByController.text = currentFullName ?? "";
  53. }
  54. @override
  55. void initState() {
  56. super.initState();
  57. getSharedPrefs();
  58. changeFileController.initValue();
  59. _other.cropId = widget.cropId;
  60. if (!widget.isEdit) {
  61. getActionTypeBloc.getActionTypes((data) {
  62. _actionTypes = data;
  63. }, (err) {});
  64. }
  65. }
  66. _validateInputs() async {
  67. if (_formKey.currentState.validate()) {
  68. _formKey.currentState.save();
  69. LoadingDialog.showLoadingDialog(context);
  70. filePaths = Get.find<ChangeFileController>().newFiles;
  71. try {
  72. _other.mediaDel = Get.find<ChangeFileController>().deleteFiles;
  73. var activityOther = jsonEncode(_other.toJson()).toString();
  74. //ADD NEW
  75. if (_other.activityId == null) {
  76. _repository.createAction((value) {
  77. LoadingDialog.hideLoadingDialog(context);
  78. Get.back(result: value);
  79. Utils.showSnackBarSuccess(message: label_add_success);
  80. }, (error) {
  81. LoadingDialog.hideLoadingDialog(context);
  82. Utils.showSnackBarError(message: AppException.handleError(error));
  83. },
  84. apiAddAction: ConstCommon.apiAddOther,
  85. paramActivity: ConstCommon.paramsActionOther,
  86. activityAction: activityOther,
  87. filePaths: filePaths);
  88. } else {
  89. //UPDATE
  90. _repository.updateAction((value) {
  91. LoadingDialog.hideLoadingDialog(context);
  92. Get.back(result: value);
  93. Utils.showSnackBarSuccess(message: label_update_success);
  94. }, (error) {
  95. LoadingDialog.hideLoadingDialog(context);
  96. Utils.showSnackBarError(message: AppException.handleError(error));
  97. },
  98. apiUpdateAction: ConstCommon.apiUpdateOther,
  99. paramActivity: ConstCommon.paramsActionOther,
  100. activityAction: activityOther,
  101. filePaths: filePaths);
  102. }
  103. } catch (e) {
  104. LoadingDialog.hideLoadingDialog(context);
  105. print(e.toString());
  106. }
  107. } else {
  108. _autoValidate = true;
  109. }
  110. }
  111. Widget _btnExecuteTimePicker() {
  112. return WidgetFieldDateTimePicker(
  113. initDateTime: executeTime,
  114. onUpdateDateTime: (selectedDate) {
  115. _other.executeDate =
  116. selectedDate.convertLocalDateTimeToStringUtcDateTime();
  117. });
  118. }
  119. List<DropdownMenuItem<ActionType>> _buildDropMenu(List<ActionType> actions) {
  120. return actions
  121. .map((action) => DropdownMenuItem<ActionType>(
  122. child: Text(action.description.toString()),
  123. value: action,
  124. ))
  125. .toList();
  126. }
  127. Widget _dropdownAcionTypes() {
  128. return StreamBuilder(
  129. stream: getActionTypeBloc.actions,
  130. builder: (context, AsyncSnapshot<dynamic> snapshot) {
  131. if (snapshot.hasData) {
  132. return DropdownButtonFormField<ActionType>(
  133. value: _actionType,
  134. hint: Text("Hoạt động *"),
  135. onChanged: (ActionType newValue) {
  136. setState(() {
  137. _actionType = newValue;
  138. _other.activityTypeName = newValue.name;
  139. });
  140. },
  141. validator: (value) => value == null ? "Hoạt động" : null,
  142. isExpanded: true,
  143. items: _buildDropMenu(_actionTypes));
  144. } else if (snapshot.hasError) {
  145. return Container();
  146. } else {
  147. return Center(
  148. child: CircularProgressIndicator(),
  149. );
  150. }
  151. },
  152. );
  153. }
  154. Widget _desciptionField() {
  155. return TextFormField(
  156. keyboardType: TextInputType.text,
  157. decoration: InputDecoration(labelText: "Ghi chú"),
  158. controller: _descriptionController,
  159. onSaved: (newValue) {
  160. _other.description = newValue;
  161. },
  162. );
  163. }
  164. Widget _executeByField() {
  165. return TextFormField(
  166. keyboardType: TextInputType.text,
  167. decoration: InputDecoration(labelText: "Người thực hiện"),
  168. enabled: false,
  169. controller: _executeByController,
  170. onSaved: (newValue) {},
  171. );
  172. }
  173. _actionAppBar() {
  174. IconButton iconButton;
  175. if (1 == 1) {
  176. iconButton = IconButton(
  177. icon: Icon(
  178. Icons.done,
  179. color: Colors.black,
  180. ),
  181. onPressed: () {
  182. FocusScopeNode currentFocus = FocusScope.of(context);
  183. if (!currentFocus.hasPrimaryFocus) {
  184. currentFocus.unfocus();
  185. }
  186. _validateInputs();
  187. },
  188. );
  189. return <Widget>[iconButton];
  190. }
  191. return <Widget>[Container()];
  192. }
  193. @override
  194. Widget build(BuildContext context) => KeyboardDismisser(
  195. gestures: [
  196. GestureType.onTap,
  197. GestureType.onPanUpdateDownDirection,
  198. ],
  199. child: Scaffold(
  200. key: _scaffoldKey,
  201. appBar: AppBar(
  202. centerTitle: true,
  203. title: Text(plot_action_other),
  204. actions: _actionAppBar()),
  205. body: KeyboardDismisser(
  206. child: MultiBlocProvider(
  207. providers: [
  208. BlocProvider<ActionDetailBloc>(
  209. create: (context) =>
  210. ActionDetailBloc(repository: Repository())
  211. ..add(FetchData(
  212. isNeedFetchData: widget.isEdit,
  213. apiActivity: ConstCommon.apiDetailOther,
  214. activityId: widget.activityId))),
  215. BlocProvider<MediaHelperBloc>(
  216. create: (context) =>
  217. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  218. )
  219. ],
  220. child: Form(
  221. key: _formKey,
  222. autovalidate: _autoValidate,
  223. child: SingleChildScrollView(
  224. padding: EdgeInsets.all(8.0),
  225. child: BlocConsumer<ActionDetailBloc, ActionDetailState>(
  226. listener: (context, state) async {
  227. if (state is ActionDetailFailure) {
  228. LoadingDialog.hideLoadingDialog(context);
  229. } else if (state is ActionDetailSuccess) {
  230. LoadingDialog.hideLoadingDialog(context);
  231. _other = Other.fromJson(state.item);
  232. _other.activityId = widget.activityId;
  233. _descriptionController.text =
  234. _other.description ?? "";
  235. _executeByController.text = _other.createdByName;
  236. //select harvest
  237. getActionTypeBloc.getActionTypes((data) {
  238. _actionTypes = data;
  239. for (var item in _actionTypes) {
  240. if (item.name == _other.activityTypeName) {
  241. _actionType = item;
  242. break;
  243. }
  244. }
  245. }, (err) {});
  246. Get.find<ChangeDateTimePicker>().change(_other
  247. .executeDate
  248. .convertStringServerDateTimeToLocalDateTime());
  249. //Show media
  250. if (Validators.stringNotNullOrEmpty(_other.media)) {
  251. BlocProvider.of<MediaHelperBloc>(context).add(
  252. ChangeListMedia(
  253. items: UtilAction.convertFilePathToMedia(
  254. _other.media)));
  255. }
  256. } else if (state is ActionDetailInitial) {
  257. } else if (state is ActionDetailLoading) {
  258. LoadingDialog.showLoadingDialog(context);
  259. }
  260. },
  261. builder: (context, state) {
  262. return Column(
  263. children: <Widget>[
  264. Container(
  265. width: double.infinity,
  266. child: Text(
  267. "Ngày thực hiện *",
  268. style: TextStyle(
  269. color: Colors.black54, fontSize: 13.0),
  270. ),
  271. ),
  272. _btnExecuteTimePicker(),
  273. SizedBox(
  274. height: 8.0,
  275. ),
  276. _dropdownAcionTypes(),
  277. SizedBox(
  278. height: 8.0,
  279. ),
  280. _desciptionField(),
  281. SizedBox(
  282. height: 8.0,
  283. ),
  284. _executeByField(),
  285. SizedBox(
  286. height: 8.0,
  287. ),
  288. BlocBuilder<MediaHelperBloc, MediaHelperState>(
  289. builder: (context, state) {
  290. if (state is MediaHelperSuccess) {
  291. return WidgetMediaPicker(
  292. currentItems: state.items,
  293. onChangeFiles: (newPathFiles,
  294. deletePathFiles) async {
  295. Get.find<ChangeFileController>().change(
  296. newPathFiles, deletePathFiles);
  297. });
  298. } else {
  299. return Center(
  300. child: CircularProgressIndicator());
  301. }
  302. }),
  303. ],
  304. );
  305. },
  306. ),
  307. )),
  308. ))));
  309. @override
  310. void dispose() {
  311. _descriptionController.dispose();
  312. _executeByController.dispose();
  313. super.dispose();
  314. }
  315. }