Flutter app for Asset Management
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 

552 строки
26 KiB

  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'dart:io';
  4. import 'package:assetstock/util/download_Upload_Handler.dart';
  5. import 'package:path/path.dart';
  6. import 'package:flutter/cupertino.dart';
  7. import 'package:flutter/material.dart';
  8. import 'package:path_provider/path_provider.dart';
  9. import 'main.dart';
  10. import 'util/prefsKey.dart';
  11. import 'util/dbHandler.dart';
  12. class Home extends StatefulWidget {
  13. Home({Key key}) : super(key: key);
  14. @override
  15. _HomeState createState() => _HomeState();
  16. }
  17. class _HomeState extends State<Home> {
  18. List<Widget> Menus = [];
  19. final hostAddress = new TextEditingController();
  20. StreamSubscription _dlulStream;
  21. double progress,progressDL;
  22. loadMenu()async{
  23. Menus.add(Padding(
  24. padding: const EdgeInsets.all(8.0),
  25. child: Container(
  26. decoration: BoxDecoration(
  27. color: Colors.white,
  28. borderRadius: BorderRadius.circular(5)
  29. ),
  30. child: Text('Get Data'),
  31. ),
  32. ));
  33. setState(() {
  34. });
  35. }
  36. @override
  37. void initState() {
  38. // TODO: implement initState
  39. super.initState();
  40. WidgetsBinding.instance.addPostFrameCallback((_) async {
  41. // await loadMenu();
  42. });
  43. }
  44. clearData(context)async{
  45. String errMsg;
  46. Directory documentsDirectory = await getApplicationDocumentsDirectory();
  47. String path = join(documentsDirectory.path, "assets.db");
  48. File db = File(path);
  49. if(db.existsSync()){
  50. bool result = await showDialog(context: context,builder: (context)=>WillPopScope(
  51. onWillPop: ()async{
  52. Navigator.pop(context,false);
  53. return false;
  54. },
  55. child: AlertDialog(
  56. title: Text('Clear Data ?'),
  57. content: Text('Proceed to clear any remaining units data on this device?'),
  58. actions: <Widget>[
  59. FlatButton(
  60. child: Text('Proceed'),
  61. onPressed: ()async{
  62. util.showLoading(context);
  63. await Future.sync(()async{
  64. await prefs.remove(keyClass.dbName);
  65. // await prefs.setString(keyClass.lastDownload, null);
  66. // await prefs.setString(keyClass.lastUpload, null);
  67. // await prefs.setString(keyClass.targetProccess, null);
  68. setState(() {
  69. // lastUpload = '';
  70. // lastDownload = '';
  71. // timeString = '';
  72. });
  73. // var result = await DBHelper.database.deleteAll();
  74. // if(result!=null) {
  75. // if(result!=null){
  76. try{
  77. await DBHelper.database.closeDb();
  78. db.deleteSync();
  79. }
  80. catch(e){
  81. print(e);
  82. util.showToast('ERROR','Failed to delete database file');
  83. }
  84. // }
  85. // else{
  86. // errMsg = 'Failed to clear unit data';
  87. // }
  88. // }
  89. // else{
  90. // errMsg = 'Failed to clear unit data';
  91. // }
  92. });
  93. Navigator.pop(context);
  94. Navigator.pop(context,true);
  95. util.showToast(errMsg==null?"SUCCESS":"ERROR",errMsg??'Data Cleared');
  96. },
  97. ),
  98. FlatButton(
  99. child: Text('Cancel'),
  100. onPressed: (){Navigator.pop(context,false);},
  101. )
  102. ],
  103. ),
  104. ));
  105. return result;
  106. }
  107. else return true;
  108. }
  109. @override
  110. Widget build(BuildContext context) {
  111. return Scaffold(
  112. floatingActionButton: Padding(
  113. padding: const EdgeInsets.only(bottom:45.0),
  114. child: FloatingActionButton(
  115. onPressed: ()async{
  116. Directory documentsDirectory = await getApplicationDocumentsDirectory();
  117. String path = join(documentsDirectory.path, "assets.db");
  118. File db = File(path);
  119. if(db.existsSync()){
  120. Navigator.pushNamed(context, '/logs');
  121. }
  122. else{
  123. util.showToast("ALERT", 'Get data Master first');
  124. }
  125. },
  126. child: Icon(Icons.description,size: 30,),
  127. ),
  128. ),
  129. body: Container(
  130. color: Colors.grey.withOpacity(0.3),
  131. child:
  132. // (Menus.length==0)?Container(alignment: Alignment.center,
  133. // child: Text('Empty',
  134. // style: TextStyle(fontSize: 20,color: Colors.black38,fontWeight: FontWeight.bold),),)
  135. // :
  136. Column(
  137. children: <Widget>[
  138. Expanded(
  139. flex: 1,
  140. child: Container(
  141. padding: const EdgeInsets.only(left: 10,top:10,right: 5),
  142. alignment: Alignment.bottomCenter,
  143. child: Row(
  144. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  145. children: <Widget>[
  146. Row(
  147. children: <Widget>[
  148. Icon(Icons.dashboard,color: Colors.blueGrey,size: 20,),
  149. SizedBox(width: 5,),
  150. Text('Menu')
  151. ],
  152. ),
  153. PopupMenuButton(
  154. itemBuilder: (context)=>[
  155. PopupMenuItem(
  156. value: "changeAddress",
  157. child: Row(
  158. children: <Widget>[
  159. Icon(Icons.network_wifi,color: Colors.blueGrey,),
  160. SizedBox(width: 10,),
  161. Text('Change Host Address',style: TextStyle(color: Colors.blueGrey,fontWeight: FontWeight.w500),)
  162. ],
  163. ),
  164. )
  165. ],
  166. onSelected: (value)async{
  167. if(value == "changeAddress"){
  168. hostAddress.text = prefs.getString(keyClass.hostAddress)??'https://asset.thamringroup.web.id';
  169. await showDialog(context: context,builder: (context)=>AlertDialog(
  170. title: Text('Set IP Address'),
  171. content: TextField(
  172. controller: hostAddress,
  173. onSubmitted: (value){
  174. prefs.setString(keyClass.hostAddress,(value=='')?'https://asset.thamringroup.web.id':value);
  175. Navigator.pop(context);
  176. },
  177. ),
  178. actions: <Widget>[
  179. FlatButton(
  180. child: Text('OK'),
  181. onPressed: (){
  182. prefs.setString(keyClass.hostAddress,(hostAddress.text=='')?'https://asset.thamringroup.web.id':hostAddress.text);
  183. Navigator.pop(context);
  184. },
  185. )
  186. ],
  187. ));
  188. setState(() {
  189. });
  190. }
  191. },
  192. child: Padding(
  193. padding: const EdgeInsets.all(8.0),
  194. child: Icon(Icons.clear_all,color: Colors.blueGrey,size: 20,),
  195. ),
  196. ),
  197. ],
  198. ),
  199. ),
  200. ),
  201. Flexible(
  202. flex: 10,
  203. child: Container(
  204. alignment: Alignment.topCenter,
  205. child: GridView.count(
  206. padding: EdgeInsets.all(0),
  207. crossAxisCount: 2,
  208. children: [
  209. InkWell(
  210. onTap: ()async{
  211. String Address = prefs.getString(keyClass.hostAddress);
  212. // await Future.delayed(Duration(milliseconds: 300));
  213. util.showLoading(context,dissmissable: false);
  214. var bUnits = await util.JsonDataPostRaw({}, "${Address??"https://asset.thamringroup.web.id"}/admin/getBisnisList",timeout: true,duration: 5);
  215. Navigator.pop(context);
  216. if(bUnits["STATUS"]==1){
  217. var selectedBisnis= bUnits["DATA"][0]["id"];
  218. var bisnisPicked = await showDialog(context: context,builder: (context)=>StatefulBuilder(
  219. builder: (context,setState)=>AlertDialog(
  220. title: Text('Pick Bisnis Unit'),
  221. content: DropdownButtonFormField(
  222. onChanged: (value)async{
  223. setState(() {
  224. selectedBisnis = value;
  225. });
  226. },
  227. value: selectedBisnis,
  228. items: new List<DropdownMenuItem<dynamic>>.from(bUnits['DATA'].map((value){
  229. String showText = value["name"];
  230. if(showText.length>30) showText = showText.substring(0,30);
  231. return DropdownMenuItem(
  232. child: Text(showText),
  233. value: value["id"],
  234. );
  235. })),
  236. ),
  237. actions: <Widget>[
  238. FlatButton(
  239. onPressed: ()async{
  240. Navigator.pop(context,true);
  241. },
  242. child: Text('Next'),
  243. ),
  244. FlatButton(
  245. onPressed: ()async{
  246. Navigator.pop(context,false);
  247. },
  248. child: Text('Cancel'),
  249. )
  250. ],
  251. ),
  252. ));
  253. if(bisnisPicked??false){
  254. util.showLoading(context,dissmissable: false);
  255. var result = await util.JsonDataPostRaw({"bUnit":selectedBisnis}, "${Address??"https://asset.thamringroup.web.id"}/admin/getrefDbList");
  256. Navigator.pop(context);
  257. if(result['STATUS']==1){
  258. bool isClear = await clearData(context);
  259. if(isClear??false){
  260. String selected = result['DATA'][0]["fullName"];
  261. bool res =await showDialog(context: context,builder: (context)=>StatefulBuilder(
  262. builder: (context,setState)=>AlertDialog(
  263. title: Text('Pick Database'),
  264. content: DropdownButtonFormField(
  265. onChanged: (value){
  266. setState(() {
  267. selected = value;
  268. });
  269. },
  270. value: selected,
  271. items: new List<DropdownMenuItem<dynamic>>.from(result['DATA'].map((value){
  272. String showText = value["name"];
  273. if(showText.length>20) showText = showText.substring(0,20);
  274. return DropdownMenuItem(
  275. child: Text(showText),
  276. value: value["fullName"],
  277. );
  278. })),
  279. ),
  280. actions: <Widget>[
  281. FlatButton(
  282. onPressed: ()async{
  283. Navigator.pop(context,true);
  284. },
  285. child: Text('Get'),
  286. ),
  287. FlatButton(
  288. onPressed: ()async{
  289. Navigator.pop(context,false);
  290. },
  291. child: Text('Cancel'),
  292. )
  293. ],
  294. ),
  295. ));
  296. if(res??false){
  297. // util.showLoading(context,dissmissable: false);
  298. await prefs.setString(keyClass.dbName,selected);
  299. file_Trans_Handler trans = new file_Trans_Handler();
  300. await trans.downloadFile("assets.db", "${Address??"https://asset.thamringroup.web.id"}/admin/downloadDb/$selectedBisnis/$selected");
  301. _dlulStream = trans.progress.listen((value)async {
  302. setState(() {
  303. progressDL = (value!=-1.0)?value:null;
  304. });
  305. if(value!=null&&value >= 1.0) {
  306. _dlulStream.cancel();
  307. progressDL = null;
  308. // setState(() {
  309. // lastDownload = DateTime.now().toIso8601String();
  310. // });
  311. // await prefs.setString(keyClass.lastDownload, lastDownload);
  312. // await DBHelper.database.insertUpdateValue(new valueTab(name: 'TGL_START',value: DateFormat('dd-MM-yyyy HH:mm:ss').format(DateTime.parse(lastDownload))));
  313. // await DBHelper.database.insertUpdateValue(new valueTab(name: 'TGL_STOCK_TAKING',value: DateFormat('dd-MM-yyyy').format(DateTime.parse(lastDownload))));
  314. // await DBHelper.database.closeDb();
  315. // var allUnits = await DBHelper.database.getAllAsset();
  316. // print('${allUnits.length} Units');
  317. util.showToast('ALERT','Data Downloaded');
  318. }
  319. if(value==-1.0){
  320. util.showToast('ALERT','Data Error ${trans.error}');
  321. }
  322. });
  323. // Navigator.pop(context);
  324. setState(() {
  325. });
  326. }
  327. }
  328. }
  329. else{
  330. await util.showToast("ERROR",result['ERROR']??"Database tidak ditemukan");
  331. }
  332. }
  333. }
  334. else{
  335. await util.showToast("ERROR",bUnits['DATA']??'not responding');
  336. }
  337. },
  338. child: Padding(
  339. padding: const EdgeInsets.only(left: 10,top:10,right: 5),
  340. child: Container(
  341. decoration: BoxDecoration(
  342. color: Colors.white,
  343. borderRadius: BorderRadius.circular(10)
  344. ),
  345. child: Column(
  346. mainAxisAlignment: MainAxisAlignment.center,
  347. children: <Widget>[
  348. Expanded(
  349. flex: 4,
  350. child: Container(alignment: Alignment.center,child: (progressDL==null)?Icon(Icons.add_to_home_screen,size: 100,color: Colors.blueGrey,):Stack(
  351. children: <Widget>[
  352. Container(width: 100,height: 100,child: CircularProgressIndicator(backgroundColor: Color(0xFFB4B4B4),valueColor:new AlwaysStoppedAnimation<Color>(Colors.blueGrey),value: progressDL,)),
  353. Container(width: 100,height: 100,alignment: Alignment.center,child: Text("${(progressDL*100).floor().toString()}%",style: TextStyle(color: Colors.blueGrey,fontWeight: FontWeight.bold,fontSize: 25),),)
  354. ],
  355. )),
  356. ),
  357. Flexible(
  358. flex: 2,
  359. child: Text('Get Data Master',style: TextStyle(color: Colors.blueGrey,fontSize: 18,fontWeight: FontWeight.bold),),
  360. ),
  361. ],
  362. ),
  363. ),
  364. ),
  365. ),
  366. Padding(
  367. padding: const EdgeInsets.only(left: 5,top:10,right: 10),
  368. child: Material(
  369. color: Colors.white,
  370. child: InkWell(
  371. onTap: ()async{
  372. await Future.delayed(Duration(milliseconds: 300));
  373. Directory documentsDirectory = await getApplicationDocumentsDirectory();
  374. String path = join(documentsDirectory.path, "assets.db");
  375. File db = File(path);
  376. if(db.existsSync()) Navigator.pushNamed(context, '/stocking');
  377. else{
  378. util.showToast('Alert', 'Please download data master first');
  379. }
  380. },
  381. child: Container(
  382. decoration: BoxDecoration(
  383. borderRadius: BorderRadius.circular(10)
  384. ),
  385. child: Column(
  386. mainAxisAlignment: MainAxisAlignment.center,
  387. children: <Widget>[
  388. Expanded(
  389. flex: 4,
  390. child: Container(alignment: Alignment.center,child: Icon(Icons.aspect_ratio,size: 100,color: Colors.blueGrey,)),
  391. ),
  392. Flexible(
  393. flex: 2,
  394. child: Text('Start Stocking',style: TextStyle(color: Colors.blueGrey,fontSize: 18,fontWeight: FontWeight.bold),),
  395. ),
  396. ],
  397. ),
  398. ),
  399. ),
  400. ),
  401. ),
  402. InkWell(
  403. onTap: ()async{
  404. final file = File(
  405. "${(await getApplicationDocumentsDirectory()).path}/assets.db");
  406. if(file.existsSync()){
  407. TextEditingController sendingUser = new TextEditingController();
  408. sendingUser.text = prefs.getString(keyClass.user)??'';
  409. bool isUserDefined = await showDialog(context: context,
  410. barrierDismissible: false,
  411. builder: (context)=>AlertDialog(
  412. title: Text('Sender'),
  413. content: TextField(
  414. controller: sendingUser,
  415. ),
  416. actions: [
  417. FlatButton(
  418. child: Text('Send'),
  419. onPressed: ()async{
  420. if(sendingUser.text!='') Navigator.pop(context,true);
  421. else Navigator.pop(context,false);
  422. },
  423. )
  424. ],
  425. ));
  426. if(isUserDefined??false){
  427. prefs.setString(keyClass.user, sendingUser.text);
  428. util.showToast("ALERT",'Preparing Data');
  429. await DBHelper.database.closeDb();
  430. file_Trans_Handler trans = new file_Trans_Handler();
  431. util.showToast("ALERT",'Sending Data');
  432. setState(() {
  433. progress = 0;
  434. });
  435. trans.uploadFile("assets.db", "${prefs.getString(keyClass.hostAddress)??"https://asset.thamringroup.web.id"}/admin/uploadSqliteDb",sendingUser.text,context);
  436. _dlulStream = trans.progress.listen((value) async {
  437. setState(() {
  438. progress = (value!=-1.0)?value:null;
  439. });
  440. if(value!=null&&value >= 1.0) {
  441. if(trans.error==''&&trans.isFinish){
  442. _dlulStream.cancel();
  443. progress = null;
  444. util.showToast("SUCCESS",(trans.success!='')?trans.success:'Data uploaded');
  445. }
  446. }
  447. if(value==-1.0&&trans.isFinish){
  448. _dlulStream.cancel();
  449. progress = null;
  450. util.showToast("ERROR",'Data upload error. ${trans.error}');
  451. }
  452. });
  453. }
  454. else util.showToast("ALERT",'Sending user not filled');
  455. }
  456. else{
  457. util.showToast("ALERT",'No database file found');
  458. }
  459. },
  460. child: Padding(
  461. padding: const EdgeInsets.only(left: 10,top:10,right: 5),
  462. child: Container(
  463. decoration: BoxDecoration(
  464. color: Colors.white,
  465. borderRadius: BorderRadius.circular(10)
  466. ),
  467. child: Column(
  468. mainAxisAlignment: MainAxisAlignment.center,
  469. children: <Widget>[
  470. Expanded(
  471. flex: 4,
  472. child: Container(alignment: Alignment.center,child: (progress==null)?Icon(Icons.send,size: 100,color: Colors.blueGrey,):Stack(
  473. children: <Widget>[
  474. Container(width: 100,height: 100,child: CircularProgressIndicator(backgroundColor: Color(0xFFB4B4B4),valueColor:new AlwaysStoppedAnimation<Color>(Colors.blueGrey),value: progress,)),
  475. Container(width: 100,height: 100,alignment: Alignment.center,child: Text("${(progress*100).floor().toString()}%",style: TextStyle(color: Colors.blueGrey,fontWeight: FontWeight.bold,fontSize: 25),),)
  476. ],
  477. )),
  478. ),
  479. Flexible(
  480. flex: 2,
  481. child: Text('Send Data',style: TextStyle(color: Colors.blueGrey,fontSize: 18,fontWeight: FontWeight.bold),),
  482. ),
  483. ],
  484. ),
  485. ),
  486. ),
  487. ),
  488. InkWell(
  489. onTap: ()async{
  490. Directory documentsDirectory = await getApplicationDocumentsDirectory();
  491. String path = join(documentsDirectory.path, "assets.db");
  492. File db = File(path);
  493. if(db.existsSync()) await clearData(context);
  494. else util.showToast('Alert', 'No database file found');
  495. },
  496. child: Padding(
  497. padding: const EdgeInsets.only(left: 5,top:10,right: 10),
  498. child: Container(
  499. decoration: BoxDecoration(
  500. color: Colors.white,
  501. borderRadius: BorderRadius.circular(10)
  502. ),
  503. child: Column(
  504. mainAxisAlignment: MainAxisAlignment.center,
  505. children: <Widget>[
  506. Expanded(
  507. flex: 4,
  508. child: Container(alignment: Alignment.center,child: Icon(Icons.delete,size: 100,color: Colors.blueGrey,)),
  509. ),
  510. Flexible(
  511. flex: 2,
  512. child: Text('Clear Data',style: TextStyle(color: Colors.blueGrey,fontSize: 18,fontWeight: FontWeight.bold),),
  513. ),
  514. ],
  515. ),
  516. ),
  517. ),
  518. ),
  519. ],
  520. ),
  521. ),
  522. ),
  523. Flexible(
  524. flex: 2,
  525. child: Container(
  526. padding: EdgeInsets.all(8),
  527. alignment: Alignment.bottomRight,
  528. child: Column(
  529. crossAxisAlignment: CrossAxisAlignment.end,
  530. mainAxisAlignment: MainAxisAlignment.end,
  531. children: <Widget>[
  532. Text((prefs.getString(keyClass.dbName)!=null)?"Master Data : ${prefs.getString(keyClass.dbName)}":'',style: TextStyle(color: Colors.blueGrey),),
  533. Text('Connected to ${prefs.getString(keyClass.hostAddress)??'https://asset.thamringroup.web.id'}',style: TextStyle(color: Colors.blueGrey),),
  534. ],
  535. ),
  536. ),
  537. ),
  538. ],
  539. ),
  540. ),
  541. );
  542. }
  543. }