From 54a0b47920936fa110ea33c3d94ced92e9e008b1 Mon Sep 17 00:00:00 2001 From: kizzy Date: Thu, 3 Sep 2026 18:09:09 +0700 Subject: [PATCH] QR standalone settlement is working now, enhanced on dual settlement . --- .../kbz/ui/kpay/QRConnectingFragment.java | 11 +- .../SettlementTransactionFragment.java | 91 ++++++- .../ui/settlement/SettlementViewModel.java | 226 ++++++++++-------- .../com/utsmm/kbz/util/tms/TMSSetupsImpl.java | 12 + .../java/com/utsmm/kbz/util/tms/TMSUtil.java | 5 +- .../paylibs/print/printx/BaseXPrint.java | 2 +- 6 files changed, 234 insertions(+), 113 deletions(-) diff --git a/app/src/main/java/com/utsmm/kbz/ui/kpay/QRConnectingFragment.java b/app/src/main/java/com/utsmm/kbz/ui/kpay/QRConnectingFragment.java index c5128f6..bfb2d24 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/kpay/QRConnectingFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/kpay/QRConnectingFragment.java @@ -153,11 +153,12 @@ public class QRConnectingFragment extends DataBindingFragment implements DataBin .subscribe( response -> { + if(response.getResponse().getQrCode() != null && !response.getResponse().getQrCode().isEmpty()) { LogUtil.d(TAG,response.getResponse().getQrCode()); if(response.getResponse().getQrCode() == null || response.getResponse().getQrCode().isEmpty()) { - endAction(); + endAction(response.getResponse().getMsg()); } refLabel = response.getResponse().getMerchOrderId(); @@ -191,7 +192,7 @@ public class QRConnectingFragment extends DataBindingFragment implements DataBin } else { dismissLoadingDialog(); // showDeclineDialog("Failed to generate QR!\n"+response.getMessage()); - endAction(); + endAction(response.getResponse().getMsg()); } }, @@ -199,7 +200,7 @@ public class QRConnectingFragment extends DataBindingFragment implements DataBin Throwable.printStackTrace(); dismissLoadingDialog(); // showDeclineDialog("Failed to generate QR!\nMessage - "+Throwable.getMessage()); - endAction(); + endAction(""); }, () -> { LogUtil.d(TAG,"On Complete!"); @@ -210,8 +211,8 @@ public class QRConnectingFragment extends DataBindingFragment implements DataBin } - private void endAction() { - showDeclineDialog("Failed to generate QR!\n Communication Error! "); + private void endAction(String msg) { + showDeclineDialog("Failed to generate QR!\n "+(msg.isEmpty()? "Communication Error!" : msg)); ecrActionCancel(getResourceString(R.string.txt_qr_generate_failed)); navigateToMain(); } 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 55f6ffb..f6831ba 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 @@ -67,6 +67,8 @@ public class SettlementTransactionFragment extends DataBindingFragment implement private final CurrencyBucket mmkBucket = new CurrencyBucket(); private final CurrencyBucket usdBucket = new CurrencyBucket(); + /** Accumulates card lines from USD + MMK settle passes for one combined slip. */ + private final List accumulatedCardSettleData = new ArrayList<>(); private List cardTransactionsList = new ArrayList<>(); private final ArrayList qrTransactionsList = new ArrayList<>(); @@ -671,6 +673,11 @@ public class SettlementTransactionFragment extends DataBindingFragment implement } private void performAutoSettle() { + accumulatedCardSettleData.clear(); + if (!isCardSettleNeeded()) { + finishQrOnlySettlement(); + return; + } if (isUSDSettleNeeded()) { currencySelectionHelper.applyCardCurrencyAndHost("USD"); settlementViewModel.startSettlementProcess(usdBucket, false); @@ -685,6 +692,59 @@ public class SettlementTransactionFragment extends DataBindingFragment implement return (usdBucket.saleCount != 0 || usdBucket.preCount != 0 || usdBucket.refundCount != 0 || usdBucket.caCount != 0 || usdBucket.voidCount != 0); } + + private boolean isMmkSettleNeeded() { + return (mmkBucket.saleCount != 0 || mmkBucket.preCount != 0 || mmkBucket.refundCount != 0 + || mmkBucket.caCount != 0 || mmkBucket.voidCount != 0); + } + + private boolean isCardSettleNeeded() { + return isUSDSettleNeeded() || isMmkSettleNeeded(); + } + + + private void finishQrOnlySettlement() { + if (qrTransactionsList.isEmpty()) { + showDeclineDialog(getResourceString(R.string.txt_there_is_no_trans_to_clear)); + return; + } + + showLoadingDialog("Settling ..."); + + TradeData tradeData = Params.newTrade(false); + PayDetail payDetail = tradeData.getPayDetail(); + SettleData settleData = new SettleData(qrSaleCount, qrSaleAmount, 0, 0L, qrRefundCount, qrRefundAmount, 0, 0L); + payDetail.setSettleDataObj(settleData); + payDetail.setTransactionType(TransactionsType.MMQR_SETTLEMENT.value); + payDetail.setTransType(TransactionsType.MMQR_SETTLEMENT.name); + payDetail.setAmount(qrTotalAmount); + payDetail.setTradeAnswerCode("000"); + payDetail.setBatchNo(SystemParamsOperation.getInstance().getCurrentBatchNum()); + payDetail.setQrSettleData(QRSettleData.convertFromPayDetail(qrTransactionsList)); + + if (sharedViewModel.getTransMenu().getValue() != TransMenu.LAST_SETTLEMENT) { + sharedViewModel.insertPayDetail(payDetail); + } + + sharedViewModel.payDetail.setValue(payDetail); + sharedViewModel.payDetails.setValue(new ArrayList<>(qrTransactionsList)); + + settlementViewModel.markAllUnsettledQRTransactionsSettled(); + for (PayDetail pay : qrTransactionsList) { + settlementViewModel.markQRTransactionSettled(pay); + } + for (PayDetail pay : qrTransListAll) { + settlementViewModel.markQRTransactionSettled(pay); + } + + EReceiptRequest request = EReceiptUtil.getInstance() + .generateQRSettlement(payDetail, QRSettleData.convertFromPayDetail(qrTransactionsList)); + sharedViewModel.pushReceipt(request); + + dismissLoadingDialog(); + navigateToNext(); + } + private void networkCutOver() { EchoTestProcess.getInstance().enqueueCutOver().startSignOn(new SignOnListener() { @@ -737,12 +797,18 @@ public class SettlementTransactionFragment extends DataBindingFragment implement case ON_SUCCESS: updateData(); dismissLoadingDialog(); - networkCutOver(); + // Cut-over only between card currency passes — not for QR-only. + if (isCardSettleNeeded()) { + networkCutOver(); + } else { + navigateToNext(); + } break; case ON_FINAL_SUCCESS: dismissLoadingDialog(); updateData(); - if (!SystemParamsOperation.getInstance().getDemoStatus()) { + // QR-only / empty card batch must not send network cut-over. + if (isCardSettleNeeded() && !SystemParamsOperation.getInstance().getDemoStatus()) { networkCutOver(); // bpc } else { navigateToNext(); @@ -764,17 +830,22 @@ public class SettlementTransactionFragment extends DataBindingFragment implement private void updateData() { PayDetail payDetail = settlementViewModel.getPayDetail(); - // Keep cardSettleData from ViewModel (built before updateDB clears payDetails). + List passCards = payDetail.getCardSettleData(); + if (passCards != null && !passCards.isEmpty()) { + accumulatedCardSettleData.addAll(passCards); + } if (qrTransactionsList != null && !qrTransactionsList.isEmpty()) { payDetail.setQrSettleData(QRSettleData.convertFromPayDetail(qrTransactionsList)); } - sharedViewModel.payDetail.setValue(payDetail); - - EReceiptRequest request = EReceiptUtil.getInstance().generateMPUReceipt(sharedViewModel.payDetail.getValue()); - + // Per-currency e-receipt first (pass cards only). + EReceiptRequest request = EReceiptUtil.getInstance().generateMPUReceipt(payDetail); sharedViewModel.pushReceipt(request); + + // Combined slip for print: USD + MMK card lines. + payDetail.setCardSettleData(new ArrayList<>(accumulatedCardSettleData)); + sharedViewModel.payDetail.setValue(payDetail); settleQr(); } @@ -855,6 +926,12 @@ public class SettlementTransactionFragment extends DataBindingFragment implement if(sharedViewModel.getTransMenu().getValue() == TransMenu.SETTLEMENT) { /* April 10 , 2024 Smile requested not to send to host even settlement button was clicked */ + accumulatedCardSettleData.clear(); + if (!isCardSettleNeeded()) { + // QR-only: settle QR locally, skip card ISO + cut-over + finishQrOnlySettlement(); + return; + } if(isUSDSettleNeeded()) { currencySelectionHelper.applyCardCurrencyAndHost("USD"); settlementViewModel.startSettlementProcess(usdBucket,false); 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 496ac77..2927ec6 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 @@ -69,6 +69,8 @@ public class SettlementViewModel extends ViewModel { private boolean isSecondCall = false; private int i = 0; + private List batchUploadQueue; + private int batchUploadIndex = 0; public SingleLiveEvent> payDetailList = new SingleLiveEvent<>(); private List payDetails; @@ -344,6 +346,12 @@ public class SettlementViewModel extends ViewModel { @SuppressWarnings("ConstantConditions") public void startSettlementProcess(CurrencyBucket currencyBucket,boolean isLast) { this.isLast = isLast; + this.flag = false; + this.i = 0; + this.batchUploadQueue = null; + this.batchUploadIndex = 0; + this.errorFlag = false; + this.isSecondCall = false; // Switch TID/MID/IP/currency before building ISO // isLast=false => USD pass; isLast=true => MMK pass. @@ -354,10 +362,19 @@ public class SettlementViewModel extends ViewModel { SystemParamsOperation.getInstance().getIncrementBatchNo(); + // Void-only currency (e.g. USD sale then void) must not be treated as empty: + // previously that skipped 0500 and posted ON_FINAL_SUCCESS, which also skipped MMK. boolean bucketIsEmpty = currencyBucket.saleCount == 0 && currencyBucket.preCount == 0 && currencyBucket.refundCount == 0 - && currencyBucket.caCount == 0; + && currencyBucket.caCount == 0 + && currencyBucket.voidCount == 0; + + LogUtil.d(TAG, "Settlement bucket sale=" + currencyBucket.saleCount + + " void=" + currencyBucket.voidCount + + " empty=" + bucketIsEmpty + + " demo=" + SystemParamsOperation.getInstance().getDemoStatus() + + " isLast=" + isLast); if (bucketIsEmpty || SystemParamsOperation.getInstance().getDemoStatus()) { requestDemoProcessSettlement(currencyBucket); @@ -411,33 +428,61 @@ public class SettlementViewModel extends ViewModel { enrichSettleDataWithVoids(settleData); payDetail.setSettleDataObj(settleData); payDetail.setCardSettleData(CardSettleData.convertFromPayDetail(buildCardPayDetailList())); - - long totalAmount = currencyBucket.saleAmount + currencyBucket.preAmount + currencyBucket.refundAmount + currencyBucket.caAmount; - - String settlementData = ""; - if(currencyBucket.refundAmount != 0L) { - - 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)); - } else { - settlementData = "C"+ String.format(Locale.getDefault(), "%012d", subTotal); - } - - - } else { - settlementData = "C"+ String.format(Locale.getDefault(), "%012d", totalAmount); - } - - payDetail.setSettleData(settlementData); - payDetail.setAmount(totalAmount); + applySettlementIsoAmounts(payDetail, settleData); payDetail.setTradeAnswerCode("000"); - updateDB(); + // Only clear batch after the final (MMK) pass — clearing on USD wiped MMK txns. + if (isLast) { + updateDB(); + } insertPayDetail(payDetail); - resultString.postValue(TransactionStatus.ON_FINAL_SUCCESS); + if (isLast) { + resultString.postValue(TransactionStatus.ON_FINAL_SUCCESS); + } else { + resultString.postValue(TransactionStatus.ON_SUCCESS); + } + } + + + private void applySettlementIsoAmounts(PayDetail payDetail, SettleData settleData) { + HostName hostName = HostName.BPC; + long saleAmount = settleData.getSaleAmount(); + long preAmount = settleData.getPreAuthCompAmount(); + long refundAmount = settleData.getRefundAmount(); + long caAmount = settleData.getCashAdvanceAmount(); + + if (hostName == HostName.BPC) { + long totalAmount = saleAmount + preAmount + refundAmount + caAmount; + String settlementData; + if (refundAmount != 0L) { + long creditTotal = saleAmount + preAmount + caAmount; + long subTotal = creditTotal - refundAmount; + if (subTotal < 0L) { + settlementData = "D" + String.format(Locale.getDefault(), "%012d", Math.abs(subTotal)); + } else { + settlementData = "C" + String.format(Locale.getDefault(), "%012d", subTotal); + } + } else { + settlementData = "C" + String.format(Locale.getDefault(), "%012d", totalAmount); + } + payDetail.setSettleData(settlementData); + payDetail.setAmount(totalAmount); + LogUtil.d(TAG, "Settlement ISO amount=" + settlementData + + " sale=" + saleAmount + + " void=" + settleData.getVoidSaleAmount()); + } else { + int sale2Count = settleData.getSaleCount() + settleData.getPreAuthCompCount(); + long sale2Amount = saleAmount + preAmount; + String totalSaleCount = String.format(Locale.getDefault(), "%03d", sale2Count); + String totalSaleAmount = String.format(Locale.getDefault(), "%010d00", sale2Amount); + String totalRefundCount = String.format(Locale.getDefault(), "%03d", settleData.getRefundCount()); + String totalRefundAmount = String.format(Locale.getDefault(), "%010d00", refundAmount == 0L ? 0 : refundAmount); + String totalDebitSaleCount = String.format(Locale.getDefault(), "%03d", settleData.getCashAdvanceCount()); + String totalDebitSaleAmount = String.format(Locale.getDefault(), "%010d00", caAmount == 0L ? 0 : caAmount); + payDetail.setSettleData(totalSaleCount + totalSaleAmount + totalRefundCount + totalRefundAmount + + totalDebitSaleCount + totalDebitSaleAmount); + payDetail.setAmount(sale2Amount + refundAmount + caAmount); + } } private void requestOnlineProcessSettlement(CurrencyBucket currencyBucket) { @@ -446,22 +491,8 @@ public class SettlementViewModel extends ViewModel { HostName hostName = HostName.BPC; - String field60 = SystemParamsOperation.getInstance().getCurrentBatchNum(); - 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", 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); - - TradeData tradeData = Params.newTrade(true); payDetail = tradeData.getPayDetail(); @@ -508,33 +539,8 @@ public class SettlementViewModel extends ViewModel { payDetail.setSettleDataObj(settleData); payDetail.setCardSettleData(CardSettleData.convertFromPayDetail(buildCardPayDetailList())); - if(hostName == HostName.BPC) { - long totalAmount = currencyBucket.saleAmount + currencyBucket.preAmount + currencyBucket.refundAmount + currencyBucket.caAmount; - - String settlementData = ""; - if(currencyBucket.refundAmount != 0L) { - - 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)); - } else { - settlementData = "C"+ String.format(Locale.getDefault(), "%012d", subTotal); - } - - - } else { - settlementData = "C"+ String.format(Locale.getDefault(), "%012d", totalAmount); - } - - payDetail.setSettleData(settlementData); - payDetail.setAmount(totalAmount); - } else { -// payDetail.setSettleData(totalSaleCount + totalSaleAmount + totalRefundCount + totalRefundAmount + totalDebitSaleCount + totalDebitSaleAmount + totalERefundCount + totalERefundAmount); //field 63 BPC - payDetail.setSettleData(totalSaleCount + totalSaleAmount + totalRefundCount + totalRefundAmount + totalDebitSaleCount + totalDebitSaleAmount ); //field 63 - } - + // ISO F005 must include voided/canceled sales (host still holds them until batch upload). + applySettlementIsoAmounts(payDetail, settleData); tradeData.setPayDetail(payDetail); tradeData.setField60(field60); @@ -607,6 +613,8 @@ public class SettlementViewModel extends ViewModel { /* reset batch upload count...*/ i = 0; + batchUploadQueue = null; + batchUploadIndex = 0; // to leave data for testing // if (settlementType.getValue() == SettlementType.NORMAL) { @@ -686,51 +694,37 @@ public class SettlementViewModel extends ViewModel { private void batchUploadProcess(boolean isLast) { resultString.postValue(TransactionStatus.ON_BATCH_UPLOAD); - if (payDetails == null || payDetails.isEmpty()) { + if (batchUploadQueue == null) { + batchUploadQueue = buildBatchUploadList(isLast); + batchUploadIndex = 0; + LogUtil.d(TAG, "Batch upload queue size=" + batchUploadQueue.size() + + " currency=" + (isLast ? "MMK" : "USD")); + } + + if (batchUploadQueue.isEmpty() || batchUploadIndex >= batchUploadQueue.size()) { + batchUploadQueue = null; + batchUploadIndex = 0; 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); + PayDetail uploadPay = batchUploadQueue.get(batchUploadIndex); + LogUtil.d(TAG, "Batch upload [" + batchUploadIndex + "/" + batchUploadQueue.size() + "] type=" + + uploadPay.getTransType() + " amt=" + uploadPay.getAmount() + + " currency=" + uploadPay.getCurrencyCode()); TradeData tradeData = new TradeData(); - tradeData.setPayDetail(payDetail); + tradeData.setPayDetail(uploadPay); 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) { - i++; + batchUploadIndex++; + if (batchUploadIndex < batchUploadQueue.size()) { batchUploadProcess(isLast); } else { + batchUploadQueue = null; + batchUploadIndex = 0; requestOnlineProcessSettlement(currentBucket); } } @@ -743,4 +737,38 @@ public class SettlementViewModel extends ViewModel { } + private List buildBatchUploadList(boolean isLast) { + String expectedCurrency = isLast ? "104" : "840"; + List list = new ArrayList<>(); + + if (payDetails != null) { + for (PayDetail pay : payDetails) { + if (matchesSettlementCurrency(pay.getCurrencyCode(), expectedCurrency)) { + list.add(pay); + } + } + } + + for (PayDetail pay : deleteTrans) { + if (!matchesSettlementCurrency(pay.getCurrencyCode(), expectedCurrency)) { + continue; + } + // Canceled original sale first, then void record. + if (pay.getTransactionType() == TransactionType.SALE && pay.isCanceled) { + list.add(pay); + } + } + for (PayDetail pay : deleteTrans) { + if (!matchesSettlementCurrency(pay.getCurrencyCode(), expectedCurrency)) { + continue; + } + if (pay.getTransactionType() == TransactionType.VOID && !pay.isCanceled) { + list.add(pay); + } + } + + return list; + } + + } 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 1632244..1041bbb 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 @@ -288,6 +288,18 @@ public class TMSSetupsImpl implements TMSSetups{ SystemParamsOperation.getInstance().setShortCode(""); } } + } else { + + SystemParamsOperation.getInstance().setSecHostId(""); + SystemParamsOperation.getInstance().setSecHostName(""); + SystemParamsOperation.getInstance().setSecHostTerminalId(""); + SystemParamsOperation.getInstance().setSecHostMerchantId(""); + SystemParamsOperation.getInstance().setShortCode(""); + SystemParamsOperation.getInstance().setSecHostIpAddress(""); + SystemParamsOperation.getInstance().setSecHostSecIpAddress(""); + SystemParamsOperation.getInstance().setSecHostCurrency(""); + + } 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 2479b2e..dd1fb14 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 @@ -262,7 +262,10 @@ public class TMSUtil { String shortCode = SystemParamsOperation.getInstance().getShortCode(); String appId = SystemParamsOperation.getInstance().getAppId(); String appKey = SystemParamsOperation.getInstance().getAppKey(); - + + LogUtil.d(TAG,"shortCode:"+shortCode); + LogUtil.d(TAG,"appId:"+appId); + LogUtil.d(TAG,"appKey:"+appKey); if(shortCode.length() == 11 && !appId.isEmpty() && !appKey.isEmpty()) { tmsValidity = new TMSValidity(ValidityStatus.SUCCESS,"Success"); 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 82be1a6..7e23097 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 @@ -383,7 +383,7 @@ public abstract class BaseXPrint { if ("SALE".equals(transType)) { summary.saleCount++; summary.saleAmount += amount; - } else if ("VOID SALE".equals(transType) || "VOID_SALE".equals(transType)) { + } else if ("VOID SALE".equals(transType) || "VOID_SALE".equals(transType) || "VOID".equals(transType)) { summary.voidSaleCount++; summary.voidSaleAmount += amount; } else if ("PREAUTH COMPLETION".equals(transType) || "PRE_AUTH_COMPLETE".equals(transType)) {