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.

479 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/bloc/media_helper_bloc.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  7. import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart';
  8. import 'package:farm_tpf/presentation/custom_widgets/widget_text_form_field.dart';
  9. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  10. import 'package:farm_tpf/presentation/screens/actions/bloc/action_detail_bloc.dart';
  11. import 'package:farm_tpf/presentation/screens/actions/harvest_process/sc_edit_action_harvest_process.dart';
  12. import 'package:farm_tpf/presentation/screens/actions/packing/sc_edit_action_packing.dart';
  13. import 'package:farm_tpf/presentation/screens/actions/sell/sc_edit_action_sell.dart';
  14. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_file_controller.dart';
  15. import 'package:farm_tpf/presentation/screens/actions/util_action.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. class EditActionHarvestScreen extends StatefulWidget {
  30. final int cropId;
  31. final bool isEdit;
  32. final int activityId;
  33. EditActionHarvestScreen(
  34. {@required this.cropId, this.isEdit = false, this.activityId});
  35. @override
  36. _EditActionHarvestScreenState createState() =>
  37. _EditActionHarvestScreenState();
  38. }
  39. class _EditActionHarvestScreenState extends State<EditActionHarvestScreen> {
  40. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  41. final _repository = Repository();
  42. GlobalKey<FormState> _formKey = GlobalKey();
  43. bool _autoValidate = false;
  44. Harvest _harvest = Harvest();
  45. TextEditingController _l1Controller = TextEditingController();
  46. TextEditingController _l2Controller = TextEditingController();
  47. TextEditingController _l3Controller = TextEditingController();
  48. TextEditingController _removedQuantityController = TextEditingController();
  49. TextEditingController _descriptionController = TextEditingController();
  50. final _executeByController = TextEditingController();
  51. var pref = LocalPref();
  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. var parsedExecuteDate =
  66. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(executeTime);
  67. _harvest.executeDate = "$parsedExecuteDate";
  68. executeTimeView = DateFormat("dd/MM/yyyy HH:mm").format(executeTime);
  69. _harvest.cropId = widget.cropId;
  70. }
  71. _validateInputs() async {
  72. if (_formKey.currentState.validate()) {
  73. _formKey.currentState.save();
  74. LoadingDialog.showLoadingDialog(context);
  75. filePaths = Get.find<ChangeFileController>().newFiles;
  76. try {
  77. _harvest.mediaDel = Get.find<ChangeFileController>().deleteFiles;
  78. var activityHarvest = jsonEncode(_harvest.toJson()).toString();
  79. //ADD NEW
  80. if (_harvest.activityId == null) {
  81. _repository.createAction((value) {
  82. LoadingDialog.hideLoadingDialog(context);
  83. Get.back(result: value);
  84. Utils.showSnackBarSuccess(message: label_add_success);
  85. }, (error) {
  86. LoadingDialog.hideLoadingDialog(context);
  87. Utils.showSnackBarError(message: AppException.handleError(error));
  88. },
  89. apiAddAction: ConstCommon.apiAddHarvest,
  90. paramActivity: ConstCommon.paramsActionHarvest,
  91. activityAction: activityHarvest,
  92. filePaths: filePaths);
  93. } else {
  94. //UPDATE
  95. _repository.updateAction((value) {
  96. LoadingDialog.hideLoadingDialog(context);
  97. Get.back(result: value);
  98. Utils.showSnackBarSuccess(message: label_update_success);
  99. }, (error) {
  100. LoadingDialog.hideLoadingDialog(context);
  101. Utils.showSnackBarError(message: AppException.handleError(error));
  102. },
  103. apiUpdateAction: ConstCommon.apiUpdateHarvest,
  104. paramActivity: ConstCommon.paramsActionHarvest,
  105. activityAction: activityHarvest,
  106. filePaths: filePaths);
  107. }
  108. } catch (e) {
  109. LoadingDialog.hideLoadingDialog(context);
  110. print(e.toString());
  111. }
  112. } else {
  113. _autoValidate = true;
  114. }
  115. }
  116. Widget _btnExecuteTimePicker() {
  117. return FlatButton(
  118. padding: EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
  119. onPressed: () {
  120. DatePicker.showDateTimePicker(context,
  121. showTitleActions: true, onChanged: (date) {}, onConfirm: (date) {
  122. setState(() {
  123. var parsedDate =
  124. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(date);
  125. _harvest.executeDate = "$parsedDate";
  126. executeTimeView = DateFormat("dd/MM/yyyy HH:mm").format(date);
  127. });
  128. }, currentTime: executeTime, locale: LocaleType.vi);
  129. },
  130. child: Container(
  131. padding:
  132. EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  133. decoration: BoxDecoration(
  134. border: kBorderTextField,
  135. ),
  136. child: Row(
  137. children: [
  138. Expanded(
  139. child: Text(
  140. //TODO: check condition
  141. executeTimeView == null ? "$executeTime" : executeTimeView,
  142. style: TextStyle(fontSize: 14.0, color: Colors.black87),
  143. )),
  144. Icon(
  145. Icons.date_range,
  146. color: Colors.blue,
  147. ),
  148. ],
  149. )));
  150. }
  151. Widget _l1Field() {
  152. return WidgetTextFormFieldNumber(
  153. hintValue: "Số lượng/khối lượng loại 1",
  154. textController: _l1Controller,
  155. onSaved: (newValue) {
  156. _harvest.collectedQuantityLv1 = newValue.parseDoubleThousand();
  157. },
  158. );
  159. }
  160. Widget _l2Field() {
  161. return WidgetTextFormFieldNumber(
  162. hintValue: "Số lượng/khối lượng loại 2",
  163. textController: _l2Controller,
  164. onSaved: (newValue) {
  165. _harvest.collectedQuantityLv2 = newValue.parseDoubleThousand();
  166. },
  167. );
  168. }
  169. Widget _l3Field() {
  170. return WidgetTextFormFieldNumber(
  171. hintValue: "Số lượng/khối lượng loại 3",
  172. textController: _l3Controller,
  173. onSaved: (newValue) {
  174. _harvest.collectedQuantityLv3 = newValue.parseDoubleThousand();
  175. },
  176. );
  177. }
  178. Widget _removedQuantityField() {
  179. return WidgetTextFormFieldNumber(
  180. hintValue: "Số lượng/khối lượng loại bỏ",
  181. textController: _removedQuantityController,
  182. onSaved: (newValue) {
  183. _harvest.removedQuantity = newValue.parseDoubleThousand();
  184. },
  185. );
  186. }
  187. Widget _descriptionField() {
  188. return TextFormField(
  189. keyboardType: TextInputType.text,
  190. decoration: InputDecoration(labelText: "Ghi chú"),
  191. controller: _descriptionController,
  192. onSaved: (newValue) {
  193. _harvest.description = newValue;
  194. },
  195. );
  196. }
  197. Widget _executeByField() {
  198. return TextFormField(
  199. keyboardType: TextInputType.text,
  200. decoration: InputDecoration(labelText: "Người thực hiện"),
  201. enabled: false,
  202. controller: _executeByController,
  203. onSaved: (newValue) {},
  204. );
  205. }
  206. _actionAppBar() {
  207. IconButton iconButton;
  208. if (1 == 1) {
  209. iconButton = IconButton(
  210. icon: Icon(
  211. Icons.done,
  212. color: Colors.black,
  213. ),
  214. onPressed: () {
  215. FocusScopeNode currentFocus = FocusScope.of(context);
  216. if (!currentFocus.hasPrimaryFocus) {
  217. currentFocus.unfocus();
  218. }
  219. _validateInputs();
  220. },
  221. );
  222. return <Widget>[iconButton];
  223. }
  224. return <Widget>[Container()];
  225. }
  226. @override
  227. Widget build(BuildContext context) => KeyboardDismisser(
  228. gestures: [
  229. GestureType.onTap,
  230. GestureType.onPanUpdateDownDirection,
  231. ],
  232. child: Scaffold(
  233. key: _scaffoldKey,
  234. appBar: AppBar(
  235. centerTitle: true,
  236. title: Text(plot_action_harvest),
  237. actions: _actionAppBar()),
  238. body: KeyboardDismisser(
  239. child: MultiBlocProvider(
  240. providers: [
  241. BlocProvider<ActionDetailBloc>(
  242. create: (context) =>
  243. ActionDetailBloc(repository: Repository())
  244. ..add(FetchData(
  245. isNeedFetchData: widget.isEdit,
  246. apiActivity: ConstCommon.apiDetailHarvest,
  247. activityId: widget.activityId))),
  248. BlocProvider<MediaHelperBloc>(
  249. create: (context) =>
  250. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  251. )
  252. ],
  253. child: Form(
  254. key: _formKey,
  255. autovalidate: _autoValidate,
  256. child: SingleChildScrollView(
  257. padding: EdgeInsets.all(8.0),
  258. child: BlocConsumer<ActionDetailBloc, ActionDetailState>(
  259. listener: (context, state) async {
  260. if (state is ActionDetailFailure) {
  261. LoadingDialog.hideLoadingDialog(context);
  262. } else if (state is ActionDetailSuccess) {
  263. LoadingDialog.hideLoadingDialog(context);
  264. print(state.item);
  265. _harvest = Harvest.fromJson(state.item);
  266. _harvest.activityId = widget.activityId;
  267. _l1Controller.text = _harvest.collectedQuantityLv1
  268. .formatNumtoStringDecimal();
  269. _l2Controller.text = _harvest.collectedQuantityLv2
  270. .formatNumtoStringDecimal();
  271. _l3Controller.text = _harvest.collectedQuantityLv3
  272. .formatNumtoStringDecimal();
  273. _removedQuantityController.text = _harvest
  274. .removedQuantity
  275. .formatNumtoStringDecimal();
  276. _descriptionController.text =
  277. _harvest.description ?? "";
  278. _executeByController.text = _harvest.executeBy;
  279. try {
  280. executeTime =
  281. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
  282. .parse(_harvest.executeDate);
  283. executeTimeView = DateFormat("dd/MM/yyyy HH:mm")
  284. .format(executeTime);
  285. } catch (_) {}
  286. //Show media
  287. if (Validators.stringNotNullOrEmpty(
  288. _harvest.media)) {
  289. BlocProvider.of<MediaHelperBloc>(context).add(
  290. ChangeListMedia(
  291. items: UtilAction.convertFilePathToMedia(
  292. _harvest.media)));
  293. }
  294. } else if (state is ActionDetailInitial) {
  295. } else if (state is ActionDetailLoading) {
  296. LoadingDialog.showLoadingDialog(context);
  297. }
  298. },
  299. builder: (context, state) {
  300. return Column(
  301. children: <Widget>[
  302. Container(
  303. width: double.infinity,
  304. child: Text(
  305. "Ngày thực hiện *",
  306. style: TextStyle(
  307. color: Colors.black54, fontSize: 13.0),
  308. ),
  309. ),
  310. _btnExecuteTimePicker(),
  311. SizedBox(
  312. height: 8.0,
  313. ),
  314. _l1Field(),
  315. SizedBox(
  316. height: 8.0,
  317. ),
  318. _l2Field(),
  319. SizedBox(
  320. height: 8.0,
  321. ),
  322. _l3Field(),
  323. SizedBox(
  324. height: 8.0,
  325. ),
  326. _removedQuantityField(),
  327. SizedBox(
  328. height: 8.0,
  329. ),
  330. _descriptionField(),
  331. SizedBox(
  332. height: 8.0,
  333. ),
  334. _executeByField(),
  335. SizedBox(
  336. height: 8.0,
  337. ),
  338. BlocBuilder<MediaHelperBloc, MediaHelperState>(
  339. builder: (context, state) {
  340. if (state is MediaHelperSuccess) {
  341. return WidgetMediaPicker(
  342. currentItems: state.items,
  343. onChangeFiles: (newPathFiles,
  344. deletePathFiles) async {
  345. Get.find<ChangeFileController>().change(
  346. newPathFiles, deletePathFiles);
  347. });
  348. } else {
  349. return Center(
  350. child: CircularProgressIndicator());
  351. }
  352. }),
  353. Row(
  354. mainAxisAlignment:
  355. MainAxisAlignment.spaceBetween,
  356. children: [
  357. SizedBox(
  358. width: Get.width / 2 - 16,
  359. child: FlatButton(
  360. padding: EdgeInsets.all(14),
  361. shape: RoundedRectangleBorder(
  362. borderRadius:
  363. new BorderRadius.circular(8.0)),
  364. color: Colors.lightGreen,
  365. onPressed: () {
  366. if (_harvest.id != null) {
  367. Get.to(EditActionHarvestProcessScreen(
  368. cropId: widget.cropId,
  369. harvestId: _harvest.id,
  370. ));
  371. } else {
  372. Get.to(EditActionHarvestProcessScreen(
  373. cropId: widget.cropId));
  374. }
  375. },
  376. child: Text(
  377. plot_action_harvest_process,
  378. style: TextStyle(
  379. color: Colors.white, fontSize: 14),
  380. ),
  381. ),
  382. ),
  383. SizedBox(
  384. width: Get.width / 2 - 16,
  385. child: FlatButton(
  386. padding: EdgeInsets.all(14),
  387. shape: RoundedRectangleBorder(
  388. borderRadius:
  389. new BorderRadius.circular(8.0)),
  390. color: Colors.lightGreen,
  391. onPressed: () {
  392. if (_harvest.id != null) {
  393. Get.to(EditActionPackingScreen(
  394. cropId: widget.cropId,
  395. harvestId: _harvest.id,
  396. ));
  397. } else {
  398. Get.to(EditActionPackingScreen(
  399. cropId: widget.cropId));
  400. }
  401. },
  402. child: Text(
  403. plot_action_packing,
  404. style: TextStyle(
  405. color: Colors.white, fontSize: 14),
  406. ),
  407. ),
  408. )
  409. ],
  410. ),
  411. SizedBox(
  412. height: 8,
  413. ),
  414. Row(
  415. mainAxisAlignment: MainAxisAlignment.start,
  416. children: [
  417. SizedBox(
  418. width: Get.width / 2 - 16,
  419. child: FlatButton(
  420. padding: EdgeInsets.all(14),
  421. shape: RoundedRectangleBorder(
  422. borderRadius:
  423. new BorderRadius.circular(8.0)),
  424. color: Colors.lightGreen,
  425. onPressed: () {
  426. if (_harvest.id != null) {
  427. Get.to(EditActionSellScreen(
  428. cropId: widget.cropId,
  429. harvestId: _harvest.id,
  430. ));
  431. } else {
  432. Get.to(EditActionSellScreen(
  433. cropId: widget.cropId));
  434. }
  435. },
  436. child: Text(
  437. plot_action_sell,
  438. style: TextStyle(
  439. color: Colors.white, fontSize: 14),
  440. ),
  441. ),
  442. )
  443. ],
  444. ),
  445. ],
  446. );
  447. },
  448. ),
  449. )),
  450. ))));
  451. @override
  452. void dispose() {
  453. _l1Controller.dispose();
  454. _l2Controller.dispose();
  455. _l3Controller.dispose();
  456. _removedQuantityController.dispose();
  457. _descriptionController.dispose();
  458. _executeByController.dispose();
  459. super.dispose();
  460. }
  461. }