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.

530 lines
21KB

  1. import 'package:farm_tpf/custom_model/Nursery.dart';
  2. import 'package:farm_tpf/data/repository/repository.dart';
  3. import 'package:farm_tpf/models/index.dart';
  4. import 'package:farm_tpf/presentation/screens/actions/nursery/bloc/expansion_list_bloc.dart';
  5. import 'package:farm_tpf/presentation/screens/resources/sc_resource_helper.dart';
  6. import 'package:farm_tpf/utils/bloc/bloc/status_add_form_bloc.dart';
  7. import 'package:farm_tpf/utils/const_color.dart';
  8. import 'package:farm_tpf/utils/const_common.dart';
  9. import 'package:farm_tpf/utils/const_string.dart';
  10. import 'package:farm_tpf/utils/const_style.dart';
  11. import 'package:farm_tpf/utils/pref.dart';
  12. import 'package:farm_tpf/utils/validators.dart';
  13. import 'package:flutter/material.dart';
  14. import 'package:flutter_bloc/flutter_bloc.dart';
  15. import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
  16. import 'package:fluttertoast/fluttertoast.dart';
  17. import 'package:get/get.dart';
  18. import 'package:get/state_manager.dart';
  19. import 'package:intl/intl.dart';
  20. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  21. import 'package:pattern_formatter/pattern_formatter.dart';
  22. import 'package:farm_tpf/utils/formatter.dart';
  23. class EditActionNurseryScreen extends StatefulWidget {
  24. @override
  25. _EditActionNurseryState createState() => _EditActionNurseryState();
  26. }
  27. class _EditActionNurseryState extends State<EditActionNurseryScreen> {
  28. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  29. final _repository = Repository();
  30. GlobalKey<FormState> _formKey = GlobalKey();
  31. bool _autoValidate = false;
  32. Nursery _nursery = Nursery();
  33. var pref = LocalPref();
  34. FlutterToast flutterToast;
  35. TextEditingController _substrateController = TextEditingController();
  36. TextEditingController _seedLengthController = TextEditingController();
  37. TextEditingController _quantityController = TextEditingController();
  38. TextEditingController _seedIncubationTimeController = TextEditingController();
  39. TextEditingController _descriptionController = TextEditingController();
  40. TextEditingController _workerNameController = TextEditingController();
  41. TextEditingController _trayNumberController = TextEditingController();
  42. String executeTimeView;
  43. DateTime executeTime = DateTime.now();
  44. List<NurseryDetail> currentNurseryDetail = List<NurseryDetail>();
  45. ExpansionListBloc _bloc;
  46. int currentIndexUpdate = -1;
  47. bool isResetForm = true;
  48. final changeSupply = Get.put(ChangeSupply());
  49. int selectedSupplyId = -1;
  50. @override
  51. void initState() {
  52. super.initState();
  53. changeSupply.initValue();
  54. _nursery.nurseryDetail = new List<NurseryDetail>();
  55. flutterToast = FlutterToast(context);
  56. //UPDATE
  57. if (_nursery != null) {
  58. try {
  59. executeTime =
  60. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(_nursery.executeDate);
  61. } catch (_) {}
  62. } else {
  63. //ADD NEW
  64. var parsedExecuteDate =
  65. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(executeTime);
  66. _nursery.executeDate = "$parsedExecuteDate";
  67. }
  68. executeTimeView = DateFormat("dd/MM/yyyy HH:mm").format(executeTime);
  69. }
  70. Widget _btnExecuteTimePicker() {
  71. return FlatButton(
  72. padding: EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
  73. onPressed: () {
  74. DatePicker.showDateTimePicker(context,
  75. showTitleActions: true, onChanged: (date) {}, onConfirm: (date) {
  76. setState(() {
  77. var parsedDate =
  78. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(date);
  79. _nursery.executeDate = "$parsedDate";
  80. executeTimeView = DateFormat("dd/MM/yyyy HH:mm").format(date);
  81. });
  82. }, currentTime: executeTime, locale: LocaleType.vi);
  83. },
  84. child: Container(
  85. padding:
  86. EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  87. decoration: BoxDecoration(
  88. border: kBorderTextField,
  89. ),
  90. child: Row(
  91. children: [
  92. Expanded(
  93. child: Text(
  94. //TODO: check condition
  95. executeTimeView == null ? "$executeTime" : executeTimeView,
  96. style: TextStyle(fontSize: 14.0, color: Colors.black87),
  97. )),
  98. Icon(
  99. Icons.date_range,
  100. color: Colors.blue,
  101. ),
  102. ],
  103. )));
  104. }
  105. Widget _btnSelectSeed() {
  106. return FlatButton(
  107. padding: EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
  108. onPressed: () {
  109. Navigator.of(context)
  110. .push(MaterialPageRoute(
  111. builder: (_) => ResourceHelperScreen(
  112. titleName: "Gía thể",
  113. type: ConstCommon.supplyTypeSubStrate,
  114. selectedId: Get.find<ChangeSupply>().selectedSupplyId),
  115. fullscreenDialog: false))
  116. .then((value) {
  117. if (value != null) {
  118. var result = value as Supply;
  119. _nursery.substrates = result.name;
  120. changeSupply.change(result);
  121. print("Home: $value");
  122. }
  123. });
  124. },
  125. child: Container(
  126. padding:
  127. EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  128. decoration: BoxDecoration(
  129. border: kBorderTextField,
  130. ),
  131. child: Row(
  132. children: [
  133. GetBuilder<ChangeSupply>(
  134. builder: (_) => Expanded(
  135. child: Text(
  136. changeSupply.currentSupply.name == null
  137. ? "Loại giá thể"
  138. : _nursery.substrates.toString(),
  139. style: TextStyle(
  140. fontSize: 14.0, color: Colors.black87)))),
  141. Icon(
  142. Icons.arrow_drop_down,
  143. color: Colors.grey,
  144. ),
  145. ],
  146. )));
  147. }
  148. Widget _seedLengthField() {
  149. return TextFormField(
  150. keyboardType: TextInputType.numberWithOptions(decimal: true),
  151. inputFormatters: [
  152. ThousandsFormatter(
  153. formatter: NumberFormat("#,###.##", "es"), allowFraction: true)
  154. ],
  155. decoration: InputDecoration(labelText: "Chiều dài mần"),
  156. controller: _seedLengthController,
  157. validator: (String value) {
  158. return Validators.validNumber(value, "Chiều dài mần");
  159. },
  160. onSaved: (newValue) {
  161. _nursery.seedLength = newValue.parseDoubleThousand();
  162. },
  163. );
  164. }
  165. Widget _quantityField() {
  166. return TextFormField(
  167. keyboardType: TextInputType.numberWithOptions(decimal: true),
  168. inputFormatters: [
  169. ThousandsFormatter(
  170. formatter: NumberFormat("#,###.##", "es"), allowFraction: true)
  171. ],
  172. decoration: InputDecoration(labelText: "Số lượng hạt gieo"),
  173. controller: _quantityController,
  174. validator: (String value) {
  175. return Validators.validNumber(value, "Số lượng hạt gieo");
  176. },
  177. onSaved: (newValue) {
  178. _nursery.quantity = newValue.parseDoubleThousand();
  179. },
  180. );
  181. }
  182. Widget _seedIncubationTimeField() {
  183. return TextFormField(
  184. keyboardType: TextInputType.numberWithOptions(decimal: true),
  185. inputFormatters: [
  186. ThousandsFormatter(
  187. formatter: NumberFormat("#,###.##", "es"), allowFraction: true)
  188. ],
  189. decoration: InputDecoration(labelText: "Thời gian ngâm hạt"),
  190. controller: _seedIncubationTimeController,
  191. validator: (String value) {
  192. return Validators.validNumber(value, "Thời gian ngâm hạt");
  193. },
  194. onSaved: (newValue) {
  195. _nursery.seedIncubationTime = newValue.parseDoubleThousand();
  196. },
  197. );
  198. }
  199. Widget _desciptionField() {
  200. return TextFormField(
  201. keyboardType: TextInputType.text,
  202. decoration: InputDecoration(labelText: "Ghi chú"),
  203. controller: _descriptionController,
  204. onSaved: (newValue) {
  205. _nursery.description = newValue;
  206. },
  207. );
  208. }
  209. Widget _btnAddWorker() {
  210. return Builder(builder: (context) {
  211. return BlocConsumer<StatusAddFormBloc, StatusAddFormState>(
  212. listener: (context, state) {
  213. if (state is Edit) {
  214. isResetForm = false;
  215. _workerNameController.text = state.nurseryDetail.workerName;
  216. _trayNumberController.text = state.nurseryDetail.trayNumber;
  217. } else if (state is Delete) {
  218. if (currentIndexUpdate == state.index) {
  219. isResetForm = true;
  220. _workerNameController.text = "";
  221. _trayNumberController.text = "";
  222. }
  223. } else {
  224. isResetForm = true;
  225. _workerNameController.text = "";
  226. _trayNumberController.text = "";
  227. }
  228. }, builder: (context, state) {
  229. return Container(
  230. padding: EdgeInsets.all(8.0),
  231. decoration: BoxDecoration(
  232. shape: BoxShape.rectangle,
  233. borderRadius: BorderRadius.circular(10),
  234. color: Colors.white,
  235. border: Border.all(color: COLOR_CONST.DEFAULT)),
  236. child: Column(
  237. children: [
  238. TextFormField(
  239. keyboardType: TextInputType.text,
  240. controller: _workerNameController,
  241. decoration: InputDecoration(labelText: "Tên công nhân"),
  242. onSaved: (newValue) {
  243. _nursery.description = newValue;
  244. },
  245. ),
  246. TextFormField(
  247. keyboardType: TextInputType.text,
  248. controller: _trayNumberController,
  249. decoration: InputDecoration(labelText: "Ươm khây số"),
  250. onSaved: (newValue) {
  251. _nursery.description = newValue;
  252. },
  253. ),
  254. Align(
  255. alignment: Alignment.centerRight,
  256. child: Row(
  257. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  258. children: [
  259. isResetForm
  260. ? Container()
  261. : OutlineButton(
  262. shape: RoundedRectangleBorder(
  263. borderRadius: new BorderRadius.circular(8.0)),
  264. child: Text("Huỷ"),
  265. onPressed: () {
  266. context.bloc<StatusAddFormBloc>().add(Reset());
  267. }),
  268. FlatButton(
  269. color: COLOR_CONST.DEFAULT,
  270. shape: RoundedRectangleBorder(
  271. borderRadius: new BorderRadius.circular(8.0)),
  272. onPressed: () {
  273. if (_workerNameController.text.isEmpty ||
  274. _trayNumberController.text.isEmpty) {
  275. return;
  276. }
  277. NurseryDetail _nurseryDetail = NurseryDetail()
  278. ..workerName = _workerNameController.text
  279. ..trayNumber = _trayNumberController.text;
  280. if (state is Edit) {
  281. context.bloc<ExpansionListBloc>().add(Update(
  282. index: state.index,
  283. item: _nurseryDetail,
  284. items: state.items));
  285. } else {
  286. currentNurseryDetail.insert(0, _nurseryDetail);
  287. BlocProvider.of<ExpansionListBloc>(context)
  288. .add(AddNew(items: currentNurseryDetail));
  289. }
  290. context.bloc<StatusAddFormBloc>().add(Reset());
  291. },
  292. child: Text(
  293. (state is Edit) ? "Sửa" : "Thêm",
  294. style: TextStyle(color: Colors.white),
  295. ))
  296. ],
  297. ),
  298. ),
  299. ],
  300. ));
  301. });
  302. });
  303. }
  304. Widget _buildListAddWorker() {
  305. return Builder(builder: (context) {
  306. return BlocBuilder<ExpansionListBloc, ExpansionListState>(
  307. builder: (context, state) {
  308. if (state is ExpansionListSuccess) {
  309. currentNurseryDetail = state.items;
  310. if (currentNurseryDetail.isEmpty) {
  311. return Container();
  312. }
  313. return Container(
  314. height: 70,
  315. child: ListView.builder(
  316. physics: ClampingScrollPhysics(),
  317. scrollDirection: Axis.horizontal,
  318. shrinkWrap: true,
  319. itemCount: currentNurseryDetail.length,
  320. itemBuilder: (context, index) {
  321. return GestureDetector(
  322. onTap: () {
  323. print("Show preview image or video");
  324. currentIndexUpdate = index;
  325. context.bloc<StatusAddFormBloc>().add(Changed(
  326. status: CRUDStatus.edit,
  327. index: index,
  328. nurseryDetail: currentNurseryDetail[index],
  329. items: currentNurseryDetail));
  330. },
  331. child: Card(
  332. child: Stack(
  333. alignment: Alignment.bottomCenter,
  334. overflow: Overflow.visible,
  335. children: <Widget>[
  336. Positioned(
  337. child: ClipRRect(
  338. borderRadius: BorderRadius.circular(8),
  339. child: Container(
  340. padding: EdgeInsets.all(4),
  341. width: 120,
  342. child: Column(
  343. children: [
  344. SizedBox(
  345. height: 12.0,
  346. ),
  347. Flexible(
  348. child: Text(
  349. currentNurseryDetail[index]
  350. .workerName ??
  351. "",
  352. overflow: TextOverflow.ellipsis,
  353. maxLines: 1),
  354. ),
  355. Flexible(
  356. child: Text(currentNurseryDetail[index]
  357. .trayNumber ??
  358. ""))
  359. ],
  360. ),
  361. ),
  362. )),
  363. Positioned(
  364. top: -10,
  365. right: -10,
  366. child: IconButton(
  367. icon: Icon(
  368. Icons.cancel,
  369. color: Colors.redAccent,
  370. ),
  371. onPressed: () {
  372. print("On tap delete media");
  373. context.bloc<ExpansionListBloc>().add(
  374. DeleteItem(
  375. index: index,
  376. items: currentNurseryDetail));
  377. context.bloc<StatusAddFormBloc>().add(
  378. Changed(
  379. status: CRUDStatus.delete,
  380. index: index,
  381. nurseryDetail:
  382. currentNurseryDetail[index],
  383. items: currentNurseryDetail));
  384. }),
  385. )
  386. ],
  387. )));
  388. }));
  389. } else if (state is ExpansionListFailure) {
  390. return Container();
  391. } else {
  392. return Container();
  393. }
  394. });
  395. });
  396. }
  397. _actionAppBar() {
  398. IconButton iconButton;
  399. if (1 == 1) {
  400. iconButton = IconButton(
  401. icon: Icon(
  402. Icons.done,
  403. color: Colors.black,
  404. ),
  405. onPressed: () {},
  406. );
  407. return <Widget>[iconButton];
  408. }
  409. return <Widget>[Container()];
  410. }
  411. @override
  412. Widget build(BuildContext context) => KeyboardDismisser(
  413. gestures: [
  414. GestureType.onTap,
  415. GestureType.onPanUpdateDownDirection,
  416. ],
  417. child: Scaffold(
  418. key: _scaffoldKey,
  419. appBar: AppBar(
  420. centerTitle: true,
  421. title: Text(plot_action_nursery),
  422. actions: _actionAppBar()),
  423. body: KeyboardDismisser(
  424. child: MultiBlocProvider(
  425. providers: [
  426. BlocProvider<ExpansionListBloc>(
  427. create: (context) => ExpansionListBloc(),
  428. ),
  429. BlocProvider<StatusAddFormBloc>(
  430. create: (context) => StatusAddFormBloc(),
  431. )
  432. ],
  433. child: Form(
  434. key: _formKey,
  435. autovalidate: _autoValidate,
  436. child: SingleChildScrollView(
  437. padding: EdgeInsets.all(8.0),
  438. child: Column(
  439. children: <Widget>[
  440. Container(
  441. width: double.infinity,
  442. child: Text(
  443. "Ngày thực hiện",
  444. style: TextStyle(
  445. color: Colors.black54, fontSize: 13.0),
  446. ),
  447. ),
  448. _btnExecuteTimePicker(),
  449. SizedBox(
  450. height: 8.0,
  451. ),
  452. Container(
  453. width: double.infinity,
  454. child: Text(
  455. "Tên giống",
  456. style: TextStyle(
  457. color: Colors.black54, fontSize: 13.0),
  458. ),
  459. ),
  460. _btnSelectSeed(),
  461. SizedBox(
  462. height: 8.0,
  463. ),
  464. _seedLengthField(),
  465. SizedBox(
  466. height: 8.0,
  467. ),
  468. _quantityField(),
  469. SizedBox(
  470. height: 8.0,
  471. ),
  472. _seedIncubationTimeField(),
  473. SizedBox(
  474. height: 8.0,
  475. ),
  476. _desciptionField(),
  477. SizedBox(
  478. height: 8.0,
  479. ),
  480. _btnAddWorker(),
  481. SizedBox(
  482. height: 8.0,
  483. ),
  484. _buildListAddWorker(),
  485. Container(child: Text("Them hinh anh")),
  486. ],
  487. ),
  488. ))))));
  489. @override
  490. void dispose() {
  491. _substrateController.dispose();
  492. _seedLengthController.dispose();
  493. _quantityController.dispose();
  494. _seedIncubationTimeController.dispose();
  495. _descriptionController.dispose();
  496. super.dispose();
  497. }
  498. }
  499. class ChangeSupply extends GetxController {
  500. Supply currentSupply;
  501. int selectedSupplyId;
  502. void initValue() {
  503. currentSupply = Supply();
  504. selectedSupplyId = -1;
  505. update();
  506. }
  507. void change(Supply supply) {
  508. currentSupply = supply;
  509. selectedSupplyId = supply.id;
  510. update();
  511. }
  512. }