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.

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