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
18KB

  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/app_bar_widget.dart';
  7. import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart';
  8. import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart';
  9. import 'package:farm_tpf/presentation/custom_widgets/widget_field_time_picker.dart';
  10. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  11. import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart';
  12. import 'package:farm_tpf/presentation/custom_widgets/widget_text_field_description.dart';
  13. import 'package:farm_tpf/presentation/custom_widgets/widget_text_form_field.dart';
  14. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  15. import 'package:farm_tpf/presentation/screens/actions/bloc/action_detail_bloc.dart';
  16. import 'package:farm_tpf/presentation/screens/actions/controller/ChangeFieldInForm.dart';
  17. import 'package:farm_tpf/presentation/screens/actions/controller/ChangeSupplyUsing.dart';
  18. import 'package:farm_tpf/presentation/screens/actions/dung/widget_dung_supply.dart';
  19. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_file_controller.dart';
  20. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_supply.dart';
  21. import 'package:farm_tpf/utils/const_common.dart';
  22. import 'package:farm_tpf/utils/const_string.dart';
  23. import 'package:farm_tpf/utils/const_style.dart';
  24. import 'package:farm_tpf/utils/pref.dart';
  25. import 'package:farm_tpf/utils/validators.dart';
  26. import 'package:flutter/material.dart';
  27. import 'package:flutter_bloc/flutter_bloc.dart';
  28. import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
  29. import 'package:get/get.dart';
  30. import 'package:intl/intl.dart';
  31. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  32. import 'package:pattern_formatter/pattern_formatter.dart';
  33. import 'package:farm_tpf/utils/formatter.dart';
  34. import '../util_action.dart';
  35. class EditActionDungScreen extends StatefulWidget {
  36. final int cropId;
  37. final bool isEdit;
  38. final int activityId;
  39. EditActionDungScreen(
  40. {@required this.cropId, this.isEdit = false, this.activityId});
  41. @override
  42. _EditActionDungScreenState createState() => _EditActionDungScreenState();
  43. }
  44. class _EditActionDungScreenState extends State<EditActionDungScreen> {
  45. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  46. final _repository = Repository();
  47. GlobalKey<FormState> _formKey = GlobalKey();
  48. bool _autoValidate = false;
  49. Dung _dung = Dung();
  50. var pref = LocalPref();
  51. final _descriptionController = TextEditingController();
  52. final _purposeController = TextEditingController();
  53. final _weatherController = TextEditingController();
  54. final _executeByController = TextEditingController();
  55. final _quarantinePeriodController = TextEditingController();
  56. List<SuppliesUsing> suppliesUsing = new List<SuppliesUsing>();
  57. DateTime executeTime = DateTime.now();
  58. List<String> filePaths = List<String>();
  59. var changeFileController = Get.put(ChangeFileController());
  60. Future<Null> getSharedPrefs() async {
  61. var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  62. _executeByController.text = currentFullName ?? "";
  63. }
  64. @override
  65. void initState() {
  66. super.initState();
  67. getSharedPrefs();
  68. changeFileController.initValue();
  69. _dung.suppliesUsing = new List<SuppliesUsing>();
  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 WidgetFieldDateTimePicker(
  122. initDateTime: executeTime,
  123. onUpdateDateTime: (selectedDate) {
  124. _dung.executeDate =
  125. selectedDate.convertLocalDateTimeToStringUtcDateTime();
  126. });
  127. }
  128. Widget _purposeField() {
  129. return TextFormField(
  130. keyboardType: TextInputType.text,
  131. decoration: InputDecoration(labelText: "Lý do sử dụng"),
  132. controller: _purposeController,
  133. onSaved: (newValue) {
  134. _dung.purpose = newValue;
  135. },
  136. );
  137. }
  138. Widget _quarantinePeriodField() {
  139. return WidgetTextFormFieldNumber(
  140. hintValue: "Thời gian cách ly",
  141. textController: _quarantinePeriodController,
  142. onSaved: (newValue) {
  143. _dung.quarantinePeriod = newValue.parseDoubleThousand();
  144. },
  145. );
  146. }
  147. Widget _weatherField() {
  148. return TextFormField(
  149. keyboardType: TextInputType.text,
  150. decoration: InputDecoration(labelText: "Thời tiết"),
  151. controller: _weatherController,
  152. onSaved: (newValue) {
  153. _dung.weatherConditions = newValue;
  154. },
  155. );
  156. }
  157. Widget _desciptionField() {
  158. return TextFieldDescriptionWidget(
  159. controller: _descriptionController,
  160. onSaved: (newValue) {
  161. _dung.description = newValue;
  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. @override
  174. Widget build(BuildContext context) => KeyboardDismisser(
  175. gestures: [
  176. GestureType.onTap,
  177. GestureType.onPanUpdateDownDirection,
  178. ],
  179. child: Scaffold(
  180. backgroundColor: Colors.white,
  181. key: _scaffoldKey,
  182. appBar: AppBarWidget(
  183. isBack: true,
  184. action: InkWell(
  185. child: Text(
  186. 'Huỷ',
  187. style: TextStyle(
  188. color: Colors.red, fontWeight: FontWeight.normal),
  189. ),
  190. onTap: () {
  191. if (Get.isSnackbarOpen) Get.back();
  192. Get.back();
  193. },
  194. ),
  195. ),
  196. body: KeyboardDismisser(
  197. child: MultiBlocProvider(
  198. providers: [
  199. BlocProvider<ActionDetailBloc>(
  200. create: (context) =>
  201. ActionDetailBloc(repository: Repository())
  202. ..add(FetchData(
  203. isNeedFetchData: widget.isEdit,
  204. apiActivity: ConstCommon.apiDetailDung,
  205. activityId: widget.activityId))),
  206. BlocProvider<MediaHelperBloc>(
  207. create: (context) =>
  208. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  209. )
  210. ],
  211. child: Form(
  212. key: _formKey,
  213. autovalidate: _autoValidate,
  214. child: SafeArea(
  215. child: SingleChildScrollView(
  216. child: BlocConsumer<ActionDetailBloc,
  217. ActionDetailState>(
  218. listener: (context, state) async {
  219. if (state is ActionDetailFailure) {
  220. LoadingDialog.hideLoadingDialog(context);
  221. } else if (state is ActionDetailSuccess) {
  222. LoadingDialog.hideLoadingDialog(context);
  223. _dung = Dung.fromJson(state.item);
  224. _dung.activityId = widget.activityId;
  225. _purposeController.text =
  226. _dung.purpose ?? "";
  227. _quarantinePeriodController.text = _dung
  228. .quarantinePeriod
  229. .formatNumtoStringDecimal();
  230. _weatherController.text =
  231. _dung.weatherConditions ?? "";
  232. _descriptionController.text =
  233. _dung.description;
  234. _executeByController.text = _dung.executeBy;
  235. Get.find<ChangeDateTimePicker>().change(_dung
  236. .executeDate
  237. .convertStringServerDateTimeToLocalDateTime());
  238. //Show media
  239. if (Validators.stringNotNullOrEmpty(
  240. _dung.media)) {
  241. BlocProvider.of<MediaHelperBloc>(context)
  242. .add(ChangeListMedia(
  243. items: UtilAction
  244. .convertFilePathToMedia(
  245. _dung.media)));
  246. }
  247. //list supply
  248. suppliesUsing = _dung.suppliesUsing;
  249. Get.find<ChangeSupplyUsing>()
  250. .changeInitList(suppliesUsing);
  251. } else if (state is ActionDetailInitial) {
  252. print("init");
  253. } else if (state is ActionDetailLoading) {
  254. print("loading");
  255. LoadingDialog.showLoadingDialog(context);
  256. }
  257. },
  258. builder: (context, state) {
  259. return Column(
  260. children: [
  261. Padding(
  262. padding: const EdgeInsets.all(8.0),
  263. child: Column(
  264. crossAxisAlignment:
  265. CrossAxisAlignment.start,
  266. children: <Widget>[
  267. Text(
  268. plot_action_dung,
  269. style: TextStyle(
  270. fontWeight: FontWeight.w500,
  271. fontSize: 22),
  272. ),
  273. SizedBox(
  274. height: 8.0,
  275. ),
  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. ],
  310. ),
  311. ),
  312. Container(
  313. width: double.infinity,
  314. height: 16,
  315. color: Colors.grey[200],
  316. ),
  317. WidgetDungSupply(
  318. currentItems: [],
  319. onChangeSupplies: (value) {
  320. suppliesUsing = value;
  321. }),
  322. Container(
  323. width: double.infinity,
  324. height: 16,
  325. color: Colors.grey[200],
  326. ),
  327. BlocBuilder<MediaHelperBloc,
  328. MediaHelperState>(
  329. builder: (context, state) {
  330. if (state is MediaHelperSuccess) {
  331. return WidgetMediaPicker(
  332. currentItems: state.items,
  333. onChangeFiles: (newPathFiles,
  334. deletePathFiles) async {
  335. Get.find<ChangeFileController>()
  336. .change(newPathFiles,
  337. deletePathFiles);
  338. });
  339. } else {
  340. return Center(
  341. child:
  342. CircularProgressIndicator());
  343. }
  344. }),
  345. Padding(
  346. padding: const EdgeInsets.all(8.0),
  347. child: ButtonWidget(
  348. title: 'CẬP NHẬT',
  349. onPressed: () {
  350. FocusScopeNode currentFocus =
  351. FocusScope.of(context);
  352. if (!currentFocus
  353. .hasPrimaryFocus) {
  354. currentFocus.unfocus();
  355. }
  356. if (Get.find<
  357. ChangeFieldFormSupply>()
  358. .isChanged) {
  359. Utils.showDialogConfirmSupply(
  360. onConfirm: () {
  361. Get.back();
  362. _validateInputs();
  363. });
  364. } else {
  365. _validateInputs();
  366. }
  367. }),
  368. ),
  369. ],
  370. );
  371. },
  372. ),
  373. ),
  374. ))))));
  375. @override
  376. void dispose() {
  377. _quarantinePeriodController.dispose();
  378. _purposeController.dispose();
  379. _weatherController.dispose();
  380. _descriptionController.dispose();
  381. _executeByController.dispose();
  382. super.dispose();
  383. }
  384. }