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.

438 lines
20KB

  1. import 'dart:convert';
  2. import 'package:farm_tpf/custom_model/Harvest.dart';
  3. import 'package:farm_tpf/data/api/app_exception.dart';
  4. import 'package:farm_tpf/data/repository/repository.dart';
  5. import 'package:farm_tpf/presentation/custom_widgets/app_bar_widget.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart';
  7. import 'package:farm_tpf/presentation/custom_widgets/button_icon_widget.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/harvest_process/sc_edit_action_harvest_process.dart';
  17. import 'package:farm_tpf/presentation/screens/actions/packing/sc_edit_action_packing.dart';
  18. import 'package:farm_tpf/presentation/screens/actions/sell/sc_edit_action_sell.dart';
  19. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_file_controller.dart';
  20. import 'package:farm_tpf/presentation/screens/actions/util_action.dart';
  21. import 'package:farm_tpf/utils/const_common.dart';
  22. import 'package:farm_tpf/utils/const_icons.dart';
  23. import 'package:farm_tpf/utils/const_string.dart';
  24. import 'package:farm_tpf/utils/const_style.dart';
  25. import 'package:farm_tpf/utils/pref.dart';
  26. import 'package:farm_tpf/utils/validators.dart';
  27. import 'package:flutter/material.dart';
  28. import 'package:flutter_bloc/flutter_bloc.dart';
  29. import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
  30. import 'package:get/get.dart';
  31. import 'package:intl/intl.dart';
  32. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  33. import 'package:pattern_formatter/pattern_formatter.dart';
  34. import 'package:farm_tpf/utils/formatter.dart';
  35. class EditActionHarvestScreen extends StatefulWidget {
  36. final int cropId;
  37. final bool isEdit;
  38. final int activityId;
  39. EditActionHarvestScreen(
  40. {@required this.cropId, this.isEdit = false, this.activityId});
  41. @override
  42. _EditActionHarvestScreenState createState() =>
  43. _EditActionHarvestScreenState();
  44. }
  45. class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
  46. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  47. final _repository = Repository();
  48. GlobalKey<FormState> _formKey = GlobalKey();
  49. bool _autoValidate = false;
  50. Harvest _harvest = Harvest();
  51. TextEditingController _l1Controller = TextEditingController();
  52. TextEditingController _l2Controller = TextEditingController();
  53. TextEditingController _l3Controller = TextEditingController();
  54. TextEditingController _removedQuantityController = TextEditingController();
  55. TextEditingController _descriptionController = TextEditingController();
  56. final _executeByController = TextEditingController();
  57. var pref = LocalPref();
  58. DateTime executeTime = DateTime.now();
  59. List<String> filePaths = List<String>();
  60. var changeFileController = Get.put(ChangeFileController());
  61. Future<Null> getSharedPrefs() async {
  62. var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  63. _executeByController.text = currentFullName ?? "";
  64. }
  65. @override
  66. void initState() {
  67. super.initState();
  68. getSharedPrefs();
  69. changeFileController.initValue();
  70. _harvest.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. try {
  78. _harvest.mediaDel = Get.find<ChangeFileController>().deleteFiles;
  79. var activityHarvest = jsonEncode(_harvest.toJson()).toString();
  80. //ADD NEW
  81. if (_harvest.activityId == null) {
  82. _repository.createAction((value) {
  83. LoadingDialog.hideLoadingDialog(context);
  84. Get.back(result: value);
  85. Utils.showSnackBarSuccess(message: label_add_success);
  86. }, (error) {
  87. LoadingDialog.hideLoadingDialog(context);
  88. Utils.showSnackBarError(message: AppException.handleError(error));
  89. },
  90. apiAddAction: ConstCommon.apiAddHarvest,
  91. paramActivity: ConstCommon.paramsActionHarvest,
  92. activityAction: activityHarvest,
  93. filePaths: filePaths);
  94. } else {
  95. //UPDATE
  96. _repository.updateAction((value) {
  97. LoadingDialog.hideLoadingDialog(context);
  98. Get.back(result: value);
  99. Utils.showSnackBarSuccess(message: label_update_success);
  100. }, (error) {
  101. LoadingDialog.hideLoadingDialog(context);
  102. Utils.showSnackBarError(message: AppException.handleError(error));
  103. },
  104. apiUpdateAction: ConstCommon.apiUpdateHarvest,
  105. paramActivity: ConstCommon.paramsActionHarvest,
  106. activityAction: activityHarvest,
  107. filePaths: filePaths);
  108. }
  109. } catch (e) {
  110. LoadingDialog.hideLoadingDialog(context);
  111. print(e.toString());
  112. }
  113. } else {
  114. _autoValidate = true;
  115. }
  116. }
  117. Widget _btnExecuteTimePicker() {
  118. return WidgetFieldDateTimePicker(
  119. initDateTime: executeTime,
  120. onUpdateDateTime: (selectedDate) {
  121. _harvest.executeDate =
  122. selectedDate.convertLocalDateTimeToStringUtcDateTime();
  123. });
  124. }
  125. Widget _l1Field() {
  126. return WidgetTextFormFieldNumber(
  127. hintValue: "Số lượng/khối lượng loại 1",
  128. textController: _l1Controller,
  129. onSaved: (newValue) {
  130. _harvest.collectedQuantityLv1 = newValue.parseDoubleThousand();
  131. },
  132. );
  133. }
  134. Widget _l2Field() {
  135. return WidgetTextFormFieldNumber(
  136. hintValue: "Số lượng/khối lượng loại 2",
  137. textController: _l2Controller,
  138. onSaved: (newValue) {
  139. _harvest.collectedQuantityLv2 = newValue.parseDoubleThousand();
  140. },
  141. );
  142. }
  143. Widget _l3Field() {
  144. return WidgetTextFormFieldNumber(
  145. hintValue: "Số lượng/khối lượng loại 3",
  146. textController: _l3Controller,
  147. onSaved: (newValue) {
  148. _harvest.collectedQuantityLv3 = newValue.parseDoubleThousand();
  149. },
  150. );
  151. }
  152. Widget _removedQuantityField() {
  153. return WidgetTextFormFieldNumber(
  154. hintValue: "Số lượng/khối lượng loại bỏ",
  155. textController: _removedQuantityController,
  156. onSaved: (newValue) {
  157. _harvest.removedQuantity = newValue.parseDoubleThousand();
  158. },
  159. );
  160. }
  161. Widget _descriptionField() {
  162. return TextFieldDescriptionWidget(
  163. controller: _descriptionController,
  164. onSaved: (newValue) {
  165. _harvest.description = newValue;
  166. });
  167. }
  168. Widget _executeByField() {
  169. return TextFormField(
  170. keyboardType: TextInputType.text,
  171. decoration: InputDecoration(labelText: "Người thực hiện"),
  172. enabled: false,
  173. controller: _executeByController,
  174. onSaved: (newValue) {},
  175. );
  176. }
  177. @override
  178. Widget build(BuildContext context) => KeyboardDismisser(
  179. gestures: [
  180. GestureType.onTap,
  181. GestureType.onPanUpdateDownDirection,
  182. ],
  183. child: Scaffold(
  184. backgroundColor: Colors.white,
  185. key: _scaffoldKey,
  186. appBar: AppBarWidget(
  187. isBack: true,
  188. action: InkWell(
  189. child: Text(
  190. 'Huỷ',
  191. style: TextStyle(
  192. color: Colors.red, fontWeight: FontWeight.normal),
  193. ),
  194. onTap: () {
  195. if (Get.isSnackbarOpen) Get.back();
  196. Get.back();
  197. },
  198. ),
  199. ),
  200. body: KeyboardDismisser(
  201. child: MultiBlocProvider(
  202. providers: [
  203. BlocProvider<ActionDetailBloc>(
  204. create: (context) =>
  205. ActionDetailBloc(repository: Repository())
  206. ..add(FetchData(
  207. isNeedFetchData: widget.isEdit,
  208. apiActivity: ConstCommon.apiDetailHarvest,
  209. activityId: widget.activityId))),
  210. BlocProvider<MediaHelperBloc>(
  211. create: (context) =>
  212. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  213. )
  214. ],
  215. child: Form(
  216. key: _formKey,
  217. autovalidate: _autoValidate,
  218. child: SafeArea(
  219. child: SingleChildScrollView(
  220. child:
  221. BlocConsumer<ActionDetailBloc, ActionDetailState>(
  222. listener: (context, state) async {
  223. if (state is ActionDetailFailure) {
  224. LoadingDialog.hideLoadingDialog(context);
  225. } else if (state is ActionDetailSuccess) {
  226. LoadingDialog.hideLoadingDialog(context);
  227. print(state.item);
  228. _harvest = Harvest.fromJson(state.item);
  229. _harvest.activityId = widget.activityId;
  230. _l1Controller.text = _harvest.collectedQuantityLv1
  231. .formatNumtoStringDecimal();
  232. _l2Controller.text = _harvest.collectedQuantityLv2
  233. .formatNumtoStringDecimal();
  234. _l3Controller.text = _harvest.collectedQuantityLv3
  235. .formatNumtoStringDecimal();
  236. _removedQuantityController.text = _harvest
  237. .removedQuantity
  238. .formatNumtoStringDecimal();
  239. _descriptionController.text =
  240. _harvest.description ?? "";
  241. _executeByController.text = _harvest.executeBy;
  242. Get.find<ChangeDateTimePicker>().change(_harvest
  243. .executeDate
  244. .convertStringServerDateTimeToLocalDateTime());
  245. //Show media
  246. if (Validators.stringNotNullOrEmpty(
  247. _harvest.media)) {
  248. BlocProvider.of<MediaHelperBloc>(context).add(
  249. ChangeListMedia(
  250. items:
  251. UtilAction.convertFilePathToMedia(
  252. _harvest.media)));
  253. }
  254. } else if (state is ActionDetailInitial) {
  255. } else if (state is ActionDetailLoading) {
  256. LoadingDialog.showLoadingDialog(context);
  257. }
  258. },
  259. builder: (context, state) {
  260. return Column(
  261. children: [
  262. Padding(
  263. padding: const EdgeInsets.all(8.0),
  264. child: Column(
  265. crossAxisAlignment:
  266. CrossAxisAlignment.start,
  267. children: <Widget>[
  268. Text(
  269. plot_action_harvest,
  270. style: TextStyle(
  271. fontWeight: FontWeight.w500,
  272. fontSize: 22),
  273. ),
  274. SizedBox(
  275. height: 8.0,
  276. ),
  277. Container(
  278. width: double.infinity,
  279. child: Text(
  280. "Ngày thực hiện *",
  281. style: TextStyle(
  282. color: Colors.black54,
  283. fontSize: 13.0),
  284. ),
  285. ),
  286. _btnExecuteTimePicker(),
  287. SizedBox(
  288. height: 8.0,
  289. ),
  290. _l1Field(),
  291. SizedBox(
  292. height: 8.0,
  293. ),
  294. _l2Field(),
  295. SizedBox(
  296. height: 8.0,
  297. ),
  298. _l3Field(),
  299. SizedBox(
  300. height: 8.0,
  301. ),
  302. _removedQuantityField(),
  303. SizedBox(
  304. height: 8.0,
  305. ),
  306. _descriptionField(),
  307. SizedBox(
  308. height: 8.0,
  309. ),
  310. _executeByField(),
  311. SizedBox(
  312. height: 8.0,
  313. ),
  314. ],
  315. ),
  316. ),
  317. Container(
  318. width: double.infinity,
  319. height: 16,
  320. color: Colors.grey[200],
  321. ),
  322. BlocBuilder<MediaHelperBloc, MediaHelperState>(
  323. builder: (context, state) {
  324. if (state is MediaHelperSuccess) {
  325. return WidgetMediaPicker(
  326. currentItems: state.items,
  327. onChangeFiles: (newPathFiles,
  328. deletePathFiles) async {
  329. Get.find<ChangeFileController>()
  330. .change(newPathFiles,
  331. deletePathFiles);
  332. });
  333. } else {
  334. return Center(
  335. child: CircularProgressIndicator());
  336. }
  337. }),
  338. Container(
  339. width: double.infinity,
  340. height: 16,
  341. color: Colors.grey[200],
  342. ),
  343. ButtonIconWidget(
  344. leadingIcon: AppIcons.icHarvestProcess,
  345. trailingIcon: AppIcons.icArrowRight,
  346. title: plot_action_harvest_process,
  347. onTap: () {
  348. if (_harvest.id != null) {
  349. Get.to(EditActionHarvestProcessScreen(
  350. cropId: widget.cropId,
  351. harvestId: _harvest.id,
  352. ));
  353. } else {
  354. Get.to(EditActionHarvestProcessScreen(
  355. cropId: widget.cropId));
  356. }
  357. }),
  358. ButtonIconWidget(
  359. leadingIcon: AppIcons.icPacking,
  360. trailingIcon: AppIcons.icArrowRight,
  361. title: plot_action_packing,
  362. onTap: () {
  363. if (_harvest.id != null) {
  364. Get.to(EditActionPackingScreen(
  365. cropId: widget.cropId,
  366. harvestId: _harvest.id,
  367. ));
  368. } else {
  369. Get.to(EditActionPackingScreen(
  370. cropId: widget.cropId));
  371. }
  372. }),
  373. ButtonIconWidget(
  374. leadingIcon: AppIcons.icSell,
  375. trailingIcon: AppIcons.icArrowRight,
  376. title: plot_action_sell,
  377. onTap: () {
  378. if (_harvest.id != null) {
  379. Get.to(EditActionSellScreen(
  380. cropId: widget.cropId,
  381. harvestId: _harvest.id,
  382. ));
  383. } else {
  384. Get.to(EditActionSellScreen(
  385. cropId: widget.cropId));
  386. }
  387. }),
  388. SizedBox(
  389. height: 16,
  390. ),
  391. Padding(
  392. padding: const EdgeInsets.all(8.0),
  393. child: ButtonWidget(
  394. title: 'CẬP NHẬT',
  395. onPressed: () {
  396. FocusScopeNode currentFocus =
  397. FocusScope.of(context);
  398. if (!currentFocus.hasPrimaryFocus) {
  399. currentFocus.unfocus();
  400. }
  401. _validateInputs();
  402. }),
  403. ),
  404. ],
  405. );
  406. },
  407. ),
  408. ),
  409. )),
  410. ))));
  411. @override
  412. void dispose() {
  413. _l1Controller.dispose();
  414. _l2Controller.dispose();
  415. _l3Controller.dispose();
  416. _removedQuantityController.dispose();
  417. _descriptionController.dispose();
  418. _executeByController.dispose();
  419. super.dispose();
  420. }
  421. }