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.

243 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
  138. ? '${cropPlot.tbCropDTO?.startDate?.format_DDMMYY_HHmm() ?? '--'}'
  139. : '--'),
  140. WidgetRowPlotInfo(
  141. color: AppColors.DEFAULT.withOpacity(0.3),
  142. name: 'Ngày vô khây ươm',
  143. value: cropPlot.tbCropDTO?.tbCropTypeId == 1
  144. ? '${cropPlot.tbCropDTO?.startDate?.format_DDMMYY_HHmm() ?? '--'}'
  145. : '--'),
  146. WidgetRowPlotInfo(
  147. color: AppColors.DEFAULT.withOpacity(0.1),
  148. name: 'Thời gian ngâm hạt',
  149. value: '${cropPlot.seedIncubationTime ?? '--'} ngày'),
  150. WidgetRowPlotInfo(
  151. color: AppColors.DEFAULT.withOpacity(0.3), name: 'Số lượng cây trồng', value: '${cropPlot.numberPlants ?? '--'}'),
  152. WidgetRowPlotInfo(
  153. color: AppColors.DEFAULT.withOpacity(0.1),
  154. name: 'Số lượng cây hiện tại',
  155. value: '${cropPlot.numberCurrentPlants ?? '--'}'),
  156. WidgetRowPlotInfo(
  157. color: AppColors.DEFAULT.withOpacity(0.3),
  158. name: 'Ngày kết thúc canh tác',
  159. value: '${cropPlot.tbCropDTO?.endDate?.format_DDMMYY_HHmm() ?? '--'}'),
  160. WidgetRowPlotInfo(color: AppColors.DEFAULT.withOpacity(0.1), name: 'Kỹ sư trực tiếp', value: '$technicians'),
  161. WidgetRowPlotInfo(
  162. color: AppColors.DEFAULT.withOpacity(0.3),
  163. name: 'Diện tích (m\u00B2)',
  164. value: '${cropPlot.tbCropDTO?.areaM2?.formatNumtoStringDecimal()}'),
  165. SizedBox(
  166. height: 8,
  167. ),
  168. _descriptionField(),
  169. SizedBox(
  170. height: 16,
  171. ),
  172. GetBuilder<DescriptionChangeControler>(
  173. builder: (_) {
  174. return ButtonWidget(
  175. title: 'CẬP NHẬT',
  176. onPressed: controller.isChanged == false
  177. ? () {}
  178. : () {
  179. FocusScopeNode currentFocus = FocusScope.of(context);
  180. if (!currentFocus.hasPrimaryFocus) {
  181. currentFocus.unfocus();
  182. }
  183. _validateInputs();
  184. },
  185. );
  186. },
  187. )
  188. ],
  189. ),
  190. ));
  191. } else if (snapshot.hasError) {
  192. return Center(
  193. child: Text(snapshot.error.toString()),
  194. );
  195. } else {
  196. return LoadingListPage();
  197. }
  198. },
  199. ),
  200. ),
  201. ),
  202. ),
  203. ),
  204. );
  205. @override
  206. void dispose() {
  207. _descriptionController?.dispose();
  208. super.dispose();
  209. }
  210. @override
  211. bool get wantKeepAlive => true;
  212. }
  213. class DescriptionChangeControler extends GetxController {
  214. bool isChanged = false;
  215. void initValue() {
  216. isChanged = false;
  217. update();
  218. }
  219. void changeValue(String oldValue, String newValue) {
  220. if (oldValue != newValue) {
  221. isChanged = true;
  222. } else {
  223. isChanged = false;
  224. }
  225. if (newValue.isEmpty) {
  226. isChanged = false;
  227. }
  228. update();
  229. }
  230. }