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.

364 lines
15KB

  1. import 'dart:convert';
  2. import 'package:farm_tpf/custom_model/Dung.dart';
  3. import 'package:farm_tpf/custom_model/SuppliesUsing.dart';
  4. import 'package:farm_tpf/data/api/app_exception.dart';
  5. import 'package:farm_tpf/data/repository/repository.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_text_form_field.dart';
  11. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  12. import 'package:farm_tpf/presentation/screens/actions/bloc/action_detail_bloc.dart';
  13. import 'package:farm_tpf/presentation/screens/actions/controller/ChangeSupplyUsing.dart';
  14. import 'package:farm_tpf/presentation/screens/actions/dung/widget_dung_supply.dart';
  15. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_file_controller.dart';
  16. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_supply.dart';
  17. import 'package:farm_tpf/utils/const_common.dart';
  18. import 'package:farm_tpf/utils/const_string.dart';
  19. import 'package:farm_tpf/utils/const_style.dart';
  20. import 'package:farm_tpf/utils/pref.dart';
  21. import 'package:farm_tpf/utils/validators.dart';
  22. import 'package:flutter/material.dart';
  23. import 'package:flutter_bloc/flutter_bloc.dart';
  24. import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
  25. import 'package:get/get.dart';
  26. import 'package:intl/intl.dart';
  27. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  28. import 'package:pattern_formatter/pattern_formatter.dart';
  29. import 'package:farm_tpf/utils/formatter.dart';
  30. import '../util_action.dart';
  31. class EditActionDungScreen extends StatefulWidget {
  32. final int cropId;
  33. final bool isEdit;
  34. final int activityId;
  35. EditActionDungScreen(
  36. {@required this.cropId, this.isEdit = false, this.activityId});
  37. @override
  38. _EditActionDungScreenState createState() => _EditActionDungScreenState();
  39. }
  40. class _EditActionDungScreenState extends State<EditActionDungScreen> {
  41. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  42. final _repository = Repository();
  43. GlobalKey<FormState> _formKey = GlobalKey();
  44. bool _autoValidate = false;
  45. Dung _dung = Dung();
  46. var pref = LocalPref();
  47. final _descriptionController = TextEditingController();
  48. final _purposeController = TextEditingController();
  49. final _weatherController = TextEditingController();
  50. final _executeByController = TextEditingController();
  51. final _quarantinePeriodController = TextEditingController();
  52. List<SuppliesUsing> suppliesUsing = new List<SuppliesUsing>();
  53. DateTime executeTime = DateTime.now();
  54. List<String> filePaths = List<String>();
  55. var changeFileController = Get.put(ChangeFileController());
  56. Future<Null> getSharedPrefs() async {
  57. var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  58. _executeByController.text = currentFullName ?? "";
  59. }
  60. @override
  61. void initState() {
  62. super.initState();
  63. getSharedPrefs();
  64. changeFileController.initValue();
  65. _dung.suppliesUsing = new List<SuppliesUsing>();
  66. _dung.cropId = widget.cropId;
  67. }
  68. _validateInputs() async {
  69. if (_formKey.currentState.validate()) {
  70. _formKey.currentState.save();
  71. LoadingDialog.showLoadingDialog(context);
  72. filePaths = Get.find<ChangeFileController>().newFiles;
  73. List<SuppliesUsing> newSups = [];
  74. suppliesUsing.forEach((sup) {
  75. var newSup = sup;
  76. newSup.suppliesInWarehouseId = sup.tbSuppliesInWarehouseId;
  77. newSup.equipmentOfCustomerId = sup.tbEquipmentOfCustomerId;
  78. newSups.add(newSup);
  79. });
  80. _dung.suppliesUsing = newSups;
  81. _dung.mediaDel = Get.find<ChangeFileController>().deleteFiles;
  82. var activityDung = jsonEncode(_dung.toJson()).toString();
  83. //ADD NEW
  84. if (_dung.activityId == null) {
  85. _repository.createAction((value) {
  86. LoadingDialog.hideLoadingDialog(context);
  87. Get.back(result: value);
  88. Utils.showSnackBarSuccess(message: label_add_success);
  89. }, (error) {
  90. LoadingDialog.hideLoadingDialog(context);
  91. Utils.showSnackBarError(message: AppException.handleError(error));
  92. },
  93. apiAddAction: ConstCommon.apiAddDung,
  94. paramActivity: ConstCommon.paramsActionDung,
  95. activityAction: activityDung,
  96. filePaths: filePaths);
  97. } else {
  98. //UPDATE
  99. _repository.updateAction((value) {
  100. LoadingDialog.hideLoadingDialog(context);
  101. Get.back(result: value);
  102. Utils.showSnackBarSuccess(message: label_update_success);
  103. }, (error) {
  104. LoadingDialog.hideLoadingDialog(context);
  105. Utils.showSnackBarError(message: AppException.handleError(error));
  106. },
  107. apiUpdateAction: ConstCommon.apiUpdateDung,
  108. paramActivity: ConstCommon.paramsActionDung,
  109. activityAction: activityDung,
  110. filePaths: filePaths);
  111. }
  112. } else {
  113. _autoValidate = true;
  114. }
  115. }
  116. Widget _btnExecuteTimePicker() {
  117. return WidgetFieldDateTimePicker(
  118. initDateTime: executeTime,
  119. onUpdateDateTime: (selectedDate) {
  120. _dung.executeDate =
  121. selectedDate.convertLocalDateTimeToStringUtcDateTime();
  122. });
  123. }
  124. Widget _purposeField() {
  125. return TextFormField(
  126. keyboardType: TextInputType.text,
  127. decoration: InputDecoration(labelText: "Lý do sử dụng"),
  128. controller: _purposeController,
  129. onSaved: (newValue) {
  130. _dung.purpose = newValue;
  131. },
  132. );
  133. }
  134. Widget _quarantinePeriodField() {
  135. return WidgetTextFormFieldNumber(
  136. hintValue: "Thời gian cách ly",
  137. textController: _quarantinePeriodController,
  138. onSaved: (newValue) {
  139. _dung.quarantinePeriod = newValue.parseDoubleThousand();
  140. },
  141. );
  142. }
  143. Widget _weatherField() {
  144. return TextFormField(
  145. keyboardType: TextInputType.text,
  146. decoration: InputDecoration(labelText: "Thời tiết"),
  147. controller: _weatherController,
  148. onSaved: (newValue) {
  149. _dung.weatherConditions = newValue;
  150. },
  151. );
  152. }
  153. Widget _desciptionField() {
  154. return TextFormField(
  155. keyboardType: TextInputType.text,
  156. decoration: InputDecoration(labelText: "Ghi chú"),
  157. controller: _descriptionController,
  158. onSaved: (newValue) {
  159. _dung.description = newValue;
  160. },
  161. );
  162. }
  163. Widget _executeByField() {
  164. return TextFormField(
  165. keyboardType: TextInputType.text,
  166. decoration: InputDecoration(labelText: "Người thực hiện"),
  167. enabled: false,
  168. controller: _executeByController,
  169. onSaved: (newValue) {},
  170. );
  171. }
  172. _actionAppBar() {
  173. IconButton iconButton;
  174. if (1 == 1) {
  175. iconButton = IconButton(
  176. icon: Icon(
  177. Icons.done,
  178. color: Colors.black,
  179. ),
  180. onPressed: () {
  181. FocusScopeNode currentFocus = FocusScope.of(context);
  182. if (!currentFocus.hasPrimaryFocus) {
  183. currentFocus.unfocus();
  184. }
  185. if (Get.find<ChangeSupply>().selectedSupplyId > 0) {
  186. Utils.showDialogConfirmSupply(onConfirm: () {
  187. Get.back();
  188. _validateInputs();
  189. });
  190. } else {
  191. _validateInputs();
  192. }
  193. },
  194. );
  195. return <Widget>[iconButton];
  196. }
  197. return <Widget>[Container()];
  198. }
  199. @override
  200. Widget build(BuildContext context) => KeyboardDismisser(
  201. gestures: [
  202. GestureType.onTap,
  203. GestureType.onPanUpdateDownDirection,
  204. ],
  205. child: Scaffold(
  206. key: _scaffoldKey,
  207. appBar: AppBar(
  208. centerTitle: true,
  209. title: Text(plot_action_dung),
  210. actions: _actionAppBar()),
  211. body: KeyboardDismisser(
  212. child: MultiBlocProvider(
  213. providers: [
  214. BlocProvider<ActionDetailBloc>(
  215. create: (context) =>
  216. ActionDetailBloc(repository: Repository())
  217. ..add(FetchData(
  218. isNeedFetchData: widget.isEdit,
  219. apiActivity: ConstCommon.apiDetailDung,
  220. activityId: widget.activityId))),
  221. BlocProvider<MediaHelperBloc>(
  222. create: (context) =>
  223. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  224. )
  225. ],
  226. child: Form(
  227. key: _formKey,
  228. autovalidate: _autoValidate,
  229. child: SingleChildScrollView(
  230. padding: EdgeInsets.all(8.0),
  231. child: BlocConsumer<ActionDetailBloc,
  232. ActionDetailState>(
  233. listener: (context, state) async {
  234. if (state is ActionDetailFailure) {
  235. LoadingDialog.hideLoadingDialog(context);
  236. } else if (state is ActionDetailSuccess) {
  237. LoadingDialog.hideLoadingDialog(context);
  238. _dung = Dung.fromJson(state.item);
  239. _dung.activityId = widget.activityId;
  240. _purposeController.text = _dung.purpose ?? "";
  241. _quarantinePeriodController.text = _dung
  242. .quarantinePeriod
  243. .formatNumtoStringDecimal();
  244. _weatherController.text =
  245. _dung.weatherConditions ?? "";
  246. _descriptionController.text =
  247. _dung.description;
  248. _executeByController.text = _dung.executeBy;
  249. Get.find<ChangeDateTimePicker>().change(_dung
  250. .executeDate
  251. .convertStringServerDateTimeToLocalDateTime());
  252. //Show media
  253. if (Validators.stringNotNullOrEmpty(
  254. _dung.media)) {
  255. BlocProvider.of<MediaHelperBloc>(context)
  256. .add(ChangeListMedia(
  257. items: UtilAction
  258. .convertFilePathToMedia(
  259. _dung.media)));
  260. }
  261. //list supply
  262. suppliesUsing = _dung.suppliesUsing;
  263. Get.find<ChangeSupplyUsing>()
  264. .changeInitList(suppliesUsing);
  265. } else if (state is ActionDetailInitial) {
  266. print("init");
  267. } else if (state is ActionDetailLoading) {
  268. print("loading");
  269. LoadingDialog.showLoadingDialog(context);
  270. }
  271. },
  272. builder: (context, state) {
  273. return Column(
  274. children: <Widget>[
  275. Container(
  276. width: double.infinity,
  277. child: Text(
  278. "Ngày thực hiện *",
  279. style: TextStyle(
  280. color: Colors.black54,
  281. fontSize: 13.0),
  282. ),
  283. ),
  284. _btnExecuteTimePicker(),
  285. SizedBox(
  286. height: 8.0,
  287. ),
  288. _purposeField(),
  289. SizedBox(
  290. height: 8.0,
  291. ),
  292. _quarantinePeriodField(),
  293. SizedBox(
  294. height: 8.0,
  295. ),
  296. _weatherField(),
  297. SizedBox(
  298. height: 8.0,
  299. ),
  300. _desciptionField(),
  301. SizedBox(
  302. height: 8.0,
  303. ),
  304. _executeByField(),
  305. SizedBox(
  306. height: 8.0,
  307. ),
  308. WidgetDungSupply(
  309. currentItems: [],
  310. onChangeSupplies: (value) {
  311. suppliesUsing = value;
  312. }),
  313. SizedBox(
  314. height: 8.0,
  315. ),
  316. BlocBuilder<MediaHelperBloc,
  317. MediaHelperState>(
  318. builder: (context, state) {
  319. if (state is MediaHelperSuccess) {
  320. return WidgetMediaPicker(
  321. currentItems: state.items,
  322. onChangeFiles: (newPathFiles,
  323. deletePathFiles) async {
  324. Get.find<ChangeFileController>()
  325. .change(newPathFiles,
  326. deletePathFiles);
  327. });
  328. } else {
  329. return Center(
  330. child: CircularProgressIndicator());
  331. }
  332. }),
  333. ],
  334. );
  335. },
  336. ),
  337. ))))));
  338. @override
  339. void dispose() {
  340. _quarantinePeriodController.dispose();
  341. _purposeController.dispose();
  342. _weatherController.dispose();
  343. _descriptionController.dispose();
  344. _executeByController.dispose();
  345. super.dispose();
  346. }
  347. }