Flutter app for Asset Management
25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

506 lines
24 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. // await Future.delayed(Duration(milliseconds: 300));
  212. String Address = prefs.getString(keyClass.hostAddress);
  213. util.showLoading(context,dissmissable: false);
  214. var result = await util.JsonDataPostRaw({}, "${Address??"https://asset.thamringroup.web.id"}/admin/getDbList");
  215. Navigator.pop(context);
  216. if(result['STATUS']==1){
  217. bool isClear = await clearData(context);
  218. if(isClear??false){
  219. String selected = result['DATA'][0];
  220. bool res =await showDialog(context: context,builder: (context)=>StatefulBuilder(
  221. builder: (context,setState)=>AlertDialog(
  222. title: Text('Pick Database'),
  223. content: DropdownButtonFormField(
  224. onChanged: (value){
  225. setState(() {
  226. selected = value;
  227. });
  228. },
  229. value: selected,
  230. items: new List<DropdownMenuItem<dynamic>>.from(result['DATA'].map((value){
  231. String showText = value;
  232. if(showText.length>30) showText = showText.substring(0,30);
  233. return DropdownMenuItem(
  234. child: Text(showText),
  235. value: value,
  236. );
  237. })),
  238. ),
  239. actions: <Widget>[
  240. FlatButton(
  241. onPressed: ()async{
  242. Navigator.pop(context,true);
  243. },
  244. child: Text('Get'),
  245. ),
  246. FlatButton(
  247. onPressed: ()async{
  248. Navigator.pop(context,false);
  249. },
  250. child: Text('Cancel'),
  251. )
  252. ],
  253. ),
  254. ));
  255. if(res??false){
  256. // util.showLoading(context,dissmissable: false);
  257. await prefs.setString(keyClass.dbName,selected);
  258. file_Trans_Handler trans = new file_Trans_Handler();
  259. await trans.downloadFile("assets.db", "${Address??"https://asset.thamringroup.web.id"}/admin/downloadDb/$selected");
  260. _dlulStream = trans.progress.listen((value)async {
  261. setState(() {
  262. progressDL = (value!=-1.0)?value:null;
  263. });
  264. if(value!=null&&value >= 1.0) {
  265. _dlulStream.cancel();
  266. progressDL = null;
  267. // setState(() {
  268. // lastDownload = DateTime.now().toIso8601String();
  269. // });
  270. // await prefs.setString(keyClass.lastDownload, lastDownload);
  271. // await DBHelper.database.insertUpdateValue(new valueTab(name: 'TGL_START',value: DateFormat('dd-MM-yyyy HH:mm:ss').format(DateTime.parse(lastDownload))));
  272. // await DBHelper.database.insertUpdateValue(new valueTab(name: 'TGL_STOCK_TAKING',value: DateFormat('dd-MM-yyyy').format(DateTime.parse(lastDownload))));
  273. // await DBHelper.database.closeDb();
  274. // var allUnits = await DBHelper.database.getAllAsset();
  275. // print('${allUnits.length} Units');
  276. util.showToast('ALERT','Data Downloaded');
  277. }
  278. if(value==-1.0){
  279. util.showToast('ALERT','Data Error ${trans.error}');
  280. }
  281. });
  282. // Navigator.pop(context);
  283. setState(() {
  284. });
  285. }
  286. }
  287. }
  288. else{
  289. await util.showToast("ERROR",result['ERROR']);
  290. }
  291. },
  292. child: Padding(
  293. padding: const EdgeInsets.only(left: 10,top:10,right: 5),
  294. child: Container(
  295. decoration: BoxDecoration(
  296. color: Colors.white,
  297. borderRadius: BorderRadius.circular(10)
  298. ),
  299. child: Column(
  300. mainAxisAlignment: MainAxisAlignment.center,
  301. children: <Widget>[
  302. Expanded(
  303. flex: 4,
  304. child: Container(alignment: Alignment.center,child: (progressDL==null)?Icon(Icons.add_to_home_screen,size: 100,color: Colors.blueGrey,):Stack(
  305. children: <Widget>[
  306. Container(width: 100,height: 100,child: CircularProgressIndicator(backgroundColor: Color(0xFFB4B4B4),valueColor:new AlwaysStoppedAnimation<Color>(Colors.blueGrey),value: progressDL,)),
  307. Container(width: 100,height: 100,alignment: Alignment.center,child: Text("${(progressDL*100).floor().toString()}%",style: TextStyle(color: Colors.blueGrey,fontWeight: FontWeight.bold,fontSize: 25),),)
  308. ],
  309. )),
  310. ),
  311. Flexible(
  312. flex: 2,
  313. child: Text('Get Data Master',style: TextStyle(color: Colors.blueGrey,fontSize: 18,fontWeight: FontWeight.bold),),
  314. ),
  315. ],
  316. ),
  317. ),
  318. ),
  319. ),
  320. Padding(
  321. padding: const EdgeInsets.only(left: 5,top:10,right: 10),
  322. child: Material(
  323. color: Colors.white,
  324. child: InkWell(
  325. onTap: ()async{
  326. await Future.delayed(Duration(milliseconds: 300));
  327. Directory documentsDirectory = await getApplicationDocumentsDirectory();
  328. String path = join(documentsDirectory.path, "assets.db");
  329. File db = File(path);
  330. if(db.existsSync())Navigator.pushNamed(context, '/stocking');
  331. else{
  332. util.showToast('Alert', 'Please download data master first');
  333. }
  334. },
  335. child: Container(
  336. decoration: BoxDecoration(
  337. borderRadius: BorderRadius.circular(10)
  338. ),
  339. child: Column(
  340. mainAxisAlignment: MainAxisAlignment.center,
  341. children: <Widget>[
  342. Expanded(
  343. flex: 4,
  344. child: Container(alignment: Alignment.center,child: Icon(Icons.aspect_ratio,size: 100,color: Colors.blueGrey,)),
  345. ),
  346. Flexible(
  347. flex: 2,
  348. child: Text('Start Stocking',style: TextStyle(color: Colors.blueGrey,fontSize: 18,fontWeight: FontWeight.bold),),
  349. ),
  350. ],
  351. ),
  352. ),
  353. ),
  354. ),
  355. ),
  356. InkWell(
  357. onTap: ()async{
  358. final file = File(
  359. "${(await getApplicationDocumentsDirectory()).path}/assets.db");
  360. if(file.existsSync()){
  361. TextEditingController sendingUser = new TextEditingController();
  362. sendingUser.text = prefs.getString(keyClass.user)??'';
  363. bool isUserDefined = await showDialog(context: context,
  364. barrierDismissible: false,
  365. builder: (context)=>AlertDialog(
  366. title: Text('Sender'),
  367. content: TextField(
  368. controller: sendingUser,
  369. ),
  370. actions: [
  371. FlatButton(
  372. child: Text('Send'),
  373. onPressed: ()async{
  374. if(sendingUser.text!='') Navigator.pop(context,true);
  375. else Navigator.pop(context,false);
  376. },
  377. )
  378. ],
  379. ));
  380. if(isUserDefined??false){
  381. prefs.setString(keyClass.user, sendingUser.text);
  382. util.showToast("ALERT",'Preparing Data');
  383. await DBHelper.database.closeDb();
  384. file_Trans_Handler trans = new file_Trans_Handler();
  385. util.showToast("ALERT",'Sending Data');
  386. setState(() {
  387. progress = 0;
  388. });
  389. trans.uploadFile("assets.db", "${prefs.getString(keyClass.hostAddress)??"https://asset.thamringroup.web.id"}/admin/uploadSqliteDb",sendingUser.text,context);
  390. _dlulStream = trans.progress.listen((value) async {
  391. setState(() {
  392. progress = (value!=-1.0)?value:null;
  393. });
  394. if(value!=null&&value >= 1.0) {
  395. if(trans.error==''&&trans.isFinish){
  396. _dlulStream.cancel();
  397. progress = null;
  398. util.showToast("SUCCESS",(trans.success!='')?trans.success:'Data uploaded');
  399. }
  400. }
  401. if(value==-1.0&&trans.isFinish){
  402. _dlulStream.cancel();
  403. progress = null;
  404. util.showToast("ERROR",'Data upload error. ${trans.error}');
  405. }
  406. });
  407. }
  408. else util.showToast("ALERT",'Sending user not filled');
  409. }
  410. else{
  411. util.showToast("ALERT",'No database file found');
  412. }
  413. },
  414. child: Padding(
  415. padding: const EdgeInsets.only(left: 10,top:10,right: 5),
  416. child: Container(
  417. decoration: BoxDecoration(
  418. color: Colors.white,
  419. borderRadius: BorderRadius.circular(10)
  420. ),
  421. child: Column(
  422. mainAxisAlignment: MainAxisAlignment.center,
  423. children: <Widget>[
  424. Expanded(
  425. flex: 4,
  426. child: Container(alignment: Alignment.center,child: (progress==null)?Icon(Icons.send,size: 100,color: Colors.blueGrey,):Stack(
  427. children: <Widget>[
  428. Container(width: 100,height: 100,child: CircularProgressIndicator(backgroundColor: Color(0xFFB4B4B4),valueColor:new AlwaysStoppedAnimation<Color>(Colors.blueGrey),value: progress,)),
  429. Container(width: 100,height: 100,alignment: Alignment.center,child: Text("${(progress*100).floor().toString()}%",style: TextStyle(color: Colors.blueGrey,fontWeight: FontWeight.bold,fontSize: 25),),)
  430. ],
  431. )),
  432. ),
  433. Flexible(
  434. flex: 2,
  435. child: Text('Send Data',style: TextStyle(color: Colors.blueGrey,fontSize: 18,fontWeight: FontWeight.bold),),
  436. ),
  437. ],
  438. ),
  439. ),
  440. ),
  441. ),
  442. InkWell(
  443. onTap: ()async{
  444. Directory documentsDirectory = await getApplicationDocumentsDirectory();
  445. String path = join(documentsDirectory.path, "assets.db");
  446. File db = File(path);
  447. if(db.existsSync()) await clearData(context);
  448. else util.showToast('Alert', 'No database file found');
  449. },
  450. child: Padding(
  451. padding: const EdgeInsets.only(left: 5,top:10,right: 10),
  452. child: Container(
  453. decoration: BoxDecoration(
  454. color: Colors.white,
  455. borderRadius: BorderRadius.circular(10)
  456. ),
  457. child: Column(
  458. mainAxisAlignment: MainAxisAlignment.center,
  459. children: <Widget>[
  460. Expanded(
  461. flex: 4,
  462. child: Container(alignment: Alignment.center,child: Icon(Icons.delete,size: 100,color: Colors.blueGrey,)),
  463. ),
  464. Flexible(
  465. flex: 2,
  466. child: Text('Clear Data',style: TextStyle(color: Colors.blueGrey,fontSize: 18,fontWeight: FontWeight.bold),),
  467. ),
  468. ],
  469. ),
  470. ),
  471. ),
  472. ),
  473. ],
  474. ),
  475. ),
  476. ),
  477. Flexible(
  478. flex: 1,
  479. child: Container(
  480. padding: EdgeInsets.all(8),
  481. alignment: Alignment.bottomRight,
  482. child: Column(
  483. crossAxisAlignment: CrossAxisAlignment.end,
  484. mainAxisAlignment: MainAxisAlignment.end,
  485. children: <Widget>[
  486. Text((prefs.getString(keyClass.dbName)!=null)?"Master Data : ${prefs.getString(keyClass.dbName)}":'',style: TextStyle(color: Colors.blueGrey),),
  487. Text('Connected to ${prefs.getString(keyClass.hostAddress)??'https://asset.thamringroup.web.id'}',style: TextStyle(color: Colors.blueGrey),),
  488. ],
  489. ),
  490. ),
  491. ),
  492. ],
  493. ),
  494. ),
  495. );
  496. }
  497. }