Compare commits

...

31 Commits

Author SHA1 Message Date
Rustem b28c8278e2 flutter upgrade 2026-06-10 13:21:40 +05:00
Rustem e1b6f7c2cb flutter upgrade 2026-06-10 13:21:12 +05:00
Rustem 913170ce20 fortenew commit prod 2026-06-09 10:26:39 +05:00
Rustem 7c7e50b78e fortenew commit prod 2026-06-07 14:40:31 +05:00
Rustem 1a39e1eed4 fortenew commit prod 2024-12-11 16:27:40 +05:00
Rustem 86adf1b2cf fortenew commit prod 2024-12-06 00:30:43 +05:00
Rustem 64a1ea99c4 fortenew commit prod 2024-12-04 11:23:52 +05:00
Rustem a050407beb fortenew commit test 2024-12-04 01:18:29 +05:00
Rustem 9ab70203ac fortenew commit test 2024-12-02 23:48:31 +05:00
Rustem c397062da2 fortenew commit test 2024-12-02 23:48:28 +05:00
suvaysov e224df165a push 2023-01-27 11:00:21 +06:00
suvaysov 8e654c5ab1 xReport fix? url is nullable 2022-08-12 16:13:54 +06:00
suvaysov 2e255fa8a2 add mobile paymennt
add iin field
2022-08-11 17:46:32 +06:00
suvaysov d2ff26e89c fixes 41 build 2022-04-19 22:11:15 +06:00
suvaysov b343d433e9 android:exported="true" 2022-04-04 12:20:38 +06:00
suvaysov 7c735834af Исправления типа оплаты при Халык ПОС как карточный 2022-03-30 13:06:00 +06:00
suvaysov 0336d6918b major version upped
android version started from 40
2022-03-29 09:35:11 +06:00
suvaysov d39baca7c2 bank prod url added 2022-03-29 09:22:06 +06:00
suvaysov ccd668a5c9 blue + bank commit 2022-03-21 13:21:44 +06:00
suvaysov 2f2a4dce3a Merge branch 'ns-printer' of ssh://206.189.105.187:22022/Serik/aman-kassa-flutter into ns-printer 2022-03-21 10:31:28 +06:00
suvaysov d23036ebf0 fix problems 2022-03-21 10:31:20 +06:00
Serik Uvaissov 005c00071d ios version - 1 2022-02-18 09:43:28 +06:00
Serik Uvaissov 95aeb07fc8 ios version 2022-02-01 14:05:33 +06:00
error500 16ea7ead94 flutter_blue added for ios 2022-02-01 13:22:39 +06:00
error500 7b06e4c390 ns blue_print_service.dart 2022-01-27 09:35:05 +06:00
error500 988d6a6c6b migrate ns-printer 2022-01-26 09:05:15 +06:00
error500 fcbf12f193 Merge branch 'migrate_to_ns' into ns_bank_merge
# Conflicts:
#	lib/core/models/user.dart
2022-01-25 17:31:24 +06:00
error500 f29d9edb22 migrate fix int Null 2022-01-25 17:30:21 +06:00
error500 0345a310e5 Merge branch 'backend_nfc' into ns_bank_merge
# Conflicts:
#	lib/core/logger.dart
#	lib/core/models/check_data.dart
#	lib/core/router.dart
#	lib/core/services/DataService.dart
#	lib/main.dart
#	lib/redux/store.dart
#	lib/views/check/image_show_container.dart
#	lib/views/history/history_view.dart
#	lib/views/home/home_view_m.dart
#	lib/views/home/tabs/AdditionalTab.dart
#	lib/views/login/login_view.dart
#	lib/views/payment/payment_view.dart
#	lib/views/start_up/start_up_view.dart
#	pubspec.lock
#	pubspec.yaml
2022-01-25 17:04:36 +06:00
error500 97250689c1 migrate fix print 2022-01-25 13:52:53 +06:00
error500 875f930da4 migrate initial 2022-01-25 13:42:34 +06:00
420 changed files with 101881 additions and 2043 deletions

View File

@ -1,3 +1,9 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties() def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties') def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) { if (localPropertiesFile.exists()) {
@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
} }
} }
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode') def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) { if (flutterVersionCode == null) {
flutterVersionCode = '4' flutterVersionCode = '4'
@ -21,20 +22,16 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0.4' flutterVersionName = '1.0.4'
} }
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
def keystoreProperties = new Properties() def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties') def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) { if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
} }
android { android {
compileSdkVersion 30 namespace "kz.com.aman.kassa"
compileSdkVersion 36
ndkVersion "28.2.13676358"
sourceSets { sourceSets {
main.java.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/kotlin'
@ -46,8 +43,8 @@ android {
defaultConfig { defaultConfig {
applicationId "kz.com.aman.kassa" applicationId "kz.com.aman.kassa"
minSdkVersion 21 minSdkVersion flutter.minSdkVersion
targetSdkVersion 30 targetSdkVersion 35
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
multiDexEnabled true multiDexEnabled true
@ -62,38 +59,34 @@ android {
storePassword keystoreProperties['storePassword'] storePassword keystoreProperties['storePassword']
} }
} }
buildTypes { buildTypes {
// all {
// buildConfigField ("String[]", "SUPPORTED_DEVICES", collectSupportedDevicesToArray())
// }
debug { debug {
shrinkResources false shrinkResources false
minifyEnabled false minifyEnabled false
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
defaultConfig {
minSdkVersion 24
}
} }
release { release {
shrinkResources false shrinkResources false
minifyEnabled false minifyEnabled false
useProguard false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release signingConfig signingConfigs.release
} }
} }
compileOptions { compileOptions {
//coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_17
sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_1_8 }
packagingOptions {
exclude "META-INF/library_release.kotlin_module"
exclude "META-INF/com.android.tools/proguard/coroutines.pro"
} }
kotlinOptions { kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString() jvmTarget = JavaVersion.VERSION_17.toString()
} }
} }
flutter { flutter {
@ -101,7 +94,6 @@ 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.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3' implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
@ -109,20 +101,5 @@ dependencies {
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 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(",") + '}'
//}

View File

@ -0,0 +1,39 @@
{
"project_info": {
"project_number": "1086013480150",
"project_id": "aman-f670e",
"storage_bucket": "aman-f670e.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:1086013480150:android:d00d738289818373f17d77",
"android_client_info": {
"package_name": "kz.com.aman.kassa"
}
},
"oauth_client": [
{
"client_id": "1086013480150-tbavt0qel11hs9eqsfni0j8hhr1nbis1.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyAlAhTjrXj0s1Qep2_mP_u4QtMnltMi4RA"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "1086013480150-tbavt0qel11hs9eqsfni0j8hhr1nbis1.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

View File

@ -14,17 +14,17 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- android:name="io.flutter.app.FlutterApplication"-->
<application <application
tools:replace="android:label" android:name="${applicationName}"
android:name="io.flutter.app.FlutterApplication"
android:icon="@mipmap/ic_launcher"
android:label="Аман Касса" android:label="Аман Касса"
android:icon="@mipmap/ic_launcher"
android:allowBackup="false" android:allowBackup="false"
android:roundIcon="@mipmap/ic_launcher_rounded" android:roundIcon="@mipmap/ic_launcher_rounded"
> >
<activity <activity
android:name=".MainActivity" android:name=".MainActivity"
android:exported="true"
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:launchMode="singleTop"
@ -44,12 +44,14 @@
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. Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java This is used by the Flutter tool to generate GeneratedPluginRegistrant.java

View File

@ -1,6 +1,7 @@
package kz.com.aman.kassa package kz.com.aman.kassa
import android.app.Activity import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.ComponentName import android.content.ComponentName
import android.content.Intent import android.content.Intent
import android.os.Build import android.os.Build
@ -69,7 +70,9 @@ class MainActivity : FlutterActivity() {
amount = call.argument<Long>("amount")!!.toLong() amount = call.argument<Long>("amount")!!.toLong()
} }
val operationParameters = createOperationParameters(token) val operationParameters = createOperationParameters(token)
startOperation(OperationType.PAYMENT, JsonForExternalCall.getPaymentCardJson(operationParameters.authToken, amount.toString())) val packageName = call.argument<String>("packageName").toString()
startOperation(OperationType.PAYMENT, JsonForExternalCall.getPaymentCardJson(operationParameters.authToken, amount.toString()), packageName)
} }
private fun operationRefund(call: MethodCall) { private fun operationRefund(call: MethodCall) {
@ -78,8 +81,14 @@ class MainActivity : FlutterActivity() {
val operDay = call.argument<String>("operDay").toString() val operDay = call.argument<String>("operDay").toString()
val transNum = call.argument<String>("transNum").toString() val transNum = call.argument<String>("transNum").toString()
val amount = call.argument<String>("amount").toString() val amount = call.argument<String>("amount").toString()
val packageName = call.argument<String>("packageName").toString()
val operationParameters = createOperationParameters(token) val operationParameters = createOperationParameters(token)
startOperation(OperationType.REFUND, JsonForExternalCall.getRefundCardJson(operationParameters.authToken, terminalId, operDay, transNum, amount)) val body = JsonForExternalCall.getRefundCardJson(operationParameters.authToken, terminalId, operDay, transNum, amount)
startOperation(
OperationType.REFUND,
body,
packageName
)
} }
private fun operationReversal(call: MethodCall) { private fun operationReversal(call: MethodCall) {
@ -88,15 +97,24 @@ class MainActivity : FlutterActivity() {
val operDay = call.argument<String>("operDay").toString() val operDay = call.argument<String>("operDay").toString()
val transNum = call.argument<String>("transNum").toString() val transNum = call.argument<String>("transNum").toString()
val operationParameters = createOperationParameters(token) val operationParameters = createOperationParameters(token)
val body = JsonForExternalCall.getReversalJson(operationParameters.authToken, terminalId, operDay, transNum); val packageName = call.argument<String>("packageName").toString()
println(body) val body = JsonForExternalCall.getReversalJson(operationParameters.authToken, terminalId, operDay, transNum)
startOperation(OperationType.REVERSAL, body) startOperation(
OperationType.REVERSAL,
body,
packageName
)
} }
private fun operationCloseDay(call: MethodCall) { private fun operationCloseDay(call: MethodCall) {
val token = call.argument<String>("token").toString() val token = call.argument<String>("token").toString()
val packageName = call.argument<String>("packageName").toString()
val operationParameters = createOperationParameters(token) val operationParameters = createOperationParameters(token)
startOperation(OperationType.CLOSE_DAY, JsonForExternalCall.getCloseDayJson(operationParameters.authToken)) startOperation(
OperationType.CLOSE_DAY,
JsonForExternalCall.getCloseDayJson(operationParameters.authToken),
packageName
)
} }
@ -104,18 +122,32 @@ class MainActivity : FlutterActivity() {
return OperationParameters(authToken = token, operDay = operDay, terminalId = terminalId, transNum = transNum) return OperationParameters(authToken = token, operDay = operDay, terminalId = terminalId, transNum = transNum)
} }
private fun startOperation(operationType: OperationType, inputJsonData: String?) { private fun startOperation(
operationType: OperationType,
inputJsonData: String?,
packageName: String
) {
try {
val intent = Intent() val intent = Intent()
intent.component = ComponentName("ru.m4bank.softpos.halyk", "ru.m4bank.feature.externalapplication.ExternalApplicationActivity") intent.component = ComponentName(packageName, "ru.m4bank.feature.externalapplication.ExternalApplicationActivity")
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
// intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP // intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
intent.putExtra(externalOperationTypeKey, operationType.code) intent.putExtra(externalOperationTypeKey, operationType.code)
intent.putExtra(externalInputDataKey, inputJsonData) intent.putExtra(externalInputDataKey, inputJsonData)
if (intent.resolveActivity(packageManager) != null) {
startActivityForResult(intent, externalApplicationRequestCode) startActivityForResult(intent, externalApplicationRequestCode)
} else {
_result.error("008", "Не удалось найти подходящее приложение", "aaa")
}
} catch (e: ActivityNotFoundException) {
_result.error("008", "Не удалось найти подходящее приложение", "aaa")
}
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data) super.onActivityResult(requestCode, resultCode, data)
try {
if (requestCode == externalApplicationRequestCode) { if (requestCode == externalApplicationRequestCode) {
println("---------------") println("---------------")
println(requestCode) println(requestCode)
@ -140,6 +172,9 @@ class MainActivity : FlutterActivity() {
// } else // } else
// _result.success(null) // _result.success(null)
} }
} catch (e: IllegalStateException) {
print("IllegalStateException")
}
} }

View File

@ -37,7 +37,7 @@ object JsonForExternalCall {
"instrument": "CARD", "instrument": "CARD",
"amountData" : { "amountData" : {
"currencyCode": "348", "currencyCode": "348",
"amount": "6000", "amount": "$amount",
"amountExponent": "2" "amountExponent": "2"
}, },
"parentTransaction" : { "parentTransaction" : {

View File

@ -1,23 +1,19 @@
buildscript { buildscript {
ext.kotlin_version = '1.3.61' ext.kotlin_version = '2.2.20'
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.5.0' classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2'
classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }
allprojects { allprojects {
repositories { repositories {
google() google()
jcenter() mavenCentral()
} }
configurations.all { configurations.all {
@ -35,13 +31,42 @@ subprojects {
project.evaluationDependsOn(':app') project.evaluationDependsOn(':app')
} }
task clean(type: Delete) { gradle.beforeProject { proj ->
delete rootProject.buildDir proj.afterEvaluate {
if (proj.plugins.hasPlugin("com.android.library")) {
try {
if (!proj.android.namespace) {
def manifestFile = proj.file("src/main/AndroidManifest.xml")
if (manifestFile.exists()) {
def manifest = new groovy.xml.XmlSlurper().parse(manifestFile)
def packageName = manifest.'@package'?.toString()
if (packageName) {
proj.android.namespace = packageName
}
}
}
} catch (Exception ignored) {}
}
// Force Java 17 for all Android subprojects to match global Kotlin JVM target 17
if (proj.plugins.hasPlugin("com.android.library") || proj.plugins.hasPlugin("com.android.application")) {
try {
proj.android.compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
} catch (Exception ignored) {}
}
}
} }
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { tasks.register("clean", Delete) {
delete rootProject.layout.buildDirectory
}
allprojects {
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).configureEach {
kotlinOptions { kotlinOptions {
jvmTarget = "1.8" jvmTarget = "17"
}
} }
} }

File diff suppressed because one or more lines are too long

View File

@ -2,3 +2,8 @@ org.gradle.jvmargs=-Xmx1536M
android.enableR8=true android.enableR8=true
android.useAndroidX=true android.useAndroidX=true
android.enableJetifier=true android.enableJetifier=true
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false
android.defaults.buildfeatures.buildconfig=true

View File

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-all.zip

View File

@ -1,15 +1,25 @@
include ':app' pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()
def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
def plugins = new Properties() repositories {
def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') google()
if (pluginsFile.exists()) { mavenCentral()
pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } gradlePluginPortal()
}
} }
plugins.each { name, path -> plugins {
def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() id "dev.flutter.flutter-plugin-loader" version "1.0.0"
include ":$name" id "com.android.application" version "8.11.1" apply false
project(":$name").projectDir = pluginDirectory id "org.jetbrains.kotlin.android" version "2.2.20" apply false
} }
include ":app"

BIN
assets/images/fortepos.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

View File

@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>8.0</string> <string>9.0</string>
</dict> </dict>
</plist> </plist>

View File

@ -0,0 +1,32 @@
#
# Generated file, do not edit.
#
import lldb
def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict):
"""Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages."""
base = frame.register["x0"].GetValueAsAddress()
page_len = frame.register["x1"].GetValueAsUnsigned()
# Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the
# first page to see if handled it correctly. This makes diagnosing
# misconfiguration (e.g. missing breakpoint) easier.
data = bytearray(page_len)
data[0:8] = b'IHELPED!'
error = lldb.SBError()
frame.GetThread().GetProcess().WriteMemory(base, data, error)
if not error.Success():
print(f'Failed to write into {base}[+{page_len}]', error)
return
def __lldb_init_module(debugger: lldb.SBDebugger, _):
target = debugger.GetDummyTarget()
# Caveat: must use BreakpointCreateByRegEx here and not
# BreakpointCreateByName. For some reasons callback function does not
# get carried over from dummy target for the later.
bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$")
bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__))
bp.SetAutoContinue(True)
print("-- LLDB integration loaded --")

View File

@ -0,0 +1,5 @@
#
# Generated file, do not edit.
#
command script import --relative-to-command-file flutter_lldb_helper.py

View File

@ -0,0 +1,12 @@
FLUTTER_ROOT=/home/rustem/development/flutter
FLUTTER_APPLICATION_PATH=/home/rustem/PhpstormProjects/aman-kassa-flutter
FLUTTER_FRAMEWORK_SWIFT_PACKAGE_PATH=/home/rustem/PhpstormProjects/aman-kassa-flutter/ios/Flutter/ephemeral/Packages/.packages/FlutterFramework
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_TARGET=lib/main.dart
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=1.4.0
FLUTTER_BUILD_NUMBER=45
DART_OBFUSCATION=false
TRACK_WIDGET_CREATION=true
TREE_SHAKE_ICONS=false
PACKAGE_CONFIG=.dart_tool/package_config.json

View File

@ -1,98 +1,111 @@
PODS: PODS:
- barcode_scan (0.0.1): - barcode_scan2 (0.0.1):
- Flutter - Flutter
- MTBBarcodeScanner - MTBBarcodeScanner
- SwiftProtobuf - SwiftProtobuf
- bluetooth_print (0.0.1):
- Flutter
- charset_converter (0.0.1): - charset_converter (0.0.1):
- Flutter - Flutter
- device_info (0.0.1): - device_info (0.0.1):
- Flutter - Flutter
- esys_flutter_share (0.0.1):
- Flutter
- Flutter (1.0.0) - Flutter (1.0.0)
- flutter_bluetooth_basic (0.0.1): - flutter_blue (0.0.1):
- Flutter - Flutter
- flutter_blue/Protos (= 0.0.1)
- flutter_blue/Protos (0.0.1):
- Flutter
- Protobuf (~> 3.11.4)
- 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): - local_auth (0.0.1):
- Flutter - Flutter
- MTBBarcodeScanner (5.0.11) - MTBBarcodeScanner (5.0.11)
- path_provider (0.0.1): - path_provider_ios (0.0.1):
- Flutter - Flutter
- "permission_handler (5.1.0+2)": - "permission_handler (5.1.0+2)":
- Flutter - Flutter
- shared_preferences (0.0.1): - Protobuf (3.11.4)
- shared_preferences_ios (0.0.1):
- Flutter - Flutter
- sqflite (0.0.2): - sqflite (0.0.2):
- Flutter - Flutter
- FMDB (>= 2.7.5) - FMDB (>= 2.7.5)
- SwiftProtobuf (1.9.0) - SwiftProtobuf (1.18.0)
- url_launcher (0.0.1): - url_launcher_ios (0.0.1):
- Flutter
- vocsy_esys_flutter_share (0.0.1):
- Flutter - Flutter
DEPENDENCIES: DEPENDENCIES:
- barcode_scan (from `.symlinks/plugins/barcode_scan/ios`) - barcode_scan2 (from `.symlinks/plugins/barcode_scan2/ios`)
- bluetooth_print (from `.symlinks/plugins/bluetooth_print/ios`)
- charset_converter (from `.symlinks/plugins/charset_converter/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`)
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_bluetooth_basic (from `.symlinks/plugins/flutter_bluetooth_basic/ios`) - flutter_blue (from `.symlinks/plugins/flutter_blue/ios`)
- local_auth (from `.symlinks/plugins/local_auth/ios`) - local_auth (from `.symlinks/plugins/local_auth/ios`)
- path_provider (from `.symlinks/plugins/path_provider/ios`) - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
- permission_handler (from `.symlinks/plugins/permission_handler/ios`) - permission_handler (from `.symlinks/plugins/permission_handler/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - shared_preferences_ios (from `.symlinks/plugins/shared_preferences_ios/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`)
- url_launcher (from `.symlinks/plugins/url_launcher/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
- vocsy_esys_flutter_share (from `.symlinks/plugins/vocsy_esys_flutter_share/ios`)
SPEC REPOS: SPEC REPOS:
trunk: trunk:
- FMDB - FMDB
- MTBBarcodeScanner - MTBBarcodeScanner
- Protobuf
- SwiftProtobuf - SwiftProtobuf
EXTERNAL SOURCES: EXTERNAL SOURCES:
barcode_scan: barcode_scan2:
:path: ".symlinks/plugins/barcode_scan/ios" :path: ".symlinks/plugins/barcode_scan2/ios"
bluetooth_print:
:path: ".symlinks/plugins/bluetooth_print/ios"
charset_converter: charset_converter:
:path: ".symlinks/plugins/charset_converter/ios" :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:
:path: ".symlinks/plugins/esys_flutter_share/ios"
Flutter: Flutter:
:path: Flutter :path: Flutter
flutter_bluetooth_basic: flutter_blue:
:path: ".symlinks/plugins/flutter_bluetooth_basic/ios" :path: ".symlinks/plugins/flutter_blue/ios"
local_auth: local_auth:
:path: ".symlinks/plugins/local_auth/ios" :path: ".symlinks/plugins/local_auth/ios"
path_provider: path_provider_ios:
:path: ".symlinks/plugins/path_provider/ios" :path: ".symlinks/plugins/path_provider_ios/ios"
permission_handler: permission_handler:
:path: ".symlinks/plugins/permission_handler/ios" :path: ".symlinks/plugins/permission_handler/ios"
shared_preferences: shared_preferences_ios:
:path: ".symlinks/plugins/shared_preferences/ios" :path: ".symlinks/plugins/shared_preferences_ios/ios"
sqflite: sqflite:
:path: ".symlinks/plugins/sqflite/ios" :path: ".symlinks/plugins/sqflite/ios"
url_launcher: url_launcher_ios:
:path: ".symlinks/plugins/url_launcher/ios" :path: ".symlinks/plugins/url_launcher_ios/ios"
vocsy_esys_flutter_share:
:path: ".symlinks/plugins/vocsy_esys_flutter_share/ios"
SPEC CHECKSUMS: SPEC CHECKSUMS:
barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479 barcode_scan2: 0af2bb63c81b4565aab6cd78278e4c0fa136dbb0
bluetooth_print: da8f47e8881a0b1f0fd8d73cd6fa84c9bd41ac28
charset_converter: 215c7b04932ec2b9ba43be96a9bc34afed3e5322 charset_converter: 215c7b04932ec2b9ba43be96a9bc34afed3e5322
device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 device_info: d7d233b645a32c40dfdc212de5cf646ca482f175
esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4 Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c flutter_blue: eeb381dc4727a0954dede73515f683865494b370
flutter_bluetooth_basic: 0e4e27e22b50b3a25cc1d1e131953feb4af414f4
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
local_auth: 25938960984c3a7f6e3253e3f8d962fdd16852bd local_auth: ef62030a2731330b95df7ef1331bd15f6a64b8a6
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c path_provider_ios: 7d7ce634493af4477d156294792024ec3485acd5
permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0 permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d Protobuf: 176220c526ad8bd09ab1fb40a978eac3fef665f7
shared_preferences_ios: aef470a42dc4675a1cdd50e3158b42e3d1232b32
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
SwiftProtobuf: ecbec1be9036d15655f6b3443a1c4ea693c97932 SwiftProtobuf: c3c12645230d9b09c72267e0de89468c5543bd86
url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef url_launcher_ios: 02f1989d4e14e998335b02b67a7590fa34f971af
vocsy_esys_flutter_share: 98b79fad467203ababde56a7289ac90da6a4ddf5
PODFILE CHECKSUM: 5aafc9b59da66d8d46f05cbbbd21261eb9757176 PODFILE CHECKSUM: 5aafc9b59da66d8d46f05cbbbd21261eb9757176

View File

@ -3,7 +3,7 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 46; objectVersion = 50;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
@ -166,7 +166,7 @@
97C146E61CF9000F007C117D /* Project object */ = { 97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastUpgradeCheck = 1020; LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "The Chromium Authors"; ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = { TargetAttributes = {
97C146ED1CF9000F007C117D = { 97C146ED1CF9000F007C117D = {
@ -256,31 +256,35 @@
"${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",
"${BUILT_PRODUCTS_DIR}/MTBBarcodeScanner/MTBBarcodeScanner.framework", "${BUILT_PRODUCTS_DIR}/MTBBarcodeScanner/MTBBarcodeScanner.framework",
"${BUILT_PRODUCTS_DIR}/Protobuf/protobuf.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_scan2/barcode_scan2.framework",
"${BUILT_PRODUCTS_DIR}/charset_converter/charset_converter.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}/flutter_blue/flutter_blue.framework",
"${BUILT_PRODUCTS_DIR}/local_auth/local_auth.framework", "${BUILT_PRODUCTS_DIR}/local_auth/local_auth.framework",
"${BUILT_PRODUCTS_DIR}/path_provider/path_provider.framework", "${BUILT_PRODUCTS_DIR}/path_provider_ios/path_provider_ios.framework",
"${BUILT_PRODUCTS_DIR}/shared_preferences/shared_preferences.framework", "${BUILT_PRODUCTS_DIR}/shared_preferences_ios/shared_preferences_ios.framework",
"${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework", "${BUILT_PRODUCTS_DIR}/sqflite/sqflite.framework",
"${BUILT_PRODUCTS_DIR}/url_launcher/url_launcher.framework", "${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework",
"${BUILT_PRODUCTS_DIR}/vocsy_esys_flutter_share/vocsy_esys_flutter_share.framework",
); );
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}/MTBBarcodeScanner.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MTBBarcodeScanner.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/protobuf.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_scan2.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/charset_converter.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}/flutter_blue.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/local_auth.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_ios.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences_ios.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/sqflite.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/vocsy_esys_flutter_share.framework",
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh; shellPath = /bin/sh;
@ -376,7 +380,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -401,7 +405,10 @@
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
@ -463,7 +470,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES; MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos; SDKROOT = iphoneos;
@ -512,7 +519,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES; GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0; IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO; MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos; SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos; SUPPORTED_PLATFORMS = iphoneos;
@ -538,7 +545,10 @@
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
@ -570,7 +580,10 @@
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",
); );
INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Flutter", "$(PROJECT_DIR)/Flutter",

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1020" LastUpgradeVersion = "1300"
version = "1.3"> version = "1.3">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>1086013480150-93mcqf1l60dvmd2k1lkg2ikmvm3u29ca.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.1086013480150-93mcqf1l60dvmd2k1lkg2ikmvm3u29ca</string>
<key>API_KEY</key>
<string>AIzaSyApELiWrEflqtXPo8cndFnPW0sRVVHmkYQ</string>
<key>GCM_SENDER_ID</key>
<string>1086013480150</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.kz.amankassaflutter</string>
<key>PROJECT_ID</key>
<string>aman-f670e</string>
<key>STORAGE_BUCKET</key>
<string>aman-f670e.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false></false>
<key>IS_ANALYTICS_ENABLED</key>
<false></false>
<key>IS_APPINVITE_ENABLED</key>
<true></true>
<key>IS_GCM_ENABLED</key>
<true></true>
<key>IS_SIGNIN_ENABLED</key>
<true></true>
<key>GOOGLE_APP_ID</key>
<string>1:1086013480150:ios:958c91234e46010cf17d77</string>
</dict>
</plist>

View File

@ -0,0 +1,7 @@
{
"file_generated_by": "FlutterFire CLI",
"purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory",
"GOOGLE_APP_ID": "1:1086013480150:ios:958c91234e46010cf17d77",
"FIREBASE_PROJECT_ID": "aman-f670e",
"GCM_SENDER_ID": "1086013480150"
}

View File

@ -3,9 +3,9 @@ import 'package:logger/logger.dart';
import '../logger.dart'; import '../logger.dart';
class BaseService { class BaseService {
Logger log; late Logger log;
BaseService({String title}) { BaseService({String? title}) {
this.log = getLogger( this.log = getLogger(
title ?? this.runtimeType.toString(), title ?? this.runtimeType.toString(),
); );

View File

@ -5,10 +5,10 @@ const String Category_columnName = 'name';
const String Category_columnAppCompanyId = 'app_company_id'; const String Category_columnAppCompanyId = 'app_company_id';
class Category { class Category {
int id; int? id;
int parentIn; int? parentIn;
String name; String name = '';
int appCompanyId; int? appCompanyId;
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
var map = <String, dynamic>{ var map = <String, dynamic>{

View File

@ -13,17 +13,17 @@ const String Goog_columnOkei = 'okei';
const String Goog_columnDiscount = 'discount'; const String Goog_columnDiscount = 'discount';
class Good { class Good {
int id; int? id;
int articul; int articul = -1;
String name; String name = '';
double price; double price = -1;
int categoryId; int categoryId = -1;
String ean; String? ean;
int appCompanyId; int? appCompanyId;
String description; String? description;
double showPrice; double? showPrice;
int okei; int? okei;
double discount; double? discount;
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
var map = <String, dynamic>{ var map = <String, dynamic>{

View File

@ -14,16 +14,15 @@ const String Service_columnDiscount = 'discount';
class Service { class Service {
int id; int? id;
int articul; int articul = -1;
String name; String name = '';
double price; double price = -1;
String ean; int? appCompanyId;
int appCompanyId; String? description;
String description; double? showPrice;
double showPrice; String? okei;
String okei; double? discount;
double discount;
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
var map = <String, dynamic>{ var map = <String, dynamic>{

View File

@ -17,16 +17,16 @@ const String VoucherTypeReport = 'report';
const String VoucherTypeCloseDayPosReport = 'closeDayPosReport'; const String VoucherTypeCloseDayPosReport = 'closeDayPosReport';
class Voucher { class Voucher {
int id; int? id;
String name; String? name;
double total; double? total;
String data; String? data;
String base64Data; String? base64Data;
DateTime dateTime; DateTime? dateTime;
int appCompanyId; int? appCompanyId;
int kassaId; int? kassaId;
String type; String? type;
String url; String? url;
Voucher(); Voucher();
@ -36,7 +36,7 @@ class Voucher {
Voucher_columnTotal: total, Voucher_columnTotal: total,
Voucher_columnData: data, Voucher_columnData: data,
Voucher_columnBase64Data: base64Data, Voucher_columnBase64Data: base64Data,
Voucher_columnDateTime: dateTime.toIso8601String(), Voucher_columnDateTime: dateTime?.toIso8601String(),
Voucher_columnKassaId: kassaId, Voucher_columnKassaId: kassaId,
Voucher_columnAppCompanyId: appCompanyId, Voucher_columnAppCompanyId: appCompanyId,
Voucher_columnType: type, Voucher_columnType: type,
@ -48,7 +48,7 @@ class Voucher {
return map; return map;
} }
Voucher.fromMap(Map<String, dynamic> map) { Voucher.fromMap(Map<dynamic, dynamic> map) {
id = map[Voucher_columnId]; id = map[Voucher_columnId];
name = map[Voucher_columnName]; name = map[Voucher_columnName];
total = map[Voucher_columnTotal]?.toDouble(); total = map[Voucher_columnTotal]?.toDouble();

View File

@ -1,7 +1,10 @@
import 'package:aman_kassa_flutter/core/services/BankService.dart'; import 'package:aman_kassa_flutter/core/services/BankService.dart' as bank;
import 'package:aman_kassa_flutter/core/services/ForteService.dart' as forte;
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/NctService.dart';
import 'package:aman_kassa_flutter/core/services/blue_print_service.dart';
import '../core/services/DbService.dart'; import '../core/services/DbService.dart';
@ -26,14 +29,20 @@ class LocatorInjector {
locator.registerLazySingleton<DialogService>(() => DialogService()); locator.registerLazySingleton<DialogService>(() => DialogService());
_log.d('Initializing DbService Service'); _log.d('Initializing DbService Service');
locator.registerLazySingleton<DbService>(() => DbService.instance); locator.registerLazySingleton<DbService>(() => DbService.instance);
_log.d('Initializing BluePrintService Service');
locator.registerLazySingleton<BluePrintService>(() => BluePrintService());
// depencies // depencies
_log.d('Initializing NctService Service');
locator.registerLazySingleton<NctService>(() => NctService());
_log.d('Initializing DataService Service'); _log.d('Initializing DataService Service');
locator.registerLazySingleton<DataService>(() => DataService()); locator.registerLazySingleton<DataService>(() => DataService());
_log.d('Initializing BankService Service'); _log.d('Initializing BankService Service');
locator.registerLazySingleton<BankService>(() => BankService()); locator.registerLazySingleton<bank.BankService>(() => bank.BankService());
_log.d('Initializing Forte Service');
locator.registerLazySingleton<forte.ForteService>(() => forte.ForteService());
} }
} }

View File

@ -14,13 +14,13 @@ class SimpleLogPrinter extends LogPrinter {
var error = event.error?.toString() ?? ''; var error = event.error?.toString() ?? '';
var color = PrettyPrinter.levelColors[level]; var color = PrettyPrinter.levelColors[level];
var emoji = PrettyPrinter.levelEmojis[level]; var emoji = PrettyPrinter.levelEmojis[level];
String stack; String? stack;
if (event.stackTrace == null) { if (event.stackTrace == null) {
stack = formatStackTrace(StackTrace.current, 2); stack = formatStackTrace(StackTrace.current, 2);
} else { } else {
stack = formatStackTrace(event.stackTrace, 2); stack = formatStackTrace(event.stackTrace!, 1);
} }
print(color(' $emoji $message $error -> $stack ')); print(color!(' $emoji $message $error -> $stack '));
return []; return [];
} }
@ -33,9 +33,9 @@ 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;
for (var line in lines) { for (var line in lines) {
@ -62,7 +62,7 @@ class SimpleLogPrinter extends LogPrinter {
if (match == null) { if (match == null) {
return false; return false;
} }
return match.group(2).startsWith('package:logger'); return match.group(2)!.startsWith('package:logger');
} }
bool _discardWebStacktraceLine(String line) { bool _discardWebStacktraceLine(String line) {
@ -70,8 +70,8 @@ class SimpleLogPrinter extends LogPrinter {
if (match == null) { if (match == null) {
return false; return false;
} }
return match.group(1).startsWith('packages/logger') || return match.group(1)!.startsWith('packages/logger') ||
match.group(1).startsWith('dart-sdk/lib'); match.group(1)!.startsWith('dart-sdk/lib');
} }
} }

View File

@ -1,8 +1,8 @@
class AmanDao<T> { class AmanDao<T> {
final T data; final T? data;
final dynamic rows; final dynamic? rows;
final String msg; final String? msg;
final bool success; final bool? success;
AmanDao({this.data, this.success, this.msg, this.rows}); AmanDao({this.data, this.success, this.msg, this.rows});

View File

@ -2,9 +2,9 @@ import '../utilsParse.dart';
import 'user.dart'; import 'user.dart';
class AuthResponse { class AuthResponse {
final AuthBody body; final AuthBody? body;
final int status; final int? status;
final bool operation; final bool? operation;
AuthResponse( {this.body, this.status, this.operation}); AuthResponse( {this.body, this.status, this.operation});
@ -19,10 +19,10 @@ class AuthResponse {
} }
class AuthBody { class AuthBody {
final List<String> email; final List<String>? email;
final List<String> password; final List<String>? password;
final String message; final String? message;
final User user; final User? user;
AuthBody({this.message, this.user, this.email, this.password}); AuthBody({this.message, this.user, this.email, this.password});
factory AuthBody.fromJson(Map<String, dynamic> json) { factory AuthBody.fromJson(Map<String, dynamic> json) {
return AuthBody( return AuthBody(

View File

@ -0,0 +1,25 @@
class BluetoothDevice {
String? name;
String? address;
int? type;
bool? connected;
BluetoothDevice();
factory BluetoothDevice.fromJson(Map<String, dynamic> json) {
return BluetoothDevice()
..name = json['name']
..address = json['address']
..type = json['type']
..connected = json['connected'];
}
Map<String, dynamic> toJson() {
return {
'name': name,
'address': address,
'type': type,
'connected': connected,
};
}
}

View File

@ -1,9 +1,9 @@
class CalcModel { class CalcModel {
String num1; String num1;
String num2; String? num2;
bool closed; bool closed;
String operation; String operation;
CalcModel({this.num1, this.num2, this.operation, this.closed = false}); CalcModel({required this.num1, this.num2, required this.operation, this.closed = false});
@override @override
String toString() { String toString() {

View File

@ -1,15 +1,15 @@
class CardData { class CardData {
final int transactionNumber; final int? transactionNumber;
final int operationDay; final int? operationDay;
final int terminalId; final int? terminalId;
final String cardNumber; final String? cardNumber;
final String cardholderName; final String? cardholderName;
final String authorizationCode; final String? authorizationCode;
final String transactionType; final String? transactionType;
CardData({this.transactionNumber, this.operationDay, this.cardNumber, this.cardholderName, this.authorizationCode, this.terminalId, this.transactionType }); CardData({this.transactionNumber, this.operationDay, this.cardNumber, this.cardholderName, this.authorizationCode, this.terminalId, this.transactionType });
static CardData fromJson(Map<String, dynamic> json) { static CardData? fromJson(Map<String, dynamic>? json) {
return json != null ? return json != null ?
CardData( CardData(
transactionNumber: json['transactionNumber'], transactionNumber: json['transactionNumber'],

View File

@ -2,25 +2,31 @@ 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; num? mobile;
CardData cardData; String? contragent;
CheckData({this.type, this.card, this.items, this.cardData}); final List<CheckItem>? items;
CardData? cardData;
CheckData({this.type, this.card, this.mobile, this.items, this.cardData, this.contragent});
static CheckData fromJson(Map<String, dynamic> json) { static CheckData fromJson(Map<String, dynamic> json) {
return CheckData( return CheckData(
type: json['type'], type: json['type'] as String?,
card: json['card'], card: json['card'] as num?,
mobile: json['mobile'] as num?,
items: (json['items'] as List).map((e) => CheckItem.fromJson(e)).toList(), items: (json['items'] as List).map((e) => CheckItem.fromJson(e)).toList(),
cardData: CardData.fromJson(json['cardData']) cardData: CardData.fromJson(json['cardData']),
contragent: json['type'] as String?,
); );
} }
Map<String, dynamic> toJson() => Map<String, dynamic> toJson() =>
{ {
'type': type, 'type': type,
'card': card, 'card': card,
'items': items.map((e) => e.toJson()).toList(), 'mobile': mobile,
'cardData': cardData!=null ? cardData.toJson() : null 'items': items?.map((e) => e.toJson()).toList(),
'cardData': cardData?.toJson(),
'contragent': contragent,
}; };
} }

View File

@ -1,6 +1,6 @@
class CheckImageModal { class CheckImageModal {
final String base64Data; final String? base64Data;
final String textData; final String? textData;
CheckImageModal({this.base64Data, this.textData}); CheckImageModal({this.base64Data, this.textData});
static CheckImageModal fromJson(Map<String, dynamic> json) { static CheckImageModal fromJson(Map<String, dynamic> json) {

View File

@ -3,8 +3,10 @@ class CheckItem {
final num cnt; final num cnt;
final num price; final num price;
final int articul; final int articul;
final String excise; final String? excise;
CheckItem({this.name, this.cnt, this.price, this.articul, this.excise}); final String? ntin;
CheckItem({required this.name, required this.cnt, required this.price, required this.articul, this.excise, this.ntin});
static CheckItem fromJson(Map<String, dynamic> json) { static CheckItem fromJson(Map<String, dynamic> json) {
return CheckItem( return CheckItem(
@ -13,14 +15,17 @@ class CheckItem {
price: json['price'], price: json['price'],
articul: json['articul'], articul: json['articul'],
excise: json['excise'], excise: json['excise'],
ntin: json['ntin'],
); );
} }
Map<String, dynamic> toJson() => Map<String, dynamic> toJson() =>
{ {
'name': name, 'name': name,
'cnt': cnt, 'cnt': cnt,
'price': price, 'price': price,
'articul': articul, 'articul': articul,
'excise' : excise 'excise': excise,
'ntin': ntin ?? '',
}; };
} }

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class Choice { class Choice {
const Choice({this.title, this.icon, this.command}); const Choice({required this.title, required this.icon, required this.command});
final String command; final String command;
final String title; final String title;
final IconData icon; final IconData icon;

View File

@ -4,13 +4,13 @@ class DialogRequest {
final String title; final String title;
final String description; final String description;
final String buttonTitle; final String buttonTitle;
final String cancelTitle; final String? cancelTitle;
final String formatType; final String? formatType;
DialogRequest( DialogRequest(
{@required this.title, {required this.title,
@required this.description, required this.description,
@required this.buttonTitle, required this.buttonTitle,
this.cancelTitle, this.cancelTitle,
this.formatType}); this.formatType});
} }
@ -18,13 +18,13 @@ class DialogRequest {
class DialogResponse { class DialogResponse {
//final String fieldOne; //final String fieldOne;
//final String fieldTwo; //final String fieldTwo;
final String responseText; final String? responseText;
final bool confirmed; final bool confirmed;
DialogResponse({ DialogResponse({
//this.fieldOne, //this.fieldOne,
//this.fieldTwo, //this.fieldTwo,
this.responseText, this.responseText,
this.confirmed, required this.confirmed,
}); });
} }

View File

@ -1,5 +1,5 @@
class DictDao { class DictDao {
final int id; final int id;
final String name; final String name;
DictDao({ this.id, this.name}); DictDao({ required this.id, required this.name});
} }

View File

@ -1,20 +1,20 @@
import 'package:aman_kassa_flutter/core/models/transaction_item.dart'; import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
import 'halyk/halyk_close_day_dao.dart'; import 'forte_close_day_dao.dart';
class CloseDayData { class CloseDayData {
final String title; final String? title;
final num totalAmount; final num? totalAmount;
final int totalCount; final int? totalCount;
final num paymentAmount; final num? paymentAmount;
final int paymentCount; final int? paymentCount;
final num refundAmount; final num? refundAmount;
final int refundCount; final int? refundCount;
final num cancelAmount; final num? cancelAmount;
final int cancelCount; final int? cancelCount;
final List<TransactionBean> items; final List<TransactionBean>? items;
CloseDayData({ CloseDayData({
this.title, this.title,
this.items, this.items,
@ -49,6 +49,6 @@ class CloseDayData {
'refundCount': refundCount, 'refundCount': refundCount,
'cancelAmount': cancelAmount, 'cancelAmount': cancelAmount,
'cancelCount': cancelCount, 'cancelCount': cancelCount,
'items': items.map((e) => e.toJson()).toList(), 'items': items?.map((e) => e.toJson()).toList(),
}; };
} }

View File

@ -0,0 +1,180 @@
/// 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 ForteCloseDayDao {
ResultBean? result;
TransactionsBean? transactions;
CloseDayResultsBean? closeDayResults;
ForteCloseDayDao({ this.result, this.closeDayResults, this.transactions});
static ForteCloseDayDao? fromMap(Map<String, dynamic>? map) {
if (map == null) return null;
ForteCloseDayDao forteCloseDayDaoBean = ForteCloseDayDao();
forteCloseDayDaoBean.result = ResultBean.fromMap(map['result']);
forteCloseDayDaoBean.transactions = TransactionsBean.fromMap(map['transactions']);
forteCloseDayDaoBean.closeDayResults = CloseDayResultsBean.fromMap(map['closeDayResults']);
return forteCloseDayDaoBean;
}
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 = (map['reconciliationResult'] as List)
.map((o) => ReconciliationResultBean.fromMap(o))
.toList();
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) {
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 = (map['transaction'] as List)
.map((o) => TransactionBean.fromMap(o))
.toList();
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 = 0;
int? terminalId;
int? operationDay;
int? transactionNumber;
InstrumentSpecificDataBean? instrumentSpecificData;
static TransactionBean fromMap(Map<String, dynamic> map) {
TransactionBean transactionBean = TransactionBean();
transactionBean.type = map['type'];
transactionBean.instrument = map['instrument'];
transactionBean.amount = map['amount'] ?? 0;
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,
};
}

View File

@ -0,0 +1,79 @@
import 'package:intl/intl.dart';
class FortePosSession {
const FortePosSession({
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 FortePosSession fromJson(Map<String, dynamic> data) => FortePosSession(
login: data['login'] as String?,
token: data['token'] as String?,
result: data['result'] != null ? ResultBean.fromMap(data['result'] as Map<String, dynamic>) : null,
serverTime: data['ServerTime'] != null
? DateFormat("dd.MM.yyyy HH:mm:ss ZZZ").parse(data['ServerTime'])
: null,
tokenTimeout: data['TokenTimeout'] as int?,
);
Map<String, dynamic> toJson() => {
"login": login,
"token": token,
"ServerTime": serverTime != null
? DateFormat("dd.MM.yyyy HH:mm:ss ZZZ").format(serverTime!)
: null,
"TokenTimeout": tokenTimeout,
"result": result?.toJson(),
};
}
class ResultBean {
late String ServerTime;
late String ResultCode;
late String ResultStr;
late ResponseBean? Response;
static ResultBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null;
ResultBean resultBean = ResultBean();
resultBean.ServerTime = map['ServerTime'] as String? ?? '';
resultBean.ResultCode = map['ResultCode'] as String? ?? '';
resultBean.ResultStr = map['ResultStr'] as String? ?? '';
resultBean.Response = map['Response'] != null ? ResponseBean.fromMap(map['Response'] as Map<String, dynamic>) : null;
return resultBean;
}
Map<String, dynamic> toJson() => {
"ServerTime": ServerTime,
"ResultCode": ResultCode,
"ResultStr": ResultStr,
"Response": Response?.toJson(),
};
}
class ResponseBean {
late String Code;
late String Description;
static ResponseBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null;
ResponseBean responseBean = ResponseBean();
responseBean.Code = map['Code'] as String? ?? '';
responseBean.Description = map['Description'] as String? ?? '';
return responseBean;
}
Map<String, dynamic> toJson() => {
"Code": Code,
"Description": Description,
};
}

View File

@ -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 ForteResponse {
ResultBean? result;
TransactionBean? transaction;
ForteResponse({this.result, this.transaction});
static ForteResponse? fromMap(Map<String, dynamic>? map) {
if (map == null) return null;
ForteResponse forteResponseBean = ForteResponse();
forteResponseBean.result = ResultBean.fromMap(map['result']);
forteResponseBean.transaction = TransactionBean.fromMap(map['transaction']);
return forteResponseBean;
}
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 {
int? 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,
};
}

View File

@ -0,0 +1,54 @@
import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
import '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(),
};
}

View File

@ -3,13 +3,13 @@
/// closeDayResults : {"reconciliationResult":[{"hostResultCode":"000","hostResultDescription":"Success","terminalExternalId":"example_terminal_id"}]} /// closeDayResults : {"reconciliationResult":[{"hostResultCode":"000","hostResultDescription":"Success","terminalExternalId":"example_terminal_id"}]}
class HalykCloseDayDao { class HalykCloseDayDao {
ResultBean result; ResultBean? result;
TransactionsBean transactions; TransactionsBean? transactions;
CloseDayResultsBean closeDayResults; CloseDayResultsBean? closeDayResults;
HalykCloseDayDao({ this.result, this.closeDayResults, this.transactions}); HalykCloseDayDao({ this.result, this.closeDayResults, this.transactions});
static HalykCloseDayDao fromMap(Map<String, dynamic> map) { static HalykCloseDayDao? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
HalykCloseDayDao halykCloseDayDaoBean = HalykCloseDayDao(); HalykCloseDayDao halykCloseDayDaoBean = HalykCloseDayDao();
halykCloseDayDaoBean.result = ResultBean.fromMap(map['result']); halykCloseDayDaoBean.result = ResultBean.fromMap(map['result']);
@ -28,13 +28,13 @@ class HalykCloseDayDao {
/// reconciliationResult : [{"hostResultCode":"000","hostResultDescription":"Success","terminalExternalId":"example_terminal_id"}] /// reconciliationResult : [{"hostResultCode":"000","hostResultDescription":"Success","terminalExternalId":"example_terminal_id"}]
class CloseDayResultsBean { class CloseDayResultsBean {
List<ReconciliationResultBean> reconciliationResult; List<ReconciliationResultBean>? reconciliationResult;
static CloseDayResultsBean fromMap(Map<String, dynamic> map) { static CloseDayResultsBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
CloseDayResultsBean closeDayResultsBean = CloseDayResultsBean(); CloseDayResultsBean closeDayResultsBean = CloseDayResultsBean();
closeDayResultsBean.reconciliationResult = List()..addAll( closeDayResultsBean.reconciliationResult = List.empty()..addAll(
(map['reconciliationResult'] as List ?? []).map((o) => ReconciliationResultBean.fromMap(o)) (map['reconciliationResult'] as List).map((o) => ReconciliationResultBean.fromMap(o))
); );
return closeDayResultsBean; return closeDayResultsBean;
} }
@ -49,12 +49,11 @@ class CloseDayResultsBean {
/// terminalExternalId : "example_terminal_id" /// terminalExternalId : "example_terminal_id"
class ReconciliationResultBean { class ReconciliationResultBean {
String hostResultCode; String? hostResultCode;
String hostResultDescription; String? hostResultDescription;
String terminalExternalId; String? terminalExternalId;
static ReconciliationResultBean fromMap(Map<String, dynamic> map) { static ReconciliationResultBean fromMap(Map<String, dynamic> map) {
if (map == null) return null;
ReconciliationResultBean reconciliationResultBean = ReconciliationResultBean(); ReconciliationResultBean reconciliationResultBean = ReconciliationResultBean();
reconciliationResultBean.hostResultCode = map['hostResultCode']; reconciliationResultBean.hostResultCode = map['hostResultCode'];
reconciliationResultBean.hostResultDescription = map['hostResultDescription']; reconciliationResultBean.hostResultDescription = map['hostResultDescription'];
@ -72,13 +71,13 @@ class ReconciliationResultBean {
/// 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"}}] /// 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 { class TransactionsBean {
List<TransactionBean> transaction; List<TransactionBean>? transaction;
static TransactionsBean fromMap(Map<String, dynamic> map) { static TransactionsBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
TransactionsBean transactionsBean = TransactionsBean(); TransactionsBean transactionsBean = TransactionsBean();
transactionsBean.transaction = List()..addAll( transactionsBean.transaction = List.empty()..addAll(
(map['transaction'] as List ?? []).map((o) => TransactionBean.fromMap(o)) (map['transaction'] as List).map((o) => TransactionBean.fromMap(o))
); );
return transactionsBean; return transactionsBean;
} }
@ -97,20 +96,19 @@ class TransactionsBean {
/// instrumentSpecificData : {"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"} /// instrumentSpecificData : {"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}
class TransactionBean { class TransactionBean {
String type; String? type;
String instrument; String? instrument;
num amount; num amount = 0;
int terminalId; int? terminalId;
int operationDay; int? operationDay;
int transactionNumber; int? transactionNumber;
InstrumentSpecificDataBean instrumentSpecificData; InstrumentSpecificDataBean? instrumentSpecificData;
static TransactionBean fromMap(Map<String, dynamic> map) { static TransactionBean fromMap(Map<String, dynamic> map) {
if (map == null) return null;
TransactionBean transactionBean = TransactionBean(); TransactionBean transactionBean = TransactionBean();
transactionBean.type = map['type']; transactionBean.type = map['type'];
transactionBean.instrument = map['instrument']; transactionBean.instrument = map['instrument'];
transactionBean.amount = map['amount']; transactionBean.amount = map['amount'] ?? 0;
transactionBean.terminalId = map['terminalId']; transactionBean.terminalId = map['terminalId'];
transactionBean.operationDay = map['operationDay']; transactionBean.operationDay = map['operationDay'];
transactionBean.transactionNumber = map['transactionNumber']; transactionBean.transactionNumber = map['transactionNumber'];
@ -135,12 +133,12 @@ class TransactionBean {
/// maskedPan : "123456******7890" /// maskedPan : "123456******7890"
class InstrumentSpecificDataBean { class InstrumentSpecificDataBean {
String authorizationCode; String? authorizationCode;
String rrn; String? rrn;
String cardholderName; String? cardholderName;
String maskedPan; String? maskedPan;
static InstrumentSpecificDataBean fromMap(Map<String, dynamic> map) { static InstrumentSpecificDataBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
InstrumentSpecificDataBean instrumentSpecificDataBean = InstrumentSpecificDataBean(); InstrumentSpecificDataBean instrumentSpecificDataBean = InstrumentSpecificDataBean();
instrumentSpecificDataBean.authorizationCode = map['authorizationCode']; instrumentSpecificDataBean.authorizationCode = map['authorizationCode'];
@ -162,12 +160,12 @@ class InstrumentSpecificDataBean {
/// description : "Successfully completed" /// description : "Successfully completed"
class ResultBean { class ResultBean {
int code; int? code;
String description; String? description;
ResultBean({this.code, this.description}); ResultBean({this.code, this.description});
static ResultBean fromMap(Map<String, dynamic> map) { static ResultBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
ResultBean resultBean = ResultBean(); ResultBean resultBean = ResultBean();
resultBean.code = map['code']; resultBean.code = map['code'];

View File

@ -8,11 +8,11 @@ class HalykPosSession {
this.tokenTimeout, this.tokenTimeout,
this.result}); this.result});
final String login; final String? login;
final String token; final String? token;
final DateTime serverTime; final DateTime? serverTime;
final int tokenTimeout; final int? tokenTimeout;
final ResultBean result; final ResultBean? result;
static HalykPosSession fromJson(Map<String, dynamic> data) => HalykPosSession( static HalykPosSession fromJson(Map<String, dynamic> data) => HalykPosSession(
login: data['login'], login: data['login'],
@ -30,12 +30,12 @@ class HalykPosSession {
/// Response : {"Code":"040","Description":"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 { class ResultBean {
String ServerTime; String? ServerTime;
String ResultCode; String? ResultCode;
String ResultStr; String? ResultStr;
ResponseBean Response; ResponseBean? Response;
static ResultBean fromMap(Map<String, dynamic> map) { static ResultBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
ResultBean resultBean = ResultBean(); ResultBean resultBean = ResultBean();
resultBean.ServerTime = map['ServerTime']; resultBean.ServerTime = map['ServerTime'];
@ -57,10 +57,10 @@ class ResultBean {
/// Description : "Unknown operator login. Check the correctness of the data or contact support." /// Description : "Unknown operator login. Check the correctness of the data or contact support."
class ResponseBean { class ResponseBean {
String Code; String? Code;
String Description; String? Description;
static ResponseBean fromMap(Map<String, dynamic> map) { static ResponseBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
ResponseBean responseBean = ResponseBean(); ResponseBean responseBean = ResponseBean();
responseBean.Code = map['Code']; responseBean.Code = map['Code'];

View File

@ -2,12 +2,12 @@
/// transaction : {"terminalId":"123321","operationDay":"4","transactionNumber":"69","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}} /// transaction : {"terminalId":"123321","operationDay":"4","transactionNumber":"69","instrumentSpecificData":{"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}}
class HalykResponse { class HalykResponse {
ResultBean result; ResultBean? result;
TransactionBean transaction; TransactionBean? transaction;
HalykResponse({this.result, this.transaction}); HalykResponse({this.result, this.transaction});
static HalykResponse fromMap(Map<String, dynamic> map) { static HalykResponse? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
HalykResponse halykResponseBean = HalykResponse(); HalykResponse halykResponseBean = HalykResponse();
halykResponseBean.result = ResultBean.fromMap(map['result']); halykResponseBean.result = ResultBean.fromMap(map['result']);
@ -28,12 +28,12 @@ class HalykResponse {
/// instrumentSpecificData : {"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"} /// instrumentSpecificData : {"authorizationCode":"000000","rrn":"1234567890","cardholderName":"IVAN IVANOV","maskedPan":"123456******7890"}
class TransactionBean { class TransactionBean {
int terminalId; int? terminalId;
int operationDay; int? operationDay;
int transactionNumber; int? transactionNumber;
InstrumentSpecificDataBean instrumentSpecificData; InstrumentSpecificDataBean? instrumentSpecificData;
static TransactionBean fromMap(Map<String, dynamic> map) { static TransactionBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
TransactionBean transactionBean = TransactionBean(); TransactionBean transactionBean = TransactionBean();
transactionBean.terminalId = map['terminalId']; transactionBean.terminalId = map['terminalId'];
@ -58,12 +58,12 @@ class TransactionBean {
/// maskedPan : "123456******7890" /// maskedPan : "123456******7890"
class InstrumentSpecificDataBean { class InstrumentSpecificDataBean {
String authorizationCode; String? authorizationCode;
String rrn; String? rrn;
String cardholderName; String? cardholderName;
String maskedPan; String? maskedPan;
static InstrumentSpecificDataBean fromMap(Map<String, dynamic> map) { static InstrumentSpecificDataBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
InstrumentSpecificDataBean instrumentSpecificDataBean = InstrumentSpecificDataBean(); InstrumentSpecificDataBean instrumentSpecificDataBean = InstrumentSpecificDataBean();
instrumentSpecificDataBean.authorizationCode = map['authorizationCode']; instrumentSpecificDataBean.authorizationCode = map['authorizationCode'];
@ -87,14 +87,14 @@ class InstrumentSpecificDataBean {
/// hostResponse : {"code":"0","description":"Successfully completed"} /// hostResponse : {"code":"0","description":"Successfully completed"}
class ResultBean { class ResultBean {
int code; int? code;
String description; String? description;
HostResponseBean hostResponse; HostResponseBean? hostResponse;
ErrorResponseBean errorData; ErrorResponseBean? errorData;
ResultBean({this.code, this.description}); ResultBean({this.code, this.description});
static ResultBean fromMap(Map<String, dynamic> map) { static ResultBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
ResultBean resultBean = ResultBean(); ResultBean resultBean = ResultBean();
resultBean.code = map['code']; resultBean.code = map['code'];
@ -117,10 +117,10 @@ class ResultBean {
/// description : "Successfully completed" /// description : "Successfully completed"
class HostResponseBean { class HostResponseBean {
String code; String? code;
String description; String? description;
static HostResponseBean fromMap(Map<String, dynamic> map) { static HostResponseBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
HostResponseBean hostResponseBean = HostResponseBean(); HostResponseBean hostResponseBean = HostResponseBean();
hostResponseBean.code = map['code']; hostResponseBean.code = map['code'];
@ -136,10 +136,10 @@ class HostResponseBean {
} }
class ErrorResponseBean { class ErrorResponseBean {
int code; int? code;
String description; String? description;
static ErrorResponseBean fromMap(Map<String, dynamic> map) { static ErrorResponseBean? fromMap(Map<String, dynamic>? map) {
if (map == null) return null; if (map == null) return null;
ErrorResponseBean errorResponseBean = ErrorResponseBean(); ErrorResponseBean errorResponseBean = ErrorResponseBean();
errorResponseBean.code = map['code']; errorResponseBean.code = map['code'];

View File

@ -1,7 +1,7 @@
class Message { class Message {
final String message; final String message;
Message({this.message}); Message({required this.message});
static Message fromJson(Map<String, dynamic> data) => Message(message : data['message']); static Message fromJson(Map<String, dynamic> data) => Message(message : data['message']);

View File

@ -1,5 +1,5 @@
class Money { class Money {
final num total; final num? total;
final bool loading; final bool loading;
Money({this.total, this.loading}); Money({this.total, required this.loading});
} }

View File

@ -0,0 +1,53 @@
class NctProduct {
final int? id;
final String? nameRu;
final String? nameKk;
final String? gtin;
final String? ntinCode;
final bool? isSocial;
final int? status;
final bool? isMarkedEac;
final String? measure;
final bool? ntinIsDeactivated;
final String? ntinDeactivationReason;
final String? ntinDuplicateOfProduct;
NctProduct({
this.id,
this.nameRu,
this.nameKk,
this.gtin,
this.ntinCode,
this.isSocial,
this.status,
this.isMarkedEac,
this.measure,
this.ntinIsDeactivated,
this.ntinDeactivationReason,
this.ntinDuplicateOfProduct,
});
factory NctProduct.fromJson(Map<String, dynamic> json) {
return NctProduct(
id: json['id'] is int ? json['id'] as int : null,
nameRu: json['name_ru'] is String ? json['name_ru'] as String : null,
nameKk: json['name_kk'] is String ? json['name_kk'] as String : null,
gtin: json['gtin'] is String ? json['gtin'] as String : null,
ntinCode: json['ntin_code'] is String ? json['ntin_code'] as String : null,
isSocial: json['is_social'] is bool ? json['is_social'] as bool : null,
status: json['status'] is int ? json['status'] as int : null,
isMarkedEac: json['is_markedeac'] is bool ? json['is_markedeac'] as bool : null,
measure: _parseStringOrObject(json['measure']),
ntinIsDeactivated: json['ntin_isdeactivated'] is bool ? json['ntin_isdeactivated'] as bool : null,
ntinDeactivationReason: _parseStringOrObject(json['ntin_deactivationreason']),
ntinDuplicateOfProduct: _parseStringOrObject(json['ntin_duplicateofproduct']),
);
}
static String? _parseStringOrObject(dynamic value) {
if (value == null) return null;
if (value is String) return value;
if (value is Map) return value['name_ru']?.toString() ?? value['name']?.toString() ?? value.toString();
return value.toString();
}
}

View File

@ -6,11 +6,10 @@ class ProductDao {
final num price; final num price;
num count; num count;
num total; num total;
final Good good; final Good? good;
final Service service; final Service? service;
final String excise; final String? excise;
final String? ntin;
ProductDao( {this.name, this.price, this.count, this.total, this.good, this.service, this.excise });
ProductDao({required this.name, required this.price, required this.count, required this.total, this.good, this.service, this.excise, this.ntin});
} }

View File

@ -1,9 +1,9 @@
class Response<T> { class Response<T> {
final T body; final T? body;
final int status; final int status;
final bool operation; final bool operation;
Response({this.body, this.operation, this.status}); Response({this.body, required this.operation, required this.status});
factory Response.fromJson(Map<String, dynamic> data, Function parser) { factory Response.fromJson(Map<String, dynamic> data, Function parser) {
return Response( return Response(

View File

@ -1,6 +1,6 @@
class SettingModel { class SettingModel {
const SettingModel({this.name, this.type, this.address}); const SettingModel({this.name, this.type, this.address});
final String type; final String? type;
final String name; final String? name;
final String address; final String? address;
} }

View File

@ -1,8 +1,8 @@
class Smena { class Smena {
final int id; final int? id;
final DateTime startedAt; final DateTime? startedAt;
final DateTime endedAt; final DateTime? endedAt;
final String message; final String? message;
Smena({this.id, this.startedAt, this.endedAt, this.message}); Smena({this.id, this.startedAt, this.endedAt, this.message});

View File

@ -1,10 +1,10 @@
class TransactionItem { class TransactionItem {
final String cardType; final String? cardType;
final String cardExpireDate; final String? cardExpireDate;
final String cardNumber; final String? cardNumber;
final String transactionType; final String? transactionType;
final num amount; final num? amount;
final DateTime date; final DateTime? date;
TransactionItem({this.cardType, this.cardExpireDate, this.cardNumber, this.transactionType, this.amount, this.date}); TransactionItem({this.cardType, this.cardExpireDate, this.cardNumber, this.transactionType, this.amount, this.date});
static TransactionItem fromJson(Map<String, dynamic> json) { static TransactionItem fromJson(Map<String, dynamic> json) {

View File

@ -1,23 +1,23 @@
class User { class User {
final String name; final String? name;
final String email; final String? email;
final String fullName; final String? fullName;
final String token; final String? token;
int appCompanyId; int? appCompanyId;
int kassaId; int? kassaId;
User({this.email, this.fullName, this.name, this.token, this.appCompanyId, this.kassaId}); User({this.email, this.fullName, this.name, this.token, this.appCompanyId, this.kassaId});
static User fromJson(Map<String, dynamic> json) { static User? fromJson(Map<String, dynamic> json) {
return json != null return json != null
? User ( ? User (
name: json['name'], name: json['name'],
email: json['mail'], email: json['mail'],
token: json['api_token'], token: json['api_token'],
fullName: json['fullname'], fullName: json['fullname'],
appCompanyId: json['app_company_id'] as int, appCompanyId: json['app_company_id'] ,
kassaId: json['kassa_id'] as int, kassaId: json['kassa_id'] ,
) )
: null; : null;
} }

View File

@ -10,6 +10,7 @@ const String SettingsViewRoute = "SettingsViewRoute";
const String QrViewRoute = "QrViewRoute"; const String QrViewRoute = "QrViewRoute";
const String BankViewRoute = "BankViewRoute"; const String BankViewRoute = "BankViewRoute";
const String BankSettingViewRoute = "BankSettingViewRoute"; const String BankSettingViewRoute = "BankSettingViewRoute";
const String ForteSettingViewRoute = "ForteSettingViewRoute";
const String SettingsPrinterRoute = "SettingsPrinterRoute"; const String SettingsPrinterRoute = "SettingsPrinterRoute";

View File

@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:aman_kassa_flutter/core/models/close_day_data.dart'; import 'package:aman_kassa_flutter/core/models/halyk/close_day_data.dart' as halyk;
import 'package:aman_kassa_flutter/core/models/forte/close_day_data.dart' as forte;
import 'package:aman_kassa_flutter/views/bank_setting/bank_setting_view.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/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';
@ -16,7 +17,10 @@ import 'package:aman_kassa_flutter/views/settings/printer/views/PrinterEncoding.
import 'package:aman_kassa_flutter/views/settings/printer/views/PrinterPaperSize.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/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 '../redux/state/bank_state.dart';
import '../redux/store.dart';
import './route_names.dart'; import './route_names.dart';
import 'package:aman_kassa_flutter/views/bank_setting/forte_setting_view.dart';
Route<dynamic> generateRoute(RouteSettings settings) { Route<dynamic> generateRoute(RouteSettings settings) {
@ -24,92 +28,116 @@ Route<dynamic> generateRoute(RouteSettings settings) {
case LoginViewRoute: case LoginViewRoute:
LoginModel model = settings.arguments as LoginModel; LoginModel model = settings.arguments as LoginModel;
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: LoginView( viewToShow: LoginView(loginModel: model,),
loginModel: model,
),
); );
case HomeViewRoute: case HomeViewRoute:
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: HomeView(), viewToShow: HomeView(),
); );
case PaymentViewRoute: case PaymentViewRoute:
PaymentModel model = settings.arguments as PaymentModel; PaymentModel model = settings.arguments as PaymentModel;
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: PaymentView(model: model), viewToShow: PaymentView(model: model),
); );
case PaymentNfcViewRoute: case PaymentNfcViewRoute:
PaymentModel model = settings.arguments as PaymentModel; PaymentModel model = settings.arguments as PaymentModel;
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: PaymentNfcView(model: model), viewToShow: PaymentNfcView(model: model),
); );
case HistoryViewRoute: case HistoryViewRoute:
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: HistoryView(), viewToShow: HistoryView(),
); );
case InfoKkmViewRoute: case InfoKkmViewRoute:
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: InfoKkmView(), viewToShow: InfoKkmView(),
); );
case SettingsViewRoute: case SettingsViewRoute:
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: SettingView(), viewToShow: SettingView(),
); );
case BankViewRoute: case BankViewRoute:
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: BankView(), viewToShow: BankView(),
); );
case BankSettingViewRoute: case BankSettingViewRoute:
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: BankSettingView(), viewToShow: BankSettingView(),
); );
case ForteSettingViewRoute:
return _getPageRoute(
routeName: settings.name!,
viewToShow: ForteSettingView(),
);
case QrViewRoute: case QrViewRoute:
ImageShowModel data = settings.arguments as ImageShowModel; ImageShowModel data = settings.arguments as ImageShowModel;
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: QrView(data), viewToShow: QrView(data),
); );
case ImageShowRoute: case ImageShowRoute:
ImageShowModel data = settings.arguments as ImageShowModel; ImageShowModel data = settings.arguments as ImageShowModel;
//return SlideRightRoute(widget: ImageShowContainer(data)); //return SlideRightRoute(widget: ImageShowContainer(data));
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: ImageShowContainer(data), viewToShow: ImageShowContainer(data),
); );
case SettingsPrinterRoute: case SettingsPrinterRoute:
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: SettingPrinterView(), viewToShow: SettingPrinterView(),
); );
case SettingsPrinterBTRoute: case SettingsPrinterBTRoute:
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: PrinterSelectView(), viewToShow: PrinterSelectView(),
); );
case SettingsPrinterEncodingRoute: case SettingsPrinterEncodingRoute:
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: PrinterEncodingView(), viewToShow: PrinterEncodingView(),
); );
case SettingsPrinterPaperRoute: case SettingsPrinterPaperRoute:
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: PrinterPaperView(), viewToShow: PrinterPaperView(),
); );
case CloseDayShowRoute: case CloseDayShowRoute:
CloseDayData data = settings.arguments as CloseDayData; var data = settings.arguments;
if (data is halyk.CloseDayData) {
return _getPageRoute( return _getPageRoute(
routeName: settings.name, routeName: settings.name!,
viewToShow: CloseDayShowContainer(data), viewToShow: CloseDayShowContainer(data),
); );
} else if (data is forte.CloseDayData) {
return _getPageRoute(
routeName: settings.name!,
viewToShow: CloseDayShowContainer(data),
);
} else {
return _getPageRoute(
routeName: settings.name!,
viewToShow: Scaffold(
appBar: AppBar(
title: Text('Информация недоступна'),
),
body: Center(
child: Text('Данные не могут быть отображены. Пожалуйста, попробуйте позже.'),
),
),
);
}
default: default:
return MaterialPageRoute( return MaterialPageRoute(
builder: (_) => Scaffold( builder: (_) => Scaffold(
@ -119,7 +147,7 @@ Route<dynamic> generateRoute(RouteSettings settings) {
} }
} }
PageRoute _getPageRoute({String routeName, Widget viewToShow}) { PageRoute _getPageRoute({required String routeName, required Widget viewToShow}) {
return MaterialPageRoute( return MaterialPageRoute(
settings: RouteSettings( settings: RouteSettings(
name: routeName, name: routeName,
@ -129,7 +157,7 @@ PageRoute _getPageRoute({String routeName, Widget viewToShow}) {
class SlideRightRoute extends PageRouteBuilder { class SlideRightRoute extends PageRouteBuilder {
final Widget widget; final Widget widget;
SlideRightRoute({this.widget}) SlideRightRoute({required this.widget})
: super( : super(
pageBuilder: (BuildContext context, Animation<double> animation, pageBuilder: (BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) { Animation<double> secondaryAnimation) {

View File

@ -3,11 +3,12 @@ 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/core/models/halyk/halyk_post_session.dart';
import 'package:aman_kassa_flutter/core/models/forte/forte_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:crypto/crypto.dart';
import 'package:device_info/device_info.dart'; import 'package:device_info_plus/device_info_plus.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';
import 'package:aman_kassa_flutter/core/models/smena.dart'; import 'package:aman_kassa_flutter/core/models/smena.dart';
@ -43,7 +44,7 @@ class ApiService extends BaseService {
}; };
String response = await requestFormData('/authenticate', requestBody, statusCheck: statusCheck ); String response = await requestFormData('/authenticate', requestBody, statusCheck: statusCheck );
AuthResponse aman = AuthResponse.fromJson(json.decode(response)); AuthResponse aman = AuthResponse.fromJson(json.decode(response));
return aman.body; return aman.body!;
} }
Future<AuthBody> authenticateToken(String token, { bool statusCheck = true}) async { Future<AuthBody> authenticateToken(String token, { bool statusCheck = true}) async {
@ -52,7 +53,7 @@ class ApiService extends BaseService {
}; };
String response = await requestFormData('/activate_token', requestBody, statusCheck: statusCheck ); String response = await requestFormData('/activate_token', requestBody, statusCheck: statusCheck );
AuthResponse aman = AuthResponse.fromJson(json.decode(response)); AuthResponse aman = AuthResponse.fromJson(json.decode(response));
return aman.body; return aman.body!;
} }
Future<Response<Message>> isActive(String token) async { Future<Response<Message>> isActive(String token) async {
@ -73,12 +74,25 @@ class ApiService extends BaseService {
print(hash); print(hash);
Map<String, String> requestBody = <String, String>{'login': login, 'hash': hash}; Map<String, String> requestBody = <String, String>{'login': login, 'hash': hash};
//var response = await requestFormData('/halykpos/gettoken', requestBody, bodyEntry: true, posEndPoint: true, statusCheck: false); String pointUrl = test ? '/hb/pos/gettoken' : '/halykpos/gettoken';
var response = await requestFormData('/hb/pos/gettoken', requestBody, bodyEntry: true, posEndPoint: true, statusCheck: false); var response = await requestFormData(pointUrl, requestBody, bodyEntry: true, posEndPoint: true, statusCheck: false);
print(response); print(response);
return HalykPosSession.fromJson(jsonDecode(response)); return HalykPosSession.fromJson(jsonDecode(response));
} }
Future<FortePosSession> fortePosToken(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};
// String pointUrl = '/fortepos/test/gettoken';
String pointUrl = '/fortepos/prod/gettoken';
var response = await requestFormData(pointUrl, requestBody, bodyEntry: true, posEndPoint: true, statusCheck: false);
print(response);
return FortePosSession.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);
@ -133,14 +147,17 @@ class ApiService extends BaseService {
return Response.fromJsonDynamic(json.decode(response)); return Response.fromJsonDynamic(json.decode(response));
} }
Future<Response<dynamic>> sellReturn(String token, String checkData) async { Future<Response<dynamic>> sellReturn(String token, String checkData, {String? ticketNumber}) async {
Map<String, String> requestBody = <String, String>{'api_token': token, 'data': checkData}; Map<String, String> requestBody = <String, String>{'api_token': token, 'data': checkData};
if (ticketNumber != null && ticketNumber.isNotEmpty) {
requestBody['ticketNumber'] = ticketNumber;
}
var response = await requestFormData('/sell_return', requestBody); var response = await requestFormData('/sell_return', requestBody);
return Response.fromJsonDynamic(json.decode(response)); return Response.fromJsonDynamic(json.decode(response));
} }
Future<String> requestFormData(String point, Map<String, dynamic> requestBody, { bool statusCheck = true, bool bodyEntry = false, bool posEndPoint= false } ) async { Future<String> requestFormData(String point, Map<String, String> requestBody, { bool statusCheck = true, bool bodyEntry = false, bool posEndPoint= false } ) async {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
@ -178,6 +195,10 @@ class ApiService extends BaseService {
String body; String body;
// log.i(uri);
// log.i(jsonEncode(headers));
// log.i(jsonEncode(requestBody));
if(bodyEntry) { if(bodyEntry) {
http.Response res = await http.post(uri, body: jsonEncode(requestBody), headers: headers ); http.Response res = await http.post(uri, body: jsonEncode(requestBody), headers: headers );
body = res.body; body = res.body;
@ -197,7 +218,7 @@ class ApiService extends BaseService {
new Future.delayed(const Duration(milliseconds: 1000), (){ new Future.delayed(const Duration(milliseconds: 1000), (){
_dialogService.showDialog(description: 'Необходимо пройти повторную авторизацию'); _dialogService.showDialog(description: 'Необходимо пройти повторную авторизацию');
UserState state = Redux.store.state.userState; UserState state = Redux.store!.state.userState!;
_navigatorService.replace(LoginViewRoute, arguments: LoginModel(authType: state.authenticateType, login: state.login, password: state.password )); _navigatorService.replace(LoginViewRoute, arguments: LoginModel(authType: state.authenticateType, login: state.login, password: state.password ));
}); });

View File

@ -1,7 +1,7 @@
import 'dart:convert'; import 'dart:convert';
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/locator.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/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_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_post_session.dart' as Ps;
import 'package:aman_kassa_flutter/core/models/halyk/halyk_response_dao.dart'; import 'package:aman_kassa_flutter/core/models/halyk/halyk_response_dao.dart';
@ -15,6 +15,7 @@ import '../models/aman_dao.dart';
class BankService extends BaseService { class BankService extends BaseService {
int sdkVersion = 27; int sdkVersion = 27;
String packageName = 'ru.m4bank.softpos.halyk';
final ApiService _api = locator<ApiService>(); final ApiService _api = locator<ApiService>();
final MethodChannel _channel = MethodChannel('channel:com.amanKassa/bank'); final MethodChannel _channel = MethodChannel('channel:com.amanKassa/bank');
@ -28,11 +29,11 @@ class BankService extends BaseService {
result = '0'; result = '0';
} }
log.i(result); log.i(result);
return int.parse(result) ?? 0; return int.parse(result);
} }
Future<Ps.HalykPosSession> renewToken({String token, String login, String password}) async { Future<Ps.HalykPosSession?> renewToken({required String token, required String login, required String password}) async {
Ps.HalykPosSession result; Ps.HalykPosSession? result;
try { try {
result = await _api.halykPosToken(token, login, password); result = await _api.halykPosToken(token, login, password);
} catch (e, stack) { } catch (e, stack) {
@ -43,11 +44,14 @@ class BankService extends BaseService {
Future<Cd.HalykCloseDayDao> closeDay({ String token}) async { Future<Cd.HalykCloseDayDao?> closeDay({ required String token}) async {
try { try {
String response = await _channel.invokeMethod("closeDay", <String, dynamic>{'token': token }); String response = await _channel.invokeMethod("closeDay", <String, dynamic>{
'token': token,
'packageName': packageName
});
log.i(response); log.i(response);
Cd.HalykCloseDayDao dao = Cd.HalykCloseDayDao.fromMap(json.decode(response)); Cd.HalykCloseDayDao dao = Cd.HalykCloseDayDao.fromMap(json.decode(response))!;
return dao; return dao;
} catch (e, stack) { } catch (e, stack) {
log.e("BankService", e, stack); log.e("BankService", e, stack);
@ -55,14 +59,18 @@ class BankService extends BaseService {
} }
} }
Future<HalykResponse> pay({double amount, String token}) async { Future<HalykResponse> pay({required double amount, required String token}) async {
try { try {
double total = amount * 100; double total = amount * 100;
log.i('total: $total, ${total.toInt()}'); log.i('total: $total, ${total.toInt()}');
String response = await _channel.invokeMethod("pay", <String, dynamic>{'amount': total.toInt(), 'token': token }); String response = await _channel.invokeMethod("pay", <String, dynamic>{
'amount': total.toInt(),
'token': token,
'packageName': packageName
});
log.i(response); log.i(response);
HalykResponse dao = HalykResponse.fromMap(json.decode(response)); HalykResponse dao = HalykResponse.fromMap(json.decode(response))!;
return dao; return dao;
} catch (e, stack) { } catch (e, stack) {
log.e("BankService", e, stack); log.e("BankService", e, stack);
@ -70,12 +78,17 @@ class BankService extends BaseService {
} }
} }
Future<HalykResponse> refund({double amount, String token, int terminalId, int operDay, int transNum }) async { Future<HalykResponse> refund({required double amount, required String token, required int terminalId, required int operDay, required int transNum }) async {
try { try {
String response = await _channel.invokeMethod("refund", <String, dynamic>{ String response = await _channel.invokeMethod("refund", <String, dynamic>{
'amount': amount.toInt(), 'token': token , 'terminalId': terminalId, 'operDay': operDay, 'transNum': transNum 'amount': amount.toInt(),
'token': token,
'terminalId': terminalId,
'operDay': operDay,
'transNum': transNum,
'packageName': packageName
}); });
HalykResponse dao = HalykResponse.fromMap(json.decode(response)); HalykResponse dao = HalykResponse.fromMap(json.decode(response))!;
return dao; return dao;
} catch (e, stack) { } catch (e, stack) {
log.e("BankService", e, stack); log.e("BankService", e, stack);
@ -83,13 +96,17 @@ class BankService extends BaseService {
} }
} }
Future<HalykResponse> reversal({ String token, int terminalId, int operDay, int transNum }) async { Future<HalykResponse> reversal({ required String token, required int terminalId, required int operDay, required int transNum }) async {
try { try {
String response = await _channel.invokeMethod("reversal", <String, dynamic>{ String response = await _channel.invokeMethod("reversal", <String, dynamic>{
'token': token , 'terminalId': terminalId, 'operDay': operDay, 'transNum': transNum 'token': token,
'terminalId': terminalId,
'operDay': operDay,
'transNum': transNum,
'packageName': packageName
}); });
log.i(response); log.i(response);
HalykResponse dao = HalykResponse.fromMap(json.decode(response)); HalykResponse dao = HalykResponse.fromMap(json.decode(response))!;
return dao; return dao;
} catch (e, stack) { } catch (e, stack) {
log.e("BankService", e, stack); log.e("BankService", e, stack);
@ -102,7 +119,7 @@ class BankService extends BaseService {
final DateFormat formatter = DateFormat('dd.MM.yyyy'); final DateFormat formatter = DateFormat('dd.MM.yyyy');
final DateTime now = DateTime.now(); final DateTime now = DateTime.now();
final String formatted = formatter.format(now); final String formatted = formatter.format(now);
List<Cd.TransactionBean> items = transactions.transaction; List<Cd.TransactionBean> items = transactions.transaction!;
num totalAmount = 0; num totalAmount = 0;
int totalCount = 0; int totalCount = 0;
num paymentAmount = 0; num paymentAmount = 0;

View File

@ -1,4 +1,5 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:ffi';
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/entity/Category.dart'; import 'package:aman_kassa_flutter/core/entity/Category.dart';
@ -26,7 +27,8 @@ class DataService extends BaseService {
final ApiService _api = locator<ApiService>(); final ApiService _api = locator<ApiService>();
final DbService _db = locator<DbService>(); final DbService _db = locator<DbService>();
Future<List<Category>> getCategoriesByParentId({int parentId}) async { Future<List<Category>> getCategoriesByParentId(
{int? parentId}) async {
List<Map<String, dynamic>> list = await _db.queryRowsWithWhere( List<Map<String, dynamic>> list = await _db.queryRowsWithWhere(
Category_tableName, '$Category_columnParentIn = ?', [parentId ?? 0]); Category_tableName, '$Category_columnParentIn = ?', [parentId ?? 0]);
return list.map((e) => Category.fromMap(e)).toList(); return list.map((e) => Category.fromMap(e)).toList();
@ -37,35 +39,39 @@ class DataService extends BaseService {
return list.map((e) => Service.fromMap(e)).toList(); return list.map((e) => Service.fromMap(e)).toList();
} }
Future<List<Good>> getGoodsByCategoryId({int categoryId}) async { Future<List<Good>> getGoodsByCategoryId({int? categoryId}) async {
List<Map<String, dynamic>> list = await _db.queryRowsWithWhere( List<Map<String, dynamic>> list = await _db.queryRowsWithWhere(
Goog_tableName, '$Goog_columnCategoryId = ?', [categoryId ?? 0]); Goog_tableName, '$Goog_columnCategoryId = ?', [categoryId ?? 0]);
return list.map((e) => Good.fromMap(e)).toList(); return list.map((e) => Good.fromMap(e)).toList();
} }
Future<List<Good>> getGoodsByBarcode ({ String barcode}) async { Future<List<Good>> getGoodsByBarcode({required String barcode}) async {
List<Map<String, dynamic>> list = await _db.queryRowsWithWhere(Goog_tableName, ' $Goog_columnEan = ?', [barcode]); List<Map<String, dynamic>> list = await _db
.queryRowsWithWhere(Goog_tableName, ' $Goog_columnEan = ?', [barcode]);
return list.map((e) => Good.fromMap(e)).toList(); return list.map((e) => Good.fromMap(e)).toList();
} }
CheckData _transformProductsToCheckData( CheckData _transformProductsToCheckData(
{String paymentType, String tradeType, List<ProductDao> items}) { {String? paymentType,
String? tradeType,
required List<ProductDao> items}) {
List<CheckItem> itemsList = []; List<CheckItem> itemsList = [];
int iterator = 1; int iterator = 1;
num summ = 0.0; num summ = 0.0;
items.forEach((el) { items.forEach((el) {
int articul = iterator; int articul = iterator;
if (el.service != null) { if (el.service != null) {
articul = el.service.articul; articul = el.service!.articul;
} else if (el.good != null) { } else if (el.good != null) {
articul = el.good.articul; articul = el.good!.articul;
} }
itemsList.add(CheckItem( itemsList.add(CheckItem(
name: el.name ?? 'Позиция №$iterator', name: el.name,
cnt: el.count, cnt: el.count,
price: el.price, price: el.price,
articul: articul, articul: articul,
excise: el.excise, excise: el.excise,
ntin: el.ntin,
)); ));
summ += el.total; summ += el.total;
iterator++; iterator++;
@ -73,12 +79,16 @@ class DataService extends BaseService {
CheckData checkData = CheckData(type: tradeType, items: itemsList); CheckData checkData = CheckData(type: tradeType, items: itemsList);
if ((paymentType ?? 'cash') == 'card') { if ((paymentType ?? 'cash') == 'card') {
checkData.card = summ; checkData.card = summ;
} else if ((paymentType ?? 'cash') == 'mobile') {
checkData.mobile = summ;
} }
return checkData; return checkData;
} }
CheckData _transformCalcModelToCheckData( CheckData _transformCalcModelToCheckData(
{String paymentType, String tradeType, List<CalcModel> items}) { {String? paymentType,
String? tradeType,
required List<CalcModel> items}) {
List<CheckItem> itemsList = []; List<CheckItem> itemsList = [];
int iterator = 1; int iterator = 1;
num summ = 0.0; num summ = 0.0;
@ -86,7 +96,7 @@ class DataService extends BaseService {
int articul = iterator; int articul = iterator;
CheckItem item = CheckItem( CheckItem item = CheckItem(
name: 'Позиция $iterator', name: 'Позиция $iterator',
cnt: el.num2 != null ? double.parse(el.num2) : 1.0, cnt: el.num2 != null ? double.parse(el.num2!) : 1.0,
price: double.parse(el.num1), price: double.parse(el.num1),
articul: articul); articul: articul);
@ -97,6 +107,8 @@ class DataService extends BaseService {
CheckData checkData = CheckData(type: tradeType, items: itemsList); CheckData checkData = CheckData(type: tradeType, items: itemsList);
if ((paymentType ?? 'cash') == 'card') { if ((paymentType ?? 'cash') == 'card') {
checkData.card = summ; checkData.card = summ;
} else if ((paymentType ?? 'cash') == 'mobile') {
checkData.mobile = summ;
} }
return checkData; return checkData;
} }
@ -112,13 +124,13 @@ class DataService extends BaseService {
* type * type
*/ */
Future<void> insertVoucher( Future<void> insertVoucher(
{@required User user, {required User user,
String data, String? data,
String base64Data, String? base64Data,
@required String name, required String name,
double total = 0.0, double total = 0.0,
String type = VoucherTypePayment, String type = VoucherTypePayment,
String url}) { String? url}) async {
assert(user != null); assert(user != null);
assert(name != null); assert(name != null);
Voucher voucher = Voucher() Voucher voucher = Voucher()
@ -134,14 +146,13 @@ class DataService extends BaseService {
log.i( log.i(
'save to db appCompanyId: ${user.appCompanyId}, kassaId: ${user.kassaId}'); 'save to db appCompanyId: ${user.appCompanyId}, kassaId: ${user.kassaId}');
_db.insert(Voucher_tableName, voucher.toMap()); _db.insert(Voucher_tableName, voucher.toMap());
return null;
} }
Future<Response<dynamic>> refundM4Bank( Future<Response<dynamic>?> refundM4Bank(
{ {
String token, required String token,
CheckData checkData, required CheckData checkData,
CardData cardData}) async { required CardData cardData}) async {
try { try {
var json = cardData.toJson(); var json = cardData.toJson();
json['transactionType'] = VoucherTypeReturnPay; json['transactionType'] = VoucherTypeReturnPay;
@ -154,10 +165,10 @@ class DataService extends BaseService {
log.i('response status: ${response.status}'); log.i('response status: ${response.status}');
log.i('response operation: ${response.operation}'); 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'];
dynamic journal = response?.body['journal']; dynamic journal = response.body['journal'];
String url = response?.body['link']; String url = response.body['link'];
int checkNum = journal['check_num']; int checkNum = journal['check_num'];
var summ = journal['summ']; var summ = journal['summ'];
double total = summ != null ? double.parse(summ.toString()) : 0.0; double total = summ != null ? double.parse(summ.toString()) : 0.0;
@ -177,26 +188,30 @@ class DataService extends BaseService {
return null; return null;
} }
Future<Response<dynamic>> sellOrReturn( Future<Response<dynamic>?> sellOrReturn(
{String paymentType, {String? paymentType,
String tradeType, String? tradeType,
String token, String? contragent,
List<ProductDao> kassaItems, String? ticketNumber,
List<CalcModel> calcItems, required String token,
String operationType, required List<ProductDao> kassaItems,
String mode, required List<CalcModel> calcItems,
CardData cardData}) async { required String operationType,
required String mode,
required CardData? cardData}) async {
try { try {
String data; String data = "";
if (mode == SettingModeKassa) { if (mode == SettingModeKassa) {
CheckData checkData = _transformProductsToCheckData( CheckData checkData = _transformProductsToCheckData(
paymentType: paymentType, tradeType: tradeType, items: kassaItems); paymentType: paymentType, tradeType: tradeType, items: kassaItems);
checkData.cardData = cardData; checkData.cardData = cardData;
checkData.contragent = contragent;
data = jsonEncode(checkData.toJson()); data = jsonEncode(checkData.toJson());
} else if (mode == SettingModeCalc) { } else if (mode == SettingModeCalc) {
CheckData checkData = _transformCalcModelToCheckData( CheckData checkData = _transformCalcModelToCheckData(
paymentType: paymentType, tradeType: tradeType, items: calcItems); paymentType: paymentType, tradeType: tradeType, items: calcItems);
checkData.cardData = cardData; checkData.cardData = cardData;
checkData.contragent = contragent;
data = jsonEncode(checkData.toJson()); data = jsonEncode(checkData.toJson());
} }
@ -204,22 +219,24 @@ class DataService extends BaseService {
// log.i('data: $data'); // log.i('data: $data');
Response<dynamic> response = await (operationType == OperationTypePay Response<dynamic> response = await (operationType == OperationTypePay
? _api.sell(token, data) ? _api.sell(token, data)
: _api.sellReturn(token, data)); : _api.sellReturn(token, data, ticketNumber: ticketNumber));
// log.i('response status: ${response.status}'); // log.i('response status: ${response.status}');
// log.i('response operation: ${response.operation}'); // 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!;
//check compare //check compare
String check = response?.body['check']; String check = response.body['check'];
var checkText = response?.body['check_text']; var checkText = response.body['check_text'];
CheckImageModal imageModal = new CheckImageModal( base64Data: check, textData: checkText !=null ? jsonEncode(checkText) : null ); CheckImageModal imageModal = new CheckImageModal(
base64Data: check,
textData: checkText != null ? jsonEncode(checkText) : null);
// journal analyze // journal analyze
dynamic journal = response?.body['journal']; dynamic journal = response.body['journal'];
int checkNum = journal['check_num']; int checkNum = journal['check_num'];
var summ = journal['summ']; var summ = journal['summ'];
// short url // short url
String url = response?.body['link']; String url = response.body['link'];
// total // total
double total = summ != null ? double.parse(summ.toString()) : 0.0; double total = summ != null ? double.parse(summ.toString()) : 0.0;
@ -243,9 +260,9 @@ class DataService extends BaseService {
} }
Future<void> checkDbFill(User user) async { Future<void> checkDbFill(User user) async {
int serviceCount = await _db.queryRowCount(Service_tableName); int serviceCount = await _db.queryRowCount(Service_tableName) ?? 0;
if (serviceCount == 0) { if (serviceCount == 0) {
int goodCount = await _db.queryRowCount(Goog_tableName); int goodCount = await _db.queryRowCount(Goog_tableName) ?? 0;
if (goodCount == 0) { if (goodCount == 0) {
await getDataFromServer(user); await getDataFromServer(user);
} else { } else {
@ -259,9 +276,10 @@ class DataService extends BaseService {
Future<bool> getDataFromServer(User user) async { Future<bool> getDataFromServer(User user) async {
log.i('Get Data from server'); log.i('Get Data from server');
try { try {
String token = user.token; String token = user.token!;
Response<dynamic> goods = await _api.getGoodsFromServer(token); Response<dynamic> goods = await _api.getGoodsFromServer(token);
if(goods.operation==false && [401,402,403,412].contains(goods.status)){ if (goods.operation == false &&
[401, 402, 403, 412].contains(goods.status)) {
log.i('session is closed'); log.i('session is closed');
return false; return false;
} }
@ -272,7 +290,6 @@ class DataService extends BaseService {
await _db.deleteAll(Service_tableName); await _db.deleteAll(Service_tableName);
log.i('All tables cleaned'); log.i('All tables cleaned');
if (goods.body.isNotEmpty) { if (goods.body.isNotEmpty) {
for (var key in goods.body.keys) { for (var key in goods.body.keys) {
Good row = Good.fromJson(goods.body[key]); Good row = Good.fromJson(goods.body[key]);

View File

@ -19,13 +19,13 @@ class DbService extends BaseService {
static final DbService instance = DbService._privateConstructor(); static final DbService instance = DbService._privateConstructor();
// only have a single app-wide reference to the database // only have a single app-wide reference to the database
static Database _database; static Database? _database;
Future<Database> get database async { Future<Database> get database async {
if (_database != null) return _database; if (_database != null) return _database!;
// lazily instantiate the db the first time it is accessed // lazily instantiate the db the first time it is accessed
_database = await _initDatabase(); _database = await _initDatabase();
return _database; return _database!;
} }
// this opens the database (and creates it if it doesn't exist) // this opens the database (and creates it if it doesn't exist)
@ -136,7 +136,7 @@ class DbService extends BaseService {
// All of the methods (insert, query, update, delete) can also be done using // All of the methods (insert, query, update, delete) can also be done using
// raw SQL commands. This method uses a raw query to give the row count. // raw SQL commands. This method uses a raw query to give the row count.
Future<int> queryRowCount(String table) async { Future<int?> queryRowCount(String table) async {
Database db = await instance.database; Database db = await instance.database;
return Sqflite.firstIntValue( return Sqflite.firstIntValue(
await db.rawQuery('SELECT COUNT(*) FROM $table')); await db.rawQuery('SELECT COUNT(*) FROM $table'));

View File

@ -0,0 +1,161 @@
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/forte/close_day_data.dart';
import 'package:aman_kassa_flutter/core/models/forte/forte_close_day_dao.dart' as Cd;
import 'package:aman_kassa_flutter/core/models/forte/forte_post_session.dart' as Ps;
import 'package:aman_kassa_flutter/core/models/forte/forte_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 ForteService extends BaseService {
int sdkVersion = 27;
String packageName = 'kz.forte.pos';
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("ForteService", e, stack);
result = '0';
}
log.i(result);
return int.parse(result);
}
Future<Ps.FortePosSession?> renewToken({required String token, required String login, required String password}) async {
Ps.FortePosSession? result;
try {
result = await _api.fortePosToken(token, login, password);
} catch (e, stack) {
log.e("ForteService", e, stack);
}
return result;
}
Future<Cd.ForteCloseDayDao?> closeDay({ required String token}) async {
try {
String response = await _channel.invokeMethod("closeDay", <String, dynamic>{
'token': token,
'packageName': packageName
});
log.i(response);
Cd.ForteCloseDayDao dao = Cd.ForteCloseDayDao.fromMap(json.decode(response))!;
return dao;
} catch (e, stack) {
log.e("ForteService", e, stack);
return new Cd.ForteCloseDayDao(result: Cd.ResultBean(description: 'Ошибка при закрытии дня', code: -1));
}
}
Future<ForteResponse> pay({required double amount, required 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,
'packageName': packageName
});
log.i(response);
ForteResponse dao = ForteResponse.fromMap(json.decode(response))!;
return dao;
} catch (e, stack) {
log.e("ForteService", e, stack);
return new ForteResponse(result: ResultBean(description: 'Ошибка оплаты', code: -1));
}
}
Future<ForteResponse> refund({required double amount, required String token, required int terminalId, required int operDay, required int transNum }) async {
try {
double total = amount * 100;
String response = await _channel.invokeMethod("refund", <String, dynamic>{
'amount': total,
'token': token,
'terminalId': terminalId,
'operDay': operDay,
'transNum': transNum,
'packageName': packageName
});
ForteResponse dao = ForteResponse.fromMap(json.decode(response))!;
return dao;
} catch (e, stack) {
log.e("ForteService", e, stack);
return new ForteResponse(result: ResultBean(description: 'Ошибка при возврате', code: -1));
}
}
Future<ForteResponse> reversal({ required String token, required int terminalId, required int operDay, required int transNum }) async {
try {
String response = await _channel.invokeMethod("reversal", <String, dynamic>{
'token': token,
'terminalId': terminalId,
'operDay': operDay,
'transNum': transNum,
'packageName': packageName
});
log.i(response);
ForteResponse dao = ForteResponse.fromMap(json.decode(response))!;
return dao;
} catch (e, stack) {
log.e("ForteService", e, stack);
return new ForteResponse(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;
}
}

View File

@ -0,0 +1,75 @@
import 'dart:convert';
import 'dart:io';
import 'package:aman_kassa_flutter/core/base/base_service.dart';
import 'package:aman_kassa_flutter/core/models/nct_product.dart';
import 'package:http/http.dart' as http;
import 'package:http/io_client.dart';
class NctService extends BaseService {
static const String _baseUrl = 'https://nct.gov.kz/api/integration/ofd/search_ofd/';
Future<List<NctProduct>> searchByNtin(String ntin) async {
final uri = Uri.parse(_baseUrl).replace(queryParameters: {'tin': ntin});
log.i('NCT request: $uri');
http.Client client = _buildClient();
late http.Response response;
try {
response = await client.get(uri, headers: {'Accept': 'application/json'});
} on TlsException catch (e) {
log.e('NCT TLS error', e);
throw NctServiceException('Ошибка SSL при подключении к NCT: ${e.message}');
} on SocketException catch (e) {
log.e('NCT network error', e);
throw NctServiceException('Ошибка сети при подключении к NCT: ${e.message}');
} catch (e) {
log.e('NCT request error', e);
throw NctServiceException('Ошибка запроса к NCT: $e');
} finally {
client.close();
}
log.i('NCT status: ${response.statusCode}');
if (response.statusCode != 200) {
throw NctServiceException('NCT вернул статус ${response.statusCode}');
}
try {
final bodyString = utf8.decode(response.bodyBytes);
log.i('NCT body: ${bodyString.length > 300 ? bodyString.substring(0, 300) : bodyString}');
final decoded = json.decode(bodyString);
List<dynamic> list;
if (decoded is List) {
list = decoded;
} else if (decoded is Map && decoded.containsKey('results')) {
list = decoded['results'] as List<dynamic>;
} else {
log.w('NCT unexpected response format: ${decoded.runtimeType}');
return [];
}
return list
.map((e) => NctProduct.fromJson(e as Map<String, dynamic>))
.toList();
} catch (e) {
log.e('NCT JSON parse error', e);
throw NctServiceException('Ошибка разбора ответа NCT: $e');
}
}
http.Client _buildClient() {
final httpClient = HttpClient()
..badCertificateCallback = (cert, host, port) {
log.w('NCT bad certificate for $host:$port — subject: ${cert.subject}');
return host == 'nct.gov.kz';
};
return IOClient(httpClient);
}
}
class NctServiceException implements Exception {
final String message;
NctServiceException(this.message);
@override
String toString() => message;
}

View File

@ -10,18 +10,18 @@ import 'ApiService.dart';
class AuthenticationService extends BaseService { class AuthenticationService extends BaseService {
final ApiService _api; final ApiService _api;
AuthenticationService({ApiService api}) : _api = api; AuthenticationService({required ApiService api}) : _api = api;
User _currentUser; User? _currentUser;
User get currentUser => _currentUser; User? get currentUser => _currentUser;
Future<AuthBody> loginWithEmail({ Future<AuthBody?> loginWithEmail({
@required String email, required String email,
@required String password, required String password,
}) async { }) async {
try { try {
AuthBody result = await _api.authenticate(email, password); AuthBody? result = await _api.authenticate(email, password);
if (result.user != null) { if (result!=null && result.user != null) {
_currentUser = result.user; _currentUser = result.user;
} }
return result; return result;
@ -32,7 +32,7 @@ class AuthenticationService extends BaseService {
Future<bool> isUserLoggedIn(String token) async { Future<bool> isUserLoggedIn(String token) async {
Response<Message> session = await _api.isActive(token); Response<Message> session = await _api.isActive(token);
if ("OK" == session.body.message) { if ("OK" == session.body?.message) {
//_session = session; //_session = session;
return true; return true;
} }
@ -40,7 +40,7 @@ class AuthenticationService extends BaseService {
} }
Future<bool> logout(String token) async { Future<bool> logout(String token) async {
Response<Message> session = await _api.logout(token); Response<dynamic> session = await _api.logout(token);
if ("logout" == session.body.message) { if ("logout" == session.body.message) {
return true; return true;
} }

View File

@ -0,0 +1,30 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:aman_kassa_flutter/core/base/base_service.dart';
import 'package:aman_kassa_flutter/core/models/bluetooth_device.dart';
// Stub implementation bluetooth print disabled
class BluePrintService extends BaseService {
BluetoothDevice? _device;
Future<void> scan() async {}
Future<void> stopScan() async {}
Stream<List<BluetoothDevice>> get scanResult =>
Stream<List<BluetoothDevice>>.value([]);
Stream<bool> get isScanning => Stream<bool>.value(false);
Stream<int> get state => Stream<int>.value(0);
set device(BluetoothDevice device) => _device = device;
Future<bool> connect() async => false;
Future<bool> disconnect() async => true;
Future<bool> printBytes(Uint8List bytes,
{int chunkSizeBytes = 20, int queueSleepTimeMs = 20}) async => false;
}

View File

@ -5,11 +5,11 @@ import 'package:flutter/cupertino.dart';
class DialogService { class DialogService {
GlobalKey<NavigatorState> _dialogNavigationKey = GlobalKey<NavigatorState>(); GlobalKey<NavigatorState> _dialogNavigationKey = GlobalKey<NavigatorState>();
Function(DialogRequest) _showDialogListener; Function(DialogRequest)? _showDialogListener;
Function(DialogRequest) _showDialogInputListener; Function(DialogRequest)? _showDialogInputListener;
Completer<DialogResponse> _dialogCompleter; Completer<DialogResponse>? _dialogCompleter;
Completer<DialogResponse> get completer => this._dialogCompleter; Completer<DialogResponse>? get completer => this._dialogCompleter;
GlobalKey<NavigatorState> get dialogNavigationKey => _dialogNavigationKey; GlobalKey<NavigatorState> get dialogNavigationKey => _dialogNavigationKey;
@ -23,53 +23,53 @@ class DialogService {
/// Calls the dialog listener and returns a Future that will wait for dialogComplete. /// Calls the dialog listener and returns a Future that will wait for dialogComplete.
Future<DialogResponse> showDialog({ Future<DialogResponse> showDialog({
String title = 'Aman Касса', String title = 'Aman Касса',
String description, required String description,
String buttonTitle = 'Ok', String buttonTitle = 'Ok',
}) { }) {
_dialogCompleter = Completer<DialogResponse>(); _dialogCompleter = Completer<DialogResponse>();
_showDialogListener(DialogRequest( _showDialogListener!(DialogRequest(
title: title, title: title,
description: description, description: description,
buttonTitle: buttonTitle, buttonTitle: buttonTitle,
)); ));
return _dialogCompleter.future; return _dialogCompleter!.future;
} }
/// Shows a confirmation dialog /// Shows a confirmation dialog
Future<DialogResponse> showConfirmationDialog( Future<DialogResponse> showConfirmationDialog(
{String title, {required String title,
String description, required String description,
String confirmationTitle = 'Ok', String confirmationTitle = 'Ok',
String cancelTitle = 'Cancel'}) { String cancelTitle = 'Cancel'}) {
_dialogCompleter = Completer<DialogResponse>(); _dialogCompleter = Completer<DialogResponse>();
_showDialogListener(DialogRequest( _showDialogListener!(DialogRequest(
title: title, title: title,
description: description, description: description,
buttonTitle: confirmationTitle, buttonTitle: confirmationTitle,
cancelTitle: cancelTitle)); cancelTitle: cancelTitle));
return _dialogCompleter.future; return _dialogCompleter!.future;
} }
Future<DialogResponse> showConfirmationDialogInput( Future<DialogResponse> showConfirmationDialogInput(
{String title = ' Aman Касса', {String title = ' Aman Касса',
String description, required String description,
String confirmationTitle = 'Ok', String confirmationTitle = 'Ok',
String cancelTitle = 'Cancel', String cancelTitle = 'Cancel',
String formatType}) { String? formatType}) {
_dialogCompleter = Completer<DialogResponse>(); _dialogCompleter = Completer<DialogResponse>();
_showDialogInputListener(DialogRequest( _showDialogInputListener!(DialogRequest(
title: title, title: title,
description: description, description: description,
buttonTitle: confirmationTitle, buttonTitle: confirmationTitle,
cancelTitle: cancelTitle, cancelTitle: cancelTitle,
formatType: formatType)); formatType: formatType));
return _dialogCompleter.future; return _dialogCompleter!.future;
} }
/// Completes the _dialogCompleter to resume the Future's execution call /// Completes the _dialogCompleter to resume the Future's execution call
void dialogComplete(DialogResponse response) { void dialogComplete(DialogResponse response) {
_dialogNavigationKey.currentState.pop(); _dialogNavigationKey.currentState!.pop();
_dialogCompleter.complete(response); _dialogCompleter!.complete(response);
_dialogCompleter = null; _dialogCompleter = null;
} }
} }

View File

@ -6,27 +6,27 @@ class NavigatorService extends BaseService {
Future<dynamic> push(String routeName, {dynamic arguments}) { Future<dynamic> push(String routeName, {dynamic arguments}) {
log.i('routeName: $routeName'); log.i('routeName: $routeName');
return navigatorKey.currentState return navigatorKey.currentState!
.pushNamed(routeName, arguments: arguments); .pushNamed(routeName, arguments: arguments);
} }
Future<dynamic> replace(String routeName, {dynamic arguments}) { Future<dynamic> replace(String routeName, {dynamic arguments}) {
log.i('routeName: $routeName'); log.i('routeName: $routeName');
return navigatorKey.currentState return navigatorKey.currentState!
.pushNamedAndRemoveUntil(routeName, (Route<dynamic> route) => false, arguments: arguments); .pushNamedAndRemoveUntil(routeName, (Route<dynamic> route) => false, arguments: arguments);
} }
Future<T> navigateToPage<T>(MaterialPageRoute<T> pageRoute) async { Future<T?> navigateToPage<T>(MaterialPageRoute<T> pageRoute) async {
log.i('navigateToPage: pageRoute: ${pageRoute.settings.name}'); log.i('navigateToPage: pageRoute: ${pageRoute.settings.name}');
if (navigatorKey.currentState == null) { if (navigatorKey.currentState == null) {
log.e('navigateToPage: Navigator State is null'); log.e('navigateToPage: Navigator State is null');
return null; return null;
} }
return navigatorKey.currentState.push(pageRoute); return navigatorKey.currentState!.push(pageRoute);
} }
Future<T> navigateToPageWithReplacement<T>( Future<T?> navigateToPageWithReplacement<T>(
MaterialPageRoute<T> pageRoute) async { MaterialPageRoute<T> pageRoute) async {
log.i('navigateToPageWithReplacement: ' log.i('navigateToPageWithReplacement: '
'pageRoute: ${pageRoute.settings.name}'); 'pageRoute: ${pageRoute.settings.name}');
@ -34,15 +34,15 @@ class NavigatorService extends BaseService {
log.e('navigateToPageWithReplacement: Navigator State is null'); log.e('navigateToPageWithReplacement: Navigator State is null');
return null; return null;
} }
return navigatorKey.currentState.pushReplacement(pageRoute); return navigatorKey.currentState!.pushReplacement(pageRoute);
} }
void pop<T>([T result]) { void pop<T>([T? result]) {
log.i('goBack:'); log.i('goBack:');
if (navigatorKey.currentState == null) { if (navigatorKey.currentState == null) {
log.e('goBack: Navigator State is null'); log.e('goBack: Navigator State is null');
return; return;
} }
navigatorKey.currentState.pop(result); navigatorKey.currentState!.pop(result);
} }
} }

View File

@ -1,4 +1,4 @@
List<String> parseListString(json){ List<String>? parseListString(json){
if(json==null) return null; if(json==null) return null;
return new List<String>.from(json); return new List<String>.from(json);
} }

69
lib/firebase_options.dart Normal file
View File

@ -0,0 +1,69 @@
// File generated by FlutterFire CLI.
// ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for web - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for macos - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.windows:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for windows - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyAlAhTjrXj0s1Qep2_mP_u4QtMnltMi4RA',
appId: '1:1086013480150:android:d00d738289818373f17d77',
messagingSenderId: '1086013480150',
projectId: 'aman-f670e',
storageBucket: 'aman-f670e.appspot.com',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyApELiWrEflqtXPo8cndFnPW0sRVVHmkYQ',
appId: '1:1086013480150:ios:958c91234e46010cf17d77',
messagingSenderId: '1086013480150',
projectId: 'aman-f670e',
storageBucket: 'aman-f670e.appspot.com',
iosClientId: '1086013480150-93mcqf1l60dvmd2k1lkg2ikmvm3u29ca.apps.googleusercontent.com',
iosBundleId: 'com.kz.amankassaflutter',
);
}

View File

@ -1,14 +1,16 @@
//general //general
import 'dart:io'; import 'dart:io';
import 'package:firebase_messaging/firebase_messaging.dart';
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 '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/flutter_screenutil.dart';
import 'package:flutter_screenutil/screenutil_init.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:google_fonts/google_fonts.dart'; import 'firebase_options.dart';
//service & tools //service & tools
import 'package:aman_kassa_flutter/redux/store.dart'; import 'package:aman_kassa_flutter/redux/store.dart';
import 'core/locator.dart'; import 'core/locator.dart';
@ -16,13 +18,16 @@ import 'core/router.dart';
import 'core/services/navigator_service.dart'; import 'core/services/navigator_service.dart';
import 'core/services/dialog_service.dart'; import 'core/services/dialog_service.dart';
import './widgets/dialog_manager.dart'; import './widgets/dialog_manager.dart';
//pages //pages
import 'views/start_up/start_up_view.dart'; import 'views/start_up/start_up_view.dart';
//main start //main start
void main() async { void main() async {
HttpOverrides.global = MyHttpOverrides(); // HttpOverrides.global = MyHttpOverrides();
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
HttpOverrides.global = MyHttpOverrides(); HttpOverrides.global = MyHttpOverrides();
@ -34,29 +39,79 @@ void main() async {
yield LicenseEntryWithLineBreaks(['google_fonts'], license); yield LicenseEntryWithLineBreaks(['google_fonts'], license);
}); });
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FirebaseMessaging messaging = FirebaseMessaging.instance;
NotificationSettings settings = await messaging.requestPermission(
alert: true,
announcement: false,
badge: true,
carPlay: false,
criticalAlert: false,
provisional: false,
sound: true,
);
print('User granted permission: ${settings.authorizationStatus}');
await FirebaseMessaging.instance.subscribeToTopic('all');
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (message.notification != null) {
locator<DialogService>().showDialog(description: message.notification?.body ?? '');
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async {
if (message.notification != null) {
locator<DialogService>().showDialog(description: message.notification?.body ?? '');
}
});
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await Redux.init(); await Redux.init();
runApp(MainApplication()); runApp(MainApplication());
} }
class MainApplication extends StatelessWidget { Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
await Firebase.initializeApp();
}
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}
class MainApplication extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StoreProvider<AppState>( return StoreProvider<AppState>(
store: Redux.store, store: Redux.store!,
child: ScreenUtilInit( child: ScreenUtilInit(
designSize: Size(411.43, 683.43), designSize: const Size(
allowFontScaling: false, 411.43,
builder: () => MaterialApp( 683.43,
),
builder: (context, child) => MaterialApp(
theme: ThemeData( theme: ThemeData(
backgroundColor: backgroundColor, colorScheme: ColorScheme.fromSeed(seedColor: primaryColor).copyWith(surface: backgroundColor),
primaryColor: primaryColor, primaryColor: primaryColor,
accentColor: yellowColor,
scaffoldBackgroundColor: Colors.white, scaffoldBackgroundColor: Colors.white,
textTheme: GoogleFonts.latoTextTheme( // textTheme: GoogleFonts.latoTextTheme(
Theme.of(context).textTheme, // Theme.of(context).textTheme,
) // )
), ),
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
builder: (context, child) => Navigator( builder: (context, child) => Navigator(
@ -65,18 +120,10 @@ class MainApplication extends StatelessWidget {
builder: (context) => DialogManager(child: child)), builder: (context) => DialogManager(child: child)),
), ),
navigatorKey: locator<NavigatorService>().navigatorKey, navigatorKey: locator<NavigatorService>().navigatorKey,
home: StartUpView(), // first page home: StartUpView(),
// first page
onGenerateRoute: generateRoute, onGenerateRoute: generateRoute,
), ),
), ));
);
}
}
class MyHttpOverrides extends HttpOverrides{
@override
HttpClient createHttpClient(SecurityContext context){
return super.createHttpClient(context)
..badCertificateCallback = (X509Certificate cert, String host, int port)=> true;
} }
} }

View File

@ -1,5 +1,6 @@
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart'; import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
import 'package:aman_kassa_flutter/core/models/forte/forte_post_session.dart';
import 'package:aman_kassa_flutter/redux/state/bank_state.dart'; import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
@ -13,9 +14,58 @@ class SetBankStateAction {
SetBankStateAction(this.bankState); SetBankStateAction(this.bankState);
} }
ThunkAction<AppState> saveData(String login, String password) { ThunkAction<AppState> saveData(String login, String password, {String? sessionType}) {
return (Store<AppState> store) async { return (Store<AppState> store) async {
store.dispatch(SetBankStateAction(BankState(login: login, password: password))); final currentState = store.state.bankState;
dynamic session;
if (sessionType == 'Halyk') {
session = HalykPosSession(
login: login,
token: currentState?.session != null &&
currentState?.session is HalykPosSession
? (currentState?.session as HalykPosSession).token
: null,
serverTime: currentState?.session != null &&
currentState?.session is HalykPosSession
? (currentState?.session as HalykPosSession).serverTime
: null,
tokenTimeout: currentState?.session != null &&
currentState?.session is HalykPosSession
? (currentState?.session as HalykPosSession).tokenTimeout
: null,
result: currentState?.session != null &&
currentState?.session is HalykPosSession
? (currentState?.session as HalykPosSession).result
: null,
);
} else if (sessionType == 'Forte') {
session = FortePosSession(
login: login,
token: currentState?.session != null &&
currentState?.session is FortePosSession
? (currentState?.session as FortePosSession).token
: null,
serverTime: currentState?.session != null &&
currentState?.session is FortePosSession
? (currentState?.session as FortePosSession).serverTime
: null,
tokenTimeout: currentState?.session != null &&
currentState?.session is FortePosSession
? (currentState?.session as FortePosSession).tokenTimeout
: null,
result: currentState?.session != null &&
currentState?.session is FortePosSession
? (currentState?.session as FortePosSession).result
: null,
);
}
store.dispatch(SetBankStateAction(BankState(
login: login,
password: password,
session: session,
sessionType: sessionType,
)));
}; };
} }

View File

@ -1,3 +1,4 @@
import 'package:aman_kassa_flutter/core/models/calc_model.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/widgets/components/calculator/calculator.dart'; import 'package:aman_kassa_flutter/widgets/components/calculator/calculator.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
@ -26,7 +27,7 @@ ThunkAction<AppState> onTapAction(String value) {
if(value == Calculations.EQUAL){ if(value == Calculations.EQUAL){
return setEqual(store); return setEqual(store);
} }
List calcItems = Calculator.action(value: value, items: store.state.calcState.calcItems); List<CalcModel> calcItems = Calculator.action(value: value, items: store.state.calcState!.calcItems!);
store.dispatch(SetCalcStateAction(CalcState(calcItems: calcItems, isEqual: false))); store.dispatch(SetCalcStateAction(CalcState(calcItems: calcItems, isEqual: false)));
}; };
} }

View File

@ -24,8 +24,8 @@ final DataService _dataService = locator<DataService>();
final DialogService _dialogService = locator<DialogService>(); final DialogService _dialogService = locator<DialogService>();
Future<void> backBottomElement(Store<AppState> store) async { Future<void> backBottomElement(Store<AppState> store) async {
List<DictDao> prevCategories = store.state.kassaState.prevCategories; List<DictDao>? prevCategories = store.state.kassaState!.prevCategories;
DictDao last = prevCategories.removeLast(); DictDao? last = prevCategories?.removeLast() ;
if (last != null) { if (last != null) {
store.dispatch(SetKassaStateAction(KassaState(prevCategories: prevCategories))); store.dispatch(SetKassaStateAction(KassaState(prevCategories: prevCategories)));
store.dispatch(selectBottomElement(last.id)); store.dispatch(selectBottomElement(last.id));
@ -36,18 +36,18 @@ Future<void> cleanKassaItems(Store<AppState> store) async {
store.dispatch(SetKassaStateAction(KassaState(kassaItems: []))); store.dispatch(SetKassaStateAction(KassaState(kassaItems: [])));
} }
ThunkAction<AppState> addCustomProductToKassaItems(String name, int count, double price, double total) { ThunkAction<AppState> addCustomProductToKassaItems(String name, double count, double price, double total, {String? ntin}) {
return (Store<AppState> store) async { return (Store<AppState> store) async {
List<ProductDao> items = store.state.kassaState.kassaItems; List<ProductDao> items = store.state.kassaState!.kassaItems!;
items.add(new ProductDao(name: name, count: count, price: price, total: total)); items.add(new ProductDao(name: name, count: count, price: price, total: total, ntin: ntin));
store.dispatch(SetKassaStateAction(KassaState(kassaItems: items))); store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
}; };
} }
ThunkAction<AppState> addProductToKassaItems(Good good, String excise) { ThunkAction<AppState> addProductToKassaItems(Good good, String? excise) {
return (Store<AppState> store) async { return (Store<AppState> store) async {
List<ProductDao> items = store.state.kassaState.kassaItems; List<ProductDao> items = store.state.kassaState!.kassaItems!;
int index = items.indexWhere((element) => element.excise == null && element.good?.id == good.id); int index = items.indexWhere((element) => element.excise == null && element.good?.id == good.id);
if(excise !=null) { if(excise !=null) {
int existIndex = items.indexWhere((element) => element.excise != null && element.excise == excise); int existIndex = items.indexWhere((element) => element.excise != null && element.excise == excise);
@ -68,7 +68,7 @@ ThunkAction<AppState> addProductToKassaItems(Good good, String excise) {
ThunkAction<AppState> addServiceToKassaItems(Service service) { ThunkAction<AppState> addServiceToKassaItems(Service service) {
return (Store<AppState> store) async { return (Store<AppState> store) async {
List<ProductDao> items = store.state.kassaState.kassaItems; List<ProductDao> items = store.state.kassaState!.kassaItems!;
int index = items.indexWhere((element) => element.good?.id == service.id); int index = items.indexWhere((element) => element.good?.id == service.id);
if (index > -1) { if (index > -1) {
store.dispatch(counterProductFromKassaItems(index, 1)); store.dispatch(counterProductFromKassaItems(index, 1));
@ -82,7 +82,7 @@ ThunkAction<AppState> addServiceToKassaItems(Service service) {
ThunkAction<AppState> removeProductFromKassaItems(int index) { ThunkAction<AppState> removeProductFromKassaItems(int index) {
return (Store<AppState> store) async { return (Store<AppState> store) async {
List<ProductDao> items = List.from(store.state.kassaState.kassaItems); List<ProductDao> items = List.from(store.state.kassaState!.kassaItems!);
items.removeAt(index); items.removeAt(index);
store.dispatch(SetKassaStateAction(KassaState(kassaItems: items))); store.dispatch(SetKassaStateAction(KassaState(kassaItems: items)));
}; };
@ -90,7 +90,7 @@ ThunkAction<AppState> removeProductFromKassaItems(int index) {
ThunkAction<AppState> counterProductFromKassaItems(int index, int counter) { ThunkAction<AppState> counterProductFromKassaItems(int index, int counter) {
return (Store<AppState> store) async { return (Store<AppState> store) async {
List<ProductDao> items = store.state.kassaState.kassaItems; List<ProductDao> items = store.state.kassaState!.kassaItems!;
ProductDao product = items.elementAt(index); ProductDao product = items.elementAt(index);
if (product.count == 1 && counter < 0) { if (product.count == 1 && counter < 0) {
//if count to zero need delete element //if count to zero need delete element
@ -107,24 +107,24 @@ ThunkAction<AppState> selectBottomElement(int parentId) {
return (Store<AppState> store) async { return (Store<AppState> store) async {
store.dispatch(SetKassaStateAction(KassaState(bottomSheetLoading: true, bottomSheetElements: []))); store.dispatch(SetKassaStateAction(KassaState(bottomSheetLoading: true, bottomSheetElements: [])));
try { try {
List<DictDao> prevCategories = store.state.kassaState.prevCategories; List<DictDao> prevCategories = store.state.kassaState!.prevCategories!;
if (parentId == 0) { if (parentId == 0) {
prevCategories = []; prevCategories = [];
} }
store.state.kassaState.bottomSheetElements.forEach((element) { store.state.kassaState!.bottomSheetElements!.forEach((element) {
if (element is Category && element.id == parentId) { if (element is Category && element.id == parentId) {
prevCategories.add(DictDao(id: element.parentIn, name: element.name)); prevCategories.add(DictDao(id: element.parentIn!, name: element.name));
} }
}); });
List _bottomSheetElements = []; List _bottomSheetElements = [];
if(store.state.settingState.tradeType == SettingTradeTypeGood) { if(store.state.settingState!.tradeType == SettingTradeTypeGood) {
List<Category> categories = await _dataService.getCategoriesByParentId(parentId: parentId); List<Category> categories = await _dataService.getCategoriesByParentId(parentId: parentId);
_bottomSheetElements.addAll(categories); _bottomSheetElements.addAll(categories);
List<Good> goods = await _dataService.getGoodsByCategoryId(categoryId: parentId); List<Good> goods = await _dataService.getGoodsByCategoryId(categoryId: parentId);
_bottomSheetElements.addAll(goods); _bottomSheetElements.addAll(goods);
} else if(store.state.settingState.tradeType == SettingTradeTypeService) { } else if(store.state.settingState!.tradeType == SettingTradeTypeService) {
List<Service> services = await _dataService.getServices(); List<Service> services = await _dataService.getServices();
_bottomSheetElements.addAll(services); _bottomSheetElements.addAll(services);
} }

View File

@ -1,9 +1,9 @@
import 'package:aman_kassa_flutter/core/models/bluetooth_device.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/setting_state.dart'; 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

View File

@ -30,17 +30,17 @@ final DialogService _dialogService = locator<DialogService>();
Future<void> checkUserAction(Store<AppState> store) async { Future<void> checkUserAction(Store<AppState> store) async {
store.dispatch(SetUserStateAction(UserState(isLoading: true))); store.dispatch(SetUserStateAction(UserState(isLoading: true)));
try { try {
User user = store.state.userState.user; User? user = store.state.userState?.user;
String token = user?.token; String? token = user?.token;
bool isAuthenticated = false; bool isAuthenticated = false;
if (token != null) { if (token != null && user !=null) {
if(user.email!=null && user.email.toLowerCase().trim().startsWith('test')){ if(user.email!=null && user.email!.toLowerCase().trim().startsWith('test')){
_api.test = true; _api.test = true;
} else { } else {
_api.test = false; _api.test = false;
} }
Response<Message> session = await _api.isActive(token); Response<Message> session = await _api.isActive(token);
isAuthenticated = "OK" == session.body.message; isAuthenticated = "OK" == session.body?.message;
} else { } else {
await Future.delayed(Duration(milliseconds: 2000)); await Future.delayed(Duration(milliseconds: 2000));
@ -82,11 +82,11 @@ Future<void> logoutAction(Store<AppState> store) async {
} }
} }
Future<Response<dynamic>> checkMoney(Store<AppState> store) async { Future<Response<dynamic>?> checkMoney(Store<AppState> store) async {
store.dispatch(SetUserStateAction(UserState(money: Money(loading: true)))); store.dispatch(SetUserStateAction(UserState(money: Money(loading: true))));
try { try {
Response<dynamic> result = Response<dynamic> result =
await _api.money(store.state.userState.user.token); await _api.money(store.state.userState!.user!.token!);
if (result.operation) { if (result.operation) {
store.dispatch(SetUserStateAction(UserState( store.dispatch(SetUserStateAction(UserState(
money: Money( money: Money(
@ -165,20 +165,20 @@ ThunkAction<AppState> authenticate(String email, String password) {
} }
Future<void> checkSmena(Store<AppState> store) async { Future<void> checkSmena(Store<AppState> store) async {
String token = store.state.userState.user.token; String token = store.state.userState!.user!.token!;
Response<Smena> result = await _api.smena(token); Response<Smena> result = await _api.smena(token);
store.dispatch(SetUserStateAction(UserState(smena: result.body))); store.dispatch(SetUserStateAction(UserState(smena: result.body)));
} }
Future<void> closeSmena(Store<AppState> store) async { Future<void> closeSmena(Store<AppState> store) async {
String token = store.state.userState.user.token; String token = store.state.userState!.user!.token!;
Response<Smena> result = await _api.closeSmena(token); Response<Smena> result = await _api.closeSmena(token);
store.dispatch(SetUserStateAction(UserState(smena: result.body))); store.dispatch(SetUserStateAction(UserState(smena: result.body)));
store.dispatch(checkMoney); store.dispatch(checkMoney);
} }
Future<void> openSmena(Store<AppState> store) async { Future<void> openSmena(Store<AppState> store) async {
String token = store.state.userState.user.token; String token = store.state.userState!.user!.token!;
Response<Smena> result = await _api.openSmena(token); Response<Smena> result = await _api.openSmena(token);
store.dispatch(SetUserStateAction(UserState(smena: result.body))); store.dispatch(SetUserStateAction(UserState(smena: result.body)));
if (result.operation) { if (result.operation) {

View File

@ -3,5 +3,11 @@ import 'package:aman_kassa_flutter/redux/state/bank_state.dart';
bankReducer(BankState prevState, SetBankStateAction action) { bankReducer(BankState prevState, SetBankStateAction action) {
final payload = action.bankState; final payload = action.bankState;
return prevState.copyWith(login: payload.login, password: payload.password, session: payload.session); return prevState.copyWith(
login: payload.login ?? prevState.login,
password: payload.password ?? prevState.password,
session: payload.session ?? prevState.session,
sessionType: payload.sessionType ?? prevState.sessionType,
loading: null,
);
} }

View File

@ -1,22 +1,27 @@
import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart'; import 'package:aman_kassa_flutter/core/models/halyk/halyk_post_session.dart';
import 'package:aman_kassa_flutter/core/models/forte/forte_post_session.dart';
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';
@immutable @immutable
class BankState { class BankState {
final String login; final String? login;
final String password; final String? password;
final HalykPosSession session; final dynamic session;
final String? sessionType;
final bool? loading;
BankState({this.login, this.password, this.session,}); BankState({this.login, this.password, this.session,this.loading,this.sessionType});
//read hive //read hive
factory BankState.initial(BankState payload) { factory BankState.initial(BankState? payload) {
return BankState( return BankState(
login: payload?.login, login: payload?.login,
password: payload?.password, password: payload?.password,
session: payload?.session session: payload?.session,
loading: payload?.loading,
sessionType: payload?.sessionType,
); );
} }
@ -25,24 +30,49 @@ class BankState {
@required login, @required login,
@required password, @required password,
@required session, @required session,
@required loading,
@required sessionType,
}) { }) {
return BankState( return BankState(
login: login ?? this.login, login: login ?? this.login,
password: password ?? this.password, password: password ?? this.password,
session: session ?? this.session session: session ?? this.session,
loading: loading ?? this.loading,
sessionType: sessionType ?? this.sessionType
); );
} }
static BankState fromJson(dynamic json) { static BankState? fromJson(Map<String, dynamic> json) {
return json != null if (json == null) return null;
? BankState(
password: json['password'], // Определяем тип сессии
login: json['login'], dynamic session;
) final String? sessionType = json['sessionType'] as String?;
: null; if (sessionType == "Halyk") {
session = HalykPosSession.fromJson(json['session']);
} else if (sessionType == "Forte") {
session = FortePosSession.fromJson(json['session']);
} }
dynamic toJson() { return BankState(
return {"password": password, "login": login}; login: json['login'],
password: json['password'],
session: session,
sessionType: sessionType,
);
}
Map<String, dynamic> toJson() {
return {
"login": login,
"password": password,
"sessionType": sessionType,
"session": session?.toJson(),
};
}
@override
String toString() {
return 'BankState(login: $login, password: $password, sessionType: $sessionType, session: $session)';
} }
} }

View File

@ -3,8 +3,8 @@ import 'package:meta/meta.dart';
@immutable @immutable
class CalcState { class CalcState {
final List<CalcModel> calcItems; final List<CalcModel>? calcItems;
final bool isEqual; final bool? isEqual;
CalcState({this.calcItems, this.isEqual}); CalcState({this.calcItems, this.isEqual});

View File

@ -4,10 +4,10 @@ import 'package:meta/meta.dart';
@immutable @immutable
class KassaState { class KassaState {
final List bottomSheetElements; final List? bottomSheetElements;
final bool bottomSheetLoading; final bool? bottomSheetLoading;
final List<DictDao> prevCategories; final List<DictDao>? prevCategories;
final List<ProductDao> kassaItems; final List<ProductDao>? kassaItems;
KassaState( KassaState(

View File

@ -1,17 +1,17 @@
import 'package:aman_kassa_flutter/core/models/bluetooth_device.dart';
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 String? pinCode;
final bool pinLocked; final bool? pinLocked;
final bool pinSkip; final bool? pinSkip;
final BluetoothDevice printerBT; final BluetoothDevice? printerBT;
final String printerEncoding; final String? printerEncoding;
final String printerPaperSize; final String? printerPaperSize;
SettingState({this.mode, this.tradeType, this.pinCode, this.pinLocked, this.pinSkip, this.printerBT, SettingState({this.mode, this.tradeType, this.pinCode, this.pinLocked, this.pinSkip, this.printerBT,
@ -19,7 +19,7 @@ class SettingState {
this.printerPaperSize}); 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,
@ -56,7 +56,7 @@ class SettingState {
); );
} }
static SettingState fromJson(dynamic json) { static SettingState? fromJson(dynamic json) {
return json != null return json != null
? SettingState( ? SettingState(
tradeType: json['tradeType'], tradeType: json['tradeType'],
@ -80,7 +80,7 @@ class SettingState {
"pinCode": pinCode, "pinCode": pinCode,
"pinLocked" : pinLocked, "pinLocked" : pinLocked,
"pinSkip" : pinSkip, "pinSkip" : pinSkip,
"printerBT": printerBT != null ? printerBT.toJson() : null, "printerBT": printerBT != null ? printerBT!.toJson() : null,
"printerEncoding": printerEncoding, "printerEncoding": printerEncoding,
"printerPaperSize": printerPaperSize, "printerPaperSize": printerPaperSize,
}; };

View File

@ -5,16 +5,16 @@ import 'package:meta/meta.dart';
@immutable @immutable
class UserState { class UserState {
final bool isError; final bool? isError;
final bool isLoading; final bool? isLoading;
final bool isAuthenticated; final bool? isAuthenticated;
final String authenticateType; final String? authenticateType;
final String login; final String? login;
final String password; final String? password;
final LoginFormMessage loginFormMessage; final LoginFormMessage? loginFormMessage;
final User user; final User? user;
final Smena smena; final Smena? smena;
final Money money; final Money? money;
UserState( UserState(
@ -30,7 +30,7 @@ class UserState {
this.money, this.money,
}); });
factory UserState.initial(UserState payload) => UserState( factory UserState.initial(UserState? payload) => UserState(
isLoading: false, isLoading: false,
isError: false, isError: false,
isAuthenticated: false, isAuthenticated: false,
@ -44,16 +44,16 @@ class UserState {
); );
UserState copyWith({ UserState copyWith({
@required bool isError, @required bool? isError,
@required bool isLoading, @required bool? isLoading,
@required User user, @required User? user,
@required bool isAuthenticated, @required bool? isAuthenticated,
@required LoginFormMessage loginFormMessage, @required LoginFormMessage? loginFormMessage,
@required Smena smena, @required Smena? smena,
@required String authenticateType, @required String? authenticateType,
@required String login, @required String? login,
@required String password, @required String? password,
@required Money money, @required Money? money,
}) { }) {
return UserState( return UserState(
isError: isError ?? this.isError, isError: isError ?? this.isError,
@ -69,7 +69,7 @@ class UserState {
); );
} }
static UserState fromJson(dynamic json) { static UserState? fromJson(dynamic json) {
return json != null return json != null
? UserState( ? UserState(
user: User.fromJson(json['user']), user: User.fromJson(json['user']),
@ -82,7 +82,7 @@ class UserState {
dynamic toJson() { dynamic toJson() {
return { return {
"user": user != null ? user.toJson() : null, "user": user != null ? user!.toJson() : null,
"authenticateType": authenticateType, "authenticateType": authenticateType,
"login": login, "login": login,
"password": password, "password": password,
@ -91,9 +91,9 @@ class UserState {
} }
class LoginFormMessage { class LoginFormMessage {
final String email; final String? email;
final String password; final String? password;
final String message; final String? message;
LoginFormMessage({this.email, this.password, this.message}); LoginFormMessage({this.email, this.password, this.message});
} }

View File

@ -11,6 +11,7 @@ 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';
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/views/payment/halyk_pos_service.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import 'package:redux/redux.dart'; import 'package:redux/redux.dart';
import 'package:redux_persist_flutter/redux_persist_flutter.dart'; import 'package:redux_persist_flutter/redux_persist_flutter.dart';
@ -24,23 +25,23 @@ import 'actions/calc_actions.dart';
AppState appReducer(AppState state, dynamic action) { AppState appReducer(AppState state, dynamic action) {
if (action is SetUserStateAction) { if (action is SetUserStateAction) {
/** UserAction **/ /** UserAction **/
final nextUserState = userReducer(state.userState, action); final nextUserState = userReducer(state.userState!, action);
return state.copyWith(userState: nextUserState); return state.copyWith(userState: nextUserState);
} else if (action is SetKassaStateAction) { } else if (action is SetKassaStateAction) {
/** KassaAction **/ /** KassaAction **/
final nextMainState = mainReducer(state.kassaState, action); final nextMainState = mainReducer(state.kassaState!, action);
return state.copyWith(kassaState: nextMainState); return state.copyWith(kassaState: nextMainState);
} else if (action is SetSettingStateAction) { } else if (action is SetSettingStateAction) {
/** SettingAction **/ /** SettingAction **/
final nextSettingState = settingReducer(state.settingState, action); final nextSettingState = settingReducer(state.settingState!, action);
return state.copyWith(settingState: nextSettingState); return state.copyWith(settingState: nextSettingState);
} else if (action is SetCalcStateAction) { } else if (action is SetCalcStateAction) {
/** 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) { } else if (action is SetBankStateAction) {
/** BankAction **/ /** BankAction **/
final nextBankState = bankReducer(state.bankState, action); final nextBankState = bankReducer(state.bankState!, action);
return state.copyWith(bankState: nextBankState); return state.copyWith(bankState: nextBankState);
} }
return state; return state;
@ -49,11 +50,11 @@ AppState appReducer(AppState state, dynamic action) {
//Main State //Main State
@immutable @immutable
class AppState { class AppState {
final UserState userState; final UserState? userState;
final KassaState kassaState; final KassaState? kassaState;
final SettingState settingState; final SettingState? settingState;
final CalcState calcState; final CalcState? calcState;
final BankState bankState; final BankState? bankState;
AppState({ AppState({
this.userState, this.userState,
@ -65,11 +66,11 @@ class AppState {
//stable work //stable work
AppState copyWith({ AppState copyWith({
UserState userState, UserState? userState,
KassaState kassaState, KassaState? kassaState,
SettingState settingState, SettingState? settingState,
CalcState calcState, CalcState? calcState,
BankState bankState, BankState? bankState,
}) { }) {
return AppState( return AppState(
userState: userState ?? this.userState, userState: userState ?? this.userState,
@ -80,7 +81,7 @@ class AppState {
); );
} }
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']),
@ -92,17 +93,17 @@ class AppState {
dynamic toJson() { dynamic toJson() {
return { return {
"settingState": settingState.toJson(), "settingState": settingState?.toJson(),
"userState": userState.toJson(), "userState": userState?.toJson(),
"bankState": bankState.toJson(), "bankState": bankState?.toJson(),
}; };
} }
} }
class Redux { class Redux {
static Store<AppState> _store; static Store<AppState>? _store;
static Store<AppState> get store { static Store<AppState>? get store {
if (_store == null) { if (_store == null) {
throw Exception("store is not initialized"); throw Exception("store is not initialized");
} else { } else {
@ -119,7 +120,12 @@ class Redux {
AppState.fromJson), // Or use other serializers AppState.fromJson), // Or use other serializers
); );
final initialState = await persist.load(); AppState? initialState;
try {
initialState = await persist.load();
} catch (e, stack) {
log.e('message', e, stack);
}
final userStateInitial = UserState.initial(initialState?.userState); final userStateInitial = UserState.initial(initialState?.userState);
final kassaStateInitial = KassaState.initial(); final kassaStateInitial = KassaState.initial();

View File

@ -5,6 +5,7 @@ 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 halykColor = Color.fromRGBO(0, 118, 59, 1);
const Color forteColor = Color.fromRGBO(175, 32, 92, 1.0);
const Color menuColor = Color.fromRGBO(0, 75, 120, 1); const Color menuColor = Color.fromRGBO(0, 75, 120, 1);

View File

@ -12,6 +12,8 @@ import 'package:aman_kassa_flutter/shared/ui_helpers.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import '../../core/services/navigator_service.dart';
class BankSettingView extends StatefulWidget { class BankSettingView extends StatefulWidget {
BankSettingView(); BankSettingView();
@ -20,18 +22,20 @@ class BankSettingView extends StatefulWidget {
} }
class _BankSettingViewState extends State<BankSettingView> { class _BankSettingViewState extends State<BankSettingView> {
TextEditingController _emailController; late TextEditingController _emailController;
TextEditingController _passwordController; late TextEditingController _passwordController;
final BankService _bankService = locator<BankService>(); final NavigatorService _navigatorService = locator<NavigatorService>();
final DialogService _dialogService = locator<DialogService>(); final DialogService _dialogService = locator<DialogService>();
late String _sessionType;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
BankState state = Redux.store.state.bankState; BankState state = Redux.store!.state.bankState!;
_emailController = new TextEditingController(text: state.login); _emailController = new TextEditingController(text: state.login);
_passwordController = new TextEditingController(text: state.password); _passwordController = new TextEditingController(text: state.password);
//permissions(); //permissions();
_sessionType = 'Halyk';
} }
// Future<void> permissions() async { // Future<void> permissions() async {
@ -52,14 +56,40 @@ class _BankSettingViewState extends State<BankSettingView> {
void _saveData(BuildContext _context) async { void _saveData(BuildContext _context) async {
FocusScope.of(_context).unfocus(); FocusScope.of(_context).unfocus();
await Redux.store.dispatch(saveData(_emailController.text, _passwordController.text)); await Redux.store!.dispatch(saveData(
_emailController.text,
_passwordController.text,
sessionType: _sessionType,
));
_dialogService.showDialog(description: 'Данные сохранены'); _dialogService.showDialog(description: 'Данные сохранены');
_navigatorService.pop();
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final BankState? state = Redux.store?.state.bankState;
// Проверяем, активна ли Forte-сессия
if ((state?.login != null && state!.login!.isNotEmpty) ||
(state?.password != null && state!.password!.isNotEmpty)) {
if (state.sessionType != 'Halyk') {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Настройка HalykPos'),
),
body: Center(
child: Text(
'У вас подключен терминал Forte',
style: TextStyle(fontSize: 16.0, color: Colors.grey),
),
),
);
}
}
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
centerTitle: true, centerTitle: true,
@ -72,7 +102,7 @@ class _BankSettingViewState extends State<BankSettingView> {
children: <Widget>[ children: <Widget>[
verticalSpaceTiny, verticalSpaceTiny,
Text( Text(
'Необходимо указать почту и пароль для подключения к системе проведения платежей', 'Необходимо указать почту/номер и пароль для подключения к системе проведения платежей',
style: TextStyle(fontSize: 15.0), style: TextStyle(fontSize: 15.0),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
@ -80,7 +110,7 @@ class _BankSettingViewState extends State<BankSettingView> {
TextField( TextField(
controller: _emailController, controller: _emailController,
decoration: InputDecoration( decoration: InputDecoration(
labelText: 'E-Mail', hintText: "Введите адрес почты"), labelText: 'E-Mail / Номер телефона ', hintText: "Введите адрес почты"),
keyboardType: TextInputType.emailAddress, keyboardType: TextInputType.emailAddress,
), ),
TextField( TextField(
@ -90,15 +120,16 @@ class _BankSettingViewState extends State<BankSettingView> {
labelText: 'Пароль', hintText: "Введите пароль"), labelText: 'Пароль', hintText: "Введите пароль"),
), ),
verticalSpaceMedium, verticalSpaceMedium,
RaisedButton( ElevatedButton(
onPressed: () => this._saveData(context), onPressed: () => this._saveData(context),
child: Text( child: Text(
'Cохранить', 'Cохранить',
style: TextStyle(color: whiteColor, fontSize: 25.0), style: TextStyle(color: whiteColor, fontSize: 25.0),
), ),
color: primaryColor, style: ElevatedButton.styleFrom(
padding: backgroundColor: primaryColor,
const EdgeInsets.symmetric(vertical: 5.0, horizontal: 20.0), padding: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 20.0),
),
), ),
], ],

View File

@ -0,0 +1,143 @@
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/ForteService.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';
import '../../core/services/navigator_service.dart';
class ForteSettingView extends StatefulWidget {
ForteSettingView();
@override
_ForteSettingViewState createState() => _ForteSettingViewState();
}
class _ForteSettingViewState extends State<ForteSettingView> {
late TextEditingController _emailController;
late TextEditingController _passwordController;
final NavigatorService _navigatorService = locator<NavigatorService>();
final DialogService _dialogService = locator<DialogService>();
late String _sessionType;
@override
void initState() {
super.initState();
BankState state = Redux.store!.state.bankState!;
_emailController = new TextEditingController(text: state.login);
_passwordController = new TextEditingController(text: state.password);
//permissions();
_sessionType = 'Forte';
}
// 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,
sessionType: _sessionType
));
_dialogService.showDialog(description: 'Данные сохранены');
_navigatorService.pop();
}
@override
Widget build(BuildContext context) {
final BankState? state = Redux.store?.state.bankState;
// Проверяем, активна ли Halyk-сессия
if ((state?.login != null && state!.login!.isNotEmpty) ||
(state?.password != null && state!.password!.isNotEmpty)) {
if (state.sessionType != 'Forte') {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Настройка FortePos'),
),
body: Center(
child: Text(
'У вас подключен терминал Halyk',
style: TextStyle(fontSize: 16.0, color: Colors.grey),
),
),
);
}
}
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text('Настройка FortePos'),
),
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 / Номер телефона в формете 77xx ', hintText: "Введите адрес почты/телефон"),
keyboardType: TextInputType.emailAddress,
),
TextField(
controller: _passwordController,
obscureText: true,
decoration: InputDecoration(
labelText: 'Пароль', hintText: "Введите пароль"),
),
verticalSpaceMedium,
ElevatedButton(
onPressed: () => this._saveData(context),
child: Text(
'Cохранить',
style: TextStyle(color: whiteColor, fontSize: 25.0),
),
style: ElevatedButton.styleFrom(
backgroundColor: primaryColor,
padding: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 20.0),
),
),
],
),
),
),
);
}
}

View File

@ -16,17 +16,17 @@ class _BankViewState extends State<BankView> {
MethodChannel('channel:com.amanKassa/bank'); MethodChannel('channel:com.amanKassa/bank');
static const MethodChannel _activity = static const MethodChannel _activity =
MethodChannel('channel:com.amanKassa/activity'); MethodChannel('channel:com.amanKassa/activity');
String initValue; String? initValue;
String connectionValue; String? connectionValue;
String authValue; String? authValue;
String payValue; String? payValue;
String cancelValue; String? cancelValue;
String shutdownValue; String? shutdownValue;
String versionValue; String? versionValue;
String transactionValue; String? transactionValue;
String closeDayValue; String? closeDayValue;
String getValue; String? getValue;
String errorValue; String? errorValue;
bool loading = false; bool loading = false;
@override @override
@ -40,21 +40,21 @@ class _BankViewState extends State<BankView> {
'serverUrl': 'http://195.200.74.83:5000', 'serverUrl': 'http://195.200.74.83:5000',
}); });
setState(() { setState(() {
initValue = result ?? 'none'; initValue = result;
}); });
} }
version() async { version() async {
String result = await _channel.invokeMethod('version'); String result = await _channel.invokeMethod('version');
setState(() { setState(() {
versionValue = result ?? 'none'; versionValue = result;
}); });
} }
transaction() async { transaction() async {
String result = await _channel.invokeMethod('transaction'); String result = await _channel.invokeMethod('transaction');
setState(() { setState(() {
transactionValue = result ?? 'none'; transactionValue = result ;
}); });
} }
@ -171,13 +171,13 @@ class _BankViewState extends State<BankView> {
child: Column( child: Column(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
RaisedButton( ElevatedButton(
child: Text('Activity m4Bank'), onPressed: activity), child: Text('Activity m4Bank'), onPressed: activity),
Column( Column(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
Text('version: $versionValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false), Text('version: $versionValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
RaisedButton( ElevatedButton(
child: Text('Version'), onPressed: version), child: Text('Version'), onPressed: version),
], ],
), ),
@ -185,7 +185,7 @@ class _BankViewState extends State<BankView> {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
Text('init: $initValue' , overflow: TextOverflow.clip, maxLines: 2, softWrap: false), Text('init: $initValue' , overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
RaisedButton( ElevatedButton(
child: Text('Init'), onPressed: initialize), child: Text('Init'), onPressed: initialize),
], ],
), ),
@ -193,7 +193,7 @@ class _BankViewState extends State<BankView> {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
Text('connection: $connectionValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false), Text('connection: $connectionValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
RaisedButton( ElevatedButton(
child: Text('Connect'), onPressed: connect), child: Text('Connect'), onPressed: connect),
], ],
), ),
@ -201,21 +201,21 @@ class _BankViewState extends State<BankView> {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
Text('auth: $authValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false), Text('auth: $authValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
RaisedButton(child: Text('Auth'), onPressed: auth), ElevatedButton(child: Text('Auth'), onPressed: auth),
], ],
), ),
Column( Column(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
Text('cancel: $cancelValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false), Text('cancel: $cancelValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
RaisedButton(child: Text('Cancel'), onPressed: cancel), ElevatedButton(child: Text('Cancel'), onPressed: cancel),
], ],
), ),
Column( Column(
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
Text('shutdown: $shutdownValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false), Text('shutdown: $shutdownValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
RaisedButton( ElevatedButton(
child: Text('Shutdown'), onPressed: shutdown), child: Text('Shutdown'), onPressed: shutdown),
], ],
), ),
@ -223,7 +223,7 @@ class _BankViewState extends State<BankView> {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
Text('transaction: $transactionValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false), Text('transaction: $transactionValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
RaisedButton( ElevatedButton(
child: Text('Transaction'), onPressed: transaction), child: Text('Transaction'), onPressed: transaction),
], ],
), ),
@ -231,7 +231,7 @@ class _BankViewState extends State<BankView> {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
Text('get: $getValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false), Text('get: $getValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
RaisedButton( ElevatedButton(
child: Text('Get'), onPressed: get), child: Text('Get'), onPressed: get),
], ],
), ),
@ -239,7 +239,7 @@ class _BankViewState extends State<BankView> {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
Text('error: $errorValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false), Text('error: $errorValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
RaisedButton( ElevatedButton(
child: Text('Error'), onPressed: error), child: Text('Error'), onPressed: error),
], ],
), ),
@ -247,12 +247,12 @@ class _BankViewState extends State<BankView> {
mainAxisAlignment: MainAxisAlignment.spaceAround, mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[ children: <Widget>[
Text('error: $closeDayValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false), Text('error: $closeDayValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
RaisedButton( ElevatedButton(
child: Text('CloseDay'), onPressed: closeDay), child: Text('CloseDay'), onPressed: closeDay),
], ],
), ),
Text('pay: $payValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false), Text('pay: $payValue', overflow: TextOverflow.clip, maxLines: 2, softWrap: false),
RaisedButton(child: Text('Payment'), onPressed: pay), ElevatedButton(child: Text('Payment'), onPressed: pay),
], ],
), ),
), ),

View File

@ -1,6 +1,7 @@
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/entity/Voucher.dart';
import 'dart:typed_data';
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_data.dart';
import 'package:aman_kassa_flutter/core/models/check_image_modal.dart'; import 'package:aman_kassa_flutter/core/models/check_image_modal.dart';
@ -11,6 +12,7 @@ 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/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/blue_print_service.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/setting_actions.dart';
@ -24,16 +26,18 @@ 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/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:aman_kassa_flutter/widgets/loader/Dialogs.dart';
import 'package:esc_pos_bluetooth/esc_pos_bluetooth.dart'; import 'package:aman_kassa_flutter/core/models/bluetooth_device.dart';
import 'package:esc_pos_utils/esc_pos_utils.dart'; import 'package:esc_pos_utils/esc_pos_utils.dart';
import 'package:flutter/cupertino.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:share_plus/share_plus.dart';
import 'package:path_provider/path_provider.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../../core/models/aman_dao.dart'; import '../../core/models/aman_dao.dart';
import '../../redux/state/bank_state.dart';
import '../payment/forte_pos_service.dart';
class ImageShowContainer extends StatefulWidget { class ImageShowContainer extends StatefulWidget {
final ImageShowModel showModel; final ImageShowModel showModel;
@ -45,19 +49,18 @@ class ImageShowContainer extends StatefulWidget {
} }
class _ImageShowContainerState extends State<ImageShowContainer> { class _ImageShowContainerState extends State<ImageShowContainer> {
final PrinterBluetoothManager printerManager = PrinterBluetoothManager(); final BluePrintService printerManager = locator<BluePrintService>();
final DialogService _dialogService = locator<DialogService>(); final DialogService _dialogService = locator<DialogService>();
final BluetoothDevice? printerBtDevice =
final BluetoothDevice printerBtDevice = Redux.store.state.settingState.printerBT; Redux.store!.state.settingState!.printerBT;
final BluetoothManager bluetoothManager = BluetoothManager.instance;
bool _printing = false; bool _printing = false;
void _preparePrint() async { void _preparePrint() async {
if (Platform.isIOS) { if (Platform.isIOS) {
await _print(); _print();
} else { } else {
bluetoothManager.state.listen((val) { printerManager.state.listen((val) {
print("state = $val"); print("state = $val");
if (!mounted) return; if (!mounted) return;
if (val == 12) { if (val == 12) {
@ -65,17 +68,31 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
_print(); _print();
} else if (val == 10) { } else if (val == 10) {
print('off'); print('off');
_dialogService.showDialog(description: 'Отсутвует соеденение Bluetooth или он отключен', title: 'Bluetooth'); _dialogService.showDialog(
description: 'Отсутвует соеденение Bluetooth или он отключен',
title: 'Bluetooth');
} }
print('state is $val'); print('state is $val');
}); });
} }
} }
@override
void dispose() {
disconnect();
super.dispose();
}
void disconnect() async {
await printerManager.disconnect();
}
void _print() async { void _print() async {
final SettingState state = Redux.store.state.settingState; final SettingState state = Redux.store!.state.settingState!;
if (state.printerBT == null) { if (state.printerBT == null) {
_dialogService.showDialog(description: 'Укажите в настройках принтер для печати чеков'); _dialogService.showDialog(
description: 'Укажите в настройках принтер для печати чеков');
return; return;
} }
@ -92,29 +109,32 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
_printing = true; _printing = true;
}); });
try { try {
printerManager.selectPrinter(PrinterBluetooth(state.printerBT)); printerManager.device = state.printerBT!;
PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80 ? PaperSize.mm80 : PaperSize.mm58; await printerManager.connect();
PaperSize paper = state.printerPaperSize == SettingPrinterPaperM80
? PaperSize.mm80
: PaperSize.mm58;
if (SettingPrinterEncodingImage == state.printerEncoding) { if (SettingPrinterEncodingImage == state.printerEncoding) {
final PosPrintResult res = await printerManager.printTicket( final bool res = await printerManager.printBytes(
await printImageCheck(paper, widget.showModel.data.base64Data), Uint8List.fromList(await printImageCheck(paper, widget.showModel.data!.base64Data!)));
chunkSizeBytes: chunkSizeBytes, if (!res) {
queueSleepTimeMs: queueSleepTimeMs); _dialogService.showDialog(description: 'Ошибка при печати');
if (res.value != 1) {
_dialogService.showDialog(description: res.msg);
} }
} else { } else {
final PosPrintResult res = await printerManager.printTicket( final bool res = await printerManager.printBytes(
await printTextCheck(paper, state.printerEncoding, jsonDecode(widget.showModel.data.textData)), Uint8List.fromList(await printTextCheck(paper, state.printerEncoding!,
chunkSizeBytes: chunkSizeBytes, jsonDecode(widget.showModel.data!.textData!)))
queueSleepTimeMs: queueSleepTimeMs); );
if (res.value != 1) { if (!res) {
_dialogService.showDialog(description: res.msg); _dialogService.showDialog(description: 'Ошибка при печати');
} }
} }
} catch (e) { } catch (e) {
print(e); print(e);
} }
await Future.delayed(Duration(seconds: 7)); await Future.delayed(Duration(seconds: 15));
setState(() { setState(() {
_printing = false; _printing = false;
}); });
@ -145,7 +165,9 @@ class _ImageShowContainerState extends State<ImageShowContainer> {
], ],
), ),
body: ListView( body: ListView(
children: <Widget>[imageFromBase64String(widget.showModel.data.base64Data)], children: <Widget>[
imageFromBase64String(widget.showModel.data!.base64Data!)
],
), ),
floatingActionButton: MyFloatingActionButton(widget.showModel), floatingActionButton: MyFloatingActionButton(widget.showModel),
); );
@ -160,13 +182,13 @@ Padding imageFromBase64String(String base64String) {
} }
class ImageShowModel { class ImageShowModel {
final CheckImageModal data; final CheckImageModal? data;
final String title; final String title;
final String url; final String? url;
final CardData cardData; final CardData? cardData;
final Voucher voucher; final Voucher? voucher;
ImageShowModel({this.data, this.title, this.url, this.cardData, this.voucher}); ImageShowModel({this.data, required this.title, this.url, this.cardData, this.voucher});
} }
class MyFloatingActionButton extends StatefulWidget { class MyFloatingActionButton extends StatefulWidget {
@ -196,7 +218,7 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
return Column( return Column(
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: [ children: [
if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment") if (widget.data.cardData?.transactionType == "payment")
FloatingActionButton( FloatingActionButton(
backgroundColor: redColor, backgroundColor: redColor,
tooltip: 'Отмена', tooltip: 'Отмена',
@ -207,23 +229,27 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
onPressed: () async { onPressed: () async {
var today = new DateTime.now(); var today = new DateTime.now();
var yesterday = today.subtract(new Duration(days: 1)); var yesterday = today.subtract(new Duration(days: 1));
if( Redux.store.state.userState == null if(Redux.store?.state.userState?.smena?.startedAt == null
|| Redux.store.state.userState.smena == null || yesterday.isAfter(Redux.store!.state.userState!.smena!.startedAt!)) {
|| Redux.store.state.userState.smena.startedAt == null
|| yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) {
_dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.'); _dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
return; return;
} }
try { try {
await Redux.store.dispatch(changePinSkipFromSetting(true)); await Redux.store!.dispatch(changePinSkipFromSetting(true));
AmanDao<CardData> response = await reversalHalykPos(widget.data.cardData, widget.data.voucher.total); // Определяем метод отмены в зависимости от типа сессии
if (response.success) { final BankState? state = Redux.store?.state.bankState;
final isForteSessionActive = state?.sessionType == 'Forte';
final AmanDao<CardData> response = isForteSessionActive
? await reversalFortePos(widget.data.cardData!, widget.data.voucher!.total!)
: await reversalHalykPos(widget.data.cardData!, widget.data.voucher!.total!);
if (response.success == true) {
pressRefund(); pressRefund();
} else { } else {
_dialog.showDialog(description: response.msg); _dialog.showDialog(description: response.msg!);
} }
} finally { } finally {
await Redux.store.dispatch(changePinSkipFromSetting(false)); await Redux.store!.dispatch(changePinSkipFromSetting(false));
} }
_navigatorService.replace(HomeViewRoute); _navigatorService.replace(HomeViewRoute);
}, },
@ -236,7 +262,7 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
SizedBox( SizedBox(
height: 10, height: 10,
), ),
if (widget.data.cardData != null && widget.data.cardData.transactionType == "payment") if (widget.data.cardData != null && widget.data.cardData?.transactionType == "payment")
FloatingActionButton( FloatingActionButton(
backgroundColor: redColor, backgroundColor: redColor,
tooltip: 'Возврат', tooltip: 'Возврат',
@ -247,24 +273,29 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
onPressed: () async { onPressed: () async {
var today = new DateTime.now(); var today = new DateTime.now();
var yesterday = today.subtract(new Duration(days: 1)); var yesterday = today.subtract(new Duration(days: 1));
if( Redux.store.state.userState == null if( Redux.store!.state.userState == null
|| Redux.store.state.userState.smena == null || Redux.store!.state.userState?.smena == null
|| Redux.store.state.userState.smena.startedAt == null || Redux.store!.state.userState?.smena?.startedAt == null
|| yesterday.isAfter(Redux.store.state.userState.smena.startedAt)) { || yesterday.isAfter(Redux.store!.state.userState!.smena!.startedAt!)) {
_dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.'); _dialog.showDialog(description: 'Текущая смена открыта более 24 ч. Необходимо закрыть смену и открыть ее заново.');
return; return;
} }
try { try {
await Redux.store.dispatch(changePinSkipFromSetting(true)); await Redux.store!.dispatch(changePinSkipFromSetting(true));
AmanDao<CardData> response = await refundHalykPos(widget.data.cardData, widget.data.voucher.total); final BankState? state = Redux.store?.state.bankState;
if (response.success) { final isForteSessionActive = state?.sessionType == 'Forte';
final AmanDao<CardData> response = isForteSessionActive
? await refundFortePos(widget.data.cardData!, widget.data.voucher!.total!)
: await refundHalykPos(widget.data.cardData!, widget.data.voucher!.total!);
if (response.success == true) {
pressRefund(); pressRefund();
} else { } else {
_dialog.showDialog(description: response.msg); _dialog.showDialog(description: response.msg!);
} }
} finally { } finally {
await Redux.store.dispatch(changePinSkipFromSetting(false)); await Redux.store!.dispatch(changePinSkipFromSetting(false));
} }
}, },
heroTag: null, heroTag: null,
@ -286,7 +317,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(blurRadius: 10, color: Colors.grey[300], spreadRadius: 5)]), boxShadow: [BoxShadow(blurRadius: 10, color: Colors.grey[300]!, spreadRadius: 5)]),
height: 260, height: 260,
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
@ -331,22 +362,22 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
pressRefund() async { pressRefund() async {
Dialogs.showLoadingDialog(context, _keyLoader); Dialogs.showLoadingDialog(context, _keyLoader);
try { try {
AppState _state = Redux.store.state; AppState _state = Redux.store!.state;
String _token = _state.userState.user.token; String _token = _state.userState!.user!.token!;
CardData _cardData = widget.data.cardData; CardData _cardData = widget.data.cardData!;
CheckData _checkData = CheckData.fromJson(json.decode(widget.data.voucher.data)); CheckData _checkData = CheckData.fromJson(json.decode(widget.data.voucher!.data!));
Response<dynamic> response = Response<dynamic>? response =
await _dataService.refundM4Bank(token: _token, cardData: _cardData, checkData: _checkData); await _dataService.refundM4Bank(token: _token, cardData: _cardData, checkData: _checkData);
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']; var checkText = response.body['check_text'];
String url = response?.body['link']; String url = response.body['link'];
print('url : $url'); print('url : $url');
Redux.store.dispatch(checkMoney); Redux.store!.dispatch(checkMoney);
Redux.store.dispatch(openSmenaPseudo); Redux.store!.dispatch(openSmenaPseudo);
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
_navigatorService.replace(HomeViewRoute); _navigatorService.replace(HomeViewRoute);
_navigatorService.push(ImageShowRoute, _navigatorService.push(ImageShowRoute,
arguments: ImageShowModel( arguments: ImageShowModel(
@ -355,23 +386,27 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
title: message, title: message,
url: url)); url: url));
} else if (!response.operation && ![401, 402, 403, 412, 500].contains(response.status)) { } 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();
_dialog.showDialog(description: response.body['message']); _dialog.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();
} }
} }
void shareFile() async { void shareFile() async {
try { try {
await Share.file('Aman Kassa', 'aman_kassa_check.png', base64Decode(widget.data.data.base64Data), 'image/png'); final bytes = base64Decode(widget.data.data!.base64Data!);
final tempDir = await getTemporaryDirectory();
final file = File('${tempDir.path}/aman_kassa_check.png');
await file.writeAsBytes(bytes);
await Share.shareXFiles([XFile(file.path, mimeType: 'image/png')], subject: 'Aman Kassa');
} catch (e) { } catch (e) {
print('error: $e'); print('error: $e');
} }
@ -385,15 +420,15 @@ class _MyFloatingActionButtonState extends State<MyFloatingActionButton> {
DialogResponse response = await _dialog.showConfirmationDialogInput( DialogResponse response = await _dialog.showConfirmationDialogInput(
description: 'Номер телефона', cancelTitle: 'Отмена', confirmationTitle: 'Отправить', formatType: 'phone'); description: 'Номер телефона', 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} ";
launchWhatsApp(phone: phoneNumber, message: msg); launchWhatsApp(phone: phoneNumber, message: msg);
} }
} }
void launchWhatsApp({ void launchWhatsApp({
@required String phone, required String phone,
@required String message, required String message,
}) async { }) async {
String url() { String url() {
if (Platform.isIOS) { if (Platform.isIOS) {

View File

@ -1,13 +1,18 @@
import 'package:aman_kassa_flutter/core/models/close_day_data.dart'; import 'package:aman_kassa_flutter/core/models/halyk/close_day_data.dart' as halyk;
import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart'; import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart' as halykDao;
import 'package:aman_kassa_flutter/core/models/forte/close_day_data.dart' as forte;
import 'package:aman_kassa_flutter/core/models/forte/forte_close_day_dao.dart' as forteDao;
import 'package:aman_kassa_flutter/core/models/transaction_item.dart'; import 'package:aman_kassa_flutter/core/models/transaction_item.dart';
import 'package:aman_kassa_flutter/shared/shared_styles.dart'; import 'package:aman_kassa_flutter/shared/shared_styles.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import '../../redux/state/bank_state.dart';
import '../../redux/store.dart';
class CloseDayShowContainer extends StatelessWidget { class CloseDayShowContainer extends StatelessWidget {
final CloseDayData data; final dynamic data;
DateFormat dateFormat = DateFormat("dd.MM.yyyy HH:mm:ss"); DateFormat dateFormat = DateFormat("dd.MM.yyyy HH:mm:ss");
CloseDayShowContainer(this.data); CloseDayShowContainer(this.data);
@override @override
@ -55,19 +60,27 @@ class CloseDayShowContainer extends StatelessWidget {
Divider(), Divider(),
Expanded( Expanded(
child: ListView.separated( child: ListView.separated(
itemCount: data.items.length, itemCount: data.items?.length ?? 0,
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (BuildContext context, int index) {
return Divider(); return Divider();
}, },
itemBuilder: (BuildContext context, int index) { itemBuilder: (BuildContext context, int index) {
TransactionBean item = data.items.elementAt(index); final BankState? state = Redux.store?.state.bankState;
final isForteSessionActive = state?.sessionType == 'Forte';
var item;
if (isForteSessionActive == true) {
item = data.items!.elementAt(index) as forteDao.TransactionBean;
} else {
item = data.items!.elementAt(index) as halykDao.TransactionBean;
}
return ListTile( return ListTile(
title: Text(item.instrumentSpecificData.maskedPan), title: Text(item.instrumentSpecificData?.maskedPan ?? ''),
subtitle: Column( subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if(item.instrumentSpecificData.cardholderName!=null) if(item.instrumentSpecificData!.cardholderName!=null)
Text(item.instrumentSpecificData.cardholderName), Text(item.instrumentSpecificData!.cardholderName!),
Text('Операционный день № ${item.operationDay?.toString()}'), Text('Операционный день № ${item.operationDay?.toString()}'),
], ],
), ),

View File

@ -5,7 +5,7 @@ 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/check_image_modal.dart';
import 'package:aman_kassa_flutter/core/models/card_data.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/close_day_data.dart'; import 'package:aman_kassa_flutter/core/models/halyk/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';
@ -47,7 +47,7 @@ class _HistoryViewState extends State<HistoryView> {
appBar: AppBar( appBar: AppBar(
title: Text('История чеков'), title: Text('История чеков'),
actions: <Widget>[ actions: <Widget>[
FlatButton( TextButton(
child: Text( child: Text(
'Очистить', 'Очистить',
style: TextStyle( style: TextStyle(
@ -68,16 +68,16 @@ 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; CardData? cardData;
CloseDayData closeDayData; CloseDayData? closeDayData;
if( voucher.type == VoucherTypeCloseDayPosReport ) { if( voucher.type == VoucherTypeCloseDayPosReport ) {
closeDayData = CloseDayData.fromJson(json.decode(voucher.data)); closeDayData = CloseDayData.fromJson(json.decode(voucher.data!));
} else if( voucher.data !=null ) { } else if( voucher.data !=null ) {
CheckData checkData = CheckData.fromJson(json.decode(voucher.data)); CheckData checkData = CheckData.fromJson(json.decode(voucher.data!));
cardData = checkData.cardData; cardData = checkData.cardData;
} }
String base64Data = voucher.base64Data; String? base64Data = voucher.base64Data;
CheckImageModal checkImageData; CheckImageModal checkImageData;
if(base64Data !=null && base64Data.startsWith('{')){ if(base64Data !=null && base64Data.startsWith('{')){
checkImageData = CheckImageModal.fromJson(jsonDecode(base64Data)); checkImageData = CheckImageModal.fromJson(jsonDecode(base64Data));
@ -94,7 +94,7 @@ class _HistoryViewState extends State<HistoryView> {
_navigatorService.push(ImageShowRoute, _navigatorService.push(ImageShowRoute,
arguments: ImageShowModel( arguments: ImageShowModel(
data: checkImageData, data: checkImageData,
title: voucher.name, title: voucher.name ?? '',
url: voucher.url, url: voucher.url,
cardData: cardData, cardData: cardData,
voucher: voucher, voucher: voucher,
@ -105,7 +105,7 @@ class _HistoryViewState extends State<HistoryView> {
subtitle: Column( subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text(dateFormat.format(voucher.dateTime)), Text(dateFormat.format(voucher.dateTime!)),
cardData != null ? Text('${cardData.cardNumber} holder: ${cardData.cardholderName}') : Text(''), cardData != null ? Text('${cardData.cardNumber} holder: ${cardData.cardholderName}') : Text(''),
], ],
), ),
@ -138,7 +138,7 @@ class _HistoryViewState extends State<HistoryView> {
Text buildText(Voucher voucher) { Text buildText(Voucher voucher) {
if (voucher.type == VoucherTypePayment || voucher.type == VoucherTypeReturnPay) { if (voucher.type == VoucherTypePayment || voucher.type == VoucherTypeReturnPay) {
return Text( return Text(
'${voucher.name} на сумму: ${voucher.total.toStringAsFixed(2)}'); '${voucher.name} на сумму: ${voucher.total?.toStringAsFixed(2)}');
} }
return Text('${voucher.name}'); return Text('${voucher.name}');
} }

View File

@ -11,20 +11,20 @@ class BottomBar extends StatelessWidget {
final int selectedTabIndex; final int selectedTabIndex;
BottomBar({ BottomBar({
this.pageController, required this.pageController,
this.selectedTabIndex, required this.selectedTabIndex,
}); });
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StoreConnector<AppState, SettingState>( return StoreConnector<AppState, SettingState>(
converter: (store) => store.state.settingState, converter: (store) => store.state.settingState!,
builder: (context, vm) { builder: (context, vm) {
return BottomNavigationBar( return BottomNavigationBar(
currentIndex: selectedTabIndex, currentIndex: selectedTabIndex,
showUnselectedLabels: true,
backgroundColor: menuColor, backgroundColor: menuColor,
type: BottomNavigationBarType.shifting, type: BottomNavigationBarType.shifting,
showUnselectedLabels: true,
items: [ items: [
vm.mode == SettingModeKassa vm.mode == SettingModeKassa
? BottomNavigationBarItem( ? BottomNavigationBarItem(

View File

@ -11,7 +11,7 @@ class HeaderTitle extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StoreConnector<AppState, UserState>( return StoreConnector<AppState, UserState>(
converter: (store) => store.state.userState, converter: (store) => store.state.userState!,
builder: (context, vm) { builder: (context, vm) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
@ -30,7 +30,7 @@ class HeaderTitle extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Text( Text(
'Пользователь: ${vm.user.email}', 'Пользователь: ${vm.user?.email}',
overflow: TextOverflow.fade, overflow: TextOverflow.fade,
maxLines: 1, maxLines: 1,
softWrap: false, softWrap: false,
@ -39,10 +39,10 @@ class HeaderTitle extends StatelessWidget {
color: Colors.black, color: Colors.black,
), ),
), ),
vm.smena.message != null vm.smena?.message != null
? Text(vm.smena.message, ? Text(vm.smena!.message!,
style: TextStyle(fontSize: 13, color: redColor)) style: TextStyle(fontSize: 13, color: redColor))
: vm.smena.startedAt != null : vm.smena!.startedAt != null
? Text( ? Text(
'Смена открыта', 'Смена открыта',
overflow: TextOverflow.fade, overflow: TextOverflow.fade,

View File

@ -9,7 +9,7 @@ class PopupMenu extends StatefulWidget {
final void Function(Choice value) onSelectChoice; final void Function(Choice value) onSelectChoice;
PopupMenu({this.onSelectChoice}); PopupMenu({required this.onSelectChoice});
@override @override
_PopupMenuState createState() => _PopupMenuState(); _PopupMenuState createState() => _PopupMenuState();
@ -17,7 +17,7 @@ class PopupMenu extends StatefulWidget {
class _PopupMenuState extends State<PopupMenu> { class _PopupMenuState extends State<PopupMenu> {
BankService _bankService = locator<BankService>(); BankService _bankService = locator<BankService>();
List<Choice> choices; List<Choice> choices = <Choice>[];
@override @override
void initState() { void initState() {
// TODO: implement initState // TODO: implement initState
@ -34,6 +34,7 @@ class _PopupMenuState extends State<PopupMenu> {
// const Choice(title: 'Bank', icon: Icons.text_fields, command: 'bank'), // const Choice(title: 'Bank', icon: Icons.text_fields, command: 'bank'),
if (version >= _bankService.sdkVersion ) if (version >= _bankService.sdkVersion )
const Choice(title: 'Настройка HalykPos', icon: Icons.phonelink_lock_outlined, command: 'tap2phone'), const Choice(title: 'Настройка HalykPos', icon: Icons.phonelink_lock_outlined, command: 'tap2phone'),
const Choice(title: 'Настройка FortePos', icon: Icons.phonelink_lock_outlined, command: 'fortepos'),
const Choice(title: 'Настройки', icon: Icons.settings, command: 'settings'), const Choice(title: 'Настройки', icon: Icons.settings, command: 'settings'),
const Choice(title: 'Принтер', icon: Icons.print, command: 'print'), const Choice(title: 'Принтер', icon: Icons.print, command: 'print'),
const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit') const Choice(title: 'Выйти', icon: Icons.exit_to_app, command: 'exit')

View File

@ -34,8 +34,8 @@ class HomeView extends StatefulWidget {
class _HomeViewState extends State<HomeView> with WidgetsBindingObserver { class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
Logger log = getLogger('HomeView'); Logger log = getLogger('HomeView');
PageController pageController; late PageController pageController;
int selectedTabIndex; late int selectedTabIndex;
DataService _dataService = locator<DataService>(); DataService _dataService = locator<DataService>();
ApiService _api = locator<ApiService>(); ApiService _api = locator<ApiService>();
NavigatorService _navigatorService = locator<NavigatorService>(); NavigatorService _navigatorService = locator<NavigatorService>();
@ -55,8 +55,8 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
final prevState = sp.getInt(lastKnownStateKey); final prevState = sp.getInt(lastKnownStateKey);
final prevStateIsNotPaused = prevState != null && final prevStateIsNotPaused = prevState != null &&
AppLifecycleState.values[prevState] != AppLifecycleState.paused; AppLifecycleState.values[prevState] != AppLifecycleState.paused;
final bool pinIsExist = Redux.store.state.settingState?.pinCode?.isNotEmpty; final bool pinIsExist = Redux.store!.state.settingState?.pinCode != null && Redux.store!.state.settingState!.pinCode!.length > 3;
final bool pinSkipped = Redux.store.state.settingState.pinSkip; final bool pinSkipped = Redux.store!.state.settingState?.pinSkip == true;
print('prevStateIsNotPaused=$prevStateIsNotPaused, pinIsExist=$pinIsExist, pinSkipped=$pinSkipped'); print('prevStateIsNotPaused=$prevStateIsNotPaused, pinIsExist=$pinIsExist, pinSkipped=$pinSkipped');
if(prevStateIsNotPaused && pinSkipped == false && pinIsExist == true) { if(prevStateIsNotPaused && pinSkipped == false && pinIsExist == true) {
// save App backgrounded time to Shared preferences // save App backgrounded time to Shared preferences
@ -72,7 +72,7 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
final allowedBackgroundTime = bgTime + pinLockMillis; final allowedBackgroundTime = bgTime + pinLockMillis;
final shouldShowPIN = DateTime.now().millisecondsSinceEpoch > allowedBackgroundTime; final shouldShowPIN = DateTime.now().millisecondsSinceEpoch > allowedBackgroundTime;
if(shouldShowPIN && bgTime > 0) { if(shouldShowPIN && bgTime > 0) {
await Redux.store.dispatch(changePinLockedFromSetting(true)); await Redux.store!.dispatch(changePinLockedFromSetting(true));
pushToLockScreen(); pushToLockScreen();
} }
sp.remove(backgroundedTimeKey); // clean sp.remove(backgroundedTimeKey); // clean
@ -92,8 +92,8 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
} }
_checkLockPin () async { _checkLockPin () async {
final bool pinIsExist = Redux.store.state.settingState?.pinCode?.isNotEmpty; final bool pinIsExist = Redux.store!.state.settingState?.pinCode != null && Redux.store!.state.settingState!.pinCode!.length > 3;
final bool pinLocked = Redux.store.state.settingState?.pinLocked; final bool pinLocked = Redux.store!.state.settingState?.pinLocked == true;
final sp = await SharedPreferences.getInstance(); final sp = await SharedPreferences.getInstance();
sp.remove(backgroundedTimeKey); sp.remove(backgroundedTimeKey);
sp.setInt(lastKnownStateKey, AppLifecycleState.resumed.index);// previous state sp.setInt(lastKnownStateKey, AppLifecycleState.resumed.index);// previous state
@ -109,8 +109,8 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
selectedTabIndex = 0; selectedTabIndex = 0;
pageController = new PageController(initialPage: selectedTabIndex); pageController = new PageController(initialPage: selectedTabIndex);
Redux.store.dispatch(checkSmena); Redux.store!.dispatch(checkSmena);
_dataService.checkDbFill(Redux.store.state.userState.user); _dataService.checkDbFill(Redux.store!.state.userState!.user!);
_checkLockPin(); _checkLockPin();
} }
@ -143,12 +143,11 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
void _onSelectChoice(Choice choice) async { void _onSelectChoice(Choice choice) async {
if (choice.command == 'exit') { if (choice.command == 'exit') {
Dialogs.showLoadingDialog(context, _keyLoader); Dialogs.showLoadingDialog(context, _keyLoader);
Response<dynamic> result = Response<dynamic> result = await _api.logout(Redux.store!.state.userState!.user!.token!);
await _api.logout(Redux.store.state.userState.user.token);
if(result.operation && result.status == 200) { if(result.operation && result.status == 200) {
Redux.store.dispatch(logoutAction); Redux.store!.dispatch(logoutAction);
} }
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
} else if (choice.command == 'infokkm') { } else if (choice.command == 'infokkm') {
_navigatorService.push(InfoKkmViewRoute); _navigatorService.push(InfoKkmViewRoute);
} else if (choice.command == 'settings') { } else if (choice.command == 'settings') {
@ -159,6 +158,8 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
_navigatorService.push(BankViewRoute); _navigatorService.push(BankViewRoute);
} else if (choice.command == 'tap2phone') { } else if (choice.command == 'tap2phone') {
_navigatorService.push(BankSettingViewRoute); _navigatorService.push(BankSettingViewRoute);
} else if (choice.command == 'fortepos') {
_navigatorService.push(ForteSettingViewRoute);
} }
} }
@ -167,7 +168,6 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
titleSpacing: 5.0, titleSpacing: 5.0,
brightness: Brightness.light,
title: HeaderTitle(), title: HeaderTitle(),
actions: <Widget>[ actions: <Widget>[
PopupMenu( PopupMenu(
@ -177,9 +177,10 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
backgroundColor: fillColor, backgroundColor: fillColor,
), ),
body:StoreConnector<AppState, SettingState>( body:StoreConnector<AppState, SettingState>(
converter: (store) => store.state.settingState, converter: (store) => store.state.settingState!,
builder: (context, vm) { builder: (context, vm) {
return PageView( return PageView(
pageSnapping: true,
onPageChanged: (index) { onPageChanged: (index) {
setState(() { setState(() {
selectedTabIndex = index; selectedTabIndex = index;
@ -191,7 +192,8 @@ class _HomeViewState extends State<HomeView> with WidgetsBindingObserver {
AdditionalTab(1), AdditionalTab(1),
], ],
); );
}), }
),
bottomNavigationBar: BottomBar( bottomNavigationBar: BottomBar(
pageController: pageController, pageController: pageController,
selectedTabIndex: selectedTabIndex, selectedTabIndex: selectedTabIndex,

View File

@ -3,8 +3,10 @@ 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/check_image_modal.dart';
import 'package:aman_kassa_flutter/core/models/close_day_data.dart'; import 'package:aman_kassa_flutter/core/models/halyk/close_day_data.dart' as halyk_models;
import 'package:aman_kassa_flutter/core/models/forte/close_day_data.dart' as forte_models;
import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart'; import 'package:aman_kassa_flutter/core/models/halyk/halyk_close_day_dao.dart';
import 'package:aman_kassa_flutter/core/models/forte/forte_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';
@ -12,6 +14,7 @@ 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/BankService.dart';
import 'package:aman_kassa_flutter/core/services/ForteService.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';
@ -27,11 +30,14 @@ 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:aman_kassa_flutter/views/payment/halyk_pos_service.dart' as halyk;
import 'package:aman_kassa_flutter/views/payment/forte_pos_service.dart' as forte;
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';
import '../../../redux/state/bank_state.dart';
class AdditionalTab extends StatefulWidget { class AdditionalTab extends StatefulWidget {
final int index; final int index;
@ -45,18 +51,18 @@ 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>(); dynamic _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; late bool isMoneyCheckBusy;
bool isClosePosBusy; late bool closeSmenaBusy;
bool closeSmenaBusy; late bool openSmenaBusy;
bool openSmenaBusy; late bool depositBusy;
bool depositBusy; late bool withdrawalBusy;
bool withdrawalBusy; late bool xReportBusy;
bool xReportBusy; late bool updateCatalog;
bool updateCatalog; late bool isClosePosBusy;
@override @override
void initState() { void initState() {
@ -76,7 +82,7 @@ class _AdditionalTabState extends State<AdditionalTab> {
closeSmenaBusy = true; closeSmenaBusy = true;
}); });
try { try {
await Redux.store.dispatch(closeSmena); await Redux.store!.dispatch(closeSmena);
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
@ -91,7 +97,7 @@ class _AdditionalTabState extends State<AdditionalTab> {
openSmenaBusy = true; openSmenaBusy = true;
}); });
try { try {
await Redux.store.dispatch(openSmena); await Redux.store!.dispatch(openSmena);
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
@ -106,15 +112,16 @@ class _AdditionalTabState extends State<AdditionalTab> {
xReportBusy = true; xReportBusy = true;
}); });
try { try {
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']; String check = response.body['check'];
var checkText = response.body['check_text']; var checkText = response.body['check_text'];
_navigator.push(ImageShowRoute, _navigator.push(ImageShowRoute,
arguments: arguments:
ImageShowModel(data: CheckImageModal(base64Data: check, textData: checkText !=null ? jsonEncode(checkText) : null ), 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,
name: 'X Отчет', name: 'X Отчет',
@ -139,8 +146,8 @@ class _AdditionalTabState extends State<AdditionalTab> {
}); });
try { try {
Dialogs.showLoadingDialog(context, _keyLoader); Dialogs.showLoadingDialog(context, _keyLoader);
await _dataService.getDataFromServer(Redux.store.state.userState.user); await _dataService.getDataFromServer(Redux.store!.state.userState!.user!);
Navigator.of(_keyLoader.currentContext, rootNavigator: true).pop(); Navigator.of(_keyLoader.currentContext!, rootNavigator: true).pop();
} catch (e) { } catch (e) {
print(e); print(e);
} finally { } finally {
@ -162,10 +169,10 @@ class _AdditionalTabState extends State<AdditionalTab> {
); );
if (response.confirmed) { if (response.confirmed) {
Response<dynamic> result = await _api.deposit( Response<dynamic> result = await _api.deposit(
Redux.store.state.userState.user.token, response.responseText); Redux.store!.state.userState!.user!.token!, response.responseText!);
_dialog.showDialog(description: result.body['message']); _dialog.showDialog(description: result.body['message']);
if (result.operation) { if (result.operation) {
await Redux.store.dispatch(checkMoney); await Redux.store!.dispatch(checkMoney);
} }
} }
} catch (e) { } catch (e) {
@ -189,10 +196,10 @@ class _AdditionalTabState extends State<AdditionalTab> {
); );
if (response.confirmed) { if (response.confirmed) {
Response<dynamic> result = await _api.withdrawal( Response<dynamic> result = await _api.withdrawal(
Redux.store.state.userState.user.token, response.responseText); Redux.store!.state.userState!.user!.token!, response.responseText!);
_dialog.showDialog(description: result.body['message']); _dialog.showDialog(description: result.body['message']);
if (result.operation) { if (result.operation) {
await Redux.store.dispatch(checkMoney); await Redux.store!.dispatch(checkMoney);
} }
} }
} catch (e) { } catch (e) {
@ -209,7 +216,7 @@ class _AdditionalTabState extends State<AdditionalTab> {
isMoneyCheckBusy = true; isMoneyCheckBusy = true;
}); });
try { try {
await Redux.store.dispatch(checkMoney); await Redux.store!.dispatch(checkMoney);
setState(() { setState(() {
isMoneyCheckBusy = false; isMoneyCheckBusy = false;
}); });
@ -227,6 +234,14 @@ class _AdditionalTabState extends State<AdditionalTab> {
isClosePosBusy = true; isClosePosBusy = true;
}); });
BankState? state = Redux.store?.state.bankState;
if (state?.sessionType == 'Halyk' && state?.session != null) {
_bankService = locator<BankService>();
} else if (state?.sessionType == 'Forte' && state?.session != null) {
_bankService = locator<ForteService>();
}
int version = await _bankService.version(); int version = await _bankService.version();
if (version < _bankService.sdkVersion ) { if (version < _bankService.sdkVersion ) {
setState(() { setState(() {
@ -235,14 +250,24 @@ class _AdditionalTabState extends State<AdditionalTab> {
_dialog.showDialog(description: 'Функция Tap2Phone доступна c Android версии 8.1'); _dialog.showDialog(description: 'Функция Tap2Phone доступна c Android версии 8.1');
return; return;
} }
final isForteSessionActive = state?.sessionType == 'Forte';
await Redux.store.dispatch(changePinSkipFromSetting(true)); await Redux.store!.dispatch(changePinSkipFromSetting(true));
HalykCloseDayDao closeDayDao = await closeDayHalykPos();
await Redux.store.dispatch(changePinSkipFromSetting(false)); dynamic closeDayDao;
log.i(closeDayDao.toJson()); if (isForteSessionActive) {
if (closeDayDao.result.code != 0) { closeDayDao = await forte.closeDayFortePos();
if (closeDayDao.result.description != null) { } else {
_dialog.showDialog(description: closeDayDao.result.description); closeDayDao = await halyk.closeDayHalykPos();
}
await Redux.store!.dispatch(changePinSkipFromSetting(false));
forte.log.i(closeDayDao.toJson());
halyk.log.i(closeDayDao.toJson());
if (closeDayDao?.result?.code != 0) {
if (closeDayDao!.result?.description != null) {
_dialog.showDialog(description: closeDayDao.result!.description!);
} }
setState(() { setState(() {
isClosePosBusy = false; isClosePosBusy = false;
@ -250,24 +275,27 @@ class _AdditionalTabState extends State<AdditionalTab> {
return; return;
} }
User user = Redux.store!.state.userState!.user!;
CloseDayData closeDayData = _bankService.closeDayDataConvert(closeDayDao.transactions); if (isForteSessionActive) {
final closeDayData = _bankService.closeDayDataConvert(closeDayDao!.transactions!);
User user = Redux.store.state.userState.user;
_dataService.insertVoucher( _dataService.insertVoucher(
user: user, user: user,
name: closeDayData.title, name: closeDayData.title!,
data: jsonEncode(closeDayData.toJson()), data: jsonEncode(closeDayData.toJson()),
total: closeDayData.totalAmount.toDouble(), total: closeDayData.totalAmount!.toDouble(),
type: VoucherTypeCloseDayPosReport); type: VoucherTypeCloseDayPosReport);
} else {
final closeDayData = _bankService.closeDayDataConvert(closeDayDao!.transactions!);
// _dialog.showDialog(description: 'Закрытие дня: операция прошла успешно!'); _dataService.insertVoucher(
setState(() { user: user,
isClosePosBusy = false; name: closeDayData.title!,
}); data: jsonEncode(closeDayData.toJson()),
total: closeDayData.totalAmount!.toDouble(),
_navigator.push(CloseDayShowRoute, type: VoucherTypeCloseDayPosReport);
arguments: closeDayData); }
} }
@override @override
@ -282,7 +310,7 @@ class _AdditionalTabState extends State<AdditionalTab> {
right: 20.0, right: 20.0,
), ),
child: StoreConnector<AppState, SettingState>( child: StoreConnector<AppState, SettingState>(
converter: (store) => store.state.settingState, converter: (store) => store.state.settingState!,
builder: (context, vm) { builder: (context, vm) {
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -336,7 +364,7 @@ class _AdditionalTabState extends State<AdditionalTab> {
height: 50, height: 50,
// width: double.infinity, // width: double.infinity,
child: StoreConnector<AppState, Money>( child: StoreConnector<AppState, Money>(
converter: (store) => store.state.userState.money, converter: (store) => store.state.userState!.money!,
builder: (_, vm) { builder: (_, vm) {
if (vm.loading == true) { if (vm.loading == true) {
return Center( return Center(
@ -478,6 +506,6 @@ class _AdditionalTabState extends State<AdditionalTab> {
} }
void changeMode(el) { void changeMode(el) {
Redux.store.dispatch(changeModeFromSetting(el)); Redux.store!.dispatch(changeModeFromSetting(el));
} }
} }

View File

@ -28,18 +28,17 @@ class CalculatorTab extends StatelessWidget {
body: Column( body: Column(
children: <Widget>[ children: <Widget>[
StoreConnector<AppState, CalcState>( StoreConnector<AppState, CalcState>(
converter: (store) => store.state.calcState, converter: (store) => store.state.calcState!,
builder: (context, vm) { builder: (context, vm) {
return NumberDisplay( return NumberDisplay(
value: Calculator.parseItems(vm.calcItems, vm.isEqual)); value: Calculator.parseItems(vm.calcItems!, vm.isEqual!));
}), }),
CalculatorButtons(onTap: _onPress), CalculatorButtons(onTap: _onPress),
Row( Row(
children: <Widget>[ children: <Widget>[
Expanded( Expanded(
child: RaisedButton( child: ElevatedButton(
padding: EdgeInsets.all(16.0), style: ElevatedButton.styleFrom(backgroundColor: redColor, padding: EdgeInsets.all(16.0)),
color: redColor,
child: Text( child: Text(
"возврат", "возврат",
style: buttonBigTitleTextStyle, style: buttonBigTitleTextStyle,
@ -52,9 +51,8 @@ class CalculatorTab extends StatelessWidget {
}), }),
), ),
Expanded( Expanded(
child: RaisedButton( child: ElevatedButton(
padding: EdgeInsets.all(16.0), style: ElevatedButton.styleFrom(backgroundColor: greenColor, padding: EdgeInsets.all(16.0)),
color: greenColor,
child: Text( child: Text(
"оплата", "оплата",
style: buttonBigTitleTextStyle, style: buttonBigTitleTextStyle,
@ -74,7 +72,7 @@ class CalculatorTab extends StatelessWidget {
)); ));
} }
void _onPress({String buttonText}) { void _onPress({required String buttonText}) {
Redux.store.dispatch(onTapAction(buttonText)); Redux.store!.dispatch(onTapAction(buttonText));
} }
} }

View File

@ -1,8 +1,10 @@
import 'package:aman_kassa_flutter/core/entity/Goods.dart'; import 'package:aman_kassa_flutter/core/entity/Goods.dart';
import 'package:aman_kassa_flutter/core/locator.dart'; import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/nct_product.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/route_names.dart'; import 'package:aman_kassa_flutter/core/route_names.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/NctService.dart' show NctService, NctServiceException;
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';
@ -17,10 +19,10 @@ import 'package:aman_kassa_flutter/views/home/tabs/kassaView/CatalogBottomSheet.
import 'package:aman_kassa_flutter/views/home/tabs/kassaView/ProductAddBottomSheet.dart'; import 'package:aman_kassa_flutter/views/home/tabs/kassaView/ProductAddBottomSheet.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/widgets/components/ProductListItem.dart'; import 'package:aman_kassa_flutter/widgets/components/ProductListItem.dart';
import 'package:barcode_scan/gen/protos/protos.pb.dart'; import 'package:barcode_scan2/gen/protos/protos.pb.dart';
import 'package:barcode_scan/gen/protos/protos.pbenum.dart'; import 'package:barcode_scan2/gen/protos/protos.pbenum.dart';
import 'package:barcode_scan/model/scan_options.dart'; import 'package:barcode_scan2/model/scan_options.dart';
import 'package:barcode_scan/platform_wrapper.dart'; import 'package:barcode_scan2/platform_wrapper.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.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';
@ -30,6 +32,7 @@ class KassaTab extends StatelessWidget {
final NavigatorService _navigatorService = locator<NavigatorService>(); final NavigatorService _navigatorService = locator<NavigatorService>();
final DialogService _dialogService = locator<DialogService>(); final DialogService _dialogService = locator<DialogService>();
final DataService _dataService = locator<DataService>(); final DataService _dataService = locator<DataService>();
final NctService _nctService = locator<NctService>();
final int index; final int index;
@ -69,9 +72,8 @@ class KassaTab extends StatelessWidget {
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.all(4.0), padding: const EdgeInsets.all(4.0),
child: RaisedButton( child: ElevatedButton(
padding: const EdgeInsets.all(8), style: ElevatedButton.styleFrom(backgroundColor: primaryColor, padding: const EdgeInsets.all(8)),
color: primaryColor,
child: Text( child: Text(
"Добавить", "Добавить",
style: buttonBigTitleTextStyle, style: buttonBigTitleTextStyle,
@ -85,9 +87,8 @@ class KassaTab extends StatelessWidget {
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.all(4.0), padding: const EdgeInsets.all(4.0),
child: RaisedButton( child: ElevatedButton(
padding: EdgeInsets.all(8), style: ElevatedButton.styleFrom(backgroundColor: greenColor, padding: EdgeInsets.all(8)),
color: greenColor,
child: Text( child: Text(
"Каталог", "Каталог",
style: buttonBigTitleTextStyle, style: buttonBigTitleTextStyle,
@ -103,12 +104,12 @@ class KassaTab extends StatelessWidget {
Expanded( Expanded(
child: Container( child: Container(
child: StoreConnector<AppState, KassaState>( child: StoreConnector<AppState, KassaState>(
converter: (store) => store.state.kassaState, converter: (store) => store.state.kassaState!,
builder: (context, vm) { builder: (context, vm) {
return ListView.builder( return ListView.builder(
itemCount: vm.kassaItems.length, itemCount: vm.kassaItems!.length,
itemBuilder: (BuildContext ctxt, int index) => itemBuilder: (BuildContext ctxt, int index) =>
buildItem(ctxt, index, vm.kassaItems[index])); buildItem(ctxt, index, vm.kassaItems![index]));
}), }),
), ),
), ),
@ -119,9 +120,9 @@ class KassaTab extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.end, mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[ children: <Widget>[
StoreConnector<AppState, KassaState>( StoreConnector<AppState, KassaState>(
converter: (store) => store.state.kassaState, converter: (store) => store.state.kassaState!,
builder: (context, vm) { builder: (context, vm) {
return Text(totalCalc(vm.kassaItems), return Text(totalCalc(vm.kassaItems!),
style: TextStyle(fontSize: 25)); style: TextStyle(fontSize: 25));
}), }),
], ],
@ -132,9 +133,8 @@ class KassaTab extends StatelessWidget {
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.all(4.0), padding: const EdgeInsets.all(4.0),
child: RaisedButton( child: ElevatedButton(
padding: const EdgeInsets.all(8), style: ElevatedButton.styleFrom(backgroundColor: redColor, padding: const EdgeInsets.all(8)),
color: redColor,
child: Text( child: Text(
"возврат", "возврат",
style: buttonBigTitleTextStyle, style: buttonBigTitleTextStyle,
@ -150,9 +150,8 @@ class KassaTab extends StatelessWidget {
Expanded( Expanded(
child: Padding( child: Padding(
padding: const EdgeInsets.all(4.0), padding: const EdgeInsets.all(4.0),
child: RaisedButton( child: ElevatedButton(
padding: const EdgeInsets.all(8), style: ElevatedButton.styleFrom(backgroundColor: greenColor, padding: const EdgeInsets.all(8)),
color: greenColor,
child: Text( child: Text(
"оплата", "оплата",
style: buttonBigTitleTextStyle, style: buttonBigTitleTextStyle,
@ -184,7 +183,7 @@ class KassaTab extends StatelessWidget {
Future<void> scan() async { Future<void> scan() async {
try { try {
await Redux.store.dispatch(changePinSkipFromSetting(true)); await Redux.store!.dispatch(changePinSkipFromSetting(true));
var options = ScanOptions(strings: { var options = ScanOptions(strings: {
"cancel": 'Отмена', "cancel": 'Отмена',
"flash_on": 'Вкл фонарик', "flash_on": 'Вкл фонарик',
@ -197,8 +196,8 @@ class KassaTab extends StatelessWidget {
// print(result.formatNote); // If a unknown format was scanned this field contains a note // print(result.formatNote); // If a unknown format was scanned this field contains a note
// print(result.rawContent); // content // print(result.rawContent); // content
if (result.type == ResultType.Barcode ) { if (result.type == ResultType.Barcode ) {
String barcode; String? barcode;
String dataMatrix; String? dataMatrix;
if(result.format == BarcodeFormat.ean13 || result.format == BarcodeFormat.ean8) { if(result.format == BarcodeFormat.ean13 || result.format == BarcodeFormat.ean8) {
barcode = result.rawContent; barcode = result.rawContent;
} else if( result.format == BarcodeFormat.dataMatrix ) { } else if( result.format == BarcodeFormat.dataMatrix ) {
@ -219,10 +218,22 @@ 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) {
await Redux.store.dispatch(addProductToKassaItems(goods.first, dataMatrix)); await Redux.store!.dispatch(addProductToKassaItems(goods.first, dataMatrix));
} else { } else {
_dialogService.showDialog( try {
description: 'Товар не найден: $barcode'); List<NctProduct> nctResults = await _nctService.searchByNtin(barcode);
if (nctResults.isNotEmpty) {
final NctProduct nctProduct = nctResults.first;
final String? name = nctProduct.nameRu ?? nctProduct.nameKk;
_openAddSheetWithName(name, ntinCode: nctProduct.ntinCode);
} else {
_dialogService.showDialog(description: 'Товар не найден: $barcode');
}
} on NctServiceException catch (e) {
_dialogService.showDialog(description: e.message);
} catch (e) {
_dialogService.showDialog(description: 'Ошибка поиска NCT: $e');
}
} }
} else if (result.type == ResultType.Error) { } else if (result.type == ResultType.Error) {
_dialogService.showDialog(description: 'Не верный формат QR кода'); _dialogService.showDialog(description: 'Не верный формат QR кода');
@ -241,12 +252,18 @@ class KassaTab extends StatelessWidget {
_dialogService.showDialog(description: 'Неизвестная ошибка: $e'); _dialogService.showDialog(description: 'Неизвестная ошибка: $e');
} }
} finally { } finally {
await Redux.store.dispatch(changePinSkipFromSetting(false)); await Redux.store!.dispatch(changePinSkipFromSetting(false));
} }
} }
void _openAddSheetWithName(String? name, {String? ntinCode}) {
_navigatorService.navigateToPage(
MaterialPageRoute(builder: (_) => ProductAddBottomSheet(initialName: name, initialNtinCode: ntinCode))
);
}
void showModalBottomSheetCatalog(BuildContext context, String action) { void showModalBottomSheetCatalog(BuildContext context, String action) {
if (action == 'add') { if (action == 'add') {

View File

@ -15,20 +15,20 @@ import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_redux/flutter_redux.dart';
class CatalogBottomSheet extends StatelessWidget { class CatalogBottomSheet extends StatelessWidget {
final ScrollController scrollController; final ScrollController? scrollController;
CatalogBottomSheet({this.scrollController}); CatalogBottomSheet({this.scrollController});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return StoreConnector<AppState, KassaState>( return StoreConnector<AppState, KassaState>(
converter: (store) => store.state.kassaState, converter: (store) => store.state.kassaState!,
onInit: (store) => Redux.store.dispatch(selectBottomElement(0)), onInit: (store) => Redux.store!.dispatch(selectBottomElement(0)),
builder: (context, vm) { builder: (context, vm) {
return WillPopScope( return WillPopScope(
onWillPop: () { onWillPop: () {
if (vm.prevCategories.length > 0) { if (vm.prevCategories!.length > 0) {
Redux.store.dispatch(backBottomElement); Redux.store!.dispatch(backBottomElement);
} else } else
Navigator.pop(context); Navigator.pop(context);
return new Future(() => false); return new Future(() => false);
@ -36,8 +36,8 @@ class CatalogBottomSheet extends StatelessWidget {
child: Scaffold( child: Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text( title: Text(
vm.prevCategories.isNotEmpty vm.prevCategories!.isNotEmpty
? vm.prevCategories?.last?.name ? vm.prevCategories!.last.name
: '', : '',
style: TextStyle(color: Colors.black45), style: TextStyle(color: Colors.black45),
), ),
@ -45,12 +45,12 @@ class CatalogBottomSheet extends StatelessWidget {
backgroundColor: whiteColor, backgroundColor: whiteColor,
elevation: 1, elevation: 1,
leading: IconButton( leading: IconButton(
icon: Icon(vm.prevCategories.length > 0 icon: Icon(vm.prevCategories!.length > 0
? Icons.arrow_back ? Icons.arrow_back
: Icons.close), : Icons.close),
onPressed: () { onPressed: () {
if (vm.prevCategories.length > 0) { if (vm.prevCategories!.length > 0) {
Redux.store.dispatch(backBottomElement); Redux.store!.dispatch(backBottomElement);
} else } else
Navigator.pop(context); Navigator.pop(context);
}, },
@ -63,11 +63,11 @@ class CatalogBottomSheet extends StatelessWidget {
Expanded( Expanded(
child: ListView.builder( child: ListView.builder(
controller: scrollController, controller: scrollController,
itemCount: vm.bottomSheetElements.length, itemCount: vm.bottomSheetElements!.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
var el = vm.bottomSheetElements[index]; var el = vm.bottomSheetElements![index];
String name; String? name;
String price; String? price;
if (el is Category) { if (el is Category) {
Category category = el; Category category = el;
name = category.name; name = category.name;
@ -86,19 +86,19 @@ class CatalogBottomSheet extends StatelessWidget {
? Icon(Icons.layers, size: 25) ? Icon(Icons.layers, size: 25)
: null, : null,
title: Text( title: Text(
name, name ?? '',
style: TextStyle(fontSize: 15), style: TextStyle(fontSize: 15),
), ),
onTap: () async { onTap: () async {
if (el is Category) { if (el is Category) {
Redux.store Redux.store!
.dispatch(selectBottomElement(el.id)); .dispatch(selectBottomElement(el.id!));
} else if (el is Good) { } else if (el is Good) {
await Redux.store await Redux.store!
.dispatch(addProductToKassaItems(el, null)); .dispatch(addProductToKassaItems(el, null));
Navigator.pop(context); Navigator.pop(context);
} else if (el is Service) { } else if (el is Service) {
await Redux.store await Redux.store!
.dispatch(addServiceToKassaItems(el)); .dispatch(addServiceToKassaItems(el));
Navigator.pop(context); Navigator.pop(context);
} }
@ -106,7 +106,7 @@ class CatalogBottomSheet extends StatelessWidget {
trailing: el is Category trailing: el is Category
? Icon(Icons.chevron_right) ? Icon(Icons.chevron_right)
: Text( : Text(
price, price ?? '',
style: TextStyle( style: TextStyle(
fontSize: 15, color: Colors.black54), fontSize: 15, color: Colors.black54),
), ),
@ -115,12 +115,12 @@ class CatalogBottomSheet extends StatelessWidget {
}, },
), ),
), ),
RaisedButton( ElevatedButton(
child: Text( child: Text(
'Отмена', 'Отмена',
style: buttonBigTitleTextStyle, style: buttonBigTitleTextStyle,
), ),
color: redColor, style: ElevatedButton.styleFrom(backgroundColor: redColor),
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);
}), }),
@ -135,12 +135,12 @@ class CatalogBottomSheet extends StatelessWidget {
return Container( return Container(
margin: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 5.0), margin: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 5.0),
child: StoreConnector<AppState, KassaState>( child: StoreConnector<AppState, KassaState>(
converter: (store) => store.state.kassaState, converter: (store) => store.state.kassaState!,
builder: (_, mainState) { builder: (_, mainState) {
return StoreConnector<AppState, SettingState>( return StoreConnector<AppState, SettingState>(
converter: (store) => store.state.settingState, converter: (store) => store.state.settingState!,
builder: (_, settingState) { builder: (_, settingState) {
if (mainState.kassaItems.isNotEmpty) { if (mainState.kassaItems!.isNotEmpty) {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
locator<DialogService>().showDialog( locator<DialogService>().showDialog(
@ -169,8 +169,8 @@ class CatalogBottomSheet extends StatelessWidget {
underline: Container( underline: Container(
height: 1, height: 1,
), ),
onChanged: (String newValue) { onChanged: (String? newValue) {
onChangeTradeType(newValue, settingState.tradeType); onChangeTradeType(newValue!, settingState.tradeType!);
}, },
items: [ items: [
DropdownMenuItem<String>( DropdownMenuItem<String>(
@ -190,8 +190,8 @@ class CatalogBottomSheet extends StatelessWidget {
void onChangeTradeType(String newValue, String oldValue) async { void onChangeTradeType(String newValue, String oldValue) async {
if (oldValue != newValue) { if (oldValue != newValue) {
await Redux.store.dispatch(changeTradeTypeFromSetting(newValue)); await Redux.store!.dispatch(changeTradeTypeFromSetting(newValue));
await Redux.store.dispatch(selectBottomElement(0)); await Redux.store!.dispatch(selectBottomElement(0));
} }
} }
} }

View File

@ -1,3 +1,6 @@
import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/models/nct_product.dart';
import 'package:aman_kassa_flutter/core/services/NctService.dart' show NctService, NctServiceException;
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/store.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';
@ -6,30 +9,40 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
class ProductAddBottomSheet extends StatefulWidget { class ProductAddBottomSheet extends StatefulWidget {
final ScrollController scrollController; final ScrollController? scrollController;
final String? initialName;
final String? initialNtinCode;
ProductAddBottomSheet({this.scrollController}); ProductAddBottomSheet({this.scrollController, this.initialName, this.initialNtinCode});
@override @override
_ProductAddBottomSheetState createState() => _ProductAddBottomSheetState(); _ProductAddBottomSheetState createState() => _ProductAddBottomSheetState();
} }
class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> { class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
TextEditingController nameController; final NctService _nctService = locator<NctService>();
TextEditingController countController;
TextEditingController priceController; late TextEditingController ntinController;
late TextEditingController nameController;
late TextEditingController countController;
late TextEditingController priceController;
double sum = 0.0; double sum = 0.0;
bool _isSearching = false;
String? _foundNtinCode;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
nameController = new TextEditingController(); ntinController = new TextEditingController();
nameController = new TextEditingController(text: widget.initialName ?? '');
countController = new TextEditingController(); countController = new TextEditingController();
priceController = new TextEditingController(); priceController = new TextEditingController();
_foundNtinCode = widget.initialNtinCode;
} }
@override @override
void dispose() { void dispose() {
ntinController.dispose();
nameController.dispose(); nameController.dispose();
countController.dispose(); countController.dispose();
priceController.dispose(); priceController.dispose();
@ -55,6 +68,44 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
child: ListView( child: ListView(
controller: widget.scrollController, controller: widget.scrollController,
children: <Widget>[ children: <Widget>[
Row(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Expanded(
child: TextField(
decoration: new InputDecoration(
border: new OutlineInputBorder(
borderSide: new BorderSide(color: primaryColor)),
hintText: 'Введите NTIN/GTIN',
labelText: 'NTIN/GTIN',
prefixText: ' ',
),
keyboardType: TextInputType.text,
controller: ntinController,
),
),
SizedBox(width: 8),
SizedBox(
height: 56,
child: ElevatedButton(
onPressed: _isSearching ? null : _searchByNtin,
style: ElevatedButton.styleFrom(
backgroundColor: primaryColor,
padding: EdgeInsets.symmetric(horizontal: 12),
),
child: _isSearching
? SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
color: Colors.white, strokeWidth: 2),
)
: Icon(Icons.search, color: Colors.white),
),
),
],
),
verticalSpaceSmall,
TextField( TextField(
decoration: new InputDecoration( decoration: new InputDecoration(
border: new OutlineInputBorder( border: new OutlineInputBorder(
@ -75,11 +126,10 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
prefixText: ' ', prefixText: ' ',
), ),
keyboardType: const TextInputType.numberWithOptions( keyboardType: const TextInputType.numberWithOptions(
decimal: false, decimal: true,
), ),
inputFormatters: <TextInputFormatter>[ inputFormatters: <TextInputFormatter>[
// WhitelistingTextInputFormatter.digitsOnly FilteringTextInputFormatter.allow(RegExp("^[0-9.]*")),
FilteringTextInputFormatter.digitsOnly
], ],
controller: countController, controller: countController,
onChanged: calcOnChange, onChanged: calcOnChange,
@ -151,17 +201,52 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
); );
} }
Future<void> _searchByNtin() async {
final ntin = ntinController.text.trim();
if (ntin.isEmpty) {
_showErrorDialog('Введите NTIN/GTIN для поиска.');
return;
}
setState(() => _isSearching = true);
try {
List<NctProduct> results = await _nctService.searchByNtin(ntin);
if (results.isNotEmpty) {
final product = results.first;
setState(() {
nameController.text = product.nameRu ?? product.nameKk ?? '';
_foundNtinCode = product.ntinCode;
});
if (product.ntinIsDeactivated == true) {
String reason = product.ntinDeactivationReason ?? '';
String duplicate = product.ntinDuplicateOfProduct != null
? '\nДубликат: ${product.ntinDuplicateOfProduct}'
: '';
_showErrorDialog('Карточка деактивирована.$reason$duplicate');
}
} else {
_showErrorDialog('Товар с NTIN/GTIN "$ntin" не найден.');
}
} on NctServiceException catch (e) {
_showErrorDialog(e.message);
} catch (e) {
_showErrorDialog('Ошибка поиска NCT: $e');
} finally {
setState(() => _isSearching = false);
}
}
void submit() { void submit() {
if (nameController.text.isEmpty || if (nameController.text.isEmpty ||
countController.text.isEmpty || countController.text.isEmpty ||
priceController.text.isEmpty) { priceController.text.isEmpty) {
_showDialog(); _showErrorDialog('Введите наименование, количество и цену');
} else { } else {
Redux.store.dispatch(addCustomProductToKassaItems( Redux.store!.dispatch(addCustomProductToKassaItems(
nameController.text, nameController.text,
int.parse(countController.text), double.parse(countController.text),
double.parse(priceController.text), double.parse(priceController.text),
sum)); sum,
ntin: _foundNtinCode));
Navigator.pop(context); Navigator.pop(context);
} }
} }
@ -184,18 +269,17 @@ class _ProductAddBottomSheetState extends State<ProductAddBottomSheet> {
} }
} }
void _showDialog() { void _showErrorDialog(String message) {
// flutter defined function
showDialog( showDialog(
context: context, context: context,
builder: (BuildContext context) { builder: (BuildContext context) {
return AlertDialog( return AlertDialog(
title: new Text("Aman Касса"), title: new Text("Aman Касса"),
content: new Text("Введите наименование, количество и цену"), content: new Text(message),
actions: <Widget>[ actions: <Widget>[
FlatButton( TextButton(
child: Text( child: Text(
"ОK", "ОК",
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold), style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold),
), ),
onPressed: () { onPressed: () {

View File

@ -28,8 +28,8 @@ class _InfoKkmViewState extends State<InfoKkmView> {
setState(() { setState(() {
loading = true; loading = true;
}); });
User user = Redux.store.state.userState.user; User user = Redux.store!.state.userState!.user!;
Response<dynamic> response = await _apiService.infoKkm(user.token); Response<dynamic> response = await _apiService.infoKkm(user.token!);
if (response.operation) { if (response.operation) {
List<dynamic> list = []; List<dynamic> list = [];
for (var key in response.body.keys) { for (var key in response.body.keys) {

View File

@ -8,7 +8,7 @@ import 'package:aman_kassa_flutter/core/locator.dart';
import 'package:aman_kassa_flutter/core/services/navigator_service.dart'; import 'package:aman_kassa_flutter/core/services/navigator_service.dart';
class PassCodeScreen extends StatefulWidget { class PassCodeScreen extends StatefulWidget {
PassCodeScreen({Key key, this.title}) : super(key: key); PassCodeScreen({Key? key, required this.title}) : super(key: key);
final String title; final String title;
@ -45,7 +45,7 @@ class _PassCodeScreenState extends State<PassCodeScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
var myPass = []; var myPass = [];
String _pinCode = Redux.store.state.settingState.pinCode; String _pinCode = Redux.store!.state.settingState!.pinCode!;
for (var i = 0; i < _pinCode.length; i++) { for (var i = 0; i < _pinCode.length; i++) {
myPass.add(int.parse(_pinCode[i])); myPass.add(int.parse(_pinCode[i]));
} }
@ -72,7 +72,7 @@ class _PassCodeScreenState extends State<PassCodeScreen> {
return true; return true;
}, },
onSuccess: () { onSuccess: () {
Redux.store.dispatch(changePinLockedFromSetting(false)); Redux.store!.dispatch(changePinLockedFromSetting(false));
_navigatorService.replace(HomeViewRoute); _navigatorService.replace(HomeViewRoute);
}); });
} }

Some files were not shown because too many files have changed in this diff Show More