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.

526 lines
20KB

  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. NurseryDetail _nurseryDetail = NurseryDetail()
  274. ..workerName = _workerNameController.text
  275. ..trayNumber = _trayNumberController.text;
  276. if (state is Edit) {
  277. context.bloc<ExpansionListBloc>().add(Update(
  278. index: state.index,
  279. item: _nurseryDetail,
  280. items: state.items));
  281. } else {
  282. currentNurseryDetail.insert(0, _nurseryDetail);
  283. BlocProvider.of<ExpansionListBloc>(context)
  284. .add(AddNew(items: currentNurseryDetail));
  285. }
  286. context.bloc<StatusAddFormBloc>().add(Reset());
  287. },
  288. child: Text(
  289. (state is Edit) ? "Sửa" : "Thêm",
  290. style: TextStyle(color: Colors.white),
  291. ))
  292. ],
  293. ),
  294. ),
  295. ],
  296. ));
  297. });
  298. });
  299. }
  300. Widget _buildListAddWorker() {
  301. return Builder(builder: (context) {
  302. return BlocBuilder<ExpansionListBloc, ExpansionListState>(
  303. builder: (context, state) {
  304. if (state is ExpansionListSuccess) {
  305. currentNurseryDetail = state.items;
  306. if (currentNurseryDetail.isEmpty) {
  307. return Container();
  308. }
  309. return Container(
  310. height: 70,
  311. child: ListView.builder(
  312. physics: ClampingScrollPhysics(),
  313. scrollDirection: Axis.horizontal,
  314. shrinkWrap: true,
  315. itemCount: currentNurseryDetail.length,
  316. itemBuilder: (context, index) {
  317. return GestureDetector(
  318. onTap: () {
  319. print("Show preview image or video");
  320. currentIndexUpdate = index;
  321. context.bloc<StatusAddFormBloc>().add(Changed(
  322. status: CRUDStatus.edit,
  323. index: index,
  324. nurseryDetail: currentNurseryDetail[index],
  325. items: currentNurseryDetail));
  326. },
  327. child: Card(
  328. child: Stack(
  329. alignment: Alignment.bottomCenter,
  330. overflow: Overflow.visible,
  331. children: <Widget>[
  332. Positioned(
  333. child: ClipRRect(
  334. borderRadius: BorderRadius.circular(8),
  335. child: Container(
  336. padding: EdgeInsets.all(4),
  337. width: 120,
  338. child: Column(
  339. children: [
  340. SizedBox(
  341. height: 12.0,
  342. ),
  343. Flexible(
  344. child: Text(
  345. currentNurseryDetail[index]
  346. .workerName ??
  347. "",
  348. overflow: TextOverflow.ellipsis,
  349. maxLines: 1),
  350. ),
  351. Flexible(
  352. child: Text(currentNurseryDetail[index]
  353. .trayNumber ??
  354. ""))
  355. ],
  356. ),
  357. ),
  358. )),
  359. Positioned(
  360. top: -10,
  361. right: -10,
  362. child: IconButton(
  363. icon: Icon(
  364. Icons.cancel,
  365. color: Colors.redAccent,
  366. ),
  367. onPressed: () {
  368. print("On tap delete media");
  369. context.bloc<ExpansionListBloc>().add(
  370. DeleteItem(
  371. index: index,
  372. items: currentNurseryDetail));
  373. context.bloc<StatusAddFormBloc>().add(
  374. Changed(
  375. status: CRUDStatus.delete,
  376. index: index,
  377. nurseryDetail:
  378. currentNurseryDetail[index],
  379. items: currentNurseryDetail));
  380. }),
  381. )
  382. ],
  383. )));
  384. }));
  385. } else if (state is ExpansionListFailure) {
  386. return Container();
  387. } else {
  388. return Container();
  389. }
  390. });
  391. });
  392. }
  393. _actionAppBar() {
  394. IconButton iconButton;
  395. if (1 == 1) {
  396. iconButton = IconButton(
  397. icon: Icon(
  398. Icons.done,
  399. color: Colors.black,
  400. ),
  401. onPressed: () {},
  402. );
  403. return <Widget>[iconButton];
  404. }
  405. return <Widget>[Container()];
  406. }
  407. @override
  408. Widget build(BuildContext context) => KeyboardDismisser(
  409. gestures: [
  410. GestureType.onTap,
  411. GestureType.onPanUpdateDownDirection,
  412. ],
  413. child: Scaffold(
  414. key: _scaffoldKey,
  415. appBar: AppBar(
  416. centerTitle: true,
  417. title: Text(plot_action_nursery),
  418. actions: _actionAppBar()),
  419. body: KeyboardDismisser(
  420. child: MultiBlocProvider(
  421. providers: [
  422. BlocProvider<ExpansionListBloc>(
  423. create: (context) => ExpansionListBloc(),
  424. ),
  425. BlocProvider<StatusAddFormBloc>(
  426. create: (context) => StatusAddFormBloc(),
  427. )
  428. ],
  429. child: Form(
  430. key: _formKey,
  431. autovalidate: _autoValidate,
  432. child: SingleChildScrollView(
  433. padding: EdgeInsets.all(8.0),
  434. child: Column(
  435. children: <Widget>[
  436. Container(
  437. width: double.infinity,
  438. child: Text(
  439. "Ngày thực hiện",
  440. style: TextStyle(
  441. color: Colors.black54, fontSize: 13.0),
  442. ),
  443. ),
  444. _btnExecuteTimePicker(),
  445. SizedBox(
  446. height: 8.0,
  447. ),
  448. Container(
  449. width: double.infinity,
  450. child: Text(
  451. "Tên giống",
  452. style: TextStyle(
  453. color: Colors.black54, fontSize: 13.0),
  454. ),
  455. ),
  456. _btnSelectSeed(),
  457. SizedBox(
  458. height: 8.0,
  459. ),
  460. _seedLengthField(),
  461. SizedBox(
  462. height: 8.0,
  463. ),
  464. _quantityField(),
  465. SizedBox(
  466. height: 8.0,
  467. ),
  468. _seedIncubationTimeField(),
  469. SizedBox(
  470. height: 8.0,
  471. ),
  472. _desciptionField(),
  473. SizedBox(
  474. height: 8.0,
  475. ),
  476. _btnAddWorker(),
  477. SizedBox(
  478. height: 8.0,
  479. ),
  480. _buildListAddWorker(),
  481. Container(child: Text("Them hinh anh")),
  482. ],
  483. ),
  484. ))))));
  485. @override
  486. void dispose() {
  487. _substrateController.dispose();
  488. _seedLengthController.dispose();
  489. _quantityController.dispose();
  490. _seedIncubationTimeController.dispose();
  491. _descriptionController.dispose();
  492. super.dispose();
  493. }
  494. }
  495. class ChangeSupply extends GetxController {
  496. Supply currentSupply;
  497. int selectedSupplyId;
  498. void initValue() {
  499. currentSupply = Supply();
  500. selectedSupplyId = -1;
  501. update();
  502. }
  503. void change(Supply supply) {
  504. currentSupply = supply;
  505. selectedSupplyId = supply.id;
  506. update();
  507. }
  508. }