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.

232 lines
9.6KB

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