Compare commits
8 Commits
ee91e6f787
...
4884152faa
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4884152faa | ||
|
|
beb6ddcba8 | ||
|
|
b2e8e13a81 | ||
|
|
511c3e0128 | ||
|
|
40c392cc01 | ||
|
|
86f3e099db | ||
|
|
f4d9dfaf7b | ||
|
|
b3cb166f1a |
@ -40,8 +40,8 @@ android {
|
||||
dimension = "env"
|
||||
applicationIdSuffix = ".uat"
|
||||
versionNameSuffix = "-UAT"
|
||||
versionCode = 12
|
||||
versionName = "3.0"
|
||||
versionCode = 14
|
||||
versionName = "3.2"
|
||||
buildConfigField("String", "ENV", "\"UAT\"")
|
||||
resValue("string", "app_name", "MOB-UAT")
|
||||
}
|
||||
|
||||
10
app/changelog.md
Normal file
10
app/changelog.md
Normal file
@ -0,0 +1,10 @@
|
||||
## Change Logs For UAT
|
||||
|
||||
### version 3.3
|
||||
* config auto update after transaction
|
||||
* signature removed on void
|
||||
* "Enter Password" color to LegacyRed
|
||||
* Amount and Card Number show in signature pad
|
||||
* fixed recent transaction only working for top 3
|
||||
* routed to dashboard after printing receipt
|
||||
* receipt printing animation re-scale
|
||||
@ -25,24 +25,25 @@ class DashboardMenuItem(
|
||||
val onClick: () -> Unit
|
||||
)
|
||||
|
||||
val settlementEnabled = false
|
||||
val voidEnabled = true
|
||||
val refundEnabled = true
|
||||
val preAuthEnabled = true
|
||||
val preAuthVoidEnabled = true
|
||||
val preAuthCompleteEnabled = true
|
||||
val preAuthCompleteVoidEnabled = true
|
||||
val cashAdvEnabled = true
|
||||
|
||||
fun buildMenuItems(
|
||||
onNavigateAmount: (String) -> Unit,
|
||||
onNavigateSignOn: () -> Unit,
|
||||
onNavigateSettlement: () -> Unit,
|
||||
onNavigateHistory: () -> Unit,
|
||||
onNavigateAction: (String) -> Unit
|
||||
): List<DashboardMenuItem> = buildList {
|
||||
): List<DashboardMenuItem> {
|
||||
val sp = SystemParamsOperation.getInstance()
|
||||
val settlementEnabled = sp.settlementStatus
|
||||
val voidEnabled = sp.voidStatus
|
||||
val refundEnabled = sp.refundStatus
|
||||
val preAuthEnabled = sp.preAuthStatus
|
||||
val preAuthVoidEnabled = sp.preAuthStatus
|
||||
val preAuthCompleteEnabled = sp.preAuthStatus
|
||||
val preAuthCompleteVoidEnabled = sp.preAuthStatus
|
||||
val cashAdvEnabled = sp.cashAdvanceStatus
|
||||
val mmqrEnabled = sp.mmqrStatus
|
||||
return buildList {
|
||||
|
||||
val mmqrEnabled = SystemParamsOperation.getInstance().mmqrStatus
|
||||
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
@ -59,175 +60,174 @@ fun buildMenuItems(
|
||||
)
|
||||
|
||||
|
||||
if (mmqrEnabled) {
|
||||
if (mmqrEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"MMQR",
|
||||
{
|
||||
Image(
|
||||
painter = painterResource(R.drawable.ic_mmqr_logo),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.height(48.dp)
|
||||
)
|
||||
}
|
||||
) { }
|
||||
)
|
||||
}
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"MMQR",
|
||||
{
|
||||
Image(
|
||||
painter = painterResource(R.drawable.ic_mmqr_logo),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.height(48.dp)
|
||||
)
|
||||
}
|
||||
) { }
|
||||
)
|
||||
}
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"History",
|
||||
{
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_history),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateHistory() }
|
||||
)
|
||||
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Sign On",
|
||||
{
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_sign_on),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateSignOn() }
|
||||
)
|
||||
|
||||
if (settlementEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Settlement",
|
||||
"History",
|
||||
{
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_settlement),
|
||||
painterResource(R.drawable.ic_history),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateSettlement() }
|
||||
) { onNavigateHistory() }
|
||||
)
|
||||
}
|
||||
|
||||
if (voidEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Void",
|
||||
"Sign On",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.Lock,
|
||||
painterResource(R.drawable.ic_sign_on),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAction("Void") }
|
||||
) { onNavigateSignOn() }
|
||||
)
|
||||
|
||||
if (settlementEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Settlement",
|
||||
{
|
||||
Icon(
|
||||
painterResource(R.drawable.ic_settlement),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateSettlement() }
|
||||
)
|
||||
}
|
||||
|
||||
if (voidEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Void",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.Lock,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAction("Void") }
|
||||
)
|
||||
}
|
||||
|
||||
if (refundEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Refund",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.Replay,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAction("Refund") }
|
||||
)
|
||||
}
|
||||
|
||||
if (preAuthEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Pre-Auth",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.Lock,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAmount("Pre-Auth") }
|
||||
)
|
||||
}
|
||||
|
||||
if (preAuthVoidEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Pre-Auth Void",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.LockOpen,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAction("Pre-Auth Void") }
|
||||
)
|
||||
}
|
||||
|
||||
if (preAuthCompleteEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Pre-Auth Complete",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.CreditCard,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAction("Pre-Auth Complete") }
|
||||
)
|
||||
}
|
||||
|
||||
if (preAuthCompleteVoidEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Pre-Auth Comp Void",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.SwapHoriz,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAction("Pre-Auth Complete Void") }
|
||||
)
|
||||
}
|
||||
|
||||
if (cashAdvEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Cash Adv",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.AccountBalanceWallet,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAmount("Cash Adv") }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (refundEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Refund",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.Replay,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAction("Refund") }
|
||||
)
|
||||
}
|
||||
|
||||
if (preAuthEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Pre-Auth",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.Lock,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAmount("Pre-Auth") }
|
||||
)
|
||||
}
|
||||
|
||||
if (preAuthVoidEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Pre-Auth Void",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.LockOpen,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAction("Pre-Auth Void") }
|
||||
)
|
||||
}
|
||||
|
||||
if (preAuthCompleteEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Pre-Auth Complete",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.CreditCard,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAction("Pre-Auth Complete") }
|
||||
)
|
||||
}
|
||||
|
||||
if (preAuthCompleteVoidEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Pre-Auth Comp Void",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.SwapHoriz,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAction("Pre-Auth Complete Void") }
|
||||
)
|
||||
}
|
||||
|
||||
if (cashAdvEnabled) {
|
||||
add(
|
||||
DashboardMenuItem(
|
||||
"Cash Adv",
|
||||
{
|
||||
Icon(
|
||||
Icons.Default.AccountBalanceWallet,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(32.dp),
|
||||
tint = Color.LegacyRed
|
||||
)
|
||||
}
|
||||
) { onNavigateAmount("Cash Adv") }
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -92,6 +92,8 @@ fun AppNavGraph(
|
||||
val sharedViewModel: SharedViewModel = hiltViewModel(activity)
|
||||
SignaturePad(
|
||||
onBack = { navController.popBackStack() },
|
||||
amount = sharedViewModel.payDetail.value?.amount,
|
||||
cardNumber = sharedViewModel.payDetail.value?.cardNo ?: "",
|
||||
onConfirm = { bitmap, signatureBlob ->
|
||||
sharedViewModel.signBitmap = bitmap
|
||||
sharedViewModel.updateSignatureBlob(signatureBlob)
|
||||
@ -111,10 +113,10 @@ fun AppNavGraph(
|
||||
val transResultViewModel: TransactionResultViewModel = hiltViewModel(activity)
|
||||
val dashboardViewModel: DashboardViewModel = hiltViewModel(activity)
|
||||
val dashboardUiState = dashboardViewModel.uiState.collectAsStateWithLifecycle().value
|
||||
val recentPayDetails by sharedViewModel.getLastThreeTransactions().observeAsState(emptyList())
|
||||
val recentPayDetails by sharedViewModel.getLastTenTransactions().observeAsState(emptyList())
|
||||
val deviceInfoViewModel: DeviceInfoViewModel = hiltViewModel(activity)
|
||||
val deviceInfoUiState = deviceInfoViewModel.uiState.collectAsStateWithLifecycle().value
|
||||
val tmsSetupViewModel: TmsSetupViewModel = hiltViewModel();
|
||||
val tmsSetupViewModel: TmsSetupViewModel = hiltViewModel(activity);
|
||||
|
||||
LaunchedEffect(deviceInfoViewModel) {
|
||||
deviceInfoViewModel.loadDeviceInfo()
|
||||
@ -750,9 +752,14 @@ fun AppNavGraph(
|
||||
composable(Routes.TransactionResult.route) {
|
||||
val sharedViewModel: SharedViewModel = hiltViewModel(activity)
|
||||
val transResultViewModel: TransactionResultViewModel = hiltViewModel(activity)
|
||||
val tmsSetupViewModel: TmsSetupViewModel = hiltViewModel(activity)
|
||||
val dashboardViewModel: DashboardViewModel = hiltViewModel(activity)
|
||||
|
||||
TransactionResultRoute(
|
||||
viewModel = transResultViewModel,
|
||||
sharedViewModel = sharedViewModel,
|
||||
tmsSetupViewModel = tmsSetupViewModel,
|
||||
dashboardViewModel = dashboardViewModel,
|
||||
onNavigateMain = {
|
||||
navController.navigate(Routes.Dashboard.route) {
|
||||
popUpTo(Routes.Dashboard.route) {
|
||||
@ -794,6 +801,14 @@ fun AppNavGraph(
|
||||
}
|
||||
launchSingleTop = true
|
||||
}
|
||||
},
|
||||
onPrintFinished = {
|
||||
navController.navigate(Routes.Dashboard.route) {
|
||||
popUpTo(Routes.Dashboard.route) {
|
||||
inclusive = false
|
||||
}
|
||||
launchSingleTop = true
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ fun InputPassword(
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(text = "Enter Password", color = Color.Gray, fontSize = 18.sp)
|
||||
Text(text = "Enter Password", color = Color.LegacyRed, fontSize = 18.sp)
|
||||
Spacer(Modifier.height(16.dp))
|
||||
PasswordDots(filledCount = uiState.input.length, totalCount = PASSWORD_LENGTH)
|
||||
Spacer(Modifier.height(8.dp))
|
||||
|
||||
@ -44,9 +44,7 @@ import com.mob.utsmyanmar.ui.transaction_result.TransactionResultViewModel
|
||||
import com.mob.utsmyanmar.viewmodel.SharedViewModel
|
||||
import com.utsmyanmar.paylibs.utils.POSUtil
|
||||
import com.utsmyanmar.paylibs.utils.PrintStatus
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
private enum class ReceiptCopy(val label: String) {
|
||||
MERCHANT("MERCHANT COPY"),
|
||||
@ -58,12 +56,12 @@ fun PrintReceiptScreen(
|
||||
transactionResultViewModel: TransactionResultViewModel,
|
||||
sharedViewModel: SharedViewModel,
|
||||
onPrint: () -> Unit,
|
||||
onDone: () -> Unit
|
||||
onDone: () -> Unit,
|
||||
onPrintFinished : () -> Unit,
|
||||
) {
|
||||
val state by transactionResultViewModel.state.collectAsStateWithLifecycle()
|
||||
val scope = rememberCoroutineScope()
|
||||
val receiptOffsetY = remember { Animatable(0f) }
|
||||
val animationDuration = 5000
|
||||
val merchant_copy_autoprint = true
|
||||
val customer_copy_autoprint = false
|
||||
var currentCopy by remember { mutableStateOf(ReceiptCopy.MERCHANT) }
|
||||
@ -72,10 +70,10 @@ fun PrintReceiptScreen(
|
||||
|
||||
suspend fun animatePrint() {
|
||||
receiptOffsetY.animateTo(
|
||||
targetValue = -1500f,
|
||||
animationSpec = tween(durationMillis = animationDuration, easing = FastOutSlowInEasing)
|
||||
targetValue = -1400f,
|
||||
animationSpec = tween(durationMillis = 4000, easing = FastOutSlowInEasing)
|
||||
)
|
||||
delay(1000.milliseconds)
|
||||
// delay(1000.milliseconds)
|
||||
receiptOffsetY.animateTo(
|
||||
targetValue = 0f,
|
||||
animationSpec = tween(durationMillis = 0, easing = FastOutSlowInEasing)
|
||||
@ -84,21 +82,30 @@ fun PrintReceiptScreen(
|
||||
|
||||
fun isReprintMode() = sharedViewModel.isReprint.value == true
|
||||
|
||||
fun doPrint(copy: ReceiptCopy, onFinished: () -> Unit) {
|
||||
fun doPrint(copy: ReceiptCopy, onFinished: (printFinished: ReceiptCopy) -> Unit) {
|
||||
val reprint = isReprintMode()
|
||||
val actualCopy = if (reprint && copy == ReceiptCopy.MERCHANT) ReceiptCopy.CUSTOMER else copy
|
||||
currentCopy = actualCopy
|
||||
|
||||
sharedViewModel.setPrintStatus(
|
||||
if (actualCopy == ReceiptCopy.MERCHANT) PrintStatus.FIRST_PRINT else PrintStatus.SECOND_PRINT
|
||||
if (actualCopy == ReceiptCopy.MERCHANT)
|
||||
PrintStatus.FIRST_PRINT
|
||||
else
|
||||
PrintStatus.SECOND_PRINT
|
||||
)
|
||||
onPrint()
|
||||
scope.launch {
|
||||
isPrinting = true
|
||||
animatePrint()
|
||||
isPrinting = false
|
||||
nextCopy = if (reprint) ReceiptCopy.CUSTOMER
|
||||
else if (actualCopy == ReceiptCopy.MERCHANT) ReceiptCopy.CUSTOMER else ReceiptCopy.MERCHANT
|
||||
onFinished()
|
||||
val upcomingCopy = if (reprint) ReceiptCopy.CUSTOMER
|
||||
else if (actualCopy == ReceiptCopy.MERCHANT) ReceiptCopy.CUSTOMER
|
||||
else ReceiptCopy.CUSTOMER
|
||||
|
||||
currentCopy = upcomingCopy
|
||||
nextCopy = upcomingCopy
|
||||
|
||||
onFinished(actualCopy)
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,7 +181,12 @@ fun PrintReceiptScreen(
|
||||
),
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
onClick = {
|
||||
doPrint(nextCopy) { }
|
||||
doPrint(nextCopy) { printFinished ->
|
||||
if (printFinished == ReceiptCopy.CUSTOMER) {
|
||||
onPrintFinished()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
) {
|
||||
Text(
|
||||
@ -295,7 +307,8 @@ fun PreviewPrintReceiptScreen() {
|
||||
sharedViewModel = hiltViewModel(),
|
||||
transactionResultViewModel = hiltViewModel(),
|
||||
onPrint = {},
|
||||
onDone = {}
|
||||
onDone = {},
|
||||
onPrintFinished = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -55,7 +55,7 @@ fun ProcessingRoute(
|
||||
when(transStatus) {
|
||||
TransResultStatus.SUCCESS -> {
|
||||
sharedViewModel.payDetail.value = transProcessViewModel.payDetailResult.value
|
||||
if (requiresSignature(sharedViewModel.payDetail.value)) {
|
||||
if (requiresSignature(sharedViewModel.transactionsType.value, sharedViewModel.payDetail.value)) {
|
||||
onNavigateSignature()
|
||||
} else {
|
||||
onNavigateTransactionResult()
|
||||
@ -94,7 +94,9 @@ fun ProcessingRoute(
|
||||
|
||||
}
|
||||
|
||||
private fun requiresSignature(payDetail: com.utsmyanmar.paylibs.model.PayDetail?): Boolean {
|
||||
// return payDetail?.transCVM == TransCVM.SIGNATURE && payDetail.isFreeSign == false
|
||||
return true;
|
||||
private fun requiresSignature(transType: TransactionsType?, payDetail: com.utsmyanmar.paylibs.model.PayDetail?): Boolean {
|
||||
if (transType == TransactionsType.VOID || transType == TransactionsType.PRE_AUTH_COMPLETE_VOID || transType == TransactionsType.PRE_AUTH_VOID) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.mob.utsmyanmar.ui.signature_pad
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@ -15,16 +16,21 @@ import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.mob.utsmyanmar.ui.components.appbar.AppBar
|
||||
import com.mob.utsmyanmar.ui.theme.MOBPOSTheme
|
||||
import com.mob.utsmyanmar.utils.formatAmount
|
||||
import com.mob.utsmyanmar.utils.maskCardNumber
|
||||
import se.warting.signaturepad.SignaturePadAdapter
|
||||
import se.warting.signaturepad.SignaturePadView
|
||||
import java.io.ByteArrayOutputStream
|
||||
@ -34,9 +40,13 @@ import com.mob.utsmyanmar.ui.theme.Color as AppColor
|
||||
fun SignaturePad(
|
||||
modifier: Modifier = Modifier,
|
||||
onBack: () -> Unit = {},
|
||||
onConfirm: (Bitmap?, ByteArray?) -> Unit = { _, _ -> }
|
||||
onConfirm: (Bitmap?, ByteArray?) -> Unit = { _, _ -> },
|
||||
amount: Long? = 0L,
|
||||
cardNumber: String,
|
||||
) {
|
||||
var signaturePadAdapter: SignaturePadAdapter? = null
|
||||
var selectedMode by remember { mutableStateOf(SignatureMode.Digital) }
|
||||
val isManualMode = selectedMode == SignatureMode.Manual
|
||||
|
||||
val scaledWidth = 300
|
||||
|
||||
@ -69,33 +79,137 @@ fun SignaturePad(
|
||||
.padding(16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
SignaturePadView(
|
||||
onReady = { signaturePadAdapter = it },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(200.dp)
|
||||
.border(width = 1.dp, color = AppColor.LegacyRed)
|
||||
)
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(0.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "Amount",
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = AppColor.LegacyRed
|
||||
)
|
||||
Text(
|
||||
text = amount.formatAmount(),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = AppColor.LegacyRed
|
||||
)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.padding(0.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
Text(
|
||||
text = "Card Number",
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = AppColor.LegacyRed
|
||||
)
|
||||
Text(
|
||||
text = cardNumber.maskCardNumber(),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = AppColor.LegacyRed
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
if (isManualMode) {
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(200.dp),
|
||||
shape = RoundedCornerShape(8.dp),
|
||||
colors = CardDefaults.cardColors(containerColor = Color.White),
|
||||
border = androidx.compose.foundation.BorderStroke(
|
||||
width = 1.dp,
|
||||
color = AppColor.Gray.copy(alpha = 0.35f)
|
||||
)
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(16.dp),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = androidx.compose.ui.Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = "Manual Signature",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = AppColor.Gray
|
||||
)
|
||||
Text(
|
||||
text = "Customer need to sign on paper",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = AppColor.Gray.copy(alpha = 0.7f)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
SignaturePadView(
|
||||
onReady = { signaturePadAdapter = it },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(200.dp)
|
||||
.background(AppColor.White)
|
||||
.border(
|
||||
width = 1.dp,
|
||||
color = AppColor.LegacyRed,
|
||||
shape = RoundedCornerShape(8.dp)
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
SignatureModeOption(
|
||||
title = "Digital",
|
||||
subtitle = "Sign on screen",
|
||||
selected = !isManualMode,
|
||||
onClick = { selectedMode = SignatureMode.Digital },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
SignatureModeOption(
|
||||
title = "Manual",
|
||||
subtitle = "Sign on paper",
|
||||
selected = isManualMode,
|
||||
onClick = { selectedMode = SignatureMode.Manual },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
OutlinedButton(
|
||||
onClick = { signaturePadAdapter?.clear() },
|
||||
Button(
|
||||
onClick = {
|
||||
if (!isManualMode) {
|
||||
signaturePadAdapter?.clear()
|
||||
}
|
||||
},
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = AppColor.White,
|
||||
contentColor = Color.White
|
||||
),
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.height(50.dp)
|
||||
.height(50.dp),
|
||||
enabled = !isManualMode
|
||||
) {
|
||||
Text("Clear")
|
||||
Text("Clear", color = AppColor.Black)
|
||||
}
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
val rawBitmap = signaturePadAdapter?.getSignatureBitmap()
|
||||
val bitmap = rawBitmap?.let { scaleBitmap(it) }
|
||||
val signatureBlob = bitmap?.let { bitmapToBlob(it) }
|
||||
onConfirm(bitmap, signatureBlob)
|
||||
if (isManualMode) {
|
||||
onConfirm(null, null)
|
||||
} else {
|
||||
val rawBitmap = signaturePadAdapter?.getSignatureBitmap()
|
||||
val bitmap = rawBitmap?.let { scaleBitmap(it) }
|
||||
val signatureBlob = bitmap?.let { bitmapToBlob(it) }
|
||||
onConfirm(bitmap, signatureBlob)
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
@ -159,6 +273,9 @@ private fun SignatureModeOption(
|
||||
@Composable
|
||||
fun SignaturePadPreview() {
|
||||
MOBPOSTheme {
|
||||
SignaturePad()
|
||||
SignaturePad(
|
||||
amount = 1000000L,
|
||||
cardNumber = "6244310034582136"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,4 @@
|
||||
package com.mob.utsmyanmar.ui.transaction_result
|
||||
|
||||
class TransactionResultRepository {
|
||||
}
|
||||
@ -4,8 +4,9 @@ package com.mob.utsmyanmar.ui.transaction_result
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.mob.utsmyanmar.ui.dashboard.DashboardViewModel
|
||||
import com.mob.utsmyanmar.ui.tms_setup.TmsSetupViewModel
|
||||
import com.mob.utsmyanmar.viewmodel.SharedViewModel
|
||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||
|
||||
@ -17,7 +18,9 @@ fun TransactionResultRoute(
|
||||
onNavigatePrintReceipt: () -> Unit,
|
||||
onShowError: (String) -> Unit,
|
||||
onShowSuccess: (String) -> Unit,
|
||||
onShowPrinterDialog: (String) -> Unit
|
||||
onShowPrinterDialog: (String) -> Unit,
|
||||
tmsSetupViewModel: TmsSetupViewModel,
|
||||
dashboardViewModel: DashboardViewModel,
|
||||
) {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
val canGoBack = sharedViewModel.transactionsType.value != TransactionsType.SALE
|
||||
@ -27,6 +30,8 @@ fun TransactionResultRoute(
|
||||
TransactionResultEvent.Start,
|
||||
sharedViewModel
|
||||
)
|
||||
dashboardViewModel.refreshLastSyncTime()
|
||||
tmsSetupViewModel.downloadConfigs()
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
|
||||
20
app/src/main/java/com/mob/utsmyanmar/utils/Converter.kt
Normal file
20
app/src/main/java/com/mob/utsmyanmar/utils/Converter.kt
Normal file
@ -0,0 +1,20 @@
|
||||
package com.mob.utsmyanmar.utils
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
fun Long?.formatAmount(): String {
|
||||
val amount = (this ?: 0L) / 100.0
|
||||
return String.format("%,.2f", amount)
|
||||
}
|
||||
|
||||
fun String?.maskCardNumber(): String {
|
||||
if (this.isNullOrEmpty()) return ""
|
||||
val maskedPan = StringBuilder(this)
|
||||
if (this.length > 12) {
|
||||
maskedPan.replace(6, 12, "******")
|
||||
} else {
|
||||
maskedPan.append(" ")
|
||||
}
|
||||
return maskedPan.toString()
|
||||
}
|
||||
@ -438,6 +438,10 @@ class SharedViewModel @Inject constructor(
|
||||
return repository.getLastThreeTransactions()
|
||||
}
|
||||
|
||||
fun getLastTenTransactions(): LiveData<List<PayDetail>> {
|
||||
return repository.getLastTenTransactions()
|
||||
}
|
||||
|
||||
fun getSettlementRecords(): LiveData<List<PayDetail>> {
|
||||
return repository.getSettlementPOS()
|
||||
}
|
||||
|
||||
11
opencode.json
Normal file
11
opencode.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"$schema": "https://opencode.ai/config.json",
|
||||
"mcp": {
|
||||
"codebase-memory": {
|
||||
"type": "local",
|
||||
"command": "codebase-memory-mcp",
|
||||
"args": [],
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user