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.

465 lines
17KB

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