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.

451 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. _packing.executeDate =
  71. executeTime.convertLocalDateTimeToStringUtcDateTime();
  72. executeTimeView = executeTime.displayDateTime_DDMMYYYY_HHmm();
  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. executeTime = date;
  171. _packing.executeDate =
  172. executeTime.convertLocalDateTimeToStringUtcDateTime();
  173. executeTimeView = executeTime.displayDateTime_DDMMYYYY_HHmm();
  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. executeTime = _packing.executeDate
  337. .convertStringServerDateTimeToLocalDateTime();
  338. executeTimeView =
  339. executeTime.displayDateTime_DDMMYYYY_HHmm();
  340. //Show media
  341. if (Validators.stringNotNullOrEmpty(
  342. _packing.media)) {
  343. BlocProvider.of<MediaHelperBloc>(context).add(
  344. ChangeListMedia(
  345. items: UtilAction.convertFilePathToMedia(
  346. _packing.media)));
  347. }
  348. } else if (state is ActionDetailInitial) {
  349. } else if (state is ActionDetailLoading) {
  350. LoadingDialog.showLoadingDialog(context);
  351. }
  352. },
  353. builder: (context, state) {
  354. return Column(
  355. children: <Widget>[
  356. Container(
  357. width: double.infinity,
  358. child: Text(
  359. "Ngày thực hiện *",
  360. style: TextStyle(
  361. color: Colors.black54, fontSize: 13.0),
  362. ),
  363. ),
  364. _btnExecuteTimePicker(),
  365. SizedBox(
  366. height: 8.0,
  367. ),
  368. _dropdownHarvest(),
  369. SizedBox(
  370. height: 8.0,
  371. ),
  372. _l1Field(),
  373. SizedBox(
  374. height: 8.0,
  375. ),
  376. _l2Field(),
  377. SizedBox(
  378. height: 8.0,
  379. ),
  380. _l3Field(),
  381. SizedBox(
  382. height: 8.0,
  383. ),
  384. _removedQuantityField(),
  385. SizedBox(
  386. height: 8.0,
  387. ),
  388. _descriptionField(),
  389. SizedBox(
  390. height: 8.0,
  391. ),
  392. _executeByField(),
  393. SizedBox(
  394. height: 8.0,
  395. ),
  396. BlocBuilder<MediaHelperBloc, MediaHelperState>(
  397. builder: (context, state) {
  398. if (state is MediaHelperSuccess) {
  399. return WidgetMediaPicker(
  400. currentItems: state.items,
  401. onChangeFiles: (newPathFiles,
  402. deletePathFiles) async {
  403. Get.find<ChangeFileController>().change(
  404. newPathFiles, deletePathFiles);
  405. });
  406. } else {
  407. return Center(
  408. child: CircularProgressIndicator());
  409. }
  410. }),
  411. ],
  412. );
  413. },
  414. ),
  415. )),
  416. ))));
  417. @override
  418. void dispose() {
  419. _l1Controller.dispose();
  420. _l2Controller.dispose();
  421. _l3Controller.dispose();
  422. _removedQuantityController.dispose();
  423. _descriptionController.dispose();
  424. _executeByController.dispose();
  425. super.dispose();
  426. }
  427. }