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.

290 lines
14KB

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