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.

348 lines
14KB

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