Compare commits
95 Commits
4.4
...
backend_nf
| Author | SHA1 | Date |
|---|---|---|
|
|
fe9e9c5fe4 | |
|
|
7e7fa11623 | |
|
|
12040f4c2a | |
|
|
0fe16b5ac9 | |
|
|
1dd045a4d9 | |
|
|
f34080dc6b | |
|
|
85af519d77 | |
|
|
7638d5391c | |
|
|
40efff3fb7 | |
|
|
9bb4c47249 | |
|
|
583b7b74e9 | |
|
|
1c7730bf2e | |
|
|
b05251e920 | |
|
|
33897977a8 | |
|
|
cb6e68bb1e | |
|
|
b23c505fc5 | |
|
|
f4ce7b85b9 | |
|
|
a9ce27cbb1 | |
|
|
32100a3ecb | |
|
|
77ed845505 | |
|
|
7544788744 | |
|
|
a5dd1dac5f | |
|
|
9cea8b445b | |
|
|
5a1f086d78 | |
|
|
c497fa7ed6 | |
|
|
51b531c129 | |
|
|
27d0d6d11d | |
|
|
760fc63da0 | |
|
|
f45835d215 | |
|
|
0de81ff7d2 | |
|
|
07fa2d683a | |
|
|
9d54a20f65 | |
|
|
93e6163ef2 | |
|
|
881c96f620 | |
|
|
fb1f030fb1 | |
|
|
f09dba0b54 | |
|
|
7a50652eda | |
|
|
fb63b8acb2 | |
|
|
09062fb8a3 | |
|
|
228ffd1400 | |
|
|
6d385d16e8 | |
|
|
2a3519500e | |
|
|
0cfbd11ade | |
|
|
8c3451ffd2 | |
|
|
a45bbc03c3 | |
|
|
54df0728f3 | |
|
|
fd4168b614 | |
|
|
8a53233afd | |
|
|
e1301e7340 | |
|
|
8c0ae9939a | |
|
|
839432d011 | |
|
|
923e32274a | |
|
|
50b3694cac | |
|
|
e4bf1db47b | |
|
|
f8d7e4717f | |
|
|
b31e685af0 | |
|
|
62f107d7ac | |
|
|
a1b8223980 | |
|
|
48398435e8 | |
|
|
0de65ff2e9 | |
|
|
4a1f65c681 | |
|
|
f9ed7711e9 | |
|
|
bc853d5bdd | |
|
|
b22abd1389 | |
|
|
5f4d20fce4 | |
|
|
b83d8974df | |
|
|
e06d192dcb | |
|
|
34dc1cb8a2 | |
|
|
1f18d5d928 | |
|
|
273aba6ce8 | |
|
|
1b9a8af2c5 | |
|
|
8edcc2cdb3 | |
|
|
e0c4ade930 | |
|
|
23774d69dc | |
|
|
adc323f383 | |
|
|
cb2e5093ca | |
|
|
3eb69b1ff2 | |
|
|
4196636df1 | |
|
|
ee598f59d8 | |
|
|
e6e2b3516b | |
|
|
39153af143 | |
|
|
ef10080cd2 | |
|
|
49c3cc5b8d | |
|
|
c3cf63fdbe | |
|
|
b09646b475 | |
|
|
72f59553b4 | |
|
|
ce8f20b7b0 | |
|
|
f630d1584f | |
|
|
cb7a2765c6 | |
|
|
4f9bea7980 | |
|
|
e5f6cad039 | |
|
|
f8f646279f | |
|
|
e90982d202 | |
|
|
44e85646fd | |
|
|
8d6ec6bfe1 |
|
|
@ -46,10 +46,11 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
applicationId "kz.com.aman.kassa"
|
||||
minSdkVersion 18
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 30
|
||||
versionCode flutterVersionCode.toInteger()
|
||||
versionName flutterVersionName
|
||||
multiDexEnabled true
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
|
|
@ -62,10 +63,37 @@ android {
|
|||
}
|
||||
}
|
||||
buildTypes {
|
||||
// all {
|
||||
// buildConfigField ("String[]", "SUPPORTED_DEVICES", collectSupportedDevicesToArray())
|
||||
// }
|
||||
debug {
|
||||
shrinkResources false
|
||||
minifyEnabled false
|
||||
useProguard false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
defaultConfig {
|
||||
minSdkVersion 24
|
||||
}
|
||||
}
|
||||
release {
|
||||
shrinkResources false
|
||||
minifyEnabled false
|
||||
useProguard false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
signingConfig signingConfigs.release
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
//coreLibraryDesugaringEnabled true
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
flutter {
|
||||
|
|
@ -73,8 +101,28 @@ flutter {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
//coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test:runner:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
|
||||
|
||||
// https://mvnrepository.com/artifact/com.google.code.gson/gson
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.6'
|
||||
|
||||
|
||||
implementation 'com.android.support:multidex:1.0.3'
|
||||
//m4bank dependencies
|
||||
|
||||
}
|
||||
|
||||
//def collectSupportedDevicesToArray() {
|
||||
// return '{' + rootProject.ext."supportedDevices${getProject().name}".collect {
|
||||
// "\"${it}\""
|
||||
// }.join(",") + '}'
|
||||
//}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in C:\android_sdk\sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
#Flutter Wrapper
|
||||
-keep class io.flutter.app.** { *; }
|
||||
-keep class io.flutter.plugin.** { *; }
|
||||
-keep class io.flutter.util.** { *; }
|
||||
-keep class io.flutter.view.** { *; }
|
||||
-keep class io.flutter.** { *; }
|
||||
-keep class io.flutter.plugins.** { *; }
|
||||
#M4Bank Wrapper
|
||||
-keep class java9.util.stream.** { *; }
|
||||
|
|
@ -1,46 +1,62 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="kz.com.aman.kassa">
|
||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
package="kz.com.aman.kassa"> <!--
|
||||
io.flutter.app.FlutterApplication is an android.app.Application that
|
||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||
In most cases you can leave this as-is, but you if you want to provide
|
||||
additional functionality it is fine to subclass or reimplement
|
||||
FlutterApplication and put your custom class here. -->
|
||||
FlutterApplication and put your custom class here.
|
||||
-->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
|
||||
|
||||
|
||||
<application
|
||||
tools:replace="android:label"
|
||||
android:name="io.flutter.app.FlutterApplication"
|
||||
android:label="Аман Касса"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="Аман Касса"
|
||||
android:allowBackup="false"
|
||||
android:roundIcon="@mipmap/ic_launcher_rounded"
|
||||
>
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:launchMode="singleTop"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||
android:hardwareAccelerated="true"
|
||||
android:launchMode="singleTop"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/LaunchTheme"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<!-- <meta-data
|
||||
|
||||
<!--
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.NormalTheme"
|
||||
android:resource="@style/NormalTheme"
|
||||
/> -->
|
||||
<!-- <meta-data
|
||||
/>
|
||||
-->
|
||||
<!--
|
||||
<meta-data
|
||||
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
||||
android:resource="@drawable/splash"
|
||||
/> -->
|
||||
/>
|
||||
-->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<!-- Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
|
||||
<!--
|
||||
Don't delete the meta-data below.
|
||||
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java
|
||||
-->
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package kz.com.aman.kassa.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AmanDao<E> {
|
||||
private boolean success;
|
||||
private String msg;
|
||||
private E data;
|
||||
private List<E> rows = new ArrayList<>();
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public E getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(E data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public List<E> getRows() {
|
||||
return rows;
|
||||
}
|
||||
|
||||
public void setRows(List<E> rows) {
|
||||
this.rows = rows;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package kz.com.aman.kassa.model;
|
||||
|
||||
public class CardData {
|
||||
private Integer transactionNumber;
|
||||
private String cardExpiryDate;
|
||||
private String cardNumber;
|
||||
private String transactionType;
|
||||
private String cardPaymentSystemType;
|
||||
private String authorizationCode;
|
||||
|
||||
public String getAuthorizationCode() {
|
||||
return authorizationCode;
|
||||
}
|
||||
|
||||
public void setAuthorizationCode(String authorizationCode) {
|
||||
this.authorizationCode = authorizationCode;
|
||||
}
|
||||
|
||||
public String getCardExpiryDate() {
|
||||
return cardExpiryDate;
|
||||
}
|
||||
|
||||
public void setCardExpiryDate(String cardExpiryDate) {
|
||||
this.cardExpiryDate = cardExpiryDate;
|
||||
}
|
||||
|
||||
public String getCardNumber() {
|
||||
return cardNumber;
|
||||
}
|
||||
|
||||
public void setCardNumber(String cardNumber) {
|
||||
this.cardNumber = cardNumber;
|
||||
}
|
||||
|
||||
public String getTransactionType() {
|
||||
return transactionType;
|
||||
}
|
||||
|
||||
public void setTransactionType(String transactionType) {
|
||||
this.transactionType = transactionType;
|
||||
}
|
||||
|
||||
public String getCardPaymentSystemType() {
|
||||
return cardPaymentSystemType;
|
||||
}
|
||||
|
||||
public void setCardPaymentSystemType(String cardPaymentSystemType) {
|
||||
this.cardPaymentSystemType = cardPaymentSystemType;
|
||||
}
|
||||
|
||||
public Integer getTransactionNumber() {
|
||||
return transactionNumber;
|
||||
}
|
||||
|
||||
public void setTransactionNumber(Integer transactionNumber) {
|
||||
this.transactionNumber = transactionNumber;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package kz.com.aman.kassa.model;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
|
||||
public class TransactionDao {
|
||||
String cardType;
|
||||
String cardExpireDate;
|
||||
String cardNumber;
|
||||
String transactionType;
|
||||
Long amount;
|
||||
String date;
|
||||
|
||||
public void setDate(String date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
public String getDate() {
|
||||
return date;
|
||||
}
|
||||
|
||||
public String getCardType() {
|
||||
return cardType;
|
||||
}
|
||||
|
||||
public void setCardType(String cardType) {
|
||||
this.cardType = cardType;
|
||||
}
|
||||
|
||||
public String getCardExpireDate() {
|
||||
return cardExpireDate;
|
||||
}
|
||||
|
||||
public void setCardExpireDate(String cardExpireDate) {
|
||||
this.cardExpireDate = cardExpireDate;
|
||||
}
|
||||
|
||||
public String getCardNumber() {
|
||||
return cardNumber;
|
||||
}
|
||||
|
||||
public void setCardNumber(String cardNumber) {
|
||||
this.cardNumber = cardNumber;
|
||||
}
|
||||
|
||||
public String getTransactionType() {
|
||||
return transactionType;
|
||||
}
|
||||
|
||||
public void setTransactionType(String transactionType) {
|
||||
this.transactionType = transactionType;
|
||||
}
|
||||
|
||||
public Long getAmount() {
|
||||
return amount;
|
||||
}
|
||||
|
||||
public void setAmount(Long amount) {
|
||||
this.amount = amount;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
package kz.com.aman.kassa.plugins;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
||||
import io.flutter.plugin.common.MethodChannel.Result;
|
||||
import kz.com.aman.kassa.MainActivity;
|
||||
|
||||
import kz.com.aman.kassa.model.AmanDao;
|
||||
|
||||
enum OperationType {
|
||||
PAYMENT, // payment
|
||||
REFUND, // return
|
||||
REVERSAL, // cancel
|
||||
CLOSE_DAY, // closing of the trading day
|
||||
OPERATIONS_LIST // get the list of operations
|
||||
}
|
||||
|
||||
public class BankNfcPlugins implements MethodCallHandler {
|
||||
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
//main activity
|
||||
private MainActivity activity;
|
||||
|
||||
|
||||
public MainActivity getActivity() {
|
||||
return this.activity;
|
||||
}
|
||||
|
||||
public BankNfcPlugins(MainActivity activity) {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onMethodCall(MethodCall call, Result result) {
|
||||
switch (call.method) {
|
||||
case "init":
|
||||
init(call, result);
|
||||
break;
|
||||
case "permissions":
|
||||
permissions(result);
|
||||
break;
|
||||
case "connection":
|
||||
connection(result);
|
||||
break;
|
||||
case "currency":
|
||||
currency(result);
|
||||
break;
|
||||
case "auth":
|
||||
authentication(call, result);
|
||||
break;
|
||||
case "pay":
|
||||
pay(call, result);
|
||||
break;
|
||||
case "cancel":
|
||||
cancel(call, result);
|
||||
break;
|
||||
case "shutdown":
|
||||
shutdown(call, result);
|
||||
break;
|
||||
case "closeDay":
|
||||
closeDay(call, result);
|
||||
break;
|
||||
case "transaction":
|
||||
showTransaction(call, result);
|
||||
break;
|
||||
case "findTransaction":
|
||||
findTransaction(call, result);
|
||||
break;
|
||||
case "refund":
|
||||
refund(call, result);
|
||||
break;
|
||||
case "version":
|
||||
result.success(String.valueOf(Build.VERSION.SDK_INT));
|
||||
break;
|
||||
case "get":
|
||||
AmanDao<String> dao = new AmanDao<>();
|
||||
dao.setSuccess(true);
|
||||
dao.setMsg("Hello World");
|
||||
result.success(gson.toJson(dao));
|
||||
break;
|
||||
case "error":
|
||||
result.error("0-code","0-message", "0-details");
|
||||
break;
|
||||
default:
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static int getVersion() {
|
||||
String version = System.getProperty("java.version");
|
||||
if(version.startsWith("1.")) {
|
||||
version = version.substring(2, 3);
|
||||
} else {
|
||||
int dot = version.indexOf(".");
|
||||
if(dot != -1) { version = version.substring(0, dot); }
|
||||
} return Integer.parseInt(version);
|
||||
}
|
||||
|
||||
private void permissions(Result result) {
|
||||
// try {
|
||||
// PermissionsManager.PermissionsCheckResultHandler permissionsCheckResultHandler =
|
||||
// new PermissionsManager.PermissionsCheckResultHandler() {
|
||||
// @Override
|
||||
// public void onPermissionsGranted() {
|
||||
// activity.runOnUiThread(() -> {
|
||||
// AmanDao<String> dao = new AmanDao<>();
|
||||
// dao.setSuccess(true);
|
||||
// dao.setMsg("OK");
|
||||
// result.success(gson.toJson(dao));
|
||||
// }
|
||||
// );
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onPermissionsDeclined() {
|
||||
// AmanDao<String> dao = new AmanDao<>();
|
||||
// dao.setSuccess(false);
|
||||
// dao.setMsg("decline");
|
||||
// result.success(gson.toJson(dao));
|
||||
// }
|
||||
// };
|
||||
// permissionsManager = new PermissionsManagerImpl(this.activity);
|
||||
// permissionsManager.checkPermissions(permissionsCheckResultHandler);
|
||||
//
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// result.error("1", e.getMessage(), e.getLocalizedMessage());
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
private void init(MethodCall call, Result result) {
|
||||
String serverUrl = call.argument("serverUrl");
|
||||
String token = call.argument("token");
|
||||
start(token);
|
||||
AmanDao<String> dao = new AmanDao<>();
|
||||
dao.setSuccess(true);
|
||||
dao.setMsg("OK");
|
||||
result.success(gson.toJson(dao));
|
||||
|
||||
}
|
||||
|
||||
//start after all permissions granted
|
||||
private void start(String token) {
|
||||
// clientInterface = M4BankMposClient.getInstance(
|
||||
// new M4BankMposParameters(
|
||||
// Format.JSON,
|
||||
// "rus",
|
||||
// null,
|
||||
// this.activity,
|
||||
// new SessionExpiringCallbackHandlerImpl(),
|
||||
// "appName",
|
||||
// ServerChoose.API_5_0,
|
||||
// new ConfigurationSettings
|
||||
// .Builder()
|
||||
// .printerUsed(true)
|
||||
// .umkaEnabled(true)
|
||||
// .networkConfiguration(createNetworkConfiguration(serverUrl))
|
||||
// .terminalConfiguration(createTerminalConfiguration())
|
||||
// .build())
|
||||
// );
|
||||
}
|
||||
|
||||
private void connection(Result result) {
|
||||
// clientInterface.getConfigurationManager()
|
||||
// .checkConnection(
|
||||
// new ConnectionCheckHandlerImpl(this.activity, result));
|
||||
}
|
||||
private void currency(Result result) {
|
||||
// CurrencyDataHolder dataHolder = clientInterface.getConfigurationManager()
|
||||
// .getCurrencyDataHolder();
|
||||
// Currency currentCurrency = dataHolder.getCurrency();
|
||||
// if(currentCurrency!=null){
|
||||
// System.out.println(currentCurrency.getName());
|
||||
// System.out.println(currentCurrency.getCurrency3DigitCode());
|
||||
// } else {
|
||||
// System.out.println("currentCurrency is null");
|
||||
// }
|
||||
// System.out.println("===========================");
|
||||
// if(currentCurrency == null || !"398".equalsIgnoreCase(currentCurrency.getCurrency3DigitCode()) ){
|
||||
// List<Currency> currencies = dataHolder.getCurrencyList();
|
||||
// boolean changed = false;
|
||||
// for(Currency currency : currencies ){
|
||||
// System.out.println(currency.getName());
|
||||
// System.out.println(currency.getLetterCode());
|
||||
// System.out.println(currency.getCurrency3DigitCode());
|
||||
// if("398".equalsIgnoreCase(currency.getCurrency3DigitCode())){
|
||||
// dataHolder.setCurrency(currency);
|
||||
// changed = true;
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// AmanDao<String> dao = new AmanDao<>();
|
||||
// dao.setSuccess(changed);
|
||||
// dao.setMsg("current currency " + (currentCurrency!=null ? currentCurrency.getLetterCode() : "NULL"));
|
||||
// result.success(gson.toJson(dao));
|
||||
// } else {
|
||||
// AmanDao<String> dao = new AmanDao<>();
|
||||
// dao.setSuccess(true);
|
||||
// dao.setMsg("exist");
|
||||
// result.success(gson.toJson(dao));
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void authentication(MethodCall call, Result result) {
|
||||
// String login = call.argument("login");
|
||||
// String password = call.argument("password");
|
||||
// clientInterface.getAuthorizationManager().authorize(new AuthorizationHandlerImpl(this, result, login, password) );
|
||||
}
|
||||
|
||||
private void pay(MethodCall call, Result result) {
|
||||
// try {
|
||||
// Integer value = call.argument("amount");
|
||||
// long amount = value.longValue();
|
||||
// clientInterface.cancel();
|
||||
// clientInterface.getTransactionManager().makeCardPayment(new CardPaymentHandlerImpl(this, result, amount, TransactionTypeConv.PAYMENT));
|
||||
// } catch (Exception e) {
|
||||
// System.out.println("=============>ERROR:"+e.getMessage());
|
||||
// result.error("2", e.getMessage(), e.getLocalizedMessage());
|
||||
// }
|
||||
}
|
||||
|
||||
private void findTransaction(MethodCall call, Result result) {
|
||||
// try {
|
||||
// Integer transactionNumber = call.argument("transactionNumber");
|
||||
// String authorizationCode = call.argument("authorizationCode");
|
||||
// clientInterface.getTransactionManager()
|
||||
// .getTransactionsList(new CardRefundAmanHandlerImpl(this, result, transactionNumber, authorizationCode , transaction), 1000,
|
||||
// 0, GetOperationType.SHOW, null);
|
||||
// } catch (Exception e) {
|
||||
// System.out.println("=============>ERROR:"+e.getMessage());
|
||||
// result.error("2", e.getMessage(), e.getLocalizedMessage());
|
||||
// }
|
||||
}
|
||||
|
||||
private void refund(MethodCall call, Result result) {
|
||||
// try {
|
||||
// clientInterface.getTransactionManager()
|
||||
// .makeCardRefund(new CardRefundAmanHandlerImpl(this, result, null, null, transaction));
|
||||
// } catch (Exception e) {
|
||||
// System.out.println("=============>ERROR:"+e.getMessage());
|
||||
// result.error("2", e.getMessage(), e.getLocalizedMessage());
|
||||
// }
|
||||
}
|
||||
|
||||
private void closeDay(MethodCall call, Result result) {
|
||||
// try {
|
||||
// clientInterface.cancel();
|
||||
// clientInterface.getTransactionManager().closeDay(new CloseDayHandlerImpl(this, result));
|
||||
// } catch (Exception e) {
|
||||
// System.out.println("=============>ERROR:"+e.getMessage());
|
||||
// result.error("2", e.getMessage(), e.getLocalizedMessage());
|
||||
// }
|
||||
}
|
||||
|
||||
private void showTransaction(MethodCall call, Result result){
|
||||
// clientInterface.getTransactionManager()
|
||||
// .getTransactionsList(
|
||||
// new TransactionDetailsHandlerImpl(this),
|
||||
// 20, 0,
|
||||
// GetOperationType.SHOW,
|
||||
// null);
|
||||
}
|
||||
|
||||
private void cancel(MethodCall call, Result result) {
|
||||
// try {
|
||||
// clientInterface.cancel();
|
||||
// AmanDao<String> dao = new AmanDao<>();
|
||||
// dao.setSuccess(true);
|
||||
// dao.setMsg("OK");
|
||||
// result.success(gson.toJson(dao));
|
||||
// } catch (Exception e) {
|
||||
// System.out.println("=============>ERROR:"+e.getMessage());
|
||||
// result.error("2", e.getMessage(), e.getLocalizedMessage());
|
||||
// }
|
||||
}
|
||||
|
||||
private void shutdown(MethodCall call, Result result) {
|
||||
// try {
|
||||
// clientInterface.shutdown();
|
||||
// AmanDao<String> dao = new AmanDao<>();
|
||||
// dao.setSuccess(true);
|
||||
// dao.setMsg("OK");
|
||||
// result.success(gson.toJson(dao));
|
||||
// } catch (Exception e) {
|
||||
// System.out.println("=============>ERROR:"+e.getMessage());
|
||||
// result.error("2", e.getMessage(), e.getLocalizedMessage());
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -1,83 +1,149 @@
|
|||
package kz.com.aman.kassa
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.app.Activity
|
||||
import android.content.ComponentName
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.BatteryManager
|
||||
import android.os.Build.VERSION
|
||||
import android.os.Build.VERSION_CODES
|
||||
import android.os.Build
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.NonNull
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
import io.flutter.embedding.engine.FlutterEngine
|
||||
import io.flutter.plugin.common.MethodCall
|
||||
import io.flutter.plugin.common.MethodChannel
|
||||
import io.flutter.plugins.GeneratedPluginRegistrant
|
||||
import kz.com.aman.kassa.bank.JsonForExternalCall
|
||||
import kz.com.aman.kassa.bank.OperationType
|
||||
|
||||
|
||||
class MainActivity: FlutterActivity() {
|
||||
private val CHANNEL = "samples.flutter.dev/battery"
|
||||
class MainActivity : FlutterActivity() {
|
||||
private val externalApplicationRequestCode = 207
|
||||
private val externalOperationTypeKey = "ru.m4bank.ExternalApplication.OperationTypeKey"
|
||||
private val externalInputDataKey = "ru.m4bank.ExternalApplication.InputDataKey"
|
||||
private val externalResultDataKey = "ru.m4bank.ExternalApplication.ResultDataKey"
|
||||
|
||||
private val bankChannel = "channel:com.amanKassa/bank"
|
||||
|
||||
private lateinit var _result: MethodChannel.Result
|
||||
|
||||
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
|
||||
GeneratedPluginRegistrant.registerWith(flutterEngine);
|
||||
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
|
||||
// Note: this method is invoked on the main thread.
|
||||
call, result ->
|
||||
if (call.method == "getBatteryLevel") {
|
||||
val batteryLevel = getBatteryLevel()
|
||||
GeneratedPluginRegistrant.registerWith(flutterEngine)
|
||||
//MethodChannel(flutterEngine.dartExecutor.binaryMessenger, BANK_CHANNEL).setMethodCallHandler(BankNfcPlugins(this))
|
||||
|
||||
if (batteryLevel != -1) {
|
||||
result.success(batteryLevel)
|
||||
} else {
|
||||
result.error("UNAVAILABLE", "Battery level not available.", null)
|
||||
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, bankChannel).setMethodCallHandler { call, result ->
|
||||
_result = result
|
||||
when (call.method) {
|
||||
"pay" -> {
|
||||
operationPayment(call)
|
||||
}
|
||||
} else if (call.method == "sendMessage") {
|
||||
val batteryLevel = sendMessage()
|
||||
|
||||
if (batteryLevel != -1) {
|
||||
result.success(batteryLevel)
|
||||
} else {
|
||||
result.error("UNAVAILABLE", "Battery level not available.", null)
|
||||
"refund" -> {
|
||||
operationRefund(call)
|
||||
}
|
||||
"reversal" -> {
|
||||
operationReversal(call)
|
||||
}
|
||||
"closeDay" -> {
|
||||
operationCloseDay(call)
|
||||
}
|
||||
"version" -> {
|
||||
result.success(Build.VERSION.SDK_INT.toString())
|
||||
}
|
||||
else -> {
|
||||
result.notImplemented()
|
||||
}
|
||||
} else {
|
||||
result.notImplemented()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getBatteryLevel(): Int {
|
||||
val batteryLevel: Int
|
||||
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
|
||||
val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
|
||||
batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
|
||||
} else {
|
||||
val intent = ContextWrapper(applicationContext).registerReceiver(null, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
||||
batteryLevel = intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
|
||||
// private fun getOperationList(call: MethodCall) {
|
||||
// val token: String = call.argument<String>("token").toString()
|
||||
// val operationParameters = createOperationParameters(token)
|
||||
// startOperation(OperationType.OPERATIONS_LIST,
|
||||
// JsonForExternalCall.getOperationsListJson(operationParameters.authToken))
|
||||
//
|
||||
// }
|
||||
|
||||
private fun operationPayment(call: MethodCall) {
|
||||
val token = call.argument<String>("token").toString()
|
||||
var amount: Long = 0
|
||||
if (call.argument<Long>("amount") != null) {
|
||||
amount = call.argument<Long>("amount")!!.toLong()
|
||||
}
|
||||
println("batteryLevel");
|
||||
println(batteryLevel);
|
||||
return batteryLevel
|
||||
val operationParameters = createOperationParameters(token)
|
||||
startOperation(OperationType.PAYMENT, JsonForExternalCall.getPaymentCardJson(operationParameters.authToken, amount.toString()))
|
||||
}
|
||||
|
||||
private fun sendMessage(): Int {
|
||||
val packageManager: PackageManager = context.packageManager
|
||||
val i = Intent(Intent.ACTION_VIEW)
|
||||
try {
|
||||
val mobileNo: String = "77774904900" //call.argument("mobileNo")
|
||||
val message: String = "Hello world" //call.argument("message")
|
||||
//https://wa.me/919167370647?text=Yes%20We'll%20do%20this%20in%20frag4%20inOCW
|
||||
println("mobileNo: $mobileNo message: $message")
|
||||
val url = "https://wa.me/" + mobileNo.trim { it <= ' ' } + "?text=" + message.trim { it <= ' ' }
|
||||
i.setPackage("com.whatsapp")
|
||||
i.data = Uri.parse(url)
|
||||
if (i.resolveActivity(packageManager) != null) {
|
||||
context.startActivity(i)
|
||||
}
|
||||
println("finish method - 2")
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
return 25
|
||||
private fun operationRefund(call: MethodCall) {
|
||||
val token = call.argument<String>("token").toString()
|
||||
val terminalId = call.argument<String>("terminalId").toString()
|
||||
val operDay = call.argument<String>("operDay").toString()
|
||||
val transNum = call.argument<String>("transNum").toString()
|
||||
val amount = call.argument<String>("amount").toString()
|
||||
val operationParameters = createOperationParameters(token)
|
||||
startOperation(OperationType.REFUND, JsonForExternalCall.getRefundCardJson(operationParameters.authToken, terminalId, operDay, transNum, amount))
|
||||
}
|
||||
|
||||
private fun operationReversal(call: MethodCall) {
|
||||
val token = call.argument<String>("token").toString()
|
||||
val terminalId = call.argument<String>("terminalId").toString()
|
||||
val operDay = call.argument<String>("operDay").toString()
|
||||
val transNum = call.argument<String>("transNum").toString()
|
||||
val operationParameters = createOperationParameters(token)
|
||||
val body = JsonForExternalCall.getReversalJson(operationParameters.authToken, terminalId, operDay, transNum);
|
||||
println(body)
|
||||
startOperation(OperationType.REVERSAL, body)
|
||||
}
|
||||
|
||||
private fun operationCloseDay(call: MethodCall) {
|
||||
val token = call.argument<String>("token").toString()
|
||||
val operationParameters = createOperationParameters(token)
|
||||
startOperation(OperationType.CLOSE_DAY, JsonForExternalCall.getCloseDayJson(operationParameters.authToken))
|
||||
}
|
||||
|
||||
|
||||
private fun createOperationParameters(token: String, operDay: String = "", terminalId: String = "", transNum: String = ""): OperationParameters {
|
||||
return OperationParameters(authToken = token, operDay = operDay, terminalId = terminalId, transNum = transNum)
|
||||
}
|
||||
|
||||
private fun startOperation(operationType: OperationType, inputJsonData: String?) {
|
||||
val intent = Intent()
|
||||
intent.component = ComponentName("ru.m4bank.softpos.halyk", "ru.m4bank.feature.externalapplication.ExternalApplicationActivity")
|
||||
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
|
||||
// intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
intent.putExtra(externalOperationTypeKey, operationType.code)
|
||||
intent.putExtra(externalInputDataKey, inputJsonData)
|
||||
startActivityForResult(intent, externalApplicationRequestCode)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
super.onActivityResult(requestCode, resultCode, data)
|
||||
if (requestCode == externalApplicationRequestCode) {
|
||||
println("---------------")
|
||||
println(requestCode)
|
||||
println(resultCode)
|
||||
println(data)
|
||||
if (data != null) {
|
||||
println(data.getStringExtra(externalResultDataKey))
|
||||
}
|
||||
println("---------------")
|
||||
if (requestCode == externalApplicationRequestCode && resultCode == Activity.RESULT_OK && data != null) {
|
||||
println(data.getStringExtra(externalResultDataKey))
|
||||
//Toast.makeText(this, data.getStringExtra(externalResultDataKey), Toast.LENGTH_LONG).show()
|
||||
_result.success(data.getStringExtra(externalResultDataKey))
|
||||
} else {
|
||||
_result.error("008", "Error while apps connecting", "aaa")
|
||||
//Toast.makeText(this, "Error while apps connecting", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
// if (resultCode == Activity.RESULT_OK) {
|
||||
// _result.success(data?.getStringExtra("result"))
|
||||
// } else if (resultCode == Activity.RESULT_CANCELED) {
|
||||
// _result.error("008", "123","aaa")
|
||||
// } else
|
||||
// _result.success(null)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
data class OperationParameters(val authToken: String, val terminalId: String, val operDay: String, val transNum: String)
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package kz.com.aman.kassa.bank;
|
||||
|
||||
data class ExternalPackage(val packageName: String, val activityName: String)
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
package kz.com.aman.kassa.bank;
|
||||
|
||||
object JsonForExternalCall {
|
||||
|
||||
fun getPaymentCardJson(authToken: String, amount: String): String {
|
||||
return """{
|
||||
"credentials" : {
|
||||
"authorizationToken": "$authToken"
|
||||
},
|
||||
"operationData" : {
|
||||
"instrument": "CARD",
|
||||
"amountData" : {
|
||||
"currencyCode": "398",
|
||||
"amount": "$amount",
|
||||
"amountExponent": "2"
|
||||
},
|
||||
"goods" : {
|
||||
"product": [{
|
||||
"name": "Товар",
|
||||
"price": "$amount",
|
||||
"quantity": "1",
|
||||
"quantityExponent": "0",
|
||||
"taxRate": "TAX_20",
|
||||
"accountingSubject": "PRODUCT"
|
||||
}]
|
||||
}
|
||||
}
|
||||
}"""
|
||||
}
|
||||
|
||||
fun getRefundCardJson(authToken: String, terminalId: String, operDay: String, transNum: String, amount: String): String {
|
||||
return """{
|
||||
"credentials" :{
|
||||
"authorizationToken": "$authToken"
|
||||
},
|
||||
"operationData" :{
|
||||
"instrument": "CARD",
|
||||
"amountData" : {
|
||||
"currencyCode": "348",
|
||||
"amount": "6000",
|
||||
"amountExponent": "2"
|
||||
},
|
||||
"parentTransaction" : {
|
||||
"terminalId": "$terminalId",
|
||||
"operationDay": "$operDay",
|
||||
"transactionNumber": "$transNum"
|
||||
}
|
||||
}
|
||||
}"""
|
||||
}
|
||||
|
||||
fun getCloseDayJson(authToken: String): String {
|
||||
return """{
|
||||
"credentials" : {
|
||||
"authorizationToken": "$authToken"
|
||||
}
|
||||
}"""
|
||||
}
|
||||
|
||||
fun getOperationsListJson(authToken: String): String {
|
||||
return """{
|
||||
"credentials" : {
|
||||
"authorizationToken": "$authToken"
|
||||
},
|
||||
"operationData": {
|
||||
"params": {
|
||||
"offset": "0",
|
||||
"limit": "20"
|
||||
},
|
||||
"filter": {
|
||||
"transactionTypes": [PAYMENT, REFUND]
|
||||
}
|
||||
}
|
||||
}"""
|
||||
}
|
||||
|
||||
fun getReversalJson(authToken: String, terminalId: String, operDay: String, transNum: String): String {
|
||||
return """{
|
||||
"credentials" : {
|
||||
"authorizationToken": "$authToken"
|
||||
},
|
||||
"operationData" : {
|
||||
"parentTransaction" : {
|
||||
"terminalId": "$terminalId",
|
||||
"operationDay": "$operDay",
|
||||
"transactionNumber": "$transNum"
|
||||
}
|
||||
}
|
||||
}"""
|
||||
}
|
||||
|
||||
// fun getPaymentCashJson(authToken: String): String {
|
||||
// return """{
|
||||
// "credentials" : {
|
||||
// "authorizationToken": "$authToken"
|
||||
// },
|
||||
// "operationData" : {
|
||||
// "instrument": "CASH",
|
||||
// "amountData" : {
|
||||
// "currencyCode": "643",
|
||||
// "amount": "6000",
|
||||
// "amountExponent": "2"
|
||||
// },
|
||||
// "goods" : {
|
||||
// "product": [{
|
||||
// "name": "Печеньки",
|
||||
// "price": "3000",
|
||||
// "quantity": "2",
|
||||
// "quantityExponent": "0",
|
||||
// "taxRate": "TAX_20",
|
||||
// "accountingSubject": "PRODUCT"
|
||||
// }]
|
||||
// }
|
||||
// }
|
||||
// }"""
|
||||
// }
|
||||
|
||||
//
|
||||
// fun getRefundCashJson(authToken: String, terminalId: String, operDay: String, transNum: String): String {
|
||||
// return """{
|
||||
// "credentials" :{
|
||||
// "authorizationToken": "$authToken"
|
||||
// },
|
||||
// "operationData" :{
|
||||
// "instrument": "CASH",
|
||||
// "amountData" : {
|
||||
// "currencyCode": "643",
|
||||
// "amount": "6000",
|
||||
// "amountExponent": "2"
|
||||
// },
|
||||
// "parentTransaction" : {
|
||||
// "terminalId": "$terminalId",
|
||||
// "operationDay": "$operDay",
|
||||
// "transactionNumber": "$transNum"
|
||||
// }
|
||||
// }
|
||||
// }"""
|
||||
// }
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
package kz.com.aman.kassa.bank;
|
||||
|
||||
enum class OperationType(val code: String) {
|
||||
PAYMENT("PAYMENT"),
|
||||
REFUND("REFUND"),
|
||||
REVERSAL("REVERSAL"),
|
||||
CLOSE_DAY("CLOSE_DAY"),
|
||||
OPERATIONS_LIST("OPERATIONS_LIST")
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/design_default_color_background"
|
||||
tools:context=".activities.BankActivity"
|
||||
>
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginTop="32dp"
|
||||
android:layout_marginRight="20dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonClose"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="myClickHandler"
|
||||
tools:text="@android:string/cancel" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="82dp"
|
||||
android:layout_height="82dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:src="@mipmap/ic_launcher_foreground" />
|
||||
</RelativeLayout>
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
</ScrollView>
|
||||
|
|
@ -0,0 +1,494 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:context=".bank.M4BankActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin">
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
<Button
|
||||
android:id="@+id/authorize"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/authorize_button" />
|
||||
<EditText
|
||||
android:id="@+id/amountField"
|
||||
android:layout_weight="1"
|
||||
android:inputType="numberDecimal"
|
||||
android:hint="@string/amount_hint"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/login"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/login_hint"
|
||||
android:inputType="text" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/password"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/password_hint"
|
||||
android:inputType="textPassword" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/logout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/logout_button" />
|
||||
|
||||
<!--<Button-->
|
||||
<!--android:id="@+id/changePassword"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:layout_gravity="center_horizontal"-->
|
||||
<!--android:text="@string/change_password_button" />-->
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!--<EditText-->
|
||||
<!--android:id="@+id/oldPassword"-->
|
||||
<!--android:layout_width="0dp"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:layout_weight="1"-->
|
||||
<!--android:hint="@string/old_password_hint"-->
|
||||
<!--android:inputType="textPassword" />-->
|
||||
|
||||
<!--<EditText-->
|
||||
<!--android:id="@+id/newPassword"-->
|
||||
<!--android:layout_width="0dp"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:layout_weight="1"-->
|
||||
<!--android:hint="@string/new_password_hint"-->
|
||||
<!--android:inputType="textPassword" />-->
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!--<Button-->
|
||||
<!--android:id="@+id/register"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:text="@string/register_button" />-->
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!--<EditText-->
|
||||
<!--android:id="@+id/code"-->
|
||||
<!--android:layout_width="0dp"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:layout_weight="1"-->
|
||||
<!--android:hint="@string/code_hint"-->
|
||||
<!--android:inputType="number" />-->
|
||||
|
||||
<!--<EditText-->
|
||||
<!--android:id="@+id/pin"-->
|
||||
<!--android:layout_width="0dp"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:layout_weight="1"-->
|
||||
<!--android:hint="@string/pin_hint"-->
|
||||
<!--android:inputType="number" />-->
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/checkAccess"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/check_access" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/checkAccessSpinner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:entries="@array/accessTypes" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/getAccesses"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/get_available_operations" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<!--<Button-->
|
||||
<!--android:id="@+id/setLanguage"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:text="@string/set_language" />-->
|
||||
|
||||
<!--<Spinner-->
|
||||
<!--android:id="@+id/setLanguageSpinner"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--android:entries="@array/languages" />-->
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/checkConnection"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/check_connection" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/getLicense"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/get_license" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/makeCardPayment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/make_card_payment" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/getCommonCardData"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/get_common_card_data" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<Button
|
||||
android:id="@+id/makeReversalLast"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/make_reversal_last" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/getCurrentTransactionDetails"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/get_current_transaction_details" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/completePayment"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/complete_payment" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/readerInformation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/reader_information" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/versionStore"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/version_store" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/versionTracker"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/version_tracker" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/makeReversalLastWithCallback"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/make_reversal_last_saved_operation" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/makeCashPayment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/make_cash_payment" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/makeAlipayPayment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/make_alipay_payment" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/makeCardRefund"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/make_card_refund" />
|
||||
|
||||
<!--<Button-->
|
||||
<!--android:id="@+id/makeCardRefundWithD200"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:text="@string/make_card_refund_with_d200" />-->
|
||||
|
||||
<Button
|
||||
android:id="@+id/makeCashRefund"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/make_cash_refund" />
|
||||
|
||||
<!--<Button-->
|
||||
<!--android:id="@+id/makeCashRefundWithD200"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:text="@string/make_cash_refund_with_d200" />-->
|
||||
|
||||
<Button
|
||||
android:id="@+id/makeAlipayRefund"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/make_alipay_refund" />
|
||||
|
||||
<!--<Button-->
|
||||
<!--android:id="@+id/makeReversal"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:text="@string/make_reversal" />-->
|
||||
|
||||
<Button
|
||||
android:id="@+id/makeEasyReversal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/make_easy_reversal" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/makeEasyCardReversal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/make_easy_card_reversal" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/makeReversalSavedUnsuccessfulOperation"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/makeReversalSavedUnsuccessfulOperation" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<!--<Button-->
|
||||
<!--android:id="@+id/makeReconciliation"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:text="@string/make_reconciliation" />-->
|
||||
|
||||
<!--<Button-->
|
||||
<!--android:id="@+id/enterServiceMenu"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:text="@string/enter_service_menu" />-->
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!--<Button-->
|
||||
<!--android:id="@+id/addAdditionalCardReader"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:text="@string/add_additional_card_reader" />-->
|
||||
|
||||
<!--<Button-->
|
||||
<!--android:id="@+id/getReadersInfo"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:text="@string/get_readers_info" />-->
|
||||
|
||||
<Button
|
||||
android:id="@+id/getMerchantUsers"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/get_merchant_users" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/resendReceipt"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/resend_receipt" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/getTransactionDetails"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/get_transaction_details" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/getTransactionListFilter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/get_filter_list" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/activate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/activate" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/addPrinter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/add_new_printer" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/deletePrinter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/delete_printer" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/printFiscal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/printing_fiscal_check" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/printSlipCheck"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/printing_slip_check" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/printTemplate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/print_template" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/printReportX"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/printing_x_report" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/printReportZ"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/printing_z_report" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/printFullReport"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/printing_full_report" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/printShortReport"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/printing_short_report" />
|
||||
|
||||
<!--<Button-->
|
||||
<!--android:id="@+id/executeExternalApplication"-->
|
||||
<!--android:layout_width="wrap_content"-->
|
||||
<!--android:layout_height="match_parent"-->
|
||||
<!--android:text="@string/call_external_application" />-->
|
||||
|
||||
<Button
|
||||
android:id="@+id/sendRegisterRequest"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/send_register_request" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/cancel"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/cancel_interface" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/ecomPayment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/make_ecom_payment" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/getAccessPaymentInstruments"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/get_access_payment_instruments" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/closeDay"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/close_day" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/writeTerminalKeys"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:text="@string/write_terminal_keys" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/readBarCode"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/read_barcode" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/updateDictionary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/update_dictionary" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/white"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/labelMessage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:text="Choose element" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@+id/labelMessage"
|
||||
android:layout_marginLeft="20dp"
|
||||
android:layout_marginRight="20dp"
|
||||
android:layout_marginTop="20dp"
|
||||
android:cacheColorHint="#00000000"
|
||||
android:divider="@android:color/transparent"
|
||||
android:dividerHeight="1dp"
|
||||
android:listSelector="@android:color/transparent" />
|
||||
</RelativeLayout>
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:weightSum="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="New Text"
|
||||
android:textSize="30sp" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pin_text_btn_1" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pin_text_btn_2" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pin_text_btn_3" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button4"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pin_text_btn_4" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button5"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pin_text_btn_5" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button6"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pin_text_btn_6" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button7"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pin_text_btn_7" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button8"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pin_text_btn_8" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/button9"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pin_text_btn_9" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="0.36"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/button0"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pin_text_btn_0" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttoncan"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonconfirm"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/confirm" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonclean"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/clear" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonstart"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pin_text_btn_start" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonexit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/pin_text_btn_exit" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/itemView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:padding="20dp"
|
||||
android:textColor="@android:color/black" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
<color name="colorAccent">#FF4081</color>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<resources>
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
<resources>
|
||||
<string name="app_name">TestAppM4bank</string>
|
||||
<string name="authorize_button">Authorize</string>
|
||||
<string name="logout_button">Log Out</string>
|
||||
<string name="change_password_button">Change Password</string>
|
||||
<string name="login_hint">Enter Your Login</string>
|
||||
<string name="password_hint">Enter Your Password</string>
|
||||
<string name="old_password_hint">Enter Old Password</string>
|
||||
<string name="new_password_hint">Enter New Password</string>
|
||||
<string name="register_button">Register</string>
|
||||
<string name="code_hint">Enter Reader Code</string>
|
||||
<string name="pin_hint">Enter Reader Pin</string>
|
||||
<string name="serial_hint">Enter Reader Serial Number</string>
|
||||
<string name="default_server_address1">http://10.10.0.245:29978</string>
|
||||
<string name="default_server_address2">http://10.45.49.31:29978</string>
|
||||
<string name="default_server_address_sber_test">http://sbertest.m4bank.ru:21017</string>
|
||||
<!--<string name="default_server_address_mpos_5_0_test">http://217.174.185.218:35997</string>-->
|
||||
<string name="default_server_address_mpos_5_0_test">http://185.98.84.231:2000</string>
|
||||
|
||||
<string name="check_access">Check access</string>
|
||||
<string name="get_available_operations">Get available operations</string>
|
||||
<string name="set_language">Set language</string>
|
||||
<string name="check_connection">Check connection</string>
|
||||
<string name="make_card_payment">Make card payment</string>
|
||||
<string name="get_common_card_data">Get common card data</string>
|
||||
<string name="add_additional_card_reader">Add additional card reader</string>
|
||||
<string name="get_readers_info">Get readers info</string>
|
||||
<string name="make_cash_payment">Make cash payment</string>
|
||||
<string name="make_alipay_payment">Make alipay payment</string>
|
||||
<string name="make_card_refund">Make card refund</string>
|
||||
<string name="make_card_refund_with_d200">Make card refund with D200</string>
|
||||
<string name="make_cash_refund_with_d200">Make easy cash refund</string>
|
||||
<string name="make_alipay_refund">Make alipay refund</string>
|
||||
<string name="make_cash_refund">Make cash refund</string>
|
||||
<string name="make_reversal">Make reversal</string>
|
||||
<string name="make_easy_reversal">Make easy reversal</string>
|
||||
<string name="make_easy_card_reversal">Make easy card reversal</string>
|
||||
<string name="makeReversalSavedUnsuccessfulOperation">make Reversal Saved Unsuccessful Operation</string>
|
||||
<string name="make_reconciliation">Make reconciliation</string>
|
||||
<string name="get_merchant_users">Get merchant users</string>
|
||||
<string name="get_access_payment_instruments">Get access PI</string>
|
||||
<string name="close_day">Close day</string>
|
||||
<string name="write_terminal_keys">Write terminal keys</string>
|
||||
<string name="read_barcode">Read BarCode</string>
|
||||
<string name="update_dictionary">Update Dictionary</string>
|
||||
|
||||
<string-array name="accessTypes">
|
||||
<item>Payment</item>
|
||||
<item>Reversal</item>
|
||||
<item>Refund</item>
|
||||
<item>Cash</item>
|
||||
<item>PartRefund</item>
|
||||
<item>AddReader</item>
|
||||
<item>CloseDay</item>
|
||||
<item>AddPrinter</item>
|
||||
<item>FuncPrinter</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="languages">
|
||||
<item>rus</item>
|
||||
<item>eng</item>
|
||||
</string-array>
|
||||
|
||||
<string name="confirm">confirm</string>
|
||||
<string name="clear">clear</string>
|
||||
<string name="cancel">cancel</string>
|
||||
<string name="resend_receipt">Resend receipt</string>
|
||||
<string name="get_transaction_details">Get transaction details</string>
|
||||
<string name="get_filter_list">Get filter list</string>
|
||||
<string name="activate">Activate</string>
|
||||
<string name="add_new_printer">Add new printer</string>
|
||||
<string name="delete_printer">Delete printer</string>
|
||||
<string name="printing_fiscal_check">Printing fiscal check</string>
|
||||
<string name="printing_slip_check">Printing slip check</string>
|
||||
<string name="print_template">print template</string>
|
||||
<string name="printing_x_report">Printing X report</string>
|
||||
<string name="printing_z_report">Printing Z report</string>
|
||||
<string name="printing_full_report">Printing full report</string>
|
||||
<string name="printing_short_report">Printing short report</string>
|
||||
<string name="call_external_application">Call external application</string>
|
||||
<string name="send_register_request">Send register request</string>
|
||||
<string name="cancel_interface">Cancel interface</string>
|
||||
<string name="make_ecom_payment">Make ecom payment</string>
|
||||
<string name="enter_service_menu">Enter service menu</string>
|
||||
<string name="make_reversal_last_saved_operation">Make reversal last saved operation</string>
|
||||
<string name="reader_information">Get reader information</string>
|
||||
<string name="version_store">Store version</string>
|
||||
<string name="version_tracker">Tracker version</string>
|
||||
|
||||
<string name="pin_text_btn_1">1</string>
|
||||
<string name="pin_text_btn_2">2</string>
|
||||
<string name="pin_text_btn_3">3</string>
|
||||
<string name="pin_text_btn_4">4</string>
|
||||
<string name="pin_text_btn_5">5</string>
|
||||
<string name="pin_text_btn_6">6</string>
|
||||
<string name="pin_text_btn_7">7</string>
|
||||
<string name="pin_text_btn_8">8</string>
|
||||
<string name="pin_text_btn_9">9</string>
|
||||
<string name="pin_text_btn_0">0</string>
|
||||
<string name="pin_text_btn_start">start</string>
|
||||
<string name="pin_text_btn_exit">exit</string>
|
||||
<string name="get_license">Get license</string>
|
||||
<string name="make_reversal_last">Make reversal last</string>
|
||||
<string name="get_current_transaction_details">Get current transaction details</string>
|
||||
<string name="complete_payment">Complete payment</string>
|
||||
<string name="amount_hint">Amount</string>
|
||||
</resources>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<!--Set application-wide security config using base-config tag.-->
|
||||
<base-config cleartextTrafficPermitted="false" />
|
||||
<domain-config cleartextTrafficPermitted="true">
|
||||
<domain includeSubdomains="true">kassa.aman.com.kz</domain>
|
||||
<domain includeSubdomains="true">kassa.aman.systems</domain>
|
||||
<domain includeSubdomains="true">partner.aman.com.kz</domain>
|
||||
<domain includeSubdomains="true">partner.aman.systems</domain>
|
||||
</domain-config>
|
||||
|
||||
</network-security-config>
|
||||
|
|
@ -7,8 +7,11 @@ buildscript {
|
|||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.0'
|
||||
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
allprojects {
|
||||
|
|
@ -16,6 +19,12 @@ allprojects {
|
|||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
resolutionStrategy {
|
||||
cacheDynamicVersionsFor 2, 'minutes'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.buildDir = '../build'
|
||||
|
|
@ -29,3 +38,10 @@ subprojects {
|
|||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
||||
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
||||
kotlinOptions {
|
||||
jvmTarget = "1.8"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 42 KiB |
44
ios/Podfile
|
|
@ -37,5 +37,49 @@ end
|
|||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
|
||||
|
||||
target.build_configurations.each do |config|
|
||||
|
||||
# You can enable the permissions needed here. For example to enable camera
|
||||
# permission, just remove the `#` character in front so it looks like this:
|
||||
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
|
||||
'$(inherited)',
|
||||
|
||||
## dart: PermissionGroup.calendar
|
||||
'PERMISSION_EVENTS=0',
|
||||
|
||||
## dart: PermissionGroup.reminders
|
||||
'PERMISSION_REMINDERS=0',
|
||||
|
||||
## dart: PermissionGroup.contacts
|
||||
'PERMISSION_CONTACTS=0',
|
||||
|
||||
## dart: PermissionGroup.camera
|
||||
'PERMISSION_CAMERA=0',
|
||||
|
||||
## dart: PermissionGroup.microphone
|
||||
'PERMISSION_MICROPHONE=0',
|
||||
|
||||
## dart: PermissionGroup.speech
|
||||
'PERMISSION_SPEECH_RECOGNIZER=0',
|
||||
|
||||
## dart: PermissionGroup.photos
|
||||
'PERMISSION_PHOTOS=0',
|
||||
|
||||
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
|
||||
'PERMISSION_LOCATION=0',
|
||||
|
||||
## dart: PermissionGroup.notification
|
||||
'PERMISSION_NOTIFICATIONS=0',
|
||||
|
||||
## dart: PermissionGroup.mediaLibrary
|
||||
'PERMISSION_MEDIA_LIBRARY=0',
|
||||
|
||||
## dart: PermissionGroup.sensors
|
||||
'PERMISSION_SENSORS=0'
|
||||
]
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,17 +3,25 @@ PODS:
|
|||
- Flutter
|
||||
- MTBBarcodeScanner
|
||||
- SwiftProtobuf
|
||||
- charset_converter (0.0.1):
|
||||
- Flutter
|
||||
- device_info (0.0.1):
|
||||
- Flutter
|
||||
- esys_flutter_share (0.0.1):
|
||||
- Flutter
|
||||
- Flutter (1.0.0)
|
||||
- flutter_bluetooth_basic (0.0.1):
|
||||
- Flutter
|
||||
- FMDB (2.7.5):
|
||||
- FMDB/standard (= 2.7.5)
|
||||
- FMDB/standard (2.7.5)
|
||||
- local_auth (0.0.1):
|
||||
- Flutter
|
||||
- MTBBarcodeScanner (5.0.11)
|
||||
- path_provider (0.0.1):
|
||||
- Flutter
|
||||
- "permission_handler (5.1.0+2)":
|
||||
- Flutter
|
||||
- shared_preferences (0.0.1):
|
||||
- Flutter
|
||||
- sqflite (0.0.2):
|
||||
|
|
@ -25,10 +33,14 @@ PODS:
|
|||
|
||||
DEPENDENCIES:
|
||||
- barcode_scan (from `.symlinks/plugins/barcode_scan/ios`)
|
||||
- charset_converter (from `.symlinks/plugins/charset_converter/ios`)
|
||||
- device_info (from `.symlinks/plugins/device_info/ios`)
|
||||
- esys_flutter_share (from `.symlinks/plugins/esys_flutter_share/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_bluetooth_basic (from `.symlinks/plugins/flutter_bluetooth_basic/ios`)
|
||||
- local_auth (from `.symlinks/plugins/local_auth/ios`)
|
||||
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
|
||||
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
|
||||
|
|
@ -42,14 +54,22 @@ SPEC REPOS:
|
|||
EXTERNAL SOURCES:
|
||||
barcode_scan:
|
||||
:path: ".symlinks/plugins/barcode_scan/ios"
|
||||
charset_converter:
|
||||
:path: ".symlinks/plugins/charset_converter/ios"
|
||||
device_info:
|
||||
:path: ".symlinks/plugins/device_info/ios"
|
||||
esys_flutter_share:
|
||||
:path: ".symlinks/plugins/esys_flutter_share/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_bluetooth_basic:
|
||||
:path: ".symlinks/plugins/flutter_bluetooth_basic/ios"
|
||||
local_auth:
|
||||
:path: ".symlinks/plugins/local_auth/ios"
|
||||
path_provider:
|
||||
:path: ".symlinks/plugins/path_provider/ios"
|
||||
permission_handler:
|
||||
:path: ".symlinks/plugins/permission_handler/ios"
|
||||
shared_preferences:
|
||||
:path: ".symlinks/plugins/shared_preferences/ios"
|
||||
sqflite:
|
||||
|
|
@ -59,17 +79,21 @@ EXTERNAL SOURCES:
|
|||
|
||||
SPEC CHECKSUMS:
|
||||
barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479
|
||||
charset_converter: 215c7b04932ec2b9ba43be96a9bc34afed3e5322
|
||||
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
|
||||
esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4
|
||||
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
||||
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
|
||||
flutter_bluetooth_basic: 0e4e27e22b50b3a25cc1d1e131953feb4af414f4
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd
|
||||
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
|
||||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||
permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
|
||||
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
|
||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||
SwiftProtobuf: ecbec1be9036d15655f6b3443a1c4ea693c97932
|
||||
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
|
||||
|
||||
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
||||
PODFILE CHECKSUM: 5aafc9b59da66d8d46f05cbbbd21261eb9757176
|
||||
|
||||
COCOAPODS: 1.8.4
|
||||
COCOAPODS: 1.10.1
|
||||
|
|
|
|||
|
|
@ -255,12 +255,13 @@
|
|||
inputPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||
"${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework",
|
||||
"${PODS_ROOT}/../Flutter/Flutter.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/MTBBarcodeScanner/MTBBarcodeScanner.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/barcode_scan/barcode_scan.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/charset_converter/charset_converter.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/device_info/device_info.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/esys_flutter_share/esys_flutter_share.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/local_auth/local_auth.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/shared_preferences/shared_preferences.framework",
|
||||
"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
|
||||
|
|
@ -269,12 +270,13 @@
|
|||
name = "[CP] Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MTBBarcodeScanner.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/barcode_scan.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/charset_converter.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/device_info.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/esys_flutter_share.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/local_auth.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences.framework",
|
||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
<Workspace
|
||||
version = "1.0">
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
location = "self:">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
|
|
|||
|
|
@ -26,8 +26,17 @@
|
|||
</array>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSBluetoothAlwaysUsageDescription</key>
|
||||
<string>Требуется доступ к Bluetooth для подключения к принтерам и печати чеков</string>
|
||||
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||
<string>Требуется доступ к Bluetooth для подключения к принтерам и печати чеков</string>
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Требуется доступ к камере для сканирования QR-кодов и штрих-кодов</string>
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>bluetooth-central</string>
|
||||
<string>bluetooth-peripheral</string>
|
||||
</array>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ const String Voucher_columnUrl = 'url';
|
|||
const String VoucherTypePayment = 'payment';
|
||||
const String VoucherTypeReturnPay = 'returnPay';
|
||||
const String VoucherTypeReport = 'report';
|
||||
const String VoucherTypeCloseDayPosReport = 'closeDayPosReport';
|
||||
|
||||
class Voucher {
|
||||
int id;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
|
||||
|
||||
void main() {
|
||||
var date = "2021-01-14T12:15:34.511Z";
|
||||
|
||||
String text = '{'+
|
||||
'"amount": 5500,'+
|
||||
'"cardExpireDate": "09/22",'+
|
||||
'"cardNumber": "400303******6254",'+
|
||||
'"cardType": "VISA",'+
|
||||
'"date": "2021-01-14 12:22:09",'+
|
||||
'"transactionType": "PAYMENT"'+
|
||||
'}';
|
||||
|
||||
print(text);
|
||||
dynamic data = json.decode(text);
|
||||
TransactionItem item = TransactionItem.fromJson(data);
|
||||
|
||||
print(item.date);
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
|
||||
|
||||
import 'package:aman_kassa_flutter/core/services/BankService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||
|
||||
import '../core/services/DbService.dart';
|
||||
|
|
@ -32,5 +33,7 @@ class LocatorInjector {
|
|||
|
||||
_log.d('Initializing DataService Service');
|
||||
locator.registerLazySingleton<DataService>(() => DataService());
|
||||
_log.d('Initializing BankService Service');
|
||||
locator.registerLazySingleton<BankService>(() => BankService());
|
||||
}
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ class SimpleLogPrinter extends LogPrinter {
|
|||
}
|
||||
|
||||
String formatStackTrace(StackTrace stackTrace, int methodPosition) {
|
||||
|
||||
var lines = stackTrace.toString()?.split('\n');
|
||||
var formatted = <String>[];
|
||||
var count = 0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,17 @@
|
|||
class AmanDao<T> {
|
||||
final T data;
|
||||
final dynamic rows;
|
||||
final String msg;
|
||||
final bool success;
|
||||
|
||||
AmanDao({this.data, this.success, this.msg, this.rows});
|
||||
|
||||
|
||||
factory AmanDao.fromJson(Map<String, dynamic> data) {
|
||||
return AmanDao(
|
||||
data: data['data'],
|
||||
msg: data['msg'],
|
||||
success: data['success'],
|
||||
rows: data['rows']);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
class CardData {
|
||||
final int transactionNumber;
|
||||
final int operationDay;
|
||||
final int terminalId;
|
||||
final String cardNumber;
|
||||
final String cardholderName;
|
||||
final String authorizationCode;
|
||||
final String transactionType;
|
||||
|
||||
CardData({this.transactionNumber, this.operationDay, this.cardNumber, this.cardholderName, this.authorizationCode, this.terminalId, this.transactionType });
|
||||
|
||||
static CardData fromJson(Map<String, dynamic> json) {
|
||||
return json != null ?
|
||||
CardData(
|
||||
transactionNumber: json['transactionNumber'],
|
||||
operationDay: json['operationDay'],
|
||||
terminalId: json['terminalId'],
|
||||
cardNumber: json['cardNumber'],
|
||||
cardholderName: json['cardholderName'],
|
||||
authorizationCode: json['authorizationCode'],
|
||||
transactionType: json['transactionType'],
|
||||
)
|
||||
: null;
|
||||
}
|
||||
Map<String, dynamic> toJson() =>
|
||||
{
|
||||
'transactionNumber': transactionNumber,
|
||||
'operationDay': operationDay,
|
||||
'cardNumber': cardNumber,
|
||||
'cardholderName': cardholderName,
|
||||
'authorizationCode': authorizationCode,
|
||||
'terminalId' : terminalId,
|
||||
'transactionType' : transactionType,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,22 +1,26 @@
|
|||
import 'package:aman_kassa_flutter/core/models/card_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_item.dart';
|
||||
|
||||
class CheckData {
|
||||
final String type;
|
||||
num card;
|
||||
final List<CheckItem> items;
|
||||
CheckData({this.type, this.card, this.items});
|
||||
CardData cardData;
|
||||
CheckData({this.type, this.card, this.items, this.cardData});
|
||||
|
||||
static CheckData fromJson(Map<String, dynamic> json) {
|
||||
return CheckData(
|
||||
type: json['type'],
|
||||
card: json['card'],
|
||||
items: json['items'],
|
||||
items: (json['items'] as List).map((e) => CheckItem.fromJson(e)).toList(),
|
||||
cardData: CardData.fromJson(json['cardData'])
|
||||
);
|
||||
}
|
||||
Map<String, dynamic> toJson() =>
|
||||
{
|
||||
'type': type,
|
||||
'card': card,
|
||||
'items': items.map((e) => e.toJson()).toList()
|
||||
'items': items.map((e) => e.toJson()).toList(),
|
||||
'cardData': cardData!=null ? cardData.toJson() : null
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
class CheckImageModal {
|
||||
final String base64Data;
|
||||
final String textData;
|
||||
CheckImageModal({this.base64Data, this.textData});
|
||||
|
||||
static CheckImageModal fromJson(Map<String, dynamic> json) {
|
||||
return CheckImageModal(
|
||||
base64Data: json['base64Data'],
|
||||
textData: json['textData']
|
||||
);
|
||||
}
|
||||
Map<String, dynamic> toJson() =>
|
||||
{
|
||||
'base64Data': base64Data,
|
||||
'textData': textData
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
|
||||
|
||||
import 'halyk/halyk_close_day_dao.dart';
|
||||
|
||||
class CloseDayData {
|
||||
final String title;
|
||||
final num totalAmount;
|
||||
final int totalCount;
|
||||
final num paymentAmount;
|
||||
final int paymentCount;
|
||||
final num refundAmount;
|
||||
final int refundCount;
|
||||
final num cancelAmount;
|
||||
final int cancelCount;
|
||||
|
||||
final List<TransactionBean> items;
|
||||
CloseDayData({
|
||||
this.title,
|
||||
this.items,
|
||||
this.totalAmount, this.totalCount,
|
||||
this.paymentAmount, this.paymentCount,
|
||||
this.refundAmount, this.refundCount,
|
||||
this.cancelAmount, this.cancelCount
|
||||
});
|
||||
|
||||
static CloseDayData fromJson(Map<String, dynamic> json) {
|
||||
return CloseDayData(
|
||||
title: json['title'],
|
||||
totalAmount: json['totalAmount'],
|
||||
totalCount: json['totalCount'],
|
||||
paymentAmount: json['paymentAmount'],
|
||||
paymentCount: json['paymentCount'],
|
||||
refundAmount: json['refundAmount'],
|
||||
refundCount: json['refundCount'],
|
||||
cancelAmount: json['cancelAmount'],
|
||||
cancelCount: json['cancelCount'],
|
||||
items: (json['items'] as List).map((e) => TransactionBean.fromMap(e)).toList(),
|
||||
);
|
||||
}
|
||||
Map<String, dynamic> toJson() =>
|
||||
{
|
||||
'title': title,
|
||||
'totalAmount': totalAmount,
|
||||
'totalCount': totalCount,
|
||||
'paymentAmount': paymentAmount,
|
||||
'paymentCount': paymentCount,
|
||||
'refundAmount': refundAmount,
|
||||
'refundCount': refundCount,
|
||||
'cancelAmount': cancelAmount,
|
||||
'cancelCount': cancelCount,
|
||||
'items': items.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
/// result : {"code":"0","description":"Successfully completed"}
|
||||
/// transactions : {"transaction":[{"type":"PAYMENT","instrument":"CARD","amount":"6000","terminalId":"123321","operationDay":"4","transactionNumber":"69","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}},{"type":"REFUND","instrument":"CARD","amount":"4500","terminalId":"123321","operationDay":"4","transactionNumber":"70","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"},"parentTransaction":{"terminalId":"123321","operationDay":"4","transactionNumber":"69"}}]}
|
||||
/// closeDayResults : {"reconciliationResult":[{"hostResultCode":"000","hostResultDescription":"Success","terminalExternalId":"example_terminal_id"}]}
|
||||
|
||||
class HalykCloseDayDao {
|
||||
ResultBean result;
|
||||
TransactionsBean transactions;
|
||||
CloseDayResultsBean closeDayResults;
|
||||
|
||||
HalykCloseDayDao({ this.result, this.closeDayResults, this.transactions});
|
||||
|
||||
static HalykCloseDayDao fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
HalykCloseDayDao halykCloseDayDaoBean = HalykCloseDayDao();
|
||||
halykCloseDayDaoBean.result = ResultBean.fromMap(map['result']);
|
||||
halykCloseDayDaoBean.transactions = TransactionsBean.fromMap(map['transactions']);
|
||||
halykCloseDayDaoBean.closeDayResults = CloseDayResultsBean.fromMap(map['closeDayResults']);
|
||||
return halykCloseDayDaoBean;
|
||||
}
|
||||
|
||||
Map toJson() => {
|
||||
"result": result,
|
||||
"transactions": transactions,
|
||||
"closeDayResults": closeDayResults,
|
||||
};
|
||||
}
|
||||
|
||||
/// reconciliationResult : [{"hostResultCode":"000","hostResultDescription":"Success","terminalExternalId":"example_terminal_id"}]
|
||||
|
||||
class CloseDayResultsBean {
|
||||
List<ReconciliationResultBean> reconciliationResult;
|
||||
|
||||
static CloseDayResultsBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
CloseDayResultsBean closeDayResultsBean = CloseDayResultsBean();
|
||||
closeDayResultsBean.reconciliationResult = List()..addAll(
|
||||
(map['reconciliationResult'] as List ?? []).map((o) => ReconciliationResultBean.fromMap(o))
|
||||
);
|
||||
return closeDayResultsBean;
|
||||
}
|
||||
|
||||
Map toJson() => {
|
||||
"reconciliationResult": reconciliationResult,
|
||||
};
|
||||
}
|
||||
|
||||
/// hostResultCode : "000"
|
||||
/// hostResultDescription : "Success"
|
||||
/// terminalExternalId : "example_terminal_id"
|
||||
|
||||
class ReconciliationResultBean {
|
||||
String hostResultCode;
|
||||
String hostResultDescription;
|
||||
String terminalExternalId;
|
||||
|
||||
static ReconciliationResultBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
ReconciliationResultBean reconciliationResultBean = ReconciliationResultBean();
|
||||
reconciliationResultBean.hostResultCode = map['hostResultCode'];
|
||||
reconciliationResultBean.hostResultDescription = map['hostResultDescription'];
|
||||
reconciliationResultBean.terminalExternalId = map['terminalExternalId'];
|
||||
return reconciliationResultBean;
|
||||
}
|
||||
|
||||
Map toJson() => {
|
||||
"hostResultCode": hostResultCode,
|
||||
"hostResultDescription": hostResultDescription,
|
||||
"terminalExternalId": terminalExternalId,
|
||||
};
|
||||
}
|
||||
|
||||
/// transaction : [{"type":"PAYMENT","instrument":"CARD","amount":"6000","terminalId":"123321","operationDay":"4","transactionNumber":"69","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}},{"type":"REFUND","instrument":"CARD","amount":"4500","terminalId":"123321","operationDay":"4","transactionNumber":"70","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"},"parentTransaction":{"terminalId":"123321","operationDay":"4","transactionNumber":"69"}}]
|
||||
|
||||
class TransactionsBean {
|
||||
List<TransactionBean> transaction;
|
||||
|
||||
static TransactionsBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
TransactionsBean transactionsBean = TransactionsBean();
|
||||
transactionsBean.transaction = List()..addAll(
|
||||
(map['transaction'] as List ?? []).map((o) => TransactionBean.fromMap(o))
|
||||
);
|
||||
return transactionsBean;
|
||||
}
|
||||
|
||||
Map toJson() => {
|
||||
"transaction": transaction,
|
||||
};
|
||||
}
|
||||
|
||||
/// type : "PAYMENT"
|
||||
/// instrument : "CARD"
|
||||
/// amount : "6000"
|
||||
/// terminalId : "123321"
|
||||
/// operationDay : "4"
|
||||
/// transactionNumber : "69"
|
||||
/// instrumentSpecificData : {"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}
|
||||
|
||||
class TransactionBean {
|
||||
String type;
|
||||
String instrument;
|
||||
num amount;
|
||||
int terminalId;
|
||||
int operationDay;
|
||||
int transactionNumber;
|
||||
InstrumentSpecificDataBean instrumentSpecificData;
|
||||
|
||||
static TransactionBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
TransactionBean transactionBean = TransactionBean();
|
||||
transactionBean.type = map['type'];
|
||||
transactionBean.instrument = map['instrument'];
|
||||
transactionBean.amount = map['amount'];
|
||||
transactionBean.terminalId = map['terminalId'];
|
||||
transactionBean.operationDay = map['operationDay'];
|
||||
transactionBean.transactionNumber = map['transactionNumber'];
|
||||
transactionBean.instrumentSpecificData = InstrumentSpecificDataBean.fromMap(map['instrumentSpecificData']);
|
||||
return transactionBean;
|
||||
}
|
||||
|
||||
Map toJson() => {
|
||||
"type": type,
|
||||
"instrument": instrument,
|
||||
"amount": amount,
|
||||
"terminalId": terminalId,
|
||||
"operationDay": operationDay,
|
||||
"transactionNumber": transactionNumber,
|
||||
"instrumentSpecificData": instrumentSpecificData,
|
||||
};
|
||||
}
|
||||
|
||||
/// authorizationCode : "000000"
|
||||
/// rrn : "1234567890"
|
||||
/// cardholderName : "IVAN IVANOV"
|
||||
/// maskedPan : "123456******7890"
|
||||
|
||||
class InstrumentSpecificDataBean {
|
||||
String authorizationCode;
|
||||
String rrn;
|
||||
String cardholderName;
|
||||
String maskedPan;
|
||||
|
||||
static InstrumentSpecificDataBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
InstrumentSpecificDataBean instrumentSpecificDataBean = InstrumentSpecificDataBean();
|
||||
instrumentSpecificDataBean.authorizationCode = map['authorizationCode'];
|
||||
instrumentSpecificDataBean.rrn = map['rrn'];
|
||||
instrumentSpecificDataBean.cardholderName = map['cardholderName'];
|
||||
instrumentSpecificDataBean.maskedPan = map['maskedPan'];
|
||||
return instrumentSpecificDataBean;
|
||||
}
|
||||
|
||||
Map toJson() => {
|
||||
"authorizationCode": authorizationCode,
|
||||
"rrn": rrn,
|
||||
"cardholderName": cardholderName,
|
||||
"maskedPan": maskedPan,
|
||||
};
|
||||
}
|
||||
|
||||
/// code : "0"
|
||||
/// description : "Successfully completed"
|
||||
|
||||
class ResultBean {
|
||||
int code;
|
||||
String description;
|
||||
|
||||
ResultBean({this.code, this.description});
|
||||
|
||||
static ResultBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
ResultBean resultBean = ResultBean();
|
||||
resultBean.code = map['code'];
|
||||
resultBean.description = map['description'];
|
||||
return resultBean;
|
||||
}
|
||||
|
||||
Map toJson() => {
|
||||
"code": code,
|
||||
"description": description,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
import 'package:intl/intl.dart';
|
||||
|
||||
class HalykPosSession {
|
||||
const HalykPosSession(
|
||||
{this.login,
|
||||
this.token,
|
||||
this.serverTime,
|
||||
this.tokenTimeout,
|
||||
this.result});
|
||||
|
||||
final String login;
|
||||
final String token;
|
||||
final DateTime serverTime;
|
||||
final int tokenTimeout;
|
||||
final ResultBean result;
|
||||
|
||||
static HalykPosSession fromJson(Map<String, dynamic> data) => HalykPosSession(
|
||||
login: data['login'],
|
||||
token: data['token'],
|
||||
result: ResultBean.fromMap(data['result']),
|
||||
serverTime: data['ServerTime'] != null
|
||||
? new DateFormat("dd.MM.yyyy HH:mm:ss ZZZ").parse(data['ServerTime'])
|
||||
: null,
|
||||
tokenTimeout: data['TokenTimeout']);
|
||||
}
|
||||
|
||||
/// ServerTime : "25.06.2021 13:18:00 GMT+06:00"
|
||||
/// ResultCode : "040"
|
||||
/// ResultStr : "Unknown operator login. Check the correctness of the data or contact support."
|
||||
/// Response : {"Code":"040","Description":"Unknown operator login. Check the correctness of the data or contact support."}
|
||||
|
||||
class ResultBean {
|
||||
String ServerTime;
|
||||
String ResultCode;
|
||||
String ResultStr;
|
||||
ResponseBean Response;
|
||||
|
||||
static ResultBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
ResultBean resultBean = ResultBean();
|
||||
resultBean.ServerTime = map['ServerTime'];
|
||||
resultBean.ResultCode = map['ResultCode'];
|
||||
resultBean.ResultStr = map['ResultStr'];
|
||||
resultBean.Response = ResponseBean.fromMap(map['Response']);
|
||||
return resultBean;
|
||||
}
|
||||
|
||||
Map toJson() => {
|
||||
"ServerTime": ServerTime,
|
||||
"ResultCode": ResultCode,
|
||||
"ResultStr": ResultStr,
|
||||
"Response": Response,
|
||||
};
|
||||
}
|
||||
|
||||
/// Code : "040"
|
||||
/// Description : "Unknown operator login. Check the correctness of the data or contact support."
|
||||
|
||||
class ResponseBean {
|
||||
String Code;
|
||||
String Description;
|
||||
|
||||
static ResponseBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
ResponseBean responseBean = ResponseBean();
|
||||
responseBean.Code = map['Code'];
|
||||
responseBean.Description = map['Description'];
|
||||
return responseBean;
|
||||
}
|
||||
|
||||
Map toJson() => {
|
||||
"Code": Code,
|
||||
"Description": Description,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/// result : {"code":"0","description":"Successfully completed","hostResponse":{"code":"0","description":"Successfully completed"}}
|
||||
/// transaction : {"terminalId":"123321","operationDay":"4","transactionNumber":"69","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}}
|
||||
|
||||
class HalykResponse {
|
||||
ResultBean result;
|
||||
TransactionBean transaction;
|
||||
|
||||
HalykResponse({this.result, this.transaction});
|
||||
|
||||
static HalykResponse fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
HalykResponse halykResponseBean = HalykResponse();
|
||||
halykResponseBean.result = ResultBean.fromMap(map['result']);
|
||||
halykResponseBean.transaction = TransactionBean.fromMap(map['transaction']);
|
||||
return halykResponseBean;
|
||||
}
|
||||
|
||||
Map toJson() =>
|
||||
{
|
||||
"result": result,
|
||||
"transaction": transaction,
|
||||
};
|
||||
}
|
||||
|
||||
/// terminalId : "123321"
|
||||
/// operationDay : "4"
|
||||
/// transactionNumber : "69"
|
||||
/// instrumentSpecificData : {"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}
|
||||
|
||||
class TransactionBean {
|
||||
int terminalId;
|
||||
int operationDay;
|
||||
int transactionNumber;
|
||||
InstrumentSpecificDataBean instrumentSpecificData;
|
||||
|
||||
static TransactionBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
TransactionBean transactionBean = TransactionBean();
|
||||
transactionBean.terminalId = map['terminalId'];
|
||||
transactionBean.operationDay = map['operationDay'];
|
||||
transactionBean.transactionNumber = map['transactionNumber'];
|
||||
transactionBean.instrumentSpecificData = InstrumentSpecificDataBean.fromMap(map['instrumentSpecificData']);
|
||||
return transactionBean;
|
||||
}
|
||||
|
||||
Map toJson() =>
|
||||
{
|
||||
"terminalId": terminalId,
|
||||
"operationDay": operationDay,
|
||||
"transactionNumber": transactionNumber,
|
||||
"instrumentSpecificData": instrumentSpecificData,
|
||||
};
|
||||
}
|
||||
|
||||
/// authorizationCode : "000000"
|
||||
/// rrn : "1234567890"
|
||||
/// cardholderName : "IVAN IVANOV"
|
||||
/// maskedPan : "123456******7890"
|
||||
|
||||
class InstrumentSpecificDataBean {
|
||||
String authorizationCode;
|
||||
String rrn;
|
||||
String cardholderName;
|
||||
String maskedPan;
|
||||
|
||||
static InstrumentSpecificDataBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
InstrumentSpecificDataBean instrumentSpecificDataBean = InstrumentSpecificDataBean();
|
||||
instrumentSpecificDataBean.authorizationCode = map['authorizationCode'];
|
||||
instrumentSpecificDataBean.rrn = map['rrn'];
|
||||
instrumentSpecificDataBean.cardholderName = map['cardholderName'];
|
||||
instrumentSpecificDataBean.maskedPan = map['maskedPan'];
|
||||
return instrumentSpecificDataBean;
|
||||
}
|
||||
|
||||
Map toJson() =>
|
||||
{
|
||||
"authorizationCode": authorizationCode,
|
||||
"rrn": rrn,
|
||||
"cardholderName": cardholderName,
|
||||
"maskedPan": maskedPan,
|
||||
};
|
||||
}
|
||||
|
||||
/// code : "0"
|
||||
/// description : "Successfully completed"
|
||||
/// hostResponse : {"code":"0","description":"Successfully completed"}
|
||||
|
||||
class ResultBean {
|
||||
int code;
|
||||
String description;
|
||||
HostResponseBean hostResponse;
|
||||
ErrorResponseBean errorData;
|
||||
|
||||
ResultBean({this.code, this.description});
|
||||
|
||||
static ResultBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
ResultBean resultBean = ResultBean();
|
||||
resultBean.code = map['code'];
|
||||
resultBean.description = map['description'];
|
||||
resultBean.hostResponse = HostResponseBean.fromMap(map['hostResponse']);
|
||||
resultBean.errorData = ErrorResponseBean.fromMap(map['errorData']);
|
||||
return resultBean;
|
||||
}
|
||||
|
||||
Map toJson() =>
|
||||
{
|
||||
"code": code,
|
||||
"description": description,
|
||||
"hostResponse": hostResponse,
|
||||
"errorData": errorData,
|
||||
};
|
||||
}
|
||||
|
||||
/// code : "0"
|
||||
/// description : "Successfully completed"
|
||||
|
||||
class HostResponseBean {
|
||||
String code;
|
||||
String description;
|
||||
|
||||
static HostResponseBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
HostResponseBean hostResponseBean = HostResponseBean();
|
||||
hostResponseBean.code = map['code'];
|
||||
hostResponseBean.description = map['description'];
|
||||
return hostResponseBean;
|
||||
}
|
||||
|
||||
Map toJson() =>
|
||||
{
|
||||
"code": code,
|
||||
"description": description,
|
||||
};
|
||||
}
|
||||
|
||||
class ErrorResponseBean {
|
||||
int code;
|
||||
String description;
|
||||
|
||||
static ErrorResponseBean fromMap(Map<String, dynamic> map) {
|
||||
if (map == null) return null;
|
||||
ErrorResponseBean errorResponseBean = ErrorResponseBean();
|
||||
errorResponseBean.code = map['code'];
|
||||
errorResponseBean.description = map['description'];
|
||||
return errorResponseBean;
|
||||
}
|
||||
|
||||
Map toJson() =>
|
||||
{
|
||||
"code": code,
|
||||
"description": description,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
class SettingModel {
|
||||
const SettingModel({this.name, this.type, this.address});
|
||||
final String type;
|
||||
final String name;
|
||||
final String address;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
class TransactionItem {
|
||||
final String cardType;
|
||||
final String cardExpireDate;
|
||||
final String cardNumber;
|
||||
final String transactionType;
|
||||
final num amount;
|
||||
final DateTime date;
|
||||
TransactionItem({this.cardType, this.cardExpireDate, this.cardNumber, this.transactionType, this.amount, this.date});
|
||||
|
||||
static TransactionItem fromJson(Map<String, dynamic> json) {
|
||||
return TransactionItem(
|
||||
cardType: json['cardType'],
|
||||
cardExpireDate: json['cardExpireDate'],
|
||||
cardNumber: json['cardNumber'],
|
||||
transactionType: json['transactionType'],
|
||||
amount: json['amount'],
|
||||
date: json['date'] != null
|
||||
? DateTime.parse(json['date'])
|
||||
: null,
|
||||
);
|
||||
}
|
||||
Map<String, dynamic> toJson() =>
|
||||
{
|
||||
'cardType': cardType,
|
||||
'cardExpireDate': cardExpireDate,
|
||||
'cardNumber': cardNumber,
|
||||
'transactionType': transactionType,
|
||||
'amount': amount,
|
||||
'date' : date !=null ? date.toString() : null,
|
||||
};
|
||||
}
|
||||
|
|
@ -1,8 +1,19 @@
|
|||
const String LoginViewRoute = "LoginView";
|
||||
const String HomeViewRoute = "HomeView";
|
||||
const String ImageShowRoute = "ImageShowRoute";
|
||||
const String CloseDayShowRoute = "CloseDayShowRoute";
|
||||
const String PaymentViewRoute = "PaymentView";
|
||||
const String PaymentNfcViewRoute = "PaymentNfcViewRoute";
|
||||
const String HistoryViewRoute = "HistoryView";
|
||||
const String InfoKkmViewRoute = "InfoKkmViewRoute";
|
||||
const String SettingsViewRoute = "SettingsViewRoute";
|
||||
const String QrViewRoute = "QrViewRoute";
|
||||
const String BankViewRoute = "BankViewRoute";
|
||||
const String BankSettingViewRoute = "BankSettingViewRoute";
|
||||
|
||||
|
||||
const String SettingsPrinterRoute = "SettingsPrinterRoute";
|
||||
const String SettingsPrinterBTRoute = "SettingsPrinterBTRoute";
|
||||
const String SettingsPrinterEncodingRoute = "SettingsPrinterEncodingRoute";
|
||||
const String SettingsPrinterPaperRoute = "SettingsPrinterPaperRoute";
|
||||
// Generate the views here
|
||||
|
|
|
|||
|
|
@ -1,13 +1,23 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/close_day_data.dart';
|
||||
import 'package:aman_kassa_flutter/views/bank_setting/bank_setting_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/bank_view/bank_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
|
||||
import "package:aman_kassa_flutter/views/home/home_view_m.dart";
|
||||
import 'package:aman_kassa_flutter/views/close_day_view/close_day_show_container.dart';
|
||||
import 'package:aman_kassa_flutter/views/history/history_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/info_kkm/info_kkm_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/payment/payment_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/payment_nfc/payment_nfc_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/qr_view/qr_view.dart';
|
||||
|
||||
import './route_names.dart';
|
||||
import 'package:aman_kassa_flutter/views/home/home_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/settings/printer/views/PrinterSelect.dart';
|
||||
import 'package:aman_kassa_flutter/views/settings/settings_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/settings/printer/views/PrinterEncoding.dart';
|
||||
import 'package:aman_kassa_flutter/views/settings/printer/views/PrinterPaperSize.dart';
|
||||
import 'package:aman_kassa_flutter/views/settings/setting_printer_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/login/login_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import './route_names.dart';
|
||||
|
||||
|
||||
Route<dynamic> generateRoute(RouteSettings settings) {
|
||||
switch (settings.name) {
|
||||
|
|
@ -15,7 +25,9 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
|||
LoginModel model = settings.arguments as LoginModel;
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: LoginView(loginModel: model,),
|
||||
viewToShow: LoginView(
|
||||
loginModel: model,
|
||||
),
|
||||
);
|
||||
case HomeViewRoute:
|
||||
return _getPageRoute(
|
||||
|
|
@ -28,6 +40,12 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
|||
routeName: settings.name,
|
||||
viewToShow: PaymentView(model: model),
|
||||
);
|
||||
case PaymentNfcViewRoute:
|
||||
PaymentModel model = settings.arguments as PaymentModel;
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: PaymentNfcView(model: model),
|
||||
);
|
||||
case HistoryViewRoute:
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
|
|
@ -38,6 +56,21 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
|||
routeName: settings.name,
|
||||
viewToShow: InfoKkmView(),
|
||||
);
|
||||
case SettingsViewRoute:
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: SettingView(),
|
||||
);
|
||||
case BankViewRoute:
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: BankView(),
|
||||
);
|
||||
case BankSettingViewRoute:
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: BankSettingView(),
|
||||
);
|
||||
case QrViewRoute:
|
||||
ImageShowModel data = settings.arguments as ImageShowModel;
|
||||
return _getPageRoute(
|
||||
|
|
@ -51,6 +84,32 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
|||
routeName: settings.name,
|
||||
viewToShow: ImageShowContainer(data),
|
||||
);
|
||||
case SettingsPrinterRoute:
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: SettingPrinterView(),
|
||||
);
|
||||
case SettingsPrinterBTRoute:
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: PrinterSelectView(),
|
||||
);
|
||||
case SettingsPrinterEncodingRoute:
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: PrinterEncodingView(),
|
||||
);
|
||||
case SettingsPrinterPaperRoute:
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: PrinterPaperView(),
|
||||
);
|
||||
case CloseDayShowRoute:
|
||||
CloseDayData data = settings.arguments as CloseDayData;
|
||||
return _getPageRoute(
|
||||
routeName: settings.name,
|
||||
viewToShow: CloseDayShowContainer(data),
|
||||
);
|
||||
default:
|
||||
return MaterialPageRoute(
|
||||
builder: (_) => Scaffold(
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@ import 'dart:convert';
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/user_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
import 'package:aman_kassa_flutter/views/login/login_view.dart';
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:device_info/device_info.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/message.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||
|
|
@ -17,12 +19,14 @@ import '../models/auth_response.dart';
|
|||
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
/// The service responsible for networking requests
|
||||
/// The service responsible fworking requests
|
||||
class ApiService extends BaseService {
|
||||
static const test_host = 'https://kassa-test.aman.com.kz';
|
||||
static const test_endpoint = '$test_host/ru/api/v2';
|
||||
static const host = 'https://kassa.aman.com.kz';
|
||||
static const endpoint = '$host/ru/api/v2';
|
||||
|
||||
static const pos_endpoint = 'https://partner.aman.com.kz/api';
|
||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
|
||||
|
|
@ -63,6 +67,18 @@ class ApiService extends BaseService {
|
|||
return Response.fromJsonDynamic(json.decode(response));
|
||||
}
|
||||
|
||||
Future<HalykPosSession> halykPosToken(String token, login, password) async {
|
||||
String salt = '!=uF:w1N_Salh?1gVSJ#eGfJYHA(wS4D';
|
||||
String hash = md5.convert(utf8.encode('$login$salt')).toString();
|
||||
print(hash);
|
||||
|
||||
Map<String, String> requestBody = <String, String>{'login': login, 'hash': hash};
|
||||
//var response = await requestFormData('/halykpos/gettoken', requestBody, bodyEntry: true, posEndPoint: true, statusCheck: false);
|
||||
var response = await requestFormData('/hb/pos/gettoken', requestBody, bodyEntry: true, posEndPoint: true, statusCheck: false);
|
||||
print(response);
|
||||
return HalykPosSession.fromJson(jsonDecode(response));
|
||||
}
|
||||
|
||||
Future<Response<dynamic>> money(String token) async {
|
||||
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||
var response = await requestFormData('/money', requestBody);
|
||||
|
|
@ -124,15 +140,17 @@ class ApiService extends BaseService {
|
|||
}
|
||||
|
||||
|
||||
Future<String> requestFormData(String point, Map<String, String> requestBody, { bool statusCheck = true } ) async {
|
||||
Future<String> requestFormData(String point, Map<String, dynamic> requestBody, { bool statusCheck = true, bool bodyEntry = false, bool posEndPoint= false } ) async {
|
||||
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
|
||||
|
||||
|
||||
Map<String, String> headers = <String, String>{
|
||||
HttpHeaders.contentTypeHeader: "multipart/form-data",
|
||||
HttpHeaders.contentTypeHeader: bodyEntry ? "application/json" : "multipart/form-data",
|
||||
HttpHeaders.cacheControlHeader: "no-cache"
|
||||
};
|
||||
|
||||
|
||||
|
||||
if(Platform.isAndroid) {
|
||||
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
|
||||
headers.addAll(<String, String>{
|
||||
|
|
@ -153,14 +171,26 @@ class ApiService extends BaseService {
|
|||
if(this._test) {
|
||||
url = '$test_endpoint$point';
|
||||
}
|
||||
if(posEndPoint){
|
||||
url = '$pos_endpoint$point';
|
||||
}
|
||||
var uri = Uri.parse(url);
|
||||
var request = http.MultipartRequest('POST', uri)
|
||||
..headers.addAll(headers)
|
||||
..fields.addAll(requestBody);
|
||||
|
||||
var response = await request.send();
|
||||
String body;
|
||||
|
||||
if(bodyEntry) {
|
||||
http.Response res = await http.post(uri, body: jsonEncode(requestBody), headers: headers );
|
||||
body = res.body;
|
||||
} else {
|
||||
var request = http.MultipartRequest('POST', uri)
|
||||
..headers.addAll(headers)
|
||||
..fields.addAll(requestBody);
|
||||
var response = await request.send();
|
||||
body = await response.stream.bytesToString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
String body = await response.stream.bytesToString();
|
||||
if(statusCheck) { //Проверка на авторизованный запрос, необязательный параметр
|
||||
Response check = Response.fromJsonDynamic(json.decode(body));
|
||||
if (!check.operation && ( [401,402,403,412].contains(check.status) ) ) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,143 @@
|
|||
import 'dart:convert';
|
||||
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/close_day_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart' as Cd;
|
||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart' as Ps;
|
||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_response_dao.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../models/aman_dao.dart';
|
||||
|
||||
|
||||
class BankService extends BaseService {
|
||||
int sdkVersion = 27;
|
||||
final ApiService _api = locator<ApiService>();
|
||||
final MethodChannel _channel = MethodChannel('channel:com.amanKassa/bank');
|
||||
|
||||
|
||||
Future<int> version() async {
|
||||
String result;
|
||||
try {
|
||||
result = await _channel.invokeMethod('version');
|
||||
} catch (e, stack) {
|
||||
log.e("BankService", e, stack);
|
||||
result = '0';
|
||||
}
|
||||
log.i(result);
|
||||
return int.parse(result) ?? 0;
|
||||
}
|
||||
|
||||
Future<Ps.HalykPosSession> renewToken({String token, String login, String password}) async {
|
||||
Ps.HalykPosSession result;
|
||||
try {
|
||||
result = await _api.halykPosToken(token, login, password);
|
||||
} catch (e, stack) {
|
||||
log.e("BankService", e, stack);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Future<Cd.HalykCloseDayDao> closeDay({ String token}) async {
|
||||
try {
|
||||
String response = await _channel.invokeMethod("closeDay", <String, dynamic>{'token': token });
|
||||
log.i(response);
|
||||
Cd.HalykCloseDayDao dao = Cd.HalykCloseDayDao.fromMap(json.decode(response));
|
||||
return dao;
|
||||
} catch (e, stack) {
|
||||
log.e("BankService", e, stack);
|
||||
return new Cd.HalykCloseDayDao(result: Cd.ResultBean(description: 'Ошибка при закрытии дня', code: -1));
|
||||
}
|
||||
}
|
||||
|
||||
Future<HalykResponse> pay({double amount, String token}) async {
|
||||
try {
|
||||
|
||||
double total = amount * 100;
|
||||
log.i('total: $total, ${total.toInt()}');
|
||||
String response = await _channel.invokeMethod("pay", <String, dynamic>{'amount': total.toInt(), 'token': token });
|
||||
log.i(response);
|
||||
HalykResponse dao = HalykResponse.fromMap(json.decode(response));
|
||||
return dao;
|
||||
} catch (e, stack) {
|
||||
log.e("BankService", e, stack);
|
||||
return new HalykResponse(result: ResultBean(description: 'Ошибка оплаты', code: -1));
|
||||
}
|
||||
}
|
||||
|
||||
Future<HalykResponse> refund({double amount, String token, int terminalId, int operDay, int transNum }) async {
|
||||
try {
|
||||
String response = await _channel.invokeMethod("refund", <String, dynamic>{
|
||||
'amount': amount.toInt(), 'token': token , 'terminalId': terminalId, 'operDay': operDay, 'transNum': transNum
|
||||
});
|
||||
HalykResponse dao = HalykResponse.fromMap(json.decode(response));
|
||||
return dao;
|
||||
} catch (e, stack) {
|
||||
log.e("BankService", e, stack);
|
||||
return new HalykResponse(result: ResultBean(description: 'Ошибка при возврате', code: -1));
|
||||
}
|
||||
}
|
||||
|
||||
Future<HalykResponse> reversal({ String token, int terminalId, int operDay, int transNum }) async {
|
||||
try {
|
||||
String response = await _channel.invokeMethod("reversal", <String, dynamic>{
|
||||
'token': token , 'terminalId': terminalId, 'operDay': operDay, 'transNum': transNum
|
||||
});
|
||||
log.i(response);
|
||||
HalykResponse dao = HalykResponse.fromMap(json.decode(response));
|
||||
return dao;
|
||||
} catch (e, stack) {
|
||||
log.e("BankService", e, stack);
|
||||
return new HalykResponse(result: ResultBean(description: 'Ошибка при возврате', code: -1));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CloseDayData closeDayDataConvert(Cd.TransactionsBean transactions) {
|
||||
final DateFormat formatter = DateFormat('dd.MM.yyyy');
|
||||
final DateTime now = DateTime.now();
|
||||
final String formatted = formatter.format(now);
|
||||
List<Cd.TransactionBean> items = transactions.transaction;
|
||||
num totalAmount = 0;
|
||||
int totalCount = 0;
|
||||
num paymentAmount = 0;
|
||||
int paymentCount = 0;
|
||||
num refundAmount = 0;
|
||||
int refundCount = 0;
|
||||
num cancelAmount = 0;
|
||||
int cancelCount = 0;
|
||||
|
||||
for(Cd.TransactionBean item in items) {
|
||||
if(item.type == 'PAYMENT') {
|
||||
paymentCount++;
|
||||
paymentAmount += ( item.amount / 100 );
|
||||
totalAmount += ( item.amount / 100 );
|
||||
} else if(item.type == 'REFUND') {
|
||||
refundCount++;
|
||||
refundAmount += ( item.amount / 100 );
|
||||
totalAmount -= ( item.amount / 100 );
|
||||
} else if(item.type == 'REVERSAL') {
|
||||
cancelCount++;
|
||||
cancelAmount += ( item.amount / 100 );
|
||||
totalAmount -= ( item.amount / 100 );
|
||||
}
|
||||
totalCount++;
|
||||
}
|
||||
|
||||
CloseDayData closeDayData = new CloseDayData(
|
||||
items: items,
|
||||
title: 'Отчет POS от $formatted',
|
||||
totalAmount: totalAmount, totalCount: totalCount,
|
||||
paymentAmount: paymentAmount, paymentCount: paymentCount,
|
||||
refundAmount: refundAmount, refundCount: refundCount,
|
||||
cancelAmount: cancelAmount, cancelCount: cancelCount,
|
||||
);
|
||||
return closeDayData;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -7,7 +7,9 @@ import 'package:aman_kassa_flutter/core/entity/Service.dart';
|
|||
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/calc_model.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/card_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_item.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/product_dao.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||
|
|
@ -135,35 +137,22 @@ class DataService extends BaseService {
|
|||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Future<Response<dynamic>> sellOrReturn(
|
||||
{String paymentType,
|
||||
String tradeType,
|
||||
String token,
|
||||
List<ProductDao> kassaItems,
|
||||
List<CalcModel> calcItems,
|
||||
String operationType,
|
||||
String mode}) async {
|
||||
Future<Response<dynamic>> refundM4Bank(
|
||||
{
|
||||
String token,
|
||||
CheckData checkData,
|
||||
CardData cardData}) async {
|
||||
try {
|
||||
String data;
|
||||
if (mode == SettingModeKassa) {
|
||||
CheckData checkData = _transformProductsToCheckData(
|
||||
paymentType: paymentType, tradeType: tradeType, items: kassaItems);
|
||||
data = jsonEncode(checkData.toJson());
|
||||
} else if (mode == SettingModeCalc) {
|
||||
CheckData checkData = _transformCalcModelToCheckData(
|
||||
paymentType: paymentType, tradeType: tradeType, items: calcItems);
|
||||
data = jsonEncode(checkData.toJson());
|
||||
}
|
||||
var json = cardData.toJson();
|
||||
json['transactionType'] = VoucherTypeReturnPay;
|
||||
checkData.cardData = CardData.fromJson(json);
|
||||
String data = jsonEncode(checkData.toJson());
|
||||
|
||||
// log.i('token: $token');
|
||||
// log.i('data: $data');
|
||||
Response<dynamic> response = await (operationType == OperationTypePay
|
||||
? _api.sell(token, data)
|
||||
: _api.sellReturn(token, data));
|
||||
// log.i('response status: ${response.status}');
|
||||
// log.i('response operation: ${response.operation}');
|
||||
log.i('token: $token');
|
||||
log.i('data: $data');
|
||||
Response<dynamic> response = await _api.sellReturn(token, data);
|
||||
log.i('response status: ${response.status}');
|
||||
log.i('response operation: ${response.operation}');
|
||||
if (response.status == 200 && response.operation == true) {
|
||||
User user = Redux.store.state.userState.user;
|
||||
String check = response?.body['check'];
|
||||
|
|
@ -179,6 +168,69 @@ class DataService extends BaseService {
|
|||
base64Data: check,
|
||||
total: total,
|
||||
url: url,
|
||||
type: VoucherTypeReturnPay);
|
||||
}
|
||||
return response;
|
||||
} catch (e, stack) {
|
||||
log.e("sellOrReturn", e, stack);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
Future<Response<dynamic>> sellOrReturn(
|
||||
{String paymentType,
|
||||
String tradeType,
|
||||
String token,
|
||||
List<ProductDao> kassaItems,
|
||||
List<CalcModel> calcItems,
|
||||
String operationType,
|
||||
String mode,
|
||||
CardData cardData}) async {
|
||||
try {
|
||||
String data;
|
||||
if (mode == SettingModeKassa) {
|
||||
CheckData checkData = _transformProductsToCheckData(
|
||||
paymentType: paymentType, tradeType: tradeType, items: kassaItems);
|
||||
checkData.cardData = cardData;
|
||||
data = jsonEncode(checkData.toJson());
|
||||
} else if (mode == SettingModeCalc) {
|
||||
CheckData checkData = _transformCalcModelToCheckData(
|
||||
paymentType: paymentType, tradeType: tradeType, items: calcItems);
|
||||
checkData.cardData = cardData;
|
||||
data = jsonEncode(checkData.toJson());
|
||||
}
|
||||
|
||||
// log.i('token: $token');
|
||||
// log.i('data: $data');
|
||||
Response<dynamic> response = await (operationType == OperationTypePay
|
||||
? _api.sell(token, data)
|
||||
: _api.sellReturn(token, data));
|
||||
// log.i('response status: ${response.status}');
|
||||
// log.i('response operation: ${response.operation}');
|
||||
if (response.status == 200 && response.operation == true) {
|
||||
User user = Redux.store.state.userState.user;
|
||||
//check compare
|
||||
|
||||
String check = response?.body['check'];
|
||||
var checkText = response?.body['check_text'];
|
||||
CheckImageModal imageModal = new CheckImageModal( base64Data: check, textData: checkText !=null ? jsonEncode(checkText) : null );
|
||||
// journal analyze
|
||||
dynamic journal = response?.body['journal'];
|
||||
int checkNum = journal['check_num'];
|
||||
var summ = journal['summ'];
|
||||
// short url
|
||||
String url = response?.body['link'];
|
||||
// total
|
||||
double total = summ != null ? double.parse(summ.toString()) : 0.0;
|
||||
|
||||
//insert data to db
|
||||
this.insertVoucher(
|
||||
user: user,
|
||||
name: 'Чек №$checkNum',
|
||||
data: data,
|
||||
base64Data: jsonEncode(imageModal.toJson()),
|
||||
total: total,
|
||||
url: url,
|
||||
type: operationType == OperationTypeReturn
|
||||
? VoucherTypeReturnPay
|
||||
: VoucherTypePayment);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
//general
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:flutter_screenutil/screenutil_init.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
//service & tools
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
|
|
@ -21,6 +22,8 @@ import 'views/start_up/start_up_view.dart';
|
|||
|
||||
//main start
|
||||
void main() async {
|
||||
HttpOverrides.global = MyHttpOverrides();
|
||||
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
HttpOverrides.global = MyHttpOverrides();
|
||||
//initialize locator
|
||||
|
|
@ -35,6 +38,41 @@ void main() async {
|
|||
runApp(MainApplication());
|
||||
}
|
||||
|
||||
class MainApplication extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return StoreProvider<AppState>(
|
||||
store: Redux.store,
|
||||
child: ScreenUtilInit(
|
||||
designSize: Size(411.43, 683.43),
|
||||
allowFontScaling: false,
|
||||
builder: () => MaterialApp(
|
||||
theme: ThemeData(
|
||||
backgroundColor: backgroundColor,
|
||||
primaryColor: primaryColor,
|
||||
accentColor: yellowColor,
|
||||
scaffoldBackgroundColor: Colors.white,
|
||||
textTheme: GoogleFonts.latoTextTheme(
|
||||
Theme.of(context).textTheme,
|
||||
)
|
||||
),
|
||||
debugShowCheckedModeBanner: false,
|
||||
builder: (context, child) => Navigator(
|
||||
key: locator<DialogService>().dialogNavigationKey,
|
||||
onGenerateRoute: (settings) => MaterialPageRoute(
|
||||
builder: (context) => DialogManager(child: child)),
|
||||
),
|
||||
navigatorKey: locator<NavigatorService>().navigatorKey,
|
||||
home: StartUpView(), // first page
|
||||
onGenerateRoute: generateRoute,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHttpOverrides extends HttpOverrides{
|
||||
@override
|
||||
HttpClient createHttpClient(SecurityContext context){
|
||||
|
|
@ -42,34 +80,3 @@ class MyHttpOverrides extends HttpOverrides{
|
|||
..badCertificateCallback = (X509Certificate cert, String host, int port)=> true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MainApplication extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StoreProvider<AppState>(
|
||||
store: Redux.store,
|
||||
child: MaterialApp(
|
||||
theme: ThemeData(
|
||||
backgroundColor: backgroundColor,
|
||||
primaryColor: primaryColor,
|
||||
accentColor: yellowColor,
|
||||
scaffoldBackgroundColor: Colors.white,
|
||||
textTheme: GoogleFonts.latoTextTheme(
|
||||
Theme.of(context).textTheme,
|
||||
)
|
||||
),
|
||||
debugShowCheckedModeBanner: false,
|
||||
builder: (context, child) => Navigator(
|
||||
key: locator<DialogService>().dialogNavigationKey,
|
||||
onGenerateRoute: (settings) => MaterialPageRoute(
|
||||
builder: (context) => DialogManager(child: child)),
|
||||
),
|
||||
navigatorKey: locator<NavigatorService>().navigatorKey,
|
||||
home: StartUpView(), // first page
|
||||
onGenerateRoute: generateRoute,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
import 'package:redux_thunk/redux_thunk.dart';
|
||||
|
||||
import '../store.dart';
|
||||
|
||||
@immutable
|
||||
class SetBankStateAction {
|
||||
final BankState bankState;
|
||||
SetBankStateAction(this.bankState);
|
||||
}
|
||||
|
||||
ThunkAction<AppState> saveData(String login, String password) {
|
||||
return (Store<AppState> store) async {
|
||||
store.dispatch(SetBankStateAction(BankState(login: login, password: password)));
|
||||
};
|
||||
}
|
||||
|
||||
ThunkAction<AppState> setHalykSession(HalykPosSession session) {
|
||||
return (Store<AppState> store) async {
|
||||
store.dispatch(SetBankStateAction(BankState(session: session)));
|
||||
};
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
|||
import 'package:meta/meta.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
import 'package:redux_thunk/redux_thunk.dart';
|
||||
|
||||
import 'package:flutter_bluetooth_basic/src/bluetooth_device.dart';
|
||||
import '../store.dart';
|
||||
|
||||
@immutable
|
||||
|
|
@ -24,3 +24,39 @@ ThunkAction<AppState> changeTradeTypeFromSetting(String tradeType) {
|
|||
store.dispatch(SetSettingStateAction(SettingState(tradeType: tradeType )));
|
||||
};
|
||||
}
|
||||
|
||||
ThunkAction<AppState> changePinCodeFromSetting(String pinCode) {
|
||||
return (Store<AppState> store) async {
|
||||
store.dispatch(SetSettingStateAction(SettingState(pinCode: pinCode)));
|
||||
};
|
||||
}
|
||||
|
||||
ThunkAction<AppState> changePinLockedFromSetting(bool locked) {
|
||||
return (Store<AppState> store) async {
|
||||
store.dispatch(SetSettingStateAction(SettingState(pinLocked: locked)));
|
||||
};
|
||||
}
|
||||
|
||||
ThunkAction<AppState> changePinSkipFromSetting(bool skip) {
|
||||
return (Store<AppState> store) async {
|
||||
store.dispatch(SetSettingStateAction(SettingState(pinSkip: skip)));
|
||||
};
|
||||
}
|
||||
|
||||
ThunkAction<AppState> selectPrinterFromSetting(BluetoothDevice device) {
|
||||
return (Store<AppState> store) async {
|
||||
store.dispatch(SetSettingStateAction(SettingState(printerBT: device )));
|
||||
};
|
||||
}
|
||||
|
||||
ThunkAction<AppState> selectPrinterEncodingFromSetting(String encoding) {
|
||||
return (Store<AppState> store) async {
|
||||
store.dispatch(SetSettingStateAction(SettingState(printerEncoding: encoding )));
|
||||
};
|
||||
}
|
||||
|
||||
ThunkAction<AppState> selectPrinterPaperSizeFromSetting(String paperSize) {
|
||||
return (Store<AppState> store) async {
|
||||
store.dispatch(SetSettingStateAction(SettingState(printerPaperSize: paperSize )));
|
||||
};
|
||||
}
|
||||
|
|
@ -72,7 +72,7 @@ Future<void> logoutAction(Store<AppState> store) async {
|
|||
UserState(
|
||||
isLoading: false,
|
||||
isAuthenticated: false,
|
||||
user: User(),
|
||||
user: User()
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -4,3 +4,16 @@ const String SettingModeCalc = 'calcMode';
|
|||
|
||||
const String SettingTradeTypeGood = 'g';
|
||||
const String SettingTradeTypeService = 's';
|
||||
|
||||
|
||||
const String SettingPrinterEncodingCp866 = 'cp866';
|
||||
const String SettingPrinterEncodingWin1251 = 'windows-1251';
|
||||
const String SettingPrinterEncodingImage = 'image';
|
||||
|
||||
const String SettingPrinterPaperM58 = '58mm';
|
||||
const String SettingPrinterPaperM80 = '80mm';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
import 'package:aman_kassa_flutter/redux/actions/bank_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
|
||||
|
||||
bankReducer(BankState prevState, SetBankStateAction action) {
|
||||
final payload = action.bankState;
|
||||
return prevState.copyWith(login: payload.login, password: payload.password, session: payload.session);
|
||||
}
|
||||
|
|
@ -5,6 +5,12 @@ settingReducer(SettingState prevState, SetSettingStateAction action) {
|
|||
final payload = action.settingState;
|
||||
return prevState.copyWith(
|
||||
mode: payload.mode,
|
||||
tradeType: payload.tradeType
|
||||
tradeType: payload.tradeType,
|
||||
pinCode: payload.pinCode,
|
||||
pinLocked: payload.pinLocked,
|
||||
pinSkip: payload.pinSkip,
|
||||
printerBT: payload.printerBT,
|
||||
printerEncoding: payload.printerEncoding,
|
||||
printerPaperSize: payload.printerPaperSize,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
|
||||
@immutable
|
||||
class BankState {
|
||||
final String login;
|
||||
final String password;
|
||||
final HalykPosSession session;
|
||||
|
||||
BankState({this.login, this.password, this.session,});
|
||||
|
||||
//read hive
|
||||
factory BankState.initial(BankState payload) {
|
||||
return BankState(
|
||||
login: payload?.login,
|
||||
password: payload?.password,
|
||||
session: payload?.session
|
||||
);
|
||||
}
|
||||
|
||||
//write hive
|
||||
BankState copyWith({
|
||||
@required login,
|
||||
@required password,
|
||||
@required session,
|
||||
}) {
|
||||
return BankState(
|
||||
login: login ?? this.login,
|
||||
password: password ?? this.password,
|
||||
session: session ?? this.session
|
||||
);
|
||||
}
|
||||
|
||||
static BankState fromJson(dynamic json) {
|
||||
return json != null
|
||||
? BankState(
|
||||
password: json['password'],
|
||||
login: json['login'],
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
dynamic toJson() {
|
||||
return {"password": password, "login": login};
|
||||
}
|
||||
}
|
||||
|
|
@ -1,28 +1,58 @@
|
|||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
import 'package:meta/meta.dart';
|
||||
import 'package:flutter_bluetooth_basic/src/bluetooth_device.dart';
|
||||
|
||||
@immutable
|
||||
class SettingState {
|
||||
final String mode;
|
||||
final String tradeType;
|
||||
final String pinCode;
|
||||
final bool pinLocked;
|
||||
final bool pinSkip;
|
||||
final BluetoothDevice printerBT;
|
||||
final String printerEncoding;
|
||||
final String printerPaperSize;
|
||||
|
||||
SettingState({this.mode, this.tradeType});
|
||||
|
||||
SettingState({this.mode, this.tradeType, this.pinCode, this.pinLocked, this.pinSkip, this.printerBT,
|
||||
this.printerEncoding,
|
||||
this.printerPaperSize});
|
||||
|
||||
//read hive
|
||||
factory SettingState.initial(SettingState payload) {
|
||||
return SettingState(
|
||||
mode: payload?.mode ?? SettingModeKassa,
|
||||
tradeType: payload?.tradeType ?? SettingTradeTypeGood);
|
||||
tradeType: payload?.tradeType ?? SettingTradeTypeGood,
|
||||
pinCode: payload?.pinCode ?? null,
|
||||
pinLocked: true,
|
||||
pinSkip: false,
|
||||
printerBT: payload?.printerBT ?? null,
|
||||
printerEncoding:
|
||||
payload?.printerEncoding ?? SettingPrinterEncodingCp866,
|
||||
printerPaperSize: payload?.printerPaperSize ?? SettingPrinterPaperM58
|
||||
);
|
||||
}
|
||||
|
||||
//write hive
|
||||
SettingState copyWith({
|
||||
@required mode,
|
||||
@required tradeType,
|
||||
@required pinCode,
|
||||
@required pinLocked,
|
||||
@required pinSkip,
|
||||
@required printerBT,
|
||||
@required printerEncoding,
|
||||
@required printerPaperSize,
|
||||
}) {
|
||||
return SettingState(
|
||||
mode: mode ?? this.mode,
|
||||
tradeType: tradeType ?? this.tradeType,
|
||||
pinCode: pinCode ?? this.pinCode,
|
||||
pinLocked: pinLocked ?? this.pinLocked,
|
||||
pinSkip: pinSkip ?? this.pinSkip,
|
||||
printerBT: printerBT ?? this.printerBT,
|
||||
printerEncoding: printerEncoding ?? this.printerEncoding,
|
||||
printerPaperSize: printerPaperSize ?? this.printerPaperSize
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -31,11 +61,28 @@ class SettingState {
|
|||
? SettingState(
|
||||
tradeType: json['tradeType'],
|
||||
mode: json['mode'],
|
||||
pinCode: json['pinCode'],
|
||||
pinLocked: json['pinLocked'],
|
||||
pinSkip: json['pinSkip'],
|
||||
printerEncoding: json['printerEncoding'],
|
||||
printerPaperSize: json['printerPaperSize'],
|
||||
printerBT: json['printerBT'] != null
|
||||
? BluetoothDevice.fromJson(json['printerBT'])
|
||||
: null,
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
dynamic toJson() {
|
||||
return {"tradeType": tradeType, "mode": mode};
|
||||
return {
|
||||
"tradeType": tradeType,
|
||||
"mode": mode,
|
||||
"pinCode": pinCode,
|
||||
"pinLocked" : pinLocked,
|
||||
"pinSkip" : pinSkip,
|
||||
"printerBT": printerBT != null ? printerBT.toJson() : null,
|
||||
"printerEncoding": printerEncoding,
|
||||
"printerPaperSize": printerPaperSize,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class UserState {
|
|||
final Smena smena;
|
||||
final Money money;
|
||||
|
||||
|
||||
UserState(
|
||||
{this.isError,
|
||||
this.isLoading,
|
||||
|
|
@ -26,7 +27,8 @@ class UserState {
|
|||
this.user,
|
||||
this.loginFormMessage,
|
||||
this.smena,
|
||||
this.money});
|
||||
this.money,
|
||||
});
|
||||
|
||||
factory UserState.initial(UserState payload) => UserState(
|
||||
isLoading: false,
|
||||
|
|
@ -73,7 +75,8 @@ class UserState {
|
|||
user: User.fromJson(json['user']),
|
||||
authenticateType: json['authenticateType'],
|
||||
login: json['login'],
|
||||
password: json['password'])
|
||||
password: json['password'],
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/reducers/bank_reducer.dart';
|
||||
import 'package:aman_kassa_flutter/redux/reducers/calc_reducer.dart';
|
||||
import 'package:aman_kassa_flutter/redux/reducers/main_reducer.dart';
|
||||
import 'package:aman_kassa_flutter/redux/reducers/setting_reducer.dart';
|
||||
import 'package:aman_kassa_flutter/redux/reducers/user_reducer.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/calc_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||
|
|
@ -15,6 +17,7 @@ import 'package:redux_persist_flutter/redux_persist_flutter.dart';
|
|||
import 'package:redux_thunk/redux_thunk.dart';
|
||||
import 'package:redux_persist/redux_persist.dart';
|
||||
|
||||
import 'actions/bank_actions.dart';
|
||||
import 'actions/calc_actions.dart';
|
||||
|
||||
//reducer context
|
||||
|
|
@ -35,6 +38,10 @@ AppState appReducer(AppState state, dynamic action) {
|
|||
/** CalcAction **/
|
||||
final nextCalcState = calcReducer(state.calcState, action);
|
||||
return state.copyWith(calcState: nextCalcState);
|
||||
} else if (action is SetBankStateAction) {
|
||||
/** BankAction **/
|
||||
final nextBankState = bankReducer(state.bankState, action);
|
||||
return state.copyWith(bankState: nextBankState);
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
|
@ -46,12 +53,14 @@ class AppState {
|
|||
final KassaState kassaState;
|
||||
final SettingState settingState;
|
||||
final CalcState calcState;
|
||||
final BankState bankState;
|
||||
|
||||
AppState({
|
||||
this.userState,
|
||||
this.kassaState,
|
||||
this.settingState,
|
||||
this.calcState,
|
||||
this.bankState,
|
||||
});
|
||||
|
||||
//stable work
|
||||
|
|
@ -60,28 +69,32 @@ class AppState {
|
|||
KassaState kassaState,
|
||||
SettingState settingState,
|
||||
CalcState calcState,
|
||||
BankState bankState,
|
||||
}) {
|
||||
return AppState(
|
||||
userState: userState ?? this.userState,
|
||||
kassaState: kassaState ?? this.kassaState,
|
||||
settingState: settingState ?? this.settingState,
|
||||
calcState: calcState ?? this.calcState,
|
||||
bankState: bankState ?? this.bankState,
|
||||
);
|
||||
}
|
||||
|
||||
static AppState fromJson(dynamic json){
|
||||
return json !=null
|
||||
static AppState fromJson(dynamic json) {
|
||||
return json != null
|
||||
? AppState(
|
||||
settingState: SettingState.fromJson(json['settingState']),
|
||||
userState: UserState.fromJson(json['userState']),
|
||||
)
|
||||
settingState: SettingState.fromJson(json['settingState']),
|
||||
userState: UserState.fromJson(json['userState']),
|
||||
bankState: BankState.fromJson(json['bankState']),
|
||||
)
|
||||
: null;
|
||||
}
|
||||
|
||||
dynamic toJson() {
|
||||
return {
|
||||
"settingState": settingState.toJson(),
|
||||
"userState" : userState.toJson(),
|
||||
"userState": userState.toJson(),
|
||||
"bankState": bankState.toJson(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -102,7 +115,8 @@ class Redux {
|
|||
// Create Persistor
|
||||
final persist = Persistor<AppState>(
|
||||
storage: FlutterStorage(), // Or use other engines
|
||||
serializer: JsonSerializer<AppState>(AppState.fromJson), // Or use other serializers
|
||||
serializer: JsonSerializer<AppState>(
|
||||
AppState.fromJson), // Or use other serializers
|
||||
);
|
||||
|
||||
final initialState = await persist.load();
|
||||
|
|
@ -111,15 +125,17 @@ class Redux {
|
|||
final kassaStateInitial = KassaState.initial();
|
||||
final settingStateInitial = SettingState.initial(initialState?.settingState);
|
||||
final calcStateInitial = CalcState.initial();
|
||||
final bankStateInitial = BankState.initial(initialState?.bankState);
|
||||
|
||||
_store = Store<AppState>(
|
||||
appReducer,
|
||||
middleware: [thunkMiddleware, persist.createMiddleware() ],
|
||||
middleware: [thunkMiddleware, persist.createMiddleware()],
|
||||
initialState: AppState(
|
||||
userState: userStateInitial,
|
||||
kassaState: kassaStateInitial,
|
||||
settingState: settingStateInitial,
|
||||
calcState: calcStateInitial),
|
||||
calcState: calcStateInitial,
|
||||
bankState: bankStateInitial),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ const Color backgroundColor = Color.fromRGBO(255, 255, 255, 1);
|
|||
const Color fillColor = Color.fromRGBO(248, 248, 248, 1);
|
||||
const Color primaryColor = Color.fromRGBO(51, 122, 183, 1);
|
||||
|
||||
const Color halykColor = Color.fromRGBO(0, 118, 59, 1);
|
||||
|
||||
|
||||
const Color menuColor = Color.fromRGBO(0, 75, 120, 1);
|
||||
|
||||
|
|
@ -12,6 +14,9 @@ const Color greenColor = Color.fromRGBO(92, 184, 92, 1);
|
|||
const Color whiteColor = Color.fromRGBO(255, 255, 255, 1);
|
||||
const Color yellowColor = Color.fromRGBO(250, 175, 0, 1);
|
||||
|
||||
const Color purpleColor = Color.fromRGBO(118, 122, 230, 1);
|
||||
const Color purpleSecondColor = Color.fromRGBO(140, 143, 236, 1);
|
||||
|
||||
const Color textColor = Color.fromRGBO(51, 51, 51, 1);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ const TextStyle productTextStyle = const TextStyle(
|
|||
fontWeight: FontWeight.w400, color: Colors.black, fontSize: 15);
|
||||
const TextStyle buttonTitleTextStyle = const TextStyle(
|
||||
fontWeight: FontWeight.w700, color: whiteColor, fontSize: 14);
|
||||
const TextStyle buttonTitleDisableTextStyle = const TextStyle(
|
||||
fontWeight: FontWeight.w700, color: fillColor, fontSize: 14);
|
||||
const TextStyle buttonBigTitleTextStyle = const TextStyle(
|
||||
fontWeight: FontWeight.w700,
|
||||
color: whiteColor,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
// Define a function.
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:crypto/crypto.dart';
|
||||
|
||||
void printInteger(int aNumber) {
|
||||
print('The number is $aNumber.'); // Print to console.
|
||||
}
|
||||
|
|
@ -8,4 +12,11 @@ void main() {
|
|||
String dataMatrix = "00000046208262nZ2qnLHODVFWktT";
|
||||
String numberText = dataMatrix.replaceAll(RegExp("[a-zA-Z]"), '');
|
||||
print(int.parse(numberText));
|
||||
String salt = '!=uF:w1N_Salh?1gVSJ#eGfJYHA(wS4D';
|
||||
String hash = md5.convert(utf8.encode('uvaissov@gmail.com$salt')).toString();
|
||||
print(hash);
|
||||
|
||||
|
||||
String value = "100.0";
|
||||
print(double.parse(value));
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/aman_dao.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/BankService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/bank_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class BankSettingView extends StatefulWidget {
|
||||
BankSettingView();
|
||||
|
||||
@override
|
||||
_BankSettingViewState createState() => _BankSettingViewState();
|
||||
}
|
||||
|
||||
class _BankSettingViewState extends State<BankSettingView> {
|
||||
TextEditingController _emailController;
|
||||
TextEditingController _passwordController;
|
||||
final BankService _bankService = locator<BankService>();
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
BankState state = Redux.store.state.bankState;
|
||||
_emailController = new TextEditingController(text: state.login);
|
||||
_passwordController = new TextEditingController(text: state.password);
|
||||
//permissions();
|
||||
}
|
||||
|
||||
// Future<void> permissions() async {
|
||||
// try {
|
||||
// await _bankService.permissions();
|
||||
// } on PlatformException {
|
||||
//
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_emailController.dispose();
|
||||
_passwordController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _saveData(BuildContext _context) async {
|
||||
FocusScope.of(_context).unfocus();
|
||||
await Redux.store.dispatch(saveData(_emailController.text, _passwordController.text));
|
||||
_dialogService.showDialog(description: 'Данные сохранены');
|
||||
}
|
||||
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: Text('Настройка HalykPos'),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 14.0),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
verticalSpaceTiny,
|
||||
Text(
|
||||
'Необходимо указать почту и пароль для подключения к системе проведения платежей',
|
||||
style: TextStyle(fontSize: 15.0),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
verticalSpaceTiny,
|
||||
TextField(
|
||||
controller: _emailController,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'E-Mail', hintText: "Введите адрес почты"),
|
||||
keyboardType: TextInputType.emailAddress,
|
||||
),
|
||||
TextField(
|
||||
controller: _passwordController,
|
||||
obscureText: true,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Пароль', hintText: "Введите пароль"),
|
||||
),
|
||||
verticalSpaceMedium,
|
||||
RaisedButton(
|
||||
onPressed: () => this._saveData(context),
|
||||
child: Text(
|
||||
'Cохранить',
|
||||
style: TextStyle(color: whiteColor, fontSize: 25.0),
|
||||
),
|
||||
color: primaryColor,
|
||||
padding:
|
||||
const EdgeInsets.symmetric(vertical: 5.0, horizontal: 20.0),
|
||||
),
|
||||
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,262 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:aman_kassa_flutter/core/models/aman_dao.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
|
||||
class BankView extends StatefulWidget {
|
||||
BankView();
|
||||
|
||||
@override
|
||||
_BankViewState createState() => _BankViewState();
|
||||
}
|
||||
|
||||
class _BankViewState extends State<BankView> {
|
||||
static const MethodChannel _channel =
|
||||
MethodChannel('channel:com.amanKassa/bank');
|
||||
static const MethodChannel _activity =
|
||||
MethodChannel('channel:com.amanKassa/activity');
|
||||
String initValue;
|
||||
String connectionValue;
|
||||
String authValue;
|
||||
String payValue;
|
||||
String cancelValue;
|
||||
String shutdownValue;
|
||||
String versionValue;
|
||||
String transactionValue;
|
||||
String closeDayValue;
|
||||
String getValue;
|
||||
String errorValue;
|
||||
bool loading = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
//load();
|
||||
}
|
||||
|
||||
initialize() async {
|
||||
String result = await _channel.invokeMethod('init', <String, dynamic>{
|
||||
'serverUrl': 'http://195.200.74.83:5000',
|
||||
});
|
||||
setState(() {
|
||||
initValue = result ?? 'none';
|
||||
});
|
||||
}
|
||||
|
||||
version() async {
|
||||
String result = await _channel.invokeMethod('version');
|
||||
setState(() {
|
||||
versionValue = result ?? 'none';
|
||||
});
|
||||
}
|
||||
|
||||
transaction() async {
|
||||
String result = await _channel.invokeMethod('transaction');
|
||||
setState(() {
|
||||
transactionValue = result ?? 'none';
|
||||
});
|
||||
}
|
||||
|
||||
connect() async {
|
||||
String result = await _channel.invokeMethod("connection");
|
||||
setState(() {
|
||||
connectionValue = result;
|
||||
});
|
||||
}
|
||||
|
||||
auth() async {
|
||||
String result = await _channel.invokeMethod("auth",
|
||||
<String, dynamic>{'login': 'uvaissov@gmail.com', 'password': '8147'});
|
||||
setState(() {
|
||||
authValue = result;
|
||||
});
|
||||
}
|
||||
|
||||
pay() async {
|
||||
String result;
|
||||
try {
|
||||
result =
|
||||
await _channel.invokeMethod("pay", <String, dynamic>{'amount': 100});
|
||||
} catch (e) {
|
||||
result = (e.toString());
|
||||
}
|
||||
setState(() {
|
||||
payValue = result;
|
||||
});
|
||||
}
|
||||
|
||||
cancel() async {
|
||||
String result;
|
||||
try {
|
||||
result = await _channel.invokeMethod("cancel");
|
||||
} catch (e) {
|
||||
result = (e.toString());
|
||||
}
|
||||
setState(() {
|
||||
cancelValue = result;
|
||||
});
|
||||
}
|
||||
|
||||
shutdown() async {
|
||||
String result;
|
||||
try {
|
||||
result = await _channel.invokeMethod("shutdown");
|
||||
} catch (e) {
|
||||
result = (e.toString());
|
||||
}
|
||||
setState(() {
|
||||
shutdownValue = result;
|
||||
});
|
||||
}
|
||||
|
||||
get() async {
|
||||
String result;
|
||||
try {
|
||||
String response = await _channel.invokeMethod("get");
|
||||
AmanDao dao = AmanDao.fromJson(json.decode(response));
|
||||
result = '${dao.data} - ${dao.msg}';
|
||||
} catch (e) {
|
||||
result = (e.toString());
|
||||
}
|
||||
setState(() {
|
||||
getValue = result;
|
||||
});
|
||||
}
|
||||
|
||||
closeDay() async {
|
||||
String result;
|
||||
try {
|
||||
String response = await _channel.invokeMethod("closeDay");
|
||||
AmanDao dao = AmanDao.fromJson(json.decode(response));
|
||||
result = '${dao.data} - ${dao.msg}';
|
||||
} catch (e) {
|
||||
result = (e.toString());
|
||||
}
|
||||
setState(() {
|
||||
closeDayValue = result;
|
||||
});
|
||||
}
|
||||
|
||||
error() async {
|
||||
String result;
|
||||
try {
|
||||
String json = await _channel.invokeMethod("error");
|
||||
dynamic data = JsonDecoder().convert(json);
|
||||
result = data["msg"];
|
||||
} catch (e) {
|
||||
result = (e.toString());
|
||||
}
|
||||
setState(() {
|
||||
errorValue = result;
|
||||
});
|
||||
}
|
||||
|
||||
activity() async {
|
||||
String result = await _activity.invokeMethod("start");
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: Text('Банковская страница'),
|
||||
),
|
||||
body: loading
|
||||
? Container(child: Center(child: CircularProgressIndicator()))
|
||||
: SingleChildScrollView(
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(horizontal: 14.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
RaisedButton(
|
||||
child: Text('Activity m4Bank'), onPressed: activity),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text('version: $versionValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
|
||||
RaisedButton(
|
||||
child: Text('Version'), onPressed: version),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text('init: $initValue' , overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
|
||||
RaisedButton(
|
||||
child: Text('Init'), onPressed: initialize),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text('connection: $connectionValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
|
||||
RaisedButton(
|
||||
child: Text('Connect'), onPressed: connect),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text('auth: $authValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
|
||||
RaisedButton(child: Text('Auth'), onPressed: auth),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text('cancel: $cancelValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
|
||||
RaisedButton(child: Text('Cancel'), onPressed: cancel),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text('shutdown: $shutdownValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
|
||||
RaisedButton(
|
||||
child: Text('Shutdown'), onPressed: shutdown),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text('transaction: $transactionValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
|
||||
RaisedButton(
|
||||
child: Text('Transaction'), onPressed: transaction),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text('get: $getValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
|
||||
RaisedButton(
|
||||
child: Text('Get'), onPressed: get),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text('error: $errorValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
|
||||
RaisedButton(
|
||||
child: Text('Error'), onPressed: error),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: <Widget>[
|
||||
Text('error: $closeDayValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
|
||||
RaisedButton(
|
||||
child: Text('CloseDay'), onPressed: closeDay),
|
||||
],
|
||||
),
|
||||
Text('pay: $payValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
|
||||
RaisedButton(child: Text('Payment'), onPressed: pay),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +1,153 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/aman_dao.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/card_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/dialog_models.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/BankService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||
import 'package:aman_kassa_flutter/views/settings/printer/PrinterTest.dart';
|
||||
import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/fields/busy_button_icon.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
||||
import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart';
|
||||
import 'package:esc_pos_utils/esc_pos_utils.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bluetooth_basic/flutter_bluetooth_basic.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
import 'package:esys_flutter_share/esys_flutter_share.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class ImageShowContainer extends StatelessWidget {
|
||||
final ImageShowModel data;
|
||||
import '../../core/models/aman_dao.dart';
|
||||
|
||||
ImageShowContainer(this.data);
|
||||
class ImageShowContainer extends StatefulWidget {
|
||||
final ImageShowModel showModel;
|
||||
|
||||
ImageShowContainer(this.showModel);
|
||||
|
||||
@override
|
||||
_ImageShowContainerState createState() => _ImageShowContainerState();
|
||||
}
|
||||
|
||||
class _ImageShowContainerState extends State<ImageShowContainer> {
|
||||
final PrinterBluetoothManager printerManager = PrinterBluetoothManager();
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
|
||||
final BluetoothDevice printerBtDevice = Redux.store.state.settingState.printerBT;
|
||||
final BluetoothManager bluetoothManager = BluetoothManager.instance;
|
||||
|
||||
bool _printing = false;
|
||||
|
||||
void _preparePrint() async {
|
||||
if (Platform.isIOS) {
|
||||
await _print();
|
||||
} else {
|
||||
bluetoothManager.state.listen((val) {
|
||||
print("state = $val");
|
||||
if (!mounted) return;
|
||||
if (val == 12) {
|
||||
print('on');
|
||||
_print();
|
||||
} else if (val == 10) {
|
||||
print('off');
|
||||
_dialogService.showDialog(description: 'Отсутвует соеденение Bluetooth или он отключен', title: 'Bluetooth');
|
||||
}
|
||||
print('state is $val');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _print() async {
|
||||
final SettingState state = Redux.store.state.settingState;
|
||||
if (state.printerBT == null) {
|
||||
_dialogService.showDialog(description: 'Укажите в настройках принтер для печати чеков');
|
||||
return;
|
||||
}
|
||||
|
||||
bool isIos = Platform.isIOS;
|
||||
int chunkSizeBytes = 3096;
|
||||
int queueSleepTimeMs = 100;
|
||||
|
||||
if (isIos) {
|
||||
chunkSizeBytes = 75;
|
||||
queueSleepTimeMs = 10;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_printing = true;
|
||||
});
|
||||
try {
|
||||
printerManager.selectPrinter(PrinterBluetooth(state.printerBT));
|
||||
PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80 ? PaperSize.mm80 : PaperSize.mm58;
|
||||
if (SettingPrinterEncodingImage == state.printerEncoding) {
|
||||
final PosPrintResult res = await printerManager.printTicket(
|
||||
await printImageCheck(paper, widget.showModel.data.base64Data),
|
||||
chunkSizeBytes: chunkSizeBytes,
|
||||
queueSleepTimeMs: queueSleepTimeMs);
|
||||
if (res.value != 1) {
|
||||
_dialogService.showDialog(description: res.msg);
|
||||
}
|
||||
} else {
|
||||
final PosPrintResult res = await printerManager.printTicket(
|
||||
await printTextCheck(paper, state.printerEncoding, jsonDecode(widget.showModel.data.textData)),
|
||||
chunkSizeBytes: chunkSizeBytes,
|
||||
queueSleepTimeMs: queueSleepTimeMs);
|
||||
if (res.value != 1) {
|
||||
_dialogService.showDialog(description: res.msg);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
await Future.delayed(Duration(seconds: 7));
|
||||
setState(() {
|
||||
_printing = false;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
//backgroundColor: fillColor,
|
||||
title: Text(data.title),
|
||||
title: Text(widget.showModel.title),
|
||||
actions: [
|
||||
if (_printing)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: SizedBox(
|
||||
width: 36.0,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: new AlwaysStoppedAnimation<Color>(whiteColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
IconButton(icon: Icon(Icons.print), onPressed: _preparePrint)
|
||||
],
|
||||
),
|
||||
body: ListView(
|
||||
children: <Widget>[imageFromBase64String(data.data)],
|
||||
children: <Widget>[imageFromBase64String(widget.showModel.data.base64Data)],
|
||||
),
|
||||
floatingActionButton: MyFloatingActionButton(data),
|
||||
floatingActionButton: MyFloatingActionButton(widget.showModel),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -41,16 +160,20 @@ Padding imageFromBase64String(String base64String) {
|
|||
}
|
||||
|
||||
class ImageShowModel {
|
||||
final String data;
|
||||
final CheckImageModal data;
|
||||
final String title;
|
||||
final String url;
|
||||
final CardData cardData;
|
||||
final Voucher voucher;
|
||||
|
||||
ImageShowModel({this.data, this.title, this.url});
|
||||
ImageShowModel({this.data, this.title, this.url, this.cardData, this.voucher});
|
||||
}
|
||||
|
||||
class MyFloatingActionButton extends StatefulWidget {
|
||||
final ImageShowModel data;
|
||||
|
||||
MyFloatingActionButton(this.data);
|
||||
|
||||
@override
|
||||
_MyFloatingActionButtonState createState() => _MyFloatingActionButtonState();
|
||||
}
|
||||
|
|
@ -59,11 +182,101 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
|||
bool showFab = true;
|
||||
DialogService _dialog = locator<DialogService>();
|
||||
NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||
final DataService _dataService = locator<DataService>();
|
||||
|
||||
double sheetHeight = 260;
|
||||
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return showFab
|
||||
? FloatingActionButton(
|
||||
//print(widget.data.cardData.transactionType);
|
||||
if (showFab) {
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment")
|
||||
FloatingActionButton(
|
||||
backgroundColor: redColor,
|
||||
tooltip: 'Отмена',
|
||||
child: Icon(
|
||||
Icons.cancel,
|
||||
color: whiteColor,
|
||||
),
|
||||
onPressed: () async {
|
||||
var today = new DateTime.now();
|
||||
var yesterday = today.subtract(new Duration(days: 1));
|
||||
if( Redux.store.state.userState == null
|
||||
|| Redux.store.state.userState.smena == null
|
||||
|| Redux.store.state.userState.smena.startedAt == null
|
||||
|| yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
|
||||
_dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
||||
AmanDao<CardData> response = await reversalHalykPos(widget.data.cardData, widget.data.voucher.total);
|
||||
if (response.success) {
|
||||
pressRefund();
|
||||
} else {
|
||||
_dialog.showDialog(description: response.msg);
|
||||
}
|
||||
} finally {
|
||||
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
||||
}
|
||||
_navigatorService.replace(HomeViewRoute);
|
||||
},
|
||||
heroTag: null,
|
||||
)
|
||||
else
|
||||
SizedBox(
|
||||
height: 0,
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment")
|
||||
FloatingActionButton(
|
||||
backgroundColor: redColor,
|
||||
tooltip: 'Возврат',
|
||||
child: Icon(
|
||||
Icons.settings_backup_restore,
|
||||
color: whiteColor,
|
||||
),
|
||||
onPressed: () async {
|
||||
var today = new DateTime.now();
|
||||
var yesterday = today.subtract(new Duration(days: 1));
|
||||
if( Redux.store.state.userState == null
|
||||
|| Redux.store.state.userState.smena == null
|
||||
|| Redux.store.state.userState.smena.startedAt == null
|
||||
|| yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
|
||||
_dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
||||
AmanDao<CardData> response = await refundHalykPos(widget.data.cardData, widget.data.voucher.total);
|
||||
if (response.success) {
|
||||
pressRefund();
|
||||
} else {
|
||||
_dialog.showDialog(description: response.msg);
|
||||
}
|
||||
} finally {
|
||||
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
||||
}
|
||||
},
|
||||
heroTag: null,
|
||||
)
|
||||
else
|
||||
SizedBox(
|
||||
height: 0,
|
||||
),
|
||||
SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
FloatingActionButton(
|
||||
child: Icon(Icons.share),
|
||||
onPressed: () {
|
||||
var bottomSheetController = showBottomSheet(
|
||||
|
|
@ -73,12 +286,7 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
|||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
blurRadius: 10,
|
||||
color: Colors.grey[300],
|
||||
spreadRadius: 5)
|
||||
]),
|
||||
boxShadow: [BoxShadow(blurRadius: 10, color: Colors.grey[300], spreadRadius: 5)]),
|
||||
height: 260,
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
|
|
@ -107,36 +315,75 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
|||
),
|
||||
],
|
||||
)));
|
||||
showFoatingActionButton(false);
|
||||
showFloatingActionButton(false);
|
||||
bottomSheetController.closed.then((value) {
|
||||
showFoatingActionButton(true);
|
||||
showFloatingActionButton(true);
|
||||
});
|
||||
},
|
||||
)
|
||||
: Container();
|
||||
),
|
||||
],
|
||||
);
|
||||
} else {
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
||||
pressRefund() async {
|
||||
Dialogs.showLoadingDialog(context, _keyLoader);
|
||||
try {
|
||||
AppState _state = Redux.store.state;
|
||||
String _token = _state.userState.user.token;
|
||||
CardData _cardData = widget.data.cardData;
|
||||
CheckData _checkData = CheckData.fromJson(json.decode(widget.data.voucher.data));
|
||||
Response<dynamic> response =
|
||||
await _dataService.refundM4Bank(token: _token, cardData: _cardData, checkData: _checkData);
|
||||
if (response != null) {
|
||||
if (response.operation) {
|
||||
String message = response.body['message'];
|
||||
String check = response.body['check'];
|
||||
var checkText = response.body['check_text'];
|
||||
String url = response?.body['link'];
|
||||
print('url : $url');
|
||||
Redux.store.dispatch(checkMoney);
|
||||
Redux.store.dispatch(openSmenaPseudo);
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
_navigatorService.replace(HomeViewRoute);
|
||||
_navigatorService.push(ImageShowRoute,
|
||||
arguments: ImageShowModel(
|
||||
data: new CheckImageModal(
|
||||
base64Data: check, textData: checkText != null ? jsonEncode(checkText) : null),
|
||||
title: message,
|
||||
url: url));
|
||||
} else if (!response.operation && ![401, 402, 403, 412, 500].contains(response.status)) {
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
_dialog.showDialog(description: response.body['message']);
|
||||
} else {
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
}
|
||||
} else {
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
}
|
||||
}
|
||||
|
||||
void shareFile() async {
|
||||
try {
|
||||
await Share.file('Aman Kassa', 'aman_kassa_check.png',
|
||||
base64Decode(widget.data.data), 'image/png');
|
||||
await Share.file('Aman Kassa', 'aman_kassa_check.png', base64Decode(widget.data.data.base64Data), 'image/png');
|
||||
} catch (e) {
|
||||
print('error: $e');
|
||||
}
|
||||
}
|
||||
|
||||
void qrGenerate() async {
|
||||
_navigatorService.push(QrViewRoute,
|
||||
arguments:
|
||||
ImageShowModel(data: widget.data.url, title: 'Спасибо за покупку'));
|
||||
_navigatorService.push(QrViewRoute, arguments: ImageShowModel(url: widget.data.url, title: 'Спасибо за покупку'));
|
||||
}
|
||||
|
||||
void callWhatsApp() async {
|
||||
DialogResponse response = await _dialog.showConfirmationDialogInput(
|
||||
description: 'Номер телефона',
|
||||
cancelTitle: 'Отмена',
|
||||
confirmationTitle: 'Отправить',
|
||||
formatType: 'phone');
|
||||
description: 'Номер телефона', cancelTitle: 'Отмена', confirmationTitle: 'Отправить', formatType: 'phone');
|
||||
if (response.confirmed) {
|
||||
String phoneNumber = response.responseText;
|
||||
String msg = "Спасибо за покупку! \r\n ${widget.data.url} ";
|
||||
|
|
@ -156,7 +403,6 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
|||
}
|
||||
}
|
||||
|
||||
print(url());
|
||||
if (await canLaunch(url())) {
|
||||
await launch(url());
|
||||
} else {
|
||||
|
|
@ -164,7 +410,7 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
|||
}
|
||||
}
|
||||
|
||||
void showFoatingActionButton(bool value) {
|
||||
void showFloatingActionButton(bool value) {
|
||||
setState(() {
|
||||
showFab = value;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,85 @@
|
|||
import 'package:aman_kassa_flutter/core/models/close_day_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
|
||||
import 'package:aman_kassa_flutter/shared/shared_styles.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class CloseDayShowContainer extends StatelessWidget {
|
||||
final CloseDayData data;
|
||||
DateFormat dateFormat = DateFormat("dd.MM.yyyy HH:mm:ss");
|
||||
CloseDayShowContainer(this.data);
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(data.title ?? 'Отчет: Закрытие дня POS'),
|
||||
),
|
||||
body: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Общий итоги', style: const TextStyle(fontWeight: FontWeight.bold, color: Colors.black, fontSize: 15) ),
|
||||
Table(
|
||||
children: [
|
||||
TableRow(children: [
|
||||
TableCell(child: Text('Оплат:', style: productTextStyle,)),
|
||||
TableCell(child: Text('${data.paymentCount}', textAlign: TextAlign.center, style: productTextStyle)),
|
||||
TableCell(child: Text('${data.paymentAmount} T', textAlign: TextAlign.end, style: productTextStyle)),
|
||||
]),
|
||||
TableRow(children: [
|
||||
TableCell(child: Text('Отмен:', style: productTextStyle,)),
|
||||
TableCell(child: Text('${data.cancelCount}', textAlign: TextAlign.center, style: productTextStyle)),
|
||||
TableCell(child: Text('${data.cancelAmount} T', textAlign: TextAlign.end, style: productTextStyle)),
|
||||
]),
|
||||
TableRow(children: [
|
||||
TableCell(child: Text('Возвратов:', style: productTextStyle,)),
|
||||
TableCell(child: Text('${data.refundCount}', textAlign: TextAlign.center, style: productTextStyle)),
|
||||
TableCell(child: Text('${data.refundAmount} T', textAlign: TextAlign.end, style: productTextStyle)),
|
||||
]),
|
||||
TableRow(children: [
|
||||
TableCell(child: Text('Итого:', style: productTextStyle,)),
|
||||
TableCell(child: Text('${data.totalCount}', textAlign: TextAlign.center, style: productTextStyle)),
|
||||
TableCell(child: Text('${data.totalAmount} T', textAlign: TextAlign.end, style: productTextStyle)),
|
||||
]),
|
||||
],
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(),
|
||||
Expanded(
|
||||
child: ListView.separated(
|
||||
itemCount: data.items.length,
|
||||
separatorBuilder: (BuildContext context, int index) {
|
||||
return Divider();
|
||||
},
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
TransactionBean item = data.items.elementAt(index);
|
||||
return ListTile(
|
||||
title: Text(item.instrumentSpecificData.maskedPan),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if(item.instrumentSpecificData.cardholderName!=null)
|
||||
Text(item.instrumentSpecificData.cardholderName),
|
||||
Text('Операционный день № ${item.operationDay?.toString()}'),
|
||||
],
|
||||
),
|
||||
trailing: Text('${item.amount / 100} T'),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/card_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/close_day_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/DbService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
|
|
@ -62,16 +68,47 @@ class _HistoryViewState extends State<HistoryView> {
|
|||
},
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
Voucher voucher = data[index];
|
||||
CardData cardData;
|
||||
CloseDayData closeDayData;
|
||||
if( voucher.type == VoucherTypeCloseDayPosReport ) {
|
||||
closeDayData = CloseDayData.fromJson(json.decode(voucher.data));
|
||||
} else if( voucher.data !=null ) {
|
||||
CheckData checkData = CheckData.fromJson(json.decode(voucher.data));
|
||||
cardData = checkData.cardData;
|
||||
}
|
||||
|
||||
String base64Data = voucher.base64Data;
|
||||
CheckImageModal checkImageData;
|
||||
if(base64Data !=null && base64Data.startsWith('{')){
|
||||
checkImageData = CheckImageModal.fromJson(jsonDecode(base64Data));
|
||||
} else {
|
||||
checkImageData = new CheckImageModal(base64Data: base64Data);
|
||||
}
|
||||
return ListTile(
|
||||
onTap: () {
|
||||
_navigatorService.push(ImageShowRoute,
|
||||
arguments: ImageShowModel(
|
||||
data: voucher.base64Data,
|
||||
|
||||
if( voucher.type == VoucherTypeCloseDayPosReport ) {
|
||||
_navigatorService.push(CloseDayShowRoute,
|
||||
arguments: closeDayData);
|
||||
} else {
|
||||
_navigatorService.push(ImageShowRoute,
|
||||
arguments: ImageShowModel(
|
||||
data: checkImageData,
|
||||
title: voucher.name,
|
||||
url: voucher.url));
|
||||
url: voucher.url,
|
||||
cardData: cardData,
|
||||
voucher: voucher,
|
||||
));
|
||||
}
|
||||
},
|
||||
title: buildText(voucher),
|
||||
subtitle: Text(dateFormat.format(voucher.dateTime)),
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(dateFormat.format(voucher.dateTime)),
|
||||
cardData != null ? Text('№ ${cardData.cardNumber} holder: ${cardData.cardholderName}') : Text(''),
|
||||
],
|
||||
),
|
||||
trailing: Icon(Icons.arrow_right),
|
||||
leading: voucher.type == VoucherTypePayment
|
||||
? Icon(
|
||||
|
|
@ -83,6 +120,11 @@ class _HistoryViewState extends State<HistoryView> {
|
|||
MdiIcons.backupRestore,
|
||||
size: 40,
|
||||
)
|
||||
: voucher.type == VoucherTypeCloseDayPosReport ?
|
||||
Icon(
|
||||
Icons.phonelink_lock_outlined,
|
||||
size: 40,
|
||||
)
|
||||
: Icon(
|
||||
Icons.description,
|
||||
size: 40,
|
||||
|
|
|
|||
|
|
@ -24,29 +24,36 @@ class BottomBar extends StatelessWidget {
|
|||
currentIndex: selectedTabIndex,
|
||||
backgroundColor: menuColor,
|
||||
type: BottomNavigationBarType.shifting,
|
||||
showUnselectedLabels: true,
|
||||
items: [
|
||||
vm.mode == SettingModeKassa
|
||||
? BottomNavigationBarItem(
|
||||
backgroundColor: menuColor,
|
||||
icon: Icon(MdiIcons.cashRegister, color: Colors.white),
|
||||
title: new Text(
|
||||
'Касса',
|
||||
style: TextStyle(color: Colors.white),
|
||||
))
|
||||
label: 'Касса',
|
||||
// title: new Text(
|
||||
// 'Касса',
|
||||
// style: TextStyle(color: Colors.white),
|
||||
// )
|
||||
)
|
||||
: BottomNavigationBarItem(
|
||||
backgroundColor: menuColor,
|
||||
icon: Icon(MdiIcons.calculator, color: Colors.white),
|
||||
title: new Text(
|
||||
'Калькулятор',
|
||||
style: TextStyle(color: Colors.white),
|
||||
)),
|
||||
label: 'Калькулятор',
|
||||
// title: new Text(
|
||||
// 'Калькулятор',
|
||||
// style: TextStyle(color: Colors.white),
|
||||
// )
|
||||
),
|
||||
BottomNavigationBarItem(
|
||||
backgroundColor: menuColor,
|
||||
icon: Icon(MdiIcons.tune, color: Colors.white),
|
||||
title: new Text(
|
||||
'Опции',
|
||||
style: TextStyle(color: Colors.white),
|
||||
)),
|
||||
label: 'Опции'
|
||||
// title: new Text(
|
||||
// 'Опции',
|
||||
// style: TextStyle(color: Colors.white),
|
||||
// )
|
||||
),
|
||||
],
|
||||
onTap: (index) {
|
||||
pageController.animateToPage(
|
||||
|
|
|
|||
|
|
@ -1,21 +1,48 @@
|
|||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/choice.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/BankService.dart';
|
||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
const List<Choice> choices = const <Choice>[
|
||||
//const Choice(title: 'Обновить номенклатуру', icon: Icons.update, command: 'update'),
|
||||
//const Choice(title: 'Помощь', icon: Icons.help, command: 'help'),
|
||||
const Choice(
|
||||
title: 'Информация о ККМ', icon: Icons.info_outline, command: 'infokkm'),
|
||||
//const Choice(title: 'Язык', icon: Icons.language, command: 'language'),
|
||||
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
|
||||
];
|
||||
class PopupMenu extends StatefulWidget {
|
||||
|
||||
class PopupMenu extends StatelessWidget {
|
||||
final void Function(Choice value) onSelectChoice;
|
||||
|
||||
PopupMenu({this.onSelectChoice});
|
||||
|
||||
@override
|
||||
_PopupMenuState createState() => _PopupMenuState();
|
||||
}
|
||||
|
||||
class _PopupMenuState extends State<PopupMenu> {
|
||||
BankService _bankService = locator<BankService>();
|
||||
List<Choice> choices;
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
load();
|
||||
}
|
||||
|
||||
load () async {
|
||||
int version = await _bankService.version();
|
||||
|
||||
List<Choice> _choices = <Choice>[
|
||||
const Choice(title: 'Информация о ККМ', icon: Icons.info_outline, command: 'infokkm'),
|
||||
//if (version >= 24 )
|
||||
// const Choice(title: 'Bank', icon: Icons.text_fields, command: 'bank'),
|
||||
if (version >= _bankService.sdkVersion )
|
||||
const Choice(title: 'Настройка HalykPos', icon: Icons.phonelink_lock_outlined, command: 'tap2phone'),
|
||||
const Choice(title: 'Настройки', icon: Icons.settings, command: 'settings'),
|
||||
const Choice(title: 'Принтер', icon: Icons.print, command: 'print'),
|
||||
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')
|
||||
];
|
||||
setState(() {
|
||||
choices= _choices;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PopupMenuButton<Choice>(
|
||||
|
|
@ -23,23 +50,16 @@ class PopupMenu extends StatelessWidget {
|
|||
Icons.more_vert,
|
||||
color: menuColor,
|
||||
),
|
||||
onSelected: onSelectChoice,
|
||||
onSelected: widget.onSelectChoice,
|
||||
itemBuilder: (BuildContext context) {
|
||||
return choices.map((Choice choice) {
|
||||
return PopupMenuItem<Choice>(
|
||||
value: choice,
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(
|
||||
choice.icon,
|
||||
color: primaryColor,
|
||||
),
|
||||
SizedBox(
|
||||
width: 5,
|
||||
),
|
||||
Text(choice.title)
|
||||
],
|
||||
),
|
||||
child: Row(children: <Widget>[
|
||||
Icon(choice.icon, color: primaryColor,),
|
||||
SizedBox(width: 5,),
|
||||
Text(choice.title)
|
||||
], ),
|
||||
);
|
||||
}).toList();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,107 +0,0 @@
|
|||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/logger.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/choice.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:aman_kassa_flutter/views/home/components/header_title.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
|
||||
import './tabs/KassaTab.dart';
|
||||
import './tabs/AdditionalTab.dart';
|
||||
import './tabs/CalculatorTab.dart';
|
||||
|
||||
import './components/popup_menu.dart';
|
||||
import 'components/bottom_bar.dart';
|
||||
|
||||
class HomeView extends StatefulWidget {
|
||||
@override
|
||||
_HomeViewState createState() => _HomeViewState();
|
||||
}
|
||||
|
||||
class _HomeViewState extends State<HomeView> {
|
||||
Logger log = getLogger('HomeView');
|
||||
PageController pageController;
|
||||
int selectedTabIndex;
|
||||
DataService _dataService = locator<DataService>();
|
||||
ApiService _api = locator<ApiService>();
|
||||
NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
selectedTabIndex = 0;
|
||||
pageController = new PageController(initialPage: selectedTabIndex);
|
||||
Redux.store.dispatch(checkSmena);
|
||||
_dataService.checkDbFill(Redux.store.state.userState.user);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
pageController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onSelectChoice(Choice choice) async {
|
||||
if (choice.command == 'exit') {
|
||||
Dialogs.showLoadingDialog(context, _keyLoader);
|
||||
Response<dynamic> result = await _api.logout(Redux.store.state.userState.user.token);
|
||||
if(result.operation && result.status == 200) {
|
||||
Redux.store.dispatch(logoutAction);
|
||||
}
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
} else if (choice.command == 'infokkm') {
|
||||
_navigatorService.push(InfoKkmViewRoute);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
titleSpacing: 5.0,
|
||||
brightness: Brightness.light,
|
||||
title: HeaderTitle(),
|
||||
actions: <Widget>[
|
||||
PopupMenu(
|
||||
onSelectChoice: _onSelectChoice,
|
||||
)
|
||||
],
|
||||
backgroundColor: fillColor,
|
||||
),
|
||||
body:StoreConnector<AppState, SettingState>(
|
||||
converter: (store) => store.state.settingState,
|
||||
builder: (context, vm) {
|
||||
return PageView(
|
||||
onPageChanged: (index) {
|
||||
setState(() {
|
||||
selectedTabIndex = index;
|
||||
});
|
||||
},
|
||||
controller: pageController,
|
||||
children: <Widget>[
|
||||
vm.mode == SettingModeKassa ? KassaTab(0) : CalculatorTab(0),
|
||||
AdditionalTab(1),
|
||||
],
|
||||
);
|
||||
}
|
||||
),
|
||||
bottomNavigationBar: BottomBar(
|
||||
pageController: pageController,
|
||||
selectedTabIndex: selectedTabIndex,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/logger.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/choice.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/setting_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:aman_kassa_flutter/views/home/components/header_title.dart';
|
||||
import 'package:aman_kassa_flutter/views/lockscreen/passcodescreen.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import './tabs/KassaTab.dart';
|
||||
import './tabs/AdditionalTab.dart';
|
||||
import './tabs/CalculatorTab.dart';
|
||||
|
||||
import './components/popup_menu.dart';
|
||||
import './components/bottom_bar.dart';
|
||||
|
||||
class HomeView extends StatefulWidget {
|
||||
@override
|
||||
_HomeViewState createState() => _HomeViewState();
|
||||
}
|
||||
|
||||
class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
|
||||
Logger log = getLogger('HomeView');
|
||||
PageController pageController;
|
||||
int selectedTabIndex;
|
||||
DataService _dataService = locator<DataService>();
|
||||
ApiService _api = locator<ApiService>();
|
||||
NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||
|
||||
final lastKnownStateKey = 'lastKnownStateKey';
|
||||
final backgroundedTimeKey = 'backgroundedTimeKey';
|
||||
final pinLockMillis = 2000; // 2 seconds
|
||||
|
||||
Future _paused() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
sp.setInt(lastKnownStateKey, AppLifecycleState.paused.index);
|
||||
}
|
||||
|
||||
Future _inactive() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
final prevState = sp.getInt(lastKnownStateKey);
|
||||
final prevStateIsNotPaused = prevState != null &&
|
||||
AppLifecycleState.values[prevState] != AppLifecycleState.paused;
|
||||
final bool pinIsExist = Redux.store.state.settingState?.pinCode?.isNotEmpty;
|
||||
final bool pinSkipped = Redux.store.state.settingState.pinSkip;
|
||||
print('prevStateIsNotPaused=$prevStateIsNotPaused, pinIsExist=$pinIsExist, pinSkipped=$pinSkipped');
|
||||
if(prevStateIsNotPaused && pinSkipped == false && pinIsExist == true) {
|
||||
// save App backgrounded time to Shared preferences
|
||||
sp.setInt(backgroundedTimeKey, DateTime.now().millisecondsSinceEpoch);
|
||||
}
|
||||
// update previous state as inactive
|
||||
sp.setInt(lastKnownStateKey, AppLifecycleState.inactive.index);
|
||||
}
|
||||
|
||||
Future _resumed() async {
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
final bgTime = sp.getInt(backgroundedTimeKey) ?? 0;
|
||||
final allowedBackgroundTime = bgTime + pinLockMillis;
|
||||
final shouldShowPIN = DateTime.now().millisecondsSinceEpoch > allowedBackgroundTime;
|
||||
if(shouldShowPIN && bgTime > 0) {
|
||||
await Redux.store.dispatch(changePinLockedFromSetting(true));
|
||||
pushToLockScreen();
|
||||
}
|
||||
sp.remove(backgroundedTimeKey); // clean
|
||||
sp.setInt(lastKnownStateKey, AppLifecycleState.resumed.index);// previous state
|
||||
}
|
||||
|
||||
void pushToLockScreen() {
|
||||
Navigator.of(context).push(MaterialPageRoute(
|
||||
builder: (_) =>
|
||||
WillPopScope(
|
||||
onWillPop: () async {
|
||||
return false;
|
||||
},
|
||||
child: PassCodeScreen( title: 'Безопасность',)
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
_checkLockPin () async {
|
||||
final bool pinIsExist = Redux.store.state.settingState?.pinCode?.isNotEmpty;
|
||||
final bool pinLocked = Redux.store.state.settingState?.pinLocked;
|
||||
final sp = await SharedPreferences.getInstance();
|
||||
sp.remove(backgroundedTimeKey);
|
||||
sp.setInt(lastKnownStateKey, AppLifecycleState.resumed.index);// previous state
|
||||
if ( pinIsExist == true && pinLocked == true ) {
|
||||
await Future.delayed(Duration(milliseconds: 50));
|
||||
pushToLockScreen();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
WidgetsBinding.instance.addObserver(this);
|
||||
selectedTabIndex = 0;
|
||||
pageController = new PageController(initialPage: selectedTabIndex);
|
||||
Redux.store.dispatch(checkSmena);
|
||||
_dataService.checkDbFill(Redux.store.state.userState.user);
|
||||
_checkLockPin();
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
super.didChangeAppLifecycleState(state);
|
||||
print('state = $state');
|
||||
switch(state) {
|
||||
case AppLifecycleState.resumed:
|
||||
_resumed();
|
||||
break;
|
||||
case AppLifecycleState.paused:
|
||||
_paused();
|
||||
break;
|
||||
case AppLifecycleState.inactive:
|
||||
_inactive();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
WidgetsBinding.instance.removeObserver(this);
|
||||
pageController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _onSelectChoice(Choice choice) async {
|
||||
if (choice.command == 'exit') {
|
||||
Dialogs.showLoadingDialog(context, _keyLoader);
|
||||
Response<dynamic> result =
|
||||
await _api.logout(Redux.store.state.userState.user.token);
|
||||
if (result.operation && result.status == 200) {
|
||||
Redux.store.dispatch(logoutAction);
|
||||
}
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
} else if (choice.command == 'infokkm') {
|
||||
_navigatorService.push(InfoKkmViewRoute);
|
||||
} else if (choice.command == 'settings') {
|
||||
_navigatorService.push(SettingsViewRoute);
|
||||
} else if (choice.command == 'print') {
|
||||
_navigatorService.push(SettingsPrinterRoute);
|
||||
} else if (choice.command == 'bank') {
|
||||
_navigatorService.push(BankViewRoute);
|
||||
} else if (choice.command == 'tap2phone') {
|
||||
_navigatorService.push(BankSettingViewRoute);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
titleSpacing: 5.0,
|
||||
brightness: Brightness.light,
|
||||
title: HeaderTitle(),
|
||||
actions: <Widget>[
|
||||
PopupMenu(
|
||||
onSelectChoice: _onSelectChoice,
|
||||
)
|
||||
],
|
||||
backgroundColor: fillColor,
|
||||
),
|
||||
body: StoreConnector<AppState, SettingState>(
|
||||
converter: (store) => store.state.settingState,
|
||||
builder: (context, vm) {
|
||||
return PageView(
|
||||
onPageChanged: (index) {
|
||||
setState(() {
|
||||
selectedTabIndex = index;
|
||||
});
|
||||
},
|
||||
controller: pageController,
|
||||
children: <Widget>[
|
||||
vm.mode == SettingModeKassa ? KassaTab(0) : CalculatorTab(0),
|
||||
AdditionalTab(1),
|
||||
],
|
||||
);
|
||||
}),
|
||||
bottomNavigationBar: BottomBar(
|
||||
pageController: pageController,
|
||||
selectedTabIndex: selectedTabIndex,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,17 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/close_day_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/money.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/dialog_models.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/user.dart';
|
||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/ApiService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/BankService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
|
|
@ -21,6 +27,7 @@ import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button.dart';
|
|||
import 'package:aman_kassa_flutter/widgets/fields/aman_icon_button_horizontal.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
||||
import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
|
@ -38,10 +45,12 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
|||
ApiService _api = locator<ApiService>();
|
||||
NavigatorService _navigator = locator<NavigatorService>();
|
||||
DialogService _dialog = locator<DialogService>();
|
||||
final BankService _bankService = locator<BankService>();
|
||||
DataService _dataService = locator<DataService>();
|
||||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||
|
||||
bool isMoneyCheckBusy;
|
||||
bool isClosePosBusy;
|
||||
bool closeSmenaBusy;
|
||||
bool openSmenaBusy;
|
||||
bool depositBusy;
|
||||
|
|
@ -59,6 +68,7 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
|||
withdrawalBusy = false;
|
||||
xReportBusy = false;
|
||||
updateCatalog = false;
|
||||
isClosePosBusy = false;
|
||||
}
|
||||
|
||||
void _closeSmena() async {
|
||||
|
|
@ -99,9 +109,11 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
|||
User user = Redux.store.state.userState.user;
|
||||
Response response = await _api.xReport(user.token);
|
||||
if (response.operation) {
|
||||
String check = response.body['check'];
|
||||
var checkText = response.body['check_text'];
|
||||
_navigator.push(ImageShowRoute,
|
||||
arguments:
|
||||
ImageShowModel(data: response.body['check'], title: 'X Отчет'));
|
||||
ImageShowModel(data: CheckImageModal(base64Data: check, textData: checkText !=null ? jsonEncode(checkText) : null ), title: 'X Отчет'));
|
||||
String url = response?.body['link'];
|
||||
_dataService.insertVoucher(
|
||||
user: user,
|
||||
|
|
@ -209,6 +221,55 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
|||
}
|
||||
}
|
||||
|
||||
void _closeDay() async {
|
||||
|
||||
setState(() {
|
||||
isClosePosBusy = true;
|
||||
});
|
||||
|
||||
int version = await _bankService.version();
|
||||
if (version < _bankService.sdkVersion ) {
|
||||
setState(() {
|
||||
isClosePosBusy = false;
|
||||
});
|
||||
_dialog.showDialog(description: 'Функция Tap2Phone доступна c Android версии 8.1');
|
||||
return;
|
||||
}
|
||||
|
||||
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
||||
HalykCloseDayDao closeDayDao = await closeDayHalykPos();
|
||||
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
||||
log.i(closeDayDao.toJson());
|
||||
if (closeDayDao.result.code != 0) {
|
||||
if (closeDayDao.result.description != null) {
|
||||
_dialog.showDialog(description: closeDayDao.result.description);
|
||||
}
|
||||
setState(() {
|
||||
isClosePosBusy = false;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
CloseDayData closeDayData = _bankService.closeDayDataConvert(closeDayDao.transactions);
|
||||
|
||||
User user = Redux.store.state.userState.user;
|
||||
_dataService.insertVoucher(
|
||||
user: user,
|
||||
name: closeDayData.title,
|
||||
data: jsonEncode(closeDayData.toJson()),
|
||||
total: closeDayData.totalAmount.toDouble(),
|
||||
type: VoucherTypeCloseDayPosReport);
|
||||
|
||||
// _dialog.showDialog(description: 'Закрытие дня: операция прошла успешно!');
|
||||
setState(() {
|
||||
isClosePosBusy = false;
|
||||
});
|
||||
|
||||
_navigator.push(CloseDayShowRoute,
|
||||
arguments: closeDayData);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
|
|
@ -256,52 +317,72 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
|||
verticalSpaceMedium,
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||
child: Center(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'Денег в кассе:',
|
||||
style: TextStyle(color: primaryColor, fontSize: 15),
|
||||
),
|
||||
SizedBox(
|
||||
height: 50,
|
||||
width: double.infinity,
|
||||
child: StoreConnector<AppState, Money>(
|
||||
converter: (store) => store.state.userState.money,
|
||||
builder: (_, vm) {
|
||||
if (vm.loading == true) {
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
width: 30,
|
||||
height: 30,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: new AlwaysStoppedAnimation<Color>(
|
||||
primaryColor),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Row(
|
||||
children: [
|
||||
Icon(Icons.money, color: primaryColor),
|
||||
Text(
|
||||
'Денег в кассе:',
|
||||
style: TextStyle(color: primaryColor, fontSize: 15),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(
|
||||
height: 50,
|
||||
// width: double.infinity,
|
||||
child: StoreConnector<AppState, Money>(
|
||||
converter: (store) => store.state.userState.money,
|
||||
builder: (_, vm) {
|
||||
if (vm.loading == true) {
|
||||
return Center(
|
||||
child: SizedBox(
|
||||
width: 30,
|
||||
height: 30,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor:
|
||||
new AlwaysStoppedAnimation<Color>(
|
||||
primaryColor),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Center(
|
||||
child: Text(
|
||||
vm.total != null
|
||||
? '${vm.total} тенге'
|
||||
: 'нет информации',
|
||||
style: TextStyle(
|
||||
color: vm.total != null
|
||||
? primaryColor
|
||||
: Colors.grey.withOpacity(0.5),
|
||||
fontSize: 25,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return Center(
|
||||
child: Text(
|
||||
vm.total != null
|
||||
? '${vm.total} тенге'
|
||||
: 'нет информации',
|
||||
style: TextStyle(
|
||||
color: vm.total != null
|
||||
? primaryColor
|
||||
: Colors.grey.withOpacity(0.5),
|
||||
fontSize: 25,
|
||||
fontWeight: FontWeight.bold),
|
||||
),
|
||||
);
|
||||
}),
|
||||
);
|
||||
}),
|
||||
),
|
||||
],
|
||||
),
|
||||
Container(
|
||||
child: AmanIconButton(
|
||||
title: 'Обновить',
|
||||
onPressed: _checkMoney,
|
||||
busy: isMoneyCheckBusy,
|
||||
icon: Icons.replay_circle_filled,
|
||||
mainColor: primaryColor,
|
||||
),
|
||||
),
|
||||
],
|
||||
)),
|
||||
),
|
||||
),
|
||||
verticalSpaceMedium,
|
||||
Wrap(
|
||||
|
|
@ -325,12 +406,19 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
|||
busy: closeSmenaBusy,
|
||||
icon: Icons.lock_outline,
|
||||
),
|
||||
// AmanIconButton(
|
||||
// title: 'Денег в кассе',
|
||||
// onPressed: _checkMoney,
|
||||
// busy: isMoneyCheckBusy,
|
||||
// icon: MdiIcons.walletOutline,
|
||||
// mainColor: primaryColor,
|
||||
// ),
|
||||
AmanIconButton(
|
||||
title: 'Денег в кассе',
|
||||
onPressed: _checkMoney,
|
||||
busy: isMoneyCheckBusy,
|
||||
icon: MdiIcons.walletOutline,
|
||||
mainColor: primaryColor,
|
||||
title: 'Закрыть POS',
|
||||
onPressed: _closeDay,
|
||||
busy: isClosePosBusy,
|
||||
icon: Icons.phonelink_lock_outlined,
|
||||
mainColor: purpleColor,
|
||||
),
|
||||
AmanIconButton(
|
||||
title: 'Х Отчет',
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
|||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/operation_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||
|
|
@ -183,6 +184,7 @@ class KassaTab extends StatelessWidget {
|
|||
|
||||
Future<void> scan() async {
|
||||
try {
|
||||
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
||||
var options = ScanOptions(strings: {
|
||||
"cancel": 'Отмена',
|
||||
"flash_on": 'Вкл фонарик',
|
||||
|
|
@ -217,7 +219,7 @@ class KassaTab extends StatelessWidget {
|
|||
List<Good> goods =
|
||||
await _dataService.getGoodsByBarcode(barcode: barcode);
|
||||
if (goods != null && goods.isNotEmpty) {
|
||||
Redux.store.dispatch(addProductToKassaItems(goods.first, dataMatrix));
|
||||
await Redux.store.dispatch(addProductToKassaItems(goods.first, dataMatrix));
|
||||
} else {
|
||||
_dialogService.showDialog(
|
||||
description: 'Товар не найден: $barcode');
|
||||
|
|
@ -238,33 +240,48 @@ class KassaTab extends StatelessWidget {
|
|||
result.rawContent = 'Unknown error: $e';
|
||||
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
|
||||
}
|
||||
} finally {
|
||||
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void showModalBottomSheetCatalog(BuildContext context, String action) {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
backgroundColor: Colors.transparent,
|
||||
builder: (context) {
|
||||
return DraggableScrollableSheet(
|
||||
initialChildSize: 0.8,
|
||||
maxChildSize: 0.95,
|
||||
minChildSize: 0.5,
|
||||
builder: (BuildContext context, ScrollController scrollController) {
|
||||
if (action == 'add') {
|
||||
return ProductAddBottomSheet(
|
||||
scrollController: scrollController,
|
||||
);
|
||||
} else {
|
||||
return CatalogBottomSheet(
|
||||
scrollController: scrollController,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
if (action == 'add') {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => ProductAddBottomSheet())
|
||||
);
|
||||
} else {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => CatalogBottomSheet())
|
||||
);
|
||||
}
|
||||
|
||||
// showModalBottomSheet(
|
||||
// context: context,
|
||||
// isScrollControlled: true,
|
||||
// backgroundColor: Colors.transparent,
|
||||
// builder: (context) {
|
||||
// return DraggableScrollableSheet(
|
||||
// initialChildSize: 0.8,
|
||||
// maxChildSize: 0.95,
|
||||
// minChildSize: 0.5,
|
||||
// builder: (BuildContext context, ScrollController scrollController) {
|
||||
// if (action == 'add') {
|
||||
// return ProductAddBottomSheet(
|
||||
// scrollController: scrollController,
|
||||
// );
|
||||
// } else {
|
||||
// return CatalogBottomSheet(
|
||||
// scrollController: scrollController,
|
||||
// );
|
||||
// }
|
||||
// },
|
||||
// );
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
|
|||
),
|
||||
),
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.only(top: 15, left: 10, right: 15),
|
||||
padding: EdgeInsets.only(top: 15, left: 10, right: 15, bottom: 0 ),
|
||||
child: ListView(
|
||||
controller: widget.scrollController,
|
||||
children: <Widget>[
|
||||
|
|
@ -78,7 +78,8 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
|
|||
decimal: false,
|
||||
),
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
WhitelistingTextInputFormatter.digitsOnly
|
||||
// WhitelistingTextInputFormatter.digitsOnly
|
||||
FilteringTextInputFormatter.digitsOnly
|
||||
],
|
||||
controller: countController,
|
||||
onChanged: calcOnChange,
|
||||
|
|
@ -95,7 +96,7 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
|
|||
keyboardType:
|
||||
const TextInputType.numberWithOptions(decimal: true),
|
||||
inputFormatters: <TextInputFormatter>[
|
||||
WhitelistingTextInputFormatter(RegExp("^[0-9.]*")),
|
||||
FilteringTextInputFormatter.allow(RegExp("^[0-9.]*")),
|
||||
],
|
||||
controller: priceController,
|
||||
onChanged: calcOnChange,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_lock_screen/flutter_lock_screen.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
|
||||
class PassCodeScreen extends StatefulWidget {
|
||||
PassCodeScreen({Key key, this.title}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
_PassCodeScreenState createState() => new _PassCodeScreenState();
|
||||
}
|
||||
|
||||
class _PassCodeScreenState extends State<PassCodeScreen> {
|
||||
// bool isFingerprint = false;
|
||||
NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
final backgroundedTimeKey = 'backgroundedTimeKey';
|
||||
|
||||
|
||||
// Future<Null> biometrics() async {
|
||||
// final LocalAuthentication auth = new LocalAuthentication();
|
||||
// bool authenticated = false;
|
||||
//
|
||||
// try {
|
||||
// authenticated = await auth.authenticateWithBiometrics(
|
||||
// localizedReason: 'Scan your fingerprint to authenticate',
|
||||
// useErrorDialogs: true,
|
||||
// stickyAuth: false);
|
||||
// } on PlatformException catch (e) {
|
||||
// print(e);
|
||||
// }
|
||||
// if (!mounted) return;
|
||||
// if (authenticated) {
|
||||
// setState(() {
|
||||
// isFingerprint = true;
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var myPass = [];
|
||||
String _pinCode = Redux.store.state.settingState.pinCode;
|
||||
for (var i = 0; i < _pinCode.length; i++) {
|
||||
myPass.add(int.parse(_pinCode[i]));
|
||||
}
|
||||
return LockScreen(
|
||||
title: "Введите ПИН-код",
|
||||
passLength: myPass.length,
|
||||
bgImage: "assets/images/secBg.jpg",
|
||||
// fingerPrintImage: "assets/images/finger.png",
|
||||
// showFingerPass: true,
|
||||
// fingerFunction: biometrics,
|
||||
// fingerVerify: isFingerprint,
|
||||
borderColor: Colors.white,
|
||||
showWrongPassDialog: true,
|
||||
wrongPassContent: "Неверный код, повторите попытку",
|
||||
wrongPassTitle: "Aman Kassa",
|
||||
wrongPassCancelButtonText: "Отмена",
|
||||
passCodeVerify: (passcode) async {
|
||||
for (int i = 0; i < myPass.length; i++) {
|
||||
if (passcode[i] != myPass[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
onSuccess: () {
|
||||
Redux.store.dispatch(changePinLockedFromSetting(false));
|
||||
_navigatorService.replace(HomeViewRoute);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -70,75 +70,79 @@ class _LoginViewState extends State<LoginView> {
|
|||
return Scaffold(
|
||||
key: _scaffoldKey,
|
||||
backgroundColor: fillColor,
|
||||
body: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Stack(
|
||||
alignment: Alignment.bottomLeft,
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 150,
|
||||
child: Image.asset('assets/images/logo.png'),
|
||||
),
|
||||
Positioned(
|
||||
child: Text(
|
||||
'онлайн касса',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
body: SingleChildScrollView(
|
||||
physics: BouncingScrollPhysics(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
verticalSpaceLarge,
|
||||
Stack(
|
||||
alignment: Alignment.bottomLeft,
|
||||
children: <Widget>[
|
||||
SizedBox(
|
||||
height: 150,
|
||||
child: Image.asset('assets/images/logo.png'),
|
||||
),
|
||||
bottom: 23.0,
|
||||
left: 25.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
Positioned(
|
||||
child: Text(
|
||||
'онлайн касса',
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
bottom: 23.0,
|
||||
left: 25.0,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
InputField(
|
||||
placeholder: 'Электронная почта',
|
||||
controller: emailController,
|
||||
textInputType: TextInputType.emailAddress,
|
||||
nextFocusNode: passwordNode,
|
||||
additionalNote: vm.loginFormMessage.email,
|
||||
),
|
||||
verticalSpaceSmall,
|
||||
InputField(
|
||||
placeholder: 'Пароль',
|
||||
password: true,
|
||||
controller: passwordController,
|
||||
fieldFocusNode: passwordNode,
|
||||
additionalNote: vm.loginFormMessage.password,
|
||||
enterPressed: _pressBtnEnter,
|
||||
textInputAction: TextInputAction.done,
|
||||
),
|
||||
verticalSpaceMedium,
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 150,
|
||||
child: BusyButton(
|
||||
title: 'Войти',
|
||||
busy: vm.isLoading,
|
||||
onPressed: _pressBtnEnter,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
verticalSpaceLarge,
|
||||
InputField(
|
||||
placeholder: 'Электронная почта',
|
||||
controller: emailController,
|
||||
textInputType: TextInputType.emailAddress,
|
||||
nextFocusNode: passwordNode,
|
||||
additionalNote: vm.loginFormMessage.email,
|
||||
),
|
||||
verticalSpaceSmall,
|
||||
InputField(
|
||||
placeholder: 'Пароль',
|
||||
password: true,
|
||||
controller: passwordController,
|
||||
fieldFocusNode: passwordNode,
|
||||
additionalNote: vm.loginFormMessage.password,
|
||||
enterPressed: _pressBtnEnter,
|
||||
textInputAction: TextInputAction.done,
|
||||
),
|
||||
verticalSpaceMedium,
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 150,
|
||||
child: BusyButton(
|
||||
title: 'Войти',
|
||||
busy: vm.isLoading,
|
||||
onPressed: _pressBtnEnter,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
verticalSpaceLarge,
|
||||
// TextLink(
|
||||
// 'Регистрация',
|
||||
// onPressed: () {},
|
||||
// ),
|
||||
IconButton(
|
||||
icon: Icon(MdiIcons.qrcodeScan),
|
||||
iconSize: 40,
|
||||
tooltip: "Scan",
|
||||
onPressed: scan,
|
||||
)
|
||||
],
|
||||
IconButton(
|
||||
icon: Icon(MdiIcons.qrcodeScan),
|
||||
iconSize: 40,
|
||||
tooltip: "Scan",
|
||||
onPressed: scan,
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,158 @@
|
|||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/logger.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart'
|
||||
as Cd;
|
||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_response_dao.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
import '../../core/models/aman_dao.dart';
|
||||
import '../../core/models/card_data.dart';
|
||||
import '../../core/models/halyk/halyk_post_session.dart';
|
||||
import '../../core/services/BankService.dart';
|
||||
import '../../redux/state/bank_state.dart';
|
||||
|
||||
BankService _bankService = locator<BankService>();
|
||||
DialogService _dialogService = locator<DialogService>();
|
||||
final DataService _dataService = locator<DataService>();
|
||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
Logger log = getLogger('PaymentNfcView');
|
||||
|
||||
Future<AmanDao<CardData>> paymentHalykPos(double total) async {
|
||||
//Авторизация
|
||||
String token = Redux.store.state.userState.user.token;
|
||||
BankState bankState = Redux.store.state.bankState;
|
||||
//права доступа
|
||||
HalykPosSession session = await _bankService.renewToken(
|
||||
token: token, login: bankState.login, password: bankState.password);
|
||||
if (session.token == null) {
|
||||
return sessionDeclineDao(session);
|
||||
}
|
||||
|
||||
//Инициализация
|
||||
HalykResponse response =
|
||||
await _bankService.pay(token: session.token, amount: total);
|
||||
if (response.result.code == 0) {
|
||||
CardData cardData = new CardData(
|
||||
authorizationCode:
|
||||
response.transaction.instrumentSpecificData.authorizationCode,
|
||||
cardholderName:
|
||||
response.transaction.instrumentSpecificData.cardholderName,
|
||||
cardNumber: response.transaction.instrumentSpecificData.maskedPan,
|
||||
operationDay: response.transaction.operationDay,
|
||||
transactionNumber: response.transaction.transactionNumber,
|
||||
terminalId: response.transaction.terminalId,
|
||||
transactionType: 'payment');
|
||||
return AmanDao<CardData>(
|
||||
msg: response.result.description, success: true, data: cardData);
|
||||
}
|
||||
return AmanDao<CardData>(
|
||||
msg: response.result.errorData != null
|
||||
? response.result.errorData.description
|
||||
: response.result.description,
|
||||
success: false);
|
||||
}
|
||||
|
||||
AmanDao<CardData> sessionDeclineDao(HalykPosSession session) {
|
||||
String msg = 'Отказано в доступе к API банка';
|
||||
if(session.result?.Response?.Description != null) {
|
||||
msg = '${session.result.Response.Description} (${session.result.Response.Code}) ';
|
||||
}
|
||||
return AmanDao<CardData>(success: false, msg: msg);
|
||||
}
|
||||
|
||||
Future<AmanDao<CardData>> refundHalykPos(
|
||||
CardData refundData, double total) async {
|
||||
//Авторизация
|
||||
String token = Redux.store.state.userState.user.token;
|
||||
BankState bankState = Redux.store.state.bankState;
|
||||
//права доступа
|
||||
HalykPosSession session = await _bankService.renewToken(
|
||||
token: token, login: bankState.login, password: bankState.password);
|
||||
if (session.token == null) {
|
||||
return sessionDeclineDao(session);
|
||||
}
|
||||
HalykResponse response = await _bankService.refund(
|
||||
token: session.token,
|
||||
amount: total,
|
||||
operDay: refundData.operationDay,
|
||||
terminalId: refundData.terminalId,
|
||||
transNum: refundData.transactionNumber);
|
||||
if (response.result.code == 0) {
|
||||
CardData cardData = new CardData(
|
||||
authorizationCode:
|
||||
response.transaction.instrumentSpecificData.authorizationCode,
|
||||
cardholderName:
|
||||
response.transaction.instrumentSpecificData.cardholderName,
|
||||
cardNumber: response.transaction.instrumentSpecificData.maskedPan,
|
||||
operationDay: response.transaction.operationDay,
|
||||
transactionNumber: response.transaction.transactionNumber,
|
||||
terminalId: response.transaction.terminalId,
|
||||
transactionType: 'refund');
|
||||
return AmanDao<CardData>(
|
||||
msg: response.result.description, success: true, data: cardData);
|
||||
}
|
||||
return AmanDao<CardData>(
|
||||
msg: response.result.errorData != null
|
||||
? response.result.errorData.description
|
||||
: response.result.description,
|
||||
success: false);
|
||||
}
|
||||
|
||||
Future<AmanDao<CardData>> reversalHalykPos(
|
||||
CardData refundData, double total) async {
|
||||
//Авторизация
|
||||
String token = Redux.store.state.userState.user.token;
|
||||
BankState bankState = Redux.store.state.bankState;
|
||||
//права доступа
|
||||
HalykPosSession session = await _bankService.renewToken(
|
||||
token: token, login: bankState.login, password: bankState.password);
|
||||
if (session.token == null) {
|
||||
return sessionDeclineDao(session);
|
||||
}
|
||||
log.i(refundData.toJson());
|
||||
HalykResponse response = await _bankService.reversal(
|
||||
token: session.token,
|
||||
operDay: refundData.operationDay,
|
||||
terminalId: refundData.terminalId,
|
||||
transNum: refundData.transactionNumber);
|
||||
if (response.result.code == 0) {
|
||||
CardData cardData = new CardData(
|
||||
authorizationCode:
|
||||
response.transaction.instrumentSpecificData.authorizationCode,
|
||||
cardholderName:
|
||||
response.transaction.instrumentSpecificData.cardholderName,
|
||||
cardNumber: response.transaction.instrumentSpecificData.maskedPan,
|
||||
operationDay: response.transaction.operationDay,
|
||||
transactionNumber: response.transaction.transactionNumber,
|
||||
terminalId: response.transaction.terminalId,
|
||||
transactionType: 'reversal');
|
||||
return AmanDao<CardData>(
|
||||
msg: response.result.description, success: true, data: cardData);
|
||||
}
|
||||
return AmanDao<CardData>(
|
||||
msg: response.result.errorData != null
|
||||
? response.result.errorData.description
|
||||
: response.result.description,
|
||||
success: false);
|
||||
}
|
||||
|
||||
Future<Cd.HalykCloseDayDao> closeDayHalykPos() async {
|
||||
//Авторизация
|
||||
String token = Redux.store.state.userState.user.token;
|
||||
BankState bankState = Redux.store.state.bankState;
|
||||
//права доступа
|
||||
HalykPosSession session = await _bankService.renewToken(
|
||||
token: token, login: bankState.login, password: bankState.password);
|
||||
if (session.token == null) {
|
||||
return new Cd.HalykCloseDayDao(
|
||||
result: Cd.ResultBean(
|
||||
description: 'Отказано в доступе к API банка', code: -1));
|
||||
}
|
||||
//Инициализация
|
||||
Cd.HalykCloseDayDao response =
|
||||
await _bankService.closeDay(token: session.token);
|
||||
return response;
|
||||
}
|
||||
|
|
@ -1,16 +1,24 @@
|
|||
import 'dart:convert';
|
||||
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
|
||||
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/calc_model.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/card_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/product_dao.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/BankService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/calc_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/setting_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/operation_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/calc_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
|
|
@ -22,6 +30,12 @@ import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
|||
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart';
|
||||
|
||||
import '../../core/models/aman_dao.dart';
|
||||
import '../../core/models/card_data.dart';
|
||||
import '../../core/models/card_data.dart';
|
||||
|
||||
class PaymentView extends StatefulWidget {
|
||||
final PaymentModel model;
|
||||
|
|
@ -36,13 +50,26 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||
final DataService _dataService = locator<DataService>();
|
||||
final DialogService _dialogService = locator<DialogService>();
|
||||
BankService _bankService = locator<BankService>();
|
||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
bool isBusy;
|
||||
bool isBankApiAccess;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
isBusy = false;
|
||||
isBankApiAccess = false;
|
||||
_bankInit();
|
||||
}
|
||||
|
||||
_bankInit() async {
|
||||
int version = await _bankService.version();
|
||||
if (version >= _bankService.sdkVersion) {
|
||||
setState(() {
|
||||
isBankApiAccess = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -92,9 +119,10 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
String dataTitle() =>
|
||||
widget.model.operationType == OperationTypePay ? 'Оплата' : 'Возврат';
|
||||
|
||||
String dataText() => widget.model.operationType == OperationTypePay
|
||||
? 'К оплате'
|
||||
: 'К возврату';
|
||||
String dataText() =>
|
||||
widget.model.operationType == OperationTypePay
|
||||
? 'К оплате'
|
||||
: 'К возврату';
|
||||
|
||||
StoreConnector buildStoreConnector() {
|
||||
if (widget.model.mode == SettingModeCalc) {
|
||||
|
|
@ -130,42 +158,139 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
children: <Widget>[
|
||||
Expanded(
|
||||
child: BusyButton(
|
||||
title: 'Оплатить картой',
|
||||
onPressed: () {
|
||||
pressPayment('card');
|
||||
},
|
||||
mainColor: greenColor,
|
||||
)),
|
||||
title: 'Оплатить картой',
|
||||
onPressed: () {
|
||||
pressPayment('card', null);
|
||||
},
|
||||
mainColor: primaryColor,
|
||||
)),
|
||||
horizontalSpaceSmall,
|
||||
Expanded(
|
||||
child: BusyButton(
|
||||
title: 'Наличными',
|
||||
onPressed: () {
|
||||
pressPayment('cash');
|
||||
},
|
||||
mainColor: primaryColor,
|
||||
)),
|
||||
title: 'Наличными',
|
||||
onPressed: () {
|
||||
pressPayment('cash', null);
|
||||
},
|
||||
mainColor: greenColor,
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
verticalSpaceLarge,
|
||||
_nfsButtonRender(),
|
||||
verticalSpaceSmall,
|
||||
Expanded(
|
||||
child: Container(),
|
||||
),
|
||||
Container(
|
||||
child: BusyButton(
|
||||
title: 'Отмена',
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
mainColor: redColor,
|
||||
)),
|
||||
title: 'Отмена',
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
mainColor: redColor,
|
||||
)),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
pressPayment(String type) async {
|
||||
Widget _nfsButtonRender() {
|
||||
if (!isBankApiAccess || widget.model.operationType != OperationTypePay) {
|
||||
return Container();
|
||||
}
|
||||
return StoreConnector<AppState, AppState>(
|
||||
converter: (store) => store.state,
|
||||
builder: (_, _state) {
|
||||
BankState state = _state.bankState;
|
||||
double _total;
|
||||
if (widget.model.mode == SettingModeCalc) {
|
||||
String value = totalCalc(_state.calcState.calcItems);
|
||||
_total = double.parse(value);
|
||||
} else {
|
||||
String value = totalKassa(_state.kassaState.kassaItems);
|
||||
_total = double.parse(value);
|
||||
}
|
||||
|
||||
if (state.password == null || state.login == null || state.password.length < 1 || state.login.length < 1) {
|
||||
return Container();
|
||||
}
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
|
||||
var today = new DateTime.now();
|
||||
var yesterday = today.subtract(new Duration(days: 1));
|
||||
if( Redux.store.state.userState == null
|
||||
|| Redux.store.state.userState.smena == null
|
||||
|| Redux.store.state.userState.smena.startedAt == null
|
||||
|| yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
|
||||
_dialogService.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
||||
AmanDao<CardData> data = await paymentHalykPos(_total);
|
||||
if (data.success) {
|
||||
pressPayment(widget.model.operationType, data.data);
|
||||
} else {
|
||||
_dialogService.showDialog(description: data.msg);
|
||||
}
|
||||
} finally {
|
||||
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
||||
}
|
||||
},
|
||||
splashColor: halykColor.withOpacity(0.4),
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
highlightColor: halykColor.withOpacity(0.1),
|
||||
child: Container(
|
||||
width: ScreenUtil().setSp(100.0),
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(10.0)
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
width: ScreenUtil().setSp(80.0),
|
||||
height: ScreenUtil().setSp(80.0),
|
||||
margin: const EdgeInsets.only(bottom: 8.0),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.white),
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
image: DecorationImage(
|
||||
image: AssetImage('assets/images/halykpos.png'), fit: BoxFit.fitWidth
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset: Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: [
|
||||
// Icon(
|
||||
// MdiIcons.nfc,
|
||||
// color: halykColor,
|
||||
// size: ScreenUtil().setSp(20.0),
|
||||
// ),
|
||||
// Text('Tap2Phone',style: TextStyle(fontSize: ScreenUtil().setSp(10.0), color: halykColor, fontWeight: FontWeight.bold ),),
|
||||
// ],
|
||||
// ),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
pressPayment(String type, CardData cardData) async {
|
||||
setState(() {
|
||||
isBusy = true;
|
||||
});
|
||||
|
|
@ -187,14 +312,17 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
operationType: widget.model.operationType,
|
||||
tradeType: _tradeType,
|
||||
calcItems: calcItems,
|
||||
mode: _mode);
|
||||
mode: _mode,
|
||||
cardData: cardData
|
||||
);
|
||||
setState(() {
|
||||
isBusy = false;
|
||||
});
|
||||
if( response != null) {
|
||||
if (response != null) {
|
||||
if (response.operation) {
|
||||
String message = response.body['message'];
|
||||
String check = response.body['check'];
|
||||
var checkText = response.body['check_text'];
|
||||
String url = response?.body['link'];
|
||||
print('url : $url');
|
||||
if (_mode == SettingModeCalc) {
|
||||
|
|
@ -207,24 +335,26 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
_navigatorService.pop();
|
||||
_navigatorService.push(ImageShowRoute,
|
||||
arguments: ImageShowModel(data:check, title: message, url: url ));
|
||||
} else if (!response.operation && ![401,402,403,412,500].contains(response.status)) {
|
||||
arguments: ImageShowModel(data: new CheckImageModal(
|
||||
base64Data: check, textData: checkText != null ? jsonEncode(checkText) : null),
|
||||
title: message,
|
||||
url: url));
|
||||
} else if (!response.operation && ![401, 402, 403, 412, 500].contains(response.status)) {
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
_dialogService.showDialog(description: response.body['message']);
|
||||
} else if(!response.operation && response.body['message'] != null) {
|
||||
} else if (!response.operation && response.body['message'] != null) {
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
_dialogService.showDialog(description: response.body['message']);
|
||||
} else {
|
||||
} else {
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
}
|
||||
} else {
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
} finally {
|
||||
|
||||
//Navigator.of(context, rootNavigator: true).pop();
|
||||
setState(() {
|
||||
isBusy = false;
|
||||
|
|
@ -258,5 +388,8 @@ class _PaymentViewState extends State<PaymentView> {
|
|||
class PaymentModel {
|
||||
String operationType;
|
||||
String mode;
|
||||
PaymentModel({this.mode, this.operationType});
|
||||
Voucher voucher;
|
||||
CardData cardData;
|
||||
|
||||
PaymentModel({this.mode, this.operationType, this.voucher, this.cardData});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,525 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:aman_kassa_flutter/core/entity/Voucher.dart';
|
||||
import 'package:aman_kassa_flutter/core/locator.dart';
|
||||
import 'package:aman_kassa_flutter/core/logger.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/aman_dao.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/calc_model.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/card_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_data.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/product_dao.dart';
|
||||
import 'package:aman_kassa_flutter/core/models/response.dart';
|
||||
import 'package:aman_kassa_flutter/core/route_names.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/BankService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/dialog_service.dart';
|
||||
import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/calc_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/kassa_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/actions/user_actions.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/operation_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/calc_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:aman_kassa_flutter/views/check/image_show_container.dart';
|
||||
import 'package:aman_kassa_flutter/views/payment/payment_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/payment_nfc/widgets/action_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/payment_nfc/widgets/background_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/payment_nfc/widgets/card_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/payment_nfc/widgets/logo_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/payment_nfc/widgets/phone_view.dart';
|
||||
import 'package:aman_kassa_flutter/views/payment_nfc/widgets/text_state.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/components/calculator/calculator.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:logger/logger.dart';
|
||||
|
||||
class PaymentNfcView extends StatefulWidget {
|
||||
final PaymentModel model;
|
||||
const PaymentNfcView({Key key, this.model}) : super(key: key);
|
||||
|
||||
@override
|
||||
_PaymentNfcViewState createState() => _PaymentNfcViewState();
|
||||
}
|
||||
|
||||
class _PaymentNfcViewState extends State<PaymentNfcView> {
|
||||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||
BankService _bankService = locator<BankService>();
|
||||
DialogService _dialogService = locator<DialogService>();
|
||||
final DataService _dataService = locator<DataService>();
|
||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||
Logger log = getLogger('PaymentNfcView');
|
||||
bool isBusy;
|
||||
bool isPhoneScaled;
|
||||
int status;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
isBusy = false;
|
||||
isPhoneScaled = false;
|
||||
status = 0;
|
||||
start();
|
||||
}
|
||||
|
||||
void start() async {
|
||||
|
||||
//Авторизация
|
||||
String token = Redux.store.state.userState.user.token;
|
||||
BankState bankState = Redux.store.state.bankState;
|
||||
//права доступа
|
||||
HalykPosSession session = await _bankService.renewToken(token: token, login: bankState.login, password: bankState.password);
|
||||
log.i(session);
|
||||
if (session.token ==null) {
|
||||
setState(() {
|
||||
status = 4;
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//права доступа
|
||||
// bool success = await _bankService.permissions();
|
||||
// log.i(success);
|
||||
// if (!success) {
|
||||
// setState(() {
|
||||
// status = 4;
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
var today = new DateTime.now();
|
||||
var yesterday = today.subtract(new Duration(days: 1));
|
||||
if( Redux.store.state.userState == null
|
||||
|| Redux.store.state.userState.smena == null
|
||||
|| Redux.store.state.userState.smena.startedAt == null
|
||||
|| yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
|
||||
_dialogService.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
|
||||
_navigatorService.pop();
|
||||
return;
|
||||
}
|
||||
|
||||
// //Инициализация
|
||||
// bool initialized = await _bankService.init();
|
||||
// log.i(initialized);
|
||||
// if (!initialized) {
|
||||
// setState(() {
|
||||
// status = 4;
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
//Проверка связи
|
||||
// bool connected = await _bankService.connect();
|
||||
// log.i(connected);
|
||||
// if (!connected) {
|
||||
// setState(() {
|
||||
// status = 5;
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
|
||||
// AmanDao authDao = await _bankService.auth(
|
||||
// login: bankState.login, password: bankState.password);
|
||||
// if (!authDao.success) {
|
||||
// setState(() {
|
||||
// status = 6;
|
||||
// });
|
||||
//
|
||||
// if (authDao.msg != null) {
|
||||
// log.i(authDao.msg);
|
||||
// _dialogService.showDialog(description: authDao.msg);
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// //валюта
|
||||
// bool currency = await _bankService.currency();
|
||||
// log.i(currency);
|
||||
// if (!currency) {
|
||||
// setState(() {
|
||||
// status = 4;
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
|
||||
if(widget.model.voucher == null) {
|
||||
//pay();
|
||||
} else {
|
||||
refund();
|
||||
}
|
||||
}
|
||||
|
||||
refund() async {
|
||||
CardData _cardData = widget.model.cardData;
|
||||
// AmanDao findTransaction = await _bankService.findTransaction(transactionNumber: _cardData.transactionNumber, authorizationCode: _cardData.authorizationCode);
|
||||
// if(!findTransaction.success){
|
||||
// _dialogService.showDialog(description: findTransaction.msg);
|
||||
// setState(() {
|
||||
// status = 8;
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// setState(() {
|
||||
// status = 1;
|
||||
// isPhoneScaled = true;
|
||||
// });
|
||||
|
||||
// AmanDao refundDao = await _bankService.refund();
|
||||
// if (!refundDao.success) {
|
||||
// int _status = 7;
|
||||
//
|
||||
// setState(() {
|
||||
// status = _status;
|
||||
// isPhoneScaled = false;
|
||||
// });
|
||||
//
|
||||
// if (refundDao.msg != null) {
|
||||
// log.i(refundDao.msg);
|
||||
// _dialogService.showDialog(description: refundDao.msg);
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
|
||||
setState(() {
|
||||
status = 9;
|
||||
isPhoneScaled = false;
|
||||
});
|
||||
|
||||
//check
|
||||
//pressRefund('card' , refundDao.data);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// pay() async {
|
||||
// //Платеж
|
||||
// num total = 0.0;
|
||||
// if (widget.model.mode == SettingModeCalc) {
|
||||
// total = totalCalc(Redux.store.state.calcState.calcItems);
|
||||
// } else {
|
||||
// total = totalKassa(Redux.store.state.kassaState.kassaItems);
|
||||
// }
|
||||
//
|
||||
// setState(() {
|
||||
// status = 1;
|
||||
// isPhoneScaled = true;
|
||||
// });
|
||||
//
|
||||
// log.i('total: $total');
|
||||
// AmanDao payDao = await _bankService.pay(amount: total);
|
||||
// if (!payDao.success) {
|
||||
// int _status = 7;
|
||||
// if (payDao.data != null ) {
|
||||
// if("onWrongApiCalled" == payDao.data.toString()) {
|
||||
// cancel();
|
||||
// } else if("notAuthorized" == payDao.data.toString() ) {
|
||||
// cancel();
|
||||
// _status = 6;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// setState(() {
|
||||
// status = _status;
|
||||
// isPhoneScaled = false;
|
||||
// });
|
||||
//
|
||||
// if (payDao.msg != null) {
|
||||
// log.i(payDao.msg);
|
||||
// _dialogService.showDialog(description: payDao.msg);
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// setState(() {
|
||||
// status = 3;
|
||||
// isPhoneScaled = false;
|
||||
// });
|
||||
//
|
||||
// //check
|
||||
// pressPayment('card' , payDao.data);
|
||||
// }
|
||||
|
||||
cancel() async {
|
||||
// bool isCanceled = await _bankService.cancel();
|
||||
// _navigatorService.pop();
|
||||
}
|
||||
|
||||
pressPayment(String type, dynamic cardDataDynamic) async {
|
||||
setState(() {
|
||||
isBusy = true;
|
||||
});
|
||||
Dialogs.showLoadingDialog(context, _keyLoader);
|
||||
try {
|
||||
AppState _state = Redux.store.state;
|
||||
String _token = _state.userState.user.token;
|
||||
String _tradeType = _state.settingState.tradeType;
|
||||
String _mode = _state.settingState.mode;
|
||||
if (_mode == SettingModeCalc) {
|
||||
_tradeType = SettingTradeTypeGood;
|
||||
}
|
||||
CardData cardData = cardDataDynamic != null ? CardData.fromJson(cardDataDynamic) : null;
|
||||
|
||||
List<ProductDao> kassaItems = _state.kassaState.kassaItems;
|
||||
List<CalcModel> calcItems = _state.calcState.calcItems;
|
||||
Response<dynamic> response = await _dataService.sellOrReturn(
|
||||
token: _token,
|
||||
kassaItems: kassaItems,
|
||||
paymentType: type,
|
||||
operationType: widget.model.operationType,
|
||||
tradeType: _tradeType,
|
||||
calcItems: calcItems,
|
||||
mode: _mode,
|
||||
cardData: cardData
|
||||
);
|
||||
setState(() {
|
||||
isBusy = false;
|
||||
});
|
||||
if (response != null) {
|
||||
if (response.operation) {
|
||||
String message = response.body['message'];
|
||||
String check = response.body['check'];
|
||||
var checkText = response.body['check_text'];
|
||||
String url = response?.body['link'];
|
||||
if (_mode == SettingModeCalc) {
|
||||
Redux.store.dispatch(cleanCalcItems);
|
||||
} else if (_mode == SettingModeKassa) {
|
||||
Redux.store.dispatch(cleanKassaItems);
|
||||
}
|
||||
Redux.store.dispatch(checkMoney);
|
||||
Redux.store.dispatch(openSmenaPseudo);
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
_navigatorService.replace(HomeViewRoute);
|
||||
_navigatorService.push(ImageShowRoute,
|
||||
arguments: ImageShowModel(data: new CheckImageModal(base64Data: check, textData: checkText !=null ? jsonEncode(checkText) : null ), title: message, url: url));
|
||||
} else if (!response.operation &&
|
||||
![401, 402, 403, 412, 500].contains(response.status)) {
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
_dialogService.showDialog(description: response.body['message']);
|
||||
} else {
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
}
|
||||
} else {
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
}
|
||||
} catch (e) {
|
||||
print(e);
|
||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||
} finally {
|
||||
//Navigator.of(context, rootNavigator: true).pop();
|
||||
setState(() {
|
||||
isBusy = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
//_bankService.shutdown();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return WillPopScope(
|
||||
onWillPop: () {
|
||||
if (!isBusy) Navigator.pop(context);
|
||||
return new Future(() => false);
|
||||
},
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
brightness: Brightness.light,
|
||||
backgroundColor: purpleColor,
|
||||
elevation: 0,
|
||||
leading: IconButton(
|
||||
icon: Icon(Icons.arrow_back_ios),
|
||||
color: whiteColor,
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
title: Text(
|
||||
dataTitle(),
|
||||
style: TextStyle(color: whiteColor),
|
||||
),
|
||||
),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(color: purpleColor),
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: ScreenUtil().setSp(12.0),
|
||||
horizontal: ScreenUtil().setSp(12.0)),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
dataText(),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: whiteColor.withOpacity(0.7),
|
||||
fontSize: ScreenUtil().setSp(15.0)),
|
||||
),
|
||||
buildStoreConnector(),
|
||||
Expanded(
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
BackgroundView(),
|
||||
LogoView(),
|
||||
TextStateView(
|
||||
status: status,
|
||||
),
|
||||
CardView(
|
||||
show: isPhoneScaled,
|
||||
),
|
||||
PhoneView(
|
||||
scaled: isPhoneScaled,
|
||||
status: status,
|
||||
),
|
||||
buildActionView()
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
ActionView buildActionView() {
|
||||
switch (status) {
|
||||
case 5:
|
||||
return ActionView(
|
||||
show: true,
|
||||
acceptText: 'Повторить',
|
||||
acceptCallback: () async {
|
||||
//await _bankService.shutdown();
|
||||
start();
|
||||
},
|
||||
declineText: 'Отмена',
|
||||
declineCallback: () {
|
||||
cancel();
|
||||
},
|
||||
);
|
||||
break;
|
||||
case 6:
|
||||
return ActionView(
|
||||
show: true,
|
||||
acceptText: 'Повторить',
|
||||
acceptCallback: () async {
|
||||
//await _bankService.shutdown();
|
||||
start();
|
||||
},
|
||||
declineText: 'Отмена',
|
||||
declineCallback: () {
|
||||
cancel();
|
||||
},
|
||||
);
|
||||
break;
|
||||
case 7:
|
||||
return ActionView(
|
||||
show: true,
|
||||
acceptText: 'Повторить',
|
||||
acceptCallback: () {
|
||||
//pay();
|
||||
},
|
||||
declineText: 'Отмена',
|
||||
declineCallback: () {
|
||||
cancel();
|
||||
},
|
||||
);
|
||||
break;
|
||||
case 8:
|
||||
return ActionView(
|
||||
show: true,
|
||||
acceptText: 'Повторить',
|
||||
acceptCallback: () {
|
||||
refund();
|
||||
},
|
||||
declineText: 'Отмена',
|
||||
declineCallback: () {
|
||||
cancel();
|
||||
},
|
||||
);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
|
||||
return ActionView();
|
||||
}
|
||||
|
||||
String dataTitle() =>
|
||||
widget.model.operationType == OperationTypePay ? 'Оплата' : 'Возврат';
|
||||
|
||||
String dataText() => widget.model.operationType == OperationTypePay
|
||||
? 'К оплате'
|
||||
: 'К возврату';
|
||||
|
||||
StoreConnector buildStoreConnector() {
|
||||
if (widget.model.mode == SettingModeCalc) {
|
||||
return StoreConnector<AppState, CalcState>(
|
||||
converter: (store) => store.state.calcState,
|
||||
builder: (_, vm) {
|
||||
return Text('${totalCalc(vm.calcItems)} тнг',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: whiteColor,
|
||||
fontSize: 35));
|
||||
});
|
||||
}
|
||||
if(widget.model.voucher !=null) {
|
||||
return StoreConnector<AppState, KassaState>(
|
||||
converter: (store) => store.state.kassaState,
|
||||
builder: (_, vm) {
|
||||
return Text('${widget.model.voucher.total} тнг',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: whiteColor,
|
||||
fontSize: 35));
|
||||
});
|
||||
}
|
||||
return StoreConnector<AppState, KassaState>(
|
||||
converter: (store) => store.state.kassaState,
|
||||
builder: (_, vm) {
|
||||
return Text('${totalKassa(vm.kassaItems)} тнг',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: whiteColor,
|
||||
fontSize: 35));
|
||||
});
|
||||
}
|
||||
|
||||
num totalKassa(List<ProductDao> kassaItems) {
|
||||
num total = 0.0;
|
||||
kassaItems.forEach((element) {
|
||||
total += element.total == null ? 0.0 : element.total.toDouble();
|
||||
});
|
||||
return total;
|
||||
}
|
||||
|
||||
num totalCalc(List<CalcModel> items) {
|
||||
num total = 0.0;
|
||||
items.forEach((element) {
|
||||
if (element.operation == Calculations.MULTIPLY) {
|
||||
double num1 = element.num1 == null ? 0.0 : double.parse(element.num1);
|
||||
double num2 = element.num2 == null ? 0.0 : double.parse(element.num2);
|
||||
total += num1 * num2;
|
||||
} else {
|
||||
total += element.num1 == null ? 0.0 : double.parse(element.num1);
|
||||
}
|
||||
});
|
||||
return total;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:aman_kassa_flutter/widgets/fields/busy_button.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class ActionView extends StatelessWidget {
|
||||
final String acceptText;
|
||||
final String declineText;
|
||||
final void Function() acceptCallback;
|
||||
final void Function() declineCallback;
|
||||
final bool show;
|
||||
|
||||
const ActionView(
|
||||
{Key key,
|
||||
this.acceptText,
|
||||
this.declineText,
|
||||
this.acceptCallback,
|
||||
this.declineCallback,
|
||||
this.show = false})
|
||||
: super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Positioned(
|
||||
bottom: ScreenUtil().setSp(100),
|
||||
left: ScreenUtil().setSp(25),
|
||||
right: ScreenUtil().setSp(25),
|
||||
child: AnimatedOpacity(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
opacity: show ? 1.0 : 0.0,
|
||||
child: AnimatedContainer(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: buildContainer()),
|
||||
));
|
||||
}
|
||||
|
||||
Row buildContainer() {
|
||||
return Row(
|
||||
children: <Widget>[
|
||||
if (acceptCallback !=null && acceptText !=null)
|
||||
Expanded(child: BusyButton(title: acceptText, onPressed: acceptCallback)),
|
||||
SizedBox(width: 5.0,),
|
||||
if (declineCallback !=null && declineText !=null)
|
||||
BusyButton(title: declineText, onPressed: declineCallback, mainColor: redColor,)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class BackgroundView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Center(
|
||||
heightFactor: 1.5,
|
||||
child: Container(
|
||||
height: ScreenUtil().setSp(250.0),
|
||||
width: ScreenUtil().setSp(250.0),
|
||||
decoration:
|
||||
BoxDecoration(color: purpleSecondColor, shape: BoxShape.circle),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class CardView extends StatefulWidget {
|
||||
|
||||
final bool show;
|
||||
|
||||
const CardView({this.show = false });
|
||||
|
||||
@override
|
||||
_CardViewState createState() => _CardViewState();
|
||||
}
|
||||
|
||||
class _CardViewState extends State<CardView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Positioned(
|
||||
child: AnimatedOpacity(
|
||||
opacity: widget.show? 1 : 0.0,
|
||||
duration: Duration(seconds: 1),
|
||||
child: AnimatedContainer(
|
||||
height: ScreenUtil().setSp(250),
|
||||
width: ScreenUtil().setSp(250),
|
||||
transform: Matrix4.translationValues(widget.show? ScreenUtil().setSp(20.0) : 0.0, widget.show? ScreenUtil().setSp(-20.0) : 0.0, 0)
|
||||
//..rotateZ(widget.show? -0.2:0.0)
|
||||
,
|
||||
duration: const Duration(milliseconds: 1500),
|
||||
curve: Curves.fastOutSlowIn,
|
||||
child: Container(
|
||||
//color: Colors.red.withOpacity(0.1),
|
||||
//alignment: Alignment.bottomCenter,
|
||||
child: Image.asset(
|
||||
'assets/images/card.png',
|
||||
fit: BoxFit.contain,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class LogoView extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Positioned(
|
||||
bottom: ScreenUtil().setSp(75),
|
||||
left: ScreenUtil().setSp(25),
|
||||
right: ScreenUtil().setSp(25),
|
||||
child: Opacity(
|
||||
opacity: 0.5,
|
||||
child: Image.asset(
|
||||
'assets/images/NBK_Logo.png',
|
||||
fit: BoxFit.fitHeight,
|
||||
width: ScreenUtil().setSp(80.0),
|
||||
height: ScreenUtil().setSp(120.0),
|
||||
),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
|
||||
class PhoneView extends StatefulWidget {
|
||||
final bool scaled;
|
||||
final int status;
|
||||
|
||||
const PhoneView({this.scaled = false, this.status });
|
||||
|
||||
@override
|
||||
_PhoneViewState createState() => _PhoneViewState();
|
||||
}
|
||||
|
||||
class _PhoneViewState extends State<PhoneView> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AnimatedContainer(
|
||||
alignment: Alignment.topCenter,
|
||||
transform: Matrix4.translationValues(widget.scaled? ScreenUtil().setHeight(120) : 0.0, widget.scaled? ScreenUtil().setHeight(50) : 0.0, 0)
|
||||
..scale(widget.scaled? ScreenUtil().setSp(0.65) : 1.0)..rotateZ(widget.scaled? ScreenUtil().setSp(-0.2):0.0),
|
||||
duration: const Duration(milliseconds: 1500),
|
||||
curve: Curves.fastOutSlowIn,
|
||||
child: Container(
|
||||
width: ScreenUtil().setSp(380.0),
|
||||
height: ScreenUtil().setSp(520.0),
|
||||
//color: Colors.red.withOpacity(0.1),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: ScreenUtil().setSp(210.0),
|
||||
height: ScreenUtil().setSp(430.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white
|
||||
),
|
||||
child: Center(
|
||||
child: AnimatedSwitcher(child: buildContent(), duration: const Duration( milliseconds: 300),),
|
||||
),
|
||||
),
|
||||
Image.asset(
|
||||
'assets/images/phone_fit.png',
|
||||
fit: BoxFit.fitWidth,
|
||||
width: ScreenUtil().setSp(260.0),
|
||||
height: ScreenUtil().setSp(500.0),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildContent() {
|
||||
if(widget.status == 0){
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Icon(MdiIcons.timerSand, color: yellowColor,size: ScreenUtil().setSp(90.0),),
|
||||
verticalSpaceSmall,
|
||||
AutoSizeText('Инициализация', style: TextStyle(fontWeight: FontWeight.bold),)
|
||||
],
|
||||
);
|
||||
}
|
||||
if(widget.status == 1){
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: ScreenUtil().setSp(80.0),
|
||||
height: ScreenUtil().setSp(80.0),
|
||||
margin: const EdgeInsets.only(bottom: 8.0),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.white),
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
image: DecorationImage(
|
||||
image: AssetImage('assets/images/halykpos.png'), fit: BoxFit.fitWidth
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset: Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
verticalSpaceSmall,
|
||||
AutoSizeText('Ожидание карты', style: TextStyle(fontWeight: FontWeight.bold),)
|
||||
],
|
||||
);
|
||||
}
|
||||
if(widget.status == 2){
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Container(
|
||||
width: ScreenUtil().setSp(80.0),
|
||||
height: ScreenUtil().setSp(80.0),
|
||||
margin: const EdgeInsets.only(bottom: 8.0),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.white),
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
image: DecorationImage(
|
||||
image: AssetImage('assets/images/halykpos.png'), fit: BoxFit.fitWidth
|
||||
),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: Colors.grey.withOpacity(0.5),
|
||||
spreadRadius: 5,
|
||||
blurRadius: 7,
|
||||
offset: Offset(0, 3), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
verticalSpaceSmall,
|
||||
AutoSizeText('Проверка', style: TextStyle(fontWeight: FontWeight.bold),)
|
||||
],
|
||||
);
|
||||
}
|
||||
if(widget.status == 3){
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Icon(MdiIcons.checkBold, color: greenColor,size: ScreenUtil().setSp(90.0),),
|
||||
verticalSpaceSmall,
|
||||
AutoSizeText('Оплачено', style: TextStyle(fontWeight: FontWeight.bold),)
|
||||
],
|
||||
);
|
||||
}
|
||||
if(widget.status == 4){
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Icon(MdiIcons.closeOctagon, color: redColor,size: ScreenUtil().setSp(90.0),),
|
||||
verticalSpaceSmall,
|
||||
AutoSizeText('Ошибка инициализации', style: TextStyle(fontWeight: FontWeight.bold),)
|
||||
],
|
||||
);
|
||||
}
|
||||
if(widget.status == 5){
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Icon(MdiIcons.closeOctagon, color: redColor,size: ScreenUtil().setSp(90.0),),
|
||||
verticalSpaceSmall,
|
||||
AutoSizeText('Ошибка соединения', style: TextStyle(fontWeight: FontWeight.bold),),
|
||||
AutoSizeText('попробуйте еще раз', style: TextStyle(fontWeight: FontWeight.bold),)
|
||||
],
|
||||
);
|
||||
}
|
||||
if(widget.status == 6){
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Icon(MdiIcons.closeOctagon, color: redColor,size: ScreenUtil().setSp(90.0),),
|
||||
verticalSpaceSmall,
|
||||
AutoSizeText('Ошибка авторизации', style: TextStyle(fontWeight: FontWeight.bold),),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
if(widget.status == 7){
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Icon(MdiIcons.closeOctagon, color: redColor,size: ScreenUtil().setSp(90.0),),
|
||||
verticalSpaceSmall,
|
||||
AutoSizeText('Ошибка чтения карты', style: TextStyle(fontWeight: FontWeight.bold),),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
if(widget.status == 8){
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Icon(MdiIcons.closeOctagon, color: redColor,size: ScreenUtil().setSp(90.0),),
|
||||
verticalSpaceSmall,
|
||||
AutoSizeText('Ошибка транзакции', style: TextStyle(fontWeight: FontWeight.bold),),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
if(widget.status == 9){
|
||||
return Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Icon(MdiIcons.checkBold, color: greenColor,size: ScreenUtil().setSp(90.0),),
|
||||
verticalSpaceSmall,
|
||||
AutoSizeText('Возврат транзакции', style: TextStyle(fontWeight: FontWeight.bold),)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
return Container();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||
import 'package:auto_size_text/auto_size_text.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||
|
||||
class TextStateView extends StatelessWidget {
|
||||
final int status;
|
||||
final String text;
|
||||
|
||||
const TextStateView({Key key, this.status, this.text = ''}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Positioned(
|
||||
bottom: ScreenUtil().setSp(25),
|
||||
left: ScreenUtil().setSp(25),
|
||||
right: ScreenUtil().setSp(25),
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 300),
|
||||
child: buildAutoSizeText()));
|
||||
}
|
||||
|
||||
AutoSizeText buildAutoSizeText() {
|
||||
switch(status) {
|
||||
case 0:
|
||||
return AutoSizeText(
|
||||
'Инициализация',
|
||||
key: UniqueKey(),
|
||||
style: TextStyle(
|
||||
fontSize: ScreenUtil().setSp(25.0),
|
||||
color: whiteColor),
|
||||
);
|
||||
break;
|
||||
case 1:
|
||||
return AutoSizeText(
|
||||
'Сканирование',
|
||||
key: UniqueKey(),
|
||||
style: TextStyle(
|
||||
fontSize: ScreenUtil().setSp(25.0),
|
||||
color: whiteColor),
|
||||
);
|
||||
break;
|
||||
case 2:
|
||||
return AutoSizeText(
|
||||
'Проверка данных',
|
||||
key: UniqueKey(),
|
||||
style: TextStyle(
|
||||
fontSize: ScreenUtil().setSp(25.0),
|
||||
color: whiteColor),
|
||||
);
|
||||
break;
|
||||
case 3:
|
||||
return AutoSizeText(
|
||||
'Платеж прошел успешно',
|
||||
key: UniqueKey(),
|
||||
style: TextStyle(
|
||||
fontSize: ScreenUtil().setSp(25.0),
|
||||
color: whiteColor),
|
||||
);
|
||||
break;
|
||||
case 4:
|
||||
return AutoSizeText(
|
||||
'Ошибка',
|
||||
key: UniqueKey(),
|
||||
style: TextStyle(
|
||||
fontSize: ScreenUtil().setSp(25.0),
|
||||
color: whiteColor),
|
||||
);
|
||||
break;
|
||||
default:
|
||||
return AutoSizeText(
|
||||
text,
|
||||
key: UniqueKey(),
|
||||
style: TextStyle(
|
||||
fontSize: ScreenUtil().setSp(25.0),
|
||||
color: whiteColor),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ class _QrViewState extends State<QrView> {
|
|||
body: Container(
|
||||
child: Center(
|
||||
child: QrImage(
|
||||
data: widget.data.data,
|
||||
data: widget.data.url,
|
||||
version: QrVersions.auto,
|
||||
size: 220.0,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class SettingItem extends StatefulWidget {
|
||||
|
||||
final String name;
|
||||
final String value;
|
||||
final String title;
|
||||
final Function onTap;
|
||||
|
||||
SettingItem({Key key, this.name, this.value, this.onTap, this.title }) : super(key: key);
|
||||
|
||||
@override
|
||||
_SettingItemState createState() => _SettingItemState();
|
||||
}
|
||||
|
||||
class _SettingItemState extends State<SettingItem> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Card(
|
||||
child: ListTile(
|
||||
title: Text(widget.title),
|
||||
subtitle: Text.rich(
|
||||
TextSpan(
|
||||
text: widget.name,
|
||||
style: TextStyle(fontWeight: FontWeight.w500),
|
||||
children: <TextSpan>[
|
||||
if(widget.value !=null)
|
||||
TextSpan(text: ' ${widget.value}', style: TextStyle(fontStyle: FontStyle.italic)),
|
||||
],
|
||||
)
|
||||
),
|
||||
trailing: Icon(Icons.chevron_right),
|
||||
onTap: widget.onTap,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
import 'package:charset_converter/charset_converter.dart';
|
||||
import 'package:esc_pos_utils/esc_pos_utils.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:image/image.dart' as Im;
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
|
||||
Future<Ticket> testTicket(PaperSize paper) async {
|
||||
final Ticket ticket = Ticket(paper);
|
||||
|
||||
//Uint8List encTxt11 = await CharsetConverter.encode("cp866", "Russian: Привет Мир!");
|
||||
//ticket.textEncoded(encTxt11, styles: PosStyles(codeTable: PosCodeTable.pc866_2));
|
||||
//ticket.textEncoded(encTxt11);
|
||||
|
||||
// ticket.text('Special 1: àÀ', styles: PosStyles(codeTable: PosCodeTable.westEur)); //А
|
||||
// ticket.text('Special 1: á'.toUpperCase(), styles: PosStyles(codeTable: PosCodeTable.westEur));// Б
|
||||
// ticket.text('Special 1: â', styles: PosStyles(codeTable: PosCodeTable.westEur)); //В
|
||||
// ticket.text('Special 1: ã', styles: PosStyles(codeTable: PosCodeTable.westEur));// Г
|
||||
// ticket.text('Special 1: äÄ', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Д
|
||||
// ticket.text('Special 1: å', styles: PosStyles(codeTable: PosCodeTable.westEur));// Е
|
||||
// ticket.text('Special 1: æÆ', styles: PosStyles(codeTable: PosCodeTable.westEur));// Ж
|
||||
// ticket.text('Special 1: ç', styles: PosStyles(codeTable: PosCodeTable.westEur));//З
|
||||
// ticket.text('Special 1: èÈ', styles: PosStyles(codeTable: PosCodeTable.westEur)); // И
|
||||
// ticket.text('Special 1: éÉ', styles: PosStyles(codeTable: PosCodeTable.westEur)); // Й
|
||||
// ticket.text('Special 1: ê', styles: PosStyles(codeTable: PosCodeTable.westEur));//К
|
||||
// ticket.text('Special 1: ëË', styles: PosStyles(codeTable: PosCodeTable.westEur)); // Л
|
||||
// ticket.text('Special 1: ìÌ', styles: PosStyles(codeTable: PosCodeTable.westEur));// M
|
||||
// ticket.text('Special 1: íÍ', styles: PosStyles(codeTable: PosCodeTable.westEur)); // Н
|
||||
// ticket.text('Special 1: î', styles: PosStyles(codeTable: PosCodeTable.westEur));// О
|
||||
// ticket.text('Special 1: ï', styles: PosStyles(codeTable: PosCodeTable.westEur)); // П
|
||||
// ticket.text('Special 1: ð', styles: PosStyles(codeTable: PosCodeTable.westEur));// Р
|
||||
// ticket.text('Special 1: ñ', styles: PosStyles(codeTable: PosCodeTable.westEur));// С
|
||||
// ticket.text('Special 1: ò', styles: PosStyles(codeTable: PosCodeTable.westEur)); // Т
|
||||
// ticket.text('Special 1: óÓ', styles: PosStyles(codeTable: PosCodeTable.westEur)); //У
|
||||
// ticket.text('Special 1: ô', styles: PosStyles(codeTable: PosCodeTable.westEur));// Ф
|
||||
// ticket.text('Special 1: õÕ', styles: PosStyles(codeTable: PosCodeTable.westEur));// Х
|
||||
// ticket.text('Special 1: ö', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Ц
|
||||
// ticket.text('Special 1: ÷', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Ч
|
||||
// ticket.text('Special 1: ø', styles: PosStyles(codeTable: PosCodeTable.westEur));//Ш
|
||||
// ticket.text('Special 1: ù', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Щ
|
||||
// ticket.text('Special 1: ú', styles: PosStyles(codeTable: PosCodeTable.westEur));//Ъ
|
||||
// ticket.text('Special 1: û', styles: PosStyles(codeTable: PosCodeTable.westEur));//Ы
|
||||
// ticket.text('Special 1: üÜ', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Ь
|
||||
// ticket.text('Special 1: ý', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Э
|
||||
// ticket.text('Special 1: þ', styles: PosStyles(codeTable: PosCodeTable.westEur)); // ю
|
||||
// ticket.text('Special 1: ÿß', styles: PosStyles(codeTable: PosCodeTable.westEur)); //Я
|
||||
|
||||
// Uint8List encTxt11 = await CharsetConverter.encode("cp866", "Russian: Привет Мир!");
|
||||
// //ticket.textEncoded(encTxt11, styles: PosStyles(codeTable: PosCodeTable.pc866_2));
|
||||
// ticket.textEncoded(encTxt11);
|
||||
|
||||
ticket.text(
|
||||
'Regular: aA bB cC dD eE fF gG hH iI jJ kK lL mM nN oO pP qQ rR sS tT uU vV wW xX yY zZ');
|
||||
//ticket.text('Special 1: àÀ èÈ éÉ ûÛ üÜ çÇ ôÔ', styles: PosStyles(codeTable: PosCodeTable.westEur));
|
||||
//ticket.text('Special 2: blåbærgrød', styles: PosStyles(codeTable: PosCodeTable.westEur));
|
||||
|
||||
ticket.text('Bold text', styles: PosStyles(bold: true));
|
||||
ticket.text('Reverse text', styles: PosStyles(reverse: true));
|
||||
ticket.text('Underlined text',
|
||||
styles: PosStyles(underline: true), linesAfter: 1);
|
||||
ticket.text('Align left', styles: PosStyles(align: PosAlign.left));
|
||||
ticket.text('Align center', styles: PosStyles(align: PosAlign.center));
|
||||
ticket.text('Align right',
|
||||
styles: PosStyles(align: PosAlign.right), linesAfter: 1);
|
||||
|
||||
ticket.row([
|
||||
PosColumn(
|
||||
text: 'col3',
|
||||
width: 3,
|
||||
styles: PosStyles(align: PosAlign.center, underline: true),
|
||||
),
|
||||
PosColumn(
|
||||
text: 'col6',
|
||||
width: 6,
|
||||
styles: PosStyles(align: PosAlign.center, underline: true),
|
||||
),
|
||||
PosColumn(
|
||||
text: 'col3',
|
||||
width: 3,
|
||||
styles: PosStyles(align: PosAlign.center, underline: true),
|
||||
),
|
||||
]);
|
||||
|
||||
ticket.text('Text size 200%',
|
||||
styles: PosStyles(
|
||||
height: PosTextSize.size2,
|
||||
width: PosTextSize.size2,
|
||||
));
|
||||
|
||||
// Print image
|
||||
//final ByteData data = await rootBundle.load('assets/images/logo.png');
|
||||
//final Uint8List bytes = data.buffer.asUint8List();
|
||||
// Print image using alternative commands
|
||||
// ticket.imageRaster(image);
|
||||
// ticket.imageRaster(image, imageFn: PosImageFn.graphics);
|
||||
|
||||
// Print barcode
|
||||
final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
|
||||
ticket.barcode(Barcode.upcA(barData));
|
||||
|
||||
|
||||
|
||||
ticket.feed(2);
|
||||
|
||||
ticket.cut();
|
||||
return ticket;
|
||||
}
|
||||
|
||||
Future<Ticket> testTicketImage(PaperSize paper) async {
|
||||
final Ticket ticket = Ticket(paper);
|
||||
|
||||
// Print image
|
||||
final ByteData byteData = await rootBundle.load('assets/images/check.png');
|
||||
final Uint8List bytes = byteData.buffer.asUint8List();
|
||||
final Im.Image image = Im.decodeImage(bytes);
|
||||
// Using `ESC *`
|
||||
//ticket.image(imagea);
|
||||
// Using `GS v 0` (obsolete)
|
||||
//ticket.imageRaster(imagea);
|
||||
// Using `GS ( L`
|
||||
ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster);
|
||||
//ticket.image(imagea);
|
||||
|
||||
|
||||
ticket.feed(2);
|
||||
|
||||
ticket.cut();
|
||||
return ticket;
|
||||
}
|
||||
|
||||
Future<Ticket> printImageCheck(PaperSize paper, String base64Src) async {
|
||||
final Ticket ticket = Ticket(paper);
|
||||
final Uint8List bytes = base64Decode(base64Src);
|
||||
final Im.Image image = Im.decodeImage(bytes);
|
||||
ticket.imageRaster(image, imageFn: PosImageFn.bitImageRaster);
|
||||
//ticket.image(image);
|
||||
ticket.feed(2);
|
||||
ticket.cut();
|
||||
return ticket;
|
||||
}
|
||||
|
||||
|
||||
Future<Ticket> printTextCheck(PaperSize paper, String encoding, var data ) async {
|
||||
final Ticket ticket = Ticket(paper);
|
||||
ticket.emptyLines(1);
|
||||
|
||||
|
||||
PosCodeTable codeTable;
|
||||
if(encoding == SettingPrinterEncodingCp866) {
|
||||
codeTable = PosCodeTable.pc866_2;
|
||||
} else if(encoding == SettingPrinterEncodingWin1251) {
|
||||
codeTable = PosCodeTable.wpc1251;
|
||||
}
|
||||
|
||||
//ticket.setGlobalCodeTable(codeTable);
|
||||
ticket.setGlobalFont(PosFontType.fontB);
|
||||
|
||||
|
||||
String qr = data['qr'];
|
||||
|
||||
|
||||
List<dynamic> rows = data['rows'] as List;
|
||||
for(dynamic element in rows) {
|
||||
var text = element['text'];
|
||||
int size = element['size'] as int;
|
||||
bool center = element['center'] !=null ? element['center'] as bool : false;
|
||||
if(text is List) {
|
||||
Uint8List firstCol = await CharsetConverter.encode(encoding, (text).first as String);
|
||||
Uint8List lastCol = await CharsetConverter.encode(encoding, (text).last as String);
|
||||
ticket.row([
|
||||
PosColumn(
|
||||
textEncoded: firstCol,
|
||||
width: 6,
|
||||
styles: PosStyles(align: PosAlign.left, codeTable: codeTable ),
|
||||
),
|
||||
PosColumn(
|
||||
textEncoded: lastCol,
|
||||
width: 6,
|
||||
styles: PosStyles(align: PosAlign.right, codeTable: codeTable ),
|
||||
),
|
||||
]);
|
||||
} else {
|
||||
String line = text as String;
|
||||
if(line == 'breakline') {
|
||||
ticket.hr();
|
||||
} else if(line == 'br') {
|
||||
ticket.emptyLines(1);
|
||||
} else if(line.trim() == '') {
|
||||
ticket.emptyLines(1);
|
||||
} else {
|
||||
line = line.replaceAll("«", '\"');
|
||||
line = line.replaceAll("»", '\"');
|
||||
Uint8List encTxt11 = await CharsetConverter.encode(encoding, line);
|
||||
ticket.textEncoded( encTxt11, styles: PosStyles( align: center ? PosAlign.center : PosAlign.left, codeTable: codeTable ));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print barcode
|
||||
//final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
|
||||
//ticket.barcode(Barcode.upcA(barData));
|
||||
//ticket.qrcode(qr, align: PosAlign.center);
|
||||
ticket.emptyLines(1);
|
||||
const double qrSize = 200;
|
||||
try {
|
||||
final uiImg = await QrPainter(
|
||||
data: qr,
|
||||
version: QrVersions.auto,
|
||||
gapless: true,
|
||||
).toImageData(qrSize);
|
||||
//final dir = await getTemporaryDirectory();
|
||||
//final pathName = '${dir.path}/qr_tmp.png';
|
||||
//final qrFile = File(pathName);
|
||||
//final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List());
|
||||
final img = Im.decodePng(uiImg.buffer.asUint8List());
|
||||
ticket.image(img);
|
||||
|
||||
//ticket.qrcode(qr, size: QRSize.Size1 );
|
||||
} catch (e) {
|
||||
print(e);
|
||||
}
|
||||
|
||||
|
||||
ticket.emptyLines(1);
|
||||
ticket.feed(1);
|
||||
|
||||
ticket.cut();
|
||||
return ticket;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||
|
||||
var encoding = {
|
||||
SettingPrinterEncodingCp866: "CP-866",
|
||||
SettingPrinterEncodingWin1251: "Windows-1251",
|
||||
SettingPrinterEncodingImage: "Big-Encoding",
|
||||
};
|
||||
|
||||
var paperSize = {
|
||||
SettingPrinterPaperM58: "58 мм",
|
||||
SettingPrinterPaperM80: "80 мм"
|
||||
};
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
var exampleJson = {
|
||||
"check_text": {
|
||||
"rows": [
|
||||
{"size": 14, "text": "", "center": true},
|
||||
{"size": 15, "text": "breakline", "center": true},
|
||||
{"size": 14, "text": "ТОО «Aman Systems»"},
|
||||
{"size": 14, "text": "ИИН/БИН: 180640018960"},
|
||||
{"size": 14, "text": "Сер. номер ККМ: TEST00000005"},
|
||||
{"size": 14, "text": "Регистрационный номер: 123132132323"},
|
||||
{"size": 14, "text": "Коргальджинское шоссе, д.19 оф.308"},
|
||||
{"size": 15, "text": "breakline", "center": true},
|
||||
{"size": 14, "text": "Продажа,Наличные, ", "center": true},
|
||||
{"size": 15, "text": "ФИСКАЛЬНЫЙ ЧЕК №16580", "center": true},
|
||||
{"size": 15, "text": "ФП 471369529060", "center": true},
|
||||
{"size": 15, "text": "Дата: 03.03.2021 23:16", "center": true},
|
||||
{"size": 15, "text": "breakline", "center": true},
|
||||
{"size": 14, "text": "Кассир: Амантай ИХ"},
|
||||
{"size": 14, "text": "Касса: Касса 1"},
|
||||
{"size": 15, "text": "breakline", "center": true},
|
||||
{"size": 15, "text": "br"},
|
||||
{"size": 14, "text": "1. test"},
|
||||
{"size": 14, "text": "200,00 x 1 = 200,00"},
|
||||
{"size": 10, "text": "br"},
|
||||
{"size": 15, "text": "breakline"},
|
||||
{
|
||||
"size": 17,
|
||||
"text": ["ИТОГО:", "200,00"]
|
||||
},
|
||||
{
|
||||
"size": 14,
|
||||
"text": ["Наличные", "200,00"]
|
||||
},
|
||||
{"size": 15, "text": "breakline"},
|
||||
{"size": 17, "text": "В том числе НДС:"},
|
||||
{
|
||||
"size": 14,
|
||||
"text": ["12 %", "21,43"]
|
||||
},
|
||||
{"size": 14, "text": ""},
|
||||
{"size": 15, "text": "breakline"},
|
||||
{"size": 15, "text": "ОФД АО \"Транстелеком\"", "center": true},
|
||||
{"size": 15, "text": "ofd1.kz", "center": true},
|
||||
{"size": 14, "text": ""},
|
||||
{"size": 15, "text": "breakline"},
|
||||
{"size": 14, "text": "", "center": true},
|
||||
{"size": 13, "text": "порядковый номер чека:19800", "center": true},
|
||||
{"size": 14, "text": "Онлайн касса Aman", "center": true},
|
||||
{"size": 14, "text": "kassa.aman.com.kz", "center": true}
|
||||
],
|
||||
"qr":
|
||||
"87.255.215.94:4000/t/?i=471369529060&f=123132132323&s=200.0&t=20210303T231651"
|
||||
}
|
||||
};
|
||||