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.

413 lines
17KB

  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_loading.dart';
  8. import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart';
  9. import 'package:farm_tpf/presentation/screens/actions/bloc/action_detail_bloc.dart';
  10. import 'package:farm_tpf/presentation/screens/actions/controller/ChangeSupplyUsing.dart';
  11. import 'package:farm_tpf/presentation/screens/actions/dung/widget_dung_supply.dart';
  12. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_file_controller.dart';
  13. import 'package:farm_tpf/utils/const_common.dart';
  14. import 'package:farm_tpf/utils/const_string.dart';
  15. import 'package:farm_tpf/utils/const_style.dart';
  16. import 'package:farm_tpf/utils/pref.dart';
  17. import 'package:flutter/material.dart';
  18. import 'package:flutter_bloc/flutter_bloc.dart';
  19. import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
  20. import 'package:get/get.dart';
  21. import 'package:intl/intl.dart';
  22. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  23. import 'package:pattern_formatter/pattern_formatter.dart';
  24. import 'package:farm_tpf/utils/formatter.dart';
  25. import '../util_action.dart';
  26. class EditActionDungScreen extends StatefulWidget {
  27. final int cropId;
  28. final bool isEdit;
  29. final int activityId;
  30. EditActionDungScreen(
  31. {@required this.cropId, this.isEdit = false, this.activityId});
  32. @override
  33. _EditActionDungScreenState createState() => _EditActionDungScreenState();
  34. }
  35. class _EditActionDungScreenState extends State<EditActionDungScreen> {
  36. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  37. final _repository = Repository();
  38. GlobalKey<FormState> _formKey = GlobalKey();
  39. bool _autoValidate = false;
  40. Dung _dung = Dung();
  41. var pref = LocalPref();
  42. final _descriptionController = TextEditingController();
  43. final _purposeController = TextEditingController();
  44. final _weatherController = TextEditingController();
  45. final _executeByController = TextEditingController();
  46. final _quarantinePeriodController = TextEditingController();
  47. List<SuppliesUsing> suppliesUsing = new List<SuppliesUsing>();
  48. String executeTimeView;
  49. DateTime executeTime = DateTime.now();
  50. List<String> filePaths = List<String>();
  51. var changeFileController = Get.put(ChangeFileController());
  52. Future<Null> getSharedPrefs() async {
  53. var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  54. _executeByController.text = currentFullName ?? "";
  55. }
  56. @override
  57. void initState() {
  58. super.initState();
  59. getSharedPrefs();
  60. changeFileController.initValue();
  61. _dung.suppliesUsing = new List<SuppliesUsing>();
  62. var parsedExecuteDate =
  63. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(executeTime);
  64. _dung.executeDate = "$parsedExecuteDate";
  65. executeTimeView = DateFormat("dd/MM/yyyy HH:mm").format(executeTime);
  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>().files;
  73. List<SuppliesUsing> newSups = [];
  74. suppliesUsing.forEach((sup) {
  75. var newSup = sup;
  76. newSup.suppliesInWarehouseId = sup.tbSuppliesInWarehouseId;
  77. newSups.add(newSup);
  78. });
  79. _dung.suppliesUsing = newSups;
  80. var activityDung = jsonEncode(_dung.toJson()).toString();
  81. //ADD NEW
  82. if (_dung.activityId == null) {
  83. _repository.createAction((value) {
  84. LoadingDialog.hideLoadingDialog(context);
  85. Get.back(result: value);
  86. Get.snackbar(label_add_success, "Hoạt động bón phân",
  87. snackPosition: SnackPosition.BOTTOM);
  88. }, (error) {
  89. LoadingDialog.hideLoadingDialog(context);
  90. _scaffoldKey.currentState.showSnackBar(SnackBar(
  91. content: Row(
  92. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  93. children: <Widget>[
  94. Flexible(child: Text(AppException.handleError(error))),
  95. Icon(Icons.error),
  96. ],
  97. ),
  98. backgroundColor: Colors.red,
  99. duration: Duration(seconds: 3),
  100. ));
  101. },
  102. apiAddAction: ConstCommon.apiAddDung,
  103. paramActivity: ConstCommon.paramsActionDung,
  104. activityAction: activityDung,
  105. filePaths: filePaths);
  106. } else {
  107. //UPDATE
  108. _repository.updateAction((value) {
  109. LoadingDialog.hideLoadingDialog(context);
  110. Get.back(result: value);
  111. Get.snackbar(label_update_success, "Hoạt động bón phân",
  112. snackPosition: SnackPosition.BOTTOM);
  113. }, (error) {
  114. LoadingDialog.hideLoadingDialog(context);
  115. _scaffoldKey.currentState.showSnackBar(SnackBar(
  116. content: Row(
  117. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  118. children: <Widget>[
  119. Flexible(child: Text(AppException.handleError(error))),
  120. Icon(Icons.error),
  121. ],
  122. ),
  123. backgroundColor: Colors.red,
  124. duration: Duration(seconds: 3),
  125. ));
  126. },
  127. apiUpdateAction: ConstCommon.apiUpdateDung,
  128. paramActivity: ConstCommon.paramsActionDung,
  129. activityAction: activityDung,
  130. filePaths: filePaths);
  131. }
  132. } else {
  133. _autoValidate = true;
  134. }
  135. }
  136. Widget _btnExecuteTimePicker() {
  137. return FlatButton(
  138. padding: EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
  139. onPressed: () {
  140. DatePicker.showDateTimePicker(context,
  141. showTitleActions: true, onChanged: (date) {}, onConfirm: (date) {
  142. setState(() {
  143. var parsedDate =
  144. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(date);
  145. _dung.executeDate = "$parsedDate";
  146. executeTimeView = DateFormat("dd/MM/yyyy HH:mm").format(date);
  147. });
  148. }, currentTime: executeTime, locale: LocaleType.vi);
  149. },
  150. child: Container(
  151. padding:
  152. EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  153. decoration: BoxDecoration(
  154. border: kBorderTextField,
  155. ),
  156. child: Row(
  157. children: [
  158. Expanded(
  159. child: Text(
  160. //TODO: check condition
  161. executeTimeView == null ? "$executeTime" : executeTimeView,
  162. style: TextStyle(fontSize: 14.0, color: Colors.black87),
  163. )),
  164. Icon(
  165. Icons.date_range,
  166. color: Colors.blue,
  167. ),
  168. ],
  169. )));
  170. }
  171. Widget _purposeField() {
  172. return TextFormField(
  173. keyboardType: TextInputType.text,
  174. decoration: InputDecoration(labelText: "Lý do sử dụng"),
  175. controller: _purposeController,
  176. onSaved: (newValue) {
  177. _dung.purpose = newValue;
  178. },
  179. );
  180. }
  181. Widget _quarantinePeriodField() {
  182. return TextFormField(
  183. keyboardType: TextInputType.numberWithOptions(decimal: true),
  184. inputFormatters: [
  185. ThousandsFormatter(
  186. formatter: NumberFormat("#,###.##", "es"), allowFraction: true)
  187. ],
  188. decoration: InputDecoration(labelText: "Thời gian cách ly"),
  189. controller: _quarantinePeriodController,
  190. onSaved: (newValue) {
  191. _dung.quarantinePeriod = newValue.parseDoubleThousand();
  192. },
  193. );
  194. }
  195. Widget _weatherField() {
  196. return TextFormField(
  197. keyboardType: TextInputType.text,
  198. decoration: InputDecoration(labelText: "Thời tiết"),
  199. controller: _weatherController,
  200. onSaved: (newValue) {
  201. _dung.weatherConditions = newValue;
  202. },
  203. );
  204. }
  205. Widget _desciptionField() {
  206. return TextFormField(
  207. keyboardType: TextInputType.text,
  208. decoration: InputDecoration(labelText: "Ghi chú"),
  209. controller: _descriptionController,
  210. onSaved: (newValue) {
  211. _dung.description = newValue;
  212. },
  213. );
  214. }
  215. Widget _executeByField() {
  216. return TextFormField(
  217. keyboardType: TextInputType.text,
  218. decoration: InputDecoration(labelText: "Người thực hiện"),
  219. enabled: false,
  220. controller: _executeByController,
  221. onSaved: (newValue) {},
  222. );
  223. }
  224. _actionAppBar() {
  225. IconButton iconButton;
  226. if (1 == 1) {
  227. iconButton = IconButton(
  228. icon: Icon(
  229. Icons.done,
  230. color: Colors.black,
  231. ),
  232. onPressed: () {
  233. FocusScopeNode currentFocus = FocusScope.of(context);
  234. if (!currentFocus.hasPrimaryFocus) {
  235. currentFocus.unfocus();
  236. }
  237. _validateInputs();
  238. },
  239. );
  240. return <Widget>[iconButton];
  241. }
  242. return <Widget>[Container()];
  243. }
  244. @override
  245. Widget build(BuildContext context) => KeyboardDismisser(
  246. gestures: [
  247. GestureType.onTap,
  248. GestureType.onPanUpdateDownDirection,
  249. ],
  250. child: Scaffold(
  251. key: _scaffoldKey,
  252. appBar: AppBar(
  253. centerTitle: true,
  254. title: Text(plot_action_dung),
  255. actions: _actionAppBar()),
  256. body: KeyboardDismisser(
  257. child: MultiBlocProvider(
  258. providers: [
  259. BlocProvider<ActionDetailBloc>(
  260. create: (context) =>
  261. ActionDetailBloc(repository: Repository())
  262. ..add(FetchData(
  263. isNeedFetchData: widget.isEdit,
  264. apiActivity: ConstCommon.apiDetailDung,
  265. activityId: widget.activityId))),
  266. BlocProvider<MediaHelperBloc>(
  267. create: (context) =>
  268. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  269. )
  270. ],
  271. child: Form(
  272. key: _formKey,
  273. autovalidate: _autoValidate,
  274. child: SingleChildScrollView(
  275. padding: EdgeInsets.all(8.0),
  276. child: BlocConsumer<ActionDetailBloc,
  277. ActionDetailState>(
  278. listener: (context, state) async {
  279. if (state is ActionDetailFailure) {
  280. LoadingDialog.hideLoadingDialog(context);
  281. } else if (state is ActionDetailSuccess) {
  282. LoadingDialog.hideLoadingDialog(context);
  283. _dung = Dung.fromJson(state.item);
  284. _dung.activityId = widget.activityId;
  285. _purposeController.text = _dung.purpose ?? "";
  286. _quarantinePeriodController.text = _dung
  287. .quarantinePeriod
  288. .formatNumtoStringDecimal();
  289. _weatherController.text =
  290. _dung.weatherConditions ?? "";
  291. _descriptionController.text =
  292. _dung.description;
  293. _executeByController.text = _dung.executeBy;
  294. try {
  295. executeTime =
  296. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
  297. .parse(_dung.executeDate);
  298. } catch (_) {}
  299. executeTimeView =
  300. DateFormat("dd/MM/yyyy HH:mm")
  301. .format(executeTime);
  302. //Show media
  303. if (_dung.media != null) {
  304. await UtilAction.cacheFiles(_dung.media)
  305. .then((value) {
  306. BlocProvider.of<MediaHelperBloc>(context)
  307. .add(ChangeListMedia(items: value));
  308. }).whenComplete(() {
  309. print("completed");
  310. });
  311. }
  312. //list supply
  313. suppliesUsing = _dung.suppliesUsing;
  314. Get.find<ChangeSupplyUsing>()
  315. .changeInitList(suppliesUsing);
  316. } else if (state is ActionDetailInitial) {
  317. print("init");
  318. } else if (state is ActionDetailLoading) {
  319. print("loading");
  320. LoadingDialog.showLoadingDialog(context);
  321. }
  322. },
  323. builder: (context, state) {
  324. return Column(
  325. children: <Widget>[
  326. Container(
  327. width: double.infinity,
  328. child: Text(
  329. "Ngày thực hiện *",
  330. style: TextStyle(
  331. color: Colors.black54,
  332. fontSize: 13.0),
  333. ),
  334. ),
  335. _btnExecuteTimePicker(),
  336. SizedBox(
  337. height: 8.0,
  338. ),
  339. _purposeField(),
  340. SizedBox(
  341. height: 8.0,
  342. ),
  343. _quarantinePeriodField(),
  344. SizedBox(
  345. height: 8.0,
  346. ),
  347. _weatherField(),
  348. SizedBox(
  349. height: 8.0,
  350. ),
  351. _desciptionField(),
  352. SizedBox(
  353. height: 8.0,
  354. ),
  355. _executeByField(),
  356. SizedBox(
  357. height: 8.0,
  358. ),
  359. WidgetDungSupply(
  360. currentItems: [],
  361. onChangeSupplies: (value) {
  362. suppliesUsing = value;
  363. }),
  364. SizedBox(
  365. height: 8.0,
  366. ),
  367. BlocBuilder<MediaHelperBloc,
  368. MediaHelperState>(
  369. builder: (context, state) {
  370. if (state is MediaHelperSuccess) {
  371. return WidgetMediaPicker(
  372. currentItems: state.items,
  373. onChangeFiles: (filePaths) async {
  374. Get.find<ChangeFileController>()
  375. .addAllFile(filePaths);
  376. });
  377. } else {
  378. return Center(
  379. child: CircularProgressIndicator());
  380. }
  381. }),
  382. ],
  383. );
  384. },
  385. ),
  386. ))))));
  387. @override
  388. void dispose() {
  389. _quarantinePeriodController.dispose();
  390. _purposeController.dispose();
  391. _weatherController.dispose();
  392. _descriptionController.dispose();
  393. _executeByController.dispose();
  394. super.dispose();
  395. }
  396. }