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.

394 lines
16KB

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