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.

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