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.

327 lines
13KB

  1. import 'dart:convert';
  2. import 'package:farm_tpf/custom_model/End.dart';
  3. import 'package:farm_tpf/data/api/app_exception.dart';
  4. import 'package:farm_tpf/data/repository/repository.dart';
  5. import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  7. import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart';
  8. import 'package:farm_tpf/presentation/screens/actions/bloc/action_detail_bloc.dart';
  9. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_file_controller.dart';
  10. import 'package:farm_tpf/utils/const_common.dart';
  11. import 'package:farm_tpf/utils/const_string.dart';
  12. import 'package:farm_tpf/utils/const_style.dart';
  13. import 'package:farm_tpf/utils/pref.dart';
  14. import 'package:flutter/material.dart';
  15. import 'package:flutter_bloc/flutter_bloc.dart';
  16. import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
  17. import 'package:get/get.dart';
  18. import 'package:intl/intl.dart';
  19. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  20. import '../util_action.dart';
  21. class EditActionEndScreen extends StatefulWidget {
  22. final int cropId;
  23. final bool isEdit;
  24. final int activityId;
  25. EditActionEndScreen(
  26. {@required this.cropId, this.isEdit = false, this.activityId});
  27. @override
  28. _EditActionEndScreenState createState() => _EditActionEndScreenState();
  29. }
  30. class _EditActionEndScreenState extends State<EditActionEndScreen> {
  31. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  32. final _repository = Repository();
  33. GlobalKey<FormState> _formKey = GlobalKey();
  34. bool _autoValidate = false;
  35. End _end = End();
  36. final _descriptionController = TextEditingController();
  37. final _executeByController = TextEditingController();
  38. var pref = LocalPref();
  39. String executeTimeView;
  40. DateTime executeTime = DateTime.now();
  41. List<String> filePaths = List<String>();
  42. var changeFileController = Get.put(ChangeFileController());
  43. Future<Null> getSharedPrefs() async {
  44. var currentFullName = await pref.getString(DATA_CONST.CURRENT_FULL_NAME);
  45. _executeByController.text = currentFullName ?? "";
  46. }
  47. @override
  48. void initState() {
  49. super.initState();
  50. getSharedPrefs();
  51. changeFileController.initValue();
  52. var parsedExecuteDate =
  53. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(executeTime);
  54. _end.executeDate = "$parsedExecuteDate";
  55. executeTimeView = DateFormat("dd/MM/yyyy HH:mm").format(executeTime);
  56. _end.cropId = widget.cropId;
  57. }
  58. _validateInputs() async {
  59. if (_formKey.currentState.validate()) {
  60. _formKey.currentState.save();
  61. LoadingDialog.showLoadingDialog(context);
  62. filePaths = Get.find<ChangeFileController>().files;
  63. try {
  64. var activityEnd = jsonEncode(_end.toJson()).toString();
  65. //ADD NEW
  66. if (_end.activityId == null) {
  67. _repository.createAction((value) {
  68. LoadingDialog.hideLoadingDialog(context);
  69. Get.back(result: value);
  70. Get.snackbar(label_add_success, "Hoạt động kết thúc canh tác",
  71. snackPosition: SnackPosition.BOTTOM);
  72. }, (error) {
  73. LoadingDialog.hideLoadingDialog(context);
  74. _scaffoldKey.currentState.showSnackBar(SnackBar(
  75. content: Row(
  76. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  77. children: <Widget>[
  78. Flexible(child: Text(AppException.handleError(error))),
  79. Icon(Icons.error),
  80. ],
  81. ),
  82. backgroundColor: Colors.red,
  83. duration: Duration(seconds: 3),
  84. ));
  85. },
  86. apiAddAction: ConstCommon.apiAddEnd,
  87. paramActivity: ConstCommon.paramsActionEnd,
  88. activityAction: activityEnd,
  89. filePaths: filePaths);
  90. } else {
  91. //UPDATE
  92. _repository.updateAction((value) {
  93. LoadingDialog.hideLoadingDialog(context);
  94. Get.back(result: value);
  95. Get.snackbar(label_update_success, "Hoạt động kết thúc canh tác",
  96. snackPosition: SnackPosition.BOTTOM);
  97. }, (error) {
  98. LoadingDialog.hideLoadingDialog(context);
  99. _scaffoldKey.currentState.showSnackBar(SnackBar(
  100. content: Row(
  101. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  102. children: <Widget>[
  103. Flexible(child: Text(AppException.handleError(error))),
  104. Icon(Icons.error),
  105. ],
  106. ),
  107. backgroundColor: Colors.red,
  108. duration: Duration(seconds: 3),
  109. ));
  110. },
  111. apiUpdateAction: ConstCommon.apiUpdateEnd,
  112. paramActivity: ConstCommon.paramsActionEnd,
  113. activityAction: activityEnd,
  114. filePaths: filePaths);
  115. }
  116. } catch (e) {
  117. LoadingDialog.hideLoadingDialog(context);
  118. print(e.toString());
  119. }
  120. } else {
  121. _autoValidate = true;
  122. }
  123. }
  124. Widget _btnExecuteTimePicker() {
  125. return FlatButton(
  126. padding: EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
  127. onPressed: () {
  128. DatePicker.showDateTimePicker(context,
  129. showTitleActions: true, onChanged: (date) {}, onConfirm: (date) {
  130. setState(() {
  131. var parsedDate =
  132. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(date);
  133. _end.executeDate = "$parsedDate";
  134. executeTimeView = DateFormat("dd/MM/yyyy HH:mm").format(date);
  135. });
  136. }, currentTime: executeTime, locale: LocaleType.vi);
  137. },
  138. child: Container(
  139. padding:
  140. EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  141. decoration: BoxDecoration(
  142. border: kBorderTextField,
  143. ),
  144. child: Row(
  145. children: [
  146. Expanded(
  147. child: Text(
  148. //TODO: check condition
  149. executeTimeView == null ? "$executeTime" : executeTimeView,
  150. style: TextStyle(fontSize: 14.0, color: Colors.black87),
  151. )),
  152. Icon(
  153. Icons.date_range,
  154. color: Colors.blue,
  155. ),
  156. ],
  157. )));
  158. }
  159. _actionAppBar() {
  160. IconButton iconButton;
  161. if (1 == 1) {
  162. iconButton = IconButton(
  163. icon: Icon(
  164. Icons.done,
  165. color: Colors.black,
  166. ),
  167. onPressed: () {
  168. FocusScopeNode currentFocus = FocusScope.of(context);
  169. if (!currentFocus.hasPrimaryFocus) {
  170. currentFocus.unfocus();
  171. }
  172. _validateInputs();
  173. },
  174. );
  175. return <Widget>[iconButton];
  176. }
  177. return <Widget>[Container()];
  178. }
  179. Widget _descriptionField() {
  180. return TextFormField(
  181. keyboardType: TextInputType.text,
  182. decoration: InputDecoration(labelText: "Ghi chú"),
  183. controller: _descriptionController,
  184. onSaved: (newValue) {
  185. _end.description = newValue;
  186. },
  187. );
  188. }
  189. Widget _executeByField() {
  190. return TextFormField(
  191. keyboardType: TextInputType.text,
  192. decoration: InputDecoration(labelText: "Người thực hiện"),
  193. enabled: false,
  194. controller: _executeByController,
  195. onSaved: (newValue) {},
  196. );
  197. }
  198. @override
  199. Widget build(BuildContext context) => KeyboardDismisser(
  200. gestures: [
  201. GestureType.onTap,
  202. GestureType.onPanUpdateDownDirection,
  203. ],
  204. child: Scaffold(
  205. key: _scaffoldKey,
  206. appBar: AppBar(
  207. centerTitle: true,
  208. title: Text(plot_action_finish),
  209. actions: _actionAppBar()),
  210. body: KeyboardDismisser(
  211. child: MultiBlocProvider(
  212. providers: [
  213. BlocProvider<ActionDetailBloc>(
  214. create: (context) =>
  215. ActionDetailBloc(repository: Repository())
  216. ..add(FetchData(
  217. isNeedFetchData: widget.isEdit,
  218. apiActivity: ConstCommon.apiDetailEnd,
  219. activityId: widget.activityId))),
  220. BlocProvider<MediaHelperBloc>(
  221. create: (context) =>
  222. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  223. )
  224. ],
  225. child: Form(
  226. key: _formKey,
  227. autovalidate: _autoValidate,
  228. child: SingleChildScrollView(
  229. padding: EdgeInsets.all(8.0),
  230. child: BlocConsumer<ActionDetailBloc, ActionDetailState>(
  231. listener: (context, state) async {
  232. if (state is ActionDetailFailure) {
  233. LoadingDialog.hideLoadingDialog(context);
  234. } else if (state is ActionDetailSuccess) {
  235. LoadingDialog.hideLoadingDialog(context);
  236. _end = End.fromJson(state.item);
  237. _end.activityId = widget.activityId;
  238. _descriptionController.text =
  239. _end.description ?? "";
  240. _executeByController.text = _end.createdByName;
  241. try {
  242. executeTime =
  243. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
  244. .parse(_end.executeDate);
  245. executeTimeView = DateFormat("dd/MM/yyyy HH:mm")
  246. .format(executeTime);
  247. } catch (_) {}
  248. //Show media
  249. if (_end.media != null) {
  250. await UtilAction.cacheFiles(_end.media)
  251. .then((value) {
  252. BlocProvider.of<MediaHelperBloc>(context)
  253. .add(ChangeListMedia(items: value));
  254. }).whenComplete(() {
  255. print("completed");
  256. });
  257. }
  258. } else if (state is ActionDetailInitial) {
  259. } else if (state is ActionDetailLoading) {
  260. LoadingDialog.showLoadingDialog(context);
  261. }
  262. },
  263. builder: (context, state) {
  264. return Column(
  265. children: <Widget>[
  266. Container(
  267. width: double.infinity,
  268. child: Text(
  269. "Ngày thực hiện *",
  270. style: TextStyle(
  271. color: Colors.black54, fontSize: 13.0),
  272. ),
  273. ),
  274. _btnExecuteTimePicker(),
  275. SizedBox(
  276. height: 8.0,
  277. ),
  278. _descriptionField(),
  279. SizedBox(
  280. height: 8.0,
  281. ),
  282. _executeByField(),
  283. SizedBox(
  284. height: 8.0,
  285. ),
  286. BlocBuilder<MediaHelperBloc, MediaHelperState>(
  287. builder: (context, state) {
  288. if (state is MediaHelperSuccess) {
  289. return WidgetMediaPicker(
  290. currentItems: state.items,
  291. onChangeFiles: (filePaths) async {
  292. Get.find<ChangeFileController>()
  293. .addAllFile(filePaths);
  294. });
  295. } else {
  296. return Center(
  297. child: CircularProgressIndicator());
  298. }
  299. }),
  300. ],
  301. );
  302. },
  303. ),
  304. )),
  305. ))));
  306. @override
  307. void dispose() {
  308. _descriptionController.dispose();
  309. _executeByController.dispose();
  310. super.dispose();
  311. }
  312. }