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.

559 lines
25KB

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