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.

390 lines
18KB

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