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.

575 lines
26KB

  1. import 'package:farm_tpf/custom_model/Device.dart';
  2. import 'package:farm_tpf/custom_model/SuppliesUsing.dart';
  3. import 'package:farm_tpf/custom_model/Supply.dart';
  4. import 'package:farm_tpf/presentation/custom_widgets/WidgetErrorTextField.dart';
  5. import 'package:farm_tpf/presentation/custom_widgets/widget_text_form_field.dart';
  6. import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart';
  7. import 'package:farm_tpf/presentation/screens/actions/controller/ChangeDevice.dart';
  8. import 'package:farm_tpf/presentation/screens/actions/controller/ChangeFieldInForm.dart';
  9. import 'package:farm_tpf/presentation/screens/actions/controller/ChangeFormButton.dart';
  10. import 'package:farm_tpf/presentation/screens/actions/controller/ChangeSupplyUsing.dart';
  11. import 'package:farm_tpf/presentation/screens/actions/controller/ChangeUnit.dart';
  12. import 'package:farm_tpf/presentation/screens/actions/resource_device_activity/sc_device_activity.dart';
  13. import 'package:farm_tpf/presentation/screens/actions/state_management_helper/change_supply.dart';
  14. import 'package:farm_tpf/presentation/screens/resources/sc_resource_helper.dart';
  15. import 'package:farm_tpf/utils/const_common.dart';
  16. import 'package:farm_tpf/utils/const_string.dart';
  17. import 'package:farm_tpf/utils/const_style.dart';
  18. import 'package:farm_tpf/utils/validators.dart';
  19. import 'package:flutter/material.dart';
  20. import 'package:get/get.dart';
  21. import 'package:farm_tpf/utils/formatter.dart';
  22. import '../util_action.dart';
  23. class WidgetDungSupply extends StatefulWidget {
  24. final List<SuppliesUsing> currentItems;
  25. final Function(List<SuppliesUsing> supplyChanges) onChangeSupplies;
  26. WidgetDungSupply({required this.currentItems, required this.onChangeSupplies});
  27. @override
  28. _WidgetDungSupplyState createState() => _WidgetDungSupplyState();
  29. }
  30. class _WidgetDungSupplyState extends State<WidgetDungSupply> {
  31. final _dosageController = TextEditingController();
  32. final _quantityController = TextEditingController();
  33. final _howToUseController = TextEditingController();
  34. final changeSelectedSupply = Get.put(ChangeSupply());
  35. final changeSupplyUsing = Get.put(ChangeSupplyUsing());
  36. final changeUnit = Get.put(ChangeUnit());
  37. final changeButton = Get.put(ChangeButtonInForm());
  38. final changeSelectedDevice = Get.put(ChangeDevice());
  39. final changeFormField = Get.put(ChangeFieldFormSupply());
  40. GlobalKey<FormState> _formSupplyKey = GlobalKey();
  41. @override
  42. void initState() {
  43. super.initState();
  44. changeSelectedSupply.initValue();
  45. changeSelectedDevice.initValue();
  46. changeSupplyUsing.init(widget.currentItems);
  47. changeUnit.initValue();
  48. changeButton.resetValue();
  49. changeFormField.init();
  50. }
  51. Widget _buildListSupply() {
  52. return GetBuilder<ChangeSupplyUsing>(builder: (value) {
  53. widget.onChangeSupplies(value.currentItems ?? []);
  54. if (value.currentItems!.isEmpty) {
  55. return Container();
  56. } else {
  57. return Container(
  58. height: 120,
  59. child: ListView.builder(
  60. physics: ClampingScrollPhysics(),
  61. scrollDirection: Axis.horizontal,
  62. shrinkWrap: true,
  63. itemCount: value.currentItems?.length,
  64. itemBuilder: (context, index) {
  65. return GestureDetector(
  66. onTap: () {
  67. print("edit");
  68. changeSupplyUsing.changeIndexEdit(index);
  69. changeButton.updateToEdit(true);
  70. var editedSupplyUsing = value.currentItems?[index] ?? SuppliesUsing();
  71. var editedSupply = Supply()
  72. ..id = editedSupplyUsing.tbSuppliesInWarehouseId
  73. ..tbSuppliesName = editedSupplyUsing.supplyName
  74. ..unit = editedSupplyUsing.supplyUnit;
  75. changeSelectedSupply.change(editedSupply);
  76. var editedDevice = Device()
  77. ..id = editedSupplyUsing.tbEquipmentOfCustomerId
  78. ..name = editedSupplyUsing.equipmentName;
  79. changeSelectedDevice.change(editedDevice);
  80. changeUnit.updateListByUnitName(editedSupplyUsing.supplyUnit ?? '');
  81. changeUnit.updateSelected(editedSupplyUsing.supplyUnit ?? '');
  82. _dosageController.text = editedSupplyUsing.dosage ?? '';
  83. _howToUseController.text = editedSupplyUsing.howToUse ?? '';
  84. _quantityController.text = editedSupplyUsing.quantity?.formatNumtoStringDecimal() ?? '0';
  85. },
  86. child: Card(
  87. child: Stack(
  88. alignment: Alignment.bottomCenter,
  89. children: <Widget>[
  90. Positioned(
  91. child: ClipRRect(
  92. borderRadius: BorderRadius.circular(8),
  93. child: Container(
  94. padding: EdgeInsets.all(4),
  95. width: 150,
  96. child: Column(
  97. crossAxisAlignment: CrossAxisAlignment.center,
  98. mainAxisAlignment: MainAxisAlignment.center,
  99. children: [
  100. SizedBox(
  101. height: 12.0,
  102. ),
  103. Flexible(
  104. child: Text(value.currentItems?[index].supplyName ?? "", overflow: TextOverflow.ellipsis, maxLines: 1),
  105. ),
  106. Validators.stringNotNullOrEmpty(value.currentItems?[index].dosage ?? '')
  107. ? Flexible(child: Text("${value.currentItems?[index].dosage ?? ""}"))
  108. : SizedBox(),
  109. Validators.stringNotNullOrEmpty(value.currentItems?[index].quantity?.formatNumtoStringDecimal() ?? '0')
  110. ? Flexible(
  111. child: Text(
  112. "${value.currentItems?[index].quantity?.formatNumtoStringDecimal() ?? ""} ${value.currentItems?[index].supplyUnit ?? ""}"))
  113. : SizedBox(),
  114. Validators.stringNotNullOrEmpty(value.currentItems?[index].equipmentName ?? '')
  115. ? Flexible(child: Text("${value.currentItems?[index].equipmentName ?? ""}"))
  116. : SizedBox(),
  117. Validators.stringNotNullOrEmpty(value.currentItems?[index].howToUse ?? '')
  118. ? Flexible(child: Text("${value.currentItems?[index].howToUse ?? ""}"))
  119. : SizedBox(),
  120. ],
  121. ),
  122. ),
  123. )),
  124. Positioned(
  125. top: -10,
  126. right: -10,
  127. child: IconButton(
  128. icon: Icon(
  129. Icons.cancel,
  130. color: Colors.redAccent,
  131. ),
  132. onPressed: () {
  133. changeSupplyUsing.deleteSupply(index);
  134. }),
  135. )
  136. ],
  137. )));
  138. }));
  139. }
  140. });
  141. }
  142. Widget _btnSelectSubstrates() {
  143. return GetBuilder<ChangeSupply>(builder: (data) {
  144. return TextButton(onPressed: () {
  145. var currentIndexEdit = changeSupplyUsing.currentIndex;
  146. Navigator.of(context)
  147. .push(MaterialPageRoute(
  148. builder: (_) => ResourceHelperScreen(
  149. titleName: "Phân bón",
  150. type: ConstCommon.supplyTypeDung,
  151. selectedId: changeSelectedSupply.selectedSupplyId ?? -1,
  152. currentItems: changeSupplyUsing.currentItems ?? [],
  153. currentEditId:
  154. ((currentIndexEdit ?? 0) >= 0) ? changeSupplyUsing.currentItems![currentIndexEdit!].tbSuppliesInWarehouseId ?? -1 : -1,
  155. ),
  156. fullscreenDialog: false))
  157. .then((value) {
  158. if (value != null) {
  159. var result = value as Supply;
  160. changeSelectedSupply.change(result);
  161. changeUnit.updateListByUnitName(result.unit ?? '');
  162. changeFormField.change(true);
  163. }
  164. });
  165. }, child: GetBuilder<ChangeSupply>(builder: (_) {
  166. var isValid = changeSelectedSupply.isValid;
  167. return Column(
  168. crossAxisAlignment: CrossAxisAlignment.start,
  169. children: [
  170. Container(
  171. padding: EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  172. decoration: BoxDecoration(
  173. border: Border(bottom: BorderSide(width: 1, color: (isValid ?? false) ? Colors.grey : Colors.red)),
  174. ),
  175. child: Column(
  176. crossAxisAlignment: CrossAxisAlignment.start,
  177. children: [
  178. Validators.stringNotNullOrEmpty(changeSelectedSupply.selectedSupplyName ?? '')
  179. ? Text(
  180. 'Tên thương mại *',
  181. style:
  182. TextStyle(fontSize: 13, fontWeight: FontWeight.normal, color: (isValid ?? false) ? Colors.black54 : Colors.red[600]),
  183. )
  184. : Text(
  185. '',
  186. style:
  187. TextStyle(fontSize: 13, fontWeight: FontWeight.normal, color: (isValid ?? false) ? Colors.black54 : Colors.red[600]),
  188. ),
  189. Row(
  190. children: [
  191. Expanded(
  192. child: Validators.stringNotNullOrEmpty(changeSelectedSupply.selectedSupplyName ?? '')
  193. ? Text(changeSelectedSupply.selectedSupplyName ?? '', style: TextStyle(fontSize: 14.0, color: Colors.black87))
  194. : Text("Tên thương mại*", style: TextStyle(fontSize: 14.0, color: Colors.black54)),
  195. ),
  196. Icon(
  197. Icons.arrow_drop_down,
  198. color: Colors.grey,
  199. ),
  200. ],
  201. )
  202. ],
  203. )),
  204. (isValid ?? false) ? SizedBox() : WidgetErrorTextField()
  205. ],
  206. );
  207. }));
  208. });
  209. }
  210. Widget _btnSelectDevice() {
  211. return GetBuilder<ChangeDevice>(builder: (data) {
  212. return TextButton(
  213. onPressed: () {
  214. Navigator.of(context)
  215. .push(MaterialPageRoute(
  216. builder: (_) => ListDeviceActivity(selectedId: changeSelectedDevice.selectedDeviceId ?? -1), fullscreenDialog: false))
  217. .then((value) {
  218. if (value != null) {
  219. var result = value as Device;
  220. changeSelectedDevice.change(result);
  221. changeFormField.change(true);
  222. }
  223. });
  224. },
  225. child: Container(
  226. padding: EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  227. decoration: BoxDecoration(
  228. border: kBorderTextField,
  229. ),
  230. child: Column(
  231. crossAxisAlignment: CrossAxisAlignment.start,
  232. children: [
  233. Validators.stringNotNullOrEmpty(changeSelectedDevice.selectedDeviceName ?? '')
  234. ? Text(
  235. 'Thiết bị',
  236. style: TextStyle(fontSize: 13, fontWeight: FontWeight.normal, color: Colors.black54),
  237. )
  238. : Text(
  239. '',
  240. style: TextStyle(fontSize: 13, fontWeight: FontWeight.normal, color: Colors.black54),
  241. ),
  242. Row(
  243. children: [
  244. GetBuilder<ChangeSupply>(
  245. builder: (_) => Expanded(
  246. child: Validators.stringNotNullOrEmpty(changeSelectedDevice.selectedDeviceName ?? '')
  247. ? Text(changeSelectedDevice.selectedDeviceName ?? '', style: TextStyle(fontSize: 14.0, color: Colors.black87))
  248. : Text("Thiết bị", style: TextStyle(fontSize: 14.0, color: Colors.black54)),
  249. )),
  250. Icon(
  251. Icons.arrow_drop_down,
  252. color: Colors.grey,
  253. ),
  254. ],
  255. ),
  256. ],
  257. )));
  258. });
  259. }
  260. Widget _dropdownUnitTypes() {
  261. return GetBuilder<ChangeUnit>(builder: (data) {
  262. return DropdownButtonFormField<String>(
  263. itemHeight: 100,
  264. value: !Validators.stringNotNullOrEmpty(data.selectedUnit ?? '') ? null : data.selectedUnit,
  265. items: data.currentUnits!
  266. .map((label) => DropdownMenuItem(
  267. child: Text(label),
  268. value: label,
  269. ))
  270. .toList(),
  271. onChanged: (value) {
  272. var currentQuantity = _quantityController.text;
  273. num assignValue = currentQuantity.parseDoubleThousand();
  274. if (assignValue != null) {
  275. var oldSelected = data.selectedUnit;
  276. if (oldSelected == value) {
  277. } else {
  278. assignValue = UtilAction.convertUnit(
  279. inputValue: assignValue,
  280. oldUnit: oldSelected ?? '',
  281. newUnit: value ?? '',
  282. );
  283. }
  284. _quantityController.text = assignValue.formatNumtoStringDecimal();
  285. }
  286. changeUnit.updateSelected(value ?? '');
  287. },
  288. );
  289. });
  290. }
  291. _quantityField() {
  292. return WidgetTextFormFieldNumber(
  293. hintValue: "Tổng lượng sử dụng *",
  294. labelText: "Tổng lượng sử dụng *",
  295. textController: _quantityController,
  296. validator: (String? value) {
  297. return Validators.validateNotNullOrEmpty(value ?? '', label_validate_input_empty);
  298. },
  299. onChanged: (value) {
  300. if (!Validators.stringNotNullOrEmpty(value ?? '') &&
  301. !Validators.stringNotNullOrEmpty(_howToUseController.text) &&
  302. !Validators.stringNotNullOrEmpty(_dosageController.text) &&
  303. (Get.find<ChangeSupply>().selectedSupplyId ?? -1) <= 0 &&
  304. (changeSelectedDevice.selectedDeviceId ?? -1) <= 0) {
  305. changeFormField.change(false);
  306. } else {
  307. changeFormField.change(true);
  308. }
  309. },
  310. );
  311. }
  312. _buttonInForm() {
  313. return GetBuilder<ChangeButtonInForm>(builder: (_) {
  314. return Row(
  315. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  316. children: [
  317. _.isEdit ?? false
  318. ? TextButton(
  319. child: Text("Huỷ"),
  320. onPressed: () {
  321. changeButton.resetValue();
  322. _resetForm();
  323. _hidenKeyboard(context);
  324. })
  325. : SizedBox(),
  326. _.isEdit ?? false
  327. ? Expanded(
  328. child: TextButton(
  329. onPressed: () {
  330. if (_formSupplyKey.currentState!.validate()) {
  331. _formSupplyKey.currentState!.save();
  332. if ((changeSelectedSupply.selectedSupplyId ?? -1) <= 0) {
  333. changeSelectedSupply.changeValid(false);
  334. } else {
  335. changeSelectedSupply.changeValid(true);
  336. }
  337. var currentSupply = changeSelectedSupply.currentSupply;
  338. var currentDevice = changeSelectedDevice.currentDevice;
  339. var currentQuantity = _quantityController.text.parseDoubleThousand();
  340. if (currentSupply?.id != null && (currentQuantity ?? 0) > 0) {
  341. var quantityWithCurrentSupplyUnit = UtilAction.convertUnit(
  342. inputValue: currentQuantity,
  343. oldUnit: changeUnit.selectedUnit ?? '',
  344. newUnit: changeSelectedSupply.currentSupply?.unit ?? '',
  345. );
  346. SuppliesUsing newSup = SuppliesUsing()
  347. ..dosage = _dosageController.text
  348. ..howToUse = _howToUseController.text
  349. ..quantity = quantityWithCurrentSupplyUnit
  350. ..tbSuppliesInWarehouseId = currentSupply?.id
  351. ..suppliesInWarehouseId = currentSupply?.id
  352. ..supplyName = currentSupply?.tbSuppliesName
  353. ..tbEquipmentOfCustomerId = currentDevice?.id ?? -1
  354. ..equipmentOfCustomerId = currentDevice?.id ?? -1
  355. ..equipmentName = currentDevice?.name ?? ''
  356. ..supplyUnit = currentSupply?.unit
  357. ..unit = currentSupply?.unit;
  358. changeSupplyUsing.editSupply(changeSupplyUsing.currentIndex ?? -1, newSup);
  359. _resetForm();
  360. _hidenKeyboard(context);
  361. } else if (currentSupply?.id == null || ((currentQuantity ?? 0) <= 0)) {
  362. Utils.showSnackBarWarning(message: "Vui lòng nhập vật tư và số lượng");
  363. }
  364. } else {
  365. Utils.showSnackBarWarning(message: "Vui lòng nhập vật tư và số lượng");
  366. if ((changeSelectedSupply.selectedSupplyId ?? -1) <= 0) {
  367. changeSelectedSupply.changeValid(false);
  368. } else {
  369. changeSelectedSupply.changeValid(true);
  370. }
  371. }
  372. },
  373. child: Text(
  374. "Sửa phân bón",
  375. style: TextStyle(color: Colors.blue),
  376. )),
  377. )
  378. : Expanded(
  379. child: TextButton(
  380. onPressed: () {
  381. if (_formSupplyKey.currentState!.validate()) {
  382. _formSupplyKey.currentState!.save();
  383. if ((changeSelectedSupply.selectedSupplyId ?? -1) <= 0) {
  384. changeSelectedSupply.changeValid(false);
  385. } else {
  386. changeSelectedSupply.changeValid(true);
  387. }
  388. var currentSupply = changeSelectedSupply.currentSupply;
  389. var currentDevice = changeSelectedDevice.currentDevice;
  390. var currentQuantity = _quantityController.text.parseDoubleThousand();
  391. if (currentSupply?.id != null && (currentQuantity ?? 0) > 0) {
  392. var quantityWithCurrentSupplyUnit = UtilAction.convertUnit(
  393. inputValue: currentQuantity,
  394. oldUnit: changeUnit.selectedUnit ?? '',
  395. newUnit: changeSelectedSupply.currentSupply?.unit ?? '',
  396. );
  397. SuppliesUsing newSup = SuppliesUsing()
  398. ..dosage = _dosageController.text
  399. ..howToUse = _howToUseController.text
  400. ..quantity = quantityWithCurrentSupplyUnit
  401. ..tbSuppliesInWarehouseId = currentSupply?.id
  402. ..suppliesInWarehouseId = currentSupply?.id
  403. ..supplyName = currentSupply?.tbSuppliesName
  404. ..supplyUnit = currentSupply?.unit
  405. ..tbEquipmentOfCustomerId = currentDevice?.id ?? -1
  406. ..equipmentOfCustomerId = currentDevice?.id ?? -1
  407. ..equipmentName = currentDevice?.name
  408. ..unit = currentSupply?.unit;
  409. changeSupplyUsing.addSupply(newSup);
  410. _resetForm();
  411. _hidenKeyboard(context);
  412. } else if (currentSupply?.id == null || ((currentQuantity ?? 0) <= 0)) {
  413. Utils.showSnackBarWarning(message: "Vui lòng nhập vật tư và số lượng");
  414. }
  415. } else {
  416. Utils.showSnackBarWarning(message: "Vui lòng nhập vật tư và số lượng");
  417. if ((changeSelectedSupply.selectedSupplyId ?? -1) <= 0) {
  418. changeSelectedSupply.changeValid(false);
  419. } else {
  420. changeSelectedSupply.changeValid(true);
  421. }
  422. //
  423. }
  424. },
  425. child: Text(
  426. "+ Thêm phân bón",
  427. style: TextStyle(color: Colors.blue),
  428. )),
  429. )
  430. ],
  431. );
  432. });
  433. }
  434. Widget _formEdit() {
  435. return Form(
  436. key: _formSupplyKey,
  437. child: Column(
  438. children: [
  439. Container(
  440. padding: EdgeInsets.all(8.0),
  441. margin: EdgeInsets.all(8.0),
  442. decoration: BoxDecoration(
  443. shape: BoxShape.rectangle,
  444. borderRadius: BorderRadius.circular(10),
  445. color: Colors.white,
  446. border: Border.all(color: Colors.grey),
  447. ),
  448. child: Column(
  449. children: [
  450. _btnSelectSubstrates(),
  451. TextFormField(
  452. keyboardType: TextInputType.text,
  453. controller: _dosageController,
  454. decoration: InputDecoration(labelText: "Liều lượng sử dụng"),
  455. onSaved: (newValue) {},
  456. onChanged: (value) {
  457. if (!Validators.stringNotNullOrEmpty(_quantityController.text) &&
  458. !Validators.stringNotNullOrEmpty(_howToUseController.text) &&
  459. !Validators.stringNotNullOrEmpty(value) &&
  460. (Get.find<ChangeSupply>().selectedSupplyId ?? -1) <= 0 &&
  461. (changeSelectedDevice.selectedDeviceId ?? -1) <= 0) {
  462. changeFormField.change(false);
  463. } else {
  464. changeFormField.change(true);
  465. }
  466. },
  467. ),
  468. Row(
  469. mainAxisSize: MainAxisSize.min,
  470. mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  471. crossAxisAlignment: CrossAxisAlignment.center,
  472. children: [
  473. Expanded(
  474. flex: 2,
  475. child: Container(
  476. height: 82,
  477. child: _quantityField(),
  478. ),
  479. ),
  480. SizedBox(
  481. width: 16.0,
  482. ),
  483. Expanded(
  484. flex: 1,
  485. child: Align(
  486. alignment: Alignment.bottomCenter,
  487. child: _dropdownUnitTypes(),
  488. )),
  489. ]),
  490. _btnSelectDevice(),
  491. TextFormField(
  492. keyboardType: TextInputType.text,
  493. controller: _howToUseController,
  494. decoration: InputDecoration(labelText: "Phương pháp sử dụng"),
  495. onSaved: (newValue) {},
  496. onChanged: (value) {
  497. if (!Validators.stringNotNullOrEmpty(_quantityController.text) &&
  498. !Validators.stringNotNullOrEmpty(value) &&
  499. !Validators.stringNotNullOrEmpty(_dosageController.text) &&
  500. (Get.find<ChangeSupply>().selectedSupplyId ?? -1) <= 0 &&
  501. (changeSelectedDevice.selectedDeviceId ?? -1) <= 0) {
  502. changeFormField.change(false);
  503. } else {
  504. changeFormField.change(true);
  505. }
  506. },
  507. ),
  508. ],
  509. ),
  510. ),
  511. _buttonInForm()
  512. ],
  513. ),
  514. );
  515. }
  516. _resetForm() {
  517. changeSupplyUsing.changeIndexEdit(-1);
  518. changeButton.resetValue();
  519. _dosageController.text = "";
  520. _howToUseController.text = "";
  521. _quantityController.text = "";
  522. changeUnit.initValue();
  523. changeSelectedSupply.initValue();
  524. changeSelectedDevice.initValue();
  525. changeFormField.change(false);
  526. }
  527. _hidenKeyboard(BuildContext context) {
  528. FocusScopeNode currentFocus = FocusScope.of(context);
  529. if (!currentFocus.hasPrimaryFocus) {
  530. currentFocus.unfocus();
  531. }
  532. }
  533. @override
  534. Widget build(BuildContext context) {
  535. return Column(
  536. children: [
  537. Padding(
  538. padding: const EdgeInsets.all(8.0),
  539. child: Align(
  540. alignment: Alignment.centerLeft,
  541. child: Text(
  542. 'Phân bón',
  543. style: TextStyle(color: Colors.black54, fontSize: 14),
  544. ),
  545. ),
  546. ),
  547. _buildListSupply(),
  548. SizedBox(
  549. height: 8.0,
  550. ),
  551. _formEdit(),
  552. SizedBox(
  553. height: 8.0,
  554. ),
  555. ],
  556. );
  557. }
  558. }