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.

301 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. if (_crop.tbDetailUsers != null) {
  56. for (var i = 0; i < _crop.tbDetailUsers.length; i++) {
  57. if (i == 0) {
  58. technicians += _crop.tbDetailUsers[i].fullName ?? '';
  59. } else {
  60. technicians += ', ${_crop.tbDetailUsers[i].fullName ?? ''}';
  61. }
  62. }
  63. }
  64. }, (err) {});
  65. }
  66. _validateInputs() async {
  67. if (_formKey.currentState.validate()) {
  68. _formKey.currentState.save();
  69. LoadingDialog.showLoadingDialog(context);
  70. _repository.updatePlot(_crop).then((value) {
  71. LoadingDialog.hideLoadingDialog(context);
  72. Utils.showSnackBarSuccess(message: label_update_success);
  73. controller.initValue();
  74. }).catchError((error) {
  75. LoadingDialog.hideLoadingDialog(context);
  76. Utils.showSnackBarError(message: AppException.handleError(error));
  77. });
  78. } else {
  79. _autoValidate = true;
  80. }
  81. }
  82. Widget _descriptionField() {
  83. return Container(
  84. padding: EdgeInsets.all(8),
  85. color: AppColors.YELLOW.withOpacity(0.1),
  86. child: TextFormField(
  87. keyboardType: TextInputType.text,
  88. controller: _descriptionController,
  89. decoration: InputDecoration(
  90. labelText: "Ghi chú",
  91. hintText: 'Ghi chú',
  92. enabledBorder: UnderlineInputBorder(
  93. borderSide: BorderSide(color: Colors.grey, width: 0.35))),
  94. onSaved: (newValue) {
  95. _crop.description = newValue;
  96. },
  97. onChanged: (newValue) {
  98. controller.changeValue(_crop.description, newValue);
  99. },
  100. ),
  101. );
  102. }
  103. @override
  104. Widget build(BuildContext context) => KeyboardDismisser(
  105. gestures: [GestureType.onTap],
  106. child: Container(
  107. color: AppColors.ITEM_BG,
  108. child: SafeArea(
  109. top: false,
  110. bottom: true,
  111. child: Scaffold(
  112. appBar: widget.isShowAppbar
  113. ? AppBarWidget()
  114. : PreferredSize(
  115. preferredSize: Size(0, 0),
  116. child: SizedBox(),
  117. ),
  118. key: _scaffoldKey,
  119. body: KeyboardDismisser(
  120. child: StreamBuilder(
  121. stream: getPlotInfoBloc.actions,
  122. builder: (BuildContext context,
  123. AsyncSnapshot<dynamic> snapshot) {
  124. if (snapshot.hasData) {
  125. return Form(
  126. key: _formKey,
  127. autovalidate: _autoValidate,
  128. child: SingleChildScrollView(
  129. padding: EdgeInsets.all(8.0),
  130. child: Column(
  131. children: <Widget>[
  132. WidgetRowPlotInfo(
  133. color: AppColors.DEFAULT
  134. .withOpacity(0.1),
  135. name: 'Mã lô',
  136. value:
  137. '${cropPlot.tbCropDTO.code}'),
  138. WidgetRowPlotInfo(
  139. color: AppColors.DEFAULT
  140. .withOpacity(0.3),
  141. name: 'Trạng thái',
  142. value: '$statusCrop'),
  143. WidgetRowPlotInfo(
  144. color: AppColors.DEFAULT
  145. .withOpacity(0.1),
  146. name: 'Nhà màng',
  147. value:
  148. '${cropPlot.tbCropDTO.netHouseName ?? '--'}'),
  149. WidgetRowPlotInfo(
  150. color: AppColors.DEFAULT
  151. .withOpacity(0.3),
  152. name: 'Giống',
  153. value:
  154. '${cropPlot.tbCropDTO.suppliesName ?? '--'}'),
  155. WidgetRowPlotInfo(
  156. color: AppColors.DEFAULT
  157. .withOpacity(0.1),
  158. name: 'Ngày gieo trồng',
  159. value: cropPlot.tbCropDTO.type == 0
  160. ? '${cropPlot.tbCropDTO?.startDate?.format_DDMMYY_HHmm() ?? '--'}'
  161. : '--'),
  162. WidgetRowPlotInfo(
  163. color: AppColors.DEFAULT
  164. .withOpacity(0.3),
  165. name: 'Ngày vô khây ươm',
  166. value: cropPlot.tbCropDTO.type == 1
  167. ? '${cropPlot.tbCropDTO?.startDate?.format_DDMMYY_HHmm() ?? '--'}'
  168. : '--'),
  169. WidgetRowPlotInfo(
  170. color: AppColors.DEFAULT
  171. .withOpacity(0.1),
  172. name: 'Thời gian ngâm hạt',
  173. value:
  174. '${cropPlot.seedIncubationTime ?? '--'} ngày'),
  175. WidgetRowPlotInfo(
  176. color: AppColors.DEFAULT
  177. .withOpacity(0.3),
  178. name: 'Số lượng cây trồng',
  179. value:
  180. '${cropPlot.numberPlants ?? '--'}'),
  181. WidgetRowPlotInfo(
  182. color: AppColors.DEFAULT
  183. .withOpacity(0.1),
  184. name: 'Số lượng cây hiện tại',
  185. value:
  186. '${cropPlot.numberCurrentPlants ?? '--'}'),
  187. WidgetRowPlotInfo(
  188. color: AppColors.DEFAULT
  189. .withOpacity(0.3),
  190. name: 'Ngày kết thúc canh tác',
  191. value:
  192. '${cropPlot.tbCropDTO.endDate.format_DDMMYY_HHmm() ?? '--'}'),
  193. WidgetRowPlotInfo(
  194. color: AppColors.DEFAULT
  195. .withOpacity(0.1),
  196. name: 'Kỹ sư trực tiếp',
  197. value: '$technicians'),
  198. WidgetRowPlotInfo(
  199. color: AppColors.DEFAULT
  200. .withOpacity(0.3),
  201. name: 'Diện tích (m\u00B2)',
  202. value:
  203. '${cropPlot.tbCropDTO.areaM2.formatNumtoStringDecimal()}'),
  204. SizedBox(
  205. height: 8,
  206. ),
  207. _descriptionField(),
  208. SizedBox(
  209. height: 16,
  210. ),
  211. GetBuilder<DescriptionChangeControler>(
  212. builder: (_) {
  213. return SizedBox(
  214. width: double.infinity,
  215. height: 55,
  216. child: FlatButton(
  217. onPressed:
  218. controller.isChanged ==
  219. false
  220. ? () {}
  221. : () {
  222. FocusScopeNode
  223. currentFocus =
  224. FocusScope.of(
  225. context);
  226. if (!currentFocus
  227. .hasPrimaryFocus) {
  228. currentFocus
  229. .unfocus();
  230. }
  231. _validateInputs();
  232. },
  233. color: controller.isChanged
  234. ? AppColors.DEFAULT
  235. : Colors.grey[400],
  236. shape: RoundedRectangleBorder(
  237. borderRadius:
  238. new BorderRadius.circular(
  239. 7.0),
  240. ),
  241. child: Text(
  242. 'Cập nhật'.toUpperCase(),
  243. style: TextStyle(
  244. fontWeight:
  245. FontWeight.bold,
  246. color: AppColors.WHITE,
  247. fontSize: 18)),
  248. ),
  249. );
  250. },
  251. )
  252. ],
  253. ),
  254. ));
  255. } else if (snapshot.hasError) {
  256. return Center(
  257. child: Text(snapshot.error.toString()),
  258. );
  259. } else {
  260. return LoadingListPage();
  261. }
  262. }))))));
  263. @override
  264. void dispose() {
  265. _descriptionController.dispose();
  266. super.dispose();
  267. }
  268. @override
  269. bool get wantKeepAlive => true;
  270. }
  271. class DescriptionChangeControler extends GetxController {
  272. bool isChanged = false;
  273. void initValue() {
  274. isChanged = false;
  275. update();
  276. }
  277. void changeValue(String oldValue, String newValue) {
  278. if (oldValue != newValue) {
  279. isChanged = true;
  280. } else {
  281. isChanged = false;
  282. }
  283. if (oldValue.isNullOrBlank && newValue.isEmpty) {
  284. isChanged = false;
  285. }
  286. update();
  287. }
  288. }