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.

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