added mock card and integrated partially for MPU
This commit is contained in:
parent
40ee7c600f
commit
9a87493945
@ -1,5 +1,5 @@
|
||||
package com.mob.utsmyanmar.model
|
||||
|
||||
enum class CardTransactionType {
|
||||
MPU, EMV, MAG, FALLBACK
|
||||
MPU, EMV, MAG, FALLBACK, MOCK
|
||||
}
|
||||
@ -87,7 +87,8 @@ fun CardWaitingScreen(
|
||||
amount = amount,
|
||||
uiState = uiState,
|
||||
onBackClick = viewModel::onBackPressed,
|
||||
onManualEntryClick = viewModel::onManualEntryClick
|
||||
onManualEntryClick = viewModel::onManualEntryClick,
|
||||
onMockClick = viewModel::onMockClick
|
||||
)
|
||||
}
|
||||
|
||||
@ -96,7 +97,8 @@ private fun CardWaitingScreenContent(
|
||||
amount: String,
|
||||
uiState: CardWaitingUiState,
|
||||
onBackClick: () -> Unit,
|
||||
onManualEntryClick: () -> Unit
|
||||
onManualEntryClick: () -> Unit,
|
||||
onMockClick: () -> Unit
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
@ -210,7 +212,7 @@ private fun CardWaitingScreenContent(
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
InsertCardRow()
|
||||
InsertCardRow(onMockClick = onMockClick)
|
||||
|
||||
Spacer(modifier = Modifier.height(18.dp))
|
||||
|
||||
@ -294,7 +296,7 @@ private fun CircleBorder(
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun InsertCardRow() {
|
||||
private fun InsertCardRow(onMockClick: ()->Unit) {
|
||||
Row(
|
||||
modifier = Modifier.height(44.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
@ -304,6 +306,7 @@ private fun InsertCardRow() {
|
||||
contentDescription = null,
|
||||
tint = Color.LegacyRed,
|
||||
modifier = Modifier.size(28.dp)
|
||||
.clickable(onClick = onMockClick)
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.width(10.dp))
|
||||
@ -437,6 +440,7 @@ fun PreviewCardWaitingScreen() {
|
||||
amount = "50,000",
|
||||
uiState = CardWaitingUiState(),
|
||||
onBackClick = {},
|
||||
onManualEntryClick = {}
|
||||
onManualEntryClick = {},
|
||||
onMockClick = {}
|
||||
)
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import sunmi.sunmiui.utils.LogUtil
|
||||
|
||||
class CardWaitingViewModel(
|
||||
private val cardReadViewModel: CardReaderViewModel,
|
||||
@ -121,6 +122,21 @@ class CardWaitingViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
fun onMockClick() {
|
||||
onScreenPause()
|
||||
cardReadViewModel.setCardTransactionType(CardTransactionType.MOCK)
|
||||
viewModelScope.launch {
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
alertMessage = "Mock card detected.",
|
||||
isLoading = false,
|
||||
isCardCaptured = true
|
||||
)
|
||||
}
|
||||
_events.send(CardWaitingEvent.GoProcessingCard)
|
||||
}
|
||||
}
|
||||
|
||||
private fun startCardReadWhenReady(isFallback: Boolean) {
|
||||
readerInitJob?.cancel()
|
||||
readerInitJob = viewModelScope.launch {
|
||||
|
||||
@ -34,9 +34,11 @@ import com.mob.utsmyanmar.ui.sale_void.VoidTraceScreen
|
||||
import com.mob.utsmyanmar.viewmodel.CardReaderViewModel
|
||||
import com.mob.utsmyanmar.viewmodel.EmvTransactionProcessViewModel
|
||||
import com.mob.utsmyanmar.ui.pinpad.PinPadViewModel
|
||||
import com.mob.utsmyanmar.ui.settlement.SettlementViewModel
|
||||
import com.mob.utsmyanmar.ui.version.VersionScreen
|
||||
import com.mob.utsmyanmar.viewmodel.SharedViewModel
|
||||
import com.mob.utsmyanmar.viewmodel.TransProcessViewModel
|
||||
import com.utsmyanmar.ecr.data.TransType
|
||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||
|
||||
@SuppressLint("ContextCastToActivity")
|
||||
@ -125,12 +127,14 @@ fun AppNavGraph(
|
||||
|
||||
composable(Routes.Settlement.route) {
|
||||
val sharedViewModel: SharedViewModel = hiltViewModel(activity)
|
||||
val settlementViewMode: SettlementViewModel = hiltViewModel(activity)
|
||||
|
||||
SettlementScreen(
|
||||
sharedViewModel = sharedViewModel,
|
||||
settlementViewMode = settlementViewMode,
|
||||
onBack = { navController.popBackStack(Routes.Dashboard.route,false) },
|
||||
onStartSettlement = {
|
||||
sharedViewModel.transactionsType.value = com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType.SETTLEMENT
|
||||
sharedViewModel.transactionsType.value = TransactionsType.SETTLEMENT
|
||||
navController.navigate(Routes.Processing.route) {
|
||||
popUpTo(Routes.Settlement.route) {
|
||||
inclusive = true
|
||||
@ -150,6 +154,7 @@ fun AppNavGraph(
|
||||
)
|
||||
) { backStackEntry ->
|
||||
val voidViewModel: VoidViewModel = hiltViewModel()
|
||||
val transProcessViewModel: TransProcessViewModel = hiltViewModel(activity)
|
||||
val sharedViewModel: SharedViewModel = hiltViewModel(activity)
|
||||
val trace = backStackEntry.arguments?.getString("trace").orEmpty()
|
||||
|
||||
@ -158,7 +163,8 @@ fun AppNavGraph(
|
||||
trace = trace,
|
||||
onBack = { navController.popBackStack() },
|
||||
onProceedVoid = { payDetail ->
|
||||
sharedViewModel.transactionsType.value = com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType.VOID
|
||||
sharedViewModel.transactionsType.value = TransactionsType.VOID
|
||||
transProcessViewModel.setTransType(TransactionsType.VOID)
|
||||
sharedViewModel.payDetail.value = payDetail
|
||||
navController.navigate(Routes.Processing.route) {
|
||||
popUpTo(Routes.VoidTranDetail.route) {
|
||||
@ -365,10 +371,11 @@ fun AppNavGraph(
|
||||
composable(Routes.Processing.route) {
|
||||
val sharedViewModel: SharedViewModel = hiltViewModel(activity)
|
||||
val transProcessViewModel: TransProcessViewModel = hiltViewModel(activity)
|
||||
|
||||
val settlementViewModel: SettlementViewModel = hiltViewModel(activity)
|
||||
ProcessingRoute(
|
||||
sharedViewModel = sharedViewModel,
|
||||
transProcessViewModel = transProcessViewModel,
|
||||
settlementViewModel = settlementViewModel,
|
||||
onNavigateTransactionResult = {
|
||||
navController.navigate(Routes.TransactionResult.route) {
|
||||
popUpTo(Routes.Processing.route) {
|
||||
@ -376,6 +383,14 @@ fun AppNavGraph(
|
||||
}
|
||||
launchSingleTop = true
|
||||
}
|
||||
},
|
||||
onNavigateMain = {
|
||||
navController.navigate(Routes.Dashboard.route) {
|
||||
popUpTo(Routes.Dashboard.route) {
|
||||
inclusive = false
|
||||
}
|
||||
launchSingleTop = true
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.mob.utsmyanmar.ui.pinpad
|
||||
|
||||
import android.text.TextUtils
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
@ -10,6 +11,8 @@ import com.mob.utsmyanmar.model.PinPadStatus
|
||||
import com.mob.utsmyanmar.viewmodel.SharedViewModel
|
||||
import com.mob.utsmyanmar.viewmodel.TransProcessViewModel
|
||||
import com.utsmyanmar.paylibs.Constant
|
||||
import com.utsmyanmar.paylibs.model.TradeData
|
||||
import com.utsmyanmar.paylibs.utils.POSUtil
|
||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||
|
||||
@Composable
|
||||
@ -30,6 +33,19 @@ fun PinPadRoute(
|
||||
onBack()
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
|
||||
val tradeData: TradeData = pinPadViewModel.getTradeData()!!
|
||||
val payDetail = tradeData.getPayDetail()
|
||||
|
||||
val processCode = sharedViewModel.processCode.getValue()
|
||||
val amount = sharedViewModel.amount.getValue()
|
||||
payDetail.setAmount(POSUtil.getInstance().convertAmount(amount))
|
||||
if (!TextUtils.equals(processCode, "")) {
|
||||
payDetail.setProcessCode(processCode)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(pinStatus) {
|
||||
when (pinStatus) {
|
||||
PinPadStatus.ON_CONFIRM,
|
||||
@ -38,7 +54,7 @@ fun PinPadRoute(
|
||||
payDetail?.tradeAnswerCode = Constant.ANSWER_CODE_APPROVED
|
||||
sharedViewModel.payDetail.value = payDetail
|
||||
transProcessViewModel.resetTransactionStatus()
|
||||
if (sharedViewModel.transactionsType.value == TransactionsType.REFUND) {
|
||||
if (sharedViewModel.transactionsType.value == TransactionsType.REFUND || sharedViewModel.transactionsType.value == TransactionsType.PRE_AUTH_VOID || sharedViewModel.transactionsType.value == TransactionsType.PRE_AUTH_COMPLETE) {
|
||||
onNavigateInputRrn()
|
||||
} else {
|
||||
onNavigateProcessing()
|
||||
|
||||
@ -472,15 +472,15 @@ class PinPadViewModel @Inject constructor(
|
||||
return
|
||||
}
|
||||
|
||||
val isCardValid = SunmiSDK.getInstance().checkCardExist() == 2 ||
|
||||
payDetail?.cardType == AidlConstants.CardType.MAGNETIC.getValue() ||
|
||||
payDetail?.cardType == -9
|
||||
|
||||
if (!isCardValid) {
|
||||
isTerminalStateReached = true
|
||||
_pinStatus.value = PinPadStatus.ON_CARD_REMOVED
|
||||
return
|
||||
}
|
||||
// val isCardValid = SunmiSDK.getInstance().checkCardExist() == 2 ||
|
||||
// payDetail?.cardType == AidlConstants.CardType.MAGNETIC.getValue() ||
|
||||
// payDetail?.cardType == -9
|
||||
//
|
||||
// if (!isCardValid) {
|
||||
// isTerminalStateReached = true
|
||||
// _pinStatus.value = PinPadStatus.ON_CARD_REMOVED
|
||||
// return
|
||||
// }
|
||||
|
||||
if (pinBlock != null) {
|
||||
payDetail?.pinCipher = ByteUtil.bytes2HexStr(pinBlock)
|
||||
|
||||
@ -6,10 +6,12 @@ import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.mob.utsmyanmar.model.CardTransactionType
|
||||
import com.mob.utsmyanmar.ui.pinpad.PinPadViewModel
|
||||
import com.mob.utsmyanmar.utils.MockCardData
|
||||
import com.mob.utsmyanmar.utils.MockData
|
||||
import com.mob.utsmyanmar.utils.TransactionUtil
|
||||
import com.mob.utsmyanmar.viewmodel.CardReaderViewModel
|
||||
import com.mob.utsmyanmar.viewmodel.EmvTransactionProcessViewModel
|
||||
import com.mob.utsmyanmar.ui.pinpad.PinPadViewModel
|
||||
import com.mob.utsmyanmar.viewmodel.SharedViewModel
|
||||
import com.mob.utsmyanmar.viewmodel.TransProcessViewModel
|
||||
import com.utsmyanmar.checkxread.model.CardDataX
|
||||
@ -23,7 +25,6 @@ import com.utsmyanmar.paylibs.model.enums.TransCVM
|
||||
import com.utsmyanmar.paylibs.utils.POSUtil
|
||||
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
||||
import com.utsmyanmar.paylibs.utils.enums.TransMenu
|
||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||
import com.utsmyanmar.paylibs.utils.params.Params
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@ -86,6 +87,7 @@ class ProcessingCardViewModel(
|
||||
|
||||
private fun checkCardTransactionType() {
|
||||
when (cardReadViewModel.getCardTransactionType()) {
|
||||
CardTransactionType.MOCK -> mockCardData()
|
||||
CardTransactionType.MPU -> readMPUCard()
|
||||
CardTransactionType.EMV -> handlePreEmvProcess()
|
||||
CardTransactionType.FALLBACK -> readMAGStripe(
|
||||
@ -107,6 +109,22 @@ class ProcessingCardViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
private fun mockCardData() {
|
||||
sharedViewModel.setEmvTrans(false)
|
||||
|
||||
transProcessViewModel.setTransType(sharedViewModel.transactionsType.value)
|
||||
pinPadViewModel.setTransType(sharedViewModel.transactionsType.value)
|
||||
|
||||
val cardDataX = MockData.generateMPUCard();
|
||||
|
||||
val tradeData = TransactionUtil.initMPUTransaction(cardDataX, CardTypeX.IC)
|
||||
|
||||
transProcessViewModel.setTradeData(tradeData)
|
||||
pinPadViewModel.setTradeData(tradeData)
|
||||
sharedViewModel.setCardDataExist(true)
|
||||
|
||||
sendUiEvent(ProcessingCardUiEvent.NavigateToPinPad)
|
||||
}
|
||||
private fun readMPUCard() {
|
||||
cardReadViewModel.startReadXProcess(
|
||||
MPUXReadCard.getInstance(),
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.mob.utsmyanmar.ui.refund_rrn
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
@ -22,6 +23,11 @@ fun InputRrnRoute(
|
||||
}
|
||||
var errorMessage by rememberSaveable { mutableStateOf<String?>(null) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
rrn = ""
|
||||
errorMessage = null
|
||||
}
|
||||
|
||||
NumericEntryScreen(
|
||||
title = "Input RRN",
|
||||
prompt = "Enter RRN",
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
package com.mob.utsmyanmar.ui.sending_to_host
|
||||
|
||||
data class ProcessingState(
|
||||
val title: String = "Processing",
|
||||
)
|
||||
@ -8,7 +8,14 @@ import com.mob.utsmyanmar.viewmodel.SharedViewModel
|
||||
import com.mob.utsmyanmar.viewmodel.TransProcessViewModel
|
||||
import kotlinx.coroutines.delay
|
||||
import androidx.compose.runtime.getValue
|
||||
import com.mob.utsmyanmar.ui.transaction_result.TransactionResultState
|
||||
import com.mob.utsmyanmar.viewmodel.ProcessingTransaction
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import com.mob.utsmyanmar.model.TransactionStatus
|
||||
import com.mob.utsmyanmar.ui.settlement.SettlementViewModel
|
||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||
|
||||
private const val MOCK_HOST_DELAY_MS = 2000L
|
||||
|
||||
@ -16,30 +23,52 @@ private const val MOCK_HOST_DELAY_MS = 2000L
|
||||
fun ProcessingRoute(
|
||||
sharedViewModel: SharedViewModel,
|
||||
transProcessViewModel: TransProcessViewModel,
|
||||
onNavigateTransactionResult: () -> Unit
|
||||
settlementViewModel: SettlementViewModel,
|
||||
onNavigateTransactionResult: () -> Unit,
|
||||
onNavigateMain: ()-> Unit
|
||||
) {
|
||||
|
||||
val transStatus by transProcessViewModel.transResultStatus.collectAsStateWithLifecycle()
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
transProcessViewModel.startOnlineProcess()
|
||||
val state by transProcessViewModel.state.collectAsStateWithLifecycle()
|
||||
|
||||
val settlementStatus by settlementViewModel.uiState.collectAsStateWithLifecycle()
|
||||
|
||||
|
||||
if(sharedViewModel.transactionsType.value == TransactionsType.SETTLEMENT) {
|
||||
LaunchedEffect(Unit) {
|
||||
settlementViewModel.startSettlementProcess()
|
||||
}
|
||||
} else {
|
||||
LaunchedEffect(Unit) {
|
||||
transProcessViewModel.startOnlineProcess()
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(transStatus) {
|
||||
// sharedViewModel.saveMockHostResultForTesting()
|
||||
// delay(MOCK_HOST_DELAY_MS)
|
||||
|
||||
|
||||
when(transStatus) {
|
||||
|
||||
|
||||
TransResultStatus.SUCCESS -> onNavigateTransactionResult()
|
||||
TransResultStatus.FAIL -> onNavigateTransactionResult()
|
||||
TransResultStatus.REVERSAL_SUCCESS -> onNavigateMain()
|
||||
TransResultStatus.REVERSAL_FAIL -> onNavigateMain()
|
||||
else -> {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
ProcessingScreen()
|
||||
LaunchedEffect(settlementStatus.status) {
|
||||
when(settlementStatus.status) {
|
||||
TransactionStatus.ON_SUCCESS -> onNavigateTransactionResult()
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(sharedViewModel.transactionsType.value == TransactionsType.SETTLEMENT) {
|
||||
ProcessingScreen(settlementStatus.processingState)
|
||||
} else {
|
||||
ProcessingScreen(state)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -20,12 +20,13 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.mob.utsmyanmar.ui.processing_card.ProcessingCardState
|
||||
import com.mob.utsmyanmar.ui.theme.Black
|
||||
import com.mob.utsmyanmar.ui.theme.Primary
|
||||
import com.mob.utsmyanmar.ui.theme.White
|
||||
|
||||
@Composable
|
||||
fun ProcessingScreen() {
|
||||
fun ProcessingScreen(state: ProcessingState) {
|
||||
Scaffold(
|
||||
containerColor = White
|
||||
) { paddingValues ->
|
||||
@ -57,7 +58,7 @@ fun ProcessingScreen() {
|
||||
Spacer(modifier = Modifier.height(20.dp))
|
||||
|
||||
Text(
|
||||
text = "Processing",
|
||||
text = state.title,
|
||||
color = White,
|
||||
fontSize = 24.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
|
||||
@ -20,6 +20,7 @@ import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -35,12 +36,14 @@ import com.utsmyanmar.paylibs.utils.POSUtil
|
||||
@Composable
|
||||
fun SettlementScreen(
|
||||
sharedViewModel: SharedViewModel,
|
||||
settlementViewMode: SettlementViewModel,
|
||||
onBack: () -> Unit,
|
||||
onStartSettlement: () -> Unit
|
||||
) {
|
||||
val records by sharedViewModel.getSettlementRecords().observeAsState(emptyList())
|
||||
val records by settlementViewMode.getSettlementPOS().observeAsState(emptyList())
|
||||
val totalAmount = records.sumOf { it.amount }
|
||||
|
||||
|
||||
Scaffold(
|
||||
containerColor = Color.IvoryBeige,
|
||||
topBar = {
|
||||
|
||||
@ -2,10 +2,12 @@ package com.mob.utsmyanmar.ui.settlement
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asFlow
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.mob.utsmyanmar.config.Constants
|
||||
import com.mob.utsmyanmar.model.SettlementType
|
||||
import com.mob.utsmyanmar.model.TransactionStatus
|
||||
import com.mob.utsmyanmar.ui.sending_to_host.ProcessingState
|
||||
import com.utsmyanmar.baselib.repo.Repository
|
||||
import com.utsmyanmar.paylibs.Constant
|
||||
import com.utsmyanmar.paylibs.batch_upload.BatchListener
|
||||
@ -56,7 +58,8 @@ data class SettlementUiState(
|
||||
val bottomLayout: Int = 0,
|
||||
|
||||
val status: TransactionStatus? = null,
|
||||
val isLoading: Boolean = false
|
||||
val isLoading: Boolean = false,
|
||||
val processingState: ProcessingState = ProcessingState("Processing")
|
||||
)
|
||||
|
||||
sealed interface SettlementEvent {
|
||||
@ -84,11 +87,20 @@ class SettlementViewModel @Inject constructor(
|
||||
|
||||
private var bitmap = ""
|
||||
|
||||
val records: LiveData<List<PayDetail>> = getSettlementPOS()
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
records.asFlow().collect { list ->
|
||||
setSettlementData(list)
|
||||
}
|
||||
}
|
||||
}
|
||||
private val isoMsgX: ISOMsgX =
|
||||
ISOMsgX.ISOMsgXBuilder(
|
||||
ISOVersion.VERSION_1993,
|
||||
ISOMode.BOTH_HEADER_TPDU,
|
||||
HostName.BPC
|
||||
HostName.MPU
|
||||
).build()
|
||||
|
||||
private val _uiState = MutableStateFlow(SettlementUiState())
|
||||
@ -123,6 +135,51 @@ class SettlementViewModel @Inject constructor(
|
||||
payDetails = list
|
||||
}
|
||||
|
||||
fun setSettlementData(list: List<PayDetail>) {
|
||||
val newState = list.fold(_uiState.value) { state, payDetail ->
|
||||
val transType = payDetail.transactionType
|
||||
val transName = payDetail.transType
|
||||
|
||||
when {
|
||||
(transType == TransactionType.SALE || transName.equals("SALE", ignoreCase = true))
|
||||
&& !payDetail.isCanceled ->
|
||||
state.copy(
|
||||
saleCount = state.saleCount + 1,
|
||||
saleAmount = state.saleAmount + payDetail.amount
|
||||
)
|
||||
|
||||
(transType == TransactionType.PRE_SALE_COMPLETE
|
||||
|| transName.equals("PREAUTH COMPLETION", ignoreCase = true)
|
||||
|| transName.equals("PRE_AUTH_COMPLETE", ignoreCase = true))
|
||||
&& !payDetail.isCanceled ->
|
||||
state.copy(
|
||||
preCount = state.preCount + 1,
|
||||
preAmount = state.preAmount + payDetail.amount
|
||||
)
|
||||
|
||||
transType == TransactionType.REFUND
|
||||
|| transName.equals("REFUND", ignoreCase = true) ->
|
||||
state.copy(
|
||||
refundCount = state.refundCount + 1,
|
||||
refundAmount = state.refundAmount + payDetail.amount
|
||||
)
|
||||
|
||||
transType == TransactionType.CASH_ADVANCE
|
||||
|| transName.equals("CASH_OUT", ignoreCase = true)
|
||||
|| transName.equals("CASH_ADVANCE", ignoreCase = true) ->
|
||||
state.copy(
|
||||
caCount = state.caCount + 1,
|
||||
caAmount = state.caAmount + payDetail.amount
|
||||
)
|
||||
|
||||
else -> state
|
||||
}
|
||||
}
|
||||
|
||||
LogUtil.d(TAG,"sale count ${newState.saleCount} and sale amount ${newState.saleAmount}")
|
||||
_uiState.update { newState }
|
||||
}
|
||||
|
||||
fun setSettlementSummary(
|
||||
saleCount: Int,
|
||||
saleAmount: Long,
|
||||
@ -195,12 +252,14 @@ class SettlementViewModel @Inject constructor(
|
||||
private fun requestOnlineProcessSettlement() {
|
||||
val state = _uiState.value
|
||||
|
||||
val hostName = HostName.BPC
|
||||
val hostName = HostName.MPU
|
||||
val field60 = SystemParamsOperation.getInstance().getCurrentBatchNum()
|
||||
|
||||
val sale2Count = state.saleCount + state.preCount
|
||||
val sale2Amount = state.saleAmount + state.preAmount
|
||||
|
||||
LogUtil.d(TAG,"Sale count :$sale2Count and Sale amount :$sale2Amount")
|
||||
|
||||
val totalSaleCount = String.format(Locale.getDefault(), "%03d", sale2Count)
|
||||
val totalSaleAmount = String.format(Locale.getDefault(), "%010d00", sale2Amount)
|
||||
|
||||
@ -226,7 +285,7 @@ class SettlementViewModel @Inject constructor(
|
||||
|
||||
payDetail = currentPayDetail
|
||||
|
||||
bitmap = BitmapConfig.BPC_SETTLEMENT
|
||||
bitmap = BitmapConfig.MPU_NEW_SETTLE
|
||||
|
||||
currentPayDetail.transType = TransactionsType.SETTLEMENT.name
|
||||
currentPayDetail.transactionType = TransactionType.SETTLEMENT
|
||||
@ -234,8 +293,8 @@ class SettlementViewModel @Inject constructor(
|
||||
if (!flag) {
|
||||
currentPayDetail.processCode = TransactionsType.SETTLEMENT.processCode
|
||||
} else {
|
||||
bitmap = BitmapConfig.BPC_SETTLEMENT_TRAILER
|
||||
currentPayDetail.processCode = "910000"
|
||||
bitmap = BitmapConfig.MPU_NEW_SETTLE
|
||||
currentPayDetail.processCode = "960000"
|
||||
}
|
||||
|
||||
currentPayDetail.batchNo = SystemParamsOperation.getInstance().getCurrentBatchNum()
|
||||
@ -384,6 +443,7 @@ class SettlementViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
private fun batchUploadProcess() {
|
||||
_uiState.value = _uiState.value.copy(processingState = ProcessingState("Processing Batch Upload"))
|
||||
postStatus(TransactionStatus.ON_BATCH_UPLOAD)
|
||||
|
||||
val currentPayDetails = payDetails
|
||||
|
||||
@ -24,6 +24,7 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.mob.utsmyanmar.ui.preview.P2Preview
|
||||
import com.mob.utsmyanmar.ui.theme.Color
|
||||
import com.utsmyanmar.paylibs.model.PayDetail
|
||||
import com.utsmyanmar.paylibs.print.PrintReceipt
|
||||
|
||||
|
||||
@ -75,14 +76,14 @@ fun TransactionResultScreen(
|
||||
|
||||
Spacer(modifier = Modifier.height(28.dp))
|
||||
|
||||
AmountCard(amount = "50,000")
|
||||
AmountCard(amount = state.payDetail?.amount.toString())
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
InfoCard(
|
||||
date = "26 May 2026",
|
||||
time = "12:06 PM",
|
||||
transactionId = "1234568333"
|
||||
transactionId = state.payDetail?.referNo.toString()
|
||||
)
|
||||
|
||||
}
|
||||
@ -281,7 +282,8 @@ private fun InfoItem(
|
||||
fun PreviewTransactionResultScreen() {
|
||||
TransactionResultScreen(
|
||||
state = TransactionResultState(
|
||||
"Success"
|
||||
"Success",
|
||||
payDetail = PayDetail()
|
||||
),
|
||||
canGoBack = true,
|
||||
onEvent = {},
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
package com.mob.utsmyanmar.ui.transaction_result
|
||||
|
||||
import com.utsmyanmar.paylibs.model.PayDetail
|
||||
|
||||
data class TransactionResultState(
|
||||
val title: String = "Transaction Result",
|
||||
val message: String = "",
|
||||
val isLoading: Boolean = false
|
||||
val isLoading: Boolean = false,
|
||||
val payDetail: PayDetail? = null
|
||||
)
|
||||
|
||||
@ -62,6 +62,8 @@ class TransactionResultViewModel @Inject constructor(
|
||||
if (started) return
|
||||
started = true
|
||||
|
||||
_state.value = _state.value.copy(payDetail = sharedViewModel.payDetail.value)
|
||||
|
||||
sharedViewModel.setPrintStatus(PrintStatus.FIRST_PRINT)
|
||||
sharedViewModel.printXStatus.value = null
|
||||
|
||||
|
||||
57
app/src/main/java/com/mob/utsmyanmar/utils/MockCard.kt
Normal file
57
app/src/main/java/com/mob/utsmyanmar/utils/MockCard.kt
Normal file
@ -0,0 +1,57 @@
|
||||
package com.mob.utsmyanmar.utils
|
||||
|
||||
import com.utsmyanmar.checkxread.model.CardDataX
|
||||
|
||||
data class MockCardData(
|
||||
val cardNo: String = "",
|
||||
val expDate: String = "",
|
||||
val cardScheme: String = "",
|
||||
val cardHolderName: String = "",
|
||||
val phoneNo: String = "",
|
||||
val iccData: String = ""
|
||||
)
|
||||
|
||||
object MockData {
|
||||
|
||||
private val mockCardData: MockCardData = MockCardData(
|
||||
cardNo="9503712156912514",
|
||||
expDate="2912",
|
||||
cardScheme="MPU",
|
||||
cardHolderName="Htin Kyaw Win",
|
||||
iccData="9503712156912514=29121010000000000000"
|
||||
)
|
||||
|
||||
fun generateMPUCard(): CardDataX = CardDataX().apply {
|
||||
pan = mockCardData.cardNo
|
||||
exp = mockCardData.expDate
|
||||
cardHolderName = mockCardData.cardHolderName
|
||||
track2 = mockCardData.iccData
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
// VISA
|
||||
MockCardData(cardNo="3230101288181", expDate="0425", cardScheme="VISA",
|
||||
cardHolderName="U AYE", iccData="5F21BLAHBLAH")
|
||||
|
||||
// MPU - KBZ Debit
|
||||
MockCardData(cardNo="9503051034047056", expDate="3002", cardScheme="MPU",
|
||||
cardHolderName="KBZ Debit", iccData="9503051034047056=30021015930000000000")
|
||||
|
||||
// MPU - KBZ Credit
|
||||
MockCardData(cardNo="9505050161133125", expDate="2701", cardScheme="MPU",
|
||||
cardHolderName="KBZ Credit", iccData="9505050161133125=27011017250000000000")
|
||||
|
||||
// MPU - Htin Kyaw Win
|
||||
MockCardData(cardNo="9503712156912514", expDate="2912", cardScheme="MPU",
|
||||
cardHolderName="Htin Kyaw Win", iccData="9503712156912514=29121010000000000000")
|
||||
|
||||
// MPU - Bank Q
|
||||
MockCardData(cardNo="9503742975107251", expDate="0629", cardScheme="MPU",
|
||||
cardHolderName="Bank Q", iccData="9503742975107251=22081010000000000000")
|
||||
|
||||
// WALLET
|
||||
MockCardData(phoneNo="9794452506", expDate="0425", cardScheme="WALLET",
|
||||
cardHolderName="YOMA VALUED CUSTOMER")
|
||||
*/
|
||||
}
|
||||
@ -5,6 +5,8 @@ import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.mob.utsmyanmar.model.SettlementType
|
||||
import com.mob.utsmyanmar.ui.processing_card.ProcessingCardState
|
||||
import com.mob.utsmyanmar.ui.sending_to_host.ProcessingState
|
||||
import com.utsmyanmar.baselib.network.model.sirius.SiriusRequest
|
||||
import com.utsmyanmar.baselib.network.model.sirius.SiriusResponse
|
||||
import com.utsmyanmar.baselib.repo.Repository
|
||||
@ -24,6 +26,8 @@ import com.utsmyanmar.paylibs.utils.enums.TransMenu
|
||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import io.reactivex.rxjava3.core.Observable
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import sunmi.sunmiui.utils.LogUtil
|
||||
import javax.inject.Inject
|
||||
|
||||
@ -150,6 +154,8 @@ class SharedViewModel @Inject constructor(
|
||||
|
||||
private val _isAmountExist = SingleLiveEvent<Boolean>()
|
||||
|
||||
|
||||
|
||||
private var mPayDetail = PayDetail()
|
||||
|
||||
init {
|
||||
|
||||
@ -3,6 +3,8 @@ package com.mob.utsmyanmar.viewmodel
|
||||
import android.text.TextUtils
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.mob.utsmyanmar.model.TransResultStatus
|
||||
import com.mob.utsmyanmar.ui.processing_card.ProcessingCardState
|
||||
import com.mob.utsmyanmar.ui.sending_to_host.ProcessingState
|
||||
import com.utsmyanmar.baselib.repo.Repository
|
||||
import com.utsmyanmar.paylibs.model.PayDetail
|
||||
import com.utsmyanmar.paylibs.model.TradeData
|
||||
@ -103,6 +105,9 @@ class TransProcessViewModel @Inject constructor(
|
||||
fun setOldTransPayDetail(payDetail: PayDetail) {
|
||||
oldTransPayDetail = payDetail
|
||||
}
|
||||
private val _state = MutableStateFlow(ProcessingState())
|
||||
val state = _state.asStateFlow()
|
||||
|
||||
|
||||
/*
|
||||
* Transaction
|
||||
@ -110,6 +115,8 @@ class TransProcessViewModel @Inject constructor(
|
||||
|
||||
override fun startOnlineProcess() {
|
||||
|
||||
_state.value = _state.value.copy("Processing")
|
||||
|
||||
TransactionsOperation.getInstance()
|
||||
.getStartOperation(
|
||||
tradeData,
|
||||
@ -188,6 +195,7 @@ class TransProcessViewModel @Inject constructor(
|
||||
_transResultStatus.value =
|
||||
TransResultStatus.REVERSAL_PREPARE
|
||||
|
||||
_state.value = _state.value.copy("Preparing Reversal")
|
||||
callReversal(tradeData)
|
||||
}
|
||||
|
||||
@ -261,6 +269,7 @@ class TransProcessViewModel @Inject constructor(
|
||||
|
||||
private fun callReversal(tradeData: TradeData) {
|
||||
|
||||
_state.value = _state.value.copy("Processing Reversal")
|
||||
payDetail = tradeData.payDetail
|
||||
|
||||
ReversalAction.getInstance()
|
||||
|
||||
@ -48,7 +48,7 @@ public interface PayDetailDao {
|
||||
// 1 = SALE & 7 = PRE_SALE_COMPLETE & 4 = REFUND & 9 = CASH_ADVANCE & 18 = TIP ADJUSTMENT
|
||||
// @Query("SELECT * FROM paydetail WHERE isSettle = 0 AND isCanceled = 0 AND accountType != 'MPU' and accountType != 'UPI' AND (transactionType = 1 OR transactionType = 7 OR transactionType = 4 OR transactionType = 9)")
|
||||
|
||||
@Query("SELECT * FROM paydetail WHERE isSettle = 0 AND isCanceled = 0 AND accountType NOT IN ( 'MPU','UnionPay') AND transactionType IN (1, 7, 4, 9)")
|
||||
@Query("SELECT * FROM paydetail WHERE isSettle = 0 AND isCanceled = 0 AND transactionType IN (1, 7, 4, 9)")
|
||||
LiveData<List<PayDetail>> getSettlementPOS();
|
||||
|
||||
// 1 = SALE & 7 = PRE_SALE_COMPLETE & 4 = REFUND & 9 = CASH_ADVANCE & 18 = TIP ADJUSTMENT & 6 = PRE_AUTH_VOID & 20 = WALLET
|
||||
|
||||
@ -329,10 +329,10 @@ public class ISOSocket {
|
||||
|
||||
public void switchIp() {
|
||||
isSwitchIp = true;
|
||||
serverIP = "posuat.myanmarorientalbank.com";
|
||||
serverPort = 5033;
|
||||
// serverIP = "192.168.0.107";
|
||||
// serverPort = 5001;
|
||||
// serverIP = "posuat.myanmarorientalbank.com";
|
||||
// serverPort = 5033;
|
||||
serverIP = "192.168.0.100";
|
||||
serverPort = 5001;
|
||||
// serverIP = getSecondaryIp();
|
||||
// serverPort = getSecondaryPort();
|
||||
}
|
||||
@ -353,11 +353,11 @@ public class ISOSocket {
|
||||
if (!isSwitchIp) {
|
||||
// serverIP = getIp();
|
||||
// serverPort = getPort();
|
||||
// serverIP = "192.168.0.107";
|
||||
// serverPort = 5001;
|
||||
SystemParamsOperation.getInstance().setSslSwitchStatus(true);
|
||||
serverIP = "posuat.myanmarorientalbank.com";
|
||||
serverPort = 5033;
|
||||
serverIP = "192.168.0.100";
|
||||
serverPort = 5001;
|
||||
SystemParamsOperation.getInstance().setSslSwitchStatus(false);
|
||||
// serverIP = "posuat.myanmarorientalbank.com";
|
||||
// serverPort = 5033;
|
||||
} else {
|
||||
isSwitchIp = false;
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@ public class SignOnProcess {
|
||||
private SignOnProcess() {
|
||||
tradeData = Params.newTrade(true);
|
||||
// payDetail = tradeData.getPayDetail();
|
||||
isoMsgX = new ISOMsgX.ISOMsgXBuilder(ISOVersion.VERSION_1993, ISOMode.ONLY_HEADER,HostName.CARDZONE)
|
||||
isoMsgX = new ISOMsgX.ISOMsgXBuilder(ISOVersion.VERSION_1993, ISOMode.BOTH_HEADER_TPDU,HostName.MPU)
|
||||
.build();
|
||||
}
|
||||
|
||||
@ -59,13 +59,13 @@ public class SignOnProcess {
|
||||
flag = false;
|
||||
return listener -> {
|
||||
// LogUtil.d(TAG, "Starting TX SignOn");
|
||||
HostName hostName = HostName.CARDZONE;
|
||||
HostName hostName = HostName.MPU;
|
||||
PayDetail payDetail = tradeData.getPayDetail();
|
||||
|
||||
payDetail.setProcessCode(TransactionsType.SIGN_ON.processCode);
|
||||
payDetail.setTransType(TransactionsType.SIGN_ON.name);
|
||||
payDetail.setTransactionType(TransactionsType.SIGN_ON.value);
|
||||
payDetail.setHostName(HostName.CARDZONE.name);
|
||||
payDetail.setHostName(hostName.name);
|
||||
|
||||
byte[] sendBytes = isoMsgX.buildISOPackets(tradeData, BitmapConfig.CZ_SIGN_ON, MessageType.NETWORK_MANAGEMENT);
|
||||
ISOSocket.getInstance().enqueue(sendBytes, sendBytes.length,false, new ISOCallback() {
|
||||
|
||||
@ -3,7 +3,9 @@ package com.utsmyanmar.paylibs.utils.enums;
|
||||
public enum HostName {
|
||||
BPC("BPC"),
|
||||
FINEXUS("FINEXUS"),
|
||||
CARDZONE("CARDZONE");
|
||||
CARDZONE("CARDZONE"),
|
||||
|
||||
MPU("MPU");
|
||||
|
||||
|
||||
public final String name;
|
||||
|
||||
@ -26,69 +26,65 @@ public class HostUtils {
|
||||
boolean isVisaMaster = cardScheme.equals(CardScheme.VISA.name) || cardScheme.equals(CardScheme.MASTERCARD.name);
|
||||
switch (transactionsType) {
|
||||
case SALE:
|
||||
if (hostName == HostName.BPC){
|
||||
bitmap = BitmapConfig.BPC_SALE;
|
||||
if (hostName == HostName.MPU){
|
||||
bitmap = BitmapConfig.MPU_NEW_SALE;
|
||||
} else {
|
||||
bitmap = BitmapConfig.CZ_SALE;
|
||||
}
|
||||
break;
|
||||
case CASH_OUT:
|
||||
if (hostName == HostName.BPC) {
|
||||
bitmap = BitmapConfig.BPC_SALE;
|
||||
if (hostName == HostName.MPU) {
|
||||
bitmap = BitmapConfig.MPU_NEW_CASH_ADVANCE;
|
||||
} else {
|
||||
bitmap = BitmapConfig.CZ_SALE;
|
||||
}
|
||||
break;
|
||||
case VOID:
|
||||
|
||||
if (hostName == HostName.BPC) {
|
||||
if(isVisaMaster) {
|
||||
bitmap = BitmapConfig.BPC_VOID;
|
||||
break;
|
||||
}
|
||||
bitmap = BitmapConfig.BPC_VOID;
|
||||
if (hostName == HostName.MPU) {
|
||||
bitmap = BitmapConfig.MPU_NEW_VOID;
|
||||
} else {
|
||||
bitmap = BitmapConfig.FINEXUS_VOID;
|
||||
}
|
||||
break;
|
||||
case SETTLEMENT:
|
||||
if (hostName == HostName.BPC) {
|
||||
bitmap = BitmapConfig.BPC_SETTLEMENT;
|
||||
if (hostName == HostName.MPU) {
|
||||
bitmap = BitmapConfig.MPU_NEW_BATCH_UPLOAD;
|
||||
} else {
|
||||
bitmap = BitmapConfig.FINEXUS_BATCH_UPLOAD;
|
||||
}
|
||||
break;
|
||||
case PRE_AUTH_SALE:
|
||||
if (hostName == HostName.BPC) {
|
||||
bitmap = BitmapConfig.BPC_PRE_AUTH_SALE;
|
||||
if (hostName == HostName.MPU) {
|
||||
bitmap = BitmapConfig.MPU_NEW_PRE_AUTH;
|
||||
} else {
|
||||
bitmap = BitmapConfig.FUND_TRANSFER_PRE_CHECK;
|
||||
}
|
||||
break;
|
||||
case PRE_AUTH_VOID:
|
||||
if (hostName == HostName.BPC) {
|
||||
bitmap = BitmapConfig.BPC_PRE_AUTH_SALE_VOID_REVERSAL;
|
||||
if (hostName == HostName.MPU) {
|
||||
bitmap = BitmapConfig.MPU_NEW_PRE_AUTH_CANCEL;
|
||||
} else {
|
||||
bitmap = BitmapConfig.CZ_SALE;
|
||||
}
|
||||
break;
|
||||
case PRE_AUTH_COMPLETE:
|
||||
if (hostName == HostName.BPC) {
|
||||
bitmap = BitmapConfig.BPC_PRE_AUTH_SALE_COMPLETE;
|
||||
if (hostName == HostName.MPU) {
|
||||
bitmap = BitmapConfig.MPU_NEW_PRE_AUTH_COMPLETE_BITMAP;
|
||||
} else {
|
||||
bitmap = BitmapConfig.CZ_SALE;
|
||||
}
|
||||
break;
|
||||
case PRE_AUTH_COMPLETE_VOID:
|
||||
if (hostName == HostName.BPC) {
|
||||
bitmap = BitmapConfig.BPC_VOID;
|
||||
if (hostName == HostName.MPU) {
|
||||
bitmap = BitmapConfig.MPU_NEW_PRE_AUTH_COMPLETE_CANCEL;
|
||||
} else {
|
||||
bitmap = BitmapConfig.FINEXUS_PRE_AUTH_VOID;
|
||||
}
|
||||
break;
|
||||
case REFUND:
|
||||
if (hostName == HostName.BPC) {
|
||||
bitmap = BitmapConfig.BPC_REFUND;
|
||||
if (hostName == HostName.MPU) {
|
||||
bitmap = BitmapConfig.MPU_NEW_REFUND;
|
||||
} else {
|
||||
bitmap = BitmapConfig.CZ_SALE;
|
||||
}
|
||||
|
||||
@ -535,8 +535,8 @@ public class FieldUtils {
|
||||
|
||||
break;
|
||||
case 63: //Private Use
|
||||
// String settleData = payDetail.getSettleData();
|
||||
// field.setDataStr(settleData);
|
||||
String settleData = payDetail.getSettleData();
|
||||
field.setDataStr(settleData);
|
||||
break;
|
||||
case 64: //Message Authentication Code (MAC) Required when the 39 field in the response message is "00"
|
||||
field.setDataStr("0000000000000000");
|
||||
|
||||
@ -82,7 +82,7 @@ public class Params {
|
||||
payDetail.setIsCanceled(false);
|
||||
payDetail.transNum = System.currentTimeMillis() / 1000;
|
||||
// need to add host logic in another place
|
||||
payDetail.setHostName("CARDZONE");
|
||||
payDetail.setHostName("MPU");
|
||||
|
||||
payDetail.setOriginalTransDate(SystemDateTime.getMMDD()+SystemDateTime.getYYYY());
|
||||
|
||||
|
||||
BIN
paylibs/src/main/res/raw/mpucert.crt
Normal file
BIN
paylibs/src/main/res/raw/mpucert.crt
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user