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.

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