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.

508 lines
21KB

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