Fixed ReprintAnyTransactions and new keyboard layout

This commit is contained in:
moon 2026-08-25 23:34:00 +06:30
parent 2ca1b5eee0
commit c45c8adf65
2 changed files with 188 additions and 24 deletions

View File

@ -46,6 +46,7 @@ internal fun displayTransactionTitle(payDetail: PayDetail): String {
internal fun isValidForReprint(payDetail: PayDetail): Boolean {
if (payDetail.transactionType == TransactionsType.SETTLEMENT.value) return false
if (payDetail.transactionType == TransactionsType.REVERSAL.value) return false
if (payDetail.transactionType == TransactionsType.WAVEPAY.value && payDetail.qrTransStatus != 1) {
return false
}
@ -59,14 +60,8 @@ internal fun filterReprintAnyTransactions(
transactions: List<PayDetail>,
hostType: HostType
): List<PayDetail> {
val yesterday = POSUtil.getInstance().yesterdayDate
val dateFormat = SimpleDateFormat("dd/MM/yy", Locale.getDefault())
return transactions.filter { pay ->
val transDate = parseTransDate(pay.transDate, dateFormat) ?: return@filter false
if (yesterday.compareTo(transDate) > 0) return@filter false
if (pay.transactionType == TransactionsType.SETTLEMENT.value) return@filter false
if (pay.transactionType == TransactionsType.REVERSAL.value) return@filter false
if (!isValidForReprint(pay)) return@filter false
when (hostType) {
HostType.MPU ->

View File

@ -1,8 +1,13 @@
package com.mob.utsmyanmar.ui.history_functions
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
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
@ -10,11 +15,20 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material.icons.automirrored.rounded.Backspace
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
@ -23,12 +37,27 @@ 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.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import com.mob.utsmyanmar.ui.components.appbar.AppBar
import androidx.compose.ui.unit.sp
import com.mob.utsmyanmar.ui.components.NumericKeypad
import com.mob.utsmyanmar.ui.preview.P2Preview
import com.mob.utsmyanmar.ui.preview.P3Preview
import com.mob.utsmyanmar.ui.theme.Color
import com.mob.utsmyanmar.ui.theme.MOBPOSTheme
import com.utsmyanmar.paylibs.model.PayDetail
import com.utsmyanmar.paylibs.utils.enums.HostType
private val searchKeys = listOf(
listOf("1", "2", "3"),
listOf("4", "5", "6"),
listOf("7", "8", "9"),
listOf("C", "0", "\u232B")
)
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ReprintAnyTransactionScreen(
viewModel: HistoryViewModel,
@ -38,6 +67,7 @@ fun ReprintAnyTransactionScreen(
) {
val allTransactions by viewModel.getTransactionHistory().observeAsState(emptyList())
var searchQuery by remember { mutableStateOf("") }
var isFocused by remember { mutableStateOf(false) }
val filtered = remember(allTransactions, hostType, searchQuery) {
val base = filterReprintAnyTransactions(allTransactions, hostType)
@ -47,10 +77,32 @@ fun ReprintAnyTransactionScreen(
Scaffold(
containerColor = Color.IvoryBeige,
topBar = {
AppBar(
title = "Transactions",
icon = Icons.AutoMirrored.Filled.ArrowBack,
onIconClick = onBack
TopAppBar(
title = {
Column {
Text(
text = "Reprint Transaction",
style = MaterialTheme.typography.titleMedium
)
Text(
text = hostTypeLabel(hostType),
style = MaterialTheme.typography.labelSmall,
color = Color.Gray
)
}
},
navigationIcon = {
IconButton(onClick = onBack) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = "Back",
tint = Color.LegacyRed
)
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = Color.IvoryBeige
)
)
}
) { paddingValues ->
@ -58,37 +110,154 @@ fun ReprintAnyTransactionScreen(
modifier = Modifier
.fillMaxSize()
.padding(paddingValues)
.padding(16.dp)
.padding(horizontal = 16.dp)
) {
OutlinedTextField(
value = searchQuery,
onValueChange = { searchQuery = it },
modifier = Modifier.fillMaxWidth(),
label = { Text("Trace (6) or RRN (12)") },
singleLine = true
SearchInputBox(
query = searchQuery,
isFocused = isFocused,
onFocus = { isFocused = true }
)
Spacer(modifier = Modifier.height(12.dp))
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "${filtered.size} transaction(s) found",
style = MaterialTheme.typography.labelSmall,
color = Color.Gray,
modifier = Modifier.padding(horizontal = 4.dp)
)
Spacer(modifier = Modifier.height(8.dp))
if (filtered.isEmpty()) {
Box(
modifier = Modifier.fillMaxSize(),
modifier = Modifier.weight(1f),
contentAlignment = Alignment.Center
) {
Text("No transactions found.", color = Color.Gray)
Text(
text = if (allTransactions.isEmpty()) "No transactions available" else "No matching transactions",
color = Color.Gray,
style = MaterialTheme.typography.bodyMedium
)
}
} else {
LazyColumn(
modifier = Modifier.fillMaxSize(),
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
items(filtered, key = { "${it.voucherNo}_${it.referNo}_${it.PID}" }) { payDetail ->
HistoryTransactionCard(payDetail) {
isFocused = false
onReprintTransaction(prepareReprintPayDetail(payDetail))
}
}
}
}
AnimatedVisibility(
visible = isFocused,
enter = slideInVertically(initialOffsetY = { it }),
exit = slideOutVertically(targetOffsetY = { it })
) {
NumericKeypad(
keys = searchKeys,
modifier = Modifier
.fillMaxWidth()
.height(280.dp)
.padding(top = 8.dp),
onKeyClick = { key ->
when (key) {
"C" -> searchQuery = ""
"\u232B" -> searchQuery = searchQuery.dropLast(1)
else -> if (searchQuery.length < 12) searchQuery += key
}
}
)
}
}
}
}
@Composable
private fun SearchInputBox(
query: String,
isFocused: Boolean,
onFocus: () -> Unit,
) {
Card(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onFocus),
colors = CardDefaults.cardColors(containerColor = Color.White),
shape = RoundedCornerShape(12.dp),
elevation = CardDefaults.cardElevation(defaultElevation = if (isFocused) 6.dp else 2.dp)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp, vertical = 14.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Column(modifier = Modifier.weight(1f)) {
Text(
text = if (isFocused) "Trace or RRN" else "Tap to search by Trace or RRN",
style = MaterialTheme.typography.bodySmall,
color = if (isFocused) Color.LegacyRed else Color.Gray
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = query.ifEmpty { "_" },
color = Color.LegacyRed,
style = MaterialTheme.typography.headlineSmall.copy(
fontWeight = FontWeight.Bold,
letterSpacing = 2.sp
)
)
}
if (query.isNotEmpty()) {
Card(
shape = RoundedCornerShape(18.dp),
colors = CardDefaults.cardColors(containerColor = Color.White),
elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
modifier = Modifier
.shadow(2.dp, RoundedCornerShape(18.dp))
.clickable { }
) {
Icon(
imageVector = Icons.AutoMirrored.Rounded.Backspace,
contentDescription = "Delete",
tint = Color.LegacyRed,
modifier = Modifier.padding(horizontal = 14.dp, vertical = 12.dp)
)
}
}
}
}
}
@P2Preview
@P3Preview
@Composable
private fun ReprintAnyTransactionScreenPreview() {
MOBPOSTheme {
Box(modifier = Modifier.height(600.dp)) {
Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(containerColor = Color.White)
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = "SALE",
color = Color.LegacyRed,
style = MaterialTheme.typography.titleSmall
)
Spacer(modifier = Modifier.height(4.dp))
Text("Trace 000001", style = MaterialTheme.typography.bodySmall)
Text("RRN 123456789012", style = MaterialTheme.typography.bodySmall, color = Color.Gray)
}
}
}
}
}