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.

305 lines
14KB

  1. import 'package:farm_tpf/custom_model/CropPlot.dart';
  2. import 'package:farm_tpf/custom_model/TbCropDTO.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/app_bar_widget.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/bloc/widget_row_plot_info.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
  160. .tbCropTypeId ==
  161. 0
  162. ? '${cropPlot.tbCropDTO?.startDate?.format_DDMMYY_HHmm() ?? '--'}'
  163. : '--'),
  164. WidgetRowPlotInfo(
  165. color: AppColors.DEFAULT
  166. .withOpacity(0.3),
  167. name: 'Ngày vô khây ươm',
  168. value: cropPlot.tbCropDTO
  169. .tbCropTypeId ==
  170. 1
  171. ? '${cropPlot.tbCropDTO?.startDate?.format_DDMMYY_HHmm() ?? '--'}'
  172. : '--'),
  173. WidgetRowPlotInfo(
  174. color: AppColors.DEFAULT
  175. .withOpacity(0.1),
  176. name: 'Thời gian ngâm hạt',
  177. value:
  178. '${cropPlot.seedIncubationTime ?? '--'} ngày'),
  179. WidgetRowPlotInfo(
  180. color: AppColors.DEFAULT
  181. .withOpacity(0.3),
  182. name: 'Số lượng cây trồng',
  183. value:
  184. '${cropPlot.numberPlants ?? '--'}'),
  185. WidgetRowPlotInfo(
  186. color: AppColors.DEFAULT
  187. .withOpacity(0.1),
  188. name: 'Số lượng cây hiện tại',
  189. value:
  190. '${cropPlot.numberCurrentPlants ?? '--'}'),
  191. WidgetRowPlotInfo(
  192. color: AppColors.DEFAULT
  193. .withOpacity(0.3),
  194. name: 'Ngày kết thúc canh tác',
  195. value:
  196. '${cropPlot.tbCropDTO.endDate.format_DDMMYY_HHmm() ?? '--'}'),
  197. WidgetRowPlotInfo(
  198. color: AppColors.DEFAULT
  199. .withOpacity(0.1),
  200. name: 'Kỹ sư trực tiếp',
  201. value: '$technicians'),
  202. WidgetRowPlotInfo(
  203. color: AppColors.DEFAULT
  204. .withOpacity(0.3),
  205. name: 'Diện tích (m\u00B2)',
  206. value:
  207. '${cropPlot.tbCropDTO.areaM2.formatNumtoStringDecimal()}'),
  208. SizedBox(
  209. height: 8,
  210. ),
  211. _descriptionField(),
  212. SizedBox(
  213. height: 16,
  214. ),
  215. GetBuilder<DescriptionChangeControler>(
  216. builder: (_) {
  217. return SizedBox(
  218. width: double.infinity,
  219. height: 55,
  220. child: FlatButton(
  221. onPressed:
  222. controller.isChanged ==
  223. false
  224. ? () {}
  225. : () {
  226. FocusScopeNode
  227. currentFocus =
  228. FocusScope.of(
  229. context);
  230. if (!currentFocus
  231. .hasPrimaryFocus) {
  232. currentFocus
  233. .unfocus();
  234. }
  235. _validateInputs();
  236. },
  237. color: controller.isChanged
  238. ? AppColors.DEFAULT
  239. : Colors.grey[400],
  240. shape: RoundedRectangleBorder(
  241. borderRadius:
  242. new BorderRadius.circular(
  243. 7.0),
  244. ),
  245. child: Text(
  246. 'Cập nhật'.toUpperCase(),
  247. style: TextStyle(
  248. fontWeight:
  249. FontWeight.bold,
  250. color: AppColors.WHITE,
  251. fontSize: 18)),
  252. ),
  253. );
  254. },
  255. )
  256. ],
  257. ),
  258. ));
  259. } else if (snapshot.hasError) {
  260. return Center(
  261. child: Text(snapshot.error.toString()),
  262. );
  263. } else {
  264. return LoadingListPage();
  265. }
  266. }))))));
  267. @override
  268. void dispose() {
  269. _descriptionController?.dispose();
  270. super.dispose();
  271. }
  272. @override
  273. bool get wantKeepAlive => true;
  274. }
  275. class DescriptionChangeControler extends GetxController {
  276. bool isChanged = false;
  277. void initValue() {
  278. isChanged = false;
  279. update();
  280. }
  281. void changeValue(String oldValue, String newValue) {
  282. if (oldValue != newValue) {
  283. isChanged = true;
  284. } else {
  285. isChanged = false;
  286. }
  287. if (oldValue.isNullOrBlank && newValue.isEmpty) {
  288. isChanged = false;
  289. }
  290. update();
  291. }
  292. }