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.

240 lines
10KB

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