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.

372 lines
15KB

  1. import 'dart:convert';
  2. import 'package:farm_tpf/custom_model/Plant.dart';
  3. import 'package:farm_tpf/custom_model/SuppliesUsing.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/controller/ChangeSupplyUsing.dart';
  13. import 'package:farm_tpf/presentation/screens/actions/plant/widget_plant_supply.dart';
  14. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_file_controller.dart';
  15. import 'package:farm_tpf/utils/const_common.dart';
  16. import 'package:farm_tpf/utils/const_string.dart';
  17. import 'package:farm_tpf/utils/const_style.dart';
  18. import 'package:farm_tpf/utils/pref.dart';
  19. import 'package:farm_tpf/utils/validators.dart';
  20. import 'package:flutter/material.dart';
  21. import 'package:flutter/services.dart';
  22. import 'package:flutter_bloc/flutter_bloc.dart';
  23. import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
  24. import 'package:get/get.dart';
  25. import 'package:intl/intl.dart';
  26. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  27. import 'package:pattern_formatter/pattern_formatter.dart';
  28. import 'package:farm_tpf/utils/formatter.dart';
  29. import '../util_action.dart';
  30. class EditActionPlantScreen extends StatefulWidget {
  31. final int cropId;
  32. final bool isEdit;
  33. final int activityId;
  34. EditActionPlantScreen(
  35. {@required this.cropId, this.isEdit = false, this.activityId});
  36. @override
  37. _EditActionPlantScreenState createState() => _EditActionPlantScreenState();
  38. }
  39. class _EditActionPlantScreenState extends State<EditActionPlantScreen> {
  40. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  41. final _repository = Repository();
  42. GlobalKey<FormState> _formKey = GlobalKey();
  43. bool _autoValidate = false;
  44. Plant _plant = Plant();
  45. var pref = LocalPref();
  46. final _descriptionController = TextEditingController();
  47. final _quantityController = TextEditingController();
  48. final _densityController = TextEditingController();
  49. final _executeByController = TextEditingController();
  50. List<SuppliesUsing> suppliesUsing = new List<SuppliesUsing>();
  51. String executeTimeView;
  52. DateTime executeTime = DateTime.now();
  53. List<String> filePaths = List<String>();
  54. var changeFileController = Get.put(ChangeFileController());
  55. Future<Null> getSharedPrefs() async {
  56. var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  57. _executeByController.text = currentFullName ?? "";
  58. }
  59. @override
  60. void initState() {
  61. super.initState();
  62. getSharedPrefs();
  63. changeFileController.initValue();
  64. _plant.suppliesUsing = new List<SuppliesUsing>();
  65. var parsedExecuteDate =
  66. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(executeTime);
  67. _plant.executeDate = "$parsedExecuteDate";
  68. executeTimeView = DateFormat("dd/MM/yyyy HH:mm").format(executeTime);
  69. _plant.cropId = widget.cropId;
  70. }
  71. _validateInputs() async {
  72. if (_formKey.currentState.validate()) {
  73. _formKey.currentState.save();
  74. LoadingDialog.showLoadingDialog(context);
  75. filePaths = Get.find<ChangeFileController>().newFiles;
  76. List<SuppliesUsing> newSups = [];
  77. suppliesUsing.forEach((sup) {
  78. var newSup = sup;
  79. newSup.suppliesInWarehouseId = sup.tbSuppliesInWarehouseId;
  80. newSups.add(newSup);
  81. });
  82. _plant.suppliesUsing = newSups;
  83. _plant.mediaDel = Get.find<ChangeFileController>().deleteFiles;
  84. var activityPlant = jsonEncode(_plant.toJson()).toString();
  85. //ADD NEW
  86. if (_plant.activityId == null) {
  87. _repository.createAction((value) {
  88. LoadingDialog.hideLoadingDialog(context);
  89. Get.back(result: value);
  90. Utils.showSnackBarSuccess(message: label_add_success);
  91. }, (error) {
  92. LoadingDialog.hideLoadingDialog(context);
  93. Utils.showSnackBarError(message: AppException.handleError(error));
  94. },
  95. apiAddAction: ConstCommon.apiAddPlant,
  96. paramActivity: ConstCommon.paramsActionPlant,
  97. activityAction: activityPlant,
  98. filePaths: filePaths);
  99. } else {
  100. //UPDATE
  101. _repository.updateAction((value) {
  102. LoadingDialog.hideLoadingDialog(context);
  103. Get.back(result: value);
  104. Utils.showSnackBarSuccess(message: label_update_success);
  105. }, (error) {
  106. LoadingDialog.hideLoadingDialog(context);
  107. Utils.showSnackBarError(message: AppException.handleError(error));
  108. },
  109. apiUpdateAction: ConstCommon.apiUpdatePlant,
  110. paramActivity: ConstCommon.paramsActionPlant,
  111. activityAction: activityPlant,
  112. filePaths: filePaths);
  113. }
  114. } else {
  115. _autoValidate = true;
  116. }
  117. }
  118. Widget _btnExecuteTimePicker() {
  119. return FlatButton(
  120. padding: EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
  121. onPressed: () {
  122. DatePicker.showDateTimePicker(context,
  123. showTitleActions: true, onChanged: (date) {}, onConfirm: (date) {
  124. setState(() {
  125. var parsedDate =
  126. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(date);
  127. _plant.executeDate = "$parsedDate";
  128. executeTimeView = DateFormat("dd/MM/yyyy HH:mm").format(date);
  129. });
  130. }, currentTime: executeTime, locale: LocaleType.vi);
  131. },
  132. child: Container(
  133. padding:
  134. EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  135. decoration: BoxDecoration(
  136. border: kBorderTextField,
  137. ),
  138. child: Row(
  139. children: [
  140. Expanded(
  141. child: Text(
  142. //TODO: check condition
  143. executeTimeView == null ? "$executeTime" : executeTimeView,
  144. style: TextStyle(fontSize: 14.0, color: Colors.black87),
  145. )),
  146. Icon(
  147. Icons.date_range,
  148. color: Colors.blue,
  149. ),
  150. ],
  151. )));
  152. }
  153. Widget _quantityField() {
  154. return WidgetTextFormFieldNumber(
  155. hintValue: "Số lượng cây trồng",
  156. textController: _quantityController,
  157. onSaved: (newValue) {
  158. _plant.quantity = newValue.parseDoubleThousand();
  159. },
  160. );
  161. }
  162. Widget _densityField() {
  163. return TextFormField(
  164. keyboardType: TextInputType.text,
  165. decoration: InputDecoration(labelText: "Mật độ"),
  166. controller: _densityController,
  167. onSaved: (newValue) {
  168. _plant.density = newValue;
  169. },
  170. );
  171. }
  172. Widget _desciptionField() {
  173. return TextFormField(
  174. keyboardType: TextInputType.text,
  175. decoration: InputDecoration(labelText: "Ghi chú"),
  176. controller: _descriptionController,
  177. onSaved: (newValue) {
  178. _plant.description = newValue;
  179. },
  180. );
  181. }
  182. Widget _executeByField() {
  183. return TextFormField(
  184. keyboardType: TextInputType.text,
  185. decoration: InputDecoration(labelText: "Người thực hiện"),
  186. enabled: false,
  187. controller: _executeByController,
  188. onSaved: (newValue) {},
  189. );
  190. }
  191. _actionAppBar() {
  192. IconButton iconButton;
  193. if (1 == 1) {
  194. iconButton = IconButton(
  195. icon: Icon(
  196. Icons.done,
  197. color: Colors.black,
  198. ),
  199. onPressed: () {
  200. FocusScopeNode currentFocus = FocusScope.of(context);
  201. if (!currentFocus.hasPrimaryFocus) {
  202. currentFocus.unfocus();
  203. }
  204. _validateInputs();
  205. },
  206. );
  207. return <Widget>[iconButton];
  208. }
  209. return <Widget>[Container()];
  210. }
  211. @override
  212. Widget build(BuildContext context) => KeyboardDismisser(
  213. gestures: [
  214. GestureType.onTap,
  215. GestureType.onPanUpdateDownDirection,
  216. ],
  217. child: Scaffold(
  218. key: _scaffoldKey,
  219. appBar: AppBar(
  220. centerTitle: true,
  221. title: Text(plot_action_plant),
  222. actions: _actionAppBar()),
  223. body: KeyboardDismisser(
  224. child: MultiBlocProvider(
  225. providers: [
  226. BlocProvider<ActionDetailBloc>(
  227. create: (context) =>
  228. ActionDetailBloc(repository: Repository())
  229. ..add(FetchData(
  230. isNeedFetchData: widget.isEdit,
  231. apiActivity: ConstCommon.apiDetailPlant,
  232. activityId: widget.activityId))),
  233. BlocProvider<MediaHelperBloc>(
  234. create: (context) =>
  235. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  236. )
  237. ],
  238. child: Form(
  239. key: _formKey,
  240. autovalidate: _autoValidate,
  241. child: SingleChildScrollView(
  242. padding: EdgeInsets.all(8.0),
  243. child: BlocConsumer<ActionDetailBloc,
  244. ActionDetailState>(
  245. listener: (context, state) async {
  246. if (state is ActionDetailFailure) {
  247. LoadingDialog.hideLoadingDialog(context);
  248. } else if (state is ActionDetailSuccess) {
  249. LoadingDialog.hideLoadingDialog(context);
  250. _plant = Plant.fromJson(state.item);
  251. _plant.activityId = widget.activityId;
  252. _quantityController.text = _plant.quantity
  253. .formatNumtoStringDecimal();
  254. _densityController.text = _plant.density;
  255. _descriptionController.text =
  256. _plant.description;
  257. _executeByController.text = _plant.executeBy;
  258. try {
  259. executeTime =
  260. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
  261. .parse(_plant.executeDate);
  262. } catch (_) {}
  263. executeTimeView =
  264. DateFormat("dd/MM/yyyy HH:mm")
  265. .format(executeTime);
  266. //Show media
  267. if (Validators.stringNotNullOrEmpty(
  268. _plant.media)) {
  269. BlocProvider.of<MediaHelperBloc>(context)
  270. .add(ChangeListMedia(
  271. items: UtilAction
  272. .convertFilePathToMedia(
  273. _plant.media)));
  274. }
  275. //list supply
  276. suppliesUsing = _plant.suppliesUsing;
  277. Get.find<ChangeSupplyUsing>()
  278. .changeInitList(suppliesUsing);
  279. } else if (state is ActionDetailInitial) {
  280. print("init");
  281. } else if (state is ActionDetailLoading) {
  282. print("loading");
  283. LoadingDialog.showLoadingDialog(context);
  284. }
  285. },
  286. builder: (context, state) {
  287. return Column(
  288. children: <Widget>[
  289. Container(
  290. width: double.infinity,
  291. child: Text(
  292. "Ngày thực hiện *",
  293. style: TextStyle(
  294. color: Colors.black54,
  295. fontSize: 13.0),
  296. ),
  297. ),
  298. _btnExecuteTimePicker(),
  299. SizedBox(
  300. height: 8.0,
  301. ),
  302. _quantityField(),
  303. SizedBox(
  304. height: 8.0,
  305. ),
  306. _densityField(),
  307. SizedBox(
  308. height: 8.0,
  309. ),
  310. _desciptionField(),
  311. SizedBox(
  312. height: 8.0,
  313. ),
  314. _executeByField(),
  315. SizedBox(
  316. height: 8.0,
  317. ),
  318. WidgetPlantSupply(
  319. currentItems: [],
  320. onChangeSupplies: (value) {
  321. suppliesUsing = value;
  322. }),
  323. SizedBox(
  324. height: 8.0,
  325. ),
  326. BlocBuilder<MediaHelperBloc,
  327. MediaHelperState>(
  328. builder: (context, state) {
  329. if (state is MediaHelperSuccess) {
  330. return WidgetMediaPicker(
  331. currentItems: state.items,
  332. onChangeFiles: (newPathFiles,
  333. deletePathFiles) async {
  334. Get.find<ChangeFileController>()
  335. .change(newPathFiles,
  336. deletePathFiles);
  337. });
  338. } else {
  339. return Center(
  340. child: CircularProgressIndicator());
  341. }
  342. }),
  343. ],
  344. );
  345. },
  346. ),
  347. ))))));
  348. @override
  349. void dispose() {
  350. _quantityController.dispose();
  351. _densityController.dispose();
  352. _descriptionController.dispose();
  353. _executeByController.dispose();
  354. super.dispose();
  355. }
  356. }