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.

281 lines
12KB

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