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.

596 lines
28KB

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