diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index d0d4139..8e60dc8 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -13,7 +13,6 @@
-
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..b6fcc1b
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,11 @@
+# Change log UAT
+
+## [2.12] - 2026-05-06
+
+- **Pinpad Sound Toggle**
+ - Beep is ON by default
+ - Can Toggle PinPad sound on Side Navigation ( Under SystemManagement Tab)
+
+- **Transaction Search**
+ - Search now matches by both Trace No and RRN instead of Trace No only
+ - Trace No uses partial match (`contains`), RRN uses exact match (`equals`)
\ No newline at end of file
diff --git a/app/build.gradle b/app/build.gradle
index 274ea31..f57d89d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -14,8 +14,8 @@ android {
applicationId "com.utsmm.kbz"
minSdk 24
targetSdk 33
- versionCode 21
- versionName "2.1"
+ versionCode 2
+ versionName "2.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -50,7 +50,7 @@ android {
buildTypes {
release {
minifyEnabled true
- shrinkResources false
+ shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
@@ -204,7 +204,7 @@ dependencies {
// ECR Dependencies - Modern ECR Client Library
// implementation project(path: ':ecr-client-lib')
- implementation project(path: ':ecr-service-lib')
+// implementation project(path: ':ecr-service-lib')
// Core Libraries
implementation project(path: ':paylibs')
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 91cbd61..700ec22 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -265,4 +265,5 @@
-dontshrink
-dontwarn com.xgd.smartpos.manager.app.UsageInfo
--dontwarn com.xgd.smartpos.manager.app.UsageStats
\ No newline at end of file
+-dontwarn com.xgd.smartpos.manager.app.UsageStats
+-dontwarn javax.lang.model.element.Modifier
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9c36dce..f81b423 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -35,6 +35,10 @@
+
+
+
+
diff --git a/app/src/main/java/com/utsmm/kbz/MainActivity.java b/app/src/main/java/com/utsmm/kbz/MainActivity.java
index 189f63a..ea2f59d 100644
--- a/app/src/main/java/com/utsmm/kbz/MainActivity.java
+++ b/app/src/main/java/com/utsmm/kbz/MainActivity.java
@@ -4,6 +4,7 @@ import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.drawerlayout.widget.DrawerLayout;
+import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.NavDestination;
@@ -32,6 +33,7 @@ import com.nexgo.downloadkey.downloadflow.DownloadFlowResultEntity;
import com.nexgo.downloadkey.downloadflow.DownloadResult;
import com.nexgo.oaf.apiv3.device.pinpad.PinPad;
import com.nexgo.oaf.apiv3.device.pinpad.WorkKeyTypeEnum;
+import com.utsmm.kbz.util.LocationUtil;
import com.utsmyanmar.baselib.BaseApplication;
import com.utsmyanmar.baselib.repo.Repository;
import com.utsmyanmar.baselib.ui.AnimationDialog;
@@ -115,6 +117,7 @@ public class MainActivity extends AppCompatActivity implements
super.onCreate(savedInstanceState);
BaseApplication.getInstance().deviceEngine.getPlatform().hideNavigationBar();
+// BaseApplication.getInstance().deviceEngine.getPlatform().showNavigationBar();
// Keep screen on
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
@@ -157,10 +160,8 @@ public class MainActivity extends AppCompatActivity implements
}
private void initKey(){
- SystemParamsOperation.getInstance().setTmsAddress("https://api-tms-uat.kbzbank.com:8443/sirius");
-// SystemParamsOperation.getInstance().setTmsAddress("https://sirius-nest.utsmyanmar.com");
- SystemParamsOperation.getInstance().setEReceiptAddress("https://api-tms-uat.kbzbank.com:8443/receipt");
-// SystemParamsOperation.getInstance().setEReceiptAddress("http://receipt-nest.utsmyanmar.com");
+ SystemParamsOperation.getInstance().setTmsAddress("https://api-tms.kbzbank.com/sirius");
+ SystemParamsOperation.getInstance().setEReceiptAddress("https://api-tms.kbzbank.com/receipt");
PinPad pinPad = MyApplication.getInstance().deviceEngine.getPinPad();
byte[] encryptedPIK = SystemParamsOperation.getInstance().getPIK();
@@ -176,6 +177,7 @@ public class MainActivity extends AppCompatActivity implements
private void initViewModels() {
sharedViewModel = new ViewModelProvider(this).get(SharedViewModel.class);
+ sharedViewModel.getToastMsg().observe(this, this::showToast);
}
private void setupUI() {
@@ -427,20 +429,19 @@ public class MainActivity extends AppCompatActivity implements
@Override
public void onResume() {
super.onResume();
-
+ getLocation();
SystemParamsOperation.getInstance().setSetupEcr(false);
SystemParamsOperation.getInstance().setDownloadedParams(false);
handleAutoSettlementIntent(getIntent());
BaseApplication.getInstance().deviceEngine.getPlatform().hideNavigationBar();
+// BaseApplication.getInstance().deviceEngine.getPlatform().showNavigationBar();
}
@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();
}
@Override
@@ -450,69 +451,114 @@ public class MainActivity extends AppCompatActivity implements
handleAutoSettlementIntent(intent);
}
+ public void getLocation() {
+ LocationUtil.getCurrentLocation(MainActivity.this, new LocationUtil.LocationCallback() {
+ @Override
+ public void onSuccess(double lat, double lng) {
+ LogUtil.d("Location", "Current Location: " + lat + ", " + lng);
+ LocationUtil.setLat(lat);
+ LocationUtil.setLng(lng);
+ }
+
+ @Override
+ public void onError(String reason) {
+ LogUtil.e("Location", "get Location error: " + reason);
+ LocationUtil.setLat(0.00);
+ LocationUtil.setLng(0.00);
+ }
+ });
+ }
+
private void handleAutoSettlementIntent(Intent intent) {
if (intent == null) return;
-
- // Handle regular auto settlement
- boolean auto = intent.getBooleanExtra("AUTO_SETTLEMENT", false);
- if (auto) {
+
+ boolean hasPOS = intent.getBooleanExtra("AUTO_SETTLEMENT", false);
+ boolean hasQR = intent.getBooleanExtra("AUTO_QR_SETTLEMENT", false);
+
+ if (hasPOS) {
PayDetail payDetail = (PayDetail) intent.getSerializableExtra("EXTRA_PAY_DETAIL");
if (payDetail != null) {
-
sharedViewModel.payDetail.setValue(payDetail);
sharedViewModel.transactionsType.setValue(TransactionsType.SETTLEMENT);
sharedViewModel.setAmount(POSUtil.getInstance().getDecimalAmountSeparatorFormat(payDetail.getAmount()));
+
try {
navController.navigate(R.id.transactionResultFragment);
} catch (Exception e) {
LogUtil.e(TAG, "Navigation error: " + e.getMessage());
}
+
+ // If QR also exists, trigger it AFTER POS result is done
+ if (hasQR) {
+ navigateToQRSettlementAfterPOS(intent);
+ }
+ } else {
+
+ // POS had no data, go straight to QR if available
+ if (hasQR) {
+ handleQRSettlement(intent);
+ }
}
- return;
+
+ } else if (hasQR) {
+ // Only QR settlement, no POS
+ handleQRSettlement(intent);
}
-
- // Handle QR auto settlement
- boolean autoQR = intent.getBooleanExtra("AUTO_QR_SETTLEMENT", false);
- if (autoQR) {
- int qrSaleCount = intent.getIntExtra("QR_SALE_COUNT", 0);
- long qrSaleAmount = intent.getLongExtra("QR_SALE_AMOUNT", 0L);
- int qrRefundCount = intent.getIntExtra("QR_REFUND_COUNT", 0);
- long qrRefundAmount = intent.getLongExtra("QR_REFUND_AMOUNT", 0L);
- long totalAmount = intent.getLongExtra("QR_TOTAL_AMOUNT", 0L);
- List qrTransList = (List) intent.getSerializableExtra("QR_TRANS_LIST");
+ }
- // Create QR settlement PayDetail
- SettleData settleData = new SettleData(
- qrSaleCount, qrSaleAmount, 0, 0L, qrRefundCount, qrRefundAmount, 0, 0L);
-
- TradeData tradeData = Params.newTrade(false);
- PayDetail payDetail = tradeData.getPayDetail();
- payDetail.setSettleDataObj(settleData);
- payDetail.setTransactionType(TransactionsType.MMQR_SETTLEMENT.value);
- payDetail.setTransType(TransactionsType.MMQR_SETTLEMENT.name);
- payDetail.setAmount(totalAmount);
- payDetail.setTradeAnswerCode("000");
-
-
- sharedViewModel.setAmount(POSUtil.getInstance().getDecimalAmountSeparatorFormat(totalAmount));
- sharedViewModel.payDetails.setValue(qrTransList);
- sharedViewModel.payDetail.setValue(payDetail);
- sharedViewModel.transactionsType.setValue(TransactionsType.MMQR_SETTLEMENT);
-
- try {
- navController.navigate(R.id.transactionResultFragment);
- } catch (Exception e) {
- LogUtil.e(TAG, "QR Auto Settlement navigation error: " + e.getMessage());
+ private void navigateToQRSettlementAfterPOS(Intent intent) {
+ // Observe transactionResultFragment's completion via ViewModel
+ // When POS result screen signals "done" (print complete / user dismissed),
+ // then navigate to QR result
+ sharedViewModel.onSettlementResultDone.observe(this, new Observer() {
+ @Override
+ public void onChanged(Boolean done) {
+ if (done != null && done) {
+ // Remove observer so it only fires once
+ sharedViewModel.onSettlementResultDone.removeObserver(this);
+ // Reset flag
+ sharedViewModel.onSettlementResultDone.postValue(false);
+ // Now navigate to QR
+ handleQRSettlement(intent);
+ }
}
+ });
+ }
+
+ private void handleQRSettlement(Intent intent) {
+ int qrSaleCount = intent.getIntExtra("QR_SALE_COUNT", 0);
+ long qrSaleAmount = intent.getLongExtra("QR_SALE_AMOUNT", 0L);
+ int qrRefundCount = intent.getIntExtra("QR_REFUND_COUNT", 0);
+ long qrRefundAmount = intent.getLongExtra("QR_REFUND_AMOUNT", 0L);
+ long totalAmount = intent.getLongExtra("QR_TOTAL_AMOUNT", 0L);
+ List qrTransList = (List) intent.getSerializableExtra("QR_TRANS_LIST");
+
+ SettleData settleData = new SettleData(
+ qrSaleCount, qrSaleAmount, 0, 0L, qrRefundCount, qrRefundAmount, 0, 0L);
+
+ TradeData tradeData = Params.newTrade(false);
+ PayDetail payDetail = tradeData.getPayDetail();
+ payDetail.setSettleDataObj(settleData);
+ payDetail.setTransactionType(TransactionsType.MMQR_SETTLEMENT.value);
+ payDetail.setTransType(TransactionsType.MMQR_SETTLEMENT.name);
+ payDetail.setAmount(totalAmount);
+ payDetail.setTradeAnswerCode("000");
+
+ sharedViewModel.setAmount(POSUtil.getInstance().getDecimalAmountSeparatorFormat(totalAmount));
+ sharedViewModel.payDetails.setValue(qrTransList);
+ sharedViewModel.payDetail.setValue(payDetail);
+ sharedViewModel.transactionsType.setValue(TransactionsType.MMQR_SETTLEMENT);
+
+ try {
+ navController.navigate(R.id.transactionResultFragment);
+ } catch (Exception e) {
+ LogUtil.e(TAG, "QR Auto Settlement navigation error: " + e.getMessage());
}
}
@Override
public void onDestroy() {
super.onDestroy();
-// BaseApplication.getInstance().deviceEngine.getPlatform().showNavigationBar();
-// BaseApplication.getInstance().deviceEngine.getPlatform().enableHomeButton();
-// BaseApplication.getInstance().deviceEngine.getPlatform().enableTaskButton();
// Clean up RxJava disposables
compositeDisposable.clear();
// Reset screen mode
@@ -625,4 +671,4 @@ public class MainActivity extends AppCompatActivity implements
private void showToast(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/utsmm/kbz/MainFragment.java b/app/src/main/java/com/utsmm/kbz/MainFragment.java
index 9b1a4de..bfefb33 100644
--- a/app/src/main/java/com/utsmm/kbz/MainFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/MainFragment.java
@@ -29,9 +29,11 @@ import com.denzcoskun.imageslider.constants.ScaleTypes;
import com.denzcoskun.imageslider.models.SlideModel;
import com.nexgo.oaf.apiv3.emv.AidEntity;
import com.nexgo.oaf.apiv3.emv.CapkEntity;
-import com.pos.connection.bridge.binder.ECRConstant;
+//import com.pos.connection.bridge.binder.ECRConstant;
import com.utsmm.kbz.util.MockData;
+//import com.utsmm.kbz.util.ecr.ModernECRFactory;
+//import com.utsmm.kbz.util.ecr.ModernECRManager;
import com.utsmyanmar.baselib.BaseApplication;
import com.utsmyanmar.baselib.emv.EmvParamOperation;
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
@@ -63,6 +65,7 @@ import com.utsmm.kbz.ui.core_viewmodel.TMSProcessViewModel;
import com.utsmm.kbz.util.Connectivity;
+import com.utsmm.kbz.util.CurrencySelectionHelper;
import com.utsmm.kbz.util.dialog.AlertXDialog;
import com.utsmm.kbz.util.enums.SettlementType;
import com.utsmm.kbz.util.ecr.CoreUtils;
@@ -112,6 +115,7 @@ public class MainFragment extends DataBindingFragment {
private String cardPrimaryIp = "";
private String cardPrimarySecIp = "";
private CurrencyType cardPrimaryCurrency = CurrencyType.MMK;
+ private CurrencySelectionHelper currencySelectionHelper;
@Inject
EmvParamOperation emvParamOperation;
@@ -136,6 +140,7 @@ public class MainFragment extends DataBindingFragment {
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
mainViewModel = getFragmentScopeViewModel(MainViewModel.class);
tmsProcessViewModel = getFragmentScopeViewModel(TMSProcessViewModel.class);
+ currencySelectionHelper = new CurrencySelectionHelper(this, sharedViewModel);
// Initialize ModernECRManager
// ModernECRFactory factory = new ModernECRFactory(requireContext(), sharedViewModel);
@@ -170,12 +175,10 @@ public class MainFragment extends DataBindingFragment {
NexGoSDK.getInstance().cancelCheckCard();
NexGoSDK.getInstance().closeReader();
enableHomeButton();
-// disableTaskButton();
-// BaseApplication.getInstance().deviceEngine.getPlatform().hideNavigationBar();
- BaseApplication.getInstance().deviceEngine.getPlatform().showNavigationBar();
+
});
}
-
+
private void disableHomeButton() {
int result = BaseApplication.getInstance().deviceEngine.getPlatform().disableHomeButton();
LogUtil.d(TAG, "Disable Home Button Result:" + result);
@@ -262,7 +265,7 @@ public class MainFragment extends DataBindingFragment {
sharedViewModel.setManualEntryStatus(SystemParamsOperation.getInstance().getManualEntryStatus());
// queryAidCAPKList();
- queryAidCAPKList();
+// queryAidCAPKList();
// generateMockQR();
}
@@ -281,16 +284,21 @@ public class MainFragment extends DataBindingFragment {
LogUtil.d(TAG, "Total CAPK :" + noCAPK);
for (CapkEntity capkEntity : capkList) {
LogUtil.d(TAG, "CAPK Entity :" + capkEntity.getRid());
- if(capkEntity.getRid().equals("A000000003")) {
+ if(capkEntity.getRid().equals("A000000004")) {
LogUtil.d(TAG, "CAPK Entity check sum:" + capkEntity.getCheckSum());
LogUtil.d(TAG, "CAPK Entity modulus:" + capkEntity.getModulus());
LogUtil.d(TAG, "CAPK Entity index:" + capkEntity.getCapkIdx());
}
}
-// for (AidEntity aidEntity : aidList) {
-// LogUtil.d(TAG, "AID Entity :" + aidEntity.getAid());
-// }
+ for (AidEntity aidEntity : aidList) {
+ LogUtil.d(TAG, "AID Entity :" + aidEntity.getAid());
+// if(aidEntity.getAid().startsWith("A000000003")) {
+ LogUtil.d(TAG, "AID Entity AID:" + aidEntity.getAid());
+ LogUtil.d(TAG, "AID Entity ASI:" + aidEntity.getAsi());
+ LogUtil.d(TAG, "AID Entity Version:" + aidEntity.getAppVerNum());
+// }
+ }
}
@@ -316,8 +324,8 @@ public class MainFragment extends DataBindingFragment {
if (checkECRServiceAppExistOrNot()) {
// Initialize Modern ECR Manager
// modernECRManager.init();
-//
-// // Observe navigation requests
+////
+//// // Observe navigation requests
// modernECRManager.getNavigationRequest().observe(getViewLifecycleOwner(), destinationId -> {
// if (destinationId != null) {
// delayFunctionCall(() -> isRouteValidAndNavigateToRoute(destinationId));
@@ -627,6 +635,16 @@ public class MainFragment extends DataBindingFragment {
default:
return value;
}
+// currencySelectionHelper.showCardCurrencyChooser(this::startCardSaleFlow);
+ }
+
+ private void showCurrencyChooserForSignOn() {
+ currencySelectionHelper.showCardCurrencyChooser(this::navigateToSignOn);
+ }
+
+ private void navigateToSignOn() {
+ routeId = R.id.action_nav_main_to_nav_sign_on;
+ safeNavigateToRouteId();
}
private void processBatch() {
@@ -1017,12 +1035,10 @@ public class MainFragment extends DataBindingFragment {
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();
+ showCurrencyChooserForSignOn();
});
} else {
- routeId = R.id.action_nav_main_to_nav_sign_on;
- safeNavigateToRouteId();
+ showCurrencyChooserForSignOn();
}
}
diff --git a/app/src/main/java/com/utsmm/kbz/service/AutoSettleService.java b/app/src/main/java/com/utsmm/kbz/service/AutoSettleService.java
index e397ac3..85a488d 100644
--- a/app/src/main/java/com/utsmm/kbz/service/AutoSettleService.java
+++ b/app/src/main/java/com/utsmm/kbz/service/AutoSettleService.java
@@ -20,6 +20,7 @@ import com.google.gson.Gson;
import com.utsmm.kbz.MainActivity;
import com.utsmm.kbz.util.EReceiptUtil;
+import com.utsmm.kbz.util.enums.TransactionStatus;
import com.utsmyanmar.baselib.network.model.e_receipt.EReceiptRequest;
import com.utsmyanmar.baselib.repo.Repository;
import com.utsmm.kbz.BuildConfig;
@@ -34,6 +35,8 @@ import io.reactivex.rxjava3.schedulers.Schedulers;
import retrofit2.HttpException;
import com.utsmyanmar.paylibs.Constant;
+import com.utsmyanmar.paylibs.batch_upload.BatchListener;
+import com.utsmyanmar.paylibs.batch_upload.BatchUploadProcess;
import com.utsmyanmar.paylibs.isobuilder.ISOMode;
import com.utsmyanmar.paylibs.isobuilder.builderx.ISOMsgX;
import com.utsmyanmar.paylibs.isobuilder.builderx.ISOVersion;
@@ -44,6 +47,8 @@ import com.utsmyanmar.paylibs.model.SettleData;
import com.utsmyanmar.paylibs.model.TradeData;
import com.utsmyanmar.paylibs.network.ISOCallback;
import com.utsmyanmar.paylibs.network.ISOSocket;
+import com.utsmyanmar.paylibs.sign_on.EchoTestProcess;
+import com.utsmyanmar.paylibs.sign_on.SignOnListener;
import com.utsmyanmar.paylibs.utils.LogUtil;
import com.utsmyanmar.paylibs.utils.MessageType;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
@@ -73,15 +78,26 @@ public class AutoSettleService extends Service {
// Flags to prevent infinite loops
private boolean regularSettlementCompleted = false;
private boolean qrSettlementCompleted = false;
+
+ private boolean posHasData = false; // true = POS actually ran and has result
+ private boolean qrHasData = false; // true = QR actually ran and has result
// Observers to keep reference for cleanup
- private Observer> regularSettlementObserver;
- private Observer> qrSettlementObserver;
+ private Observer> regularSettlementObserver;
+ private Observer> qrSettlementObserver;
+ private int i = 0;
+
+ private boolean flag = false;
@Inject
Repository repository;
+ private PayDetail pendingPayDetail = null;
+ private Bundle pendingQrData = null;
+ private boolean posSettlementReady = false;
+ private boolean qrSettlementReady = false;
+ ArrayList payDetails = new ArrayList<>();
public static final String NOTIFICATION_CHANNEL_ID = "10001";
private final static String default_notification_channel_id = "default";
@@ -188,6 +204,10 @@ public class AutoSettleService extends Service {
if (regularSettlementCompleted) {
return;
}
+
+ payDetails.clear();
+ payDetails.addAll(list);
+
regularSettlementCompleted = true;
repository.getSettlementPOS().removeObserver(this);
@@ -225,7 +245,13 @@ public class AutoSettleService extends Service {
String bitmap = BitmapConfig.BPC_SETTLEMENT;
payDetail.setTransType(TransactionsType.SETTLEMENT.name);
payDetail.setTransactionType(TransactionType.SETTLEMENT);
- payDetail.setProcessCode(TransactionsType.SETTLEMENT.processCode);
+ if(!flag) {
+ payDetail.setProcessCode(TransactionsType.SETTLEMENT.processCode);
+ } else {
+ bitmap = BitmapConfig.BPC_SETTLEMENT_TRAILER;
+ payDetail.setProcessCode("910000");
+ }
+
payDetail.setBatchNo(SystemParamsOperation.getInstance().getCurrentBatchNum());
SettleData settleData = new SettleData(
@@ -245,6 +271,14 @@ public class AutoSettleService extends Service {
} else {
settlementData = "C" + String.format(Locale.getDefault(), "%012d", totalAmount);
}
+
+ if(totalAmount == 0 && (saleCount == 0 || preCount == 0 || refundCount == 0 || caCount == 0)) {
+ posSettlementReady = true;
+ posHasData = false;
+ checkAndLaunch();
+ checkIfBothSettlementsComplete();
+ return;
+ }
payDetail.setSettleData(settlementData);
payDetail.setAmount(totalAmount);
@@ -269,7 +303,7 @@ public class AutoSettleService extends Service {
if (TextUtils.equals(resultStr, Constant.ANSWER_CODE_ACCEPT) || TextUtils.equals(resultStr, Constant.ANSWER_CODE_APPROVED)) {
payDetail.setIsNeedReversal(false);
} else if (TextUtils.equals(resultStr, "95") || TextUtils.equals(resultStr, "095")) {
- payDetail.setIsNeedReversal(true);
+ payDetail.setIsNeedReversal(!flag);
}
}
}
@@ -284,34 +318,25 @@ public class AutoSettleService extends Service {
public void onComplete() {
LogUtil.d(TAG, "Auto settlement transaction completed successfully");
- if (list != null && !list.isEmpty()) {
- for (PayDetail p : list) {
- repository.deletePayDetail(p);
+ if(payDetail.getIsNeedReversal()) {
+ flag = true;
+ batchUploadProcess();
+ } else {
+
+ flag = false;
+
+ if (!list.isEmpty()) {
+ for (PayDetail p : list) {
+ repository.deletePayDetail(p);
+ }
}
+ repository.insertPayDetail(payDetail);
+
+ networkCutOver(payDetail);
+
}
- repository.insertPayDetail(payDetail);
-
- try {
- PayDetail cleanPayDetail = new PayDetail();
- cleanPayDetail.setTransType(payDetail.getTransType());
- cleanPayDetail.setTransactionType(payDetail.getTransactionType());
- cleanPayDetail.setProcessCode(payDetail.getProcessCode());
- cleanPayDetail.setBatchNo(payDetail.getBatchNo());
- cleanPayDetail.setSettleData(payDetail.getSettleData());
- cleanPayDetail.setAmount(payDetail.getAmount());
- cleanPayDetail.setTradeAnswerCode(payDetail.getTradeAnswerCode());
- cleanPayDetail.setIsNeedReversal(payDetail.getIsNeedReversal());
-
- // Use notification-based approach to reliably launch the app
- launchAppWithSettlementResult("AUTO_SETTLEMENT", cleanPayDetail, null);
-
- } catch (Exception e) {
- LogUtil.e(TAG, "Error launching app with settlement result: " + e.getMessage());
- e.printStackTrace();
}
- checkIfBothSettlementsComplete();
- }
});
}
};
@@ -319,6 +344,41 @@ public class AutoSettleService extends Service {
repository.getSettlementPOS().observeForever(regularSettlementObserver);
}
+ private void batchUploadProcess() {
+
+ if(payDetails == null || payDetails.isEmpty()){
+ regularSettlementCompleted = false;
+ performSettlement();
+ return;
+ }
+
+ PayDetail payDetail = payDetails.get(i);
+ TradeData tradeData = new TradeData();
+ tradeData.setPayDetail(payDetail);
+ BatchUploadProcess.getInstance().enqueue(tradeData).startBatchUpload(new BatchListener() {
+ @Override
+ public void onSuccessBatch() {
+
+ if (i < payDetails.size() - 1) {
+ LogUtil.d(TAG, "Pay detail Size:" + payDetails.size());
+ LogUtil.d(TAG, "Count value:" + i);
+ i++;
+ batchUploadProcess();
+ } else {
+ regularSettlementCompleted = false;
+ performSettlement();
+ }
+
+ LogUtil.e(TAG, "Batch Upload Success");
+ }
+
+ @Override
+ public void onFailBatch() {
+ LogUtil.e(TAG, "Batch Upload Fail");
+ }
+ });
+ }
+
private void performQRSettlement() {
if (qrSettlementCompleted) {
return;
@@ -365,6 +425,9 @@ public class AutoSettleService extends Service {
}
} catch (IllegalStateException e) {
LogUtil.e(TAG, "QR Auto Settlement: Database cursor error - likely due to large data size: " + e);
+ qrSettlementReady = true;
+ qrHasData = false;
+ checkAndLaunch();
checkIfBothSettlementsComplete();
return;
}
@@ -422,19 +485,24 @@ public class AutoSettleService extends Service {
qrData.putLong("QR_TOTAL_AMOUNT", totalAmount);
qrData.putSerializable("QR_TRANS_LIST", qrTransactionsList);
// Use notification-based approach to reliably launch the app
- launchAppWithSettlementResult("AUTO_QR_SETTLEMENT", null, qrData);
+ pendingQrData = qrData;
+ qrHasData = true;
+// launchAppWithSettlementResult("AUTO_QR_SETTLEMENT", null, qrData,false);
} catch (Exception e) {
LogUtil.e(TAG, "Error launching app for QR settlement: " + e.getMessage());
+ qrHasData = false;
e.printStackTrace();
}
LogUtil.d(TAG, "QR Auto Settlement completed successfully");
} else {
LogUtil.d(TAG, "No QR transactions found for auto settlement");
+ qrHasData = false;
}
}
-
+ qrSettlementReady = true;
+ checkAndLaunch();
checkIfBothSettlementsComplete();
}
};
@@ -448,7 +516,7 @@ public class AutoSettleService extends Service {
stopSelf();
}
}
-
+
@Override
public void onCreate() {
super.onCreate();
@@ -480,69 +548,120 @@ public class AutoSettleService extends Service {
}
- private void launchAppWithSettlementResult(String settlementType,
- PayDetail payDetail,
- Bundle qrData) {
+ private void networkCutOver(PayDetail payDetail) {
+ EchoTestProcess.getInstance().enqueueCutOver().startSignOn(new SignOnListener() {
+ @Override
+ public void onSuccessSignOn() {
+
+ pendingPayDetail = payDetail;
+ posHasData = true;
+ posSettlementReady = true;
+ checkAndLaunch();
+ checkIfBothSettlementsComplete();
+
+ }
+
+ @Override
+ public void onFailureSignOn(Integer resultCode) {
+ LogUtil.d(TAG,"Failure Cut Over message: "+resultCode);
+ // POS done but cutover failed — still mark ready
+ posSettlementReady = true;
+ posHasData = false;
+ checkAndLaunch();
+ checkIfBothSettlementsComplete();
+ }
+
+ @Override
+ public void onNetworkFailSignOn(String message) {
+ LogUtil.d(TAG,"Network Fail Cut Over message: "+message);
+ posSettlementReady = true;
+ posHasData = false;
+ checkAndLaunch();
+ checkIfBothSettlementsComplete();
+
+ }
+ });
+ }
+
+ private void checkAndLaunch() {
+ // !!!! need to add flag, if don't want both at once
+ if (!posSettlementReady || !qrSettlementReady) {
+ LogUtil.d(TAG, "Waiting for both settlements... POS=" + posSettlementReady + " QR=" + qrSettlementReady);
+ return;
+ }
+
+ LogUtil.d(TAG, "Both settlements ready. POS has data=" + posHasData + ", QR has data=" + qrHasData);
+
+ if (!posHasData && !qrHasData) {
+ LogUtil.d(TAG, "No settlement data to display");
+ return;
+ }
+
+ launchMainActivity();
+ }
+
+ private void launchMainActivity() {
try {
Intent launchIntent = new Intent(this, MainActivity.class);
- launchIntent.putExtra(settlementType, true);
-
- if ("AUTO_SETTLEMENT".equals(settlementType) && payDetail != null) {
+ launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+ Intent.FLAG_ACTIVITY_CLEAR_TOP |
+ Intent.FLAG_ACTIVITY_SINGLE_TOP);
+
+ if (posHasData && pendingPayDetail != null) {
+ launchIntent.putExtra("AUTO_SETTLEMENT", true);
launchIntent.putExtra("EXTRA_TRANSACTION_TYPE", TransactionsType.SETTLEMENT.value);
- launchIntent.putExtra("EXTRA_PAY_DETAIL", payDetail);
- } else if ("AUTO_QR_SETTLEMENT".equals(settlementType) && qrData != null) {
- launchIntent.putExtra("EXTRA_TRANSACTION_TYPE", TransactionsType.MMQR_SETTLEMENT.value);
- launchIntent.putExtras(qrData);
+ launchIntent.putExtra("EXTRA_PAY_DETAIL", pendingPayDetail);
+ }
+
+ if (qrHasData && pendingQrData != null) {
+ launchIntent.putExtra("AUTO_QR_SETTLEMENT", true);
+ launchIntent.putExtra("EXTRA_QR_TRANSACTION_TYPE", TransactionsType.MMQR_SETTLEMENT.value);
+ launchIntent.putExtras(pendingQrData);
}
PendingIntent pendingIntent = PendingIntent.getActivity(
- this,
- (int) System.currentTimeMillis(),
- launchIntent,
- PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
+ this,
+ (int) System.currentTimeMillis(),
+ launchIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
- "SETTLEMENT_COMPLETE",
- "Settlement Complete",
- NotificationManager.IMPORTANCE_HIGH
- );
+ "SETTLEMENT_COMPLETE", "Settlement Complete", NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("Auto settlement completion notifications");
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "SETTLEMENT_COMPLETE")
- .setSmallIcon(R.drawable.ic_launcher_foreground)
- .setContentTitle("Auto Settlement Complete")
- .setContentText("Tap to view settlement results and print receipt")
- .setPriority(NotificationCompat.PRIORITY_HIGH)
- .setAutoCancel(true)
- .setContentIntent(pendingIntent)
- .setFullScreenIntent(pendingIntent, true);
+ .setSmallIcon(R.drawable.ic_launcher_foreground)
+ .setContentTitle("Auto Settlement Complete")
+ .setContentText("Tap to view settlement results and print receipt")
+ .setPriority(NotificationCompat.PRIORITY_HIGH)
+ .setAutoCancel(true)
+ .setContentIntent(pendingIntent)
+ .setFullScreenIntent(pendingIntent, true);
notificationManager.notify(2001, builder.build());
-
- LogUtil.d(TAG, " Settlement complete notification created - will launch app when tapped");
-
- try {
- launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
- Intent.FLAG_ACTIVITY_CLEAR_TOP |
- Intent.FLAG_ACTIVITY_SINGLE_TOP |
- Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
- Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
- startActivity(launchIntent);
- } catch (Exception directException) {
- LogUtil.d(TAG, "Direct launch failed (expected on modern Android), notification approach will handle it");
- }
+
+ // Reset state
+ pendingPayDetail = null;
+ pendingQrData = null;
+ posSettlementReady = false;
+ qrSettlementReady = false;
+ posHasData = false;
+ qrHasData = false;
+
+ startActivity(launchIntent);
} catch (Exception e) {
- LogUtil.e(TAG, "Error creating settlement notification: " + e.getMessage());
+ LogUtil.e(TAG, "Error launching MainActivity: " + e.getMessage());
e.printStackTrace();
}
}
+
+
private void sendEReceipt(EReceiptRequest request) {
try {
LogUtil.d(TAG, "Sending e-receipt: " + new Gson().toJson(request));
diff --git a/app/src/main/java/com/utsmm/kbz/ui/SettingsFragment.java b/app/src/main/java/com/utsmm/kbz/ui/SettingsFragment.java
index 965cd4c..43c422e 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/SettingsFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/SettingsFragment.java
@@ -13,6 +13,7 @@ import androidx.navigation.Navigation;
import com.google.gson.Gson;
import com.google.gson.stream.MalformedJsonException;
+import com.utsmm.kbz.MainActivity;
import com.utsmm.kbz.config.Constants;
import com.nexgo.downloadkey.downloadflow.DownloadFEntity;
import com.nexgo.downloadkey.downloadflow.DownloadFlow;
@@ -162,6 +163,10 @@ public class SettingsFragment extends DataBindingFragment {
}
private void updateReversalSettings() {
+ boolean isVisible = SystemParamsOperation.getInstance().getAutoReversalEnable();
+ LogUtil.d("SettingsFragment", "isVisible " + isVisible);
+ binding.reversalCard.setVisibility(isVisible ? View.VISIBLE : View.GONE);
+
boolean isEnabled = SystemParamsOperation.getInstance().isReversalOn();
binding.reversalSwitch.setChecked(isEnabled);
binding.reversalSummary.setText(isEnabled ?
@@ -327,6 +332,17 @@ public class SettingsFragment extends DataBindingFragment {
}
}
+ public void onClearReversalClick() {
+ try {
+ sharedViewModel.transactionsType.postValue(TransactionsType.CLEAR_REVERSAL);
+ sharedViewModel.setTransMenu(TransMenu.CLEAR_REVERSAL);
+ Navigation.findNavController(requireActivity(), R.id.nav_host_fragment)
+ .navigate(R.id.inputPasswordFragment);
+ } catch (Exception e) {
+ LogUtil.e(TAG, "Error in clear reversal click: " + e.getMessage());
+ }
+ }
+
public void onTmsConfigClick() {
try {
LogUtil.d(TAG, "TMS Config clicked");
@@ -393,6 +409,9 @@ public class SettingsFragment extends DataBindingFragment {
private void downloadParams(String lastTransName, String lastTransTime) {
try {
LogUtil.d(TAG, "Downloading params for transaction: " + lastTransName);
+
+ ((MainActivity) requireActivity()).getLocation();
+
SiriusRequest siriusReq = TMSUtil.getInstance().generateRequestParams(getContext(), lastTransName, lastTransTime);
mainViewModel.getParams(siriusReq)
diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_ui/CardWaitingFragment.java b/app/src/main/java/com/utsmm/kbz/ui/core_ui/CardWaitingFragment.java
index 66b3966..5ae02ab 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/core_ui/CardWaitingFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/core_ui/CardWaitingFragment.java
@@ -151,6 +151,12 @@ public class CardWaitingFragment extends DataBindingFragment implements DataBind
}else if(sharedViewModel.getIsSeePhone().getValue() != null && sharedViewModel.getIsSeePhone().getValue()) {
cardReadViewModel.setCheckCardAlertMsg("Please Tap!",false);
setupCardReadProcess(true);
+ } else if(sharedViewModel.getIsCardAppBlock().getValue() != null && sharedViewModel.getIsCardAppBlock().getValue()) {
+ cardReadViewModel.setCheckCardAlertMsg("Magstripe not allowed!",false);
+ setupCardReadProcess(true);
+ } else if(sharedViewModel.getIsContactlessRestricted().getValue() != null && sharedViewModel.getIsContactlessRestricted().getValue()) {
+ cardReadViewModel.setCheckCardAlertMsg("Tap not allowed!",false);
+ setupCardReadProcess(true);
} else {
setupCardReadProcess(false);
}
@@ -163,6 +169,7 @@ public class CardWaitingFragment extends DataBindingFragment implements DataBind
sharedViewModel.setIsFallback(false);
sharedViewModel.setIsSeePhone(false);
+ sharedViewModel.setIsContactlessRestricted(false);
// cardReadViewModel.cancelCheckCard();
@@ -256,9 +263,20 @@ public class CardWaitingFragment extends DataBindingFragment implements DataBind
if(sharedViewModel.getIsSeePhone().getValue() != null && sharedViewModel.getIsSeePhone().getValue()) {
allType.add(CardSlotTypeEnum.RF);
waitTimeout = 20;
- } else {
+ } else if(!SystemParamsOperation.getInstance().isNfcEnabled()) {
+ allType.add(CardSlotTypeEnum.ICC1);
+ allType.add(CardSlotTypeEnum.SWIPE);
+ } else if(sharedViewModel.getIsContactlessRestricted().getValue() != null && sharedViewModel.getIsContactlessRestricted().getValue()) {
+ allType.add(CardSlotTypeEnum.ICC1);
+// allType.add(CardSlotTypeEnum.SWIPE);
+ } else {
allType.add(CardSlotTypeEnum.ICC1);
allType.add(CardSlotTypeEnum.RF);
+
+ if(SystemParamsOperation.getInstance().isMagStripeEnabled()) {
+ allType.add(CardSlotTypeEnum.SWIPE);
+ }
+
}
// int allType = AidlConstants.CardType.IC.getValue() | AidlConstants.CardType.MAGNETIC.getValue();
@@ -286,7 +304,7 @@ public class CardWaitingFragment extends DataBindingFragment implements DataBind
} else if (isFallback && cardType == CardTypeX.MAG) {
/* do fallback transactions */
- sharedViewModel.isEmv.setValue(false);
+ sharedViewModel.isEmv.postValue(false);
cardReadViewModel.setCardTransactionType(CardTransactionType.FALLBACK);
} else if (cardType == CardTypeX.IC || cardType == CardTypeX.NFC) {
diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_ui/ConfirmTransactionFragment.java b/app/src/main/java/com/utsmm/kbz/ui/core_ui/ConfirmTransactionFragment.java
index 109f350..42a19ce 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/core_ui/ConfirmTransactionFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/core_ui/ConfirmTransactionFragment.java
@@ -246,7 +246,6 @@ public class ConfirmTransactionFragment extends DataBindingFragment implements D
public void onConfirm(){
if (sharedViewModel.transactionsType.getValue() == TransactionsType.TIP_ADJUSTMENT) {
-
routeId = R.id.action_confirmTransactionFragment_to_inputTipAmountFragment;
safeNavigateToRouteId();
diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_ui/EmvTransactionFragment.java b/app/src/main/java/com/utsmm/kbz/ui/core_ui/EmvTransactionFragment.java
index 913470f..ecd9418 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/core_ui/EmvTransactionFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/core_ui/EmvTransactionFragment.java
@@ -3,6 +3,7 @@ package com.utsmm.kbz.ui.core_ui;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
+import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -158,6 +159,7 @@ public class EmvTransactionFragment extends DataBindingFragment {
}
observeEmvResultStatus();
+ observePinWarning();
}
private boolean isNotManualTransaction() {
@@ -230,7 +232,19 @@ public class EmvTransactionFragment extends DataBindingFragment {
case ON_NEXT_SCREEN:
navigateToRRNScreen();
break;
+ case INSERT_OR_MANUAL:
+ if(cardReadViewModel.cardTypeData.getValue() != null && cardReadViewModel.cardTypeData.getValue() == CardTypeX.NFC.value) {
+ isCardTaped("Please insert or type card",new CardDetectCallback() {
+ @Override
+ public void onComplete() {
+ sharedViewModel.setIsContactlessRestricted(true);
+ navigateToCheckCard();
+ }
+ });
+ }
+ break;
case READ_CARD_RETRY:
+ LogUtil.d(TAG,"Card type :"+cardReadViewModel.cardTypeData.getValue());
if(cardReadViewModel.cardTypeData.getValue()!= null && cardReadViewModel.cardTypeData.getValue() == CardTypeX.IC.value) {
isCardInserted(new CardDetectCallback() {
@Override
@@ -243,12 +257,30 @@ public class EmvTransactionFragment extends DataBindingFragment {
isCardTaped("Please try again",new CardDetectCallback() {
@Override
public void onComplete() {
- sharedViewModel.setIsSeePhone(true);
+ sharedViewModel.setIsSeePhone(false);
+ navigateToCheckCard();
+ }
+ });
+ }
+ break;
+ case CARD_APP_BLOCKED:
+ if(cardReadViewModel.cardTypeData.getValue()!= null && cardReadViewModel.cardTypeData.getValue() == CardTypeX.IC.value) {
+ isCardInserted(new CardDetectCallback() {
+ @Override
+ public void onComplete() {
+ sharedViewModel.setIsCardAppBlock(true);
+ navigateToCheckCard();
+ }
+ });
+ } else if(cardReadViewModel.cardTypeData.getValue() != null && cardReadViewModel.cardTypeData.getValue() == CardTypeX.NFC.value) {
+ isCardTaped("Please try again",new CardDetectCallback() {
+ @Override
+ public void onComplete() {
+ sharedViewModel.setIsCardAppBlock(true);
navigateToCheckCard();
}
});
}
-
// sharedViewModel.set_errorFragmentMsg("Interface not found!");
// navigateToError();
break;
@@ -330,6 +362,15 @@ public class EmvTransactionFragment extends DataBindingFragment {
});
}
+ private void observePinWarning() {
+ emvTransactionViewModel.pinRemainingCount.observe(getViewLifecycleOwner(), msg -> {
+ if (!TextUtils.isEmpty(msg)) {
+ Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show();
+ emvTransactionViewModel.pinRemainingCount.setValue("");
+ }
+ });
+ }
+
private void observeEmvErrorCode() {
dismissLoadingDialog();
emvTransactionViewModel.errorCodeMsg.observe(getViewLifecycleOwner(), pair -> {
diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_ui/InputRRNFragment.java b/app/src/main/java/com/utsmm/kbz/ui/core_ui/InputRRNFragment.java
index 6e40d14..345a506 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/core_ui/InputRRNFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/core_ui/InputRRNFragment.java
@@ -201,7 +201,7 @@ public class InputRRNFragment extends DataBindingFragment {
private void checkRRNPreAuthVoid(boolean isECR) {
- rrnViewModel.searchPayDetail(cardNo,rrnNo).observe(getViewLifecycleOwner(), new Observer() {
+ rrnViewModel.searchPayDetailPreCancel(cardNo,rrnNo).observe(getViewLifecycleOwner(), new Observer() {
@Override
public void onChanged(PayDetail payDetail) {
if(payDetail != null) {
@@ -245,6 +245,8 @@ public class InputRRNFragment extends DataBindingFragment {
} else {
+ LogUtil.d(TAG,"PreAuth Cancel RRN not found!");
+
terminateProcess(isECR);
}
@@ -551,16 +553,16 @@ public class InputRRNFragment extends DataBindingFragment {
// }
} else {
- terminatedTransRefund(isECR);
+// terminatedTransRefund(isECR);
-// PayDetail newPay = transProcessViewModel.getPayDetail();
-// newPay.setReferNo(rrnNo);
-//
-// transProcessViewModel.setPayDetail(newPay);
-//
-// sharedViewModel.rrNNo.setValue(rrnNo);
-//
-// callNextScreen();
+ PayDetail newPay = transProcessViewModel.getPayDetail();
+ newPay.setReferNo(rrnNo);
+
+ transProcessViewModel.setPayDetail(newPay);
+
+ sharedViewModel.rrNNo.setValue(rrnNo);
+
+ callNextScreen();
}
}
diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_ui/InputTraceNoFragment.java b/app/src/main/java/com/utsmm/kbz/ui/core_ui/InputTraceNoFragment.java
index 6fee0b4..54c2863 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/core_ui/InputTraceNoFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/core_ui/InputTraceNoFragment.java
@@ -173,6 +173,7 @@ public class InputTraceNoFragment extends DataBindingFragment {
}
sharedViewModel.payDetail.setValue(payDetail);
+ sharedViewModel.setAmount(POSUtil.getInstance().getDecimalAmountSeparatorFormat(payDetail.getAmount()));
if(sharedViewModel.hostType.getValue() == HostType.MPU) {
boolean isMpu = "MPU".equals(payDetail.getAccountType());
diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_ui/ProcessingCardFragment.java b/app/src/main/java/com/utsmm/kbz/ui/core_ui/ProcessingCardFragment.java
index c6511e4..414b05a 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/core_ui/ProcessingCardFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/core_ui/ProcessingCardFragment.java
@@ -131,6 +131,7 @@ public class ProcessingCardFragment extends DataBindingFragment {
}
private void mockMPUCard() {
LogUtil.d(TAG,"initialize mock card data...");
+ sharedViewModel.isEmv.setValue(false);
routeId = R.id.action_processingCardFragment_to_pinPadFragment;
transProcessViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
pinPadViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
@@ -159,6 +160,7 @@ public class ProcessingCardFragment extends DataBindingFragment {
return;
}
}
+ sharedViewModel.isEmv.setValue(false);
routeId = R.id.action_processingCardFragment_to_pinPadFragment;
transProcessViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
@@ -168,12 +170,29 @@ public class ProcessingCardFragment extends DataBindingFragment {
transProcessViewModel.setTradeData(tradeData);
pinPadViewModel.setTradeData(tradeData);
- if(sharedViewModel.getTransactionsType().getValue() == TransactionsType.PRE_AUTH_VOID ) {
+ if(sharedViewModel.getTransactionsType().getValue() == TransactionsType.PRE_AUTH_VOID && SystemParamsOperation.getInstance().getPreAuthVoidManualEnabled() ) {
sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_alert_pre_auth_cancel));
routeId = R.id.action_processingCardFragment_to_errorFragment;
safeNavigateToRouteId();
return;
+
+ }
+ if(sharedViewModel.getTransactionsType().getValue() == TransactionsType.PRE_AUTH_SALE && SystemParamsOperation.getInstance().getPreAuthManualEnabled()) {
+
+ sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_alert_pre_auth_cancel));
+ routeId = R.id.action_processingCardFragment_to_errorFragment;
+ safeNavigateToRouteId();
+ return;
+
+ }
+ if(sharedViewModel.getTransactionsType().getValue() == TransactionsType.PRE_AUTH_COMPLETE && SystemParamsOperation.getInstance().getPreAuthCompleteManualEnabled()) {
+
+ sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_alert_pre_auth_cancel));
+ routeId = R.id.action_processingCardFragment_to_errorFragment;
+ safeNavigateToRouteId();
+ return;
+
}
// else if(sharedViewModel.transactionsType.getValue() == TransactionsType.REFUND) {
// sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_card_not_supported));
@@ -183,7 +202,9 @@ public class ProcessingCardFragment extends DataBindingFragment {
sharedViewModel.setCardDataExist(true);
- if(sharedViewModel.getAmountExist().getValue() != null && !sharedViewModel.getAmountExist().getValue()) {
+ if(sharedViewModel.getTransMenu().getValue() != TransMenu.PRE_AUTH_FULL_VOID
+ && sharedViewModel.getAmountExist().getValue() != null
+ && !sharedViewModel.getAmountExist().getValue()) {
routeId = R.id.action_processingCardFragment_to_inputAmountFragment;
}
@@ -238,13 +259,28 @@ public class ProcessingCardFragment extends DataBindingFragment {
transProcessViewModel.setTradeData(tradeData);
}
-
- if(sharedViewModel.getTransactionsType().getValue() == TransactionsType.PRE_AUTH_VOID ) {
+ if(sharedViewModel.getTransactionsType().getValue() == TransactionsType.PRE_AUTH_VOID && SystemParamsOperation.getInstance().getPreAuthVoidManualEnabled() ) {
sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_alert_pre_auth_cancel));
routeId = R.id.action_processingCardFragment_to_errorFragment;
}
+ if(sharedViewModel.getTransactionsType().getValue() == TransactionsType.PRE_AUTH_SALE && SystemParamsOperation.getInstance().getPreAuthManualEnabled()) {
+
+ sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_alert_pre_auth_cancel));
+ routeId = R.id.action_processingCardFragment_to_errorFragment;
+
+
+ }
+ if(sharedViewModel.getTransactionsType().getValue() == TransactionsType.PRE_AUTH_COMPLETE && SystemParamsOperation.getInstance().getPreAuthCompleteManualEnabled()) {
+
+ sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_alert_pre_auth_cancel));
+ routeId = R.id.action_processingCardFragment_to_errorFragment;
+
+
+ }
+
+
// else if(sharedViewModel.transactionsType.getValue() == TransactionsType.REFUND) {
// routeId = R.id.action_processingCardFragment_to_errorFragment;
// }
@@ -274,8 +310,39 @@ public class ProcessingCardFragment extends DataBindingFragment {
emvTransactionViewModel.transType.setValue(sharedViewModel.transactionsType.getValue());
if (SystemParamsOperation.getInstance().isEmvEnabled()) {
+
prepareEmvTransaction();
+
+ if(sharedViewModel.getTransactionsType().getValue() == TransactionsType.PRE_AUTH_VOID && SystemParamsOperation.getInstance().getPreAuthVoidManualEnabled() ) {
+
+ sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_alert_pre_auth_cancel));
+ routeId = R.id.action_processingCardFragment_to_errorFragment;
+ safeNavigateToRouteId();
+ return;
+
+ }
+ if(sharedViewModel.getTransactionsType().getValue() == TransactionsType.PRE_AUTH_SALE && SystemParamsOperation.getInstance().getPreAuthManualEnabled()) {
+
+ sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_alert_pre_auth_cancel));
+ routeId = R.id.action_processingCardFragment_to_errorFragment;
+ safeNavigateToRouteId();
+ return;
+
+
+ }
+ if(sharedViewModel.getTransactionsType().getValue() == TransactionsType.PRE_AUTH_COMPLETE && SystemParamsOperation.getInstance().getPreAuthCompleteManualEnabled()) {
+
+ sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_alert_pre_auth_cancel));
+ routeId = R.id.action_processingCardFragment_to_errorFragment;
+ safeNavigateToRouteId();
+ return;
+
+
+ }
+
+
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));
@@ -307,9 +374,7 @@ public class ProcessingCardFragment extends DataBindingFragment {
LogUtil.d(TAG,"card type:"+cardType);
LogUtil.d(TAG,"is MPU:"+isMPU);
-// delayFunctionCall(()->{
-//
-// });
+
handlePreEmvProcess();
}
diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_ui/ProcessingFragment.java b/app/src/main/java/com/utsmm/kbz/ui/core_ui/ProcessingFragment.java
index 07d3038..1b962f8 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/core_ui/ProcessingFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/core_ui/ProcessingFragment.java
@@ -6,6 +6,8 @@ import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.Observer;
import androidx.navigation.NavController;
import androidx.navigation.NavDestination;
@@ -17,6 +19,11 @@ import com.utsmyanmar.baselib.fragment.DataBindingFragment;
import com.utsmyanmar.baselib.network.model.e_receipt.EReceiptRequest;
import com.utsmyanmar.baselib.util.DataBindingConfig;
import com.utsmyanmar.baselib.util.TimeoutCallback;
+import com.utsmyanmar.paylibs.model.TradeData;
+import com.utsmyanmar.paylibs.print.PrintUtils;
+import com.utsmyanmar.paylibs.reversal.ReversalAction;
+import com.utsmyanmar.paylibs.reversal.ReversalListener;
+import com.utsmyanmar.paylibs.system.BaseErrorCode;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmm.kbz.BR;
import com.utsmm.kbz.R;
@@ -104,6 +111,17 @@ public class ProcessingFragment extends DataBindingFragment {
setToolBarTitleWithoutBackIcon(getResourceString(R.string.title_processing));
+ checkReversal();
+
+
+
+// disableNavigationBar();
+
+ getNavController(Constants.NAV_HOST_ID).addOnDestinationChangedListener(listener);
+
+ }
+
+ private void startTransactionProcess() {
if(isEmvTrans()) {
startTransactionProcess(emvTransactionProcessViewModel);
} else {
@@ -111,13 +129,55 @@ public class ProcessingFragment extends DataBindingFragment {
}
sharedViewModel.loadingMsg(getResourceString(R.string.txt_sending));
-
-// disableNavigationBar();
-
- getNavController(Constants.NAV_HOST_ID).addOnDestinationChangedListener(listener);
-
}
+ private void checkReversal() {
+ observeOnce(sharedViewModel.getLastReversalTransaction(), payDetail -> {
+ if (payDetail != null) {
+ TradeData tradeData = new TradeData();
+ tradeData.setPayDetail(payDetail);
+ LogUtil.d(TAG, "Sending Reversal!");
+ sharedViewModel.loadingMsg(getResourceString(R.string.txt_sending_reversal));
+
+ ReversalAction.getInstance().setData(tradeData).enqueue().startReversal(new ReversalListener() {
+ @Override
+ public void onSuccessReversal() {
+ LogUtil.d(TAG, "Reversal Success!");
+ payDetail.setIsNeedReversal(false);
+ sharedViewModel.updatePayDetail(payDetail);
+ delayFunctionCall(()->startTransactionProcess());
+ }
+
+ @Override
+ public void onNetworkFail(String msg) {
+ LogUtil.d(TAG, "Reversal Network Fail!" + msg);
+ startTransactionProcess();
+ }
+
+ @Override
+ public void onFailReversal(String msg) {
+ LogUtil.d(TAG, "Reversal Fail!" + msg);
+ startTransactionProcess();
+ }
+ });
+ } else {
+ LogUtil.d(TAG,"No reversal found!");
+ startTransactionProcess();
+ }
+ });
+ }
+
+ private void observeOnce(LiveData liveData, Observer observer) {
+ liveData.observe(getViewLifecycleOwner(), new Observer() {
+ @Override
+ public void onChanged(T t) {
+ liveData.removeObserver(this);
+ observer.onChanged(t);
+ }
+ });
+ }
+
+
private boolean isEmvTrans() {
return sharedViewModel.isEmv.getValue() != null && sharedViewModel.isEmv.getValue();
}
@@ -258,6 +318,18 @@ public class ProcessingFragment extends DataBindingFragment {
safeNavigateToRouteId();
}
+ private void handleAfterTransaction() {
+ if (SystemParamsOperation.getInstance().getDemoStatus()) {
+ delayFunctionCall(() -> {
+ sharedViewModel.dismissLoadingMsg();
+ callNextScreen();
+ }, 1500);
+ } else {
+ sharedViewModel.dismissLoadingMsg();
+ callNextScreen();
+ }
+ }
+
private void observeData(ProcessingTransaction processingTransaction) {
processingTransaction.getTransStatus().observe(getViewLifecycleOwner(), transResultStatus -> {
@@ -269,9 +341,13 @@ public class ProcessingFragment extends DataBindingFragment {
switch (transResultStatus) {
case FAIL:
- sharedViewModel.pushReceipt(buildEReceiptCardReceipt(payDetail, false, "FAILED"));
+ sharedViewModel.pushReceipt(buildEReceiptCardReceipt(payDetail, false, BaseErrorCode.getCode(payDetail.getTradeAnswerCode())));
+ handleAfterTransaction();
+ break;
case SUCCESS:
- sharedViewModel.pushReceipt(buildEReceiptCardReceipt(payDetail, true, "SUCCESS"));
+ sharedViewModel.pushReceipt(buildEReceiptCardReceipt(payDetail, true, BaseErrorCode.getCode(payDetail.getTradeAnswerCode())));
+ handleAfterTransaction();
+ break;
case OFFLINE_SUCCESS:
if(SystemParamsOperation.getInstance().getDemoStatus()) {
delayFunctionCall(()->{
@@ -288,6 +364,7 @@ public class ProcessingFragment extends DataBindingFragment {
break;
case OFFLINE_FAILURE:
+ sharedViewModel.pushReceipt(buildEReceiptCardReceipt(payDetail, false, BaseErrorCode.getCode(payDetail.getTradeAnswerCode())));
sharedViewModel.dismissLoadingMsg();
sharedViewModel.set_errorFragmentMsg(getResourceString(R.string.txt_offline_failure));
navigateToError();
@@ -385,20 +462,6 @@ public class ProcessingFragment extends DataBindingFragment {
});
}
-
- private String mapDE3ToShortCode(String de3) {
- if (de3 == null) return "UNK";
-
- switch (de3) {
- case "000000": return "S"; // Sale
- case "020000": return "V"; // Void
- case "200000": return "R"; // Refund
- case "030000": return "P"; // Preauth
- case "310000": return "PC"; // Preauth Complete
- }
- return "UNK"; // Unknown
- }
-
public static String mapTransactionType(int type) {
switch (type) {
case 1: // SALE
@@ -450,6 +513,16 @@ public class ProcessingFragment extends DataBindingFragment {
default: return currency; // Already alphabetic? return as-is
}
}
+
+ private String formatDE43(String value) {
+ if (value == null) value = "";
+
+ if (value.length() > 40) {
+ return value.substring(0, 40);
+ }
+
+ return String.format("%-40s", value); // right pad with space
+ }
private EReceiptCardRequest buildEReceiptCardReceipt(PayDetail payDetail, boolean isSuccess, String reason){
//current timestamp
String currentTimestamp = new java.text.SimpleDateFormat(
@@ -467,16 +540,30 @@ public class ProcessingFragment extends DataBindingFragment {
double realAmount = payDetail.getAmount() / 100.0;
DecimalFormat df = new DecimalFormat("0.00");
String amount = df.format(realAmount);
+
+ String rawName = PrintUtils.getInstance()
+ .getCardHolderName(payDetail.getCardHolderName());
+ String secondLine = PrintUtils.getInstance()
+ .processNameSpaceSecondLine(rawName);
+
+ String firstLine = PrintUtils.getInstance()
+ .processNameSpaceFirstLine(rawName, secondLine);
+
+
+ String cardHolderName = firstLine +
+ (secondLine.isEmpty() ? "" : " " + secondLine);
+
EReceiptCardRequest request = new EReceiptCardRequest();
- request.setDE2(payDetail.getCardNo());
- request.setDE3(mapDE3ToShortCode(payDetail.getProcessCode()));
+ request.setDE2(PrintUtils.getInstance().maskCardNumberPciDss(payDetail.getCardNo()));
+ request.setDE3(mapTransactionType(payDetail.getTransactionType()));
request.setDE4(amount);
request.setDE7(currentTimestamp);
request.setDE11(payDetail.getVoucherNo());
- request.setDE22(mapTransactionType(payDetail.getTransactionType()));
+// request.setDE22(mapTransactionType(payDetail.getTransactionType()));
+ request.setDE22(PrintUtils.getInstance().getEntryType(payDetail.getCardType()));
request.setDE37(payDetail.getReferNo());
- request.setDE38(payDetail.getAuthNo());
+ request.setDE38(payDetail.getApprovalCode());
request.setDE39(isSuccess ? "A" : "E");
request.setDE41(terminalId);
request.setDE42(merchantId);
@@ -485,6 +572,12 @@ public class ProcessingFragment extends DataBindingFragment {
request.setInvoiceNumber(payDetail.getInvoiceNo());
request.setAppId(appId);
request.setDescription(reason);
+ request.setBatchNumber(payDetail.batchNo);
+ request.setDE55(payDetail.getAppLabel());
+ request.setCardLabel(payDetail.getAccountType());
+ request.setDE14(PrintUtils.getInstance().getFormatExpDate(payDetail.getEXPDate()));
+ request.setDE43(formatDE43(cardHolderName));
+ request.setDE48(payDetail.getAID());
return request;
}
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 7e27c51..2d8d7f9 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
@@ -10,6 +10,8 @@ import androidx.appcompat.app.AppCompatActivity;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.stream.MalformedJsonException;
+import com.utsmm.kbz.MainActivity;
+import com.utsmm.kbz.util.LocationUtil;
import com.utsmyanmar.baselib.emv.EmvParamOperation;
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
import com.utsmyanmar.baselib.network.model.sirius.SiriusError;
@@ -156,6 +158,8 @@ public class TransactionResultFragment extends DataBindingFragment implements Da
return;
}
+ ((MainActivity) requireActivity()).getLocation();
+
SiriusRequest siriusReq = TMSUtil.getInstance().generateRequestParams(
getContext(),
payDetail.getTransType(),
@@ -331,6 +335,7 @@ public class TransactionResultFragment extends DataBindingFragment implements Da
sharedViewModel.startPrintSettlement(new PrintXStatus() {
@Override
public void onSuccess() {
+ sharedViewModel.onSettlementResultDone.postValue(true);
isCardInside();
}
diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/EmvTransactionProcessViewModel.java b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/EmvTransactionProcessViewModel.java
index 7e13cb6..ebf42f2 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/EmvTransactionProcessViewModel.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/EmvTransactionProcessViewModel.java
@@ -78,13 +78,21 @@ public class EmvTransactionProcessViewModel extends EmvBaseViewModel implements
break;
}
try {
- if (mPayDetail.PINCipher != null && !mPayDetail.PINCipher.isEmpty()) {
+ LogUtil.d("EmvTransactionProcessViewModel", "mPayDetail" + mPayDetail.PINCipher);
+ LogUtil.d("EmvTransactionProcessViewModel", "is offline pin entered " + isOfflinePinEntered);
+
+ if ((mPayDetail.PINCipher != null && !mPayDetail.PINCipher.isEmpty())) {
+ LogUtil.d("EmvTransactionProcessViewModel", "condition 1");
emvHandler.onSetPinInputResponse(true, false);
- } else if (isOfflinePinEntered) {
- emvHandler.onSetPinInputResponse(true, false);
- } else {
+ } else if(isOfflinePinEntered){
+ LogUtil.d("EmvTransactionProcessViewModel", "condition 2");
emvHandler.onSetPinInputResponse(true, false);
+ }else {
+ LogUtil.d("EmvTransactionProcessViewModel", "condition 3");
+
+ emvHandler.onSetPinInputResponse(true, true);
}
+
if (transType.getValue() == TransactionsType.PRE_AUTH_COMPLETE || transType.getValue() == TransactionsType.PRE_AUTH_VOID || transType.getValue() == TransactionsType.REFUND) {
emvResultStatus.postValue(EmvResultStatus.ON_NEXT_SCREEN);
}
@@ -162,7 +170,13 @@ public class EmvTransactionProcessViewModel extends EmvBaseViewModel implements
handleTransactionFail(msg.arg1, msg.obj.toString());
break;
case EMV_TRY_AGAIN:
- emvResultStatus.postValue(EmvResultStatus.READ_CARD);
+ emvResultStatus.postValue(EmvResultStatus.READ_CARD_RETRY);
+ break;
+ case EMV_INSERT_OR_MANUAL:
+ emvResultStatus.postValue(EmvResultStatus.INSERT_OR_MANUAL);
+ break;
+ case EMV_CARD_APP_BLOCK:
+ emvResultStatus.postValue(EmvResultStatus.CARD_APP_BLOCKED);
break;
case EMV_CONFIRM_CODE_VERIFY:
emvResultStatus.postValue(EmvResultStatus.CONFIRM_CODE_VERIFY);
@@ -443,8 +457,8 @@ public class EmvTransactionProcessViewModel extends EmvBaseViewModel implements
@Override
public void processPreVoidDb(PayDetail payResult) {
- mPayDetail.setIsCanceled(true);
- updatePayDetail(mPayDetail);
+ oldTransPayDetail.setIsCanceled(true);
+ updatePayDetail(oldTransPayDetail);
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
}
@@ -458,9 +472,11 @@ public class EmvTransactionProcessViewModel extends EmvBaseViewModel implements
if(oldTransPayDetail.getAmount() == payResult.getAmount()) {
oldTransPayDetail.setIsCanceled(true);
+ oldTransPayDetail.setAdjust(true);
updatePayDetail(oldTransPayDetail);
} else {
oldTransPayDetail.setIsCanceled(false);
+ oldTransPayDetail.setAdjust(true);
updatePayDetail(oldTransPayDetail);
}
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/InputAmountViewModel.java b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/InputAmountViewModel.java
index a291968..8c31a80 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/InputAmountViewModel.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/InputAmountViewModel.java
@@ -13,112 +13,109 @@ import java.util.Objects;
public class InputAmountViewModel extends ViewModel {
- private static final String TAG = InputAmountViewModel.class.getSimpleName();
-
public MutableLiveData inputAmountView = new MutableLiveData<>();
-
public SingleLiveEvent invalidAmountMsg = new SingleLiveEvent<>();
-
public SingleLiveEvent availableAmount = new SingleLiveEvent<>();
+ private static final int MAX_INT_DIGITS = 10;
+ private static final int MAX_DECIMAL_DIGITS = 2;
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;
+ private String formatInteger(String value) {
+ if (TextUtils.isEmpty(value)) return "0";
+ double amt = Double.parseDouble(value);
+ DecimalFormat formatter = new DecimalFormat("#,###");
+ return formatter.format(amt);
}
-
-
-
public NumberKeyboard.KeyClickCallback onKeyClick() {
return new NumberKeyboard.KeyClickCallback() {
+
@Override
public void onNumClick(int keyNum) {
- if (inputAmountView.getValue().length() == 15) {
- return;
- }
+ String current = inputAmountView.getValue();
+ if (current == null) return;
- if (TextUtils.equals(inputAmountView.getValue(), "0")) {
- inputAmountView.setValue(keyNum + "");
- } else if (inputAmountView.getValue().contains(".")) {
- StringBuilder inputAmount = new StringBuilder();
- inputAmount.append(inputAmountView.getValue());
+ String raw = current.replace(",", "");
- int dotIndex = inputAmount.indexOf(".");
+ if (raw.contains(".")) {
- if(inputAmount.substring(dotIndex).length() > 0 && inputAmount.substring(dotIndex+1).length() == 2) {
+ String[] parts = raw.split("\\.");
+ String intPart = parts[0];
+ String decimalPart = parts.length > 1 ? parts[1] : "";
+
+ if (decimalPart.length() >= MAX_DECIMAL_DIGITS) {
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);
- }
+ raw = raw + keyNum;
} else {
- if (inputAmountView.getValue().contains(",")) {
- inputAmountView.setValue(inputAmountView.getValue().replace(",", ""));
+
+ if (raw.length() >= MAX_INT_DIGITS) {
+ return;
}
- inputAmountView.setValue(inputAmountView.getValue() + keyNum);
- double amt = Double.parseDouble(inputAmountView.getValue());
- DecimalFormat formatter = new DecimalFormat("#,###");
- inputAmountView.setValue(formatter.format(amt));
+
+ if (TextUtils.equals(raw, "0")) {
+ raw = String.valueOf(keyNum);
+ } else {
+ raw = raw + keyNum;
+ }
+ }
+
+ if (raw.contains(".")) {
+ String[] parts = raw.split("\\.");
+ String formattedInt = formatInteger(parts[0]);
+ String decimal = parts.length > 1 ? parts[1] : "";
+ inputAmountView.setValue(formattedInt + "." + decimal);
+ } else {
+ inputAmountView.setValue(formatInteger(raw));
}
}
@Override
public void onDelClick() {
- if (Objects.requireNonNull(inputAmountView.getValue()).contains(".")) {
- return;
- }
- if (inputAmountView.getValue().length() == 15) {
- return;
- }
- if (TextUtils.equals(inputAmountView.getValue(), "0")) {
+
+ String current = inputAmountView.getValue();
+ if (current == null) return;
+
+ if (current.contains(".")) return;
+
+ if (TextUtils.equals(current, "0")) {
inputAmountView.setValue("0.");
} else {
-
- inputAmountView.setValue(inputAmountView.getValue() + ".");
+ inputAmountView.setValue(current + ".");
}
-
}
@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")) {
- String currentValue = inputAmountView.getValue();
- String rawNumber = currentValue.replace(",", "");
+ String current = inputAmountView.getValue();
+ if (current == null) return;
- if (rawNumber.length() > 1) {
- rawNumber = rawNumber.substring(0, rawNumber.length() - 1);
+ String raw = current.replace(",", "");
- double amt = Double.parseDouble(rawNumber);
- DecimalFormat formatter = new DecimalFormat("#,###");
- inputAmountView.setValue(formatter.format(amt));
- } else {
- inputAmountView.setValue("0");
- }
- }
+ if (raw.length() <= 1) {
+ inputAmountView.setValue("0");
+ return;
+ }
+
+ raw = raw.substring(0, raw.length() - 1);
+
+ if (raw.contains(".")) {
+ String[] parts = raw.split("\\.");
+ String formattedInt = formatInteger(parts[0]);
+ String decimal = parts.length > 1 ? parts[1] : "";
+ inputAmountView.setValue(formattedInt + "." + decimal);
+ } else {
+ inputAmountView.setValue(formatInteger(raw));
}
}
};
}
-
-
-}
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/InputRRNViewModel.java b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/InputRRNViewModel.java
index b7f918d..afa3826 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/InputRRNViewModel.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/InputRRNViewModel.java
@@ -41,6 +41,12 @@ public class InputRRNViewModel extends ViewModel {
return repository.searchPayDetail(cardNo,rrn);
}
+ public LiveData searchPayDetailPreCancel(String cardNo,String rrn) {
+ return repository.searchPayDetailPreCancel(cardNo,rrn);
+ }
+
+
+
public NumberKeyboard.KeyClickCallback onKeyClick(){
return new NumberKeyboard.KeyClickCallback() {
diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/SharedViewModel.java b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/SharedViewModel.java
index 822858e..f6b74bc 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/SharedViewModel.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/SharedViewModel.java
@@ -1,7 +1,9 @@
package com.utsmm.kbz.ui.core_viewmodel;
+import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.util.Log;
+import android.widget.ListView;
import dagger.hilt.android.lifecycle.HiltViewModel;
import androidx.lifecycle.LiveData;
@@ -73,7 +75,8 @@ public class SharedViewModel extends ViewModel {
public SingleLiveEvent transactionName = new SingleLiveEvent<>();
-
+ // In SharedViewModel
+ public MutableLiveData onSettlementResultDone = new MutableLiveData<>(false);
/*May 16 2022*/
public SingleLiveEvent isEcr = new SingleLiveEvent<>();
@@ -161,10 +164,14 @@ public class SharedViewModel extends ViewModel {
public MutableLiveData loadingView = new MutableLiveData<>(8);
public SingleLiveEvent loadingMsg = new SingleLiveEvent<>();
+ private final SingleLiveEvent toastMsg = new SingleLiveEvent<>();
private SingleLiveEvent isFallback = new SingleLiveEvent<>();
private SingleLiveEvent isSeePhone = new SingleLiveEvent<>();
+ private SingleLiveEvent isContactlessRestricted = new SingleLiveEvent<>();
+ private SingleLiveEvent isCardAppBlock = new SingleLiveEvent<>();
+
private SingleLiveEvent _isCardDataExist = new SingleLiveEvent<>();
private SingleLiveEvent _isAmountExist = new SingleLiveEvent<>();
@@ -233,10 +240,18 @@ public class SharedViewModel extends ViewModel {
public SingleLiveEvent getIsFallback() { return isFallback;}
+ public void setIsCardAppBlock(boolean status) { isCardAppBlock.setValue(status);}
+
+ public SingleLiveEvent getIsCardAppBlock() {return isCardAppBlock;}
+
public void setIsSeePhone(boolean status) { isSeePhone.setValue(status);}
public SingleLiveEvent getIsSeePhone() { return isSeePhone;}
+ public void setIsContactlessRestricted(boolean status) { isContactlessRestricted.setValue(status);}
+
+ public SingleLiveEvent getIsContactlessRestricted() {return isContactlessRestricted;}
+
public void setCardDataExist(boolean exist) { _isCardDataExist.setValue(exist);}
public SingleLiveEvent getCardDataExist() { return _isCardDataExist; }
@@ -288,6 +303,14 @@ public class SharedViewModel extends ViewModel {
loadingMsg.setValue("");
}
+ public SingleLiveEvent getToastMsg() {
+ return toastMsg;
+ }
+
+ public void postToastMsg(String msg) {
+ toastMsg.postValue(msg);
+ }
+
public Observable getParams(SiriusRequest siriusRequest) {
return repository.getParams(siriusRequest);
}
@@ -441,6 +464,14 @@ public class SharedViewModel extends ViewModel {
return repository.getReversalTransaction(voucherNo);
}
+ public LiveData getLastReversalTransaction() {
+ return repository.getLastReversalTransaction();
+ }
+
+ public LiveData> getAllReversalTransaction() {
+ return repository.getAllReversalTransactions();
+ }
+
public void updatePayDetail(PayDetail payDetail){
repository.updatePayDetail(payDetail);
}
@@ -456,13 +487,17 @@ public class SharedViewModel extends ViewModel {
}
+ @SuppressLint("CheckResult")
public void pushReceipt(Object body){
Log.d("push receipt", new Gson().toJson(body));
repository.sendReceipt(body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
- response -> Log.d("E-Receipt", "Success =>"+ response.getMessage()),
+ response -> {
+ Log.d("E-Receipt", "Success =>"+ response.getMessage());
+ postToastMsg("E-Receipt saved successfully");
+ },
error -> {
if (error instanceof HttpException) {
HttpException httpEx = (HttpException) error;
@@ -474,11 +509,14 @@ public class SharedViewModel extends ViewModel {
// Parse JSON to model
EReceiptResponse res = new Gson().fromJson(errorJson, EReceiptResponse.class);
Log.e("E-Receipt", "Parsed Error => " + res.getMessage());
+ postToastMsg("E-Receipt could not save!");
} catch (Exception e) {
e.printStackTrace();
+ postToastMsg("E-Receipt could not save!");
}
} else {
Log.e("E-Receipt", "Unexpected error => " + error.getMessage());
+ postToastMsg("E-Receipt could not save!");
}
}
);
diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/TransProcessViewModel.java b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/TransProcessViewModel.java
index 3af3b10..7e0709a 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/TransProcessViewModel.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/core_viewmodel/TransProcessViewModel.java
@@ -304,13 +304,16 @@ public class TransProcessViewModel extends ViewModel implements ProcessingTransa
}
@Override
+
public void processPreCompDb(PayDetail payResult) {
if(oldTransPayDetail.getAmount() == payResult.getAmount()) {
oldTransPayDetail.setIsCanceled(true);
+ oldTransPayDetail.setAdjust(true);
updatePayDetail(oldTransPayDetail);
} else {
oldTransPayDetail.setIsCanceled(false);
+ oldTransPayDetail.setAdjust(true);
updatePayDetail(oldTransPayDetail);
}
repository.insertPayDetail(updateCurrentDateAndTime(payResult));
diff --git a/app/src/main/java/com/utsmm/kbz/ui/dashboard/DashboardPreAuthBottomSheet.java b/app/src/main/java/com/utsmm/kbz/ui/dashboard/DashboardPreAuthBottomSheet.java
index 9141c61..558fbf4 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/dashboard/DashboardPreAuthBottomSheet.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/dashboard/DashboardPreAuthBottomSheet.java
@@ -9,12 +9,14 @@ import com.utsmm.kbz.MainViewModel;
import com.utsmm.kbz.R;
import com.utsmm.kbz.config.Constants;
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
+import com.utsmm.kbz.util.CurrencySelectionHelper;
public class DashboardPreAuthBottomSheet extends DataBindingBottomSheetFragment {
private MainViewModel mainViewModel;
private SharedViewModel sharedViewModel;
+ private CurrencySelectionHelper currencySelectionHelper;
private static final int hostId = Constants.NAV_HOST_ID;
private int routeId;
@@ -24,6 +26,7 @@ public class DashboardPreAuthBottomSheet extends DataBindingBottomSheetFragment
protected void initViewModel() {
mainViewModel = getFragmentScopeViewModel(MainViewModel.class);
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
+ currencySelectionHelper = new CurrencySelectionHelper(this, sharedViewModel);
}
@Override
@@ -52,10 +55,11 @@ public class DashboardPreAuthBottomSheet extends DataBindingBottomSheetFragment
} 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);
+ showCurrencyChooserForCardFlow(() -> {
+ sharedViewModel.transactionsType.setValue(TransactionsType.PRE_AUTH_SALE);
+ routeId = R.id.action_dashboardPreAuthBottomSheet_to_inputAmountFragment;
+ safeRouteTo(currentId, routeId, hostId);
+ });
}
}
@@ -65,10 +69,11 @@ public class DashboardPreAuthBottomSheet extends DataBindingBottomSheetFragment
} 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);
+ showCurrencyChooserForCardFlow(() -> {
+ sharedViewModel.transactionsType.setValue(TransactionsType.PRE_AUTH_COMPLETE);
+ routeId = R.id.action_dashboardPreAuthBottomSheet_to_inputPasswordFragment;
+ safeRouteTo(currentId, routeId, hostId);
+ });
}
}
@@ -86,4 +91,8 @@ public class DashboardPreAuthBottomSheet extends DataBindingBottomSheetFragment
}
}
}
+
+ private void showCurrencyChooserForCardFlow(Runnable onSelected) {
+ currencySelectionHelper.showCardCurrencyChooser(onSelected);
+ }
}
diff --git a/app/src/main/java/com/utsmm/kbz/ui/dashboard/DashboardPreAuthCancelBottomSheet.java b/app/src/main/java/com/utsmm/kbz/ui/dashboard/DashboardPreAuthCancelBottomSheet.java
index 87f0a65..bce7996 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/dashboard/DashboardPreAuthCancelBottomSheet.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/dashboard/DashboardPreAuthCancelBottomSheet.java
@@ -10,6 +10,7 @@ import com.utsmm.kbz.MainViewModel;
import com.utsmm.kbz.R;
import com.utsmm.kbz.config.Constants;
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
+import com.utsmm.kbz.util.CurrencySelectionHelper;
public class DashboardPreAuthCancelBottomSheet extends DataBindingBottomSheetFragment {
@@ -17,6 +18,7 @@ public class DashboardPreAuthCancelBottomSheet extends DataBindingBottomSheetFra
private MainViewModel mainViewModel;
private SharedViewModel sharedViewModel;
+ private CurrencySelectionHelper currencySelectionHelper;
private int currentId = R.id.dashboardPreAuthCancelBottomSheet;
private int routeId;
@@ -26,6 +28,7 @@ public class DashboardPreAuthCancelBottomSheet extends DataBindingBottomSheetFra
protected void initViewModel() {
mainViewModel = getFragmentScopeViewModel(MainViewModel.class);
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
+ currencySelectionHelper = new CurrencySelectionHelper(this, sharedViewModel);
}
@Override
@@ -61,12 +64,13 @@ public class DashboardPreAuthCancelBottomSheet extends DataBindingBottomSheetFra
} 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);
+ showCurrencyChooserForCardFlow(() -> {
+ 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);
+ });
}
}
@@ -82,14 +86,19 @@ public class DashboardPreAuthCancelBottomSheet extends DataBindingBottomSheetFra
} 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);
+ showCurrencyChooserForCardFlow(() -> {
+ 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);
+ });
}
}
}
+ private void showCurrencyChooserForCardFlow(Runnable onSelected) {
+ currencySelectionHelper.showCardCurrencyChooser(onSelected);
+ }
+
}
diff --git a/app/src/main/java/com/utsmm/kbz/ui/dashboard/DashboardTransFragment.java b/app/src/main/java/com/utsmm/kbz/ui/dashboard/DashboardTransFragment.java
index 89b1983..44e1a75 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/dashboard/DashboardTransFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/dashboard/DashboardTransFragment.java
@@ -30,6 +30,7 @@ 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.CurrencySelectionHelper;
import com.utsmm.kbz.util.tms.TMSUtil;
import java.util.ArrayList;
@@ -41,6 +42,7 @@ public class DashboardTransFragment extends DataBindingFragment {
private MainViewModel mainViewModel;
private SharedViewModel sharedViewModel;
+ private CurrencySelectionHelper currencySelectionHelper;
private ArrayList featuresList = new ArrayList<>();
@@ -76,6 +78,7 @@ public class DashboardTransFragment extends DataBindingFragment {
protected void initViewModel() {
mainViewModel = getFragmentScopeViewModel(MainViewModel.class);
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
+ currencySelectionHelper = new CurrencySelectionHelper(this, sharedViewModel);
}
@Override
@@ -175,6 +178,9 @@ public class DashboardTransFragment extends DataBindingFragment {
case CASH_ADVANCE:
new DashboardTransFragment.ClickEvent().onClickCashAdvance();
break;
+ case CLEAR_REVERSAL:
+ new DashboardTransFragment.ClickEvent().onClickClearReversal();
+ break;
case DEVICE_CONFIG:
new DashboardTransFragment.ClickEvent().onClickDeviceConfig();
break;
@@ -227,9 +233,11 @@ public class DashboardTransFragment extends DataBindingFragment {
}
public void onClickRefund() {
- sharedViewModel.setTransactionsType(TransactionsType.REFUND);
- routeId = R.id.action_dashboardTransFragment_to_inputPasswordFragment;
- safeRouteTo(currentId,routeId,hostId);
+ showCurrencyChooserForCardFlow(() -> {
+ sharedViewModel.setTransactionsType(TransactionsType.REFUND);
+ routeId = R.id.action_dashboardTransFragment_to_inputPasswordFragment;
+ safeRouteTo(currentId, routeId, hostId);
+ });
}
public void onClickPreAuth () {
@@ -248,19 +256,23 @@ public class DashboardTransFragment extends DataBindingFragment {
}
public void onClickPreAuthCancel () {
- sharedViewModel.setTransactionsType(TransactionsType.PRE_AUTH_VOID);
- sharedViewModel.setTransMenu(TransMenu.PRE_AUTH_FULL_VOID);
- sharedViewModel.amount.postValue("0"); // null to 0
-// sharedViewModel.amount.postValue(null);
- routeId = R.id.action_dashboardTransFragment_to_inputPasswordFragment;
- safeRouteTo(currentId,routeId,hostId);
+ showCurrencyChooserForCardFlow(() -> {
+ sharedViewModel.setTransactionsType(TransactionsType.PRE_AUTH_VOID);
+ sharedViewModel.setTransMenu(TransMenu.PRE_AUTH_FULL_VOID);
+ sharedViewModel.amount.postValue("0"); // null to 0
+// 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);
+ showCurrencyChooserForCardFlow(() -> {
+ sharedViewModel.setTransactionsType(TransactionsType.PRE_AUTH_COMPLETE);
+ routeId = R.id.action_dashboardTransFragment_to_inputPasswordFragment;
+ safeRouteTo(currentId, routeId, hostId);
+ });
}
@@ -281,6 +293,14 @@ public class DashboardTransFragment extends DataBindingFragment {
});
}
+
+ public void onClickClearReversal() {
+ sharedViewModel.transactionsType.postValue(TransactionsType.CLEAR_REVERSAL);
+ sharedViewModel.setTransMenu(TransMenu.CLEAR_REVERSAL);
+ routeId = R.id.action_dashboardTransFragment_to_inputPasswordFragment;
+ safeRouteTo(currentId, routeId, hostId);
+ }
+
public void onClickDeviceConfig(){
routeId = R.id.action_dashboardTransFragment_to_deviceConfig;
safeRouteTo(currentId, routeId, hostId);
@@ -471,6 +491,7 @@ public class DashboardTransFragment extends DataBindingFragment {
private interface CurrencySelectCallback {
void onSelected(String currency);
+// currencySelectionHelper.showCardCurrencyChooser(onSelected);
}
}
diff --git a/app/src/main/java/com/utsmm/kbz/ui/disabled/DisabledTerminalFragment.java b/app/src/main/java/com/utsmm/kbz/ui/disabled/DisabledTerminalFragment.java
index f7d00fb..5eb56e2 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/disabled/DisabledTerminalFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/disabled/DisabledTerminalFragment.java
@@ -4,6 +4,7 @@ import androidx.databinding.library.baseAdapters.BR;
import androidx.lifecycle.Observer;
import com.google.gson.stream.MalformedJsonException;
+import com.utsmm.kbz.MainActivity;
import com.utsmyanmar.baselib.emv.EmvParamOperation;
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
import com.utsmyanmar.baselib.network.model.sirius.SiriusRequest;
@@ -104,6 +105,7 @@ public class DisabledTerminalFragment extends DataBindingFragment {
private void downloadParams(String lastTransName,String lastTransTime) {
showLoadingDialog("Downloading...");
+ ((MainActivity) requireActivity()).getLocation();
SiriusRequest siriusReq = TMSUtil.getInstance().generateRequestParams(getContext(),lastTransName,lastTransTime);
mainViewModel.getParams(siriusReq).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
diff --git a/app/src/main/java/com/utsmm/kbz/ui/management/ManagementFunctionFragment.java b/app/src/main/java/com/utsmm/kbz/ui/management/ManagementFunctionFragment.java
index d6e4eaf..f9c91e6 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/management/ManagementFunctionFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/management/ManagementFunctionFragment.java
@@ -53,6 +53,7 @@ public class ManagementFunctionFragment extends DataBindingFragment {
public void onResume() {
super.onResume();
+ sharedViewModel.printerDisabled.setValue(!SystemParamsOperation.getInstance().getPrinterEnabled());
setToolBarTitleWithBackIcon(getString(R.string.title_select_function));
}
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 dd073b8..e52a9b7 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
@@ -145,6 +145,18 @@ public class ReprintAnyTransactionFragment extends DataBindingFragment {
cardViewAdapter.updateList(searchedLists);
}
+ private void searchByTraceAndRRN(String input) {
+ for (PayDetail s : lists) {
+ boolean matchTrace = s.getVoucherNo() != null && s.getVoucherNo().contains(input);
+ boolean matchRRN = s.getReferNo() != null && s.getReferNo().contains(input);
+
+ if (matchTrace || matchRRN) {
+ searchedLists.add(s);
+ }
+ }
+ cardViewAdapter.updateList(searchedLists);
+ }
+
public class ClickEvent {
public void onClickSearch() {
@@ -152,7 +164,7 @@ public class ReprintAnyTransactionFragment extends DataBindingFragment {
String input = managementViewModel.txtRRNTrace.getValue();
if(input != null && !input.isEmpty()) {
- searchByTrace(input);
+ searchByTraceAndRRN(input);
} else {
searchedLists.addAll(lists);
}
diff --git a/app/src/main/java/com/utsmm/kbz/ui/management/SelectHostFragment.java b/app/src/main/java/com/utsmm/kbz/ui/management/SelectHostFragment.java
index 668d63d..66deee9 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/management/SelectHostFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/management/SelectHostFragment.java
@@ -210,21 +210,43 @@ public class SelectHostFragment extends DataBindingFragment implements DataBindi
private void clearReversal() {
checkPointReversal = false;
- sharedViewModel.getReversalTransaction(SystemParamsOperation.getInstance().getCurrentSerialNum()).observe(getViewLifecycleOwner(), payDetail -> {
- if (payDetail != null) {
- if (!checkPointReversal) {
- payDetail.setIsNeedReversal(false);
- sharedViewModel.updatePayDetail(payDetail);
- checkPointReversal = true;
+// sharedViewModel.getReversalTransaction(SystemParamsOperation.getInstance().getCurrentSerialNum()).observe(getViewLifecycleOwner(), payDetail -> {
+// if (payDetail != null) {
+// if (!checkPointReversal) {
+// payDetail.setIsNeedReversal(false);
+// sharedViewModel.updatePayDetail(payDetail);
+// checkPointReversal = true;
+//
+// showSuccessDialog("Clear reversal success!");
+// }
+// } else {
+// if (!checkPointReversal) {
+// showInfoDialog("Clear reversal", "No reversal found!");
+// checkPointReversal = true;
+// }
+//
+// }
+// });
- showSuccessDialog("Clear reversal success!");
- }
- } else {
- if (!checkPointReversal) {
- showInfoDialog("Clear reversal", "No reversal found!");
- checkPointReversal = true;
- }
+ sharedViewModel.getAllReversalTransaction().observe(getViewLifecycleOwner(), new Observer>() {
+ @Override
+ public void onChanged(List payDetails) {
+ if(payDetails != null && !payDetails.isEmpty()) {
+ if(!checkPointReversal) {
+ for (PayDetail payDetail : payDetails) {
+ payDetail.setIsNeedReversal(false);
+ sharedViewModel.updatePayDetail(payDetail);
+ }
+ checkPointReversal = true;
+ showSuccessDialog("Clear reversal success!");
+ }
+ } else {
+ if (!checkPointReversal) {
+ showInfoDialog("Clear reversal", "No reversal found!");
+ checkPointReversal = true;
+ }
+ }
}
});
}
diff --git a/app/src/main/java/com/utsmm/kbz/ui/management/TransactionSummaryFragment.java b/app/src/main/java/com/utsmm/kbz/ui/management/TransactionSummaryFragment.java
index 9b618f6..3fc4a4e 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/management/TransactionSummaryFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/management/TransactionSummaryFragment.java
@@ -51,6 +51,8 @@ public class TransactionSummaryFragment extends DataBindingFragment {
final Calendar myCalendar = Calendar.getInstance();
final Calendar myCalendar2 = Calendar.getInstance();
+ ArrayList filteredLists = new ArrayList<>();
+
@Override
protected void initViewModel() {
managementViewModel = getFragmentScopeViewModel(ManagementViewModel.class);
@@ -224,10 +226,15 @@ public class TransactionSummaryFragment extends DataBindingFragment {
}
}
- private SettleData processTransactionData(List payDetailList, SimpleDateFormat formatter,
- Date yesterday, Date start, Date end) {
+ private SettleData processTransactionData(List payDetailList,
+ SimpleDateFormat formatter,
+ Date yesterday,
+ Date start,
+ Date end) {
try {
- // Create a local helper class for readable mutability
+ // ✅ IMPORTANT: clear old data
+ filteredLists.clear();
+
class Counter {
int count = 0;
long amount = 0L;
@@ -250,38 +257,32 @@ public class TransactionSummaryFragment extends DataBindingFragment {
Counter preAuthCompVoid = new Counter();
Counter refund = new Counter();
+ // ✅ Use ONE consistent format
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yy HH:mm", Locale.getDefault());
- ArrayList filteredLists = new ArrayList<>();
- // Filter transactions by date
for (PayDetail pay : payDetailList) {
try {
- Date transDate = formatter.parse(pay.getTransDate());
- if (yesterday.compareTo(transDate) <= 0) {
- filteredLists.add(pay);
- }
- } catch (ParseException e) {
- LogUtil.e(TAG, "Error parsing transaction date: " + e.getMessage());
- }
- }
-
- LogUtil.d(TAG, "Filtered transactions count: " + filteredLists.size());
-
- // Process filtered transactions
- for (PayDetail pay : filteredLists) {
- try {
+ // ✅ Combine date + time correctly
Date currentDate = sdf.parse(pay.transDate + " " + pay.transTime);
- if ((currentDate.after(start) || currentDate.equals(start)) &&
- (currentDate.before(end) || currentDate.equals(end))) {
+ if (currentDate == null) continue;
+
+ // ✅ Correct inclusive range check
+ if (!currentDate.before(start) && !currentDate.after(end)) {
+
+ // ✅ Keep filtered list for printing
+ filteredLists.add(pay);
if (sharedViewModel.hostType.getValue() == HostType.QR) {
+
if (pay.getTransactionType() == TransactionsType.MMQR.value && pay.getQrTransStatus() == 1) {
wave.inc(pay.amount);
} else if (pay.getTransactionType() == TransactionsType.MMQR_REFUND.value && pay.getQrTransStatus() == 1) {
waveRefund.inc(pay.amount);
}
+
} else if (sharedViewModel.hostType.getValue() == HostType.MPU) {
+
if (pay.getTransactionType() == TransactionsType.VOID.value) {
voidTran.inc(pay.amount);
} else if (pay.getTransactionType() == TransactionsType.SALE.value) {
@@ -301,11 +302,14 @@ public class TransactionSummaryFragment extends DataBindingFragment {
}
}
}
+
} catch (ParseException e) {
LogUtil.e(TAG, "Error parsing transaction datetime: " + e.getMessage());
}
}
+ LogUtil.d(TAG, "Filtered transactions count: " + filteredLists.size());
+
return new SettleData(
sale.count, sale.amount,
wave.count, wave.amount,
@@ -318,6 +322,7 @@ public class TransactionSummaryFragment extends DataBindingFragment {
refund.count, refund.amount,
waveRefund.count, waveRefund.amount
);
+
} catch (Exception e) {
LogUtil.e(TAG, "Error processing transaction data: " + e.getMessage());
return null;
@@ -366,7 +371,7 @@ public class TransactionSummaryFragment extends DataBindingFragment {
private void printReceipt(PayDetail payDetail) {
try {
LogUtil.d(TAG, "Starting receipt print");
- PrintXReceipt.getInstance().printSmileSummaryReport(payDetail, sharedViewModel.hostType.getValue(), new PrintXStatus() {
+ PrintXReceipt.getInstance().printSmileSummaryReport(payDetail, filteredLists, sharedViewModel.hostType.getValue(), new PrintXStatus() {
@Override
public void onSuccess() {
LogUtil.d(TAG, "Receipt printed successfully");
diff --git a/app/src/main/java/com/utsmm/kbz/ui/manual_entry/ManualEntryFragment.java b/app/src/main/java/com/utsmm/kbz/ui/manual_entry/ManualEntryFragment.java
index b18eab2..eddcbd2 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/manual_entry/ManualEntryFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/manual_entry/ManualEntryFragment.java
@@ -77,7 +77,7 @@ public class ManualEntryFragment extends DataBindingFragment {
}
private void processEmvCard() {
- if(sharedViewModel.transactionsType.getValue() == TransactionsType.REFUND || sharedViewModel.transactionsType.getValue() == TransactionsType.PRE_AUTH_VOID) {
+ if(sharedViewModel.transactionsType.getValue() == TransactionsType.REFUND || sharedViewModel.transactionsType.getValue() == TransactionsType.PRE_AUTH_VOID || sharedViewModel.transactionsType.getValue() == TransactionsType.PRE_AUTH_COMPLETE) {
routeId = R.id.action_manualEntryFragment_to_inputRRNFragment;
} else {
routeId = R.id.action_manualEntryFragment_to_emvTransactionFragment;
@@ -106,7 +106,7 @@ public class ManualEntryFragment extends DataBindingFragment {
payDetail.setICC55("");
// payDetail.setAuthNo(manualEntryViewModel.cvv.getValue());
-
+ emvTransactionProcessViewModel.cardNum.setValue(cardNo);
emvTransactionProcessViewModel.setTradeData(tradeData);
safeNavigateToRouteId();
diff --git a/app/src/main/java/com/utsmm/kbz/ui/navigation/NaviMainFragment.java b/app/src/main/java/com/utsmm/kbz/ui/navigation/NaviMainFragment.java
index 07d9709..6ffd8df 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/navigation/NaviMainFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/navigation/NaviMainFragment.java
@@ -4,6 +4,8 @@ import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
+import androidx.databinding.ObservableBoolean;
+
import com.nexgo.oaf.apiv3.APIProxy;
import com.nexgo.oaf.apiv3.DeviceEngine;
import com.nexgo.oaf.apiv3.DeviceInfo;
@@ -12,6 +14,7 @@ import com.nexgo.oaf.apiv3.device.printer.AlignEnum;
import com.nexgo.oaf.apiv3.device.printer.GrayLevelEnum;
import com.nexgo.oaf.apiv3.device.printer.LineOptionEntity;
import com.nexgo.oaf.apiv3.device.printer.Printer;
+import com.utsmyanmar.baselib.BaseApplication;
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
import com.utsmyanmar.baselib.network.model.sirius.SiriusHost;
import com.utsmyanmar.baselib.network.model.sirius.SiriusMerchant;
@@ -20,12 +23,14 @@ import com.utsmyanmar.baselib.util.DataBindingConfig;
import com.utsmyanmar.paylibs.Constant;
import com.utsmyanmar.paylibs.sign_on.EchoTestProcess;
import com.utsmyanmar.paylibs.sign_on.SignOnListener;
+import com.utsmyanmar.paylibs.utils.LogUtil;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmm.kbz.BR;
import com.utsmm.kbz.R;
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
import java.util.List;
+import java.util.Observable;
public class NaviMainFragment extends DataBindingFragment {
@@ -114,6 +119,36 @@ public class NaviMainFragment extends DataBindingFragment {
}
public class ClickEvent {
+
+ private static final String PREF_NAME = "pinpad_prefs";
+ private static final String KEY_PINPAD_SOUND = "pinpad_sound_enabled";
+
+ public final ObservableBoolean pinpadSoundEnabled;
+
+ public ClickEvent() {
+ boolean savedValue = loadPinpadSoundState();
+ this.pinpadSoundEnabled = new ObservableBoolean(savedValue);
+
+ BaseApplication.getInstance().deviceEngine.getPlatform().enablePinpadBeep(savedValue);
+ }
+
+ public boolean loadPinpadSoundState(){
+ return BaseApplication.getInstance().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).getBoolean(KEY_PINPAD_SOUND, true);
+ }
+
+ public void savePinpadSoundState(boolean enabled){
+ BaseApplication.getInstance().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE).edit().putBoolean(KEY_PINPAD_SOUND, enabled).apply();
+ }
+
+ public void onClickPinpadSound(){
+ boolean newState = !pinpadSoundEnabled.get();
+ int result = BaseApplication.getInstance().deviceEngine.getPlatform().enablePinpadBeep(newState);
+ if(result == SdkResult.Success){
+ pinpadSoundEnabled.set(newState);
+ savePinpadSoundState(newState);
+// LogUtil.d("NaviMainFragment", "pinpad enabled");
+ }
+ }
public void onClickEcho() {
showLoadingDialog("Sending Echo!");
diff --git a/app/src/main/java/com/utsmm/kbz/ui/pinpad/PinPadViewModel.java b/app/src/main/java/com/utsmm/kbz/ui/pinpad/PinPadViewModel.java
index f475406..923d05d 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/pinpad/PinPadViewModel.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/pinpad/PinPadViewModel.java
@@ -359,7 +359,10 @@ public class PinPadViewModel extends ViewModel {
handler.obtainMessage(ON_ERROR_PIN_PAD,retCode).sendToTarget();
}
LogUtil.d(TAG,"RetCode:"+retCode);
- payDetail.setPINCipher(ByteUtil.bytes2HexStr(data));
+ if(retCode != SdkResult.PinPad_No_Pin_Input) {
+ payDetail.setPINCipher(ByteUtil.bytes2HexStr(data));
+ }
+
LogUtil.d(TAG,"data bytes:"+ByteUtil.bytes2HexStr(data));
}
diff --git a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRPayFragment.java b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRPayFragment.java
index 5f0f3bb..8c0fdc9 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRPayFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRPayFragment.java
@@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.fragment.NavHostFragment;
import com.utsmm.kbz.BR;
+import com.utsmm.kbz.MainActivity;
import com.utsmm.kbz.MainViewModel;
import com.utsmm.kbz.R;
import com.utsmm.kbz.config.Constants;
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 136ab3f..009c5ea 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
@@ -42,8 +42,7 @@ public class RefundCertificateManager {
return;
};
-// String downloadBase = tmsAddress.trim() + "/api/v1/file/download?filePath="; //local
- String downloadBase = tmsAddress.trim() + "/file/download?filePath="; // uat and prod
+ String downloadBase = tmsAddress.trim() + "/file/download?filePath=";
String certUrl = SystemParamsOperation.getInstance().getCertificateUrl();
String clientCertUrl = SystemParamsOperation.getInstance().getCertificateClientUrl();
diff --git a/app/src/main/java/com/utsmm/kbz/ui/settings/HostConfigViewModel.java b/app/src/main/java/com/utsmm/kbz/ui/settings/HostConfigViewModel.java
index d690c53..37009f8 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/settings/HostConfigViewModel.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/settings/HostConfigViewModel.java
@@ -44,6 +44,8 @@ public class HostConfigViewModel extends ViewModel {
// Third Host
public MutableLiveData thirdHostName = new MutableLiveData<>();
+ public MutableLiveData thirdHostTid = new MutableLiveData<>();
+ public MutableLiveData thirdHostMid = new MutableLiveData<>();
public MutableLiveData thirdHostShortCode = new MutableLiveData<>();
public MutableLiveData thirdHostPrimaryIp = new MutableLiveData<>();
public MutableLiveData thirdHostPrimaryPort = new MutableLiveData<>();
@@ -96,6 +98,8 @@ public class HostConfigViewModel extends ViewModel {
if (sp.getThirdHostName() != null && !sp.getThirdHostName().isEmpty()) {
thirdHostName.setValue(sp.getThirdHostName());
+ thirdHostTid.setValue(sp.getThirdHostTerminalId());
+ thirdHostMid.setValue(sp.getThirdHostMerchantId());
thirdHostShortCode.setValue(sp.getThirdHostShortCode());
String[] thp = split(sp.getThirdHostIpAddress());
diff --git a/app/src/main/java/com/utsmm/kbz/ui/settings/InjectKeyFragment.java b/app/src/main/java/com/utsmm/kbz/ui/settings/InjectKeyFragment.java
index 59f1227..3d42d79 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/settings/InjectKeyFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/settings/InjectKeyFragment.java
@@ -15,7 +15,6 @@ import com.nexgo.downloadkey.downloadflow.DownloadFlowResultEntity;
import com.nexgo.downloadkey.downloadflow.DownloadResult;
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.databinding.FragmentInjectKeyBinding;
@@ -84,22 +83,11 @@ public class InjectKeyFragment extends DataBindingFragment {
}
private void updateConfigurationInfo() {
+ binding.serialNumberValue.setText(getDisplayValue(TMSUtil.getInstance().getSerialNumber()));
+ }
- String terminalId = SystemParamsOperation.getInstance().getTerminalId();
- binding.terminalIdValue.setText(terminalId != null && !terminalId.isEmpty() ?
- terminalId : "Not configured");
-
- // Update Merchant ID
- String merchantId = SystemParamsOperation.getInstance().getMerchantId();
- binding.merchantIdValue.setText(merchantId != null && !merchantId.isEmpty() ?
- merchantId : "Not configured");
-
- // Update Serial Number
- String serialNo = TMSUtil.getInstance().getSerialNumber();
- binding.serialNumberValue.setText(serialNo != null && !serialNo.isEmpty() ?
- serialNo : "Not configured");
-
-
+ private String getDisplayValue(String value) {
+ return !TextUtils.isEmpty(value) ? value : "Not configured";
}
private void loadKeyFromKeyPOS() {
@@ -122,21 +110,18 @@ public class InjectKeyFragment extends DataBindingFragment {
mDownloadFlow = DownloadFlow.getInstance();
- String terminalId = SystemParamsOperation.getInstance().getTerminalId();
- String merchantId = SystemParamsOperation.getInstance().getMerchantId();
String serialNo = TMSUtil.getInstance().getSerialNumber();
- // Validate configuration
- if (TextUtils.isEmpty(terminalId) || TextUtils.isEmpty(merchantId) || TextUtils.isEmpty(serialNo)) {
+ if (TextUtils.isEmpty(serialNo)) {
dismissLoadingDialog();
- showDeclineDialog("Please configure Terminal ID, Merchant ID first in TMS Configuration");
+ showDeclineDialog("Serial number is not configured");
return;
}
final DownloadFEntity downloadFEntity = new DownloadFEntity();
downloadFEntity.setSn(serialNo.getBytes());
- downloadFEntity.setMid(merchantId.getBytes());
- downloadFEntity.setTid(terminalId.getBytes());
+ downloadFEntity.setMid(null);
+ downloadFEntity.setTid(null);
downloadFEntity.setTmkIndex(keyIndexTmp);
downloadFEntity.setPort(0);
downloadFEntity.setTimeOut(10);
@@ -190,4 +175,4 @@ public class InjectKeyFragment extends DataBindingFragment {
}
}
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/com/utsmm/kbz/ui/settlement/QRSettlementTransactionFragment.java b/app/src/main/java/com/utsmm/kbz/ui/settlement/QRSettlementTransactionFragment.java
index a54223d..55593b8 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/settlement/QRSettlementTransactionFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/settlement/QRSettlementTransactionFragment.java
@@ -86,6 +86,7 @@ public class QRSettlementTransactionFragment extends DataBindingFragment impleme
@Override
public void onResume() {
super.onResume();
+ sharedViewModel.printerDisabled.setValue(!SystemParamsOperation.getInstance().getPrinterEnabled());
setToolBarTitleWithBackIcon(getString(R.string.title_qr_settlement));
String merchantName = SystemParamsOperation.getInstance().getMerchantName();
@@ -134,7 +135,7 @@ public class QRSettlementTransactionFragment extends DataBindingFragment impleme
managementViewModel.detailReportLayoutLoadingVisibility.setValue(8);
managementViewModel.detailReportLayoutVisibility.setValue(8);
managementViewModel.detailReportLayoutViewVisibility.setValue(0);
- managementViewModel.detailReportBottomLayoutVisibility.setValue(0);
+ managementViewModel.detailReportBottomLayoutVisibility.setValue(isLastSettlementPrinterDisabled() ? 8 : 0);
}
private void showEmptyDataView() {
@@ -149,6 +150,13 @@ public class QRSettlementTransactionFragment extends DataBindingFragment impleme
managementViewModel.cardTypeDR.setValue("QR PAY");
}
+ private boolean isLastSettlementPrinterDisabled() {
+ Boolean printerDisabled = sharedViewModel.printerDisabled.getValue();
+ return sharedViewModel.getTransMenu().getValue() == TransMenu.LAST_SETTLEMENT
+ && printerDisabled != null
+ && printerDisabled;
+ }
+
private void observeQRTransactions() {
managementViewModel.getTransactionHistory().observe(getViewLifecycleOwner(), payDetailList -> {
if (payDetailList != null) {
@@ -385,4 +393,4 @@ public class QRSettlementTransactionFragment extends DataBindingFragment impleme
}
}
-}
\ No newline at end of file
+}
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 902694c..fae2aac 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
@@ -9,10 +9,14 @@ import androidx.annotation.Nullable;
import androidx.lifecycle.Observer;
import com.utsmm.kbz.ui.management.ManagementViewModel;
+import com.utsmm.kbz.ui.settlement.model.CurrencyBucket;
+import com.utsmm.kbz.util.CurrencySelectionHelper;
import com.utsmm.kbz.util.EReceiptUtil;
+import com.utsmm.kbz.util.enums.TransactionStatus;
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
import com.utsmyanmar.baselib.network.model.e_receipt.EReceiptRequest;
import com.utsmyanmar.baselib.util.DataBindingConfig;
+import com.utsmyanmar.paylibs.model.CardSettleData;
import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.model.TradeData;
import com.utsmyanmar.paylibs.print.printx.PrintXStatus;
@@ -32,6 +36,7 @@ import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
import com.utsmm.kbz.util.ecr.CoreUtils;
import java.util.List;
+import java.util.Locale;
public class SettlementTransactionFragment extends DataBindingFragment implements DataBindingFragment.BackPressCallback{
@@ -42,7 +47,7 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
private SharedViewModel sharedViewModel;
private ManagementViewModel managementViewModel;
-
+ private CurrencySelectionHelper currencySelectionHelper;
private int routeId;
int saleCount = 0;
@@ -54,11 +59,16 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
long refundAmount = 0;
long caAmount = 0;
+ private final CurrencyBucket mmkBucket = new CurrencyBucket();
+ private final CurrencyBucket usdBucket = new CurrencyBucket();
+
@Override
protected void initViewModel() {
settlementViewModel = getFragmentScopeViewModel(SettlementViewModel.class);
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
managementViewModel = getFragmentScopeViewModel(ManagementViewModel.class);
+
+ currencySelectionHelper = new CurrencySelectionHelper(this, sharedViewModel);
}
@Override
@@ -88,6 +98,8 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
public void onResume() {
super.onResume();
+ boolean printerDisabled = !SystemParamsOperation.getInstance().getPrinterEnabled();
+ sharedViewModel.printerDisabled.setValue(printerDisabled);
if(sharedViewModel.getTransMenu().getValue() == TransMenu.LAST_SETTLEMENT) {
setToolBarTitleWithBackIcon(getString(R.string.txt_subtitle_reprint_last_settle_report));
@@ -103,6 +115,8 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
if(sharedViewModel.getTransMenu().getValue() == TransMenu.REVIEW_BATCH){
settlementViewModel.btmLayout.setValue(8);
+ } else if(sharedViewModel.getTransMenu().getValue() == TransMenu.LAST_SETTLEMENT && printerDisabled) {
+ settlementViewModel.btmLayout.setValue(8);
} else {
settlementViewModel.btmLayout.setValue(0);
}
@@ -170,6 +184,7 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
caCount = payDetail.getSettleDataObj().getCashAdvanceCount();
caAmount = payDetail.getSettleDataObj().getCashAdvanceAmount();
+ applyStoredCurrencyBreakdown(payDetail);
settlementViewModel.isNoData.setValue(false);
@@ -222,20 +237,24 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
if((transType == TransactionType.SALE || "SALE".equalsIgnoreCase(transName)) && !payDetail.isCanceled){
saleCount ++;
saleAmount += payDetail.getAmount();
+ addToCurrencyBucket(payDetail, BucketType.SALE);
} else if((transType == TransactionType.PRE_SALE_COMPLETE
|| "PREAUTH COMPLETION".equalsIgnoreCase(transName)
|| "PRE_AUTH_COMPLETE".equalsIgnoreCase(transName)) && !payDetail.isCanceled){
preCount ++;
preAmount += payDetail.getAmount();
+ addToCurrencyBucket(payDetail, BucketType.PRE_AUTH_COMPLETE);
}
else if(transType == TransactionType.REFUND || "REFUND".equalsIgnoreCase(transName)){
refundCount ++;
refundAmount += payDetail.getAmount();
+ addToCurrencyBucket(payDetail, BucketType.REFUND);
}else if(transType == TransactionType.CASH_ADVANCE
|| "CASH_OUT".equalsIgnoreCase(transName)
|| "CASH_ADVANCE".equalsIgnoreCase(transName)){
caCount ++;
caAmount += payDetail.getAmount();
+ addToCurrencyBucket(payDetail, BucketType.CASH_ADVANCE);
}
}
long totalAmount = saleAmount + preAmount + caAmount;
@@ -276,6 +295,8 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
preAmount = 0L;
refundAmount = 0L;
caAmount = 0L;
+ resetCurrencyBucket(mmkBucket);
+ resetCurrencyBucket(usdBucket);
}
private void setSettlementViewModelData(int saleCount,long saleAmount,int preCount,long preAmount,int refundCount,long refundAmount,int caCount,long caAmount) {
@@ -287,6 +308,10 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
settlementViewModel.refund_amount.setValue(refundAmount);
settlementViewModel.ca_count.setValue(caCount);
settlementViewModel.ca_amount.setValue(caAmount);
+ settlementViewModel.sale_breakdown.setValue(buildBreakdownText(mmkBucket.saleCount, mmkBucket.saleAmount, usdBucket.saleCount, usdBucket.saleAmount));
+ settlementViewModel.pre_breakdown.setValue(buildBreakdownText(mmkBucket.preCount, mmkBucket.preAmount, usdBucket.preCount, usdBucket.preAmount));
+ settlementViewModel.refund_breakdown.setValue(buildBreakdownText(mmkBucket.refundCount, mmkBucket.refundAmount, usdBucket.refundCount, usdBucket.refundAmount));
+ settlementViewModel.ca_breakdown.setValue(buildBreakdownText(mmkBucket.caCount, mmkBucket.caAmount, usdBucket.caCount, usdBucket.caAmount));
if(sharedViewModel.getTransMenu().getValue() == TransMenu.REVIEW_BATCH) {
SettleData settleData = new SettleData(saleCount,saleAmount,preCount,preAmount,refundCount,refundAmount,caCount,caAmount);
@@ -300,6 +325,118 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
}
+ private enum BucketType {
+ SALE,
+ PRE_AUTH_COMPLETE,
+ REFUND,
+ CASH_ADVANCE
+ }
+
+
+
+ private void resetCurrencyBucket(CurrencyBucket bucket) {
+ bucket.saleCount = 0;
+ bucket.saleAmount = 0L;
+ bucket.preCount = 0;
+ bucket.preAmount = 0L;
+ bucket.refundCount = 0;
+ bucket.refundAmount = 0L;
+ bucket.caCount = 0;
+ bucket.caAmount = 0L;
+ }
+
+ private void addToCurrencyBucket(PayDetail payDetail, BucketType bucketType) {
+ CurrencyBucket bucket = getCurrencyBucket(payDetail.getCurrencyCode());
+ long amount = payDetail.getAmount();
+ switch (bucketType) {
+ case SALE:
+ bucket.saleCount++;
+ bucket.saleAmount += amount;
+ break;
+ case PRE_AUTH_COMPLETE:
+ bucket.preCount++;
+ bucket.preAmount += amount;
+ break;
+ case REFUND:
+ bucket.refundCount++;
+ bucket.refundAmount += amount;
+ break;
+ case CASH_ADVANCE:
+ bucket.caCount++;
+ bucket.caAmount += amount;
+ break;
+ }
+ }
+
+ private CurrencyBucket getCurrencyBucket(String currencyCode) {
+ return "USD".equals(normalizeCurrency(currencyCode)) ? usdBucket : mmkBucket;
+ }
+
+ private void applyStoredCurrencyBreakdown(PayDetail payDetail) {
+ resetCurrencyBucket(mmkBucket);
+ resetCurrencyBucket(usdBucket);
+
+ List cardSettleDataList = payDetail.getCardSettleData();
+ if (cardSettleDataList != null && !cardSettleDataList.isEmpty()) {
+ for (CardSettleData item : cardSettleDataList) {
+ applyStoredCardSettle(item);
+ }
+ return;
+ }
+
+ String normalizedCurrency = normalizeCurrency(payDetail.getCurrencyCode());
+ CurrencyBucket bucket = "USD".equals(normalizedCurrency) ? usdBucket : mmkBucket;
+ bucket.saleCount = saleCount;
+ bucket.saleAmount = saleAmount;
+ bucket.preCount = preCount;
+ bucket.preAmount = preAmount;
+ bucket.refundCount = refundCount;
+ bucket.refundAmount = refundAmount;
+ bucket.caCount = caCount;
+ bucket.caAmount = caAmount;
+ }
+
+ private void applyStoredCardSettle(CardSettleData item) {
+ CurrencyBucket bucket = getCurrencyBucket(item.getCurrencyCode());
+ String transType = item.getTransType() == null ? "" : item.getTransType().trim().toUpperCase(Locale.getDefault());
+
+ if ("SALE".equals(transType)) {
+ bucket.saleCount++;
+ bucket.saleAmount += item.getAmount();
+ } else if ("PREAUTH COMPLETION".equals(transType) || "PRE_AUTH_COMPLETE".equals(transType)) {
+ bucket.preCount++;
+ bucket.preAmount += item.getAmount();
+ } else if ("REFUND".equals(transType)) {
+ bucket.refundCount++;
+ bucket.refundAmount += item.getAmount();
+ } else if ("CASH_OUT".equals(transType) || "CASH_ADVANCE".equals(transType)) {
+ bucket.caCount++;
+ bucket.caAmount += item.getAmount();
+ }
+ }
+
+ private String buildBreakdownText(int mmkCount, long mmkAmount, int usdCount, long usdAmount) {
+ return "MMK " + mmkCount + " / " + POSUtil.getInstance().getDecimalAmountSeparatorFormat(mmkAmount)
+ + " USD " + usdCount + " / " + POSUtil.getInstance().getDecimalAmountSeparatorFormat(usdAmount);
+ }
+
+ private String normalizeCurrency(String currencyCode) {
+ if (currencyCode == null) {
+ return "MMK";
+ }
+
+ String value = currencyCode.trim().toUpperCase(Locale.getDefault());
+ switch (value) {
+ case "840":
+ case "USD":
+ return "USD";
+ case "104":
+ case "MMK":
+ default:
+ return "MMK";
+ }
+ }
+
private void navigateMainScreen(){
routeId = R.id.action_settlementTransactionFragment_to_nav_main;
@@ -311,13 +448,22 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
safeNavigateToRouteId();
}
+ private boolean isUSDSettleNeeded() {
+ return (usdBucket.saleCount != 0 || usdBucket.preCount != 0 || usdBucket.refundCount != 0 || usdBucket.caCount != 0);
+ }
private void networkCutOver() {
EchoTestProcess.getInstance().enqueueCutOver().startSignOn(new SignOnListener() {
@Override
public void onSuccessSignOn() {
-// showSuccessDialog("Approved!");
- navigateToNext();
+ if(settlementViewModel.resultString.getValue() != TransactionStatus.ON_FINAL_SUCCESS) {
+ currencySelectionHelper.applyCardCurrencyAndHost("MMK");
+ settlementViewModel.startSettlementProcess(mmkBucket,true);
+ } else {
+ navigateToNext();
+ }
+
+
}
@Override
@@ -345,12 +491,15 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
showLoadingDialog("Sending Batch Upload...");
break;
case ON_SUCCESS:
+ updateData();
+ dismissLoadingDialog();
+ networkCutOver();
+ break;
+ case ON_FINAL_SUCCESS:
dismissLoadingDialog();
updateData();
if (!SystemParamsOperation.getInstance().getDemoStatus()) {
-
networkCutOver(); // bpc
- navigateToNext();
} else {
navigateToNext();
}
@@ -415,11 +564,22 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
}
+
+
public void onConfirm(){
if(sharedViewModel.getTransMenu().getValue() == TransMenu.SETTLEMENT) {
/* April 10 , 2024 Smile requested not to send to host even settlement button was clicked */
- settlementViewModel.startSettlementProcess();
+
+ if(isUSDSettleNeeded()) {
+ currencySelectionHelper.applyCardCurrencyAndHost("USD");
+ settlementViewModel.startSettlementProcess(usdBucket,false);
+ } else {
+ currencySelectionHelper.applyCardCurrencyAndHost("MMK");
+ settlementViewModel.startSettlementProcess(mmkBucket,true);
+ }
+
+
showLoadingDialog("Sending ...");
} else if(sharedViewModel.getTransMenu().getValue() == TransMenu.REVIEW_BATCH) {
sharedViewModel.startPrintSettlement(new PrintXStatus() {
diff --git a/app/src/main/java/com/utsmm/kbz/ui/settlement/SettlementViewModel.java b/app/src/main/java/com/utsmm/kbz/ui/settlement/SettlementViewModel.java
index 7094ec3..951443f 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/settlement/SettlementViewModel.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/settlement/SettlementViewModel.java
@@ -7,6 +7,7 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
+import com.utsmm.kbz.ui.settlement.model.CurrencyBucket;
import com.utsmm.kbz.util.EReceiptUtil;
import com.utsmyanmar.baselib.network.model.e_receipt.EReceiptRequest;
import com.utsmyanmar.baselib.repo.Repository;
@@ -75,15 +76,19 @@ public class SettlementViewModel extends ViewModel {
public SingleLiveEvent sale_count = new SingleLiveEvent<>();
public SingleLiveEvent sale_amount = new SingleLiveEvent<>();
+ public SingleLiveEvent sale_breakdown = new SingleLiveEvent<>();
public SingleLiveEvent pre_count = new SingleLiveEvent<>();
public SingleLiveEvent pre_amount = new SingleLiveEvent<>();
+ public SingleLiveEvent pre_breakdown = new SingleLiveEvent<>();
public SingleLiveEvent refund_count = new SingleLiveEvent<>();
public SingleLiveEvent refund_amount = new SingleLiveEvent<>();
+ public SingleLiveEvent refund_breakdown = new SingleLiveEvent<>();
public SingleLiveEvent ca_count = new SingleLiveEvent<>();
public SingleLiveEvent ca_amount = new SingleLiveEvent<>();
+ public SingleLiveEvent ca_breakdown = new SingleLiveEvent<>();
public SingleLiveEvent settlementType = new SingleLiveEvent<>();
@@ -111,18 +116,26 @@ public class SettlementViewModel extends ViewModel {
private ISOMsgX isoMsgX;
+ public CurrencyBucket currentBucket= new CurrencyBucket();
+
+ private boolean isLast = true;
+
@Inject
public SettlementViewModel(Repository repository) {
this.repository = repository;
sale_count.setValue(0);
sale_amount.setValue(0L);
+ sale_breakdown.setValue("");
pre_count.setValue(0);
pre_amount.setValue(0L);
+ pre_breakdown.setValue("");
refund_count.setValue(0);
refund_amount.setValue(0L);
+ refund_breakdown.setValue("");
ca_count.setValue(0);
ca_amount.setValue(0L);
+ ca_breakdown.setValue("");
isoMsgX = new ISOMsgX.ISOMsgXBuilder(ISOVersion.VERSION_1993, ISOMode.BOTH_HEADER_TPDU,HostName.BPC)
.build();
@@ -221,14 +234,7 @@ public class SettlementViewModel extends ViewModel {
if(payDetails != null && payDetails.size() > 0) {
for (PayDetail pay:payDetails) {
-// if(paydetail.getTransactionType() == TransactionsType.SALE.value) {
-// paydetail.setIsSettle(true);
-// updatePayDetail(paydetail);
-// } else {
deletePayDetail(pay);
-// repository.deletePayDetail(paydetail);
-// }
-
}
}
@@ -257,22 +263,14 @@ public class SettlementViewModel extends ViewModel {
@SuppressWarnings("ConstantConditions")
- public void startSettlementProcess() {
- saleCount = sale_count.getValue();
- saleAmount = sale_amount.getValue();
- preAuthCount = pre_count.getValue();
- preAuthAmount = pre_amount.getValue();
- refundCount = refund_count.getValue();
- refundAmount = refund_amount.getValue();
- caCount = ca_count.getValue();
- caAmount = ca_amount.getValue();
-
+ public void startSettlementProcess(CurrencyBucket currencyBucket,boolean isLast) {
+ this.isLast = isLast;
SystemParamsOperation.getInstance().getIncrementBatchNo();
if(SystemParamsOperation.getInstance().getDemoStatus()) {
- requestDemoProcessSettlement();
+ requestDemoProcessSettlement(currencyBucket);
} else {
- requestOnlineProcessSettlement();
+ requestOnlineProcessSettlement(currencyBucket);
}
}
@@ -291,7 +289,7 @@ public class SettlementViewModel extends ViewModel {
- private void requestDemoProcessSettlement() {
+ private void requestDemoProcessSettlement(CurrencyBucket currencyBucket) {
TradeData tradeData = Params.newTrade(true);
@@ -313,18 +311,18 @@ public class SettlementViewModel extends ViewModel {
payDetail.setBatchNo(SystemParamsOperation.getInstance().getCurrentBatchNum()); //for print receipt
/*POS*/
- payDetail.setSettleList(sale_count.getValue() + ":" + sale_amount.getValue() + "-" + ca_count.getValue() + ":" + ca_amount.getValue() + "-" + refund_count.getValue() + ":" + refund_amount.getValue() + "-" + pre_count.getValue() + ":" + pre_amount.getValue()); // for print receipt
+ payDetail.setSettleList(currencyBucket.saleCount+ ":" + currencyBucket.saleAmount + "-" + currencyBucket.caCount + ":" + currencyBucket.caAmount + "-" + currencyBucket.refundCount + ":" + currencyBucket.refundAmount + "-" + currencyBucket.preCount + ":" + currencyBucket.preAmount); // for print receipt
/*POS*/
- SettleData settleData = new SettleData(saleCount,saleAmount,preAuthCount,preAuthAmount,refundCount,refundAmount,caCount,caAmount);
+ SettleData settleData = new SettleData(currencyBucket.saleCount, currencyBucket.saleAmount, currencyBucket.preCount, currencyBucket.preAmount, currencyBucket.refundCount, currencyBucket.refundAmount, currencyBucket.caCount, currencyBucket.caAmount);
payDetail.setSettleDataObj(settleData);
- long totalAmount = saleAmount + preAuthAmount + refundAmount + caAmount;
+ long totalAmount = currencyBucket.saleAmount + currencyBucket.preAmount + currencyBucket.refundAmount + currencyBucket.caAmount;
String settlementData = "";
- if(refundAmount != 0L) {
+ if(currencyBucket.refundAmount != 0L) {
- long creditTotal = saleAmount + preAuthAmount + caAmount;
- long subTotal = creditTotal - refundAmount;
+ long creditTotal = currencyBucket.saleAmount + currencyBucket.preAmount + currencyBucket.caAmount;
+ long subTotal = creditTotal - currencyBucket.refundAmount;
if(subTotal < 0L) {
settlementData = "D"+ String.format(Locale.getDefault(), "%012d", Math.abs(subTotal));
@@ -343,27 +341,27 @@ public class SettlementViewModel extends ViewModel {
updateDB();
insertPayDetail(payDetail);
- resultString.postValue(TransactionStatus.ON_SUCCESS);
+ resultString.postValue(TransactionStatus.ON_FINAL_SUCCESS);
}
- private void requestOnlineProcessSettlement() {
-
+ private void requestOnlineProcessSettlement(CurrencyBucket currencyBucket) {
+ currentBucket = currencyBucket;
HostName hostName = HostName.BPC;
String field60 = SystemParamsOperation.getInstance().getCurrentBatchNum();
- int sale2Count = saleCount + preAuthCount;
- long sale2Amount = saleAmount + preAuthAmount;
+ int sale2Count = currencyBucket.saleCount + currencyBucket.preCount;
+ long sale2Amount = currencyBucket.saleAmount + currencyBucket.preAmount;
String totalSaleCount = String.format(Locale.getDefault(), "%03d", sale2Count);
String totalSaleAmount = String.format(Locale.getDefault(), "%010d00", sale2Amount);
- String totalRefundCount = String.format(Locale.getDefault(), "%03d", refundCount);
- String totalRefundAmount = String.format(Locale.getDefault(), "%010d00", refundAmount == 0L ? 0 : refundAmount);
- String totalDebitSaleCount = String.format(Locale.getDefault(), "%03d", caCount);
- String totalDebitSaleAmount = String.format(Locale.getDefault(), "%010d00", caAmount == 0L ? 0 : caAmount);
+ String totalRefundCount = String.format(Locale.getDefault(), "%03d", currencyBucket.refundCount);
+ String totalRefundAmount = String.format(Locale.getDefault(), "%010d00", currencyBucket.refundAmount == 0L ? 0 : currencyBucket.refundAmount);
+ String totalDebitSaleCount = String.format(Locale.getDefault(), "%03d", currencyBucket.caCount);
+ String totalDebitSaleAmount = String.format(Locale.getDefault(), "%010d00", currencyBucket.caAmount == 0L ? 0 : currencyBucket.caAmount);
String totalERefundCount = String.format(Locale.getDefault(), "%03d", 0);
String totalERefundAmount = String.format(Locale.getDefault(), "%010d00", 0);
@@ -394,26 +392,32 @@ public class SettlementViewModel extends ViewModel {
}
+ if(isLast) {
+ payDetail.setCurrencyCode("104");
+ } else {
+ payDetail.setCurrencyCode("840");
+ }
+
// CA:CA - CD - FT
payDetail.setBatchNo(SystemParamsOperation.getInstance().getCurrentBatchNum()); //for print receipt
/*POS*/
- payDetail.setSettleList(sale_count.getValue() + ":" + sale_amount.getValue() + "-" + ca_count.getValue() + ":" + ca_amount.getValue() + "-" + refund_count.getValue() + ":" + refund_amount.getValue() + "-" + pre_count.getValue() + ":" + pre_amount.getValue()); // for print receipt
+ payDetail.setSettleList(currencyBucket.saleCount+ ":" + currencyBucket.saleAmount + "-" + currencyBucket.caCount + ":" + currencyBucket.caAmount + "-" + currencyBucket.refundCount + ":" + currencyBucket.refundAmount + "-" + currencyBucket.preCount + ":" + currencyBucket.preAmount); // for print receipt
/*POS*/
- SettleData settleData = new SettleData(saleCount,saleAmount,preAuthCount,preAuthAmount,refundCount,refundAmount,caCount,caAmount);
+ SettleData settleData = new SettleData(currencyBucket.saleCount, currencyBucket.saleAmount, currencyBucket.preCount, currencyBucket.preAmount, currencyBucket.refundCount, currencyBucket.refundAmount, currencyBucket.caCount, currencyBucket.caAmount);
payDetail.setSettleDataObj(settleData);
if(payDetails != null)
payDetail.setCardSettleData(CardSettleData.convertFromPayDetail(payDetails));
if(hostName == HostName.BPC) {
- long totalAmount = saleAmount + preAuthAmount + refundAmount + caAmount;
+ long totalAmount = currencyBucket.saleAmount + currencyBucket.preAmount + currencyBucket.refundAmount + currencyBucket.caAmount;
String settlementData = "";
- if(refundAmount != 0L) {
+ if(currencyBucket.refundAmount != 0L) {
- long creditTotal = saleAmount + preAuthAmount + caAmount;
- long subTotal = creditTotal - refundAmount;
+ long creditTotal = currencyBucket.saleAmount + currencyBucket.preAmount + currencyBucket.caAmount;
+ long subTotal = creditTotal - currencyBucket.refundAmount;
if(subTotal < 0L) {
settlementData = "D"+ String.format(Locale.getDefault(), "%012d", Math.abs(subTotal));
@@ -462,11 +466,7 @@ public class SettlementViewModel extends ViewModel {
} else if (TextUtils.equals(resultStr, "95") || TextUtils.equals(resultStr, "095")) {
//reversal
// if (!flag && isNoData.getValue()) {
- if (!flag ) {
- payDetail.setIsNeedReversal(true);
- } else {
- payDetail.setIsNeedReversal(false);
- }
+ payDetail.setIsNeedReversal(!flag);
}
} else {
@@ -480,7 +480,7 @@ public class SettlementViewModel extends ViewModel {
if (!isSecondCall) {
ISOSocket.getInstance().switchIp();
resultString.postValue(TransactionStatus.ON_SECONDARY);
- requestOnlineProcessSettlement();
+ requestOnlineProcessSettlement(currencyBucket);
isSecondCall = true;
} else {
resultString.postValue(TransactionStatus.ON_ERROR);
@@ -501,7 +501,7 @@ public class SettlementViewModel extends ViewModel {
/* Batch Upload Start Here*/
flag = true;
- batchUploadProcess();
+ batchUploadProcess(isLast);
} else {
/* this flag is to send batch upload again when host response 95 next time */
@@ -512,19 +512,21 @@ public class SettlementViewModel extends ViewModel {
// to leave data for testing
// if (settlementType.getValue() == SettlementType.NORMAL) {
- updateDB();
-
-
-// }
-
-
+ if(isLast) {
+ updateDB();
+ }
insertPayDetail(payDetail);
if (errorFlag) {
resultString.postValue(TransactionStatus.ON_ERROR);
} else {
- resultString.postValue(TransactionStatus.ON_SUCCESS);
+ if(isLast) {
+ resultString.postValue(TransactionStatus.ON_FINAL_SUCCESS);
+ } else {
+ resultString.postValue(TransactionStatus.ON_SUCCESS);
+ }
+
}
@@ -533,31 +535,56 @@ public class SettlementViewModel extends ViewModel {
});
}
- private void batchUploadProcess() {
+ private void batchUploadProcess(boolean isLast) {
resultString.postValue(TransactionStatus.ON_BATCH_UPLOAD);
- if(payDetails == null || payDetails.size() == 0){
- requestOnlineProcessSettlement();
+ if (payDetails == null || payDetails.isEmpty()) {
+ requestOnlineProcessSettlement(currentBucket);
+ return;
+ }
+
+ // Advance index, skipping entries that don't belong to this pass
+ while (i < payDetails.size()) {
+ PayDetail payDetail = payDetails.get(i);
+ boolean isMMK = payDetail.getCurrencyCode().equals("104");
+
+ if (isLast && !isMMK) {
+ // isLast = true → MMK pass, skip USD
+ LogUtil.d(TAG, "Skipping USD transaction at index: " + i);
+ i++;
+ continue;
+ } else if (!isLast && isMMK) {
+ // isLast = false → USD pass, skip MMK
+ LogUtil.d(TAG, "Skipping MMK transaction at index: " + i);
+ i++;
+ continue;
+ }
+
+ break;
+ }
+
+ if (i >= payDetails.size()) {
+ requestOnlineProcessSettlement(currentBucket);
return;
}
PayDetail payDetail = payDetails.get(i);
+
TradeData tradeData = new TradeData();
tradeData.setPayDetail(payDetail);
BatchUploadProcess.getInstance().enqueue(tradeData).startBatchUpload(new BatchListener() {
@Override
public void onSuccessBatch() {
+ LogUtil.e(TAG, "Batch Upload Success");
+ LogUtil.d(TAG, "Pay detail Size: " + payDetails.size());
+ LogUtil.d(TAG, "Count value: " + i);
if (i < payDetails.size() - 1) {
- LogUtil.d(TAG, "Pay detail Size:" + payDetails.size());
- LogUtil.d(TAG, "Count value:" + i);
i++;
- batchUploadProcess();
+ batchUploadProcess(isLast);
} else {
- requestOnlineProcessSettlement();
+ requestOnlineProcessSettlement(currentBucket);
}
-
- LogUtil.e(TAG, "Batch Upload Success");
}
@Override
diff --git a/app/src/main/java/com/utsmm/kbz/ui/settlement/model/CurrencyBucket.java b/app/src/main/java/com/utsmm/kbz/ui/settlement/model/CurrencyBucket.java
new file mode 100644
index 0000000..1baee36
--- /dev/null
+++ b/app/src/main/java/com/utsmm/kbz/ui/settlement/model/CurrencyBucket.java
@@ -0,0 +1,89 @@
+package com.utsmm.kbz.ui.settlement.model;
+
+public class CurrencyBucket {
+ public int saleCount;
+ public long saleAmount;
+ public int preCount;
+ public long preAmount;
+ public int refundCount;
+ public long refundAmount;
+ public int caCount;
+ public long caAmount;
+
+ public CurrencyBucket(){}
+
+ public CurrencyBucket(int saleCount, long saleAmount, int preCount, long preAmount, int refundCount, long refundAmount, int caCount, long caAmount) {
+ this.saleCount = saleCount;
+ this.saleAmount = saleAmount;
+ this.preCount = preCount;
+ this.preAmount = preAmount;
+ this.refundCount = refundCount;
+ this.refundAmount = refundAmount;
+ this.caCount = caCount;
+ this.caAmount = caAmount;
+ }
+
+ public void setSaleCount(int saleCount) {
+ this.saleCount = saleCount;
+ }
+
+ public void setSaleAmount(long saleAmount) {
+ this.saleAmount = saleAmount;
+ }
+
+ public void setPreCount(int preCount) {
+ this.preCount = preCount;
+ }
+
+ public void setPreAmount(long preAmount) {
+ this.preAmount = preAmount;
+ }
+
+ public void setRefundCount(int refundCount) {
+ this.refundCount = refundCount;
+ }
+
+ public void setRefundAmount(long refundAmount) {
+ this.refundAmount = refundAmount;
+ }
+
+ public void setCaCount(int caCount) {
+ this.caCount = caCount;
+ }
+
+ public void setCaAmount(long caAmount) {
+ this.caAmount = caAmount;
+ }
+
+ public int getSaleCount() {
+ return saleCount;
+ }
+
+ public long getSaleAmount() {
+ return saleAmount;
+ }
+
+ public int getPreCount() {
+ return preCount;
+ }
+
+ public long getPreAmount() {
+ return preAmount;
+ }
+
+ public int getRefundCount() {
+ return refundCount;
+ }
+
+ public long getRefundAmount() {
+ return refundAmount;
+ }
+
+ public int getCaCount() {
+ return caCount;
+ }
+
+ public long getCaAmount() {
+ return caAmount;
+ }
+}
diff --git a/app/src/main/java/com/utsmm/kbz/ui/sign_on/SignOnFragment.java b/app/src/main/java/com/utsmm/kbz/ui/sign_on/SignOnFragment.java
index 74ab960..bdc7795 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/sign_on/SignOnFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/sign_on/SignOnFragment.java
@@ -13,7 +13,6 @@ import com.utsmm.kbz.BR;
import com.utsmm.kbz.R;
import com.utsmm.kbz.config.Constants;
import com.utsmm.kbz.util.enums.ResponseStatus;
-import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
/*
* This file is not using in this project cuz IPEK is used instead of TMK.
@@ -56,7 +55,6 @@ public class SignOnFragment extends DataBindingFragment {
super.onViewCreated(view, savedInstanceState);
signOnViewModel.startSignOnProcess();
-
observeData();
}
diff --git a/app/src/main/java/com/utsmm/kbz/ui/tms/TMSProcessFragment.java b/app/src/main/java/com/utsmm/kbz/ui/tms/TMSProcessFragment.java
index 2652321..f5ef81c 100644
--- a/app/src/main/java/com/utsmm/kbz/ui/tms/TMSProcessFragment.java
+++ b/app/src/main/java/com/utsmm/kbz/ui/tms/TMSProcessFragment.java
@@ -15,6 +15,7 @@ import androidx.annotation.Nullable;
import com.google.gson.Gson;
import com.google.gson.stream.MalformedJsonException;
+import com.utsmm.kbz.MainActivity;
import com.utsmm.kbz.service.AutoAlarmReceiver;
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
import com.utsmyanmar.baselib.network.model.sirius.SiriusError;
@@ -139,6 +140,8 @@ public class TMSProcessFragment extends DataBindingFragment {
private void downloadParams(String lastTransName,String lastTransTime,TMSUpdate tmsUpdate) {
+ ((MainActivity) requireActivity()).getLocation();
+
tmsProcessViewModel.setTmsDownloadStatus(TMSDownloadStatus.DOWNLOADING);
tmsProcessViewModel.setTmsDownloadMsg("Downloading...");
diff --git a/app/src/main/java/com/utsmm/kbz/util/CurrencySelectionHelper.java b/app/src/main/java/com/utsmm/kbz/util/CurrencySelectionHelper.java
new file mode 100644
index 0000000..8b82825
--- /dev/null
+++ b/app/src/main/java/com/utsmm/kbz/util/CurrencySelectionHelper.java
@@ -0,0 +1,269 @@
+package com.utsmm.kbz.util;
+
+import android.text.TextUtils;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.widget.AppCompatButton;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.Fragment;
+
+import com.utsmm.kbz.R;
+import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
+import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
+import com.utsmyanmar.paylibs.utils.enums.CurrencyType;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+public class CurrencySelectionHelper {
+
+ private static boolean globalPrimaryHostCached = false;
+ private static String globalPrimaryHostName = "";
+ private static String globalPrimaryTid = "";
+ private static String globalPrimaryMid = "";
+ private static String globalPrimaryIp = "";
+ private static String globalPrimarySecIp = "";
+ private static CurrencyType globalPrimaryCurrency = CurrencyType.MMK;
+
+ private final Fragment fragment;
+ private final SharedViewModel sharedViewModel;
+ private String primaryHostName = "";
+ private String primaryTid = "";
+ private String primaryMid = "";
+ private String primaryIp = "";
+ private String primarySecIp = "";
+ private CurrencyType primaryCurrency = CurrencyType.MMK;
+
+ public CurrencySelectionHelper(Fragment fragment, SharedViewModel sharedViewModel) {
+ this.fragment = fragment;
+ this.sharedViewModel = sharedViewModel;
+ }
+
+ public void showCardCurrencyChooser(Runnable onSelected) {
+ showCardCurrencyChooser(onSelected, null);
+ }
+
+ public void showCardCurrencyChooser(Runnable onSelected, Runnable onCancelled) {
+ List currencies = getAvailableCardCurrencies();
+ if (currencies.isEmpty()) {
+ applyCardCurrencyAndHost("MMK");
+ onSelected.run();
+ return;
+ }
+
+ if (currencies.size() == 1) {
+ applyCardCurrencyAndHost(currencies.get(0));
+ onSelected.run();
+ return;
+ }
+
+ showCurrencyPickerDialog("Choose Currency", currencies, currency -> {
+ applyCardCurrencyAndHost(currency);
+ onSelected.run();
+ }, onCancelled);
+ }
+
+ private List getAvailableCardCurrencies() {
+ cachePrimaryCardHostIfNeeded();
+ LinkedHashSet values = new LinkedHashSet<>();
+
+ if (primaryCurrency != null && !TextUtils.isEmpty(primaryCurrency.name)) {
+ values.add(normalizeCurrency(primaryCurrency.name));
+ }
+
+ if (!SystemParamsOperation.getInstance().getDuelCurrencyStatus()) {
+ return new ArrayList<>(values);
+ }
+
+ String secondaryCurrency = normalizeCurrency(SystemParamsOperation.getInstance().getThirdHostCurrency());
+ if (!TextUtils.isEmpty(SystemParamsOperation.getInstance().getThirdHostName()) && !TextUtils.isEmpty(secondaryCurrency)) {
+ values.add(secondaryCurrency);
+ }
+
+ return new ArrayList<>(values);
+ }
+
+ public void applyCardCurrencyAndHost(String selectedCurrency) {
+ cachePrimaryCardHostIfNeeded();
+
+ String selected = normalizeCurrency(selectedCurrency);
+ String secondaryCurrency = normalizeCurrency(SystemParamsOperation.getInstance().getThirdHostCurrency());
+ boolean dualCurrencyEnabled = SystemParamsOperation.getInstance().getDuelCurrencyStatus();
+
+ boolean useSecondaryCardHost = dualCurrencyEnabled
+ && !TextUtils.isEmpty(SystemParamsOperation.getInstance().getThirdHostName())
+ && !TextUtils.isEmpty(secondaryCurrency)
+ && secondaryCurrency.equals(selected);
+
+ if (useSecondaryCardHost) {
+ SystemParamsOperation.getInstance().setHostName(SystemParamsOperation.getInstance().getThirdHostName());
+ SystemParamsOperation.getInstance().setTerminalId(SystemParamsOperation.getInstance().getThirdHostTerminalId());
+ SystemParamsOperation.getInstance().setMerchantId(SystemParamsOperation.getInstance().getThirdHostMerchantId());
+ SystemParamsOperation.getInstance().setIpAddress(SystemParamsOperation.getInstance().getThirdHostIpAddress());
+ SystemParamsOperation.getInstance().setSecIpAddress(SystemParamsOperation.getInstance().getThirdHostSecIpAddress());
+ } else {
+ SystemParamsOperation.getInstance().setHostName(primaryHostName);
+ SystemParamsOperation.getInstance().setTerminalId(primaryTid);
+ SystemParamsOperation.getInstance().setMerchantId(primaryMid);
+ SystemParamsOperation.getInstance().setIpAddress(primaryIp);
+ SystemParamsOperation.getInstance().setSecIpAddress(primarySecIp);
+ }
+
+ CurrencyType currencyType = useSecondaryCardHost ? toCurrencyType(selected) : primaryCurrency;
+ SystemParamsOperation.getInstance().setCurrencyType(currencyType);
+ if (sharedViewModel != null) {
+ sharedViewModel.set_currencyText(currencyType.name);
+ }
+ }
+
+ private void cachePrimaryCardHostIfNeeded() {
+ SystemParamsOperation sp = SystemParamsOperation.getInstance();
+ String currentHostName = sp.getHostName();
+ String secondaryHostName = sp.getThirdHostName();
+ boolean currentIsSecondary = !TextUtils.isEmpty(secondaryHostName)
+ && secondaryHostName.equals(currentHostName);
+
+ if (!currentIsSecondary) {
+ globalPrimaryHostName = currentHostName;
+ globalPrimaryTid = sp.getTerminalId();
+ globalPrimaryMid = sp.getMerchantId();
+ globalPrimaryIp = sp.getIpAddress();
+ globalPrimarySecIp = sp.getSecIpAddress();
+ CurrencyType activeCurrency = sp.getCurrencyType();
+ globalPrimaryCurrency = activeCurrency == null ? CurrencyType.MMK : activeCurrency;
+ globalPrimaryHostCached = true;
+ }
+
+ if (!globalPrimaryHostCached) {
+ CurrencyType activeCurrency = sp.getCurrencyType();
+ globalPrimaryCurrency = activeCurrency == null ? CurrencyType.MMK : activeCurrency;
+ globalPrimaryHostCached = true;
+ }
+
+ primaryHostName = globalPrimaryHostName;
+ primaryTid = globalPrimaryTid;
+ primaryMid = globalPrimaryMid;
+ primaryIp = globalPrimaryIp;
+ primarySecIp = globalPrimarySecIp;
+ primaryCurrency = globalPrimaryCurrency;
+ }
+
+ private CurrencyType toCurrencyType(String value) {
+ String normalized = normalizeCurrency(value);
+ try {
+ return CurrencyType.valueOf(normalized);
+ } catch (Exception ignored) {
+ return CurrencyType.MMK;
+ }
+ }
+
+ private String normalizeCurrency(String raw) {
+ if (TextUtils.isEmpty(raw)) {
+ return "";
+ }
+
+ String value = raw.trim().toUpperCase();
+ switch (value) {
+ case "104":
+ case "MMK":
+ return "MMK";
+ case "840":
+ case "USD":
+ return "USD";
+ case "156":
+ case "CNY":
+ case "RMB":
+ return "CNY";
+ case "764":
+ case "THB":
+ return "THB";
+ case "643":
+ case "RUB":
+ return "RUB";
+ default:
+ return value;
+ }
+ }
+
+ private void showCurrencyPickerDialog(
+ String title,
+ List currencies,
+ CurrencySelectCallback callback,
+ Runnable onCancelled
+ ) {
+ LinearLayout root = new LinearLayout(fragment.requireContext());
+ root.setOrientation(LinearLayout.VERTICAL);
+ root.setPadding(dp(20), dp(20), dp(20), dp(12));
+
+ TextView tvTitle = new TextView(fragment.requireContext());
+ tvTitle.setText(title);
+ tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
+ tvTitle.setTextColor(ContextCompat.getColor(fragment.requireContext(), R.color.colorTextTitle));
+ tvTitle.setPadding(0, 0, 0, dp(16));
+ root.addView(tvTitle);
+
+ final AlertDialog[] dialogHolder = new AlertDialog[1];
+ for (String currency : currencies) {
+ AppCompatButton button = new AppCompatButton(fragment.requireContext());
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ dp(56)
+ );
+ lp.bottomMargin = dp(10);
+ button.setLayoutParams(lp);
+ button.setAllCaps(false);
+ button.setText(currency);
+ button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
+ button.setGravity(Gravity.CENTER);
+ button.setBackgroundResource(R.drawable.bg_rounded_btn_cv);
+ button.setTextColor(ContextCompat.getColor(fragment.requireContext(), R.color.white));
+ button.setOnClickListener(v -> {
+ if (dialogHolder[0] != null) {
+ dialogHolder[0].dismiss();
+ }
+ callback.onSelected(currency);
+ });
+ root.addView(button);
+ }
+
+ AppCompatButton cancel = new AppCompatButton(fragment.requireContext());
+ LinearLayout.LayoutParams cancelLp = new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ dp(52)
+ );
+ cancel.setLayoutParams(cancelLp);
+ cancel.setAllCaps(false);
+ cancel.setText("Cancel");
+ cancel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
+ cancel.setBackgroundResource(R.drawable.bg_rounded_btn_cancel_cv);
+ cancel.setTextColor(ContextCompat.getColor(fragment.requireContext(), R.color.colorPrimary));
+ cancel.setOnClickListener(v -> {
+ if (dialogHolder[0] != null) {
+ dialogHolder[0].dismiss();
+ }
+ if (onCancelled != null) {
+ onCancelled.run();
+ }
+ });
+ root.addView(cancel);
+
+ AlertDialog dialog = new AlertDialog.Builder(fragment.requireContext())
+ .setView(root)
+ .create();
+ dialogHolder[0] = dialog;
+ dialog.show();
+ }
+
+ private int dp(int value) {
+ return Math.round(value * fragment.requireContext().getResources().getDisplayMetrics().density);
+ }
+
+ private interface CurrencySelectCallback {
+ void onSelected(String currency);
+ }
+}
diff --git a/app/src/main/java/com/utsmm/kbz/util/EReceiptUtil.java b/app/src/main/java/com/utsmm/kbz/util/EReceiptUtil.java
index 49f329c..6c6ab26 100644
--- a/app/src/main/java/com/utsmm/kbz/util/EReceiptUtil.java
+++ b/app/src/main/java/com/utsmm/kbz/util/EReceiptUtil.java
@@ -160,11 +160,16 @@ public class EReceiptUtil {
return request;
}
+ private String getDecimalAmount(long amount) {
+ double realAmount = amount / 100.0;
+ DecimalFormat df = new DecimalFormat("0.00");
+ return df.format(realAmount);
+ }
+
public EReceiptRequest generateMPUReceipt(PayDetail payDetail) {
- double realAmount = payDetail.getAmount() / 100.0;
- DecimalFormat df = new DecimalFormat("0.00");
- String amount = df.format(realAmount);
+
+ String amount = getDecimalAmount(payDetail.getAmount());
String currentTimeStamp = new java.text.SimpleDateFormat("MMddHHmmss", java.util.Locale.getDefault())
.format(new java.util.Date());
@@ -178,26 +183,27 @@ public class EReceiptUtil {
SettleData settleData = payDetail.getSettleDataObj();
long totalAmt = settleData.getSaleAmount() + settleData.getRefundAmount() + settleData.getPreAuthCompAmount() + settleData.getCashAdvanceAmount();
- double realTotalAmount = totalAmt / 100.0;
- String totalAmount = df.format(realTotalAmount);
- request.setDE4(totalAmount);
+
+ request.setDE4(getDecimalAmount(totalAmt));
request.setDE63_01(settleData.getSaleCount() + "");
- request.setDE63_02(settleData.getSaleAmount() + "");
+ request.setDE63_02(getDecimalAmount(settleData.getSaleAmount()));
request.setDE63_03(settleData.getRefundCount() + "");
- request.setDE63_04(settleData.getRefundAmount() + "");
+ request.setDE63_04(getDecimalAmount(settleData.getRefundAmount()));
request.setDE63_05(settleData.getPreAuthCompCount() + "");
- request.setDE63_06(settleData.getPreAuthCompAmount() + "");
+ request.setDE63_06(getDecimalAmount(settleData.getPreAuthCompAmount()));
request.setDE63_07(settleData.getCashAdvanceCount() + "");
- request.setDE63_08(settleData.getCashAdvanceAmount() + "");
+ request.setDE63_08(getDecimalAmount(settleData.getCashAdvanceAmount()));
invoiceNo = SystemParamsOperation.getInstance().getIncrementInvoiceNum();
request.setBatchNumber(batchNumber);
request.setInvoiceNumber(invoiceNo);
request.setDescription("success");
request.setDE39("A");
request.setDE37("0000");
- request.setDE49("MMK");
+ request.setDE49(currencyCodeToText(payDetail.getCurrencyCode()));
+
+
} else {
request.setDE2(POSUtil.getInstance().getCardNumMasking(payDetail.getCardNo()));
@@ -207,9 +213,9 @@ public class EReceiptUtil {
request.setDE37(payDetail.getReferNo());
request.setDE38(payDetail.getApprovalCode());
// will check it later for currency code
- request.setDE49("MMK");
+ request.setDE49(currencyCodeToText(payDetail.getCurrencyCode()));
request.setInvoiceNumber(payDetail.getInvoiceNo());
- request.setCardLabel("MPU");
+ request.setCardLabel(payDetail.getAccountType());
if (payDetail.getTradeAnswerCode().equals("000") || payDetail.getTradeAnswerCode().equals("00")) {
@@ -279,6 +285,28 @@ public class EReceiptUtil {
return request;
}
+ private String currencyCodeToText(String currencyCode) {
+ String currencyText = "MMK";
+ switch (currencyCode) {
+ case "840":
+ currencyCode = "USD";
+ break;
+ case "156":
+ currencyCode = "RMB";
+ break;
+ case "764":
+ currencyCode = "THB";
+ break;
+ case "643":
+ currencyCode = "RUB";
+ break;
+ default:
+ currencyCode = "MMK";
+ break;
+ }
+ return currencyCode;
+ }
+
private static List buildTransactions(List qrSettleData) {
List list = new ArrayList<>();
diff --git a/app/src/main/java/com/utsmm/kbz/util/LocationUtil.java b/app/src/main/java/com/utsmm/kbz/util/LocationUtil.java
new file mode 100644
index 0000000..e3d1a8f
--- /dev/null
+++ b/app/src/main/java/com/utsmm/kbz/util/LocationUtil.java
@@ -0,0 +1,111 @@
+package com.utsmm.kbz.util;
+
+import android.Manifest;
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+
+import androidx.annotation.NonNull;
+import androidx.core.app.ActivityCompat;
+
+public class LocationUtil {
+ public interface LocationCallback {
+ void onSuccess(double lat, double lng);
+ void onError(String reason);
+ }
+
+ private static LocationListener listener;
+ private static double lat = 0.00;
+ private static double lng = 0.00;
+
+ public static void getCurrentLocation(
+ @NonNull Activity activity,
+ @NonNull LocationCallback callback) {
+
+ LocationManager lm =
+ (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
+
+ if (lm == null) {
+ callback.onError("LocationManager is null");
+ return;
+ }
+
+ if (ActivityCompat.checkSelfPermission(activity,
+ Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+
+ ActivityCompat.requestPermissions(
+ activity,
+ new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
+ 201
+ );
+ callback.onError("Permission not granted");
+ return;
+ }
+
+ boolean gpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
+ boolean netEnabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
+
+ if (!gpsEnabled && !netEnabled) {
+ callback.onError("No location provider enabled");
+ return;
+ }
+
+ Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
+ if (location == null) {
+ location = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
+ }
+
+ if (location != null) {
+ callback.onSuccess(location.getLatitude(), location.getLongitude());
+ return;
+ }
+
+ listener = new LocationListener() {
+ @Override
+ public void onLocationChanged(@NonNull Location location) {
+ callback.onSuccess(
+ location.getLatitude(),
+ location.getLongitude()
+ );
+ lm.removeUpdates(this); // 🔥 stop GPS
+ }
+ };
+
+ lm.requestLocationUpdates(
+ LocationManager.GPS_PROVIDER,
+ 2000,
+ 1,
+ listener
+ );
+ }
+
+ public static void stop(Context context) {
+ if (listener != null) {
+ LocationManager lm =
+ (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
+ if (lm != null) lm.removeUpdates(listener);
+ listener = null;
+ }
+ }
+
+ public static double getLat() {
+ return lat;
+ }
+
+ public static double getLng() {
+ return lng;
+ }
+
+ public static void setLat(double lat) {
+ LocationUtil.lat = lat;
+ }
+
+ public static void setLng(double lng) {
+ LocationUtil.lng = lng;
+ }
+
+}
diff --git a/app/src/main/java/com/utsmm/kbz/util/TransactionUtil.java b/app/src/main/java/com/utsmm/kbz/util/TransactionUtil.java
index 35e0a8e..f8890db 100644
--- a/app/src/main/java/com/utsmm/kbz/util/TransactionUtil.java
+++ b/app/src/main/java/com/utsmm/kbz/util/TransactionUtil.java
@@ -6,6 +6,7 @@ import com.utsmyanmar.paylibs.model.CardInfo;
import com.utsmyanmar.paylibs.model.MAGCardInfo;
import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.model.TradeData;
+import com.utsmyanmar.paylibs.model.enums.TransCVM;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
import com.utsmyanmar.paylibs.utils.params.Params;
@@ -98,7 +99,8 @@ public class TransactionUtil {
PayDetail payDetail = tradeData.getPayDetail();
payDetail.setCardNo(cardDataX.getPan());
payDetail.setEXPDate(cardDataX.getExp());
-
+ payDetail.setTransCVM(TransCVM.SIGNATURE);
+
if(cardDataX.getPan().startsWith("4")) {
payDetail.setAccountType(VISA_CARD_SCHEME);
} else if(cardDataX.getPan().startsWith("5")) {
diff --git a/app/src/main/java/com/utsmm/kbz/util/enums/FeaturesType.java b/app/src/main/java/com/utsmm/kbz/util/enums/FeaturesType.java
index 7c92e7a..e1980f2 100644
--- a/app/src/main/java/com/utsmm/kbz/util/enums/FeaturesType.java
+++ b/app/src/main/java/com/utsmm/kbz/util/enums/FeaturesType.java
@@ -22,5 +22,6 @@ public enum FeaturesType {
QR_INQUIRY,
QR_REFUND,
LOG_OUT,
- DEVICE_CONFIG
-}
\ No newline at end of file
+ DEVICE_CONFIG,
+ CLEAR_REVERSAL
+}
diff --git a/app/src/main/java/com/utsmm/kbz/util/enums/TransactionStatus.java b/app/src/main/java/com/utsmm/kbz/util/enums/TransactionStatus.java
index 43e2319..546e524 100644
--- a/app/src/main/java/com/utsmm/kbz/util/enums/TransactionStatus.java
+++ b/app/src/main/java/com/utsmm/kbz/util/enums/TransactionStatus.java
@@ -3,6 +3,8 @@ package com.utsmm.kbz.util.enums;
public enum TransactionStatus {
ON_SUCCESS,
+
+ ON_FINAL_SUCCESS,
ON_REVERSAL,
ON_BATCH_UPLOAD,
ON_FAIL,
diff --git a/app/src/main/java/com/utsmm/kbz/util/tms/TMSSetupsImpl.java b/app/src/main/java/com/utsmm/kbz/util/tms/TMSSetupsImpl.java
index d2a8606..7deeab2 100644
--- a/app/src/main/java/com/utsmm/kbz/util/tms/TMSSetupsImpl.java
+++ b/app/src/main/java/com/utsmm/kbz/util/tms/TMSSetupsImpl.java
@@ -149,6 +149,9 @@ public class TMSSetupsImpl implements TMSSetups{
List siriusHosts = siriusResponse.getHosts();
List siriusProperties = siriusResponse.getProperties();
+ boolean isDualCurrencyEnabled = isDualCurrencyEnabled(siriusProperties);
+
+ SystemParamsOperation.getInstance().setDuelCurrencyStatus(isDualCurrencyEnabled);
ArrayList imgUrls = new ArrayList<>();
@@ -579,12 +582,23 @@ public class TMSSetupsImpl implements TMSSetups{
emvParamOperation.updatePayPassCurrencyCode(data);
- } else if (TextUtils.equals(name,"terminal_capability")) {
-
- if(!data.isEmpty()) {
- SystemParamsOperation.getInstance().setTerminalCapability(data);
+ } else if (TextUtils.equals(name, "visa_terminal_capability")) {
+ if(!data.isEmpty()){
+ SystemParamsOperation.getInstance().setVisaTerminalCapability(data);
+ }
+ }else if (TextUtils.equals(name, "master_terminal_capability")) {
+ if(!data.isEmpty()){
+ SystemParamsOperation.getInstance().setMasterTerminalCapability(data);
+ }
+ }
+ else if (TextUtils.equals(name, "upi_terminal_capability")) {
+ if(!data.isEmpty()){
+ SystemParamsOperation.getInstance().setUpiTerminalCapability(data);
+ }
+ } else if (TextUtils.equals(name, "jcb_terminal_capability")) {
+ if(!data.isEmpty()){
+ SystemParamsOperation.getInstance().setJcbTerminalCapability(data);
}
-
} else if (TextUtils.equals(name,"upi_ttq")) {
emvParamOperation.updateQuickPassTTQ(data);
} else if (TextUtils.equals(name, "upi_tc_enabled")) {
@@ -631,8 +645,24 @@ public class TMSSetupsImpl implements TMSSetups{
else if(TextUtils.equals(name,"bin_list")) {
SystemParamsOperation.getInstance().setBinValue(data);
}
+ else if (TextUtils.equals(name, "restricted_bin_list")) {
+ SystemParamsOperation.getInstance().setRestrictedBinValue(data);
+ }
else if(TextUtils.equals(name, "printer_enabled")){
SystemParamsOperation.getInstance().setPrinterEnabled(parseBoolean(data));
+ }else if(TextUtils.equals(name, "is_duel_currency")){
+ SystemParamsOperation.getInstance().setDuelCurrencyStatus(parseBoolean(data));
+ }
+ else if(TextUtils.equals(name, "pre_auth_cancel_manual_enabled")) {
+ SystemParamsOperation.getInstance().setPreAuthVoidManualEnabled(parseBoolean(data));
+ }
+ else if(TextUtils.equals(name, "pre_auth_complete_manual_enabled")) {
+ SystemParamsOperation.getInstance().setPreAuthCompleteManualEnabled(parseBoolean(data));
+ }
+ else if(TextUtils.equals(name, "pre_auth_manual_enabled")) {
+ SystemParamsOperation.getInstance().setPreAuthManualEnabled(parseBoolean(data));
+ }else if(TextUtils.equals(name, "auto_reversal_enable")) {
+ SystemParamsOperation.getInstance().setAutoReversalEnable(parseBoolean(data));
}
}
@@ -645,6 +675,24 @@ public class TMSSetupsImpl implements TMSSetups{
return EReceiptHelper.sha256(dataToHash);
}
+ private boolean isDualCurrencyEnabled(List siriusProperties) {
+ if (siriusProperties == null) {
+ return false;
+ }
+
+ for (SiriusProperty siriusProperty : siriusProperties) {
+ if (siriusProperty == null) {
+ continue;
+ }
+
+ if (TextUtils.equals("is_duel_currency", siriusProperty.getName())) {
+ return parseBoolean(siriusProperty.getProperty());
+ }
+ }
+
+ return false;
+ }
+
private String convertToString(ArrayList list) {
diff --git a/app/src/main/java/com/utsmm/kbz/util/tms/TMSUtil.java b/app/src/main/java/com/utsmm/kbz/util/tms/TMSUtil.java
index a3a8b4c..bb85203 100644
--- a/app/src/main/java/com/utsmm/kbz/util/tms/TMSUtil.java
+++ b/app/src/main/java/com/utsmm/kbz/util/tms/TMSUtil.java
@@ -7,6 +7,7 @@ import android.text.TextUtils;
import android.util.Log;
import com.kizzy.xpay.XPay;
+import com.utsmm.kbz.util.LocationUtil;
import com.utsmyanmar.baselib.emv.EmvParamOperation;
import com.utsmyanmar.baselib.network.model.sirius.SiriusRequest;
import com.utsmyanmar.baselib.network.model.sirius.SiriusResponse;
@@ -139,6 +140,7 @@ public class TMSUtil {
public SiriusRequest generateRequestParams(Context context,String lastTransName,String lastTransTime) {
+
SiriusRequest siriusRequest = new SiriusRequest();
siriusRequest.setSerial(getSerialNumber());
siriusRequest.setAppPackage(BuildConfig.APPLICATION_ID);
@@ -148,6 +150,8 @@ public class TMSUtil {
siriusRequest.setCurrentNetwork(getNetworkType(context));
siriusRequest.setLastTransaction(lastTransName);
siriusRequest.setLastTranTime(Long.parseLong(lastTransTime));
+ siriusRequest.setLatitude(LocationUtil.getLat());
+ siriusRequest.setLongitude(LocationUtil.getLng());
siriusRequest.setValue("YourValueHere");
return siriusRequest;
@@ -219,6 +223,7 @@ public class TMSUtil {
// featuresList.add(new Features(5, fragmentActivity.getString(R.string.menu_wavepay_inquiry), R.drawable.ic_wave_status_dash, FeaturesType.WAVE_PAY_INQUIRY, wavePayInquiryStatus));
featuresList.add(new Features(1, fragmentActivity.getString(R.string.menu_cash_advance), R.drawable.ic_cash_advance, FeaturesType.CASH_ADVANCE, cashAdvanceStatus));
// featuresList.add(new Features(9, fragmentActivity.getString(R.string.menu_history), R.drawable.ic_history, FeaturesType.HISTORY, true));
+ featuresList.add(new Features(11, "Clear Reversal", R.drawable.ic_clear_all, FeaturesType.CLEAR_REVERSAL, true));
featuresList.add(new Features(10, "Configs", R.drawable.ic_host, FeaturesType.DEVICE_CONFIG, true));
}
diff --git a/app/src/main/res/layout/fragment_capture_card_screen.xml b/app/src/main/res/layout/fragment_capture_card_screen.xml
index a479148..3445f63 100644
--- a/app/src/main/res/layout/fragment_capture_card_screen.xml
+++ b/app/src/main/res/layout/fragment_capture_card_screen.xml
@@ -39,6 +39,7 @@
app:layout_constraintEnd_toEndOf="parent">
+
diff --git a/app/src/main/res/layout/fragment_inject_key.xml b/app/src/main/res/layout/fragment_inject_key.xml
index 4157264..9f46697 100644
--- a/app/src/main/res/layout/fragment_inject_key.xml
+++ b/app/src/main/res/layout/fragment_inject_key.xml
@@ -100,6 +100,7 @@
android:textColor="@color/colorTextContent"
android:textSize="14sp"
tools:fontFamily="sans-serif" />
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -93,6 +94,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
+ android:visibility="@{sharedViewModel.printerDisabled ? View.GONE : View.VISIBLE}"
app:cardCornerRadius="12dp"
app:cardElevation="0dp"
app:cardBackgroundColor="@color/white"
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 4123609..5246a3f 100644
--- a/app/src/main/res/layout/fragment_print_receipt_screen.xml
+++ b/app/src/main/res/layout/fragment_print_receipt_screen.xml
@@ -187,7 +187,7 @@
+ app:cardElevation="2dp"
+
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+ android:orientation="horizontal">
+
+
+
+
+
+
+
-
-
+ android:text="@{settleViewModel.sale_breakdown}"
+ android:textColor="@color/colorTextContent"
+ android:textSize="12sp"
+ tools:text="MMK 2 / 10,000.00 USD 1 / 25.00" />
@@ -122,41 +137,56 @@
android:layout_marginTop="19dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
+ android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
-
+ android:orientation="horizontal">
+
+
+
+
+
+
+
-
-
+ android:text="@{settleViewModel.pre_breakdown}"
+ android:textColor="@color/colorTextContent"
+ android:textSize="12sp"
+ tools:text="MMK 1 / 8,000.00 USD 1 / 15.00" />
@@ -170,42 +200,56 @@
android:layout_marginTop="19dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
+ android:orientation="vertical"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
-
+ android:orientation="horizontal">
+
+
+
+
+
+
+
-
-
+ android:text="@{settleViewModel.refund_breakdown}"
+ android:textColor="@color/colorTextContent"
+ android:textSize="12sp"
+ tools:text="MMK 0 / 0.00 USD 1 / 10.00" />
@@ -219,43 +263,57 @@
android:layout_marginTop="19dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="horizontal"
+ android:orientation="vertical"
android:visibility="@{settleViewModel.ca_count > 0 ? 0 : 8}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
-
+ android:orientation="horizontal">
+
+
+
+
+
+
+
-
-
+ android:text="@{settleViewModel.ca_breakdown}"
+ android:textColor="@color/colorTextContent"
+ android:textSize="12sp"
+ tools:text="MMK 1 / 5,000.00 USD 0 / 0.00" />
diff --git a/app/src/main/res/layout/item_view_detail_report.xml b/app/src/main/res/layout/item_view_detail_report.xml
index ca3e691..80a1ec1 100644
--- a/app/src/main/res/layout/item_view_detail_report.xml
+++ b/app/src/main/res/layout/item_view_detail_report.xml
@@ -77,6 +77,35 @@
tools:text="000045" />
+
+
+
+
+
+
+
+
@@ -376,6 +377,84 @@
android:textSize="16sp"
android:textStyle="bold"
tools:fontFamily="sans-serif-medium" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Total QR Transactions
No QR transactions to settle
Confirm
- Search By Trace No
+ Search By Inv No
Continue
\ No newline at end of file
diff --git a/app/src/test/java/com/utsmm/kbz/GeneralTest.java b/app/src/test/java/com/utsmm/kbz/GeneralTest.java
index 74c314a..33550d7 100644
--- a/app/src/test/java/com/utsmm/kbz/GeneralTest.java
+++ b/app/src/test/java/com/utsmm/kbz/GeneralTest.java
@@ -4,6 +4,7 @@ import com.utsmyanmar.baselib.util.EReceiptHelper;
import org.junit.Test;
+import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -21,6 +22,19 @@ public class GeneralTest {
}
+ @Test
+ public void testDecimalAmount() {
+ long amount = 0L;
+ String decimalAmount = getDecimalAmount(amount);
+ System.out.println("amount :"+decimalAmount);
+ }
+
+ private String getDecimalAmount(long amount) {
+ double realAmount = amount / 100.0;
+ DecimalFormat df = new DecimalFormat("0.00");
+ return df.format(realAmount);
+ }
+
private static String generateSignature(String timestamp) {
String secret = "y812J21lhha11OS";
String bodyString = "{}";
diff --git a/app/uat/release/baselineProfiles/0/app-uat-release.dm b/app/uat/release/baselineProfiles/0/app-uat-release.dm
index 5279a49..a76f01b 100644
Binary files a/app/uat/release/baselineProfiles/0/app-uat-release.dm and b/app/uat/release/baselineProfiles/0/app-uat-release.dm differ
diff --git a/app/uat/release/baselineProfiles/1/app-uat-release.dm b/app/uat/release/baselineProfiles/1/app-uat-release.dm
index 9f46aca..2dffc85 100644
Binary files a/app/uat/release/baselineProfiles/1/app-uat-release.dm and b/app/uat/release/baselineProfiles/1/app-uat-release.dm differ
diff --git a/app/uat/release/output-metadata.json b/app/uat/release/output-metadata.json
index 8b7cf73..b498057 100644
--- a/app/uat/release/output-metadata.json
+++ b/app/uat/release/output-metadata.json
@@ -11,8 +11,8 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
- "versionCode": 1,
- "versionName": "1.00-uat",
+ "versionCode": 33,
+ "versionName": "2.13-uat",
"outputFile": "app-uat-release.apk"
}
],
diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/TerminalKeyUtil.java b/baselib/src/main/java/com/utsmyanmar/baselib/TerminalKeyUtil.java
index f2880e8..f9feb9a 100644
--- a/baselib/src/main/java/com/utsmyanmar/baselib/TerminalKeyUtil.java
+++ b/baselib/src/main/java/com/utsmyanmar/baselib/TerminalKeyUtil.java
@@ -21,12 +21,8 @@ import com.utsmyanmar.paylibs.utils.LogUtil;
public final class TerminalKeyUtil {
public static final String TAG = TerminalKeyUtil.class.getSimpleName();
-
-// private static final byte[] main_key_data = ByteUtil.hexStr2Bytes("875f63741753d18811a3449090d1777b".toUpperCase()); // KBZ UAT
- private static final byte[] main_key_data = ByteUtil.hexStr2Bytes("e121249099a677e8b7d4f6a9d49fe8d1".toUpperCase()); // MPU
+ private static final byte[] main_key_data = ByteUtil.hexStr2Bytes("".toUpperCase()); // KBZ PROD
private static final byte[] work_key_data = new byte[16];
-
-
public static void initNexKey() {
byte[] IPEKByte = ByteUtil.hexStr2Bytes("5A4CFF6DE93F0488926166F3317EFD2F"); // IPEK
byte[] IPEKKCVByte = ByteUtil.hexStr2Bytes("1F0C18");
@@ -38,6 +34,7 @@ public final class TerminalKeyUtil {
PinPad pinPad = BaseApplication.getInstance().deviceEngine.getPinPad();
int result = pinPad.writeMKey(9, main_key_data, main_key_data.length);
+ byte[] kcv = pinPad.calcWKeyKCV(9,WorkKeyTypeEnum.ENCRYPTIONKEY);
//
// int resultPINKEY = pinPad.writeWKey(0, WorkKeyTypeEnum.PINKEY, work_key_data, work_key_data.length);
@@ -49,7 +46,8 @@ public final class TerminalKeyUtil {
// int result = pinPad.dukptKeyInject(9, DukptKeyTypeEnum.IPEK,IPEKByte,16,KSNByte);
// int result = pinPad.dukptKeyInject(9, DukptKeyTypeEnum.BDK,IPEKByte,16,ksn);
- LogUtil.d(TAG, "save tmk key result: "+result);
+// LogUtil.d(TAG, "save tmk key result: "+result);
+// LogUtil.d(TAG, "save tmk kcv: "+ByteUtil.bytes2HexStr(kcv));
// byte[] encryptedPIK = SystemParamsOperation.getInstance().getKeyPIK().get(0);
//
diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/db/dao/PayDetailDao.java b/baselib/src/main/java/com/utsmyanmar/baselib/db/dao/PayDetailDao.java
index 24da99c..fcd0116 100644
--- a/baselib/src/main/java/com/utsmyanmar/baselib/db/dao/PayDetailDao.java
+++ b/baselib/src/main/java/com/utsmyanmar/baselib/db/dao/PayDetailDao.java
@@ -97,6 +97,12 @@ public interface PayDetailDao {
@Query("SELECT * FROM paydetail WHERE transactionType = 10 AND isNeedReversal = 1 AND voucherNo IN(:voucherNo)")
LiveData getReversalTransaction(String voucherNo);
+ @Query("SELECT * FROM PayDetail WHERE isNeedReversal = 1 ORDER BY PID DESC LIMIT 1")
+ LiveData getLastReversalTransactionLive();
+
+ @Query("SELECT * FROM PayDetail WHERE isNeedReversal = 1 ORDER BY PID DESC")
+ LiveData> getAllReversalTransactionsLive();
+
// @Query("SELECT * FROM paydetail WHERE transactionType != 10 ORDER BY PID DESC")
@Query("SELECT * FROM paydetail ORDER BY PID DESC")
LiveData> getTransactionHistory();
@@ -137,6 +143,10 @@ public interface PayDetailDao {
@Query(("SELECT * FROM paydetail WHERE isCanceled = 0 AND CardNo IN(:cardNo) AND referNo IN(:referNo)"))
LiveData searchPayDetail(String cardNo,String referNo);
+ @Query(("SELECT * FROM paydetail WHERE isCanceled = 0 AND isAdjust = 0 AND CardNo IN(:cardNo) AND referNo IN(:referNo)"))
+ LiveData searchPayDetailPreCancel(String cardNo,String referNo);
+
+
@Query("SELECT * FROM paydetail WHERE isCanceled = 0 AND transactionType = 5")
LiveData> getPreAuthCompData();
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 c8732f3..426b8a0 100644
--- a/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java
+++ b/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java
@@ -254,7 +254,8 @@ public class NetworkModule {
}
if (baseUrl.isEmpty()) {
- baseUrl = "http://api-uat.kbzpay.com/payment/gateway/uat/";
+// baseUrl = "http://api-uat.kbzpay.com/payment/gateway/uat/"; //UAT
+ baseUrl = "https://api.kbzpay.com/payment/gateway/"; //Prod
}
return new Retrofit.Builder()
.baseUrl(baseUrl)
@@ -310,8 +311,8 @@ public Retrofit provideKPayRefundRetrofit(@ApplicationContext Context context) {
// char[] password = "test123".toCharArray();
-// String refundBaseUrl = "https://api.kbzpay.com:8008/payment/gateway/";
- String refundBaseUrl = "https://api-uat.kbzpay.com:18008/payment/gateway/uat/";
+ String refundBaseUrl = "https://api.kbzpay.com:8008/payment/gateway/";
+// String refundBaseUrl = "https://api-uat.kbzpay.com:18008/payment/gateway/uat/";
// String IpAddress = SystemParamsOperation.getInstance().getSecHostIpAddress();
@@ -325,7 +326,7 @@ public Retrofit provideKPayRefundRetrofit(@ApplicationContext Context context) {
String pass = SystemParamsOperation.getInstance().getCertificatePassword();
if (TextUtils.isEmpty(pass)) {
- pass = "test123";
+ pass = "";
}
char[] password = pass.toCharArray();
diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/emv/EmvParamHelper.java b/baselib/src/main/java/com/utsmyanmar/baselib/emv/EmvParamHelper.java
index 02ad555..405bd70 100644
--- a/baselib/src/main/java/com/utsmyanmar/baselib/emv/EmvParamHelper.java
+++ b/baselib/src/main/java/com/utsmyanmar/baselib/emv/EmvParamHelper.java
@@ -349,7 +349,7 @@ public class EmvParamHelper {
private AidEntity convertContactlessAIDNex(ContactlessAid contactlessAid) {
AidEntity aidV2 = new AidEntity();
- aidV2.setTransType("FF");
+ aidV2.setTransType("FF"); // FF
aidV2.setOnlinePinCap(1);
aidV2.setAsi(0);
aidV2.setThreshold(0);
@@ -412,7 +412,8 @@ public class EmvParamHelper {
aidV2.setTransType("FF");
aidV2.setOnlinePinCap(1);
- aidV2.setAsi(1);
+ aidV2.setAsi(1); //1
+// aidV2.setThreshold(99);
if (!(contactAid.getCvmLimit() < 0)) {
aidV2.setContactlessCvmLimit(contactAid.getCvmLimit());
@@ -464,12 +465,17 @@ public class EmvParamHelper {
aidV2.setAppVerNum(contactAid.getApplicationVersion());
}
+ if (contactAid.getThreshold() != null && !contactAid.getThreshold().isEmpty()) {
+ aidV2.setThreshold(Long.parseLong(contactAid.getThreshold()));
+ }
+
return aidV2;
}
private CapkEntity convertRidNex(RidEntity ridEntity) {
CapkEntity capkV2 = new CapkEntity();
+
if (ridEntity.getRid() != null && !ridEntity.getRid().isEmpty()) {
capkV2.setRid(ridEntity.getRid());
}
diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/emv/EmvParamOperation.java b/baselib/src/main/java/com/utsmyanmar/baselib/emv/EmvParamOperation.java
index 6bd8a1b..f848932 100644
--- a/baselib/src/main/java/com/utsmyanmar/baselib/emv/EmvParamOperation.java
+++ b/baselib/src/main/java/com/utsmyanmar/baselib/emv/EmvParamOperation.java
@@ -116,7 +116,7 @@ public class EmvParamOperation extends ParamOperation{
processPayWave();
processPayPass();
processQuickPass();
- processJSpeedy();
+// processJSpeedy();
processMPUCtls();
processChips();
processRids();
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 c361087..55d8cb8 100644
--- a/baselib/src/main/java/com/utsmyanmar/baselib/network/KPayApiService.java
+++ b/baselib/src/main/java/com/utsmyanmar/baselib/network/KPayApiService.java
@@ -3,15 +3,10 @@ package com.utsmyanmar.baselib.network;
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.MMQRStatusResponse;
-import com.utsmyanmar.baselib.network.model.WaveQRRequest;
-import com.utsmyanmar.baselib.network.model.WaveQRResponse;
-import com.utsmyanmar.baselib.network.model.WaveStatusRequest;
import io.reactivex.rxjava3.core.Observable;
import retrofit2.http.Body;
import retrofit2.http.POST;
-import retrofit2.http.Url;
public interface KPayApiService {
@@ -23,13 +18,13 @@ public interface KPayApiService {
Observable checkStatus(@Body KPayQRQueryRequest.QRQueryRequest waveStatusRequest);
- //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);
+ //this accepts "url" bez this api start with https and other are http in uat
+// @POST
+// Observable closeOrder(@Url String url, @Body KPayQRRequest.CloseOrderRequest closeOrderRequest);
//this 2 is for production
-// @POST("closeorder")
-// Observable closeOrder(@Body KPayQRRequest.CloseOrderRequest closeOrderRequest);
+ @POST("closeorder")
+ Observable closeOrder(@Body KPayQRRequest.CloseOrderRequest closeOrderRequest);
}
diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/network/model/e_receipt/EReceiptCardRequest.java b/baselib/src/main/java/com/utsmyanmar/baselib/network/model/e_receipt/EReceiptCardRequest.java
index 8d8fd39..be05387 100644
--- a/baselib/src/main/java/com/utsmyanmar/baselib/network/model/e_receipt/EReceiptCardRequest.java
+++ b/baselib/src/main/java/com/utsmyanmar/baselib/network/model/e_receipt/EReceiptCardRequest.java
@@ -18,10 +18,19 @@ public class EReceiptCardRequest {
private String DE11;
private String description;
private String DE38;
-
+ private String batchNumber;
+ private String DE55;
+ private String DE14;
+ private String cardLabel;
+ private String DE43;
+ private String DE48;
+
public EReceiptCardRequest() {}
// GETTERS
+ public String getDE14(){ return DE14;}
+ public String getCardLabel(){ return cardLabel;}
+ public String getDE43(){return DE43;}
public String getDE3() {
return DE3;
}
@@ -61,6 +70,8 @@ public class EReceiptCardRequest {
public String getAppId(){
return appId;
}
+
+ public String getDE55(){return DE55;}
public String getInvoiceNumber(){
return invoiceNumber;
@@ -75,6 +86,7 @@ public class EReceiptCardRequest {
public String getDE2(){ return DE2; }
public String getDE38(){ return DE38; }
public String getDE22(){ return DE22; }
+ public String getBatchNumber(){ return batchNumber; }
// SETTERS
public void setDE3(String DE3) {
this.DE3 = DE3;
@@ -132,4 +144,23 @@ public class EReceiptCardRequest {
public void setDE38(String DE38){ this.DE38 = DE38; }
public void setDE22(String DE22){ this.DE22 = DE22; }
+
+ public void setBatchNumber(String batchNumber) {
+ this.batchNumber = batchNumber;
+ }
+ public void setDE55(String DE55){
+ this.DE55 = DE55;
+ }
+ public void setDE14(String DE14){
+ this.DE14 = DE14;
+ }
+ public void setCardLabel(String cardLabel){
+ this.cardLabel = cardLabel;
+ }
+ public void setDE43(String DE43){
+ this.DE43 = DE43;
+ }
+ public void setDE48(String DE48){
+ this.DE48 = DE48;
+ }
}
diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/network/model/sirius/SiriusRequest.java b/baselib/src/main/java/com/utsmyanmar/baselib/network/model/sirius/SiriusRequest.java
index aef258e..5770f8c 100644
--- a/baselib/src/main/java/com/utsmyanmar/baselib/network/model/sirius/SiriusRequest.java
+++ b/baselib/src/main/java/com/utsmyanmar/baselib/network/model/sirius/SiriusRequest.java
@@ -18,9 +18,23 @@ public class SiriusRequest {
private Long lastTranTime;
private String value;
+ private double latitude;
+ private double longitude;
public SiriusRequest() {}
- public SiriusRequest(String serial, String appPackage, String androidVersion, String firmwareVersion, String applicationVersion, String currentNetwork, String lastTransaction, Long lastTranTime, String value) {
+ public SiriusRequest(
+ String serial,
+ String appPackage,
+ String androidVersion,
+ String firmwareVersion,
+ String applicationVersion,
+ String currentNetwork,
+ String lastTransaction,
+ Long lastTranTime,
+ double latitude,
+ double longitude,
+ String value
+ ) {
this.serial = serial;
this.appPackage = appPackage;
this.androidVersion = androidVersion;
@@ -29,6 +43,8 @@ public class SiriusRequest {
this.currentNetwork = currentNetwork;
this.lastTransaction = lastTransaction;
this.lastTranTime = lastTranTime;
+ this.latitude = latitude;
+ this.longitude = longitude;
this.value = value;
}
@@ -100,6 +116,22 @@ public class SiriusRequest {
return value;
}
+ public double getLatitude(){
+ return latitude;
+ }
+
+ public double getLongitude(){
+ return longitude;
+ }
+
+ public void setLatitude(double latitude){
+ this.latitude = latitude;
+ }
+
+ public void setLongitude(double longitude){
+ this.longitude = longitude;
+ }
+
public void setValue(String value) {
this.value = value;
}
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 7608977..011203c 100644
--- a/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java
+++ b/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java
@@ -86,9 +86,9 @@ public class Repository {
}
public Observable qrCloseOrder(KPayQRRequest.CloseOrderRequest request){
- String url = "https://api-uat.kbzpay.com/payment/gateway/uat/closeorder"; //close this in prod
- return kPayApiService.closeOrder(url, request); // this is for local
-// return kPayApiService.closeOrder(request); //this is for prod
+// String url = "https://api-uat.kbzpay.com/payment/gateway/uat/closeorder"; //close this in prod
+// return kPayApiService.closeOrder(url, request); // this is for uat
+ return kPayApiService.closeOrder(request); //this is for prod
}
public Observable qrStatusCheck(KPayQRQueryRequest.QRQueryRequest request) {
@@ -146,6 +146,8 @@ public class Repository {
public void updatePayDetail(PayDetail payDetail){payDetailDao.update(payDetail);}
public LiveData getReversalTransaction(String voucherNo) { return payDetailDao.getReversalTransaction(voucherNo);}
+ public LiveData getLastReversalTransaction() { return payDetailDao.getLastReversalTransactionLive();}
+ public LiveData> getAllReversalTransactions() { return payDetailDao.getAllReversalTransactionsLive();}
public LiveData> getTransactionHistory(){ return payDetailDao.getTransactionHistory();}
@@ -196,6 +198,10 @@ public class Repository {
return payDetailDao.searchPayDetail(cardNo,referNo);
}
+ public LiveData searchPayDetailPreCancel(String cardNo,String referNo) {
+ return payDetailDao.searchPayDetailPreCancel(cardNo,referNo);
+ }
+
public Flowable searchPayDetailByRefNum(String refNum) {
return payDetailDao.searchPayDetailByRefNum(refNum);
}
diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/util/TerminalUtil.java b/baselib/src/main/java/com/utsmyanmar/baselib/util/TerminalUtil.java
index c470290..e1b8e26 100644
--- a/baselib/src/main/java/com/utsmyanmar/baselib/util/TerminalUtil.java
+++ b/baselib/src/main/java/com/utsmyanmar/baselib/util/TerminalUtil.java
@@ -75,4 +75,13 @@ public class TerminalUtil {
else
return binParser(SystemParamsOperation.getInstance().getBinValues());
}
+
+ public List getRestrictedBinList() {
+ if (SystemParamsOperation.getInstance().getRestrictedBinValues() == null
+ || SystemParamsOperation.getInstance().getRestrictedBinValues().isEmpty()) {
+ return new ArrayList<>();
+ } else {
+ return binParser(SystemParamsOperation.getInstance().getRestrictedBinValues());
+ }
+ }
}
diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/util/enums/EmvResultStatus.java b/baselib/src/main/java/com/utsmyanmar/baselib/util/enums/EmvResultStatus.java
index beac357..f6b5fea 100644
--- a/baselib/src/main/java/com/utsmyanmar/baselib/util/enums/EmvResultStatus.java
+++ b/baselib/src/main/java/com/utsmyanmar/baselib/util/enums/EmvResultStatus.java
@@ -30,5 +30,7 @@ public enum EmvResultStatus {
CONFIRM_CODE_VERIFY,
MPU_CARD,
SEE_PHONE,
- OTHER_INTERFACE
+ OTHER_INTERFACE,
+ CARD_APP_BLOCKED,
+ INSERT_OR_MANUAL
}
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 da353a5..cc8cf7c 100644
--- a/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java
+++ b/baselib/src/main/java/com/utsmyanmar/baselib/viewModel/EmvBaseViewModel.java
@@ -1,12 +1,15 @@
package com.utsmyanmar.baselib.viewModel;
+import android.app.AlertDialog;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.util.Log;
+import android.view.View;
import android.view.ViewTreeObserver;
+import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.lifecycle.MutableLiveData;
@@ -23,6 +26,7 @@ import com.nexgo.oaf.apiv3.device.pinpad.PinPad;
import com.nexgo.oaf.apiv3.device.pinpad.PinPadKeyCode;
import com.nexgo.oaf.apiv3.device.pinpad.PinpadLayoutEntity;
import com.nexgo.oaf.apiv3.device.reader.CardInfoEntity;
+import com.nexgo.oaf.apiv3.emv.AidEntity;
import com.nexgo.oaf.apiv3.emv.CandidateAppInfoEntity;
import com.nexgo.oaf.apiv3.emv.EmvCardBrandEnum;
import com.nexgo.oaf.apiv3.emv.EmvCvmResultEnum;
@@ -74,7 +78,7 @@ import java.util.Locale;
import com.utsmyanmar.paylibs.utils.LogUtil;
-public abstract class EmvBaseViewModel extends BaseViewModel {
+public abstract class EmvBaseViewModel extends BaseViewModel {
private static final String TAG = EmvBaseViewModel.class.getSimpleName();
@@ -105,6 +109,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
public MutableLiveData pinPadVisibility = new MutableLiveData<>(8);
protected int pinEnterCount;
+ private int offlinePinIncorrectPromptCount;
public CustomPinPadKeyboard customPinPadKeyboard;
private int mWidth = 239; // Single item width of password keyboard
@@ -154,6 +159,10 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
protected static final int EMV_ERROR = 12;
protected static final int EMV_TRY_AGAIN = 13;
+ protected static final int EMV_INSERT_OR_MANUAL = 24;
+ protected static final int EMV_CARD_APP_BLOCK = 23;
+ protected static final int EMV_CTLS_TRY_AGAIN = 13;
+
protected static final int EMV_CONFIRM_CODE_VERIFY = 14;
protected static final int EMV_SUCCESS_ONLINE = 15;
protected static final int EMV_FAILURE_ONLINE = 16;
@@ -170,8 +179,21 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
protected boolean isSecondCall = false;
protected int mProcessStep;
protected int mAppSelect = 0;
-
-
+ private static final String[] RESTRICTED_BINS = {
+ "624430",
+ "624431",
+ "624445",
+ "626220",
+ "623476",
+ "629214",
+ "623466",
+ "623433",
+ "62911028",
+ "62441900",
+ "62441901"
+ };
+ private boolean isMPU_UPIContactless = false;
+ private boolean mMPUContactlessConfigured = false;
private Looper mLooper = Looper.getMainLooper();
private final Handler mHandler = new Handler(mLooper) {
@Override
@@ -205,6 +227,9 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
}
public void startProcess() {
+ isOfflinePinEntered = false;
+ mMPUContactlessConfigured = false;
+ isMPU_UPIContactless = false;
initData();
// Check if initialization was successful
@@ -242,6 +267,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
transData.setTransTime(new SimpleDateFormat("hhmmss", Locale.getDefault()).format(new Date()));
transData.setTraceNo(mPayDetail.getVoucherNo());
+
transData.setEmvProcessFlowEnum(EmvProcessFlowEnum.EMV_PROCESS_FLOW_STANDARD);
if (mPayDetail.getCardType() == CardTypeX.NFC.value) {
transData.setEmvEntryModeEnum(EmvEntryModeEnum.EMV_ENTRY_MODE_CONTACTLESS);
@@ -251,21 +277,28 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
+
//for UPI
UnionPayTransDataEntity unionPayTransDataEntity = new UnionPayTransDataEntity();
unionPayTransDataEntity.setQpbocForGlobal(true);
unionPayTransDataEntity.setSupportCDCVM(true);
//if support QPS, please enable below lines
unionPayTransDataEntity.setSupportContactlessQps(true);
- unionPayTransDataEntity.setContactlessQpsLimit("000090000000");
+ unionPayTransDataEntity.setContactlessQpsLimit("000000030000");
+
transData.setUnionPayTransDataEntity(unionPayTransDataEntity);
+ setTransactionLimitForMPUCtls(false);
-// emvHandler.contactlessConfigKernelId(EmvCardBrandEnum.EMV_CARD_BRAND_JCB,(byte) 0x01,ByteUtils.hexString2ByteArray("06"));
- emvHandler.contactlessAppendAidIntoKernel(EmvCardBrandEnum.EMV_CARD_BRAND_MASTER, (byte) 0x08, ByteUtils.hexString2ByteArray("A000000732100123"));
+
+ emvHandler.contactlessConfigKernelId(EmvCardBrandEnum.EMV_CARD_BRAND_JCB,(byte) 0x01,ByteUtils.hexString2ByteArray("06"));
+ emvHandler.contactlessAppendAidIntoKernel(EmvCardBrandEnum.EMV_CARD_BRAND_MASTER, (byte) 0x07, ByteUtils.hexString2ByteArray("A0000008890101"));
+// emvHandler.contactlessAppendAidIntoKernelFirst(true);
LogUtil.d(TAG, "TransData :" + transData.getTransAmount());
LogUtil.d(TAG, "start emv ");
+
+// emvHandler.emvDebugLog(true);
emvHandler.emvProcess(transData, emvProcessListener);
@@ -273,7 +306,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
private void initData() {
try {
- emvHandler = BaseApplication.getInstance().deviceEngine.getEmvHandler2("app2");
+ emvHandler = BaseApplication.getInstance().deviceEngine.getEmvHandler2("app2");
if (emvHandler == null) {
LogUtil.e(TAG, "Failed to initialize EMV handler - emvHandler is null");
// Post error status to inform UI
@@ -305,8 +338,8 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
return;
}
try {
- LogUtil.d(TAG, "Selected :" + position);
- emvHandler.onSetSelAppResponse(position);
+ LogUtil.d(TAG, "Selected :" + position + 1);
+ emvHandler.onSetSelAppResponse(position + 1);
} catch (Exception e) {
LogUtil.e(TAG, "Exception during app selection: " + e.getMessage());
e.printStackTrace();
@@ -315,76 +348,6 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
}
}
- private void initPayPassTlv() {
- emvParamOperation.retrievePayPassData(new ProcessSingleDataResult() {
- @Override
- public void onSuccess(PayPassEntity data) {
-
- String DF8117Value = "E0";
- String DF8118Value = "F8";
- String DF8119Value = "28";
-
- if (!data.getTerminalCapability().isEmpty()) {
- DF8117Value = data.getTerminalCapability().substring(0, 2);
- DF8118Value = data.getTerminalCapability().substring(2, 4);
- DF8119Value = data.getTerminalCapability().substring(4, 6);
- }
- String DF8123Value = data.getFloorLimit();
- String DF8124Value = data.getTransLimitCDV();
- String DF8125Value = data.getTransLimit();
- String DF8126Value = ParamHelper.getInstance().convertPaddedString(data.getCvmLimit());
- String DF8120Value = data.getTacDefault();
- String DF8121Value = data.getTacDenial();
- String DF8122Value = data.getTacOnline();
-
- String[] tagsPayPass = {"DF8117", "DF8118", "DF8119", "DF811F", "DF811E", "DF812C",
- "DF8123", "DF8124", "DF8125", "DF8126",
- "DF811B", "DF811D", "DF8120", "DF8121", "DF8122"};
-
- String[] valuesPayPass = {DF8117Value, DF8118Value, DF8119Value, "C8", "00", "00",
- DF8123Value, DF8124Value, DF8125Value, DF8126Value,
- "30", "02", DF8120Value, DF8121Value, DF8122Value};
-// try {
-// mEMVOptV2.setTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_PAYPASS, tagsPayPass, valuesPayPass);
-//
-// LogUtil.d(TAG,"<<<<< PayPass TLV data are successfully setup >>>>>");
-// } catch (RemoteException e) {
-// throw new RuntimeException(e);
-// }
- }
-
- @Override
- public void onDataNotFound() {
- LogUtil.d(TAG, "PayPass Data not found!");
- }
- });
- }
-
-
- protected void increasedKSN() {
- pinPad.dukptKsnIncrease(pinIndex); //3
-
- LogUtil.d(TAG,"DUKPT KSN Increased!");
- }
-
- private void getKSN() {
- try {
-
- byte[] result = pinPad.dukptCurrentKsn(pinIndex);
- if (result != null) {
- String ksnStr = ByteUtil.bytes2HexStr(result);
- LogUtil.d(TAG, "ksnStr: " + ksnStr);
- mPayDetail.setReference(ksnStr);
- mPayDetail.tempKSN = ksnStr;
-
- LogUtil.d(TAG, "final ksnStr: " + ksnStr);
- } else {
- LogUtil.e(TAG, "Result code for current KSN:" + result);
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
private String getTransactionType() {
String trnxType = "00";
@@ -422,219 +385,168 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
initKeyboard(isOnlinePin == 1);
}
-
-
private void initKeyboard(boolean isOnlinePin) {
-
- LogUtil.d(TAG,"init keyboard!");
+ LogUtil.d(TAG, "init keyboard!");
pinPadVisibility.setValue(0);
- LogUtil.d(TAG,"pin pad is visible now!");
- customPinPadKeyboard.getViewTreeObserver().addOnGlobalLayoutListener(
- new ViewTreeObserver.OnGlobalLayoutListener() {
- @Override
- public void onGlobalLayout() {
- customPinPadKeyboard.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ LogUtil.d(TAG, "pin pad is visible now!");
- LogUtil.d(TAG,"inside the global layout!");
- PinpadLayoutEntity pinpadLayout = new PinpadLayoutEntity();
- int[] location = new int[2];
- Rect r;
- customPinPadKeyboard.getKey_1().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_1().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_1().getHeight() + r.top;
- pinpadLayout.setKey1(r);
-
- customPinPadKeyboard.getKey_2().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_2().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_2().getHeight() + r.top;
- pinpadLayout.setKey2(r);
-
- customPinPadKeyboard.getKey_3().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_3().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_3().getHeight() + r.top;
- pinpadLayout.setKey3(r);
-
- customPinPadKeyboard.getKey_4().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_4().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_4().getHeight() + r.top;
- pinpadLayout.setKey4(r);
-
- customPinPadKeyboard.getKey_5().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_5().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_5().getHeight() + r.top;
- pinpadLayout.setKey5(r);
-
- customPinPadKeyboard.getKey_6().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_6().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_6().getHeight() + r.top;
- pinpadLayout.setKey6(r);
-
- customPinPadKeyboard.getKey_7().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_7().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_7().getHeight() + r.top;
- pinpadLayout.setKey7(r);
-
- customPinPadKeyboard.getKey_8().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_8().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_8().getHeight() + r.top;
- pinpadLayout.setKey8(r);
-
- customPinPadKeyboard.getKey_9().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_9().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_9().getHeight() + r.top;
- pinpadLayout.setKey9(r);
-
- customPinPadKeyboard.getKey_0().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_0().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_0().getHeight() + r.top;
- pinpadLayout.setKey10(r);
-
- customPinPadKeyboard.getKey_cancel().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_cancel().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_cancel().getHeight() + r.top;
- pinpadLayout.setKeyCancel(r);
-
- customPinPadKeyboard.getKey_clear().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_clear().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_clear().getHeight() + r.top;
- pinpadLayout.setKeyClear(r);
-
- customPinPadKeyboard.getKey_ok().getLocationOnScreen(location);
- r = new Rect();
- r.left = location[0];
- r.top = location[1];
- r.right = customPinPadKeyboard.getKey_ok().getWidth() + r.left;
- r.bottom = customPinPadKeyboard.getKey_ok().getHeight() + r.top;
- pinpadLayout.setKeyConfirm(r);
-
-
- byte[] number = pinPad.setPinpadLayout(pinpadLayout);
-
-
- OnPinPadInputListener pinPadInputListener = new OnPinPadInputListener() {
- @Override
- public void onInputResult(final int retCode, final byte[] data) {
- if (retCode == SdkResult.Success) {
- LogUtil.d(TAG, "Success");
- if(isOnlinePin) {
- mPayDetail.setPINCipher(ByteUtil.bytes2HexStr(data));
- }
- mHandler.obtainMessage(PIN_CLICK_CONFIRM).sendToTarget();
- } else if (retCode == SdkResult.Fail) {
- LogUtil.d(TAG, "Failure");
- } else if (retCode == SdkResult.PinPad_Input_Cancel) {
- LogUtil.d(TAG, "Cancel");
- mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
- } else if (retCode == SdkResult.PinPad_Input_Timeout) {
- mHandler.obtainMessage(PIN_TIME_OUT,-7009).sendToTarget();
- } else if (retCode == SdkResult.PinPad_No_Pin_Input) {
- mHandler.obtainMessage(PIN_CLICK_CONFIRM).sendToTarget();
- } else {
- mHandler.obtainMessage(PIN_ERROR).sendToTarget();
- }
-
- LogUtil.d(TAG, "RetCode:" + retCode);
- LogUtil.d(TAG, "data bytes:" + ByteUtil.bytes2HexStr(data));
- }
-
- @Override
- public void onSendKey(byte keyCode) {
- increaseCount();
- if (keyCode == PinPadKeyCode.KEYCODE_CLEAR) {
- LogUtil.d(TAG, "on clear");
- mHandler.obtainMessage(PIN_CLICK_CLEAR).sendToTarget();
- } else if (keyCode == PinPadKeyCode.KEYCODE_CANCEL) {
- LogUtil.d(TAG, "on click cancel");
- mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
- } else if (keyCode == PinPadKeyCode.KEYCODE_CONFIRM) {
- LogUtil.d(TAG, "on click confirm");
- mHandler.obtainMessage(PIN_CLICK_CONFIRM).sendToTarget();
- } else {
- LogUtil.d(TAG, "on click number");
- mHandler.obtainMessage(PIN_CLICK_NUMBER, pinEnterCount, 0).sendToTarget();
- }
- LogUtil.d(TAG, "SendKey: " + ByteUtil.byte2HexStr(keyCode));
- }
- };
-
- if (number != null) {
- customPinPadKeyboard.setKeyBoard(number);
-// customPinPadKeyboard.setKeyBoard(ByteUtil.bytes2HexStr(number));
-
- LogUtil.d(TAG, "PinPad: " + ByteUtil.bytes2HexStr(number));
- int[] supperLen = new int[]{0x00, 0x04, 0x06};
-
-
- pinPad.setPinKeyboardViewMode(PinKeyboardViewModeEnum.DEFAULT);
- pinPad.setPinKeyboardMode(PinKeyboardModeEnum.FIXED);
-// pinPad.setAlgorithmMode(AlgorithmModeEnum.DES);
-
-
- if(cardNo == null){
- cardNo = emvHandler.getEmvCardDataInfo().getCardNo();
- }
- int length = cardNo.length();
- byte[] panBytes = cardNo.substring( length- 13).getBytes(StandardCharsets.US_ASCII);
- LogUtil.d(TAG,"card num :"+cardNo);
- LogUtil.d(TAG,"Is Online Pin:"+isOnlinePin);
-// pinPad.inputOnlinePin(supperLen, 60, pan, 0, PinAlgorithmModeEnum.ISO9564FMT0, pinPadInputListener);
- if (isOnlinePin) {
-
- pinPad.inputOnlinePin(supperLen, 60, panBytes, pinIndex, PinAlgorithmModeEnum.ISO9564FMT0, pinPadInputListener);
-
- } else {
- mPayDetail.transCVM = TransCVM.OFFLINE_PIN;
- pinPad.inputOfflinePin(supperLen, 60, pinPadInputListener);
+ // Check if the view is already laid out
+ if (customPinPadKeyboard.getWidth() > 0 && customPinPadKeyboard.getHeight() > 0) {
+ // View already laid out — call setup directly
+ setupPinPadLayout(isOnlinePin);
+ } else {
+ // View not yet laid out — wait for layout
+ customPinPadKeyboard.getViewTreeObserver().addOnGlobalLayoutListener(
+ new ViewTreeObserver.OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ if (customPinPadKeyboard.getWidth() > 0 && customPinPadKeyboard.getHeight() > 0) {
+ customPinPadKeyboard.getViewTreeObserver().removeOnGlobalLayoutListener(this);
+ setupPinPadLayout(isOnlinePin);
}
}
}
+ );
+ }
+ }
+ private void setupPinPadLayout(boolean isOnlinePin) {
+ LogUtil.d(TAG, "inside the global layout!");
+ PinpadLayoutEntity pinpadLayout = new PinpadLayoutEntity();
+
+ // Helper to avoid repetition
+ pinpadLayout.setKey1(getRectForView(customPinPadKeyboard.getKey_1()));
+ pinpadLayout.setKey2(getRectForView(customPinPadKeyboard.getKey_2()));
+ pinpadLayout.setKey3(getRectForView(customPinPadKeyboard.getKey_3()));
+ pinpadLayout.setKey4(getRectForView(customPinPadKeyboard.getKey_4()));
+ pinpadLayout.setKey5(getRectForView(customPinPadKeyboard.getKey_5()));
+ pinpadLayout.setKey6(getRectForView(customPinPadKeyboard.getKey_6()));
+ pinpadLayout.setKey7(getRectForView(customPinPadKeyboard.getKey_7()));
+ pinpadLayout.setKey8(getRectForView(customPinPadKeyboard.getKey_8()));
+ pinpadLayout.setKey9(getRectForView(customPinPadKeyboard.getKey_9()));
+ pinpadLayout.setKey10(getRectForView(customPinPadKeyboard.getKey_0()));
+ pinpadLayout.setKeyCancel(getRectForView(customPinPadKeyboard.getKey_cancel()));
+ pinpadLayout.setKeyClear(getRectForView(customPinPadKeyboard.getKey_clear()));
+ pinpadLayout.setKeyConfirm(getRectForView(customPinPadKeyboard.getKey_ok()));
+
+
+ byte[] number = pinPad.setPinpadLayout(pinpadLayout);
+
+
+ OnPinPadInputListener pinPadInputListener = new OnPinPadInputListener() {
+ @Override
+ public void onInputResult(final int retCode, final byte[] data) {
+ if (retCode == SdkResult.Success) {
+ LogUtil.d(TAG, "Success");
+ if(isOnlinePin) {
+ if(ByteUtil.bytes2HexStr(data).equals("0000000000000000")) {
+ mPayDetail.setPINCipher("");
+ } else {
+ mPayDetail.setPINCipher(ByteUtil.bytes2HexStr(data));
+ }
+// mPayDetail.setPINCipher(ByteUtil.bytes2HexStr(data));
+ } else {
+ isOfflinePinEntered = true;
+ }
+ mHandler.obtainMessage(PIN_CLICK_CONFIRM).sendToTarget();
+ } else if (retCode == SdkResult.Fail) {
+ LogUtil.d(TAG, "Failure");
+ } else if (retCode == SdkResult.PinPad_Input_Cancel) {
+ LogUtil.d(TAG, "Cancel");
+ mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
+ } else if (retCode == SdkResult.PinPad_Input_Timeout) {
+ mHandler.obtainMessage(PIN_TIME_OUT,-7009).sendToTarget();
+ } else if (retCode == SdkResult.PinPad_No_Pin_Input) {
+ mHandler.obtainMessage(PIN_CLICK_CONFIRM).sendToTarget();
+ } else {
+ mHandler.obtainMessage(PIN_ERROR).sendToTarget();
}
- );
+
+ LogUtil.d(TAG, "RetCode:" + retCode);
+ LogUtil.d(TAG, "data bytes:" + ByteUtil.bytes2HexStr(data));
+ }
+
+ @Override
+ public void onSendKey(byte keyCode) {
+ increaseCount();
+ if (keyCode == PinPadKeyCode.KEYCODE_CLEAR) {
+ LogUtil.d(TAG, "on clear");
+ mHandler.obtainMessage(PIN_CLICK_CLEAR).sendToTarget();
+ } else if (keyCode == PinPadKeyCode.KEYCODE_CANCEL) {
+ LogUtil.d(TAG, "on click cancel");
+ mHandler.obtainMessage(PIN_CLICK_CANCEL).sendToTarget();
+ } else if (keyCode == PinPadKeyCode.KEYCODE_CONFIRM) {
+ // Wait for onInputResult() so the PIN cipher / offline PIN state is ready
+ // before EmvTransactionProcessViewModel handles PIN confirmation.
+ LogUtil.d(TAG, "on click confirm - waiting for input result");
+ } else {
+ LogUtil.d(TAG, "on click number");
+ mHandler.obtainMessage(PIN_CLICK_NUMBER, pinEnterCount, 0).sendToTarget();
+ }
+ LogUtil.d(TAG, "SendKey: " + ByteUtil.byte2HexStr(keyCode));
+ }
+ };
+
+ if (number != null) {
+ customPinPadKeyboard.setKeyBoard(number);
+// customPinPadKeyboard.setKeyBoard(ByteUtil.bytes2HexStr(number));
+
+ LogUtil.d(TAG, "PinPad: " + ByteUtil.bytes2HexStr(number));
+ int[] supperLen = new int[]{0x00, 0x04, 0x06, 0x0c};
+ pinPad.setPinKeyboardViewMode(PinKeyboardViewModeEnum.DEFAULT);
+ pinPad.setPinKeyboardMode(PinKeyboardModeEnum.FIXED);
+// pinPad.setAlgorithmMode(AlgorithmModeEnum.DES);
+
+
+ if(cardNo == null){
+ cardNo = emvHandler.getEmvCardDataInfo().getCardNo();
+ }
+ int length = cardNo.length();
+ byte[] panBytes = cardNo.substring( length- 13).getBytes(StandardCharsets.US_ASCII);
+ LogUtil.d(TAG,"card num :"+cardNo);
+ LogUtil.d(TAG,"Is Online Pin:"+isOnlinePin);
+
+// pinPad.inputOnlinePin(supperLen, 60, pan, 0, PinAlgorithmModeEnum.ISO9564FMT0, pinPadInputListener);
+ if (isOnlinePin) {
+
+ pinPad.inputOnlinePin(supperLen, 60, panBytes, pinIndex, PinAlgorithmModeEnum.ISO9564FMT0, pinPadInputListener);
+
+ } else {
+ mPayDetail.transCVM = TransCVM.OFFLINE_PIN;
+ pinPad.inputOfflinePin(supperLen, 60, pinPadInputListener);
+ }
+ }
+ }
+
+ // Reusable rect helper
+ private Rect getRectForView(View view) {
+ int[] location = new int[2];
+ view.getLocationOnScreen(location);
+ Rect r = new Rect();
+ r.left = location[0];
+ r.top = location[1];
+ r.right = view.getWidth() + r.left;
+ r.bottom = view.getHeight() + r.top;
+ return r;
}
private void increaseCount() {
++pinEnterCount;
}
+ private boolean isRestrictedBin(String cardNo) {
+ if (cardNo == null || cardNo.isEmpty()) return false;
+ List restrictedBins = TerminalUtil.getInstance().getRestrictedBinList();
+ for (String bin : restrictedBins) {
+ if (cardNo.startsWith(bin)) {
+ LogUtil.d(TAG, "isRestrictedBin: matched BIN " + bin);
+ return true;
+ }
+ }
+ return false;
+ }
private OnEmvProcessListener2 emvProcessListener = new OnEmvProcessListener2() {
@Override
@@ -648,40 +560,116 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
@Override
public void onTransInitBeforeGPO() {
+
+ if (mMPUContactlessConfigured) {
+ LogUtil.d(TAG, "onTransInitBeforeGPO: skipping — MPU contactless already configured");
+ emvHandler.onSetTransInitBeforeGPOResponse(true);
+ return;
+ }
+
byte[] aid = emvHandler.getTlv(new byte[]{0x4F}, EmvDataSourceEnum.FROM_KERNEL);
- LogUtil.d(TAG, "onTransInitBeforeGPO :");
- String terminalCapability = SystemParamsOperation.getInstance().getTerminalCapability();
-// emvHandler.setTlv(new byte[]{(byte) 0x9F, (byte) 0x33}, new byte[]{(byte) 0xE0, (byte) 0x28, (byte) 0xC8});
- emvHandler.setTlv(new byte[]{(byte) 0x9F, (byte) 0x33}, ByteUtil.hexStr2Bytes(terminalCapability));
+ LogUtil.d(TAG, "onTransInitBeforeGPO :"+ByteUtil.bytes2HexStr(aid));
+
+ String visaTerminalCapability = SystemParamsOperation.getInstance().getVisaTerminalCapability();
+ String masterTerminalCapability = SystemParamsOperation.getInstance().getMasterTerminalCapability();
+ String upiTerminalCapability = SystemParamsOperation.getInstance().getUpiTerminalCapability();
+ String jcbTerminalCapability = SystemParamsOperation.getInstance().getJcbTerminalCapability();
+
+
+ String selectedTerminalCapability = "";
+
+ if (aid != null) {
+ String aidStr = ByteUtils.byteArray2HexString(aid).toUpperCase();
+
+ if (aidStr.contains("A000000003")) {
+ // VISA
+ selectedTerminalCapability = visaTerminalCapability;
+ } else if (aidStr.contains("A000000004")) {
+ // MasterCard
+ selectedTerminalCapability = masterTerminalCapability;
+ } else if (aidStr.contains("A000000333") || aidStr.contains("A000000025")) {
+ // UPI
+ selectedTerminalCapability = upiTerminalCapability;
+ } else if (aidStr.contains("A00000006510") || aidStr.contains("A0000001570040")) {
+ // UPI (maybe JCB)
+ selectedTerminalCapability = jcbTerminalCapability;
+ } else if (aidStr.contains("A000000065")){
+ selectedTerminalCapability = jcbTerminalCapability;
+ }
+ }
+
+
+ //9F33
+ emvHandler.setTlv(
+ new byte[]{(byte) 0x9F, (byte) 0x33},
+ ByteUtil.hexStr2Bytes(selectedTerminalCapability)
+ );
+
+ // -------- Contactless --------
if (mPayDetail.getCardType() == CardTypeX.NFC.value) {
if (aid != null) {
- if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000004")) {
- //Paypass
- configPaypassParameter(aid);
- } else if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000003")) {
- //Paywave
- configPaywaveParameters();
- } else if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000025")) {
- //ExpressPay
-// configExpressPayParameter();
- } else if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000541")) {
- configPureContactlessParameter();
- } else if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000065")) {
- configJcbContactlessParameter();
- }
- }
- } else {
- //contact terminal capability ; if different card brand(depend on aid) have different terminal capability
- if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000004")) {
- emvHandler.setTlv(new byte[]{(byte) 0x9F, (byte) 0x33}, new byte[]{(byte) 0xE0, (byte) 0x28, (byte) 0xC8});
- emvHandler.setTlv(new byte[]{(byte) 0x9F, (byte) 0x1D}, ByteUtils.hexString2ByteArray("6C00800000000000"));//terminal risk
+ String aidStr = ByteUtils.byteArray2HexString(aid).toUpperCase();
+ if (aidStr.contains("A000000004")) {
+ configPaypassParameter(aid);
+ } else if (aidStr.contains("A000000003")) {
+ configPaywaveParameters();
+ } else if (aidStr.contains("A000000333")) {
+// configureQuickPassParamerter();
+ } else if (aidStr.contains("A000000541")) {
+ configPureContactlessParameter();
+ } else if (aidStr.contains("A000000065")) {
+ configJcbContactlessParameter();
+ } else if (aidStr.contains("A000000889")) {
+ configMPUContactlessParameter();
+ mMPUContactlessConfigured = true;
+ }
}
}
emvHandler.onSetTransInitBeforeGPOResponse(true);
}
+// @Override
+// public void onTransInitBeforeGPO() {
+// byte[] aid = emvHandler.getTlv(new byte[]{0x4F}, EmvDataSourceEnum.FROM_KERNEL);
+// LogUtil.d(TAG, "onTransInitBeforeGPO :");
+//// String terminalCapability = SystemParamsOperation.getInstance().getTerminalCapability();
+// String visaTerminalCapability = SystemParamsOperation.getInstance().getVisaTerminalCapability();
+// String masterTerminalCapability = SystemParamsOperation.getInstance().getMasterTerminalCapability();
+// String upiTerminalCapability = SystemParamsOperation.getInstance().getUpiTerminalCapability();
+//// LogUtil.d(TAG,"Terminal capability :"+terminalCapability);
+//// emvHandler.setTlv(new byte[]{(byte) 0x9F, (byte) 0x33}, new byte[]{(byte) 0xE0, (byte) 0x28, (byte) 0xC8});
+// emvHandler.setTlv(new byte[]{(byte) 0x9F, (byte) 0x33}, ByteUtil.hexStr2Bytes(terminalCapability));
+// if (mPayDetail.getCardType() == CardTypeX.NFC.value) {
+// if (aid != null) {
+// if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000004")) {
+// //Paypass
+// configPaypassParameter(aid);
+// } else if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000003")) {
+// //Paywave
+// configPaywaveParameters();
+// } else if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000025")) {
+// //ExpressPay
+//// configExpressPayParameter();
+// } else if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000541")) {
+// configPureContactlessParameter();
+// } else if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000065")) {
+// configJcbContactlessParameter();
+// }
+// }
+// } else {
+// //contact terminal capability ; if different card brand(depend on aid) have different terminal capability
+//// if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A000000004")) {
+//// emvHandler.setTlv(new byte[]{(byte) 0x9F, (byte) 0x33}, ByteUtil.hexStr2Bytes(terminalCapability));
+//// emvHandler.setTlv(new byte[]{(byte) 0xE0, (byte) 0x1D}, ByteUtils.hexString2ByteArray("6C00800000000000"));//terminal risk
+////
+//// }
+// }
+//
+// emvHandler.onSetTransInitBeforeGPOResponse(true);
+// }
+
@Override
public void onConfirmCardNo(CardInfoEntity cardInfoEntity) {
LogUtil.d(TAG, "onConfirmCardNo");
@@ -690,6 +678,17 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
cardNo = cardInfoEntity.getCardNo();
+
+ if (mPayDetail.getCardType() == CardTypeX.NFC.value) {
+ if (isRestrictedBin(cardNo)) {
+ isMPU_UPIContactless = true;
+ LogUtil.d(TAG, "onConfirmCardNo: restricted BIN detected — " + cardNo);
+ emvHandler.onSetConfirmCardNoResponse(false);
+ emvHandler.emvProcessCancel();
+ }
+ }
+
+
if (mPayDetail.getCardType() == CardTypeX.NFC.value) {
cardNum.postValue(cardInfoEntity.getCardNo());
mPayDetail.setCardNo(cardInfoEntity.getCardNo());
@@ -701,6 +700,9 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
public void onCardHolderInputPin(boolean isOnlinePin, int leftTimes) {
LogUtil.d(TAG, "onCardHolderInputPin isOnlinePin = " + isOnlinePin);
LogUtil.d(TAG, "onCardHolderInputPin leftTimes = " + leftTimes);
+ if (isOnlinePin) {
+ pinRemainingCount.postValue("");
+ }
// startPinProcess(isOnlinePin ? 1 : 0);
mProcessStep = EMV_SHOW_PIN_PAD;
// mHandler.obtainMessage(EMV_SHOW_PIN_PAD, isOnlinePin ? 1 : 0).sendToTarget();
@@ -739,7 +741,17 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
@Override
public void onPrompt(PromptEnum promptEnum) {
LogUtil.d(TAG, "onPrompt->" + promptEnum);
- emvHandler.onSetPromptResponse(true);
+ if( promptEnum == PromptEnum.OFFLINE_PIN_INCORRECT_TRY_AGAIN) {
+ offlinePinIncorrectPromptCount++;
+ pinEnterCount = 0;
+ pinText.postValue("");
+ int attemptLeft = Math.max(0, 3 - offlinePinIncorrectPromptCount);
+ pinRemainingCount.postValue("Please try again!\n" + attemptLeft + " attempt left!");
+ emvHandler.onSetPromptResponse(false);
+
+ } else {
+ emvHandler.onSetPromptResponse(true);
+ }
}
@Override
@@ -797,6 +809,9 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
byte[] tlv_50 = emvHandler.getTlv(new byte[]{(byte) 0x50}, EmvDataSourceEnum.FROM_KERNEL);
LogUtil.d(TAG, "tlv_50--" + ByteUtils.byteArray2HexString(tlv_50));
+ byte[] tlv_9B = emvHandler.getTlv(new byte[]{(byte) 0x9B}, EmvDataSourceEnum.FROM_KERNEL);
+ LogUtil.d(TAG, "tlv_9B--" + ByteUtils.byteArray2HexString(tlv_9B));
+
switch (retCode) {
case SdkResult.Emv_Success_Arpc_Fail:
case SdkResult.Success:
@@ -824,20 +839,38 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
//union pay online contactless--application should go online
break;
+ case SdkResult.Emv_App_Block:
+ case SdkResult.Emv_Card_Block:
+ mHandler.sendEmptyMessage(EMV_CARD_APP_BLOCK);
+ break;
+
case SdkResult.Emv_Candidatelist_Empty:// Application have no aid list
case SdkResult.Emv_FallBack:// FallBack ,chip card reset failed
//fallback process
- emvResultStatus.postValue(EmvResultStatus.READ_CARD_RETRY);
+ if(mMPUContactlessConfigured) {
+ mHandler.sendEmptyMessage(EMV_INSERT_OR_MANUAL);
+ } else {
+ mHandler.sendEmptyMessage(EMV_TRY_AGAIN);
+ }
+
+
break;
case SdkResult.Emv_Declined:
case SdkResult.Emv_Arpc_Fail: //
+ offlineDenial();
+// mHandler.obtainMessage(EMV_ERROR, retCode, retCode, "Emv Declined!").sendToTarget();
//// case SdkResult.Emv_Declined:
// //online decline ,if it is in second gac, application should decide if it is need reversal the transaction
break;
//
case SdkResult.Emv_Cancel:// Transaction Cancel
// //user cancel
- mHandler.obtainMessage(EMV_ERROR, retCode, retCode, "Canceled").sendToTarget();
+ if(isMPU_UPIContactless) {
+ mHandler.sendEmptyMessage(EMV_INSERT_OR_MANUAL);
+ } else {
+ mHandler.obtainMessage(EMV_ERROR, retCode, retCode, "Canceled").sendToTarget();
+ }
+
break;
//
// case SdkResult.Emv_Offline_Declined: //
@@ -955,6 +988,7 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
emvCardType.postValue("");
pinText.setValue("");
pinEnterCount = 0;
+ offlinePinIncorrectPromptCount = 0;
}
protected void getCardInfo() {
@@ -1210,11 +1244,11 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x1B}, new byte[]{(byte) 0x30});
//EMV MODE :amount >contactless cvm limit, set 60 = online pin and signature , set 20 = signature
- emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x18}, new byte[]{(byte) 0x28});
+ emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x18}, new byte[]{(byte) 0xF0}); //F8 //F0
//EMV mode :amount < contactless cvm limit, set 08 = no cvm
emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x19}, new byte[]{(byte) 0x08}); //08
- emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x25}, ByteUtils.hexString2ByteArray("000999999999"));
+ emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x25}, ByteUtils.hexString2ByteArray("999999999999"));
if (ByteUtils.byteArray2HexString(aid).toUpperCase().contains("A0000000043060")) {
Log.d("nexgo", "======maestro===== ");
@@ -1231,6 +1265,75 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
}
+
+ }
+
+ private void configMPUContactlessParameter() {
+ LogUtil.d(TAG,"MPU Contactless Parameter configurations....");
+ //kernel configuration, enable RRP and cdcvm
+
+
+ emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x1B}, new byte[]{(byte) 0x30});
+
+ //EMV MODE :amount >contactless cvm limit, set 60 = online pin and signature , set 20 = signature
+ emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x18}, new byte[]{(byte) 0xF0}); //F8
+ //EMV mode :amount < contactless cvm limit, set 08 = no cvm
+ emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x19}, new byte[]{(byte) 0x28}); //08
+
+ emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x24}, ByteUtils.hexString2ByteArray("000010000000"));
+ emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x25}, ByteUtils.hexString2ByteArray("000010000000"));
+ emvHandler.setTlv(new byte[]{(byte) 0xDF, (byte) 0x81, (byte) 0x26}, ByteUtils.hexString2ByteArray("000010000000"));
+
+
+
+ emvHandler.setTlv(new byte[]{(byte) 0x9F, (byte) 0x1d}, ByteUtils.hexString2ByteArray("6C00800000000000"));
+
+ setTransactionLimitForMPUCtls(true);
+
+
+ byte[] getTLVofDF8124 = emvHandler.getTlv(ByteUtil.hexStr2Bytes("DF8124"),EmvDataSourceEnum.FROM_KERNEL);
+ LogUtil.d(TAG,"DF8124: "+ByteUtil.bytes2HexStr(getTLVofDF8124));
+
+
+ }
+
+ private void setTransactionLimitForMPUCtls(boolean flag){
+ if(emvHandler.getAidList() != null) {
+ for (AidEntity aidEntity:emvHandler.getAidList()
+ ) {
+
+ if(aidEntity.getAid() != null) {
+ if(aidEntity.getAid().equals("A00000000410") || aidEntity.getAid().equals("A0000000041010")){
+
+ if(flag) {
+ aidEntity.setTransLimit(Long.parseLong("000010000000"));
+ aidEntity.setContactlessTransLimit(Long.parseLong("000010000000"));
+ } else {
+ aidEntity.setTransLimit(Long.parseLong("999999999999"));
+ aidEntity.setContactlessTransLimit(Long.parseLong("999999999999"));
+ }
+
+ emvHandler.delOneAid(ByteUtil.hexStr2Bytes(aidEntity.getAid()));
+ emvHandler.setAidParaList(List.of(aidEntity));
+ LogUtil.d(TAG,"added AID+"+aidEntity.getAid());
+ }
+ }
+
+ }
+
+ for (AidEntity aidEntity1:emvHandler.getAidList()
+ ) {
+ if (aidEntity1.getAid() != null) {
+ if (aidEntity1.getAid().equals("A00000000410") || aidEntity1.getAid().equals("A0000000041010")) {
+
+
+ LogUtil.d(TAG, " AID+" + aidEntity1.getAid());
+ LogUtil.d(TAG, " transactionLimit+" + aidEntity1.getContactlessTransLimit());
+ LogUtil.d(TAG, " transactionLimit+" + aidEntity1.getTransLimit());
+ }
+ }
+ }
+ }
}
private void configPaywaveParameters() {
@@ -1239,13 +1342,12 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
LogUtil.d(TAG, "configPaywaveParameters, TTQ" + ByteUtils.byteArray2HexString(kernelTTQ));
//default TTQ value
- TTQ = ByteUtils.hexString2ByteArray("36A04000");
+ TTQ = ByteUtils.hexString2ByteArray("32A04000"); // 36A04000
kernelTTQ[0] = TTQ[0];
kernelTTQ[1] = TTQ[1];
kernelTTQ[2] = TTQ[2];
kernelTTQ[3] = TTQ[3];
-
- // FIXME: 2019/3/20
+
//If there is no special requirements, do not change TTQ byte1
//if online force required , can set byte2 bit 8 = 1
emvHandler.setTlv(ByteUtils.hexString2ByteArray("9F66"), kernelTTQ);
@@ -1278,6 +1380,11 @@ public abstract class EmvBaseViewModel extends BaseViewModel {
}
+ private void configPureQuickPassParameter() {
+ LogUtil.d(TAG, "configQuickPassParameter");
+
+
+ }
private void configJcbContactlessParameter() {
LogUtil.d(TAG, "configJcbContactlessParameter");
diff --git a/baselib/src/main/res/raw/contacts_config.json b/baselib/src/main/res/raw/contacts_config.json
index f147bdb..4d3736c 100644
--- a/baselib/src/main/res/raw/contacts_config.json
+++ b/baselib/src/main/res/raw/contacts_config.json
@@ -1,9 +1,10 @@
[
+
{
"aidEnable": true,
"aid": "A0000000031010",
"cardScheme": "VISA",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -26,7 +27,7 @@
"aidEnable": true,
"aid": "A0000000032010",
"cardScheme": "VISA",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -49,7 +50,7 @@
"aidEnable": true,
"aid": "A000000003101001",
"cardScheme": "VISA",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -72,7 +73,7 @@
"aidEnable": true,
"aid": "A000000003101002",
"cardScheme": "VISA",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -95,7 +96,7 @@
"aidEnable": true,
"aid": "A000000003101003",
"cardScheme": "VISA",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -118,7 +119,7 @@
"aidEnable": true,
"aid": "A000000003101004",
"cardScheme": "VISA",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -141,7 +142,7 @@
"aidEnable": true,
"aid": "A000000003101005",
"cardScheme": "VISA",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -164,7 +165,7 @@
"aidEnable": true,
"aid": "A0000000033010",
"cardScheme": "VISA",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -187,7 +188,7 @@
"aidEnable": true,
"aid": "A0000000038010",
"cardScheme": "VISA",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -210,7 +211,7 @@
"aidEnable": true,
"aid": "A000000003101008",
"cardScheme": "VISA",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -233,7 +234,7 @@
"aidEnable": true,
"aid": "A000000003101009",
"cardScheme": "VISA",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -529,33 +530,10 @@
"currencyCode": "0104"
},
{
- "aidEnable": true,
- "aid": "A0000000651010",
- "cardScheme": "JCB",
- "applicationVersion": "0020",
- "emvDDOL": "9F3704",
- "emvTDOL": "9F3704",
- "partialAidSelection": false,
- "targetPercent": "99",
- "maxTargetPercent": "99",
- "threshold": "00000000",
- "tacDefault": "D84000A800",
- "tacOnline": "DC4004F800",
- "tacDenial": "0000000000",
- "floorLimit": "000000000000",
- "cvmLimit": 75000,
- "transLimit": "999999999999",
- "transLimitCDV": "999999999999",
- "terminalCapability": "0000000000000000",
- "riskManageData": "01",
- "cateCode": "2701",
- "currencyCode": "0104"
- },
- {
- "aidEnable": true,
+ "aidEnable": false,
"aid": "A00000006510",
"cardScheme": "JCB",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -575,10 +553,33 @@
"currencyCode": "0104"
},
{
- "aidEnable": true,
+ "aidEnable": false,
+ "aid": "A0000000651010",
+ "cardScheme": "JCB",
+ "applicationVersion": "0030",
+ "emvDDOL": "9F3704",
+ "emvTDOL": "9F3704",
+ "partialAidSelection": false,
+ "targetPercent": "99",
+ "maxTargetPercent": "99",
+ "threshold": "00000000",
+ "tacDefault": "D84000A800",
+ "tacOnline": "DC4004F800",
+ "tacDenial": "0000000000",
+ "floorLimit": "000000000000",
+ "cvmLimit": 75000,
+ "transLimit": "999999999999",
+ "transLimitCDV": "999999999999",
+ "terminalCapability": "0000000000000000",
+ "riskManageData": "01",
+ "cateCode": "2701",
+ "currencyCode": "0104"
+},
+ {
+ "aidEnable": false,
"aid": "A0000001570040",
"cardScheme": "JCB",
- "applicationVersion": "0020",
+ "applicationVersion": "0030",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
diff --git a/baselib/src/main/res/raw/mpu_ctls_config.json b/baselib/src/main/res/raw/mpu_ctls_config.json
index 3f6983e..3732939 100644
--- a/baselib/src/main/res/raw/mpu_ctls_config.json
+++ b/baselib/src/main/res/raw/mpu_ctls_config.json
@@ -14,7 +14,7 @@
"tacOnline": "DC4004F800",
"tacDenial": "0000000000",
"floorLimit": "000000000000",
- "cvmLimit": 100000,
+ "cvmLimit": 10000000,
"transLimit": "000010000000",
"transLimitCDV": "999999999999",
"terminalCapability": "0000000000000000",
diff --git a/baselib/src/main/res/raw/paypass_config.json b/baselib/src/main/res/raw/paypass_config.json
index e5c1ed1..d55b33f 100644
--- a/baselib/src/main/res/raw/paypass_config.json
+++ b/baselib/src/main/res/raw/paypass_config.json
@@ -1,35 +1,9 @@
[
{
"aidEnable": true,
- "aid": "A0000000041010",
+ "aid": "A00000000410",
"cardLabel": "MASTERCARD",
- "applicationVersion": "0020",
- "emvDDOL": "9F3704",
- "emvTDOL": "9F3704",
- "partialAidSelection": false,
- "targetPercent": "00",
- "maxTargetPercent": "00",
- "threshold": "00000040",
- "tacDefault": "D84000A800",
- "tacOnline": "DC4004F800",
- "tacDenial": "0000000000",
- "floorLimit": "000000000000",
- "cvmLimit": 75000,
- "transLimit": "999999999999",
- "transLimitCDV": "999999999999",
- "terminalCapability": "E0F8F8",
- "riskManageData": "6C7A800000000000",
- "kernelType": "02",
- "ttq": "36804000",
- "cateCode": "2701",
- "currencyCode": "0104"
- },
-
- {
- "aidEnable": true,
- "aid": "A0000000041010C123456789",
- "cardLabel": "MASTERCARD",
- "applicationVersion": "0020",
+ "applicationVersion": "0002",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
@@ -43,7 +17,7 @@
"cvmLimit": 75000,
"transLimit": "999999999999",
"transLimitCDV": "999999999999",
- "terminalCapability": "E0F8F8",
+ "terminalCapability": "E0F8C8",
"riskManageData": "6C7A800000000000",
"kernelType": "02",
"ttq": "36804000",
@@ -52,9 +26,34 @@
},
{
"aidEnable": true,
- "aid": "A0000000043060",
+ "aid": "A0000000041010",
"cardLabel": "MASTERCARD",
- "applicationVersion": "0020",
+ "applicationVersion": "0002",
+ "emvDDOL": "9F3704",
+ "emvTDOL": "9F3704",
+ "partialAidSelection": false,
+ "targetPercent": "99",
+ "maxTargetPercent": "99",
+ "threshold": "00000040",
+ "tacDefault": "D84000A800",
+ "tacOnline": "DC4004F800",
+ "tacDenial": "0000000000",
+ "floorLimit": "000000000000",
+ "cvmLimit": 75000,
+ "transLimit": "999999999999",
+ "transLimitCDV": "999999999999",
+ "terminalCapability": "E0F8C8",
+ "riskManageData": "6C7A800000000000",
+ "kernelType": "02",
+ "ttq": "36804000",
+ "cateCode": "2701",
+ "currencyCode": "0104"
+ },
+ {
+ "aidEnable": true,
+ "aid": "A0000000041010C123456789",
+ "cardLabel": "MASTERCARD",
+ "applicationVersion": "0002",
"emvDDOL": "9F3704",
"emvTDOL": "9F3704",
"partialAidSelection": false,
diff --git a/baselib/src/main/res/raw/paywave_config.json b/baselib/src/main/res/raw/paywave_config.json
index f0fbdaf..f3e6f43 100644
--- a/baselib/src/main/res/raw/paywave_config.json
+++ b/baselib/src/main/res/raw/paywave_config.json
@@ -173,30 +173,5 @@
"ttq": "32A04000",
"cateCode": "2701",
"currencyCode": "0104"
- },
- {
- "aidEnable": true,
- "aid": "325041592E5359532E4444463031",
- "cardLabel": "VISA",
- "applicationVersion": "0030",
- "emvDDOL": "9F3704",
- "emvTDOL": "9F3704",
- "partialAidSelection": false,
- "targetPercent": "00",
- "maxTargetPercent": "00",
- "threshold": "00000000",
- "tacDefault": "DC4000A800",
- "tacOnline": "DC4004F800",
- "tacDenial": "0010000000",
- "floorLimit": "000000000000",
- "cvmLimit": 70000,
- "transLimit": "999999999999",
- "transLimitCDV": "999999999999",
- "terminalCapability": "0000000000000000",
- "riskManageData": "01",
- "kernelType": "03",
- "ttq": "32A04000",
- "cateCode": "2701",
- "currencyCode": "0104"
}
]
\ No newline at end of file
diff --git a/baselib/src/main/res/raw/quickpass_config.json b/baselib/src/main/res/raw/quickpass_config.json
index a56020b..143a86d 100644
--- a/baselib/src/main/res/raw/quickpass_config.json
+++ b/baselib/src/main/res/raw/quickpass_config.json
@@ -14,7 +14,7 @@
"tacOnline": "DC4004F800",
"tacDenial": "0000000000",
"floorLimit": "000000000000",
- "cvmLimit": 75000,
+ "cvmLimit": 30000,
"transLimit": "9999999999",
"transLimitCDV": "9999999999",
"terminalCapability": "0000000000000000",
@@ -39,7 +39,57 @@
"tacOnline": "DC4004F800",
"tacDenial": "0000000000",
"floorLimit": "000000000000",
- "cvmLimit": 75000,
+ "cvmLimit": 30000,
+ "transLimit": "9999999999",
+ "transLimitCDV": "9999999999",
+ "terminalCapability": "0000000000000000",
+ "riskManageData": "01",
+ "kernelType": "01",
+ "ttq": "36800000",
+ "cateCode": "2701",
+ "currencyCode": "0104"
+ },
+ {
+ "aidEnable": true,
+ "aid": "A000000333010105",
+ "cardLabel": "UPI",
+ "applicationVersion": "0002",
+ "emvDDOL": "9F3704",
+ "emvTDOL": "9F3704",
+ "partialAidSelection": false,
+ "targetPercent": "99",
+ "maxTargetPercent": "99",
+ "threshold": "00000000",
+ "tacDefault": "D84000A800",
+ "tacOnline": "DC4004F800",
+ "tacDenial": "0000000000",
+ "floorLimit": "000000000000",
+ "cvmLimit": 30000,
+ "transLimit": "9999999999",
+ "transLimitCDV": "9999999999",
+ "terminalCapability": "0000000000000000",
+ "riskManageData": "01",
+ "kernelType": "01",
+ "ttq": "36800000",
+ "cateCode": "2701",
+ "currencyCode": "0104"
+ },
+ {
+ "aidEnable": true,
+ "aid": "A000000333010106",
+ "cardLabel": "UPI",
+ "applicationVersion": "0002",
+ "emvDDOL": "9F3704",
+ "emvTDOL": "9F3704",
+ "partialAidSelection": false,
+ "targetPercent": "99",
+ "maxTargetPercent": "99",
+ "threshold": "00000000",
+ "tacDefault": "D84000A800",
+ "tacOnline": "DC4004F800",
+ "tacDenial": "0000000000",
+ "floorLimit": "000000000000",
+ "cvmLimit": 30000,
"transLimit": "9999999999",
"transLimitCDV": "9999999999",
"terminalCapability": "0000000000000000",
diff --git a/baselib/src/main/res/raw/rid_config.json b/baselib/src/main/res/raw/rid_config.json
index 6ba056b..4f639b0 100644
--- a/baselib/src/main/res/raw/rid_config.json
+++ b/baselib/src/main/res/raw/rid_config.json
@@ -51,15 +51,175 @@
"checkSum": "1FF80A40173F52D7D27E0F26A146A1C8CCB29046"
},
{
- "rid": "A000000333",
- "indx": "0A",
+ "rid": "A000000004",
+ "indx": "00",
"hashInd": "01",
"arithInd": "01",
- "modul": "B2AB1B6E9AC55A75ADFD5BBC34490E53C4C3381F34E60E7FAC21CC2B26DD34462B64A6FAE2495ED1DD383B8138BEA100FF9B7A111817E7B9869A9742B19E5C9DAC56F8B8827F11B05A08ECCF9E8D5E85B0F7CFA644EFF3E9B796688F38E006DEB21E101C01028903A06023AC5AAB8635F8E307A53AC742BDCE6A283F585F48EF",
+ "modul": "9c6be5adb10b4be3dce2099b4b210672b89656eba091204f613ecc623bedc9c6d77b660e8baeea7f7ce30f1b153879a4e36459343d1fe47acdbd41fcd710030c2ba1d9461597982c6e1bdd08554b726f5eff7913ce59e79e357295c321e26d0b8be270a9442345c753e2aa2acfc9d30850602fe6cac00c6ddf6b8d9d9b4879b2826b042a07f0e5ae526a3d3c4d22c72b9eaa52eed8893866f866387ac05a1399",
"exponent": "03",
- "expDate": "3230333031323331",
- "checkSum": "C88BE6B2417C4F941C9371EA35A377158767E4E3"
+ "expDate": "20201231",
+ "checkSum": "ec0a59d35d19f031e9e8cbec56db80e22b1de130"
},
+ {
+ "rid": "A000000004",
+ "indx": "01",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "C696034213D7D8546984579D1D0F0EA519CFF8DEFFC429354CF3A871A6F7183F1228DA5C7470C055387100CB935A712C4E2864DF5D64BA93FE7E63E71F25B1E5F5298575EBE1C63AA617706917911DC2A75AC28B251C7EF40F2365912490B939BCA2124A30A28F54402C34AECA331AB67E1E79B285DD5771B5D9FF79EA630B75",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "8C05A64127485B923C94B63D264AF0BF85CB45D9"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "03",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "c2490747fe17eb0584c88d47b1602704150adc88c5b998bd59ce043edebf0ffee3093ac7956ad3b6ad4554c6de19a178d6da295be15d5220645e3c8131666fa4be5b84fe131ea44b039307638b9e74a8c42564f892a64df1cb15712b736e3374f1bbb6819371602d8970e97b900793c7c2a89a4a1649a59be680574dd0b60145",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "5addf21d09278661141179cbeff272ea384b13bb"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "04",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "a6da428387a502d7ddfb7a74d3f412be762627197b25435b7a81716a700157ddd06f7cc99d6ca28c2470527e2c03616b9c59217357c2674f583b3ba5c7dcf2838692d023e3562420b4615c439ca97c44dc9a249cfce7b3bfb22f68228c3af13329aa4a613cf8dd853502373d62e49ab256d2bc17120e54aedced6d96a4287acc5c04677d4a5a320db8bee2f775e5fec5",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "381a035da58b482ee2af75f4c3f2ca469ba4aa6c"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "05",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "b8048abc30c90d976336543e3fd7091c8fe4800df820ed55e7e94813ed00555b573feca3d84af6131a651d66cff4284fb13b635edd0ee40176d8bf04b7fd1c7bacf9ac7327dfaa8aa72d10db3b8e70b2ddd811cb4196525ea386acc33c0d9d4575916469c4e4f53e8e1c912cc618cb22dde7c3568e90022e6bba770202e4522a2dd623d180e215bd1d1507fe3dc90ca310d27b3efccd8f83de3052cad1e48938c68d095aac91b5f37e28bb49ec7ed597",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "ebfa0d5d06d8ce702da3eae890701d45e274c845"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "06",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "cb26fc830b43785b2bce37c81ed334622f9622f4c89aae641046b2353433883f307fb7c974162da72f7a4ec75d9d657336865b8d3023d3d645667625c9a07a6b7a137cf0c64198ae38fc238006fb2603f41f4f3bb9da1347270f2f5d8c606e420958c5f7d50a71de30142f70de468889b5e3a08695b938a50fc980393a9cbce44ad2d64f630bb33ad3f5f5fd495d31f37818c1d94071342e07f1bec2194f6035ba5ded3936500eb82dfda6e8afb655b1ef3d0d7ebf86b66dd9f29f6b1d324fe8b26ce38ab2013dd13f611e7a594d675c4432350ea244cc34f3873cba06592987a1d7e852adc22ef5a2ee28132031e48f74037e3b34ab747f",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "f910a1504d5ffb793d94f3b500765e1abcad72d9"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "F1",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "a0dcf4bde19c3546b4b6f0414d174dde294aabbb828c5a834d73aae27c99b0b053a90278007239b6459ff0bbcd7b4b9c6c50ac02ce91368da1bd21aaeadbc65347337d89b68f5c99a09d05be02dd1f8c5ba20e2f13fb2a27c41d3f85cad5cf6668e75851ec66edbf98851fd4e42c44c1d59f5984703b27d5b9f21b8fa0d93279fbbf69e090642909c9ea27f898959541aa6757f5f624104f6e1d3a9532f2a6e51515aead1b43b3d7835088a2fafa7be7",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "d8e68da167ab5a85d8c3d55ecb9b0517a1a5b4bb"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "F3",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "98f0c770f23864c2e766df02d1e833dff4ffe92d696e1642f0a88c5694c6479d16db1537bfe29e4fdc6e6e8afd1b0eb7ea0124723c333179bf19e93f10658b2f776e829e87daeda9c94a8b3382199a350c077977c97aff08fd11310ac950a72c3ca5002ef513fccc286e646e3c5387535d509514b3b326e1234f9cb48c36ddd44b416d23654034a66f403ba511c5efa3",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "a69ac7603daf566e972dedc2cb433e07e8b01a9a"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "F5",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "a6e6fb72179506f860ccca8c27f99cecd94c7d4f3191d303bbee37481c7aa15f233ba755e9e4376345a9a67e7994bdc1c680bb3522d8c93eb0ccc91ad31ad450da30d337662d19ac03e2b4ef5f6ec18282d491e19767d7b24542dfdeff6f62185503532069bbb369e3bb9fb19ac6f1c30b97d249eee764e0bac97f25c873d973953e5153a42064bbfabfd06a4bb486860bf6637406c9fc36813a4a75f75c31cca9f69f8de59adecef6bde7e07800fcbe035d3176af8473e23e9aa3dfee221196d1148302677c720cfe2544a03db553e7f1b8427ba1cc72b0f29b12dfef4c081d076d353e71880aadff386352af0ab7b28ed49e1e672d11f9",
+ "exponent": "010001",
+ "expDate": "20201231",
+ "checkSum": "c2239804c8098170be52d6d5d4159e81ce8466bf"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "F6",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "a25a6bd783a5ef6b8fb6f83055c260f5f99ea16678f3b9053e0f6498e82c3f5d1e8c38f13588017e2b12b3d8ff6f50167f46442910729e9e4d1b3739e5067c0ac7a1f4487e35f675bc16e233315165cb142bfdb25e301a632a54a3371ebab6572deebaf370f337f057ee73b4ae46d1a8bc4da853ec3cc12c8cbc2da18322d68530c70b22bdac351dd36068ae321e11abf264f4d3569bb71214545005558de26083c735db776368172fe8c2f5c85e8b5b890cc682911d2de71fa626b8817fccc08922b703869f3baeac1459d77cd85376bc36182f4238314d6c4212fbdd7f23d3",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "502909ed545e3c8dbd00ea582d0617fee9f6f684"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "F7",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "94ea62f6d58320e354c022addcf0559d8cf206cd92e869564905ce21d720f971b7aea374830ebe1757115a85e088d41c6b77cf5ec821f30b1d890417bf2fa31e5908ded5fa677f8c7b184ad09028fdde96b6a6109850aa800175eabcdbbb684a96c2eb6379dfea08d32fe2331fe103233ad58dcdb1e6e077cb9f24eaec5c25af",
+ "exponent": "010001",
+ "expDate": "20201231",
+ "checkSum": "eeb0dd9b2477bee3209a914cdba94c1c4a9bded9"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "F8",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "a1f5e1c9bd8650bd43ab6ee56b891ef7459c0a24fa84f9127d1a6c79d4930f6db1852e2510f18b61cd354db83a356bd190b88ab8df04284d02a4204a7b6cb7c5551977a9b36379ca3de1a08e69f301c95cc1c20506959275f41723dd5d2925290579e5a95b0df6323fc8e9273d6f849198c4996209166d9bfc973c361cc826e1",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "f06ecc6d2aaebf259b7e755a38d9a9b24e2ff3dd"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "F9",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "a99a6d3e071889ed9e3a0c391c69b0b804fc160b2b4bdd570c92dd5a0f45f53e8621f7c96c40224266735e1ee1b3c06238ae35046320fd8e81f8ceb3f8b4c97b940930a3ac5e790086dad41a6a4f5117ba1ce2438a51ac053eb002aed866d2c458fd73359021a12029a0c043045c11664fe0219ec63c10bf2155bb2784609a106421d45163799738c1c30909bb6c6fe52bbb76397b9740ce064a613ff8411185f08842a423ead20edffbff1cd6c3fe0c9821479199c26d8572cc8afff087a9c3",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "336712dcc28554809c6aa9b02358de6f755164db"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "FA",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "a90fcd55aa2d5d9963e35ed0f440177699832f49c6bab15cdae5794be93f934d4462d5d12762e48c38ba83d8445deaa74195a301a102b2f114eada0d180ee5e7a5c73e0c4e11f67a43ddab5d55683b1474cc0627f44b8d3088a492ffaadad4f42422d0e7013536c3c49ad3d0fae96459b0f6b1b6056538a3d6d44640f94467b108867dec40faaecd740c00e2b7a8852d",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "5bed4068d96ea16d2d77e03d6036fc7a160ea99c"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "FE",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "a653eac1c0f786c8724f737f172997d63d1c3251c44402049b865bae877d0f398cbfbe8a6035e24afa086befde9351e54b95708ee672f0968bcd50dce40f783322b2aba04ef137ef18abf03c7dbc5813aeaef3aa7797ba15df7d5ba1cbaf7fd520b5a482d8d3fee105077871113e23a49af3926554a70fe10ed728cf793b62a1",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "9a295b05fb390ef7923f57618a9fda2941fc34e0"
+ },
+ {
+ "rid": "A000000004",
+ "indx": "EF",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "a191cb87473f29349b5d60a88b3eaee0973aa6f1a082f358d849fddff9c091f899eda9792caf09ef28f5d22404b88a2293eebbc1949c43bea4d60cfd879a1539544e09e0f09f60f065b2bf2a13ecc705f3d468b9d33ae77ad9d3f19ca40f23dcf5eb7c04dc8f69eba565b1ebcb4686cd274785530ff6f6e9ee43aa43fdb02ce00daec15c7b8fd6a9b394baba419d3f6dc85e16569be8e76989688efea2df22ff7d35c043338deaa982a02b866de5328519ebbcd6f03cdd686673847f84db651ab86c28cf1462562c577b853564a290c8556d818531268d25cc98a4cc6a0bdfffda2dcca3a94c998559e307fddf915006d9a987b07ddaeb3b",
+ "exponent": "03",
+ "expDate": "20201231",
+ "checkSum": "21766ebb0ee122afb65d7845b73db46bab65427a"
+ },
+ {
+ "rid": "A000000333",
+ "indx": "0A",
+ "hashInd": "01",
+ "arithInd": "01",
+ "modul": "B2AB1B6E9AC55A75ADFD5BBC34490E53C4C3381F34E60E7FAC21CC2B26DD34462B64A6FAE2495ED1DD383B8138BEA100FF9B7A111817E7B9869A9742B19E5C9DAC56F8B8827F11B05A08ECCF9E8D5E85B0F7CFA644EFF3E9B796688F38E006DEB21E101C01028903A06023AC5AAB8635F8E307A53AC742BDCE6A283F585F48EF",
+ "exponent": "03",
+ "expDate": "3230333031323331",
+ "checkSum": "C88BE6B2417C4F941C9371EA35A377158767E4E3"
+},
{
"rid": "A000000333",
"indx": "08",
@@ -90,6 +250,16 @@
"expDate": "3230333031323331",
"checkSum": "BD331F9996A490B33C13441066A09AD3FEB5F66C"
},
+ {
+ "rid": "A000000065",
+ "indx": "07",
+ "hashInd": "01",
+ "arithInd": "00",
+ "modul": "B8DAB883EF1B5763E4F861F9EA3044B276635D402F3AE5E6B6C0547E368E79A36366DAC5609B6EC486DA1A8D2002CA4F4EFC2CB0EC1573A0B0917969EB60645BAEDF11C050C5D07FED817D11E84A174859A0DAE7F7935F109229C0AC4EE5BFB3D65533A679F0486C5AEFCC937379833BEC45D79DCF97B5228B1910FA03765331",
+ "exponent": "010001",
+ "expDate": "20201231",
+ "checkSum": "4896DD5A9EB5B11B9DCCA6DFE336C009F69F509A"
+ },
{
"rid": "A000000065",
"indx": "08",
@@ -97,7 +267,7 @@
"arithInd": "00",
"modul": "B74670DAD1DC8983652000E5A7F2F8B35DFD083EE593E5BA895C95729F2BADE9C8ABF3DD9CE240C451C6CEFFC768D83CBAC76ABB8FEA58F013C647007CFF7617BAC2AE3981816F25CC7E5238EF34C4F02D0B01C24F80C2C65E7E7743A4FA8E23206A23ECE290C26EA56DB085C5C5EAE26292451FC8292F9957BE8FF20FAD53E5",
"exponent": "03",
- "expDate": "3230333031323331",
+ "expDate": "20201231",
"checkSum": "DD36D5896228C8C4900742F107E2F91FE50BC7EE"
},
{
@@ -117,7 +287,7 @@
"arithInd": "00",
"modul": "99B63464EE0B4957E4FD23BF923D12B61469B8FFF8814346B2ED6A780F8988EA9CF0433BC1E655F05EFA66D0C98098F25B659D7A25B8478A36E489760D071F54CDF7416948ED733D816349DA2AADDA227EE45936203CBF628CD033AABA5E5A6E4AE37FBACB4611B4113ED427529C636F6C3304F8ABDD6D9AD660516AE87F7F2DDF1D2FA44C164727E56BBC9BA23C0285",
"exponent": "03",
- "expDate": "3230333031323331",
+ "expDate": "20201231",
"checkSum": "C75E5210CBE6E8F0594A0F1911B07418CADB5BAB"
},
{
@@ -127,7 +297,7 @@
"arithInd": "00",
"modul": "A2583AA40746E3A63C22478F576D1EFC5FB046135A6FC739E82B55035F71B09BEB566EDB9968DD649B94B6DEDC033899884E908C27BE1CD291E5436F762553297763DAA3B890D778C0F01E3344CECDFB3BA70D7E055B8C760D0179A403D6B55F2B3B083912B183ADB7927441BED3395A199EEFE0DEBD1F5FC3264033DA856F4A8B93916885BD42F9C1F456AAB8CFA83AC574833EB5E87BB9D4C006A4B5346BD9E17E139AB6552D9C58BC041195336485",
"exponent": "03",
- "expDate": "3230333031323331",
+ "expDate": "20201231",
"checkSum": "D9FD62C9DD4E6DE7741E9A17FB1FF2C5DB948BCB"
},
{
@@ -137,28 +307,17 @@
"arithInd": "00",
"modul": "AEED55B9EE00E1ECEB045F61D2DA9A66AB637B43FB5CDBDB22A2FBB25BE061E937E38244EE5132F530144A3F268907D8FD648863F5A96FED7E42089E93457ADC0E1BC89C58A0DB72675FBC47FEE9FF33C16ADE6D341936B06B6A6F5EF6F66A4EDD981DF75DA8399C3053F430ECA342437C23AF423A211AC9F58EAF09B0F837DE9D86C7109DB1646561AA5AF0289AF5514AC64BC2D9D36A179BB8A7971E2BFA03A9E4B847FD3D63524D43A0E8003547B94A8A75E519DF3177D0A60BC0B4BAB1EA59A2CBB4D2D62354E926E9C7D3BE4181E81BA60F8285A896D17DA8C3242481B6C405769A39D547C74ED9FF95A70A796046B5EFF36682DC29",
"exponent": "03",
- "expDate": "3230333031323331",
+ "expDate": "20201231",
"checkSum": "43A3151513B7ADCEB92DBEA2A262CEB336D26C83"
},
{
- "rid": "A000000004",
- "indx": "F1",
+ "rid": "A000000065",
+ "indx": "13",
"hashInd": "01",
- "arithInd": "01",
- "modul": "A0DCF4BDE19C3546B4B6F0414D174DDE294AABBB828C5A834D73AAE27C99B0B053A90278007239B6459FF0BBCD7B4B9C6C50AC02CE91368DA1BD21AAEADBC65347337D89B68F5C99A09D05BE02DD1F8C5BA20E2F13FB2A27C41D3F85CAD5CF6668E75851EC66EDBF98851FD4E42C44C1D59F5984703B27D5B9F21B8FA0D93279FBBF69E090642909C9EA27F898959541AA6757F5F624104F6E1D3A9532F2A6E51515AEAD1B43B3D7835088A2FAFA7BE7",
+ "arithInd": "00",
+ "modul": "A3270868367E6E29349FC2743EE545AC53BD3029782488997650108524FD051E3B6EACA6A9A6C1441D28889A5F46413C8F62F3645AAEB30A1521EEF41FD4F3445BFA1AB29F9AC1A74D9A16B93293296CB09162B149BAC22F88AD8F322D684D6B49A12413FC1B6AC70EDEDB18EC1585519A89B50B3D03E14063C2CA58B7C2BA7FB22799A33BCDE6AFCBEB4A7D64911D08D18C47F9BD14A9FAD8805A15DE5A38945A97919B7AB88EFA11A88C0CD92C6EE7DC352AB0746ABF13585913C8A4E04464B77909C6BD94341A8976C4769EA6C0D30A60F4EE8FA19E767B170DF4FA80312DBA61DB645D5D1560873E2674E1F620083F30180BD96CA589",
"exponent": "03",
"expDate": "20201231",
- "checkSum": "D8E68DA167AB5A85D8C3D55ECB9B0517A1A5B4BB"
- },
- {
- "rid": "A000000004",
- "indx": "EF",
- "hashInd": "01",
- "arithInd": "01",
- "modul": "A191CB87473F29349B5D60A88B3EAEE0973AA6F1A082F358D849FDDFF9C091F899EDA9792CAF09EF28F5D22404B88A2293EEBBC1949C43BEA4D60CFD879A1539544E09E0F09F60F065B2BF2A13ECC705F3D468B9D33AE77AD9D3F19CA40F23DCF5EB7C04DC8F69EBA565B1EBCB4686CD274785530FF6F6E9EE43AA43FDB02CE00DAEC15C7B8FD6A9B394BABA419D3F6DC85E16569BE8E76989688EFEA2DF22FF7D35C043338DEAA982A02B866DE5328519EBBCD6F03CDD686673847F84DB651AB86C28CF1462562C577B853564A290C8556D818531268D25CC98A4CC6A0BDFFFDA2DCCA3A94C998559E307FDDF915006D9A987B07DDAEB3B",
- "exponent": "03",
- "expDate": "20201231",
- "checkSum": "21766EBB0EE122AFB65D7845B73DB46BAB65427A"
+ "checkSum": "54CFAE617150DFA09D3F901C9123524523EBEDF3"
}
-
]
\ No newline at end of file
diff --git a/baselib/src/test/java/com/utsmyanmar/baselib/ExampleUnitTest.java b/baselib/src/test/java/com/utsmyanmar/baselib/ExampleUnitTest.java
index 8147a3e..d4c6913 100644
--- a/baselib/src/test/java/com/utsmyanmar/baselib/ExampleUnitTest.java
+++ b/baselib/src/test/java/com/utsmyanmar/baselib/ExampleUnitTest.java
@@ -21,7 +21,7 @@ public class ExampleUnitTest {
@Test
public void testCAPKIndex() {
- String index = "99";
+ String index = "F1";
int data = Integer.parseInt(index,16);
System.out.println("Data: "+data);
diff --git a/mpulib/src/main/java/com/utsmyanmar/checkxread/checkcard/CheckCardX.java b/mpulib/src/main/java/com/utsmyanmar/checkxread/checkcard/CheckCardX.java
index f63029c..567475a 100644
--- a/mpulib/src/main/java/com/utsmyanmar/checkxread/checkcard/CheckCardX.java
+++ b/mpulib/src/main/java/com/utsmyanmar/checkxread/checkcard/CheckCardX.java
@@ -6,6 +6,7 @@ import android.os.Looper;
import android.os.RemoteException;
import android.util.Log;
+import com.nexgo.common.LogUtils;
import com.nexgo.oaf.apiv3.SdkResult;
import com.nexgo.oaf.apiv3.device.reader.CardInfoEntity;
import com.nexgo.oaf.apiv3.device.reader.CardSlotTypeEnum;
@@ -106,6 +107,14 @@ public class CheckCardX {
Log.d(TAG, "Find IC");
} else if(cardInfoEntity.getCardExistslot() == CardSlotTypeEnum.RF) {
checkCardResultX.onSuccess(CardTypeX.NFC,false);
+ } else if(cardInfoEntity.getCardExistslot() == CardSlotTypeEnum.SWIPE) {
+ LogUtils.debug(TAG,"Found Swipe");
+ Bundle info = new Bundle();
+ info.putString("TRACK1",cardInfoEntity.getTk1());
+ info.putString("TRACK2",cardInfoEntity.getTk2());
+ info.putString("TRACK3",cardInfoEntity.getTk3());
+ MAGXReadCard.getInstance().setBundle(info);
+ checkCardResultX.onSuccess(CardTypeX.MAG,false);
}
} else if( i == SdkResult.Fail) {
checkCardResultX.onError(i,"Failure");
diff --git a/nexsdk-lib/build.gradle b/nexsdk-lib/build.gradle
index c48aa82..2e99dd9 100644
--- a/nexsdk-lib/build.gradle
+++ b/nexsdk-lib/build.gradle
@@ -1,2 +1,2 @@
configurations.maybeCreate("default")
-artifacts.add("default", file('nexgo-smartpos-sdk-v3.08.006_20241216.aar'))
\ No newline at end of file
+artifacts.add("default", file('nexgo-smartpos-sdk-v3.08.013_20260416.aar'))
\ No newline at end of file
diff --git a/nexsdk-lib/nexgo-smartpos-sdk-v3.08.013_20260416.aar b/nexsdk-lib/nexgo-smartpos-sdk-v3.08.013_20260416.aar
new file mode 100644
index 0000000..f920be7
Binary files /dev/null and b/nexsdk-lib/nexgo-smartpos-sdk-v3.08.013_20260416.aar differ
diff --git a/paylibs/src/main/assets/fonts/firaCode_bold.ttf b/paylibs/src/main/assets/fonts/firaCode_bold.ttf
new file mode 100644
index 0000000..82a931f
Binary files /dev/null and b/paylibs/src/main/assets/fonts/firaCode_bold.ttf differ
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/model/CardSettleData.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/model/CardSettleData.java
index b799fa5..c06a2f5 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/model/CardSettleData.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/model/CardSettleData.java
@@ -1,15 +1,17 @@
package com.utsmyanmar.paylibs.model;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-public class CardSettleData {
+public class CardSettleData implements Serializable {
private String cardType;
private String cardNum;
private String expDate;
private String invoiceNum;
private String transType;
+ private String currencyCode;
private long amount;
@@ -21,12 +23,13 @@ public class CardSettleData {
public CardSettleData() {
}
- public CardSettleData(String cardType, String cardNum, String expDate, String invoiceNum, String transType, long amount, String transDate, String transTime, String approvalCode) {
+ public CardSettleData(String cardType, String cardNum, String expDate, String invoiceNum, String transType, String currencyCode, long amount, String transDate, String transTime, String approvalCode) {
this.cardType = cardType;
this.cardNum = cardNum;
this.expDate = expDate;
this.invoiceNum = invoiceNum;
this.transType = transType;
+ this.currencyCode = currencyCode;
this.amount = amount;
this.transDate = transDate;
this.transTime = transTime;
@@ -53,6 +56,10 @@ public class CardSettleData {
this.transType = transType;
}
+ public void setCurrencyCode(String currencyCode) {
+ this.currencyCode = currencyCode;
+ }
+
public void setAmount(long amount) {
this.amount = amount;
}
@@ -85,6 +92,10 @@ public class CardSettleData {
return transType;
}
+ public String getCurrencyCode() {
+ return currencyCode;
+ }
+
public long getAmount() {
return amount;
}
@@ -114,6 +125,7 @@ public class CardSettleData {
cardSettleData.setExpDate(pay.getEXPDate());
cardSettleData.setInvoiceNum(pay.getInvoiceNo());
cardSettleData.setTransType(pay.getTransType());
+ cardSettleData.setCurrencyCode(pay.getCurrencyCode());
cardSettleData.setAmount(pay.getAmount());
cardSettleData.setTransDate(pay.getTransDate());
cardSettleData.setTransTime(pay.getTransTime());
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/model/QRSettleData.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/model/QRSettleData.java
index e080e78..67d11c1 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/model/QRSettleData.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/model/QRSettleData.java
@@ -1,9 +1,10 @@
package com.utsmyanmar.paylibs.model;
+import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-public class QRSettleData {
+public class QRSettleData implements Serializable {
private String transId;
private String date;
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/model/SettleData.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/model/SettleData.java
index 900f336..e0e6b14 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/model/SettleData.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/model/SettleData.java
@@ -1,6 +1,8 @@
package com.utsmyanmar.paylibs.model;
-public class SettleData {
+import java.io.Serializable;
+
+public class SettleData implements Serializable {
private int saleCount;
private long saleAmount;
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/model/enums/TransCVM.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/model/enums/TransCVM.java
index d3546a4..2dc403e 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/model/enums/TransCVM.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/model/enums/TransCVM.java
@@ -1,6 +1,8 @@
package com.utsmyanmar.paylibs.model.enums;
-public enum TransCVM {
+import java.io.Serializable;
+
+public enum TransCVM implements Serializable {
OFFLINE_PIN("Offline PIN"),
ONLINE_PIN("Online PIN"),
SIGNATURE("Signature"),
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 8d66a7e..e3e43f4 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
@@ -45,6 +45,7 @@ import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
@@ -122,7 +123,7 @@ public abstract class BaseXPrint {
returnText[1] = 0x33;
returnText[2] = (byte) height;
Resources resources = PayLibNex.getInstance().context.getResources();
- printer.setTypeface(Typeface.createFromAsset(PayLibNex.getInstance().context.getAssets(), "fonts/fira_code_medium.ttf"));
+ printer.setTypeface(Typeface.createFromAsset(PayLibNex.getInstance().context.getAssets(), "fonts/firaCode_bold.ttf"));
printer.setGray(getGrayLevel());
}
@@ -212,26 +213,38 @@ public abstract class BaseXPrint {
}
protected void printTransDetailSettlement(PayDetail payDetail) {
-
-
SettleData settleData = payDetail.getSettleDataObj();
- int totalCount = settleData.getSaleCount() + settleData.getPreAuthCompCount() + settleData.getRefundCount() + settleData.getCashAdvanceCount();
- long totalAmount = settleData.getSaleAmount() + settleData.getPreAuthCompAmount() + settleData.getCashAdvanceAmount();
+ List cardSettleDataList = payDetail.getCardSettleData();
+ CurrencySettlementSummary mmkSummary = new CurrencySettlementSummary();
+ CurrencySettlementSummary usdSummary = new CurrencySettlementSummary();
- print3ColumnsString("TRX TYPE ", "CNT", "AMOUNT");
- print3ColumnsString("SALE ", countStringFormat(settleData.getSaleCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getSaleAmount()));
- print3ColumnsString("PREAUTH COMP ", countStringFormat(settleData.getPreAuthCompCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getPreAuthCompAmount()));
- if (settleData.getCashAdvanceCount() != 0)
- print3ColumnsString("CASH ADVANCE ", countStringFormat(settleData.getCashAdvanceCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getCashAdvanceAmount()));
- print3ColumnsString("REFUND ", countStringFormat(settleData.getRefundCount()), "- " + PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getRefundAmount()));
- print3ColumnsString("TOTAL(MMK) ", countStringFormat(totalCount), PrintUtils.getInstance().getSeparatorNumberFormat(totalAmount));
+ if (cardSettleDataList != null && !cardSettleDataList.isEmpty()) {
+ for (CardSettleData cardSettleData : cardSettleDataList) {
+ CurrencySettlementSummary summary = "USD".equals(normalizeSettlementCurrency(cardSettleData.getCurrencyCode())) ? usdSummary : mmkSummary;
+ applyCardSettlementSummary(summary, cardSettleData);
+ }
+ } else {
+ mmkSummary.saleCount = settleData.getSaleCount();
+ mmkSummary.saleAmount = settleData.getSaleAmount();
+ mmkSummary.preAuthCompCount = settleData.getPreAuthCompCount();
+ mmkSummary.preAuthCompAmount = settleData.getPreAuthCompAmount();
+ mmkSummary.refundCount = settleData.getRefundCount();
+ mmkSummary.refundAmount = settleData.getRefundAmount();
+ mmkSummary.cashAdvanceCount = settleData.getCashAdvanceCount();
+ mmkSummary.cashAdvanceAmount = settleData.getCashAdvanceAmount();
+ }
+
+ printSettlementCurrencySection("MMK", mmkSummary);
+ if (usdSummary.hasAnyValue()) {
+ emptyLine(1);
+ printSettlementCurrencySection("USD", usdSummary);
+ }
emptyLine(2);
-
-
}
protected void printTransDetailSettlement(PayDetail payDetail, List cardSettleDataList) {
+ boolean isDecimalEnabled = SystemParamsOperation.getInstance().getDecimalEnable();
lineBreak();
print2SideStringMargin("CARD TYPE ","CARD NUMBER");
@@ -243,7 +256,7 @@ public abstract class BaseXPrint {
for (CardSettleData cardSettleData:cardSettleDataList) {
print2SideStringMargin(cardSettleData.getCardType(),PrintUtils.getInstance().maskCardNumberPciDss(cardSettleData.getCardNum()));
print2SideStringMargin("XX/XX",cardSettleData.getInvoiceNum());
- print2SideStringMargin(cardSettleData.getTransType(),"MMK "+PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAmount(),true));
+ print2SideStringMargin(cardSettleData.getTransType(),"MMK "+PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAmount(), isDecimalEnabled));
print2SideStringMargin(cardSettleData.getApprovalCode(),cardSettleData.getTransDate() + " " + cardSettleData.getTransTime() );
emptyLine(1);
}
@@ -254,28 +267,95 @@ public abstract class BaseXPrint {
long totalAmount = settleData.getSaleAmount() + settleData.getPreAuthCompAmount() + settleData.getCashAdvanceAmount();
print3ColumnsString("TRX TYPE ", "CNT", "AMOUNT");
- print3ColumnsString("SALE ", countStringFormat(settleData.getSaleCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getSaleAmount()));
- print3ColumnsString("VOID SALE ", countStringFormat(settleData.getVoidSaleCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getVoidSaleAmount()));
- print3ColumnsString("PREAUTH COMP ", countStringFormat(settleData.getPreAuthCompCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getPreAuthCompAmount()));
+ print3ColumnsString("SALE ", countStringFormat(settleData.getSaleCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getSaleAmount(), isDecimalEnabled));
+ print3ColumnsString("VOID SALE ", countStringFormat(settleData.getVoidSaleCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getVoidSaleAmount(), isDecimalEnabled));
+ print3ColumnsString("PREAUTH COMP ", countStringFormat(settleData.getPreAuthCompCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getPreAuthCompAmount(), isDecimalEnabled));
if (settleData.getCashAdvanceCount() != 0)
- print3ColumnsString("CASH ADV ", countStringFormat(settleData.getCashAdvanceCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getCashAdvanceAmount()));
- print3ColumnsString("REFUND ", countStringFormat(settleData.getRefundCount()), "- " + PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getRefundAmount()));
+ print3ColumnsString("CASH ADV ", countStringFormat(settleData.getCashAdvanceCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getCashAdvanceAmount(), isDecimalEnabled));
+ print3ColumnsString("REFUND ", countStringFormat(settleData.getRefundCount()), "- " + PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getRefundAmount(), isDecimalEnabled));
emptyLine(1);
printer.appendPrnStr("GRAND TOTAL", fontLarge, AlignEnum.LEFT,true);
emptyLine(1);
// print3ColumnsString("TOTAL(MMK) ", countStringFormat(totalCount), PrintUtils.getInstance().getSeparatorNumberFormat(totalAmount));
print3ColumnsString("TRX TYPE ", "CNT", "AMOUNT");
- print3ColumnsString("SALE ", countStringFormat(settleData.getSaleCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getSaleAmount()));
- print3ColumnsString("VOID SALE ", countStringFormat(settleData.getVoidSaleCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getVoidSaleAmount()));
- print3ColumnsString("PREAUTH COMP ", countStringFormat(settleData.getPreAuthCompCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getPreAuthCompAmount()));
+ print3ColumnsString("SALE ", countStringFormat(settleData.getSaleCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getSaleAmount(), isDecimalEnabled));
+ print3ColumnsString("VOID SALE ", countStringFormat(settleData.getVoidSaleCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getVoidSaleAmount(), isDecimalEnabled));
+ print3ColumnsString("PREAUTH COMP ", countStringFormat(settleData.getPreAuthCompCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getPreAuthCompAmount(), isDecimalEnabled));
if (settleData.getCashAdvanceCount() != 0)
- print3ColumnsString("CASH ADV ", countStringFormat(settleData.getCashAdvanceCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getCashAdvanceAmount()));
- print3ColumnsString("REFUND ", countStringFormat(settleData.getRefundCount()), "- " + PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getRefundAmount()));
+ print3ColumnsString("CASH ADV ", countStringFormat(settleData.getCashAdvanceCount()), PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getCashAdvanceAmount(), isDecimalEnabled));
+ print3ColumnsString("REFUND ", countStringFormat(settleData.getRefundCount()), "- " + PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getRefundAmount(), isDecimalEnabled));
emptyLine(2);
}
+ private void printSettlementCurrencySection(String currencyLabel, CurrencySettlementSummary summary) {
+ if (!summary.hasAnyValue()) {
+ return;
+ }
+ boolean isDecimalEnabled = SystemParamsOperation.getInstance().getDecimalEnable();
+
+ int totalCount = summary.saleCount + summary.preAuthCompCount + summary.refundCount + summary.cashAdvanceCount;
+ long totalAmount = summary.saleAmount + summary.preAuthCompAmount + summary.cashAdvanceAmount - summary.refundAmount;
+
+ printString("CURRENCY : " + currencyLabel, true);
+ print3ColumnsString("TRX TYPE ", "CNT", "AMOUNT");
+ print3ColumnsString("SALE ", countStringFormat(summary.saleCount), PrintUtils.getInstance().getSeparatorNumberFormat(summary.saleAmount, isDecimalEnabled));
+ print3ColumnsString("PREAUTH COMP ", countStringFormat(summary.preAuthCompCount), PrintUtils.getInstance().getSeparatorNumberFormat(summary.preAuthCompAmount, isDecimalEnabled));
+ if (summary.cashAdvanceCount != 0) {
+ print3ColumnsString("CASH ADVANCE ", countStringFormat(summary.cashAdvanceCount), PrintUtils.getInstance().getSeparatorNumberFormat(summary.cashAdvanceAmount, isDecimalEnabled));
+ }
+ print3ColumnsString("REFUND ", countStringFormat(summary.refundCount), "- " + PrintUtils.getInstance().getSeparatorNumberFormat(summary.refundAmount, isDecimalEnabled));
+ print3ColumnsString("TOTAL(" + currencyLabel + ") ", countStringFormat(totalCount), PrintUtils.getInstance().getSeparatorNumberFormat(totalAmount, isDecimalEnabled));
+ }
+
+ private void applyCardSettlementSummary(CurrencySettlementSummary summary, CardSettleData cardSettleData) {
+ String transType = cardSettleData.getTransType() == null ? "" : cardSettleData.getTransType().trim().toUpperCase(Locale.getDefault());
+ long amount = cardSettleData.getAmount();
+
+ if ("SALE".equals(transType)) {
+ summary.saleCount++;
+ summary.saleAmount += amount;
+ } else if ("PREAUTH COMPLETION".equals(transType) || "PRE_AUTH_COMPLETE".equals(transType)) {
+ summary.preAuthCompCount++;
+ summary.preAuthCompAmount += amount;
+ } else if ("REFUND".equals(transType)) {
+ summary.refundCount++;
+ summary.refundAmount += amount;
+ } else if ("CASH_OUT".equals(transType) || "CASH_ADVANCE".equals(transType)) {
+ summary.cashAdvanceCount++;
+ summary.cashAdvanceAmount += amount;
+ }
+ }
+
+ private String normalizeSettlementCurrency(String currencyCode) {
+ if (currencyCode == null) {
+ return "MMK";
+ }
+
+ String value = currencyCode.trim().toUpperCase(Locale.getDefault());
+ if ("840".equals(value) || "USD".equals(value)) {
+ return "USD";
+ }
+ return "MMK";
+ }
+
+ private static class CurrencySettlementSummary {
+ int saleCount;
+ long saleAmount;
+ int preAuthCompCount;
+ long preAuthCompAmount;
+ int refundCount;
+ long refundAmount;
+ int cashAdvanceCount;
+ long cashAdvanceAmount;
+
+ boolean hasAnyValue() {
+ return saleCount > 0 || preAuthCompCount > 0 || refundCount > 0 || cashAdvanceCount > 0
+ || saleAmount > 0 || preAuthCompAmount > 0 || refundAmount > 0 || cashAdvanceAmount > 0;
+ }
+ }
+
private String currencyCodeToText(String currencyCode) {
String currencyText = "MMK";
@@ -324,7 +404,7 @@ public abstract class BaseXPrint {
print2ColumnsStringNoSpace("ENTRY MODE :", PrintUtils.getInstance().getEntryType(payDetail.getCardType()));
print2ColumnsStringNoSpace("EXP DATE :",PrintUtils.getInstance().getFormatExpDate(payDetail.getEXPDate()));
print2ColumnsStringNoSpace("CARD TYPE :", payDetail.getAccountType());
- print2ColumnsStringNoSpace("TRACE NUM :", payDetail.getVoucherNo());
+ print2ColumnsStringNoSpace("TRACE NUM :", payDetail.getInvoiceNo());
if (payDetail.getCardType() != BaseCardType.MAGNETIC.getValue()) {
print2ColumnsStringNoSpace("CARD HOLDER:", firsLineName);
@@ -350,10 +430,11 @@ public abstract class BaseXPrint {
+ boolean isDecimalEnabled = SystemParamsOperation.getInstance().getDecimalEnable();
if (payDetail.getTradeAnswerCode().equals("00") || payDetail.getTradeAnswerCode().equals("000")) {
if (payDetail.getTransactionType() == TransactionType.CASH_ADVANCE) {
- print2ColumnsStringNoSpace("TXN AMOUNT", ":" + PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAmount()));
- print2ColumnsStringNoSpace("TXN FEES", ":" + PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAdditionalAmount()));
+ print2ColumnsStringNoSpace("TXN AMOUNT", ":" + PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAmount(), isDecimalEnabled));
+ print2ColumnsStringNoSpace("TXN FEES", ":" + PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAdditionalAmount(), isDecimalEnabled));
}
}
dotBreak();
@@ -364,12 +445,12 @@ public abstract class BaseXPrint {
printer.appendPrnStr("MMK " + PrintUtils.getInstance().getBalanceInquiryNumberFormat(payDetail.getAmount()), fontNormal, AlignEnum.LEFT,false);
} else if (payDetail.getTransactionType() == TransactionType.VOID || payDetail.getTransactionType() == TransactionType.REFUND || payDetail.getTransactionType() == TransactionType.PRE_SALE_CANCEL || payDetail.getTransactionType() == TransactionType.PRE_SALE_COMPLETE_VOID) {
- print2SideString("AMT:" + currencySign, "- " + PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAmount()));
+ print2SideString("AMT:" + currencySign, "- " + PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAmount(), isDecimalEnabled));
} else if (payDetail.getTransactionType() == TransactionType.CASH_ADVANCE) {
long totalAmount = payDetail.getAmount() + payDetail.getAdditionalAmount();
- print2SideString("AMT:" + currencySign, PrintUtils.getInstance().getSeparatorNumberFormat(totalAmount));
+ print2SideString("AMT:" + currencySign, PrintUtils.getInstance().getSeparatorNumberFormat(totalAmount, isDecimalEnabled));
} else {
- print2SideString("AMT:" + currencySign, PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAmount()));
+ print2SideString("AMT:" + currencySign, PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAmount(), isDecimalEnabled));
}
dotBreak();
} else {
@@ -446,15 +527,14 @@ public abstract class BaseXPrint {
printer.appendPrnStr("BTH NO:" + batchNum, fontNormal, AlignEnum.LEFT,false);
} else {
// printer.printColumnsString(new String[]{"BATCH NO :" + batchNum, "INV NO: " + invoiceNo}, new int[]{2, 2}, new int[]{0, 2}, null);
- printer.appendPrnStr("BTH NO:" + batchNum + " TRACE NO:" + traceNo, fontNormal, AlignEnum.LEFT,false);
+ printer.appendPrnStr("BTH NO:" + batchNum + " INV NO:" + traceNo, fontNormal, AlignEnum.LEFT,false);
}
-
- printer.appendPrnStr("\n", fontNormal, AlignEnum.LEFT,false);
+// printer.appendPrnStr("\n", fontNormal, AlignEnum.LEFT,false);
printer.appendPrnStr("\n", fontNormal, AlignEnum.LEFT,false);
printer.appendPrnStr(transType.replace("_", " "), fontNormal, AlignEnum.CENTER,true);
- printer.appendPrnStr("\n", fontNormal, AlignEnum.LEFT,false);
- printer.appendPrnStr("\n", fontNormal, AlignEnum.LEFT,false);
+// printer.appendPrnStr("\n", fontNormal, AlignEnum.LEFT,false);
+// printer.appendPrnStr("\n", fontNormal, AlignEnum.LEFT,false);
}
@@ -496,7 +576,7 @@ public abstract class BaseXPrint {
print2ColumnsStringNoSpace("ENTRY MODE:", PrintUtils.getInstance().getEntryType(payDetail.getCardType()));
print2ColumnsStringNoSpace("EXP DATE :",PrintUtils.getInstance().getFormatExpDate(payDetail.getEXPDate()));
print2ColumnsStringNoSpace("CARD TYPE :", payDetail.getAccountType());
- print2ColumnsStringNoSpace("TRACE NUM :", payDetail.getVoucherNo());
+ print2ColumnsStringNoSpace("TRACE NUM :", payDetail.getInvoiceNo());
if (payDetail.getCardType() != BaseCardType.MAGNETIC.getValue()) {
print2ColumnsStringNoSpace("CARD HOLDER:", firsLineName);
@@ -516,26 +596,27 @@ public abstract class BaseXPrint {
print2ColumnsStringNoSpace("AID :", payDetail.getAID());
- lineBreak();
+ dotBreak();
// check is pin change
if (payDetail.getTradeAnswerCode().equals("00") || payDetail.getTradeAnswerCode().equals("000")) {
+ boolean isDecimalEnabled = SystemParamsOperation.getInstance().getDecimalEnable();
String currencySign = currencyCodeToText(payDetail.getCurrencyCode());
// CurrencyType currencySign = currencyTextToCurrencyType(payDetail.getCurrencyCode());
if (payDetail.getTransactionType() == TransactionType.BALANCE_INQUIRY) {
printer.appendPrnStr("MMK " + PrintUtils.getInstance().getBalanceInquiryNumberFormat(payDetail.getAmount()), fontNormal, AlignEnum.LEFT,true);
} else {
- print2SideString("AMOUNT:" + currencySign, PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAmount()));
+ print2SideString("AMT:" + currencySign, PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAmount(), isDecimalEnabled));
// printer.appendPrnStr("AMOUNT:" + currencySign + " " + PrintUtils.getInstance().getSeparatorNumberFormat(payDetail.getAmount()), fontNormal, AlignEnum.LEFT,true);
}
- lineBreak();
+ dotBreak();
} else {
// lineBreak();
emptyLine(1);
printer.appendPrnStr(BaseErrorCode.getCode(payDetail.getTradeAnswerCode()), fontNormal, AlignEnum.CENTER,true);
emptyLine(1);
- lineBreak();
+ dotBreak();
}
emptyLine(1);
@@ -545,11 +626,12 @@ public abstract class BaseXPrint {
private void printColumnString(String label, int count, long amount, boolean isNegative) {
if (count > 0) {
- String amountString = PrintUtils.getInstance().getSeparatorNumberFormat(amount);
+ boolean isDecimalEnabled = SystemParamsOperation.getInstance().getDecimalEnable();
+ String amountString = PrintUtils.getInstance().getSeparatorNumberFormat(amount, isDecimalEnabled);
if (isNegative) {
amountString = "-" + amountString;
}
- printer.appendPrnStr(label + countStringFormat(count) + MMK + " " + PrintUtils.getInstance().getSeparatorNumberFormat(amount), fontNormal, AlignEnum.LEFT,false);
+ printer.appendPrnStr(label + countStringFormat(count) + MMK + " " + amountString, fontNormal, AlignEnum.LEFT,false);
}
}
@@ -683,6 +765,296 @@ public abstract class BaseXPrint {
}
+ class TempSummary {
+ int saleCount, voidSaleCount, refundCount, cashOutCount;
+ int preAuthSaleCount, preAuthVoidCount;
+ int qrPayCount, qrRefundCount;
+ int preAuthCompCount, preAuthCompVoidCount;
+
+ long saleAmount, voidSaleAmount, refundAmount, cashOutAmount;
+ long preAuthSaleAmount, preAuthVoidAmount;
+ long qrPayAmount, qrRefundAmount;
+ long preAuthCompAmount, preAuthCompVoidAmount;
+ }
+
+ private void applyTempSummary(TempSummary summary, PayDetail item) {
+ int transactionType = item.getTransactionType();
+ long amount = item.getAmount();
+
+ if (transactionType == TransactionsType.SALE.value) {
+ summary.saleCount++;
+ summary.saleAmount += amount;
+ return;
+ }
+
+ if (transactionType == TransactionsType.VOID.value) {
+ summary.voidSaleCount++;
+ summary.voidSaleAmount += amount;
+ return;
+ }
+
+ if (transactionType == TransactionsType.REFUND.value) {
+ summary.refundCount++;
+ summary.refundAmount += amount;
+ return;
+ }
+
+ if (transactionType == TransactionsType.CASH_OUT.value) {
+ summary.cashOutCount++;
+ summary.cashOutAmount += amount;
+ return;
+ }
+
+ if (transactionType == TransactionsType.PRE_AUTH_SALE.value) {
+ summary.preAuthSaleCount++;
+ summary.preAuthSaleAmount += amount;
+ return;
+ }
+
+ if (transactionType == TransactionsType.PRE_AUTH_VOID.value) {
+ summary.preAuthVoidCount++;
+ summary.preAuthVoidAmount += amount;
+ return;
+ }
+
+ if (transactionType == TransactionsType.MMQR.value) {
+ summary.qrPayCount++;
+ summary.qrPayAmount += amount;
+ return;
+ }
+
+ if (transactionType == TransactionsType.MMQR_REFUND.value) {
+ summary.qrRefundCount++;
+ summary.qrRefundAmount += amount;
+ return;
+ }
+
+ if (transactionType == TransactionsType.PRE_AUTH_COMPLETE.value) {
+ summary.preAuthCompCount++;
+ summary.preAuthCompAmount += amount;
+ return;
+ }
+
+ if (transactionType == TransactionsType.PRE_AUTH_COMPLETE_VOID.value) {
+ summary.preAuthCompVoidCount++;
+ summary.preAuthCompVoidAmount += amount;
+ return;
+ }
+
+ String transType = item.getTransType() == null ? "" : item.getTransType().trim().toUpperCase(Locale.getDefault());
+
+ switch (transType) {
+ case "SALE":
+ summary.saleCount++;
+ summary.saleAmount += amount;
+ break;
+
+ case "VOID SALE":
+ case "VOID_SALE":
+ summary.voidSaleCount++;
+ summary.voidSaleAmount += amount;
+ break;
+
+ case "REFUND":
+ summary.refundCount++;
+ summary.refundAmount += amount;
+ break;
+
+ case "PRE-AUTH":
+ case "PRE_AUTH_SALE":
+ summary.preAuthSaleCount++;
+ summary.preAuthSaleAmount += amount;
+ break;
+
+ case "PREAUTH CANCELLATION":
+ case "PRE_AUTH_VOID":
+ summary.preAuthVoidCount++;
+ summary.preAuthVoidAmount += amount;
+ break;
+
+ case "CASH OUT":
+ case "CASH_OUT":
+ case "CASH_ADVANCE":
+ summary.cashOutCount++;
+ summary.cashOutAmount += amount;
+ break;
+
+ case "QR_PAY":
+ summary.qrPayCount++;
+ summary.qrPayAmount += amount;
+ break;
+
+ case "QR_REFUND":
+ summary.qrRefundCount++;
+ summary.qrRefundAmount += amount;
+ break;
+
+ case "PREAUTH COMPLETION":
+ case "PRE_AUTH_COMPLETE":
+ case "PREAUTH_COMP":
+ summary.preAuthCompCount++;
+ summary.preAuthCompAmount += amount;
+ break;
+
+ case "VOID PREAUTH COMPLETE":
+ case "PRE_AUTH_COMPLETE_VOID":
+ case "PREAUTH_COMP_VOID":
+ summary.preAuthCompVoidCount++;
+ summary.preAuthCompVoidAmount += amount;
+ break;
+ }
+ }
+
+ private boolean matchesSummaryHostType(PayDetail item, HostType hostType) {
+ if (hostType == null || item == null) {
+ return true;
+ }
+
+ int transactionType = item.getTransactionType();
+
+ if (hostType == HostType.QR) {
+ return transactionType == TransactionsType.MMQR.value
+ || transactionType == TransactionsType.MMQR_REFUND.value;
+ }
+
+ if (hostType == HostType.MPU || hostType == HostType.VISA_MASTER) {
+ return transactionType != TransactionsType.MMQR.value
+ && transactionType != TransactionsType.MMQR_REFUND.value;
+ }
+
+ return true;
+ }
+
+ protected void printTransDetailSummary(PayDetail payDetail, List list) {
+ printTransDetailSummary(payDetail, list, null);
+ }
+
+ protected void printTransDetailSummary(PayDetail payDetail, List list, HostType hostType) {
+
+ if (list == null || list.isEmpty()) {
+ printErrorBlock("NO TRANSACTION FOUND");
+ printer.appendPrnStr("\n", fontNormal, AlignEnum.LEFT,false);
+ return;
+ }
+
+ Map currencyMap = new HashMap<>();
+
+ for (PayDetail item : list) {
+
+ if (item == null) continue;
+ if (!matchesSummaryHostType(item, hostType)) continue;
+
+ String currency = item.getCurrencyCode();
+ TempSummary s = currencyMap.get(currency);
+
+ if (s == null) {
+ s = new TempSummary();
+ currencyMap.put(currency, s);
+ }
+
+ applyTempSummary(s, item);
+ }
+
+ if (currencyMap.isEmpty()) {
+ printErrorBlock("NO TRANSACTION FOUND");
+ printer.appendPrnStr("\n", fontNormal, AlignEnum.LEFT,false);
+ return;
+ }
+
+ boolean isQrDecimalEnabled = SystemParamsOperation.getInstance().isQrDecimalEnable();
+ boolean isDecimalEnabled = SystemParamsOperation.getInstance().getDecimalEnable();
+
+ for (String currency : currencyMap.keySet()) {
+
+ TempSummary data = currencyMap.get(currency);
+ boolean isQrHost = hostType == HostType.QR;
+
+ printer.appendPrnStr( currencyCodeToText(currency) + " " +"Transactions", fontNormal, AlignEnum.LEFT, false);
+ emptyLine(1);
+
+// printer.appendPrnStr("(COUNT)TRANS", "AMOUNT(" + currencyCodeToText(currency) + ")", fontNormal, false);
+ print3ColumnsStringWithAlign("COUNT", "TRANS", "AMOUNT" + "(" + currencyCodeToText(currency) + ")", fontNormal, false);
+
+ if (isQrHost) {
+ if (data.qrPayCount > 0) {
+ print3ColumnsStringWithAlign("(" + data.qrPayCount + ")",
+ "QR PAY",
+ PrintUtils.getInstance().getSeparatorNumberFormat(data.qrPayAmount, isQrDecimalEnabled),
+ fontNormal, false);
+ }
+
+ if (data.qrRefundCount > 0) {
+ print3ColumnsStringWithAlign("(" + data.qrRefundCount + ")",
+ "QR REFUND",
+ "- " + PrintUtils.getInstance().getSeparatorNumberFormat(data.qrRefundAmount, isQrDecimalEnabled),
+ fontNormal, false);
+ }
+ } else {
+ if (data.saleCount > 0) {
+ print3ColumnsStringWithAlign("(" + data.saleCount + ")",
+ "SALES",
+ PrintUtils.getInstance().getSeparatorNumberFormat(data.saleAmount, isDecimalEnabled),
+ fontNormal, false);
+ }
+
+ if (data.voidSaleCount > 0) {
+ print3ColumnsStringWithAlign("(" + data.voidSaleCount + ")",
+ "VOID",
+ "- " + PrintUtils.getInstance().getSeparatorNumberFormat(data.voidSaleAmount, isDecimalEnabled),
+ fontNormal, false);
+ }
+
+ if (data.cashOutCount > 0) {
+ print3ColumnsStringWithAlign("(" + data.cashOutCount + ")",
+ "CASH ADV",
+ PrintUtils.getInstance().getSeparatorNumberFormat(data.cashOutAmount, isDecimalEnabled),
+ fontNormal, false);
+ }
+
+ if (data.preAuthSaleCount > 0) {
+ print3ColumnsStringWithAlign("(" + data.preAuthSaleCount + ")",
+ "PRE-AUTH",
+ PrintUtils.getInstance().getSeparatorNumberFormat(data.preAuthSaleAmount, isDecimalEnabled),
+ fontNormal, false);
+ }
+
+ if (data.preAuthVoidCount > 0) {
+ print3ColumnsStringWithAlign("(" + data.preAuthVoidCount + ")",
+ "PREAUTH VOID",
+ "- " + PrintUtils.getInstance().getSeparatorNumberFormat(data.preAuthVoidAmount, isDecimalEnabled),
+ fontNormal, false);
+ }
+
+ if (data.refundCount > 0) {
+ print3ColumnsStringWithAlign("(" + data.refundCount + ")",
+ "REFUND",
+ "- " + PrintUtils.getInstance().getSeparatorNumberFormat(data.refundAmount, isDecimalEnabled),
+ fontNormal, false);
+ }
+
+ if (data.preAuthCompCount > 0) {
+ print3ColumnsStringWithAlign("(" + data.preAuthCompCount + ")",
+ "PREAUTH COMP",
+ PrintUtils.getInstance().getSeparatorNumberFormat(data.preAuthCompAmount, isDecimalEnabled),
+ fontNormal, false);
+ }
+ }
+
+ dotBreak();
+
+ long totalAmount = isQrHost
+ ? data.qrPayAmount - data.qrRefundAmount
+ : (data.saleAmount + data.cashOutAmount + data.preAuthSaleAmount + data.preAuthCompAmount)
+ - (data.voidSaleAmount + data.preAuthVoidAmount + data.refundAmount + data.preAuthCompVoidAmount);
+
+ printer.appendPrnStr( "TOTAL"+ " " + currencyCodeToText(currency),
+ PrintUtils.getInstance().getSeparatorNumberFormat(totalAmount, isQrHost ? isQrDecimalEnabled : isDecimalEnabled),
+ fontNormal, false);
+
+ emptyLine(2);
+ }
+ }
+
/* private void backup(){
SettleData settleData = payDetail.getSettleDataObj();
@@ -775,48 +1147,60 @@ public abstract class BaseXPrint {
// printer.appendPrnStr(first + " " + second + " " + third, fontNormal, AlignEnum.LEFT,false);
printer.appendPrnStr(first + " " + second + " " + third, fontNormal, AlignEnum.LEFT,isBold);
}
-
- protected void dotBreak(){
- printer.appendPrnStr(new String(new char[29]).replace("\0", "."), fontNormal, AlignEnum.LEFT, false);
+
+ protected void print3ColumnsStringWithAlign(String first, String second, String third, int font, boolean isBold){
+ String fixedSizeString = String.format("%-5s", first);
+ printer.appendPrnStr(fixedSizeString + " " + second, third, font, isBold);
}
+ protected void dotBreak(){
+ printer.appendPrnStr(new String(new char[29]).replace("\0", "."), fontNormal, AlignEnum.CENTER, false);
+ }
+
+ class CurrencySummary {
+ long total = 0;
+ int count = 0;
+ }
protected void printTransDetailReport(List lists, HostType hostType) {
-
- if (hostType == HostType.MPU || hostType == HostType.VISA_MASTER) {
- // Use the same line-by-line style as QR detail report
- } else if (hostType == HostType.QR) {
-// print2ColumnsString("PAYMENT NAME", "");
-// print2ColumnsString("DATE", "TIME");
-// print2ColumnsString("TRANSACTION", "TRACE NO");
-// print2ColumnsString("TRXN ID", "");
-// print2ColumnsString("AMOUNT", "");
+ // ✅ Summary holder (total + count per currency)
+ class CurrencySummary {
+ long total = 0;
+ int count = 0;
}
-
-// breakingLine();
-
- long totalAmount = 0;
+ Map currencyMap = new HashMap<>();
for (PayDetail pay : lists) {
- boolean isNeedMinusSign = pay.getTransactionType() == TransactionsType.VOID.value || pay.getTransactionType() == TransactionsType.REFUND.value || pay.getTransactionType() == TransactionsType.MMQR_REFUND.value;
- boolean isDecimalEnabled = SystemParamsOperation.getInstance().isQrDecimalEnable();
+ boolean isNeedMinusSign =
+ pay.getTransactionType() == TransactionsType.VOID.value ||
+ pay.getTransactionType() == TransactionsType.REFUND.value ||
+ pay.getTransactionType() == TransactionsType.MMQR_REFUND.value;
+
+ boolean isDecimalEnabledQr = SystemParamsOperation.getInstance().isQrDecimalEnable();
+ String currency = currencyCodeToText(pay.getCurrencyCode());
+
+ // =============================
+ // PRINT DETAIL
+ // =============================
if (hostType == HostType.MPU || hostType == HostType.VISA_MASTER) {
+
boolean isDecimalEnabledCard = SystemParamsOperation.getInstance().getDecimalEnable();
+
printString("CARD TYPE:" + pay.getAccountType());
printString("CARD NO :" + PrintUtils.getInstance().maskCardNumberPciDss(pay.getCardNo()));
- printString("TRACE NO :" + pay.getVoucherNo());
+ printString("INV NO :" + pay.getVoucherNo());
printString("RRN :" + pay.getReferNo());
- printString("DATE :" + POSUtil.getInstance().formatDisplayDate(pay.getTransDate()) + " " + pay.getTransTime());
+ printString("DATE :" + POSUtil.getInstance().formatDisplayDate(pay.getTransDate()));
+ printString(" " + pay.getTransTime());
printString("TYPE :" + pay.getTransType().replace("_", " "));
printString("AMOUNT :" +
- (isNeedMinusSign
- ? "-" + PrintUtils.getInstance()
- .getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabledCard)
- : PrintUtils.getInstance()
- .getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabledCard))
- + " " + "MMK");
+ (isNeedMinusSign
+ ? "-" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabledCard)
+ : PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabledCard))
+ + " " + currency);
+
dotBreak();
} else if (hostType == HostType.QR) {
@@ -824,64 +1208,91 @@ public abstract class BaseXPrint {
printString("TRANS ID:" + pay.getQrTransId());
printString("STATUS :" + pay.getTC());
printString("SOURCE :" +
- (pay.getTransactionType() == TransactionsType.MMQR_REFUND.value
- ? "QR PAYMENT"
- : pay.getCustomerMobile())
- );
-// printString("TXN NAME:" + pay.getTransType().replace("_", " "));
- printString("DATE :" + POSUtil.getInstance().formatDisplayDate(pay.getTransDate()) + " " + pay.getTransTime());
- printString("TRACE NO:" + pay.getVoucherNo());
+ (pay.getTransactionType() == TransactionsType.MMQR_REFUND.value
+ ? "QR PAYMENT"
+ : pay.getCustomerMobile()));
+ printString("DATE :" + POSUtil.getInstance().formatDisplayDate(pay.getTransDate()));
+ printString(" " + pay.getTransTime());
+ printString("INV NO :" + pay.getVoucherNo());
+
if (pay.getTransactionType() == TransactionsType.MMQR_REFUND.value) {
printString("RRN :" + pay.getReferNo());
}
+
printString("AMOUNT :" +
- (isNeedMinusSign
- ? "-" + PrintUtils.getInstance()
- .getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled)
- : PrintUtils.getInstance()
- .getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled))
- + " " +"MMK");
+ (isNeedMinusSign
+ ? "-" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabledQr)
+ : PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabledQr))
+ + " " + currency);
+
dotBreak();
-
-// if (pay.getTransactionType() == TransactionsType.MMQR_REFUND.value) {
-// print2ColumnsString("QR PAYMENT", "");
-// } else {
-// print2ColumnsString(pay.getCustomerMobile(), "");
-// }
-// print2ColumnsString(pay.getTransDate(), pay.getTransTime());
-// print2ColumnsString(pay.getTransType().replace("_", " "), pay.getVoucherNo());
-// if (pay.getTransactionType() == TransactionsType.MMQR_REFUND.value) {
-// print2ColumnsString(pay.getReferNo() + "(RRN)", "");
-// print2ColumnsString(isNeedMinusSign ? "-" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled) : "" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled), "");
-// } else {
-// print2ColumnsString(pay.getQrTransId(), "");
-// print2ColumnsString(isNeedMinusSign ? "-" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled) : "" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled) , "");
-// }
-
}
emptyLine(1);
+ // =============================
+ // ✅ ACCUMULATE TOTAL + COUNT PER CURRENCY
+ // =============================
+ CurrencySummary summary = currencyMap.getOrDefault(currency, new CurrencySummary());
+
if (isNeedMinusSign) {
- totalAmount -= pay.getAmount();
+ summary.total -= pay.getAmount();
} else {
- totalAmount += pay.getAmount();
+ summary.total += pay.getAmount();
}
+
+ summary.count++; // ✅ count per currency
+
+ currencyMap.put(currency, summary);
}
+ // =============================
+ // PRINT SUMMARY
+ // =============================
if (hostType == HostType.MPU || hostType == HostType.VISA_MASTER) {
+
boolean isDecimalEnabled = SystemParamsOperation.getInstance().getDecimalEnable();
+
print2ColumnsString("CARD", "");
- print3ColumnsString("TYPE ", "COUNT", "AMOUNT");
- print3ColumnsString("CARD", " " + countStringFormat(lists.size()), "MMK " + PrintUtils.getInstance().getSeparatorNumberFormat(totalAmount, isDecimalEnabled), true);
+ print3ColumnsStringWithAlign("TYPE ", "COUNT", "AMOUNT", fontNormal, true);
+
+ for (Map.Entry entry : currencyMap.entrySet()) {
+
+ String currency = entry.getKey();
+ CurrencySummary summary = entry.getValue();
+
+ print3ColumnsStringWithAlign(
+ "CARD",
+ " " + countStringFormat(summary.count),
+ currency + " " + PrintUtils.getInstance()
+ .getSeparatorNumberFormat(summary.total, isDecimalEnabled),
+ fontNormal,
+ false
+ );
+ }
+
} else if (hostType == HostType.QR) {
+
boolean isDecimalEnabled = SystemParamsOperation.getInstance().isQrDecimalEnable();
+
print2ColumnsString("PAYMENT", "");
- print3ColumnsString("TYPE ", "COUNT", "AMOUNT");
-// emptyLine(1);
- print3ColumnsString("QR PAY", " "+ countStringFormat(lists.size()), "MMK " + PrintUtils.getInstance().getSeparatorNumberFormat(totalAmount, isDecimalEnabled), true);
+ print3ColumnsStringWithAlign("TYPE ", "COUNT", "AMOUNT", fontNormal, true);
+
+ for (Map.Entry entry : currencyMap.entrySet()) {
+
+ String currency = entry.getKey();
+ CurrencySummary summary = entry.getValue();
+
+ print3ColumnsStringWithAlign(
+ "QR PAY",
+ " " + countStringFormat(summary.count),
+ currency + " " + PrintUtils.getInstance()
+ .getSeparatorNumberFormat(summary.total, isDecimalEnabled),
+ fontNormal,
+ false
+ );
+ }
}
-// emptyLine(2);
}
protected void printQRSettlementTransDetail(List lists) {
@@ -1162,6 +1573,7 @@ public abstract class BaseXPrint {
String transType = payDetail.getTransType();
String batchNum = "";
String traceNum = payDetail.getVoucherNo();
+ boolean isDuelCurrency = SystemParamsOperation.getInstance().getDuelCurrencyStatus();
String currencySign = currencyCodeToText(payDetail.getCurrencyCode());
boolean isSettlement = payDetail.getTransactionType() == TransactionsType.SETTLEMENT.value;
@@ -1176,7 +1588,7 @@ public abstract class BaseXPrint {
if (payDetail.getTransactionType() == TransactionsType.MMQR.value && payDetail.getQrTransStatus() == 1) {
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:" + traceNum, fontNormal, AlignEnum.LEFT,false);
} else if (payDetail.getTransType().equals(SUMMARY)) {
printer.appendPrnStr("HOST :" + HOST_NAME_MPU + "", fontNormal, AlignEnum.LEFT,false);
}
@@ -1186,8 +1598,16 @@ public abstract class BaseXPrint {
if (payDetail.getTransactionType() == TransactionsType.MMQR.value || payDetail.getTransactionType() == TransactionsType.MMQR_REFUND.value){
printer.appendPrnStr("SHORT CODE :" + payDetail.getMerchantNo(), fontNormal, AlignEnum.LEFT,false);
}else{
- printer.appendPrnStr("MID :" + payDetail.getMerchantNo(), fontNormal, AlignEnum.LEFT,false);
- printer.appendPrnStr("TID :" + payDetail.getTerminalNo(), fontNormal, AlignEnum.LEFT,false);
+
+ if(isSettlement && isDuelCurrency){
+ printer.appendPrnStr("MID :" + safe(SystemParamsOperation.getInstance().getMerchantId()), fontNormal, AlignEnum.LEFT, false);
+ printer.appendPrnStr("TID :" + safe(SystemParamsOperation.getInstance().getTerminalId()), fontNormal, AlignEnum.LEFT, false);
+ printer.appendPrnStr("MID :" + safe(SystemParamsOperation.getInstance().getThirdHostMerchantId()), fontNormal, AlignEnum.LEFT, false);
+ printer.appendPrnStr("TID :" + safe(SystemParamsOperation.getInstance().getThirdHostTerminalId()), fontNormal, AlignEnum.LEFT, false);
+ }else{
+ printer.appendPrnStr("MID :" + payDetail.getMerchantNo(), fontNormal, AlignEnum.LEFT,false);
+ printer.appendPrnStr("TID :" + payDetail.getTerminalNo(), fontNormal, AlignEnum.LEFT,false);
+ }
}
if(isSettlement) {
@@ -1257,7 +1677,7 @@ public abstract class BaseXPrint {
// 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:" + traceNum, fontNormal, AlignEnum.LEFT,false);
} else if (payDetail.getTransType().equals(SUMMARY)) {
printer.appendPrnStr("HOST :" + HOST_NAME_MPU + "", fontNormal, AlignEnum.LEFT,false);
}
@@ -1316,18 +1736,19 @@ public abstract class BaseXPrint {
protected void printTerminalConfiguration() {
SystemParamsOperation sp = SystemParamsOperation.getInstance();
+
// ---------- PRIMARY HOST ----------
printer.appendPrnStr("PRIMARY HOST", fontNormal, AlignEnum.LEFT, true);
- printer.appendPrnStr("Name : " + sp.getHostName(), fontNormal, AlignEnum.LEFT, false);
- printer.appendPrnStr("TID : " + sp.getTerminalId(), fontNormal, AlignEnum.LEFT, false);
- printer.appendPrnStr("MID : " + sp.getMerchantId(), fontNormal, AlignEnum.LEFT, false);
+ printer.appendPrnStr("Name : " + safe(sp.getHostName()), fontNormal, AlignEnum.LEFT, false);
+ printer.appendPrnStr("TID : " + safe(sp.getTerminalId()), fontNormal, AlignEnum.LEFT, false);
+ printer.appendPrnStr("MID : " + safe(sp.getMerchantId()), fontNormal, AlignEnum.LEFT, false);
String[] ipPort = splitIpAndPort(sp.getIpAddress());
- printer.appendPrnStr("Primary Ip : " + ipPort[0], fontNormal, AlignEnum.LEFT, false);
+ printer.appendPrnStr("Primary IP : " + ipPort[0], fontNormal, AlignEnum.LEFT, false);
printer.appendPrnStr("Primary Port : " + ipPort[1], fontNormal, AlignEnum.LEFT, false);
String[] secIpPort = splitIpAndPort(sp.getSecIpAddress());
- printer.appendPrnStr("Secondary Ip : " + secIpPort[0], fontNormal, AlignEnum.LEFT, false);
+ printer.appendPrnStr("Secondary IP : " + secIpPort[0], fontNormal, AlignEnum.LEFT, false);
printer.appendPrnStr("Secondary Port: " + secIpPort[1], fontNormal, AlignEnum.LEFT, false);
- printer.appendPrnStr("Currency Code : " + sp.getCurrencyType(), fontNormal, AlignEnum.LEFT, false);
+ printer.appendPrnStr("Currency : " + normalizeHostCurrency(sp.getCurrencyType() == null ? "" : sp.getCurrencyType().toString()), fontNormal, AlignEnum.LEFT, false);
dotBreak();
// ---------- SECONDARY HOST (optional) ----------
if (!TextUtils.isEmpty(sp.getSecHostName())) {
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/PrintX.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/PrintX.java
index 97c8e5a..871de4e 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/PrintX.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/PrintX.java
@@ -20,6 +20,8 @@ public interface PrintX {
void printSmileSummaryReport(PayDetail payDetail, HostType hostType, PrintXStatus printXStatus);
+ void printSmileSummaryReport(PayDetail payDetail, List list, HostType hostType, PrintXStatus printXStatus);
+
void printSmileSettlementReport(PayDetail payDetail,PrintXStatus printXStatus);
void printQRSettlementReport(PayDetail payDetail, List list, PrintXStatus printXStatus);
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/PrintXImpl.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/PrintXImpl.java
index 44c43d0..4acbb91 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/PrintXImpl.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/PrintXImpl.java
@@ -222,6 +222,8 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
e.printStackTrace();
}
}
+
+
@Override
public void printDetailReport(PayDetail payDetail, List lists, HostType hostType,PrintXStatus printXStatus) {
@@ -431,7 +433,6 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
this.callbackStatus = printXStatus;
try {
// LogUtil.d(TAG, payDetail.getSettleDataObj().toString());
-
setHeight(0x12);
printLogo();
printMerchantHeader();
@@ -447,6 +448,21 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
}
}
+ @Override
+ public void printSmileSummaryReport(PayDetail payDetail, List list, HostType hostType, PrintXStatus printXStatus) {
+ this.callbackStatus = printXStatus;
+ try {
+ setHeight(0x12);
+ printLogo();
+ printMerchantHeader();
+ printTranHeader("SUMMARY REPORT");
+ printTransDetailSummary(payDetail, list, hostType);
+ startPrintNex();
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
@Override
public void printTerminalConfig(PrintXStatus printXStatus) {
this.callbackStatus = printXStatus;
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/PrintXReceipt.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/PrintXReceipt.java
index 8db6d73..4f13d7b 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/PrintXReceipt.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/PrintXReceipt.java
@@ -59,6 +59,9 @@ public class PrintXReceipt {
public void printSmileSummaryReport(PayDetail payDetail, HostType hostType, PrintXStatus printXStatus) {
printX.printSmileSummaryReport(payDetail, hostType, printXStatus);
}
+ public void printSmileSummaryReport(PayDetail payDetail,List list, HostType hostType, PrintXStatus printXStatus) {
+ printX.printSmileSummaryReport(payDetail, list, hostType, printXStatus);
+ }
public void printTerminalHostConfig(PrintXStatus printXStatus){
printX.printTerminalConfig(printXStatus);
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/transactions/TransactionsOperation.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/transactions/TransactionsOperation.java
index 6ea2400..d5fc057 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/transactions/TransactionsOperation.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/transactions/TransactionsOperation.java
@@ -434,6 +434,7 @@ public class TransactionsOperation {
} else {
boolean equals = TextUtils.equals(resultStr, Constant.ANSWER_CODE_ACCEPT) || TextUtils.equals(resultStr, Constant.ANSWER_CODE_APPROVED);
EmvOnlineResultEntity emvOnlineResult = new EmvOnlineResultEntity();
+ emvOnlineResult.setRejCode("00");
// MsgField field38,field39,field55;
// if (resp != null) {
// field38 = resp.get("F038");
@@ -455,7 +456,10 @@ public class TransactionsOperation {
// }
//
// }
+
if(equals) {
+ emvOnlineResult.setRejCode("00");
+ emvOnlineResult.setRecvField55(null);
importOnlineProcessStatus(SdkResult.Success,emvOnlineResult);
} else {
importOnlineProcessStatus(SdkResult.Fail,emvOnlineResult);
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/AuthorizationProcessUtil.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/AuthorizationProcessUtil.java
index b2de037..fce4236 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/AuthorizationProcessUtil.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/AuthorizationProcessUtil.java
@@ -52,7 +52,11 @@ public class AuthorizationProcessUtil {
if(field39 != null && field39.getDataStr() != null ) {
LogUtil.d(TAG,"Field 39:"+field39.getDataStr());
- emvOnlineResult.setRejCode(field39.getDataStr());
+ if(field39.getDataStr().equals("000")){
+ emvOnlineResult.setRejCode("00");
+ }else{
+ emvOnlineResult.setRejCode(field39.getDataStr());
+ }
}
if(field55 != null && field55.getDataStr() != null) {
@@ -154,7 +158,6 @@ public class AuthorizationProcessUtil {
hexValues[i] = value;
}
int status;
- String f055Data = getF055Data();
LogUtil.d(TAG,"is equal:"+equals);
LogUtil.d(TAG,"Emv Online Result:"+emvOnlineResult);
if (equals) {
@@ -177,7 +180,7 @@ public class AuthorizationProcessUtil {
LogUtil.e(Constant.TAG, "scriptResult: " + scriptResult);
payDetail.setScriptResult(scriptResult);
-
+ String f055Data = getF055Data();
LogUtil.e(Constant.TAG, "f055Data: " + f055Data);
// if (status >= 0) {
@@ -205,6 +208,9 @@ public class AuthorizationProcessUtil {
private void importOnlineProcessStatus(int sdkResult,EmvOnlineResultEntity emvOnlineResult) {
LogUtil.d(TAG, "importOnlineProcessStatus sdkResult:"+sdkResult);
LogUtil.d(TAG, "importOnlineProcessStatus emvOnlineResult:"+emvOnlineResult.toString());
+ LogUtil.d(TAG, "importOnlineProcessStatus emvOnlineResult:"+emvOnlineResult.getAuthCode());
+ LogUtil.d(TAG, "importOnlineProcessStatus emvOnlineResult:"+emvOnlineResult.getRejCode());
+ LogUtil.d(TAG, "importOnlineProcessStatus emvOnlineResult:"+ ByteUtil.bytes2HexStr(emvOnlineResult.getRecvField55()));
PayLibNex.getInstance().deviceEngine.getEmvHandler2("app2").onSetOnlineProcResponse(sdkResult, emvOnlineResult);
}
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/core_utils/KernelDataProcessUtil.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/core_utils/KernelDataProcessUtil.java
index 150af89..2452bc2 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/core_utils/KernelDataProcessUtil.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/core_utils/KernelDataProcessUtil.java
@@ -2,7 +2,10 @@ package com.utsmyanmar.paylibs.utils.core_utils;
import android.text.TextUtils;
+import com.nexgo.oaf.apiv3.emv.EmvDataSourceEnum;
+import com.nexgo.oaf.apiv3.emv.EmvHandler2;
import com.utsmyanmar.paylibs.Constant;
+import com.utsmyanmar.paylibs.PayLibNex;
import com.utsmyanmar.paylibs.model.BaseCardInfo;
import com.utsmyanmar.paylibs.model.CardInfo;
import com.utsmyanmar.paylibs.model.ICCardInfo;
@@ -670,43 +673,42 @@ public class KernelDataProcessUtil {
}
LogUtil.d(TAG,"9F6E data :"+hexStr);
-// byte[] dataOut = new byte[1024];
-//
-// try {
-// int len = PayLibsUtils.getInstance().emvOptV2.getTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_PAYWAVE, tagList, dataOut);
-// if (len > 0) {
-// byte[] dataOutBytes = Arrays.copyOf(dataOut, len);
-// hexStr = ByteUtil.bytes2HexStr(dataOutBytes);
-// LogUtil.d(TAG, "get 9F6E Data :" + hexStr);
-// Map map = TLVUtil.buildTLVMap(hexStr);
-// LogUtil.d(TAG, "get 9F6E Data :" + map);
-//
-// } else {
-// LogUtil.e(TAG, "Get the data length of payWave is negative = " + len);
-// }
-// } catch (Exception e) {
-// e.printStackTrace();
-// }
-//
+ byte[] dataOut = new byte[1024];
+ EmvHandler2 emvHandler = PayLibNex.getInstance().deviceEngine.getEmvHandler2("app2");
+ try {
+
+ byte[] dateValue = emvHandler.getTlv(ByteUtil.hexStr2Bytes("9F6E"), EmvDataSourceEnum.FROM_CARD);
+ if (dateValue != null) {
+
+ hexStr = ByteUtil.bytes2HexStr(dateValue);
+ LogUtil.d(TAG, "get 9F6E Data :" + hexStr);
+
+
+ } else {
+ LogUtil.e(TAG, "Get the data length of payWave is null = " );
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
// if (hexStr.equals("9F6E00")) {
// try {
-// int len = PayLibsUtils.getInstance().emvOptV2.getTlvList(AidlConstantsV2.EMV.TLVOpCode.OP_PAYPASS, tagList, dataOut);
-// if (len > 0) {
-// byte[] dataOutBytes = Arrays.copyOf(dataOut, len);
-// hexStr = ByteUtil.bytes2HexStr(dataOutBytes);
+// byte[] dateValue = emvHandler.getTlv(ByteUtil.hexStr2Bytes("9F6E"), EmvDataSourceEnum.FROM_CARD);
+// if (dateValue != null) {
+// hexStr = ByteUtil.bytes2HexStr(dateValue);
// LogUtil.d(TAG, "get 9F6E Data :" + hexStr);
// Map map = TLVUtil.buildTLVMap(hexStr);
// LogUtil.d(TAG, "get 9F6E Data :" + map);
//
// } else {
-// LogUtil.e(TAG, "Get the data length of payPass is negative = " + len);
+// LogUtil.e(TAG, "Get the data length of payPass is null = ");
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
-// if (!hexStr.equals("9F6E00")) {
-// f55WaveDataStr += hexStr;
+// if (!hexStr.isEmpty()) {
+// f55WaveDataStr += "9F6E04"+hexStr;
// }
icCardInfo.setICC55(f55WaveDataStr);
payDetail.setICC55(f55WaveDataStr);
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/core_utils/SystemParamsOperation.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/core_utils/SystemParamsOperation.java
index 6112ccf..020a4dc 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/core_utils/SystemParamsOperation.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/core_utils/SystemParamsOperation.java
@@ -653,15 +653,56 @@ public class SystemParamsOperation {
return CurrencyType.valueOf(params.getCurrencyType());
}
- public void setTerminalCapability(String terminalCapability) {
+// public void setTerminalCapability(String terminalCapability) {
+// SystemParamsSettings params = getSystemParamsSettings();
+// params.setTerminalCapability(terminalCapability);
+// saveSystemParamsSettings(params);
+// }
+//
+// public String getTerminalCapability() {
+// SystemParamsSettings params = getSystemParamsSettings();
+// return params.getTerminalCapability();
+// }
+ public void setVisaTerminalCapability(String visaTerminalCapability){
SystemParamsSettings params = getSystemParamsSettings();
- params.setTerminalCapability(terminalCapability);
+ params.setVisaTerminalCapability(visaTerminalCapability);
+ saveSystemParamsSettings(params);
+ }
+
+ public void setMasterTerminalCapability(String masterTerminalCapability){
+ SystemParamsSettings params = getSystemParamsSettings();
+ params.setMasterTerminalCapability(masterTerminalCapability);
saveSystemParamsSettings(params);
}
- public String getTerminalCapability() {
+ public void setUpiTerminalCapability(String upiTerminalCapability){
SystemParamsSettings params = getSystemParamsSettings();
- return params.getTerminalCapability();
+ params.setUpiTerminalCapability(upiTerminalCapability);
+ saveSystemParamsSettings(params);
+ }
+
+ public void setJcbTerminalCapability(String jcbTerminalCapability){
+ SystemParamsSettings params = getSystemParamsSettings();
+ params.setJcbTerminalCapability(jcbTerminalCapability);
+ saveSystemParamsSettings(params);
+ }
+
+ public String getVisaTerminalCapability(){
+ SystemParamsSettings params = getSystemParamsSettings();
+ return params.getVisaTerminalCapability();
+ }
+ public String getMasterTerminalCapability(){
+ SystemParamsSettings params = getSystemParamsSettings();
+ return params.getMasterTerminalCapability();
+ }
+ public String getUpiTerminalCapability(){
+ SystemParamsSettings params = getSystemParamsSettings();
+ return params.getUpiTerminalCapability();
+ }
+
+ public String getJcbTerminalCapability() {
+ SystemParamsSettings params = getSystemParamsSettings();
+ return params.getJcbTerminalCapability();
}
public void setAuthToken(String authToken) {
@@ -1495,6 +1536,17 @@ public class SystemParamsOperation {
return params.getBinValues();
}
+ public void setRestrictedBinValue(String value) {
+ SystemParamsSettings params = getSystemParamsSettings();
+ params.setRestrictedBinValues(value);
+ saveSystemParamsSettings(params);
+ }
+
+ public String getRestrictedBinValues() {
+ SystemParamsSettings params = getSystemParamsSettings();
+ return params.getRestrictedBinValues();
+ }
+
public String getSecHostMerchantId() {
SystemParamsSettings params = getSystemParamsSettings();
return params.getSecHostMerchantId();
@@ -1840,4 +1892,62 @@ public class SystemParamsOperation {
SystemParamsSettings paramsSettings = getSystemParamsSettings();
return paramsSettings.getPrinterEnabled();
}
+
+ public void setDuelCurrencyStatus(boolean duelCurrencyStatus) {
+ SystemParamsSettings paramsSettings = getSystemParamsSettings();
+ paramsSettings.setDuelCurrencyStatus(duelCurrencyStatus);
+ saveSystemParamsSettings(paramsSettings);
+ }
+
+ public boolean getDuelCurrencyStatus(){
+ SystemParamsSettings paramsSettings = getSystemParamsSettings();
+ return paramsSettings.getDuelCurrencyStatus();
+ }
+
+ public void setPreAuthVoidManualEnabled(boolean preAuthVoidManualEnabled) {
+ SystemParamsSettings params = getSystemParamsSettings();
+ params.setPreAuthVoidManual(preAuthVoidManualEnabled);
+ saveSystemParamsSettings(params);
+ }
+
+ public boolean getPreAuthVoidManualEnabled() {
+ SystemParamsSettings params = getSystemParamsSettings();
+ return params.getPreAuthVoidManual();
+ }
+
+ public void setPreAuthCompleteManualEnabled(boolean preAuthCompleteManualEnabled) {
+ SystemParamsSettings params = getSystemParamsSettings();
+ params.setPreAuthCompleteManual(preAuthCompleteManualEnabled);
+ saveSystemParamsSettings(params);
+ }
+
+ public boolean getPreAuthCompleteManualEnabled() {
+ SystemParamsSettings params = getSystemParamsSettings();
+ return params.getPreAuthCompleteManual();
+ }
+
+ public void setPreAuthManualEnabled(boolean preAuthManualEnabled) {
+ SystemParamsSettings params = getSystemParamsSettings();
+ params.setPreAuthManual(preAuthManualEnabled);
+ saveSystemParamsSettings(params);
+ }
+
+ public boolean getPreAuthManualEnabled() {
+ SystemParamsSettings params = getSystemParamsSettings();
+ return params.getPreAuthManual();
+ }
+
+
+ public void setAutoReversalEnable(boolean autoReversalEnable) {
+ SystemParamsSettings params = getSystemParamsSettings();
+ params.setAutoReversalEnable(autoReversalEnable);
+ saveSystemParamsSettings(params);
+ }
+
+ public boolean getAutoReversalEnable(){
+ SystemParamsSettings params = getSystemParamsSettings();
+ return params.getAutoReversalEnable();
+ }
+
+
}
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/core_utils/SystemParamsSettings.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/core_utils/SystemParamsSettings.java
index 68885f6..c845781 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/core_utils/SystemParamsSettings.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/core_utils/SystemParamsSettings.java
@@ -39,20 +39,20 @@ public class SystemParamsSettings implements Serializable {
private boolean manualEntryPinEnable = false;
private boolean checkExpSwitch = false;
-
-// private String tmsAddress = "https://tms.smile-mm.com";
-// private String tmsAddress = "http://128.199.170.203";
-// private String tmsAddress = "https://sirius-nest.utsmyanmar.com";
- private String tmsAddress = "https://api-tms-uat.kbzbank.com:8443/sirius"; //for uat
-// private String ereceiptAddress = "https://receipt-nest.utsmyanmar.com"; //for on prime
- private String ereceiptAddress = "https://api-tms-uat.kbzbank.com:8443/receipt"; //for uat
+
+ private String tmsAddress = "https://api-tms.kbzbank.com/sirius";
+ private String ereceiptAddress = "https://api-tms.kbzbank.com/receipt";
private String binValues = "";
+ private String restrictedBinValues = "";
private String terminalName = "";
- private String terminalCapability = "E0E8C8";
-
+// private String terminalCapability = "E0E8C8";
+ private String visaTerminalCapability = "E028C8";
+ private String masterTerminalCapability = "E068C8";
+ private String upiTerminalCapability = "E068C8";
+ private String jcbTerminalCapability = "E0F8C8";
private String ipAddress = "";
private String secIpAddress = "";
@@ -174,6 +174,10 @@ public class SystemParamsSettings implements Serializable {
private boolean isClearBatch = false;
+ private boolean isPreAuthVoidManual = false;
+ private boolean isPreAuthCompleteManual = false;
+ private boolean isPreAuthManual = false;
+
private boolean ssl_switch_status = false;
private boolean connect_status = false;
@@ -268,6 +272,8 @@ public class SystemParamsSettings implements Serializable {
private String certificateUrl = "";
private String certificateClientUrl = "";
private boolean printerEnabled = true;
+ private boolean duelCurrencyStatus = false;
+ private boolean autoReversalEnable = false;
public boolean isQrPartialRefundEnable(){
return qrPartialRefundEnable;
@@ -358,6 +364,14 @@ public class SystemParamsSettings implements Serializable {
return this.binValues;
}
+ protected void setRestrictedBinValues(String restrictedBinValues) {
+ this.restrictedBinValues = restrictedBinValues;
+ }
+
+ protected String getRestrictedBinValues() {
+ return this.restrictedBinValues;
+ }
+
protected void setDisabledMessage(String disabledMessage) {
this.disabledMessage = disabledMessage;
}
@@ -494,9 +508,31 @@ public class SystemParamsSettings implements Serializable {
this.qrpay_inquiry_status = status;
}
- protected String getTerminalCapability() { return terminalCapability;}
+// protected String getTerminalCapability() { return terminalCapability;}
+ protected String getVisaTerminalCapability(){
+ return visaTerminalCapability;
+ }
- protected void setTerminalCapability(String terminalCapability) { this.terminalCapability = terminalCapability; }
+ protected String getMasterTerminalCapability(){
+ return masterTerminalCapability;
+ }
+
+ protected String getUpiTerminalCapability(){
+ return upiTerminalCapability;
+ }
+// protected void setTerminalCapability(String terminalCapability) { this.terminalCapability = terminalCapability; }
+
+ protected void setVisaTerminalCapability(String visaTerminalCapability){
+ this.visaTerminalCapability = visaTerminalCapability;
+ }
+
+ protected void setMasterTerminalCapability(String masterTerminalCapability){
+ this.masterTerminalCapability = masterTerminalCapability;
+ }
+
+ protected void setUpiTerminalCapability(String upiTerminalCapability){
+ this.upiTerminalCapability = upiTerminalCapability;
+ }
protected void setLastTransTime(String lastTransTime) {
this.lastTransTime = lastTransTime;
}
@@ -530,6 +566,30 @@ public class SystemParamsSettings implements Serializable {
protected boolean getQRPayStatus() { return qrpay_status; }
+ protected void setPreAuthVoidManual(boolean status) {
+ this.isPreAuthVoidManual = status;
+ }
+
+ protected boolean getPreAuthVoidManual() {
+ return isPreAuthVoidManual;
+ }
+
+ protected void setPreAuthCompleteManual(boolean status) {
+ this.isPreAuthCompleteManual = status;
+ }
+
+ protected boolean getPreAuthCompleteManual() {
+ return isPreAuthCompleteManual;
+ }
+
+ protected void setPreAuthManual(boolean status) {
+ this.isPreAuthManual = status;
+ }
+
+ protected boolean getPreAuthManual() {
+ return isPreAuthManual;
+ }
+
protected boolean isAutoPrintCustomerCopy() {
return isAutoPrintCustomerCopy;
}
@@ -1117,6 +1177,30 @@ public class SystemParamsSettings implements Serializable {
return printerEnabled;
}
+ public void setDuelCurrencyStatus(boolean duelCurrencyStatus) {
+ this.duelCurrencyStatus = duelCurrencyStatus;
+ }
+
+ public boolean getDuelCurrencyStatus(){
+ return duelCurrencyStatus;
+ }
+
+ public void setAutoReversalEnable(boolean autoReversalEnable) {
+ this.autoReversalEnable = autoReversalEnable;
+ }
+
+ public boolean getAutoReversalEnable(){
+ return autoReversalEnable;
+ }
+
+ public String getJcbTerminalCapability() {
+ return jcbTerminalCapability;
+ }
+
+ public void setJcbTerminalCapability(String jcbTerminalCapability){
+ this.jcbTerminalCapability = jcbTerminalCapability;
+ }
+
/* // 流水号起始
private String serialNum = Configs.getInstance().SERIAL_NUM();
// 批次号起始
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/iso_utils/BitmapConfig.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/iso_utils/BitmapConfig.java
index b48fc22..fc24989 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/iso_utils/BitmapConfig.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/iso_utils/BitmapConfig.java
@@ -69,7 +69,8 @@ public class BitmapConfig {
// public static final String BPC_VOID = "3230058028C08000";
// commented on Nov 13,2024
- public static final String BPC_VOID = "3230058028C18000"; // original
+// public static final String BPC_VOID = "3230058028C18000"; // original
+ public static final String BPC_VOID = "3230058028C08000"; // original March 25, 2026
// public static final String BPC_VOID = "3230058028C08000"; // 16-May-2025 removed DE48 requested by KoAAT added DE2
// public static final String BPC_VOID = "3230058028C08000"; // 16-May-2025 removed DE48 requested by KoAAT
// public static final String BPC_VOID = "3230058028C18200";
@@ -108,8 +109,9 @@ public class BitmapConfig {
// public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "7230058028C19800"; // added DE 2
// public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "7234058008C09000"; // for tmk MPU
// public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "7230058008C09000"; // for KBZ MPU
- public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "7234058008C09000"; // for KBZ MPU added DE 14
-// public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "3230058028C19800";
+// public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "7234058008C09000"; // for KBZ MPU added DE 14 Mar 25, 26
+ public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "7230058028C08000"; // from log March 25
+
// public static final String BPC_PRE_AUTH_SALE_VOID_REVERSAL = "3230058028C19A00"; //DE55
//
// public static final String BPC_PRE_AUTH_SALE_COMPLETE_VOID = "3230058028C09200";
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/iso_utils/FieldConfig.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/iso_utils/FieldConfig.java
index be8b436..41223a6 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/iso_utils/FieldConfig.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/iso_utils/FieldConfig.java
@@ -103,8 +103,8 @@ public class FieldConfig {
/* FLD 49 */ {0, SDK_8583_LEN_BCD, 3, SDK_8583_DATA_ASC, SDK_8583_ALIGN_R, ' '},
/* FLD 50 */ {0, SDK_8583_LEN_BCD, 12, SDK_8583_DATA_BCD, SDK_8583_ALIGN_R, '0'},
/* FLD 51 */ {0, SDK_8583_LEN_BCD, 12, SDK_8583_DATA_BCD, SDK_8583_ALIGN_R, '0'},
- /* FLD 52 */ {0, SDK_8583_LEN_BCD, 8, SDK_8583_DATA_BIT, SDK_8583_ALIGN_L, 0},
-// /* FLD 52 */ {0, SDK_8583_LEN_BCD, 8, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, ' '},
+ /* FLD 52 */ {2, SDK_8583_LEN_ASC, 8, SDK_8583_DATA_BIT, SDK_8583_ALIGN_L, '0'},
+// /* FLD 52 */ {0, SDK_8583_LEN_BCD, 8, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, 0},
/* FLD 53 */ {2, SDK_8583_LEN_ASC, 32, SDK_8583_DATA_BCD, SDK_8583_ALIGN_L, '0'},
/* FLD 54 */ {3, SDK_8583_LEN_BCD, 40, SDK_8583_DATA_ASC, SDK_8583_ALIGN_L, ' '},
diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/iso_utils/FieldUtils.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/iso_utils/FieldUtils.java
index 41f7bb0..2ec1ad7 100644
--- a/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/iso_utils/FieldUtils.java
+++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/utils/iso_utils/FieldUtils.java
@@ -341,7 +341,8 @@ public class FieldUtils {
} else if (BaseCardType.IC.getValue() == cardType) { // IC
value = "05";
} else if (FALLBACK == cardType){ // Fallback
- value = "08";
+ value = "72";
+// value = "08";
} else { // Hand-in card number
value = "01";
}
@@ -350,11 +351,16 @@ public class FieldUtils {
if(payDetail.getTransCVM() == TransCVM.OFFLINE_PIN) {
value += "9";
} else {
- if (payDetail.getPINCipher() != null && !payDetail.getPINCipher().trim().isEmpty()) {
- value += "1";
+ if(payDetail.getTransactionType() == VOID.value) {
+ value += "0";
} else {
- value += "2";
+ if (payDetail.getPINCipher() != null && !payDetail.getPINCipher().trim().isEmpty()) {
+ value += "1";
+ } else {
+ value += "2";
+ }
}
+
}
@@ -396,7 +402,11 @@ public class FieldUtils {
field.setDataStr("61"); // BPC
// field.setDataStr("00");// MPU
} else {
- field.setDataStr("00");
+ if (FALLBACK == cardType){ // Fallback
+ field.setDataStr("02");
+ } else {
+ field.setDataStr("00");
+ }
}
diff --git a/settings.gradle b/settings.gradle
index 460fa7a..457b0f5 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -32,7 +32,7 @@ include ':baselib'
include ':mpulib'
//include ':ecr-client-lib'
-include ':ecr-service'
+//include ':ecr-service'
include ':xpay'
include ':ecr'
include ':ecr-service-lib'