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.

313 lines
15KB

  1. import 'package:farm_tpf/custom_model/CropPlot.dart';
  2. import 'package:farm_tpf/data/api/app_exception.dart';
  3. import 'package:farm_tpf/data/repository/repository.dart';
  4. import 'package:farm_tpf/presentation/custom_widgets/bloc/widget_row_plot_info.dart';
  5. import 'package:farm_tpf/presentation/custom_widgets/button_widget.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart';
  7. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  8. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  9. import 'package:farm_tpf/presentation/screens/plot_detail/bloc_plot_information.dart';
  10. import 'package:farm_tpf/utils/const_color.dart';
  11. import 'package:farm_tpf/utils/const_string.dart';
  12. import 'package:flutter/material.dart';
  13. import 'package:get/get.dart';
  14. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  15. import 'package:farm_tpf/utils/formatter.dart';
  16. class PlotInformationScreen extends StatefulWidget {
  17. final int cropId;
  18. PlotInformationScreen({@required this.cropId});
  19. @override
  20. _PlotInformationScreenState createState() => _PlotInformationScreenState();
  21. }
  22. class _PlotInformationScreenState extends State<PlotInformationScreen>
  23. with AutomaticKeepAliveClientMixin {
  24. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  25. GlobalKey<FormState> _formKey = GlobalKey();
  26. TextEditingController _descriptionController = TextEditingController();
  27. bool _autoValidate = false;
  28. CropPlot cropPlot = CropPlot();
  29. TbCropDTO _crop = TbCropDTO();
  30. final controller = Get.put(DescriptionChangeControler());
  31. Repository _repository = Repository();
  32. String statusCrop = plot_status_unknown;
  33. String technicians = '--';
  34. @override
  35. void initState() {
  36. super.initState();
  37. getPlotInfoBloc.getPlotInfo(widget.cropId, (data) {
  38. var result = data as CropPlot;
  39. cropPlot = result;
  40. _crop = result.tbCropDTO;
  41. switch (_crop.status) {
  42. case "STATUS_ARE_ACTIVE":
  43. statusCrop = plot_status_active;
  44. break;
  45. case "STATUS_FINISHED":
  46. statusCrop = plot_status_end;
  47. break;
  48. default:
  49. statusCrop = plot_status_unknown;
  50. }
  51. _descriptionController.text =
  52. _crop.description == null ? "" : _crop.description.toString();
  53. }, (err) {});
  54. }
  55. _validateInputs() async {
  56. if (_formKey.currentState.validate()) {
  57. _formKey.currentState.save();
  58. LoadingDialog.showLoadingDialog(context);
  59. _repository.updatePlot(_crop).then((value) {
  60. LoadingDialog.hideLoadingDialog(context);
  61. Utils.showSnackBarSuccess(message: label_update_success);
  62. controller.initValue();
  63. }).catchError((error) {
  64. LoadingDialog.hideLoadingDialog(context);
  65. Utils.showSnackBarError(message: AppException.handleError(error));
  66. });
  67. } else {
  68. _autoValidate = true;
  69. }
  70. }
  71. Widget _descriptionField() {
  72. return Container(
  73. padding: EdgeInsets.all(8),
  74. color: Colors.yellow[100],
  75. child: TextFormField(
  76. keyboardType: TextInputType.text,
  77. controller: _descriptionController,
  78. decoration: InputDecoration(
  79. labelText: "Ghi chú",
  80. hintText: 'Ghi chú',
  81. enabledBorder: UnderlineInputBorder(
  82. borderSide: BorderSide(color: Colors.grey, width: 0.35))),
  83. onSaved: (newValue) {
  84. _crop.description = newValue;
  85. },
  86. onChanged: (newValue) {
  87. controller.changeValue(_crop.description, newValue);
  88. },
  89. ),
  90. );
  91. }
  92. _actionAppBar() {
  93. return <Widget>[
  94. GetBuilder<DescriptionChangeControler>(
  95. builder: (_) {
  96. return IconButton(
  97. icon: Icon(
  98. Icons.done,
  99. ),
  100. disabledColor: Colors.grey,
  101. onPressed: controller.isChanged == false
  102. ? null
  103. : () {
  104. FocusScopeNode currentFocus = FocusScope.of(context);
  105. if (!currentFocus.hasPrimaryFocus) {
  106. currentFocus.unfocus();
  107. }
  108. _validateInputs();
  109. },
  110. );
  111. },
  112. )
  113. ];
  114. }
  115. @override
  116. Widget build(BuildContext context) => KeyboardDismisser(
  117. gestures: [
  118. GestureType.onTap,
  119. GestureType.onPanUpdateDownDirection,
  120. ],
  121. child: Container(
  122. color: AppColors.ITEM_BG,
  123. child: SafeArea(
  124. top: false,
  125. bottom: true,
  126. child: Scaffold(
  127. key: _scaffoldKey,
  128. body: KeyboardDismisser(
  129. child: StreamBuilder(
  130. stream: getPlotInfoBloc.actions,
  131. builder: (BuildContext context,
  132. AsyncSnapshot<dynamic> snapshot) {
  133. if (snapshot.hasData) {
  134. return Form(
  135. key: _formKey,
  136. autovalidate: _autoValidate,
  137. child: SingleChildScrollView(
  138. padding: EdgeInsets.all(8.0),
  139. child: Column(
  140. children: <Widget>[
  141. WidgetRowPlotInfo(
  142. color: AppColors.DEFAULT
  143. .withOpacity(0.1),
  144. name: 'Mã lô',
  145. value:
  146. '${cropPlot.tbCropDTO.code}'),
  147. WidgetRowPlotInfo(
  148. color: AppColors.DEFAULT
  149. .withOpacity(0.3),
  150. name: 'Trạng thái',
  151. value: '$statusCrop'),
  152. WidgetRowPlotInfo(
  153. color: AppColors.DEFAULT
  154. .withOpacity(0.1),
  155. name: 'Nhà màng',
  156. value:
  157. '${cropPlot.tbCropDTO.netHouseName ?? '--'}'),
  158. WidgetRowPlotInfo(
  159. color: AppColors.DEFAULT
  160. .withOpacity(0.3),
  161. name: 'Giống',
  162. value:
  163. '${cropPlot.tbCropDTO.suppliesName ?? '--'}'),
  164. WidgetRowPlotInfo(
  165. color: AppColors.DEFAULT
  166. .withOpacity(0.1),
  167. name: 'Ngày gieo trồng',
  168. value:
  169. '${cropPlot.sowingDate ?? '--'}'),
  170. WidgetRowPlotInfo(
  171. color: AppColors.DEFAULT
  172. .withOpacity(0.3),
  173. name: 'Thời gian ngâm hạt',
  174. value:
  175. '${cropPlot.soakSeedsTime ?? '--'}'),
  176. WidgetRowPlotInfo(
  177. color: AppColors.DEFAULT
  178. .withOpacity(0.1),
  179. name: 'Ngày vô khây ươm',
  180. value:
  181. '${cropPlot.seedIncubationTime ?? '--'}'),
  182. WidgetRowPlotInfo(
  183. color: AppColors.DEFAULT
  184. .withOpacity(0.3),
  185. name: 'Số lượng cây trồng',
  186. value:
  187. '${cropPlot.numberPlants ?? '--'}'),
  188. WidgetRowPlotInfo(
  189. color: AppColors.DEFAULT
  190. .withOpacity(0.1),
  191. name: 'Số lượng cây hiện tại',
  192. value:
  193. '${cropPlot.numberCurrentPlants ?? '--'}'),
  194. WidgetRowPlotInfo(
  195. color: AppColors.DEFAULT
  196. .withOpacity(0.3),
  197. name: 'Ngày kết thúc canh tác',
  198. value:
  199. '${cropPlot.tbCropDTO.endDate ?? '--'}'),
  200. WidgetRowPlotInfo(
  201. color: AppColors.DEFAULT
  202. .withOpacity(0.1),
  203. name: 'Kỹ sư trực tiếp',
  204. value: '$technicians'),
  205. WidgetRowPlotInfo(
  206. color: AppColors.DEFAULT
  207. .withOpacity(0.3),
  208. name: 'Diện tích (m\u00B2)',
  209. value:
  210. '${cropPlot.tbCropDTO.areaM2.formatNumtoStringDecimal()}'),
  211. SizedBox(
  212. height: 8,
  213. ),
  214. _descriptionField(),
  215. SizedBox(
  216. height: 16,
  217. ),
  218. GetBuilder<
  219. DescriptionChangeControler>(
  220. builder: (_) {
  221. return SizedBox(
  222. width: double.infinity,
  223. height: 55,
  224. child: FlatButton(
  225. onPressed:
  226. controller.isChanged ==
  227. false
  228. ? () {}
  229. : () {
  230. FocusScopeNode
  231. currentFocus =
  232. FocusScope.of(
  233. context);
  234. if (!currentFocus
  235. .hasPrimaryFocus) {
  236. currentFocus
  237. .unfocus();
  238. }
  239. _validateInputs();
  240. },
  241. color: controller.isChanged
  242. ? AppColors.DEFAULT
  243. : Colors.grey[400],
  244. shape:
  245. RoundedRectangleBorder(
  246. borderRadius:
  247. new BorderRadius
  248. .circular(7.0),
  249. ),
  250. child: Text(
  251. 'Cập nhật'
  252. .toUpperCase(),
  253. style: TextStyle(
  254. fontWeight:
  255. FontWeight.bold,
  256. color:
  257. AppColors.WHITE,
  258. fontSize: 18)),
  259. ),
  260. );
  261. },
  262. )
  263. ],
  264. ),
  265. ));
  266. } else if (snapshot.hasError) {
  267. return Center(
  268. child: Text(snapshot.error.toString()),
  269. );
  270. } else {
  271. return LoadingListPage();
  272. }
  273. }))))));
  274. @override
  275. void dispose() {
  276. _descriptionController.dispose();
  277. super.dispose();
  278. }
  279. @override
  280. bool get wantKeepAlive => true;
  281. }
  282. class DescriptionChangeControler extends GetxController {
  283. bool isChanged = false;
  284. void initValue() {
  285. isChanged = false;
  286. update();
  287. }
  288. void changeValue(String oldValue, String newValue) {
  289. if (oldValue != newValue) {
  290. isChanged = true;
  291. } else {
  292. isChanged = false;
  293. }
  294. if (oldValue.isNullOrBlank && newValue.isEmpty) {
  295. isChanged = false;
  296. }
  297. update();
  298. }
  299. }