diff --git a/.gitignore b/.gitignore index c1cec63..856177e 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ .cxx local.properties /.idea -/app/release -/app/sit/release -/app/uat/release \ No newline at end of file +/app/release/* +/app/sit/release/* +/app/uat/release/* +/app/uat +/.idea +/app/prod/release diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml index da6c8f6..a7ec23d 100644 --- a/.idea/deploymentTargetSelector.xml +++ b/.idea/deploymentTargetSelector.xml @@ -13,12 +13,6 @@ - - - - \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 083fb6c..d6b3ef3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,8 +14,8 @@ android { applicationId "com.utsmm.kbz" minSdk 24 targetSdk 33 - versionCode 15 - versionName "1.14" + versionCode 1 + versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } @@ -43,44 +43,18 @@ android { dimension "env" applicationId "com.utsmm.kbz" versionNameSuffix "" + resValue "string", "app_name", "KBZ-POS" } } -// defaultConfig { -// applicationId "com.utsmm.kbz.sit" -// minSdk 24 -// targetSdk 33 -// versionCode 1 -// versionName "1.0" -// -//// applicationId "com.utsmm.kbz" -//// versionName "1.10" -// -// 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 + minifyEnabled true + shrinkResources false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } debug { - debuggable true + debuggable false } } compileOptions { diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index ffc2c10..91cbd61 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -20,7 +20,249 @@ # hide the original source file name. #-renamesourcefileattribute SourceFile +-keepattributes Signature, *Annotation*, SourceFile, LineNumberTable, InnerClasses, EnclosingMethod +-dontwarn sun.misc.** -# Keep Bouncy Castle classes for security providers +# Hilt ProGuard Rules - CRITICAL FOR DEPENDENCY INJECTION +-dontwarn dagger.hilt.** +-keep class dagger.hilt.** { *; } +-keep class * extends dagger.hilt.** { *; } + +# Keep all Hilt generated classes +-keep class **_HiltComponents { *; } +-keep class **_HiltComponents$* { *; } +-keep class **_HiltModules { *; } +-keep class **_HiltModules$* { *; } +-keep class * extends dagger.hilt.android.internal.managers.ApplicationComponentManager { *; } +-keep class * extends dagger.hilt.android.internal.managers.ActivityComponentManager { *; } +-keep class * extends dagger.hilt.android.internal.managers.FragmentComponentManager { *; } +-keep class * extends dagger.hilt.android.internal.managers.ViewComponentManager { *; } +-keep class * extends dagger.hilt.android.internal.managers.ServiceComponentManager { *; } + +# Keep Hilt entry points and components +-keep @dagger.hilt.InstallIn class * { *; } +-keep @dagger.hilt.android.AndroidEntryPoint class * { *; } +-keep @dagger.hilt.android.HiltAndroidApp class * { *; } + +# Keep classes annotated with @Module, @Component, @Subcomponent +-keep @dagger.Module class * { *; } +-keep @dagger.Component class * { *; } +-keep @dagger.Component.Builder class * { *; } +-keep @dagger.Subcomponent class * { *; } +-keep @dagger.Subcomponent.Builder class * { *; } + +# Keep all classes that have @Inject constructors, fields, or methods +-keepclasseswithmembers class * { + @javax.inject.Inject (...); +} +-keepclasseswithmembers class * { + @javax.inject.Inject ; +} +-keepclasseswithmembers class * { + @javax.inject.Inject ; +} + +# Keep Application class and its generated Hilt class +-keep class com.utsmm.kbz.MyApplication { *; } +-keep class com.utsmm.kbz.Hilt_MyApplication { *; } +-keep class com.utsmyanmar.baselib.BaseApplication { *; } + +# Keep main activity and its generated classes +-keep class com.utsmm.kbz.MainActivity { *; } + +# ViewModels and Repository classes (important for injection) +-keep class * extends androidx.lifecycle.ViewModel { *; } +-keep class com.utsmyanmar.baselib.repo.Repository { *; } +-keep class com.utsmyanmar.baselib.emv.EmvParamOperation { *; } +-keep class com.utsmyanmar.baselib.emv.TerminalParamOperation { *; } + +# Keep all Dagger generated classes - these are critical! +-keep class **_Factory { *; } +-keep class **_MembersInjector { *; } +-keep class **_Provide* { *; } + +-keep class com.utsmyanmar.baselib.network.model.* { ; } +-keep class com.utsmyanmar.baselib.network.model.sirius.* { ; } +-keep class com.utsmyanmar.baselib.db.model.* { ; } + +-keep class com.utsmyanmar.ecr.data.* { ; } +-keep class com.utsmyanmar.ecr.data.model.* { ; } + +-keep class com.utsmyanmar.mpulib.data.model.* { ; } + +-keep class * extends com.google.gson.TypeAdapter +-keep class * implements com.google.gson.TypeAdapterFactory +-keep class * implements com.google.gson.JsonSerializer +-keep class * implements com.google.gson.JsonDeserializer + +# this is start -keep class org.bouncycastle.** { *; } --dontwarn org.bouncycastle.** \ No newline at end of file +-keep interface org.bouncycastle.** { *; } +-keep class okhttp3.internal.platform.BouncyCastlePlatform { *; } + +# Keep classes from the JNDI package +-keep class javax.naming.** { *; } +-keep class javax.naming.directory.** { *; } + +# Keep Bouncy Castle classes +-keep class org.bouncycastle.** { *; } + +# Keep Conscrypt classes +-keep class org.conscrypt.** { *; } + +# Keep OpenJSSE classes +-keep class org.openjsse.** { *; } + +# Keep classes from okhttp3.internal.platform.BouncyCastlePlatform +-keep class okhttp3.internal.platform.BouncyCastlePlatform { *; } + +# Keep classes from okhttp3.internal.platform.ConscryptPlatform +-keep class okhttp3.internal.platform.ConscryptPlatform$Companion { *; } +#-keep class okhttp3.internal.platform.ConscryptPlatform$platformTrustManager$2 { *; } + +# Keep classes from okhttp3.internal.platform.OpenJSSEPlatform +-keep class okhttp3.internal.platform.OpenJSSEPlatform { *; } + +#this is end + +-keepclassmembers,allowobfuscation class * { + @com.google.gson.annotations.SerializedName ; + } + +-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken +-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken + + +# Jun9 2022 + +#-keep public class * implements com.bumptech.glide.module.GlideModule +#-keep class * extends com.bumptech.glide.module.AppGlideModule { +# (...); +#} +#-keep public enum com.bumptech.glide.load.ImageHeaderParser$** { +# **[] $VALUES; +# public *; +#} + +#-assumenosideeffects class android.util.Log { +#public static int d(...); +#public static int v(...); +#public static int i(...); +#public static int w(...); +#public static int wtf(...); +# } + +-dontwarn okhttp3.internal.platform.** +-dontwarn org.conscrypt.** +-dontwarn org.bouncycastle.** +-dontwarn org.openjsse.** + +# RxJava 3 Rules - Critical for Observable chains +-keep class io.reactivex.rxjava3.** { *; } +-dontwarn io.reactivex.rxjava3.** +-keep class io.reactivex.rxjava3.core.** { *; } +-keep class io.reactivex.rxjava3.android.** { *; } +-keep class io.reactivex.rxjava3.schedulers.** { *; } + +# Retrofit and OkHttp rules +-keepattributes RuntimeVisibleAnnotations +-keep class retrofit2.** { *; } +-keepclassmembernames interface * { + @retrofit2.http.* ; +} + +# AndroidX and Lifecycle components +-keep class androidx.lifecycle.** { *; } +-keep class * extends androidx.lifecycle.ViewModel { *; } +-keep class androidx.activity.** { *; } +-keep class androidx.fragment.** { *; } + +# Navigation component rules +-keep class androidx.navigation.** { *; } +-keep class * implements androidx.navigation.NavDirections { *; } + +# DataBinding rules +-keep class androidx.databinding.** { *; } +-keep class * extends androidx.databinding.ViewDataBinding { *; } + +# Room database rules (if using Room) +-keep class androidx.room.** { *; } +-keep class * extends androidx.room.RoomDatabase { *; } + +# PayLibs and device-specific rules +-keep class com.utsmyanmar.paylibs.** { *; } +-keep class com.nexgo.** { *; } +-keep class com.sunmi.** { *; } +-keep class com.utsmyanmar.checkxread.** { *; } +-keep class com.utsmyanmar.ecr.** { *; } +-keep class com.utsmyanmar.mpulib.** { *; } +-keep class com.utsmyanmar.baselib.** { *; } + +# Enum preservation for critical enums +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +# Keep model classes from obfuscation completely +-keep class com.utsmyanmar.paylibs.model.** { *; } +-keep class com.utsmyanmar.baselib.db.model.** { *; } + +# Critical: Keep all native methods and JNI classes +-keepclasseswithmembernames class * { + native ; +} + +# Keep critical system params and utils +-keep class com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation { *; } +-keep class com.utsmyanmar.paylibs.utils.** { *; } + +# Prevent obfuscation of classes used in reflection +-keep class * extends java.lang.Exception +-keep class * extends java.lang.Error + +# CRITICAL: Keep all generated application components from obfuscation +-keep class com.utsmm.kbz.MyApplication_GeneratedInjector { *; } +#-keep class com.utsmm.kbz.MyApplication_HiltComponents$SingletonC { *; } +#-keep class com.utsmm.kbz.MyApplication_HiltComponents { *; } + +# Keep all classes with "Generated" in their name (Hilt generates these) +-keep class **_Generated { *; } +-keep class **GeneratedInjector { *; } + +# Additional protection for the specific classes causing crashes +-keep class **.D0.h { *; } +-keep class **.m2.f { *; } +-keep class **.J3.b { *; } + +# Keep everything in the di package to prevent injection failures +-keep class com.utsmyanmar.baselib.di.** { *; } +-keep class com.utsmm.kbz.di.** { *; } + +# Hilt Extension points +#-keep class * extends dagger.hilt.android.internal.managers.ApplicationComponentManager$ApplicationComponentBuilder { *; } + +# Don't obfuscate any annotation processing related classes +-keep class dagger.internal.** { *; } +-keepnames class dagger.internal.** { *; } + +# Keep annotation-based bindings +-keep @javax.inject.Inject class * { *; } +-keep @dagger.Provides class * { *; } +-keep @dagger.Module class * { *; } + +# Keep Nexgo SDK +-keep class com.nexgo.** { *; } + +# Keep DDI interface (VERY IMPORTANT) +-keep class com.xinguodu.ddiinterface.** { *; } + +# Keep printer implementations +-keep class com.nexgo.oaf.apiv3.device.printer.** { *; } + +# Prevent method shrinking/optimization +-dontoptimize +-dontshrink + +-dontwarn com.xgd.smartpos.manager.app.UsageInfo +-dontwarn com.xgd.smartpos.manager.app.UsageStats \ No newline at end of file diff --git a/app/src/main/java/com/utsmm/kbz/MainActivity.java b/app/src/main/java/com/utsmm/kbz/MainActivity.java index 541b0d6..acd42c7 100644 --- a/app/src/main/java/com/utsmm/kbz/MainActivity.java +++ b/app/src/main/java/com/utsmm/kbz/MainActivity.java @@ -110,6 +110,8 @@ public class MainActivity extends AppCompatActivity implements public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + BaseApplication.getInstance().deviceEngine.getPlatform().hideNavigationBar(); + // Keep screen on getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); @@ -426,15 +428,15 @@ public class MainActivity extends AppCompatActivity implements SystemParamsOperation.getInstance().setDownloadedParams(false); handleAutoSettlementIntent(getIntent()); - + BaseApplication.getInstance().deviceEngine.getPlatform().hideNavigationBar(); } @Override public void onStop(){ super.onStop(); - BaseApplication.getInstance().deviceEngine.getPlatform().showNavigationBar(); - BaseApplication.getInstance().deviceEngine.getPlatform().enableHomeButton(); - BaseApplication.getInstance().deviceEngine.getPlatform().enableTaskButton(); +// BaseApplication.getInstance().deviceEngine.getPlatform().showNavigationBar(); +// BaseApplication.getInstance().deviceEngine.getPlatform().enableHomeButton(); +// BaseApplication.getInstance().deviceEngine.getPlatform().enableTaskButton(); } @Override @@ -502,14 +504,15 @@ public class MainActivity extends AppCompatActivity implements @Override public void onDestroy() { super.onDestroy(); - BaseApplication.getInstance().deviceEngine.getPlatform().showNavigationBar(); - BaseApplication.getInstance().deviceEngine.getPlatform().enableHomeButton(); - BaseApplication.getInstance().deviceEngine.getPlatform().enableTaskButton(); +// BaseApplication.getInstance().deviceEngine.getPlatform().showNavigationBar(); +// BaseApplication.getInstance().deviceEngine.getPlatform().enableHomeButton(); +// BaseApplication.getInstance().deviceEngine.getPlatform().enableTaskButton(); // Clean up RxJava disposables compositeDisposable.clear(); // Reset screen mode // Disconnect ECR ECRHelper.INSTANCE.disconnect(); + BaseApplication.getInstance().deviceEngine.getPlatform().showNavigationBar(); } // Navigation drawer interaction listeners @@ -520,6 +523,12 @@ public class MainActivity extends AppCompatActivity implements navController.navigate(R.id.inputPasswordFragment); } + @Override + public void onPause(){ + super.onPause(); + BaseApplication.getInstance().deviceEngine.getPlatform().showNavigationBar(); + } + @Override public void onClickFunction() { closeDrawer(); diff --git a/app/src/main/java/com/utsmm/kbz/MainFragment.java b/app/src/main/java/com/utsmm/kbz/MainFragment.java index d6fcdc7..ee03da5 100644 --- a/app/src/main/java/com/utsmm/kbz/MainFragment.java +++ b/app/src/main/java/com/utsmm/kbz/MainFragment.java @@ -146,10 +146,10 @@ public class MainFragment extends DataBindingFragment { delayFunctionCall(() -> { NexGoSDK.getInstance().cancelCheckCard(); NexGoSDK.getInstance().closeReader(); - enableHomeButton(); - disableTaskButton(); +// enableHomeButton(); +// disableTaskButton(); // BaseApplication.getInstance().deviceEngine.getPlatform().hideNavigationBar(); - BaseApplication.getInstance().deviceEngine.getPlatform().showNavigationBar(); +// BaseApplication.getInstance().deviceEngine.getPlatform().showNavigationBar(); }); } diff --git a/app/src/main/java/com/utsmm/kbz/ui/adapters/MyBindingAdapter.java b/app/src/main/java/com/utsmm/kbz/ui/adapters/MyBindingAdapter.java index b075986..366cc31 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/adapters/MyBindingAdapter.java +++ b/app/src/main/java/com/utsmm/kbz/ui/adapters/MyBindingAdapter.java @@ -296,7 +296,9 @@ public class MyBindingAdapter { @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()); +// textView.setText("INV:"+payDetail.getInvoiceNo()); + //tempo fix for qr trace num + textView.setText("TRC:"+payDetail.getVoucherNo()); } else { textView.setText("TRC:"+payDetail.getVoucherNo()); } diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_ui/TransactionResultFragment.java b/app/src/main/java/com/utsmm/kbz/ui/core_ui/TransactionResultFragment.java index 0c3f03c..d174a43 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/core_ui/TransactionResultFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/core_ui/TransactionResultFragment.java @@ -172,9 +172,9 @@ public class TransactionResultFragment extends DataBindingFragment implements Da } else if (isQRPayNonSuccessTransaction(transactionType, payDetail)) { // startPrintProcess(false); if(transactionType == TransactionsType.MMQR_REFUND){ - showDeclineDialog("QR Refund Failed!"); + showDeclineDialog("QR Refund Failed! \n" + payDetail.getTradeResultDes()); }else{ - showDeclineDialog("QR Payment Failed!"); + showDeclineDialog("QR Payment Failed! \n" + payDetail.getTradeResultDes()); } navigateToMainScreen(); } else if (isQRPaySuccessTransaction(transactionType, payDetail)) { diff --git a/app/src/main/java/com/utsmm/kbz/ui/management/ReprintAnyTransactionFragment.java b/app/src/main/java/com/utsmm/kbz/ui/management/ReprintAnyTransactionFragment.java index a001d97..874bd4f 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/management/ReprintAnyTransactionFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/management/ReprintAnyTransactionFragment.java @@ -10,6 +10,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.utsmm.kbz.ui.kpay.KPayViewModel; +import com.utsmm.kbz.util.helper.KeyboardHelper; import com.utsmyanmar.baselib.fragment.DataBindingFragment; import com.utsmyanmar.baselib.network.model.KPayQRQueryRequest; import com.utsmyanmar.baselib.util.DataBindingConfig; @@ -128,7 +129,7 @@ public class ReprintAnyTransactionFragment extends DataBindingFragment { private void searchByTrace(String trace) { for (PayDetail s : lists) { - if(s.getVoucherNo().equals(trace)) { + if(s.getVoucherNo().contains(trace)) { searchedLists.add(s); } } @@ -151,19 +152,13 @@ public class ReprintAnyTransactionFragment extends DataBindingFragment { String input = managementViewModel.txtRRNTrace.getValue(); if(input != null && !input.isEmpty()) { - if(input.length() == 6) { - searchByTrace(input); - } else if(input.length() == 12) { - searchByRRN(input); - } + searchByTrace(input); } else { - searchedLists.addAll(lists); } cardViewAdapter.updateList(searchedLists); - - + KeyboardHelper.hide(requireActivity()); } } @@ -367,7 +362,11 @@ public class ReprintAnyTransactionFragment extends DataBindingFragment { * */ // sharedViewModel.transMenu.postValue(TransMenu.REPRINT); sharedViewModel.setTransMenu(TransMenu.REPRINT); - payDetail.setTransType(payDetail.getTransType()+"(REPRINT)"); +// payDetail.setTransType(payDetail.getTransType()+"(REPRINT)"); + //tempo guarding the Reprint duplicate by kmk + if (!payDetail.getTransType().contains("REPRINT")) { + payDetail.setTransType(payDetail.getTransType() + "(REPRINT)"); + } sharedViewModel.payDetail.postValue(payDetail); routeId = R.id.action_reprintAnyTransactionFragment_to_confirmTransactionFragment; diff --git a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundDetailFragment.java b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundDetailFragment.java index 53583c0..552ce2d 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundDetailFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundDetailFragment.java @@ -13,6 +13,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.utsmm.kbz.ui.kpay.KPayViewModel; +import com.utsmm.kbz.util.helper.KeyboardHelper; import com.utsmyanmar.baselib.fragment.DataBindingFragment; import com.utsmyanmar.baselib.util.DataBindingConfig; import com.utsmyanmar.paylibs.model.PayDetail; @@ -225,6 +226,7 @@ public class QRRefundDetailFragment extends DataBindingFragment { sharedViewModel.transactionsType.setValue(TransactionsType.MMQR_REFUND); kPayViewModel.setPayDetail(payDetail); // sharedViewModel.amount.setValue(refundAmountStr); + KeyboardHelper.hide(requireActivity()); routeId = R.id.action_qrRefundDetail_inputPasswordFragment; safeNavigateToRouteId(); } diff --git a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundFragment.java b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundFragment.java index 1a376c7..a0813e1 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundFragment.java @@ -19,6 +19,7 @@ import com.utsmm.kbz.R; import com.utsmm.kbz.config.Constants; import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel; import com.utsmm.kbz.ui.kpay.KPayViewModel; +import com.utsmm.kbz.util.helper.KeyboardHelper; import com.utsmyanmar.baselib.fragment.DataBindingFragment; import com.utsmyanmar.baselib.util.DataBindingConfig; import com.utsmyanmar.paylibs.model.PayDetail; @@ -107,7 +108,8 @@ public class QRRefundFragment extends DataBindingFragment { safeNavigateToRouteId(); } public void onSearch(){ - searchById(); + searchByTrace(); + KeyboardHelper.hide(requireActivity()); } } @@ -118,7 +120,7 @@ public class QRRefundFragment extends DataBindingFragment { NavHostFragment.findNavController(this).navigate(routeId, bundle); } - private void searchById(){ + private void searchByTrace(){ EditText editText = getView().findViewById(R.id.rnn_trace_id); String keyword = editText.getText().toString().trim(); @@ -132,12 +134,7 @@ public class QRRefundFragment extends DataBindingFragment { List filteredList = new ArrayList<>(); for(PayDetail item: originalList){ - - boolean match = - (item.getReferNo() != null && item.getReferNo().contains(keyword)) || - (item.getInvoiceNo() != null && item.getInvoiceNo().contains(keyword)) || - (item.getVoucherNo() != null && item.getVoucherNo().contains(keyword)); - + boolean match = item.getVoucherNo() != null && item.getVoucherNo().contains(keyword); if(match){ filteredList.add(item); } diff --git a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundProcessFragment.java b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundProcessFragment.java index ecc0852..00d008d 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundProcessFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundProcessFragment.java @@ -144,7 +144,6 @@ public class QRRefundProcessFragment extends DataBindingFragment { private void handleRefundResponse(KPayRefund.RefundResponse response, String referenceNo, String orgAmount) { if (response != null && response.getResponse() != null && "REFUND_SUCCESS".equalsIgnoreCase(response.getResponse().getRefundStatus())) { LogUtil.d(TAG, "Refund successful!"); - String refundAmount = response.getResponse().getRefundAmount(); long text = POSUtil.getInstance().convertAmount(refundAmount); diff --git a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/RefundCertificateManager.java b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/RefundCertificateManager.java index 4bff838..ec51cd8 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/RefundCertificateManager.java +++ b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/RefundCertificateManager.java @@ -40,15 +40,13 @@ public class RefundCertificateManager { if (tmsAddress == null || tmsAddress.trim().isEmpty()) { LogUtil.e(TAG, "TMS address is empty"); return; - } + }; - String downloadBase = - tmsAddress.trim() + "/api/v1/file/download?filePath="; + String downloadBase = tmsAddress.trim() + "/api/v1/file/download?filePath="; //local +// String downloadBase = tmsAddress.trim() + "/file/download?filePath="; // uat and prod - String certUrl = - SystemParamsOperation.getInstance().getCertificateUrl(); - String clientCertUrl = - SystemParamsOperation.getInstance().getCertificateClientUrl(); + String certUrl = SystemParamsOperation.getInstance().getCertificateUrl(); + String clientCertUrl = SystemParamsOperation.getInstance().getCertificateClientUrl(); if (certUrl == null || clientCertUrl == null) { LogUtil.e(TAG, "Certificate URLs are missing"); @@ -58,9 +56,9 @@ public class RefundCertificateManager { String timestamp = String.valueOf(System.currentTimeMillis()); String signature = generateSignature(timestamp); - LogUtil.d(TAG, "Download base => " + downloadBase); - LogUtil.d(TAG, "Cert URL => " + certUrl); - LogUtil.d(TAG, "Client Cert URL => " + clientCertUrl); +// LogUtil.d(TAG, "Download base => " + downloadBase); +// LogUtil.d(TAG, "Cert URL => " + certUrl); +// LogUtil.d(TAG, "Client Cert URL => " + clientCertUrl); // ---------- CA CERT ---------- DownloadUtil.downloadCertificateRx( diff --git a/app/src/main/java/com/utsmm/kbz/ui/settlement/SettlementTransactionFragment.java b/app/src/main/java/com/utsmm/kbz/ui/settlement/SettlementTransactionFragment.java index 3e0395b..7783e23 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/settlement/SettlementTransactionFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/settlement/SettlementTransactionFragment.java @@ -399,6 +399,10 @@ public class SettlementTransactionFragment extends DataBindingFragment implement } public void onConfirm(){ + if(saleCount == 0){ + showDeclineDialog("No Transaction Found!"); + return; + } if(sharedViewModel.getTransMenu().getValue() == TransMenu.SETTLEMENT) { /* April 10 , 2024 Smile requested not to send to host even settlement button was clicked */ settlementViewModel.startSettlementProcess(); diff --git a/app/src/main/java/com/utsmm/kbz/util/helper/KeyboardHelper.java b/app/src/main/java/com/utsmm/kbz/util/helper/KeyboardHelper.java new file mode 100644 index 0000000..1de832b --- /dev/null +++ b/app/src/main/java/com/utsmm/kbz/util/helper/KeyboardHelper.java @@ -0,0 +1,44 @@ +package com.utsmm.kbz.util.helper; + +import android.app.Activity; +import android.content.Context; +import android.view.View; +import android.view.inputmethod.InputMethodManager; + +public class KeyboardHelper { + + private KeyboardHelper() { + // no instance + } + + /** Hide keyboard using a View (Fragment-safe) */ + public static void hide(Context context, View view) { + if (context == null || view == null) return; + + InputMethodManager imm = + (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); + + if (imm != null) { + imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + view.clearFocus(); + } + } + + /** Hide keyboard using Activity (Activity-safe) */ + public static void hide(Activity activity) { + if (activity == null) return; + + View view = activity.getCurrentFocus(); + if (view == null) { + view = activity.getWindow().getDecorView(); + } + + InputMethodManager imm = + (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE); + + if (imm != null) { + imm.hideSoftInputFromWindow(view.getWindowToken(), 0); + view.clearFocus(); + } + } +} diff --git a/app/src/main/res/layout/fragment_print_receipt_screen.xml b/app/src/main/res/layout/fragment_print_receipt_screen.xml index 5dcc23c..b751701 100644 --- a/app/src/main/res/layout/fragment_print_receipt_screen.xml +++ b/app/src/main/res/layout/fragment_print_receipt_screen.xml @@ -223,6 +223,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + android:maxLines="1" + android:ellipsize="end" + + tools:text="REF123456789123456789123456789012345" /> + diff --git a/app/src/main/res/layout/fragment_qr_refund.xml b/app/src/main/res/layout/fragment_qr_refund.xml index dfc84ea..83d37c6 100644 --- a/app/src/main/res/layout/fragment_qr_refund.xml +++ b/app/src/main/res/layout/fragment_qr_refund.xml @@ -71,7 +71,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:background="@null" - android:hint="@string/txt_search_rrn_trace" + android:hint="@string/txt_search_by_trace" android:text="@={manageViewModel.txtRRNTrace}" android:textColor="@color/colorPrimary" android:textColorHint="@color/colorPrimary" diff --git a/app/src/main/res/layout/fragment_transaction_reprint_any_screen.xml b/app/src/main/res/layout/fragment_transaction_reprint_any_screen.xml index 271bcca..a9a52c8 100644 --- a/app/src/main/res/layout/fragment_transaction_reprint_any_screen.xml +++ b/app/src/main/res/layout/fragment_transaction_reprint_any_screen.xml @@ -118,7 +118,7 @@ android:layout_height="wrap_content" android:layout_weight="1" android:background="@null" - android:hint="@string/txt_search_rrn_trace" + android:hint="@string/txt_search_by_trace" android:textColorHint="@color/colorPrimary" android:alpha="0.6" android:text="@={manageViewModel.txtRRNTrace}" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4069bc7..3b885f3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -615,5 +615,6 @@ Total QR Transactions No QR transactions to settle Confirm + Search By Trace No \ No newline at end of file diff --git a/baselib/proguard-rules.pro b/baselib/proguard-rules.pro index 4af0639..8cef902 100644 --- a/baselib/proguard-rules.pro +++ b/baselib/proguard-rules.pro @@ -27,4 +27,29 @@ -keep class com.android.org.bouncycastle.** { *; } -dontwarn com.android.org.bouncycastle.** --keep class org.bouncycastle.** {*;} \ No newline at end of file +-keep class org.bouncycastle.** {*;} + +-keepclassmembers,allowobfuscation class * { + @com.google.gson.annotations.SerializedName ; +} + +# Hilt support for baselib +-keep class com.utsmyanmar.baselib.di.** { *; } +-keep class com.utsmyanmar.baselib.emv.EmvParamOperation { *; } +-keep class com.utsmyanmar.baselib.emv.TerminalParamOperation { *; } +-keep class com.utsmyanmar.baselib.repo.Repository { *; } + +# Keep all Hilt generated classes in baselib +-keep class **_HiltModules { *; } +-keep class **_HiltModules$* { *; } + +# Keep classes with @Inject annotations +-keepclasseswithmembers class * { + @javax.inject.Inject (...); +} +-keepclasseswithmembers class * { + @javax.inject.Inject ; +} +-keepclasseswithmembers class * { + @javax.inject.Inject ; +} \ No newline at end of file diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java b/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java index 7be62a0..463a011 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java @@ -82,9 +82,6 @@ public class NetworkModule { public static native String getTMSUrlFromNative(); - public static String Refund_Base_Url = "https://api.kbzpay.com:18008/payment/gateway/uat/"; - - private static OkHttpClient getUnsafeOkHttpClient() { try { // Create a trust manager that does not validate certificate chains @@ -291,7 +288,7 @@ public class NetworkModule { } String baseUrl = tmsAddress.trim() + "/api/v1/"; //for on prim -// String baseUrl = tmsAddress.trim() + "/"; //for uat +// String baseUrl = tmsAddress.trim() + "/"; //for uat and prod final Gson gson = new GsonBuilder().create(); @@ -395,6 +392,21 @@ public Retrofit provideKPayRefundRetrofit(@ApplicationContext Context context) { // char[] password = "test123".toCharArray(); +// public static String Refund_Base_Url = "https://api.kbzpay.com:18008/payment/gateway/uat/"; + + + String refundBaseUrl = "https://api.kbzpay.com:8008/payment/gateway/"; +// String IpAddress = SystemParamsOperation.getInstance().getSecHostIpAddress(); + + +// if (IpAddress != null && !IpAddress.isEmpty()) { +// refundBaseUrl = IpAddress; +// } +// +// if (refundBaseUrl.isEmpty()) { +// refundBaseUrl = "https://api.kbzpay.com/payment/gateway/"; +// } + String pass = SystemParamsOperation.getInstance().getCertificatePassword(); if (TextUtils.isEmpty(pass)) { pass = "test123"; @@ -456,7 +468,7 @@ public Retrofit provideKPayRefundRetrofit(@ApplicationContext Context context) { .build(); return new Retrofit.Builder() - .baseUrl(Refund_Base_Url) + .baseUrl(refundBaseUrl) .client(okHttp) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) @@ -468,7 +480,7 @@ public Retrofit provideKPayRefundRetrofit(@ApplicationContext Context context) { // Provide fallback Retrofit to avoid crash, but no SSL return new Retrofit.Builder() - .baseUrl(Refund_Base_Url) + .baseUrl(refundBaseUrl) .client(new OkHttpClient()) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .addConverterFactory(GsonConverterFactory.create()) diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/emv/EmvAppConfig.java b/baselib/src/main/java/com/utsmyanmar/baselib/emv/EmvAppConfig.java index 48c5621..9165a91 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/emv/EmvAppConfig.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/emv/EmvAppConfig.java @@ -1,6 +1,5 @@ package com.utsmyanmar.baselib.emv; -import com.sunmi.pay.hardware.aidlv2.bean.AidV2; import com.utsmyanmar.baselib.db.model.ContactlessAid; import com.utsmyanmar.paylibs.utils.core_utils.ByteUtil; diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/network/KPayApiService.java b/baselib/src/main/java/com/utsmyanmar/baselib/network/KPayApiService.java index 7a22441..f30168d 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/network/KPayApiService.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/network/KPayApiService.java @@ -24,12 +24,12 @@ public interface KPayApiService { //this accept "url" bez this api start with https and other are http in uat - @POST - Observable closeOrder(@Url String url, @Body KPayQRRequest.CloseOrderRequest closeOrderRequest); +// @POST("closeorder") +// Observable closeOrder(@Body KPayQRRequest.CloseOrderRequest closeOrderRequest); //this 2 is for production -// @POST("closeorder") -// Observable closeOrder(@Url String url, @Body KPayQRRequest.CloseOrderRequest closeOrderRequest); + @POST("closeorder") + Observable closeOrder(@Url String url, @Body KPayQRRequest.CloseOrderRequest closeOrderRequest); } diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/network/interceptor/SiriusInterceptor.java b/baselib/src/main/java/com/utsmyanmar/baselib/network/interceptor/SiriusInterceptor.java index 7486d67..3cec79c 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/network/interceptor/SiriusInterceptor.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/network/interceptor/SiriusInterceptor.java @@ -40,7 +40,7 @@ public class SiriusInterceptor implements Interceptor { // hashed = TerminalUtil.getInstance().generateHashedString(nonce); // old tms hashed = TerminalUtil.getInstance().generateHashedString(nonce).toLowerCase(); // new tms - LogUtil.d(TAG,"hashed :"+ hashed); +// LogUtil.d(TAG,"hashed :"+ hashed); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java b/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java index 4654e73..3011718 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java @@ -87,7 +87,7 @@ public class Repository { public Observable qrCloseOrder(KPayQRRequest.CloseOrderRequest request){ String url = "https://api.kbzpay.com/payment/gateway/uat/closeorder"; //close this in prod - return kPayApiService.closeOrder(url, request); + return kPayApiService.closeOrder(url, request); // this is for local // return kPayApiService.closeOrder(request); //this is for prod } @@ -120,7 +120,7 @@ public class Repository { } public Observable sendReceipt(Object body){ String apiSecret = BuildConfig.ERECEIPT_SECRET; - LogUtil.d("kmk", "receipt secret =>" + apiSecret); +// LogUtil.d("kmk", "receipt secret =>" + apiSecret); String timestamp = String.valueOf(System.currentTimeMillis()); String bodyString = new Gson().toJson(body); String dataToHash = bodyString + apiSecret + timestamp; diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java b/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java index 0b2abd8..af1d087 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java @@ -225,7 +225,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel { // transData.setCashbackAmount("000000000100"); //if support cashback amount transData.setEmvTransType(ByteUtil.hexStr2Byte(getTransactionType())); //0x00-sale, 0x20-refund,0x09-sale with cashback transData.setCountryCode("104"); //CountryCode - transData.setCurrencyCode("104"); //CurrencyCode, 840 indicate USD dollar + transData.setCurrencyCode(mPayDetail.getCurrencyCode()); //CurrencyCode, 840 indicate USD dollar transData.setTermId(mPayDetail.getTerminalNo()); transData.setMerId(mPayDetail.getMerchantNo()); transData.setTransDate(new SimpleDateFormat("yyMMdd", Locale.getDefault()).format(new Date())); diff --git a/paylibs/proguard-rules.pro b/paylibs/proguard-rules.pro index 481bb43..b81aa11 100644 --- a/paylibs/proguard-rules.pro +++ b/paylibs/proguard-rules.pro @@ -18,4 +18,38 @@ # If you keep the line number information, uncomment this to # hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file +#-renamesourcefileattribute SourceFile + +# Keep the JNDI classes +-keep class javax.naming.** { *; } +-keep class javax.naming.directory.** { *; } + +# Keep the Bouncy Castle classes +-keep class org.bouncycastle.** { *; } + +# Keep the Conscrypt classes +-keep class org.conscrypt.** { *; } + +# Keep the OpenJSSE classes +-keep class org.openjsse.** { *; } + +# Keep specific classes from okhttp3.internal.platform +-keep class okhttp3.internal.platform.BouncyCastlePlatform { *; } +-keep class okhttp3.internal.platform.ConscryptPlatform { *; } +-keep class okhttp3.internal.platform.OpenJSSEPlatform { *; } + +# Keep Nexgo SDK +-keep class com.nexgo.** { *; } + +# Keep DDI interface (VERY IMPORTANT) +-keep class com.xinguodu.ddiinterface.** { *; } + +# Keep printer implementations +-keep class com.nexgo.oaf.apiv3.device.printer.** { *; } + +# Prevent method shrinking/optimization +-dontoptimize +-dontshrink + +-dontwarn com.xgd.smartpos.manager.app.UsageInfo +-dontwarn com.xgd.smartpos.manager.app.UsageStats \ No newline at end of file diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/BaseXPrint.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/BaseXPrint.java index 674bb4d..203270a 100644 --- a/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/BaseXPrint.java +++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/BaseXPrint.java @@ -343,9 +343,9 @@ public abstract class BaseXPrint { // print2ColumnsStringNoSpace("AID :", MPU_AID); // } - if (payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_ACCEPT) || payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_APPROVED)) { - print2ColumnsStringNoSpace("TXN ID :",payDetail.getReferNo()); - } +// if (payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_ACCEPT) || payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_APPROVED)) { +// print2ColumnsStringNoSpace("TXN ID :",payDetail.getReferNo()); +// } @@ -891,15 +891,16 @@ public abstract class BaseXPrint { } dashBreak(); - print2ColumnsString("Refund Total:MMK", PrintUtils.getInstance().getSeparatorOnlyNumberFormat(refundTotal)); +// print2ColumnsString("Refund Total:MMK", PrintUtils.getInstance().getSeparatorOnlyNumberFormat(refundTotal)); + printer.appendPrnStr("Refund Total:MMK", PrintUtils.getInstance().getSeparatorOnlyNumberFormat(refundTotal) + " ", fontNormal, false); dashBreak(); - print2ColumnsString("Sale Total :MMK", PrintUtils.getInstance().getSeparatorOnlyNumberFormat(totalAmount)); +// print2ColumnsString("Sale Total :MMK", PrintUtils.getInstance().getSeparatorOnlyNumberFormat(totalAmount)); + printer.appendPrnStr("Sale Total :MMK", PrintUtils.getInstance().getSeparatorOnlyNumberFormat(totalAmount) + " ", fontNormal, false); dashBreak(); - print2ColumnsString("Sale Total :MMK", PrintUtils.getInstance().getSeparatorOnlyNumberFormat(totalAmount - refundTotal)); +// print2ColumnsString("Grand Total :MMK", PrintUtils.getInstance().getSeparatorOnlyNumberFormat(totalAmount - refundTotal)); + printer.appendPrnStr("Grand Total :MMK", PrintUtils.getInstance().getSeparatorOnlyNumberFormat(totalAmount - refundTotal) + " ", fontNormal, false); dashBreakEnding(); // emptyLine(2); - - } private void printErrorBlock(String msg) { @@ -1113,9 +1114,10 @@ public abstract class BaseXPrint { printer.appendPrnStr("TIME :" + payDetail.getTransTime(), fontNormal, AlignEnum.LEFT, false); if (payDetail.getTransactionType() == TransactionsType.MMQR.value && payDetail.getQrTransStatus() == 1) { // printer.appendPrnStr("TRACE NO:" + traceNum + " INV NO:" + invoiceNo, fontNormal, AlignEnum.LEFT,false); - printer.appendPrnStr("INV NO :" + invoiceNo , fontNormal, AlignEnum.LEFT,false); +// printer.appendPrnStr("INV NO :" + invoiceNo , fontNormal, AlignEnum.LEFT,false); + printer.appendPrnStr("TRACE NO :" + traceNum , fontNormal, AlignEnum.LEFT,false); } else if (!payDetail.getTransType().equals(SETTLEMENT) && !payDetail.getTransType().equals(SUMMARY) && payDetail.getTransactionType() != TransactionsType.MMQR_REFUND.value && payDetail.getTransactionType() != TransactionsType.MMQR.value) { - printer.appendPrnStr("BTH NO :" + batchNum + " INV NO:" + invoiceNo, fontNormal, AlignEnum.LEFT,false); + printer.appendPrnStr("BTH NO :" + batchNum + " INV NO:" + invoiceNo, fontNormal, AlignEnum.LEFT,false); } else if (payDetail.getTransType().equals(SUMMARY)) { printer.appendPrnStr("HOST :" + HOST_NAME_MPU + "", fontNormal, AlignEnum.LEFT,false); } @@ -1199,7 +1201,8 @@ public abstract class BaseXPrint { printer.appendPrnStr("TIME :" + payDetail.getTransTime(), fontNormal, AlignEnum.LEFT, false); if (payDetail.getTransactionType() == TransactionsType.MMQR.value && payDetail.getQrTransStatus() == 1) { // printer.appendPrnStr("TRACE NO:" + traceNum + " INV NO:" + invoiceNo, fontNormal, AlignEnum.LEFT,false); - printer.appendPrnStr("INV NO :" + invoiceNo , fontNormal, AlignEnum.LEFT,false); +// printer.appendPrnStr("INV NO :" + invoiceNo , fontNormal, AlignEnum.LEFT,false); + printer.appendPrnStr("TRACE NO :" + traceNum , fontNormal, AlignEnum.LEFT,false); } else if (!payDetail.getTransType().equals(SETTLEMENT) && !payDetail.getTransType().equals(SUMMARY) && payDetail.getTransactionType() != TransactionsType.MMQR_REFUND.value && payDetail.getTransactionType() != TransactionsType.MMQR.value) { // printer.appendPrnStr("BTH NO :" + batchNum + " INV NO:" + invoiceNo, fontNormal, AlignEnum.LEFT,false); } else if (payDetail.getTransType().equals(SUMMARY)) { diff --git a/release_key.jks b/release_key.jks new file mode 100644 index 0000000..bafec2b Binary files /dev/null and b/release_key.jks differ