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.

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