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.

453 lines
17KB

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