settlement finished for dual currency

This commit is contained in:
kizzy 2026-03-31 18:55:22 +07:00
parent aabab54048
commit 175ebab148
8 changed files with 216 additions and 73 deletions

View File

@ -252,7 +252,7 @@ public class MainFragment extends DataBindingFragment {
sharedViewModel.setManualEntryStatus(SystemParamsOperation.getInstance().getManualEntryStatus());
// queryAidCAPKList();
queryAidCAPKList();
// queryAidCAPKList();
// generateMockQR();
}

View File

@ -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());

View File

@ -9,10 +9,13 @@ 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.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;
@ -43,7 +46,7 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
private SharedViewModel sharedViewModel;
private ManagementViewModel managementViewModel;
private CurrencySelectionHelper currencySelectionHelper;
private int routeId;
int saleCount = 0;
@ -55,17 +58,6 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
long refundAmount = 0;
long caAmount = 0;
private static class CurrencyBucket {
int saleCount;
long saleAmount;
int preCount;
long preAmount;
int refundCount;
long refundAmount;
int caCount;
long caAmount;
}
private final CurrencyBucket mmkBucket = new CurrencyBucket();
private final CurrencyBucket usdBucket = new CurrencyBucket();
@ -74,6 +66,8 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
settlementViewModel = getFragmentScopeViewModel(SettlementViewModel.class);
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
managementViewModel = getFragmentScopeViewModel(ManagementViewModel.class);
currencySelectionHelper = new CurrencySelectionHelper(this, sharedViewModel);
}
@Override
@ -337,6 +331,8 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
CASH_ADVANCE
}
private void resetCurrencyBucket(CurrencyBucket bucket) {
bucket.saleCount = 0;
bucket.saleAmount = 0L;
@ -379,9 +375,9 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
resetCurrencyBucket(mmkBucket);
resetCurrencyBucket(usdBucket);
List<com.utsmyanmar.paylibs.model.CardSettleData> cardSettleDataList = payDetail.getCardSettleData();
List<CardSettleData> cardSettleDataList = payDetail.getCardSettleData();
if (cardSettleDataList != null && !cardSettleDataList.isEmpty()) {
for (com.utsmyanmar.paylibs.model.CardSettleData item : cardSettleDataList) {
for (CardSettleData item : cardSettleDataList) {
applyStoredCardSettle(item);
}
return;
@ -399,7 +395,7 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
bucket.caAmount = caAmount;
}
private void applyStoredCardSettle(com.utsmyanmar.paylibs.model.CardSettleData item) {
private void applyStoredCardSettle(CardSettleData item) {
CurrencyBucket bucket = getCurrencyBucket(item.getCurrencyCode());
String transType = item.getTransType() == null ? "" : item.getTransType().trim().toUpperCase(Locale.getDefault());
@ -451,15 +447,23 @@ 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!");
if(isUSDSettleNeeded()) {
currencySelectionHelper.applyCardCurrencyAndHost("MMK");
settlementViewModel.startSettlementProcess(mmkBucket,true);
} else {
navigateToNext();
}
}
@Override
public void onFailureSignOn(Integer resultCode) {
showDeclineDialog("Failure:"+resultCode);
@ -485,12 +489,14 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
showLoadingDialog("Sending Batch Upload...");
break;
case ON_SUCCESS:
dismissLoadingDialog();
networkCutOver();
break;
case ON_FINAL_SUCCESS:
dismissLoadingDialog();
updateData();
if (!SystemParamsOperation.getInstance().getDemoStatus()) {
networkCutOver(); // bpc
navigateToNext();
} else {
navigateToNext();
}
@ -555,11 +561,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() {

View File

@ -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;
@ -115,6 +116,10 @@ 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;
@ -265,22 +270,22 @@ 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) {
// 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();
this.isLast = isLast;
SystemParamsOperation.getInstance().getIncrementBatchNo();
if(SystemParamsOperation.getInstance().getDemoStatus()) {
requestDemoProcessSettlement();
requestDemoProcessSettlement(currencyBucket);
} else {
requestOnlineProcessSettlement();
requestOnlineProcessSettlement(currencyBucket);
}
}
@ -299,7 +304,7 @@ public class SettlementViewModel extends ViewModel {
private void requestDemoProcessSettlement() {
private void requestDemoProcessSettlement(CurrencyBucket currencyBucket) {
TradeData tradeData = Params.newTrade(true);
@ -321,18 +326,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));
@ -354,24 +359,24 @@ public class SettlementViewModel extends ViewModel {
resultString.postValue(TransactionStatus.ON_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);
@ -406,22 +411,22 @@ 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);
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));
@ -484,7 +489,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);
@ -505,7 +510,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 */
@ -516,52 +521,79 @@ public class SettlementViewModel extends ViewModel {
// to leave data for testing
// if (settlementType.getValue() == SettlementType.NORMAL) {
if(isLast) {
updateDB();
// }
}
insertPayDetail(payDetail);
if (errorFlag) {
resultString.postValue(TransactionStatus.ON_ERROR);
} else {
if(isLast) {
resultString.postValue(TransactionStatus.ON_FINAL_SUCCESS);
} else {
resultString.postValue(TransactionStatus.ON_SUCCESS);
}
}
}
}
});
}
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

View File

@ -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;
}
}

View File

@ -88,7 +88,7 @@ public class CurrencySelectionHelper {
return new ArrayList<>(values);
}
private void applyCardCurrencyAndHost(String selectedCurrency) {
public void applyCardCurrencyAndHost(String selectedCurrency) {
cachePrimaryCardHostIfNeeded();
String selected = normalizeCurrency(selectedCurrency);

View File

@ -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,

View File

@ -23,6 +23,7 @@ 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_usd_data = ByteUtil.hexStr2Bytes("3f4bcac6cc559ab12bbbc5a51118f3f5".toUpperCase()); // KBZ UAT
// private static final byte[] main_key_data = ByteUtil.hexStr2Bytes("875f63741753d18811a3449090d1777b".toUpperCase());
// private static final byte[] main_key_data = ByteUtil.hexStr2Bytes("e121249099a677e8b7d4f6a9d49fe8d1".toUpperCase()); // MPU
private static final byte[] work_key_data = new byte[16];