Compare commits
No commits in common. "0f0bd49709dbc88e14ef02940064723573ab5953" and "675e398aaf306aedeec191afc51e425c4b4d3996" have entirely different histories.
0f0bd49709
...
675e398aaf
2
.gitignore
vendored
2
.gitignore
vendored
@ -15,5 +15,3 @@
|
|||||||
local.properties
|
local.properties
|
||||||
/.idea
|
/.idea
|
||||||
/.idea
|
/.idea
|
||||||
/sunmiui-lib
|
|
||||||
/paysdk-lib
|
|
||||||
|
|||||||
@ -47,7 +47,6 @@ dependencies {
|
|||||||
implementation(libs.androidx.compose.foundation)
|
implementation(libs.androidx.compose.foundation)
|
||||||
implementation(libs.androidx.compose.material3)
|
implementation(libs.androidx.compose.material3)
|
||||||
implementation(libs.androidx.compose.runtime)
|
implementation(libs.androidx.compose.runtime)
|
||||||
implementation(libs.androidx.compose.runtime.livedata)
|
|
||||||
implementation(libs.androidx.compose.ui)
|
implementation(libs.androidx.compose.ui)
|
||||||
implementation(libs.androidx.compose.ui.graphics)
|
implementation(libs.androidx.compose.ui.graphics)
|
||||||
implementation(libs.androidx.compose.ui.tooling.preview)
|
implementation(libs.androidx.compose.ui.tooling.preview)
|
||||||
|
|||||||
@ -13,77 +13,17 @@ fun AmountRoute(
|
|||||||
onNavigateCardWaiting: () -> Unit
|
onNavigateCardWaiting: () -> Unit
|
||||||
) {
|
) {
|
||||||
AmountScreen(
|
AmountScreen(
|
||||||
title = action.ifBlank { "Amount" },
|
|
||||||
onBackClick = onBack,
|
onBackClick = onBack,
|
||||||
onChargeClick = { amount ->
|
onChargeClick = { amount ->
|
||||||
sharedViewModel.amount.value = amount
|
sharedViewModel.amount.value = amount
|
||||||
sharedViewModel.setAmountExist(true)
|
sharedViewModel.setAmountExist(true)
|
||||||
sharedViewModel.setCardDataExist(false)
|
sharedViewModel.setCardDataExist(false)
|
||||||
sharedViewModel.setTransMenu(null)
|
sharedViewModel.setTransMenu(null)
|
||||||
val config = action.toTransactionConfig()
|
sharedViewModel.transactionsType.value = TransactionsType.SALE
|
||||||
sharedViewModel.transactionName.value = config.transactionName
|
sharedViewModel.processCode.value =
|
||||||
sharedViewModel.transactionsType.value = config.transactionType
|
ProcessCode.SALE_PURCHASE + ProcessCode.SMART + ProcessCode.TO_ACCOUNT
|
||||||
sharedViewModel.processCode.value = config.processCode
|
|
||||||
|
|
||||||
onNavigateCardWaiting()
|
onNavigateCardWaiting()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class TransactionConfig(
|
|
||||||
val transactionName: String,
|
|
||||||
val transactionType: TransactionsType,
|
|
||||||
val processCode: String
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun String.toTransactionConfig(): TransactionConfig {
|
|
||||||
return when (trim().lowercase()) {
|
|
||||||
"void" -> TransactionConfig(
|
|
||||||
transactionName = "SALE",
|
|
||||||
transactionType = TransactionsType.VOID,
|
|
||||||
processCode = ProcessCode.SALE_VOID + ProcessCode.SMART + ProcessCode.TO_ACCOUNT
|
|
||||||
)
|
|
||||||
|
|
||||||
"refund" -> TransactionConfig(
|
|
||||||
transactionName = "REFUND",
|
|
||||||
transactionType = TransactionsType.REFUND,
|
|
||||||
processCode = ProcessCode.REFUND + ProcessCode.SMART + ProcessCode.TO_ACCOUNT
|
|
||||||
)
|
|
||||||
|
|
||||||
"pre-auth" -> TransactionConfig(
|
|
||||||
transactionName = "PRE_AUTH",
|
|
||||||
transactionType = TransactionsType.PRE_AUTH_SALE,
|
|
||||||
processCode = ProcessCode.PRE_AUTH_SALE + ProcessCode.SMART + ProcessCode.TO_ACCOUNT
|
|
||||||
)
|
|
||||||
|
|
||||||
"pre-auth void" -> TransactionConfig(
|
|
||||||
transactionName = "PRE_AUTH",
|
|
||||||
transactionType = TransactionsType.PRE_AUTH_VOID,
|
|
||||||
processCode = ProcessCode.PRE_AUTH_VOID + ProcessCode.SMART + ProcessCode.TO_ACCOUNT
|
|
||||||
)
|
|
||||||
|
|
||||||
"pre-auth complete" -> TransactionConfig(
|
|
||||||
transactionName = "PRE_AUTH_COMPLETE",
|
|
||||||
transactionType = TransactionsType.PRE_AUTH_COMPLETE,
|
|
||||||
processCode = ProcessCode.PRE_AUTH_COMPLETE + ProcessCode.SMART + ProcessCode.TO_ACCOUNT
|
|
||||||
)
|
|
||||||
|
|
||||||
"pre-auth complete void" -> TransactionConfig(
|
|
||||||
transactionName = "PRE_AUTH_COMPLETE",
|
|
||||||
transactionType = TransactionsType.PRE_AUTH_COMPLETE_VOID,
|
|
||||||
processCode = ProcessCode.PRE_AUTH_COMPLETE_VOID + ProcessCode.SMART + ProcessCode.TO_ACCOUNT
|
|
||||||
)
|
|
||||||
|
|
||||||
"cash out" -> TransactionConfig(
|
|
||||||
transactionName = "CASH_OUT",
|
|
||||||
transactionType = TransactionsType.CASH_OUT,
|
|
||||||
processCode = ProcessCode.CASH_ADVANCE + ProcessCode.SMART + ProcessCode.TO_ACCOUNT
|
|
||||||
)
|
|
||||||
|
|
||||||
else -> TransactionConfig(
|
|
||||||
transactionName = "SALE",
|
|
||||||
transactionType = TransactionsType.SALE,
|
|
||||||
processCode = ProcessCode.SALE_PURCHASE + ProcessCode.SMART + ProcessCode.TO_ACCOUNT
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -22,7 +22,6 @@ import com.mob.utsmyanmar.ui.theme.Color
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun AmountScreen(
|
fun AmountScreen(
|
||||||
title: String = "Amount",
|
|
||||||
onBackClick: () -> Unit = {},
|
onBackClick: () -> Unit = {},
|
||||||
onChargeClick: (String) -> Unit = {}
|
onChargeClick: (String) -> Unit = {}
|
||||||
) {
|
) {
|
||||||
@ -60,7 +59,7 @@ fun AmountScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = title,
|
text = "Amount",
|
||||||
color = Color.LegacyRed,
|
color = Color.LegacyRed,
|
||||||
fontSize = 14.sp,
|
fontSize = 14.sp,
|
||||||
fontWeight = FontWeight.Bold
|
fontWeight = FontWeight.Bold
|
||||||
@ -70,7 +69,7 @@ fun AmountScreen(
|
|||||||
Spacer(modifier = Modifier.height(36.dp))
|
Spacer(modifier = Modifier.height(36.dp))
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = "Enter $title",
|
text = "Enter Amount",
|
||||||
color = Color.Gray,
|
color = Color.Gray,
|
||||||
fontSize = 11.sp,
|
fontSize = 11.sp,
|
||||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||||
@ -101,7 +100,7 @@ fun AmountScreen(
|
|||||||
Spacer(modifier = Modifier.height(12.dp))
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = "Enter the amount to continue",
|
text = "Enter the amount to charge",
|
||||||
color = Color.Gray,
|
color = Color.Gray,
|
||||||
fontSize = 11.sp,
|
fontSize = 11.sp,
|
||||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||||
|
|||||||
@ -224,7 +224,7 @@ private fun CardWaitingScreenContent(
|
|||||||
|
|
||||||
Spacer(modifier = Modifier.height(18.dp))
|
Spacer(modifier = Modifier.height(18.dp))
|
||||||
|
|
||||||
// StatusPanel(uiState = uiState)
|
StatusPanel(uiState = uiState)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
|
|||||||
@ -84,7 +84,6 @@ import kotlinx.coroutines.launch
|
|||||||
fun DashboardScreen2(
|
fun DashboardScreen2(
|
||||||
onNavigateAmount: (String) -> Unit = {},
|
onNavigateAmount: (String) -> Unit = {},
|
||||||
onNavigateSignOn: () -> Unit = {},
|
onNavigateSignOn: () -> Unit = {},
|
||||||
onNavigateSeeMore: () -> Unit = {},
|
|
||||||
deviceInfoViewModel: DeviceInfoViewModel = viewModel()
|
deviceInfoViewModel: DeviceInfoViewModel = viewModel()
|
||||||
) {
|
) {
|
||||||
val deviceInfo by deviceInfoViewModel.uiState.collectAsState()
|
val deviceInfo by deviceInfoViewModel.uiState.collectAsState()
|
||||||
@ -92,7 +91,8 @@ fun DashboardScreen2(
|
|||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
deviceInfoViewModel.loadDeviceInfo();
|
deviceInfoViewModel.loadDeviceInfo();
|
||||||
}
|
}
|
||||||
val drawerState = rememberDrawerState(initialValue = androidx.compose.material3.DrawerValue.Closed)
|
val drawerState = rememberDrawerState(initialValue = androidx.compose.material3.DrawerValue.Open) //for preview
|
||||||
|
// val drawerState = rememberDrawerState(initialValue = androidx.compose.material3.DrawerValue.Closed) //for normal usage
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val mainHandler = remember { Handler(Looper.getMainLooper()) }
|
val mainHandler = remember { Handler(Looper.getMainLooper()) }
|
||||||
var showHostActionDialog by remember { mutableStateOf(false) }
|
var showHostActionDialog by remember { mutableStateOf(false) }
|
||||||
@ -300,8 +300,7 @@ fun DashboardScreen2(
|
|||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
MenuGrid(
|
MenuGrid(
|
||||||
onNavigateAmount = onNavigateAmount,
|
onNavigateAmount = onNavigateAmount,
|
||||||
onNavigateSignOn = onNavigateSignOn,
|
onNavigateSignOn = onNavigateSignOn
|
||||||
onNavigateSeeMore = onNavigateSeeMore
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -495,8 +494,7 @@ private fun IconCircle(
|
|||||||
@Composable
|
@Composable
|
||||||
private fun MenuGrid(
|
private fun MenuGrid(
|
||||||
onNavigateAmount: (String) -> Unit,
|
onNavigateAmount: (String) -> Unit,
|
||||||
onNavigateSignOn: () -> Unit,
|
onNavigateSignOn: () -> Unit
|
||||||
onNavigateSeeMore: () -> Unit
|
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||||
@ -521,12 +519,7 @@ private fun MenuGrid(
|
|||||||
onClick = onNavigateSignOn
|
onClick = onNavigateSignOn
|
||||||
)
|
)
|
||||||
MenuCard("Settlement", Icons.Default.Wallet, Modifier.weight(1f))
|
MenuCard("Settlement", Icons.Default.Wallet, Modifier.weight(1f))
|
||||||
MenuCard(
|
MenuCard("See More", Icons.Default.GridView, Modifier.weight(1f))
|
||||||
"See More",
|
|
||||||
Icons.Default.GridView,
|
|
||||||
Modifier.weight(1f),
|
|
||||||
onClick = onNavigateSeeMore
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,141 +0,0 @@
|
|||||||
package com.mob.utsmyanmar.ui.dashboard
|
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.grid.GridCells
|
|
||||||
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
|
|
||||||
import androidx.compose.foundation.lazy.grid.items
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
|
||||||
import androidx.compose.material.icons.filled.AccountBalanceWallet
|
|
||||||
import androidx.compose.material.icons.filled.CreditCard
|
|
||||||
import androidx.compose.material.icons.filled.Lock
|
|
||||||
import androidx.compose.material.icons.filled.LockOpen
|
|
||||||
import androidx.compose.material.icons.filled.Replay
|
|
||||||
import androidx.compose.material.icons.filled.SwapHoriz
|
|
||||||
import androidx.compose.material.icons.filled.Undo
|
|
||||||
import androidx.compose.material3.Card
|
|
||||||
import androidx.compose.material3.CardDefaults
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
|
||||||
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.components.appbar.AppBar
|
|
||||||
import com.mob.utsmyanmar.ui.preview.P2Preview
|
|
||||||
import com.mob.utsmyanmar.ui.theme.Color
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SeeMoreScreen(
|
|
||||||
onBack: () -> Unit = {},
|
|
||||||
onNavigateAmount: (String) -> Unit = {}
|
|
||||||
) {
|
|
||||||
val items = listOf(
|
|
||||||
SeeMoreItem("Void", Icons.Default.Undo),
|
|
||||||
SeeMoreItem("Refund", Icons.Default.Replay),
|
|
||||||
SeeMoreItem("Pre-Auth", Icons.Default.Lock),
|
|
||||||
SeeMoreItem("Pre-Auth Void", Icons.Default.LockOpen),
|
|
||||||
SeeMoreItem("Pre-Auth Complete", Icons.Default.CreditCard),
|
|
||||||
SeeMoreItem("Pre-Auth Complete Void", Icons.Default.SwapHoriz),
|
|
||||||
SeeMoreItem("Cash Out", Icons.Default.AccountBalanceWallet)
|
|
||||||
)
|
|
||||||
|
|
||||||
Scaffold(
|
|
||||||
containerColor = Color.IvoryBeige,
|
|
||||||
topBar = {
|
|
||||||
AppBar(
|
|
||||||
title = "See More",
|
|
||||||
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
|
||||||
onIconClick = onBack
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { paddingValues ->
|
|
||||||
LazyVerticalGrid(
|
|
||||||
columns = GridCells.Fixed(2),
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(paddingValues),
|
|
||||||
contentPadding = PaddingValues(16.dp),
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
|
||||||
) {
|
|
||||||
items(items) { item ->
|
|
||||||
MoreMenuCard(
|
|
||||||
title = item.title,
|
|
||||||
icon = item.icon,
|
|
||||||
onClick = { onNavigateAmount(item.title) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun MoreMenuCard(
|
|
||||||
title: String,
|
|
||||||
icon: ImageVector,
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
Card(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.height(132.dp)
|
|
||||||
.clickable(onClick = onClick),
|
|
||||||
shape = RoundedCornerShape(18.dp),
|
|
||||||
colors = CardDefaults.cardColors(containerColor = Color.White),
|
|
||||||
elevation = CardDefaults.cardElevation(4.dp)
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(14.dp),
|
|
||||||
verticalArrangement = Arrangement.SpaceBetween
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.background(Color.CrimsonRed, RoundedCornerShape(14.dp))
|
|
||||||
.padding(12.dp)
|
|
||||||
) {
|
|
||||||
Icon(
|
|
||||||
imageVector = icon,
|
|
||||||
contentDescription = title,
|
|
||||||
tint = Color.White
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = title,
|
|
||||||
color = Color.Black,
|
|
||||||
fontSize = 14.sp,
|
|
||||||
fontWeight = FontWeight.SemiBold,
|
|
||||||
textAlign = TextAlign.Start
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private data class SeeMoreItem(
|
|
||||||
val title: String,
|
|
||||||
val icon: ImageVector
|
|
||||||
)
|
|
||||||
|
|
||||||
@P2Preview
|
|
||||||
@Composable
|
|
||||||
private fun PreviewSeeMoreScreen() {
|
|
||||||
SeeMoreScreen()
|
|
||||||
}
|
|
||||||
@ -15,7 +15,6 @@ import com.mob.utsmyanmar.ui.amount.AmountRoute
|
|||||||
import com.mob.utsmyanmar.ui.cardwaiting.CardWaitingScreen
|
import com.mob.utsmyanmar.ui.cardwaiting.CardWaitingScreen
|
||||||
import com.mob.utsmyanmar.ui.cardwaiting.CardWaitingViewModel
|
import com.mob.utsmyanmar.ui.cardwaiting.CardWaitingViewModel
|
||||||
import com.mob.utsmyanmar.ui.dashboard.DashboardScreen2
|
import com.mob.utsmyanmar.ui.dashboard.DashboardScreen2
|
||||||
import com.mob.utsmyanmar.ui.dashboard.SeeMoreScreen
|
|
||||||
import com.mob.utsmyanmar.ui.pinpad.PinPadRoute
|
import com.mob.utsmyanmar.ui.pinpad.PinPadRoute
|
||||||
import com.mob.utsmyanmar.ui.processing_card.ProcessingCardRoute
|
import com.mob.utsmyanmar.ui.processing_card.ProcessingCardRoute
|
||||||
import com.mob.utsmyanmar.ui.processing_card.ProcessingCardViewModel
|
import com.mob.utsmyanmar.ui.processing_card.ProcessingCardViewModel
|
||||||
@ -24,8 +23,6 @@ import com.mob.utsmyanmar.ui.sign_on.SignOnResultScreen
|
|||||||
import com.mob.utsmyanmar.ui.sign_on.SignOnRoute
|
import com.mob.utsmyanmar.ui.sign_on.SignOnRoute
|
||||||
import com.mob.utsmyanmar.ui.sending_to_host.SendingToHostRoute
|
import com.mob.utsmyanmar.ui.sending_to_host.SendingToHostRoute
|
||||||
import com.mob.utsmyanmar.ui.transaction_result.TransactionResultRoute
|
import com.mob.utsmyanmar.ui.transaction_result.TransactionResultRoute
|
||||||
import com.mob.utsmyanmar.ui.sale_void.VoidViewModel
|
|
||||||
import com.mob.utsmyanmar.ui.sale_void.VoidTraceScreen
|
|
||||||
import com.mob.utsmyanmar.viewmodel.CardReaderViewModel
|
import com.mob.utsmyanmar.viewmodel.CardReaderViewModel
|
||||||
import com.mob.utsmyanmar.viewmodel.EmvTransactionProcessViewModel
|
import com.mob.utsmyanmar.viewmodel.EmvTransactionProcessViewModel
|
||||||
import com.mob.utsmyanmar.ui.pinpad.PinPadViewModel
|
import com.mob.utsmyanmar.ui.pinpad.PinPadViewModel
|
||||||
@ -57,41 +54,10 @@ fun AppNavGraph(
|
|||||||
navController.navigate(Routes.SignOn.route) {
|
navController.navigate(Routes.SignOn.route) {
|
||||||
launchSingleTop = true
|
launchSingleTop = true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
onNavigateSeeMore = {
|
|
||||||
navController.navigate(Routes.SeeMore.route) {
|
|
||||||
launchSingleTop = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
composable(Routes.SeeMore.route) {
|
|
||||||
SeeMoreScreen(
|
|
||||||
onBack = { navController.popBackStack() },
|
|
||||||
onNavigateAmount = { action ->
|
|
||||||
if (action == "Void") {
|
|
||||||
navController.navigate(Routes.VoidTrace.route) {
|
|
||||||
launchSingleTop = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
navController.navigate(Routes.Amount.createRoute(action)) {
|
|
||||||
launchSingleTop = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
composable(Routes.VoidTrace.route) {
|
|
||||||
val voidViewModel: VoidViewModel = hiltViewModel()
|
|
||||||
|
|
||||||
VoidTraceScreen(
|
|
||||||
voidViewModel = voidViewModel,
|
|
||||||
onBack = { navController.popBackStack() }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
composable(Routes.SignOn.route) {
|
composable(Routes.SignOn.route) {
|
||||||
SignOnRoute(
|
SignOnRoute(
|
||||||
onBack = { navController.popBackStack() },
|
onBack = { navController.popBackStack() },
|
||||||
@ -221,7 +187,6 @@ fun AppNavGraph(
|
|||||||
ProcessingCardRoute(
|
ProcessingCardRoute(
|
||||||
viewModel = processingCardViewModel,
|
viewModel = processingCardViewModel,
|
||||||
onNavigatePinPad = {
|
onNavigatePinPad = {
|
||||||
pinPadViewModel.resetSessionState()
|
|
||||||
navController.navigate(Routes.PinPad.route) {
|
navController.navigate(Routes.PinPad.route) {
|
||||||
popUpTo(Routes.ProcessingCard.route) {
|
popUpTo(Routes.ProcessingCard.route) {
|
||||||
inclusive = true
|
inclusive = true
|
||||||
@ -260,10 +225,7 @@ fun AppNavGraph(
|
|||||||
}
|
}
|
||||||
|
|
||||||
composable(Routes.SendingToHost.route) {
|
composable(Routes.SendingToHost.route) {
|
||||||
val sharedViewModel: SharedViewModel = hiltViewModel(activity)
|
|
||||||
|
|
||||||
SendingToHostRoute(
|
SendingToHostRoute(
|
||||||
sharedViewModel = sharedViewModel,
|
|
||||||
onNavigateTransactionResult = {
|
onNavigateTransactionResult = {
|
||||||
navController.navigate(Routes.TransactionResult.route) {
|
navController.navigate(Routes.TransactionResult.route) {
|
||||||
popUpTo(Routes.SendingToHost.route) {
|
popUpTo(Routes.SendingToHost.route) {
|
||||||
|
|||||||
@ -5,10 +5,8 @@ import android.net.Uri
|
|||||||
sealed class Routes(val route: String) {
|
sealed class Routes(val route: String) {
|
||||||
data object Dashboard : Routes("dashboard")
|
data object Dashboard : Routes("dashboard")
|
||||||
data object Amount : Routes("amount/{action}") {
|
data object Amount : Routes("amount/{action}") {
|
||||||
fun createRoute(action: String): String = "amount/${Uri.encode(action)}"
|
fun createRoute(action: String): String = "amount/$action"
|
||||||
}
|
}
|
||||||
data object SeeMore : Routes("see_more")
|
|
||||||
data object VoidTrace : Routes("void_trace")
|
|
||||||
data object SignOn : Routes("sign_on")
|
data object SignOn : Routes("sign_on")
|
||||||
data object SignOnResult : Routes("sign_on_result/{isSuccess}/{message}") {
|
data object SignOnResult : Routes("sign_on_result/{isSuccess}/{message}") {
|
||||||
fun createRoute(isSuccess: Boolean, message: String): String {
|
fun createRoute(isSuccess: Boolean, message: String): String {
|
||||||
|
|||||||
@ -83,7 +83,6 @@ class PinPadViewModel @Inject constructor(
|
|||||||
MutableStateFlow<PinPadStatus?>(null)
|
MutableStateFlow<PinPadStatus?>(null)
|
||||||
|
|
||||||
val pinStatus = _pinStatus.asStateFlow()
|
val pinStatus = _pinStatus.asStateFlow()
|
||||||
private var isTerminalStateReached = false
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Trade Data
|
* Trade Data
|
||||||
@ -117,14 +116,6 @@ class PinPadViewModel @Inject constructor(
|
|||||||
_transType.value = type
|
_transType.value = type
|
||||||
}
|
}
|
||||||
|
|
||||||
fun resetSessionState() {
|
|
||||||
_pinText.value = ""
|
|
||||||
_alertMsg.value = null
|
|
||||||
_errorCode.value = null
|
|
||||||
_pinStatus.value = null
|
|
||||||
isTerminalStateReached = false
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pin Pad
|
* Pin Pad
|
||||||
*/
|
*/
|
||||||
@ -132,8 +123,7 @@ class PinPadViewModel @Inject constructor(
|
|||||||
fun startPinPadProcess(
|
fun startPinPadProcess(
|
||||||
customPinPadKeyboard: CustomPinPadKeyboard
|
customPinPadKeyboard: CustomPinPadKeyboard
|
||||||
) {
|
) {
|
||||||
resetSessionState()
|
|
||||||
|
|
||||||
// dukptIndex = SystemParamsOperation.getInstance().tmkIndex.toInt()
|
// dukptIndex = SystemParamsOperation.getInstance().tmkIndex.toInt()
|
||||||
if(!sunmiPayManager.isReady()){
|
if(!sunmiPayManager.isReady()){
|
||||||
_alertMsg.value =
|
_alertMsg.value =
|
||||||
@ -180,10 +170,8 @@ class PinPadViewModel @Inject constructor(
|
|||||||
|
|
||||||
fun cancelPinPad() {
|
fun cancelPinPad() {
|
||||||
try {
|
try {
|
||||||
if (!isTerminalStateReached) {
|
mPinPadOptV2?.cancelInputPin()
|
||||||
mPinPadOptV2?.cancelInputPin()
|
Log.d(TAG, "PinPad Canceled")
|
||||||
Log.d(TAG, "PinPad Canceled")
|
|
||||||
}
|
|
||||||
} catch (e: RemoteException) {
|
} catch (e: RemoteException) {
|
||||||
throw RuntimeException(e)
|
throw RuntimeException(e)
|
||||||
}
|
}
|
||||||
@ -405,21 +393,17 @@ class PinPadViewModel @Inject constructor(
|
|||||||
|
|
||||||
ON_CONFIRM_CLICK -> {
|
ON_CONFIRM_CLICK -> {
|
||||||
LogUtil.d(TAG, "ON CLICK CONFIRM")
|
LogUtil.d(TAG, "ON CLICK CONFIRM")
|
||||||
isTerminalStateReached = true
|
|
||||||
_pinStatus.value = PinPadStatus.ON_CONFIRM
|
_pinStatus.value = PinPadStatus.ON_CONFIRM
|
||||||
}
|
}
|
||||||
|
|
||||||
ON_CANCEL_CLICK -> {
|
ON_CANCEL_CLICK -> {
|
||||||
LogUtil.d(TAG, "ON CLICK CANCEL")
|
LogUtil.d(TAG, "ON CLICK CANCEL")
|
||||||
if (!isTerminalStateReached) {
|
_pinStatus.value = PinPadStatus.ON_CANCEL
|
||||||
_pinStatus.value = PinPadStatus.ON_CANCEL
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ON_ERROR_PIN_PAD -> {
|
ON_ERROR_PIN_PAD -> {
|
||||||
LogUtil.d(TAG, "ON ERROR CODE: ${msg.arg1}")
|
LogUtil.d(TAG, "ON ERROR CODE: ${msg.arg1}")
|
||||||
_errorCode.value = msg.arg1
|
_errorCode.value = msg.arg1
|
||||||
isTerminalStateReached = true
|
|
||||||
_pinStatus.value = PinPadStatus.ON_ERROR
|
_pinStatus.value = PinPadStatus.ON_ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,13 +412,11 @@ class PinPadViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
ON_TIMEOUT_PIN_PAD -> {
|
ON_TIMEOUT_PIN_PAD -> {
|
||||||
isTerminalStateReached = true
|
|
||||||
_pinStatus.value = PinPadStatus.ON_TIMEOUT
|
_pinStatus.value = PinPadStatus.ON_TIMEOUT
|
||||||
}
|
}
|
||||||
|
|
||||||
ON_ERROR_DUKPT -> {
|
ON_ERROR_DUKPT -> {
|
||||||
_alertMsg.value = "Try Again!"
|
_alertMsg.value = "Try Again!"
|
||||||
isTerminalStateReached = true
|
|
||||||
_pinStatus.value = PinPadStatus.ON_ERROR_DUKPT
|
_pinStatus.value = PinPadStatus.ON_ERROR_DUKPT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -476,7 +458,6 @@ class PinPadViewModel @Inject constructor(
|
|||||||
payDetail?.cardType == -9
|
payDetail?.cardType == -9
|
||||||
|
|
||||||
if (!isCardValid) {
|
if (!isCardValid) {
|
||||||
isTerminalStateReached = true
|
|
||||||
_pinStatus.value = PinPadStatus.ON_CARD_REMOVED
|
_pinStatus.value = PinPadStatus.ON_CARD_REMOVED
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -492,7 +473,6 @@ class PinPadViewModel @Inject constructor(
|
|||||||
transType.value == TransactionsType.PRE_AUTH_VOID ||
|
transType.value == TransactionsType.PRE_AUTH_VOID ||
|
||||||
transType.value == TransactionsType.REFUND
|
transType.value == TransactionsType.REFUND
|
||||||
) {
|
) {
|
||||||
isTerminalStateReached = true
|
|
||||||
_pinStatus.value = PinPadStatus.ON_NEXT_SCREEN
|
_pinStatus.value = PinPadStatus.ON_NEXT_SCREEN
|
||||||
} else {
|
} else {
|
||||||
handler.obtainMessage(
|
handler.obtainMessage(
|
||||||
@ -502,11 +482,9 @@ class PinPadViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onCancel() {
|
override fun onCancel() {
|
||||||
if (!isTerminalStateReached) {
|
handler.obtainMessage(
|
||||||
handler.obtainMessage(
|
ON_CANCEL_CLICK
|
||||||
ON_CANCEL_CLICK
|
).sendToTarget()
|
||||||
).sendToTarget()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onError(code: Int) {
|
override fun onError(code: Int) {
|
||||||
|
|||||||
@ -1,356 +0,0 @@
|
|||||||
package com.mob.utsmyanmar.ui.sale_void
|
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
|
||||||
import androidx.compose.material.icons.rounded.Backspace
|
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.ButtonDefaults
|
|
||||||
import androidx.compose.material3.Card
|
|
||||||
import androidx.compose.material3.CardDefaults
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.shadow
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import com.mob.utsmyanmar.ui.components.appbar.AppBar
|
|
||||||
import com.mob.utsmyanmar.ui.theme.Color
|
|
||||||
import com.utsmyanmar.paylibs.model.PayDetail
|
|
||||||
import com.utsmyanmar.paylibs.utils.POSUtil
|
|
||||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun VoidTraceScreen(
|
|
||||||
voidViewModel: VoidViewModel,
|
|
||||||
onBack: () -> Unit = {}
|
|
||||||
) {
|
|
||||||
val tag = "VoidTraceScreen"
|
|
||||||
var traceNumber by remember { mutableStateOf("") }
|
|
||||||
var searchedTrace by remember { mutableStateOf("") }
|
|
||||||
val recentTransactions by voidViewModel.getLastThreeTransactions().observeAsState(emptyList())
|
|
||||||
|
|
||||||
val transactionSource: LiveData<PayDetail?> = remember(searchedTrace) {
|
|
||||||
if (searchedTrace.isBlank()) {
|
|
||||||
MutableLiveData<PayDetail?>(null)
|
|
||||||
} else {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
voidViewModel.getVoidTrans(
|
|
||||||
TransactionsType.SALE.value,
|
|
||||||
searchedTrace
|
|
||||||
) as LiveData<PayDetail?>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val transaction by transactionSource.observeAsState()
|
|
||||||
val hasSearched = searchedTrace.isNotBlank()
|
|
||||||
val headerMessage = if (hasSearched && transaction == null) {
|
|
||||||
"Warning: no previous sale transaction found for trace $searchedTrace."
|
|
||||||
} else {
|
|
||||||
"Input trace number to find previous sale transaction."
|
|
||||||
}
|
|
||||||
val headerColor = if (hasSearched && transaction == null) {
|
|
||||||
Color.LegacyRed
|
|
||||||
} else {
|
|
||||||
Color.Black
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LaunchedEffect(searchedTrace, transaction) {
|
|
||||||
Log.d(
|
|
||||||
tag,
|
|
||||||
"Recent DB traces: ${
|
|
||||||
recentTransactions.joinToString { detail ->
|
|
||||||
"${detail.voucherNo}:${detail.transType}:${detail.tradeAnswerCode}"
|
|
||||||
}
|
|
||||||
}"
|
|
||||||
)
|
|
||||||
if (searchedTrace.isNotBlank()) {
|
|
||||||
Log.d(
|
|
||||||
tag,
|
|
||||||
"Search trace=$searchedTrace result=${transaction?.voucherNo ?: "NOT_FOUND"}"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Scaffold(
|
|
||||||
containerColor = Color.IvoryBeige,
|
|
||||||
topBar = {
|
|
||||||
AppBar(
|
|
||||||
title = "Void",
|
|
||||||
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
|
||||||
onIconClick = onBack
|
|
||||||
)
|
|
||||||
}
|
|
||||||
) { paddingValues ->
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(paddingValues)
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxSize()
|
|
||||||
.padding(horizontal = 16.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = headerMessage,
|
|
||||||
color = headerColor,
|
|
||||||
fontSize = 14.sp
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(28.dp))
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = "Trace Number",
|
|
||||||
color = Color.Gray,
|
|
||||||
fontSize = 11.sp,
|
|
||||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = traceNumber.ifEmpty { "000000" },
|
|
||||||
color = Color.LegacyRed,
|
|
||||||
fontSize = 32.sp,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
|
||||||
|
|
||||||
Text(
|
|
||||||
text = "Enter 6-digit trace number",
|
|
||||||
color = Color.Gray,
|
|
||||||
fontSize = 11.sp,
|
|
||||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
|
||||||
|
|
||||||
TraceNumberKeypad(
|
|
||||||
onNumberClick = { value ->
|
|
||||||
if (traceNumber.length < 6) {
|
|
||||||
traceNumber = (traceNumber + value).take(6)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(20.dp))
|
|
||||||
|
|
||||||
Column(modifier = Modifier.weight(1f)) {
|
|
||||||
if (transaction != null) {
|
|
||||||
TransactionDetailsCard(transaction = transaction!!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(bottom = 18.dp),
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
|
||||||
) {
|
|
||||||
Button(
|
|
||||||
onClick = onBack,
|
|
||||||
modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.height(56.dp),
|
|
||||||
shape = RoundedCornerShape(8.dp),
|
|
||||||
colors = ButtonDefaults.buttonColors(
|
|
||||||
containerColor = Color.White,
|
|
||||||
contentColor = Color.LegacyRed
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
Text("Cancel")
|
|
||||||
}
|
|
||||||
|
|
||||||
Button(
|
|
||||||
onClick = {
|
|
||||||
searchedTrace = traceNumber
|
|
||||||
},
|
|
||||||
modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.height(56.dp),
|
|
||||||
enabled = traceNumber.isNotBlank(),
|
|
||||||
shape = RoundedCornerShape(8.dp),
|
|
||||||
colors = ButtonDefaults.buttonColors(
|
|
||||||
containerColor = Color.LegacyRed,
|
|
||||||
contentColor = Color.White,
|
|
||||||
disabledContainerColor = Color.LegacyRed.copy(alpha = 0.5f),
|
|
||||||
disabledContentColor = Color.White
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
Text("Enter")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Card(
|
|
||||||
modifier = Modifier
|
|
||||||
.align(Alignment.TopEnd)
|
|
||||||
.padding(top = 110.dp, end = 16.dp)
|
|
||||||
.clickable(enabled = traceNumber.isNotEmpty()) {
|
|
||||||
traceNumber = traceNumber.dropLast(1)
|
|
||||||
},
|
|
||||||
shape = RoundedCornerShape(18.dp),
|
|
||||||
colors = CardDefaults.cardColors(containerColor = Color.White),
|
|
||||||
elevation = CardDefaults.cardElevation(defaultElevation = 6.dp)
|
|
||||||
) {
|
|
||||||
androidx.compose.material3.Icon(
|
|
||||||
imageVector = Icons.Rounded.Backspace,
|
|
||||||
contentDescription = "Delete",
|
|
||||||
tint = if (traceNumber.isNotEmpty()) Color.LegacyRed else Color.Gray,
|
|
||||||
modifier = Modifier.padding(horizontal = 14.dp, vertical = 12.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TraceNumberKeypad(
|
|
||||||
onNumberClick: (String) -> Unit
|
|
||||||
) {
|
|
||||||
val keys = listOf(
|
|
||||||
listOf("1", "2", "3"),
|
|
||||||
listOf("4", "5", "6"),
|
|
||||||
listOf("7", "8", "9"),
|
|
||||||
listOf("", "0", "00")
|
|
||||||
)
|
|
||||||
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(6.dp)
|
|
||||||
) {
|
|
||||||
keys.forEach { row ->
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
horizontalArrangement = Arrangement.spacedBy(6.dp)
|
|
||||||
) {
|
|
||||||
row.forEach { key ->
|
|
||||||
if (key.isBlank()) {
|
|
||||||
Spacer(
|
|
||||||
modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.height(66.dp)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
TraceKeypadButton(
|
|
||||||
text = key,
|
|
||||||
modifier = Modifier.weight(1f),
|
|
||||||
onClick = { onNumberClick(key) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TraceKeypadButton(
|
|
||||||
text: String,
|
|
||||||
modifier: Modifier = Modifier,
|
|
||||||
onClick: () -> Unit
|
|
||||||
) {
|
|
||||||
Box(
|
|
||||||
modifier = modifier
|
|
||||||
.height(66.dp)
|
|
||||||
.shadow(
|
|
||||||
elevation = 2.dp,
|
|
||||||
shape = RoundedCornerShape(8.dp),
|
|
||||||
clip = false
|
|
||||||
)
|
|
||||||
.background(
|
|
||||||
color = Color.White,
|
|
||||||
shape = RoundedCornerShape(8.dp)
|
|
||||||
)
|
|
||||||
.clickable { onClick() },
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = text,
|
|
||||||
color = Color.LegacyRed,
|
|
||||||
fontSize = 24.sp,
|
|
||||||
fontWeight = FontWeight.Normal,
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun TransactionDetailsCard(transaction: PayDetail) {
|
|
||||||
Card(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
colors = CardDefaults.cardColors(containerColor = Color.White)
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
modifier = Modifier.padding(16.dp),
|
|
||||||
verticalArrangement = Arrangement.spacedBy(10.dp)
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = "Previous Sale",
|
|
||||||
color = Color.LegacyRed,
|
|
||||||
fontWeight = FontWeight.Bold,
|
|
||||||
fontSize = 16.sp
|
|
||||||
)
|
|
||||||
|
|
||||||
DetailRow("Trace", transaction.voucherNo)
|
|
||||||
DetailRow("Amount", POSUtil.getInstance().formatAmount(transaction.amount))
|
|
||||||
DetailRow("Card No", transaction.cardNo)
|
|
||||||
DetailRow("Reference", transaction.referNo)
|
|
||||||
DetailRow("Approval", transaction.approvalCode.orEmpty())
|
|
||||||
DetailRow("Date", transaction.tradeDate)
|
|
||||||
DetailRow("Time", transaction.tradeTime)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
private fun DetailRow(
|
|
||||||
label: String,
|
|
||||||
value: String
|
|
||||||
) {
|
|
||||||
Row(
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
horizontalArrangement = Arrangement.SpaceBetween
|
|
||||||
) {
|
|
||||||
Text(
|
|
||||||
text = label,
|
|
||||||
color = Color.Gray,
|
|
||||||
fontSize = 13.sp
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = value.ifBlank { "-" },
|
|
||||||
color = Color.Black,
|
|
||||||
fontSize = 13.sp,
|
|
||||||
fontWeight = FontWeight.Medium
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
package com.mob.utsmyanmar.ui.sale_void
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.Observer
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import com.utsmyanmar.baselib.repo.Repository
|
|
||||||
import com.utsmyanmar.paylibs.model.PayDetail
|
|
||||||
import com.utsmyanmar.paylibs.system.SingleLiveEvent
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
@HiltViewModel
|
|
||||||
class VoidViewModel @Inject constructor(
|
|
||||||
private val repository: Repository
|
|
||||||
) : ViewModel() {
|
|
||||||
|
|
||||||
val inputTrace = SingleLiveEvent<String>()
|
|
||||||
val lists = SingleLiveEvent<List<PayDetail>>()
|
|
||||||
|
|
||||||
fun getVoidTransactions(transType: Int): LiveData<List<PayDetail>> {
|
|
||||||
return repository.getVoidableTransactions(transType)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getGenericVoidTransactions(
|
|
||||||
transType: Int,
|
|
||||||
voucherNo: String,
|
|
||||||
isEmv: Boolean
|
|
||||||
): LiveData<PayDetail> {
|
|
||||||
return repository.getGenericVoidTransaction(transType, voucherNo, isEmv)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getVoidTrans(transType: Int, voucherNo: String): LiveData<PayDetail> {
|
|
||||||
return repository.getVoidTransaction(transType, voucherNo)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun observeVoidTrans(transType: Int) {
|
|
||||||
getVoidTransactions(transType).observeForever(object : Observer<List<PayDetail>> {
|
|
||||||
override fun onChanged(payDetails: List<PayDetail>) {
|
|
||||||
if (lists.value == null) {
|
|
||||||
lists.postValue(payDetails)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fun searchTransaction(voucherNo: String): LiveData<PayDetail> {
|
|
||||||
return repository.searchTransaction(voucherNo)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLastThreeTransactions(): LiveData<List<PayDetail>> {
|
|
||||||
return repository.getLastThreeTransactions()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -2,18 +2,15 @@ package com.mob.utsmyanmar.ui.sending_to_host
|
|||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import com.mob.utsmyanmar.viewmodel.SharedViewModel
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
|
|
||||||
private const val MOCK_HOST_DELAY_MS = 2000L
|
private const val MOCK_HOST_DELAY_MS = 2000L
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SendingToHostRoute(
|
fun SendingToHostRoute(
|
||||||
sharedViewModel: SharedViewModel,
|
|
||||||
onNavigateTransactionResult: () -> Unit
|
onNavigateTransactionResult: () -> Unit
|
||||||
) {
|
) {
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
sharedViewModel.saveMockApprovedSaleForVoidTesting()
|
|
||||||
delay(MOCK_HOST_DELAY_MS)
|
delay(MOCK_HOST_DELAY_MS)
|
||||||
onNavigateTransactionResult()
|
onNavigateTransactionResult()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,12 +14,10 @@ import com.utsmyanmar.paylibs.model.PayDetail
|
|||||||
import com.utsmyanmar.paylibs.print.printx.PrintXReceipt
|
import com.utsmyanmar.paylibs.print.printx.PrintXReceipt
|
||||||
import com.utsmyanmar.paylibs.print.printx.PrintXStatus
|
import com.utsmyanmar.paylibs.print.printx.PrintXStatus
|
||||||
import com.utsmyanmar.paylibs.system.SingleLiveEvent
|
import com.utsmyanmar.paylibs.system.SingleLiveEvent
|
||||||
import com.utsmyanmar.paylibs.system.SystemDateTime
|
|
||||||
import com.utsmyanmar.paylibs.utils.AccountType
|
import com.utsmyanmar.paylibs.utils.AccountType
|
||||||
import com.utsmyanmar.paylibs.utils.PrintStatus
|
import com.utsmyanmar.paylibs.utils.PrintStatus
|
||||||
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
||||||
import com.utsmyanmar.paylibs.utils.enums.HostType
|
import com.utsmyanmar.paylibs.utils.enums.HostType
|
||||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionType
|
|
||||||
import com.utsmyanmar.paylibs.utils.enums.TransMenu
|
import com.utsmyanmar.paylibs.utils.enums.TransMenu
|
||||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
@ -443,45 +441,6 @@ class SharedViewModel @Inject constructor(
|
|||||||
repository.insertPayDetail(payDetail)
|
repository.insertPayDetail(payDetail)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun saveMockApprovedSaleForVoidTesting() {
|
|
||||||
val detail = payDetail.value ?: return
|
|
||||||
|
|
||||||
val systemParams = SystemParamsOperation.getInstance()
|
|
||||||
val mockTraceNo = systemParams.incrementSerialNum
|
|
||||||
val mockInvoiceNo = systemParams.incrementInvoiceNum
|
|
||||||
val mockApprovalCode = mockTraceNo.takeLast(6).padStart(6, '0')
|
|
||||||
val mockReferenceNo = buildString {
|
|
||||||
append(SystemDateTime.getYYMMDD())
|
|
||||||
append(SystemDateTime.getHHmmss())
|
|
||||||
}.takeLast(12)
|
|
||||||
|
|
||||||
detail.voucherNo = mockTraceNo
|
|
||||||
detail.invoiceNo = mockInvoiceNo
|
|
||||||
detail.referNo = mockReferenceNo
|
|
||||||
detail.approvalCode = mockApprovalCode
|
|
||||||
detail.authNo = mockApprovalCode
|
|
||||||
detail.tradeAnswerCode = "00"
|
|
||||||
detail.tradeResultDes = "MOCK APPROVED"
|
|
||||||
detail.transactionType = TransactionType.SALE
|
|
||||||
detail.transType = TransactionsType.SALE.name
|
|
||||||
detail.isCanceled = false
|
|
||||||
detail.isSettle = false
|
|
||||||
detail.isNeedReversal = false
|
|
||||||
detail.isReturnGood = false
|
|
||||||
detail.TradeDate = SystemDateTime.getMMDD()
|
|
||||||
detail.TradeTime = SystemDateTime.getHHmmss()
|
|
||||||
detail.tradeDateAndTime = SystemDateTime.getMMDDhhmmss()
|
|
||||||
detail.tradeDateTime = SystemDateTime.getYYMMDDhhmmss()
|
|
||||||
detail.transDate = SystemDateTime.getTodayDateFormat()
|
|
||||||
detail.transTime = SystemDateTime.getTodayTimeFormat()
|
|
||||||
|
|
||||||
repository.insertPayDetail(detail)
|
|
||||||
payDetail.value = detail
|
|
||||||
traceNo.value = mockTraceNo
|
|
||||||
rrNNo.value = mockReferenceNo
|
|
||||||
approvalCode.value = mockApprovalCode
|
|
||||||
}
|
|
||||||
|
|
||||||
fun enableCardStatusIcon(
|
fun enableCardStatusIcon(
|
||||||
tapCard: Boolean,
|
tapCard: Boolean,
|
||||||
tapDevice: Boolean,
|
tapDevice: Boolean,
|
||||||
|
|||||||
@ -60,7 +60,7 @@ public class DatabaseModule {
|
|||||||
private static final String DATABASE_KEY_ALIAS = "RoomDatabaseKeyAlias"; // Alias for the database key in Android Keystore
|
private static final String DATABASE_KEY_ALIAS = "RoomDatabaseKeyAlias"; // Alias for the database key in Android Keystore
|
||||||
private static final String ANDROID_KEYSTORE = "AndroidKeyStore";
|
private static final String ANDROID_KEYSTORE = "AndroidKeyStore";
|
||||||
|
|
||||||
private static final String DATABASE_NAME = "mob";
|
private static final String DATABASE_NAME = "yoma";
|
||||||
|
|
||||||
static final Migration MIGRATION_7_8 = new Migration(7, 8) {
|
static final Migration MIGRATION_7_8 = new Migration(7, 8) {
|
||||||
@Override
|
@Override
|
||||||
@ -422,6 +422,67 @@ public class DatabaseModule {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
// if (INSTANCE == null) {
|
||||||
|
// synchronized (AppDatabase.class) {
|
||||||
|
// if (INSTANCE == null) {
|
||||||
|
// try {
|
||||||
|
// // Step 1: Try to get the database key
|
||||||
|
// byte[] databaseKey = getDatabaseKey(application.getApplicationContext());
|
||||||
|
//
|
||||||
|
// // Create the SQLCipher factory with the key
|
||||||
|
// SupportSQLiteOpenHelper.Factory factory = new SupportFactory(databaseKey);
|
||||||
|
//
|
||||||
|
// // Try to build and open the database
|
||||||
|
// try {
|
||||||
|
// INSTANCE = Room.databaseBuilder(application,
|
||||||
|
// AppDatabase.class, DATABASE_NAME)
|
||||||
|
// .openHelperFactory(factory)
|
||||||
|
// .addMigrations(MIGRATION_7_8)
|
||||||
|
// .addMigrations(MIGRATION_8_9)
|
||||||
|
// .addMigrations(MIGRATION_9_10)
|
||||||
|
// .addMigrations(MIGRATION_10_11)
|
||||||
|
// .addMigrations(MIGRATION_11_12)
|
||||||
|
// .allowMainThreadQueries()
|
||||||
|
// .build();
|
||||||
|
//
|
||||||
|
// // Validate the database connection by performing a simple query
|
||||||
|
// // This will throw an exception if the key is wrong
|
||||||
|
// INSTANCE.getOpenHelper().getWritableDatabase();
|
||||||
|
// LogUtil.d("Database", "Database opened successfully with encryption key");
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// LogUtil.e("Database", "Error opening encrypted database: " + e.getMessage()+ e);
|
||||||
|
//
|
||||||
|
// // The key might be wrong - check if this is a first-time issue or a key mismatch
|
||||||
|
// if (isDatabaseFileCorruptOrWrongKey(application)) {
|
||||||
|
// LogUtil.w("Database", "Database file exists but can't be opened with current key. Recreating database.");
|
||||||
|
//
|
||||||
|
// // Delete the existing database file
|
||||||
|
// handleDatabaseRecreation(application);
|
||||||
|
//
|
||||||
|
// // Create a new database with the current key
|
||||||
|
// INSTANCE = Room.databaseBuilder(application,
|
||||||
|
// AppDatabase.class, DATABASE_NAME)
|
||||||
|
// .openHelperFactory(factory)
|
||||||
|
// .addMigrations(MIGRATION_7_8)
|
||||||
|
// .addMigrations(MIGRATION_8_9)
|
||||||
|
// .addMigrations(MIGRATION_9_10)
|
||||||
|
// .addMigrations(MIGRATION_10_11)
|
||||||
|
// .addMigrations(MIGRATION_11_12)
|
||||||
|
// .allowMainThreadQueries()
|
||||||
|
// .build();
|
||||||
|
// } else {
|
||||||
|
// // If it's not a key issue, rethrow the exception
|
||||||
|
// throw e;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (Exception e) {
|
||||||
|
// LogUtil.e("Database", "Critical error initializing database: " + e.getMessage()+ e);
|
||||||
|
// throw new RuntimeException("Failed to initialize the database", e);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -466,7 +527,32 @@ public class DatabaseModule {
|
|||||||
.putLong("db_recreated_time", System.currentTimeMillis())
|
.putLong("db_recreated_time", System.currentTimeMillis())
|
||||||
.apply();
|
.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// return Room.databaseBuilder(application, AppDatabase.class,"yoma")
|
||||||
|
//// .fallbackToDestructiveMigration()
|
||||||
|
// .addMigrations(MIGRATION_7_8)
|
||||||
|
// .addMigrations(MIGRATION_8_9)
|
||||||
|
// .addMigrations(MIGRATION_9_10)
|
||||||
|
// .addMigrations(MIGRATION_10_11)
|
||||||
|
// .addMigrations(MIGRATION_11_12)
|
||||||
|
// .allowMainThreadQueries()
|
||||||
|
// .addCallback(new RoomDatabase.Callback() {
|
||||||
|
// @Override
|
||||||
|
// public void onCreate(@NonNull SupportSQLiteDatabase db) {
|
||||||
|
// super.onCreate(db);
|
||||||
|
// Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
|
||||||
|
// @Override
|
||||||
|
// public void run() {
|
||||||
|
//
|
||||||
|
// /*
|
||||||
|
// * init here
|
||||||
|
// * */
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// .build();
|
||||||
|
// }
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
|
|||||||
@ -20,7 +20,6 @@ runtime = "1.11.1"
|
|||||||
rxandroid = "3.0.2"
|
rxandroid = "3.0.2"
|
||||||
rxjava = "3.1.12"
|
rxjava = "3.1.12"
|
||||||
hiltNavigationCompose = "1.2.0"
|
hiltNavigationCompose = "1.2.0"
|
||||||
runtimeLivedata = "1.11.2"
|
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
androidx-compose-material-icons-core = { module = "androidx.compose.material:material-icons-core" }
|
androidx-compose-material-icons-core = { module = "androidx.compose.material:material-icons-core" }
|
||||||
@ -52,7 +51,6 @@ retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit
|
|||||||
rxandroid = { module = "io.reactivex.rxjava3:rxandroid", version.ref = "rxandroid" }
|
rxandroid = { module = "io.reactivex.rxjava3:rxandroid", version.ref = "rxandroid" }
|
||||||
rxjava = { module = "io.reactivex.rxjava3:rxjava", version.ref = "rxjava" }
|
rxjava = { module = "io.reactivex.rxjava3:rxjava", version.ref = "rxjava" }
|
||||||
androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
|
androidx-hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigationCompose" }
|
||||||
androidx-compose-runtime-livedata = { group = "androidx.compose.runtime", name = "runtime-livedata", version.ref = "runtimeLivedata" }
|
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user