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.

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