flutter app untuk unitstock
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.
 
 
 
 
 

410 line
21 KiB

  1. import 'dart:async';
  2. import 'dart:typed_data';
  3. import 'package:flutter/services.dart';
  4. import 'main.dart';
  5. import 'package:flutter/cupertino.dart';
  6. import 'package:flutter/material.dart';
  7. import 'package:unitstocks/unit_details.dart';
  8. import 'Util/DBHelper.dart';
  9. import 'Util/UnitModel.dart';
  10. import 'Util/Util.dart';
  11. import 'Util/photo_viewer.dart';
  12. import 'package:barcode_scan2/barcode_scan2.dart';
  13. class Stocking extends StatefulWidget {
  14. Stocking({Key key}) : super(key: key);
  15. @override
  16. _StockingState createState() => _StockingState();
  17. }
  18. class _StockingState extends State<Stocking> with SingleTickerProviderStateMixin {
  19. List<Unit> unitsRef = [];
  20. List<blobImage> Blobs = [];
  21. List<blobImage> BlobsRef = [];
  22. bool completed = false;
  23. Util util = new Util();
  24. int totalUnit = 0;
  25. final search_controller = new TextEditingController();
  26. bool hideAppbar = false;
  27. String search = '';
  28. loadUnit()async{
  29. print('loading units');
  30. Blobs.clear();
  31. BlobsRef.clear();
  32. await DBHelper.database.closeDb();
  33. // Units = (search=='')?await DBHelper.database.getAllInsertUnits():await DBHelper.database.searchAllInsertUnits(search.toUpperCase());
  34. unitsRef = (search=='')?await DBHelper.database.getAllUnits(inserted: completed):await DBHelper.database.searchAllUnits(search.toUpperCase(),inserted: completed);
  35. // totalUnit = await DBHelper.database.getCount();
  36. // for (int i = 0;i<Units.length;i++){
  37. // var blob = await DBHelper.database.getBlobImage(Units[i].id);
  38. // Blobs.add(blob);
  39. // }
  40. for (int i = 0;i<unitsRef.length;i++){
  41. var blob = (unitsRef[i].mesin!=null)?await DBHelper.database.getBlobImage(unitsRef[i].mesin):null;
  42. BlobsRef.add(blob);
  43. }
  44. print([BlobsRef.length,unitsRef.length]);
  45. setState(() {
  46. });
  47. }
  48. Map<Function, Timer> _timeouts = {};
  49. void debounce(Duration timeout, Function target, [List arguments = const []]) {
  50. if (_timeouts.containsKey(target)) {
  51. _timeouts[target].cancel();
  52. }
  53. Timer timer = Timer(timeout, () {
  54. Function.apply(target, arguments);
  55. });
  56. _timeouts[target] = timer;
  57. }
  58. void _onChanged(String val)async {
  59. search = search_controller.text;
  60. await loadUnit();
  61. }
  62. Future scan() async {
  63. try {
  64. search = '';
  65. setState(() => search_controller.text = search);
  66. ScanResult result = await BarcodeScanner.scan();
  67. String barcode = result.rawContent;
  68. setState(() => this.search = barcode);
  69. } on PlatformException catch (e) {
  70. if (e.code == BarcodeScanner.cameraAccessDenied) {
  71. util.showFlushbar(context, 'The user did not grant the camera permission!',color: Colors.red);
  72. setState(() {
  73. this.search = '';
  74. });
  75. } else {
  76. util.showFlushbar(context, 'Unknown error: $e',color: Colors.red);
  77. setState(() => this.search = '');
  78. }
  79. } on FormatException {
  80. setState(() => this.search =
  81. '');
  82. } catch (e) {
  83. util.showFlushbar(context, 'Unknown error: $e',color: Colors.red);
  84. setState(() => this.search = '');
  85. }
  86. setState(() => search_controller.text = search);
  87. }
  88. @override
  89. void initState() {
  90. // TODO: implement initState
  91. super.initState();
  92. // _tabBarcontroller = new TabController(length: 1, vsync:this);
  93. WidgetsBinding.instance.addPostFrameCallback((_) async {
  94. util.showLoading(context);
  95. await Future.sync(()async{await loadUnit();});
  96. Navigator.pop(context);
  97. if(locationStream==null)await util.streamLocation(context);
  98. else {
  99. if(locationStream.isPaused) locationStream.resume();
  100. }
  101. // setState(() {
  102. // unitsRef.add(new Unit(flag: 'False',tipe: "sdasdas",id: 2,mesin: "sdfasdas",kode: "dasdas",rangka: "asdasd",tahun: "2020",warna: "MERAH",state: "OnChanne;"));
  103. // unitsRef.add(new Unit(flag: 'False',tipe: "sdasdas",id: 2,mesin: "sdfasdas",kode: "dasdas",rangka: "asdasd",tahun: "2020",warna: "MERAH",state: "OnChanne;"));
  104. // unitsRef.add(new Unit(flag: 'False',tipe: "sdasdas",id: 2,mesin: "sdfasdas",kode: "dasdas",rangka: "asdasd",tahun: "2020",warna: "MERAH",state: "OnChanne;"));
  105. // unitsRef.add(new Unit(flag: 'False',tipe: "sdasdas",id: 2,mesin: "sdfasdas",kode: "dasdas",rangka: "asdasd",tahun: "2020",warna: "MERAH",state: "OnChanne;"));
  106. // unitsRef.add(new Unit(flag: 'False',tipe: "sdasdas",id: 2,mesin: "sdfasdas",kode: "dasdas",rangka: "asdasd",tahun: "2020",warna: "MERAH",state: "OnChanne;"));
  107. // });
  108. });
  109. }
  110. @override
  111. void dispose() {
  112. // TODO: implement dispose
  113. super.dispose();
  114. print('LocationStream paused');
  115. if(!locationStream.isPaused)locationStream.pause();
  116. }
  117. @override
  118. Widget build(BuildContext context) {
  119. return WillPopScope(
  120. onWillPop: ()async{
  121. if(hideAppbar) {
  122. setState(() {
  123. hideAppbar=false;
  124. search = '';
  125. search_controller.text = '';
  126. });
  127. await loadUnit();
  128. return false;
  129. }
  130. else {
  131. return true;
  132. }
  133. },
  134. child: Scaffold(
  135. appBar: (hideAppbar)?
  136. AppBar(
  137. backgroundColor: Colors.white,
  138. leading: GestureDetector(
  139. onTap:()async{
  140. setState(() {
  141. hideAppbar=false;
  142. search = '';
  143. search_controller.text = '';
  144. });
  145. await loadUnit();
  146. },child: Container(width: 20,child: Icon(Icons.arrow_back,color:Colors.grey))),
  147. title: Container(
  148. color: Colors.white,
  149. child: TextFormField(
  150. maxLines: 1,
  151. controller: search_controller,
  152. onChanged: (val) => debounce(const Duration(milliseconds: 300), _onChanged, [val]),
  153. // onChanged: (value)async{
  154. // search = search_controller.text;
  155. // await loadUnit();
  156. // },
  157. decoration: InputDecoration.collapsed(
  158. hintText: 'Search..',
  159. ),
  160. ),
  161. ),
  162. actions: <Widget>[
  163. TextButton(
  164. onPressed: ()async{await scan();await loadUnit();},
  165. child: Icon(Icons.select_all,color:Colors.grey),
  166. )
  167. ],
  168. )
  169. :null,
  170. // AppBar(
  171. // backgroundColor: Colors.indigo.withOpacity(0.8),
  172. // title: Text('Unit Stocking'),
  173. // actions: <Widget>[
  174. // IconButton(
  175. // icon: Icon(Icons.search,color:Colors.white),
  176. // onPressed: (){
  177. // setState(() {
  178. // hideAppbar = true;
  179. // });
  180. // },
  181. // ),
  182. // ],
  183. // ),
  184. body: Column(
  185. children: <Widget>[
  186. (hideAppbar)?Container():SizedBox(height: MediaQuery.of(context).size.height/25,),
  187. Expanded(
  188. child:Stack(
  189. children: <Widget>[
  190. Container(
  191. alignment: Alignment.topRight,
  192. child: (unitsRef.isEmpty)
  193. ? Container(padding: EdgeInsets.only(top: 10,left: 10,right: 10),
  194. child: Row(
  195. crossAxisAlignment: CrossAxisAlignment.start,
  196. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  197. children: <Widget>[
  198. Row(
  199. children: <Widget>[
  200. Checkbox(
  201. value: completed,
  202. onChanged: (value)async{
  203. setState(() {
  204. completed = value;
  205. });
  206. await loadUnit();
  207. },
  208. ),
  209. Text('Completed')
  210. ],
  211. ),
  212. (completed||hideAppbar)?Container():Row(
  213. mainAxisAlignment: MainAxisAlignment.end,
  214. children: <Widget>[
  215. Text('Unit : ',style: TextStyle(color: Colors.grey,fontSize: 15),),
  216. Text('${(unitsRef.where((element) => element.flag=='TRUE').length==unitsRef.length)?'Done':'${unitsRef.length-unitsRef.where((element) => element.flag=='TRUE').length}'}',style: TextStyle(color: (unitsRef.length==unitsRef.where((element) => element.flag=='TRUE').length)?Colors.green:Colors.black,fontWeight: FontWeight.bold,fontSize: 16),),
  217. Text(!(unitsRef.length==unitsRef.where((element) => element.flag=='TRUE').length)?' of':'',style: TextStyle(color: Colors.grey,fontSize: 15),),
  218. Text(!(unitsRef.length==unitsRef.where((element) => element.flag=='TRUE').length)?' ${unitsRef.length}':'',style: TextStyle(color: Colors.black,fontSize: 16,fontWeight: FontWeight.bold,),),
  219. ],
  220. ),
  221. ],
  222. ),)
  223. :ListView.builder(
  224. padding: EdgeInsets.only(bottom: 10),
  225. itemCount: unitsRef.length,
  226. shrinkWrap: false,
  227. itemBuilder: (context,index){
  228. Uint8List display;
  229. display = unitsRef[index].flag=='FALSE'?null:(BlobsRef.length==unitsRef.length)?BlobsRef[index].blob_file:null;
  230. return Column(
  231. children: <Widget>[
  232. (index==0)?Container(padding: EdgeInsets.only(top: 10,left: 10,right: 10),alignment: Alignment.centerRight,
  233. child: Row(
  234. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  235. children: <Widget>[
  236. Row(
  237. children: <Widget>[
  238. Checkbox(
  239. value: completed,
  240. onChanged: (value)async{
  241. setState(() {
  242. completed = value;
  243. });
  244. await loadUnit();
  245. },
  246. ),
  247. Text('Completed')
  248. ],
  249. ),
  250. (completed||hideAppbar)?Container():Row(
  251. mainAxisAlignment: MainAxisAlignment.end,
  252. children: <Widget>[
  253. Text('Unit : ',style: TextStyle(color: Colors.grey,fontSize: 15),),
  254. Text('${(unitsRef.where((element) => element.flag=='TRUE').length==unitsRef.length)?'Done':'${unitsRef.length-unitsRef.where((element) => element.flag=='TRUE').length}'}',style: TextStyle(color: (unitsRef.length==unitsRef.where((element) => element.flag=='TRUE').length)?Colors.green:Colors.black,fontWeight: FontWeight.bold,fontSize: 16),),
  255. Text(!(unitsRef.length==unitsRef.where((element) => element.flag=='TRUE').length)?' of':'',style: TextStyle(color: Colors.grey,fontSize: 15),),
  256. Text(!(unitsRef.length==unitsRef.where((element) => element.flag=='TRUE').length)?' ${unitsRef.length}':'',style: TextStyle(color: Colors.black,fontSize: 16,fontWeight: FontWeight.bold,),),
  257. ],
  258. ),
  259. ],
  260. ),):Container(),
  261. Padding(
  262. padding: const EdgeInsets.only(left:10,right: 10,top: 10),
  263. child: Container(
  264. padding: EdgeInsets.all(5.0),
  265. decoration: BoxDecoration(
  266. borderRadius: BorderRadius.circular(5),
  267. color: Colors.white,
  268. boxShadow: [
  269. BoxShadow(
  270. color: Colors.grey,
  271. blurRadius: 5.0, // has the effect of softening the shadow
  272. spreadRadius: 2.0, // has the effect of extending the shadow
  273. offset: Offset(
  274. 00.0, // horizontal, move right 10
  275. 2.0, // vertical, move down 10
  276. ),
  277. )
  278. ],
  279. border: Border.all(color: Colors.grey.withOpacity(0.5)),
  280. ),
  281. child:Row(
  282. children: <Widget>[
  283. Expanded(
  284. flex: 3,
  285. child: InkWell(
  286. onTap: ()async{
  287. // if(display!=null)Navigator.push(context, MaterialPageRoute(builder: (context) => PhotoViewer(Blobs[index].blob_file,id: Blobs[index].blob_id.toString(),edit: false,jenis: Blobs[index].jenis,)));
  288. if(display==null){
  289. var result = await Navigator.push(
  290. context,
  291. MaterialPageRoute(
  292. builder: (context) => UnitDetails(unit: unitsRef[index],),
  293. ),
  294. );
  295. if(result!=null){
  296. util.showLoading(context);
  297. await loadUnit();
  298. Navigator.pop(context);
  299. }
  300. }
  301. else{
  302. await Navigator.push(context, MaterialPageRoute(builder: (context) => PhotoViewer(display,id: unitsRef[index].id.toString(),jenis: '',edit: false,)));
  303. }
  304. },
  305. child: Hero(tag: unitsRef[index].id,child: Padding(
  306. padding: EdgeInsets.only(right: 10),
  307. child: Container(width: 100,height: 100,alignment: Alignment.center,child:(display==null)?Icon(Icons.crop_original,color: Colors.white,size: 80,):null,
  308. decoration: BoxDecoration(
  309. color: Colors.grey.withOpacity(0.5),
  310. image: (display!=null)?DecorationImage(
  311. image: MemoryImage(display),fit: BoxFit.cover,):null,)),
  312. )),
  313. )),
  314. Expanded(
  315. flex: 7,
  316. child: InkWell(
  317. onTap: ()async{
  318. var result;
  319. // if(display!=null) {
  320. // result = await Navigator.push(
  321. // context,
  322. // MaterialPageRoute(
  323. // builder: (context) => UnitDetails(idInsert: unitsRef[index].mesin_id,),
  324. // ),
  325. // );
  326. // }
  327. // if(display==null){
  328. result = await Navigator.push(
  329. context,
  330. MaterialPageRoute(
  331. builder: (context) => UnitDetails(unit: unitsRef[index],),
  332. ),
  333. );
  334. // }
  335. if(result!=null){
  336. util.showLoading(context);
  337. await loadUnit();
  338. Navigator.pop(context);
  339. }
  340. },
  341. child: SingleChildScrollView(
  342. scrollDirection: Axis.horizontal,
  343. child: Column(
  344. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  345. crossAxisAlignment: CrossAxisAlignment.start,
  346. children: <Widget>[
  347. Text('Rangka : ${unitsRef[index].rangka}'),
  348. Divider(height: 10,),
  349. Text('Tipe : ${unitsRef[index].tipe}'),
  350. Divider(height: 10,),
  351. Row(
  352. children: <Widget>[
  353. // Container(width: MediaQuery.of(context).size.width*0.35,child: Text('State : ${unitsRef[index].state}')),
  354. // Container(width: MediaQuery.of(context).size.width*0.5,child: Text('Tipe : ${unitsRef[index].tipe}',style: TextStyle(fontSize: 12),)),
  355. Text('Timestamp : ${unitsRef[index].timestamp}'),
  356. ],
  357. ),
  358. Divider(height: 10,),
  359. Row(
  360. children: <Widget>[
  361. Container(width: MediaQuery.of(context).size.width*0.35,child: Text('Warna : ${unitsRef[index].warna}')),
  362. Text('State : ${unitsRef[index].state}'),
  363. ],
  364. )
  365. ],
  366. ),
  367. ),
  368. )),
  369. ],
  370. )),
  371. ),
  372. ],
  373. );
  374. },
  375. ),
  376. ),
  377. ],
  378. ),
  379. ),
  380. ],
  381. ),
  382. floatingActionButton: FloatingActionButton(
  383. backgroundColor: Colors.indigo.withOpacity(0.8),
  384. onPressed: ()async{
  385. setState(() {
  386. hideAppbar = !(hideAppbar??false);
  387. });
  388. // var result = await Navigator.push(context, MaterialPageRoute(builder: (context)=>UnitDetails(unit: new Unit(flag: 'FALSE'),)));
  389. // if(result!=null){
  390. // util.showLoading(context);
  391. // await loadUnit();
  392. // Navigator.pop(context);
  393. // }
  394. },
  395. child: Icon(Icons.search,color:Colors.white),
  396. ),
  397. ),
  398. );
  399. }
  400. }