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.

370 lines
13KB

  1. import 'package:farm_tpf/custom_model/CropPlot.dart';
  2. import 'package:farm_tpf/data/api/app_exception.dart';
  3. import 'package:farm_tpf/data/repository/repository.dart';
  4. import 'package:farm_tpf/presentation/custom_widgets/loading_list_page.dart';
  5. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/widget_toast.dart';
  7. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  8. import 'package:farm_tpf/presentation/screens/plot_detail/bloc_plot_information.dart';
  9. import 'package:farm_tpf/utils/const_color.dart';
  10. import 'package:farm_tpf/utils/const_string.dart';
  11. import 'package:flutter/material.dart';
  12. import 'package:get/get.dart';
  13. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  14. import 'package:farm_tpf/utils/formatter.dart';
  15. class PlotInformationScreen extends StatefulWidget {
  16. final int cropId;
  17. PlotInformationScreen({@required this.cropId});
  18. @override
  19. _PlotInformationScreenState createState() => _PlotInformationScreenState();
  20. }
  21. class _PlotInformationScreenState extends State<PlotInformationScreen>
  22. with AutomaticKeepAliveClientMixin {
  23. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  24. GlobalKey<FormState> _formKey = GlobalKey();
  25. TextEditingController _statusController = TextEditingController();
  26. TextEditingController _houseNameController = TextEditingController();
  27. TextEditingController _codeController = TextEditingController();
  28. TextEditingController _supplyNameController = TextEditingController();
  29. TextEditingController _seedingDateController = TextEditingController();
  30. TextEditingController _timeSoakSeedController = TextEditingController();
  31. TextEditingController _timeNurserySeedController = TextEditingController();
  32. TextEditingController _quantityPlantController = TextEditingController();
  33. TextEditingController _currentPlantController = TextEditingController();
  34. TextEditingController _timeEndGrowController = TextEditingController();
  35. TextEditingController _mainTechnicianController = TextEditingController();
  36. TextEditingController _areaController = TextEditingController();
  37. TextEditingController _descriptionController = TextEditingController();
  38. bool _autoValidate = false;
  39. TbCropDTO _crop = TbCropDTO();
  40. final controller = Get.put(DescriptionChangeControler());
  41. Repository _repository = Repository();
  42. @override
  43. void initState() {
  44. super.initState();
  45. getPlotInfoBloc.getPlotInfo(widget.cropId, (data) {
  46. var result = data as CropPlot;
  47. _crop = result.tbCropDTO;
  48. var statusCrop;
  49. switch (_crop.status) {
  50. case "STATUS_ARE_ACTIVE":
  51. statusCrop = plot_status_active;
  52. break;
  53. case "STATUS_FINISHED":
  54. statusCrop = plot_status_end;
  55. break;
  56. default:
  57. statusCrop = plot_status_unknown;
  58. }
  59. _statusController.text = statusCrop;
  60. _houseNameController.text = _crop.netHouseName?.toString();
  61. _codeController.text = _crop.code?.toString();
  62. _supplyNameController.text = _crop.suppliesName?.toString();
  63. _areaController.text = _crop.areaM2.formatNumtoStringDecimal();
  64. _seedingDateController.text = result.sowingDate.format_DDMMYY_HHmm();
  65. _timeSoakSeedController.text =
  66. result.soakSeedsTime.formatNumtoStringDecimal();
  67. _timeNurserySeedController.text =
  68. result.soakSeedsTime.formatNumtoStringDecimal();
  69. _quantityPlantController.text =
  70. result.numberPlants.formatNumtoStringDecimal();
  71. _currentPlantController.text =
  72. result.numberCurrentPlants.formatNumtoStringDecimal();
  73. _timeEndGrowController.text = _crop.endDate.format_DDMMYY_HHmm();
  74. _descriptionController.text =
  75. _crop.description == null ? "" : _crop.description.toString();
  76. var technicians = _crop.tbDetailUsers.map((e) => e.fullName).join(", ");
  77. _mainTechnicianController.text = technicians;
  78. }, (err) {});
  79. }
  80. _validateInputs() async {
  81. if (_formKey.currentState.validate()) {
  82. _formKey.currentState.save();
  83. LoadingDialog.showLoadingDialog(context);
  84. _repository.updatePlot(_crop).then((value) {
  85. LoadingDialog.hideLoadingDialog(context);
  86. Utils.showSnackBarSuccess(message: label_update_success);
  87. controller.initValue();
  88. }).catchError((error) {
  89. LoadingDialog.hideLoadingDialog(context);
  90. Utils.showSnackBarError(message: AppException.handleError(error));
  91. });
  92. } else {
  93. _autoValidate = true;
  94. }
  95. }
  96. Widget _statusField() {
  97. return TextFormField(
  98. enabled: false,
  99. controller: _statusController,
  100. decoration: InputDecoration(labelText: "Trạng thái"),
  101. );
  102. }
  103. Widget _houseNameField() {
  104. return TextFormField(
  105. enabled: false,
  106. controller: _houseNameController,
  107. decoration: InputDecoration(labelText: "Nhà màng"),
  108. );
  109. }
  110. Widget _codeField() {
  111. return TextFormField(
  112. enabled: false,
  113. controller: _codeController,
  114. decoration: InputDecoration(labelText: "Mã lô"),
  115. );
  116. }
  117. Widget _supplyNameField() {
  118. return TextFormField(
  119. enabled: false,
  120. controller: _supplyNameController,
  121. decoration: InputDecoration(labelText: "Giống"),
  122. );
  123. }
  124. Widget _seedingDateField() {
  125. return TextFormField(
  126. enabled: false,
  127. controller: _seedingDateController,
  128. decoration: InputDecoration(labelText: "Ngày gieo trồng"),
  129. );
  130. }
  131. Widget _timeSoakSeedField() {
  132. return TextFormField(
  133. enabled: false,
  134. controller: _timeSoakSeedController,
  135. decoration: InputDecoration(labelText: "Thời gian ngâm hạt"),
  136. );
  137. }
  138. Widget _timeNurserySeedField() {
  139. return TextFormField(
  140. enabled: false,
  141. controller: _timeNurserySeedController,
  142. decoration: InputDecoration(labelText: "Thời gian vô khây ươm"),
  143. );
  144. }
  145. Widget _quantityPlantField() {
  146. return TextFormField(
  147. enabled: false,
  148. controller: _quantityPlantController,
  149. decoration: InputDecoration(labelText: "Số lượng cây trồng"),
  150. );
  151. }
  152. Widget _currentPlantField() {
  153. return TextFormField(
  154. enabled: false,
  155. controller: _currentPlantController,
  156. decoration: InputDecoration(labelText: "Số lượng cây hiện tại"),
  157. );
  158. }
  159. Widget _timeEndGrowField() {
  160. return TextFormField(
  161. enabled: false,
  162. controller: _timeEndGrowController,
  163. decoration: InputDecoration(labelText: "Ngày kết thúc canh tác"),
  164. );
  165. }
  166. Widget _mainTechnicianField() {
  167. return TextFormField(
  168. enabled: false,
  169. controller: _mainTechnicianController,
  170. decoration: InputDecoration(labelText: "Kỹ sư trực tiếp"),
  171. );
  172. }
  173. Widget _areaField() {
  174. return TextFormField(
  175. enabled: false,
  176. controller: _areaController,
  177. decoration: InputDecoration(labelText: "Diện tích (m\u00B2)"),
  178. );
  179. }
  180. Widget _descriptionField() {
  181. return TextFormField(
  182. keyboardType: TextInputType.text,
  183. controller: _descriptionController,
  184. decoration: InputDecoration(labelText: "Ghi chú"),
  185. onSaved: (newValue) {
  186. _crop.description = newValue;
  187. },
  188. onChanged: (newValue) {
  189. controller.changeValue(_crop.description, newValue);
  190. },
  191. );
  192. }
  193. _actionAppBar() {
  194. return <Widget>[
  195. GetBuilder<DescriptionChangeControler>(
  196. builder: (_) {
  197. return IconButton(
  198. icon: Icon(
  199. Icons.done,
  200. ),
  201. disabledColor: Colors.grey,
  202. onPressed: controller.isChanged == false
  203. ? null
  204. : () {
  205. FocusScopeNode currentFocus = FocusScope.of(context);
  206. if (!currentFocus.hasPrimaryFocus) {
  207. currentFocus.unfocus();
  208. }
  209. _validateInputs();
  210. },
  211. );
  212. },
  213. )
  214. ];
  215. }
  216. @override
  217. Widget build(BuildContext context) => KeyboardDismisser(
  218. gestures: [
  219. GestureType.onTap,
  220. GestureType.onPanUpdateDownDirection,
  221. ],
  222. child: Container(
  223. color: AppColors.ITEM_BG,
  224. child: SafeArea(
  225. top: false,
  226. bottom: true,
  227. child: Scaffold(
  228. key: _scaffoldKey,
  229. appBar: AppBar(
  230. centerTitle: true,
  231. title: Text("Thông tin lô"),
  232. actions: _actionAppBar()),
  233. body: KeyboardDismisser(
  234. child: StreamBuilder(
  235. stream: getPlotInfoBloc.actions,
  236. builder: (BuildContext context,
  237. AsyncSnapshot<dynamic> snapshot) {
  238. if (snapshot.hasData) {
  239. return Form(
  240. key: _formKey,
  241. autovalidate: _autoValidate,
  242. child: SingleChildScrollView(
  243. padding: EdgeInsets.all(8.0),
  244. child: Column(
  245. children: <Widget>[
  246. _statusField(),
  247. SizedBox(
  248. height: 4.0,
  249. ),
  250. _houseNameField(),
  251. SizedBox(
  252. height: 4.0,
  253. ),
  254. _codeField(),
  255. SizedBox(
  256. height: 4.0,
  257. ),
  258. _supplyNameField(),
  259. SizedBox(
  260. height: 4.0,
  261. ),
  262. _seedingDateField(),
  263. SizedBox(
  264. height: 4.0,
  265. ),
  266. _timeSoakSeedField(),
  267. SizedBox(
  268. height: 4.0,
  269. ),
  270. _timeNurserySeedField(),
  271. SizedBox(
  272. height: 4.0,
  273. ),
  274. _quantityPlantField(),
  275. SizedBox(
  276. height: 4.0,
  277. ),
  278. _currentPlantField(),
  279. SizedBox(
  280. height: 4.0,
  281. ),
  282. _timeEndGrowField(),
  283. SizedBox(
  284. height: 4.0,
  285. ),
  286. _mainTechnicianField(),
  287. SizedBox(
  288. height: 4.0,
  289. ),
  290. _areaField(),
  291. SizedBox(
  292. height: 4.0,
  293. ),
  294. _descriptionField()
  295. ],
  296. ),
  297. ));
  298. } else if (snapshot.hasError) {
  299. return Center(
  300. child: Text(snapshot.error.toString()),
  301. );
  302. } else {
  303. return LoadingListPage();
  304. }
  305. }))))));
  306. @override
  307. void dispose() {
  308. _statusController.dispose();
  309. _houseNameController.dispose();
  310. _codeController.dispose();
  311. _supplyNameController.dispose();
  312. _seedingDateController.dispose();
  313. _timeSoakSeedController.dispose();
  314. _timeNurserySeedController.dispose();
  315. _quantityPlantController.dispose();
  316. _currentPlantController.dispose();
  317. _timeEndGrowController.dispose();
  318. _mainTechnicianController.dispose();
  319. _areaController.dispose();
  320. _descriptionController.dispose();
  321. super.dispose();
  322. }
  323. @override
  324. bool get wantKeepAlive => true;
  325. }
  326. class DescriptionChangeControler extends GetxController {
  327. bool isChanged = false;
  328. void initValue() {
  329. isChanged = false;
  330. update();
  331. }
  332. void changeValue(String oldValue, String newValue) {
  333. if (oldValue != newValue) {
  334. isChanged = true;
  335. } else {
  336. isChanged = false;
  337. }
  338. if (oldValue.isNullOrBlank && newValue.isEmpty) {
  339. isChanged = false;
  340. }
  341. update();
  342. }
  343. }