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.

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