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 {
|
defaultConfig {
|
||||||
applicationId "kz.com.aman.kassa"
|
applicationId "kz.com.aman.kassa"
|
||||||
minSdkVersion 18
|
minSdkVersion 21
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
|
multiDexEnabled true
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -62,10 +63,37 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buildTypes {
|
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 {
|
release {
|
||||||
|
shrinkResources false
|
||||||
|
minifyEnabled false
|
||||||
|
useProguard false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compileOptions {
|
||||||
|
//coreLibraryDesugaringEnabled true
|
||||||
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
flutter {
|
flutter {
|
||||||
|
|
@ -73,8 +101,28 @@ flutter {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
//coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.9'
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
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'
|
testImplementation 'junit:junit:4.12'
|
||||||
androidTestImplementation 'androidx.test:runner:1.1.1'
|
androidTestImplementation 'androidx.test:runner:1.1.1'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.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"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="kz.com.aman.kassa">
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
|
package="kz.com.aman.kassa"> <!--
|
||||||
|
io.flutter.app.FlutterApplication is an android.app.Application that
|
||||||
calls FlutterMain.startInitialization(this); in its onCreate method.
|
calls FlutterMain.startInitialization(this); in its onCreate method.
|
||||||
In most cases you can leave this as-is, but you if you want to provide
|
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
|
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.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.CAMERA" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
|
tools:replace="android:label"
|
||||||
android:name="io.flutter.app.FlutterApplication"
|
android:name="io.flutter.app.FlutterApplication"
|
||||||
android:label="Аман Касса"
|
|
||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="Аман Касса"
|
||||||
|
android:allowBackup="false"
|
||||||
android:roundIcon="@mipmap/ic_launcher_rounded"
|
android:roundIcon="@mipmap/ic_launcher_rounded"
|
||||||
>
|
>
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:launchMode="singleTop"
|
|
||||||
android:theme="@style/LaunchTheme"
|
|
||||||
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
|
||||||
android:hardwareAccelerated="true"
|
android:hardwareAccelerated="true"
|
||||||
|
android:launchMode="singleTop"
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
|
android:theme="@style/LaunchTheme"
|
||||||
android:windowSoftInputMode="adjustResize">
|
android:windowSoftInputMode="adjustResize">
|
||||||
<!-- <meta-data
|
|
||||||
|
<!--
|
||||||
|
<meta-data
|
||||||
android:name="io.flutter.embedding.android.NormalTheme"
|
android:name="io.flutter.embedding.android.NormalTheme"
|
||||||
android:resource="@style/NormalTheme"
|
android:resource="@style/NormalTheme"
|
||||||
/> -->
|
/>
|
||||||
<!-- <meta-data
|
-->
|
||||||
|
<!--
|
||||||
|
<meta-data
|
||||||
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
android:name="io.flutter.embedding.android.SplashScreenDrawable"
|
||||||
android:resource="@drawable/splash"
|
android:resource="@drawable/splash"
|
||||||
/> -->
|
/>
|
||||||
|
-->
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN" />
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</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
|
<meta-data
|
||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
|
||||||
|
</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
|
package kz.com.aman.kassa
|
||||||
|
|
||||||
import android.content.Context
|
import android.app.Activity
|
||||||
import android.content.ContextWrapper
|
import android.content.ComponentName
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.IntentFilter
|
import android.os.Build
|
||||||
import android.content.pm.PackageManager
|
import android.widget.Toast
|
||||||
import android.net.Uri
|
|
||||||
import android.os.BatteryManager
|
|
||||||
import android.os.Build.VERSION
|
|
||||||
import android.os.Build.VERSION_CODES
|
|
||||||
import androidx.annotation.NonNull
|
import androidx.annotation.NonNull
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
import io.flutter.embedding.engine.FlutterEngine
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
|
import io.flutter.plugin.common.MethodCall
|
||||||
import io.flutter.plugin.common.MethodChannel
|
import io.flutter.plugin.common.MethodChannel
|
||||||
import io.flutter.plugins.GeneratedPluginRegistrant
|
import io.flutter.plugins.GeneratedPluginRegistrant
|
||||||
|
import kz.com.aman.kassa.bank.JsonForExternalCall
|
||||||
|
import kz.com.aman.kassa.bank.OperationType
|
||||||
|
|
||||||
|
|
||||||
class MainActivity: FlutterActivity() {
|
class MainActivity : FlutterActivity() {
|
||||||
private val CHANNEL = "samples.flutter.dev/battery"
|
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) {
|
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
|
||||||
GeneratedPluginRegistrant.registerWith(flutterEngine);
|
GeneratedPluginRegistrant.registerWith(flutterEngine)
|
||||||
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
|
//MethodChannel(flutterEngine.dartExecutor.binaryMessenger, BANK_CHANNEL).setMethodCallHandler(BankNfcPlugins(this))
|
||||||
// Note: this method is invoked on the main thread.
|
|
||||||
call, result ->
|
|
||||||
if (call.method == "getBatteryLevel") {
|
|
||||||
val batteryLevel = getBatteryLevel()
|
|
||||||
|
|
||||||
if (batteryLevel != -1) {
|
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, bankChannel).setMethodCallHandler { call, result ->
|
||||||
result.success(batteryLevel)
|
_result = result
|
||||||
} else {
|
when (call.method) {
|
||||||
result.error("UNAVAILABLE", "Battery level not available.", null)
|
"pay" -> {
|
||||||
|
operationPayment(call)
|
||||||
}
|
}
|
||||||
} else if (call.method == "sendMessage") {
|
"refund" -> {
|
||||||
val batteryLevel = sendMessage()
|
operationRefund(call)
|
||||||
|
}
|
||||||
if (batteryLevel != -1) {
|
"reversal" -> {
|
||||||
result.success(batteryLevel)
|
operationReversal(call)
|
||||||
} else {
|
}
|
||||||
result.error("UNAVAILABLE", "Battery level not available.", null)
|
"closeDay" -> {
|
||||||
|
operationCloseDay(call)
|
||||||
|
}
|
||||||
|
"version" -> {
|
||||||
|
result.success(Build.VERSION.SDK_INT.toString())
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
result.notImplemented()
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
result.notImplemented()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getBatteryLevel(): Int {
|
// private fun getOperationList(call: MethodCall) {
|
||||||
val batteryLevel: Int
|
// val token: String = call.argument<String>("token").toString()
|
||||||
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
|
// val operationParameters = createOperationParameters(token)
|
||||||
val batteryManager = getSystemService(Context.BATTERY_SERVICE) as BatteryManager
|
// startOperation(OperationType.OPERATIONS_LIST,
|
||||||
batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
|
// JsonForExternalCall.getOperationsListJson(operationParameters.authToken))
|
||||||
} 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 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");
|
val operationParameters = createOperationParameters(token)
|
||||||
println(batteryLevel);
|
startOperation(OperationType.PAYMENT, JsonForExternalCall.getPaymentCardJson(operationParameters.authToken, amount.toString()))
|
||||||
return batteryLevel
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun sendMessage(): Int {
|
private fun operationRefund(call: MethodCall) {
|
||||||
val packageManager: PackageManager = context.packageManager
|
val token = call.argument<String>("token").toString()
|
||||||
val i = Intent(Intent.ACTION_VIEW)
|
val terminalId = call.argument<String>("terminalId").toString()
|
||||||
try {
|
val operDay = call.argument<String>("operDay").toString()
|
||||||
val mobileNo: String = "77774904900" //call.argument("mobileNo")
|
val transNum = call.argument<String>("transNum").toString()
|
||||||
val message: String = "Hello world" //call.argument("message")
|
val amount = call.argument<String>("amount").toString()
|
||||||
//https://wa.me/919167370647?text=Yes%20We'll%20do%20this%20in%20frag4%20inOCW
|
val operationParameters = createOperationParameters(token)
|
||||||
println("mobileNo: $mobileNo message: $message")
|
startOperation(OperationType.REFUND, JsonForExternalCall.getRefundCardJson(operationParameters.authToken, terminalId, operDay, transNum, amount))
|
||||||
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 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 {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.5.0'
|
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"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
|
|
@ -16,6 +19,12 @@ allprojects {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configurations.all {
|
||||||
|
resolutionStrategy {
|
||||||
|
cacheDynamicVersionsFor 2, 'minutes'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rootProject.buildDir = '../build'
|
rootProject.buildDir = '../build'
|
||||||
|
|
@ -29,3 +38,10 @@ subprojects {
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
delete rootProject.buildDir
|
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|
|
post_install do |installer|
|
||||||
installer.pods_project.targets.each do |target|
|
installer.pods_project.targets.each do |target|
|
||||||
flutter_additional_ios_build_settings(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
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,25 @@ PODS:
|
||||||
- Flutter
|
- Flutter
|
||||||
- MTBBarcodeScanner
|
- MTBBarcodeScanner
|
||||||
- SwiftProtobuf
|
- SwiftProtobuf
|
||||||
|
- charset_converter (0.0.1):
|
||||||
|
- Flutter
|
||||||
- device_info (0.0.1):
|
- device_info (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- esys_flutter_share (0.0.1):
|
- esys_flutter_share (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- Flutter (1.0.0)
|
- Flutter (1.0.0)
|
||||||
|
- flutter_bluetooth_basic (0.0.1):
|
||||||
|
- Flutter
|
||||||
- FMDB (2.7.5):
|
- FMDB (2.7.5):
|
||||||
- FMDB/standard (= 2.7.5)
|
- FMDB/standard (= 2.7.5)
|
||||||
- FMDB/standard (2.7.5)
|
- FMDB/standard (2.7.5)
|
||||||
|
- local_auth (0.0.1):
|
||||||
|
- Flutter
|
||||||
- MTBBarcodeScanner (5.0.11)
|
- MTBBarcodeScanner (5.0.11)
|
||||||
- path_provider (0.0.1):
|
- path_provider (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- "permission_handler (5.1.0+2)":
|
||||||
|
- Flutter
|
||||||
- shared_preferences (0.0.1):
|
- shared_preferences (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
- sqflite (0.0.2):
|
- sqflite (0.0.2):
|
||||||
|
|
@ -25,10 +33,14 @@ PODS:
|
||||||
|
|
||||||
DEPENDENCIES:
|
DEPENDENCIES:
|
||||||
- barcode_scan (from `.symlinks/plugins/barcode_scan/ios`)
|
- barcode_scan (from `.symlinks/plugins/barcode_scan/ios`)
|
||||||
|
- charset_converter (from `.symlinks/plugins/charset_converter/ios`)
|
||||||
- device_info (from `.symlinks/plugins/device_info/ios`)
|
- device_info (from `.symlinks/plugins/device_info/ios`)
|
||||||
- esys_flutter_share (from `.symlinks/plugins/esys_flutter_share/ios`)
|
- esys_flutter_share (from `.symlinks/plugins/esys_flutter_share/ios`)
|
||||||
- Flutter (from `Flutter`)
|
- 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`)
|
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||||
|
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
|
||||||
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
|
||||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||||
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
|
- url_launcher (from `.symlinks/plugins/url_launcher/ios`)
|
||||||
|
|
@ -42,14 +54,22 @@ SPEC REPOS:
|
||||||
EXTERNAL SOURCES:
|
EXTERNAL SOURCES:
|
||||||
barcode_scan:
|
barcode_scan:
|
||||||
:path: ".symlinks/plugins/barcode_scan/ios"
|
:path: ".symlinks/plugins/barcode_scan/ios"
|
||||||
|
charset_converter:
|
||||||
|
:path: ".symlinks/plugins/charset_converter/ios"
|
||||||
device_info:
|
device_info:
|
||||||
:path: ".symlinks/plugins/device_info/ios"
|
:path: ".symlinks/plugins/device_info/ios"
|
||||||
esys_flutter_share:
|
esys_flutter_share:
|
||||||
:path: ".symlinks/plugins/esys_flutter_share/ios"
|
:path: ".symlinks/plugins/esys_flutter_share/ios"
|
||||||
Flutter:
|
Flutter:
|
||||||
:path: Flutter
|
:path: Flutter
|
||||||
|
flutter_bluetooth_basic:
|
||||||
|
:path: ".symlinks/plugins/flutter_bluetooth_basic/ios"
|
||||||
|
local_auth:
|
||||||
|
:path: ".symlinks/plugins/local_auth/ios"
|
||||||
path_provider:
|
path_provider:
|
||||||
:path: ".symlinks/plugins/path_provider/ios"
|
:path: ".symlinks/plugins/path_provider/ios"
|
||||||
|
permission_handler:
|
||||||
|
:path: ".symlinks/plugins/permission_handler/ios"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
:path: ".symlinks/plugins/shared_preferences/ios"
|
:path: ".symlinks/plugins/shared_preferences/ios"
|
||||||
sqflite:
|
sqflite:
|
||||||
|
|
@ -59,17 +79,21 @@ EXTERNAL SOURCES:
|
||||||
|
|
||||||
SPEC CHECKSUMS:
|
SPEC CHECKSUMS:
|
||||||
barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479
|
barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479
|
||||||
|
charset_converter: 215c7b04932ec2b9ba43be96a9bc34afed3e5322
|
||||||
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
|
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
|
||||||
esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4
|
esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4
|
||||||
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
|
||||||
|
flutter_bluetooth_basic: 0e4e27e22b50b3a25cc1d1e131953feb4af414f4
|
||||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||||
|
local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd
|
||||||
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
|
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
|
||||||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||||
|
permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
|
||||||
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
|
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
|
||||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||||
SwiftProtobuf: ecbec1be9036d15655f6b3443a1c4ea693c97932
|
SwiftProtobuf: ecbec1be9036d15655f6b3443a1c4ea693c97932
|
||||||
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
|
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef
|
||||||
|
|
||||||
PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c
|
PODFILE CHECKSUM: 5aafc9b59da66d8d46f05cbbbd21261eb9757176
|
||||||
|
|
||||||
COCOAPODS: 1.8.4
|
COCOAPODS: 1.10.1
|
||||||
|
|
|
||||||
|
|
@ -255,12 +255,13 @@
|
||||||
inputPaths = (
|
inputPaths = (
|
||||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
|
||||||
"${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework",
|
"${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework",
|
||||||
"${PODS_ROOT}/../Flutter/Flutter.framework",
|
|
||||||
"${BUILT_PRODUCTS_DIR}/MTBBarcodeScanner/MTBBarcodeScanner.framework",
|
"${BUILT_PRODUCTS_DIR}/MTBBarcodeScanner/MTBBarcodeScanner.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
|
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/barcode_scan/barcode_scan.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}/device_info/device_info.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/esys_flutter_share/esys_flutter_share.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}/path_provider/path_provider.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/shared_preferences/shared_preferences.framework",
|
"${BUILT_PRODUCTS_DIR}/shared_preferences/shared_preferences.framework",
|
||||||
"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
|
"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
|
||||||
|
|
@ -269,12 +270,13 @@
|
||||||
name = "[CP] Embed Pods Frameworks";
|
name = "[CP] Embed Pods Frameworks";
|
||||||
outputPaths = (
|
outputPaths = (
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework",
|
"${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}/MTBBarcodeScanner.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/barcode_scan.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}/device_info.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/esys_flutter_share.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}/path_provider.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences.framework",
|
||||||
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
|
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,6 @@
|
||||||
<Workspace
|
<Workspace
|
||||||
version = "1.0">
|
version = "1.0">
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:Runner.xcodeproj">
|
location = "self:">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,17 @@
|
||||||
</array>
|
</array>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>NSBluetoothAlwaysUsageDescription</key>
|
||||||
|
<string>Требуется доступ к Bluetooth для подключения к принтерам и печати чеков</string>
|
||||||
|
<key>NSBluetoothPeripheralUsageDescription</key>
|
||||||
|
<string>Требуется доступ к Bluetooth для подключения к принтерам и печати чеков</string>
|
||||||
<key>NSCameraUsageDescription</key>
|
<key>NSCameraUsageDescription</key>
|
||||||
<string>Требуется доступ к камере для сканирования QR-кодов и штрих-кодов</string>
|
<string>Требуется доступ к камере для сканирования QR-кодов и штрих-кодов</string>
|
||||||
|
<key>UIBackgroundModes</key>
|
||||||
|
<array>
|
||||||
|
<string>bluetooth-central</string>
|
||||||
|
<string>bluetooth-peripheral</string>
|
||||||
|
</array>
|
||||||
<key>UILaunchStoryboardName</key>
|
<key>UILaunchStoryboardName</key>
|
||||||
<string>LaunchScreen</string>
|
<string>LaunchScreen</string>
|
||||||
<key>UIMainStoryboardFile</key>
|
<key>UIMainStoryboardFile</key>
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ const String Voucher_columnUrl = 'url';
|
||||||
const String VoucherTypePayment = 'payment';
|
const String VoucherTypePayment = 'payment';
|
||||||
const String VoucherTypeReturnPay = 'returnPay';
|
const String VoucherTypeReturnPay = 'returnPay';
|
||||||
const String VoucherTypeReport = 'report';
|
const String VoucherTypeReport = 'report';
|
||||||
|
const String VoucherTypeCloseDayPosReport = 'closeDayPosReport';
|
||||||
|
|
||||||
class Voucher {
|
class Voucher {
|
||||||
int id;
|
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 'package:aman_kassa_flutter/core/services/DataService.dart';
|
||||||
|
|
||||||
import '../core/services/DbService.dart';
|
import '../core/services/DbService.dart';
|
||||||
|
|
@ -32,5 +33,7 @@ class LocatorInjector {
|
||||||
|
|
||||||
_log.d('Initializing DataService Service');
|
_log.d('Initializing DataService Service');
|
||||||
locator.registerLazySingleton<DataService>(() => DataService());
|
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) {
|
String formatStackTrace(StackTrace stackTrace, int methodPosition) {
|
||||||
|
|
||||||
var lines = stackTrace.toString()?.split('\n');
|
var lines = stackTrace.toString()?.split('\n');
|
||||||
var formatted = <String>[];
|
var formatted = <String>[];
|
||||||
var count = 0;
|
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';
|
import 'package:aman_kassa_flutter/core/models/check_item.dart';
|
||||||
|
|
||||||
class CheckData {
|
class CheckData {
|
||||||
final String type;
|
final String type;
|
||||||
num card;
|
num card;
|
||||||
final List<CheckItem> items;
|
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) {
|
static CheckData fromJson(Map<String, dynamic> json) {
|
||||||
return CheckData(
|
return CheckData(
|
||||||
type: json['type'],
|
type: json['type'],
|
||||||
card: json['card'],
|
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() =>
|
Map<String, dynamic> toJson() =>
|
||||||
{
|
{
|
||||||
'type': type,
|
'type': type,
|
||||||
'card': card,
|
'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 LoginViewRoute = "LoginView";
|
||||||
const String HomeViewRoute = "HomeView";
|
const String HomeViewRoute = "HomeView";
|
||||||
const String ImageShowRoute = "ImageShowRoute";
|
const String ImageShowRoute = "ImageShowRoute";
|
||||||
|
const String CloseDayShowRoute = "CloseDayShowRoute";
|
||||||
const String PaymentViewRoute = "PaymentView";
|
const String PaymentViewRoute = "PaymentView";
|
||||||
|
const String PaymentNfcViewRoute = "PaymentNfcViewRoute";
|
||||||
const String HistoryViewRoute = "HistoryView";
|
const String HistoryViewRoute = "HistoryView";
|
||||||
const String InfoKkmViewRoute = "InfoKkmViewRoute";
|
const String InfoKkmViewRoute = "InfoKkmViewRoute";
|
||||||
|
const String SettingsViewRoute = "SettingsViewRoute";
|
||||||
const String QrViewRoute = "QrViewRoute";
|
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
|
// 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/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/history/history_view.dart';
|
||||||
import 'package:aman_kassa_flutter/views/info_kkm/info_kkm_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/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 'package:aman_kassa_flutter/views/qr_view/qr_view.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/settings/printer/views/PrinterSelect.dart';
|
||||||
import './route_names.dart';
|
import 'package:aman_kassa_flutter/views/settings/settings_view.dart';
|
||||||
import 'package:aman_kassa_flutter/views/home/home_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:aman_kassa_flutter/views/login/login_view.dart';
|
||||||
import 'package:flutter/material.dart';
|
import './route_names.dart';
|
||||||
|
|
||||||
|
|
||||||
Route<dynamic> generateRoute(RouteSettings settings) {
|
Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
switch (settings.name) {
|
switch (settings.name) {
|
||||||
|
|
@ -15,7 +25,9 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
LoginModel model = settings.arguments as LoginModel;
|
LoginModel model = settings.arguments as LoginModel;
|
||||||
return _getPageRoute(
|
return _getPageRoute(
|
||||||
routeName: settings.name,
|
routeName: settings.name,
|
||||||
viewToShow: LoginView(loginModel: model,),
|
viewToShow: LoginView(
|
||||||
|
loginModel: model,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
case HomeViewRoute:
|
case HomeViewRoute:
|
||||||
return _getPageRoute(
|
return _getPageRoute(
|
||||||
|
|
@ -28,6 +40,12 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
routeName: settings.name,
|
routeName: settings.name,
|
||||||
viewToShow: PaymentView(model: model),
|
viewToShow: PaymentView(model: model),
|
||||||
);
|
);
|
||||||
|
case PaymentNfcViewRoute:
|
||||||
|
PaymentModel model = settings.arguments as PaymentModel;
|
||||||
|
return _getPageRoute(
|
||||||
|
routeName: settings.name,
|
||||||
|
viewToShow: PaymentNfcView(model: model),
|
||||||
|
);
|
||||||
case HistoryViewRoute:
|
case HistoryViewRoute:
|
||||||
return _getPageRoute(
|
return _getPageRoute(
|
||||||
routeName: settings.name,
|
routeName: settings.name,
|
||||||
|
|
@ -38,6 +56,21 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
routeName: settings.name,
|
routeName: settings.name,
|
||||||
viewToShow: InfoKkmView(),
|
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:
|
case QrViewRoute:
|
||||||
ImageShowModel data = settings.arguments as ImageShowModel;
|
ImageShowModel data = settings.arguments as ImageShowModel;
|
||||||
return _getPageRoute(
|
return _getPageRoute(
|
||||||
|
|
@ -51,6 +84,32 @@ Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
routeName: settings.name,
|
routeName: settings.name,
|
||||||
viewToShow: ImageShowContainer(data),
|
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:
|
default:
|
||||||
return MaterialPageRoute(
|
return MaterialPageRoute(
|
||||||
builder: (_) => Scaffold(
|
builder: (_) => Scaffold(
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,11 @@ import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/core/base/base_service.dart';
|
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/state/user_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
import 'package:aman_kassa_flutter/views/login/login_view.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:device_info/device_info.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/message.dart';
|
import 'package:aman_kassa_flutter/core/models/message.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/response.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;
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
/// The service responsible for networking requests
|
/// The service responsible fworking requests
|
||||||
class ApiService extends BaseService {
|
class ApiService extends BaseService {
|
||||||
static const test_host = 'https://kassa-test.aman.com.kz';
|
static const test_host = 'https://kassa-test.aman.com.kz';
|
||||||
static const test_endpoint = '$test_host/ru/api/v2';
|
static const test_endpoint = '$test_host/ru/api/v2';
|
||||||
static const host = 'https://kassa.aman.com.kz';
|
static const host = 'https://kassa.aman.com.kz';
|
||||||
static const endpoint = '$host/ru/api/v2';
|
static const endpoint = '$host/ru/api/v2';
|
||||||
|
|
||||||
|
static const pos_endpoint = 'https://partner.aman.com.kz/api';
|
||||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
final DialogService _dialogService = locator<DialogService>();
|
final DialogService _dialogService = locator<DialogService>();
|
||||||
|
|
||||||
|
|
@ -63,6 +67,18 @@ class ApiService extends BaseService {
|
||||||
return Response.fromJsonDynamic(json.decode(response));
|
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 {
|
Future<Response<dynamic>> money(String token) async {
|
||||||
Map<String, String> requestBody = <String, String>{'api_token': token};
|
Map<String, String> requestBody = <String, String>{'api_token': token};
|
||||||
var response = await requestFormData('/money', requestBody);
|
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();
|
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
|
||||||
|
|
||||||
|
|
||||||
Map<String, String> headers = <String, String>{
|
Map<String, String> headers = <String, String>{
|
||||||
HttpHeaders.contentTypeHeader: "multipart/form-data",
|
HttpHeaders.contentTypeHeader: bodyEntry ? "application/json" : "multipart/form-data",
|
||||||
HttpHeaders.cacheControlHeader: "no-cache"
|
HttpHeaders.cacheControlHeader: "no-cache"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if(Platform.isAndroid) {
|
if(Platform.isAndroid) {
|
||||||
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
|
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
|
||||||
headers.addAll(<String, String>{
|
headers.addAll(<String, String>{
|
||||||
|
|
@ -153,14 +171,26 @@ class ApiService extends BaseService {
|
||||||
if(this._test) {
|
if(this._test) {
|
||||||
url = '$test_endpoint$point';
|
url = '$test_endpoint$point';
|
||||||
}
|
}
|
||||||
|
if(posEndPoint){
|
||||||
|
url = '$pos_endpoint$point';
|
||||||
|
}
|
||||||
var uri = Uri.parse(url);
|
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) { //Проверка на авторизованный запрос, необязательный параметр
|
if(statusCheck) { //Проверка на авторизованный запрос, необязательный параметр
|
||||||
Response check = Response.fromJsonDynamic(json.decode(body));
|
Response check = Response.fromJsonDynamic(json.decode(body));
|
||||||
if (!check.operation && ( [401,402,403,412].contains(check.status) ) ) {
|
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/entity/Voucher.dart';
|
||||||
import 'package:aman_kassa_flutter/core/locator.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/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_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/check_item.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/product_dao.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/models/response.dart';
|
||||||
|
|
@ -135,35 +137,22 @@ class DataService extends BaseService {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<Response<dynamic>> refundM4Bank(
|
||||||
|
{
|
||||||
Future<Response<dynamic>> sellOrReturn(
|
String token,
|
||||||
{String paymentType,
|
CheckData checkData,
|
||||||
String tradeType,
|
CardData cardData}) async {
|
||||||
String token,
|
|
||||||
List<ProductDao> kassaItems,
|
|
||||||
List<CalcModel> calcItems,
|
|
||||||
String operationType,
|
|
||||||
String mode}) async {
|
|
||||||
try {
|
try {
|
||||||
String data;
|
var json = cardData.toJson();
|
||||||
if (mode == SettingModeKassa) {
|
json['transactionType'] = VoucherTypeReturnPay;
|
||||||
CheckData checkData = _transformProductsToCheckData(
|
checkData.cardData = CardData.fromJson(json);
|
||||||
paymentType: paymentType, tradeType: tradeType, items: kassaItems);
|
String data = jsonEncode(checkData.toJson());
|
||||||
data = jsonEncode(checkData.toJson());
|
|
||||||
} else if (mode == SettingModeCalc) {
|
|
||||||
CheckData checkData = _transformCalcModelToCheckData(
|
|
||||||
paymentType: paymentType, tradeType: tradeType, items: calcItems);
|
|
||||||
data = jsonEncode(checkData.toJson());
|
|
||||||
}
|
|
||||||
|
|
||||||
// log.i('token: $token');
|
log.i('token: $token');
|
||||||
// log.i('data: $data');
|
log.i('data: $data');
|
||||||
Response<dynamic> response = await (operationType == OperationTypePay
|
Response<dynamic> response = await _api.sellReturn(token, data);
|
||||||
? _api.sell(token, data)
|
log.i('response status: ${response.status}');
|
||||||
: _api.sellReturn(token, data));
|
log.i('response operation: ${response.operation}');
|
||||||
// log.i('response status: ${response.status}');
|
|
||||||
// log.i('response operation: ${response.operation}');
|
|
||||||
if (response.status == 200 && response.operation == true) {
|
if (response.status == 200 && response.operation == true) {
|
||||||
User user = Redux.store.state.userState.user;
|
User user = Redux.store.state.userState.user;
|
||||||
String check = response?.body['check'];
|
String check = response?.body['check'];
|
||||||
|
|
@ -179,6 +168,69 @@ class DataService extends BaseService {
|
||||||
base64Data: check,
|
base64Data: check,
|
||||||
total: total,
|
total: total,
|
||||||
url: url,
|
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
|
type: operationType == OperationTypeReturn
|
||||||
? VoucherTypeReturnPay
|
? VoucherTypeReturnPay
|
||||||
: VoucherTypePayment);
|
: VoucherTypePayment);
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,13 @@
|
||||||
//general
|
//general
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
|
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:flutter/material.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';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
//service & tools
|
//service & tools
|
||||||
import 'package:aman_kassa_flutter/redux/store.dart';
|
import 'package:aman_kassa_flutter/redux/store.dart';
|
||||||
|
|
@ -21,6 +22,8 @@ import 'views/start_up/start_up_view.dart';
|
||||||
|
|
||||||
//main start
|
//main start
|
||||||
void main() async {
|
void main() async {
|
||||||
|
HttpOverrides.global = MyHttpOverrides();
|
||||||
|
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
HttpOverrides.global = MyHttpOverrides();
|
HttpOverrides.global = MyHttpOverrides();
|
||||||
//initialize locator
|
//initialize locator
|
||||||
|
|
@ -35,41 +38,45 @@ void main() async {
|
||||||
runApp(MainApplication());
|
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{
|
class MyHttpOverrides extends HttpOverrides{
|
||||||
@override
|
@override
|
||||||
HttpClient createHttpClient(SecurityContext context){
|
HttpClient createHttpClient(SecurityContext context){
|
||||||
return super.createHttpClient(context)
|
return super.createHttpClient(context)
|
||||||
..badCertificateCallback = (X509Certificate cert, String host, int port)=> true;
|
..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:meta/meta.dart';
|
||||||
import 'package:redux/redux.dart';
|
import 'package:redux/redux.dart';
|
||||||
import 'package:redux_thunk/redux_thunk.dart';
|
import 'package:redux_thunk/redux_thunk.dart';
|
||||||
|
import 'package:flutter_bluetooth_basic/src/bluetooth_device.dart';
|
||||||
import '../store.dart';
|
import '../store.dart';
|
||||||
|
|
||||||
@immutable
|
@immutable
|
||||||
|
|
@ -23,4 +23,40 @@ ThunkAction<AppState> changeTradeTypeFromSetting(String tradeType) {
|
||||||
return (Store<AppState> store) async {
|
return (Store<AppState> store) async {
|
||||||
store.dispatch(SetSettingStateAction(SettingState(tradeType: 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(
|
UserState(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
isAuthenticated: false,
|
isAuthenticated: false,
|
||||||
user: User(),
|
user: User()
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,17 @@ const String SettingModeCalc = 'calcMode';
|
||||||
|
|
||||||
|
|
||||||
const String SettingTradeTypeGood = 'g';
|
const String SettingTradeTypeGood = 'g';
|
||||||
const String SettingTradeTypeService = 's';
|
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;
|
final payload = action.settingState;
|
||||||
return prevState.copyWith(
|
return prevState.copyWith(
|
||||||
mode: payload.mode,
|
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:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
|
import 'package:flutter_bluetooth_basic/src/bluetooth_device.dart';
|
||||||
|
|
||||||
@immutable
|
@immutable
|
||||||
class SettingState {
|
class SettingState {
|
||||||
final String mode;
|
final String mode;
|
||||||
final String tradeType;
|
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
|
//read hive
|
||||||
factory SettingState.initial(SettingState payload) {
|
factory SettingState.initial(SettingState payload) {
|
||||||
return SettingState(
|
return SettingState(
|
||||||
mode: payload?.mode ?? SettingModeKassa,
|
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
|
//write hive
|
||||||
SettingState copyWith({
|
SettingState copyWith({
|
||||||
@required mode,
|
@required mode,
|
||||||
@required tradeType,
|
@required tradeType,
|
||||||
|
@required pinCode,
|
||||||
|
@required pinLocked,
|
||||||
|
@required pinSkip,
|
||||||
|
@required printerBT,
|
||||||
|
@required printerEncoding,
|
||||||
|
@required printerPaperSize,
|
||||||
}) {
|
}) {
|
||||||
return SettingState(
|
return SettingState(
|
||||||
mode: mode ?? this.mode,
|
mode: mode ?? this.mode,
|
||||||
tradeType: tradeType ?? this.tradeType,
|
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(
|
? SettingState(
|
||||||
tradeType: json['tradeType'],
|
tradeType: json['tradeType'],
|
||||||
mode: json['mode'],
|
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;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic toJson() {
|
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 Smena smena;
|
||||||
final Money money;
|
final Money money;
|
||||||
|
|
||||||
|
|
||||||
UserState(
|
UserState(
|
||||||
{this.isError,
|
{this.isError,
|
||||||
this.isLoading,
|
this.isLoading,
|
||||||
|
|
@ -26,7 +27,8 @@ class UserState {
|
||||||
this.user,
|
this.user,
|
||||||
this.loginFormMessage,
|
this.loginFormMessage,
|
||||||
this.smena,
|
this.smena,
|
||||||
this.money});
|
this.money,
|
||||||
|
});
|
||||||
|
|
||||||
factory UserState.initial(UserState payload) => UserState(
|
factory UserState.initial(UserState payload) => UserState(
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
|
@ -73,7 +75,8 @@ class UserState {
|
||||||
user: User.fromJson(json['user']),
|
user: User.fromJson(json['user']),
|
||||||
authenticateType: json['authenticateType'],
|
authenticateType: json['authenticateType'],
|
||||||
login: json['login'],
|
login: json['login'],
|
||||||
password: json['password'])
|
password: json['password'],
|
||||||
|
)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
import 'package:aman_kassa_flutter/redux/actions/kassa_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/setting_actions.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/actions/user_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/calc_reducer.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/reducers/main_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/setting_reducer.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/reducers/user_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/calc_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/setting_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_thunk/redux_thunk.dart';
|
||||||
import 'package:redux_persist/redux_persist.dart';
|
import 'package:redux_persist/redux_persist.dart';
|
||||||
|
|
||||||
|
import 'actions/bank_actions.dart';
|
||||||
import 'actions/calc_actions.dart';
|
import 'actions/calc_actions.dart';
|
||||||
|
|
||||||
//reducer context
|
//reducer context
|
||||||
|
|
@ -35,6 +38,10 @@ AppState appReducer(AppState state, dynamic action) {
|
||||||
/** CalcAction **/
|
/** CalcAction **/
|
||||||
final nextCalcState = calcReducer(state.calcState, action);
|
final nextCalcState = calcReducer(state.calcState, action);
|
||||||
return state.copyWith(calcState: nextCalcState);
|
return state.copyWith(calcState: nextCalcState);
|
||||||
|
} else if (action is SetBankStateAction) {
|
||||||
|
/** BankAction **/
|
||||||
|
final nextBankState = bankReducer(state.bankState, action);
|
||||||
|
return state.copyWith(bankState: nextBankState);
|
||||||
}
|
}
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
@ -46,12 +53,14 @@ class AppState {
|
||||||
final KassaState kassaState;
|
final KassaState kassaState;
|
||||||
final SettingState settingState;
|
final SettingState settingState;
|
||||||
final CalcState calcState;
|
final CalcState calcState;
|
||||||
|
final BankState bankState;
|
||||||
|
|
||||||
AppState({
|
AppState({
|
||||||
this.userState,
|
this.userState,
|
||||||
this.kassaState,
|
this.kassaState,
|
||||||
this.settingState,
|
this.settingState,
|
||||||
this.calcState,
|
this.calcState,
|
||||||
|
this.bankState,
|
||||||
});
|
});
|
||||||
|
|
||||||
//stable work
|
//stable work
|
||||||
|
|
@ -60,28 +69,32 @@ class AppState {
|
||||||
KassaState kassaState,
|
KassaState kassaState,
|
||||||
SettingState settingState,
|
SettingState settingState,
|
||||||
CalcState calcState,
|
CalcState calcState,
|
||||||
|
BankState bankState,
|
||||||
}) {
|
}) {
|
||||||
return AppState(
|
return AppState(
|
||||||
userState: userState ?? this.userState,
|
userState: userState ?? this.userState,
|
||||||
kassaState: kassaState ?? this.kassaState,
|
kassaState: kassaState ?? this.kassaState,
|
||||||
settingState: settingState ?? this.settingState,
|
settingState: settingState ?? this.settingState,
|
||||||
calcState: calcState ?? this.calcState,
|
calcState: calcState ?? this.calcState,
|
||||||
|
bankState: bankState ?? this.bankState,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static AppState fromJson(dynamic json){
|
static AppState fromJson(dynamic json) {
|
||||||
return json !=null
|
return json != null
|
||||||
? AppState(
|
? AppState(
|
||||||
settingState: SettingState.fromJson(json['settingState']),
|
settingState: SettingState.fromJson(json['settingState']),
|
||||||
userState: UserState.fromJson(json['userState']),
|
userState: UserState.fromJson(json['userState']),
|
||||||
)
|
bankState: BankState.fromJson(json['bankState']),
|
||||||
|
)
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic toJson() {
|
dynamic toJson() {
|
||||||
return {
|
return {
|
||||||
"settingState": settingState.toJson(),
|
"settingState": settingState.toJson(),
|
||||||
"userState" : userState.toJson(),
|
"userState": userState.toJson(),
|
||||||
|
"bankState": bankState.toJson(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +115,8 @@ class Redux {
|
||||||
// Create Persistor
|
// Create Persistor
|
||||||
final persist = Persistor<AppState>(
|
final persist = Persistor<AppState>(
|
||||||
storage: FlutterStorage(), // Or use other engines
|
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();
|
final initialState = await persist.load();
|
||||||
|
|
@ -111,15 +125,17 @@ class Redux {
|
||||||
final kassaStateInitial = KassaState.initial();
|
final kassaStateInitial = KassaState.initial();
|
||||||
final settingStateInitial = SettingState.initial(initialState?.settingState);
|
final settingStateInitial = SettingState.initial(initialState?.settingState);
|
||||||
final calcStateInitial = CalcState.initial();
|
final calcStateInitial = CalcState.initial();
|
||||||
|
final bankStateInitial = BankState.initial(initialState?.bankState);
|
||||||
|
|
||||||
_store = Store<AppState>(
|
_store = Store<AppState>(
|
||||||
appReducer,
|
appReducer,
|
||||||
middleware: [thunkMiddleware, persist.createMiddleware() ],
|
middleware: [thunkMiddleware, persist.createMiddleware()],
|
||||||
initialState: AppState(
|
initialState: AppState(
|
||||||
userState: userStateInitial,
|
userState: userStateInitial,
|
||||||
kassaState: kassaStateInitial,
|
kassaState: kassaStateInitial,
|
||||||
settingState: settingStateInitial,
|
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 fillColor = Color.fromRGBO(248, 248, 248, 1);
|
||||||
const Color primaryColor = Color.fromRGBO(51, 122, 183, 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);
|
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 whiteColor = Color.fromRGBO(255, 255, 255, 1);
|
||||||
const Color yellowColor = Color.fromRGBO(250, 175, 0, 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);
|
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);
|
fontWeight: FontWeight.w400, color: Colors.black, fontSize: 15);
|
||||||
const TextStyle buttonTitleTextStyle = const TextStyle(
|
const TextStyle buttonTitleTextStyle = const TextStyle(
|
||||||
fontWeight: FontWeight.w700, color: whiteColor, fontSize: 14);
|
fontWeight: FontWeight.w700, color: whiteColor, fontSize: 14);
|
||||||
|
const TextStyle buttonTitleDisableTextStyle = const TextStyle(
|
||||||
|
fontWeight: FontWeight.w700, color: fillColor, fontSize: 14);
|
||||||
const TextStyle buttonBigTitleTextStyle = const TextStyle(
|
const TextStyle buttonBigTitleTextStyle = const TextStyle(
|
||||||
fontWeight: FontWeight.w700,
|
fontWeight: FontWeight.w700,
|
||||||
color: whiteColor,
|
color: whiteColor,
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,8 @@
|
||||||
// Define a function.
|
// Define a function.
|
||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:crypto/crypto.dart';
|
||||||
|
|
||||||
void printInteger(int aNumber) {
|
void printInteger(int aNumber) {
|
||||||
print('The number is $aNumber.'); // Print to console.
|
print('The number is $aNumber.'); // Print to console.
|
||||||
}
|
}
|
||||||
|
|
@ -8,4 +12,11 @@ void main() {
|
||||||
String dataMatrix = "00000046208262nZ2qnLHODVFWktT";
|
String dataMatrix = "00000046208262nZ2qnLHODVFWktT";
|
||||||
String numberText = dataMatrix.replaceAll(RegExp("[a-zA-Z]"), '');
|
String numberText = dataMatrix.replaceAll(RegExp("[a-zA-Z]"), '');
|
||||||
print(int.parse(numberText));
|
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:convert';
|
||||||
import 'dart:io';
|
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/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/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/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/dialog_service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/navigator_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/app_colors.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/ui_helpers.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/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/material.dart';
|
||||||
|
import 'package:flutter_bluetooth_basic/flutter_bluetooth_basic.dart';
|
||||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||||
import 'package:esys_flutter_share/esys_flutter_share.dart';
|
import 'package:esys_flutter_share/esys_flutter_share.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
class ImageShowContainer extends StatelessWidget {
|
import '../../core/models/aman_dao.dart';
|
||||||
final ImageShowModel data;
|
|
||||||
|
|
||||||
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
//backgroundColor: fillColor,
|
//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(
|
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 {
|
class ImageShowModel {
|
||||||
final String data;
|
final CheckImageModal data;
|
||||||
final String title;
|
final String title;
|
||||||
final String url;
|
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 {
|
class MyFloatingActionButton extends StatefulWidget {
|
||||||
final ImageShowModel data;
|
final ImageShowModel data;
|
||||||
|
|
||||||
MyFloatingActionButton(this.data);
|
MyFloatingActionButton(this.data);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_MyFloatingActionButtonState createState() => _MyFloatingActionButtonState();
|
_MyFloatingActionButtonState createState() => _MyFloatingActionButtonState();
|
||||||
}
|
}
|
||||||
|
|
@ -59,11 +182,101 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
bool showFab = true;
|
bool showFab = true;
|
||||||
DialogService _dialog = locator<DialogService>();
|
DialogService _dialog = locator<DialogService>();
|
||||||
NavigatorService _navigatorService = locator<NavigatorService>();
|
NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
|
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||||
|
final DataService _dataService = locator<DataService>();
|
||||||
|
|
||||||
|
double sheetHeight = 260;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return showFab
|
//print(widget.data.cardData.transactionType);
|
||||||
? FloatingActionButton(
|
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),
|
child: Icon(Icons.share),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
var bottomSheetController = showBottomSheet(
|
var bottomSheetController = showBottomSheet(
|
||||||
|
|
@ -73,12 +286,7 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||||
boxShadow: [
|
boxShadow: [BoxShadow(blurRadius: 10, color: Colors.grey[300], spreadRadius: 5)]),
|
||||||
BoxShadow(
|
|
||||||
blurRadius: 10,
|
|
||||||
color: Colors.grey[300],
|
|
||||||
spreadRadius: 5)
|
|
||||||
]),
|
|
||||||
height: 260,
|
height: 260,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
|
@ -107,36 +315,75 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)));
|
)));
|
||||||
showFoatingActionButton(false);
|
showFloatingActionButton(false);
|
||||||
bottomSheetController.closed.then((value) {
|
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 {
|
void shareFile() async {
|
||||||
try {
|
try {
|
||||||
await Share.file('Aman Kassa', 'aman_kassa_check.png',
|
await Share.file('Aman Kassa', 'aman_kassa_check.png', base64Decode(widget.data.data.base64Data), 'image/png');
|
||||||
base64Decode(widget.data.data), 'image/png');
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('error: $e');
|
print('error: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void qrGenerate() async {
|
void qrGenerate() async {
|
||||||
_navigatorService.push(QrViewRoute,
|
_navigatorService.push(QrViewRoute, arguments: ImageShowModel(url: widget.data.url, title: 'Спасибо за покупку'));
|
||||||
arguments:
|
|
||||||
ImageShowModel(data: widget.data.url, title: 'Спасибо за покупку'));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void callWhatsApp() async {
|
void callWhatsApp() async {
|
||||||
DialogResponse response = await _dialog.showConfirmationDialogInput(
|
DialogResponse response = await _dialog.showConfirmationDialogInput(
|
||||||
description: 'Номер телефона',
|
description: 'Номер телефона', cancelTitle: 'Отмена', confirmationTitle: 'Отправить', formatType: 'phone');
|
||||||
cancelTitle: 'Отмена',
|
|
||||||
confirmationTitle: 'Отправить',
|
|
||||||
formatType: 'phone');
|
|
||||||
if (response.confirmed) {
|
if (response.confirmed) {
|
||||||
String phoneNumber = response.responseText;
|
String phoneNumber = response.responseText;
|
||||||
String msg = "Спасибо за покупку! \r\n ${widget.data.url} ";
|
String msg = "Спасибо за покупку! \r\n ${widget.data.url} ";
|
||||||
|
|
@ -156,7 +403,6 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
print(url());
|
|
||||||
if (await canLaunch(url())) {
|
if (await canLaunch(url())) {
|
||||||
await launch(url());
|
await launch(url());
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -164,7 +410,7 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showFoatingActionButton(bool value) {
|
void showFloatingActionButton(bool value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
showFab = value;
|
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/entity/Voucher.dart';
|
||||||
import 'package:aman_kassa_flutter/core/locator.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/route_names.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/DbService.dart';
|
import 'package:aman_kassa_flutter/core/services/DbService.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/navigator_service.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) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
Voucher voucher = data[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(
|
return ListTile(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_navigatorService.push(ImageShowRoute,
|
|
||||||
arguments: ImageShowModel(
|
if( voucher.type == VoucherTypeCloseDayPosReport ) {
|
||||||
data: voucher.base64Data,
|
_navigatorService.push(CloseDayShowRoute,
|
||||||
|
arguments: closeDayData);
|
||||||
|
} else {
|
||||||
|
_navigatorService.push(ImageShowRoute,
|
||||||
|
arguments: ImageShowModel(
|
||||||
|
data: checkImageData,
|
||||||
title: voucher.name,
|
title: voucher.name,
|
||||||
url: voucher.url));
|
url: voucher.url,
|
||||||
|
cardData: cardData,
|
||||||
|
voucher: voucher,
|
||||||
|
));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
title: buildText(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),
|
trailing: Icon(Icons.arrow_right),
|
||||||
leading: voucher.type == VoucherTypePayment
|
leading: voucher.type == VoucherTypePayment
|
||||||
? Icon(
|
? Icon(
|
||||||
|
|
@ -83,6 +120,11 @@ class _HistoryViewState extends State<HistoryView> {
|
||||||
MdiIcons.backupRestore,
|
MdiIcons.backupRestore,
|
||||||
size: 40,
|
size: 40,
|
||||||
)
|
)
|
||||||
|
: voucher.type == VoucherTypeCloseDayPosReport ?
|
||||||
|
Icon(
|
||||||
|
Icons.phonelink_lock_outlined,
|
||||||
|
size: 40,
|
||||||
|
)
|
||||||
: Icon(
|
: Icon(
|
||||||
Icons.description,
|
Icons.description,
|
||||||
size: 40,
|
size: 40,
|
||||||
|
|
|
||||||
|
|
@ -24,29 +24,36 @@ class BottomBar extends StatelessWidget {
|
||||||
currentIndex: selectedTabIndex,
|
currentIndex: selectedTabIndex,
|
||||||
backgroundColor: menuColor,
|
backgroundColor: menuColor,
|
||||||
type: BottomNavigationBarType.shifting,
|
type: BottomNavigationBarType.shifting,
|
||||||
|
showUnselectedLabels: true,
|
||||||
items: [
|
items: [
|
||||||
vm.mode == SettingModeKassa
|
vm.mode == SettingModeKassa
|
||||||
? BottomNavigationBarItem(
|
? BottomNavigationBarItem(
|
||||||
backgroundColor: menuColor,
|
backgroundColor: menuColor,
|
||||||
icon: Icon(MdiIcons.cashRegister, color: Colors.white),
|
icon: Icon(MdiIcons.cashRegister, color: Colors.white),
|
||||||
title: new Text(
|
label: 'Касса',
|
||||||
'Касса',
|
// title: new Text(
|
||||||
style: TextStyle(color: Colors.white),
|
// 'Касса',
|
||||||
))
|
// style: TextStyle(color: Colors.white),
|
||||||
|
// )
|
||||||
|
)
|
||||||
: BottomNavigationBarItem(
|
: BottomNavigationBarItem(
|
||||||
backgroundColor: menuColor,
|
backgroundColor: menuColor,
|
||||||
icon: Icon(MdiIcons.calculator, color: Colors.white),
|
icon: Icon(MdiIcons.calculator, color: Colors.white),
|
||||||
title: new Text(
|
label: 'Калькулятор',
|
||||||
'Калькулятор',
|
// title: new Text(
|
||||||
style: TextStyle(color: Colors.white),
|
// 'Калькулятор',
|
||||||
)),
|
// style: TextStyle(color: Colors.white),
|
||||||
|
// )
|
||||||
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
backgroundColor: menuColor,
|
backgroundColor: menuColor,
|
||||||
icon: Icon(MdiIcons.tune, color: Colors.white),
|
icon: Icon(MdiIcons.tune, color: Colors.white),
|
||||||
title: new Text(
|
label: 'Опции'
|
||||||
'Опции',
|
// title: new Text(
|
||||||
style: TextStyle(color: Colors.white),
|
// 'Опции',
|
||||||
)),
|
// style: TextStyle(color: Colors.white),
|
||||||
|
// )
|
||||||
|
),
|
||||||
],
|
],
|
||||||
onTap: (index) {
|
onTap: (index) {
|
||||||
pageController.animateToPage(
|
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/models/choice.dart';
|
||||||
|
import 'package:aman_kassa_flutter/core/services/BankService.dart';
|
||||||
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
import 'package:aman_kassa_flutter/shared/app_colors.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||||
|
|
||||||
const List<Choice> choices = const <Choice>[
|
class PopupMenu extends StatefulWidget {
|
||||||
//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 StatelessWidget {
|
|
||||||
final void Function(Choice value) onSelectChoice;
|
final void Function(Choice value) onSelectChoice;
|
||||||
|
|
||||||
PopupMenu({this.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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return PopupMenuButton<Choice>(
|
return PopupMenuButton<Choice>(
|
||||||
|
|
@ -23,23 +50,16 @@ class PopupMenu extends StatelessWidget {
|
||||||
Icons.more_vert,
|
Icons.more_vert,
|
||||||
color: menuColor,
|
color: menuColor,
|
||||||
),
|
),
|
||||||
onSelected: onSelectChoice,
|
onSelected: widget.onSelectChoice,
|
||||||
itemBuilder: (BuildContext context) {
|
itemBuilder: (BuildContext context) {
|
||||||
return choices.map((Choice choice) {
|
return choices.map((Choice choice) {
|
||||||
return PopupMenuItem<Choice>(
|
return PopupMenuItem<Choice>(
|
||||||
value: choice,
|
value: choice,
|
||||||
child: Row(
|
child: Row(children: <Widget>[
|
||||||
children: <Widget>[
|
Icon(choice.icon, color: primaryColor,),
|
||||||
Icon(
|
SizedBox(width: 5,),
|
||||||
choice.icon,
|
Text(choice.title)
|
||||||
color: primaryColor,
|
], ),
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 5,
|
|
||||||
),
|
|
||||||
Text(choice.title)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}).toList();
|
}).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/entity/Voucher.dart';
|
||||||
import 'package:aman_kassa_flutter/core/locator.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/money.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/response.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/dialog_models.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/user.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/route_names.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/ApiService.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/DataService.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/dialog_service.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/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/aman_icon_button_horizontal.dart';
|
||||||
import 'package:aman_kassa_flutter/widgets/fields/busy_button.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/widgets/loader/Dialogs.dart';
|
||||||
|
import 'package:aman_kassa_flutter/views/payment/halyk_pos_service.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.dart';
|
import 'package:flutter_redux/flutter_redux.dart';
|
||||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.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>();
|
ApiService _api = locator<ApiService>();
|
||||||
NavigatorService _navigator = locator<NavigatorService>();
|
NavigatorService _navigator = locator<NavigatorService>();
|
||||||
DialogService _dialog = locator<DialogService>();
|
DialogService _dialog = locator<DialogService>();
|
||||||
|
final BankService _bankService = locator<BankService>();
|
||||||
DataService _dataService = locator<DataService>();
|
DataService _dataService = locator<DataService>();
|
||||||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||||
|
|
||||||
bool isMoneyCheckBusy;
|
bool isMoneyCheckBusy;
|
||||||
|
bool isClosePosBusy;
|
||||||
bool closeSmenaBusy;
|
bool closeSmenaBusy;
|
||||||
bool openSmenaBusy;
|
bool openSmenaBusy;
|
||||||
bool depositBusy;
|
bool depositBusy;
|
||||||
|
|
@ -59,6 +68,7 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
||||||
withdrawalBusy = false;
|
withdrawalBusy = false;
|
||||||
xReportBusy = false;
|
xReportBusy = false;
|
||||||
updateCatalog = false;
|
updateCatalog = false;
|
||||||
|
isClosePosBusy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _closeSmena() async {
|
void _closeSmena() async {
|
||||||
|
|
@ -99,9 +109,11 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
||||||
User user = Redux.store.state.userState.user;
|
User user = Redux.store.state.userState.user;
|
||||||
Response response = await _api.xReport(user.token);
|
Response response = await _api.xReport(user.token);
|
||||||
if (response.operation) {
|
if (response.operation) {
|
||||||
|
String check = response.body['check'];
|
||||||
|
var checkText = response.body['check_text'];
|
||||||
_navigator.push(ImageShowRoute,
|
_navigator.push(ImageShowRoute,
|
||||||
arguments:
|
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'];
|
String url = response?.body['link'];
|
||||||
_dataService.insertVoucher(
|
_dataService.insertVoucher(
|
||||||
user: user,
|
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
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
|
|
@ -256,52 +317,72 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
||||||
verticalSpaceMedium,
|
verticalSpaceMedium,
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||||
child: Center(
|
child: Row(
|
||||||
child: Column(
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: <Widget>[
|
children: [
|
||||||
Text(
|
Column(
|
||||||
'Денег в кассе:',
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
style: TextStyle(color: primaryColor, fontSize: 15),
|
children: <Widget>[
|
||||||
),
|
Row(
|
||||||
SizedBox(
|
children: [
|
||||||
height: 50,
|
Icon(Icons.money, color: primaryColor),
|
||||||
width: double.infinity,
|
Text(
|
||||||
child: StoreConnector<AppState, Money>(
|
'Денег в кассе:',
|
||||||
converter: (store) => store.state.userState.money,
|
style: TextStyle(color: primaryColor, fontSize: 15),
|
||||||
builder: (_, vm) {
|
),
|
||||||
if (vm.loading == true) {
|
],
|
||||||
return Center(
|
),
|
||||||
child: SizedBox(
|
SizedBox(
|
||||||
width: 30,
|
height: 50,
|
||||||
height: 30,
|
// width: double.infinity,
|
||||||
child: Padding(
|
child: StoreConnector<AppState, Money>(
|
||||||
padding: const EdgeInsets.all(8.0),
|
converter: (store) => store.state.userState.money,
|
||||||
child: CircularProgressIndicator(
|
builder: (_, vm) {
|
||||||
strokeWidth: 2,
|
if (vm.loading == true) {
|
||||||
valueColor: new AlwaysStoppedAnimation<Color>(
|
return Center(
|
||||||
primaryColor),
|
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
|
Container(
|
||||||
? '${vm.total} тенге'
|
child: AmanIconButton(
|
||||||
: 'нет информации',
|
title: 'Обновить',
|
||||||
style: TextStyle(
|
onPressed: _checkMoney,
|
||||||
color: vm.total != null
|
busy: isMoneyCheckBusy,
|
||||||
? primaryColor
|
icon: Icons.replay_circle_filled,
|
||||||
: Colors.grey.withOpacity(0.5),
|
mainColor: primaryColor,
|
||||||
fontSize: 25,
|
),
|
||||||
fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)),
|
),
|
||||||
),
|
),
|
||||||
verticalSpaceMedium,
|
verticalSpaceMedium,
|
||||||
Wrap(
|
Wrap(
|
||||||
|
|
@ -325,12 +406,19 @@ class _AdditionalTabState extends State<AdditionalTab> {
|
||||||
busy: closeSmenaBusy,
|
busy: closeSmenaBusy,
|
||||||
icon: Icons.lock_outline,
|
icon: Icons.lock_outline,
|
||||||
),
|
),
|
||||||
|
// AmanIconButton(
|
||||||
|
// title: 'Денег в кассе',
|
||||||
|
// onPressed: _checkMoney,
|
||||||
|
// busy: isMoneyCheckBusy,
|
||||||
|
// icon: MdiIcons.walletOutline,
|
||||||
|
// mainColor: primaryColor,
|
||||||
|
// ),
|
||||||
AmanIconButton(
|
AmanIconButton(
|
||||||
title: 'Денег в кассе',
|
title: 'Закрыть POS',
|
||||||
onPressed: _checkMoney,
|
onPressed: _closeDay,
|
||||||
busy: isMoneyCheckBusy,
|
busy: isClosePosBusy,
|
||||||
icon: MdiIcons.walletOutline,
|
icon: Icons.phonelink_lock_outlined,
|
||||||
mainColor: primaryColor,
|
mainColor: purpleColor,
|
||||||
),
|
),
|
||||||
AmanIconButton(
|
AmanIconButton(
|
||||||
title: 'Х Отчет',
|
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/dialog_service.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/navigator_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/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/operation_const.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
import 'package:aman_kassa_flutter/redux/constants/setting_const.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
import 'package:aman_kassa_flutter/redux/state/kassa_state.dart';
|
||||||
|
|
@ -183,6 +184,7 @@ class KassaTab extends StatelessWidget {
|
||||||
|
|
||||||
Future<void> scan() async {
|
Future<void> scan() async {
|
||||||
try {
|
try {
|
||||||
|
await Redux.store.dispatch(changePinSkipFromSetting(true));
|
||||||
var options = ScanOptions(strings: {
|
var options = ScanOptions(strings: {
|
||||||
"cancel": 'Отмена',
|
"cancel": 'Отмена',
|
||||||
"flash_on": 'Вкл фонарик',
|
"flash_on": 'Вкл фонарик',
|
||||||
|
|
@ -217,7 +219,7 @@ class KassaTab extends StatelessWidget {
|
||||||
List<Good> goods =
|
List<Good> goods =
|
||||||
await _dataService.getGoodsByBarcode(barcode: barcode);
|
await _dataService.getGoodsByBarcode(barcode: barcode);
|
||||||
if (goods != null && goods.isNotEmpty) {
|
if (goods != null && goods.isNotEmpty) {
|
||||||
Redux.store.dispatch(addProductToKassaItems(goods.first, dataMatrix));
|
await Redux.store.dispatch(addProductToKassaItems(goods.first, dataMatrix));
|
||||||
} else {
|
} else {
|
||||||
_dialogService.showDialog(
|
_dialogService.showDialog(
|
||||||
description: 'Товар не найден: $barcode');
|
description: 'Товар не найден: $barcode');
|
||||||
|
|
@ -238,33 +240,48 @@ class KassaTab extends StatelessWidget {
|
||||||
result.rawContent = 'Unknown error: $e';
|
result.rawContent = 'Unknown error: $e';
|
||||||
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
|
_dialogService.showDialog(description: 'Неизвестная ошибка: $e');
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
await Redux.store.dispatch(changePinSkipFromSetting(false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void showModalBottomSheetCatalog(BuildContext context, String action) {
|
void showModalBottomSheetCatalog(BuildContext context, String action) {
|
||||||
showModalBottomSheet(
|
|
||||||
context: context,
|
if (action == 'add') {
|
||||||
isScrollControlled: true,
|
Navigator.push(
|
||||||
backgroundColor: Colors.transparent,
|
context,
|
||||||
builder: (context) {
|
MaterialPageRoute(builder: (context) => ProductAddBottomSheet())
|
||||||
return DraggableScrollableSheet(
|
);
|
||||||
initialChildSize: 0.8,
|
} else {
|
||||||
maxChildSize: 0.95,
|
Navigator.push(
|
||||||
minChildSize: 0.5,
|
context,
|
||||||
builder: (BuildContext context, ScrollController scrollController) {
|
MaterialPageRoute(builder: (context) => CatalogBottomSheet())
|
||||||
if (action == 'add') {
|
);
|
||||||
return ProductAddBottomSheet(
|
}
|
||||||
scrollController: scrollController,
|
|
||||||
);
|
// showModalBottomSheet(
|
||||||
} else {
|
// context: context,
|
||||||
return CatalogBottomSheet(
|
// isScrollControlled: true,
|
||||||
scrollController: scrollController,
|
// 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(
|
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(
|
child: ListView(
|
||||||
controller: widget.scrollController,
|
controller: widget.scrollController,
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
|
|
@ -78,7 +78,8 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
|
||||||
decimal: false,
|
decimal: false,
|
||||||
),
|
),
|
||||||
inputFormatters: <TextInputFormatter>[
|
inputFormatters: <TextInputFormatter>[
|
||||||
WhitelistingTextInputFormatter.digitsOnly
|
// WhitelistingTextInputFormatter.digitsOnly
|
||||||
|
FilteringTextInputFormatter.digitsOnly
|
||||||
],
|
],
|
||||||
controller: countController,
|
controller: countController,
|
||||||
onChanged: calcOnChange,
|
onChanged: calcOnChange,
|
||||||
|
|
@ -95,7 +96,7 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
|
||||||
keyboardType:
|
keyboardType:
|
||||||
const TextInputType.numberWithOptions(decimal: true),
|
const TextInputType.numberWithOptions(decimal: true),
|
||||||
inputFormatters: <TextInputFormatter>[
|
inputFormatters: <TextInputFormatter>[
|
||||||
WhitelistingTextInputFormatter(RegExp("^[0-9.]*")),
|
FilteringTextInputFormatter.allow(RegExp("^[0-9.]*")),
|
||||||
],
|
],
|
||||||
controller: priceController,
|
controller: priceController,
|
||||||
onChanged: calcOnChange,
|
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(
|
return Scaffold(
|
||||||
key: _scaffoldKey,
|
key: _scaffoldKey,
|
||||||
backgroundColor: fillColor,
|
backgroundColor: fillColor,
|
||||||
body: Padding(
|
body: SingleChildScrollView(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 50),
|
physics: BouncingScrollPhysics(),
|
||||||
child: Column(
|
child: Padding(
|
||||||
mainAxisSize: MainAxisSize.max,
|
padding: const EdgeInsets.symmetric(horizontal: 50),
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: <Widget>[
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
Stack(
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
alignment: Alignment.bottomLeft,
|
children: <Widget>[
|
||||||
children: <Widget>[
|
verticalSpaceLarge,
|
||||||
SizedBox(
|
Stack(
|
||||||
height: 150,
|
alignment: Alignment.bottomLeft,
|
||||||
child: Image.asset('assets/images/logo.png'),
|
children: <Widget>[
|
||||||
),
|
SizedBox(
|
||||||
Positioned(
|
height: 150,
|
||||||
child: Text(
|
child: Image.asset('assets/images/logo.png'),
|
||||||
'онлайн касса',
|
|
||||||
style: TextStyle(fontWeight: FontWeight.bold),
|
|
||||||
),
|
),
|
||||||
bottom: 23.0,
|
Positioned(
|
||||||
left: 25.0,
|
child: Text(
|
||||||
),
|
'онлайн касса',
|
||||||
],
|
style: TextStyle(fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
|
bottom: 23.0,
|
||||||
|
left: 25.0,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
|
||||||
InputField(
|
InputField(
|
||||||
placeholder: 'Электронная почта',
|
placeholder: 'Электронная почта',
|
||||||
controller: emailController,
|
controller: emailController,
|
||||||
textInputType: TextInputType.emailAddress,
|
textInputType: TextInputType.emailAddress,
|
||||||
nextFocusNode: passwordNode,
|
nextFocusNode: passwordNode,
|
||||||
additionalNote: vm.loginFormMessage.email,
|
additionalNote: vm.loginFormMessage.email,
|
||||||
),
|
),
|
||||||
verticalSpaceSmall,
|
verticalSpaceSmall,
|
||||||
InputField(
|
InputField(
|
||||||
placeholder: 'Пароль',
|
placeholder: 'Пароль',
|
||||||
password: true,
|
password: true,
|
||||||
controller: passwordController,
|
controller: passwordController,
|
||||||
fieldFocusNode: passwordNode,
|
fieldFocusNode: passwordNode,
|
||||||
additionalNote: vm.loginFormMessage.password,
|
additionalNote: vm.loginFormMessage.password,
|
||||||
enterPressed: _pressBtnEnter,
|
enterPressed: _pressBtnEnter,
|
||||||
textInputAction: TextInputAction.done,
|
textInputAction: TextInputAction.done,
|
||||||
),
|
),
|
||||||
verticalSpaceMedium,
|
verticalSpaceMedium,
|
||||||
Row(
|
Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.end,
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
children: [
|
children: [
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 150,
|
width: 150,
|
||||||
child: BusyButton(
|
child: BusyButton(
|
||||||
title: 'Войти',
|
title: 'Войти',
|
||||||
busy: vm.isLoading,
|
busy: vm.isLoading,
|
||||||
onPressed: _pressBtnEnter,
|
onPressed: _pressBtnEnter,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
verticalSpaceLarge,
|
verticalSpaceLarge,
|
||||||
// TextLink(
|
// TextLink(
|
||||||
// 'Регистрация',
|
// 'Регистрация',
|
||||||
// onPressed: () {},
|
// onPressed: () {},
|
||||||
// ),
|
// ),
|
||||||
IconButton(
|
IconButton(
|
||||||
icon: Icon(MdiIcons.qrcodeScan),
|
icon: Icon(MdiIcons.qrcodeScan),
|
||||||
iconSize: 40,
|
iconSize: 40,
|
||||||
tooltip: "Scan",
|
tooltip: "Scan",
|
||||||
onPressed: 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/locator.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/calc_model.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/product_dao.dart';
|
||||||
import 'package:aman_kassa_flutter/core/models/response.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/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/DataService.dart';
|
||||||
import 'package:aman_kassa_flutter/core/services/dialog_service.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/core/services/navigator_service.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/actions/calc_actions.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/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/actions/user_actions.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/constants/operation_const.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/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/calc_state.dart';
|
||||||
import 'package:aman_kassa_flutter/redux/state/kassa_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/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:aman_kassa_flutter/widgets/loader/Dialogs.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_redux/flutter_redux.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 {
|
class PaymentView extends StatefulWidget {
|
||||||
final PaymentModel model;
|
final PaymentModel model;
|
||||||
|
|
@ -36,13 +50,26 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
final GlobalKey<State> _keyLoader = new GlobalKey<State>();
|
||||||
final DataService _dataService = locator<DataService>();
|
final DataService _dataService = locator<DataService>();
|
||||||
final DialogService _dialogService = locator<DialogService>();
|
final DialogService _dialogService = locator<DialogService>();
|
||||||
|
BankService _bankService = locator<BankService>();
|
||||||
final NavigatorService _navigatorService = locator<NavigatorService>();
|
final NavigatorService _navigatorService = locator<NavigatorService>();
|
||||||
bool isBusy;
|
bool isBusy;
|
||||||
|
bool isBankApiAccess;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
isBusy = false;
|
isBusy = false;
|
||||||
|
isBankApiAccess = false;
|
||||||
|
_bankInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
_bankInit() async {
|
||||||
|
int version = await _bankService.version();
|
||||||
|
if (version >= _bankService.sdkVersion) {
|
||||||
|
setState(() {
|
||||||
|
isBankApiAccess = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -92,9 +119,10 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
String dataTitle() =>
|
String dataTitle() =>
|
||||||
widget.model.operationType == OperationTypePay ? 'Оплата' : 'Возврат';
|
widget.model.operationType == OperationTypePay ? 'Оплата' : 'Возврат';
|
||||||
|
|
||||||
String dataText() => widget.model.operationType == OperationTypePay
|
String dataText() =>
|
||||||
? 'К оплате'
|
widget.model.operationType == OperationTypePay
|
||||||
: 'К возврату';
|
? 'К оплате'
|
||||||
|
: 'К возврату';
|
||||||
|
|
||||||
StoreConnector buildStoreConnector() {
|
StoreConnector buildStoreConnector() {
|
||||||
if (widget.model.mode == SettingModeCalc) {
|
if (widget.model.mode == SettingModeCalc) {
|
||||||
|
|
@ -130,42 +158,139 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Expanded(
|
Expanded(
|
||||||
child: BusyButton(
|
child: BusyButton(
|
||||||
title: 'Оплатить картой',
|
title: 'Оплатить картой',
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
pressPayment('card');
|
pressPayment('card', null);
|
||||||
},
|
},
|
||||||
mainColor: greenColor,
|
mainColor: primaryColor,
|
||||||
)),
|
)),
|
||||||
horizontalSpaceSmall,
|
horizontalSpaceSmall,
|
||||||
Expanded(
|
Expanded(
|
||||||
child: BusyButton(
|
child: BusyButton(
|
||||||
title: 'Наличными',
|
title: 'Наличными',
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
pressPayment('cash');
|
pressPayment('cash', null);
|
||||||
},
|
},
|
||||||
mainColor: primaryColor,
|
mainColor: greenColor,
|
||||||
)),
|
)),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
verticalSpaceLarge,
|
verticalSpaceLarge,
|
||||||
|
_nfsButtonRender(),
|
||||||
|
verticalSpaceSmall,
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Container(),
|
child: Container(),
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
child: BusyButton(
|
child: BusyButton(
|
||||||
title: 'Отмена',
|
title: 'Отмена',
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
mainColor: redColor,
|
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(() {
|
setState(() {
|
||||||
isBusy = true;
|
isBusy = true;
|
||||||
});
|
});
|
||||||
|
|
@ -187,14 +312,17 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
operationType: widget.model.operationType,
|
operationType: widget.model.operationType,
|
||||||
tradeType: _tradeType,
|
tradeType: _tradeType,
|
||||||
calcItems: calcItems,
|
calcItems: calcItems,
|
||||||
mode: _mode);
|
mode: _mode,
|
||||||
|
cardData: cardData
|
||||||
|
);
|
||||||
setState(() {
|
setState(() {
|
||||||
isBusy = false;
|
isBusy = false;
|
||||||
});
|
});
|
||||||
if( response != null) {
|
if (response != null) {
|
||||||
if (response.operation) {
|
if (response.operation) {
|
||||||
String message = response.body['message'];
|
String message = response.body['message'];
|
||||||
String check = response.body['check'];
|
String check = response.body['check'];
|
||||||
|
var checkText = response.body['check_text'];
|
||||||
String url = response?.body['link'];
|
String url = response?.body['link'];
|
||||||
print('url : $url');
|
print('url : $url');
|
||||||
if (_mode == SettingModeCalc) {
|
if (_mode == SettingModeCalc) {
|
||||||
|
|
@ -207,24 +335,26 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||||
_navigatorService.pop();
|
_navigatorService.pop();
|
||||||
_navigatorService.push(ImageShowRoute,
|
_navigatorService.push(ImageShowRoute,
|
||||||
arguments: ImageShowModel(data:check, title: message, url: url ));
|
arguments: ImageShowModel(data: new CheckImageModal(
|
||||||
} else if (!response.operation && ![401,402,403,412,500].contains(response.status)) {
|
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();
|
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||||
_dialogService.showDialog(description: response.body['message']);
|
_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();
|
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||||
_dialogService.showDialog(description: response.body['message']);
|
_dialogService.showDialog(description: response.body['message']);
|
||||||
} else {
|
} else {
|
||||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print(e);
|
print(e);
|
||||||
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop();
|
||||||
} finally {
|
} finally {
|
||||||
|
|
||||||
//Navigator.of(context, rootNavigator: true).pop();
|
//Navigator.of(context, rootNavigator: true).pop();
|
||||||
setState(() {
|
setState(() {
|
||||||
isBusy = false;
|
isBusy = false;
|
||||||
|
|
@ -258,5 +388,8 @@ class _PaymentViewState extends State<PaymentView> {
|
||||||
class PaymentModel {
|
class PaymentModel {
|
||||||
String operationType;
|
String operationType;
|
||||||
String mode;
|
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(
|
body: Container(
|
||||||
child: Center(
|
child: Center(
|
||||||
child: QrImage(
|
child: QrImage(
|
||||||
data: widget.data.data,
|
data: widget.data.url,
|
||||||
version: QrVersions.auto,
|
version: QrVersions.auto,
|
||||||
size: 220.0,
|
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"
|
||||||
|
}
|
||||||
|
};
|
||||||