diff --git a/app/src/main/java/com/utsmm/kbz/MainActivity.java b/app/src/main/java/com/utsmm/kbz/MainActivity.java index dc14b0f..9c82f64 100644 --- a/app/src/main/java/com/utsmm/kbz/MainActivity.java +++ b/app/src/main/java/com/utsmm/kbz/MainActivity.java @@ -49,6 +49,7 @@ import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation; import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsSettings; import com.utsmyanmar.paylibs.utils.enums.TransMenu; import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType; +import com.utsmm.kbz.util.enums.SettlementType; import com.utsmm.kbz.databinding.ActivityMainNewBinding; import com.utsmm.kbz.service.AutoAlarmReceiver; import com.utsmm.kbz.ui.core_ui.InputPasswordFragment; @@ -474,92 +475,21 @@ public class MainActivity extends AppCompatActivity implements private void handleAutoSettlementIntent(Intent intent) { if (intent == null) return; - boolean hasPOS = intent.getBooleanExtra("AUTO_SETTLEMENT", false); - boolean hasQR = intent.getBooleanExtra("AUTO_QR_SETTLEMENT", false); + boolean hasAutoSettle = intent.getBooleanExtra("AUTO_SETTLEMENT", false); + + if (!hasAutoSettle) return; - if (!hasPOS && !hasQR) return; - // Clear immediately so onResume won't re-trigger on next wake intent.removeExtra("AUTO_SETTLEMENT"); - intent.removeExtra("AUTO_QR_SETTLEMENT"); - 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); - } - } - - } else if (hasQR) { - // Only QR settlement, no POS - handleQRSettlement(intent); - } - } - - 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); + sharedViewModel.settlementType.setValue(SettlementType.NORMAL); + sharedViewModel.transactionsType.setValue(TransactionsType.SETTLEMENT); + sharedViewModel.setTransMenu(TransMenu.SETTLEMENT); + sharedViewModel.autoSettle.setValue(true); try { - navController.navigate(R.id.transactionResultFragment); + navController.navigate(R.id.settlementTransactionFragment); } catch (Exception e) { - LogUtil.e(TAG, "QR Auto Settlement navigation error: " + e.getMessage()); + LogUtil.e(TAG, "Navigation error: " + e.getMessage()); } } 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 6156a5c..157ae90 100644 --- a/app/src/main/java/com/utsmm/kbz/service/AutoSettleService.java +++ b/app/src/main/java/com/utsmm/kbz/service/AutoSettleService.java @@ -1,180 +1,68 @@ package com.utsmm.kbz.service; -import android.annotation.SuppressLint; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; import android.os.IBinder; -import android.text.TextUtils; import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; -import androidx.lifecycle.Observer; -import androidx.localbroadcastmanager.content.LocalBroadcastManager; -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; import com.utsmm.kbz.R; -import com.utsmm.kbz.ui.settlement.SettlementViewModel; - -import javax.inject.Inject; +import com.utsmyanmar.paylibs.utils.LogUtil; +import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation; import dagger.hilt.android.AndroidEntryPoint; -import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; -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; -import com.utsmyanmar.paylibs.model.CardSettleData; -import com.utsmyanmar.paylibs.model.MsgField; -import com.utsmyanmar.paylibs.model.PayDetail; -import com.utsmyanmar.paylibs.model.QRSettleData; -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; -import com.utsmyanmar.paylibs.utils.enums.HostName; -import com.utsmyanmar.paylibs.utils.iso_utils.BitmapConfig; -import com.utsmyanmar.paylibs.utils.iso_utils.TransactionType; -import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType; -import com.utsmyanmar.paylibs.utils.params.Params; - -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.Map; @AndroidEntryPoint public class AutoSettleService extends Service { private static final String TAG = AutoSettleService.class.getSimpleName(); - public static final String ACTION_DATA_RECEIVED = BuildConfig.APPLICATION_ID + ".ACTION_DATA_RECEIVED"; public static final String EXTRA_DATA = BuildConfig.APPLICATION_ID + ".EXTRA_DATA"; - private Handler handler; - private SettlementViewModel settlementViewModel; - - // 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 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"; - + private void startForegroundService() { NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); - - // Create notification channel for Android 8+ + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel( NOTIFICATION_CHANNEL_ID, "Auto Settlement Service", - NotificationManager.IMPORTANCE_LOW // Use LOW importance for foreground service + NotificationManager.IMPORTANCE_LOW ); channel.setDescription("Auto settlement background service"); notificationManager.createNotificationChannel(channel); } - - // Create foreground notification + NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID) .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentTitle("Auto Settlement Active") .setContentText("Processing scheduled settlement...") .setPriority(NotificationCompat.PRIORITY_LOW) - .setOngoing(true) // Make it non-dismissible + .setOngoing(true) .setAutoCancel(false); - - // Start foreground service + startForeground(1002, builder.build()); } - private void createNotification() { - NotificationManager mNotificationManager = (NotificationManager)getSystemService( NOTIFICATION_SERVICE ) ; - NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext() , default_notification_channel_id ) ; - mBuilder.setContentTitle( "Auto Settlement Running" ) ; - mBuilder.setContentText( "Processing transactions..." ) ; - mBuilder.setTicker( "Auto Settlement Service" ) ; - mBuilder.setSmallIcon(R.drawable. ic_launcher_foreground ) ; - mBuilder.setAutoCancel( true ) ; - if (android.os.Build.VERSION. SDK_INT >= android.os.Build.VERSION_CODES. O ) { - int importance = NotificationManager. IMPORTANCE_HIGH ; - NotificationChannel notificationChannel = new NotificationChannel( NOTIFICATION_CHANNEL_ID , "AUTO_SETTLEMENT_CHANNEL" , importance) ; - mBuilder.setChannelId( NOTIFICATION_CHANNEL_ID ) ; - assert mNotificationManager != null; - mNotificationManager.createNotificationChannel(notificationChannel) ; - } - assert mNotificationManager != null; - mNotificationManager.notify(( int ) System. currentTimeMillis () , mBuilder.build()) ; - } - - private void sendDataToViewModel(String data) { - Intent intent = new Intent(ACTION_DATA_RECEIVED); - intent.putExtra(EXTRA_DATA, data); - LocalBroadcastManager.getInstance(this).sendBroadcast(intent); - } - - @SuppressLint("CheckResult") @Override public int onStartCommand(Intent intent, int flags, int startId) { LogUtil.d(TAG, "<<<<<<<<<<<<<<< Auto Settlement Service Started >>>>>>>>>>>>>>>>."); try { - // Start as foreground service for Android 8+ if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { startForegroundService(); } - - sendDataToViewModel("Auto settlement initiated"); - - // Also create regular notification - createNotification(); if (SystemParamsOperation.getInstance().getSettlementStatus()) { - performSettlement(); -// regularSettlementCompleted = true; - performQRSettlement(); + launchSettlementFragment(); } else { LogUtil.d(TAG, "Settlement is disabled in system parameters"); stopSelf(); @@ -188,438 +76,13 @@ public class AutoSettleService extends Service { return START_NOT_STICKY; } - private void performSettlement() { - if (regularSettlementCompleted) { - return; - } - - final ISOMsgX isoMsgX = new ISOMsgX.ISOMsgXBuilder( - ISOVersion.VERSION_1993, - ISOMode.BOTH_HEADER_TPDU, - HostName.BPC - ).build(); - - regularSettlementObserver = new Observer>() { - @Override - public void onChanged(List list) { - if (regularSettlementCompleted) { - return; - } - - payDetails.clear(); - payDetails.addAll(list); - - regularSettlementCompleted = true; - - repository.getSettlementPOS().removeObserver(this); - - int saleCount = 0; - long saleAmount = 0L; - int preCount = 0; - long preAmount = 0L; - int refundCount = 0; - long refundAmount = 0L; - int caCount = 0; - long caAmount = 0L; - - if (list != null && !list.isEmpty()) { - for (PayDetail pay : list) { - if (pay.getTransactionType() == TransactionType.SALE && !pay.isCanceled) { - saleCount++; - saleAmount += pay.getAmount(); - } else if (pay.getTransactionType() == TransactionType.PRE_SALE_COMPLETE && !pay.isCanceled) { - preCount++; - preAmount += pay.getAmount(); - } else if (pay.getTransactionType() == TransactionType.REFUND) { - refundCount++; - refundAmount += pay.getAmount(); - } else if (pay.getTransactionType() == TransactionType.CASH_ADVANCE) { - caCount++; - caAmount += pay.getAmount(); - } - } - } - - TradeData tradeData = Params.newTrade(true); - PayDetail payDetail = tradeData.getPayDetail(); - - String bitmap = BitmapConfig.BPC_SETTLEMENT; - payDetail.setTransType(TransactionsType.SETTLEMENT.name); - payDetail.setTransactionType(TransactionType.SETTLEMENT); - 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( - saleCount, saleAmount, preCount, preAmount, refundCount, refundAmount, caCount, caAmount); - payDetail.setSettleDataObj(settleData); - payDetail.setCardSettleData(CardSettleData.convertFromPayDetail(list)); - - 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); - } - - if(totalAmount == 0 && (saleCount == 0 || preCount == 0 || refundCount == 0 || caCount == 0)) { - posSettlementReady = true; - posHasData = false; - checkAndLaunch(); - checkIfBothSettlementsComplete(); - return; - } - payDetail.setSettleData(settlementData); - payDetail.setAmount(totalAmount); - - tradeData.setPayDetail(payDetail); - tradeData.setField60(SystemParamsOperation.getInstance().getCurrentBatchNum()); - - byte[] sendBytes = isoMsgX.buildISOPackets(tradeData, bitmap, MessageType.SETTLEMENT); - ISOSocket.getInstance().enqueue(sendBytes, sendBytes.length, false, new ISOCallback() { - @Override - public void onReceive(byte[] bytes, int length) { - Map responseMap = isoMsgX.parseISOPackets(bytes, length); - if (responseMap != null) { - String resultStr = ""; - try { - resultStr = responseMap.get("F039").getDataStr(); - } catch (NullPointerException e) { - e.printStackTrace(); - payDetail.setIsNeedReversal(true); - return; - } - payDetail.setTradeAnswerCode(resultStr); - 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(!flag); - } - } - } - - @Override - public void onError(String msg) { - ISOSocket.getInstance().switchIp(); - ISOSocket.getInstance().enqueue(sendBytes, sendBytes.length, false, this); - } - - @Override - public void onComplete() { - LogUtil.d(TAG, "Auto settlement transaction completed successfully"); - - 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.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; - } - - qrSettlementObserver = new Observer>() { - @Override - public void onChanged(List payDetailList) { - if (qrSettlementCompleted) { - return; - } - qrSettlementCompleted = true; - - repository.getTransactionHistory().removeObserver(this); - - if (payDetailList != null) { - int qrSaleCount = 0; - long qrSaleAmount = 0; - int qrRefundCount = 0; - long qrRefundAmount = 0; - - ArrayList qrTransactionsList = new ArrayList<>(); - ArrayList qrTransListAll = new ArrayList<>(); - - try { - for (PayDetail payDetail : payDetailList) { - if ((payDetail.getTransactionType() == TransactionsType.MMQR.value - || payDetail.getTransactionType() == TransactionsType.MMQR_REFUND.value) - && payDetail.getQrTransStatus() == 1) { - - qrTransactionsList.add(payDetail); - - if (payDetail.getTransactionType() == TransactionsType.MMQR.value) { - qrSaleCount++; - qrSaleAmount += payDetail.getAmount(); - } else if (payDetail.getTransactionType() == TransactionsType.MMQR_REFUND.value) { - qrRefundCount++; - qrRefundAmount += payDetail.getAmount(); - } - } else if (payDetail.getTransactionType() == TransactionsType.MMQR.value - || payDetail.getTransactionType() == TransactionsType.MMQR_REFUND.value) { - qrTransListAll.add(payDetail); - } - } - } 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; - } - - if (!qrTransactionsList.isEmpty()) { - LogUtil.d(TAG, "Processing QR Auto Settlement with " + qrTransactionsList.size() + " transactions"); - - long totalAmount = qrSaleAmount - qrRefundAmount; - - // Increment batch number for QR settlement - SystemParamsOperation.getInstance().getIncrementBatchNo(); - - // Create settlement data for QR transactions - 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"); - payDetail.setBatchNo(SystemParamsOperation.getInstance().getCurrentBatchNum()); - payDetail.setQrSettleData(QRSettleData.convertFromPayDetail(qrTransactionsList)); - // Insert QR settlement record - repository.insertPayDetail(payDetail); - - // Delete settled QR transactions - for (PayDetail pay : qrTransactionsList) { - repository.deletePayDetail(pay); - } - - // Delete all other QR transactions (failed ones) - for (PayDetail pay : qrTransListAll) { - repository.deletePayDetail(pay); - } - - // Push e-receipt data using repository directly - try { - EReceiptRequest request = EReceiptUtil.getInstance().generateQRSettlement(payDetail, QRSettleData.convertFromPayDetail(qrTransactionsList)); - sendEReceipt(request); - LogUtil.d(TAG, "QR Settlement e-receipt data prepared and sent"); - } catch (Exception e) { - LogUtil.e(TAG, "Error preparing QR settlement e-receipt: " + e.getMessage()); - } - - try { - // Create QR settlement data bundle - Bundle qrData = new Bundle(); - qrData.putInt("QR_SALE_COUNT", qrSaleCount); - qrData.putLong("QR_SALE_AMOUNT", qrSaleAmount); - qrData.putInt("QR_REFUND_COUNT", qrRefundCount); - qrData.putLong("QR_REFUND_AMOUNT", qrRefundAmount); - qrData.putLong("QR_TOTAL_AMOUNT", totalAmount); - qrData.putSerializable("QR_TRANS_LIST", qrTransactionsList); - // Use notification-based approach to reliably launch the app - 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(); - } - }; - - repository.getTransactionHistory().observeForever(qrSettlementObserver); - } - - private void checkIfBothSettlementsComplete() { - if (regularSettlementCompleted && qrSettlementCompleted) { - LogUtil.d(TAG, "Both settlements completed, stopping service"); - stopSelf(); - } - } - - @Override - public void onCreate() { - super.onCreate(); - handler = new Handler(); - } - - @Nullable - @Override - public IBinder onBind(Intent intent) { - return null; - } - - @Override - public boolean onUnbind(Intent intent) { - return super.onUnbind(intent); - } - - @Override - public void onDestroy() { - super.onDestroy(); - - // Clean up observers to prevent memory leaks - if (regularSettlementObserver != null && repository != null) { - repository.getSettlementPOS().removeObserver(regularSettlementObserver); - } - if (qrSettlementObserver != null && repository != null) { - repository.getTransactionHistory().removeObserver(qrSettlementObserver); - } - - } - - 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() { + private void launchSettlementFragment() { try { Intent launchIntent = new Intent(this, MainActivity.class); 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", pendingPayDetail); - } - - if (qrHasData && pendingQrData != null) { - launchIntent.putExtra("AUTO_QR_SETTLEMENT", true); - launchIntent.putExtra("EXTRA_QR_TRANSACTION_TYPE", TransactionsType.MMQR_SETTLEMENT.value); - launchIntent.putExtras(pendingQrData); - } + launchIntent.putExtra("AUTO_SETTLEMENT", true); PendingIntent pendingIntent = PendingIntent.getActivity( this, @@ -638,57 +101,35 @@ public class AutoSettleService extends Service { 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") + .setContentTitle("Auto Settlement") + .setContentText("Tap to view settlement and print receipt") .setPriority(NotificationCompat.PRIORITY_HIGH) .setAutoCancel(true) .setContentIntent(pendingIntent) .setFullScreenIntent(pendingIntent, true); notificationManager.notify(2001, builder.build()); - // Reset state - pendingPayDetail = null; - pendingQrData = null; - posSettlementReady = false; - qrSettlementReady = false; - posHasData = false; - qrHasData = false; - startActivity(launchIntent); } catch (Exception e) { - LogUtil.e(TAG, "Error launching MainActivity: " + e.getMessage()); + LogUtil.e(TAG, "Error launching settlement: " + e.getMessage()); e.printStackTrace(); } } - - - private void sendEReceipt(EReceiptRequest request) { - try { - LogUtil.d(TAG, "Sending e-receipt: " + new Gson().toJson(request)); - - repository.sendReceipt(request) - .subscribeOn(Schedulers.io()) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe( - response -> LogUtil.d(TAG, "E-Receipt sent successfully: " + response.getMessage()), - error -> { - if (error instanceof HttpException) { - HttpException httpEx = (HttpException) error; - try { - String errorJson = httpEx.response().errorBody().string(); - LogUtil.e(TAG, "E-Receipt error: " + errorJson); - } catch (Exception e) { - LogUtil.e(TAG, "E-Receipt send failed: " + error.getMessage()); - } - } else { - LogUtil.e(TAG, "E-Receipt send failed: " + error.getMessage()); - } - } - ); - } catch (Exception e) { - LogUtil.e(TAG, "Error sending e-receipt: " + e.getMessage()); - } + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; } -} \ No newline at end of file + + @Override + public boolean onUnbind(Intent intent) { + return super.onUnbind(intent); + } + + @Override + public void onDestroy() { + super.onDestroy(); + } +} 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 4ca7aa2..2a63635 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 @@ -132,6 +132,8 @@ public class SharedViewModel extends ViewModel { public MutableLiveData _manualEntryStatus = new MutableLiveData<>(); + public MutableLiveData autoSettle = new MutableLiveData<>(false); + public MutableLiveData fullVoidPreauthStatus = new MutableLiveData<>(); public MutableLiveData partialVoidPreauthStatus = new MutableLiveData<>(); 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 79989ad..2a37f96 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 @@ -529,6 +529,17 @@ public class SettlementTransactionFragment extends DataBindingFragment implement safeNavigateToRouteId(); } + private void performAutoSettle() { + if (isUSDSettleNeeded()) { + currencySelectionHelper.applyCardCurrencyAndHost("USD"); + settlementViewModel.startSettlementProcess(usdBucket, false); + } else { + currencySelectionHelper.applyCardCurrencyAndHost("MMK"); + settlementViewModel.startSettlementProcess(mmkBucket, true); + } + showLoadingDialog("Sending ..."); + } + private boolean isUSDSettleNeeded() { return (usdBucket.saleCount != 0 || usdBucket.preCount != 0 || usdBucket.refundCount != 0 || usdBucket.caCount != 0); } @@ -565,6 +576,13 @@ public class SettlementTransactionFragment extends DataBindingFragment implement settlementViewModel.settlementType.setValue(sharedViewModel.settlementType.getValue()); + settlementViewModel.isNoData.observe(getViewLifecycleOwner(), noData -> { + if (Boolean.TRUE.equals(sharedViewModel.autoSettle.getValue()) && noData == false) { + sharedViewModel.autoSettle.setValue(false); + delayFunctionCall(this::performAutoSettle); + } + }); + settlementViewModel.resultString.observe(getViewLifecycleOwner(), transactionStatus -> { switch (transactionStatus) { case ON_BATCH_UPLOAD: 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 7deeab2..b762336 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 @@ -460,7 +460,7 @@ public class TMSSetupsImpl implements TMSSetups{ SystemParamsOperation.getInstance().setRandomPinPad(parseBoolean(data)); } else if (TextUtils.equals(name,"clear_batch_time")) { - SystemParamsOperation.getInstance().setClearBatchTime(data); + SystemParamsOperation.getInstance().setClearBatchTime("00:00"); } else if (TextUtils.equals(name,"alert_sound_enable")) { SystemParamsOperation.getInstance().setAlertSound(parseBoolean(data));