@@ -28,14 +28,21 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" | |||||
protobuf { | protobuf { | ||||
protoc { | protoc { | ||||
artifact = 'com.google.protobuf:protoc:3.8.0' | |||||
if (osdetector.os == "osx") { | |||||
artifact = 'com.google.protobuf:protoc:3.19.1:osx-x86_64' | |||||
} else { | |||||
artifact = 'com.google.protobuf:protoc:3.19.1' | |||||
} | |||||
// artifact = 'com.google.protobuf:protoc:3.8.0' | |||||
} | } | ||||
plugins { | plugins { | ||||
javalite { | javalite { | ||||
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0' | |||||
if (osdetector.os != "osx"){ | |||||
artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0' | |||||
} | |||||
} | } | ||||
grpc { | grpc { | ||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.0.0-pre2' | |||||
artifact = 'io.grpc:protoc-gen-grpc-java:1.42.1' | |||||
} | } | ||||
} | } | ||||
generateProtoTasks { | generateProtoTasks { | ||||
@@ -2,3 +2,4 @@ org.gradle.jvmargs=-Xmx5120M | |||||
android.enableR8=true | android.enableR8=true | ||||
android.useAndroidX=true | android.useAndroidX=true | ||||
android.enableJetifier=true | android.enableJetifier=true | ||||
@@ -1 +1,2 @@ | |||||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" | |||||
#include "Generated.xcconfig" | #include "Generated.xcconfig" |
@@ -1 +1,2 @@ | |||||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" | |||||
#include "Generated.xcconfig" | #include "Generated.xcconfig" |
@@ -0,0 +1,41 @@ | |||||
# Uncomment this line to define a global platform for your project | |||||
# platform :ios, '9.0' | |||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency. | |||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true' | |||||
project 'Runner', { | |||||
'Debug' => :debug, | |||||
'Profile' => :release, | |||||
'Release' => :release, | |||||
} | |||||
def flutter_root | |||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) | |||||
unless File.exist?(generated_xcode_build_settings_path) | |||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" | |||||
end | |||||
File.foreach(generated_xcode_build_settings_path) do |line| | |||||
matches = line.match(/FLUTTER_ROOT\=(.*)/) | |||||
return matches[1].strip if matches | |||||
end | |||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" | |||||
end | |||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) | |||||
flutter_ios_podfile_setup | |||||
target 'Runner' do | |||||
use_frameworks! | |||||
use_modular_headers! | |||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) | |||||
end | |||||
post_install do |installer| | |||||
installer.pods_project.targets.each do |target| | |||||
flutter_additional_ios_build_settings(target) | |||||
end | |||||
end |
@@ -81,7 +81,7 @@ class DBHelper { | |||||
} | } | ||||
Future<List<Unit>> searchAllUnits(String query,{inserted:false}) async { | Future<List<Unit>> searchAllUnits(String query,{inserted:false}) async { | ||||
print("${(inserted)?"${columnName.flag} = 'TRUE' AND ":''} REPLACE(${columnName.mesin},'-','') like '%$query%' or ${columnName.rangka} like '%$query%' or ${columnName.mesin} like '%$query%' or ${columnName.timestamp} like '%$query%' or ${columnName.tipe} like '%$query%' or ${columnName.warna} like '%$query%' or UPPER(${columnName.state}) like '%$query%'"); | |||||
// print("${(inserted)?"${columnName.flag} = 'TRUE' AND ":''} REPLACE(${columnName.mesin},'-','') like '%$query%' or ${columnName.rangka} like '%$query%' or ${columnName.mesin} like '%$query%' or ${columnName.timestamp} like '%$query%' or ${columnName.tipe} like '%$query%' or ${columnName.warna} like '%$query%' or UPPER(${columnName.state}) like '%$query%'"); | |||||
final database = await db; | final database = await db; | ||||
try{ | try{ | ||||
var res = await database.query(tableName.master,where: "${(inserted)?"${columnName.flag} = 'TRUE' AND ":''} (REPLACE(${columnName.mesin},'-','') like '%$query%' or ${columnName.rangka} like '%$query%' or ${columnName.mesin} like '%$query%' or ${columnName.timestamp} like '%$query%' or ${columnName.tipe} like '%$query%' or ${columnName.warna} like '%$query%' or UPPER(${columnName.state}) like '%$query%')",orderBy: "CASE WHEN ${columnName.flag} = 'FALSE' THEN 0 ELSE 1 END, ${columnName.state} desc"); | var res = await database.query(tableName.master,where: "${(inserted)?"${columnName.flag} = 'TRUE' AND ":''} (REPLACE(${columnName.mesin},'-','') like '%$query%' or ${columnName.rangka} like '%$query%' or ${columnName.mesin} like '%$query%' or ${columnName.timestamp} like '%$query%' or ${columnName.tipe} like '%$query%' or ${columnName.warna} like '%$query%' or UPPER(${columnName.state}) like '%$query%')",orderBy: "CASE WHEN ${columnName.flag} = 'FALSE' THEN 0 ELSE 1 END, ${columnName.state} desc"); | ||||
@@ -35,6 +35,7 @@ class columnName{ | |||||
static String state = 'STATE'; | static String state = 'STATE'; | ||||
static String no_urut = 'NO_URUT'; | static String no_urut = 'NO_URUT'; | ||||
static String flag = 'FLAG_INSERT'; | static String flag = 'FLAG_INSERT'; | ||||
static String channel = "CHANNEL"; | |||||
} | } | ||||
class tableName{ | class tableName{ | ||||
static String master = 'refTable'; | static String master = 'refTable'; | ||||
@@ -12,6 +12,7 @@ class Unit { | |||||
String state; | String state; | ||||
String flag; | String flag; | ||||
String timestamp; | String timestamp; | ||||
String channel; | |||||
Unit({ | Unit({ | ||||
@@ -25,6 +26,7 @@ class Unit { | |||||
this.state, | this.state, | ||||
this.flag, | this.flag, | ||||
this.timestamp, | this.timestamp, | ||||
this.channel, | |||||
}); | }); | ||||
factory Unit.fromJson(Map<String, dynamic> json) { | factory Unit.fromJson(Map<String, dynamic> json) { | ||||
@@ -38,7 +40,8 @@ class Unit { | |||||
warna : json[columnName.warna], | warna : json[columnName.warna], | ||||
state: json[columnName.state], | state: json[columnName.state], | ||||
flag: json[columnName.flag], | flag: json[columnName.flag], | ||||
timestamp: json[columnName.timestamp]??'' | |||||
timestamp: json[columnName.timestamp]??'', | |||||
channel: json[columnName.channel], | |||||
);} | );} | ||||
Map<String, dynamic> toJson() => { | Map<String, dynamic> toJson() => { | ||||
@@ -52,6 +55,7 @@ class Unit { | |||||
columnName.state :state, | columnName.state :state, | ||||
columnName.flag :flag, | columnName.flag :flag, | ||||
columnName.timestamp :timestamp, | columnName.timestamp :timestamp, | ||||
columnName.channel:channel, | |||||
}; | }; | ||||
} | } | ||||
@@ -5,16 +5,74 @@ import 'package:flutter/services.dart'; | |||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
import 'package:flushbar/flushbar.dart'; | import 'package:flushbar/flushbar.dart'; | ||||
import 'package:http/io_client.dart'; | import 'package:http/io_client.dart'; | ||||
import 'package:in_app_update/in_app_update.dart'; | |||||
import 'package:url_launcher/url_launcher.dart'; | |||||
import '../main.dart'; | import '../main.dart'; | ||||
import 'package:location/location.dart'; | import 'package:location/location.dart'; | ||||
import 'package:permission_handler/permission_handler.dart' as pHandler; | import 'package:permission_handler/permission_handler.dart' as pHandler; | ||||
import 'Prefs.dart'; | import 'Prefs.dart'; | ||||
import 'package:oauth2/oauth2.dart' as oauth2; | import 'package:oauth2/oauth2.dart' as oauth2; | ||||
// import 'package:flutter_logs/flutter_logs.dart'; | |||||
class Util{ | class Util{ | ||||
bool tokenValidity = true; | bool tokenValidity = true; | ||||
bool useLocal = false; | bool useLocal = false; | ||||
getMinAppVer()async{ | |||||
var req = await JsonDataGetRaw(null,'${prefs.getString(keyClass.hostAddress)}/app/min_ver/'); | |||||
return req; | |||||
} | |||||
launchURL(String url) async { | |||||
if (await canLaunch(url)) { | |||||
await launch(url); | |||||
} else { | |||||
throw 'Could not launch $url'; | |||||
} | |||||
} | |||||
updateDialog(context)async{ | |||||
WidgetsBinding.instance.addPostFrameCallback((_) async { | |||||
await showDialog( | |||||
context: context, | |||||
builder: (BuildContext context) { | |||||
return WillPopScope( | |||||
onWillPop: (){ | |||||
return null; | |||||
}, | |||||
child: AlertDialog( | |||||
title: Text('App version is too old'), | |||||
content: Text('Please update the application'), | |||||
actions: <Widget>[ | |||||
TextButton( | |||||
child: Text('Update',style: TextStyle(color: Colors.blue),), | |||||
onPressed: ()async{ | |||||
try{ | |||||
AppUpdateInfo _updateInfo; | |||||
_updateInfo = await InAppUpdate.checkForUpdate(); | |||||
if(_updateInfo?.updateAvailability == 2){ | |||||
await InAppUpdate.performImmediateUpdate(); | |||||
} | |||||
else throw {"message":"manual Update"}; | |||||
// util.showFlushbar(context, "${_updateInfo?.updateAvailable}"); | |||||
} | |||||
catch(e){ | |||||
await Future.delayed(Duration(milliseconds: 500)); | |||||
await launchURL('https://play.google.com/store/apps/details?id=com.thamringroup.unitstocks'); | |||||
// util.showFlushbar(context, "Failed checking updates. $e."); | |||||
} | |||||
}, | |||||
), | |||||
], | |||||
), | |||||
); | |||||
}, | |||||
barrierDismissible: false, | |||||
); | |||||
}); | |||||
} | |||||
getOauth2Client() async { | getOauth2Client() async { | ||||
bool resetClient = false; | bool resetClient = false; | ||||
oauth2.Credentials restData = (prefs.getString(keyClass.rest_data)!=null&&prefs.getString(keyClass.rest_data).contains("accessToken"))?oauth2.Credentials.fromJson(prefs.getString(keyClass.rest_data)):null; | oauth2.Credentials restData = (prefs.getString(keyClass.rest_data)!=null&&prefs.getString(keyClass.rest_data).contains("accessToken"))?oauth2.Credentials.fromJson(prefs.getString(keyClass.rest_data)):null; | ||||
@@ -101,6 +159,64 @@ class Util{ | |||||
} | } | ||||
} | } | ||||
JsonDataGetRaw(Map jsonData, String url,{secure:true,timeout:false}) async{ | |||||
var httpClient; | |||||
const JsonDecoder decoder = const JsonDecoder(); | |||||
var headers = {'Content-type': 'application/json'}; | |||||
try { | |||||
var response; | |||||
if(secure) { | |||||
httpClient = await getOauth2Client(); | |||||
oauth2.Credentials tokenRestData = oauth2.Credentials.fromJson(prefs.getString(keyClass.rest_data)); | |||||
headers["Authorization"] = | |||||
"bearer ${tokenRestData.accessToken}"; | |||||
} | |||||
else { | |||||
httpClient = http; | |||||
} | |||||
if(jsonData!= null&&jsonData.length!=0) { | |||||
url = url + '?'; | |||||
for (var i in jsonData.keys) { | |||||
url = url + i + '=' + jsonData[i] + '&'; | |||||
} | |||||
url = url.substring(0, url.length - 1); | |||||
} | |||||
if (timeout) | |||||
response = await httpClient.get( | |||||
Uri.parse(url), headers: headers, | |||||
).timeout(const Duration(seconds: 10)); | |||||
else | |||||
response = await httpClient.get( | |||||
Uri.parse(url), headers: {'Content-type': 'application/json'}, | |||||
); | |||||
if(response.statusCode == 403) tokenValidity = false; | |||||
if(htmlErrorTitle(response.body.toString())!=""){ | |||||
return {"STATUS":(response.statusCode != 200)?0:1,"DATA":htmlErrorTitle(response.body.toString())}; | |||||
} | |||||
final Map data = decoder.convert(response.body); | |||||
try{data["DATA"] = decoder.convert(data["DATA"]);}catch(e){} | |||||
return data; | |||||
} on TimeoutException catch(e){ | |||||
return {"STATUS":0,"DATA":"Request Timeout"}; | |||||
} | |||||
on HandshakeException catch(e){ | |||||
if(useLocal){ | |||||
return {"STATUS":0,"DATA":"Not Connected to Server. $e"}; | |||||
} | |||||
else{ | |||||
useLocal = true; | |||||
http = IOClient(HttpClient(context: clientContext)); | |||||
return await JsonDataPostRaw(jsonData, url,timeout:timeout,secure: secure); | |||||
} | |||||
} | |||||
on Exception catch(exception){ | |||||
print(url); | |||||
// Toast("Not Connected to Server", Colors.red); | |||||
return {"STATUS":0,"DATA":"Not Connected to Server. $exception"}; | |||||
} | |||||
} | |||||
JsonDataPutRaw(Map jsonData, String url,{secure:true,timeout:false}) async{ | JsonDataPutRaw(Map jsonData, String url,{secure:true,timeout:false}) async{ | ||||
var httpClient; | var httpClient; | ||||
const JsonDecoder decoder = const JsonDecoder(); | const JsonDecoder decoder = const JsonDecoder(); | ||||
@@ -154,12 +270,13 @@ class Util{ | |||||
} | } | ||||
htmlErrorTitle(String html){ | htmlErrorTitle(String html){ | ||||
// FlutterLogs.logInfo("TAG", "subTag", html); | |||||
try{ | try{ | ||||
if(html.contains('<title>')) { | if(html.contains('<title>')) { | ||||
String titleElement = html.substring(html.indexOf("<title>")+7,html.indexOf("<\/title>")); | String titleElement = html.substring(html.indexOf("<title>")+7,html.indexOf("<\/title>")); | ||||
return titleElement; | return titleElement; | ||||
} | } | ||||
else return ''; | |||||
return ''; | |||||
} | } | ||||
catch(e){ | catch(e){ | ||||
return ''; | return ''; | ||||
@@ -20,16 +20,25 @@ class file_Trans_Handler { | |||||
StreamController _progress = new StreamController<double>(); | StreamController _progress = new StreamController<double>(); | ||||
Stream<double> get progress =>_progress.stream; | Stream<double> get progress =>_progress.stream; | ||||
bool useLocal = false; | bool useLocal = false; | ||||
var httpClient; | |||||
Client httpClient; | |||||
downloadFile(String fileName,String link) async { | downloadFile(String fileName,String link) async { | ||||
StreamedResponse _response; | StreamedResponse _response; | ||||
List<int> _bytes = []; | List<int> _bytes = []; | ||||
int _total = 0; | int _total = 0; | ||||
httpClient = await util.getOauth2Client(); | httpClient = await util.getOauth2Client(); | ||||
print('Start Download'); | |||||
print('Start Download $link'); | |||||
_progress.add(null); | _progress.add(null); | ||||
try { | try { | ||||
void mainThrow(e){ | |||||
cancel(); | |||||
_progress.add(-1.0); | |||||
if(util.htmlErrorTitle(e.message??e)!=""){ | |||||
_error = util.htmlErrorTitle(e.message??e); | |||||
} | |||||
else _error = e.message??e; | |||||
// print("mainthrow $_error"); | |||||
} | |||||
Request req = new Request('GET', Uri.parse(link)); | Request req = new Request('GET', Uri.parse(link)); | ||||
// req.headers = ''; | // req.headers = ''; | ||||
@@ -48,38 +57,42 @@ class file_Trans_Handler { | |||||
_progress.add(((_bytes.length / _total))); | _progress.add(((_bytes.length / _total))); | ||||
} | } | ||||
else{ | else{ | ||||
// print("masuk error"); | |||||
// this.cancel(); | |||||
// cancel(); //stop stream | |||||
String resString = utf8.decode(value); | String resString = utf8.decode(value); | ||||
if(util.htmlErrorTitle(resString)!=""){ | |||||
_error = util.htmlErrorTitle(resString); | |||||
} | |||||
_error = resString; | |||||
// if(util.htmlErrorTitle(resString)!=""){ | |||||
// _error = util.htmlErrorTitle(resString); | |||||
// } | |||||
// else | |||||
// _error = resString; | |||||
mainThrow(Exception(resString)); | |||||
} | } | ||||
}) | |||||
..onDone(() async { | |||||
if(_error==''){ | |||||
_progress.add(0.0); | |||||
print('Finish Download'); | |||||
final file = File( | |||||
"${(await getApplicationDocumentsDirectory()).path}/$fileName"); | |||||
await file.writeAsBytes(_bytes); | |||||
_path = file.path; | |||||
} | |||||
else{ | |||||
print('Error Download, $_error'); | |||||
_progress.add(-1.0); | |||||
} | |||||
}) | |||||
..onError((e) async { | |||||
print('Error Download, $e'); | |||||
_progress.add(-1.0); | |||||
_error = e.toString(); | |||||
}); | |||||
},onDone:() async { | |||||
if(_error==''){ | |||||
_progress.add(0.0); | |||||
print('Finish Download'); | |||||
final file = File( | |||||
"${(await getApplicationDocumentsDirectory()).path}/$fileName"); | |||||
await file.writeAsBytes(_bytes); | |||||
_path = file.path; | |||||
} | |||||
else{ | |||||
mainThrow(_error); | |||||
} | |||||
} ,onError: (e) async { | |||||
mainThrow(e); | |||||
},cancelOnError: true); | |||||
} | } | ||||
on HandshakeException catch(e){ | on HandshakeException catch(e){ | ||||
cancel(); | |||||
if(useLocal){ | if(useLocal){ | ||||
print('Error Download, $e'); | |||||
// print('Error Download 3, $e'); | |||||
_progress.add(-1.0); | _progress.add(-1.0); | ||||
_error = e.toString(); | |||||
if(util.htmlErrorTitle(e.message ?? e)!=""){ | |||||
_error = util.htmlErrorTitle(e.message ?? e); | |||||
} | |||||
else _error = e.toString(); | |||||
} | } | ||||
else{ | else{ | ||||
useLocal = true; | useLocal = true; | ||||
@@ -88,9 +101,12 @@ class file_Trans_Handler { | |||||
} | } | ||||
} | } | ||||
catch(e){ | catch(e){ | ||||
print('Error Download, $e'); | |||||
cancel(); | |||||
_progress.add(-1.0); | _progress.add(-1.0); | ||||
_error = e.toString(); | |||||
if(util.htmlErrorTitle(e.message??e)!=""){ | |||||
_error = util.htmlErrorTitle(e.message??e); | |||||
} | |||||
else _error = e.toString(); | |||||
} | } | ||||
} | } | ||||
@@ -102,11 +118,12 @@ class file_Trans_Handler { | |||||
String mimeType = 'application/vnd.sqlite3'; | String mimeType = 'application/vnd.sqlite3'; | ||||
if(file.existsSync()){ | if(file.existsSync()){ | ||||
Uint8List byte = file.readAsBytesSync(); | Uint8List byte = file.readAsBytesSync(); | ||||
// print("file size ${file.lengthSync()/1024}"); | |||||
try{ | try{ | ||||
var _response = await httpClient.put( | var _response = await httpClient.put( | ||||
Uri.parse(link), headers: {"cabangId":cabang_id,"company":company,'Content-type': mimeType,'Authorization':'Bearer ${tokenRestData.accessToken}'}, | Uri.parse(link), headers: {"cabangId":cabang_id,"company":company,'Content-type': mimeType,'Authorization':'Bearer ${tokenRestData.accessToken}'}, | ||||
body: byte); | |||||
body: byte).onError((error, stackTrace){ | |||||
return new Response("Internal Server Error", 400); | |||||
}); | |||||
print('File send ${file.lengthSync()/1024} KB'); | print('File send ${file.lengthSync()/1024} KB'); | ||||
if(_response.statusCode!=200){ | if(_response.statusCode!=200){ | ||||
if(util.htmlErrorTitle(_response.body.toString())!=""){ | if(util.htmlErrorTitle(_response.body.toString())!=""){ | ||||
@@ -241,7 +258,7 @@ class file_Trans_Handler { | |||||
} | } | ||||
cancel()async{ | cancel()async{ | ||||
http?.close(); | |||||
// http?.close(); | |||||
await dlulStream?.cancel(); | await dlulStream?.cancel(); | ||||
_progress?.close(); | _progress?.close(); | ||||
} | } |
@@ -1,7 +1,10 @@ | |||||
import 'dart:async'; | import 'dart:async'; | ||||
import 'dart:io'; | import 'dart:io'; | ||||
import 'package:flutter/foundation.dart'; | |||||
import 'package:flutter/rendering.dart'; | import 'package:flutter/rendering.dart'; | ||||
import 'package:flutter/widgets.dart'; | import 'package:flutter/widgets.dart'; | ||||
import 'package:in_app_update/in_app_update.dart'; | |||||
import 'package:package_info/package_info.dart'; | |||||
import 'package:path/path.dart'; | import 'package:path/path.dart'; | ||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
@@ -108,7 +111,7 @@ class _HomePageState extends State<HomePage> { | |||||
if(prefs.getString(keyClass.stock_id) == null) | if(prefs.getString(keyClass.stock_id) == null) | ||||
{ | { | ||||
valueTab value = await DBHelper.database.getValue(keyClass.stock_id); | valueTab value = await DBHelper.database.getValue(keyClass.stock_id); | ||||
await prefs.setString(keyClass.stock_id, value.value); | |||||
if(value != null)await prefs.setString(keyClass.stock_id, value.value); | |||||
} | } | ||||
String stock_taking_id = prefs.getString(keyClass.stock_id); | String stock_taking_id = prefs.getString(keyClass.stock_id); | ||||
if(company!=null&&stock_taking_id!=null){ | if(company!=null&&stock_taking_id!=null){ | ||||
@@ -128,6 +131,63 @@ class _HomePageState extends State<HomePage> { | |||||
loadState(); | loadState(); | ||||
lastDownload = prefs.getString(keyClass.lastDownload)??''; | lastDownload = prefs.getString(keyClass.lastDownload)??''; | ||||
lastUpload = prefs.getString(keyClass.lastUpload)??''; | lastUpload = prefs.getString(keyClass.lastUpload)??''; | ||||
WidgetsBinding.instance.addPostFrameCallback((_) async { | |||||
await _check_Update(); | |||||
}); | |||||
} | |||||
_check_Update()async{ | |||||
if(defaultTargetPlatform == TargetPlatform.android){ | |||||
try{ | |||||
final PackageInfo info = await PackageInfo.fromPlatform(); | |||||
AppUpdateInfo _updateInfo = await InAppUpdate.checkForUpdate(); | |||||
String currentVersion = info.version.trim(); | |||||
String latestversion = '0.0.0'; | |||||
var result = await util.getMinAppVer(); | |||||
if(result['STATUS']==1){ | |||||
latestversion = result['DATA']; | |||||
} | |||||
var current = currentVersion.split('.'); | |||||
var latest = latestversion.split('.'); | |||||
if(int.parse(current[0])==int.parse(latest[0])){ | |||||
if(int.parse(current[1])==int.parse(latest[1])){ | |||||
if(int.parse(current[2])<int.parse(latest[2])) { | |||||
await util.updateDialog(context); | |||||
} | |||||
else{ | |||||
if(_updateInfo?.updateAvailability == 2) { | |||||
await InAppUpdate.startFlexibleUpdate(); | |||||
await InAppUpdate.completeFlexibleUpdate(); | |||||
} | |||||
} | |||||
} | |||||
else if(int.parse(current[1])<int.parse(latest[1])) { | |||||
await util.updateDialog(context); | |||||
// await InAppUpdate.performImmediateUpdate(); | |||||
} | |||||
else{ | |||||
if(_updateInfo?.updateAvailability == 2) { | |||||
await InAppUpdate.startFlexibleUpdate(); | |||||
await InAppUpdate.completeFlexibleUpdate(); | |||||
} | |||||
} | |||||
} | |||||
else if(int.parse(current[0])<int.parse(latest[0])) { | |||||
await util.updateDialog(context); | |||||
// await InAppUpdate.performImmediateUpdate(); | |||||
} | |||||
else{ | |||||
if(_updateInfo?.updateAvailability == 2 ) { | |||||
await InAppUpdate.startFlexibleUpdate(); | |||||
await InAppUpdate.completeFlexibleUpdate(); | |||||
} | |||||
} | |||||
} | |||||
catch(e){ | |||||
print("error Update $e"); | |||||
} | |||||
} | |||||
} | } | ||||
changeCabang(context)async{ | changeCabang(context)async{ | ||||
@@ -715,7 +775,7 @@ class _HomePageState extends State<HomePage> { | |||||
setState(() { | setState(() { | ||||
isLoading = false; | isLoading = false; | ||||
}); | }); | ||||
util.showFlushbar(context,'Data download error',color: Colors.red); | |||||
util.showFlushbar(context,trans.error??'Data download error',color: Colors.red); | |||||
} | } | ||||
}); | }); | ||||
// Navigator.popUntil(context, ModalRoute.withName('/home')); | // Navigator.popUntil(context, ModalRoute.withName('/home')); | ||||
@@ -930,7 +990,7 @@ class _HomePageState extends State<HomePage> { | |||||
)); | )); | ||||
if(result){ | if(result){ | ||||
util.showLoading(context); | util.showLoading(context); | ||||
var unpack = await util.JsonDataPutRaw({"cabangId":prefs.getString(keyClass.cabang_id),"company":prefs.getString(keyClass.company),"dbPath":prefs.getString(keyClass.targetProccess)}, '${prefs.getString(keyClass.hostAddress)}/stock_taking/add_collection/'); | |||||
var unpack = await util.JsonDataPutRaw({"userId":prefs.getString(keyClass.loginId),"cabangId":prefs.getString(keyClass.cabang_id),"company":prefs.getString(keyClass.company),"dbPath":prefs.getString(keyClass.targetProccess)}, '${prefs.getString(keyClass.hostAddress)}/stock_taking/add_collection/'); | |||||
Navigator.pop(context); | Navigator.pop(context); | ||||
util.showFlushbar(context, unpack['DATA'],color:(unpack['STATUS']!=1)?Colors.red:Colors.grey); | util.showFlushbar(context, unpack['DATA'],color:(unpack['STATUS']!=1)?Colors.red:Colors.grey); | ||||
if(unpack['STATUS']==1){ | if(unpack['STATUS']==1){ | ||||
@@ -25,13 +25,13 @@ class _LoginPageState extends State<LoginPage> { | |||||
var result = await util.JsonDataPostRaw({"User":userCon.text,"Pass":passCon.text}, '${prefs.getString(keyClass.hostAddress)}/user//login/'); | var result = await util.JsonDataPostRaw({"User":userCon.text,"Pass":passCon.text}, '${prefs.getString(keyClass.hostAddress)}/user//login/'); | ||||
if(result['STATUS']==1){ | if(result['STATUS']==1){ | ||||
prefs.setString(keyClass.loginId, result['DATA'][keyClass.loginId.toLowerCase()]); | prefs.setString(keyClass.loginId, result['DATA'][keyClass.loginId.toLowerCase()]); | ||||
print("user id ${result['DATA'][keyClass.loginId.toLowerCase()]}"); | |||||
prefs.setString(keyClass.company, result['DATA'][keyClass.company.toLowerCase()]); | prefs.setString(keyClass.company, result['DATA'][keyClass.company.toLowerCase()]); | ||||
prefs.setBool(keyClass.logged_in, true); | prefs.setBool(keyClass.logged_in, true); | ||||
var cabangList = await util.JsonDataPostRaw({"company":prefs.getString(keyClass.company),"User":prefs.getString(keyClass.loginId)}, '${prefs.getString(keyClass.hostAddress)}/user/cabangs/'); | var cabangList = await util.JsonDataPostRaw({"company":prefs.getString(keyClass.company),"User":prefs.getString(keyClass.loginId)}, '${prefs.getString(keyClass.hostAddress)}/user/cabangs/'); | ||||
Navigator.pop(context); | Navigator.pop(context); | ||||
if(cabangList['STATUS']==1){ | if(cabangList['STATUS']==1){ | ||||
cabangDrop = cabangList['DATA']; | cabangDrop = cabangList['DATA']; | ||||
print(cabangList); | |||||
selected = cabangDrop[0]['RETURN_VALUE']; | selected = cabangDrop[0]['RETURN_VALUE']; | ||||
setState(() { | setState(() { | ||||
}); | }); | ||||
@@ -11,6 +11,7 @@ import 'unit_details.dart'; | |||||
import 'package:shared_preferences/shared_preferences.dart'; | import 'package:shared_preferences/shared_preferences.dart'; | ||||
import 'package:location/location.dart'; | import 'package:location/location.dart'; | ||||
import 'Util/Util.dart'; | import 'Util/Util.dart'; | ||||
import 'package:flutter_logs/flutter_logs.dart'; | |||||
SharedPreferences prefs; | SharedPreferences prefs; | ||||
@@ -33,6 +34,21 @@ void main() async{ | |||||
await registerCert(); | await registerCert(); | ||||
if( prefs.getString(keyClass.hostAddress) ==null)await prefs.setString(keyClass.hostAddress, "https://tbg.thamringroup.web.id/ords/tbs/unit/v1"); | if( prefs.getString(keyClass.hostAddress) ==null)await prefs.setString(keyClass.hostAddress, "https://tbg.thamringroup.web.id/ords/tbs/unit/v1"); | ||||
await prefs.setString(keyClass.restTokenAddress, "https://tbg.thamringroup.web.id/ords/tbs/oauth/token"); | await prefs.setString(keyClass.restTokenAddress, "https://tbg.thamringroup.web.id/ords/tbs/oauth/token"); | ||||
await FlutterLogs.initLogs( | |||||
logLevelsEnabled: [ | |||||
LogLevel.INFO, | |||||
LogLevel.WARNING, | |||||
LogLevel.ERROR, | |||||
LogLevel.SEVERE | |||||
], | |||||
timeStampFormat: TimeStampFormat.TIME_FORMAT_READABLE, | |||||
directoryStructure: DirectoryStructure.FOR_DATE, | |||||
logTypesEnabled: ["device","network","errors"], | |||||
logFileExtension: LogFileExtension.LOG, | |||||
logsWriteDirectoryName: "MyLogs", | |||||
logsExportDirectoryName: "MyLogs/Exported", | |||||
debugFileOperations: true, | |||||
isDebuggable: true); | |||||
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]) | SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]) | ||||
.then((_) { | .then((_) { | ||||
runApp(new MyApp()); | runApp(new MyApp()); | ||||
@@ -1,7 +1,6 @@ | |||||
import 'dart:async'; | import 'dart:async'; | ||||
import 'dart:typed_data'; | import 'dart:typed_data'; | ||||
import 'package:flutter/services.dart'; | import 'package:flutter/services.dart'; | ||||
import 'main.dart'; | import 'main.dart'; | ||||
import 'package:flutter/cupertino.dart'; | import 'package:flutter/cupertino.dart'; | ||||
import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||
@@ -10,7 +9,7 @@ import 'Util/DBHelper.dart'; | |||||
import 'Util/UnitModel.dart'; | import 'Util/UnitModel.dart'; | ||||
import 'Util/Util.dart'; | import 'Util/Util.dart'; | ||||
import 'Util/photo_viewer.dart'; | import 'Util/photo_viewer.dart'; | ||||
import 'package:barcode_scan/barcode_scan.dart'; | |||||
import 'package:barcode_scan2/barcode_scan2.dart'; | |||||
class Stocking extends StatefulWidget { | class Stocking extends StatefulWidget { | ||||
Stocking({Key key}) : super(key: key); | Stocking({Key key}) : super(key: key); | ||||
@@ -20,7 +19,6 @@ class Stocking extends StatefulWidget { | |||||
} | } | ||||
class _StockingState extends State<Stocking> with SingleTickerProviderStateMixin { | class _StockingState extends State<Stocking> with SingleTickerProviderStateMixin { | ||||
// List<insertUnit> Units = []; | |||||
List<Unit> unitsRef = []; | List<Unit> unitsRef = []; | ||||
List<blobImage> Blobs = []; | List<blobImage> Blobs = []; | ||||
List<blobImage> BlobsRef = []; | List<blobImage> BlobsRef = []; | ||||
@@ -28,7 +26,6 @@ class _StockingState extends State<Stocking> with SingleTickerProviderStateMixin | |||||
Util util = new Util(); | Util util = new Util(); | ||||
int totalUnit = 0; | int totalUnit = 0; | ||||
final search_controller = new TextEditingController(); | final search_controller = new TextEditingController(); | ||||
// TabController _tabBarcontroller; | |||||
bool hideAppbar = false; | bool hideAppbar = false; | ||||
String search = ''; | String search = ''; | ||||
@@ -24,6 +24,7 @@ class _UnitDetailsState extends State<UnitDetails> { | |||||
final mesinController = TextEditingController(); | final mesinController = TextEditingController(); | ||||
final tahunController = TextEditingController(); | final tahunController = TextEditingController(); | ||||
final stateController = TextEditingController(); | final stateController = TextEditingController(); | ||||
final channelController = TextEditingController(); | |||||
// insertUnit _unitDetails; | // insertUnit _unitDetails; | ||||
bool isChanged = false; | bool isChanged = false; | ||||
@@ -39,37 +40,6 @@ class _UnitDetailsState extends State<UnitDetails> { | |||||
// List<Unit> allUnits = []; | // List<Unit> allUnits = []; | ||||
loadUnitDetails(context)async{ | loadUnitDetails(context)async{ | ||||
// if(widget.idInsert!=null){ | |||||
//// var result = await DBHelper.database.getInsertUnit(widget.idInsert); | |||||
//// if(result!=null){ | |||||
//// _unitDetails = result; | |||||
//// mesinController.text = _unitDetails.mesin; | |||||
//// tipeController.text= _unitDetails.tipe; | |||||
//// rangkaController.text = _unitDetails.rangka; | |||||
//// colorController.text = _unitDetails.warna; | |||||
//// tahunController.text = _unitDetails.tahun; | |||||
//// kodeController.text = _unitDetails.kode; | |||||
//// stateController.text = _unitDetails.state; | |||||
//// | |||||
//// result = await DBHelper.database.getAllBlobImage(_unitDetails.id); | |||||
//// if(result!=null){ | |||||
//// for(int i =0; i<result.length;i++){ | |||||
//// images.add(result[i].blob_file); | |||||
//// blobIds.add(result[i].blob_id); | |||||
//// jenisImages.add(result[i].jenis); | |||||
//// } | |||||
//// } | |||||
//// setState(() { | |||||
//// }); | |||||
//// } | |||||
//// else{ | |||||
//// util.showFlushbar(context, 'Unit can\'t be found'); | |||||
//// } | |||||
// await DBHelper.database.closeDb(); | |||||
// } | |||||
// else{ | |||||
// var result = await DBHelper.database.getUnitdetailMaster(widget.idRef); | |||||
// if (result!=null){ | |||||
_currentUnit = widget.unit; | _currentUnit = widget.unit; | ||||
tipeController.text= _currentUnit.tipe; | tipeController.text= _currentUnit.tipe; | ||||
rangkaController.text = _currentUnit.rangka; | rangkaController.text = _currentUnit.rangka; | ||||
@@ -78,8 +48,7 @@ class _UnitDetailsState extends State<UnitDetails> { | |||||
mesinController.text = _currentUnit.mesin; | mesinController.text = _currentUnit.mesin; | ||||
tahunController.text = _currentUnit.tahun; | tahunController.text = _currentUnit.tahun; | ||||
stateController.text = _currentUnit.state; | stateController.text = _currentUnit.state; | ||||
// } | |||||
// } | |||||
channelController.text = (_currentUnit.channel==null||_currentUnit.channel==""||_currentUnit.channel=="null")?'-':_currentUnit.channel; | |||||
await loadBlob(); | await loadBlob(); | ||||
} | } | ||||
// loadTipe() async{ | // loadTipe() async{ | ||||
@@ -606,6 +575,21 @@ class _UnitDetailsState extends State<UnitDetails> { | |||||
Row( | Row( | ||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | mainAxisAlignment: MainAxisAlignment.spaceBetween, | ||||
children: <Widget>[ | children: <Widget>[ | ||||
Text('Channel : '), | |||||
Expanded( | |||||
child: TextFormField( | |||||
enabled: false, | |||||
style: TextStyle(color: Colors.grey), | |||||
controller: channelController, | |||||
decoration: InputDecoration.collapsed(hintText: null), | |||||
), | |||||
), | |||||
], | |||||
), | |||||
Divider(), | |||||
Row( | |||||
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |||||
children: <Widget>[ | |||||
TextButton( | TextButton( | ||||
style: TextButton.styleFrom( | style: TextButton.styleFrom( | ||||
backgroundColor: Colors.green, | backgroundColor: Colors.green, | ||||
@@ -22,13 +22,13 @@ packages: | |||||
url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
source: hosted | source: hosted | ||||
version: "2.8.1" | version: "2.8.1" | ||||
barcode_scan: | |||||
barcode_scan2: | |||||
dependency: "direct main" | dependency: "direct main" | ||||
description: | description: | ||||
name: barcode_scan | |||||
name: barcode_scan2 | |||||
url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
source: hosted | source: hosted | ||||
version: "3.0.1" | |||||
version: "4.1.4" | |||||
boolean_selector: | boolean_selector: | ||||
dependency: transitive | dependency: transitive | ||||
description: | description: | ||||
@@ -112,7 +112,7 @@ packages: | |||||
name: fixnum | name: fixnum | ||||
url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
source: hosted | source: hosted | ||||
version: "0.10.11" | |||||
version: "1.0.0" | |||||
flushbar: | flushbar: | ||||
dependency: "direct main" | dependency: "direct main" | ||||
description: | description: | ||||
@@ -132,6 +132,13 @@ packages: | |||||
url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
source: hosted | source: hosted | ||||
version: "0.9.2" | version: "0.9.2" | ||||
flutter_logs: | |||||
dependency: "direct dev" | |||||
description: | |||||
name: flutter_logs | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "2.1.4" | |||||
flutter_plugin_android_lifecycle: | flutter_plugin_android_lifecycle: | ||||
dependency: transitive | dependency: transitive | ||||
description: | description: | ||||
@@ -176,7 +183,7 @@ packages: | |||||
name: image_picker | name: image_picker | ||||
url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
source: hosted | source: hosted | ||||
version: "0.8.4+2" | |||||
version: "0.8.4+4" | |||||
image_picker_for_web: | image_picker_for_web: | ||||
dependency: transitive | dependency: transitive | ||||
description: | description: | ||||
@@ -191,6 +198,13 @@ packages: | |||||
url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
source: hosted | source: hosted | ||||
version: "2.4.1" | version: "2.4.1" | ||||
in_app_update: | |||||
dependency: "direct main" | |||||
description: | |||||
name: in_app_update | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "2.0.0" | |||||
intl: | intl: | ||||
dependency: "direct main" | dependency: "direct main" | ||||
description: | description: | ||||
@@ -247,6 +261,13 @@ packages: | |||||
url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
source: hosted | source: hosted | ||||
version: "2.0.0" | version: "2.0.0" | ||||
package_info: | |||||
dependency: "direct main" | |||||
description: | |||||
name: package_info | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "2.0.2" | |||||
path: | path: | ||||
dependency: transitive | dependency: transitive | ||||
description: | description: | ||||
@@ -260,7 +281,21 @@ packages: | |||||
name: path_provider | name: path_provider | ||||
url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
source: hosted | source: hosted | ||||
version: "2.0.5" | |||||
version: "2.0.7" | |||||
path_provider_android: | |||||
dependency: transitive | |||||
description: | |||||
name: path_provider_android | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "2.0.9" | |||||
path_provider_ios: | |||||
dependency: transitive | |||||
description: | |||||
name: path_provider_ios | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "2.0.7" | |||||
path_provider_linux: | path_provider_linux: | ||||
dependency: transitive | dependency: transitive | ||||
description: | description: | ||||
@@ -295,7 +330,7 @@ packages: | |||||
name: permission_handler | name: permission_handler | ||||
url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
source: hosted | source: hosted | ||||
version: "8.2.2" | |||||
version: "8.3.0" | |||||
permission_handler_platform_interface: | permission_handler_platform_interface: | ||||
dependency: transitive | dependency: transitive | ||||
description: | description: | ||||
@@ -344,13 +379,27 @@ packages: | |||||
name: protobuf | name: protobuf | ||||
url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
source: hosted | source: hosted | ||||
version: "1.0.1" | |||||
version: "2.0.1" | |||||
shared_preferences: | shared_preferences: | ||||
dependency: "direct main" | dependency: "direct main" | ||||
description: | description: | ||||
name: shared_preferences | name: shared_preferences | ||||
url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
source: hosted | source: hosted | ||||
version: "2.0.9" | |||||
shared_preferences_android: | |||||
dependency: transitive | |||||
description: | |||||
name: shared_preferences_android | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "2.0.9" | |||||
shared_preferences_ios: | |||||
dependency: transitive | |||||
description: | |||||
name: shared_preferences_ios | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "2.0.8" | version: "2.0.8" | ||||
shared_preferences_linux: | shared_preferences_linux: | ||||
dependency: transitive | dependency: transitive | ||||
@@ -462,6 +511,62 @@ packages: | |||||
url: "https://pub.dartlang.org" | url: "https://pub.dartlang.org" | ||||
source: hosted | source: hosted | ||||
version: "1.3.0" | version: "1.3.0" | ||||
url_launcher: | |||||
dependency: "direct main" | |||||
description: | |||||
name: url_launcher | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "6.0.17" | |||||
url_launcher_android: | |||||
dependency: transitive | |||||
description: | |||||
name: url_launcher_android | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "6.0.13" | |||||
url_launcher_ios: | |||||
dependency: transitive | |||||
description: | |||||
name: url_launcher_ios | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "6.0.13" | |||||
url_launcher_linux: | |||||
dependency: transitive | |||||
description: | |||||
name: url_launcher_linux | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "2.0.2" | |||||
url_launcher_macos: | |||||
dependency: transitive | |||||
description: | |||||
name: url_launcher_macos | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "2.0.2" | |||||
url_launcher_platform_interface: | |||||
dependency: transitive | |||||
description: | |||||
name: url_launcher_platform_interface | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "2.0.4" | |||||
url_launcher_web: | |||||
dependency: transitive | |||||
description: | |||||
name: url_launcher_web | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "2.0.5" | |||||
url_launcher_windows: | |||||
dependency: transitive | |||||
description: | |||||
name: url_launcher_windows | |||||
url: "https://pub.dartlang.org" | |||||
source: hosted | |||||
version: "2.0.2" | |||||
vector_math: | vector_math: | ||||
dependency: transitive | dependency: transitive | ||||
description: | description: | ||||
@@ -13,24 +13,28 @@ dependencies: | |||||
# The following adds the Cupertino Icons font to your application. | # The following adds the Cupertino Icons font to your application. | ||||
# Use with the CupertinoIcons class for iOS style icons. | # Use with the CupertinoIcons class for iOS style icons. | ||||
cupertino_icons: | cupertino_icons: | ||||
image_picker: ^0.8.4+2 | |||||
image_picker: ^0.8.4+4 | |||||
photo_view: ^0.13.0 | photo_view: ^0.13.0 | ||||
sqflite: ^2.0.0+4 | sqflite: ^2.0.0+4 | ||||
path_provider: ^2.0.5 | |||||
path_provider: ^2.0.7 | |||||
flushbar: ^1.10.4 | flushbar: ^1.10.4 | ||||
http: ^0.13.4 | http: ^0.13.4 | ||||
intl: ^0.17.0 | intl: ^0.17.0 | ||||
shared_preferences: ^2.0.8 | |||||
shared_preferences: ^2.0.9 | |||||
location: ^4.3.0 | location: ^4.3.0 | ||||
# path: 'local_plugin/location-3.0.2' | # path: 'local_plugin/location-3.0.2' | ||||
permission_handler: ^8.2.2 | |||||
permission_handler: ^8.3.0 | |||||
# app_settings: | # app_settings: | ||||
# autocomplete_textfield: | # autocomplete_textfield: | ||||
barcode_scan: ^3.0.1 | |||||
barcode_scan2: ^4.1.4 | |||||
oauth2: ^2.0.0 | oauth2: ^2.0.0 | ||||
in_app_update: ^2.0.0 | |||||
url_launcher: ^6.0.17 | |||||
package_info: ^2.0.2 | |||||
dev_dependencies: | dev_dependencies: | ||||
flutter_logs: | |||||
flutter_launcher_icons: | flutter_launcher_icons: | ||||
flutter_test: | flutter_test: | ||||
sdk: flutter | sdk: flutter | ||||