Compare commits
10 Commits
b5a82a5fd1
...
a8624195b0
| Author | SHA1 | Date | |
|---|---|---|---|
| a8624195b0 | |||
| 2f9f06ce87 | |||
| 41b6fb7782 | |||
| 8da4b2399e | |||
| 5efcc7ef24 | |||
| c7ac1e90bf | |||
| 1b4a56c29f | |||
| a885d05b62 | |||
| 1cedbc987c | |||
| 0a2cc295a1 |
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
*.iml
|
||||||
|
.gradle
|
||||||
|
/local.properties
|
||||||
|
/.idea/caches
|
||||||
|
/.idea/libraries
|
||||||
|
/.idea/modules.xml
|
||||||
|
/.idea/workspace.xml
|
||||||
|
/.idea/navEditor.xml
|
||||||
|
/.idea/assetWizardSettings.xml
|
||||||
|
.DS_Store
|
||||||
|
/build
|
||||||
|
/captures
|
||||||
|
.externalNativeBuild
|
||||||
|
.cxx
|
||||||
|
local.properties
|
||||||
33
.idea/.gitignore
vendored
Normal file
33
.idea/.gitignore
vendored
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
# Built files
|
||||||
|
*.apk
|
||||||
|
*.aab
|
||||||
|
*.dex
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.gradle/
|
||||||
|
build/
|
||||||
|
*/build/
|
||||||
|
|
||||||
|
**/build/
|
||||||
|
**/build/**
|
||||||
|
**/.transforms/
|
||||||
|
**/intermediates/
|
||||||
|
**/tmp/
|
||||||
|
paysdk-lib/build/
|
||||||
|
|
||||||
|
# Android Studio
|
||||||
|
*.iml
|
||||||
|
.idea/
|
||||||
|
local.properties
|
||||||
|
|
||||||
|
# Keystore
|
||||||
|
*.jks
|
||||||
|
*.keystore
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
1
.idea/.name
Normal file
1
.idea/.name
Normal file
@ -0,0 +1 @@
|
|||||||
|
KBZ-Master
|
||||||
6
.idea/AndroidProjectSystem.xml
Normal file
6
.idea/AndroidProjectSystem.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="AndroidProjectSystem">
|
||||||
|
<option name="providerId" value="com.android.tools.idea.GradleProjectSystem" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
830
.idea/ChatHistory_schema_v3.xml
Normal file
830
.idea/ChatHistory_schema_v3.xml
Normal file
File diff suppressed because one or more lines are too long
6
.idea/compiler.xml
Normal file
6
.idea/compiler.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<bytecodeTargetLevel target="17" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
18
.idea/deploymentTargetSelector.xml
Normal file
18
.idea/deploymentTargetSelector.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="deploymentTargetSelector">
|
||||||
|
<selectionStates>
|
||||||
|
<SelectionState runConfigName="app">
|
||||||
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
|
<DropdownSelection timestamp="2025-10-28T19:40:02.148831Z">
|
||||||
|
<Target type="DEFAULT_BOOT">
|
||||||
|
<handle>
|
||||||
|
<DeviceId pluginId="PhysicalDevice" identifier="serial=0123456789ABCDEF" />
|
||||||
|
</handle>
|
||||||
|
</Target>
|
||||||
|
</DropdownSelection>
|
||||||
|
<DialogSelection />
|
||||||
|
</SelectionState>
|
||||||
|
</selectionStates>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
13
.idea/deviceManager.xml
Normal file
13
.idea/deviceManager.xml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="DeviceTable">
|
||||||
|
<option name="columnSorters">
|
||||||
|
<list>
|
||||||
|
<ColumnSorterState>
|
||||||
|
<option name="column" value="Name" />
|
||||||
|
<option name="order" value="ASCENDING" />
|
||||||
|
</ColumnSorterState>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
28
.idea/gradle.xml
Normal file
28
.idea/gradle.xml
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="GradleMigrationSettings" migrationVersion="1" />
|
||||||
|
<component name="GradleSettings">
|
||||||
|
<option name="linkedExternalProjectsSettings">
|
||||||
|
<GradleProjectSettings>
|
||||||
|
<option name="testRunner" value="CHOOSE_PER_TEST" />
|
||||||
|
<option name="externalProjectPath" value="$PROJECT_DIR$" />
|
||||||
|
<option name="gradleJvm" value="17 (2)" />
|
||||||
|
<option name="modules">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
<option value="$PROJECT_DIR$/app" />
|
||||||
|
<option value="$PROJECT_DIR$/baselib" />
|
||||||
|
<option value="$PROJECT_DIR$/ecr" />
|
||||||
|
<option value="$PROJECT_DIR$/ecr-service-lib" />
|
||||||
|
<option value="$PROJECT_DIR$/mpulib" />
|
||||||
|
<option value="$PROJECT_DIR$/nexsdk-lib" />
|
||||||
|
<option value="$PROJECT_DIR$/paylibs" />
|
||||||
|
<option value="$PROJECT_DIR$/paysdk-lib" />
|
||||||
|
<option value="$PROJECT_DIR$/qrgen-lib" />
|
||||||
|
<option value="$PROJECT_DIR$/xpay" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</GradleProjectSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
10
.idea/migrations.xml
Normal file
10
.idea/migrations.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectMigrations">
|
||||||
|
<option name="MigrateToGradleLocalJavaHome">
|
||||||
|
<set>
|
||||||
|
<option value="$PROJECT_DIR$" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
10
.idea/misc.xml
Normal file
10
.idea/misc.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectType">
|
||||||
|
<option name="id" value="Android" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
17
.idea/runConfigurations.xml
Normal file
17
.idea/runConfigurations.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="RunConfigurationProducerService">
|
||||||
|
<option name="ignoredProducers">
|
||||||
|
<set>
|
||||||
|
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
|
||||||
|
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
|
||||||
|
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
|
||||||
|
</set>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
28
app/.gitignore
vendored
Normal file
28
app/.gitignore
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/build
|
||||||
|
|
||||||
|
# Built files
|
||||||
|
*.apk
|
||||||
|
*.aab
|
||||||
|
*.dex
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.gradle/
|
||||||
|
build/
|
||||||
|
*/build/
|
||||||
|
|
||||||
|
# Android Studio
|
||||||
|
*.iml
|
||||||
|
.idea/
|
||||||
|
local.properties
|
||||||
|
|
||||||
|
# Keystore
|
||||||
|
*.jks
|
||||||
|
*.keystore
|
||||||
|
|
||||||
|
# OS files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
||||||
214
app/build.gradle
Normal file
214
app/build.gradle
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
plugins {
|
||||||
|
alias(libs.plugins.android.application)
|
||||||
|
alias(libs.plugins.kotlin.android)
|
||||||
|
alias(libs.plugins.hilt.android)
|
||||||
|
alias(libs.plugins.kotlin.kapt)
|
||||||
|
alias(libs.plugins.navigation)
|
||||||
|
}
|
||||||
|
|
||||||
|
android {
|
||||||
|
namespace 'com.utsmm.kbz'
|
||||||
|
compileSdk 34
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId "com.utsmm.kbz"
|
||||||
|
minSdk 24
|
||||||
|
targetSdk 33
|
||||||
|
versionCode 7
|
||||||
|
versionName "1.07"
|
||||||
|
|
||||||
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
|
// // Add CMake configuration
|
||||||
|
// externalNativeBuild {
|
||||||
|
// cmake {
|
||||||
|
// cppFlags "-std=c++14"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure CMake
|
||||||
|
// externalNativeBuild {
|
||||||
|
// cmake {
|
||||||
|
// path "src/main/cpp/CMakeLists.txt"
|
||||||
|
// version "3.22.1"
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
compileOptions {
|
||||||
|
sourceCompatibility JavaVersion.VERSION_11
|
||||||
|
targetCompatibility JavaVersion.VERSION_11
|
||||||
|
}
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = '11'
|
||||||
|
}
|
||||||
|
|
||||||
|
dataBinding {
|
||||||
|
enabled = true
|
||||||
|
}
|
||||||
|
|
||||||
|
buildFeatures {
|
||||||
|
buildConfig = true
|
||||||
|
}
|
||||||
|
|
||||||
|
packagingOptions {
|
||||||
|
pickFirst '**/libnative-lib.so'
|
||||||
|
pickFirst '**/libxgd_ddi_jni.so'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure native library loading
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
jniLibs.srcDirs = ['src/main/jniLibs']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exclude old Kotlin stdlib variants to prevent duplicate classes
|
||||||
|
configurations.all {
|
||||||
|
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk7'
|
||||||
|
exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8'
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure kapt for annotation processing
|
||||||
|
kapt {
|
||||||
|
correctErrorTypes true
|
||||||
|
arguments {
|
||||||
|
arg("room.schemaLocation", "$projectDir/schemas")
|
||||||
|
arg("room.incremental", "true")
|
||||||
|
arg("room.expandProjection", "true")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def nav_version = "2.3.2"
|
||||||
|
def lottieVersion = "3.5.0"
|
||||||
|
def fragment_version = "1.2.0"
|
||||||
|
def espressoVersion = "3.3.0"
|
||||||
|
def testJunitVersion = "1.1.5"
|
||||||
|
def androidXTestVersion0 = "1.2.0"
|
||||||
|
def testRunnerVersion = "1.5.2"
|
||||||
|
def testRulesVersion = "1.5.0"
|
||||||
|
// def nav_version = "2.4.1"
|
||||||
|
implementation 'com.android.support:multidex:1.0.3'
|
||||||
|
|
||||||
|
// QR
|
||||||
|
// implementation 'androidmads.library.qrgenearator:QRGenearator:1.0.5'
|
||||||
|
|
||||||
|
// QR Scan
|
||||||
|
|
||||||
|
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
|
||||||
|
|
||||||
|
implementation "androidx.lifecycle:lifecycle-common-java8:2.3.1"
|
||||||
|
//1.2.0
|
||||||
|
implementation 'androidx.appcompat:appcompat:1.3.1' //1.2.0
|
||||||
|
implementation 'com.google.android.material:material:1.4.0' //1.2.1
|
||||||
|
implementation 'androidx.constraintlayout:constraintlayout:2.0.4' //2.0.4
|
||||||
|
|
||||||
|
implementation 'com.github.denzcoskun:ImageSlideshow:0.1.2'
|
||||||
|
|
||||||
|
//signature
|
||||||
|
implementation 'com.github.gcacace:signature-pad:1.3.1'
|
||||||
|
|
||||||
|
//lottie
|
||||||
|
implementation "com.airbnb.android:lottie:$lottieVersion"
|
||||||
|
|
||||||
|
implementation "androidx.cardview:cardview:1.0.0"
|
||||||
|
|
||||||
|
//Stetho
|
||||||
|
implementation 'com.facebook.stetho:stetho:1.5.1'
|
||||||
|
|
||||||
|
//Navigation Component
|
||||||
|
implementation "androidx.navigation:navigation-fragment:$nav_version"
|
||||||
|
implementation "androidx.navigation:navigation-ui:$nav_version"
|
||||||
|
|
||||||
|
// Room dependencies
|
||||||
|
implementation "androidx.room:room-runtime:2.4.3" //2.2.5
|
||||||
|
implementation 'androidx.preference:preference:1.1.1'
|
||||||
|
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
|
||||||
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
|
// kapt "androidx.room:room-compiler:2.4.3"
|
||||||
|
implementation "androidx.room:room-rxjava3:2.4.3"
|
||||||
|
|
||||||
|
// Hilt Dependencies
|
||||||
|
implementation libs.hilt.android
|
||||||
|
kapt libs.hilt.compiler
|
||||||
|
kapt libs.androidx.hilt.compiler
|
||||||
|
|
||||||
|
// Basic dependency injection support for javax.inject
|
||||||
|
implementation 'javax.inject:javax.inject:1'
|
||||||
|
|
||||||
|
//OKHttp 4.8.1
|
||||||
|
implementation("com.squareup.okhttp3:logging-interceptor:4.8.1")
|
||||||
|
implementation("com.squareup.okhttp3:okhttp:4.8.1")
|
||||||
|
|
||||||
|
//RxJava
|
||||||
|
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
|
||||||
|
implementation 'io.reactivex.rxjava3:rxjava:3.0.0'
|
||||||
|
|
||||||
|
// Retrofit
|
||||||
|
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||||
|
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||||
|
implementation "com.github.akarnokd:rxjava3-retrofit-adapter:3.0.0"
|
||||||
|
|
||||||
|
// ViewModel
|
||||||
|
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.2.0'
|
||||||
|
|
||||||
|
// LiveData
|
||||||
|
implementation 'androidx.lifecycle:lifecycle-livedata:2.2.0'
|
||||||
|
//base64
|
||||||
|
implementation 'commons-codec:commons-codec:1.15'
|
||||||
|
//bouncy castle
|
||||||
|
implementation 'org.bouncycastle:bcpkix-jdk15on:1.56'
|
||||||
|
|
||||||
|
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||||
|
|
||||||
|
implementation 'com.sunmi:printerlibrary:1.0.23'
|
||||||
|
// implementation 'com.sunmi:sunmiui:1.1.27' //1.1.27
|
||||||
|
|
||||||
|
|
||||||
|
implementation project(path: ':ecr-service-lib')
|
||||||
|
implementation project(path: ':paylibs')
|
||||||
|
implementation project(path: ':mpulib')
|
||||||
|
implementation project(path: ':baselib')
|
||||||
|
implementation project(path: ':paysdk-lib')
|
||||||
|
implementation project(path: ':nexsdk-lib')
|
||||||
|
implementation project(path: ':qrgen-lib')
|
||||||
|
implementation project(path: ':xpay')
|
||||||
|
// implementation project(path: ':sunmiui-lib')
|
||||||
|
implementation project(path: ':qrgen-lib')
|
||||||
|
//// implementation project(path: ':samlSirius')
|
||||||
|
implementation project(path: ':ecr')
|
||||||
|
|
||||||
|
testImplementation 'junit:junit:4.13.2'
|
||||||
|
androidTestImplementation 'androidx.test.ext:junit:1.1.2' // 1.1.2
|
||||||
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||||
|
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.3.0'
|
||||||
|
|
||||||
|
|
||||||
|
androidTestImplementation 'androidx.test:core:1.5.0'
|
||||||
|
androidTestImplementation 'androidx.test:runner:1.5.2'
|
||||||
|
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||||
|
|
||||||
|
// Add Mockito dependency for mocking
|
||||||
|
testImplementation 'org.mockito:mockito-core:3.12.4'
|
||||||
|
androidTestImplementation 'org.mockito:mockito-android:3.12.4'
|
||||||
|
|
||||||
|
testImplementation 'org.powermock:powermock-api-mockito2:2.0.9'
|
||||||
|
testImplementation 'org.powermock:powermock-module-junit4:2.0.9'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
26
app/proguard-rules.pro
vendored
Normal file
26
app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# Add project specific ProGuard rules here.
|
||||||
|
# You can control the set of applied configuration files using the
|
||||||
|
# proguardFiles setting in build.gradle.
|
||||||
|
#
|
||||||
|
# For more details, see
|
||||||
|
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||||
|
|
||||||
|
# If your project uses WebView with JS, uncomment the following
|
||||||
|
# and specify the fully qualified class name to the JavaScript interface
|
||||||
|
# class:
|
||||||
|
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||||
|
# public *;
|
||||||
|
#}
|
||||||
|
|
||||||
|
# Uncomment this to preserve the line number information for
|
||||||
|
# debugging stack traces.
|
||||||
|
#-keepattributes SourceFile,LineNumberTable
|
||||||
|
|
||||||
|
# If you keep the line number information, uncomment this to
|
||||||
|
# hide the original source file name.
|
||||||
|
#-renamesourcefileattribute SourceFile
|
||||||
|
|
||||||
|
|
||||||
|
# Keep Bouncy Castle classes for security providers
|
||||||
|
-keep class org.bouncycastle.** { *; }
|
||||||
|
-dontwarn org.bouncycastle.**
|
||||||
BIN
app/release/app-release.apk
Normal file
BIN
app/release/app-release.apk
Normal file
Binary file not shown.
BIN
app/release/baselineProfiles/0/app-release.dm
Normal file
BIN
app/release/baselineProfiles/0/app-release.dm
Normal file
Binary file not shown.
BIN
app/release/baselineProfiles/1/app-release.dm
Normal file
BIN
app/release/baselineProfiles/1/app-release.dm
Normal file
Binary file not shown.
37
app/release/output-metadata.json
Normal file
37
app/release/output-metadata.json
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"artifactType": {
|
||||||
|
"type": "APK",
|
||||||
|
"kind": "Directory"
|
||||||
|
},
|
||||||
|
"applicationId": "com.utsmm.kbz",
|
||||||
|
"variantName": "release",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "SINGLE",
|
||||||
|
"filters": [],
|
||||||
|
"attributes": [],
|
||||||
|
"versionCode": 7,
|
||||||
|
"versionName": "1.07",
|
||||||
|
"outputFile": "app-release.apk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"elementType": "File",
|
||||||
|
"baselineProfiles": [
|
||||||
|
{
|
||||||
|
"minApi": 28,
|
||||||
|
"maxApi": 30,
|
||||||
|
"baselineProfiles": [
|
||||||
|
"baselineProfiles/1/app-release.dm"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"minApi": 31,
|
||||||
|
"maxApi": 2147483647,
|
||||||
|
"baselineProfiles": [
|
||||||
|
"baselineProfiles/0/app-release.dm"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"minSdkVersionForDexing": 24
|
||||||
|
}
|
||||||
@ -0,0 +1,176 @@
|
|||||||
|
package com.utsmm.kbz;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.test.platform.app.InstrumentationRegistry;
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import com.sunmi.pay.hardware.aidl.AidlConstants;
|
||||||
|
import com.utsmm.kbz.util.MockData;
|
||||||
|
import com.utsmm.kbz.util.TransactionUtil;
|
||||||
|
import com.utsmyanmar.checkxread.model.CardDataX;
|
||||||
|
import com.utsmyanmar.checkxread.util.CardTypeX;
|
||||||
|
import com.utsmyanmar.paylibs.Constant;
|
||||||
|
import com.utsmyanmar.paylibs.isobuilder.ISOMode;
|
||||||
|
import com.utsmyanmar.paylibs.isobuilder.builderx.ISOMsgX;
|
||||||
|
import com.utsmyanmar.paylibs.isobuilder.builderx.ISOVersion;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.model.TradeData;
|
||||||
|
import com.utsmyanmar.paylibs.model.enums.TransCVM;
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.MessageType;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.ByteUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.HostName;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.BitmapConfig;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmyanmar.paylibs.utils.params.Params;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instrumented test, which will execute on an Android device.
|
||||||
|
*
|
||||||
|
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||||
|
*/
|
||||||
|
@RunWith(AndroidJUnit4.class)
|
||||||
|
public class ExampleInstrumentedTest {
|
||||||
|
@Test
|
||||||
|
public void useAppContext() {
|
||||||
|
// Context of the app under test.
|
||||||
|
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||||
|
assertEquals("com.utsmm.kbz", appContext.getPackageName());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVoidPacket() {
|
||||||
|
|
||||||
|
CardDataX cardDataX = MockData.getInstance().generateMPUCard();
|
||||||
|
|
||||||
|
TradeData tradeData = TransactionUtil.getInstance().initMPUTransaction(cardDataX, CardTypeX.IC);
|
||||||
|
|
||||||
|
String bitmap = BitmapConfig.MPU_NEW_VOID;
|
||||||
|
MessageType messageType = MessageType.FINANCIAL;
|
||||||
|
|
||||||
|
ISOMsgX isoMsgX = new ISOMsgX.ISOMsgXBuilder(ISOVersion.VERSION_1987, ISOMode.ONLY_HEADER, HostName.FINEXUS)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
TradeData transTradeData = setUpRebuildTransactions(tradeData, TransactionsType.VOID, HostName.FINEXUS);
|
||||||
|
|
||||||
|
transTradeData.getPayDetail().setAmount(50000);
|
||||||
|
PayDetail transPayDetail = transTradeData.getPayDetail();
|
||||||
|
|
||||||
|
byte[] sendBytes;
|
||||||
|
try {
|
||||||
|
sendBytes = isoMsgX.buildISOPackets(transTradeData, bitmap, messageType);
|
||||||
|
|
||||||
|
System.out.println("Hex Str : "+ ByteUtil.bytes2HexStr(sendBytes));
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private TradeData setUpRebuildTransactions(TradeData tradeData, TransactionsType transactionsType, HostName hostName) {
|
||||||
|
LogUtil.d(Constant.TAG, "Starting Online Transaction--" + hostName + "--" + transactionsType);
|
||||||
|
|
||||||
|
TradeData newTrade = Params.newTrade(true);
|
||||||
|
PayDetail newPay = newTrade.getPayDetail();
|
||||||
|
PayDetail oldPay = tradeData.getPayDetail();
|
||||||
|
|
||||||
|
newPay.setCardType(100);
|
||||||
|
newPay.setPINCipher("");
|
||||||
|
newPay.setHostName(hostName.name);
|
||||||
|
newPay.setTransType(transactionsType.name);
|
||||||
|
newPay.setProcessCode(transactionsType.processCode);
|
||||||
|
newPay.setCardNo(oldPay.getCardNo());
|
||||||
|
newPay.setCardHolderName(oldPay.getCardHolderName());
|
||||||
|
newPay.setEXPDate(oldPay.getEXPDate());
|
||||||
|
newPay.setTradeDate(oldPay.getTradeDate());
|
||||||
|
newPay.setTradeTime(oldPay.getTradeTime());
|
||||||
|
newPay.setAmount(oldPay.getAmount());
|
||||||
|
newPay.setTransactionType(transactionsType.value);
|
||||||
|
newPay.setAccountType(oldPay.getAccountType());
|
||||||
|
|
||||||
|
newPay.setCardInfo(oldPay.getCardInfo());
|
||||||
|
|
||||||
|
newPay.setSettlementEnabled(SystemParamsOperation.getInstance().getSettlementStatus());
|
||||||
|
|
||||||
|
// added on Nov, 13 2024
|
||||||
|
newPay.setICC55(oldPay.getICC55());
|
||||||
|
|
||||||
|
if(newPay.getICC55() != null && !newPay.getICC55().isEmpty()) {
|
||||||
|
newPay.setAppLabel(oldPay.getAppLabel());
|
||||||
|
newPay.setAppName(oldPay.getAppName());
|
||||||
|
newPay.setTSI(oldPay.getTSI());
|
||||||
|
newPay.setAID(oldPay.getAID());
|
||||||
|
newPay.setArqC(oldPay.getArqC());
|
||||||
|
newPay.setTVR(oldPay.getTVR());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(transactionsType != TransactionsType.PRE_AUTH_COMPLETE) {
|
||||||
|
|
||||||
|
newPay.setTradeDateTime(oldPay.getTradeDateTime());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (transactionsType == TransactionsType.VOID || transactionsType == TransactionsType.REFUND) {
|
||||||
|
String field60;
|
||||||
|
if(hostName == HostName.BPC) {
|
||||||
|
field60 = String.format(Locale.getDefault(), "%010d00", oldPay.getAmount());
|
||||||
|
} else {
|
||||||
|
field60 = String.format(Locale.getDefault(), "%012d", oldPay.getAmount());
|
||||||
|
}
|
||||||
|
// String field60 = String.format(Locale.getDefault(), "%010d00", oldPay.getAmount());
|
||||||
|
newPay.setReferNo(oldPay.getReferNo());
|
||||||
|
newPay.setTransCVM(TransCVM.SIGNATURE);
|
||||||
|
newTrade.setField60(field60);
|
||||||
|
} else if (transactionsType == TransactionsType.PRE_AUTH_VOID) {
|
||||||
|
newPay.setCardType(oldPay.getCardType());
|
||||||
|
newPay.setCustomOrderNo(oldPay.getVoucherNo());
|
||||||
|
newPay.setReferNo(oldPay.getReferNo());
|
||||||
|
newPay.setCardInfo(oldPay.getCardInfo());
|
||||||
|
newPay.setPINCipher(oldPay.getPINCipher());
|
||||||
|
newPay.setTempKSN(oldPay.getTempKSN());
|
||||||
|
newPay.setTransCVM(TransCVM.SIGNATURE);
|
||||||
|
// for manual entry reversal which need de 35
|
||||||
|
|
||||||
|
} else if (transactionsType == TransactionsType.TIP_ADJUSTMENT ) {
|
||||||
|
newPay.setReferNo(oldPay.getReferNo());
|
||||||
|
newPay.setApprovalCode(oldPay.getApprovalCode());
|
||||||
|
} else if (transactionsType == TransactionsType.PRE_AUTH_COMPLETE) {
|
||||||
|
newPay.setCardType(oldPay.getCardType());
|
||||||
|
newPay.setCardInfo(oldPay.getCardInfo());
|
||||||
|
newPay.setPINCipher(oldPay.getPINCipher());
|
||||||
|
newPay.setReferNo(oldPay.getReferNo());
|
||||||
|
newPay.setTempKSN(oldPay.getTempKSN());
|
||||||
|
} else if (transactionsType == TransactionsType.PRE_AUTH_COMPLETE_VOID) {
|
||||||
|
newPay.setVoucherNo(oldPay.getVoucherNo());
|
||||||
|
newPay.setCustomOrderNo(oldPay.getVoucherNo());
|
||||||
|
newPay.setReferNo(oldPay.getReferNo());
|
||||||
|
newPay.setCardInfo(oldPay.getCardInfo());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* new requirements */
|
||||||
|
newPay.setCardType(AidlConstants.CardType.IC.getValue());
|
||||||
|
newPay.setPINCipher("55");
|
||||||
|
newPay.setTransCVM(TransCVM.SIGNATURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(oldPay.getAccountType().equals("MPU")){
|
||||||
|
// newPay.setIsFreeSign(true);
|
||||||
|
newPay.setTransCVM(TransCVM.SIGNATURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
newTrade.setPayDetail(newPay);
|
||||||
|
return newTrade;
|
||||||
|
}
|
||||||
|
}
|
||||||
80
app/src/main/AndroidManifest.xml
Normal file
80
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
package="com.utsmm.kbz">
|
||||||
|
|
||||||
|
<uses-feature
|
||||||
|
android:name="android.hardware.camera"
|
||||||
|
android:required="false" />
|
||||||
|
<uses-feature
|
||||||
|
android:name="android.hardware.telephony"
|
||||||
|
android:required="false" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" tools:ignore="QueryAllPackagesPermission" />
|
||||||
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||||
|
<uses-permission android:name="com.sunmi.perm.LED" />
|
||||||
|
<uses-permission android:name="com.sunmi.perm.MSR" />
|
||||||
|
<uses-permission android:name="com.sunmi.perm.ICC" />
|
||||||
|
<uses-permission android:name="com.sunmi.perm.PINPAD" />
|
||||||
|
<uses-permission android:name="com.sunmi.perm.SECURITY" />
|
||||||
|
<uses-permission android:name="com.sunmi.perm.CONTACTLESS_CARD" />
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"
|
||||||
|
tools:ignore="ProtectedPermissions" />
|
||||||
|
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||||
|
|
||||||
|
<!-- android:noHistory="true"-->
|
||||||
|
<!-- android:excludeFromRecents="true"-->
|
||||||
|
|
||||||
|
<!-- android:debuggable="true"-->
|
||||||
|
<!-- tools:ignore="HardcodedDebugMode"-->
|
||||||
|
<!-- Jun 14 , 2023 -->
|
||||||
|
|
||||||
|
<!--android:largeHeap="true"
|
||||||
|
android:hardwareAccelerated="false"-->
|
||||||
|
<application
|
||||||
|
android:usesCleartextTraffic="true"
|
||||||
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
|
android:name="com.utsmm.kbz.MyApplication"
|
||||||
|
tools:replace="android:allowBackup"
|
||||||
|
android:allowBackup="false"
|
||||||
|
android:icon="@mipmap/ic_launcher"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
|
android:supportsRtl="true"
|
||||||
|
android:theme="@style/AppTheme.NoActionBar">
|
||||||
|
<!-- android:manageSpaceActivity="com.utsmyanmar.upos.config.UTSManageSpaceActivity"-->
|
||||||
|
<!-- <activity-->
|
||||||
|
<!-- android:screenOrientation="portrait"-->
|
||||||
|
<!-- android:name=".config.UTSManageSpaceActivity"/>-->
|
||||||
|
<activity android:name="com.utsmm.kbz.MainActivity"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
|
</activity>
|
||||||
|
|
||||||
|
<activity android:name="com.journeyapps.barcodescanner.CaptureActivity"
|
||||||
|
android:screenOrientation="fullSensor"
|
||||||
|
tools:replace="screenOrientation" />
|
||||||
|
|
||||||
|
<receiver android:name="com.utsmm.kbz.service.SmileAlarmReceiver" />
|
||||||
|
|
||||||
|
<service
|
||||||
|
android:name="com.utsmm.kbz.service.SmileSettleService"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="false">
|
||||||
|
<meta-data
|
||||||
|
android:name="androidx.hilt.EntryPoint"
|
||||||
|
android:value="androidx.hilt.lifecycle.HiltService" />
|
||||||
|
</service>
|
||||||
|
</application>
|
||||||
|
|
||||||
|
</manifest>
|
||||||
1
app/src/main/assets/lottie-search-files.json
Normal file
1
app/src/main/assets/lottie-search-files.json
Normal file
File diff suppressed because one or more lines are too long
1
app/src/main/assets/lottie_decline.json
Normal file
1
app/src/main/assets/lottie_decline.json
Normal file
File diff suppressed because one or more lines are too long
1
app/src/main/assets/lottie_download_loading.json
Normal file
1
app/src/main/assets/lottie_download_loading.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"nm":"Comp 1","ddd":0,"h":500,"w":500,"meta":{"g":"@lottiefiles/toolkit-js 0.25.8"},"layers":[{"ty":4,"nm":"Shape Layer 2","sr":1,"st":0,"op":644.000010477231,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[250,250,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":99,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":1,"cix":2,"np":4,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[392,392],"ix":2}},{"ty":"tm","bm":0,"hd":false,"mn":"ADBE Vector Filter - Trim","nm":"Trim Paths 1","ix":2,"e":{"a":1,"k":[{"o":{"x":0.48,"y":0.04},"i":{"x":0.52,"y":0.96},"s":[1],"t":0},{"s":[24],"t":8.91800014508687}],"ix":2},"o":{"a":1,"k":[{"o":{"x":0.48,"y":0.04},"i":{"x":0.667,"y":1},"s":[-2],"t":0},{"o":{"x":0.48,"y":0.04},"i":{"x":0.52,"y":0.96},"s":[645],"t":20.798},{"o":{"x":0.48,"y":0.04},"i":{"x":0.52,"y":0.96},"s":[627],"t":30.399},{"s":[636],"t":40.0000006507597}],"ix":3},"s":{"a":1,"k":[{"o":{"x":0.48,"y":0.04},"i":{"x":0.52,"y":0.96},"s":[0],"t":13.839},{"s":[23],"t":20.7980003383625}],"ix":1},"m":1},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":2,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":28,"ix":5},"c":{"a":0,"k":[0.1725,0.2431,0.3137],"ix":3}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[1,0.5765,0.3882],"ix":4},"r":1,"o":{"a":0,"k":0,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[1,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":1},{"ty":4,"nm":"Shape Layer 1","sr":1,"st":0,"op":644.000010477231,"ip":0,"hd":false,"ddd":0,"bm":0,"hasMask":false,"ao":0,"ks":{"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6},"sk":{"a":0,"k":0},"p":{"a":0,"k":[250,250,0],"ix":2},"r":{"a":0,"k":0,"ix":10},"sa":{"a":0,"k":0},"o":{"a":0,"k":36,"ix":11}},"ef":[],"shapes":[{"ty":"gr","bm":0,"hd":false,"mn":"ADBE Vector Group","nm":"Ellipse 1","ix":1,"cix":2,"np":3,"it":[{"ty":"el","bm":0,"hd":false,"mn":"ADBE Vector Shape - Ellipse","nm":"Ellipse Path 1","d":1,"p":{"a":0,"k":[0,0],"ix":3},"s":{"a":0,"k":[392,392],"ix":2}},{"ty":"st","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Stroke","nm":"Stroke 1","lc":1,"lj":1,"ml":4,"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":36,"ix":5},"c":{"a":0,"k":[0.949,0.9686,0.9843],"ix":3}},{"ty":"fl","bm":0,"hd":false,"mn":"ADBE Vector Graphic - Fill","nm":"Fill 1","c":{"a":0,"k":[1,1,1],"ix":4},"r":1,"o":{"a":0,"k":0,"ix":5}},{"ty":"tr","a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"sk":{"a":0,"k":0,"ix":4},"p":{"a":0,"k":[1,0],"ix":2},"r":{"a":0,"k":0,"ix":6},"sa":{"a":0,"k":0,"ix":5},"o":{"a":0,"k":100,"ix":7}}]}],"ind":2}],"v":"5.5.8","fr":30.0130004882813,"op":42.0000006832977,"ip":0,"assets":[]}
|
||||||
1
app/src/main/assets/lottie_no_trans.json
Normal file
1
app/src/main/assets/lottie_no_trans.json
Normal file
File diff suppressed because one or more lines are too long
1
app/src/main/assets/lottie_processing_card.json
Normal file
1
app/src/main/assets/lottie_processing_card.json
Normal file
File diff suppressed because one or more lines are too long
1
app/src/main/assets/lottie_remove_card.json
Normal file
1
app/src/main/assets/lottie_remove_card.json
Normal file
File diff suppressed because one or more lines are too long
1
app/src/main/assets/lottie_send_data.json
Normal file
1
app/src/main/assets/lottie_send_data.json
Normal file
File diff suppressed because one or more lines are too long
1
app/src/main/assets/lottie_success.json
Normal file
1
app/src/main/assets/lottie_success.json
Normal file
File diff suppressed because one or more lines are too long
1
app/src/main/assets/lottie_timeout.json
Normal file
1
app/src/main/assets/lottie_timeout.json
Normal file
File diff suppressed because one or more lines are too long
BIN
app/src/main/assets/mm_paper_roll_empty_alert.mp3
Normal file
BIN
app/src/main/assets/mm_paper_roll_empty_alert.mp3
Normal file
Binary file not shown.
BIN
app/src/main/assets/mm_printer_alert.mp3
Normal file
BIN
app/src/main/assets/mm_printer_alert.mp3
Normal file
Binary file not shown.
BIN
app/src/main/assets/mm_printer_ready_alert.mp3
Normal file
BIN
app/src/main/assets/mm_printer_ready_alert.mp3
Normal file
Binary file not shown.
BIN
app/src/main/assets/mm_thank_you_alert.mp3
Normal file
BIN
app/src/main/assets/mm_thank_you_alert.mp3
Normal file
Binary file not shown.
BIN
app/src/main/assets/rubik.ttf
Normal file
BIN
app/src/main/assets/rubik.ttf
Normal file
Binary file not shown.
BIN
app/src/main/assets/rubik_medium.ttf
Normal file
BIN
app/src/main/assets/rubik_medium.ttf
Normal file
Binary file not shown.
499
app/src/main/java/com/utsmm/kbz/MainActivity.java
Normal file
499
app/src/main/java/com/utsmm/kbz/MainActivity.java
Normal file
@ -0,0 +1,499 @@
|
|||||||
|
package com.utsmm.kbz;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.ActionBarDrawerToggle;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
import androidx.drawerlayout.widget.DrawerLayout;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.navigation.NavController;
|
||||||
|
import androidx.navigation.NavDestination;
|
||||||
|
import androidx.navigation.fragment.NavHostFragment;
|
||||||
|
import androidx.navigation.ui.AppBarConfiguration;
|
||||||
|
import androidx.navigation.ui.NavigationUI;
|
||||||
|
|
||||||
|
import android.app.AlarmManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
import com.google.android.material.navigation.NavigationView;
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository;
|
||||||
|
import com.utsmyanmar.baselib.ui.AnimationDialog;
|
||||||
|
import com.utsmyanmar.checkxread.sdk.NexGoSDK;
|
||||||
|
import com.utsmyanmar.ecr.ECRHelper;
|
||||||
|
import com.utsmyanmar.paylibs.Constant;
|
||||||
|
import com.utsmyanmar.paylibs.print.printx.PrintXReceipt;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.TransMenu;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.databinding.ActivityMainNewBinding;
|
||||||
|
import com.utsmm.kbz.service.SmileAlarmReceiver;
|
||||||
|
import com.utsmm.kbz.ui.core_ui.InputPasswordFragment;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.ui.navigation.NaviAdminFragment;
|
||||||
|
import com.utsmm.kbz.ui.navigation.NaviMainFragment;
|
||||||
|
import com.utsmm.kbz.ui.navigation.NaviSetupFragment;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
import com.utsmm.kbz.util.tms.TMSUtil;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
|
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
|
||||||
|
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||||
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
/**
|
||||||
|
* Main Activity handling application navigation and fragment interactions
|
||||||
|
*/
|
||||||
|
@AndroidEntryPoint
|
||||||
|
public class MainActivity extends AppCompatActivity implements
|
||||||
|
NaviMainFragment.OnFragmentInteractionListener,
|
||||||
|
InputPasswordFragment.OnFragmentInteractionListener,
|
||||||
|
NaviSetupFragment.OnFragmentInteractionListener,
|
||||||
|
NaviAdminFragment.OnFragmentInteractionListener {
|
||||||
|
|
||||||
|
private static final String TAG = MainActivity.class.getSimpleName();
|
||||||
|
|
||||||
|
// ViewModels
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
// UI Components
|
||||||
|
private ActivityMainNewBinding binding;
|
||||||
|
private DrawerLayout drawerLayout;
|
||||||
|
private NavigationView navigationView;
|
||||||
|
private NavController navController;
|
||||||
|
private ActionBarDrawerToggle drawerToggle;
|
||||||
|
private AnimationDialog animationDialog;
|
||||||
|
|
||||||
|
// Navigation
|
||||||
|
private AppBarConfiguration appBarConfiguration;
|
||||||
|
|
||||||
|
// Resource management
|
||||||
|
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
|
// Set of fragment IDs that should handle back press specially
|
||||||
|
private final Set<Integer> specialBackHandlingFragments = new HashSet<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
Repository repository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// Keep screen on
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
|
||||||
|
// Initialize ViewModels
|
||||||
|
initViewModels();
|
||||||
|
|
||||||
|
// Setup UI components
|
||||||
|
setupUI();
|
||||||
|
|
||||||
|
// Setup navigation
|
||||||
|
setupNavigation();
|
||||||
|
|
||||||
|
// Setup toolbar navigation
|
||||||
|
setupToolbarNavigation();
|
||||||
|
|
||||||
|
// Initialize fragment in navigation drawer
|
||||||
|
initNavigationDrawerFragment();
|
||||||
|
|
||||||
|
// Set up daily alarm if needed
|
||||||
|
// setupAlarmIfNeeded();
|
||||||
|
|
||||||
|
// Generate app version
|
||||||
|
generateVersionInfo();
|
||||||
|
|
||||||
|
// Retrieve initial data
|
||||||
|
retrieveData();
|
||||||
|
|
||||||
|
// Initialize special back handling fragments
|
||||||
|
initSpecialBackHandlingFragments();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initViewModels() {
|
||||||
|
sharedViewModel = new ViewModelProvider(this).get(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUI() {
|
||||||
|
binding = DataBindingUtil.setContentView(this, R.layout.activity_main_new);
|
||||||
|
binding.setSharedViewModel(sharedViewModel);
|
||||||
|
binding.setLifecycleOwner(this);
|
||||||
|
|
||||||
|
MaterialToolbar toolbar = binding.toolbar;
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
drawerLayout = binding.drawerLayout;
|
||||||
|
navigationView = binding.navView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupNavigation() {
|
||||||
|
NavHostFragment navHostFragment =
|
||||||
|
(NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.nav_host_fragment);
|
||||||
|
|
||||||
|
if (navHostFragment != null) {
|
||||||
|
navController = navHostFragment.getNavController();
|
||||||
|
|
||||||
|
// Define top-level destinations
|
||||||
|
int[] topLevelDestinations = {
|
||||||
|
R.id.menu_function, R.id.menu_version, R.id.menu_logout,
|
||||||
|
R.id.menu_exit, R.id.nav_main
|
||||||
|
};
|
||||||
|
|
||||||
|
appBarConfiguration = new AppBarConfiguration.Builder(topLevelDestinations)
|
||||||
|
.setOpenableLayout(drawerLayout)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Setup navigation with UI components
|
||||||
|
NavigationUI.setupWithNavController(navigationView, navController);
|
||||||
|
NavigationUI.setupWithNavController(binding.toolbar, navController, appBarConfiguration);
|
||||||
|
|
||||||
|
// Setup drawer toggle
|
||||||
|
drawerToggle = new ActionBarDrawerToggle(
|
||||||
|
this, drawerLayout, binding.toolbar,
|
||||||
|
R.string.nav_app_bar_open_drawer_description,
|
||||||
|
R.string.navigation_drawer_close
|
||||||
|
);
|
||||||
|
drawerToggle.syncState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupToolbarNavigation() {
|
||||||
|
binding.toolbar.setNavigationOnClickListener(v -> handleNavigationClick());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleNavigationClick() {
|
||||||
|
try {
|
||||||
|
NavDestination currentDestination = navController.getCurrentDestination();
|
||||||
|
if (currentDestination != null) {
|
||||||
|
int currentId = currentDestination.getId();
|
||||||
|
|
||||||
|
if (currentId == R.id.nav_main) {
|
||||||
|
openDrawer();
|
||||||
|
} else if (isSpecialBackHandlingFragment(currentId)) {
|
||||||
|
checkForInsertedCard();
|
||||||
|
} else {
|
||||||
|
handleRegularBackPress();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Navigation error: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRegularBackPress() {
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null && sharedViewModel.isEcr.getValue()) {
|
||||||
|
finishECR();
|
||||||
|
}
|
||||||
|
onBackPressed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initSpecialBackHandlingFragments() {
|
||||||
|
specialBackHandlingFragments.add(R.id.inputAmountFragment);
|
||||||
|
specialBackHandlingFragments.add(R.id.inputPasswordFragment);
|
||||||
|
specialBackHandlingFragments.add(R.id.selectHostFragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSpecialBackHandlingFragment(int fragmentId) {
|
||||||
|
return specialBackHandlingFragments.contains(fragmentId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initNavigationDrawerFragment() {
|
||||||
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.navi_fragment, new NaviMainFragment())
|
||||||
|
.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupAlarmIfNeeded() {
|
||||||
|
if (!SystemParamsOperation.getInstance().isLoadedOnce()) {
|
||||||
|
setupDailyAlarm();
|
||||||
|
SystemParamsOperation.getInstance().setLoadedOnce(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupDailyAlarm() {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTimeInMillis(System.currentTimeMillis());
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, 23);
|
||||||
|
calendar.set(Calendar.MINUTE, 50);
|
||||||
|
calendar.set(Calendar.SECOND, 0);
|
||||||
|
|
||||||
|
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
|
||||||
|
|
||||||
|
// Set the alarm to trigger at specified time every day
|
||||||
|
if (alarmManager != null) {
|
||||||
|
PendingIntent pendingIntent = PendingIntent.getBroadcast(
|
||||||
|
this,
|
||||||
|
0,
|
||||||
|
new Intent(this, SmileAlarmReceiver.class),
|
||||||
|
PendingIntent.FLAG_UPDATE_CURRENT
|
||||||
|
);
|
||||||
|
|
||||||
|
alarmManager.setRepeating(
|
||||||
|
AlarmManager.RTC_WAKEUP,
|
||||||
|
calendar.getTimeInMillis(),
|
||||||
|
AlarmManager.INTERVAL_DAY,
|
||||||
|
pendingIntent
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows an animation dialog with a message
|
||||||
|
*/
|
||||||
|
protected void showAnimationDialog(String msg) {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
if (animationDialog == null) {
|
||||||
|
animationDialog = new AnimationDialog(this, msg);
|
||||||
|
} else {
|
||||||
|
animationDialog.setMessage(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!animationDialog.isShowing()) {
|
||||||
|
animationDialog.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dismisses the animation dialog if showing
|
||||||
|
*/
|
||||||
|
protected void dismissAnimationDialog() {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
if (animationDialog != null && animationDialog.isShowing()) {
|
||||||
|
animationDialog.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a card is inserted and handles accordingly
|
||||||
|
*/
|
||||||
|
private void checkForInsertedCard() {
|
||||||
|
Disposable disposable = Observable.create((ObservableOnSubscribe<Boolean>) emitter -> {
|
||||||
|
try {
|
||||||
|
while (NexGoSDK.getInstance().checkCardExist() == 2) {
|
||||||
|
emitter.onNext(true);
|
||||||
|
}
|
||||||
|
emitter.onComplete();
|
||||||
|
} catch (Exception e) {
|
||||||
|
emitter.onError(e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.throttleLast(2, TimeUnit.SECONDS)
|
||||||
|
.subscribe(
|
||||||
|
cardInserted -> {
|
||||||
|
if (cardInserted) {
|
||||||
|
dismissAnimationDialog();
|
||||||
|
|
||||||
|
showAnimationDialog(getString(R.string.txt_removed_card));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error -> LogUtil.e(TAG, "Error checking card: " + error.getMessage()),
|
||||||
|
() -> {
|
||||||
|
dismissAnimationDialog();
|
||||||
|
onBackPressed();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
compositeDisposable.add(disposable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates and stores the app version
|
||||||
|
*/
|
||||||
|
private void generateVersionInfo() {
|
||||||
|
try {
|
||||||
|
String finalVersion = TMSUtil.getInstance().generateFinalVersion();
|
||||||
|
SystemParamsOperation.getInstance().setFinalVersion(finalVersion);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error generating version: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves initial data from repository
|
||||||
|
*/
|
||||||
|
private void retrieveData() {
|
||||||
|
Disposable disposable = repository.getAllEmvData()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
lists -> LogUtil.d(Constant.TAG, "Size of EMV data: " + lists.size()),
|
||||||
|
error -> LogUtil.e(Constant.TAG, "Error retrieving EMV data: " + error.getMessage()),
|
||||||
|
() -> LogUtil.d(Constant.TAG, "EMV data retrieval complete")
|
||||||
|
);
|
||||||
|
|
||||||
|
compositeDisposable.add(disposable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finishes ECR process
|
||||||
|
*/
|
||||||
|
private void finishECR() {
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(getString(R.string.txt_cancel_trans));
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens the navigation drawer
|
||||||
|
*/
|
||||||
|
public void openDrawer() {
|
||||||
|
drawerLayout.openDrawer(Gravity.LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the navigation drawer
|
||||||
|
*/
|
||||||
|
public void closeDrawer() {
|
||||||
|
drawerLayout.closeDrawer(Gravity.LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the fragment in the navigation drawer
|
||||||
|
*/
|
||||||
|
public void changeNavigationFragment(androidx.fragment.app.Fragment fragment) {
|
||||||
|
getSupportFragmentManager().beginTransaction()
|
||||||
|
.replace(R.id.navi_fragment, fragment)
|
||||||
|
.commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
SystemParamsOperation.getInstance().setSetupEcr(false);
|
||||||
|
SystemParamsOperation.getInstance().setDownloadedParams(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
|
||||||
|
// Clean up RxJava disposables
|
||||||
|
compositeDisposable.clear();
|
||||||
|
|
||||||
|
// Reset screen mode
|
||||||
|
|
||||||
|
|
||||||
|
// Disconnect ECR
|
||||||
|
ECRHelper.INSTANCE.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigation drawer interaction listeners
|
||||||
|
@Override
|
||||||
|
public void onClickSetup() {
|
||||||
|
closeDrawer();
|
||||||
|
sharedViewModel.transactionsType.postValue(TransactionsType.SETTING);
|
||||||
|
navController.navigate(R.id.inputPasswordFragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickFunction() {
|
||||||
|
closeDrawer();
|
||||||
|
sharedViewModel.transactionsType.postValue(TransactionsType.FUNCTION);
|
||||||
|
navController.navigate(R.id.inputPasswordFragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickVersion() {
|
||||||
|
closeDrawer();
|
||||||
|
navController.navigate(R.id.action_nav_main_to_versionFragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickExit() {
|
||||||
|
finishAffinity();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccess() {
|
||||||
|
openDrawer();
|
||||||
|
changeNavigationFragment(new NaviSetupFragment());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickBackSetup() {
|
||||||
|
changeNavigationFragment(new NaviMainFragment());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickAdmin() {
|
||||||
|
changeNavigationFragment(new NaviAdminFragment());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickClearBatch() {
|
||||||
|
performAdminAction(
|
||||||
|
TransactionsType.CLEAR_BATCH,
|
||||||
|
TransMenu.CLEAR_BATCH,
|
||||||
|
R.id.inputPasswordFragment
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickClearReversal() {
|
||||||
|
performAdminAction(
|
||||||
|
TransactionsType.CLEAR_REVERSAL,
|
||||||
|
TransMenu.CLEAR_REVERSAL,
|
||||||
|
R.id.inputPasswordFragment
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void performAdminAction(TransactionsType transType, TransMenu transMenu, int destinationId) {
|
||||||
|
changeNavigationFragment(new NaviMainFragment());
|
||||||
|
closeDrawer();
|
||||||
|
sharedViewModel.transactionsType.postValue(transType);
|
||||||
|
sharedViewModel.setTransMenu(transMenu);
|
||||||
|
navController.navigate(destinationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickEditStan() {
|
||||||
|
changeNavigationFragment(new NaviMainFragment());
|
||||||
|
closeDrawer();
|
||||||
|
navController.navigate(R.id.editStanFragment);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickBackAdmin() {
|
||||||
|
changeNavigationFragment(new NaviSetupFragment());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickTWKLogin() {
|
||||||
|
showToast(getString(R.string.txt_twk_login));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickDestroyAllKeys() {
|
||||||
|
showToast(getString(R.string.txt_destroy_all_Keys));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickPrintKeyStatus() {
|
||||||
|
PrintXReceipt.getInstance().printKeyStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showToast(String message) {
|
||||||
|
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
926
app/src/main/java/com/utsmm/kbz/MainFragment.java
Normal file
926
app/src/main/java/com/utsmm/kbz/MainFragment.java
Normal file
@ -0,0 +1,926 @@
|
|||||||
|
package com.utsmm.kbz;
|
||||||
|
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
|
||||||
|
import com.denzcoskun.imageslider.ImageSlider;
|
||||||
|
import com.denzcoskun.imageslider.constants.ScaleTypes;
|
||||||
|
import com.denzcoskun.imageslider.models.SlideModel;
|
||||||
|
import com.pos.connection.bridge.binder.ECRConstant;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.emv.EmvParamOperation;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.DialogCallback;
|
||||||
|
import com.utsmyanmar.baselib.util.TerminalUtil;
|
||||||
|
import com.utsmyanmar.checkxread.sdk.NexGoSDK;
|
||||||
|
import com.utsmyanmar.ecr.ECRHelper;
|
||||||
|
import com.utsmyanmar.ecr.ECRProcess;
|
||||||
|
import com.utsmyanmar.ecr.data.ResultOf;
|
||||||
|
import com.utsmyanmar.ecr.data.model.Transactions;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.print.PrintHelper;
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.CurrencyType;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.TransMenu;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.config.data.model.ValidityStatus;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.TMSProcessViewModel;
|
||||||
|
import com.utsmm.kbz.util.Connectivity;
|
||||||
|
|
||||||
|
|
||||||
|
import com.utsmm.kbz.util.dialog.AlertXDialog;
|
||||||
|
import com.utsmm.kbz.util.enums.SettlementType;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
import com.utsmm.kbz.util.ProcessCode;
|
||||||
|
import com.utsmm.kbz.util.ecr.ECRConnectionStatus;
|
||||||
|
import com.utsmm.kbz.util.tms.TMSUtil;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
public class MainFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private static final String TAG = MainFragment.class.getSimpleName();
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private MainViewModel mainViewModel;
|
||||||
|
private TMSProcessViewModel tmsProcessViewModel;
|
||||||
|
private int routeId;
|
||||||
|
private ImageSlider imgSlider;
|
||||||
|
private final ArrayList<SlideModel> imgList = new ArrayList<>();
|
||||||
|
private Observer<PayDetail> observeLastTrans;
|
||||||
|
private PayDetail lastPay;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
EmvParamOperation emvParamOperation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.nav_main;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
mainViewModel = getFragmentScopeViewModel(MainViewModel.class);
|
||||||
|
tmsProcessViewModel = getFragmentScopeViewModel(TMSProcessViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setNavBarIconWithTitle(getResourceString(R.string.menu_dashboard));
|
||||||
|
|
||||||
|
// logcat is resetting cuz of this setup , because it is using serial port
|
||||||
|
if(SystemParamsOperation.getInstance().getECRStatus()){
|
||||||
|
// setUpECR();
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
|
||||||
|
CurrencyType currencyType = SystemParamsOperation.getInstance().getCurrencyType();
|
||||||
|
sharedViewModel.set_currencyText(currencyType.name);
|
||||||
|
sharedViewModel.setAmountExist(false);
|
||||||
|
sharedViewModel.setCardDataExist(false);
|
||||||
|
sharedViewModel.setTransMenu(null);
|
||||||
|
updateButtonStatus();
|
||||||
|
|
||||||
|
delayFunctionCall(this::checkTerminalStatus);
|
||||||
|
|
||||||
|
delayFunctionCall(()-> {
|
||||||
|
NexGoSDK.getInstance().cancelCheckCard();
|
||||||
|
NexGoSDK.getInstance().closeReader();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void checkTerminalStatus() {
|
||||||
|
if (!SystemParamsOperation.getInstance().isActive()) {
|
||||||
|
routeId = R.id.action_nav_main_to_disabledTerminalFragment;
|
||||||
|
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
if(SystemParamsOperation.getInstance().isAlertSound()) {
|
||||||
|
delayFunctionCall(this::checkPrinter);
|
||||||
|
}
|
||||||
|
|
||||||
|
delayFunctionCall(this::checkDownload);
|
||||||
|
|
||||||
|
mainViewModel.observeSettlementPOS();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void checkDownload() {
|
||||||
|
Log.d(TAG, "Calling from Check download: ");
|
||||||
|
if (!SystemParamsOperation.getInstance().isDownloadedParams() && SystemParamsOperation.getInstance().isActive() && tmsProcessViewModel.getIsCalled().getValue() == null) {
|
||||||
|
|
||||||
|
tmsProcessViewModel.setIsCalled(true);
|
||||||
|
routeId = R.id.action_nav_main_to_TMSProcessFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
imgSlider = mBinding.getRoot().findViewById(R.id.image_slider);
|
||||||
|
|
||||||
|
setUpCarouselImages();
|
||||||
|
|
||||||
|
if(TextUtils.equals(SystemParamsOperation.getInstance().getCurrentSerialNum(),"000001")) {
|
||||||
|
setPreviousTraceNum();
|
||||||
|
}
|
||||||
|
sharedViewModel.setManualEntryStatus(SystemParamsOperation.getInstance().getManualEntryStatus());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @param
|
||||||
|
*
|
||||||
|
* value - 0 = AID, 1 = CAPK
|
||||||
|
* */
|
||||||
|
private void queryAidCAPKList(int value) {
|
||||||
|
List<String> aidlist = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
int result = MyApplication.getInstance().mEMVOptV2.queryAidCapkList(value,aidlist);
|
||||||
|
LogUtil.d(TAG,"Query "+(value == 0?"AID":"CAPK")+" List result:"+result);
|
||||||
|
|
||||||
|
if(result == 0) {
|
||||||
|
|
||||||
|
for (String aid : aidlist) {
|
||||||
|
LogUtil.d(TAG,(value == 0?"AID:":"CAPK:")+aid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPreviousTraceNum() {
|
||||||
|
/* this function only needed after application update is performed */
|
||||||
|
mainViewModel.lastTrans.observe(getViewLifecycleOwner(), new Observer<PayDetail>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(PayDetail payDetail) {
|
||||||
|
if(payDetail == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SystemParamsOperation.getInstance().saveSerialNumber(payDetail.getVoucherNo());
|
||||||
|
SystemParamsOperation.getInstance().saveInvoiceNumber(payDetail.getInvoiceNo());
|
||||||
|
SystemParamsOperation.getInstance().saveBatchNumber(payDetail.getBatchNo());
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpECR() {
|
||||||
|
if (checkECRServiceAppExistOrNot()) {
|
||||||
|
|
||||||
|
|
||||||
|
if(!SystemParamsOperation.getInstance().isSetupEcr()){
|
||||||
|
initECR();
|
||||||
|
delayFunctionCall(this::createECRInstance);
|
||||||
|
SystemParamsOperation.getInstance().setSetupEcr(true);
|
||||||
|
onReceivedEcrCommand();
|
||||||
|
} else {
|
||||||
|
onReceivedEcrCommand();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Toast.makeText(getContext(), "ECR Service Not Found!", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createECRInstance() {
|
||||||
|
//
|
||||||
|
// currently will test with Bluetooth , afterward will switch to VSP mode
|
||||||
|
|
||||||
|
if(SystemParamsOperation.getInstance().isBluetoothMode()) {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString(ECRConstant.Configuration.MODE, ECRConstant.Mode.Bluetooth);
|
||||||
|
bundle.putString(ECRConstant.Configuration.TYPE, ECRConstant.Type.MASTER);
|
||||||
|
bundle.putString(ECRConstant.Configuration.BLUETOOTH_MAC_ADDRESS, "");
|
||||||
|
// mainViewModel.ecrConnectionStatus.setValue(ECRConnectionStatus.CREATED);
|
||||||
|
ECRHelper.INSTANCE.connect(bundle);
|
||||||
|
showShortToast("ECR service is created!");
|
||||||
|
} else {
|
||||||
|
Bundle bundle = new Bundle();
|
||||||
|
bundle.putString(ECRConstant.Configuration.MODE, ECRConstant.Mode.VSP);
|
||||||
|
bundle.putString(ECRConstant.Configuration.TYPE, ECRConstant.Type.MASTER); // MASTER
|
||||||
|
ECRHelper.INSTANCE.connect(bundle);
|
||||||
|
// mainViewModel.ecrConnectionStatus.setValue(ECRConnectionStatus.CREATED);
|
||||||
|
showShortToast("ECR service is created!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateButtonStatus() {
|
||||||
|
mainViewModel.settlementStatus.setValue(SystemParamsOperation.getInstance().getSettlementStatus());
|
||||||
|
mainViewModel.kPayStatus.setValue(SystemParamsOperation.getInstance().getQRPayStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpCarouselImages() {
|
||||||
|
|
||||||
|
String imgUrls = SystemParamsOperation.getInstance().getCarouselUrls();
|
||||||
|
|
||||||
|
imgList.clear();
|
||||||
|
|
||||||
|
if(imgUrls == null || imgUrls.isEmpty() ) {
|
||||||
|
String defaultUrl = getResourceString(R.string.txt_default_carousel_img_url);
|
||||||
|
imgList.add(new SlideModel(defaultUrl,"", ScaleTypes.CENTER_CROP));
|
||||||
|
imgSlider.setImageList(imgList);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ArrayList<String> urls = TMSUtil.getInstance().convertToArray(imgUrls);
|
||||||
|
|
||||||
|
for(String url : urls) {
|
||||||
|
imgList.add(new SlideModel(url.trim(),"", ScaleTypes.CENTER_CROP));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
imgSlider.setImageList(imgList);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private boolean checkECRServiceAppExistOrNot() {
|
||||||
|
PackageInfo packageInfo;
|
||||||
|
try {
|
||||||
|
packageInfo = requireActivity().getPackageManager().getPackageInfo("com.pos.ecr.service", 0);
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return packageInfo != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
|
||||||
|
return new DataBindingConfig(R.layout.fragment_dashboard_screen, BR.shareViewModel, sharedViewModel)
|
||||||
|
.addBindingParam(BR.mainViewModel, mainViewModel)
|
||||||
|
.addBindingParam(BR.click, new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void checkPrinter() {
|
||||||
|
if (PrintHelper.getInstance().paperRollStatus() == 2) {
|
||||||
|
}
|
||||||
|
else if (PrintHelper.getInstance().paperRollStatus() == 4) {
|
||||||
|
|
||||||
|
mainViewModel.playAtOnce.setValue(false);
|
||||||
|
showPrinterAlertDialog(getResourceString(R.string.txt_paper_roll_not_ready), new DialogCallback() {
|
||||||
|
@Override
|
||||||
|
public void onClickCancel() {
|
||||||
|
dismissPrinterAlertDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickRetry() {
|
||||||
|
dismissPrinterAlertDialog();
|
||||||
|
checkPrinter();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// startSound(getResourceString(R.string.txt_audio_printer_alert));
|
||||||
|
} else if (PrintHelper.getInstance().paperRollStatus() == 1) {
|
||||||
|
|
||||||
|
if( mainViewModel.playAtOnce.getValue() != null && !mainViewModel.playAtOnce.getValue()) {
|
||||||
|
startSound(getResourceString(R.string.txt_audio_paper_ready_alert));
|
||||||
|
mainViewModel.playAtOnce.setValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (PrintHelper.getInstance().paperRollStatus() == 0) {
|
||||||
|
LogUtil.d(TAG,"Printer not found!");
|
||||||
|
// showDeclineDialog(getResourceString(R.string.txt_alert_printer_not_found));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void isRouteValidAndNavigateToRoute(int routeId) {
|
||||||
|
if (Objects.requireNonNull(getNavController(Constants.NAV_HOST_ID).getCurrentDestination()).getId() == R.id.nav_main) {
|
||||||
|
getNavController(Constants.NAV_HOST_ID).navigate(routeId);
|
||||||
|
} else {
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
ECRHelper.INSTANCE.send(getResourceString(R.string.txt_finish_current_process).getBytes());
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_finish_current_process));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* init ECR service
|
||||||
|
*/
|
||||||
|
private void initECR() {
|
||||||
|
ECRHelper.INSTANCE.registerECRListener();
|
||||||
|
|
||||||
|
ECRHelper.INSTANCE.setOnBindSuccess(() -> {
|
||||||
|
ECRHelper.INSTANCE.registerECRListener();
|
||||||
|
LogUtil.d(TAG, "on bind success!");
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
ECRHelper.INSTANCE.setOnBindFailure(() -> {
|
||||||
|
LogUtil.d(TAG, "on bind failure!");
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
ECRHelper.INSTANCE.setOnECRConnected(() -> {
|
||||||
|
delayFunctionCall(() -> mainViewModel.ecrConnectionStatus.postValue(ECRConnectionStatus.CONNECTED));
|
||||||
|
LogUtil.d(TAG, "On ECR Connected!");
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
ECRHelper.INSTANCE.setOnECRDisconnected((integer, s) -> {
|
||||||
|
delayFunctionCall(() -> mainViewModel.ecrConnectionStatus.postValue(ECRConnectionStatus.DISCONNECTED));
|
||||||
|
LogUtil.d(TAG, "On ECR Disconnected! Code:" + integer + ":Msg:" + s);
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
ECRHelper.INSTANCE.bindECRService();
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"Bind ECR Service successfully!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onReceivedEcrCommand() {
|
||||||
|
ECRHelper.INSTANCE.setOnECRReceive(bytes -> {
|
||||||
|
String msg = new String(bytes, StandardCharsets.UTF_8);
|
||||||
|
LogUtil.d(TAG, "Received : " + msg);
|
||||||
|
if (sharedViewModel.isEcrFinished.getValue() != null) {
|
||||||
|
if (sharedViewModel.isEcrFinished.getValue()) {
|
||||||
|
ECRAction(msg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ECRAction(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param msg ECR Transaction Type
|
||||||
|
*/
|
||||||
|
private void ECRAction(String msg) {
|
||||||
|
|
||||||
|
// LogUtil.d(TAG, "ECR msg here : " + msg);
|
||||||
|
|
||||||
|
String ecrKey = SystemParamsOperation.getInstance().getEcrKey().toUpperCase();
|
||||||
|
String pkgName = BuildConfig.APPLICATION_ID;
|
||||||
|
String serialNo = TerminalUtil.getInstance().getSerialNo();
|
||||||
|
|
||||||
|
ResultOf<Transactions> result = ECRProcess.INSTANCE.parseECRRequest(ecrKey,pkgName,serialNo,msg);
|
||||||
|
|
||||||
|
if (result instanceof ResultOf.Success) {
|
||||||
|
Transactions trans = ((ResultOf.Success<Transactions>) result).getValue();
|
||||||
|
|
||||||
|
|
||||||
|
CoreUtils.getInstance(sharedViewModel).logTrans(trans);
|
||||||
|
|
||||||
|
sharedViewModel.ecrCMD.postValue(trans.getCMD());
|
||||||
|
sharedViewModel.ecrTrans.postValue(trans);
|
||||||
|
|
||||||
|
switch (Objects.requireNonNull(trans.getCMD())) {
|
||||||
|
case ECHO:
|
||||||
|
CoreUtils.getInstance(sharedViewModel).setUpECREchoTest();
|
||||||
|
break;
|
||||||
|
case SALE:
|
||||||
|
if (CoreUtils.getInstance(sharedViewModel).setUpECRSale(trans)) {
|
||||||
|
delayFunctionCall(() -> isRouteValidAndNavigateToRoute(R.id.action_nav_main_to_cardWaitingFragment));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VOID:
|
||||||
|
if(!SystemParamsOperation.getInstance().getVoidStatus()) {
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(trans,"Void is disabled!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (CoreUtils.getInstance(sharedViewModel).setUpECRVoid(trans)) {
|
||||||
|
delayFunctionCall(() -> {
|
||||||
|
if(Objects.requireNonNull(getNavController(Constants.NAV_HOST_ID).getCurrentDestination()).getId() == R.id.nav_main) {
|
||||||
|
setToolBarTitle(getResourceString(R.string.menu_sale_void));
|
||||||
|
}
|
||||||
|
|
||||||
|
isRouteValidAndNavigateToRoute(R.id.action_nav_main_to_inputPasswordFragment);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CASH_ADVANCE: {
|
||||||
|
|
||||||
|
if (CoreUtils.getInstance(sharedViewModel).setUpECRCashAdvance(trans)) {
|
||||||
|
delayFunctionCall(() -> isRouteValidAndNavigateToRoute(R.id.action_nav_main_to_cardWaitingFragment));
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case QR_SALE: {
|
||||||
|
if (CoreUtils.getInstance(sharedViewModel).setUpECRQR(trans)) {
|
||||||
|
delayFunctionCall(() -> isRouteValidAndNavigateToRoute(R.id.action_nav_main_to_QRConnectingFragment));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
case SETTLEMENT: {
|
||||||
|
if(!SystemParamsOperation.getInstance().getSettlementStatus()) {
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(trans,"Settlement is disabled!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CoreUtils.getInstance(sharedViewModel).setUpECRSettlement();
|
||||||
|
|
||||||
|
delayFunctionCall(() -> isRouteValidAndNavigateToRoute(R.id.action_nav_main_to_inputPasswordFragment));
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
showDeclineDialog("No Action found on \n" + trans.getCMD());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String errorMsg = ((ResultOf.Failure) result).getMessage();
|
||||||
|
showDeclineDialog("No Action found on \n" + errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToAmount() {
|
||||||
|
routeId = R.id.action_nav_main_to_inputAmountFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processBatch() {
|
||||||
|
|
||||||
|
calculateLastTransaction();
|
||||||
|
|
||||||
|
mainViewModel.observeSettlementPOS();
|
||||||
|
observeLastTrans = payDetail -> {
|
||||||
|
|
||||||
|
if(payDetail == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SystemParamsOperation.getInstance().saveSerialNumber(payDetail.getVoucherNo());
|
||||||
|
// SystemParamsOperation.getInstance().saveInvoiceNumber(payDetail.getInvoiceNo());
|
||||||
|
|
||||||
|
if(lastPay != null) {
|
||||||
|
Date lastPayDate = POSUtil.getInstance().getDateByString(lastPay.getTransDate());
|
||||||
|
Date observePayDate = POSUtil.getInstance().getDateByString(payDetail.getTransDate());
|
||||||
|
|
||||||
|
if(lastPayDate.compareTo(observePayDate) < 0) {
|
||||||
|
payDetail = lastPay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LogUtil.d(TAG,"TransDetail :"+payDetail.getTransType() + "- Trans Time :"+payDetail.getTransDate());
|
||||||
|
|
||||||
|
if(payDetail.getTransactionType() == TransactionsType.SETTLEMENT.value){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* saving for api post request, to send in next time.
|
||||||
|
* */
|
||||||
|
SystemParamsOperation.getInstance().setLastTransTime(String.valueOf(payDetail.getTransNum()));
|
||||||
|
SystemParamsOperation.getInstance().setLastTransName(payDetail.getTransType());
|
||||||
|
|
||||||
|
|
||||||
|
String lastTransDate = payDetail.getTransDate();
|
||||||
|
String lastTransTime = payDetail.getTransTime();
|
||||||
|
|
||||||
|
Date today = POSUtil.getInstance().getCurrentDate();
|
||||||
|
Date transDate;
|
||||||
|
Date current = new Date(System.currentTimeMillis());
|
||||||
|
String configTimer = SystemParamsOperation.getInstance().getClearBatchTime();
|
||||||
|
// LogUtil.d(TAG,"Config Time :" + configTimer);
|
||||||
|
String configTime = "23:00";
|
||||||
|
int configDay = 10;
|
||||||
|
|
||||||
|
String configRawDay = SystemParamsOperation.getInstance().getClearBatchDay();
|
||||||
|
|
||||||
|
if(configRawDay != null && !configRawDay.trim().isEmpty()) {
|
||||||
|
try {
|
||||||
|
configDay = Integer.parseInt(configRawDay);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(configTimer != null && !configTimer.trim().isEmpty() && checkValidTime(configTimer.trim())) {
|
||||||
|
configTime = configTimer.trim();
|
||||||
|
}
|
||||||
|
Date configDateTime = POSUtil.getInstance().getDateTime(configTime);
|
||||||
|
Date yesterdayConfigDateTime = POSUtil.getInstance().getYesterdayConfigDateTime(configTime);
|
||||||
|
|
||||||
|
transDate = POSUtil.getInstance().getDateByString(lastTransDate);
|
||||||
|
|
||||||
|
Date yesterdayDate = POSUtil.getInstance().getYesterdayDate();
|
||||||
|
|
||||||
|
if(today.compareTo(transDate) == 0) {
|
||||||
|
|
||||||
|
// LogUtil.d(TAG,"Last Trans is Today!");
|
||||||
|
// LogUtil.d(TAG,"date current :!"+current);
|
||||||
|
// LogUtil.d(TAG,"date config :!"+configDateTime);
|
||||||
|
|
||||||
|
// Today
|
||||||
|
if(current.compareTo(configDateTime) > 0) {
|
||||||
|
// clear batch and force update param
|
||||||
|
|
||||||
|
// LogUtil.d(TAG,"Last Trans is Today! Config time is passed!");
|
||||||
|
// if (!SystemParamsOperation.getInstance().isClearBatch()) {
|
||||||
|
if (checkSyncTrans() || !SystemParamsOperation.getInstance().isClearBatch() ) {
|
||||||
|
// LogUtil.d(TAG,"Clearing....");
|
||||||
|
if(!SystemParamsOperation.getInstance().getSettlementStatus()) {
|
||||||
|
clearBatchAndDownload(configDay,payDetail);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// LogUtil.d(TAG,"Last Trans is Today! Config time is not passed yet.....");
|
||||||
|
SystemParamsOperation.getInstance().setClearBatch(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// LogUtil.d(TAG,"Last Trans is Before Today!");
|
||||||
|
Date yest;
|
||||||
|
if(configTime.equals("00:00")) {
|
||||||
|
yest = configDateTime;
|
||||||
|
} else {
|
||||||
|
yest = yesterdayConfigDateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Date lastTransDateTime = POSUtil.getInstance().getDateByTransDateTime(lastTransDate,lastTransTime);
|
||||||
|
// LogUtil.d(TAG,"Compare Result : "+lastTransDateTime.compareTo(yest));
|
||||||
|
|
||||||
|
if(yest.compareTo(lastTransDateTime) < 0) {
|
||||||
|
// LogUtil.d(TAG,"Trans is yesterday, but after config time, no action!");
|
||||||
|
} else {
|
||||||
|
// LogUtil.d(TAG,"Trans is yesterday, before config time,");
|
||||||
|
// if(!checkSyncTrans()) {
|
||||||
|
// LogUtil.d(TAG,"Clearing....");
|
||||||
|
if(!SystemParamsOperation.getInstance().getSettlementStatus()) {
|
||||||
|
clearBatchAndDownload(configDay,payDetail);
|
||||||
|
}
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if(mainViewModel.lastTrans.hasActiveObservers()) {
|
||||||
|
mainViewModel.lastTrans.removeObserver(observeLastTrans);
|
||||||
|
}
|
||||||
|
mainViewModel.lastTrans.observe(getViewLifecycleOwner(),observeLastTrans);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculateLastTransaction() {
|
||||||
|
mainViewModel.allTrans.observe(getViewLifecycleOwner(), new Observer<List<PayDetail>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(List<PayDetail> payDetails) {
|
||||||
|
if(payDetails == null || payDetails.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
PayDetail tempPay = payDetails.get(0);
|
||||||
|
for (int i = 0; i < payDetails.size() ; i++) {
|
||||||
|
|
||||||
|
Date tempDate = POSUtil.getInstance().getDateByString(tempPay.getTransDate());
|
||||||
|
Date indexDate = POSUtil.getInstance().getDateByString(payDetails.get(i).getTransDate());
|
||||||
|
|
||||||
|
if(tempDate.compareTo(indexDate) > 0) {
|
||||||
|
// if before
|
||||||
|
tempPay = payDetails.get(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastPay = tempPay;
|
||||||
|
|
||||||
|
// LogUtil.d(TAG,"Transaction Name : "+tempPay.getTransType());
|
||||||
|
// LogUtil.d(TAG,"Transaction Type : "+tempPay.getTransactionType());
|
||||||
|
// LogUtil.d(TAG,"Transaction Amount : "+tempPay.getAmount());
|
||||||
|
// LogUtil.d(TAG,"Transaction Date/Time : "+tempPay.getTransDate()+"/"+tempPay.getTransTime());
|
||||||
|
// LogUtil.d(TAG,"RRN/Trace : "+tempPay.getReferNo()+"/"+tempPay.getVoucherNo());
|
||||||
|
// LogUtil.d(TAG,"Transaction is canceled : "+tempPay.isCanceled());
|
||||||
|
// LogUtil.d(TAG,"Transaction settlement config : "+tempPay.isSettlementEnabled());
|
||||||
|
// LogUtil.d(TAG,"----------------------------------------------------------");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkSyncTrans() {
|
||||||
|
String transDateString = SystemParamsOperation.getInstance().getSyncTransDate();
|
||||||
|
Date today = POSUtil.getInstance().getCurrentDate();
|
||||||
|
if(transDateString == null || transDateString.isEmpty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Date transDate = POSUtil.getInstance().getDateByString(transDateString);
|
||||||
|
return today.compareTo(transDate) == 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void clearBatchAndDownload(int configDay,PayDetail payDetail) {
|
||||||
|
|
||||||
|
|
||||||
|
Date yesterday = POSUtil.getInstance().getYesterdayDate();
|
||||||
|
Date lastInputDay = POSUtil.getInstance().getLastInputDay(configDay);
|
||||||
|
mainViewModel.settlementPOS.observe(getViewLifecycleOwner(), list -> {
|
||||||
|
|
||||||
|
Date transDate;
|
||||||
|
|
||||||
|
if(list == null || list.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PayDetail pay:list) {
|
||||||
|
/*
|
||||||
|
* To Hold One day transaction!
|
||||||
|
* */
|
||||||
|
|
||||||
|
transDate = POSUtil.getInstance().getDateByString(pay.getTransDate());
|
||||||
|
|
||||||
|
if (pay.getTransactionType() == TransactionsType.SALE.value) {
|
||||||
|
if(lastInputDay.compareTo(transDate) > 0) {
|
||||||
|
mainViewModel.deletePayDetail(pay);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(yesterday.compareTo(transDate) > 0 ) {
|
||||||
|
mainViewModel.deletePayDetail(pay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
mainViewModel.deleteTrans.observe(getViewLifecycleOwner(), lists -> {
|
||||||
|
Date transDate;
|
||||||
|
if(lists == null || lists.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PayDetail pay:lists) {
|
||||||
|
/*
|
||||||
|
* To Hold One day transaction!
|
||||||
|
* */
|
||||||
|
|
||||||
|
transDate = POSUtil.getInstance().getDateByString(pay.getTransDate());
|
||||||
|
// LogUtil.d(TAG,"Trans Type : "+pay.getTransType()+"<=====> Trans Date :"+pay.getTransDate());
|
||||||
|
// LogUtil.d(TAG,"Yesterday Date: "+yesterday.toString());
|
||||||
|
// LogUtil.d(TAG,"Compare result :"+yesterday.compareTo(transDate));
|
||||||
|
|
||||||
|
if(yesterday.compareTo(transDate) > 0) {
|
||||||
|
mainViewModel.deletePayDetail(pay);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
mainViewModel.preAuthTrans.observe(getViewLifecycleOwner(), lists -> {
|
||||||
|
Date transDate;
|
||||||
|
if(lists == null || lists.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PayDetail pay:lists) {
|
||||||
|
|
||||||
|
transDate = POSUtil.getInstance().getDateByString(pay.getTransDate());
|
||||||
|
|
||||||
|
if (lastInputDay.compareTo(transDate) > 0) {
|
||||||
|
mainViewModel.deletePayDetail(pay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Need to think about his problem .... Nov 7, 2024
|
||||||
|
* */
|
||||||
|
if(!SystemParamsOperation.getInstance().isClearBatch()) {
|
||||||
|
// downloadParams(payDetail.getTransType(),String.valueOf(payDetail.getTransNum()),TMSUpdate.UPDATE,false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// private void generateMockPreAuth() {
|
||||||
|
// String transDate = "01/03/24";
|
||||||
|
// String transTime = "12:27:30";
|
||||||
|
// TradeData tradeData = MockData.getInstance().generateMockDataWithTime(TransactionsType.PRE_AUTH_SALE, AidlConstantsV2.CardType.IC.getValue(),transDate,transTime);
|
||||||
|
// PayDetail payDetail = tradeData.getPayDetail();
|
||||||
|
// sharedViewModel.insertPayDetail(payDetail);
|
||||||
|
// LogUtil.d(TAG,"------------------- Inserted Mocked Data ------------------");
|
||||||
|
// LogUtil.d(TAG,"trans date : "+payDetail.getTransDate() +"- Trans Time: "+payDetail.getTransTime());
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
public void onClickTrans() {
|
||||||
|
|
||||||
|
if (!Connectivity.isConnectedWifi(getContext()) && !Connectivity.isConnectedMobile(getContext())) {
|
||||||
|
showSingleInfoDialog(getResourceString(R.string.txt_please_enable_internet));
|
||||||
|
} else if (TMSUtil.getInstance().checkParams().isStatus() == ValidityStatus.FAILURE) {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_please_download_config)+"\n"+TMSUtil.getInstance().checkParams().getMessage());
|
||||||
|
} else if(SystemParamsOperation.getInstance().isNeedSettlement()) {
|
||||||
|
AlertXDialog.getInstance().showDialog(requireContext(), getResourceString(R.string.title_need_settle), getResourceString(R.string.txt_do_you_want_to_continue), () -> {
|
||||||
|
int mainToDashboard = R.id.action_nav_main_to_dashboardTransFragment;
|
||||||
|
safeRouteTo(R.id.nav_main,mainToDashboard,Constants.NAV_HOST_ID);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
|
||||||
|
int mainToDashboard = R.id.action_nav_main_to_dashboardTransFragment;
|
||||||
|
safeRouteTo(R.id.nav_main,mainToDashboard,Constants.NAV_HOST_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickCard() {
|
||||||
|
|
||||||
|
if (mainViewModel.payDetailSingle.getValue() != null) {
|
||||||
|
mainViewModel.startReversal(mainViewModel.payDetailSingle.getValue());
|
||||||
|
} else if (TMSUtil.getInstance().checkParams().isStatus() == ValidityStatus.FAILURE) {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_please_download_config)+"\n"+TMSUtil.getInstance().checkParams().getMessage());
|
||||||
|
} else if (!Connectivity.isConnectedWifi(getContext()) && !Connectivity.isConnectedMobile(getContext())) {
|
||||||
|
showSingleInfoDialog(getResourceString(R.string.txt_please_enable_internet));
|
||||||
|
} else if(SystemParamsOperation.getInstance().isNeedSettlement()) {
|
||||||
|
AlertXDialog.getInstance().showDialog(requireContext(), getResourceString(R.string.title_need_settle), getResourceString(R.string.txt_do_you_want_to_continue), () -> {
|
||||||
|
processBatch();
|
||||||
|
sharedViewModel.transactionsType.setValue(TransactionsType.SALE);
|
||||||
|
sharedViewModel.processCode.postValue(ProcessCode.SALE_PURCHASE + ProcessCode.SMART + ProcessCode.TO_ACCOUNT);
|
||||||
|
navigateToAmount();
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
processBatch();
|
||||||
|
sharedViewModel.transactionsType.setValue(TransactionsType.SALE);
|
||||||
|
sharedViewModel.processCode.postValue(ProcessCode.SALE_PURCHASE + ProcessCode.SMART + ProcessCode.TO_ACCOUNT);
|
||||||
|
navigateToAmount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickQRPay() {
|
||||||
|
|
||||||
|
String mmqrIp = SystemParamsOperation.getInstance().getSecHostIpAddress();
|
||||||
|
|
||||||
|
if (mainViewModel.payDetailSingle.getValue() != null) {
|
||||||
|
mainViewModel.startReversal(mainViewModel.payDetailSingle.getValue());
|
||||||
|
}
|
||||||
|
// else if (TMSUtil.getInstance().checkSecHostParams().isStatus() == ValidityStatus.FAILURE) {
|
||||||
|
// showDeclineDialog(getResourceString(R.string.txt_please_download_config)+"\n"+TMSUtil.getInstance().checkSecHostParams().getMessage());
|
||||||
|
// }
|
||||||
|
else if (!Connectivity.isConnectedWifi(getContext()) && !Connectivity.isConnectedMobile(getContext())) {
|
||||||
|
showSingleInfoDialog(getResourceString(R.string.txt_please_enable_internet));
|
||||||
|
}
|
||||||
|
// else if (!isValidDomain(mmqrIp)) {
|
||||||
|
// showDeclineDialog(getResourceString(R.string.txt_please_check_mmqr_ip));
|
||||||
|
// }
|
||||||
|
else {
|
||||||
|
CurrencyType currencyType = TMSUtil.getInstance().currencyTextToCurrencyType(SystemParamsOperation.getInstance().getSecHostCurrency());
|
||||||
|
sharedViewModel.set_currencyText(currencyType.name);
|
||||||
|
processBatch();
|
||||||
|
sharedViewModel.transactionsType.setValue(TransactionsType.MMQR);
|
||||||
|
navigateToAmount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickSettlement() {
|
||||||
|
|
||||||
|
if (mainViewModel.payDetailSingle.getValue() != null) {
|
||||||
|
mainViewModel.startReversal(mainViewModel.payDetailSingle.getValue());
|
||||||
|
} else if (TMSUtil.getInstance().checkParams().isStatus() == ValidityStatus.FAILURE) {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_please_download_config)+"\n"+TMSUtil.getInstance().checkParams().getMessage());
|
||||||
|
} else if (!Connectivity.isConnectedWifi(getContext()) && !Connectivity.isConnectedMobile(getContext())) {
|
||||||
|
showSingleInfoDialog(getResourceString(R.string.txt_please_enable_internet));
|
||||||
|
} else {
|
||||||
|
sharedViewModel.settlementType.setValue(SettlementType.NORMAL);
|
||||||
|
sharedViewModel.transactionsType.setValue(TransactionsType.SETTLEMENT);
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.SETTLEMENT);
|
||||||
|
setToolBarTitle(getResourceString(R.string.menu_settlement));
|
||||||
|
|
||||||
|
routeId = R.id.action_nav_main_to_inputPasswordFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickManagementFeatures() {
|
||||||
|
|
||||||
|
if (mainViewModel.payDetailSingle.getValue() != null) {
|
||||||
|
mainViewModel.startReversal(mainViewModel.payDetailSingle.getValue());
|
||||||
|
} else if (checkTid()) {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_please_download_config));
|
||||||
|
} else {
|
||||||
|
routeId = R.id.action_nav_main_to_managementFunctionFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickSignOn() {
|
||||||
|
if (mainViewModel.payDetailSingle.getValue() != null) {
|
||||||
|
mainViewModel.startReversal(mainViewModel.payDetailSingle.getValue());
|
||||||
|
} else if (checkTid()) {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_please_download_config));
|
||||||
|
} else if (!Connectivity.isConnectedWifi(getContext()) && !Connectivity.isConnectedMobile(getContext())) {
|
||||||
|
showSingleInfoDialog(getResourceString(R.string.txt_please_enable_internet));
|
||||||
|
} else if (SystemParamsOperation.getInstance().isNeedSettlement()) {
|
||||||
|
AlertXDialog.getInstance().showDialog(requireContext(), getResourceString(R.string.title_need_settle), getResourceString(R.string.txt_do_you_want_to_continue), () -> {
|
||||||
|
routeId = R.id.action_nav_main_to_nav_sign_on;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
routeId = R.id.action_nav_main_to_nav_sign_on;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
251
app/src/main/java/com/utsmm/kbz/MainViewModel.java
Normal file
251
app/src/main/java/com/utsmm/kbz/MainViewModel.java
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
package com.utsmm.kbz;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.db.model.EmvDetail;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusResponse;
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.model.TradeData;
|
||||||
|
import com.utsmyanmar.paylibs.network.ISOSocket;
|
||||||
|
import com.utsmyanmar.paylibs.reversal.ReversalAction;
|
||||||
|
import com.utsmyanmar.paylibs.reversal.ReversalListener;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmm.kbz.service.SmileSettleService;
|
||||||
|
import com.utsmm.kbz.util.enums.ReversalStatus;
|
||||||
|
import com.utsmm.kbz.util.ecr.ECRConnectionStatus;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext;
|
||||||
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class MainViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private static final String TAG = MainViewModel.class.getSimpleName();
|
||||||
|
|
||||||
|
private final Repository repository;
|
||||||
|
|
||||||
|
public SingleLiveEvent<ReversalStatus> reversalStatus = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<PayDetail> payDetailSingle = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
private boolean isSecondCall = false;
|
||||||
|
|
||||||
|
private static final String REVERSAL = "REVERSAL";
|
||||||
|
|
||||||
|
|
||||||
|
public SingleLiveEvent<ECRConnectionStatus> ecrConnectionStatus = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<Boolean> playAtOnce = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Boolean> settlementStatus = new MutableLiveData<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Boolean> kPayStatus = new MutableLiveData<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> disabledMsg = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<List<PayDetail>> settlementPOS = new SingleLiveEvent<>();
|
||||||
|
public SingleLiveEvent<List<PayDetail>> deleteTrans = new SingleLiveEvent<>();
|
||||||
|
public SingleLiveEvent<PayDetail> lastTrans = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<List<PayDetail>> allTrans = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<List<PayDetail>> preAuthTrans = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> qrData = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
private int reversalCount = 0;
|
||||||
|
|
||||||
|
private BroadcastReceiver dataReceiver = new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (intent.getAction().equals(SmileSettleService.ACTION_DATA_RECEIVED)) {
|
||||||
|
String data = intent.getStringExtra(SmileSettleService.EXTRA_DATA);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public MainViewModel(Repository repository, @ApplicationContext Context context) {
|
||||||
|
this.repository = repository;
|
||||||
|
|
||||||
|
playAtOnce.setValue(false);
|
||||||
|
|
||||||
|
LocalBroadcastManager.getInstance(context).registerReceiver(dataReceiver,
|
||||||
|
new IntentFilter(SmileSettleService.ACTION_DATA_RECEIVED));
|
||||||
|
|
||||||
|
settlementStatus.setValue(SystemParamsOperation.getInstance().getSettlementStatus());
|
||||||
|
|
||||||
|
kPayStatus.setValue(SystemParamsOperation.getInstance().getQRPayStatus());
|
||||||
|
|
||||||
|
disabledMsg.setValue(SystemParamsOperation.getInstance().getDisabledMsg());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCleared() {
|
||||||
|
super.onCleared();
|
||||||
|
|
||||||
|
// LocalBroadcastManager.getInstance(getApplication()).unregisterReceiver(dataReceiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public LiveData<List<EmvDetail>> getAllEmvDetails() {
|
||||||
|
return repository.getAllEmvDetails();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public LiveData<PayDetail> getReversalTransaction(String voucherNo) {
|
||||||
|
return repository.getReversalTransaction(voucherNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<List<PayDetail>> getSettlementPOSClearBatch() {
|
||||||
|
return repository.getSettlementPOSClearBatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public LiveData<List<PayDetail>> getDeleteTrans(String batchNo) {
|
||||||
|
return repository.getDeleteTrans(batchNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LiveData<List<PayDetail>> getPreAuthTrans() {
|
||||||
|
return repository.getPreAuthTrans();
|
||||||
|
}
|
||||||
|
|
||||||
|
private LiveData<List<PayDetail>> getAllTrans() {
|
||||||
|
return repository.getAllTrans();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deletePayDetail(PayDetail payDetail) {
|
||||||
|
repository.deletePayDetail(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<PayDetail> getLastTransaction() {
|
||||||
|
return repository.getLastTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<SiriusResponse> getParams(SiriusRequest siriusRequest) {
|
||||||
|
return repository.getParams(siriusRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void observeSettlementPOS() {
|
||||||
|
getAllTrans().observeForever(new Observer<List<PayDetail>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(List<PayDetail> payDetails) {
|
||||||
|
allTrans.postValue(payDetails);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
getLastTransaction().observeForever(new Observer<PayDetail>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(PayDetail payDetail) {
|
||||||
|
lastTrans.postValue(payDetail);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
getSettlementPOSClearBatch().observeForever(new Observer<List<PayDetail>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(List<PayDetail> payDetails) {
|
||||||
|
settlementPOS.postValue(payDetails);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
getDeleteTrans(SystemParamsOperation.getInstance().getCurrentBatchNum()).observeForever(new Observer<List<PayDetail>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(List<PayDetail> payDetails) {
|
||||||
|
deleteTrans.postValue(payDetails);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
getPreAuthTrans().observeForever(new Observer<List<PayDetail>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(List<PayDetail> payDetails) {
|
||||||
|
preAuthTrans.postValue(payDetails);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void startReversal(PayDetail payDetail) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
reversalCount ++ ;
|
||||||
|
|
||||||
|
|
||||||
|
if(reversalCount > 3) {
|
||||||
|
payDetailSingle.postValue(null);
|
||||||
|
reversalStatus.postValue(ReversalStatus.PAUSE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isSecondCall){
|
||||||
|
reversalStatus.postValue(ReversalStatus.SENDING);
|
||||||
|
}else{
|
||||||
|
reversalStatus.postValue(ReversalStatus.SECONDARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
TradeData tradeData = new TradeData();
|
||||||
|
tradeData.setPayDetail(payDetail);
|
||||||
|
|
||||||
|
ReversalAction.getInstance().setData(tradeData).enqueue().startReversal(new ReversalListener() {
|
||||||
|
@Override
|
||||||
|
public void onSuccessReversal() {
|
||||||
|
payDetail.setIsNeedReversal(false);
|
||||||
|
repository.updatePayDetail(payDetail);
|
||||||
|
reversalStatus.postValue(ReversalStatus.ON_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNetworkFail(String msg) {
|
||||||
|
if(SystemParamsOperation.getInstance().isSecondHostEnabled()) {
|
||||||
|
if (!isSecondCall) {
|
||||||
|
|
||||||
|
ISOSocket.getInstance().switchIp();
|
||||||
|
isSecondCall = true;
|
||||||
|
startReversal(payDetail);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
reversalStatus.postValue(ReversalStatus.ON_FAILURE);
|
||||||
|
isSecondCall = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
reversalStatus.postValue(ReversalStatus.ON_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
payDetail.setNeedReversal(true);
|
||||||
|
repository.updatePayDetail(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailReversal(String msg) {
|
||||||
|
isSecondCall = false;
|
||||||
|
reversalStatus.postValue(ReversalStatus.ON_FAILURE);
|
||||||
|
payDetail.setNeedReversal(true);
|
||||||
|
repository.updatePayDetail(payDetail);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
29
app/src/main/java/com/utsmm/kbz/MyApplication.java
Normal file
29
app/src/main/java/com/utsmm/kbz/MyApplication.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package com.utsmm.kbz;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.BaseApplication;
|
||||||
|
|
||||||
|
import dagger.hilt.android.HiltAndroidApp;
|
||||||
|
|
||||||
|
@HiltAndroidApp
|
||||||
|
public class MyApplication extends BaseApplication {
|
||||||
|
|
||||||
|
private static MyApplication app;
|
||||||
|
|
||||||
|
public static MyApplication getInstance(){
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Inject
|
||||||
|
// EmvParamOperation emvParamOperation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
app = this;
|
||||||
|
|
||||||
|
|
||||||
|
// emvParamOperation.loadDataFromJSON();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
17
app/src/main/java/com/utsmm/kbz/config/Constants.java
Normal file
17
app/src/main/java/com/utsmm/kbz/config/Constants.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package com.utsmm.kbz.config;
|
||||||
|
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
|
||||||
|
public class Constants {
|
||||||
|
|
||||||
|
public static int NAV_HOST_ID = R.id.nav_host_fragment;
|
||||||
|
|
||||||
|
public static final String WALLET = "WALLET";
|
||||||
|
public static final String MPU_CARD_SCHEME = "MPU";
|
||||||
|
|
||||||
|
public static final int TIMEOUT = 30;
|
||||||
|
public static final int PROCESSING_TIMEOUT = 180;
|
||||||
|
public static final int PIN_PAD_TIMEOUT = 60;
|
||||||
|
|
||||||
|
public static final String REVERSAL = "REVERSAL";
|
||||||
|
}
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package com.utsmm.kbz.config;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
|
||||||
|
public class UTSManageSpaceActivity extends AppCompatActivity {
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_uts_manage_space);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
package com.utsmm.kbz.config.data.model;
|
||||||
|
|
||||||
|
public enum CardTransactionType {
|
||||||
|
|
||||||
|
MPU,
|
||||||
|
EMV,
|
||||||
|
MAG,
|
||||||
|
FALLBACK,
|
||||||
|
MOCK
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
package com.utsmm.kbz.config.data.model;
|
||||||
|
|
||||||
|
import com.utsmm.kbz.util.enums.FeaturesType;
|
||||||
|
|
||||||
|
public class Features {
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private String name;
|
||||||
|
private int drawable;
|
||||||
|
private FeaturesType featuresType;
|
||||||
|
private boolean active;
|
||||||
|
|
||||||
|
public Features(int id, String name, int drawable, FeaturesType featuresType) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.drawable = drawable;
|
||||||
|
this.featuresType = featuresType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Features(int id, String name, int drawable, FeaturesType featuresType, boolean active) {
|
||||||
|
this.id = id;
|
||||||
|
this.name = name;
|
||||||
|
this.drawable = drawable;
|
||||||
|
this.featuresType = featuresType;
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDrawable(int drawable) {
|
||||||
|
this.drawable = drawable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFeaturesType(FeaturesType featuresType) {
|
||||||
|
this.featuresType = featuresType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActive(boolean active) {
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FeaturesType getFeaturesType() {
|
||||||
|
return featuresType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDrawable() {
|
||||||
|
return drawable;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
package com.utsmm.kbz.config.data.model;
|
||||||
|
|
||||||
|
public enum TMSUpdate {
|
||||||
|
|
||||||
|
UPDATE,
|
||||||
|
CHECK
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.utsmm.kbz.config.data.model;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class TMSValidity {
|
||||||
|
|
||||||
|
private ValidityStatus status;
|
||||||
|
private String message;
|
||||||
|
|
||||||
|
public TMSValidity() {}
|
||||||
|
public TMSValidity(ValidityStatus status, String message) {
|
||||||
|
this.status = status;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ValidityStatus isStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(ValidityStatus status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
package com.utsmm.kbz.config.data.model;
|
||||||
|
|
||||||
|
public enum ValidityStatus {
|
||||||
|
SUCCESS,FAILURE
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package com.utsmm.kbz.service;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
public class SmileAlarmReceiver extends BroadcastReceiver {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
// Start the service to send the API request
|
||||||
|
Intent serviceIntent = new Intent(context, SmileSettleService.class);
|
||||||
|
context.startService(serviceIntent);
|
||||||
|
}
|
||||||
|
}
|
||||||
183
app/src/main/java/com/utsmm/kbz/service/SmileSettleService.java
Normal file
183
app/src/main/java/com/utsmm/kbz/service/SmileSettleService.java
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
package com.utsmm.kbz.service;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.app.Service;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.IBinder;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.app.NotificationCompat;
|
||||||
|
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository;
|
||||||
|
import com.utsmm.kbz.BuildConfig;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.ui.settlement.SettlementViewModel;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
// Temporarily disabled Hilt
|
||||||
|
// @AndroidEntryPoint
|
||||||
|
public class SmileSettleService extends Service {
|
||||||
|
|
||||||
|
private static final String TAG = SmileSettleService.class.getSimpleName();
|
||||||
|
|
||||||
|
public static final String ACTION_DATA_RECEIVED = BuildConfig.APPLICATION_ID + ".ACTION_DATA_RECEIVED";
|
||||||
|
public static final String EXTRA_DATA = BuildConfig.APPLICATION_ID + ".EXTRA_DATA";
|
||||||
|
|
||||||
|
|
||||||
|
private Handler handler;
|
||||||
|
|
||||||
|
|
||||||
|
private SettlementViewModel settlementViewModel;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
Repository repository;
|
||||||
|
|
||||||
|
public static final String NOTIFICATION_CHANNEL_ID = "10001";
|
||||||
|
private final static String default_notification_channel_id = "default";
|
||||||
|
private void createNotification() {
|
||||||
|
NotificationManager mNotificationManager = (NotificationManager)getSystemService( NOTIFICATION_SERVICE ) ;
|
||||||
|
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext() , default_notification_channel_id ) ;
|
||||||
|
mBuilder.setContentTitle( "Alarm manager is running!" ) ;
|
||||||
|
mBuilder.setContentText( "Wiping out the transactions!" ) ;
|
||||||
|
mBuilder.setTicker( "Notification Listener Service Example" ) ;
|
||||||
|
mBuilder.setSmallIcon(R.drawable. ic_launcher_foreground ) ;
|
||||||
|
mBuilder.setAutoCancel( true ) ;
|
||||||
|
if (android.os.Build.VERSION. SDK_INT >= android.os.Build.VERSION_CODES. O ) {
|
||||||
|
int importance = NotificationManager. IMPORTANCE_HIGH ;
|
||||||
|
NotificationChannel notificationChannel = new NotificationChannel( NOTIFICATION_CHANNEL_ID , "NOTIFICATION_CHANNEL_NAME" , importance) ;
|
||||||
|
mBuilder.setChannelId( NOTIFICATION_CHANNEL_ID ) ;
|
||||||
|
assert mNotificationManager != null;
|
||||||
|
mNotificationManager.createNotificationChannel(notificationChannel) ;
|
||||||
|
}
|
||||||
|
assert mNotificationManager != null;
|
||||||
|
mNotificationManager.notify(( int ) System. currentTimeMillis () , mBuilder.build()) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendDataToViewModel(String data) {
|
||||||
|
Intent intent = new Intent(ACTION_DATA_RECEIVED);
|
||||||
|
intent.putExtra(EXTRA_DATA, data);
|
||||||
|
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("CheckResult")
|
||||||
|
@Override
|
||||||
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||||
|
// Perform the Settlement request here
|
||||||
|
// ...
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"<<<<<<<<<<<<<<< This action was called >>>>>>>>>>>>>>>>.");
|
||||||
|
|
||||||
|
|
||||||
|
sendDataToViewModel("Hello there");
|
||||||
|
|
||||||
|
createNotification();
|
||||||
|
|
||||||
|
// Observer<List<PayDetail>> settleObserver = new Observer<List<PayDetail>>() {
|
||||||
|
// @Override
|
||||||
|
// public void onChanged(List<PayDetail> list) {
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// if(list == null || list.size() == 0) {
|
||||||
|
// LogUtil.d(TAG, "Settle is null");
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// LogUtil.d(TAG,"Size Settle : "+list.size());
|
||||||
|
//
|
||||||
|
// for (PayDetail pay:list) {
|
||||||
|
// repository.deletePayDetail(pay);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// repository.getSettlementPOS().observeForever(settleObserver);
|
||||||
|
//
|
||||||
|
// repository.getSettlementPOS().removeObserver(settleObserver);
|
||||||
|
//
|
||||||
|
// Observer<List<PayDetail>> deleteTransObserver = new Observer<List<PayDetail>>() {
|
||||||
|
// @Override
|
||||||
|
// public void onChanged(List<PayDetail> lists) {
|
||||||
|
// if(lists == null || lists.size() == 0) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// LogUtil.d(TAG,"Size Delete Trans : "+lists.size());
|
||||||
|
// for (PayDetail pay:lists) {
|
||||||
|
// repository.deletePayDetail(pay);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// repository.getDeleteTrans(SystemParamsOperation.getInstance().getCurrentBatchNum()).observeForever(deleteTransObserver);
|
||||||
|
//
|
||||||
|
// repository.getDeleteTrans(SystemParamsOperation.getInstance().getCurrentBatchNum()).removeObserver(deleteTransObserver);
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
// try{
|
||||||
|
// handler.post(new Runnable() {
|
||||||
|
// @Override
|
||||||
|
// public void run() {
|
||||||
|
// // Create and show the dialog
|
||||||
|
// AlertDialog.Builder builder = new AlertDialog.Builder(SmileSettleService.this);
|
||||||
|
// builder.setTitle("Auto Settle!")
|
||||||
|
// .setMessage("Settlement process is going to start!")
|
||||||
|
// .setPositiveButton("OK", new DialogInterface.OnClickListener() {
|
||||||
|
// @Override
|
||||||
|
// public void onClick(DialogInterface dialog, int which) {
|
||||||
|
// // Handle OK button click
|
||||||
|
// dialog.dismiss(); // Dismiss the dialog
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
||||||
|
// @Override
|
||||||
|
// public void onClick(DialogInterface dialog, int which) {
|
||||||
|
// // Handle Cancel button click
|
||||||
|
// dialog.dismiss(); // Dismiss the dialog
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// AlertDialog dialog = builder.create();
|
||||||
|
//// dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
|
||||||
|
//// dialog.show();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }catch (Exception e){
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
return START_NOT_STICKY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate() {
|
||||||
|
super.onCreate();
|
||||||
|
handler = new Handler();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public IBinder onBind(Intent intent) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onUnbind(Intent intent) {
|
||||||
|
return super.onUnbind(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
38
app/src/main/java/com/utsmm/kbz/ui/SettingViewModel.java
Normal file
38
app/src/main/java/com/utsmm/kbz/ui/SettingViewModel.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package com.utsmm.kbz.ui;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class SettingViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private Repository repository;
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SettingViewModel(Repository repository){
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<PayDetail> getReversalTransaction(String voucherNo) {
|
||||||
|
return repository.getReversalTransaction(voucherNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public LiveData<List<PayDetail>> getSettlement(){
|
||||||
|
return repository.getSettlement();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePayDetail(PayDetail payDetail){
|
||||||
|
repository.updatePayDetail(payDetail);
|
||||||
|
}
|
||||||
|
}
|
||||||
437
app/src/main/java/com/utsmm/kbz/ui/SettingsFragment.java
Normal file
437
app/src/main/java/com/utsmm/kbz/ui/SettingsFragment.java
Normal file
@ -0,0 +1,437 @@
|
|||||||
|
package com.utsmm.kbz.ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.navigation.Navigation;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.stream.MalformedJsonException;
|
||||||
|
import com.utsmyanmar.baselib.emv.EmvParamOperation;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusError;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusResponse;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
import com.utsmyanmar.baselib.util.URLValidator;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.MainViewModel;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.data.model.TMSUpdate;
|
||||||
|
import com.utsmm.kbz.databinding.FragmentSettingsModernBinding;
|
||||||
|
import com.utsmm.kbz.ui.settlement.SettlementViewModel;
|
||||||
|
import com.utsmm.kbz.util.tms.TMSUtil;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
import retrofit2.HttpException;
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
public class SettingsFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private static final String TAG = SettingsFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private SettlementViewModel settlementViewModel;
|
||||||
|
private MainViewModel mainViewModel;
|
||||||
|
private int count = 0;
|
||||||
|
|
||||||
|
// Data binding will handle view access automatically
|
||||||
|
private FragmentSettingsModernBinding binding;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public EmvParamOperation emvParamOperation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
// Initialize ViewModels in initViewModel as per pattern
|
||||||
|
settlementViewModel = getFragmentScopeViewModel(SettlementViewModel.class);
|
||||||
|
mainViewModel = getFragmentScopeViewModel(MainViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
// This is the key method that links the XML and fragment properly
|
||||||
|
return new DataBindingConfig(R.layout.fragment_settings_modern, 0, null)
|
||||||
|
.addBindingParam(BR.click, new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.nav_settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return R.id.nav_host_fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
try {
|
||||||
|
LogUtil.d(TAG, "onViewCreated called");
|
||||||
|
|
||||||
|
// Get the binding from the base class - this is automatically created
|
||||||
|
binding = (FragmentSettingsModernBinding) mBinding;
|
||||||
|
|
||||||
|
LogUtil.d(TAG, "Updating settings...");
|
||||||
|
updateSettings();
|
||||||
|
|
||||||
|
LogUtil.d(TAG, "Settings fragment initialized successfully");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error initializing fragment: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
try {
|
||||||
|
setToolBarTitleWithBackIcon("Settings");
|
||||||
|
LogUtil.d(TAG, "Settings screen resumed");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error in onResume: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void updateSettings() {
|
||||||
|
try {
|
||||||
|
// Set version info
|
||||||
|
try {
|
||||||
|
String versionName = requireContext().getPackageManager()
|
||||||
|
.getPackageInfo(requireContext().getPackageName(), 0).versionName;
|
||||||
|
binding.versionSummary.setText(versionName);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogUtil.e(TAG, "Error getting version name: " + ex.getMessage());
|
||||||
|
binding.versionSummary.setText("Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update switch states and summaries
|
||||||
|
updateDemoSettings();
|
||||||
|
updateAlertSoundSettings();
|
||||||
|
updateReversalSettings();
|
||||||
|
updateMultiHostSettings();
|
||||||
|
updateTmsAddressSettings();
|
||||||
|
|
||||||
|
LogUtil.d(TAG, "Settings updated successfully");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error updating settings: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateDemoSettings() {
|
||||||
|
boolean isDemo = SystemParamsOperation.getInstance().getDemoStatus();
|
||||||
|
binding.demoSwitch.setChecked(isDemo);
|
||||||
|
binding.demoSummary.setText(isDemo ?
|
||||||
|
"Demo mode active - Test transactions without real processing" :
|
||||||
|
"Simulator mode active - Real transaction processing");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateAlertSoundSettings() {
|
||||||
|
boolean isEnabled = SystemParamsOperation.getInstance().isAlertSound();
|
||||||
|
binding.alertSoundSwitch.setChecked(isEnabled);
|
||||||
|
binding.alertSoundSummary.setText(isEnabled ?
|
||||||
|
"Sound alerts enabled for notifications" :
|
||||||
|
"Sound alerts disabled - Silent mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void updateReversalSettings() {
|
||||||
|
boolean isEnabled = SystemParamsOperation.getInstance().isReversalOn();
|
||||||
|
binding.reversalSwitch.setChecked(isEnabled);
|
||||||
|
binding.reversalSummary.setText(isEnabled ?
|
||||||
|
"Automatic reversal enabled for failed transactions" :
|
||||||
|
"Automatic reversal disabled - Manual reversal only");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateMultiHostSettings() {
|
||||||
|
boolean isEnabled = SystemParamsOperation.getInstance().isMultiHost();
|
||||||
|
binding.multiHostSwitch.setChecked(isEnabled);
|
||||||
|
binding.multiHostSummary.setText(isEnabled ?
|
||||||
|
"Multiple host support enabled" :
|
||||||
|
"Single host mode - Primary host only");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTmsAddressSettings() {
|
||||||
|
String address = SystemParamsOperation.getInstance().getTmsAddress();
|
||||||
|
binding.tmsAddressSummary.setText(address != null && !address.isEmpty() ?
|
||||||
|
address : "Configure terminal management server URL");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClickEvent class for data binding - this is the proper pattern
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
public void onVersionClick() {
|
||||||
|
try {
|
||||||
|
count++;
|
||||||
|
LogUtil.d(TAG, "Version clicked " + count + " times");
|
||||||
|
if (count == 5) {
|
||||||
|
count = 0;
|
||||||
|
// Navigation for hidden settings could be added here
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error in version click: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDemoClick() {
|
||||||
|
try {
|
||||||
|
boolean newValue = !SystemParamsOperation.getInstance().getDemoStatus();
|
||||||
|
SystemParamsOperation.getInstance().setDemoStatus(newValue);
|
||||||
|
updateDemoSettings();
|
||||||
|
LogUtil.d(TAG, "Demo mode toggled to: " + newValue);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error toggling demo mode: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onAlertSoundClick() {
|
||||||
|
try {
|
||||||
|
boolean newValue = !SystemParamsOperation.getInstance().isAlertSound();
|
||||||
|
SystemParamsOperation.getInstance().setAlertSound(newValue);
|
||||||
|
updateAlertSoundSettings();
|
||||||
|
LogUtil.d(TAG, "Alert sound toggled to: " + newValue);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error toggling alert sound: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onReversalClick() {
|
||||||
|
try {
|
||||||
|
boolean newValue = !SystemParamsOperation.getInstance().isReversalOn();
|
||||||
|
SystemParamsOperation.getInstance().setReversalFlag(newValue);
|
||||||
|
updateReversalSettings();
|
||||||
|
LogUtil.d(TAG, "Reversal toggled to: " + newValue);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error toggling reversal: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onMultiHostClick() {
|
||||||
|
try {
|
||||||
|
boolean newValue = !SystemParamsOperation.getInstance().isMultiHost();
|
||||||
|
SystemParamsOperation.getInstance().setMultiHost(newValue);
|
||||||
|
updateMultiHostSettings();
|
||||||
|
LogUtil.d(TAG, "Multi-host toggled to: " + newValue);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error toggling multi-host: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTmsAddressClick() {
|
||||||
|
try {
|
||||||
|
// Show dialog to edit TMS address
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
|
||||||
|
builder.setTitle("TMS Server URL");
|
||||||
|
builder.setMessage("Enter the Terminal Management Server URL:");
|
||||||
|
|
||||||
|
// Add EditText to dialog
|
||||||
|
final android.widget.EditText input = new android.widget.EditText(requireContext());
|
||||||
|
input.setText(SystemParamsOperation.getInstance().getTmsAddress());
|
||||||
|
builder.setView(input);
|
||||||
|
|
||||||
|
builder.setPositiveButton("Save", (dialog, which) -> {
|
||||||
|
String newAddress = input.getText().toString().trim();
|
||||||
|
if (!newAddress.isEmpty()) {
|
||||||
|
if (URLValidator.isValidURL(newAddress)) {
|
||||||
|
SystemParamsOperation.getInstance().setTmsAddress(newAddress);
|
||||||
|
updateTmsAddressSettings();
|
||||||
|
showSingleInfoDialog(getResourceString(R.string.txt_kill_app));
|
||||||
|
LogUtil.d(TAG, "TMS address updated: " + newAddress);
|
||||||
|
} else {
|
||||||
|
showSingleInfoDialog(getResourceString(R.string.txt_tms_url_not_valid));
|
||||||
|
LogUtil.w(TAG, "Invalid TMS URL: " + newAddress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.setNegativeButton("Cancel", (dialog, which) -> dialog.cancel());
|
||||||
|
builder.show();
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error in TMS address click: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onUpdateConfigClick() {
|
||||||
|
try {
|
||||||
|
LogUtil.d(TAG, "Update config clicked");
|
||||||
|
settlementViewModel.getSettlementPOS().observe(getViewLifecycleOwner(), payDetails -> {
|
||||||
|
try {
|
||||||
|
if (payDetails != null && payDetails.size() > 0) {
|
||||||
|
showRequireSettlementDialog("If you can take your own risk!\nClick continue to download!");
|
||||||
|
} else {
|
||||||
|
if (SystemParamsOperation.getInstance().isNeedSettlement()) {
|
||||||
|
showRequireSettlementDialog("Params changes detected!\nIf you can take your own risk!\nClick continue to download!");
|
||||||
|
} else {
|
||||||
|
checkLastTrans();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error processing settlement check: " + e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error in update config: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onTmsConfigClick() {
|
||||||
|
try {
|
||||||
|
LogUtil.d(TAG, "TMS Config clicked");
|
||||||
|
Navigation.findNavController(requireActivity(), R.id.nav_host_fragment)
|
||||||
|
.navigate(R.id.action_nav_settings_to_configSettingsFragment);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error navigating to TMS config: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keep existing methods for settlement and download functionality
|
||||||
|
private void showRequireSettlementDialog(String message) {
|
||||||
|
try {
|
||||||
|
AlertDialog.Builder builderInner = new AlertDialog.Builder(requireContext());
|
||||||
|
builderInner.setTitle(getResourceString(R.string.txt_please_settle_first));
|
||||||
|
builderInner.setMessage(message);
|
||||||
|
builderInner.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss());
|
||||||
|
builderInner.setPositiveButton("Continue", (dialog1, which1) -> {
|
||||||
|
try {
|
||||||
|
checkLastTrans();
|
||||||
|
dialog1.dismiss();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error in settlement dialog positive action: " + e.getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builderInner.show();
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error showing settlement dialog: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkLastTrans() {
|
||||||
|
try {
|
||||||
|
LogUtil.d(TAG, "Checking last transaction");
|
||||||
|
mainViewModel.getLastTransaction().observe(getViewLifecycleOwner(), new Observer<PayDetail>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(PayDetail payDetail) {
|
||||||
|
try {
|
||||||
|
if (payDetail != null) {
|
||||||
|
downloadParams(payDetail.getTransType(), String.valueOf(payDetail.getTransNum()));
|
||||||
|
} else {
|
||||||
|
String lastTransName = SystemParamsOperation.getInstance().getLastTransName();
|
||||||
|
String lastTransTime = SystemParamsOperation.getInstance().getLastTransTime();
|
||||||
|
if (lastTransTime != null && !lastTransTime.isEmpty() &&
|
||||||
|
lastTransName != null && !lastTransName.isEmpty()) {
|
||||||
|
downloadParams(lastTransName, lastTransTime);
|
||||||
|
} else {
|
||||||
|
long transTime = System.currentTimeMillis();
|
||||||
|
String transTimeInString = String.valueOf(transTime).substring(0, 10);
|
||||||
|
downloadParams("...", transTimeInString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error processing last transaction: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error checking last transaction: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadParams(String lastTransName, String lastTransTime) {
|
||||||
|
try {
|
||||||
|
LogUtil.d(TAG, "Downloading params for transaction: " + lastTransName);
|
||||||
|
SiriusRequest siriusReq = TMSUtil.getInstance().generateRequestParams(getContext(), lastTransName, lastTransTime);
|
||||||
|
|
||||||
|
mainViewModel.getParams(siriusReq)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(new io.reactivex.rxjava3.core.Observer<SiriusResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
|
||||||
|
LogUtil.d(TAG, "Starting params download");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(@io.reactivex.rxjava3.annotations.NonNull SiriusResponse siriusResponse) {
|
||||||
|
try {
|
||||||
|
TMSUtil.getInstance().initParams(siriusResponse, TMSUpdate.UPDATE,emvParamOperation);
|
||||||
|
showLoadingDialog(getResourceString(R.string.txt_downloading));
|
||||||
|
LogUtil.d(TAG, "Params download initiated");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error processing params response: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
|
||||||
|
try {
|
||||||
|
dismissLoadingDialog();
|
||||||
|
LogUtil.e(TAG, "Params download error: " + e.getMessage());
|
||||||
|
|
||||||
|
if (e.getClass() == MalformedJsonException.class) {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_terminal_is_not_configure));
|
||||||
|
} else if (e instanceof HttpException) {
|
||||||
|
HttpException error = (HttpException) e;
|
||||||
|
try {
|
||||||
|
SiriusError siriusError = new Gson().fromJson(error.response().errorBody().string(), SiriusError.class);
|
||||||
|
showDeclineDialog(siriusError.getMessage());
|
||||||
|
} catch (IOException ex) {
|
||||||
|
LogUtil.e(TAG, "Error parsing error response: " + ex.getMessage());
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_tms_url_not_valid));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogUtil.e(TAG, "Unexpected error parsing response: " + ex.getMessage());
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_tms_url_not_valid));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_failure_next_line) + e.getMessage());
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
LogUtil.e(TAG, "Error handling download error: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
try {
|
||||||
|
dismissLoadingDialog();
|
||||||
|
showSuccessDialogAutoHide(getResourceString(R.string.txt_configs_are_updated));
|
||||||
|
updateSettings();
|
||||||
|
SystemParamsOperation.getInstance().setDownloadedParams(true);
|
||||||
|
LogUtil.d(TAG, "Params download completed successfully");
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error completing params download: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Error initiating params download: " + e.getMessage());
|
||||||
|
dismissLoadingDialog();
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_error_occurred));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
73
app/src/main/java/com/utsmm/kbz/ui/adapters/MainAdapter.java
Normal file
73
app/src/main/java/com/utsmm/kbz/ui/adapters/MainAdapter.java
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package com.utsmm.kbz.ui.adapters;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.data.model.Features;
|
||||||
|
import com.utsmm.kbz.databinding.ItemViewDashboardBinding;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {
|
||||||
|
|
||||||
|
private List<Features> list;
|
||||||
|
private final MainAdapter.ItemOnClickListener listener;
|
||||||
|
|
||||||
|
public MainAdapter(List<Features> list, MainAdapter.ItemOnClickListener listener){
|
||||||
|
this.list = list;
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
ItemViewDashboardBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.item_view_dashboard,parent,false);
|
||||||
|
// ItemViewDashboardPremiumBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.item_view_dashboard_premium,parent,false);
|
||||||
|
return new MainAdapter.ViewHolder(binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
Features features = list.get(position);
|
||||||
|
holder.bind(features,listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return list.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ItemOnClickListener{
|
||||||
|
void onItemClick(Features item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
public ItemViewDashboardBinding binding;
|
||||||
|
|
||||||
|
public ViewHolder(ItemViewDashboardBinding binding){
|
||||||
|
super(binding.getRoot());
|
||||||
|
this.binding = binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind(Object object,final MainAdapter.ItemOnClickListener listener){
|
||||||
|
binding.setVariable(BR.item,object);
|
||||||
|
binding.getRoot().setOnClickListener(v -> {
|
||||||
|
Features item = (Features) object;
|
||||||
|
if(item.isActive()){
|
||||||
|
listener.onItemClick(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
binding.executePendingBindings();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,302 @@
|
|||||||
|
package com.utsmm.kbz.ui.adapters;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.PorterDuff;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.appcompat.widget.AppCompatImageView;
|
||||||
|
import androidx.cardview.widget.CardView;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.airbnb.lottie.LottieAnimationView;
|
||||||
|
import com.squareup.picasso.Picasso;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.ui.manual_entry.EntryState;
|
||||||
|
import com.utsmm.kbz.util.QRCodeGenerator;
|
||||||
|
import com.utsmm.kbz.util.enums.TMSDownloadStatus;
|
||||||
|
import com.utsmm.kbz.util.recyclerview.SpacesItemDecoration;
|
||||||
|
|
||||||
|
import androidx.databinding.BindingAdapter;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
|
||||||
|
import androidmads.library.qrgenearator.QRGContents;
|
||||||
|
import androidmads.library.qrgenearator.QRGEncoder;
|
||||||
|
|
||||||
|
public class MyBindingAdapter {
|
||||||
|
|
||||||
|
private static final String TAG = MyBindingAdapter.class.getSimpleName();
|
||||||
|
|
||||||
|
@BindingAdapter({"setAdapter"})
|
||||||
|
public static void setMainAdapter(RecyclerView recyclerView, MainAdapter adapter) {
|
||||||
|
recyclerView.setNestedScrollingEnabled(false);
|
||||||
|
recyclerView.setAdapter(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("itemSpacing")
|
||||||
|
public static void setItemSpacing(RecyclerView recyclerView, int spacing) {
|
||||||
|
recyclerView.addItemDecoration(new SpacesItemDecoration(spacing));
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter({"imgUrl"})
|
||||||
|
public static void renderIcon(AppCompatImageView imageView, Integer imgUrl) {
|
||||||
|
Picasso.get().load(imgUrl)
|
||||||
|
.resize(60, 60)
|
||||||
|
.placeholder(R.drawable.ic_blur)
|
||||||
|
.into(imageView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter({"srcUrl"})
|
||||||
|
public static void renderIcon(ImageView imageView, Integer imgUrl) {
|
||||||
|
Picasso.get().load(imgUrl)
|
||||||
|
.placeholder(R.drawable.ic_blur)
|
||||||
|
.into(imageView);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter({"entryBg"})
|
||||||
|
public static void entryBg(EditText et, EntryState entryState) {
|
||||||
|
int bg = R.drawable.bg_edittext;
|
||||||
|
if(entryState == EntryState.SELECTED) {
|
||||||
|
bg = R.drawable.bg_edittext_focus;
|
||||||
|
} else if( entryState == EntryState.ERROR) {
|
||||||
|
bg = R.drawable.bg_edittext_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
et.setBackgroundResource(bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter({"isColorChanges"})
|
||||||
|
public static void isColorChanged(TextView textView,PayDetail payDetail) {
|
||||||
|
if(payDetail.getTransactionType() == TransactionsType.MMQR.value) {
|
||||||
|
if(payDetail.getQrTransStatus() == -1) {
|
||||||
|
|
||||||
|
textView.setTextColor(textView.getResources().getColor(R.color.smilePrimaryColor));
|
||||||
|
} else {
|
||||||
|
textView.setTextColor(textView.getResources().getColor(R.color.black));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
textView.setTextColor(textView.getResources().getColor(R.color.black));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint({"RestrictedApi", "ResourceAsColor"})
|
||||||
|
@BindingAdapter({"isActive"})
|
||||||
|
public static void isActive(ImageView imageView, boolean active) {
|
||||||
|
if(active){
|
||||||
|
imageView.setColorFilter( imageView.getResources().getColor(R.color.white), PorterDuff.Mode.SRC_IN);
|
||||||
|
} else {
|
||||||
|
imageView.setColorFilter( imageView.getResources().getColor(R.color.colorGray),PorterDuff.Mode.SRC_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressLint({"RestrictedApi", "ResourceAsColor"})
|
||||||
|
@BindingAdapter({"isEnabled"})
|
||||||
|
public static void isEnabled(ImageView imageView, int active) {
|
||||||
|
if(active == 1){
|
||||||
|
imageView.setColorFilter( imageView.getResources().getColor(R.color.black), PorterDuff.Mode.SRC_IN);
|
||||||
|
} else {
|
||||||
|
imageView.setColorFilter( imageView.getResources().getColor(R.color.colorMedGray),PorterDuff.Mode.SRC_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter({"imgLogo"})
|
||||||
|
public static void setCardLogo(AppCompatImageView imageView, String cardType) {
|
||||||
|
|
||||||
|
int imgURL = 0;
|
||||||
|
|
||||||
|
// LogUtil.d(TAG,"card type : "+cardType);
|
||||||
|
if(cardType != null){
|
||||||
|
switch (cardType) {
|
||||||
|
case "VISA":
|
||||||
|
imgURL = R.drawable.logo_visa;
|
||||||
|
break;
|
||||||
|
case "MASTER":
|
||||||
|
imgURL = R.drawable.logo_master;
|
||||||
|
break;
|
||||||
|
case "UnionPay":
|
||||||
|
imgURL = R.drawable.logo_upi;
|
||||||
|
break;
|
||||||
|
case "JCB":
|
||||||
|
imgURL = R.drawable.logo_jcb;
|
||||||
|
break;
|
||||||
|
case "DISCOVER":
|
||||||
|
imgURL = R.drawable.logo_discover;
|
||||||
|
break;
|
||||||
|
case "MIR":
|
||||||
|
imgURL = R.drawable.logo_mir;
|
||||||
|
break;
|
||||||
|
case "AMEX":
|
||||||
|
imgURL = R.drawable.logo_amex;
|
||||||
|
break;
|
||||||
|
case "MPU":
|
||||||
|
imgURL = R.drawable.logo_mpu;
|
||||||
|
break;
|
||||||
|
case "WALLET":
|
||||||
|
imgURL = R.drawable.logo_kpay;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
imgURL = R.drawable.logo_unk;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Picasso.get().load(imgURL)
|
||||||
|
.resize(60, 60)
|
||||||
|
.placeholder(R.drawable.ic_blur)
|
||||||
|
.into(imageView);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter({"disableBtn"})
|
||||||
|
public static void setDisableButton(Button button, boolean flag) {
|
||||||
|
button.setEnabled(flag);
|
||||||
|
if(!flag) {
|
||||||
|
button.setTextColor(button.getResources().getColor(R.color.colorGray));
|
||||||
|
button.setCompoundDrawableTintList(button.getResources().getColorStateList(R.color.disable_color));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
button.setTextColor(button.getResources().getColor(R.color.colorPrimary));
|
||||||
|
button.setCompoundDrawableTintList(button.getResources().getColorStateList(R.color.active_color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter({"disableBtn"})
|
||||||
|
public static void setDisableCardView(CardView cardView, boolean flag) {
|
||||||
|
cardView.setEnabled(flag);
|
||||||
|
cardView.setClickable(flag);
|
||||||
|
if (!flag) {
|
||||||
|
cardView.setAlpha(0.5f);
|
||||||
|
} else {
|
||||||
|
cardView.setAlpha(1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter({"disableBtn"})
|
||||||
|
public static void setDisableCardViewLiveData(CardView cardView, MutableLiveData<Boolean> flag) {
|
||||||
|
boolean value = flag != null && flag.getValue() != null ? flag.getValue() : false;
|
||||||
|
cardView.setEnabled(value);
|
||||||
|
cardView.setClickable(value);
|
||||||
|
if (!value) {
|
||||||
|
cardView.setAlpha(0.5f);
|
||||||
|
} else {
|
||||||
|
cardView.setAlpha(1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter({"disableQRBtn"})
|
||||||
|
public static void setDisableQRButton(Button button, boolean flag) {
|
||||||
|
button.setEnabled(flag);
|
||||||
|
if(!flag) {
|
||||||
|
button.setBackground(button.getResources().getDrawable(R.drawable.bg_rounded_btn_disabled));
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
button.setBackground(button.getResources().getDrawable(R.drawable.bg_rounded_btn_cv));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter({"disableQRImgBtn"})
|
||||||
|
public static void setDisableQRImgButton(ImageButton button, boolean flag) {
|
||||||
|
button.setEnabled(flag);
|
||||||
|
if(!flag) {
|
||||||
|
button.setBackground(button.getResources().getDrawable(R.drawable.bg_rounded_btn_disabled));
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
button.setBackground(button.getResources().getDrawable(R.drawable.bg_rounded_btn_cv));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
@BindingAdapter({"ecrStatus"})
|
||||||
|
public static void setECRConnectionStatusImage(AppCompatImageView imageView, String connectionStatus) {
|
||||||
|
|
||||||
|
int imgURL = 0;
|
||||||
|
|
||||||
|
if(connectionStatus != null){
|
||||||
|
|
||||||
|
switch (connectionStatus) {
|
||||||
|
case "CONNECTED":
|
||||||
|
imgURL = R.drawable.ic_green_circle;
|
||||||
|
break;
|
||||||
|
case "IDLE":
|
||||||
|
case "CREATED":
|
||||||
|
imgURL = R.drawable.ic_yellow_circle;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
imgURL = R.drawable.ic_red_circle;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Picasso.get().load(imgURL)
|
||||||
|
.resize(30,30)
|
||||||
|
.placeholder(R.drawable.ic_ecr_place_holder)
|
||||||
|
.error(R.drawable.ic_ecr_place_holder)
|
||||||
|
.into(imageView);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@BindingAdapter({"qrData"})
|
||||||
|
public static void setQrCode(AppCompatImageView imageView, String data) {
|
||||||
|
QRGEncoder qrgEncoder = new QRGEncoder(data, null, QRGContents.Type.TEXT, 300);
|
||||||
|
Bitmap bitmap = qrgEncoder.getBitmap();
|
||||||
|
imageView.setImageBitmap(bitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter({"mmpayData"})
|
||||||
|
public static void setMMPayQRCode(AppCompatImageView imageView,String data) {
|
||||||
|
//250
|
||||||
|
//290
|
||||||
|
int width = 270;
|
||||||
|
int height = 270;
|
||||||
|
Bitmap logo = QRCodeGenerator.getBitmapFromVectorDrawable(imageView.getContext(),R.drawable.logo_kpay);
|
||||||
|
|
||||||
|
Bitmap qrCodeBitmap = QRCodeGenerator.generateQRCode(data, width, height, logo);
|
||||||
|
imageView.setImageBitmap(qrCodeBitmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter({"tmsStatus"})
|
||||||
|
public static void setLottieView(LottieAnimationView lottieView, TMSDownloadStatus status) {
|
||||||
|
//250
|
||||||
|
//290
|
||||||
|
|
||||||
|
if(status == TMSDownloadStatus.DOWNLOADING) {
|
||||||
|
lottieView.setAnimation("lottie_download_loading.json");
|
||||||
|
} else if(status == TMSDownloadStatus.SUCCESS) {
|
||||||
|
lottieView.setAnimation("lottie_success.json");
|
||||||
|
} else if(status == TMSDownloadStatus.FAILURE) {
|
||||||
|
lottieView.setAnimation("lottie_decline.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
@BindingAdapter({"isTrace"})
|
||||||
|
public static void checkIsTraceOrInvoice(TextView textView, PayDetail payDetail) {
|
||||||
|
if(payDetail.getTransactionType() == TransactionsType.MMQR.value || payDetail.getTransactionType() == TransactionsType.MMQR_REFUND.value) {
|
||||||
|
textView.setText("INV:"+payDetail.getInvoiceNo());
|
||||||
|
} else {
|
||||||
|
textView.setText("TRC:"+payDetail.getVoucherNo());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
74
app/src/main/java/com/utsmm/kbz/ui/adapters/VoidAdapter.java
Normal file
74
app/src/main/java/com/utsmm/kbz/ui/adapters/VoidAdapter.java
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
package com.utsmm.kbz.ui.adapters;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.databinding.DataBindingUtil;
|
||||||
|
import androidx.databinding.library.baseAdapters.BR;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.databinding.ItemViewVoidBinding;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class VoidAdapter extends RecyclerView.Adapter<VoidAdapter.ViewHolder> {
|
||||||
|
|
||||||
|
private List<PayDetail> payDetailList;
|
||||||
|
private String operationType;
|
||||||
|
private final ItemOnClickListener listener;
|
||||||
|
|
||||||
|
public VoidAdapter(List<PayDetail> payDetailList,String operationType,ItemOnClickListener listener){
|
||||||
|
this.payDetailList = payDetailList;
|
||||||
|
this.operationType = operationType;
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ItemOnClickListener{
|
||||||
|
void onItemClick(PayDetail item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
ItemViewVoidBinding binding = DataBindingUtil.inflate(LayoutInflater.from(parent.getContext()), R.layout.item_view_void,parent,false);
|
||||||
|
return new ViewHolder(binding);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
|
||||||
|
PayDetail payDetail = payDetailList.get(position);
|
||||||
|
holder.bind(payDetail,listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return payDetailList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
|
||||||
|
public ItemViewVoidBinding binding;
|
||||||
|
|
||||||
|
public ViewHolder(ItemViewVoidBinding binding){
|
||||||
|
super(binding.getRoot());
|
||||||
|
this.binding = binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind(Object object,final ItemOnClickListener listener){
|
||||||
|
binding.setVariable(BR.payDetail,object);
|
||||||
|
binding.getRoot().setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
listener.onItemClick((PayDetail)object);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
binding.executePendingBindings();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,337 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.nexgo.oaf.apiv3.device.reader.CardSlotTypeEnum;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.TimeoutCallback;
|
||||||
|
import com.utsmyanmar.checkxread.checkcard.CheckCardResultX;
|
||||||
|
import com.utsmyanmar.checkxread.util.CardTypeX;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.config.data.model.CardTransactionType;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.CardReadViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.TransProcessViewModel;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
public class CardWaitingFragment extends DataBindingFragment implements DataBindingFragment.BackPressCallback{
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
private CardReadViewModel cardReadViewModel;
|
||||||
|
|
||||||
|
private TransProcessViewModel transProcessViewModel;
|
||||||
|
|
||||||
|
private static final String TAG = CardWaitingFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private static final int cardWaitingTimeOut = 60;
|
||||||
|
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
private int fallbackCounter = 0;
|
||||||
|
|
||||||
|
private boolean fallbackEnabled = false;
|
||||||
|
|
||||||
|
private int retryCounter = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
|
||||||
|
cardReadViewModel = getFragmentScopeViewModel(CardReadViewModel.class);
|
||||||
|
|
||||||
|
transProcessViewModel = getFragmentScopeViewModel(TransProcessViewModel.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_capture_card_screen, BR.readCardVM, cardReadViewModel)
|
||||||
|
.addBindingParam(BR.sharedVM, sharedViewModel)
|
||||||
|
.addBindingParam(BR.transVM,transProcessViewModel)
|
||||||
|
.addBindingParam(BR.click, new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.cardWaitingFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPress() {
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
finishECR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
popBackStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finishECR() {
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(getResourceString(R.string.txt_cancel_trans));
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
public void onClickManualEntry() {
|
||||||
|
|
||||||
|
routeId = R.id.action_cardWaitingFragment_to_manualEntryFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickTap() {
|
||||||
|
cardReadViewModel.setCardTransactionType(CardTransactionType.MOCK);
|
||||||
|
routeId = R.id.action_cardWaitingFragment_to_processingCardFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
resetUI();
|
||||||
|
|
||||||
|
setToolBarTitleWithBackIcon(getResourceString(R.string.txt_title_card_capture));
|
||||||
|
|
||||||
|
delayFunctionCall(()-> {
|
||||||
|
if(sharedViewModel.transactionsType.getValue() == TransactionsType.REFUND) {
|
||||||
|
sharedViewModel.enableCardStatusIcon(false,false,false,false);
|
||||||
|
} else {
|
||||||
|
sharedViewModel.enableCardStatusIcon(true,true,true,false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(sharedViewModel.getIsFallback().getValue() != null && sharedViewModel.getIsFallback().getValue()) {
|
||||||
|
cardReadViewModel.setCheckCardAlertMsg("Fallback!\nPlease stripe!",false);
|
||||||
|
setupCardReadProcess(true);
|
||||||
|
} else {
|
||||||
|
setupCardReadProcess(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
sharedViewModel.setIsFallback(false);
|
||||||
|
|
||||||
|
// cardReadViewModel.cancelCheckCard();
|
||||||
|
|
||||||
|
cardReadViewModel.resetOneTimeFlag();
|
||||||
|
|
||||||
|
cardReadViewModel.cancelCheckXProcess();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetUI() {
|
||||||
|
cardReadViewModel.resetUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
initData();
|
||||||
|
|
||||||
|
setupBackButtonPressDetection(this);
|
||||||
|
|
||||||
|
// if(sharedViewModel.getIsFallback().getValue() != null && sharedViewModel.getIsFallback().getValue()) {
|
||||||
|
// cardReadViewModel.setCheckCardAlertMsg("Fallback!\nPlease stripe!",false);
|
||||||
|
// setupCardReadProcess(true);
|
||||||
|
// } else {
|
||||||
|
// setupCardReadProcess(false);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData() {
|
||||||
|
|
||||||
|
retryCounter = 0;
|
||||||
|
|
||||||
|
fallbackCounter = SystemParamsOperation.getInstance().getFallbackCounter();
|
||||||
|
fallbackEnabled = SystemParamsOperation.getInstance().getFallbackEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void setupCardReadProcess(boolean isFallback) {
|
||||||
|
initCheckCard(isFallback);
|
||||||
|
setUpTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void setUpTimer() {
|
||||||
|
setupTimeout(30, new TimeoutCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTrick(long trickTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
// try {
|
||||||
|
// MyApplication.getInstance().basicOptBinder.buzzerOnDevice(1);
|
||||||
|
// } catch (RemoteException e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
|
||||||
|
routeId = R.id.action_cardWaitingFragment_to_timeoutFragment;
|
||||||
|
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initCheckCard(boolean isFallback) {
|
||||||
|
// int allType = AidlConstants.CardType.NFC.getValue() | AidlConstants.CardType.IC.getValue() | AidlConstants.CardType.MAGNETIC.getValue();
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// if(isFallback) {
|
||||||
|
// allType = AidlConstants.CardType.MAGNETIC.getValue();
|
||||||
|
// } else {
|
||||||
|
// if(SystemParamsOperation.getInstance().isMagStripeEnabled() && !SystemParamsOperation.getInstance().isNfcEnabled()) {
|
||||||
|
// allType = AidlConstants.CardType.IC.getValue() | AidlConstants.CardType.MAGNETIC.getValue();
|
||||||
|
// } else if(SystemParamsOperation.getInstance().getFallbackEnabled() && !SystemParamsOperation.getInstance().isNfcEnabled()) {
|
||||||
|
// allType = AidlConstants.CardType.IC.getValue() | AidlConstants.CardType.MAGNETIC.getValue();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
HashSet<CardSlotTypeEnum> allType = new HashSet<>();
|
||||||
|
allType.add(CardSlotTypeEnum.ICC1);
|
||||||
|
allType.add(CardSlotTypeEnum.RF);
|
||||||
|
// int allType = AidlConstants.CardType.IC.getValue() | AidlConstants.CardType.MAGNETIC.getValue();
|
||||||
|
|
||||||
|
cardReadViewModel.startCheckXProcessNex(allType, cardWaitingTimeOut + 5, new CheckCardResultX() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(CardTypeX cardType, boolean isMPU) {
|
||||||
|
LogUtil.d(TAG,"**** on success *****");
|
||||||
|
LogUtil.d(TAG,"card type:"+cardType);
|
||||||
|
LogUtil.d(TAG,"is MPU:"+isMPU);
|
||||||
|
LogUtil.d(TAG,"is fallback:"+isFallback);
|
||||||
|
|
||||||
|
if(!isFallback && cardType == CardTypeX.MAG) {
|
||||||
|
|
||||||
|
if(SystemParamsOperation.getInstance().isMagStripeEnabled()) {
|
||||||
|
|
||||||
|
cardReadViewModel.setCardTransactionType(CardTransactionType.MAG);
|
||||||
|
} else {
|
||||||
|
cardReadViewModel.setCheckCardAlertMsg(getResourceString(R.string.txt_mag_stripe_alert),true);
|
||||||
|
cancelTimeout();
|
||||||
|
setupCardReadProcess(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (isFallback && cardType == CardTypeX.MAG) {
|
||||||
|
/* do fallback transactions */
|
||||||
|
sharedViewModel.isEmv.setValue(false);
|
||||||
|
cardReadViewModel.setCardTransactionType(CardTransactionType.FALLBACK);
|
||||||
|
|
||||||
|
} else if (cardType == CardTypeX.IC || cardType == CardTypeX.NFC) {
|
||||||
|
if(isMPU) {
|
||||||
|
sharedViewModel.isEmv.setValue(false);
|
||||||
|
cardReadViewModel.setCardTransactionType(CardTransactionType.MPU);
|
||||||
|
} else {
|
||||||
|
cardReadViewModel.cardTypeData.postValue(cardType.value);
|
||||||
|
cardReadViewModel.setCardTransactionType(CardTransactionType.EMV);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delayFunctionCall(()->{
|
||||||
|
routeId = R.id.action_cardWaitingFragment_to_processingCardFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(int code, String message) {
|
||||||
|
LogUtil.d(TAG,"on error:"+code+" - message :"+message);
|
||||||
|
ecrActionCancel(getResourceString(R.string.txt_cancel_trans));
|
||||||
|
showDeclineDialog(message);
|
||||||
|
routeId = R.id.action_cardWaitingFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCommError() {
|
||||||
|
LogUtil.d(TAG,"on Comm Error...");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fallback is almost finished ! need to implement only at ISO library for ISO8583 message.
|
||||||
|
* 25 Sept,2024
|
||||||
|
* */
|
||||||
|
if(fallbackEnabled && retryCounter < fallbackCounter) {
|
||||||
|
cardReadViewModel.setCheckCardAlertMsg("Card not detected!\n Remain Attempt - "+(fallbackCounter - retryCounter),false);
|
||||||
|
cancelTimeout();
|
||||||
|
retryCounter ++;
|
||||||
|
isCardInserted(()-> {
|
||||||
|
setupCardReadProcess(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
} else if(retryCounter == fallbackCounter) {
|
||||||
|
|
||||||
|
|
||||||
|
cardReadViewModel.setCheckCardAlertMsg("Fallback!\nPlease stripe!",false);
|
||||||
|
cancelTimeout();
|
||||||
|
|
||||||
|
isCardInserted(()-> {
|
||||||
|
setupCardReadProcess(true);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ecrActionCancel(getResourceString(R.string.txt_cancel_trans));
|
||||||
|
showDeclineDialog("Chip not detected!");
|
||||||
|
routeId = R.id.action_cardWaitingFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ecrActionCancel(String msg) {
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(msg);
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,268 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.nexgo.oaf.apiv3.SdkResult;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.DialogCallback;
|
||||||
|
import com.utsmyanmar.baselib.util.TimeoutCallback;
|
||||||
|
import com.utsmyanmar.paylibs.print.PrintHelper;
|
||||||
|
import com.utsmyanmar.paylibs.print.printx.PrintXReceipt;
|
||||||
|
import com.utsmyanmar.paylibs.print.printx.PrintXStatus;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.TransMenu;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.TransProcessViewModel;
|
||||||
|
import com.utsmm.kbz.ui.sale_void.VoidViewModel;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
|
||||||
|
public class ConfirmTransactionFragment extends DataBindingFragment implements DataBindingFragment.BackPressCallback{
|
||||||
|
|
||||||
|
private VoidViewModel voidViewModel;
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private TransProcessViewModel transProcessViewModel;
|
||||||
|
private int routeId;
|
||||||
|
private boolean isMerchantCopy = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
voidViewModel = getFragmentScopeViewModel(VoidViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
transProcessViewModel = getFragmentScopeViewModel(TransProcessViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_trans_info_screen, BR.voidViewModel,voidViewModel)
|
||||||
|
.addBindingParam(BR.sharedViewModel,sharedViewModel)
|
||||||
|
.addBindingParam(BR.transProcessViewModel,transProcessViewModel)
|
||||||
|
.addBindingParam(BR.click,new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.confirmTransactionFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
setUpTimer();
|
||||||
|
|
||||||
|
setupBackButtonPressDetection(this);
|
||||||
|
|
||||||
|
String merchantName = SystemParamsOperation.getInstance().getMerchantName();
|
||||||
|
if(!TextUtils.equals(merchantName,"")){
|
||||||
|
sharedViewModel.merchantName.postValue(merchantName);
|
||||||
|
}else{
|
||||||
|
sharedViewModel.merchantName.postValue("Default Value");
|
||||||
|
}
|
||||||
|
|
||||||
|
// observeData();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpTimer(){
|
||||||
|
setupTimeout(Constants.TIMEOUT, new TimeoutCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTrick(long trickTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
routeId = R.id.action_confirmTransactionFragment_to_timeoutFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithBackIcon(getResourceString(R.string.txt_title_trans_info));
|
||||||
|
|
||||||
|
isMerchantCopy = true;
|
||||||
|
|
||||||
|
if(sharedViewModel.getTransMenu().getValue() == TransMenu.REVIEW) {
|
||||||
|
|
||||||
|
sharedViewModel.oneBtnLayout.setValue(0);
|
||||||
|
sharedViewModel.twoBtnLayout.setValue(8);
|
||||||
|
sharedViewModel.reprintBtnLayout.setValue(8);
|
||||||
|
|
||||||
|
} else if(sharedViewModel.getTransMenu().getValue() == TransMenu.TRANSACTIONS || sharedViewModel.getTransMenu().getValue() == TransMenu.TIP_ADJUSTMENT || sharedViewModel.getTransMenu().getValue() == TransMenu.VOID || sharedViewModel.getTransMenu().getValue() == TransMenu.PRE_AUTH_COMPLETE_VOID || sharedViewModel.getTransMenu().getValue() == TransMenu.PRE_AUTH_FULL_VOID) {
|
||||||
|
|
||||||
|
sharedViewModel.oneBtnLayout.setValue(8);
|
||||||
|
sharedViewModel.twoBtnLayout.setValue(0);
|
||||||
|
sharedViewModel.reprintBtnLayout.setValue(8);
|
||||||
|
|
||||||
|
} else if(sharedViewModel.getTransMenu().getValue() == TransMenu.REPRINT) {
|
||||||
|
|
||||||
|
sharedViewModel.reprintTransTypeMsg.setValue(getResourceString(R.string.txt_print_merchant_copy));
|
||||||
|
sharedViewModel.oneBtnLayout.setValue(8);
|
||||||
|
sharedViewModel.twoBtnLayout.setValue(8);
|
||||||
|
sharedViewModel.reprintBtnLayout.setValue(0);
|
||||||
|
|
||||||
|
// printReceipt(true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void finishECR() {
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(getResourceString(R.string.txt_cancel_trans));
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void callMainScreen(){
|
||||||
|
routeId = R.id.action_confirmTransactionFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ECRActionCancel(){
|
||||||
|
if(sharedViewModel.isEcr.getValue() != null){
|
||||||
|
if(sharedViewModel.isEcr.getValue()){
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(getResourceString(R.string.txt_cancel_trans));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPress() {
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
finishECR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
popBackStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printReceipt(boolean isMerchantCopy) {
|
||||||
|
if (PrintHelper.getInstance().paperRollStatus() == SdkResult.Printer_PaperLack) {
|
||||||
|
showPrinterAlertDialog(getResourceString(R.string.txt_paper_roll_empty), new DialogCallback() {
|
||||||
|
@Override
|
||||||
|
public void onClickCancel() {
|
||||||
|
|
||||||
|
dismissPrinterAlertDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickRetry() {
|
||||||
|
cancelTimeout();
|
||||||
|
setUpTimer();
|
||||||
|
|
||||||
|
dismissPrinterAlertDialog();
|
||||||
|
if (PrintHelper.getInstance().paperRollStatus() == SdkResult.Printer_PaperLack) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printReceipt();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(SystemParamsOperation.getInstance().isAlertSound()) {
|
||||||
|
|
||||||
|
startSound(getResourceString(R.string.txt_audio_empty_paper_alert));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (PrintHelper.getInstance().paperRollStatus() == SdkResult.Success) {
|
||||||
|
printReceipt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printReceipt() {
|
||||||
|
|
||||||
|
PrintXReceipt.getInstance().printSmileReceipt(sharedViewModel.payDetail.getValue(), isMerchantCopy, new PrintXStatus() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess() {
|
||||||
|
if(!isMerchantCopy) {
|
||||||
|
delayFunctionCall(ConfirmTransactionFragment.this::callMainScreen);
|
||||||
|
}
|
||||||
|
toggleCustomerMerchant();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure() {
|
||||||
|
cancelTimeout();
|
||||||
|
printReceipt(isMerchantCopy);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleCustomerMerchant() {
|
||||||
|
|
||||||
|
isMerchantCopy = !isMerchantCopy;
|
||||||
|
sharedViewModel.reprintTransTypeMsg.postValue(getResourceString(R.string.txt_print_customer_copy));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
|
||||||
|
public void onConfirm(){
|
||||||
|
|
||||||
|
if (sharedViewModel.transactionsType.getValue() == TransactionsType.TIP_ADJUSTMENT) {
|
||||||
|
|
||||||
|
routeId = R.id.action_confirmTransactionFragment_to_inputTipAmountFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
routeId = R.id.action_confirmTransactionFragment_to_processingFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void onCancel(){
|
||||||
|
ECRActionCancel();
|
||||||
|
callMainScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClose() {
|
||||||
|
popBackStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPrint() {
|
||||||
|
|
||||||
|
printReceipt(isMerchantCopy);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,68 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.InputTraceViewModel;
|
||||||
|
|
||||||
|
public class EditStanFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private InputTraceViewModel inputTraceViewModel;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
inputTraceViewModel = getFragmentScopeViewModel(InputTraceViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithBackIcon(getResourceString(R.string.title_edit_stan));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_edit_stan_screen, BR.inputTraceViewModel,inputTraceViewModel)
|
||||||
|
.addBindingParam(BR.click,new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.editStanFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
public void onCancel() {
|
||||||
|
popBackStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onConfirm() {
|
||||||
|
String traceNo = inputTraceViewModel.invoiceNo.getValue();
|
||||||
|
|
||||||
|
if(traceNo != null && traceNo.length() > 0 && traceNo.length() <= 6) {
|
||||||
|
int trace = Integer.parseInt(traceNo);
|
||||||
|
SystemParamsOperation.getInstance().setSTAN(trace);
|
||||||
|
showSuccessDialog("Success!");
|
||||||
|
inputTraceViewModel.invoiceNo.setValue("");
|
||||||
|
} else {
|
||||||
|
showDeclineDialog("Invalid STAN!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,295 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
|
||||||
|
import com.sunmi.pay.hardware.aidlv2.bean.EMVCandidateV2;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.ui.ListDialog;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.model.TradeData;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmyanmar.paylibs.utils.params.Params;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.EmvReadCardViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.TransProcessViewModel;
|
||||||
|
import com.utsmm.kbz.ui.pre_auth.PreAuthCompViewModel;
|
||||||
|
import com.utsmm.kbz.util.enums.EmvReadStatus;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Currently this class is not used
|
||||||
|
*/
|
||||||
|
public class EmvReadCardFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private EmvReadCardViewModel emvReadCardViewModel;
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
private PreAuthCompViewModel preAuthCompViewModel;
|
||||||
|
|
||||||
|
private TransProcessViewModel transProcessViewModel;
|
||||||
|
|
||||||
|
private ListDialog mListDialog;
|
||||||
|
|
||||||
|
private static final String TAG = EmvReadCardFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private int routeID;
|
||||||
|
|
||||||
|
private int popBackID;
|
||||||
|
|
||||||
|
private List<PayDetail> lists = new ArrayList<>();
|
||||||
|
|
||||||
|
private String currentCardNo = "";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
emvReadCardViewModel = getFragmentScopeViewModel(EmvReadCardViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
preAuthCompViewModel = getFragmentScopeViewModel(PreAuthCompViewModel.class);
|
||||||
|
transProcessViewModel = getFragmentScopeViewModel(TransProcessViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_emv_card_read, BR.emv,emvReadCardViewModel)
|
||||||
|
.addBindingParam(BR.click,new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
observeData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
emvReadCardViewModel.terminateTrans();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
|
||||||
|
emvReadCardViewModel.startProcess();
|
||||||
|
|
||||||
|
emvReadCardViewModel.resultStatus.observe(getViewLifecycleOwner(), new Observer<EmvReadStatus>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(EmvReadStatus emvReadStatus) {
|
||||||
|
switch (emvReadStatus){
|
||||||
|
case SUCCESS: emvReadCardViewModel.isButtonVisible.postValue(true);
|
||||||
|
currentCardNo = emvReadCardViewModel.cardNum.getValue();
|
||||||
|
break;
|
||||||
|
case FAIL: cardReadFailAction(emvReadCardViewModel.errorCode.getValue()); break;
|
||||||
|
case SELECT_APP: observeList();break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cardReadFailAction(String message){
|
||||||
|
try{
|
||||||
|
if(message == null){
|
||||||
|
message = getResourceString(R.string.txt_card_read_fail);
|
||||||
|
}else if(message.contains(":")){
|
||||||
|
message = message.split(":")[1];
|
||||||
|
}
|
||||||
|
getNavController(Constants.NAV_HOST_ID).navigate(popBackID);
|
||||||
|
|
||||||
|
showSingleInfoDialog(message);
|
||||||
|
|
||||||
|
if(sharedViewModel.isEcr.getValue() != null){
|
||||||
|
if(sharedViewModel.isEcr.getValue()){
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(message);
|
||||||
|
// ECRHelper.INSTANCE.send(message.getBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch (IllegalArgumentException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
getNavController(Constants.NAV_HOST_ID).navigate(popBackID);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void observeData(){
|
||||||
|
|
||||||
|
switch (sharedViewModel.transactionsType.getValue()){
|
||||||
|
|
||||||
|
case PRE_AUTH_COMPLETE:
|
||||||
|
observePreAuthComp();
|
||||||
|
routeID = R.id.action_emvReadCardFragment_to_inputRRNFragment;
|
||||||
|
popBackID = R.id.action_emvReadCardFragment_to_nav_main;
|
||||||
|
break;
|
||||||
|
case PRE_AUTH_VOID:
|
||||||
|
routeID = R.id.action_emvReadCardFragment_to_inputRRNFragment;
|
||||||
|
popBackID = R.id.action_emvReadCardFragment_to_nav_main;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void observePreAuthComp() {
|
||||||
|
preAuthCompViewModel.getPreAuthComData().observe(getViewLifecycleOwner(), new Observer<List<PayDetail>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(List<PayDetail> payDetails) {
|
||||||
|
if(payDetails.size() > 0) {
|
||||||
|
LogUtil.d(TAG,"Pre Auth Comp size :"+payDetails.size());
|
||||||
|
lists.addAll(payDetails);
|
||||||
|
sharedViewModel.payDetailList.postValue(payDetails);
|
||||||
|
} else {
|
||||||
|
LogUtil.d(TAG,"Pre Auth Comp data not found!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkPreAuthCardNo() {
|
||||||
|
if(sharedViewModel.transactionsType.getValue() == TransactionsType.PRE_AUTH_VOID) {
|
||||||
|
|
||||||
|
return sharedViewModel.payDetail.getValue().getCardNo().equals(currentCardNo);
|
||||||
|
|
||||||
|
} else if (sharedViewModel.transactionsType.getValue() == TransactionsType.PRE_AUTH_COMPLETE) {
|
||||||
|
|
||||||
|
for(PayDetail payDetail: lists) {
|
||||||
|
if(payDetail.getCardNo().equals(currentCardNo)){
|
||||||
|
sharedViewModel.cardNo.postValue(currentCardNo);
|
||||||
|
return true;
|
||||||
|
}else{
|
||||||
|
LogUtil.d(TAG,"not found 1!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void observeList(){
|
||||||
|
emvReadCardViewModel.emvList.observe(getViewLifecycleOwner(), new Observer<List<EMVCandidateV2>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(List<EMVCandidateV2> emvCandidateV2s) {
|
||||||
|
showListDialog(emvCandidateV2s);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showListDialog(List<EMVCandidateV2> list) {
|
||||||
|
if (mListDialog == null) {
|
||||||
|
mListDialog = new ListDialog(getContext());
|
||||||
|
mListDialog.setTitleText(R.string.index_select_app);
|
||||||
|
mListDialog.setCancelable(true);
|
||||||
|
mListDialog.setCanceledOnTouchOutside(true);
|
||||||
|
}
|
||||||
|
List<String> tempList = new ArrayList<>();
|
||||||
|
for (EMVCandidateV2 emvCandidateV2 : list) {
|
||||||
|
tempList.add(emvCandidateV2.appLabel);
|
||||||
|
}
|
||||||
|
mListDialog.setData(tempList);
|
||||||
|
mListDialog.setOnItemClickListener(
|
||||||
|
position -> {
|
||||||
|
emvReadCardViewModel.setEmvAppSelect(position);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
mListDialog.show();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buildCardData(){
|
||||||
|
TradeData tradeData = Params.newTrade(false);
|
||||||
|
PayDetail payDetails = tradeData.getPayDetail();
|
||||||
|
payDetails.setCardNo(emvReadCardViewModel.cardNum.getValue());
|
||||||
|
payDetails.setEXPDate(emvReadCardViewModel.expDate.getValue());
|
||||||
|
payDetails.setCardType(1);
|
||||||
|
payDetails.setAccountType("VISA");
|
||||||
|
payDetails.setCardHolderName("card holder");
|
||||||
|
// payDetails.setCardInfo();
|
||||||
|
|
||||||
|
transProcessViewModel.setTradeData(tradeData);
|
||||||
|
transProcessViewModel.transType.postValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkRoute(){
|
||||||
|
|
||||||
|
buildCardData();
|
||||||
|
|
||||||
|
if(checkPreAuthCardNo()){
|
||||||
|
getNavController(Constants.NAV_HOST_ID).navigate(routeID);
|
||||||
|
}else{
|
||||||
|
showDeclineDialog("Mismatch Card No!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
public void onConfirm() {
|
||||||
|
checkRoute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCancel() {
|
||||||
|
if(sharedViewModel.isEcr.getValue() != null){
|
||||||
|
if(sharedViewModel.isEcr.getValue()){
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg("Canceled Transactions!");
|
||||||
|
// ECRHelper.INSTANCE.send("Canceled Transactions!".getBytes());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getNavController(Constants.NAV_HOST_ID).navigate(popBackID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,443 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.navigation.NavController;
|
||||||
|
import androidx.navigation.NavDestination;
|
||||||
|
|
||||||
|
import com.utsmm.kbz.ui.pinpad.PinPadViewModel;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.ui.CustomPinPadKeyboard;
|
||||||
|
import com.utsmyanmar.baselib.ui.ListDialog;
|
||||||
|
import com.utsmyanmar.baselib.util.CardDetectCallback;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.checkxread.util.CardTypeX;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.model.TradeData;
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.databinding.FragmentEmvInputPinBinding;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.EmvTransactionProcessViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmyanmar.baselib.util.enums.PinUtil;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
public class EmvTransactionFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private EmvTransactionProcessViewModel emvTransactionViewModel;
|
||||||
|
|
||||||
|
private PinPadViewModel pinPadViewModel;
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
private static final String TAG = EmvTransactionFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private ListDialog mListDialog;
|
||||||
|
|
||||||
|
private TradeData tradeData;
|
||||||
|
private PayDetail payDetail;
|
||||||
|
private String ecrErrorMsg = "";
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
private int cardType;
|
||||||
|
private CustomPinPadKeyboard customPinPadKeyboard;
|
||||||
|
|
||||||
|
private FragmentEmvInputPinBinding binding;
|
||||||
|
|
||||||
|
private final NavController.OnDestinationChangedListener listener = new NavController.OnDestinationChangedListener() {
|
||||||
|
@Override
|
||||||
|
public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
|
||||||
|
if (destination.getId() == R.id.nav_main) {
|
||||||
|
|
||||||
|
ECRActionCancel(ecrErrorMsg);
|
||||||
|
emvTransactionViewModel.onCancelEmvTransaction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
emvTransactionViewModel = getFragmentScopeViewModel(EmvTransactionProcessViewModel.class);
|
||||||
|
pinPadViewModel = getFragmentScopeViewModel(PinPadViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_emv_input_pin, BR.emv, emvTransactionViewModel)
|
||||||
|
.addBindingParam(BR.sharedViewModel, sharedViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.emvTransactionFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initSharedData() {
|
||||||
|
if (sharedViewModel.transactionsType.getValue() == TransactionsType.PIN_CHANGE) {
|
||||||
|
emvTransactionViewModel.pinUtil.postValue(PinUtil.OLD_PIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData() {
|
||||||
|
tradeData = emvTransactionViewModel.getTradeData();
|
||||||
|
try {
|
||||||
|
payDetail = tradeData.getPayDetail();
|
||||||
|
cardType = payDetail.getCardType();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_please_try_again));
|
||||||
|
navigateToMain();
|
||||||
|
}
|
||||||
|
|
||||||
|
String amount = sharedViewModel.amount.getValue();
|
||||||
|
String processCode = sharedViewModel.processCode.getValue();
|
||||||
|
payDetail.setAmount(POSUtil.getInstance().convertAmount(amount));
|
||||||
|
|
||||||
|
if (!TextUtils.equals(processCode, "")) {
|
||||||
|
payDetail.setProcessCode(processCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
binding = (FragmentEmvInputPinBinding) mBinding;
|
||||||
|
|
||||||
|
emvTransactionViewModel.customPinPadKeyboard = binding.customPinPad;
|
||||||
|
|
||||||
|
initSharedData();
|
||||||
|
|
||||||
|
initData();
|
||||||
|
|
||||||
|
if(isNotManualTransaction())
|
||||||
|
emvTransactionViewModel.startProcess();
|
||||||
|
else {
|
||||||
|
if(SystemParamsOperation.getInstance().isManualEntryPinEnable()) {
|
||||||
|
pinPadViewModel.setTradeData(tradeData);
|
||||||
|
navigateToPinPad();
|
||||||
|
} else {
|
||||||
|
navigateToProcessing();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
observeEmvResultStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNotManualTransaction() {
|
||||||
|
return cardType != CardTypeX.MANUAL.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showConfirmCodeVerifyDialog() {
|
||||||
|
new AlertDialog.Builder(requireContext())
|
||||||
|
.setTitle("See Phone")
|
||||||
|
.setMessage("execute See Phone flow")
|
||||||
|
.setPositiveButton("OK", (dia, which) -> {
|
||||||
|
dia.dismiss();
|
||||||
|
// Restart transaction procedure.
|
||||||
|
try {
|
||||||
|
// mEMVOptV2.initEmvProcess();
|
||||||
|
// checkCard();
|
||||||
|
navigateToCheckCard();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToPinPad() {
|
||||||
|
routeId = R.id.action_emvTransactionFragment_to_pinPadFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void isCardTaped(String alertMsg) {
|
||||||
|
isCardTaped(alertMsg,this::navigateToCheckCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void observeEmvResultStatus() {
|
||||||
|
emvTransactionViewModel.emvResultStatus.observe(getViewLifecycleOwner(), emvResultStatus -> {
|
||||||
|
|
||||||
|
LogUtil.d(TAG, "EMV Result Status : " + emvResultStatus);
|
||||||
|
switch (emvResultStatus) {
|
||||||
|
case SELECT_APP:
|
||||||
|
observeCandiList();
|
||||||
|
break;
|
||||||
|
case READ_CARD:
|
||||||
|
|
||||||
|
isCardInserted(new CardDetectCallback() {
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
sharedViewModel.setIsFallback(true);
|
||||||
|
navigateToCheckCard();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
case PIN_PAD_CANCEL:
|
||||||
|
navigateToMain();
|
||||||
|
break;
|
||||||
|
case ON_NEXT_SCREEN:
|
||||||
|
navigateToRRNScreen();
|
||||||
|
break;
|
||||||
|
case READ_CARD_RETRY:
|
||||||
|
sharedViewModel.set_errorFragmentMsg("Interface not found!");
|
||||||
|
navigateToError();
|
||||||
|
break;
|
||||||
|
case READ_CARD_NO_APP:
|
||||||
|
isCardTaped("Terminal has no APP!");
|
||||||
|
break;
|
||||||
|
case TRY_AGAIN:
|
||||||
|
sharedViewModel.set_errorFragmentMsg("Please replace the card");
|
||||||
|
navigateToError();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OFFLINE_DECLINE:
|
||||||
|
|
||||||
|
sharedViewModel.set_errorFragmentMsg("Offline Denial");
|
||||||
|
navigateToError();
|
||||||
|
break;
|
||||||
|
case CONFIRM_CODE_VERIFY:
|
||||||
|
showConfirmCodeVerifyDialog();
|
||||||
|
break;
|
||||||
|
case SECONDARY:
|
||||||
|
LogUtil.d(TAG, "TRY_SECONDARY Here!");
|
||||||
|
dismissLoadingDialog();
|
||||||
|
showLoadingDialog("Sending secondary.....");
|
||||||
|
break;
|
||||||
|
// new code
|
||||||
|
case PIN_MISMATCH:
|
||||||
|
showDeclineDialog("PIN MISMATCH!");
|
||||||
|
navigateToMain();
|
||||||
|
break;
|
||||||
|
case SUCCESS:
|
||||||
|
navigateToProcessing();
|
||||||
|
break;
|
||||||
|
case SUCCESS_ONLINE:
|
||||||
|
case FAIL_ONLINE:
|
||||||
|
updateData();
|
||||||
|
dismissLoadingDialog();
|
||||||
|
navigateToNext();
|
||||||
|
break;
|
||||||
|
case REVERSAL_PROCESS:
|
||||||
|
dismissLoadingDialog();
|
||||||
|
showLoadingDialog("Sending reversal.....");
|
||||||
|
break;
|
||||||
|
case REVERSAL_SECONDARY:
|
||||||
|
dismissLoadingDialog();
|
||||||
|
showLoadingDialog("Sending reversal secondary...");
|
||||||
|
break;
|
||||||
|
case REVERSAL_FAIL:
|
||||||
|
ECRActionCancel("Reversal failed!");
|
||||||
|
dismissLoadingDialog();
|
||||||
|
showDeclineDialog("Reversal failed!");
|
||||||
|
navigateToMain();
|
||||||
|
break;
|
||||||
|
case REVERSAL_SUCCESS:
|
||||||
|
ECRActionCancel("Reversal success!");
|
||||||
|
dismissLoadingDialog();
|
||||||
|
showSuccessDialog("Reversal success!");
|
||||||
|
navigateToMain();
|
||||||
|
break;
|
||||||
|
case FAIL:
|
||||||
|
showDeclineDialog("");
|
||||||
|
dismissLoadingDialog();
|
||||||
|
navigateToMain();
|
||||||
|
break;
|
||||||
|
case NETWORK_ERROR:
|
||||||
|
dismissLoadingDialog();
|
||||||
|
showDeclineDialog("Com Error!");
|
||||||
|
navigateToMain();
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
observeEmvErrorCode();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LogUtil.d(TAG,"EmvResult Status : "+emvResultStatus);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void observeEmvErrorCode() {
|
||||||
|
dismissLoadingDialog();
|
||||||
|
emvTransactionViewModel.errorCodeMsg.observe(getViewLifecycleOwner(), pair -> {
|
||||||
|
LogUtil.e(TAG, "ERROR CODE MSG :" + pair);
|
||||||
|
if (!TextUtils.equals(pair, "")) {
|
||||||
|
if (pair.contains(":")) {
|
||||||
|
String code = pair.split(":")[0];
|
||||||
|
String msg = pair.split(":")[1];
|
||||||
|
|
||||||
|
if (TextUtils.equals(code, "-4100") || TextUtils.equals(code, "-4125")) {
|
||||||
|
sharedViewModel.set_errorFragmentMsg("Card read failed!");
|
||||||
|
} else {
|
||||||
|
sharedViewModel.set_errorFragmentMsg(code + "\n" + msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ecrErrorMsg = msg;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
ecrErrorMsg = pair;
|
||||||
|
|
||||||
|
sharedViewModel.set_errorFragmentMsg(pair);
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
sharedViewModel.set_errorFragmentMsg("Emv process timeout!");
|
||||||
|
|
||||||
|
ecrErrorMsg = "Emv process timeout!";
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
navigateToError();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ECRActionCancel(String message) {
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null && sharedViewModel.isEcr.getValue()) {
|
||||||
|
|
||||||
|
LogUtil.d(TAG, "isECR true");
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(message);
|
||||||
|
|
||||||
|
if (isEmvTrans()) {
|
||||||
|
emvTransactionViewModel.onCancelEmvTransaction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isEmvTrans() {
|
||||||
|
return sharedViewModel.isEmv.getValue() != null && sharedViewModel.isEmv.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateData() {
|
||||||
|
|
||||||
|
emvTransactionViewModel.payDetailResult.observe(getViewLifecycleOwner(), payDetail -> {
|
||||||
|
sharedViewModel.payDetail.setValue(payDetail);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
emvTransactionViewModel.resetUI();
|
||||||
|
|
||||||
|
getNavController(Constants.NAV_HOST_ID).addOnDestinationChangedListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
resetEmvResult();
|
||||||
|
|
||||||
|
// enableNavigationBar();
|
||||||
|
getNavController(Constants.NAV_HOST_ID).removeOnDestinationChangedListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetEmvResult() {
|
||||||
|
emvTransactionViewModel.resetTransactionStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToNext() {
|
||||||
|
routeId = R.id.action_emvTransactionFragment_to_transactionResultFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToProcessing() {
|
||||||
|
routeId = R.id.action_emvTransactionFragment_to_processingFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToMain() {
|
||||||
|
|
||||||
|
routeId = R.id.action_emvTransactionFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToError() {
|
||||||
|
routeId = R.id.action_emvTransactionFragment_to_errorFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToCheckCard() {
|
||||||
|
routeId = R.id.action_emvTransactionFragment_to_cardWaitingFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToRRNScreen() {
|
||||||
|
routeId = R.id.action_emvTransactionFragment_to_inputRRNFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void observeCandiList() {
|
||||||
|
emvTransactionViewModel.candiList.observe(getViewLifecycleOwner(), this::showCandiListDialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showCandiListDialog(String[] list) {
|
||||||
|
if (mListDialog == null) {
|
||||||
|
mListDialog = new ListDialog(requireContext());
|
||||||
|
mListDialog.setTitleText(R.string.index_select_app);
|
||||||
|
mListDialog.setCancelable(true);
|
||||||
|
mListDialog.setCanceledOnTouchOutside(true);
|
||||||
|
}
|
||||||
|
List<String> tempList = new ArrayList<>(Arrays.asList(list));
|
||||||
|
mListDialog.setData(tempList);
|
||||||
|
mListDialog.setOnItemClickListener(
|
||||||
|
position -> {
|
||||||
|
LogUtil.d(TAG,"SELECTED APP:"+list[position]);
|
||||||
|
|
||||||
|
emvTransactionViewModel.setEmvAppSelect(position);
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
try {
|
||||||
|
mListDialog.show();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
public class ErrorFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_error_screen, BR.sharedViewModel,sharedViewModel );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.errorFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return R.id.action_errorFragment_to_nav_main;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.txt_title_error));
|
||||||
|
|
||||||
|
|
||||||
|
delayFunctionCall(this::navigateToMain,2000);
|
||||||
|
super.onResume();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
sharedViewModel.setTransMenu(null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToMain() {
|
||||||
|
LogUtil.d("ERROR Fragment","navigating to Main....");
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,242 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.CardDetectCallback;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.TimeoutCallback;
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsSettings;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.InvalidAmount;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.InputAmountViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.TransProcessViewModel;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
public class InputAmountFragment extends DataBindingFragment implements DataBindingFragment.BackPressCallback{
|
||||||
|
|
||||||
|
private static final String TAG = InputAmountFragment.class.getSimpleName();
|
||||||
|
private InputAmountViewModel inputAmountViewModel;
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private TransProcessViewModel transProcessViewModel;
|
||||||
|
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
inputAmountViewModel = getFragmentScopeViewModel(InputAmountViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
transProcessViewModel = getFragmentScopeViewModel(TransProcessViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_amount_screen, BR.inputAmountVM,inputAmountViewModel)
|
||||||
|
.addBindingParam(BR.sharedViewModel,sharedViewModel)
|
||||||
|
.addBindingParam(BR.click,new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.inputAmountFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
|
||||||
|
setUpTimer();
|
||||||
|
|
||||||
|
setupBackButtonPressDetection(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpTimer(){
|
||||||
|
setupTimeout(Constants.TIMEOUT, new TimeoutCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTrick(long trickTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
routeId = R.id.action_inputAmountFragment_to_timeoutFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*May 16 2022*/
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithBackIcon(getResourceString(R.string.txt_subtitle_amount));
|
||||||
|
|
||||||
|
if(sharedViewModel.isEcr.getValue() != null){
|
||||||
|
if(sharedViewModel.isEcr.getValue()){
|
||||||
|
|
||||||
|
delayFunctionCall(()->{
|
||||||
|
observeRouteId(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inputAmountViewModel.inputAmountView.setValue("0");
|
||||||
|
inputAmountViewModel.invalidAmountMsg.setValue("");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
inputAmountViewModel.inputAmountView.postValue("0");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void finishECR() {
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg("Invalid Amount!");
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
getNavController(Constants.NAV_HOST_ID).popBackStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void observeRouteId(boolean isECR) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(sharedViewModel.transactionsType.getValue() == TransactionsType.MMQR) {
|
||||||
|
|
||||||
|
// here implement logic for min - max amount QR
|
||||||
|
|
||||||
|
|
||||||
|
String minAmount;
|
||||||
|
String maxAmount;
|
||||||
|
|
||||||
|
if(SystemParamsOperation.getInstance().getMinAmount() != null && !SystemParamsOperation.getInstance().getMinAmount().isEmpty() && SystemParamsOperation.getInstance().getMaxAmount() != null && !SystemParamsOperation.getInstance().getMaxAmount().isEmpty()) {
|
||||||
|
|
||||||
|
minAmount = SystemParamsOperation.getInstance().getMinAmount();
|
||||||
|
maxAmount = SystemParamsOperation.getInstance().getMaxAmount();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
minAmount = "0";
|
||||||
|
maxAmount = "99999999";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(POSUtil.getInstance().checkMinMaxAmount(sharedViewModel.amount.getValue(),minAmount,maxAmount) == InvalidAmount.OKAY) {
|
||||||
|
routeId = R.id.action_inputAmountFragment_to_QRConnectingFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
} else {
|
||||||
|
// routeId = R.id.action_inputAmountFragment_to_nav_main;
|
||||||
|
inputAmountViewModel.invalidAmountMsg.setValue(POSUtil.getInstance().checkMinMaxAmount(sharedViewModel.amount.getValue(),minAmount,maxAmount).msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
sharedViewModel.setAmountExist(true);
|
||||||
|
|
||||||
|
if(sharedViewModel.getCardDataExist().getValue() != null && sharedViewModel.getCardDataExist().getValue()) {
|
||||||
|
routeId = R.id.action_inputAmountFragment_to_pinPadFragment;
|
||||||
|
} else {
|
||||||
|
routeId = R.id.action_inputAmountFragment_to_cardWaitingFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPress() {
|
||||||
|
checkCard();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCard() {
|
||||||
|
isCardInserted(new CardDetectCallback() {
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
LogUtil.d(TAG,"Going to main");
|
||||||
|
safePopBackStack();
|
||||||
|
// delayFunctionCall(()->{
|
||||||
|
// LogUtil.d(TAG,"popup stack!");
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ClickEvent{
|
||||||
|
|
||||||
|
public void onConfirm(){
|
||||||
|
if(isInputValid(Objects.requireNonNull(inputAmountViewModel.inputAmountView.getValue()))){
|
||||||
|
inputAmountViewModel.invalidAmountMsg.setValue("");
|
||||||
|
|
||||||
|
boolean decimalEnabled = SystemParamsOperation.getInstance().getDecimalEnable();
|
||||||
|
String inputValue = inputAmountViewModel.inputAmountView.getValue();
|
||||||
|
|
||||||
|
if (decimalEnabled) {
|
||||||
|
// SMILE requested to add ".00" even they type non decimal amount...
|
||||||
|
// 23/09/2024
|
||||||
|
if (!inputValue.contains(".")) {
|
||||||
|
sharedViewModel.amount.setValue(inputValue + ".00");
|
||||||
|
} else {
|
||||||
|
sharedViewModel.amount.setValue(inputValue);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If decimal is not enabled, only allow integer values.
|
||||||
|
if (inputValue.contains(".")) {
|
||||||
|
// Show error if decimals are entered when disabled
|
||||||
|
showSingleInfoDialog("Decimal values are not allowed.");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
sharedViewModel.amount.setValue(inputValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
observeRouteId(false);
|
||||||
|
} else {
|
||||||
|
showSingleInfoDialog(getResourceString(R.string.txt_please_input_amount));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCancel() {
|
||||||
|
checkCard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,172 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.TimeoutCallback;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.InputApprovalViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.TransProcessViewModel;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
public class InputApprovalFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private static final String TAG = InputApprovalFragment.class.getSimpleName();
|
||||||
|
private InputApprovalViewModel inputApprovalViewModel;
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private TransProcessViewModel transProcessViewModel;
|
||||||
|
private String approvalCode = "";
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
inputApprovalViewModel = getFragmentScopeViewModel(InputApprovalViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
transProcessViewModel = getFragmentScopeViewModel(TransProcessViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_input_approval_screen, BR.approvalViewModel,inputApprovalViewModel)
|
||||||
|
.addBindingParam(BR.click,new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.inputApprovalFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
if(sharedViewModel.isEcr.getValue() != null){
|
||||||
|
if(sharedViewModel.isEcr.getValue()){
|
||||||
|
|
||||||
|
approvalCode = sharedViewModel.approvalCode.getValue();
|
||||||
|
|
||||||
|
delayFunctionCall(()-> {
|
||||||
|
validateApprovalCode(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
setUpTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpTimer(){
|
||||||
|
setupTimeout(Constants.TIMEOUT, new TimeoutCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTrick(long trickTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
routeId = R.id.action_inputApprovalFragment_to_timeoutFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigationECR(){
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg("Approval Not Match!");
|
||||||
|
getNavController(Constants.NAV_HOST_ID).popBackStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkApproval(boolean isECR) {
|
||||||
|
sharedViewModel.payDetail.observe(getViewLifecycleOwner(), payDetail -> {
|
||||||
|
if( payDetail != null ) {
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"approval code: "+payDetail.getApprovalCode());
|
||||||
|
|
||||||
|
if(payDetail.getApprovalCode().equals(approvalCode)) {
|
||||||
|
transProcessViewModel.setPayDetail(payDetail);
|
||||||
|
//route to confirm fragment
|
||||||
|
routeId = R.id.action_inputApprovalFragment_to_confirmTransactionFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if(isECR)
|
||||||
|
navigationECR();
|
||||||
|
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_please_enter_correct_approval));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if(isECR)
|
||||||
|
navigationECR();
|
||||||
|
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_please_enter_correct_approval));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
sharedViewModel.approvalCode.postValue(null);
|
||||||
|
sharedViewModel.rrNNo.postValue(null);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void validateApprovalCode(boolean isECR) {
|
||||||
|
if (!TextUtils.equals(approvalCode,"") && approvalCode.length() == 6) {
|
||||||
|
|
||||||
|
checkApproval(isECR);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_please_enter_approval));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClickEvent{
|
||||||
|
|
||||||
|
|
||||||
|
public void onCancel() {
|
||||||
|
popBackStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onConfirm() {
|
||||||
|
approvalCode = inputApprovalViewModel.txtApproval.getValue();
|
||||||
|
validateApprovalCode(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,262 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.CardDetectCallback;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.TimeoutCallback;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.TransMenu;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.InputPasswordViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.util.enums.InputPasswordType;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class InputPasswordFragment extends DataBindingFragment implements DataBindingFragment.BackPressCallback {
|
||||||
|
|
||||||
|
private static final String TAG = InputPasswordFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private InputPasswordViewModel inputPasswordViewModel;
|
||||||
|
|
||||||
|
private static final String PRE_AUTH_COMPLETE = "PRE_AUTH_COMPLETE";
|
||||||
|
|
||||||
|
private static final String SALE = "SALE";
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
private OnFragmentInteractionListener mListener;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
inputPasswordViewModel = getFragmentScopeViewModel(InputPasswordViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_password_screen, BR.passwordViewModel, inputPasswordViewModel)
|
||||||
|
.addBindingParam(BR.sharedViewModel,sharedViewModel)
|
||||||
|
.addBindingParam(BR.click, new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.inputPasswordFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Context context) {
|
||||||
|
super.onAttach(context);
|
||||||
|
if (context instanceof OnFragmentInteractionListener) {
|
||||||
|
mListener = (OnFragmentInteractionListener) context;
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException(context.toString()
|
||||||
|
+ " must implement OnFragmentInteractionListener");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDetach() {
|
||||||
|
super.onDetach();
|
||||||
|
mListener = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
setUpTimer();
|
||||||
|
|
||||||
|
setupBackButtonPressDetection(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
setToolBarTitleWithBackIcon(getResourceString(R.string.title_password));
|
||||||
|
|
||||||
|
try{
|
||||||
|
checkRoute();
|
||||||
|
} catch (NullPointerException e){
|
||||||
|
e.printStackTrace();
|
||||||
|
showShortToast(getResourceString(R.string.txt_cannot_find_route));
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// disableNavigationBar();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
inputPasswordViewModel.passwordType.postValue(null);
|
||||||
|
|
||||||
|
// enableNavigationBar();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
clearLiveData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearLiveData() {
|
||||||
|
inputPasswordViewModel.clearInput();
|
||||||
|
inputPasswordViewModel.passwordInput.postValue("");
|
||||||
|
inputPasswordViewModel.maskedPassword.postValue("");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkRoute() {
|
||||||
|
switch (Objects.requireNonNull(sharedViewModel.transactionsType.getValue())) {
|
||||||
|
case PRE_AUTH_COMPLETE_VOID:
|
||||||
|
inputPasswordViewModel.passwordType.setValue(InputPasswordType.SYSTEM);
|
||||||
|
sharedViewModel.transactionName.postValue(getResourceString(R.string.title_pre_auth_complete));
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.PRE_AUTH_COMPLETE_VOID);
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_inputTraceFragment;
|
||||||
|
// routeId = R.id.action_inputPasswordFragment_to_selectHostFragment;
|
||||||
|
break;
|
||||||
|
case TIP_ADJUSTMENT:
|
||||||
|
inputPasswordViewModel.passwordType.setValue(InputPasswordType.SYSTEM);
|
||||||
|
sharedViewModel.transactionName.postValue(SALE);
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.TIP_ADJUSTMENT);
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_selectHostFragment;
|
||||||
|
break;
|
||||||
|
case VOID:
|
||||||
|
inputPasswordViewModel.passwordType.setValue(InputPasswordType.SYSTEM);
|
||||||
|
sharedViewModel.transactionName.postValue(SALE);
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.VOID);
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_inputTraceFragment;
|
||||||
|
// routeId = R.id.action_inputPasswordFragment_to_selectHostFragment;
|
||||||
|
break;
|
||||||
|
case PRE_AUTH_VOID:
|
||||||
|
inputPasswordViewModel.passwordType.setValue(InputPasswordType.SYSTEM);
|
||||||
|
if(sharedViewModel.getTransMenu().getValue() == TransMenu.PRE_AUTH_FULL_VOID) {
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_selectHostFragment;
|
||||||
|
} else {
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_inputAmountFragment;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case REFUND:
|
||||||
|
inputPasswordViewModel.passwordType.setValue(InputPasswordType.SYSTEM);
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_selectRefundFragment;
|
||||||
|
break;
|
||||||
|
case PRE_AUTH_COMPLETE:
|
||||||
|
inputPasswordViewModel.passwordType.setValue(InputPasswordType.SYSTEM);
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_inputAmountFragment;
|
||||||
|
break;
|
||||||
|
case SETTLEMENT:
|
||||||
|
inputPasswordViewModel.passwordType.setValue(InputPasswordType.SETTLEMENT);
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_settlementTransactionFragment;
|
||||||
|
break;
|
||||||
|
case SETTING:
|
||||||
|
inputPasswordViewModel.passwordType.setValue(InputPasswordType.SETTING);
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_nav_main;
|
||||||
|
break;
|
||||||
|
case FUNCTION:
|
||||||
|
inputPasswordViewModel.passwordType.setValue(InputPasswordType.SETTING);
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_nav_settings;
|
||||||
|
break;
|
||||||
|
case CLEAR_BATCH:
|
||||||
|
case CLEAR_REVERSAL:
|
||||||
|
inputPasswordViewModel.passwordType.setValue(InputPasswordType.SYSTEM);
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_selectHostFragment;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPress() {
|
||||||
|
checkCard();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpTimer(){
|
||||||
|
setupTimeout(Constants.TIMEOUT, new TimeoutCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTrick(long trickTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
routeId = R.id.action_inputPasswordFragment_to_timeoutFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public interface OnFragmentInteractionListener {
|
||||||
|
void onSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCard() {
|
||||||
|
isCardInserted(new CardDetectCallback() {
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
delayFunctionCall(()->{
|
||||||
|
safePopBackStack();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
public void onConfirm() {
|
||||||
|
if(inputPasswordViewModel.onClickEnter()) {
|
||||||
|
clearLiveData();
|
||||||
|
|
||||||
|
if(sharedViewModel.transactionsType.getValue() == TransactionsType.SETTING) {
|
||||||
|
mListener.onSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
} else {
|
||||||
|
clearLiveData();
|
||||||
|
Toast.makeText(getContext(), "Wrong Password", Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCancel() {
|
||||||
|
checkCard();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
696
app/src/main/java/com/utsmm/kbz/ui/core_ui/InputRRNFragment.java
Normal file
696
app/src/main/java/com/utsmm/kbz/ui/core_ui/InputRRNFragment.java
Normal file
@ -0,0 +1,696 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
import androidx.navigation.NavController;
|
||||||
|
import androidx.navigation.NavDestination;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.CardDetectCallback;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.TimeoutCallback;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.TransMenu;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.databinding.FragmentInputRrnScreenBinding;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.EmvTransactionProcessViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.InputRRNViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.TransProcessViewModel;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
public class InputRRNFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
|
||||||
|
private static final String TAG = InputRRNFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private InputRRNViewModel rrnViewModel;
|
||||||
|
private TransProcessViewModel transProcessViewModel;
|
||||||
|
|
||||||
|
private EmvTransactionProcessViewModel emvTransactionProcessViewModel;
|
||||||
|
|
||||||
|
private String rrnNo = "";
|
||||||
|
|
||||||
|
private String cardNo = "";
|
||||||
|
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
private FragmentInputRrnScreenBinding binding;
|
||||||
|
|
||||||
|
private EditText etRRN;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
rrnViewModel = getFragmentScopeViewModel(InputRRNViewModel.class);
|
||||||
|
transProcessViewModel = getFragmentScopeViewModel(TransProcessViewModel.class);
|
||||||
|
emvTransactionProcessViewModel = getFragmentScopeViewModel(EmvTransactionProcessViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_input_rrn_screen, BR.inputRRNVM, rrnViewModel)
|
||||||
|
.addBindingParam(BR.click, new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.inputRRNFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private final NavController.OnDestinationChangedListener listener = new NavController.OnDestinationChangedListener() {
|
||||||
|
@Override
|
||||||
|
public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
|
||||||
|
if (destination.getId() == R.id.nav_main) {
|
||||||
|
|
||||||
|
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
emvTransactionProcessViewModel.onCancelEmvTransaction();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
setUpTimer();
|
||||||
|
|
||||||
|
etRRN = mBinding.getRoot().findViewById(R.id.et_rrn);
|
||||||
|
|
||||||
|
etRRN.setOnKeyListener(new View.OnKeyListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||||
|
if (event.getAction() == KeyEvent.ACTION_DOWN) {
|
||||||
|
cancelTimeout();
|
||||||
|
setUpTimer();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpTimer(){
|
||||||
|
setupTimeout(Constants.TIMEOUT , new TimeoutCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTrick(long trickTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
routeId = R.id.action_inputRRNFragment_to_timeoutFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithBackIcon(getResourceString(R.string.title_reference_number));
|
||||||
|
|
||||||
|
getNavController(Constants.NAV_HOST_ID).addOnDestinationChangedListener(listener);
|
||||||
|
|
||||||
|
showKeyboard();
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
|
||||||
|
rrnNo = sharedViewModel.rrNNo.getValue();
|
||||||
|
delayFunctionCall(()-> {
|
||||||
|
validateRRN(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showKeyboard(){
|
||||||
|
etRRN.requestFocus();
|
||||||
|
InputMethodManager imm = (InputMethodManager)requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void closeKeyboard(){
|
||||||
|
InputMethodManager imm = (InputMethodManager) requireActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(etRRN.getWindowToken(), 0);
|
||||||
|
etRRN.clearFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
closeKeyboard();
|
||||||
|
rrnViewModel.txtRRN.setValue("");
|
||||||
|
resetEmvResult();
|
||||||
|
getNavController(Constants.NAV_HOST_ID).removeOnDestinationChangedListener(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetEmvResult() {
|
||||||
|
emvTransactionProcessViewModel.resetTransactionStatus();
|
||||||
|
}
|
||||||
|
private void callNextScreen(){
|
||||||
|
routeId = R.id.action_inputRRNFragment_to_processingFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void callResultScreen() {
|
||||||
|
routeId = R.id.action_inputRRNFragment_to_transactionResultFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void checkRRNPreAuthVoid(boolean isECR) {
|
||||||
|
|
||||||
|
rrnViewModel.searchPayDetail(cardNo,rrnNo).observe(getViewLifecycleOwner(), new Observer<PayDetail>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(PayDetail payDetail) {
|
||||||
|
if(payDetail != null) {
|
||||||
|
|
||||||
|
Date transDate = POSUtil.getInstance().getDateByString(payDetail.getTransDate());
|
||||||
|
|
||||||
|
if(payDetail.getTransactionType() != TransactionsType.PRE_AUTH_SALE.value) {
|
||||||
|
terminateProcess(isECR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PayDetail newPay;
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
newPay = emvTransactionProcessViewModel.getPayDetail();
|
||||||
|
} else {
|
||||||
|
newPay = transProcessViewModel.getPayDetail();
|
||||||
|
}
|
||||||
|
|
||||||
|
newPay.setReferNo(rrnNo);
|
||||||
|
if(sharedViewModel.getTransMenu().getValue() == TransMenu.PRE_AUTH_FULL_VOID) {
|
||||||
|
newPay.setAmount(payDetail.getAmount());
|
||||||
|
}
|
||||||
|
|
||||||
|
newPay.setTradeDateTime(payDetail.getTradeDateTime());
|
||||||
|
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
emvTransactionProcessViewModel.setOldTransPayDetail(payDetail);
|
||||||
|
newPay.setCardInfo(payDetail.getCardInfo());
|
||||||
|
emvTransactionProcessViewModel.setPayDetail(newPay);
|
||||||
|
} else {
|
||||||
|
transProcessViewModel.setOldTransPayDetail(payDetail);
|
||||||
|
transProcessViewModel.setPayDetail(newPay);
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedViewModel.rrNNo.setValue(rrnNo);
|
||||||
|
|
||||||
|
|
||||||
|
callNextScreen();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
terminateProcess(isECR);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void terminateProcess(boolean isECR) {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_ref_no_not_found));
|
||||||
|
if (isECR) {
|
||||||
|
navigationECR();
|
||||||
|
} else {
|
||||||
|
routeId = R.id.action_inputRRNFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getConfigDay() {
|
||||||
|
int configDay = 10;
|
||||||
|
|
||||||
|
String configRawDay = SystemParamsOperation.getInstance().getClearBatchDay();
|
||||||
|
|
||||||
|
if(configRawDay != null && !configRawDay.trim().isEmpty()) {
|
||||||
|
try {
|
||||||
|
configDay = Integer.parseInt(configRawDay);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return configDay;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isEmvTrans() {
|
||||||
|
return sharedViewModel.isEmv.getValue() != null && sharedViewModel.isEmv.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void preAuthCompProcess(boolean isECR) {
|
||||||
|
|
||||||
|
Date lastInputDay = POSUtil.getInstance().getLastInputDay(getConfigDay());
|
||||||
|
rrnViewModel.searchPayDetail(cardNo,rrnNo).observe(getViewLifecycleOwner(), new Observer<PayDetail>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(PayDetail payDetail) {
|
||||||
|
if(payDetail != null) {
|
||||||
|
LogUtil.d(TAG,"Transaction Type : "+payDetail.getTransType());
|
||||||
|
LogUtil.d(TAG,"Transaction Amount : "+payDetail.getAmount());
|
||||||
|
LogUtil.d(TAG,"Transaction Date/Time : "+payDetail.getTransDate()+"/"+payDetail.getTransTime());
|
||||||
|
LogUtil.d(TAG,"RRN/Trace : "+payDetail.getReferNo()+"/"+payDetail.getVoucherNo());
|
||||||
|
LogUtil.d(TAG,"Transaction is canceled : "+payDetail.isCanceled());
|
||||||
|
LogUtil.d(TAG,"----------------------------------------------------------");
|
||||||
|
|
||||||
|
|
||||||
|
Date transDate = POSUtil.getInstance().getDateByString(payDetail.getTransDate()) ;
|
||||||
|
|
||||||
|
// transaction type must be pre auth & must be within 10 days.
|
||||||
|
if (payDetail.getTransactionType() == TransactionsType.PRE_AUTH_SALE.value && lastInputDay.compareTo(transDate) < 0) {
|
||||||
|
PayDetail newPay = new PayDetail();
|
||||||
|
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
newPay = emvTransactionProcessViewModel.getPayDetail();
|
||||||
|
} else {
|
||||||
|
newPay = transProcessViewModel.getPayDetail();
|
||||||
|
}
|
||||||
|
|
||||||
|
newPay.setReferNo(rrnNo);
|
||||||
|
|
||||||
|
if(newPay.getAmount() > payDetail.getAmount()) {
|
||||||
|
newPay.setTradeAnswerCode("C1"); // ---> refer to BaseErrorCode class// ,
|
||||||
|
newPay.setTransType(sharedViewModel.transactionsType.getValue().name);
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
emvTransactionProcessViewModel.setPayDetail(newPay);
|
||||||
|
} else {
|
||||||
|
transProcessViewModel.setPayDetail(newPay);
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedViewModel.payDetail.setValue(newPay);
|
||||||
|
sharedViewModel.rrNNo.setValue(rrnNo);
|
||||||
|
|
||||||
|
callResultScreen();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
emvTransactionProcessViewModel.setOldTransPayDetail(payDetail);
|
||||||
|
emvTransactionProcessViewModel.setPayDetail(newPay);
|
||||||
|
} else {
|
||||||
|
transProcessViewModel.setOldTransPayDetail(payDetail);
|
||||||
|
transProcessViewModel.setPayDetail(newPay);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sharedViewModel.rrNNo.setValue(rrnNo);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// transProcessViewModel.setPayDetail(newPay);
|
||||||
|
|
||||||
|
sharedViewModel.rrNNo.setValue(rrnNo);
|
||||||
|
|
||||||
|
callNextScreen();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
isCardInserted(new CardDetectCallback() {
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_ref_no_not_found));
|
||||||
|
if (isECR) {
|
||||||
|
navigationECR();
|
||||||
|
} else {
|
||||||
|
routeId = R.id.action_inputRRNFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
isCardInserted(new CardDetectCallback() {
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_ref_no_not_found));
|
||||||
|
if (isECR) {
|
||||||
|
navigationECR();
|
||||||
|
} else {
|
||||||
|
routeId = R.id.action_inputRRNFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkRRNPreAuthComp(boolean isECR) {
|
||||||
|
|
||||||
|
// pre auth complete doesn't need exact date time of pre auth sale.
|
||||||
|
// need to check it
|
||||||
|
|
||||||
|
//**************************************************//
|
||||||
|
// This code block is used in certification process //
|
||||||
|
//**************************************************//
|
||||||
|
/* PayDetail payDetail = transProcessViewModel.getPayDetail();
|
||||||
|
payDetail.setReferNo(rrnNo);
|
||||||
|
transProcessViewModel.setPayDetail(payDetail);
|
||||||
|
|
||||||
|
sharedViewModel.rrNNo.setValue(rrnNo);
|
||||||
|
|
||||||
|
callNextScreen();*/
|
||||||
|
|
||||||
|
|
||||||
|
Date lastInputDay = POSUtil.getInstance().getLastInputDay(getConfigDay());
|
||||||
|
rrnViewModel.searchPayDetail(cardNo,rrnNo).observe(getViewLifecycleOwner(), new Observer<PayDetail>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(PayDetail payDetail) {
|
||||||
|
if(payDetail != null) {
|
||||||
|
LogUtil.d(TAG,"Transaction Type : "+payDetail.getTransType());
|
||||||
|
LogUtil.d(TAG,"Transaction Amount : "+payDetail.getAmount());
|
||||||
|
LogUtil.d(TAG,"Transaction Date/Time : "+payDetail.getTransDate()+"/"+payDetail.getTransTime());
|
||||||
|
LogUtil.d(TAG,"RRN/Trace : "+payDetail.getReferNo()+"/"+payDetail.getVoucherNo());
|
||||||
|
LogUtil.d(TAG,"Transaction is canceled : "+payDetail.isCanceled());
|
||||||
|
LogUtil.d(TAG,"----------------------------------------------------------");
|
||||||
|
|
||||||
|
|
||||||
|
Date transDate = POSUtil.getInstance().getDateByString(payDetail.getTransDate()) ;
|
||||||
|
|
||||||
|
// transaction type must be pre auth & must be within 10 days.
|
||||||
|
if (payDetail.getTransactionType() == TransactionsType.PRE_AUTH_SALE.value && lastInputDay.compareTo(transDate) < 0) {
|
||||||
|
PayDetail newPay = transProcessViewModel.getPayDetail();
|
||||||
|
newPay.setReferNo(rrnNo);
|
||||||
|
|
||||||
|
if(newPay.getAmount() > payDetail.getAmount()) {
|
||||||
|
newPay.setTradeAnswerCode("C1"); // ---> refer to BaseErrorCode class// ,
|
||||||
|
newPay.setTransType(sharedViewModel.transactionsType.getValue().name);
|
||||||
|
transProcessViewModel.setPayDetail(newPay);
|
||||||
|
sharedViewModel.payDetail.setValue(newPay);
|
||||||
|
sharedViewModel.rrNNo.setValue(rrnNo);
|
||||||
|
|
||||||
|
callResultScreen();
|
||||||
|
} else {
|
||||||
|
transProcessViewModel.setOldTransPayDetail(payDetail);
|
||||||
|
transProcessViewModel.setPayDetail(newPay);
|
||||||
|
|
||||||
|
sharedViewModel.rrNNo.setValue(rrnNo);
|
||||||
|
|
||||||
|
callNextScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
transProcessViewModel.setPayDetail(newPay);
|
||||||
|
|
||||||
|
sharedViewModel.rrNNo.setValue(rrnNo);
|
||||||
|
|
||||||
|
callNextScreen();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_ref_no_not_found));
|
||||||
|
if (isECR) {
|
||||||
|
navigationECR();
|
||||||
|
} else {
|
||||||
|
routeId = R.id.action_inputRRNFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_ref_no_not_found));
|
||||||
|
if (isECR) {
|
||||||
|
navigationECR();
|
||||||
|
} else {
|
||||||
|
routeId = R.id.action_inputRRNFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refundProcessEmv(boolean isECR) {
|
||||||
|
PayDetail payDetail = emvTransactionProcessViewModel.getPayDetail();
|
||||||
|
payDetail.setReferNo(rrnNo);
|
||||||
|
|
||||||
|
|
||||||
|
emvTransactionProcessViewModel.setPayDetail(payDetail);
|
||||||
|
|
||||||
|
sharedViewModel.rrNNo.setValue(rrnNo);
|
||||||
|
|
||||||
|
callNextScreen();
|
||||||
|
}
|
||||||
|
private void checkRRNRefund(boolean isECR) {
|
||||||
|
|
||||||
|
/* 19/1/2024 Working Code! just commented for new requirements ! */
|
||||||
|
/* PayDetail payDetail = transProcessViewModel.getPayDetail();
|
||||||
|
payDetail.setReferNo(rrnNo);
|
||||||
|
|
||||||
|
|
||||||
|
transProcessViewModel.setPayDetail(payDetail);
|
||||||
|
|
||||||
|
sharedViewModel.rrNNo.setValue(rrnNo);
|
||||||
|
|
||||||
|
callNextScreen(); */
|
||||||
|
|
||||||
|
String configTimer = SystemParamsOperation.getInstance().getClearBatchTime();
|
||||||
|
String configTime;
|
||||||
|
|
||||||
|
if(configTimer != null && !configTimer.trim().isEmpty() && checkValidTime(configTimer.trim())) {
|
||||||
|
configTime = configTimer.trim();
|
||||||
|
} else {
|
||||||
|
configTime = "23:00";
|
||||||
|
}
|
||||||
|
|
||||||
|
rrnViewModel.searchPayDetail(cardNo,rrnNo).observe(getViewLifecycleOwner(), new Observer<PayDetail>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(PayDetail payDetail) {
|
||||||
|
if(payDetail != null) {
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"Trans Type:"+payDetail.getTransactionType());
|
||||||
|
|
||||||
|
if(payDetail.getTransactionType() != TransactionsType.SALE.value) {
|
||||||
|
terminatedTransRefund(isECR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String date = payDetail.getTransDate();
|
||||||
|
String time = payDetail.getTransTime();
|
||||||
|
|
||||||
|
if(checkRefund(configTime,date,time)) {
|
||||||
|
PayDetail newPay = transProcessViewModel.getPayDetail();
|
||||||
|
newPay.setReferNo(rrnNo);
|
||||||
|
|
||||||
|
transProcessViewModel.setOldTransPayDetail(payDetail);
|
||||||
|
transProcessViewModel.setPayDetail(newPay);
|
||||||
|
sharedViewModel.rrNNo.setValue(rrnNo);
|
||||||
|
|
||||||
|
|
||||||
|
callNextScreen();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
terminatedTransRefund(isECR);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
PayDetail newPay = transProcessViewModel.getPayDetail();
|
||||||
|
newPay.setReferNo(rrnNo);
|
||||||
|
|
||||||
|
transProcessViewModel.setPayDetail(newPay);
|
||||||
|
|
||||||
|
sharedViewModel.rrNNo.setValue(rrnNo);
|
||||||
|
|
||||||
|
callNextScreen();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void terminatedTransRefund(boolean isECR) {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_refund_not_allow));
|
||||||
|
if (isECR) {
|
||||||
|
navigationECR();
|
||||||
|
} else {
|
||||||
|
routeId = R.id.action_inputRRNFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
// safePopBack(currentId,hostId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkRefund(String configTime,String date,String time) {
|
||||||
|
Date yesterday = POSUtil.getInstance().getYesterdayConfigDateTime(configTime);
|
||||||
|
Date transDateTime = POSUtil.getInstance().getDateByTransDateTime(date,time);
|
||||||
|
|
||||||
|
Date configDate = POSUtil.getInstance().getDateTime(configTime);
|
||||||
|
|
||||||
|
Date transDate = POSUtil.getInstance().getDateByString(date);
|
||||||
|
Date today = POSUtil.getInstance().getCurrentDate();
|
||||||
|
|
||||||
|
Date current = new Date(System.currentTimeMillis());
|
||||||
|
|
||||||
|
System.out.println("Yesterday : "+yesterday.toString());
|
||||||
|
System.out.println("transDateTime : "+transDateTime.toString());
|
||||||
|
System.out.println("Compare : "+transDateTime.compareTo(yesterday));
|
||||||
|
if(transDate.compareTo(today) == 0 ) {
|
||||||
|
// trans is today
|
||||||
|
|
||||||
|
if(current.compareTo(configDate) > 0) {
|
||||||
|
System.out.println("Trans is today ! config time is passed yet! can do refund!");
|
||||||
|
return transDateTime.compareTo(configDate) < 0;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
System.out.println("Trans is today ! config time is not passed yet! can't do refund");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Date yest;
|
||||||
|
if(configTime.equals("00:00")) {
|
||||||
|
yest = configDate;
|
||||||
|
} else {
|
||||||
|
yest = yesterday;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Trans is Yesterday ! trans is before config time ! can do refund!");
|
||||||
|
return transDateTime.compareTo(yest) < 0; //false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void navigationECR() {
|
||||||
|
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(getResourceString(R.string.txt_rrn_not_match));
|
||||||
|
getNavController(Constants.NAV_HOST_ID).popBackStack();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
|
||||||
|
if (sharedViewModel.transactionsType.getValue() == TransactionsType.PRE_AUTH_VOID) {
|
||||||
|
|
||||||
|
sharedViewModel.traceNo.postValue(null);
|
||||||
|
sharedViewModel.rrNNo.postValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
rrnViewModel.inputRRNView.removeObservers(getViewLifecycleOwner());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isValidReferenceNo(String referNo) {
|
||||||
|
// Define a regular expression for a valid email address
|
||||||
|
String regex = "^[a-zA-Z0-9 \\\\t]{12}$";
|
||||||
|
Pattern pattern = Pattern.compile(regex);
|
||||||
|
Matcher matcher = pattern.matcher(referNo);
|
||||||
|
return matcher.matches();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateRRN(boolean isECR) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (isValidReferenceNo(rrnNo)) {
|
||||||
|
|
||||||
|
if (sharedViewModel.transactionsType.getValue() == TransactionsType.PRE_AUTH_VOID) {
|
||||||
|
|
||||||
|
checkRRNPreAuthVoid(isECR);
|
||||||
|
|
||||||
|
} else if (sharedViewModel.transactionsType.getValue() == TransactionsType.PRE_AUTH_COMPLETE) {
|
||||||
|
|
||||||
|
// checkRRNPreAuthComp(isECR);
|
||||||
|
preAuthCompProcess(isECR);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
refundProcessEmv(isECR);
|
||||||
|
} else {
|
||||||
|
checkRRNRefund(isECR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if(isECR)
|
||||||
|
navigationECR();
|
||||||
|
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_please_enter_correct_rrn));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
public void onCancel() {
|
||||||
|
|
||||||
|
routeId = R.id.action_inputRRNFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onConfirm() {
|
||||||
|
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
cardNo = emvTransactionProcessViewModel.cardNum.getValue();
|
||||||
|
} else {
|
||||||
|
cardNo = transProcessViewModel.getPayDetail().getCardNo();
|
||||||
|
}
|
||||||
|
|
||||||
|
rrnNo = rrnViewModel.txtRRN.getValue();
|
||||||
|
validateRRN(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,170 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.InputAmountViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.EmvTransactionProcessViewModel;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class InputTipAmountFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private InputAmountViewModel inputAmountViewModel;
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
private EmvTransactionProcessViewModel emvTransactionProcessViewModel;
|
||||||
|
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
inputAmountViewModel = getFragmentScopeViewModel(InputAmountViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
emvTransactionProcessViewModel = getFragmentScopeViewModel(EmvTransactionProcessViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_tip_amount_screen, BR.inputAmountVM,inputAmountViewModel)
|
||||||
|
.addBindingParam(BR.click,new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.inputTipAmountFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*May 16 2022*/
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithBackIcon(getResourceString(R.string.title_tip_amount));
|
||||||
|
|
||||||
|
if(sharedViewModel.isEcr.getValue() != null){
|
||||||
|
if(sharedViewModel.isEcr.getValue()){
|
||||||
|
|
||||||
|
delayFunctionCall(()->{
|
||||||
|
startTransactionProcess(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
inputAmountViewModel.inputAmountView.postValue("0.00");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void callNextScreen(){
|
||||||
|
routeId = R.id.action_inputTipAmountFragment_to_processingFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void startTransactionProcess(boolean isEcr) {
|
||||||
|
|
||||||
|
|
||||||
|
String amount = "";
|
||||||
|
|
||||||
|
if(isEcr) {
|
||||||
|
amount = sharedViewModel.amount.getValue();
|
||||||
|
} else {
|
||||||
|
amount = inputAmountViewModel.inputAmountView.getValue();
|
||||||
|
sharedViewModel.amount.setValue(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PayDetail payDetail = emvTransactionProcessViewModel.getPayDetail();
|
||||||
|
|
||||||
|
|
||||||
|
String processCode = sharedViewModel.processCode.getValue();
|
||||||
|
payDetail.setAmount(POSUtil.getInstance().convertAmount(amount));
|
||||||
|
if (!TextUtils.equals(processCode, "")) {
|
||||||
|
payDetail.setProcessCode(processCode);
|
||||||
|
}
|
||||||
|
emvTransactionProcessViewModel.setPayDetail(payDetail);
|
||||||
|
|
||||||
|
callNextScreen();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAmountValid() {
|
||||||
|
String amount = inputAmountViewModel.inputAmountView.getValue();
|
||||||
|
if (amount != null ) {
|
||||||
|
if(amount.contains(",")){
|
||||||
|
amount = amount.replace(",","");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
long amt = 0;
|
||||||
|
if(amount.contains(".")) {
|
||||||
|
amt = Long.parseLong(amount.substring(0,amount.length()-3));
|
||||||
|
} else {
|
||||||
|
amt = Long.parseLong(amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 100 is amount from TMS
|
||||||
|
|
||||||
|
return amt <= 100;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClickEvent{
|
||||||
|
|
||||||
|
public void onConfirm(){
|
||||||
|
|
||||||
|
if(isInputValid(Objects.requireNonNull(inputAmountViewModel.inputAmountView.getValue()))){
|
||||||
|
|
||||||
|
if(isAmountValid()) {
|
||||||
|
startTransactionProcess(false);
|
||||||
|
} else {
|
||||||
|
showSingleInfoDialog(getResourceString(R.string.txt_tip_amount_exceeded));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
showSingleInfoDialog(getResourceString(R.string.txt_please_input_amount));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCancel() {
|
||||||
|
popBackStack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,451 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.TimeoutCallback;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.TransMenu;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.EmvTransactionProcessViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.InputTraceViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.TransProcessViewModel;
|
||||||
|
import com.utsmm.kbz.ui.pre_auth.PreAuthVoidViewModel;
|
||||||
|
import com.utsmm.kbz.ui.sale_void.VoidViewModel;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.HostType;
|
||||||
|
import com.utsmm.kbz.util.enums.VoidStatus;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
public class InputTraceNoFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private static final String TAG = InputTraceNoFragment.class.getSimpleName();
|
||||||
|
private InputTraceViewModel traceViewModel;
|
||||||
|
private PreAuthVoidViewModel preAuthVoidViewModel;
|
||||||
|
private TransProcessViewModel transProcessViewModel;
|
||||||
|
|
||||||
|
private EmvTransactionProcessViewModel emvTransactionProcessViewModel;
|
||||||
|
private VoidViewModel voidViewModel;
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private boolean isContain = false;
|
||||||
|
private VoidStatus voidStatus = VoidStatus.NOT_FOUND;
|
||||||
|
private String traceNo = "";
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
ArrayList<PayDetail> payLists = new ArrayList<>();
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
traceViewModel = getFragmentScopeViewModel(InputTraceViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
preAuthVoidViewModel = getFragmentScopeViewModel(PreAuthVoidViewModel.class);
|
||||||
|
transProcessViewModel = getFragmentScopeViewModel(TransProcessViewModel.class);
|
||||||
|
voidViewModel = getFragmentScopeViewModel(VoidViewModel.class);
|
||||||
|
emvTransactionProcessViewModel = getFragmentScopeViewModel(EmvTransactionProcessViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_input_invoice_screen, BR.inputTraceViewModel, traceViewModel)
|
||||||
|
.addBindingParam(BR.sharedViewModel, sharedViewModel)
|
||||||
|
.addBindingParam(BR.voidViewModel, voidViewModel)
|
||||||
|
.addBindingParam(BR.transProcessViewModel, transProcessViewModel)
|
||||||
|
.addBindingParam(BR.click, new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.inputTraceFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
setUpTimer();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpTimer(){
|
||||||
|
setupTimeout(Constants.TIMEOUT, new TimeoutCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTrick(long trickTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
routeId = R.id.action_inputTraceFragment_to_timeoutFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
clearInputView();
|
||||||
|
|
||||||
|
setToolBarTitleWithBackIcon(getResourceString(R.string.title_trace_number));
|
||||||
|
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
/* init trace no from shared View model*/
|
||||||
|
traceNo = POSUtil.getInstance().formatTrace(Objects.requireNonNull(sharedViewModel.traceNo.getValue()));
|
||||||
|
|
||||||
|
delayFunctionCall(()->{
|
||||||
|
observeRouteId(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void voidProcess(boolean isEcr) {
|
||||||
|
int transType = 0;
|
||||||
|
|
||||||
|
if(sharedViewModel.getTransMenu().getValue() == TransMenu.VOID || sharedViewModel.getTransMenu().getValue() == TransMenu.TIP_ADJUSTMENT) {
|
||||||
|
transType = TransactionsType.SALE.value;
|
||||||
|
} else if(sharedViewModel.getTransMenu().getValue() == TransMenu.PRE_AUTH_COMPLETE_VOID) {
|
||||||
|
transType = TransactionsType.PRE_AUTH_COMPLETE.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String configTimer = SystemParamsOperation.getInstance().getClearBatchTime();
|
||||||
|
String configTime;
|
||||||
|
|
||||||
|
if(configTimer != null && !configTimer.trim().isEmpty() && checkValidTime(configTimer.trim())) {
|
||||||
|
configTime = configTimer.trim();
|
||||||
|
} else {
|
||||||
|
configTime = "23:00";
|
||||||
|
}
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"Input trace :"+traceNo);
|
||||||
|
|
||||||
|
// voidViewModel.getGenericVoidTransactions(transType,POSUtil.getInstance().formatTrace(traceNo),isEmv).observe(getViewLifecycleOwner(), new Observer<PayDetail>() {
|
||||||
|
voidViewModel.getVoidTrans(transType,POSUtil.getInstance().formatTrace(traceNo)).observe(getViewLifecycleOwner(), new Observer<PayDetail>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(PayDetail payDetail) {
|
||||||
|
|
||||||
|
if(payDetail != null) {
|
||||||
|
String date = payDetail.getTransDate();
|
||||||
|
String time = payDetail.getTransTime();
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"transactions trace :"+payDetail.getVoucherNo());
|
||||||
|
|
||||||
|
if(POSUtil.getInstance().checkVoid(configTime,date,time)) {
|
||||||
|
|
||||||
|
if(payDetail.getIsCanceled()) {
|
||||||
|
clearInputView();
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_trans_voided));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedViewModel.payDetail.setValue(payDetail);
|
||||||
|
|
||||||
|
if(sharedViewModel.hostType.getValue() == HostType.MPU) {
|
||||||
|
sharedViewModel.isEmv.setValue(false);
|
||||||
|
transProcessViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
transProcessViewModel.setOldTransPayDetail(payDetail);
|
||||||
|
transProcessViewModel.setPayDetail(payDetail);
|
||||||
|
} else {
|
||||||
|
sharedViewModel.isEmv.setValue(true);
|
||||||
|
emvTransactionProcessViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
emvTransactionProcessViewModel.setPayDetail(payDetail);
|
||||||
|
}
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (isEcr)
|
||||||
|
navigationECR();
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_void_not_found));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void preAuthVoidProcess(boolean isEcr) {
|
||||||
|
|
||||||
|
preAuthVoidViewModel.getVoidablePreAuth(traceNo).observe(getViewLifecycleOwner(), payDetail -> {
|
||||||
|
if (payDetail != null) {
|
||||||
|
|
||||||
|
if(payDetail.getIsCanceled()) {
|
||||||
|
clearInputView();
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_trans_voided));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sharedViewModel.payDetail.setValue(payDetail);
|
||||||
|
sharedViewModel.isEmv.setValue(true);
|
||||||
|
emvTransactionProcessViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
emvTransactionProcessViewModel.setPayDetail(payDetail);
|
||||||
|
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (isEcr) {
|
||||||
|
navigationECR();
|
||||||
|
}
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_void_not_found));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private void preAuthVoidAction(boolean isEcr) {
|
||||||
|
|
||||||
|
preAuthVoidViewModel.getVoidablePreAuth(traceNo).observe(getViewLifecycleOwner(), payDetail -> {
|
||||||
|
if (payDetail != null) {
|
||||||
|
|
||||||
|
traceViewModel.inputTraceView.postValue("");
|
||||||
|
sharedViewModel.payDetail.postValue(payDetail);
|
||||||
|
// route to Check card
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (isEcr) {
|
||||||
|
navigationECR();
|
||||||
|
}
|
||||||
|
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_trace_no_not_found));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void voidAction(boolean isEcr) {
|
||||||
|
|
||||||
|
int transType = 0;
|
||||||
|
|
||||||
|
if(sharedViewModel.getTransMenu().getValue() == TransMenu.VOID) {
|
||||||
|
transType = TransactionsType.SALE.value;
|
||||||
|
} else if(sharedViewModel.getTransMenu().getValue() == TransMenu.PRE_AUTH_COMPLETE_VOID) {
|
||||||
|
transType = TransactionsType.PRE_AUTH_COMPLETE.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
String configTimer = SystemParamsOperation.getInstance().getClearBatchTime();
|
||||||
|
String configTime;
|
||||||
|
|
||||||
|
if(configTimer != null && !configTimer.trim().isEmpty() && checkValidTime(configTimer.trim())) {
|
||||||
|
configTime = configTimer.trim();
|
||||||
|
} else {
|
||||||
|
configTime = "23:00";
|
||||||
|
}
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"Input trace :"+traceNo);
|
||||||
|
|
||||||
|
voidViewModel.getVoidTransactions(transType).observe(getViewLifecycleOwner(), payDetails -> {
|
||||||
|
if (payDetails != null) {
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"first list size :"+payDetails.size());
|
||||||
|
|
||||||
|
if(!payDetails.isEmpty()){
|
||||||
|
payLists.addAll(payDetails);
|
||||||
|
}
|
||||||
|
LogUtil.d(TAG,"second list size :"+payLists.size());
|
||||||
|
voidStatus = VoidStatus.NOT_FOUND;
|
||||||
|
|
||||||
|
for (PayDetail payDetail : payLists) {
|
||||||
|
|
||||||
|
String date = payDetail.getTransDate();
|
||||||
|
String time = payDetail.getTransTime();
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"transactions trace :"+payDetail.getVoucherNo());
|
||||||
|
if ( payDetail.getVoucherNo().equals(POSUtil.getInstance().formatTrace(traceNo))) {
|
||||||
|
|
||||||
|
if(POSUtil.getInstance().checkVoid(configTime,date,time)) {
|
||||||
|
|
||||||
|
if(payDetail.getIsCanceled()) {
|
||||||
|
voidStatus = VoidStatus.ALREADY_VOIDED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
isContain = true;
|
||||||
|
voidStatus = VoidStatus.OK;
|
||||||
|
|
||||||
|
sharedViewModel.payDetail.postValue(payDetail);
|
||||||
|
|
||||||
|
if(sharedViewModel.hostType.getValue() == HostType.MPU) {
|
||||||
|
sharedViewModel.isEmv.setValue(false);
|
||||||
|
transProcessViewModel.transType.postValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
transProcessViewModel.setOldTransPayDetail(payDetail);
|
||||||
|
transProcessViewModel.setPayDetail(payDetail);
|
||||||
|
} else {
|
||||||
|
sharedViewModel.isEmv.setValue(true);
|
||||||
|
emvTransactionProcessViewModel.transType.postValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
emvTransactionProcessViewModel.setPayDetail(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEcr)
|
||||||
|
navigationECR();
|
||||||
|
else {
|
||||||
|
clearInputView();
|
||||||
|
if (voidStatus == VoidStatus.ALREADY_VOIDED) {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_trans_voided));
|
||||||
|
} else {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_void_not_found));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (isEcr)
|
||||||
|
navigationECR();
|
||||||
|
else {
|
||||||
|
clearInputView();
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_void_not_found));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void reviewTransAction() {
|
||||||
|
voidViewModel.searchTransaction(traceNo).observe(getViewLifecycleOwner(), payDetail -> {
|
||||||
|
if (payDetail != null) {
|
||||||
|
traceViewModel.inputTraceView.postValue("");
|
||||||
|
sharedViewModel.payDetail.postValue(payDetail);
|
||||||
|
// route to Check card
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
} else {
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_trace_no_not_found));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigationECR() {
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(getResourceString(R.string.txt_void_not_found));
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_void_not_found));
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
routeId = R.id.action_inputTraceFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearInputView() {
|
||||||
|
traceViewModel.invoiceNo.setValue("");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void observeRouteId(boolean isEcr) {
|
||||||
|
switch (Objects.requireNonNull(sharedViewModel.transactionsType.getValue())) {
|
||||||
|
case TIP_ADJUSTMENT:
|
||||||
|
case VOID:
|
||||||
|
case PRE_AUTH_COMPLETE_VOID:
|
||||||
|
// sharedViewModel.transMenu.postValue(TransMenu.TRANSACTIONS);
|
||||||
|
routeId = R.id.action_inputTraceFragment_to_confirmTransactionFragment;
|
||||||
|
if (!TextUtils.equals(traceNo, "")) {
|
||||||
|
|
||||||
|
// voidAction(isEcr);
|
||||||
|
voidProcess(isEcr);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_empty_trace_no));
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PRE_AUTH_VOID:
|
||||||
|
routeId = R.id.action_inputTraceFragment_to_confirmTransactionFragment;
|
||||||
|
// routeId = R.id.action_inputTraceFragment_to_cardWaitingFragment;
|
||||||
|
if (!TextUtils.equals(traceNo, "")) {
|
||||||
|
|
||||||
|
preAuthVoidProcess(isEcr);
|
||||||
|
// preAuthVoidAction(isEcr);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_empty_trace_no));
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case REVIEW_TRANS:
|
||||||
|
routeId = R.id.action_inputTraceFragment_to_confirmTransactionFragment;
|
||||||
|
if (!TextUtils.equals(traceNo, "")) {
|
||||||
|
|
||||||
|
reviewTransAction();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
showDeclineDialog(getResourceString(R.string.txt_empty_trace_no));
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
public void onCancel() {
|
||||||
|
|
||||||
|
|
||||||
|
routeId = R.id.action_inputTraceFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onConfirm() {
|
||||||
|
traceNo = POSUtil.getInstance().formatTrace(Objects.requireNonNull(traceViewModel.invoiceNo.getValue()));
|
||||||
|
clearInputView();
|
||||||
|
observeRouteId(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,284 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.CardDetectCallback;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.DialogCallback;
|
||||||
|
import com.utsmyanmar.paylibs.Constant;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.print.PaperRollStatusCallback;
|
||||||
|
import com.utsmyanmar.paylibs.print.PrintHelper;
|
||||||
|
import com.utsmyanmar.paylibs.print.PrintReceipt;
|
||||||
|
import com.utsmyanmar.paylibs.utils.PrintStatus;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
|
||||||
|
public class PrintReceiptFragment extends DataBindingFragment implements DataBindingFragment.BackPressCallback {
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private static final String TAG = PrintReceipt.class.getSimpleName();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.printReceiptFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return R.id.action_printReceiptFragment_to_nav_main;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* check TMS parameter here
|
||||||
|
* if this device is ECR or contain some parameter
|
||||||
|
* skip this screen immediately
|
||||||
|
* */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* send e-receipt to portal
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
// navigateNextScreen();
|
||||||
|
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.title_print_receipt));
|
||||||
|
|
||||||
|
sharedViewModel.printReceiptButtons.setValue(0);
|
||||||
|
|
||||||
|
|
||||||
|
PayDetail payDetail = sharedViewModel.payDetail.getValue();
|
||||||
|
|
||||||
|
if(payDetail != null && !payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_APPROVED) && !payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_ACCEPT) && sharedViewModel.transactionsType.getValue() != TransactionsType.MMQR && sharedViewModel.transactionsType.getValue() != TransactionsType.MMQR_REFUND && sharedViewModel.transactionsType.getValue() != TransactionsType.MMQR_INQUIRY_STATUS) {
|
||||||
|
|
||||||
|
navigateNextScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
sharedViewModel.isReprint.postValue(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void isCardInside() {
|
||||||
|
|
||||||
|
isCardInserted(new CardDetectCallback() {
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
delayFunctionCall(()->{
|
||||||
|
|
||||||
|
navigateNextScreen();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_print_receipt_screen, BR.sharedViewModel, sharedViewModel)
|
||||||
|
.addBindingParam(BR.click, new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
sharedViewModel.setPrintStatus(PrintStatus.FIRST_PRINT);
|
||||||
|
|
||||||
|
observePrintProcess();
|
||||||
|
|
||||||
|
setBackPressCallback(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void observePrintProcess() {
|
||||||
|
sharedViewModel.getPrintStatus().observe(this, new Observer<PrintStatus>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(PrintStatus printStatus) {
|
||||||
|
switch(printStatus) {
|
||||||
|
case FIRST_PRINT:
|
||||||
|
sharedViewModel.postPrintReceiptMsg("Printing Receipt for Merchant");
|
||||||
|
startPrintProcess(true);
|
||||||
|
break;
|
||||||
|
case FIRST_PRINT_DONE:
|
||||||
|
sharedViewModel.postPrintReceiptMsg("Confirm Print Receipt for Customer");
|
||||||
|
if(sharedViewModel.isEcr.getValue() != null &&
|
||||||
|
sharedViewModel.isEcr.getValue() &&
|
||||||
|
SystemParamsOperation.getInstance().isAutoPrintCustomerCopy()) {
|
||||||
|
sharedViewModel.setVisibilityPrintReceiptButtons(8);
|
||||||
|
sharedViewModel.setPrintStatus(PrintStatus.SECOND_PRINT);
|
||||||
|
} else {
|
||||||
|
sharedViewModel.setVisibilityPrintReceiptButtons(0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SECOND_PRINT:
|
||||||
|
sharedViewModel.postPrintReceiptMsg("Printing Receipt for Customer");
|
||||||
|
startPrintProcess(false);
|
||||||
|
break;
|
||||||
|
case SECOND_PRINT_DONE:
|
||||||
|
isCardInside();
|
||||||
|
break;
|
||||||
|
case EMPTY_PAPER_ROLL_FIRST:
|
||||||
|
handleEmptyPaperRoll(true);
|
||||||
|
break;
|
||||||
|
case EMPTY_PAPER_ROLL_SECOND:
|
||||||
|
handleEmptyPaperRoll(false);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void startPrintProcess(boolean isFirstPrint) {
|
||||||
|
|
||||||
|
PrintHelper.getInstance().checkPaperRollStatus(new PaperRollStatusCallback() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printerReady() {
|
||||||
|
sharedViewModel.startPrintReceipt(isFirstPrint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paperRollIsEmpty() {
|
||||||
|
handleEmptyPaperRoll(isFirstPrint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printNotComplete() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printerTooHot() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printerFailed() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unknownStatusOccur(int code) {
|
||||||
|
// showDeclineDialog("Check Printer Status : "+code);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleEmptyPaperRoll(boolean isFirstPrint) {
|
||||||
|
sharedViewModel.printReceiptButtons.setValue(0);
|
||||||
|
sharedViewModel.printReceiptMsg.setValue(getResourceString(R.string.txt_print_receipt_failed));
|
||||||
|
|
||||||
|
showPrinterAlertDialog(getResourceString(R.string.txt_printing_paper_not_ready), new DialogCallback() {
|
||||||
|
@Override
|
||||||
|
public void onClickCancel() {
|
||||||
|
dismissPrinterAlertDialog();
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onClickRetry() {
|
||||||
|
sharedViewModel.startPrintReceipt(isFirstPrint);
|
||||||
|
dismissPrinterAlertDialog();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(SystemParamsOperation.getInstance().isAlertSound()) {
|
||||||
|
startSound(getResourceString(R.string.txt_audio_printer_alert));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
private void navigateNextScreen() {
|
||||||
|
if(sharedViewModel.isReprint.getValue()) {
|
||||||
|
safePopBackStack();
|
||||||
|
} else {
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPress() {
|
||||||
|
sharedViewModel.printReceiptButtons.setValue(8);
|
||||||
|
isCardInside();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
public void onConfirm() {
|
||||||
|
|
||||||
|
sharedViewModel.setVisibilityPrintReceiptButtons(8);
|
||||||
|
|
||||||
|
sharedViewModel.setPrintStatus(PrintStatus.SECOND_PRINT);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onCancel() {
|
||||||
|
sharedViewModel.setVisibilityPrintReceiptButtons(8);
|
||||||
|
isCardInside();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void alertPaperRoll(String title, String message) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
|
||||||
|
builder.setTitle(title)
|
||||||
|
.setMessage(message)
|
||||||
|
.setNegativeButton(getResourceString(R.string.txt_print_later), (dialog, which) -> {
|
||||||
|
|
||||||
|
dialog.dismiss();
|
||||||
|
|
||||||
|
})
|
||||||
|
.setPositiveButton(getResourceString(R.string.txt_retry_now), (dialog, which) -> {
|
||||||
|
|
||||||
|
sharedViewModel.startPrintProcess();
|
||||||
|
|
||||||
|
})
|
||||||
|
.setCancelable(false)
|
||||||
|
.create();
|
||||||
|
|
||||||
|
builder.show();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,276 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.utsmm.kbz.util.MockData;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.checkxread.model.CardDataX;
|
||||||
|
import com.utsmyanmar.checkxread.readcard.MAGXReadCard;
|
||||||
|
import com.utsmyanmar.checkxread.readcard.MPUXReadCard;
|
||||||
|
import com.utsmyanmar.checkxread.readcard.ReadCardResultX;
|
||||||
|
import com.utsmyanmar.checkxread.util.CardTypeX;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.model.TradeData;
|
||||||
|
import com.utsmyanmar.paylibs.model.enums.TransCVM;
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.TransMenu;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmyanmar.paylibs.utils.params.Params;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.CardReadViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.EmvTransactionProcessViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.TransProcessViewModel;
|
||||||
|
import com.utsmm.kbz.ui.pinpad.PinPadViewModel;
|
||||||
|
import com.utsmm.kbz.util.TransactionUtil;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
public class ProcessingCardFragment extends DataBindingFragment {
|
||||||
|
private static final String TAG = ProcessingCardFragment.class.getSimpleName();
|
||||||
|
private CardReadViewModel cardReadViewModel;
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private TransProcessViewModel transProcessViewModel;
|
||||||
|
private PinPadViewModel pinPadViewModel;
|
||||||
|
private EmvTransactionProcessViewModel emvTransactionViewModel;
|
||||||
|
|
||||||
|
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
cardReadViewModel = getFragmentScopeViewModel(CardReadViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
transProcessViewModel = getFragmentScopeViewModel(TransProcessViewModel.class);
|
||||||
|
pinPadViewModel = getFragmentScopeViewModel(PinPadViewModel.class);
|
||||||
|
emvTransactionViewModel = getFragmentScopeViewModel(EmvTransactionProcessViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_processing_card_screen, BR.cardReadViewModel, cardReadViewModel)
|
||||||
|
.addBindingParam(BR.sharedViewModel, sharedViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.processingCardFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
resetEmvTransResult();
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.title_processing_card));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetEmvTransResult() {
|
||||||
|
emvTransactionViewModel.resetTransactionStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
checkCardTransactionType();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkCardTransactionType() {
|
||||||
|
switch (cardReadViewModel.getCardTransactionType()) {
|
||||||
|
case MPU: readMPUCard();
|
||||||
|
break;
|
||||||
|
case EMV: handlePreEmvProcess();
|
||||||
|
break;
|
||||||
|
case FALLBACK: readMAGStripe(true,true);
|
||||||
|
break;
|
||||||
|
case MAG: readMAGStripe(false,true);
|
||||||
|
break;
|
||||||
|
case MOCK: mockMPUCard();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void mockMPUCard() {
|
||||||
|
LogUtil.d(TAG,"initialize mock card data...");
|
||||||
|
routeId = R.id.action_processingCardFragment_to_pinPadFragment;
|
||||||
|
transProcessViewModel.transType.postValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
pinPadViewModel.transType.postValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
|
||||||
|
CardDataX cardDataX = MockData.getInstance().generateMPUCard();
|
||||||
|
|
||||||
|
TradeData tradeData = TransactionUtil.getInstance().initMPUTransaction(cardDataX, CardTypeX.IC);
|
||||||
|
transProcessViewModel.setTradeData(tradeData);
|
||||||
|
pinPadViewModel.setTradeData(tradeData);
|
||||||
|
sharedViewModel.setCardDataExist(true);
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readMPUCard() {
|
||||||
|
cardReadViewModel.startReadXProcess(MPUXReadCard.getInstance(), new ReadCardResultX() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(CardDataX cardDataX) {
|
||||||
|
|
||||||
|
routeId = R.id.action_processingCardFragment_to_pinPadFragment;
|
||||||
|
transProcessViewModel.transType.postValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
pinPadViewModel.transType.postValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
|
||||||
|
TradeData tradeData = TransactionUtil.getInstance().initMPUTransaction(cardDataX, CardTypeX.IC);
|
||||||
|
transProcessViewModel.setTradeData(tradeData);
|
||||||
|
pinPadViewModel.setTradeData(tradeData);
|
||||||
|
|
||||||
|
if(sharedViewModel.getTransMenu().getValue() == TransMenu.PRE_AUTH_PARTIAL_VOID ) {
|
||||||
|
|
||||||
|
sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_function_not_supported));
|
||||||
|
routeId = R.id.action_processingCardFragment_to_errorFragment;
|
||||||
|
|
||||||
|
}
|
||||||
|
// else if(sharedViewModel.transactionsType.getValue() == TransactionsType.REFUND) {
|
||||||
|
// sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_card_not_supported));
|
||||||
|
// routeId = R.id.action_processingCardFragment_to_errorFragment;
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
sharedViewModel.setCardDataExist(true);
|
||||||
|
|
||||||
|
if(sharedViewModel.getAmountExist().getValue() != null && !sharedViewModel.getAmountExist().getValue()) {
|
||||||
|
routeId = R.id.action_processingCardFragment_to_inputAmountFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(int code, String message) {
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"Failure at "+code+" message: "+message);
|
||||||
|
// need to go back and ask card again!!!
|
||||||
|
showDeclineDialogAutoHide("FAILURE :"+message);
|
||||||
|
sharedViewModel.setCardDataExist(false);
|
||||||
|
safePopBackStack();
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void readMAGStripe(boolean isFallback,boolean isNeedPin) {
|
||||||
|
cardReadViewModel.startReadXProcess(MAGXReadCard.getInstance(), new ReadCardResultX() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(CardDataX cardDataX) {
|
||||||
|
sharedViewModel.isEmv.setValue(false);
|
||||||
|
if(isNeedPin) {
|
||||||
|
// pin required scenario
|
||||||
|
|
||||||
|
routeId = R.id.action_processingCardFragment_to_pinPadFragment;
|
||||||
|
transProcessViewModel.transType.postValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
pinPadViewModel.transType.postValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
|
||||||
|
/* need to check card scheme according to card number --!^--- check below function*/
|
||||||
|
TradeData tradeData = TransactionUtil.getInstance().initMagStripeTransaction(cardDataX,isFallback);
|
||||||
|
transProcessViewModel.setTradeData(tradeData);
|
||||||
|
pinPadViewModel.setTradeData(tradeData);
|
||||||
|
} else {
|
||||||
|
// pin not required scenario
|
||||||
|
routeId = R.id.action_processingCardFragment_to_processingFragment;
|
||||||
|
transProcessViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
TradeData tradeData = TransactionUtil.getInstance().initMagStripeTransaction(cardDataX,isFallback);
|
||||||
|
String processCode = sharedViewModel.processCode.getValue();
|
||||||
|
String amount = sharedViewModel.amount.getValue();
|
||||||
|
PayDetail payDetail = tradeData.getPayDetail();
|
||||||
|
payDetail.setAmount(POSUtil.getInstance().convertAmount(amount));
|
||||||
|
|
||||||
|
if (!TextUtils.equals(processCode,"")) {
|
||||||
|
payDetail.setProcessCode(processCode);
|
||||||
|
}
|
||||||
|
payDetail.setTransCVM(TransCVM.SIGNATURE);
|
||||||
|
transProcessViewModel.setTradeData(tradeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(sharedViewModel.getTransMenu().getValue() == TransMenu.PRE_AUTH_PARTIAL_VOID ) {
|
||||||
|
// sharedViewModel.transMenu.postValue(null);
|
||||||
|
sharedViewModel.setTransMenu(null);
|
||||||
|
routeId = R.id.action_processingCardFragment_to_errorFragment;
|
||||||
|
}
|
||||||
|
// else if(sharedViewModel.transactionsType.getValue() == TransactionsType.REFUND) {
|
||||||
|
// routeId = R.id.action_processingCardFragment_to_errorFragment;
|
||||||
|
// }
|
||||||
|
|
||||||
|
sharedViewModel.setCardDataExist(true);
|
||||||
|
|
||||||
|
if(sharedViewModel.getTransMenu().getValue() != TransMenu.PRE_AUTH_FULL_VOID && sharedViewModel.getAmountExist().getValue() != null && !sharedViewModel.getAmountExist().getValue()) {
|
||||||
|
routeId = R.id.action_processingCardFragment_to_inputAmountFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(int code, String message) {
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"Failure at "+code+" message: "+message);
|
||||||
|
// need to go back and ask card again!!!
|
||||||
|
showDeclineDialogAutoHide("FAILURE :"+message);
|
||||||
|
safePopBackStack();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handlePreEmvProcess() {
|
||||||
|
|
||||||
|
emvTransactionViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
|
||||||
|
|
||||||
|
if (SystemParamsOperation.getInstance().isEmvEnabled()) {
|
||||||
|
prepareEmvTransaction();
|
||||||
|
routeId = R.id.action_processingCardFragment_to_emvTransactionFragment;
|
||||||
|
} else {
|
||||||
|
routeId = R.id.action_processingCardFragment_to_errorFragment;
|
||||||
|
sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_please_enable_emv));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if(sharedViewModel.transactionsType.getValue() == TransactionsType.REFUND) {
|
||||||
|
// sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_card_not_supported));
|
||||||
|
// routeId = R.id.action_processingCardFragment_to_errorFragment;
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNormalTransactionType() {
|
||||||
|
|
||||||
|
return (sharedViewModel.transactionsType.getValue() == TransactionsType.SALE || sharedViewModel.transactionsType.getValue() == TransactionsType.CASH_OUT || sharedViewModel.transactionsType.getValue() == TransactionsType.PRE_AUTH_SALE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareEmvTransaction() {
|
||||||
|
sharedViewModel.isEmv.postValue(true);
|
||||||
|
cardReadViewModel.cardTypeData.observe(getViewLifecycleOwner(), cardType -> {
|
||||||
|
TradeData tradeData = Params.newTrade(false);
|
||||||
|
PayDetail payDetail = tradeData.getPayDetail();
|
||||||
|
|
||||||
|
payDetail.setCardType(cardType);
|
||||||
|
emvTransactionViewModel.setTradeData(tradeData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,368 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.navigation.NavController;
|
||||||
|
import androidx.navigation.NavDestination;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.TimeoutCallback;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.EmvTransactionProcessViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.TransProcessViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.transactions.ProcessingTransaction;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
public class ProcessingFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private static final String TAG = ProcessingFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private TransProcessViewModel transProcessViewModel;
|
||||||
|
private EmvTransactionProcessViewModel emvTransactionProcessViewModel;
|
||||||
|
private int routeId;
|
||||||
|
private String ecrErrorMsg = "";
|
||||||
|
|
||||||
|
private final NavController.OnDestinationChangedListener listener = new NavController.OnDestinationChangedListener() {
|
||||||
|
@Override
|
||||||
|
public void onDestinationChanged(@NonNull NavController controller, @NonNull NavDestination destination, @Nullable Bundle arguments) {
|
||||||
|
if (destination.getId() == R.id.nav_main) {
|
||||||
|
|
||||||
|
emvTransactionProcessViewModel.onCancelEmvTransaction();
|
||||||
|
ecrActionCancel(ecrErrorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
transProcessViewModel = getFragmentScopeViewModel(TransProcessViewModel.class);
|
||||||
|
emvTransactionProcessViewModel = getFragmentScopeViewModel(EmvTransactionProcessViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_processing_screen, BR.sharedViewModel,sharedViewModel)
|
||||||
|
.addBindingParam(BR.emvTransViewModel,emvTransactionProcessViewModel)
|
||||||
|
.addBindingParam(BR.transViewModel,transProcessViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.processingFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
// Added timer 3 minutes while connecting to server -- 30/01/2024
|
||||||
|
setUpTimer();
|
||||||
|
|
||||||
|
if(sharedViewModel.isEmv.getValue() != null && sharedViewModel.isEmv.getValue()) {
|
||||||
|
observeData(emvTransactionProcessViewModel);
|
||||||
|
} else {
|
||||||
|
observeData(transProcessViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.title_processing));
|
||||||
|
|
||||||
|
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
startTransactionProcess(emvTransactionProcessViewModel);
|
||||||
|
} else {
|
||||||
|
startTransactionProcess(transProcessViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedViewModel.loadingMsg(getResourceString(R.string.txt_sending));
|
||||||
|
|
||||||
|
// disableNavigationBar();
|
||||||
|
|
||||||
|
getNavController(Constants.NAV_HOST_ID).addOnDestinationChangedListener(listener);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isEmvTrans() {
|
||||||
|
return sharedViewModel.isEmv.getValue() != null && sharedViewModel.isEmv.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startTransactionProcess(ProcessingTransaction processingTransaction) {
|
||||||
|
if(SystemParamsOperation.getInstance().getDemoStatus()) {
|
||||||
|
processingTransaction.startDemoProcess();
|
||||||
|
} else {
|
||||||
|
processingTransaction.startOnlineProcess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
updateData();
|
||||||
|
resetEmvResult();
|
||||||
|
// enableNavigationBar();
|
||||||
|
clearPayDetail();
|
||||||
|
getNavController(Constants.NAV_HOST_ID).removeOnDestinationChangedListener(listener);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetEmvResult() {
|
||||||
|
emvTransactionProcessViewModel.resetTransactionStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clearPayDetail() {
|
||||||
|
emvTransactionProcessViewModel.payDetailResult.setValue(null);
|
||||||
|
transProcessViewModel.payDetailResult.setValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpTimer(){
|
||||||
|
setupTimeout(Constants.PROCESSING_TIMEOUT, new TimeoutCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTrick(long trickTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
callMainScreen();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateData(){
|
||||||
|
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
LogUtil.d(TAG,"Updated sharedViewmodel payDetail for emv");
|
||||||
|
sharedViewModel.payDetail.setValue(emvTransactionProcessViewModel.payDetailResult.getValue());
|
||||||
|
} else {
|
||||||
|
LogUtil.d(TAG,"Updated sharedViewmodel payDetail for non emv");
|
||||||
|
sharedViewModel.payDetail.setValue(transProcessViewModel.payDetailResult.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// transProcessViewModel.payDetailResult.observe(getViewLifecycleOwner(), payDetail -> sharedViewModel.payDetail.postValue(payDetail));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void callNextScreen(){
|
||||||
|
updateData();
|
||||||
|
if (requiresSignature()) {
|
||||||
|
routeId = R.id.action_processingFragment_to_signatureFragment;
|
||||||
|
} else {
|
||||||
|
routeId = R.id.action_processingFragment_to_transactionResultFragment;
|
||||||
|
}
|
||||||
|
// delayFunctionCall(this::safeNavigateToRouteId,500);
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean requiresSignature() {
|
||||||
|
// Check if signature is required based on transaction details
|
||||||
|
PayDetail payDetail = sharedViewModel.payDetail.getValue();
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
LogUtil.d(TAG,"Updated sharedViewmodel payDetail for emv");
|
||||||
|
payDetail = emvTransactionProcessViewModel.payDetailResult.getValue();
|
||||||
|
} else {
|
||||||
|
LogUtil.d(TAG,"Updated sharedViewmodel payDetail for non emv");
|
||||||
|
payDetail = transProcessViewModel.payDetailResult.getValue();
|
||||||
|
}
|
||||||
|
if (payDetail == null) {
|
||||||
|
LogUtil.d(TAG,"Paydetail is null");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"tradeAnswerCode: "+payDetail.getTradeAnswerCode());
|
||||||
|
|
||||||
|
// For now, let's check if it's a card transaction and successful
|
||||||
|
boolean isSuccessful = "00".equals(payDetail.getTradeAnswerCode());
|
||||||
|
|
||||||
|
// You can customize this logic based on your business requirements
|
||||||
|
return isSuccessful && !isEmvTrans(); // Require signature for successful non-EMV transactions
|
||||||
|
}
|
||||||
|
|
||||||
|
private void callMainScreen(){
|
||||||
|
routeId = R.id.action_processingFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void observeErrorMsg(){
|
||||||
|
|
||||||
|
transProcessViewModel.errorMessage.observe(getViewLifecycleOwner(), msg -> {
|
||||||
|
showDeclineDialog(msg);
|
||||||
|
ecrActionCancel(msg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ecrActionCancel(String msg) {
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null && sharedViewModel.isEcr.getValue()) {
|
||||||
|
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(msg);
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
emvTransactionProcessViewModel.onCancelEmvTransaction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void navigateToError() {
|
||||||
|
routeId = R.id.action_processingFragment_to_errorFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToSuccess() {
|
||||||
|
routeId = R.id.action_processingFragment_to_successFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void observeData(ProcessingTransaction processingTransaction) {
|
||||||
|
|
||||||
|
processingTransaction.getTransStatus().observe(getViewLifecycleOwner(), transResultStatus -> {
|
||||||
|
LogUtil.d(TAG,"Transaction RESULT :"+transResultStatus);
|
||||||
|
switch (transResultStatus) {
|
||||||
|
case FAIL:
|
||||||
|
case SUCCESS:
|
||||||
|
case OFFLINE_SUCCESS:
|
||||||
|
if(SystemParamsOperation.getInstance().getDemoStatus()) {
|
||||||
|
delayFunctionCall(()->{
|
||||||
|
// updateData();
|
||||||
|
sharedViewModel.dismissLoadingMsg();
|
||||||
|
callNextScreen();
|
||||||
|
},1500);
|
||||||
|
} else {
|
||||||
|
// updateData();
|
||||||
|
sharedViewModel.dismissLoadingMsg();
|
||||||
|
callNextScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case OFFLINE_FAILURE:
|
||||||
|
sharedViewModel.dismissLoadingMsg();
|
||||||
|
sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_offline_failure));
|
||||||
|
navigateToError();
|
||||||
|
break;
|
||||||
|
case REVERSAL_FAIL:
|
||||||
|
// updateData();
|
||||||
|
sharedViewModel.dismissLoadingMsg();
|
||||||
|
sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_reversal_failed));
|
||||||
|
navigateToError();
|
||||||
|
break;
|
||||||
|
case SECONDARY:
|
||||||
|
// sharedViewModel.dismissLoadingMsg();
|
||||||
|
sharedViewModel.loadingMsg(getResourceString(R.string.txt_sending_secondary));
|
||||||
|
break;
|
||||||
|
case REVERSAL_PREPARE:
|
||||||
|
sharedViewModel.dismissLoadingMsg();
|
||||||
|
sharedViewModel.loadingMsg(getResourceString(R.string.txt_prepare_reversal));
|
||||||
|
break;
|
||||||
|
case REVERSAL_PROCESS:
|
||||||
|
sharedViewModel.dismissLoadingMsg();
|
||||||
|
sharedViewModel.loadingMsg(getResourceString(R.string.txt_sending_reversal));
|
||||||
|
break;
|
||||||
|
case REVERSAL_SECONDARY:
|
||||||
|
sharedViewModel.dismissLoadingMsg();
|
||||||
|
sharedViewModel.loadingMsg(getResourceString(R.string.txt_sending_secondary_reversal));
|
||||||
|
break;
|
||||||
|
case REVERSAL_THIRD:
|
||||||
|
sharedViewModel.dismissLoadingMsg();
|
||||||
|
sharedViewModel.loadingMsg(getResourceString(R.string.txt_sending_third_reversal));
|
||||||
|
break;
|
||||||
|
case REVERSAL_SUCCESS:
|
||||||
|
// updateData();
|
||||||
|
sharedViewModel.dismissLoadingMsg();
|
||||||
|
ecrActionCancel(getResourceString(R.string.txt_reversal_success));
|
||||||
|
sharedViewModel.set_successFragmentMsg(getResourceString(R.string.txt_reversal_success));
|
||||||
|
navigateToSuccess();
|
||||||
|
// showSuccessDialog(getResourceString(R.string.txt_reversal_success));
|
||||||
|
// ecrActionCancel(getResourceString(R.string.txt_reversal_success));
|
||||||
|
// callMainScreen();
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
// updateData();
|
||||||
|
sharedViewModel.dismissLoadingMsg();
|
||||||
|
observeErrorMsg();
|
||||||
|
callMainScreen();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
sharedViewModel.dismissLoadingMsg();
|
||||||
|
ecrActionCancel("Reason - "+transResultStatus);
|
||||||
|
if(isEmvTrans()) {
|
||||||
|
observeEmvErrorCode();
|
||||||
|
} else {
|
||||||
|
showDeclineDialog("Reason - "+transResultStatus);
|
||||||
|
callMainScreen();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void observeEmvErrorCode() {
|
||||||
|
|
||||||
|
emvTransactionProcessViewModel.errorCodeMsg.observe(getViewLifecycleOwner(), pair -> {
|
||||||
|
LogUtil.e(TAG,"ERROR CODE MSG :"+pair);
|
||||||
|
if(!TextUtils.equals(pair,"")) {
|
||||||
|
if(pair.contains(":")){
|
||||||
|
String code = pair.split(":")[0];
|
||||||
|
String msg = pair.split(":")[1];
|
||||||
|
|
||||||
|
if(TextUtils.equals(code,"-4100") || TextUtils.equals(code,"-4125")){
|
||||||
|
sharedViewModel.set_errorFragmentMsg("Card read failed!");
|
||||||
|
}else{
|
||||||
|
// showInfoDialog(code,msg);
|
||||||
|
sharedViewModel.set_errorFragmentMsg(code+"\n"+msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
ecrErrorMsg = msg;
|
||||||
|
|
||||||
|
}else{
|
||||||
|
|
||||||
|
ecrErrorMsg = pair;
|
||||||
|
|
||||||
|
sharedViewModel.set_errorFragmentMsg(pair);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
sharedViewModel.set_errorFragmentMsg("Emv process timeout!");
|
||||||
|
ecrErrorMsg = "Emv process timeout!";
|
||||||
|
|
||||||
|
}
|
||||||
|
navigateToError();
|
||||||
|
// navigateToMain();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
128
app/src/main/java/com/utsmm/kbz/ui/core_ui/ReceiptFragment.java
Normal file
128
app/src/main/java/com/utsmm/kbz/ui/core_ui/ReceiptFragment.java
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.github.gcacace.signaturepad.BR;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.ui.POSReceiptView;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class ReceiptFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private POSReceiptView.ReceiptData currentReceiptData;
|
||||||
|
private POSReceiptView receiptView;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_receipt_screen, BR.sharedViewModel,sharedViewModel)
|
||||||
|
.addBindingParam(BR.click, new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.menu_receipt));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.receiptFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return R.id.action_receiptFragment_to_nav_main;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
receiptView = mBinding.getRoot().findViewById(R.id.receiptView);
|
||||||
|
generateReceipt();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateReceipt() {
|
||||||
|
try {
|
||||||
|
// Create sample receipt data
|
||||||
|
currentReceiptData = createSampleReceiptData();
|
||||||
|
|
||||||
|
// Set the data to the receipt view
|
||||||
|
receiptView.setReceiptData(currentReceiptData);
|
||||||
|
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Toast.makeText(getContext(), "Failed to generate receipt: " + e.getMessage(),
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private POSReceiptView.ReceiptData createSampleReceiptData() {
|
||||||
|
POSReceiptView.ReceiptData data = new POSReceiptView.ReceiptData();
|
||||||
|
|
||||||
|
PayDetail payDetail = sharedViewModel.payDetail.getValue();
|
||||||
|
if(payDetail == null) {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
SystemParamsOperation systemParamsOperation = SystemParamsOperation.getInstance();
|
||||||
|
// Load sample bank logo
|
||||||
|
data.bankLogo = BitmapFactory.decodeResource(getResources(), R.drawable.logo_kbzbank);
|
||||||
|
|
||||||
|
// Set sample data
|
||||||
|
data.bankName = "YOUR BANK";
|
||||||
|
data.merchantName = systemParamsOperation.getMerchantName();
|
||||||
|
data.merchantAddress = systemParamsOperation.getMerchantAddress();
|
||||||
|
|
||||||
|
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.getDefault());
|
||||||
|
data.dateTime = sdf.format(new Date());
|
||||||
|
|
||||||
|
data.traceNumber = payDetail.getVoucherNo();
|
||||||
|
data.transactionType = payDetail.getTransType();
|
||||||
|
data.cardNumber = POSUtil.getInstance().getCardNumMasking(payDetail.getCardNo());
|
||||||
|
data.retrievalReferenceNumber = payDetail.getReferNo();
|
||||||
|
data.approvalNumber = payDetail.getApprovalCode();
|
||||||
|
data.amount = POSUtil.getInstance().getDecimalAmountSeparatorFormat(payDetail.getAmount());
|
||||||
|
data.currency = payDetail.getCurrency();
|
||||||
|
data.footerMessage = "Keep this receipt for your records";
|
||||||
|
data.responseCode = payDetail.getTradeAnswerCode();
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
public void onConfirm() {
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,174 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.RadioButton;
|
||||||
|
import android.widget.RadioGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.github.gcacace.signaturepad.views.SignaturePad;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
public class SignatureFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private static final String TAG = SignatureFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private SignaturePad mSignaturePad;
|
||||||
|
private RadioButton rbDigitalSignature;
|
||||||
|
private RadioButton rbManualSignature;
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
private boolean isSigned = false;
|
||||||
|
private boolean isDigitalSignatureSelected = true;
|
||||||
|
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_signature_view, BR.vm,sharedViewModel)
|
||||||
|
.addBindingParam(BR.click,new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.signatureFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
mSignaturePad = binding.getRoot().findViewById(R.id.signature_pad);
|
||||||
|
rbDigitalSignature = binding.getRoot().findViewById(R.id.rbDigitalSignature);
|
||||||
|
rbManualSignature = binding.getRoot().findViewById(R.id.rbManualSignature);
|
||||||
|
|
||||||
|
setupSignaturePad();
|
||||||
|
setupSignatureOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupSignaturePad() {
|
||||||
|
mSignaturePad.setOnSignedListener(new SignaturePad.OnSignedListener() {
|
||||||
|
@Override
|
||||||
|
public void onStartSigning() {
|
||||||
|
isSigned = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSigned() {
|
||||||
|
LogUtil.d(TAG,"ON Signed !");
|
||||||
|
isSigned = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClear() {
|
||||||
|
isSigned = false;
|
||||||
|
LogUtil.d(TAG,"ON Clear !");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupSignatureOptions() {
|
||||||
|
// Set up radio button listeners
|
||||||
|
rbDigitalSignature.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
if (isChecked) {
|
||||||
|
rbManualSignature.setChecked(false);
|
||||||
|
isDigitalSignatureSelected = true;
|
||||||
|
mSignaturePad.setEnabled(true);
|
||||||
|
mSignaturePad.setAlpha(1.0f);
|
||||||
|
LogUtil.d(TAG, "Digital signature option selected");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
rbManualSignature.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
|
if (isChecked) {
|
||||||
|
rbDigitalSignature.setChecked(false);
|
||||||
|
isDigitalSignatureSelected = false;
|
||||||
|
mSignaturePad.setEnabled(false);
|
||||||
|
mSignaturePad.setAlpha(0.5f);
|
||||||
|
LogUtil.d(TAG, "Manual signature option selected");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set digital signature as default
|
||||||
|
rbDigitalSignature.setChecked(true);
|
||||||
|
isDigitalSignatureSelected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.signature_title));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void callNextScreen(){
|
||||||
|
routeId = R.id.action_signatureFragment_to_transactionResultFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
|
||||||
|
public void onClickConfirm() {
|
||||||
|
if (isDigitalSignatureSelected) {
|
||||||
|
// Handle digital signature
|
||||||
|
if (isSigned) {
|
||||||
|
sharedViewModel.signBitmap = mSignaturePad.getSignatureBitmap();
|
||||||
|
LogUtil.d(TAG, "Digital signature confirmed and stored");
|
||||||
|
callNextScreen();
|
||||||
|
} else {
|
||||||
|
showSingleInfoDialog("Please provide your signature on the screen!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Handle manual signature on paper
|
||||||
|
sharedViewModel.signBitmap = null; // No digital signature
|
||||||
|
LogUtil.d(TAG, "Manual signature on paper selected - no digital signature stored");
|
||||||
|
showSingleInfoDialog("Please sign on the printed receipt manually and proceed.");
|
||||||
|
callNextScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickClear() {
|
||||||
|
if (isDigitalSignatureSelected) {
|
||||||
|
mSignaturePad.clear();
|
||||||
|
isSigned = false;
|
||||||
|
LogUtil.d(TAG, "Digital signature cleared");
|
||||||
|
} else {
|
||||||
|
// For manual signature, just show a message
|
||||||
|
showSingleInfoDialog("Manual signature option selected. No digital signature to clear.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickDigitalOption() {
|
||||||
|
rbDigitalSignature.setChecked(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickManualOption() {
|
||||||
|
rbManualSignature.setChecked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
|
||||||
|
public class SuccessFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_success_screen, BR.sharedViewModel,sharedViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.successFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return R.id.action_successFragment_to_nav_main;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.txt_title_success));
|
||||||
|
|
||||||
|
|
||||||
|
delayFunctionCall(this::navigateToMain,2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToMain() {
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
}
|
||||||
124
app/src/main/java/com/utsmm/kbz/ui/core_ui/TimeoutFragment.java
Normal file
124
app/src/main/java/com/utsmm/kbz/ui/core_ui/TimeoutFragment.java
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.CountDownTimer;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.CardDetectCallback;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
|
||||||
|
public class TimeoutFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
private int resultTimeOut = 3;
|
||||||
|
private CountDownTimer countDownTimer;
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.txt_title_error));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_timeout_screen, BR.sharedViewModel,sharedViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.timeoutFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startResultTimeout() {
|
||||||
|
countDownTimer = new CountDownTimer(resultTimeOut * 1000, 1000) {
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
@Override
|
||||||
|
public void onTick(long millisUntilFinished) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
|
||||||
|
isCardInside();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}.start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ecrActionCancel(String msg) {
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(msg);
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
if(countDownTimer != null){
|
||||||
|
countDownTimer.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void isCardInside() {
|
||||||
|
|
||||||
|
isCardInserted(new CardDetectCallback() {
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
delayFunctionCall(()->{
|
||||||
|
ecrActionCancel("Timeout!");
|
||||||
|
routeId = R.id.action_timeoutFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
startResultTimeout();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.databinding.library.baseAdapters.BR;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.ByteUtil;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This fragment was called after transaction result screen, So I won't delete it for awhile for future testing process
|
||||||
|
* */
|
||||||
|
|
||||||
|
public class TransactionDetailFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
private int routeId;
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_transaction_detail, BR.sharedViewModel,sharedViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.transactionDetailFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
sendMessageProcess(sharedViewModel.payDetail.getValue().sendBag);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendMessageProcess(byte[] sendBytes){
|
||||||
|
sharedViewModel.sendMsg.setValue(ByteUtil.bytes2HexStr(sendBytes));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,413 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_ui;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.stream.MalformedJsonException;
|
||||||
|
import com.utsmyanmar.baselib.emv.EmvParamOperation;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusError;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusResponse;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.DialogCallback;
|
||||||
|
import com.utsmyanmar.baselib.util.TimeoutCallback;
|
||||||
|
import com.utsmyanmar.baselib.util.rx_helper.RxCallbackX;
|
||||||
|
import com.utsmyanmar.baselib.util.rx_helper.RxUtil;
|
||||||
|
import com.utsmyanmar.ecr.ECRHelper;
|
||||||
|
import com.utsmyanmar.ecr.ECRProcess;
|
||||||
|
import com.utsmyanmar.ecr.data.model.TransactionsResp;
|
||||||
|
import com.utsmyanmar.paylibs.Constant;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.print.PaperRollStatusCallback;
|
||||||
|
import com.utsmyanmar.paylibs.print.PrintHelper;
|
||||||
|
import com.utsmyanmar.paylibs.utils.PrintStatus;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.config.data.model.TMSUpdate;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.TransProcessViewModel;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
import com.utsmm.kbz.util.tms.TMSUtil;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
import retrofit2.HttpException;
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
|
||||||
|
// Temporarily disabled Hilt
|
||||||
|
@AndroidEntryPoint
|
||||||
|
public class TransactionResultFragment extends DataBindingFragment implements DataBindingFragment.BackPressCallback {
|
||||||
|
|
||||||
|
private static final String TAG = TransactionResultFragment.class.getSimpleName();
|
||||||
|
private TransProcessViewModel transProcessViewModel;
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private static final int resultTimeOut = 1;
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
private final RxUtil<SiriusResponse> siriusRxUtil = new RxUtil<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
EmvParamOperation emvParamOperation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
transProcessViewModel = getFragmentScopeViewModel(TransProcessViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_trans_result_screen, BR.transViewModel, transProcessViewModel)
|
||||||
|
.addBindingParam(BR.sharedViewModel, sharedViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.transactionResultFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
String resultStr = "";
|
||||||
|
|
||||||
|
if(sharedViewModel.payDetail.getValue() != null) {
|
||||||
|
resultStr = sharedViewModel.payDetail.getValue().getTradeAnswerCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
int qrStatus = -100;
|
||||||
|
|
||||||
|
if(sharedViewModel.payDetail.getValue() != null) {
|
||||||
|
qrStatus = sharedViewModel.payDetail.getValue().getQrTransStatus();
|
||||||
|
}
|
||||||
|
if (resultStr.equals(Constant.ANSWER_CODE_ACCEPT) || resultStr.equals(Constant.ANSWER_CODE_APPROVED)) {
|
||||||
|
/* ISO 8583 RESPONSE */
|
||||||
|
if(sharedViewModel.payDetail.getValue().getTransactionType() != TransactionsType.SETTLEMENT.value) {
|
||||||
|
|
||||||
|
if(SystemParamsOperation.getInstance().isAlertSound()) {
|
||||||
|
startSound(getResourceString(R.string.txt_audio_thank_you));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.txt_title_trans_result));
|
||||||
|
} else if(qrStatus == 1 || qrStatus == -1 || qrStatus == 2 || qrStatus == 3 ) {
|
||||||
|
/* WAVE QR STATUS */
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.txt_title_qr_pay));
|
||||||
|
} else {
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.txt_title_error));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sharedViewModel.isEcr.getValue() != null){
|
||||||
|
if(sharedViewModel.isEcr.getValue()){
|
||||||
|
ecrAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void startResultTimeout() {
|
||||||
|
|
||||||
|
setupTimeout(resultTimeOut, new TimeoutCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTrick(long trickTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
|
||||||
|
PayDetail payDetail = sharedViewModel.payDetail.getValue();
|
||||||
|
|
||||||
|
if (payDetail == null) {
|
||||||
|
navigateToMainScreen();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SiriusRequest siriusReq = TMSUtil.getInstance().generateRequestParams(
|
||||||
|
getContext(),
|
||||||
|
payDetail.getTransType(),
|
||||||
|
String.valueOf(payDetail.getTransNum())
|
||||||
|
);
|
||||||
|
|
||||||
|
TransactionsType transactionType = sharedViewModel.transactionsType.getValue();
|
||||||
|
|
||||||
|
if (isNonApprovedTrade(payDetail) && isNonWavepayTransaction(transactionType)) {
|
||||||
|
startPrintProcess(false);
|
||||||
|
isCardInside();
|
||||||
|
} else if (transactionType == TransactionsType.SETTLEMENT) {
|
||||||
|
handleSettlementTransaction(siriusReq);
|
||||||
|
} else if (isWavePayNonSuccessTransaction(transactionType, payDetail)) {
|
||||||
|
startPrintProcess(false);
|
||||||
|
navigateToMainScreen();
|
||||||
|
} else if (isWavePaySuccessTransaction(transactionType, payDetail)) {
|
||||||
|
handleWavePaySuccessTransaction(payDetail, siriusReq);
|
||||||
|
} else {
|
||||||
|
handleDefaultTransaction(payDetail, siriusReq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNonApprovedTrade(PayDetail payDetail) {
|
||||||
|
return !payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_APPROVED) &&
|
||||||
|
!payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_ACCEPT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isNonWavepayTransaction(TransactionsType transactionType) {
|
||||||
|
return transactionType != TransactionsType.MMQR &&
|
||||||
|
transactionType != TransactionsType.MMQR_INQUIRY_STATUS &&
|
||||||
|
transactionType != TransactionsType.MMQR_REFUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isWavePayNonSuccessTransaction(TransactionsType transactionType, PayDetail payDetail) {
|
||||||
|
return (transactionType == TransactionsType.MMQR && payDetail.getQrTransStatus() != 1) ||
|
||||||
|
(transactionType == TransactionsType.MMQR_INQUIRY_STATUS && payDetail.getQrTransStatus() != 1) ||
|
||||||
|
(transactionType == TransactionsType.MMQR_REFUND && payDetail.getQrTransStatus() != 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isWavePaySuccessTransaction(TransactionsType transactionType, PayDetail payDetail) {
|
||||||
|
|
||||||
|
return (transactionType == TransactionsType.MMQR || transactionType == TransactionsType.MMQR_REFUND) &&
|
||||||
|
payDetail.getQrTransStatus() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleSettlementTransaction(SiriusRequest siriusReq) {
|
||||||
|
startPrintProcess(true);
|
||||||
|
downloadParameters(siriusReq, TMSUpdate.UPDATE);
|
||||||
|
showSuccessDialog(getResourceString(R.string.txt_configs_are_updated));
|
||||||
|
navigateToMainScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleWavePaySuccessTransaction(PayDetail payDetail, SiriusRequest siriusReq) {
|
||||||
|
SystemParamsOperation.getInstance().setLastSuccessTrnx(payDetail.getVoucherNo());
|
||||||
|
downloadParameters(siriusReq, TMSUpdate.CHECK);
|
||||||
|
navigateToPrintScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleDefaultTransaction(PayDetail payDetail, SiriusRequest siriusReq) {
|
||||||
|
SystemParamsOperation.getInstance().setLastSuccessTrnx(payDetail.getVoucherNo());
|
||||||
|
downloadParameters(siriusReq, TMSUpdate.CHECK);
|
||||||
|
navigateToPrintScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadParameters(SiriusRequest siriusRequest,TMSUpdate tmsUpdate) {
|
||||||
|
siriusRxUtil.observableData(sharedViewModel.getParams(siriusRequest), new RxCallbackX<SiriusResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(SiriusResponse data) {
|
||||||
|
TMSUtil.getInstance().initParams(data, tmsUpdate,emvParamOperation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(Throwable throwable) {
|
||||||
|
dismissLoadingDialog();
|
||||||
|
|
||||||
|
if(throwable.getClass() == MalformedJsonException.class) {
|
||||||
|
LogUtil.d(TAG,getResourceString(R.string.txt_terminal_is_not_configure));
|
||||||
|
|
||||||
|
} else if (throwable instanceof HttpException) {
|
||||||
|
HttpException error = (HttpException)throwable;
|
||||||
|
try {
|
||||||
|
SiriusError siriusError = new Gson().fromJson(error.response().errorBody().string(), SiriusError.class);
|
||||||
|
LogUtil.d(TAG,siriusError.getMessage());
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
LogUtil.d(TAG,getResourceString(R.string.txt_failure)+throwable.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
throwable.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
dismissLoadingDialog();
|
||||||
|
// emvParamOperation.loadAidRids();
|
||||||
|
// emvParamOperation.loadEmvTerminalParam();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void isCardInside() {
|
||||||
|
isCardInserted(() -> delayFunctionCall(this::navigateToMainScreen));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToMainScreen() {
|
||||||
|
routeId = R.id.action_transactionResultFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToPrintScreen() {
|
||||||
|
routeId = R.id.action_transactionResultFragment_to_printReceiptFragment;
|
||||||
|
// routeId = R.id.action_transactionResultFragment_to_receiptFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@androidx.annotation.NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
sharedViewModel.setPrintStatus(PrintStatus.FIRST_PRINT);
|
||||||
|
sharedViewModel.printXStatus.setValue(null);
|
||||||
|
|
||||||
|
if (getActivity() instanceof AppCompatActivity) {
|
||||||
|
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
setupBackButtonPressDetection(this);
|
||||||
|
|
||||||
|
observePrintStatus();
|
||||||
|
startResultTimeout();
|
||||||
|
|
||||||
|
if(sharedViewModel.payDetail.getValue() != null)
|
||||||
|
LogUtil.d(TAG,"Result Code: "+sharedViewModel.payDetail.getValue().getTradeAnswerCode());
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void observePrintStatus() {
|
||||||
|
sharedViewModel.printXStatus.observe(getViewLifecycleOwner(), printStatus -> {
|
||||||
|
// LogUtil.d(TAG,"Print Status :"+printStatus);
|
||||||
|
if(printStatus == PrintStatus.EMPTY_PAPER_ROLL) {
|
||||||
|
cancelTimeout();
|
||||||
|
startPrintProcess(false);
|
||||||
|
} else if (printStatus == PrintStatus.DONE_PRINT) {
|
||||||
|
isCardInside();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startPrintProcess(boolean isSettlement) {
|
||||||
|
|
||||||
|
PrintHelper.getInstance().checkPaperRollStatus(new PaperRollStatusCallback() {
|
||||||
|
@Override
|
||||||
|
public void printerReady() {
|
||||||
|
if(isSettlement) {
|
||||||
|
sharedViewModel.startPrintProcessSettlement();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sharedViewModel.startPrintProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paperRollIsEmpty() {
|
||||||
|
cancelTimeout();
|
||||||
|
|
||||||
|
showPrinterAlertDialog(getResourceString(R.string.txt_paper_roll_not_ready), new DialogCallback() {
|
||||||
|
@Override
|
||||||
|
public void onClickCancel() {
|
||||||
|
|
||||||
|
dismissPrinterAlertDialog();
|
||||||
|
isCardInside();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickRetry() {
|
||||||
|
dismissPrinterAlertDialog();
|
||||||
|
startPrintProcess(isSettlement);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(SystemParamsOperation.getInstance().isAlertSound()) {
|
||||||
|
startSound(getResourceString(R.string.txt_audio_printer_alert));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printNotComplete() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printerTooHot() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void printerFailed() {
|
||||||
|
// alertPaperRoll(getResourceString(R.string.txt_lip_is_opening), getResourceString(R.string.txt_please_close_lip));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unknownStatusOccur(int code) {
|
||||||
|
// showDeclineDialog("Check Printer Status : "+code);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void alertPaperRoll(String title, String message) {
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
|
||||||
|
builder.setTitle(title)
|
||||||
|
.setMessage(message)
|
||||||
|
.setNegativeButton(getResourceString(R.string.txt_print_later), (dialog, which) -> {
|
||||||
|
dialog.dismiss();
|
||||||
|
})
|
||||||
|
.setPositiveButton(getResourceString(R.string.txt_retry_now), (dialog, which) -> {
|
||||||
|
sharedViewModel.startPrintProcess();
|
||||||
|
|
||||||
|
})
|
||||||
|
.setCancelable(false)
|
||||||
|
.create();
|
||||||
|
|
||||||
|
builder.show();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getECRResponseMessage() {
|
||||||
|
|
||||||
|
TransactionsResp resp = CoreUtils.getInstance(sharedViewModel).generateResponseMsg();
|
||||||
|
|
||||||
|
return ECRProcess.INSTANCE.generateECRResponse(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ecrAction() {
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"ECR Response :"+getECRResponseMessage());
|
||||||
|
ECRHelper.INSTANCE.send(getECRResponseMessage().getBytes());
|
||||||
|
|
||||||
|
ECRHelper.INSTANCE.setOnBindSuccess(() -> {
|
||||||
|
LogUtil.d(TAG, "Send Success!");
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPress() {
|
||||||
|
isCardInside();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,109 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.nexgo.oaf.apiv3.device.reader.CardSlotTypeEnum;
|
||||||
|
import com.utsmyanmar.checkxread.CheckXRead;
|
||||||
|
import com.utsmyanmar.checkxread.checkcard.CheckCardResultX;
|
||||||
|
import com.utsmyanmar.checkxread.model.CardDataX;
|
||||||
|
import com.utsmyanmar.checkxread.readcard.ReadCardResultX;
|
||||||
|
import com.utsmyanmar.checkxread.readcard.ReadCardX;
|
||||||
|
import com.utsmyanmar.checkxread.sdk.NexGoSDK;
|
||||||
|
//import com.utsmyanmar.mpulib.model.MPUCardData;
|
||||||
|
//import com.utsmyanmar.mpulib.readcard.CheckCardListener;
|
||||||
|
//import com.utsmyanmar.mpulib.readcard.ReadCardProcess;
|
||||||
|
//import com.utsmyanmar.mpulib.util.CardScheme;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
import com.utsmm.kbz.config.data.model.CardTransactionType;
|
||||||
|
import com.utsmm.kbz.util.enums.CardReadStatus;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.core.Single;
|
||||||
|
|
||||||
|
|
||||||
|
public class CardReadViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private static final String TAG = CardReadViewModel.class.getSimpleName();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public CardReadViewModel(){
|
||||||
|
|
||||||
|
}
|
||||||
|
private SingleLiveEvent<Boolean> flag = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> errorCode = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this was bind for UI / showing card information
|
||||||
|
* */
|
||||||
|
public SingleLiveEvent<CardDataX> cardData = new SingleLiveEvent<>();
|
||||||
|
// public SingleLiveEvent<CardScheme> cardSchemeData = new SingleLiveEvent<>();
|
||||||
|
public SingleLiveEvent<Integer> cardTypeData = new SingleLiveEvent<>();
|
||||||
|
public SingleLiveEvent<PayDetail> payDetail = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> checkCardAlertMsg = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
Handler mainThreadHandler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
|
private boolean oneTimeFlag = false;
|
||||||
|
|
||||||
|
private CardTransactionType cardTransactionType;
|
||||||
|
|
||||||
|
public void setCardTransactionType(CardTransactionType cardTransactionType) {
|
||||||
|
this.cardTransactionType = cardTransactionType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CardTransactionType getCardTransactionType() { return this.cardTransactionType; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check Card type whether it's MPU or EMV or MAG stripe card!!
|
||||||
|
* */
|
||||||
|
public void startCheckXProcess(int allType, int timeOut,CheckCardResultX cardResultX) {
|
||||||
|
CheckXRead.getInstance().startCheckXProcess(allType, timeOut,cardResultX);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startCheckXProcessNex(HashSet<CardSlotTypeEnum> allType, int timeOut, CheckCardResultX cardResultX) {
|
||||||
|
CheckXRead.getInstance().startCheckXProcessNex(allType, timeOut,cardResultX);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelCheckXProcess() {
|
||||||
|
CheckXRead.getInstance().cancelCheckXProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startReadXProcess(ReadCardX readCardX,ReadCardResultX readCardResultX) {
|
||||||
|
CheckXRead.getInstance().startReadXProcess(readCardX,readCardResultX);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCheckCardAlertMsg(String msg,boolean isAutoHide) {
|
||||||
|
checkCardAlertMsg.setValue(msg);
|
||||||
|
|
||||||
|
if(isAutoHide) {
|
||||||
|
Handler handler = new Handler(Looper.getMainLooper());
|
||||||
|
handler.postDelayed(() -> checkCardAlertMsg.setValue(null), 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetUI() {
|
||||||
|
checkCardAlertMsg.setValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetOneTimeFlag(){
|
||||||
|
oneTimeFlag = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancelCheckCard(){
|
||||||
|
NexGoSDK.getInstance().cancelCheckCard();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,460 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.sunmi.pay.hardware.aidl.bean.CardInfo;
|
||||||
|
import com.sunmi.pay.hardware.aidlv2.AidlConstantsV2;
|
||||||
|
import com.sunmi.pay.hardware.aidlv2.bean.EMVCandidateV2;
|
||||||
|
import com.sunmi.pay.hardware.aidlv2.bean.EMVTransDataV2;
|
||||||
|
import com.sunmi.pay.hardware.aidlv2.emv.EMVListenerV2;
|
||||||
|
import com.sunmi.pay.hardware.aidlv2.emv.EMVOptV2;
|
||||||
|
import com.sunmi.pay.hardware.aidlv2.pinpad.PinPadOptV2;
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.model.TradeData;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.KernelDataProcessUtil;
|
||||||
|
import com.utsmm.kbz.MyApplication;
|
||||||
|
import com.utsmm.kbz.util.enums.EmvReadStatus;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Currently this class is not used
|
||||||
|
* */
|
||||||
|
@HiltViewModel
|
||||||
|
public class EmvReadCardViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private static final String TAG = EmvReadCardViewModel.class.getSimpleName();
|
||||||
|
|
||||||
|
private final Repository repository;
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> cardNum = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> expDate = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<EmvReadStatus> resultStatus = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<List<EMVCandidateV2>> emvList = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<Boolean> isButtonVisible = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> emvCardType = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> errorCode = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
private String mTag9F06Value;
|
||||||
|
|
||||||
|
public TradeData mTradeData;
|
||||||
|
public PayDetail mPayDetail;
|
||||||
|
|
||||||
|
private EMVOptV2 mEMVOptV2;
|
||||||
|
private PinPadOptV2 mPinPadOptV2;
|
||||||
|
|
||||||
|
private static final int CHECK_CARD_FAIL = 1;
|
||||||
|
private static final int CHECK_CARD_SUCCESS = 2;
|
||||||
|
private static final int CHECK_CARD_MAG = 3;
|
||||||
|
private static final int CHECK_CARD_NFC = 4;
|
||||||
|
private static final int CHECK_CARD_IC = 5;
|
||||||
|
private static final int EMV_APP_SELECT = 6;
|
||||||
|
private static final int EMV_CONFIRM_CARD_NO = 7;
|
||||||
|
|
||||||
|
private Looper mLooper = Looper.getMainLooper();
|
||||||
|
private final Handler mHandler = new Handler(mLooper) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleMessage(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case CHECK_CARD_FAIL:
|
||||||
|
String hint = (String) msg.obj;
|
||||||
|
resultStatus.postValue(EmvReadStatus.FAIL);
|
||||||
|
// checkCardFail(msg.arg1, hint);
|
||||||
|
break;
|
||||||
|
case EMV_APP_SELECT:
|
||||||
|
List<EMVCandidateV2> list = ( List<EMVCandidateV2> ) msg.obj;
|
||||||
|
emvList.postValue(list);
|
||||||
|
resultStatus.postValue(EmvReadStatus.SELECT_APP);
|
||||||
|
case CHECK_CARD_SUCCESS:
|
||||||
|
getCardInfo();
|
||||||
|
getF055Data();
|
||||||
|
terminateTrans();
|
||||||
|
resultStatus.postValue(EmvReadStatus.SUCCESS);
|
||||||
|
break;
|
||||||
|
case EMV_CONFIRM_CARD_NO:
|
||||||
|
getCardInfo();
|
||||||
|
getF055Data();
|
||||||
|
terminateTrans();
|
||||||
|
resultStatus.postValue(EmvReadStatus.SUCCESS);
|
||||||
|
try {
|
||||||
|
mEMVOptV2.importCardNoStatus(0);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CHECK_CARD_MAG:
|
||||||
|
Bundle bundle = (Bundle) msg.obj;
|
||||||
|
// handleMagCard(bundle);
|
||||||
|
break;
|
||||||
|
case CHECK_CARD_NFC:
|
||||||
|
// handleNFCCard();
|
||||||
|
break;
|
||||||
|
case CHECK_CARD_IC:
|
||||||
|
// handleICCard();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
public void terminateTrans(){
|
||||||
|
try {
|
||||||
|
mEMVOptV2.abortTransactProcess();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEmvAppSelect(int position){
|
||||||
|
try {
|
||||||
|
mEMVOptV2.importAppSelect(position);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public EmvReadCardViewModel(Repository repository){
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTradeData(TradeData tradeData){
|
||||||
|
this.mTradeData = tradeData;
|
||||||
|
mPayDetail = mTradeData.getPayDetail();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeData getTradeData(){
|
||||||
|
return mTradeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startProcess(){
|
||||||
|
initView();
|
||||||
|
initEmvTlvData();
|
||||||
|
transactProcess();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initView(){
|
||||||
|
mEMVOptV2 = MyApplication.getInstance().mEMVOptV2;
|
||||||
|
mPinPadOptV2 = MyApplication.getInstance().mPinPadOptV2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initEmvTlvData() {
|
||||||
|
try {
|
||||||
|
|
||||||
|
// set PayWave(Visa) tlv data
|
||||||
|
String[] tagsPayWave = {"DF8124", "DF8125", "DF8126"};
|
||||||
|
String[] valuesPayWave = {"999999999999", "999999999999", "000000000000"};
|
||||||
|
mEMVOptV2.setTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_PAYWAVE, tagsPayWave, valuesPayWave);
|
||||||
|
|
||||||
|
|
||||||
|
// set JCB Wave tlv data
|
||||||
|
String[] tagsJCB = {"9F53", "DF8161"};
|
||||||
|
String[] valuesJCB = {"708000", "7F00"};
|
||||||
|
mEMVOptV2.setTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_JCB, tagsJCB, valuesJCB);
|
||||||
|
|
||||||
|
// set PayPass(MasterCard) tlv data
|
||||||
|
String[] tagsPayPass = {"DF8117", "DF8118", "DF8119", "DF811F", "DF811E", "DF812C",
|
||||||
|
"DF8123", "DF8124", "DF8125", "DF8126",
|
||||||
|
"DF811B", "DF811D", "DF8122", "DF8120", "DF8121"};
|
||||||
|
String[] valuesPayPass = {"E0", "F8", "F8", "E8", "00", "00",
|
||||||
|
"000000000000", "000000100000", "999999999999", "000000100000",
|
||||||
|
"30", "02", "0000000000", "000000000000", "000000000000"};
|
||||||
|
mEMVOptV2.setTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_PAYPASS, tagsPayPass, valuesPayPass);
|
||||||
|
|
||||||
|
// set AMEX(AmericanExpress) tlv data
|
||||||
|
String[] tagsAE = {"9F6D", "9F6E", "9F33", "9F35", "DF8168", "DF8167", "DF8169", "DF8170"};
|
||||||
|
String[] valuesAE = {"C0", "D8E00000", "E0E888", "22", "00", "00", "00", "60"};
|
||||||
|
mEMVOptV2.setTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_AE, tagsAE, valuesAE);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void transactProcess() {
|
||||||
|
// LogUtil.e(TAG, "***************************************************************");
|
||||||
|
// LogUtil.e(TAG, "****************************Start Process**********************");
|
||||||
|
// LogUtil.e(TAG, "***************************************************************");
|
||||||
|
//
|
||||||
|
// LogUtil.e(TAG, "transactProcess");
|
||||||
|
try {
|
||||||
|
|
||||||
|
mEMVOptV2.initEmvProcess();
|
||||||
|
|
||||||
|
EMVTransDataV2 emvTransData = new EMVTransDataV2();
|
||||||
|
emvTransData.amount = "1000";
|
||||||
|
// if(mPayDetail.cardType == AidlConstantsV2.CardType.NFC.getValue()){
|
||||||
|
// emvTransData.flowType = AidlConstantsV2.EMV.FlowType.TYPE_NFC_SPEEDUP;
|
||||||
|
// }else{
|
||||||
|
// emvTransData.flowType = AidlConstantsV2.EMV.FlowType.TYPE_EMV_STANDARD;
|
||||||
|
// }
|
||||||
|
emvTransData.flowType = 2;
|
||||||
|
emvTransData.cardType = mPayDetail.cardType;
|
||||||
|
|
||||||
|
mEMVOptV2.transactProcess(emvTransData, mEMVListener);
|
||||||
|
} catch (Exception e) {
|
||||||
|
resultStatus.postValue(EmvReadStatus.FAIL);
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initEmvProcess() {
|
||||||
|
try {
|
||||||
|
// Set normal TLV data
|
||||||
|
String[] tags = {"5F2A", "5F36"};
|
||||||
|
String[] values = {"0104", "00"};
|
||||||
|
mEMVOptV2.setTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_NORMAL, tags, values);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private EMVListenerV2 mEMVListener = new EMVListenerV2.Stub() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWaitAppSelect(List<EMVCandidateV2> appNameList, boolean isFirstSelect) throws RemoteException {
|
||||||
|
// LogUtil.e(TAG, "onWaitAppSelect isFirstSelect:" + isFirstSelect);
|
||||||
|
mHandler.obtainMessage(EMV_APP_SELECT, appNameList).sendToTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAppFinalSelect(String tag9F06Value) throws RemoteException {
|
||||||
|
// LogUtil.d(TAG, "tag9F06Value:" + tag9F06Value);
|
||||||
|
mTag9F06Value = tag9F06Value;
|
||||||
|
initEmvProcess();
|
||||||
|
|
||||||
|
/* if (tag9F06Value != null && tag9F06Value.length() > 0) {
|
||||||
|
boolean visa = tag9F06Value.startsWith("A000000003");
|
||||||
|
boolean master = tag9F06Value.startsWith("A000000004");
|
||||||
|
boolean unionPay = tag9F06Value.startsWith("A000000333");
|
||||||
|
boolean jcb = tag9F06Value.startsWith("A000000065");
|
||||||
|
if (visa) {
|
||||||
|
emvCardType.postValue("VISA");
|
||||||
|
// VISA - PayWave
|
||||||
|
mPayDetail.setAccountType("Visa");
|
||||||
|
LogUtil.d(TAG, "detect VISA card");
|
||||||
|
String[] tagsPayWave = {
|
||||||
|
// "DF8124", "DF8125", "DF8126"
|
||||||
|
"9F33"
|
||||||
|
|
||||||
|
};
|
||||||
|
String[] valuesPayWave = {
|
||||||
|
// "999999999999", "999999999999", "000000000000"
|
||||||
|
"002888"
|
||||||
|
|
||||||
|
};
|
||||||
|
mEMVOptV2.setTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_NORMAL, tagsPayWave, valuesPayWave);
|
||||||
|
} else if (master) {
|
||||||
|
|
||||||
|
emvCardType.postValue("MASTER");
|
||||||
|
// MasterCard - PayPass
|
||||||
|
mPayDetail.setAccountType("Master");
|
||||||
|
LogUtil.d(TAG, "detect MasterCard card");
|
||||||
|
// String[] tagsPayPass = {
|
||||||
|
// "DF8118", "DF8119", "DF811F", "DF811E",
|
||||||
|
// "DF8123", "DF8124", "DF8125", "DF8126",
|
||||||
|
// "DF811B", "DF811D", "DF8122", "DF8120", "DF8121"
|
||||||
|
// };
|
||||||
|
// String[] valuesPayPass = {
|
||||||
|
// "28", "08", "08", "10",
|
||||||
|
// "000000010000", "000000030000", "000000050000", "000000001000",
|
||||||
|
// "00", "00", "0000000000", "0000000000", "0000000000"
|
||||||
|
// };
|
||||||
|
String[] tagsPayPass = {
|
||||||
|
"DF8117", "DF8118", "DF8119", "DF811F", "DF811E", "DF812C",
|
||||||
|
"DF8123", "DF8124", "DF8125", "DF8126",
|
||||||
|
"DF811B", "DF811D", "DF8122", "DF8120", "DF8121"
|
||||||
|
};
|
||||||
|
String[] valuesPayPass = {
|
||||||
|
"E0", "F8", "F8", "E8", "00", "00",
|
||||||
|
"999999999999", "000000001000", "000000001000", "000000001000",
|
||||||
|
"30", "02", "0000000000", "000000000000", "000000000000"
|
||||||
|
};
|
||||||
|
mEMVOptV2.setTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_PAYPASS, tagsPayPass, valuesPayPass);
|
||||||
|
} else if (unionPay) {
|
||||||
|
emvCardType.postValue("UnionPay");
|
||||||
|
mPayDetail.setAccountType("UPI");
|
||||||
|
// UnionPay
|
||||||
|
LogUtil.d(TAG, "detect UnionPay card");
|
||||||
|
String[] tagsPayPass = {
|
||||||
|
"DF8120", "DF8121", "DF8122"
|
||||||
|
};
|
||||||
|
String[] valuesPayPass = {
|
||||||
|
"D84000A800", "DC4004F800", "0100000000"
|
||||||
|
};
|
||||||
|
mEMVOptV2.setTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_NORMAL, tagsPayPass, valuesPayPass);
|
||||||
|
} else if(jcb) {
|
||||||
|
emvCardType.postValue("JCB");
|
||||||
|
mPayDetail.setAccountType("JCB");
|
||||||
|
// UnionPay
|
||||||
|
LogUtil.d(TAG, "detect JCB card");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (AidlConstants.CardType.IC.getValue() == mPayDetail.cardType) {
|
||||||
|
String[] tags = {
|
||||||
|
"9F33", "9F09", "DF81FF"
|
||||||
|
};
|
||||||
|
String[] values = {
|
||||||
|
"6060C8", "0111", "01"
|
||||||
|
// "0008C8", "0111", "01"
|
||||||
|
};
|
||||||
|
mEMVOptV2.setTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_NORMAL, tags, values);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
mEMVOptV2.importAppFinalSelectStatus(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfirmCardNo(String cardNo) {
|
||||||
|
// LogUtil.e(TAG, "onConfirmCardNo cardNo:" + cardNo);
|
||||||
|
|
||||||
|
mHandler.sendEmptyMessage(EMV_CONFIRM_CARD_NO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestShowPinPad(int type, int remainTime) throws RemoteException {
|
||||||
|
// LogUtil.e(TAG, "requestShowPinPad type:" + type + " remainTime:" + remainTime);
|
||||||
|
mHandler.sendEmptyMessage(CHECK_CARD_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestSignature() throws RemoteException {
|
||||||
|
// LogUtil.e(TAG, "signatureStatus");
|
||||||
|
mEMVOptV2.importSignatureStatus(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCertVerify(int certType, String certInfo) throws RemoteException {
|
||||||
|
// LogUtil.e(TAG, "onCertVerify certType:" + certType + " certInfo:" + certInfo);
|
||||||
|
mEMVOptV2.importCertStatus(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onOnlineProc() throws RemoteException {
|
||||||
|
// LogUtil.e(TAG, "onProcessEnd");
|
||||||
|
mHandler.sendEmptyMessage(CHECK_CARD_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCardDataExchangeComplete() throws RemoteException {
|
||||||
|
// LogUtil.e(TAG, "onCardDataExchangeComplete");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConfirmationCodeVerified() throws RemoteException {
|
||||||
|
// LogUtil.e(TAG, "onConfirmationCodeVerified");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRequestDataExchange(String s) throws RemoteException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTermRiskManagement() throws RemoteException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPreFirstGenAC() throws RemoteException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTransResult(int code, String desc) throws RemoteException {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Temporary Error Message
|
||||||
|
* */
|
||||||
|
|
||||||
|
String errorMsg = "Card read failed!";
|
||||||
|
|
||||||
|
errorCode.postValue(code+":"+errorMsg);
|
||||||
|
if (code != 0) {
|
||||||
|
if( code == -50011) {
|
||||||
|
mHandler.sendEmptyMessage(CHECK_CARD_SUCCESS);
|
||||||
|
} else {
|
||||||
|
mHandler.obtainMessage(CHECK_CARD_FAIL, code, code, desc).sendToTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
mHandler.sendEmptyMessage(CHECK_CARD_SUCCESS);
|
||||||
|
}
|
||||||
|
// LogUtil.e(TAG, "onTransResult code:" + code + " desc:" + desc);
|
||||||
|
// LogUtil.e(TAG, "***************************************************************");
|
||||||
|
// LogUtil.e(TAG, "****************************End Process************************");
|
||||||
|
// LogUtil.e(TAG, "***************************************************************");
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
private void getCardInfo() {
|
||||||
|
String[] tagList = {"5A", "5F24", "57", "5F34", "9F6B"};
|
||||||
|
byte[] outData = new byte[1024];
|
||||||
|
try {
|
||||||
|
int len = mEMVOptV2.getTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_NORMAL, tagList, outData);
|
||||||
|
if (len > 0) {
|
||||||
|
byte[] data = new byte[len];
|
||||||
|
System.arraycopy(outData, 0, data, 0, len);
|
||||||
|
CardInfo cardInfo = KernelDataProcessUtil.getCardInfo(mPayDetail.cardType, data);
|
||||||
|
mTradeData = KernelDataProcessUtil.fillTradeDataInfo(cardInfo, mTradeData);
|
||||||
|
|
||||||
|
//display card data in layout
|
||||||
|
cardNum.postValue(mPayDetail.getCardNo());
|
||||||
|
expDate.postValue(mPayDetail.getEXPDate());
|
||||||
|
} else {
|
||||||
|
// LogUtil.e(Constant.TAG, "The data length of the card information is negative = " + len);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getF055Data() {
|
||||||
|
/* For Yoma */
|
||||||
|
/*Jun 6 Added 9F2A*/
|
||||||
|
String[] tagList={
|
||||||
|
"9F2A","9F26","9F27","9F10","9F37","9F36","95","9A","9C","9F02","5F2A","5F34","82","9F1A", //field 55 tag
|
||||||
|
"9F03","9F33","4F","9F08","9F34","9F35","9F1E","9F53","84","9F09","9F41", //field55 tag
|
||||||
|
"9F5B","8A","9B","9F6E","9F7C","9F4C","50","9F12","DF01","9F63","5F20","9F0B","9F42"
|
||||||
|
|
||||||
|
};
|
||||||
|
byte[] outData = new byte[2048];
|
||||||
|
try {
|
||||||
|
int len = mEMVOptV2.getTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_NORMAL, tagList, outData);
|
||||||
|
if (len > 0) {
|
||||||
|
byte[] data = new byte[len];
|
||||||
|
System.arraycopy(outData, 0, data, 0, len);
|
||||||
|
mTradeData = KernelDataProcessUtil.readKernelData(data, mTradeData);
|
||||||
|
} else {
|
||||||
|
// LogUtil.e(Constant.TAG, "Get the data length of the 55 field as a negative number = " + len);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,596 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.nexgo.common.ByteUtils;
|
||||||
|
import com.nexgo.oaf.apiv3.SdkResult;
|
||||||
|
import com.nexgo.oaf.apiv3.emv.EmvDataSourceEnum;
|
||||||
|
import com.nexgo.oaf.apiv3.emv.EmvOnlineResultEntity;
|
||||||
|
import com.utsmyanmar.baselib.emv.EmvParamOperation;
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository;
|
||||||
|
import com.utsmyanmar.baselib.util.enums.EmvResultStatus;
|
||||||
|
import com.utsmyanmar.baselib.viewModel.EmvBaseViewModel;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.model.TradeData;
|
||||||
|
import com.utsmyanmar.paylibs.model.enums.TransCVM;
|
||||||
|
import com.utsmyanmar.paylibs.network.ISOSocket;
|
||||||
|
import com.utsmyanmar.paylibs.reversal.ReversalAction;
|
||||||
|
import com.utsmyanmar.paylibs.reversal.ReversalListener;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
import com.utsmyanmar.paylibs.transactions.TransactionsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.transactions.TransactionsOperationListener;
|
||||||
|
import com.utsmyanmar.paylibs.utils.DemoUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionType;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.transactions.ProcessingTransaction;
|
||||||
|
import com.utsmm.kbz.util.enums.TransResultStatus;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class EmvTransactionProcessViewModel extends EmvBaseViewModel implements ProcessingTransaction {
|
||||||
|
|
||||||
|
|
||||||
|
private final Repository repository;
|
||||||
|
|
||||||
|
private static final String TAG = EmvTransactionProcessViewModel.class.getSimpleName();
|
||||||
|
private SingleLiveEvent<TransResultStatus> transResult = new SingleLiveEvent<>();
|
||||||
|
private static final String TRY_SECONDARY = "TRY_SECONDARY";
|
||||||
|
private static final String PIN_PAD_FAILED = "Pin pad failed";
|
||||||
|
private static final String PIN_PAD_TIMEOUT = "Pin pad timeout!";
|
||||||
|
private static final String RC_APPROVED_V1 = "00";
|
||||||
|
private static final String RC_APPROVED_V2 = "000";
|
||||||
|
private static final String REVERSAL = "REVERSAL";
|
||||||
|
|
||||||
|
private EmvOnlineResultEntity emvOnlineResult = new EmvOnlineResultEntity();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public EmvTransactionProcessViewModel(Repository repository,EmvParamOperation emvParamOperation) {
|
||||||
|
super(repository,emvParamOperation);
|
||||||
|
this.repository = repository;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handleMsg(Message msg) {
|
||||||
|
switch (msg.what) {
|
||||||
|
case PIN_CLICK_NUMBER:
|
||||||
|
showPasswordView(msg.arg1);
|
||||||
|
break;
|
||||||
|
case PIN_CLICK_CONFIRM:
|
||||||
|
// increasedKSN();
|
||||||
|
if (emvHandler == null) {
|
||||||
|
LogUtil.e(TAG, "Cannot handle PIN confirm - emvHandler is null");
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.ERROR);
|
||||||
|
errorCodeMsg.postValue("-1010:EMV Handler not available for PIN confirm");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
if (mPayDetail.PINCipher != null && !mPayDetail.PINCipher.isEmpty()) {
|
||||||
|
emvHandler.onSetPinInputResponse(true, false);
|
||||||
|
} else if (isOfflinePinEntered) {
|
||||||
|
emvHandler.onSetPinInputResponse(true, false);
|
||||||
|
} else {
|
||||||
|
emvHandler.onSetPinInputResponse(false, true);
|
||||||
|
}
|
||||||
|
if (transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE || transType.getValue() == TransactionsType.PRE_AUTH_VOID || transType.getValue() == TransactionsType.REFUND) {
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.ON_NEXT_SCREEN);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Exception during PIN confirm handling: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.ERROR);
|
||||||
|
errorCodeMsg.postValue("-1011:PIN confirm exception: " + e.getMessage());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIN_CLICK_CANCEL:
|
||||||
|
LogUtil.d(TAG, "ON CLICK CANCEL");
|
||||||
|
if (emvHandler == null) {
|
||||||
|
LogUtil.e(TAG, "Cannot handle PIN cancel - emvHandler is null");
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.ERROR);
|
||||||
|
errorCodeMsg.postValue("-1012:EMV Handler not available for PIN cancel");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
emvHandler.onSetPinInputResponse(false, false);
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.PIN_PAD_CANCEL);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Exception during PIN cancel handling: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.ERROR);
|
||||||
|
errorCodeMsg.postValue("-1013:PIN cancel exception: " + e.getMessage());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PIN_CLICK_CLEAR:
|
||||||
|
pinEnterCount = 0;
|
||||||
|
pinText.postValue("");
|
||||||
|
break;
|
||||||
|
case PIN_TIME_OUT:
|
||||||
|
handleTransactionFail(msg.arg1, PIN_PAD_TIMEOUT);
|
||||||
|
break;
|
||||||
|
case PIN_ERROR:
|
||||||
|
// increasedKSN();
|
||||||
|
// importPinInputStatus(3);
|
||||||
|
handleTransactionFail(msg.arg1, PIN_PAD_FAILED);
|
||||||
|
break;
|
||||||
|
case EMV_APP_SELECT:
|
||||||
|
String[] candiNames = (String[]) msg.obj;
|
||||||
|
candiList.postValue(candiNames);
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.SELECT_APP);
|
||||||
|
break;
|
||||||
|
case EMV_SIGNATURE:
|
||||||
|
if(SystemParamsOperation.getInstance().getUpiTCEnabled()) {
|
||||||
|
|
||||||
|
if(mPayDetail.getAmount() == 31300 || mPayDetail.getAmount() == 31400 || mPayDetail.getAmount() == 31600 || mPayDetail.getAmount() == 31700 || mPayDetail.getAmount() == 8100000) {
|
||||||
|
// importSignatureStatus(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(mPayDetail.getAmount() < (SystemParamsOperation.getInstance().getJcbCvmLimit()*100)){
|
||||||
|
// importSignatureStatus(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
mPayDetail.setIsFreeSign(false);
|
||||||
|
mPayDetail.setTransCVM( TransCVM.SIGNATURE);
|
||||||
|
// importSignatureStatus(0);
|
||||||
|
break;
|
||||||
|
case EMV_SHOW_PIN_PAD:
|
||||||
|
LogUtil.d(TAG,"msg1 "+msg.arg1 + "- msg2 :"+msg.arg2);
|
||||||
|
startPinProcess(msg.arg1);
|
||||||
|
// emvHandler.onSetPinInputResponse(true,false);
|
||||||
|
// if(transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE || transType.getValue() == TransactionsType.PRE_AUTH_VOID || transType.getValue() == TransactionsType.REFUND ) {
|
||||||
|
// emvResultStatus.postValue(EmvResultStatus.ON_NEXT_SCREEN);
|
||||||
|
// }
|
||||||
|
break;
|
||||||
|
case EMV_ONLINE_PROCESS:
|
||||||
|
handleTransactionProcess();
|
||||||
|
break;
|
||||||
|
case EMV_ERROR:
|
||||||
|
handleTransactionFail(msg.arg1, msg.obj.toString());
|
||||||
|
break;
|
||||||
|
case EMV_TRY_AGAIN:
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.TRY_AGAIN);
|
||||||
|
break;
|
||||||
|
case EMV_CONFIRM_CODE_VERIFY:
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.CONFIRM_CODE_VERIFY);
|
||||||
|
break;
|
||||||
|
case EMV_SUCCESS_ONLINE:
|
||||||
|
transResult.postValue(TransResultStatus.SUCCESS);
|
||||||
|
break;
|
||||||
|
case EMV_FAILURE_ONLINE:
|
||||||
|
transResult.postValue(TransResultStatus.FAIL);
|
||||||
|
break;
|
||||||
|
case EMV_SUCCESS_OFFLINE:
|
||||||
|
transResult.postValue(TransResultStatus.OFFLINE_SUCCESS);
|
||||||
|
break;
|
||||||
|
case EMV_FAILURE_OFFLINE:
|
||||||
|
transResult.postValue(TransResultStatus.OFFLINE_FAILURE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void onCancelEmvTransaction(){
|
||||||
|
|
||||||
|
LogUtil.e(TAG,"Terminate Transaction : "+ mProcessStep);
|
||||||
|
|
||||||
|
if (emvHandler == null) {
|
||||||
|
LogUtil.e(TAG, "Cannot cancel EMV transaction - emvHandler is null");
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.ERROR);
|
||||||
|
errorCodeMsg.postValue("-1008:EMV Handler not available for cancellation");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (mProcessStep == EMV_APP_SELECT) {
|
||||||
|
emvHandler.onSetSelAppResponse(-1);
|
||||||
|
} else if (mProcessStep == EMV_FINAL_APP_SELECT) {
|
||||||
|
emvHandler.onSetSelAppResponse(-1);
|
||||||
|
} else if (mProcessStep == EMV_CONFIRM_CARD_NO) {
|
||||||
|
emvHandler.onSetConfirmCardNoResponse(false);
|
||||||
|
} else if (mProcessStep == EMV_CERT_VERIFY) {
|
||||||
|
// importCertStatus(1);
|
||||||
|
} else if (mProcessStep == PIN_ERROR) {
|
||||||
|
emvHandler.onSetPinInputResponse(false, false);
|
||||||
|
} else if (mProcessStep == EMV_ONLINE_PROCESS) {
|
||||||
|
importOnlineProcess(SdkResult.Success, new EmvOnlineResultEntity());
|
||||||
|
} else if (mProcessStep == EMV_SIGNATURE) {
|
||||||
|
// importSignatureStatus(1);
|
||||||
|
} else if (mProcessStep == EMV_SHOW_PIN_PAD) {
|
||||||
|
emvHandler.onSetPinInputResponse(false, false);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.e(TAG, "Exception during EMV transaction cancellation: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.ERROR);
|
||||||
|
errorCodeMsg.postValue("-1009:EMV cancellation exception: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPayDetail(PayDetail payDetail) {
|
||||||
|
mPayDetail = payDetail;
|
||||||
|
mTradeData = new TradeData();
|
||||||
|
mTradeData.setPayDetail(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PayDetail getPayDetail() {
|
||||||
|
return mPayDetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetProcessStepCount() {
|
||||||
|
mProcessStep = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetTransactionStatus() {
|
||||||
|
emvResultStatus.clear();
|
||||||
|
transResult.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SingleLiveEvent<TransResultStatus> getTransStatus() {
|
||||||
|
return transResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isCardLessTrans() {
|
||||||
|
return transType.getValue() == TransactionsType.VOID || transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE_VOID || transType.getValue() == TransactionsType.PRE_AUTH_VOID || transType.getValue() == TransactionsType.REFUND;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void startOnlineProcess() {
|
||||||
|
|
||||||
|
isReversal = false;
|
||||||
|
|
||||||
|
TransactionsOperation.getInstance().getStartOperation(mTradeData, transType.getValue()).checkOperation(new TransactionsOperationListener() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(TradeData tradeData) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*Jun 15 2022*/
|
||||||
|
PayDetail payDetailRes = tradeData.getPayDetail();
|
||||||
|
|
||||||
|
payDetailRes.setInvoiceNo(SystemParamsOperation.getInstance().getIncrementInvoiceNum());
|
||||||
|
LogUtil.d(TAG,"Transaction Operation Success: "+payDetailRes.getTradeAnswerCode());
|
||||||
|
LogUtil.d(TAG,"Transaction Type: "+payDetailRes.getTransactionType());
|
||||||
|
|
||||||
|
if (TextUtils.equals(payDetailRes.getTradeAnswerCode(), RC_APPROVED_V1) || TextUtils.equals(payDetailRes.getTradeAnswerCode(), RC_APPROVED_V2) ) {
|
||||||
|
|
||||||
|
if (transType.getValue() == TransactionsType.VOID) {
|
||||||
|
processVoidDB(payDetailRes);
|
||||||
|
} else if (transType.getValue() == TransactionsType.REFUND) {
|
||||||
|
processRefundDB(payDetailRes);
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_VOID) {
|
||||||
|
processPreVoidDb(payDetailRes);
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE) {
|
||||||
|
processPreCompDb(payDetailRes);
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE_VOID) {
|
||||||
|
processPreCompVoidDb(payDetailRes);
|
||||||
|
} else {
|
||||||
|
insertDB(payDetailRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
payDetailResult.setValue(payDetailRes);
|
||||||
|
|
||||||
|
if(isCardLessTrans()) {
|
||||||
|
transResult.setValue(TransResultStatus.SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
payDetailResult.setValue(payDetailRes);
|
||||||
|
|
||||||
|
if(isCardLessTrans()) {
|
||||||
|
transResult.setValue(TransResultStatus.FAIL);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* @Note
|
||||||
|
* changed import status 2 to 0 at March 20, 2023
|
||||||
|
*/
|
||||||
|
// importOnlineProcessStatus(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReversal(TradeData tradeData) {
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"<<<< On Reversal >>>>");
|
||||||
|
|
||||||
|
isReversal = true;
|
||||||
|
|
||||||
|
transResult.postValue(TransResultStatus.REVERSAL_PREPARE);
|
||||||
|
|
||||||
|
int reversalDelay = 15000;
|
||||||
|
if (SystemParamsOperation.getInstance().getReversalDelay() != null) {
|
||||||
|
if (!TextUtils.equals(SystemParamsOperation.getInstance().getReversalDelay(), "")) {
|
||||||
|
reversalDelay = Integer.parseInt(SystemParamsOperation.getInstance().getReversalDelay() + "000");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final Handler handler = new Handler(Looper.getMainLooper());
|
||||||
|
handler.postDelayed(() -> {
|
||||||
|
|
||||||
|
PayDetail payDetailReversal = tradeData.getPayDetail();
|
||||||
|
if (payDetailReversal.getTransactionType() == TransactionType.SALE || payDetailReversal.getTransactionType() == TransactionType.VOID || payDetailReversal.getTransactionType() == TransactionType.REFUND || payDetailReversal.getTransactionType() == TransactionType.PRE_SALE || payDetailReversal.getTransactionType() == TransactionType.CASH_ADVANCE || payDetailReversal.getTransactionType() == TransactionType.PRE_SALE_CANCEL || payDetailReversal.getTransactionType() == TransactionType.PRE_SALE_COMPLETE || payDetailReversal.getTransactionType() == TransactionType.PRE_SALE_COMPLETE_VOID) {
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.REVERSAL_PROCESS);
|
||||||
|
transResult.postValue(TransResultStatus.REVERSAL_PROCESS);
|
||||||
|
callReversal(tradeData);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.REVERSAL_FAIL);
|
||||||
|
transResult.postValue(TransResultStatus.REVERSAL_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, reversalDelay);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(String message) {
|
||||||
|
LogUtil.e(TAG, "<<<< On Error >>>>");
|
||||||
|
LogUtil.e(TAG, "error message:" + message);
|
||||||
|
|
||||||
|
if (TextUtils.equals(message, TRY_SECONDARY)) {
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.SECONDARY);
|
||||||
|
transResult.postValue(TransResultStatus.SECONDARY);
|
||||||
|
startOnlineProcess();
|
||||||
|
} else {
|
||||||
|
importOnlineProcess(SdkResult.Fail,emvOnlineResult);
|
||||||
|
setNetWorkErrorDesc(message);
|
||||||
|
errorCodeMsg.setValue(message);
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.NETWORK_ERROR);
|
||||||
|
transResult.postValue(TransResultStatus.NETWORK_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startDemoProcess() {
|
||||||
|
SystemParamsOperation.getInstance().getIncrementInvoiceNum();
|
||||||
|
|
||||||
|
PayDetail payDetailRes;
|
||||||
|
|
||||||
|
if (transType.getValue() == TransactionsType.VOID) {
|
||||||
|
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoVoid(mPayDetail);
|
||||||
|
processVoidDB(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.REFUND) {
|
||||||
|
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoRefund(mPayDetail);
|
||||||
|
processRefundDB(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_VOID) {
|
||||||
|
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoPreAuthVoid(mPayDetail);
|
||||||
|
processPreVoidDb(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE) {
|
||||||
|
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoPreAuthComp(mPayDetail);
|
||||||
|
processPreCompDb(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE_VOID) {
|
||||||
|
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoPreAuthCompVoid(mPayDetail);
|
||||||
|
processPreCompVoidDb(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.CASH_OUT){
|
||||||
|
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoCashAdvance(mPayDetail, emvCardType.getValue());
|
||||||
|
repository.insertPayDetail(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.SALE){
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoSale(mPayDetail, emvCardType.getValue());
|
||||||
|
repository.insertPayDetail(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_SALE) {
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoPreAuthSale(mPayDetail, emvCardType.getValue());
|
||||||
|
repository.insertPayDetail(payDetailRes);
|
||||||
|
} else if (transType.getValue() == TransactionsType.TIP_ADJUSTMENT) {
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoTipAdjustment(mPayDetail);
|
||||||
|
repository.insertPayDetail(payDetailRes);
|
||||||
|
}else {
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoSale(mPayDetail, emvCardType.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
payDetailResult.setValue(payDetailRes);
|
||||||
|
|
||||||
|
transResult.setValue(TransResultStatus.SUCCESS);
|
||||||
|
importOnlineProcess(SdkResult.Success,new EmvOnlineResultEntity());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insertDB(PayDetail payResult) {
|
||||||
|
payResult.setPINCipher("");
|
||||||
|
repository.insertPayDetail(payResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processVoidDB(PayDetail payResult) {
|
||||||
|
mPayDetail.setIsCanceled(true);
|
||||||
|
updatePayDetail(mPayDetail);
|
||||||
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processPreVoidDb(PayDetail payResult) {
|
||||||
|
mPayDetail.setIsCanceled(true);
|
||||||
|
updatePayDetail(mPayDetail);
|
||||||
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processPreCompDb(PayDetail payResult) {
|
||||||
|
// mPayDetail.setIsSettle(true);
|
||||||
|
// mPayDetail.setIsCanceled(true);
|
||||||
|
// updatePayDetail(mPayDetail);
|
||||||
|
// repository.insertPayDetail(updateCurrentDateAndTime(payResult));
|
||||||
|
|
||||||
|
if(oldTransPayDetail.getAmount() == payResult.getAmount()) {
|
||||||
|
|
||||||
|
oldTransPayDetail.setIsCanceled(true);
|
||||||
|
updatePayDetail(oldTransPayDetail);
|
||||||
|
} else {
|
||||||
|
oldTransPayDetail.setIsCanceled(false);
|
||||||
|
updatePayDetail(oldTransPayDetail);
|
||||||
|
}
|
||||||
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processPreCompVoidDb(PayDetail payResult) {
|
||||||
|
mPayDetail.setIsCanceled(true);
|
||||||
|
updatePayDetail(mPayDetail);
|
||||||
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processRefundDB(PayDetail payResult) {
|
||||||
|
mPayDetail.setReturnGood(true);
|
||||||
|
updatePayDetail(mPayDetail);
|
||||||
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Need to await from host response , SDK called is a half in milliseconds faster than network called.
|
||||||
|
* if timeout setting is changed in terminal below code won't be work anymore... need to find out for other solutions.
|
||||||
|
* */
|
||||||
|
private void handleTransactionFail(int code, String description) {
|
||||||
|
|
||||||
|
final Handler handler = new Handler(Looper.getMainLooper());
|
||||||
|
handler.postDelayed(()-> {
|
||||||
|
LogUtil.d(TAG,"On handleTransactionFail ::");
|
||||||
|
if(isReversal) {
|
||||||
|
transResult.setValue(TransResultStatus.REVERSAL_PREPARE);
|
||||||
|
} else {
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.ERROR);
|
||||||
|
transResult.setValue(TransResultStatus.FAIL);
|
||||||
|
errorCodeMsg.postValue(code + ":" + description);
|
||||||
|
}
|
||||||
|
},500);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Online Process*/
|
||||||
|
private void handleTransactionProcess() {
|
||||||
|
|
||||||
|
String cardNo = mPayDetail.getCardNo();
|
||||||
|
// if (cardNo == null || TextUtils.equals(cardNo, "")) {
|
||||||
|
getCardInfo();
|
||||||
|
// }
|
||||||
|
getPayWaveData();
|
||||||
|
getF055Data();
|
||||||
|
if(transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE || transType.getValue() == TransactionsType.PRE_AUTH_VOID || transType.getValue() == TransactionsType.REFUND ) {
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.ON_NEXT_SCREEN);
|
||||||
|
} else {
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleTransactionProcessNex() {
|
||||||
|
|
||||||
|
Log.d("nexgo", "onOnlineProc");
|
||||||
|
|
||||||
|
Log.d("nexgo", "getEmvContactlessMode:" );
|
||||||
|
Log.d("nexgo", "getcardinfo:" + new Gson().toJson(emvHandler.getEmvCardDataInfo()));
|
||||||
|
Log.d("nexgo", "getEmvCvmResult:" + emvHandler.getEmvCvmResult());
|
||||||
|
Log.d("nexgo", "getSignNeed--" + emvHandler.getSignNeed());
|
||||||
|
|
||||||
|
byte[] tlv_5A = emvHandler.getTlv(new byte[]{(byte) 0x5A}, EmvDataSourceEnum.FROM_KERNEL);
|
||||||
|
Log.d("nexgo", "tlv_5A--" + ByteUtils.byteArray2HexString(tlv_5A));
|
||||||
|
|
||||||
|
byte[] tlv_95 = emvHandler.getTlv(new byte[]{(byte) 0x95}, EmvDataSourceEnum.FROM_KERNEL);
|
||||||
|
Log.d("nexgo", "tlv_95--" + ByteUtils.byteArray2HexString(tlv_95));
|
||||||
|
|
||||||
|
|
||||||
|
byte[] tlv_84 = emvHandler.getTlv(new byte[]{(byte) 0x84}, EmvDataSourceEnum.FROM_KERNEL);
|
||||||
|
Log.d("nexgo", "tlv_84--" + ByteUtils.byteArray2HexString(tlv_84));
|
||||||
|
|
||||||
|
byte[] tlv_50 = emvHandler.getTlv(new byte[]{(byte) 0x50}, EmvDataSourceEnum.FROM_KERNEL);
|
||||||
|
Log.d("nexgo", "tlv_50--" + ByteUtils.byteArray2HexString(tlv_50));
|
||||||
|
|
||||||
|
|
||||||
|
if(transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE || transType.getValue() == TransactionsType.PRE_AUTH_VOID || transType.getValue() == TransactionsType.REFUND ) {
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.ON_NEXT_SCREEN);
|
||||||
|
} else {
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void callReversal(TradeData tradeData) {
|
||||||
|
|
||||||
|
ReversalAction.getInstance().setData(tradeData).enqueue().startReversal(new ReversalListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSuccessReversal() {
|
||||||
|
|
||||||
|
importOnlineProcess(SdkResult.Fail,emvOnlineResult);
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.REVERSAL_SUCCESS);
|
||||||
|
transResult.postValue(TransResultStatus.REVERSAL_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNetworkFail(String msg) {
|
||||||
|
importOnlineProcess(SdkResult.Fail,emvOnlineResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailReversal(String msg) {
|
||||||
|
|
||||||
|
|
||||||
|
importOnlineProcess(SdkResult.Fail,emvOnlineResult);
|
||||||
|
|
||||||
|
if (!isSecondCall) {
|
||||||
|
if (!TextUtils.equals(msg, REVERSAL)) {
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.REVERSAL_SECONDARY);
|
||||||
|
transResult.postValue(TransResultStatus.REVERSAL_SECONDARY);
|
||||||
|
ISOSocket.getInstance().switchIp();
|
||||||
|
isSecondCall = true;
|
||||||
|
callReversal(tradeData);
|
||||||
|
} else {
|
||||||
|
mPayDetail.setNeedReversal(true);
|
||||||
|
mPayDetail.setTransactionType(TransactionType.REVERSAL);
|
||||||
|
mPayDetail.setTransType(REVERSAL);
|
||||||
|
mPayDetail.setPID(null);
|
||||||
|
// insert db
|
||||||
|
|
||||||
|
repository.insertPayDetail(mPayDetail);
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.REVERSAL_FAIL);
|
||||||
|
transResult.postValue(TransResultStatus.REVERSAL_FAIL);
|
||||||
|
|
||||||
|
isSecondCall = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mPayDetail.setNeedReversal(true);
|
||||||
|
mPayDetail.setTransactionType(TransactionType.REVERSAL);
|
||||||
|
mPayDetail.setTransType(REVERSAL);
|
||||||
|
mPayDetail.setPID(null);
|
||||||
|
// insert db
|
||||||
|
repository.insertPayDetail(mPayDetail);
|
||||||
|
emvResultStatus.postValue(EmvResultStatus.REVERSAL_FAIL);
|
||||||
|
transResult.postValue(TransResultStatus.REVERSAL_FAIL);
|
||||||
|
isSecondCall = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,138 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.ui.NumberKeyboard;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
|
||||||
|
import java.text.DecimalFormat;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public class InputAmountViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private static final String TAG = InputAmountViewModel.class.getSimpleName();
|
||||||
|
|
||||||
|
public MutableLiveData<String> inputAmountView = new MutableLiveData<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> invalidAmountMsg = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> availableAmount = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
|
||||||
|
public InputAmountViewModel() {
|
||||||
|
inputAmountView.setValue("0");
|
||||||
|
}
|
||||||
|
|
||||||
|
private int countDecimalDigits(double number) {
|
||||||
|
String numberStr = Double.toString(number);
|
||||||
|
int decimalIndex = numberStr.indexOf('.');
|
||||||
|
return decimalIndex >= 0 ? numberStr.length() - decimalIndex - 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public NumberKeyboard.KeyClickCallback onKeyClick() {
|
||||||
|
return new NumberKeyboard.KeyClickCallback() {
|
||||||
|
@Override
|
||||||
|
public void onNumClick(int keyNum) {
|
||||||
|
|
||||||
|
if (inputAmountView.getValue().length() == 15) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TextUtils.equals(inputAmountView.getValue(), "0")) {
|
||||||
|
inputAmountView.setValue(keyNum + "");
|
||||||
|
} else if (inputAmountView.getValue().contains(".")) {
|
||||||
|
StringBuilder inputAmount = new StringBuilder();
|
||||||
|
inputAmount.append(inputAmountView.getValue());
|
||||||
|
|
||||||
|
int dotIndex = inputAmount.indexOf(".");
|
||||||
|
|
||||||
|
if(inputAmount.substring(dotIndex).length() > 0 && inputAmount.substring(dotIndex+1).length() == 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inputAmountView.getValue().contains(",")) {
|
||||||
|
inputAmountView.setValue(inputAmountView.getValue().replace(",", ""));
|
||||||
|
}
|
||||||
|
double amt = Double.parseDouble(inputAmountView.getValue());
|
||||||
|
if (countDecimalDigits(amt) < 2) {
|
||||||
|
inputAmountView.setValue(inputAmountView.getValue() + keyNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (inputAmountView.getValue().contains(",")) {
|
||||||
|
inputAmountView.setValue(inputAmountView.getValue().replace(",", ""));
|
||||||
|
}
|
||||||
|
inputAmountView.setValue(inputAmountView.getValue() + keyNum);
|
||||||
|
double amt = Double.parseDouble(inputAmountView.getValue());
|
||||||
|
DecimalFormat formatter = new DecimalFormat("#,###");
|
||||||
|
inputAmountView.setValue(formatter.format(amt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDelClick() {
|
||||||
|
if (Objects.requireNonNull(inputAmountView.getValue()).contains(".")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (inputAmountView.getValue().length() == 15) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (TextUtils.equals(inputAmountView.getValue(), "0")) {
|
||||||
|
inputAmountView.setValue("0.");
|
||||||
|
} else {
|
||||||
|
|
||||||
|
inputAmountView.setValue(inputAmountView.getValue() + ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCleanClick() {
|
||||||
|
if (inputAmountView.getValue() != null) {
|
||||||
|
if (inputAmountView.getValue().contains(".")) {
|
||||||
|
StringBuilder inputAmount = new StringBuilder();
|
||||||
|
inputAmount.append(inputAmountView.getValue());
|
||||||
|
inputAmount.deleteCharAt(inputAmount.length() - 1);
|
||||||
|
inputAmountView.setValue(inputAmount.toString());
|
||||||
|
} else if (!inputAmountView.getValue().equals("0")) {
|
||||||
|
StringBuilder inputAmount = new StringBuilder();
|
||||||
|
inputAmount.append(inputAmountView.getValue());
|
||||||
|
if (inputAmount.length() > 4) {
|
||||||
|
|
||||||
|
if(inputAmount.toString().contains(",")) {
|
||||||
|
int commaIndex = inputAmount.indexOf(",");
|
||||||
|
inputAmount.deleteCharAt(commaIndex);
|
||||||
|
} else {
|
||||||
|
inputAmount.deleteCharAt(inputAmount.length() - 1);
|
||||||
|
}
|
||||||
|
inputAmountView.setValue(inputAmount.toString());
|
||||||
|
|
||||||
|
|
||||||
|
// inputAmount.deleteCharAt(inputAmount.toString().length() - 4);
|
||||||
|
// if (inputAmount.charAt(inputAmount.toString().length() - 4) == ',') {
|
||||||
|
// inputAmount.deleteCharAt(inputAmount.toString().length() - 4);
|
||||||
|
// }
|
||||||
|
// inputAmountView.setValue(inputAmount.toString());
|
||||||
|
} else if(inputAmount.length() == 1) {
|
||||||
|
inputAmountView.setValue("0");
|
||||||
|
} else {
|
||||||
|
StringBuilder currentAmount = new StringBuilder();
|
||||||
|
currentAmount.append(inputAmountView.getValue());
|
||||||
|
currentAmount.deleteCharAt(currentAmount.length() - 1);
|
||||||
|
inputAmountView.setValue(currentAmount.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.ui.NumberKeyboard;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
|
||||||
|
public class InputApprovalViewModel extends ViewModel {
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> inputApprovalView = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> txtApproval = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public InputApprovalViewModel(){
|
||||||
|
inputApprovalView.setValue("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public NumberKeyboard.KeyClickCallback onKeyClick(){
|
||||||
|
return new NumberKeyboard.KeyClickCallback() {
|
||||||
|
@Override
|
||||||
|
public void onNumClick(int keyNum) {
|
||||||
|
// if(inputApprovalView.getValue().length() == 12){
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
if (TextUtils.equals(inputApprovalView.getValue(),"-")){
|
||||||
|
inputApprovalView.setValue(keyNum + "");
|
||||||
|
} else {
|
||||||
|
inputApprovalView.setValue(inputApprovalView.getValue().replace("-","") + keyNum + "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDelClick() {
|
||||||
|
System.out.println("onDel");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCleanClick() {
|
||||||
|
if (inputApprovalView.getValue() != null) {
|
||||||
|
if (!inputApprovalView.getValue().equals("-")) {
|
||||||
|
StringBuilder inputCardNo = new StringBuilder();
|
||||||
|
inputCardNo.append(inputApprovalView.getValue());
|
||||||
|
if (inputCardNo.length() > 1) {
|
||||||
|
inputCardNo.deleteCharAt(inputCardNo.toString().length()-1);
|
||||||
|
inputApprovalView.setValue(inputCardNo.toString());
|
||||||
|
} else {
|
||||||
|
inputApprovalView.setValue("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.ui.NumberKeyboard;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
|
||||||
|
public class InputCardNoViewModel extends ViewModel {
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> inputCardView = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public InputCardNoViewModel(){
|
||||||
|
inputCardView.setValue("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public NumberKeyboard.KeyClickCallback onKeyClick(){
|
||||||
|
return new NumberKeyboard.KeyClickCallback() {
|
||||||
|
@Override
|
||||||
|
public void onNumClick(int keyNum) {
|
||||||
|
if(inputCardView.getValue().length() == 16){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (TextUtils.equals(inputCardView.getValue(),"-")){
|
||||||
|
inputCardView.setValue(keyNum + "");
|
||||||
|
} else {
|
||||||
|
inputCardView.setValue(inputCardView.getValue().replace("-","") + keyNum + "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDelClick() {
|
||||||
|
System.out.println("onDel");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCleanClick() {
|
||||||
|
if (inputCardView.getValue() != null) {
|
||||||
|
if (!inputCardView.getValue().equals("-")) {
|
||||||
|
StringBuilder inputCardNo = new StringBuilder();
|
||||||
|
inputCardNo.append(inputCardView.getValue());
|
||||||
|
if (inputCardNo.length() > 1) {
|
||||||
|
inputCardNo.deleteCharAt(inputCardNo.toString().length()-1);
|
||||||
|
inputCardView.setValue(inputCardNo.toString());
|
||||||
|
} else {
|
||||||
|
inputCardView.setValue("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,120 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.ui.NumberKeyboard;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmm.kbz.util.enums.InputPasswordType;
|
||||||
|
|
||||||
|
|
||||||
|
public class InputPasswordViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private static final String TAG = InputPasswordViewModel.class.getSimpleName();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> passwordInput = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public MutableLiveData<String> maskedPassword = new MutableLiveData<>();
|
||||||
|
|
||||||
|
private StringBuilder inputSB = new StringBuilder();
|
||||||
|
|
||||||
|
private static final int PASSWORD_LENGTH = 6;
|
||||||
|
|
||||||
|
public SingleLiveEvent<Boolean> checkValid = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<InputPasswordType> passwordType = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public InputPasswordViewModel() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public NumberKeyboard.KeyClickCallback onKeyClick() {
|
||||||
|
return new NumberKeyboard.KeyClickCallback() {
|
||||||
|
@Override
|
||||||
|
public void onNumClick(int keyNum) {
|
||||||
|
addText(keyNum + "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDelClick() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCleanClick() {
|
||||||
|
delLast();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearInput() {
|
||||||
|
if (inputSB.length() > 0) {
|
||||||
|
inputSB.delete(0, inputSB.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addText(String text) {
|
||||||
|
if (inputSB.length() == PASSWORD_LENGTH) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
inputSB.append(text);
|
||||||
|
maskedPassword.setValue(convertMaskedChar(inputSB.length()));
|
||||||
|
passwordInput.setValue(inputSB.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String convertMaskedChar(int length) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
sb.append("*");
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void delLast() {
|
||||||
|
if (inputSB.length() == 0)
|
||||||
|
return;
|
||||||
|
inputSB.deleteCharAt(inputSB.length() - 1);
|
||||||
|
maskedPassword.setValue(convertMaskedChar(inputSB.length()));
|
||||||
|
passwordInput.setValue(inputSB.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onClickEnter() {
|
||||||
|
inputSB.setLength(0);
|
||||||
|
String password = "";
|
||||||
|
|
||||||
|
if (passwordType.getValue() == InputPasswordType.SETTLEMENT) {
|
||||||
|
password = SystemParamsOperation.getInstance().getSettlementPassword();
|
||||||
|
if (TextUtils.equals(password, "") || password == null) {
|
||||||
|
password = "123456";
|
||||||
|
}
|
||||||
|
} else if (passwordType.getValue() == InputPasswordType.SYSTEM) {
|
||||||
|
password = SystemParamsOperation.getInstance().getSystemPassword();
|
||||||
|
if (TextUtils.equals(password, "") || password == null) {
|
||||||
|
password = "111111";
|
||||||
|
}
|
||||||
|
} else if (passwordType.getValue() == InputPasswordType.SETTING) {
|
||||||
|
password = SystemParamsOperation.getInstance().getSettingPassword();
|
||||||
|
if (TextUtils.equals(password, "") || password == null) {
|
||||||
|
password = "222222";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (TextUtils.equals(passwordInput.getValue(), password)) {
|
||||||
|
|
||||||
|
checkValid.setValue(true);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
checkValid.setValue(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,84 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository;
|
||||||
|
import com.utsmyanmar.baselib.ui.NumberKeyboard;
|
||||||
|
import com.utsmyanmar.paylibs.Constant;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class InputRRNViewModel extends ViewModel {
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> inputRRNView = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> txtRRN = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
|
||||||
|
private final Repository repository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public InputRRNViewModel(Repository repository){
|
||||||
|
inputRRNView.setValue("");
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<PayDetail> searchPayDetail(String rrn) {
|
||||||
|
return repository.searchPayDetail(rrn);
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<PayDetail> searchPayDetail(String cardNo,String rrn) {
|
||||||
|
return repository.searchPayDetail(cardNo,rrn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public NumberKeyboard.KeyClickCallback onKeyClick(){
|
||||||
|
return new NumberKeyboard.KeyClickCallback() {
|
||||||
|
@Override
|
||||||
|
public void onNumClick(int keyNum) {
|
||||||
|
LogUtil.d(Constant.TAG,"key click"+keyNum);
|
||||||
|
if(inputRRNView.getValue().length() == 12){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (TextUtils.equals(inputRRNView.getValue(),"-")){
|
||||||
|
inputRRNView.setValue(keyNum + "");
|
||||||
|
} else {
|
||||||
|
inputRRNView.setValue(inputRRNView.getValue().replace("-","") + keyNum + "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDelClick() {
|
||||||
|
System.out.println("onDel");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCleanClick() {
|
||||||
|
if (inputRRNView.getValue() != null) {
|
||||||
|
if (!inputRRNView.getValue().equals("-")) {
|
||||||
|
StringBuilder inputCardNo = new StringBuilder();
|
||||||
|
inputCardNo.append(inputRRNView.getValue());
|
||||||
|
if (inputCardNo.length() > 1) {
|
||||||
|
inputCardNo.deleteCharAt(inputCardNo.toString().length()-1);
|
||||||
|
inputRRNView.setValue(inputCardNo.toString());
|
||||||
|
} else {
|
||||||
|
inputRRNView.setValue("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,61 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.ui.NumberKeyboard;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
|
||||||
|
public class InputTraceViewModel extends ViewModel {
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> inputTraceView = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public MutableLiveData<String> invoiceNo = new MutableLiveData<>("");
|
||||||
|
|
||||||
|
public InputTraceViewModel(){
|
||||||
|
inputTraceView.setValue("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public NumberKeyboard.KeyClickCallback onKeyClick(){
|
||||||
|
return new NumberKeyboard.KeyClickCallback() {
|
||||||
|
@Override
|
||||||
|
public void onNumClick(int keyNum) {
|
||||||
|
if(invoiceNo.getValue().length() >= 6){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (TextUtils.equals(invoiceNo.getValue(),"")){
|
||||||
|
invoiceNo.setValue(keyNum + "");
|
||||||
|
} else {
|
||||||
|
invoiceNo.setValue(invoiceNo.getValue() + keyNum + "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDelClick() {
|
||||||
|
System.out.println("onDel");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCleanClick() {
|
||||||
|
if (invoiceNo.getValue() != null) {
|
||||||
|
if (!invoiceNo.getValue().equals("")) {
|
||||||
|
StringBuilder inputCardNo = new StringBuilder();
|
||||||
|
inputCardNo.append(invoiceNo.getValue());
|
||||||
|
if (inputCardNo.length() > 0) {
|
||||||
|
inputCardNo.deleteCharAt(inputCardNo.toString().length()-1);
|
||||||
|
invoiceNo.setValue(inputCardNo.toString());
|
||||||
|
} else {
|
||||||
|
invoiceNo.setValue("");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
|
||||||
|
public class InputTransIdViewModel extends ViewModel {
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> txtTransId = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public InputTransIdViewModel(){
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,418 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusResponse;
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository;
|
||||||
|
import com.utsmyanmar.ecr.data.TransType;
|
||||||
|
import com.utsmyanmar.ecr.data.model.Transactions;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.print.printx.PrintXReceipt;
|
||||||
|
import com.utsmyanmar.paylibs.print.printx.PrintXStatus;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
import com.utsmyanmar.paylibs.utils.PrintStatus;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.util.enums.AccountType;
|
||||||
|
import com.utsmm.kbz.util.enums.SettlementType;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.TransMenu;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.HostType;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class SharedViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private static final String TAG = SharedViewModel.class.getSimpleName();
|
||||||
|
|
||||||
|
private final Repository repository;
|
||||||
|
|
||||||
|
public SingleLiveEvent<TransactionsType> transactionsType = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<SettlementType> settlementType = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<AccountType> accountType = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> amount = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<Long> totalAmount = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
|
||||||
|
// it is to use as manual entry
|
||||||
|
public SingleLiveEvent<String> cardNo = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> processCode = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<PayDetail> payDetail = new SingleLiveEvent<>();
|
||||||
|
public SingleLiveEvent<PrintStatus> printStatus = new SingleLiveEvent<>();
|
||||||
|
public SingleLiveEvent<String> merchantName = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> transactionName = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
/*Apr 28 2022*/
|
||||||
|
public SingleLiveEvent<List<PayDetail>> payDetailList = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
/*May 16 2022*/
|
||||||
|
public SingleLiveEvent<Boolean> isEcr = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> traceNo = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> rrNNo = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> approvalCode = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
/*May 31 2022*/
|
||||||
|
public SingleLiveEvent<Boolean> isEcrFinished = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
/*Jun 3 2022*/
|
||||||
|
public SingleLiveEvent<Boolean> isEmv = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
/*Jun 22 2022*/
|
||||||
|
public SingleLiveEvent<String> sendMsg = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> qrData = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> qrRefNum = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<TransType> ecrCMD = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
|
||||||
|
// for settlement and review batch
|
||||||
|
public final SingleLiveEvent<TransMenu> _transMenu = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> twoBtnLayout = new MutableLiveData<>(0);
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> oneBtnLayout = new MutableLiveData<>(8);
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> reprintBtnLayout = new MutableLiveData<>(8);
|
||||||
|
|
||||||
|
public SingleLiveEvent<Boolean> isReprint = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public Bitmap signBitmap;
|
||||||
|
|
||||||
|
public SingleLiveEvent<HostType> hostType = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> printReceiptButtons = new MutableLiveData<>(0);
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> printReceiptMsg = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> reprintTransTypeMsg = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<Transactions> ecrTrans = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Boolean> _manualEntryStatus = new MutableLiveData<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Boolean> fullVoidPreauthStatus = new MutableLiveData<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Boolean> partialVoidPreauthStatus = new MutableLiveData<>();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* separated PrintStatus as another variable to observe error stage.
|
||||||
|
* */
|
||||||
|
public SingleLiveEvent<PrintStatus> printXStatus = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
private final SingleLiveEvent<String> _errorFragmentMsg = new SingleLiveEvent<>();
|
||||||
|
private final SingleLiveEvent<String> _successFragmentMsg = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
private final SingleLiveEvent<String> _currencyText = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> tapCardStatus = new MutableLiveData<>(1);
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> tapDeviceStatus = new MutableLiveData<>(1);
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> insertCardStatus = new MutableLiveData<>(1);
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> swipeCardStatus = new MutableLiveData<>(0);
|
||||||
|
|
||||||
|
public MutableLiveData<String> countDownTxt = new MutableLiveData<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> mmqrLoading = new MutableLiveData<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> isMMPay = new MutableLiveData<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> isWavePay = new MutableLiveData<>();
|
||||||
|
public SingleLiveEvent<String> mockData = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> qrPayVisibility = new MutableLiveData<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> loadingView = new MutableLiveData<>(8);
|
||||||
|
public SingleLiveEvent<String> loadingMsg = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
private SingleLiveEvent<Boolean> isFallback = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
private SingleLiveEvent<Boolean> _isCardDataExist = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
private SingleLiveEvent<Boolean> _isAmountExist = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
private PayDetail mPayDetail = new PayDetail();
|
||||||
|
|
||||||
|
// Updated constructor for Hilt ViewModel
|
||||||
|
@Inject
|
||||||
|
public SharedViewModel(Repository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
setPrintStatus(PrintStatus.FIRST_PRINT);
|
||||||
|
isReprint.setValue(false);
|
||||||
|
cardNo.setValue("");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setEmvTrans(boolean status) {
|
||||||
|
isEmv.setValue(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SingleLiveEvent<Boolean> isEmvTrans() { return isEmv;}
|
||||||
|
|
||||||
|
private PayDetail getPayDetail() {
|
||||||
|
return mPayDetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setPayDetail(PayDetail payDetail) {
|
||||||
|
this.mPayDetail = payDetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisibilityPrintReceiptButtons(int value) {
|
||||||
|
printReceiptButtons.postValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransactionsType(TransactionsType transactionsType) {
|
||||||
|
this.transactionsType.setValue(transactionsType);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SingleLiveEvent<TransactionsType> getTransactionsType() {
|
||||||
|
return transactionsType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrintReceiptMsg(String msg) { this.printReceiptMsg.setValue(msg);}
|
||||||
|
public void postPrintReceiptMsg(String msg) { this.printReceiptMsg.postValue(msg);}
|
||||||
|
public void setPrintStatus(PrintStatus printStatus) { this.printStatus.setValue(printStatus); }
|
||||||
|
public void postPrintStatus(PrintStatus printStatus) { this.printStatus.postValue(printStatus); }
|
||||||
|
|
||||||
|
public SingleLiveEvent<PrintStatus> getPrintStatus() { return this.printStatus; }
|
||||||
|
|
||||||
|
public void setIsFallback(boolean status) { isFallback.setValue(status);}
|
||||||
|
|
||||||
|
public SingleLiveEvent<Boolean> getIsFallback() { return isFallback;}
|
||||||
|
|
||||||
|
public void setCardDataExist(boolean exist) { _isCardDataExist.setValue(exist);}
|
||||||
|
|
||||||
|
public SingleLiveEvent<Boolean> getCardDataExist() { return _isCardDataExist; }
|
||||||
|
|
||||||
|
public void setAmountExist(boolean exist) { _isAmountExist.setValue(exist);}
|
||||||
|
|
||||||
|
public SingleLiveEvent<Boolean> getAmountExist() { return _isAmountExist; }
|
||||||
|
|
||||||
|
|
||||||
|
public MutableLiveData<Boolean> getManualEntryStatus() { return _manualEntryStatus;}
|
||||||
|
|
||||||
|
public void setManualEntryStatus(boolean status) {
|
||||||
|
_manualEntryStatus.setValue(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> getErrorFragmentMsg() {
|
||||||
|
return _errorFragmentMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set_errorFragmentMsg(String msg) {
|
||||||
|
this._errorFragmentMsg.setValue(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> getSuccessFragmentMsg() {
|
||||||
|
return _successFragmentMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set_currencyText(String msg) { this._currencyText.setValue(msg);}
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> get_currencyText() { return _currencyText; }
|
||||||
|
|
||||||
|
public void set_successFragmentMsg(String msg) { this._successFragmentMsg.setValue(msg);}
|
||||||
|
public SingleLiveEvent<TransMenu> getTransMenu() {
|
||||||
|
return _transMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTransMenu(TransMenu transMenu) {
|
||||||
|
this._transMenu.setValue(transMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void loadingMsg(String msg) {
|
||||||
|
loadingView.setValue(0);
|
||||||
|
loadingMsg.setValue(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dismissLoadingMsg() {
|
||||||
|
loadingView.setValue(8);
|
||||||
|
loadingMsg.setValue("");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<SiriusResponse> getParams(SiriusRequest siriusRequest) {
|
||||||
|
return repository.getParams(siriusRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printReceipt(boolean isMerchantCopy) {
|
||||||
|
PrintXReceipt.getInstance().printSmileReceipt(payDetail.getValue(), isMerchantCopy, new PrintXStatus() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess() {
|
||||||
|
|
||||||
|
if(isMerchantCopy) {
|
||||||
|
|
||||||
|
if(!SystemParamsOperation.getInstance().getDemoStatus()) {
|
||||||
|
if(SystemParamsOperation.getInstance().getPrintISOStatus()) {
|
||||||
|
PrintXReceipt.getInstance().printSmileISoReceipt(payDetail.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
postPrintStatus(PrintStatus.FIRST_PRINT_DONE);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
setPrintStatus(PrintStatus.SECOND_PRINT_DONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure() {
|
||||||
|
LogUtil.d(TAG,"Print Status Result Failure!");
|
||||||
|
printXStatus.postValue(PrintStatus.EMPTY_PAPER_ROLL);
|
||||||
|
printReceiptButtons.postValue(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void startPrintReceipt(boolean isFirstPrint) {
|
||||||
|
/*
|
||||||
|
* First Print is Merchant Copy..
|
||||||
|
* */
|
||||||
|
|
||||||
|
if(payDetail.getValue() != null) {
|
||||||
|
setPayDetail(payDetail.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"PayDetail trade Answer Code :"+getPayDetail().getTradeAnswerCode());
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"PayDetail trade Answer Code :"+payDetail.getValue().getTradeAnswerCode());
|
||||||
|
|
||||||
|
PrintXReceipt.getInstance().printSmileReceipt(getPayDetail(), isFirstPrint, new PrintXStatus() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess() {
|
||||||
|
|
||||||
|
if(isFirstPrint) {
|
||||||
|
|
||||||
|
if(!SystemParamsOperation.getInstance().getDemoStatus()) {
|
||||||
|
if(SystemParamsOperation.getInstance().getPrintISOStatus()) {
|
||||||
|
PrintXReceipt.getInstance().printSmileISoReceipt(getPayDetail());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
postPrintStatus(PrintStatus.FIRST_PRINT_DONE);
|
||||||
|
|
||||||
|
if(isEcr.getValue() != null &&
|
||||||
|
isEcr.getValue() &&
|
||||||
|
SystemParamsOperation.getInstance().isAutoPrintCustomerCopy()) {
|
||||||
|
printReceiptButtons.postValue(8);
|
||||||
|
} else {
|
||||||
|
printReceiptButtons.postValue(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
postPrintStatus(PrintStatus.SECOND_PRINT_DONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure() {
|
||||||
|
LogUtil.d(TAG,"Print Status Result Failure!");
|
||||||
|
if (isFirstPrint) {
|
||||||
|
setPrintStatus(PrintStatus.EMPTY_PAPER_ROLL_FIRST);
|
||||||
|
} else {
|
||||||
|
setPrintStatus(PrintStatus.EMPTY_PAPER_ROLL_SECOND);
|
||||||
|
}
|
||||||
|
printReceiptButtons.postValue(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
public void startPrintProcess() {
|
||||||
|
LogUtil.d(TAG,"Print status :"+getPrintStatus().getValue());
|
||||||
|
switch (getPrintStatus().getValue()) {
|
||||||
|
case FIRST_PRINT:
|
||||||
|
|
||||||
|
printReceipt(true);
|
||||||
|
printReceiptMsg.postValue("Printing Receipt for Merchant");
|
||||||
|
printReceiptButtons.postValue(8);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SECOND_PRINT:
|
||||||
|
printReceipt(false);
|
||||||
|
printReceiptMsg.postValue("Printing Receipt for Customer");
|
||||||
|
|
||||||
|
|
||||||
|
break;
|
||||||
|
case NOT_PRINT:
|
||||||
|
// LogUtil.d(TAG, "Customer declined to print receipt");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void startPrintProcessSettlement() {
|
||||||
|
|
||||||
|
if(payDetail.getValue() == null) return;
|
||||||
|
|
||||||
|
PrintXReceipt.getInstance().printSmileSettlementReport(payDetail.getValue(), new PrintXStatus() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure() {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
/*POS */
|
||||||
|
// PrintReceipt.getInstance().printSettlementReceiptPOS(settleData.getSaleCount(), settleData.getSaleAmount(), settleData.getRefundCount(), settleData.getRefundAmount(), settleData.getPreAuthCount(), settleData.getPreAuthAmount(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public LiveData<List<PayDetail>> getLastThreeTransactions() {
|
||||||
|
return repository.getLastThreeTransactions();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public LiveData<PayDetail> getReversalTransaction(String voucherNo) {
|
||||||
|
return repository.getReversalTransaction(voucherNo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePayDetail(PayDetail payDetail){
|
||||||
|
repository.updatePayDetail(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertPayDetail(PayDetail payDetail) { repository.insertPayDetail(payDetail); }
|
||||||
|
|
||||||
|
|
||||||
|
public void enableCardStatusIcon(boolean tapCard,boolean tapDevice,boolean insertCard, boolean swipeCard) {
|
||||||
|
tapCardStatus.setValue(tapCard ? 1 : 0);
|
||||||
|
tapDeviceStatus.setValue(tapDevice ? 1 : 0);
|
||||||
|
insertCardStatus.setValue(insertCard ? 1 : 0);
|
||||||
|
swipeCardStatus.setValue(swipeCard ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,82 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.emv.EmvParamOperation;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusResponse;
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository;
|
||||||
|
import com.utsmyanmar.baselib.repo.TMSRepository;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
import com.utsmm.kbz.util.enums.TMSDownloadStatus;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.core.Maybe;
|
||||||
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class TMSProcessViewModel extends ViewModel {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private final EmvParamOperation emvParamOperation;
|
||||||
|
|
||||||
|
private final TMSRepository tmsRepository;
|
||||||
|
|
||||||
|
private final Repository repository;
|
||||||
|
|
||||||
|
private SingleLiveEvent<TMSDownloadStatus> tmsDownloadStatus = new SingleLiveEvent<>();
|
||||||
|
private SingleLiveEvent<String> tmsDownloadMsg = new SingleLiveEvent<>();
|
||||||
|
private SingleLiveEvent<Boolean> isCalled = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public TMSProcessViewModel(EmvParamOperation emvParamOperation,TMSRepository tmsRepository,Repository repository) {
|
||||||
|
this.emvParamOperation = emvParamOperation;
|
||||||
|
this.tmsRepository = tmsRepository;
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> getTmsDownloadMsg() {
|
||||||
|
return tmsDownloadMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTmsDownloadMsg(String tmsDownloadMsg) {
|
||||||
|
this.tmsDownloadMsg.setValue(tmsDownloadMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SingleLiveEvent<Boolean> getIsCalled() {
|
||||||
|
return isCalled;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setIsCalled(boolean status) {
|
||||||
|
isCalled.setValue(status);
|
||||||
|
}
|
||||||
|
public SingleLiveEvent<TMSDownloadStatus> getTmsDownloadStatus() {
|
||||||
|
return tmsDownloadStatus;
|
||||||
|
}
|
||||||
|
public void setTmsDownloadStatus(TMSDownloadStatus tmsDownloadStatus) {
|
||||||
|
this.tmsDownloadStatus.setValue(tmsDownloadStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<SiriusResponse> getParams(SiriusRequest siriusRequest) {
|
||||||
|
return tmsRepository.getParams(siriusRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Maybe<PayDetail> getLastTransactionRx() {
|
||||||
|
return repository.getLastTransactionRx();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void loadEmvParameters() {
|
||||||
|
emvParamOperation.loadAidRids();
|
||||||
|
emvParamOperation.loadEmvTerminalParam();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmvParamOperation getEmvParamOperation() {
|
||||||
|
return emvParamOperation;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,424 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.databinding.BindingAdapter;
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.model.TradeData;
|
||||||
|
import com.utsmyanmar.paylibs.network.ISOSocket;
|
||||||
|
import com.utsmyanmar.paylibs.reversal.ReversalAction;
|
||||||
|
import com.utsmyanmar.paylibs.reversal.ReversalListener;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
import com.utsmyanmar.paylibs.system.SystemDateTime;
|
||||||
|
import com.utsmyanmar.paylibs.transactions.TransactionsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.transactions.TransactionsOperationListener;
|
||||||
|
import com.utsmyanmar.paylibs.utils.DemoUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.PrintStatus;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionType;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.transactions.ProcessingTransaction;
|
||||||
|
import com.utsmm.kbz.util.enums.TransResultStatus;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class TransProcessViewModel extends ViewModel implements ProcessingTransaction {
|
||||||
|
|
||||||
|
private static final String TAG = TransProcessViewModel.class.getSimpleName();
|
||||||
|
|
||||||
|
private String pan;
|
||||||
|
|
||||||
|
private TradeData tradeData;
|
||||||
|
public PayDetail payDetail;
|
||||||
|
|
||||||
|
private static final String RC_APPROVED_V1 = "00";
|
||||||
|
private static final String RC_APPROVED_V2 = "000";
|
||||||
|
|
||||||
|
private static final String TRY_SECONDARY = "TRY_SECONDARY";
|
||||||
|
private static final String REVERSAL = "REVERSAL";
|
||||||
|
|
||||||
|
private boolean isSecondCall = false;
|
||||||
|
private boolean isThirdCall = false;
|
||||||
|
|
||||||
|
|
||||||
|
/* PIN CHANGE ISSUE RETRY PIN MISMATCH*/
|
||||||
|
|
||||||
|
|
||||||
|
private SingleLiveEvent<TransResultStatus> transResultStatus = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<TransactionsType> transType = new SingleLiveEvent<>();
|
||||||
|
public SingleLiveEvent<PrintStatus> printStatus = new SingleLiveEvent<>();
|
||||||
|
public SingleLiveEvent<PayDetail> payDetailResult = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> errorMessage = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
private final Repository repository;
|
||||||
|
|
||||||
|
private PayDetail oldTransPayDetail;
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public TransProcessViewModel(Repository repository) {
|
||||||
|
printStatus.setValue(PrintStatus.FIRST_PRINT);
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePayDetail(PayDetail payDetail) {
|
||||||
|
repository.updatePayDetail(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deletePayDetail(PayDetail payDetail) {
|
||||||
|
repository.deletePayDetail(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("layoutMarginTop")
|
||||||
|
public static void setLayoutMarginTop(View view, float dimen) {
|
||||||
|
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
|
||||||
|
layoutParams.topMargin = (int) dimen;
|
||||||
|
view.setLayoutParams(layoutParams);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void setTradeData(TradeData tradeData) {
|
||||||
|
this.tradeData = tradeData;
|
||||||
|
payDetail = tradeData.getPayDetail();
|
||||||
|
pan = payDetail.getCardNo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeData getTradeData() {
|
||||||
|
return tradeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPayDetail(PayDetail payDetail) {
|
||||||
|
this.payDetail = payDetail;
|
||||||
|
tradeData = new TradeData();
|
||||||
|
tradeData.setPayDetail(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOldTransPayDetail(PayDetail payDetail) {
|
||||||
|
this.oldTransPayDetail = payDetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PayDetail getPayDetail() {
|
||||||
|
return payDetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resetTransactionStatus() {
|
||||||
|
transResultStatus = new SingleLiveEvent<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SingleLiveEvent<TransResultStatus> getTransStatus() {
|
||||||
|
return transResultStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startOnlineProcess() {
|
||||||
|
TransactionsOperation.getInstance().getStartOperation(tradeData, transType.getValue()).checkOperation(new TransactionsOperationListener() {
|
||||||
|
@Override
|
||||||
|
public void onSuccess(TradeData TradeData) {
|
||||||
|
|
||||||
|
PayDetail payDetailRes = TradeData.getPayDetail();
|
||||||
|
LogUtil.d(TAG,"Transaction Operation Success: "+payDetailRes.getTradeAnswerCode());
|
||||||
|
if (TextUtils.equals(payDetailRes.getTradeAnswerCode(),RC_APPROVED_V1) || TextUtils.equals(payDetailRes.getTradeAnswerCode(),RC_APPROVED_V2)) {
|
||||||
|
|
||||||
|
payDetailRes.setInvoiceNo(SystemParamsOperation.getInstance().getIncrementInvoiceNum());
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"MPU Transaction type :"+transType.getValue());
|
||||||
|
|
||||||
|
if (transType.getValue() == TransactionsType.VOID) {
|
||||||
|
|
||||||
|
// dbUpdateForVoid(payDetailRes);
|
||||||
|
processVoidDB(payDetailRes);
|
||||||
|
} else if (transType.getValue() == TransactionsType.REFUND) {
|
||||||
|
|
||||||
|
// dbUpdateForRefund(payDetailRes);
|
||||||
|
processRefundDB(payDetailRes);
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_VOID) {
|
||||||
|
|
||||||
|
// dbUpdateForPreVoid(payDetailRes);
|
||||||
|
processPreVoidDb(payDetailRes);
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE) {
|
||||||
|
|
||||||
|
// dbUpdateForPreComp(payDetailRes);
|
||||||
|
processPreCompDb(payDetailRes);
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE_VOID) {
|
||||||
|
|
||||||
|
// dbUpdateForPreCompVoid(payDetailRes);
|
||||||
|
processPreCompVoidDb(payDetailRes);
|
||||||
|
} else {
|
||||||
|
// insertPayDetail(payDetailRes);
|
||||||
|
insertDB(payDetailRes);
|
||||||
|
|
||||||
|
}
|
||||||
|
payDetailResult.postValue(payDetailRes);
|
||||||
|
|
||||||
|
transResultStatus.postValue(TransResultStatus.SUCCESS);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
payDetailResult.postValue(payDetailRes);
|
||||||
|
|
||||||
|
transResultStatus.postValue(TransResultStatus.FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReversal(TradeData TradeData) {
|
||||||
|
|
||||||
|
transResultStatus.postValue(TransResultStatus.REVERSAL_PREPARE);
|
||||||
|
|
||||||
|
int reversalDelay = 15000;
|
||||||
|
if (SystemParamsOperation.getInstance().getReversalDelay() != null) {
|
||||||
|
if (!TextUtils.equals(SystemParamsOperation.getInstance().getReversalDelay(), "")) {
|
||||||
|
reversalDelay = Integer.parseInt(SystemParamsOperation.getInstance().getReversalDelay() + "000");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//call reversal
|
||||||
|
final Handler handler = new Handler(Looper.getMainLooper());
|
||||||
|
handler.postDelayed(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
//Do something after 100ms
|
||||||
|
PayDetail payDetailReversal = TradeData.getPayDetail();
|
||||||
|
if (payDetailReversal.getTransactionType() == TransactionType.SALE || payDetailReversal.getTransactionType() == TransactionType.VOID || payDetailReversal.getTransactionType() == TransactionType.REFUND || payDetailReversal.getTransactionType() == TransactionType.PRE_SALE || payDetailReversal.getTransactionType() == TransactionType.CASH_ADVANCE || payDetailReversal.getTransactionType() == TransactionType.PRE_SALE_CANCEL || payDetailReversal.getTransactionType() == TransactionType.PRE_SALE_COMPLETE || payDetailReversal.getTransactionType() == TransactionType.PRE_SALE_COMPLETE_VOID) {
|
||||||
|
transResultStatus.postValue(TransResultStatus.REVERSAL_PROCESS);
|
||||||
|
callReversal(TradeData);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
transResultStatus.postValue(TransResultStatus.REVERSAL_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}, reversalDelay);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(String message) {
|
||||||
|
if (TextUtils.equals(message, TRY_SECONDARY)) {
|
||||||
|
transResultStatus.postValue(TransResultStatus.SECONDARY);
|
||||||
|
startOnlineProcess();
|
||||||
|
} else {
|
||||||
|
errorMessage.postValue(message);
|
||||||
|
transResultStatus.postValue(TransResultStatus.ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startDemoProcess() {
|
||||||
|
SystemParamsOperation.getInstance().getIncrementInvoiceNum();
|
||||||
|
|
||||||
|
PayDetail payDetailRes;
|
||||||
|
|
||||||
|
if (transType.getValue() == TransactionsType.VOID) {
|
||||||
|
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoVoid(payDetail);
|
||||||
|
processVoidDB(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.REFUND) {
|
||||||
|
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoRefund(payDetail);
|
||||||
|
processRefundDB(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_VOID) {
|
||||||
|
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoPreAuthVoid(payDetail);
|
||||||
|
processPreVoidDb(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE) {
|
||||||
|
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoPreAuthComp(payDetail);
|
||||||
|
processPreCompDb(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE_VOID) {
|
||||||
|
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoPreAuthCompVoid(payDetail);
|
||||||
|
processPreCompVoidDb(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.CASH_OUT){
|
||||||
|
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoCashAdvance(payDetail, "MPU");
|
||||||
|
insertPayDetail(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.SALE){
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoSale(payDetail, "MPU");
|
||||||
|
insertPayDetail(payDetailRes);
|
||||||
|
|
||||||
|
} else if (transType.getValue() == TransactionsType.PRE_AUTH_SALE) {
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoPreAuthSale(payDetail, "MPU");
|
||||||
|
insertPayDetail(payDetailRes);
|
||||||
|
} else if (transType.getValue() == TransactionsType.TIP_ADJUSTMENT) {
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoTipAdjustment(payDetail);
|
||||||
|
insertPayDetail(payDetailRes);
|
||||||
|
}else {
|
||||||
|
payDetailRes = DemoUtil.getInstance().builtDemoSale(payDetail, "MPU");
|
||||||
|
}
|
||||||
|
|
||||||
|
payDetailResult.postValue(payDetailRes);
|
||||||
|
|
||||||
|
transResultStatus.postValue(TransResultStatus.SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insertDB(PayDetail payResult) {
|
||||||
|
payDetail.setPINCipher("");
|
||||||
|
repository.insertPayDetail(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processVoidDB(PayDetail payResult) {
|
||||||
|
payDetail.setIsCanceled(true);
|
||||||
|
updatePayDetail(payDetail);
|
||||||
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processPreVoidDb(PayDetail payResult) {
|
||||||
|
oldTransPayDetail.setIsCanceled(true);
|
||||||
|
updatePayDetail(oldTransPayDetail);
|
||||||
|
|
||||||
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processPreCompDb(PayDetail payResult) {
|
||||||
|
if(oldTransPayDetail.getAmount() == payResult.getAmount()) {
|
||||||
|
|
||||||
|
oldTransPayDetail.setIsCanceled(true);
|
||||||
|
updatePayDetail(oldTransPayDetail);
|
||||||
|
} else {
|
||||||
|
oldTransPayDetail.setIsCanceled(false);
|
||||||
|
updatePayDetail(oldTransPayDetail);
|
||||||
|
}
|
||||||
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processPreCompVoidDb(PayDetail payResult) {
|
||||||
|
payDetail.setIsCanceled(true);
|
||||||
|
updatePayDetail(payDetail);
|
||||||
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processRefundDB(PayDetail payResult) {
|
||||||
|
if(oldTransPayDetail != null) {
|
||||||
|
oldTransPayDetail.setReturnGood(true);
|
||||||
|
oldTransPayDetail.setIsCanceled(true);
|
||||||
|
updatePayDetail(oldTransPayDetail);
|
||||||
|
}
|
||||||
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void insertPayDetail(PayDetail payDetail) {
|
||||||
|
payDetail.setPINCipher("");
|
||||||
|
repository.insertPayDetail(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PayDetail updateCurrentDateAndTime(PayDetail payDetail) {
|
||||||
|
String strDate = SystemDateTime.getMMDD();
|
||||||
|
String strTime = SystemDateTime.getHHmmss();
|
||||||
|
payDetail.setTradeDate(strDate);
|
||||||
|
payDetail.setTradeTime(strTime);
|
||||||
|
return payDetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Didn't setup reversal Need to check codes 25 March 21*/
|
||||||
|
private void callReversal(TradeData tradeData) {
|
||||||
|
|
||||||
|
/* added Sep 1 , 2023
|
||||||
|
* cuz getting error at inserting to db
|
||||||
|
* Unique PID
|
||||||
|
* */
|
||||||
|
payDetail = tradeData.getPayDetail();
|
||||||
|
|
||||||
|
ReversalAction.getInstance().setData(tradeData).enqueue().startReversal(new ReversalListener() {
|
||||||
|
@Override
|
||||||
|
public void onSuccessReversal() {
|
||||||
|
transResultStatus.postValue(TransResultStatus.REVERSAL_SUCCESS);
|
||||||
|
repository.insertPayDetail(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNetworkFail(String msg) {
|
||||||
|
LogUtil.d(TAG,"Reversal Action :"+msg);
|
||||||
|
SystemParamsOperation.getInstance().setSecondHostEnable(true);
|
||||||
|
if (SystemParamsOperation.getInstance().isSecondHostEnabled()) {
|
||||||
|
if (!isSecondCall) {
|
||||||
|
|
||||||
|
transResultStatus.postValue(TransResultStatus.REVERSAL_SECONDARY);
|
||||||
|
ISOSocket.getInstance().switchIp();
|
||||||
|
isSecondCall = true;
|
||||||
|
callReversal(tradeData);
|
||||||
|
|
||||||
|
} else if(!isThirdCall) {
|
||||||
|
|
||||||
|
isThirdCall = true;
|
||||||
|
transResultStatus.postValue(TransResultStatus.REVERSAL_THIRD);
|
||||||
|
callReversal(tradeData);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
transResultStatus.postValue(TransResultStatus.REVERSAL_FAIL);
|
||||||
|
isSecondCall = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
transResultStatus.postValue(TransResultStatus.REVERSAL_FAIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
payDetail.setNeedReversal(true);
|
||||||
|
repository.insertPayDetail(payDetail);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailReversal(String msg) {
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"On Fail Reversal :"+msg);
|
||||||
|
|
||||||
|
isSecondCall = false;
|
||||||
|
isThirdCall = false;
|
||||||
|
transResultStatus.postValue(TransResultStatus.REVERSAL_FAIL);
|
||||||
|
payDetail.setNeedReversal(true);
|
||||||
|
repository.insertPayDetail(payDetail);
|
||||||
|
|
||||||
|
// 8-March-2024
|
||||||
|
payDetail.setTradeAnswerCode("");
|
||||||
|
payDetailResult.setValue(payDetail);
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package com.utsmm.kbz.ui.core_viewmodel.transactions;
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
import com.utsmm.kbz.util.enums.TransResultStatus;
|
||||||
|
|
||||||
|
public interface ProcessingTransaction {
|
||||||
|
|
||||||
|
void resetTransactionStatus();
|
||||||
|
SingleLiveEvent<TransResultStatus> getTransStatus();
|
||||||
|
void startOnlineProcess();
|
||||||
|
void startDemoProcess();
|
||||||
|
void insertDB(PayDetail payResult);
|
||||||
|
|
||||||
|
void processVoidDB(PayDetail payResult);
|
||||||
|
|
||||||
|
void processPreVoidDb(PayDetail payResult);
|
||||||
|
|
||||||
|
void processPreCompDb(PayDetail payResult);
|
||||||
|
|
||||||
|
void processPreCompVoidDb(PayDetail payResult);
|
||||||
|
|
||||||
|
void processRefundDB(PayDetail payResult);
|
||||||
|
}
|
||||||
@ -0,0 +1,89 @@
|
|||||||
|
package com.utsmm.kbz.ui.dashboard;
|
||||||
|
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingBottomSheetFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.MainViewModel;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
|
||||||
|
public class DashboardPreAuthBottomSheet extends DataBindingBottomSheetFragment {
|
||||||
|
|
||||||
|
|
||||||
|
private MainViewModel mainViewModel;
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
private static final int hostId = Constants.NAV_HOST_ID;
|
||||||
|
private int routeId;
|
||||||
|
private static final int currentId = R.id.dashboardPreAuthBottomSheet;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
mainViewModel = getFragmentScopeViewModel(MainViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_dashboard_bottom_sheet_pre_auth, BR.mainViewModel,mainViewModel)
|
||||||
|
.addBindingParam(BR.shareViewModel,sharedViewModel)
|
||||||
|
.addBindingParam(BR.click,new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
public void onClickBackButton() {
|
||||||
|
// routeId = R.id.action_dashboardPreAuthBottomSheet_to_dashboardBottomSheet;
|
||||||
|
// safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickPreAuthCancel() {
|
||||||
|
routeId = R.id.action_dashboardPreAuthBottomSheet_to_dashboardPreAuthCancelBottomSheet;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickPreAuth() {
|
||||||
|
if (mainViewModel.payDetailSingle.getValue() != null) {
|
||||||
|
mainViewModel.startReversal(mainViewModel.payDetailSingle.getValue());
|
||||||
|
} else if (checkTid()) {
|
||||||
|
showDeclineDialog("Please Download Config!");
|
||||||
|
} else {
|
||||||
|
sharedViewModel.transactionsType.setValue(TransactionsType.PRE_AUTH_SALE);
|
||||||
|
|
||||||
|
routeId = R.id.action_dashboardPreAuthBottomSheet_to_inputAmountFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickPreAuthComp() {
|
||||||
|
if (mainViewModel.payDetailSingle.getValue() != null) {
|
||||||
|
mainViewModel.startReversal(mainViewModel.payDetailSingle.getValue());
|
||||||
|
} else if (checkTid()) {
|
||||||
|
showDeclineDialog("Please Download Config!");
|
||||||
|
} else {
|
||||||
|
sharedViewModel.transactionsType.setValue(TransactionsType.PRE_AUTH_COMPLETE);
|
||||||
|
|
||||||
|
routeId = R.id.action_dashboardPreAuthBottomSheet_to_inputPasswordFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickPreAuthCompCancel() {
|
||||||
|
if (mainViewModel.payDetailSingle.getValue() != null) {
|
||||||
|
mainViewModel.startReversal(mainViewModel.payDetailSingle.getValue());
|
||||||
|
} else if (checkTid()) {
|
||||||
|
showDeclineDialog("Please Download Config!");
|
||||||
|
} else {
|
||||||
|
sharedViewModel.transactionsType.setValue(TransactionsType.PRE_AUTH_COMPLETE_VOID);
|
||||||
|
|
||||||
|
routeId = R.id.action_dashboardPreAuthBottomSheet_to_inputPasswordFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
package com.utsmm.kbz.ui.dashboard;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingBottomSheetFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.TransMenu;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.MainViewModel;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
|
||||||
|
public class DashboardPreAuthCancelBottomSheet extends DataBindingBottomSheetFragment {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private MainViewModel mainViewModel;
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
private int currentId = R.id.dashboardPreAuthCancelBottomSheet;
|
||||||
|
private int routeId;
|
||||||
|
private int hostId = Constants.NAV_HOST_ID;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
mainViewModel = getFragmentScopeViewModel(MainViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_dashboard_bottom_sheet_pre_auth_cancel,BR.mainViewModel,mainViewModel )
|
||||||
|
.addBindingParam(BR.sharedViewModel,sharedViewModel)
|
||||||
|
.addBindingParam(BR.click,new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
sharedViewModel.fullVoidPreauthStatus.setValue(SystemParamsOperation.getInstance().getFullVoidPreauthStatus());
|
||||||
|
sharedViewModel.partialVoidPreauthStatus.setValue(SystemParamsOperation.getInstance().getPartialVoidPreauthStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
public void onClickBack() {
|
||||||
|
routeId = R.id.action_dashboardPreAuthCancelBottomSheet_to_dashboardPreAuthBottomSheet;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickFullPreAuthVoid() {
|
||||||
|
|
||||||
|
if(sharedViewModel.fullVoidPreauthStatus.getValue() != null && !sharedViewModel.fullVoidPreauthStatus.getValue()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mainViewModel.payDetailSingle.getValue() != null) {
|
||||||
|
mainViewModel.startReversal(mainViewModel.payDetailSingle.getValue());
|
||||||
|
} else if (checkTid()) {
|
||||||
|
showDeclineDialog("Please Download Config!");
|
||||||
|
} else {
|
||||||
|
sharedViewModel.transactionsType.setValue(TransactionsType.PRE_AUTH_VOID);
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.PRE_AUTH_FULL_VOID);
|
||||||
|
sharedViewModel.amount.postValue(null);
|
||||||
|
|
||||||
|
routeId = R.id.action_dashboardPreAuthCancelBottomSheet_to_inputPasswordFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickPartialPreAuthVoid() {
|
||||||
|
|
||||||
|
if(sharedViewModel.partialVoidPreauthStatus.getValue() != null && !sharedViewModel.partialVoidPreauthStatus.getValue()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mainViewModel.payDetailSingle.getValue() != null) {
|
||||||
|
mainViewModel.startReversal(mainViewModel.payDetailSingle.getValue());
|
||||||
|
} else if (checkTid()) {
|
||||||
|
showDeclineDialog("Please Download Config!");
|
||||||
|
} else {
|
||||||
|
sharedViewModel.transactionsType.setValue(TransactionsType.PRE_AUTH_VOID);
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.PRE_AUTH_PARTIAL_VOID);
|
||||||
|
sharedViewModel.amount.postValue(null);
|
||||||
|
|
||||||
|
routeId = R.id.action_dashboardPreAuthCancelBottomSheet_to_inputPasswordFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,216 @@
|
|||||||
|
package com.utsmm.kbz.ui.dashboard;
|
||||||
|
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.utsmm.kbz.util.enums.SettlementType;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.TransMenu;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.MainViewModel;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.config.data.model.Features;
|
||||||
|
import com.utsmm.kbz.ui.adapters.MainAdapter;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.util.tms.TMSUtil;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class DashboardTransFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
|
||||||
|
private MainViewModel mainViewModel;
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
|
||||||
|
private ArrayList<Features> featuresList = new ArrayList<>();
|
||||||
|
|
||||||
|
MainAdapter mainAdapter;
|
||||||
|
|
||||||
|
private static final int hostId = Constants.NAV_HOST_ID;
|
||||||
|
private int routeId;
|
||||||
|
private static final int currentId = R.id.dashboardTransFragment;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.dashboardTransFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
mainViewModel = getFragmentScopeViewModel(MainViewModel.class);
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithBackIcon("Transactions");
|
||||||
|
initData();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData() {
|
||||||
|
TMSUtil.getInstance().checkFeaturesList(requireActivity(),featuresList);
|
||||||
|
mainAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
|
||||||
|
|
||||||
|
mainAdapter = new MainAdapter(featuresList, item -> {
|
||||||
|
|
||||||
|
switch (item.getFeaturesType()) {
|
||||||
|
|
||||||
|
case VOID:
|
||||||
|
new DashboardTransFragment.ClickEvent().onClickVoid();
|
||||||
|
break;
|
||||||
|
case SETTLEMENT:
|
||||||
|
new DashboardTransFragment.ClickEvent().onClickSettlement();
|
||||||
|
break;
|
||||||
|
case REFUND:
|
||||||
|
new DashboardTransFragment.ClickEvent().onClickRefund();
|
||||||
|
break;
|
||||||
|
case PRE_AUTH_SALE:
|
||||||
|
new DashboardTransFragment.ClickEvent().onClickPreAuth();
|
||||||
|
break;
|
||||||
|
case PRE_AUTH_VOID:
|
||||||
|
new DashboardTransFragment.ClickEvent().onClickPreAuthCancel();
|
||||||
|
break;
|
||||||
|
case PRE_AUTH_COMPLETE:
|
||||||
|
new DashboardTransFragment.ClickEvent().onClickPreAuthComp();
|
||||||
|
break;
|
||||||
|
case PRE_AUTH_COMPLETE_VOID:
|
||||||
|
new DashboardTransFragment.ClickEvent().onClickPreAuthCompCancel();
|
||||||
|
break;
|
||||||
|
case CASH_ADVANCE:
|
||||||
|
new DashboardTransFragment.ClickEvent().onClickCashAdvance();
|
||||||
|
break;
|
||||||
|
case HISTORY:
|
||||||
|
new DashboardTransFragment.ClickEvent().onClickHistory();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// RecyclerView recyclerView = ((DashboardTransBottomSheet) mBinding).getRoot().findViewById(R.id.recyclerViewFeatures);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return new DataBindingConfig(R.layout.fragment_dashboard_trans_screen, BR.vm,mainViewModel)
|
||||||
|
.addBindingParam(BR.shareViewModel,sharedViewModel)
|
||||||
|
.addBindingParam(BR.adapter, mainAdapter)
|
||||||
|
.addBindingParam(BR.click,new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
public void onClickVoid () {
|
||||||
|
if (mainViewModel.payDetailSingle.getValue() != null) {
|
||||||
|
mainViewModel.startReversal(mainViewModel.payDetailSingle.getValue());
|
||||||
|
} else if (checkTid()) {
|
||||||
|
showDeclineDialog("Please Download Config!");
|
||||||
|
} else {
|
||||||
|
sharedViewModel.setTransactionsType(TransactionsType.VOID);
|
||||||
|
// sharedViewModel.transMenu.postValue(TransMenu.TRANSACTIONS);
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.TRANSACTIONS);
|
||||||
|
|
||||||
|
routeId = R.id.action_dashboardTransFragment_to_inputPasswordFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickSettlement() {
|
||||||
|
sharedViewModel.settlementType.setValue(SettlementType.NORMAL);
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.SETTLEMENT);
|
||||||
|
sharedViewModel.setTransactionsType(TransactionsType.SETTLEMENT);
|
||||||
|
|
||||||
|
routeId = R.id.action_dashboardTransFragment_to_inputPasswordFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickRefund() {
|
||||||
|
sharedViewModel.setTransactionsType(TransactionsType.REFUND);
|
||||||
|
routeId = R.id.action_dashboardTransFragment_to_inputPasswordFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickPreAuth () {
|
||||||
|
if (mainViewModel.payDetailSingle.getValue() != null) {
|
||||||
|
mainViewModel.startReversal(mainViewModel.payDetailSingle.getValue());
|
||||||
|
} else if (checkTid()) {
|
||||||
|
showDeclineDialog("Please Download Config!");
|
||||||
|
} else {
|
||||||
|
sharedViewModel.setTransactionsType(TransactionsType.PRE_AUTH_SALE);
|
||||||
|
routeId = R.id.action_dashboardTransFragment_to_inputAmountFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickPreAuthCancel () {
|
||||||
|
sharedViewModel.setTransactionsType(TransactionsType.PRE_AUTH_VOID);
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.PRE_AUTH_FULL_VOID);
|
||||||
|
sharedViewModel.amount.postValue(null);
|
||||||
|
routeId = R.id.action_dashboardTransFragment_to_inputPasswordFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickPreAuthComp () {
|
||||||
|
sharedViewModel.setTransactionsType(TransactionsType.PRE_AUTH_COMPLETE);
|
||||||
|
routeId = R.id.action_dashboardTransFragment_to_inputPasswordFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickPreAuthCompCancel () {
|
||||||
|
sharedViewModel.setTransactionsType(TransactionsType.PRE_AUTH_COMPLETE_VOID);
|
||||||
|
routeId = R.id.action_dashboardTransFragment_to_inputPasswordFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void onClickCashAdvance() {
|
||||||
|
sharedViewModel.setTransactionsType(TransactionsType.CASH_OUT);
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.CASH_OUT);
|
||||||
|
routeId = R.id.action_dashboardTransFragment_to_inputAmountFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onClickHistory() {
|
||||||
|
routeId = R.id.action_dashboardTransFragment_to_manageFunctionFragment;
|
||||||
|
safeRouteTo(currentId,routeId,hostId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,170 @@
|
|||||||
|
package com.utsmm.kbz.ui.disabled;
|
||||||
|
|
||||||
|
import androidx.databinding.library.baseAdapters.BR;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
|
||||||
|
import com.google.gson.stream.MalformedJsonException;
|
||||||
|
import com.utsmyanmar.baselib.emv.EmvParamOperation;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusResponse;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
//import com.utsmyanmar.samlsirius.LogOutCallback;
|
||||||
|
//import com.utsmyanmar.samlsirius.SiriusLifeCycleObserver;
|
||||||
|
import com.utsmm.kbz.MainViewModel;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.config.data.model.TMSUpdate;
|
||||||
|
import com.utsmm.kbz.util.tms.TMSUtil;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@AndroidEntryPoint
|
||||||
|
public class DisabledTerminalFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private static final String TAG = DisabledTerminalFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private MainViewModel mainViewModel;
|
||||||
|
private int routeId = R.id.action_disabledTerminalFragment_to_nav_main;
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public EmvParamOperation emvParamOperation;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
mainViewModel = getFragmentScopeViewModel(MainViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStart() {
|
||||||
|
super.onStart();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithoutBackIcon(getString(R.string.menu_disabled));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_disable_terminal, BR.mainViewModel,mainViewModel)
|
||||||
|
.addBindingParam(BR.click,new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.disabledTerminalFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getLastTrans() {
|
||||||
|
LogUtil.d(TAG,"This function was called!!!");
|
||||||
|
mainViewModel.getLastTransaction().observe(getViewLifecycleOwner(), new Observer<PayDetail>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(PayDetail payDetail) {
|
||||||
|
if(payDetail != null) {
|
||||||
|
downloadParams(payDetail.getTransType(),String.valueOf(payDetail.getTransNum()));
|
||||||
|
} else {
|
||||||
|
|
||||||
|
String lastTransName = SystemParamsOperation.getInstance().getLastTransName();
|
||||||
|
String lastTransTime = SystemParamsOperation.getInstance().getLastTransTime();
|
||||||
|
if(lastTransTime != null && !lastTransTime.isEmpty() && lastTransName != null && !lastTransName.isEmpty()) {
|
||||||
|
downloadParams(SystemParamsOperation.getInstance().getLastTransName(),SystemParamsOperation.getInstance().getLastTransTime());
|
||||||
|
} else {
|
||||||
|
long transTime = System.currentTimeMillis();
|
||||||
|
String transTimeInString = String.valueOf(transTime).substring(0,10);
|
||||||
|
downloadParams("...",transTimeInString);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadParams(String lastTransName,String lastTransTime) {
|
||||||
|
showLoadingDialog("Downloading...");
|
||||||
|
SiriusRequest siriusReq = TMSUtil.getInstance().generateRequestParams(getContext(),lastTransName,lastTransTime);
|
||||||
|
mainViewModel.getParams(siriusReq).subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(new io.reactivex.rxjava3.core.Observer<SiriusResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onSubscribe(@io.reactivex.rxjava3.annotations.NonNull Disposable d) {
|
||||||
|
LogUtil.d(TAG,"On Subscribe!");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onNext(@io.reactivex.rxjava3.annotations.NonNull SiriusResponse siriusResponse) {
|
||||||
|
|
||||||
|
TMSUtil.getInstance().initParams(siriusResponse, TMSUpdate.CHECK,emvParamOperation);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(@io.reactivex.rxjava3.annotations.NonNull Throwable e) {
|
||||||
|
dismissLoadingDialog();
|
||||||
|
|
||||||
|
if(e.getClass() == MalformedJsonException.class) {
|
||||||
|
showDeclineDialog("Terminal is not configured!");
|
||||||
|
} else {
|
||||||
|
showDeclineDialog("Failure!\n"+e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onComplete() {
|
||||||
|
dismissLoadingDialog();
|
||||||
|
mainViewModel.settlementStatus.setValue(SystemParamsOperation.getInstance().getSettlementStatus());
|
||||||
|
checkDisableStatus();
|
||||||
|
LogUtil.d(TAG,"On Complete!");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkDisableStatus(){
|
||||||
|
if(SystemParamsOperation.getInstance().isActive()){
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
} else {
|
||||||
|
showDeclineDialog("Terminal is still disabled!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void downloadTask() {
|
||||||
|
getLastTrans();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
public void onRetry() {
|
||||||
|
downloadTask();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onExit() {
|
||||||
|
requireActivity().finishAffinity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
363
app/src/main/java/com/utsmm/kbz/ui/kpay/KPayViewModel.java
Normal file
363
app/src/main/java/com/utsmm/kbz/ui/kpay/KPayViewModel.java
Normal file
@ -0,0 +1,363 @@
|
|||||||
|
package com.utsmm.kbz.ui.kpay;
|
||||||
|
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Looper;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
import io.reactivex.rxjava3.core.Completable;
|
||||||
|
import io.reactivex.rxjava3.core.Flowable;
|
||||||
|
import io.reactivex.rxjava3.core.Maybe;
|
||||||
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
|
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.kizzy.xpay.util.Sign;
|
||||||
|
import com.utsmyanmar.baselib.network.model.DemoQRRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.DemoQRResponse;
|
||||||
|
import com.utsmyanmar.baselib.network.model.DemoQRReturnRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.DemoQRReturnResponse;
|
||||||
|
import com.utsmyanmar.baselib.network.model.DemoQRStatusRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.DemoQRStatusResponse;
|
||||||
|
import com.utsmyanmar.baselib.network.model.KPayQRQueryRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.KPayQRRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.KPayQRResponse;
|
||||||
|
import com.utsmyanmar.baselib.network.model.KPayRefund;
|
||||||
|
import com.utsmyanmar.baselib.network.model.MMQRReturnRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.MMQRReturnResponse;
|
||||||
|
import com.utsmyanmar.baselib.network.model.WaveAccessTokenResponse;
|
||||||
|
import com.utsmyanmar.baselib.network.model.WaveQRRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.WaveQRResponse;
|
||||||
|
import com.utsmyanmar.baselib.network.model.WaveTokenResponse;
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository;
|
||||||
|
import com.utsmyanmar.baselib.util.TerminalUtil;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.model.TradeData;
|
||||||
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent;
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsSettings;
|
||||||
|
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class KPayViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private static final String TAG = KPayViewModel.class.getSimpleName();
|
||||||
|
|
||||||
|
private final Repository repository;
|
||||||
|
|
||||||
|
private final String appKey = SystemParamsOperation.getInstance().getAppKey();
|
||||||
|
// private final String appKey = "UTSMMuat@2025";
|
||||||
|
|
||||||
|
private final String appId = SystemParamsOperation.getInstance().getAppId();
|
||||||
|
// private final String appId = "kp9b0794b349ae85b00c51e0677484c7";
|
||||||
|
|
||||||
|
private final ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||||
|
private final Handler mainHandler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
|
// Characters for generating random nonce_str
|
||||||
|
private static final String NONCE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
private static final int NONCE_LENGTH = 32;
|
||||||
|
private final SecureRandom secureRandom = new SecureRandom();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private String generateRandomTwoChars() {
|
||||||
|
// You can reuse the existing character set and SecureRandom instance
|
||||||
|
StringBuilder randomChars = new StringBuilder(3);
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
randomChars.append(NONCE_CHARS.charAt(secureRandom.nextInt(NONCE_CHARS.length())));
|
||||||
|
}
|
||||||
|
return randomChars.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates a random nonce string of specified length using alphanumeric characters
|
||||||
|
*
|
||||||
|
* @return Random nonce string (32 characters)
|
||||||
|
*/
|
||||||
|
private String generateNonceStr() {
|
||||||
|
StringBuilder nonce = new StringBuilder(NONCE_LENGTH);
|
||||||
|
for (int i = 0; i < NONCE_LENGTH; i++) {
|
||||||
|
nonce.append(NONCE_CHARS.charAt(secureRandom.nextInt(NONCE_CHARS.length())));
|
||||||
|
}
|
||||||
|
return nonce.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a KPay refund request with proper signing, nonce, and biz_content.
|
||||||
|
*
|
||||||
|
* @param refundOrderId The refund order id (unique per refund transaction)
|
||||||
|
* @param origOrderId The original merchant order id to refund
|
||||||
|
* @param mid The merchant id
|
||||||
|
* @param refundAmount Refund amount
|
||||||
|
* @param reason Refund reason (optional)
|
||||||
|
* @return KPayRefund.RefundRequest object ready for API submission
|
||||||
|
*/
|
||||||
|
public KPayRefund.RefundRequest createRefundRequest(
|
||||||
|
String refundOrderId,
|
||||||
|
String origOrderId,
|
||||||
|
String mid,
|
||||||
|
String refundAmount,
|
||||||
|
String reason
|
||||||
|
) {
|
||||||
|
String serialNum = TerminalUtil.getInstance().getSerialNo();
|
||||||
|
String nonceStr = generateNonceStr();
|
||||||
|
String time = String.valueOf(System.currentTimeMillis());
|
||||||
|
|
||||||
|
// Compose biz_content map for signature calculation
|
||||||
|
Map<String, Object> bizContent = new HashMap<>();
|
||||||
|
bizContent.put("refund_request_no", refundOrderId);
|
||||||
|
bizContent.put("merch_order_id", origOrderId);
|
||||||
|
bizContent.put("merch_code", mid);
|
||||||
|
bizContent.put("appid", appId);
|
||||||
|
if(!refundAmount.equals("0")) {
|
||||||
|
bizContent.put("refund_amount", refundAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
bizContent.put("refund_reason", reason);
|
||||||
|
|
||||||
|
Map<String, Object> requestMap = new HashMap<>();
|
||||||
|
requestMap.put("timestamp", time);
|
||||||
|
requestMap.put("nonce_str", nonceStr);
|
||||||
|
requestMap.put("method", "kbz.payment.refund");
|
||||||
|
requestMap.put("sign_type", "SHA256");
|
||||||
|
requestMap.put("version", "1.0");
|
||||||
|
requestMap.put("biz_content", bizContent);
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"request map :"+requestMap.toString());
|
||||||
|
|
||||||
|
String sign = Sign.INSTANCE.generateSign(requestMap, appKey);
|
||||||
|
|
||||||
|
if(!refundAmount.equals("0")) {
|
||||||
|
bizContent.put("refund_amount", refundAmount);
|
||||||
|
|
||||||
|
KPayRefund.RefundRequest.RequestBody.BizContent biz =
|
||||||
|
new KPayRefund.RefundRequest.RequestBody.BizContent(
|
||||||
|
appId,
|
||||||
|
mid,
|
||||||
|
origOrderId,
|
||||||
|
refundAmount, // This can be null for original refunds
|
||||||
|
refundOrderId,
|
||||||
|
reason
|
||||||
|
);
|
||||||
|
|
||||||
|
KPayRefund.RefundRequest.RequestBody body =
|
||||||
|
new KPayRefund.RefundRequest.RequestBody(
|
||||||
|
time,
|
||||||
|
nonceStr,
|
||||||
|
"kbz.payment.refund",
|
||||||
|
"SHA256",
|
||||||
|
sign,
|
||||||
|
"1.0",
|
||||||
|
biz
|
||||||
|
);
|
||||||
|
return new KPayRefund.RefundRequest(body);
|
||||||
|
} else {
|
||||||
|
KPayRefund.RefundRequest.RequestBody.BizContent biz =
|
||||||
|
new KPayRefund.RefundRequest.RequestBody.BizContent(
|
||||||
|
appId,
|
||||||
|
mid,
|
||||||
|
origOrderId,
|
||||||
|
refundOrderId,
|
||||||
|
reason
|
||||||
|
);
|
||||||
|
|
||||||
|
KPayRefund.RefundRequest.RequestBody body =
|
||||||
|
new KPayRefund.RefundRequest.RequestBody(
|
||||||
|
time,
|
||||||
|
nonceStr,
|
||||||
|
"kbz.payment.refund",
|
||||||
|
"SHA256",
|
||||||
|
sign,
|
||||||
|
"1.0",
|
||||||
|
biz
|
||||||
|
);
|
||||||
|
|
||||||
|
return new KPayRefund.RefundRequest(body);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public KPayQRRequest.QrRequest createQR(String amount,String mid) {
|
||||||
|
return createQR(amount, String.valueOf(System.currentTimeMillis()),mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KPayQRRequest.QrRequest createQR(String amount, String time,String mid) {
|
||||||
|
String merchOrderId = "NEX"+SystemParamsOperation.getInstance().getCurrentSerialNum()+generateRandomTwoChars();
|
||||||
|
String serialNum = TerminalUtil.getInstance().getSerialNo();
|
||||||
|
String nonceStr = generateNonceStr(); // Generate random nonce_str
|
||||||
|
|
||||||
|
Map<String, Object> bizContent = new HashMap<>();
|
||||||
|
bizContent.put("merch_order_id", merchOrderId);
|
||||||
|
bizContent.put("merch_code", mid);
|
||||||
|
bizContent.put("appid", appId);
|
||||||
|
bizContent.put("trade_type", "PAY_BY_QRCODE");
|
||||||
|
bizContent.put("total_amount", amount);
|
||||||
|
bizContent.put("title", "testing");
|
||||||
|
// bizContent.put("operator_id", serialNum);
|
||||||
|
bizContent.put("timeout_express", "100m");
|
||||||
|
bizContent.put("trans_currency", "MMK");
|
||||||
|
bizContent.put("callback_info", "callback");
|
||||||
|
|
||||||
|
Map<String, Object> requestMap = new HashMap<>();
|
||||||
|
requestMap.put("timestamp", time);
|
||||||
|
requestMap.put("notify_url", "http://test.com/payment/notify");
|
||||||
|
requestMap.put("nonce_str", nonceStr); // Use random nonce_str
|
||||||
|
requestMap.put("sign_type", "SHA256");
|
||||||
|
requestMap.put("method", "kbz.payment.precreate");
|
||||||
|
requestMap.put("version", "1.0");
|
||||||
|
requestMap.put("biz_content", bizContent);
|
||||||
|
|
||||||
|
String sign = Sign.INSTANCE.generateSign(requestMap, appKey);
|
||||||
|
|
||||||
|
KPayQRRequest.QrRequest.RequestBody.BizContent biz = new KPayQRRequest.QrRequest.RequestBody.BizContent(
|
||||||
|
appId,
|
||||||
|
mid,
|
||||||
|
merchOrderId,
|
||||||
|
"PAY_BY_QRCODE",
|
||||||
|
"testing",
|
||||||
|
amount,
|
||||||
|
"MMK",
|
||||||
|
"100m",
|
||||||
|
"callback"
|
||||||
|
);
|
||||||
|
|
||||||
|
KPayQRRequest.QrRequest.RequestBody body = new KPayQRRequest.QrRequest.RequestBody(
|
||||||
|
time,
|
||||||
|
"http://test.com/payment/notify",
|
||||||
|
nonceStr, // Use random nonce_str
|
||||||
|
"kbz.payment.precreate",
|
||||||
|
"SHA256",
|
||||||
|
sign,
|
||||||
|
"1.0",
|
||||||
|
biz
|
||||||
|
);
|
||||||
|
|
||||||
|
KPayQRRequest.QrRequest qrRequest = new KPayQRRequest.QrRequest(body);
|
||||||
|
|
||||||
|
return qrRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public KPayQRQueryRequest.QRQueryRequest getQrStatus(String merchOrderId, String mid) {
|
||||||
|
|
||||||
|
String currentTime = String.valueOf(System.currentTimeMillis());
|
||||||
|
String nonceStr = generateNonceStr(); // Generate random nonce_str
|
||||||
|
|
||||||
|
Map<String, Object> bizContentMap = new HashMap<>();
|
||||||
|
bizContentMap.put("merch_order_id", merchOrderId);
|
||||||
|
bizContentMap.put("merch_code", mid);
|
||||||
|
bizContentMap.put("appid", appId);
|
||||||
|
|
||||||
|
Map<String, Object> requestMap = new HashMap<>();
|
||||||
|
requestMap.put("timestamp", currentTime);
|
||||||
|
requestMap.put("nonce_str", nonceStr); // Use random nonce_str
|
||||||
|
requestMap.put("method", "kbz.payment.queryorder");
|
||||||
|
requestMap.put("version", "3.0");
|
||||||
|
requestMap.put("biz_content", bizContentMap);
|
||||||
|
|
||||||
|
String sign = Sign.INSTANCE.generateSign(requestMap, appKey);
|
||||||
|
|
||||||
|
KPayQRQueryRequest.QRQueryRequest.Request.BizContent bizContent = new KPayQRQueryRequest.QRQueryRequest.Request.BizContent(
|
||||||
|
appId,
|
||||||
|
mid,
|
||||||
|
merchOrderId
|
||||||
|
);
|
||||||
|
|
||||||
|
KPayQRQueryRequest.QRQueryRequest.Request requestBody = new KPayQRQueryRequest.QRQueryRequest.Request(
|
||||||
|
currentTime,
|
||||||
|
nonceStr, // Use random nonce_str
|
||||||
|
"kbz.payment.queryorder",
|
||||||
|
"SHA256",
|
||||||
|
sign,
|
||||||
|
"3.0",
|
||||||
|
bizContent
|
||||||
|
);
|
||||||
|
|
||||||
|
KPayQRQueryRequest.QRQueryRequest request = new KPayQRQueryRequest.QRQueryRequest(requestBody);
|
||||||
|
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public KPayViewModel(Repository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
private TradeData tradeData;
|
||||||
|
private PayDetail payDetail;
|
||||||
|
|
||||||
|
public void setTradeData(TradeData tradeData){
|
||||||
|
this.tradeData = tradeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TradeData getTradeData() {
|
||||||
|
return tradeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setPayDetail(PayDetail payDetail) {
|
||||||
|
this.payDetail = payDetail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PayDetail getPayDetail() { return payDetail; }
|
||||||
|
|
||||||
|
public SingleLiveEvent<String> invalidAmountMsg = new SingleLiveEvent<>();
|
||||||
|
|
||||||
|
public MutableLiveData<Integer> isScanned = new MutableLiveData<>(0);
|
||||||
|
|
||||||
|
|
||||||
|
public Flowable<PayDetail> searchPayDetailByRefNum(String refNum) {
|
||||||
|
return repository.searchPayDetailByRefNum(refNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Maybe<PayDetail> searchPayByRefNum(String refNum) {
|
||||||
|
return repository.searchPayByRefNum(refNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Completable updateUnfinishedQrTrans(String appName,String transId,String refNum) {
|
||||||
|
return repository.updateUnFinishedQRTrans(appName,transId,refNum);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertPayDetail(PayDetail payDetail) {
|
||||||
|
repository.insertPayDetail(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Completable insertPay(PayDetail payDetail) {
|
||||||
|
return repository.insertPay(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Observable<KPayQRResponse.QrResponse> generateQR(KPayQRRequest.QrRequest request) {
|
||||||
|
return repository.qrGenerate(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<DemoQRResponse> generateQRDemo(DemoQRRequest demoQRRequest) {
|
||||||
|
return repository.demoQRGenerate(demoQRRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Observable<KPayQRQueryRequest.QRQueryResponse> checkStatus(KPayQRQueryRequest.QRQueryRequest request) {
|
||||||
|
return repository.qrStatusCheck(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Observable<DemoQRStatusResponse> demoQrCheckStatus(DemoQRStatusRequest demoStatusRequest) {
|
||||||
|
return repository.demoQRCheckStatus(demoStatusRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Observable<KPayRefund.RefundResponse> kPayRefund(KPayRefund.RefundRequest refundRequest) {
|
||||||
|
return repository.kPayRefund(refundRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,269 @@
|
|||||||
|
package com.utsmm.kbz.ui.kpay;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.github.gcacace.signaturepad.BR;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.network.model.DemoQRRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.KPayQRRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.WaveQRRequest;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.ecr.ECRHelper;
|
||||||
|
import com.utsmyanmar.ecr.ECRProcess;
|
||||||
|
import com.utsmyanmar.ecr.data.model.TransactionsResp;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.model.TradeData;
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.util.TransactionUtil;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||||
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
public class QRConnectingFragment extends DataBindingFragment implements DataBindingFragment.BackPressCallback {
|
||||||
|
|
||||||
|
private static final String TAG = QRConnectingFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private KPayViewModel KPayViewModel;
|
||||||
|
|
||||||
|
CompositeDisposable authDisposable = new CompositeDisposable();
|
||||||
|
CompositeDisposable generateQRDisposable = new CompositeDisposable();
|
||||||
|
private String terminalId = "";
|
||||||
|
private String merchantId = "";
|
||||||
|
private TradeData tradeData;
|
||||||
|
private PayDetail payDetail;
|
||||||
|
private String refLabel;
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
KPayViewModel = getFragmentScopeViewModel(KPayViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_qr_connecting, BR.sharedViewModel,sharedViewModel)
|
||||||
|
.addBindingParam(BR.kPayViewModel, KPayViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.QRConnectingFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.txt_title_empty));
|
||||||
|
|
||||||
|
delayFunctionCall(this::requestAuth);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
|
||||||
|
authDisposable.dispose();
|
||||||
|
generateQRDisposable.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initSetup() {
|
||||||
|
terminalId = TransactionUtil.getInstance().getQRTerminalId();
|
||||||
|
merchantId = TransactionUtil.getInstance().getQRMerchantId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
initData();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData() {
|
||||||
|
|
||||||
|
payDetail = TransactionUtil.getInstance().initWalletTransaction(TransactionsType.MMQR);
|
||||||
|
|
||||||
|
String amount = sharedViewModel.amount.getValue();
|
||||||
|
payDetail.setAmount(POSUtil.getInstance().convertAmount(amount));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkMMQR(boolean isMmQR) {
|
||||||
|
if(isMmQR) {
|
||||||
|
LogUtil.d(TAG,"<<<< MMQR Merchant >>>>");
|
||||||
|
sharedViewModel.isMMPay.setValue(0);
|
||||||
|
sharedViewModel.isWavePay.setValue(8);
|
||||||
|
} else {
|
||||||
|
LogUtil.d(TAG,"<<<< NON-MMQR Merchant >>>>");
|
||||||
|
sharedViewModel.isMMPay.setValue(8);
|
||||||
|
sharedViewModel.isWavePay.setValue(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void requestAuth() {
|
||||||
|
|
||||||
|
initSetup();
|
||||||
|
generateQR();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateQR() {
|
||||||
|
|
||||||
|
|
||||||
|
// String amount = String.format(Locale.getDefault(), "%.2f", payDetail.getAmount()/100.0);
|
||||||
|
String amount = String.format(Locale.getDefault(), "%d", (int)(payDetail.getAmount()/100.0));
|
||||||
|
|
||||||
|
|
||||||
|
KPayQRRequest.QrRequest kPayQRRequest = KPayViewModel.createQR(amount, merchantId);
|
||||||
|
Disposable qrDi = KPayViewModel.generateQR(kPayQRRequest)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
response -> {
|
||||||
|
|
||||||
|
if(response.getResponse().getQrCode() != null && !response.getResponse().getQrCode().isEmpty()) {
|
||||||
|
LogUtil.d(TAG,response.getResponse().getQrCode());
|
||||||
|
|
||||||
|
if(response.getResponse().getQrCode() == null || response.getResponse().getQrCode().isEmpty()) {
|
||||||
|
endAction();
|
||||||
|
}
|
||||||
|
|
||||||
|
refLabel = response.getResponse().getMerchOrderId();
|
||||||
|
|
||||||
|
sharedViewModel.qrData.setValue(response.getResponse().getQrCode());
|
||||||
|
sharedViewModel.qrRefNum.setValue(refLabel);
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"Ref Label :"+refLabel);
|
||||||
|
|
||||||
|
payDetail.setPayQRCode(response.getResponse().getQrCode());
|
||||||
|
payDetail.setQrReferNo(refLabel);
|
||||||
|
payDetail.setQrTransStatus(2);
|
||||||
|
payDetail.setReferNo(refLabel);
|
||||||
|
|
||||||
|
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
delayFunctionCall(this::ecrAction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KPayViewModel.setPayDetail(payDetail);
|
||||||
|
|
||||||
|
// waveViewModel.setTradeData(tradeData);
|
||||||
|
|
||||||
|
delayFunctionCall(()->{
|
||||||
|
routeId = R.id.action_QRConnectingFragment_to_QRTransactionFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
dismissLoadingDialog();
|
||||||
|
// showDeclineDialog("Failed to generate QR!\n"+response.getMessage());
|
||||||
|
endAction();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
Throwable -> {
|
||||||
|
Throwable.printStackTrace();
|
||||||
|
dismissLoadingDialog();
|
||||||
|
// showDeclineDialog("Failed to generate QR!\nMessage - "+Throwable.getMessage());
|
||||||
|
endAction();
|
||||||
|
},
|
||||||
|
() -> {
|
||||||
|
LogUtil.d(TAG,"On Complete!");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
generateQRDisposable.add(qrDi);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void endAction() {
|
||||||
|
showDeclineDialog("Failed to generate QR!\n Communication Error! ");
|
||||||
|
ecrActionCancel(getResourceString(R.string.txt_qr_generate_failed));
|
||||||
|
navigateToMain();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ecrAction() {
|
||||||
|
|
||||||
|
|
||||||
|
LogUtil.d(TAG,"ECR Response :"+getECRResponseMessage());
|
||||||
|
ECRHelper.INSTANCE.send(getECRResponseMessage().getBytes());
|
||||||
|
|
||||||
|
ECRHelper.INSTANCE.setOnBindSuccess(() -> {
|
||||||
|
LogUtil.d(TAG, "Send Success!");
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToMain() {
|
||||||
|
routeId = R.id.action_QRConnectingFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finishECR() {
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(getResourceString(R.string.txt_cancel_trans));
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ecrActionCancel(String msg) {
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(msg);
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getECRResponseMessage() {
|
||||||
|
|
||||||
|
sharedViewModel.payDetail.setValue(payDetail);
|
||||||
|
|
||||||
|
TransactionsResp resp = CoreUtils.getInstance(sharedViewModel).generateResponseMsg();
|
||||||
|
|
||||||
|
return ECRProcess.INSTANCE.generateECRResponse(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPress() {
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
finishECR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
popBackStack();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,114 @@
|
|||||||
|
package com.utsmm.kbz.ui.kpay;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.github.gcacace.signaturepad.BR;
|
||||||
|
import com.nexgo.oaf.apiv3.SdkResult;
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.DialogCallback;
|
||||||
|
import com.utsmyanmar.baselib.util.TimeoutCallback;
|
||||||
|
import com.utsmyanmar.paylibs.print.PrintHelper;
|
||||||
|
import com.utsmyanmar.paylibs.utils.PrintStatus;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
|
||||||
|
public class QRInquiryResultFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private static final int resultTimeOut = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_qr_inquiry_result, BR.sharedViewModel,sharedViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.QRInquiryResultFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return R.id.action_QRInquiryResultFragment_to_nav_main;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.txt_title_qr_pay));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
sharedViewModel.setPrintStatus(PrintStatus.FIRST_PRINT);
|
||||||
|
|
||||||
|
startPrintProcess();
|
||||||
|
|
||||||
|
setupTimeout(resultTimeOut, new TimeoutCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTrick(long trickTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
navigateToMainScreen();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void isCardInside() {
|
||||||
|
|
||||||
|
isCardInserted(() -> delayFunctionCall(this::navigateToMainScreen));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToMainScreen() {
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
private void startPrintProcess() {
|
||||||
|
|
||||||
|
if (PrintHelper.getInstance().paperRollStatus() == SdkResult.Printer_PaperLack) {
|
||||||
|
cancelTimeout();
|
||||||
|
showPrinterAlertDialog(getResourceString(R.string.txt_paper_roll_not_ready), new DialogCallback() {
|
||||||
|
@Override
|
||||||
|
public void onClickCancel() {
|
||||||
|
dismissPrinterAlertDialog();
|
||||||
|
isCardInside();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClickRetry() {
|
||||||
|
dismissPrinterAlertDialog();
|
||||||
|
startPrintProcess();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(SystemParamsOperation.getInstance().isAlertSound()) {
|
||||||
|
startSound(getResourceString(R.string.txt_audio_printer_alert));
|
||||||
|
}
|
||||||
|
} else if (PrintHelper.getInstance().paperRollStatus() == SdkResult.Success) {
|
||||||
|
sharedViewModel.startPrintProcess();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
331
app/src/main/java/com/utsmm/kbz/ui/kpay/QRRefundFragment.java
Normal file
331
app/src/main/java/com/utsmm/kbz/ui/kpay/QRRefundFragment.java
Normal file
@ -0,0 +1,331 @@
|
|||||||
|
package com.utsmm.kbz.ui.kpay;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.InputFilter;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.RadioButton;
|
||||||
|
import android.widget.RadioGroup;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.network.model.KPayRefund;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.model.TradeData;
|
||||||
|
import com.utsmyanmar.paylibs.system.SystemDateTime;
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.util.DecimalDigitsInputFilter;
|
||||||
|
import com.utsmm.kbz.util.TransactionUtil;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||||
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
public class QRRefundFragment extends DataBindingFragment {
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private KPayViewModel KPayViewModel;
|
||||||
|
private int routeId;
|
||||||
|
|
||||||
|
private TradeData tradeData;
|
||||||
|
private PayDetail payDetail;
|
||||||
|
|
||||||
|
// UI Elements
|
||||||
|
private RadioGroup radioGroupRefundType;
|
||||||
|
private RadioButton radioOriginal, radioPartial;
|
||||||
|
private EditText etReferenceNo, etOriginalAmount, etRefundAmount, etRefundReason;
|
||||||
|
private LinearLayout originalAmountLayout, refundAmountLayout;
|
||||||
|
|
||||||
|
private boolean isPartialRefund = false;
|
||||||
|
|
||||||
|
CompositeDisposable refundDisposable = new CompositeDisposable();
|
||||||
|
CompositeDisposable retrieveUpdateDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
|
private static final String TAG = QRRefundFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
KPayViewModel = getFragmentScopeViewModel(KPayViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_qr_refund_screen, BR.sharedViewModel, sharedViewModel)
|
||||||
|
.addBindingParam(BR.kPayViewModel, KPayViewModel)
|
||||||
|
.addBindingParam(BR.click, new ClickEvent());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.QRRefundFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return routeId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
setToolBarTitleWithBackIcon("KPay Refund");
|
||||||
|
KPayViewModel.invalidAmountMsg.setValue("");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
refundDisposable.dispose();
|
||||||
|
retrieveUpdateDisposable.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
initViews();
|
||||||
|
initData();
|
||||||
|
setupRadioGroupListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initViews() {
|
||||||
|
radioGroupRefundType = mBinding.getRoot().findViewById(R.id.radio_group_refund_type);
|
||||||
|
radioOriginal = mBinding.getRoot().findViewById(R.id.radio_original);
|
||||||
|
radioPartial = mBinding.getRoot().findViewById(R.id.radio_partial);
|
||||||
|
etReferenceNo = mBinding.getRoot().findViewById(R.id.et_reference_no);
|
||||||
|
etOriginalAmount = mBinding.getRoot().findViewById(R.id.et_original_amount);
|
||||||
|
etRefundAmount = mBinding.getRoot().findViewById(R.id.et_refund_amount);
|
||||||
|
etRefundReason = mBinding.getRoot().findViewById(R.id.et_refund_reason);
|
||||||
|
originalAmountLayout = mBinding.getRoot().findViewById(R.id.original_amount_layout);
|
||||||
|
refundAmountLayout = mBinding.getRoot().findViewById(R.id.refund_amount_layout);
|
||||||
|
|
||||||
|
// Set input filters for amount fields
|
||||||
|
etOriginalAmount.setFilters(new InputFilter[]{new DecimalDigitsInputFilter(11, 2)});
|
||||||
|
etRefundAmount.setFilters(new InputFilter[]{new DecimalDigitsInputFilter(11, 2)});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initData() {
|
||||||
|
payDetail = TransactionUtil.getInstance().initWalletTransaction(TransactionsType.MMQR_REFUND);
|
||||||
|
payDetail.setInvoiceNo(SystemParamsOperation.getInstance().getIncrementInvoiceNum());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupRadioGroupListener() {
|
||||||
|
radioGroupRefundType.setOnCheckedChangeListener((group, checkedId) -> {
|
||||||
|
if (checkedId == R.id.radio_partial) {
|
||||||
|
// Show both amount fields for partial refund
|
||||||
|
isPartialRefund = true;
|
||||||
|
originalAmountLayout.setVisibility(View.VISIBLE);
|
||||||
|
refundAmountLayout.setVisibility(View.VISIBLE);
|
||||||
|
} else {
|
||||||
|
// Hide amount fields for original refund
|
||||||
|
isPartialRefund = false;
|
||||||
|
originalAmountLayout.setVisibility(View.GONE);
|
||||||
|
refundAmountLayout.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void processKPayRefund(String referenceNo, String refundAmount, String originalAmount, String reason) {
|
||||||
|
String merchantId = TransactionUtil.getInstance().getQRMerchantId();
|
||||||
|
|
||||||
|
// Generate unique refund request ID
|
||||||
|
String refundRequestId = referenceNo + "R";
|
||||||
|
|
||||||
|
showLoadingDialog("Processing refund...");
|
||||||
|
|
||||||
|
// Create KPay refund request
|
||||||
|
KPayRefund.RefundRequest refundRequest = KPayViewModel.createRefundRequest(
|
||||||
|
refundRequestId,
|
||||||
|
referenceNo,
|
||||||
|
merchantId,
|
||||||
|
refundAmount,
|
||||||
|
reason != null ? reason : "Refund request"
|
||||||
|
);
|
||||||
|
|
||||||
|
Disposable refundDi = KPayViewModel.kPayRefund(refundRequest)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
response -> {
|
||||||
|
dismissLoadingDialog();
|
||||||
|
handleRefundResponse(response, referenceNo);
|
||||||
|
},
|
||||||
|
throwable -> {
|
||||||
|
dismissLoadingDialog();
|
||||||
|
LogUtil.e(TAG, "Refund error: " + throwable.getMessage());
|
||||||
|
showDeclineDialog("Refund failed!\nCommunication Error!");
|
||||||
|
ecrActionCancel("Refund failed");
|
||||||
|
navigateToMain();
|
||||||
|
},
|
||||||
|
() -> LogUtil.d(TAG, "Refund request completed")
|
||||||
|
);
|
||||||
|
|
||||||
|
refundDisposable.add(refundDi);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleRefundResponse(KPayRefund.RefundResponse response, String referenceNo) {
|
||||||
|
if (response != null && response.getResponse() != null && "REFUND_SUCCESS".equalsIgnoreCase(response.getResponse().getRefundStatus())) {
|
||||||
|
LogUtil.d(TAG, "Refund successful!");
|
||||||
|
|
||||||
|
String refundAmount = response.getResponse().getRefundAmount();
|
||||||
|
|
||||||
|
String dateTime = SystemDateTime.getTodayDateFormat() + " " + SystemDateTime.getTodayTimeFormat();
|
||||||
|
payDetail.setAmount(refundAmount == null ? 0 : POSUtil.getInstance().convertAmount(refundAmount));
|
||||||
|
payDetail.setOriginalTransDate(dateTime);
|
||||||
|
payDetail.setQrTransStatus(1);
|
||||||
|
payDetail.setQrReferNo(referenceNo);
|
||||||
|
payDetail.setReferNo(referenceNo);
|
||||||
|
payDetail.setIsCanceled(true);
|
||||||
|
|
||||||
|
retrievedUpdatePayDetail(referenceNo);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
LogUtil.d(TAG, "Refund failed!");
|
||||||
|
payDetail.setQrTransStatus(-1);
|
||||||
|
payDetail.setQrReferNo(referenceNo);
|
||||||
|
payDetail.setReferNo(referenceNo);
|
||||||
|
|
||||||
|
String errorMsg = "Refund failed";
|
||||||
|
if (response != null && response.getResponse() != null && response.getResponse().getMsg() != null) {
|
||||||
|
errorMsg = response.getResponse().getMsg();
|
||||||
|
}
|
||||||
|
payDetail.setTradeResultDes(errorMsg);
|
||||||
|
|
||||||
|
sharedViewModel.payDetail.setValue(payDetail);
|
||||||
|
navigateToNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void retrievedUpdatePayDetail(String refNum) {
|
||||||
|
LogUtil.d(TAG, "Trying to update Database!");
|
||||||
|
retrieveUpdateDisposable.add(KPayViewModel.searchPayByRefNum(refNum)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(oldPay -> {
|
||||||
|
LogUtil.d(TAG, "Inside the subscribe!");
|
||||||
|
if (oldPay != null) {
|
||||||
|
oldPay.setIsCanceled(true);
|
||||||
|
payDetail.setQrTransId(oldPay.getQrTransId());
|
||||||
|
payDetail.setCustomerMobile(oldPay.getCustomerMobile());
|
||||||
|
sharedViewModel.updatePayDetail(oldPay);
|
||||||
|
}
|
||||||
|
updateData();
|
||||||
|
navigateToNext();
|
||||||
|
},
|
||||||
|
onError -> {
|
||||||
|
LogUtil.d(TAG, "On error Unable to retrieve PayDetail");
|
||||||
|
updateData();
|
||||||
|
navigateToNext();
|
||||||
|
},
|
||||||
|
() -> {
|
||||||
|
LogUtil.d(TAG, "No data found! navigating to Result Page!");
|
||||||
|
updateData();
|
||||||
|
navigateToNext();
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateData() {
|
||||||
|
KPayViewModel.insertPayDetail(payDetail);
|
||||||
|
sharedViewModel.payDetail.postValue(payDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToMain() {
|
||||||
|
routeId = R.id.action_QRRefundFragment_to_nav_main;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void navigateToNext() {
|
||||||
|
routeId = R.id.action_QRRefundFragment_to_transactionResultFragment;
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ecrActionCancel(String msg) {
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(msg);
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ClickEvent {
|
||||||
|
|
||||||
|
public void onCancel() {
|
||||||
|
safePopBackStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onConfirm() {
|
||||||
|
KPayViewModel.invalidAmountMsg.setValue("");
|
||||||
|
|
||||||
|
String referenceNo = etReferenceNo.getText().toString().trim();
|
||||||
|
String refundReason = etRefundReason.getText().toString().trim();
|
||||||
|
|
||||||
|
// Validate reference number
|
||||||
|
if (referenceNo.isEmpty()) {
|
||||||
|
KPayViewModel.invalidAmountMsg.setValue("Enter reference number");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPartialRefund) {
|
||||||
|
// Partial refund validation
|
||||||
|
String originalAmountStr = etOriginalAmount.getText().toString().trim();
|
||||||
|
String refundAmountStr = etRefundAmount.getText().toString().trim();
|
||||||
|
|
||||||
|
if (originalAmountStr.isEmpty()) {
|
||||||
|
KPayViewModel.invalidAmountMsg.setValue("Enter original amount");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refundAmountStr.isEmpty()) {
|
||||||
|
KPayViewModel.invalidAmountMsg.setValue("Enter refund amount");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double originalAmount = Double.parseDouble(originalAmountStr);
|
||||||
|
double refundAmount = Double.parseDouble(refundAmountStr);
|
||||||
|
|
||||||
|
if (originalAmount <= 0) {
|
||||||
|
KPayViewModel.invalidAmountMsg.setValue("Enter valid original amount");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refundAmount <= 0) {
|
||||||
|
KPayViewModel.invalidAmountMsg.setValue("Enter valid refund amount");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (refundAmount > originalAmount) {
|
||||||
|
KPayViewModel.invalidAmountMsg.setValue("Refund amount cannot exceed original amount");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
processKPayRefund(referenceNo, refundAmountStr, originalAmountStr, refundReason);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Original amount refund - no amount validation needed
|
||||||
|
processKPayRefund(referenceNo, "0", String.valueOf( etOriginalAmount.getText().toString().trim()), refundReason);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,421 @@
|
|||||||
|
package com.utsmm.kbz.ui.kpay;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
|
||||||
|
import com.utsmyanmar.baselib.network.model.DemoQRStatusRequest;
|
||||||
|
import com.utsmyanmar.baselib.network.model.KPayQRQueryRequest;
|
||||||
|
import com.utsmyanmar.baselib.util.DataBindingConfig;
|
||||||
|
import com.utsmyanmar.baselib.util.TimeoutCallback;
|
||||||
|
import com.utsmyanmar.ecr.ECRHelper;
|
||||||
|
import com.utsmyanmar.ecr.ECRProcess;
|
||||||
|
import com.utsmyanmar.ecr.data.model.TransactionsResp;
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail;
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
|
||||||
|
import com.utsmm.kbz.R;
|
||||||
|
import com.utsmm.kbz.BR;
|
||||||
|
import com.utsmm.kbz.config.Constants;
|
||||||
|
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
|
||||||
|
import com.utsmm.kbz.util.TransactionUtil;
|
||||||
|
import com.utsmm.kbz.util.ecr.CoreUtils;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
|
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||||
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
import io.reactivex.rxjava3.schedulers.Schedulers;
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
|
||||||
|
public class QRTransactionFragment extends DataBindingFragment implements DataBindingFragment.BackPressCallback {
|
||||||
|
|
||||||
|
private static final String TAG = QRTransactionFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
|
||||||
|
private SharedViewModel sharedViewModel;
|
||||||
|
private KPayViewModel kPayViewModel;
|
||||||
|
|
||||||
|
private String refLabel;
|
||||||
|
|
||||||
|
CompositeDisposable retrieveUpdateDisposable = new CompositeDisposable();
|
||||||
|
CompositeDisposable setUpTimerDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
|
private PayDetail payDetail;
|
||||||
|
String terminalId = "";
|
||||||
|
String merchantId = "";
|
||||||
|
|
||||||
|
private int intervalInSec = 15;
|
||||||
|
private int totalCount = 4;
|
||||||
|
|
||||||
|
private int count = 0;
|
||||||
|
|
||||||
|
// @Inject
|
||||||
|
// QRUtils qrUtils;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void initViewModel() {
|
||||||
|
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
|
||||||
|
kPayViewModel = getFragmentScopeViewModel(KPayViewModel.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected DataBindingConfig getDataBindingConfig() {
|
||||||
|
return new DataBindingConfig(R.layout.fragment_qr_transaction, BR.sharedViewModel, sharedViewModel)
|
||||||
|
.addBindingParam(BR.kPayViewModel, kPayViewModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int currentId() {
|
||||||
|
return R.id.QRTransactionFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int hostId() {
|
||||||
|
return Constants.NAV_HOST_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int routeId() {
|
||||||
|
return R.id.action_QRTransactionFragment_to_transactionResultFragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
|
||||||
|
setToolBarTitleWithBackIcon(getResourceString(R.string.title_qr_scan));
|
||||||
|
|
||||||
|
// disableNavigationBar();
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
sharedViewModel.mmqrLoading.setValue(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
super.onPause();
|
||||||
|
|
||||||
|
// enableNavigationBar();
|
||||||
|
|
||||||
|
|
||||||
|
sharedViewModel.mmqrLoading.setValue(8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initSetup() {
|
||||||
|
// terminalId = SystemParamsOperation.getInstance().getSecHostTerminalId();
|
||||||
|
// merchantId = SystemParamsOperation.getInstance().getSecHostMerchantId();
|
||||||
|
|
||||||
|
terminalId = TransactionUtil.getInstance().getQRTerminalId();
|
||||||
|
merchantId = TransactionUtil.getInstance().getQRMerchantId();
|
||||||
|
|
||||||
|
refLabel = sharedViewModel.qrRefNum.getValue();
|
||||||
|
|
||||||
|
// tradeData = waveViewModel.getTradeData();
|
||||||
|
// payDetail = tradeData.getPayDetail();
|
||||||
|
payDetail = kPayViewModel.getPayDetail();
|
||||||
|
payDetail.setInvoiceNo(SystemParamsOperation.getInstance().getIncrementInvoiceNum());
|
||||||
|
|
||||||
|
sharedViewModel.insertPayDetail(payDetail);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void calculateIntervalAndCount() {
|
||||||
|
String data = SystemParamsOperation.getInstance().getWaveIntervalTime();
|
||||||
|
if (data == null) {
|
||||||
|
data = "15-60";
|
||||||
|
}
|
||||||
|
Pattern pattern = Pattern.compile("^(\\d+)-(\\d+)$"); // Match digits-hyphen-digits
|
||||||
|
Matcher matcher = pattern.matcher(data);
|
||||||
|
|
||||||
|
if (matcher.matches()) {
|
||||||
|
|
||||||
|
int interval = Integer.parseInt(Objects.requireNonNull(matcher.group(1)));
|
||||||
|
int waitingTime = Integer.parseInt(Objects.requireNonNull(matcher.group(2)));
|
||||||
|
|
||||||
|
intervalInSec = interval;
|
||||||
|
totalCount = waitingTime / interval;
|
||||||
|
} else {
|
||||||
|
LogUtil.d(TAG, "Invalid input format. Expected format: digits-digits");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void finishECR() {
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(getResourceString(R.string.txt_cancel_trans));
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ecrActionCancel(String msg) {
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
sharedViewModel.isEcr.postValue(false);
|
||||||
|
CoreUtils.getInstance(sharedViewModel).responseRejectMsg(msg);
|
||||||
|
sharedViewModel.isEcrFinished.postValue(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
initSetup();
|
||||||
|
calculateIntervalAndCount();
|
||||||
|
setUpTimeout();
|
||||||
|
setUpCountDown();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpCountDown() {
|
||||||
|
setupTimeout(10, new TimeoutCallback() {
|
||||||
|
@Override
|
||||||
|
public void onTrick(long trickTime) {
|
||||||
|
sharedViewModel.countDownTxt.setValue((trickTime / 1000)+"");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFinish() {
|
||||||
|
sharedViewModel.countDownTxt.setValue("Connecting to host");
|
||||||
|
sharedViewModel.mmqrLoading.setValue(0);
|
||||||
|
// disableNavigationBar();
|
||||||
|
setToolBarTitleWithoutBackIcon(getResourceString(R.string.title_qr_scan));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpTimeout() {
|
||||||
|
|
||||||
|
setUpTimer();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroyView() {
|
||||||
|
super.onDestroyView();
|
||||||
|
setUpTimerDisposable.dispose();
|
||||||
|
retrieveUpdateDisposable.dispose();
|
||||||
|
|
||||||
|
// qrUtils.disposeStatusCheck();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setUpStatusCheck() {
|
||||||
|
// qrUtils.startStatusCheck(refLabel, merchantId, new QRUtils.QRStatusCheckCallback() {
|
||||||
|
// @Override
|
||||||
|
// public void onSuccess(MMQRStatusResponse response) {
|
||||||
|
// payDetail.setCustomerMobile(response.getScannerChannel());
|
||||||
|
// payDetail.setQrReferNo(refLabel);
|
||||||
|
// payDetail.setQrTransId(response.getTransactionID());
|
||||||
|
// payDetail.setReferNo(refLabel);
|
||||||
|
// payDetail.setApprovalCode(response.getTransactionID());
|
||||||
|
// payDetail.setQrTransStatus(1);
|
||||||
|
//
|
||||||
|
// retrievedUpdatePayDetail(refLabel, payDetail,false);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void onFailure(String trnxId) {
|
||||||
|
//
|
||||||
|
// payDetail.setQrReferNo(refLabel);
|
||||||
|
// payDetail.setQrTransId(trnxId);
|
||||||
|
// payDetail.setReferNo(refLabel);
|
||||||
|
// payDetail.setApprovalCode(trnxId);
|
||||||
|
// payDetail.setQrTransStatus(-1);
|
||||||
|
//
|
||||||
|
// retrievedUpdatePayDetail(refLabel, payDetail,true);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void onReachRetryCount() {
|
||||||
|
// payDetail.setQrTransStatus(2);
|
||||||
|
// delayFunctionCall(() -> {
|
||||||
|
// sharedViewModel.payDetail.postValue(payDetail);
|
||||||
|
//
|
||||||
|
// safeRouteTo(currentId, routeId, hostId);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// @Override
|
||||||
|
// public void onNetworkError() {
|
||||||
|
// payDetail.setQrTransStatus(3);
|
||||||
|
// retrievedUpdatePayDetail(refLabel, payDetail,false);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkResult(KPayQRQueryRequest.QRQueryResponse response) {
|
||||||
|
return response.getResponse().getResult().equals("SUCCESS");
|
||||||
|
}
|
||||||
|
@SuppressLint("CheckResult")
|
||||||
|
private void setUpTimer() {
|
||||||
|
Disposable setUpDi = Observable.interval(intervalInSec, TimeUnit.SECONDS) // Emit an item every 10 seconds
|
||||||
|
.take(totalCount) // Take only 3 emissions
|
||||||
|
.flatMap(tick -> {
|
||||||
|
// Make the API call here using Retrofit
|
||||||
|
// WaveStatusRequest request = new WaveStatusRequest(refLabel, merchantId);
|
||||||
|
// DemoQRStatusRequest request = new DemoQRStatusRequest(refLabel, merchantId);
|
||||||
|
KPayQRQueryRequest.QRQueryRequest request = kPayViewModel.getQrStatus(refLabel,merchantId);
|
||||||
|
|
||||||
|
return kPayViewModel.checkStatus(request)
|
||||||
|
.takeUntil(response -> response.checkResponse() == true);
|
||||||
|
})
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(response -> {
|
||||||
|
|
||||||
|
LogUtil.d(TAG, "response status:" + response.getResponse().getResult());
|
||||||
|
// LogUtil.d(TAG, "response trans id:" + response.get());
|
||||||
|
// LogUtil.d(TAG, "response ref id:" + response.getReferenceId());
|
||||||
|
// LogUtil.d(TAG, "response trans date time:" + response.getTransactionDateTime());
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
if (response.getResponse().getTradeStatus().equals("PAY_SUCCESS") && response.getResponse().getResult().equals("SUCCESS")) {
|
||||||
|
/*
|
||||||
|
* trans is success !*/
|
||||||
|
// String transStatus = response.getTransactionStatus();
|
||||||
|
// String transTime = response.getResponse().;
|
||||||
|
|
||||||
|
payDetail.setCustomerMobile("KBZ PAY");
|
||||||
|
payDetail.setQrReferNo(refLabel);
|
||||||
|
payDetail.setQrTransId(response.getResponse().getMmOrderId());
|
||||||
|
payDetail.setReferNo(refLabel);
|
||||||
|
payDetail.setApprovalCode(response.getResponse().getMmOrderId());
|
||||||
|
payDetail.setQrTransStatus(1);
|
||||||
|
payDetail.setOriginalTransDate(response.getResponse().getPaySuccessTime());
|
||||||
|
|
||||||
|
retrievedUpdatePayDetail(refLabel, payDetail,false);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (count == totalCount) {
|
||||||
|
if(payDetail.getQrTransStatus() != -1) {
|
||||||
|
payDetail.setQrTransStatus(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedViewModel.payDetail.postValue(payDetail);
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtil.d(TAG, "On Exception::");
|
||||||
|
e.printStackTrace();
|
||||||
|
if (count == totalCount) {
|
||||||
|
if(payDetail.getQrTransStatus() != -1) {
|
||||||
|
payDetail.setQrTransStatus(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
sharedViewModel.payDetail.postValue(payDetail);
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}, Throwable -> {
|
||||||
|
LogUtil.d(TAG, "On Throwable::");
|
||||||
|
Throwable.printStackTrace();
|
||||||
|
|
||||||
|
count++;
|
||||||
|
|
||||||
|
if (count == totalCount) {
|
||||||
|
if(payDetail.getQrTransStatus() != -1) {
|
||||||
|
payDetail.setQrTransStatus(3);
|
||||||
|
}
|
||||||
|
retrievedUpdatePayDetail(refLabel, payDetail,false);
|
||||||
|
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setUpTimer();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
setUpTimerDisposable.add(setUpDi);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void retrievedUpdatePayDetail(String refNum, PayDetail payDetail,boolean isNeedRetry) {
|
||||||
|
retrieveUpdateDisposable.add(kPayViewModel.searchPayDetailByRefNum(refNum)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(oldPay -> {
|
||||||
|
if (oldPay != null)
|
||||||
|
payDetail.setPID(oldPay.getPID());
|
||||||
|
|
||||||
|
sharedViewModel.updatePayDetail(payDetail);
|
||||||
|
sharedViewModel.payDetail.postValue(payDetail);
|
||||||
|
|
||||||
|
if(isNeedRetry) {
|
||||||
|
retrieveUpdateDisposable.dispose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
safeNavigateToRouteId();
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
Throwable -> Log.e(TAG, "Unable to retrieve PayDetail", Throwable)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBackPress() {
|
||||||
|
if (sharedViewModel.isEcr.getValue() != null) {
|
||||||
|
if (sharedViewModel.isEcr.getValue()) {
|
||||||
|
finishECR();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// nav main or pop back?
|
||||||
|
popBackStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getECRResponseMessage() {
|
||||||
|
|
||||||
|
sharedViewModel.payDetail.setValue(payDetail);
|
||||||
|
|
||||||
|
TransactionsResp resp = CoreUtils.getInstance(sharedViewModel).generateResponseMsg();
|
||||||
|
|
||||||
|
return ECRProcess.INSTANCE.generateECRResponse(resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void ecrAction() {
|
||||||
|
|
||||||
|
LogUtil.d(TAG, "ECR Response :" + getECRResponseMessage());
|
||||||
|
ECRHelper.INSTANCE.send(getECRResponseMessage().getBytes());
|
||||||
|
|
||||||
|
ECRHelper.INSTANCE.setOnBindSuccess(() -> {
|
||||||
|
LogUtil.d(TAG, "Send Success!");
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
145
app/src/main/java/com/utsmm/kbz/ui/kpay/QRUtils.java
Normal file
145
app/src/main/java/com/utsmm/kbz/ui/kpay/QRUtils.java
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
package com.utsmm.kbz.ui.kpay;
|
||||||
|
|
||||||
|
import com.utsmyanmar.baselib.network.model.MMQRStatusResponse;
|
||||||
|
import com.utsmyanmar.baselib.network.model.WaveStatusRequest;
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import io.reactivex.rxjava3.core.Observable;
|
||||||
|
import io.reactivex.rxjava3.disposables.CompositeDisposable;
|
||||||
|
import io.reactivex.rxjava3.disposables.Disposable;
|
||||||
|
import com.utsmyanmar.paylibs.utils.LogUtil;
|
||||||
|
|
||||||
|
|
||||||
|
public class QRUtils {
|
||||||
|
|
||||||
|
private static final String TAG = QRUtils.class.getSimpleName();
|
||||||
|
|
||||||
|
private final Repository repository;
|
||||||
|
|
||||||
|
private int intervalInSec = 15;
|
||||||
|
private int totalCount = 4;
|
||||||
|
|
||||||
|
private int count = 0;
|
||||||
|
|
||||||
|
private boolean isFailure = false;
|
||||||
|
|
||||||
|
CompositeDisposable setUpTimerDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
|
// private static QRUtils instance;
|
||||||
|
//
|
||||||
|
// public static QRUtils getInstance() {
|
||||||
|
// if(instance == null) {
|
||||||
|
// instance = new QRUtils();
|
||||||
|
// }
|
||||||
|
// return instance;
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public QRUtils(Repository repository) {
|
||||||
|
this.repository = repository;
|
||||||
|
isFailure = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface QRStatusCheckCallback {
|
||||||
|
|
||||||
|
void onSuccess(MMQRStatusResponse response);
|
||||||
|
|
||||||
|
void onFailure(String trnxId);
|
||||||
|
|
||||||
|
void onReachRetryCount();
|
||||||
|
|
||||||
|
void onNetworkError();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void disposeStatusCheck() {
|
||||||
|
setUpTimerDisposable.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
// public void startStatusCheck(String refLabel,String merchantId,QRStatusCheckCallback callback) {
|
||||||
|
// Disposable setUpDi = Observable.interval(intervalInSec, TimeUnit.SECONDS) // Emit an item every 10 seconds
|
||||||
|
// .take(totalCount) // Take only 3 emissions
|
||||||
|
// .flatMap(tick -> {
|
||||||
|
// // Make the API call here using Retrofit
|
||||||
|
// WaveStatusRequest request = new WaveStatusRequest(refLabel, merchantId);
|
||||||
|
// return repository.checkStatus(request)
|
||||||
|
// .takeUntil(response -> response.checkResponse() == true);
|
||||||
|
// })
|
||||||
|
// .subscribe(response -> {
|
||||||
|
//
|
||||||
|
// LogUtil.d(TAG, "response status:" + response.getTransactionStatus());
|
||||||
|
// LogUtil.d(TAG, "response trans id:" + response.getTransactionID());
|
||||||
|
// LogUtil.d(TAG, "response ref id:" + response.getReferenceId());
|
||||||
|
// LogUtil.d(TAG, "response trans date time:" + response.getTransactionDateTime());
|
||||||
|
//
|
||||||
|
// count++;
|
||||||
|
//
|
||||||
|
// try {
|
||||||
|
//
|
||||||
|
// if (response.getTransactionStatus().equals("payment credit success") && response.getTransactionID() != null) {
|
||||||
|
// /*
|
||||||
|
// * trans is success !*/
|
||||||
|
// String transStatus = response.getTransactionStatus();
|
||||||
|
// String transTime = response.getTransactionDateTime();
|
||||||
|
//
|
||||||
|
// callback.onSuccess(response);
|
||||||
|
//
|
||||||
|
// return;
|
||||||
|
// } else if(response.getTransactionStatus().equals("payment credit failure") && response.getTransactionID() != null) {
|
||||||
|
// String transStatus = response.getTransactionStatus();
|
||||||
|
// String transTime = response.getTransactionDateTime();
|
||||||
|
//
|
||||||
|
// isFailure = true;
|
||||||
|
//
|
||||||
|
// callback.onFailure(response.getTransactionID());
|
||||||
|
//
|
||||||
|
//// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// if (count == totalCount) {
|
||||||
|
// if(!isFailure) {
|
||||||
|
// callback.onReachRetryCount();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// LogUtil.d(TAG, "On Exception::");
|
||||||
|
// e.printStackTrace();
|
||||||
|
// if (count == totalCount) {
|
||||||
|
//
|
||||||
|
// if(!isFailure) {
|
||||||
|
// callback.onReachRetryCount();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// }, Throwable -> {
|
||||||
|
// LogUtil.d(TAG, "On Throwable::");
|
||||||
|
// Throwable.printStackTrace();
|
||||||
|
//
|
||||||
|
// count++;
|
||||||
|
//
|
||||||
|
// if (count == totalCount) {
|
||||||
|
//
|
||||||
|
// if(!isFailure) {
|
||||||
|
// callback.onNetworkError();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// startStatusCheck(refLabel,merchantId,callback);
|
||||||
|
//
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
// setUpTimerDisposable.add(setUpDi);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user