added history functions
This commit is contained in:
parent
f827e75b1e
commit
1a7e4c2020
@ -107,6 +107,7 @@ fun DashboardScreen2(
|
|||||||
onNavigateSettlement: () -> Unit = {},
|
onNavigateSettlement: () -> Unit = {},
|
||||||
onNavigateVersion: () -> Unit = {},
|
onNavigateVersion: () -> Unit = {},
|
||||||
onNavigateFunctions: () -> Unit = {},
|
onNavigateFunctions: () -> Unit = {},
|
||||||
|
onNavigateHistory: () -> Unit = {},
|
||||||
onNavigateAction: (String) -> Unit = {},
|
onNavigateAction: (String) -> Unit = {},
|
||||||
onNavigateNotifications: () -> Unit = {},
|
onNavigateNotifications: () -> Unit = {},
|
||||||
dashboardUiState: DashboardUiState = DashboardUiState(),
|
dashboardUiState: DashboardUiState = DashboardUiState(),
|
||||||
@ -455,6 +456,7 @@ fun DashboardScreen2(
|
|||||||
onNavigateAmount = onNavigateAmount,
|
onNavigateAmount = onNavigateAmount,
|
||||||
onNavigateSignOn = onNavigateSignOn,
|
onNavigateSignOn = onNavigateSignOn,
|
||||||
onNavigateSettlement = onNavigateSettlement,
|
onNavigateSettlement = onNavigateSettlement,
|
||||||
|
onNavigateHistory = onNavigateHistory,
|
||||||
onNavigateAction = onNavigateAction
|
onNavigateAction = onNavigateAction
|
||||||
),
|
),
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
@ -675,6 +677,7 @@ private fun buildMenuItems(
|
|||||||
onNavigateAmount: (String) -> Unit,
|
onNavigateAmount: (String) -> Unit,
|
||||||
onNavigateSignOn: () -> Unit,
|
onNavigateSignOn: () -> Unit,
|
||||||
onNavigateSettlement: () -> Unit,
|
onNavigateSettlement: () -> Unit,
|
||||||
|
onNavigateHistory: () -> Unit,
|
||||||
onNavigateAction: (String) -> Unit
|
onNavigateAction: (String) -> Unit
|
||||||
): List<DashboardMenuItem> = listOf(
|
): List<DashboardMenuItem> = listOf(
|
||||||
DashboardMenuItem(
|
DashboardMenuItem(
|
||||||
@ -705,7 +708,7 @@ private fun buildMenuItems(
|
|||||||
modifier = Modifier.size(32.dp),
|
modifier = Modifier.size(32.dp),
|
||||||
tint = Color.LegacyRed
|
tint = Color.LegacyRed
|
||||||
)
|
)
|
||||||
}) { },
|
}) { onNavigateHistory() },
|
||||||
DashboardMenuItem(
|
DashboardMenuItem(
|
||||||
"Sign On",
|
"Sign On",
|
||||||
{
|
{
|
||||||
|
|||||||
@ -0,0 +1,87 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
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.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
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.livedata.observeAsState
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.mob.utsmyanmar.ui.components.appbar.AppBar
|
||||||
|
import com.mob.utsmyanmar.ui.theme.Color
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun BatchTotalScreen(
|
||||||
|
viewModel: HistoryViewModel,
|
||||||
|
onBack: () -> Unit,
|
||||||
|
) {
|
||||||
|
val batchNo = SystemParamsOperation.getInstance().currentBatchNum
|
||||||
|
val records by viewModel.getReviewBatchTransaction(batchNo).observeAsState(emptyList())
|
||||||
|
val totalAmount = records.sumOf { detailReportSignedAmount(it) }
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
containerColor = Color.IvoryBeige,
|
||||||
|
topBar = {
|
||||||
|
AppBar(
|
||||||
|
title = "Batch Total",
|
||||||
|
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
|
onIconClick = onBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
Card(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = Color.White)
|
||||||
|
) {
|
||||||
|
Column(modifier = Modifier.padding(16.dp)) {
|
||||||
|
SummaryLine("Batch No", batchNo)
|
||||||
|
SummaryLine("Record Count", records.size.toString())
|
||||||
|
SummaryLine("Total Amount", POSUtil.getInstance().formatAmount(totalAmount))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
||||||
|
if (records.isEmpty()) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text("No batch records found.", color = Color.Gray)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
items(records, key = { "${it.voucherNo}_${it.PID}" }) { record ->
|
||||||
|
HistoryTransactionCard(record, onClick = null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,162 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
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.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.CardDefaults
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
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.platform.LocalContext
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.mob.utsmyanmar.ui.components.appbar.AppBar
|
||||||
|
import com.mob.utsmyanmar.ui.theme.Color
|
||||||
|
import com.utsmyanmar.paylibs.print.PrintHelper
|
||||||
|
import com.utsmyanmar.paylibs.print.printx.PrintXReceipt
|
||||||
|
import com.utsmyanmar.paylibs.print.printx.PrintXStatus
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.HostType
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||||
|
import com.utsmyanmar.paylibs.utils.params.Params
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DetailReportScreen(
|
||||||
|
viewModel: HistoryViewModel,
|
||||||
|
hostType: HostType,
|
||||||
|
onBack: () -> Unit,
|
||||||
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val allTransactions by viewModel.getTransactionHistory().observeAsState(emptyList())
|
||||||
|
var isPrinting by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
val records = remember(allTransactions, hostType) {
|
||||||
|
filterDetailReportTransactions(allTransactions, hostType)
|
||||||
|
}
|
||||||
|
val totalAmount = remember(records) {
|
||||||
|
records.sumOf(::detailReportSignedAmount)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun printDetailReport() {
|
||||||
|
if (records.isEmpty()) {
|
||||||
|
Toast.makeText(context, "No transactions to print.", Toast.LENGTH_SHORT).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (PrintHelper.getInstance().paperRollStatus() != 1) {
|
||||||
|
Toast.makeText(context, "Paper roll not ready.", Toast.LENGTH_SHORT).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val tradeData = Params.newTrade(false)
|
||||||
|
val payDetail = tradeData.payDetail
|
||||||
|
payDetail.transType = TransactionsType.DETAIL_REPORT.name
|
||||||
|
payDetail.transactionType = TransactionsType.DETAIL_REPORT.value
|
||||||
|
|
||||||
|
isPrinting = true
|
||||||
|
PrintXReceipt.getInstance().printDetailReport(
|
||||||
|
payDetail,
|
||||||
|
ArrayList(records),
|
||||||
|
hostType,
|
||||||
|
object : PrintXStatus {
|
||||||
|
override fun onSuccess() {
|
||||||
|
isPrinting = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure() {
|
||||||
|
isPrinting = false
|
||||||
|
Toast.makeText(context, "Print failed.", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
containerColor = Color.IvoryBeige,
|
||||||
|
topBar = {
|
||||||
|
AppBar(
|
||||||
|
title = "Print Detail Report",
|
||||||
|
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
|
onIconClick = onBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
Card(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = Color.White)
|
||||||
|
) {
|
||||||
|
Column(modifier = Modifier.padding(16.dp)) {
|
||||||
|
SummaryLine("Host", hostTypeLabel(hostType))
|
||||||
|
SummaryLine("Card Type", hostTypeLabel(hostType))
|
||||||
|
SummaryLine("Transaction Count", records.size.toString())
|
||||||
|
SummaryLine("Total Amount", POSUtil.getInstance().formatAmount(totalAmount))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
||||||
|
if (records.isEmpty()) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text("No transactions available.", color = Color.Gray)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.weight(1f),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
items(records, key = { "${it.voucherNo}_${it.PID}" }) { record ->
|
||||||
|
HistoryTransactionCard(record, onClick = null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = ::printDetailReport,
|
||||||
|
enabled = records.isNotEmpty() && !isPrinting,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(56.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = Color.LegacyRed,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (isPrinting) {
|
||||||
|
CircularProgressIndicator(color = Color.White)
|
||||||
|
} else {
|
||||||
|
Text("Print")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,191 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import androidx.compose.foundation.clickable
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
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.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.Icon
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.compose.ui.unit.sp
|
||||||
|
import com.mob.utsmyanmar.ui.theme.Color
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun HistoryTransactionCard(
|
||||||
|
payDetail: PayDetail,
|
||||||
|
onClick: (() -> Unit)?,
|
||||||
|
) {
|
||||||
|
Card(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.then(
|
||||||
|
if (onClick != null) {
|
||||||
|
Modifier.clickable(onClick = onClick)
|
||||||
|
} else {
|
||||||
|
Modifier
|
||||||
|
}
|
||||||
|
),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = Color.White)
|
||||||
|
) {
|
||||||
|
Column(modifier = Modifier.padding(16.dp)) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = payDetail.transType.ifBlank { "UNKNOWN" },
|
||||||
|
color = Color.LegacyRed,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontSize = 14.sp
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = POSUtil.getInstance().formatAmount(payDetail.amount),
|
||||||
|
fontWeight = FontWeight.SemiBold,
|
||||||
|
fontSize = 14.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
Text("Trace ${payDetail.voucherNo.ifBlank { "-" }}", fontSize = 12.sp)
|
||||||
|
Text("RRN ${payDetail.referNo.ifBlank { "-" }}", fontSize = 12.sp, color = Color.Gray)
|
||||||
|
Text(
|
||||||
|
"${payDetail.transDate} ${payDetail.transTime}",
|
||||||
|
fontSize = 12.sp,
|
||||||
|
color = Color.Gray
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun HistoryTransactionDetailCard(payDetail: PayDetail) {
|
||||||
|
Card(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = Color.White)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier.padding(16.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = payDetail.transType.ifBlank { "Transaction" },
|
||||||
|
color = Color.LegacyRed,
|
||||||
|
fontWeight = FontWeight.Bold,
|
||||||
|
fontSize = 16.sp
|
||||||
|
)
|
||||||
|
SummaryLine("Trace", payDetail.voucherNo)
|
||||||
|
SummaryLine("Amount", POSUtil.getInstance().formatAmount(payDetail.amount))
|
||||||
|
SummaryLine("Card No", payDetail.cardNo)
|
||||||
|
SummaryLine("Reference", payDetail.referNo)
|
||||||
|
SummaryLine("Approval", payDetail.approvalCode.orEmpty())
|
||||||
|
SummaryLine("Date", payDetail.tradeDate)
|
||||||
|
SummaryLine("Time", payDetail.tradeTime)
|
||||||
|
SummaryLine("Status", payDetail.tradeAnswerCode.orEmpty())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun SummaryLine(label: String, value: String) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
|
Text(label, color = Color.Gray, fontSize = 13.sp)
|
||||||
|
Text(
|
||||||
|
value.ifBlank { "-" },
|
||||||
|
fontSize = 13.sp,
|
||||||
|
fontWeight = FontWeight.Medium
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun SummaryPickerRow(
|
||||||
|
label: String,
|
||||||
|
value: String,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
Card(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.clickable(onClick = onClick),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = Color.White)
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(16.dp),
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text(label, fontWeight = FontWeight.Medium)
|
||||||
|
Text(value, color = Color.Gray)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun HistoryNumericKeypad(
|
||||||
|
onDigit: (String) -> Unit,
|
||||||
|
onBackspace: () -> Unit,
|
||||||
|
onClear: () -> Unit,
|
||||||
|
) {
|
||||||
|
val rows = listOf(
|
||||||
|
listOf("1", "2", "3"),
|
||||||
|
listOf("4", "5", "6"),
|
||||||
|
listOf("7", "8", "9"),
|
||||||
|
listOf("C", "0", "⌫")
|
||||||
|
)
|
||||||
|
|
||||||
|
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
rows.forEach { row ->
|
||||||
|
Row(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
row.forEach { key ->
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
when (key) {
|
||||||
|
"C" -> onClear()
|
||||||
|
"⌫" -> onBackspace()
|
||||||
|
else -> onDigit(key)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.height(56.dp),
|
||||||
|
shape = RoundedCornerShape(8.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = Color.White,
|
||||||
|
contentColor = Color.Black
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if (key == "⌫") {
|
||||||
|
Icon(Icons.Rounded.Backspace, contentDescription = "Backspace")
|
||||||
|
} else {
|
||||||
|
Text(key, fontSize = 20.sp, fontWeight = FontWeight.Bold)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,141 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.HostType
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||||
|
import java.text.ParseException
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
enum class HistoryHostPurpose {
|
||||||
|
REPRINT_ANY,
|
||||||
|
LAST_SETTLEMENT,
|
||||||
|
DETAIL_REPORT,
|
||||||
|
SUMMARY_REPORT,
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun prepareReprintPayDetail(payDetail: PayDetail): PayDetail {
|
||||||
|
val suffix = "(REPRINT)"
|
||||||
|
payDetail.transType = if (payDetail.transType.length >= 20) {
|
||||||
|
"${payDetail.transType}\n$suffix"
|
||||||
|
} else {
|
||||||
|
payDetail.transType + suffix
|
||||||
|
}
|
||||||
|
return payDetail
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun isValidForReprint(payDetail: PayDetail): Boolean {
|
||||||
|
if (payDetail.transactionType == TransactionsType.SETTLEMENT.value) return false
|
||||||
|
if (payDetail.transactionType == TransactionsType.WAVEPAY.value && payDetail.qrTransStatus != 1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if (payDetail.transactionType == TransactionsType.WAVEPAY_REFUND.value && payDetail.qrTransStatus != 1) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
when (hostType) {
|
||||||
|
HostType.MPU ->
|
||||||
|
pay.accountType == "MPU" &&
|
||||||
|
pay.transactionType != TransactionsType.WAVEPAY.value &&
|
||||||
|
pay.transactionType != TransactionsType.WAVEPAY_REFUND.value
|
||||||
|
|
||||||
|
HostType.QR ->
|
||||||
|
(pay.transactionType == TransactionsType.WAVEPAY.value ||
|
||||||
|
pay.transactionType == TransactionsType.WAVEPAY_REFUND.value) &&
|
||||||
|
pay.qrTransStatus == 1
|
||||||
|
|
||||||
|
HostType.VISA_MASTER ->
|
||||||
|
pay.accountType != "MPU" &&
|
||||||
|
pay.transactionType != TransactionsType.WAVEPAY.value &&
|
||||||
|
pay.transactionType != TransactionsType.WAVEPAY_REFUND.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun filterDetailReportTransactions(
|
||||||
|
transactions: List<PayDetail>,
|
||||||
|
hostType: HostType
|
||||||
|
): List<PayDetail> {
|
||||||
|
val yesterday = POSUtil.getInstance().yesterdayDate
|
||||||
|
|
||||||
|
return transactions.filter { pay ->
|
||||||
|
if (POSUtil.getInstance().getDateByString(pay.transDate).before(yesterday)) return@filter false
|
||||||
|
if (pay.transactionType == TransactionsType.REVERSAL.value) return@filter false
|
||||||
|
if (pay.transactionType == TransactionsType.SETTLEMENT.value) return@filter false
|
||||||
|
|
||||||
|
when (hostType) {
|
||||||
|
HostType.MPU ->
|
||||||
|
pay.accountType == "MPU" &&
|
||||||
|
pay.transactionType != TransactionsType.WAVEPAY_REFUND.value &&
|
||||||
|
pay.transactionType != TransactionsType.WAVEPAY.value
|
||||||
|
|
||||||
|
HostType.QR ->
|
||||||
|
(pay.transactionType == TransactionsType.WAVEPAY.value ||
|
||||||
|
pay.transactionType == TransactionsType.WAVEPAY_REFUND.value) &&
|
||||||
|
pay.qrTransStatus == 1
|
||||||
|
|
||||||
|
HostType.VISA_MASTER ->
|
||||||
|
pay.accountType != "MPU" &&
|
||||||
|
pay.transactionType != TransactionsType.WAVEPAY_REFUND.value &&
|
||||||
|
pay.transactionType != TransactionsType.WAVEPAY.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun detailReportSignedAmount(payDetail: PayDetail): Long {
|
||||||
|
val isNegative = payDetail.transactionType == TransactionsType.VOID.value ||
|
||||||
|
payDetail.transactionType == TransactionsType.REFUND.value ||
|
||||||
|
payDetail.transactionType == TransactionsType.WAVEPAY_REFUND.value
|
||||||
|
return if (isNegative) -payDetail.amount else payDetail.amount
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun hostTypeLabel(hostType: HostType): String = when (hostType) {
|
||||||
|
HostType.QR -> "QR PAY"
|
||||||
|
HostType.MPU -> "MPU"
|
||||||
|
HostType.VISA_MASTER -> "VISA/MASTER"
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun hostTypeAccountLabel(hostType: HostType): String = when (hostType) {
|
||||||
|
HostType.QR -> "WALLET"
|
||||||
|
HostType.MPU -> "MPU"
|
||||||
|
HostType.VISA_MASTER -> "Visa/Master"
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun searchReprintAnyTransactions(
|
||||||
|
transactions: List<PayDetail>,
|
||||||
|
query: String
|
||||||
|
): List<PayDetail> {
|
||||||
|
if (query.isBlank()) return transactions
|
||||||
|
return when (query.length) {
|
||||||
|
6 -> transactions.filter { it.voucherNo == query }
|
||||||
|
12 -> transactions.filter { it.referNo == query }
|
||||||
|
else -> transactions.filter {
|
||||||
|
it.voucherNo.contains(query) || it.referNo.contains(query)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun parseTransDate(value: String, formatter: SimpleDateFormat): Date? {
|
||||||
|
return try {
|
||||||
|
formatter.parse(value)
|
||||||
|
} catch (_: ParseException) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.filled.ChevronRight
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.mob.utsmyanmar.ui.components.appbar.AppBar
|
||||||
|
import com.mob.utsmyanmar.ui.functions.FunctionButton
|
||||||
|
import com.mob.utsmyanmar.ui.theme.Color
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun HistoryMenuScreen(
|
||||||
|
onBack: () -> Unit,
|
||||||
|
onReprintLastTransaction: () -> Unit,
|
||||||
|
onReprintAnyTransaction: () -> Unit,
|
||||||
|
onReprintLastSettlement: () -> Unit,
|
||||||
|
onPrintDetailReport: () -> Unit,
|
||||||
|
onPrintSummaryReport: () -> Unit,
|
||||||
|
onReview: () -> Unit,
|
||||||
|
onBatchTotal: () -> Unit,
|
||||||
|
) {
|
||||||
|
Scaffold(
|
||||||
|
containerColor = Color.IvoryBeige,
|
||||||
|
topBar = {
|
||||||
|
AppBar(
|
||||||
|
title = "Select Function",
|
||||||
|
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
|
onIconClick = onBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.padding(16.dp)
|
||||||
|
.verticalScroll(rememberScrollState()),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
|
) {
|
||||||
|
HistoryMenuButton("Reprint Last Transaction", onReprintLastTransaction)
|
||||||
|
HistoryMenuButton("Reprint Any Transaction", onReprintAnyTransaction)
|
||||||
|
HistoryMenuButton("Reprint Last Settlement Report", onReprintLastSettlement)
|
||||||
|
HistoryMenuButton("Print Detail Report", onPrintDetailReport)
|
||||||
|
HistoryMenuButton("Print Summary Report", onPrintSummaryReport)
|
||||||
|
HistoryMenuButton("Review", onReview)
|
||||||
|
HistoryMenuButton("Batch Total", onBatchTotal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun HistoryMenuButton(
|
||||||
|
title: String,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
FunctionButton(
|
||||||
|
onClick = onClick,
|
||||||
|
title = title,
|
||||||
|
subTitle = "",
|
||||||
|
trailingIcon = {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Default.ChevronRight,
|
||||||
|
contentDescription = null,
|
||||||
|
tint = Color.LegacyRed
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.widget.Toast
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail
|
||||||
|
import com.utsmyanmar.paylibs.print.PrintHelper
|
||||||
|
import com.utsmyanmar.paylibs.print.printx.PrintXReceipt
|
||||||
|
import com.utsmyanmar.paylibs.print.printx.PrintXStatus
|
||||||
|
|
||||||
|
internal fun printSettlementReport(
|
||||||
|
context: Context,
|
||||||
|
payDetail: PayDetail,
|
||||||
|
onSuccess: () -> Unit,
|
||||||
|
onFailure: () -> Unit,
|
||||||
|
) {
|
||||||
|
if (PrintHelper.getInstance().paperRollStatus() != 1) {
|
||||||
|
Toast.makeText(context, "Paper roll not ready.", Toast.LENGTH_SHORT).show()
|
||||||
|
onFailure()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintXReceipt.getInstance().printSmileSettlementReport(
|
||||||
|
payDetail,
|
||||||
|
object : PrintXStatus {
|
||||||
|
override fun onSuccess() {
|
||||||
|
onSuccess()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure() {
|
||||||
|
onFailure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -0,0 +1,180 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
|
import com.mob.utsmyanmar.viewmodel.SharedViewModel
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail
|
||||||
|
import com.utsmyanmar.paylibs.utils.PrintStatus
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.HostType
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.TransMenu
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||||
|
|
||||||
|
private sealed interface HistoryDestination {
|
||||||
|
data object Menu : HistoryDestination
|
||||||
|
data class SelectHost(val purpose: HistoryHostPurpose) : HistoryDestination
|
||||||
|
data class ReprintAny(val hostType: HostType) : HistoryDestination
|
||||||
|
data class DetailReport(val hostType: HostType) : HistoryDestination
|
||||||
|
data class SummaryReport(val hostType: HostType) : HistoryDestination
|
||||||
|
data object ReviewTrace : HistoryDestination
|
||||||
|
data class ReviewDetail(val trace: String) : HistoryDestination
|
||||||
|
data object BatchTotal : HistoryDestination
|
||||||
|
data object ReprintSettlement : HistoryDestination
|
||||||
|
data object NotFound : HistoryDestination
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun HistoryRoute(
|
||||||
|
sharedViewModel: SharedViewModel,
|
||||||
|
onBack: () -> Unit,
|
||||||
|
onNavigatePrintReceipt: () -> Unit,
|
||||||
|
viewModel: HistoryViewModel = hiltViewModel(),
|
||||||
|
) {
|
||||||
|
var destination by remember { mutableStateOf<HistoryDestination>(HistoryDestination.Menu) }
|
||||||
|
var hostPurpose by remember { mutableStateOf(HistoryHostPurpose.REPRINT_ANY) }
|
||||||
|
|
||||||
|
val voucherNo = SystemParamsOperation.getInstance().lastSuccessTrnx
|
||||||
|
val lastTransactions by viewModel.getLastTransaction(voucherNo).observeAsState(emptyList())
|
||||||
|
|
||||||
|
fun navigateToHostSelection(purpose: HistoryHostPurpose) {
|
||||||
|
hostPurpose = purpose
|
||||||
|
destination = HistoryDestination.SelectHost(purpose)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleHostSelected(hostType: HostType) {
|
||||||
|
sharedViewModel.hostType.value = hostType
|
||||||
|
destination = when (hostPurpose) {
|
||||||
|
HistoryHostPurpose.REPRINT_ANY ->
|
||||||
|
HistoryDestination.ReprintAny(hostType)
|
||||||
|
|
||||||
|
HistoryHostPurpose.LAST_SETTLEMENT -> {
|
||||||
|
if (hostType == HostType.MPU) {
|
||||||
|
HistoryDestination.ReprintSettlement
|
||||||
|
} else {
|
||||||
|
HistoryDestination.NotFound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HistoryHostPurpose.DETAIL_REPORT ->
|
||||||
|
HistoryDestination.DetailReport(hostType)
|
||||||
|
|
||||||
|
HistoryHostPurpose.SUMMARY_REPORT ->
|
||||||
|
HistoryDestination.SummaryReport(hostType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reprintTransaction(payDetail: PayDetail) {
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.REPRINT)
|
||||||
|
sharedViewModel.isReprint.value = true
|
||||||
|
sharedViewModel.payDetail.value = payDetail
|
||||||
|
sharedViewModel.setPrintStatus(PrintStatus.FIRST_PRINT)
|
||||||
|
onNavigatePrintReceipt()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reprintLastTransaction() {
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.REPRINT)
|
||||||
|
if (lastTransactions.isEmpty()) {
|
||||||
|
destination = HistoryDestination.NotFound
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val payDetail = lastTransactions.last()
|
||||||
|
if (!isValidForReprint(payDetail)) {
|
||||||
|
destination = HistoryDestination.NotFound
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
reprintTransaction(prepareReprintPayDetail(payDetail))
|
||||||
|
}
|
||||||
|
|
||||||
|
when (val current = destination) {
|
||||||
|
HistoryDestination.Menu -> HistoryMenuScreen(
|
||||||
|
onBack = onBack,
|
||||||
|
onReprintLastTransaction = ::reprintLastTransaction,
|
||||||
|
onReprintAnyTransaction = {
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.TRANSACTIONS)
|
||||||
|
sharedViewModel.transactionsType.value = null
|
||||||
|
navigateToHostSelection(HistoryHostPurpose.REPRINT_ANY)
|
||||||
|
},
|
||||||
|
onReprintLastSettlement = {
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.LAST_SETTLEMENT)
|
||||||
|
navigateToHostSelection(HistoryHostPurpose.LAST_SETTLEMENT)
|
||||||
|
},
|
||||||
|
onPrintDetailReport = {
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.DETAIL_REPORT)
|
||||||
|
navigateToHostSelection(HistoryHostPurpose.DETAIL_REPORT)
|
||||||
|
},
|
||||||
|
onPrintSummaryReport = {
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.SUMMARY_REPORT)
|
||||||
|
navigateToHostSelection(HistoryHostPurpose.SUMMARY_REPORT)
|
||||||
|
},
|
||||||
|
onReview = {
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.REVIEW)
|
||||||
|
sharedViewModel.transactionsType.value = TransactionsType.REVIEW_TRANS
|
||||||
|
destination = HistoryDestination.ReviewTrace
|
||||||
|
},
|
||||||
|
onBatchTotal = {
|
||||||
|
sharedViewModel.setTransMenu(TransMenu.REVIEW_BATCH)
|
||||||
|
destination = HistoryDestination.BatchTotal
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
is HistoryDestination.SelectHost -> SelectHostScreen(
|
||||||
|
onBack = { destination = HistoryDestination.Menu },
|
||||||
|
onSelectHost = ::handleHostSelected
|
||||||
|
)
|
||||||
|
|
||||||
|
is HistoryDestination.ReprintAny -> ReprintAnyTransactionScreen(
|
||||||
|
viewModel = viewModel,
|
||||||
|
hostType = current.hostType,
|
||||||
|
onBack = { destination = HistoryDestination.Menu },
|
||||||
|
onReprintTransaction = ::reprintTransaction
|
||||||
|
)
|
||||||
|
|
||||||
|
is HistoryDestination.DetailReport -> DetailReportScreen(
|
||||||
|
viewModel = viewModel,
|
||||||
|
hostType = current.hostType,
|
||||||
|
onBack = { destination = HistoryDestination.Menu }
|
||||||
|
)
|
||||||
|
|
||||||
|
is HistoryDestination.SummaryReport -> SummaryReportScreen(
|
||||||
|
viewModel = viewModel,
|
||||||
|
hostType = current.hostType,
|
||||||
|
onBack = { destination = HistoryDestination.Menu }
|
||||||
|
)
|
||||||
|
|
||||||
|
HistoryDestination.ReviewTrace -> ReviewTraceScreen(
|
||||||
|
viewModel = viewModel,
|
||||||
|
onBack = { destination = HistoryDestination.Menu },
|
||||||
|
onNavigateReviewDetail = { trace ->
|
||||||
|
destination = HistoryDestination.ReviewDetail(trace)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
is HistoryDestination.ReviewDetail -> ReviewDetailScreen(
|
||||||
|
viewModel = viewModel,
|
||||||
|
trace = current.trace,
|
||||||
|
onBack = { destination = HistoryDestination.ReviewTrace }
|
||||||
|
)
|
||||||
|
|
||||||
|
HistoryDestination.BatchTotal -> BatchTotalScreen(
|
||||||
|
viewModel = viewModel,
|
||||||
|
onBack = { destination = HistoryDestination.Menu }
|
||||||
|
)
|
||||||
|
|
||||||
|
HistoryDestination.ReprintSettlement -> ReprintSettlementScreen(
|
||||||
|
viewModel = viewModel,
|
||||||
|
onBack = { destination = HistoryDestination.Menu },
|
||||||
|
onDone = onBack
|
||||||
|
)
|
||||||
|
|
||||||
|
HistoryDestination.NotFound -> TransactionNotFoundScreen(
|
||||||
|
onBack = { destination = HistoryDestination.Menu }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,124 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail
|
||||||
|
import com.utsmyanmar.paylibs.model.SettleData
|
||||||
|
import com.utsmyanmar.paylibs.utils.POSUtil
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.HostType
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||||
|
import java.text.ParseException
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
internal fun formatTime(hour: String, minute: String): String {
|
||||||
|
if (hour.isBlank() || minute.isBlank()) return "Select"
|
||||||
|
return "$hour:$minute"
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class SummaryCounter {
|
||||||
|
var count = 0
|
||||||
|
var amount = 0L
|
||||||
|
|
||||||
|
fun inc(value: Long) {
|
||||||
|
count++
|
||||||
|
amount += value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun buildSummarySettleData(
|
||||||
|
transactions: List<PayDetail>,
|
||||||
|
hostType: HostType,
|
||||||
|
start: Date,
|
||||||
|
end: Date,
|
||||||
|
): SettleData {
|
||||||
|
val dateFormat = SimpleDateFormat("dd/MM/yy", Locale.getDefault())
|
||||||
|
val dateTimeFormat = SimpleDateFormat("dd/MM/yy HH:mm", Locale.getDefault())
|
||||||
|
val yesterday = POSUtil.getInstance().yesterdayDate
|
||||||
|
|
||||||
|
val wave = SummaryCounter()
|
||||||
|
val waveRefund = SummaryCounter()
|
||||||
|
val voidTran = SummaryCounter()
|
||||||
|
val sale = SummaryCounter()
|
||||||
|
val ca = SummaryCounter()
|
||||||
|
val preAuth = SummaryCounter()
|
||||||
|
val preAuthVoid = SummaryCounter()
|
||||||
|
val preAuthComp = SummaryCounter()
|
||||||
|
val preAuthCompVoid = SummaryCounter()
|
||||||
|
val refund = SummaryCounter()
|
||||||
|
|
||||||
|
for (pay in transactions) {
|
||||||
|
val transDate = try {
|
||||||
|
dateFormat.parse(pay.transDate)
|
||||||
|
} catch (_: ParseException) {
|
||||||
|
continue
|
||||||
|
} ?: continue
|
||||||
|
|
||||||
|
if (yesterday.after(transDate)) continue
|
||||||
|
|
||||||
|
val currentDate = try {
|
||||||
|
dateTimeFormat.parse("${pay.transDate} ${pay.transTime}")
|
||||||
|
} catch (_: ParseException) {
|
||||||
|
continue
|
||||||
|
} ?: continue
|
||||||
|
|
||||||
|
if (currentDate.before(start) || currentDate.after(end)) continue
|
||||||
|
|
||||||
|
when (hostType) {
|
||||||
|
HostType.QR -> when (pay.transactionType) {
|
||||||
|
TransactionsType.WAVEPAY.value ->
|
||||||
|
if (pay.qrTransStatus == 1) wave.inc(pay.amount)
|
||||||
|
|
||||||
|
TransactionsType.WAVEPAY_REFUND.value ->
|
||||||
|
if (pay.qrTransStatus == 1) waveRefund.inc(pay.amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
HostType.MPU -> if (pay.accountType == "MPU") {
|
||||||
|
accumulateCardSummary(
|
||||||
|
pay, sale, voidTran, ca, preAuth, preAuthVoid, preAuthComp, preAuthCompVoid, refund
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
HostType.VISA_MASTER -> if (pay.accountType != "MPU") {
|
||||||
|
accumulateCardSummary(
|
||||||
|
pay, sale, voidTran, ca, preAuth, preAuthVoid, preAuthComp, preAuthCompVoid, refund
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SettleData(
|
||||||
|
sale.count, sale.amount,
|
||||||
|
wave.count, wave.amount,
|
||||||
|
voidTran.count, voidTran.amount,
|
||||||
|
ca.count, ca.amount,
|
||||||
|
preAuth.count, preAuth.amount,
|
||||||
|
preAuthVoid.count, preAuthVoid.amount,
|
||||||
|
preAuthComp.count, preAuthComp.amount,
|
||||||
|
preAuthCompVoid.count, preAuthCompVoid.amount,
|
||||||
|
refund.count, refund.amount,
|
||||||
|
waveRefund.count, waveRefund.amount
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun accumulateCardSummary(
|
||||||
|
pay: PayDetail,
|
||||||
|
sale: SummaryCounter,
|
||||||
|
voidTran: SummaryCounter,
|
||||||
|
ca: SummaryCounter,
|
||||||
|
preAuth: SummaryCounter,
|
||||||
|
preAuthVoid: SummaryCounter,
|
||||||
|
preAuthComp: SummaryCounter,
|
||||||
|
preAuthCompVoid: SummaryCounter,
|
||||||
|
refund: SummaryCounter,
|
||||||
|
) {
|
||||||
|
when (pay.transactionType) {
|
||||||
|
TransactionsType.VOID.value -> voidTran.inc(pay.amount)
|
||||||
|
TransactionsType.SALE.value -> sale.inc(pay.amount)
|
||||||
|
TransactionsType.CASH_OUT.value -> ca.inc(pay.amount)
|
||||||
|
TransactionsType.PRE_AUTH_SALE.value -> preAuth.inc(pay.amount)
|
||||||
|
TransactionsType.PRE_AUTH_VOID.value -> preAuthVoid.inc(pay.amount)
|
||||||
|
TransactionsType.PRE_AUTH_COMPLETE.value -> preAuthComp.inc(pay.amount)
|
||||||
|
TransactionsType.PRE_AUTH_COMPLETE_VOID.value -> preAuthCompVoid.inc(pay.amount)
|
||||||
|
TransactionsType.REFUND.value -> refund.inc(pay.amount)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import com.utsmyanmar.baselib.repo.Repository
|
||||||
|
import com.utsmyanmar.paylibs.model.PayDetail
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class HistoryViewModel @Inject constructor(
|
||||||
|
private val repository: Repository
|
||||||
|
) : ViewModel() {
|
||||||
|
|
||||||
|
fun getTransactionHistory(): LiveData<List<PayDetail>> =
|
||||||
|
repository.getTransactionHistory()
|
||||||
|
|
||||||
|
fun getLastTransaction(voucherNo: String): LiveData<List<PayDetail>> =
|
||||||
|
repository.getLastTransaction(voucherNo)
|
||||||
|
|
||||||
|
fun getLastSettlement(voucherNo: String): LiveData<List<PayDetail>> =
|
||||||
|
repository.getLastSettlement(voucherNo)
|
||||||
|
|
||||||
|
fun getReviewBatchTransaction(batchNo: String): LiveData<List<PayDetail>> =
|
||||||
|
repository.getReviewBatchTransaction(batchNo)
|
||||||
|
|
||||||
|
fun getSmileSummaryTrans(batchNo: String): LiveData<List<PayDetail>> =
|
||||||
|
repository.getSmileSummaryTrans(batchNo)
|
||||||
|
|
||||||
|
fun searchTransaction(voucherNo: String): LiveData<PayDetail> =
|
||||||
|
repository.searchTransaction(voucherNo)
|
||||||
|
}
|
||||||
@ -0,0 +1,94 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
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.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
import androidx.compose.material3.OutlinedTextField
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
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.unit.dp
|
||||||
|
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.enums.HostType
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ReprintAnyTransactionScreen(
|
||||||
|
viewModel: HistoryViewModel,
|
||||||
|
hostType: HostType,
|
||||||
|
onBack: () -> Unit,
|
||||||
|
onReprintTransaction: (PayDetail) -> Unit,
|
||||||
|
) {
|
||||||
|
val allTransactions by viewModel.getTransactionHistory().observeAsState(emptyList())
|
||||||
|
var searchQuery by remember { mutableStateOf("") }
|
||||||
|
|
||||||
|
val filtered = remember(allTransactions, hostType, searchQuery) {
|
||||||
|
val base = filterReprintAnyTransactions(allTransactions, hostType)
|
||||||
|
searchReprintAnyTransactions(base, searchQuery.trim())
|
||||||
|
}
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
containerColor = Color.IvoryBeige,
|
||||||
|
topBar = {
|
||||||
|
AppBar(
|
||||||
|
title = "Transactions",
|
||||||
|
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
|
onIconClick = onBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
OutlinedTextField(
|
||||||
|
value = searchQuery,
|
||||||
|
onValueChange = { searchQuery = it },
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
label = { Text("Trace (6) or RRN (12)") },
|
||||||
|
singleLine = true
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
|
|
||||||
|
if (filtered.isEmpty()) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text("No transactions found.", color = Color.Gray)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
LazyColumn(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
items(filtered, key = { "${it.voucherNo}_${it.referNo}_${it.PID}" }) { payDetail ->
|
||||||
|
HistoryTransactionCard(payDetail) {
|
||||||
|
onReprintTransaction(prepareReprintPayDetail(payDetail))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.CircularProgressIndicator
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
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.platform.LocalContext
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
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.core_utils.SystemParamsOperation
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ReprintSettlementScreen(
|
||||||
|
viewModel: HistoryViewModel,
|
||||||
|
onBack: () -> Unit,
|
||||||
|
onDone: () -> Unit,
|
||||||
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val voucherNo = SystemParamsOperation.getInstance().currentSerialNum
|
||||||
|
val settlements by viewModel.getLastSettlement(voucherNo).observeAsState(emptyList())
|
||||||
|
var payDetail by remember { mutableStateOf<PayDetail?>(null) }
|
||||||
|
var hasStarted by remember { mutableStateOf(false) }
|
||||||
|
var printFailed by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
LaunchedEffect(settlements) {
|
||||||
|
if (hasStarted) return@LaunchedEffect
|
||||||
|
if (settlements.isEmpty()) {
|
||||||
|
Toast.makeText(context, "No transactions to print.", Toast.LENGTH_SHORT).show()
|
||||||
|
onBack()
|
||||||
|
return@LaunchedEffect
|
||||||
|
}
|
||||||
|
hasStarted = true
|
||||||
|
val detail = prepareReprintPayDetail(settlements.last())
|
||||||
|
payDetail = detail
|
||||||
|
printSettlementReport(context, detail, onSuccess = onDone) {
|
||||||
|
printFailed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
containerColor = Color.IvoryBeige,
|
||||||
|
topBar = {
|
||||||
|
AppBar(title = "Printing Settlement Report")
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.padding(16.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
verticalArrangement = Arrangement.Center
|
||||||
|
) {
|
||||||
|
if (printFailed) {
|
||||||
|
Text("Printing settlement report failed.", color = Color.LegacyRed)
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
Button(
|
||||||
|
onClick = {
|
||||||
|
payDetail?.let { detail ->
|
||||||
|
printSettlementReport(context, detail, onSuccess = onDone) {
|
||||||
|
printFailed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = Color.LegacyRed,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text("Retry")
|
||||||
|
}
|
||||||
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
TextButton(onClick = onDone) {
|
||||||
|
Text("Done")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CircularProgressIndicator(color = Color.LegacyRed)
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
Text("Printing settlement report...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,54 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
|
import androidx.compose.ui.Alignment
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.mob.utsmyanmar.ui.components.appbar.AppBar
|
||||||
|
import com.mob.utsmyanmar.ui.theme.Color
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ReviewDetailScreen(
|
||||||
|
viewModel: HistoryViewModel,
|
||||||
|
trace: String,
|
||||||
|
onBack: () -> Unit,
|
||||||
|
) {
|
||||||
|
val transaction by viewModel.searchTransaction(trace).observeAsState()
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
containerColor = Color.IvoryBeige,
|
||||||
|
topBar = {
|
||||||
|
AppBar(
|
||||||
|
title = "Transaction Info",
|
||||||
|
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
|
onIconClick = onBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
transaction?.let { payDetail ->
|
||||||
|
HistoryTransactionDetailCard(payDetail)
|
||||||
|
} ?: Box(
|
||||||
|
modifier = Modifier.fillMaxSize(),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text("Transaction not found.", color = Color.Gray)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,142 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
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.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
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.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
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.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
|
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
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ReviewTraceScreen(
|
||||||
|
viewModel: HistoryViewModel,
|
||||||
|
onBack: () -> Unit,
|
||||||
|
onNavigateReviewDetail: (String) -> Unit,
|
||||||
|
) {
|
||||||
|
var traceNumber by remember { mutableStateOf("") }
|
||||||
|
var searchedTrace by remember { mutableStateOf("") }
|
||||||
|
var lastNavigatedTrace by remember { mutableStateOf<String?>(null) }
|
||||||
|
|
||||||
|
val transactionSource: LiveData<PayDetail?> = remember(searchedTrace) {
|
||||||
|
if (searchedTrace.isBlank()) {
|
||||||
|
MutableLiveData(null)
|
||||||
|
} else {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
viewModel.searchTransaction(searchedTrace) as LiveData<PayDetail?>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val transaction by transactionSource.observeAsState()
|
||||||
|
|
||||||
|
LaunchedEffect(transaction?.voucherNo) {
|
||||||
|
val matchedTrace = transaction?.voucherNo ?: return@LaunchedEffect
|
||||||
|
if (lastNavigatedTrace == matchedTrace) return@LaunchedEffect
|
||||||
|
lastNavigatedTrace = matchedTrace
|
||||||
|
onNavigateReviewDetail(matchedTrace)
|
||||||
|
}
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
containerColor = Color.IvoryBeige,
|
||||||
|
topBar = {
|
||||||
|
AppBar(
|
||||||
|
title = "Review",
|
||||||
|
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
|
onIconClick = onBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.padding(16.dp)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = if (searchedTrace.isNotBlank() && transaction == null) {
|
||||||
|
"No transaction found for trace $searchedTrace."
|
||||||
|
} else {
|
||||||
|
"Input trace number to review transaction."
|
||||||
|
},
|
||||||
|
color = if (searchedTrace.isNotBlank() && transaction == null) {
|
||||||
|
Color.LegacyRed
|
||||||
|
} else {
|
||||||
|
Color.Black
|
||||||
|
},
|
||||||
|
fontSize = 14.sp
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
Card(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = Color.White)
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = traceNumber.padStart(6, '0').ifEmpty { "000000" },
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(24.dp),
|
||||||
|
textAlign = TextAlign.Center,
|
||||||
|
fontSize = 28.sp,
|
||||||
|
fontWeight = FontWeight.Bold
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
|
|
||||||
|
HistoryNumericKeypad(
|
||||||
|
onDigit = { digit ->
|
||||||
|
if (traceNumber.length < 6) traceNumber += digit
|
||||||
|
},
|
||||||
|
onBackspace = {
|
||||||
|
if (traceNumber.isNotEmpty()) {
|
||||||
|
traceNumber = traceNumber.dropLast(1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onClear = { traceNumber = "" }
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = { searchedTrace = traceNumber.padStart(6, '0') },
|
||||||
|
enabled = traceNumber.isNotBlank(),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(56.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = Color.LegacyRed,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text("Search")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,99 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
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.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.ElevatedButton
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
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.text.font.FontWeight
|
||||||
|
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.theme.Color
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.HostType
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SelectHostScreen(
|
||||||
|
onBack: () -> Unit,
|
||||||
|
onSelectHost: (HostType) -> Unit,
|
||||||
|
) {
|
||||||
|
var unavailableMessage by remember { mutableStateOf<String?>(null) }
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
containerColor = Color.IvoryBeige,
|
||||||
|
topBar = {
|
||||||
|
AppBar(
|
||||||
|
title = "Select Host",
|
||||||
|
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
|
onIconClick = onBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.padding(16.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
|
) {
|
||||||
|
HostButton("MPU") { onSelectHost(HostType.MPU) }
|
||||||
|
HostButton("Visa / Master") {
|
||||||
|
if (SystemParamsOperation.getInstance().isEmvEnabled) {
|
||||||
|
onSelectHost(HostType.VISA_MASTER)
|
||||||
|
} else {
|
||||||
|
unavailableMessage = "Currently this menu is unavailable!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HostButton("QR Pay") { onSelectHost(HostType.QR) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unavailableMessage?.let { message ->
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = { unavailableMessage = null },
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(onClick = { unavailableMessage = null }) {
|
||||||
|
Text("OK")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text = { Text(message) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun HostButton(
|
||||||
|
label: String,
|
||||||
|
onClick: () -> Unit,
|
||||||
|
) {
|
||||||
|
ElevatedButton(
|
||||||
|
onClick = onClick,
|
||||||
|
shape = RoundedCornerShape(12.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = Color.White,
|
||||||
|
contentColor = Color.Black
|
||||||
|
),
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(64.dp)
|
||||||
|
) {
|
||||||
|
Text(label, fontSize = 16.sp, fontWeight = FontWeight.SemiBold)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,220 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import android.app.DatePickerDialog
|
||||||
|
import android.app.TimePickerDialog
|
||||||
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
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.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
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.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.mob.utsmyanmar.ui.components.appbar.AppBar
|
||||||
|
import com.mob.utsmyanmar.ui.theme.Color
|
||||||
|
import com.utsmyanmar.paylibs.print.PrintHelper
|
||||||
|
import com.utsmyanmar.paylibs.print.printx.PrintXReceipt
|
||||||
|
import com.utsmyanmar.paylibs.print.printx.PrintXStatus
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
||||||
|
import com.utsmyanmar.paylibs.utils.enums.HostType
|
||||||
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||||
|
import com.utsmyanmar.paylibs.utils.params.Params
|
||||||
|
import java.text.ParseException
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.Calendar
|
||||||
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun SummaryReportScreen(
|
||||||
|
viewModel: HistoryViewModel,
|
||||||
|
hostType: HostType,
|
||||||
|
onBack: () -> Unit,
|
||||||
|
) {
|
||||||
|
val context = LocalContext.current
|
||||||
|
val calendarStart = remember { Calendar.getInstance() }
|
||||||
|
val calendarEnd = remember { Calendar.getInstance() }
|
||||||
|
|
||||||
|
var startDate by remember { mutableStateOf("") }
|
||||||
|
var endDate by remember { mutableStateOf("") }
|
||||||
|
var startHour by remember { mutableStateOf("") }
|
||||||
|
var startMinute by remember { mutableStateOf("") }
|
||||||
|
var endHour by remember { mutableStateOf("") }
|
||||||
|
var endMinute by remember { mutableStateOf("") }
|
||||||
|
var isPrinting by remember { mutableStateOf(false) }
|
||||||
|
var errorMessage by remember { mutableStateOf<String?>(null) }
|
||||||
|
|
||||||
|
val allTransactions by viewModel.getSmileSummaryTrans(
|
||||||
|
SystemParamsOperation.getInstance().currentBatchNum
|
||||||
|
).observeAsState(emptyList())
|
||||||
|
|
||||||
|
fun showDatePicker(isStart: Boolean) {
|
||||||
|
val calendar = if (isStart) calendarStart else calendarEnd
|
||||||
|
DatePickerDialog(
|
||||||
|
context,
|
||||||
|
{ _, year, month, day ->
|
||||||
|
calendar.set(year, month, day)
|
||||||
|
val formatted = SimpleDateFormat("dd/MM/yy", Locale.getDefault())
|
||||||
|
.format(calendar.time)
|
||||||
|
if (isStart) startDate = formatted else endDate = formatted
|
||||||
|
},
|
||||||
|
calendar.get(Calendar.YEAR),
|
||||||
|
calendar.get(Calendar.MONTH),
|
||||||
|
calendar.get(Calendar.DAY_OF_MONTH)
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showTimePicker(isStart: Boolean) {
|
||||||
|
val calendar = if (isStart) calendarStart else calendarEnd
|
||||||
|
TimePickerDialog(
|
||||||
|
context,
|
||||||
|
{ _, hour, minute ->
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, hour)
|
||||||
|
calendar.set(Calendar.MINUTE, minute)
|
||||||
|
val hr = String.format(Locale.getDefault(), "%02d", hour)
|
||||||
|
val min = String.format(Locale.getDefault(), "%02d", minute)
|
||||||
|
if (isStart) {
|
||||||
|
startHour = hr
|
||||||
|
startMinute = min
|
||||||
|
} else {
|
||||||
|
endHour = hr
|
||||||
|
endMinute = min
|
||||||
|
}
|
||||||
|
},
|
||||||
|
calendar.get(Calendar.HOUR_OF_DAY),
|
||||||
|
calendar.get(Calendar.MINUTE),
|
||||||
|
false
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun printSummaryReport() {
|
||||||
|
if (startDate.isBlank() || endDate.isBlank() ||
|
||||||
|
startHour.isBlank() || startMinute.isBlank() ||
|
||||||
|
endHour.isBlank() || endMinute.isBlank()
|
||||||
|
) {
|
||||||
|
errorMessage = "Please select date and time!"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val pattern = "dd/MM/yy HH:mm"
|
||||||
|
val formatter = SimpleDateFormat(pattern, Locale.getDefault())
|
||||||
|
val start: Date
|
||||||
|
val end: Date
|
||||||
|
try {
|
||||||
|
start = formatter.parse("$startDate $startHour:$startMinute") ?: return
|
||||||
|
end = formatter.parse("$endDate $endHour:$endMinute") ?: return
|
||||||
|
} catch (_: ParseException) {
|
||||||
|
errorMessage = "Invalid date or time."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (start.after(end)) {
|
||||||
|
errorMessage = "Invalid end date!"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val settleData = buildSummarySettleData(allTransactions, hostType, start, end)
|
||||||
|
if (settleData.saleCount + settleData.wavePayCount +
|
||||||
|
settleData.voidSaleCount + settleData.cashAdvanceCount +
|
||||||
|
settleData.preAuthCount + settleData.refundCount + settleData.waveRefundCount == 0
|
||||||
|
) {
|
||||||
|
errorMessage = "No transactions to print."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PrintHelper.getInstance().paperRollStatus() != 1) {
|
||||||
|
errorMessage = "Paper roll not ready."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val tradeData = Params.newTrade(false)
|
||||||
|
val payDetail = tradeData.payDetail
|
||||||
|
payDetail.settleDataObj = settleData
|
||||||
|
payDetail.transType = TransactionsType.SUMMARY_REPORT.name
|
||||||
|
payDetail.transactionType = TransactionsType.SUMMARY_REPORT.value
|
||||||
|
payDetail.accountType = hostTypeAccountLabel(hostType)
|
||||||
|
|
||||||
|
isPrinting = true
|
||||||
|
PrintXReceipt.getInstance().printSmileSummaryReport(
|
||||||
|
payDetail,
|
||||||
|
object : PrintXStatus {
|
||||||
|
override fun onSuccess() {
|
||||||
|
isPrinting = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure() {
|
||||||
|
isPrinting = false
|
||||||
|
errorMessage = "Print failed."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Scaffold(
|
||||||
|
containerColor = Color.IvoryBeige,
|
||||||
|
topBar = {
|
||||||
|
AppBar(
|
||||||
|
title = "Transaction Summary",
|
||||||
|
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
|
onIconClick = onBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues)
|
||||||
|
.padding(16.dp),
|
||||||
|
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
|
) {
|
||||||
|
SummaryPickerRow("Start Date", startDate.ifBlank { "Select" }) { showDatePicker(true) }
|
||||||
|
SummaryPickerRow("Start Time", formatTime(startHour, startMinute)) { showTimePicker(true) }
|
||||||
|
SummaryPickerRow("End Date", endDate.ifBlank { "Select" }) { showDatePicker(false) }
|
||||||
|
SummaryPickerRow("End Time", formatTime(endHour, endMinute)) { showTimePicker(false) }
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = ::printSummaryReport,
|
||||||
|
enabled = !isPrinting,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.height(56.dp),
|
||||||
|
colors = ButtonDefaults.buttonColors(
|
||||||
|
containerColor = Color.LegacyRed,
|
||||||
|
contentColor = Color.White
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
Text(if (isPrinting) "Printing..." else "Print")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errorMessage?.let { message ->
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = { errorMessage = null },
|
||||||
|
confirmButton = {
|
||||||
|
TextButton(onClick = { errorMessage = null }) {
|
||||||
|
Text("OK")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
text = { Text(message) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
package com.mob.utsmyanmar.ui.history_functions
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
|
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.unit.sp
|
||||||
|
import com.mob.utsmyanmar.ui.components.appbar.AppBar
|
||||||
|
import com.mob.utsmyanmar.ui.theme.Color
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun TransactionNotFoundScreen(onBack: () -> Unit) {
|
||||||
|
Scaffold(
|
||||||
|
containerColor = Color.IvoryBeige,
|
||||||
|
topBar = {
|
||||||
|
AppBar(
|
||||||
|
title = "Transaction Info",
|
||||||
|
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
||||||
|
onIconClick = onBack
|
||||||
|
)
|
||||||
|
}
|
||||||
|
) { paddingValues ->
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(paddingValues),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Text(
|
||||||
|
text = "Transaction not found.",
|
||||||
|
color = Color.Gray,
|
||||||
|
fontSize = 16.sp
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -22,6 +22,7 @@ import com.mob.utsmyanmar.ui.dashboard.DashboardViewModel
|
|||||||
import com.mob.utsmyanmar.ui.device_info.DeviceInfoViewModel
|
import com.mob.utsmyanmar.ui.device_info.DeviceInfoViewModel
|
||||||
import com.mob.utsmyanmar.ui.disable.DisableScreen
|
import com.mob.utsmyanmar.ui.disable.DisableScreen
|
||||||
import com.mob.utsmyanmar.ui.functions.FunctionsScreen
|
import com.mob.utsmyanmar.ui.functions.FunctionsScreen
|
||||||
|
import com.mob.utsmyanmar.ui.history_functions.HistoryRoute
|
||||||
import com.mob.utsmyanmar.ui.input_amount.AmountRoute
|
import com.mob.utsmyanmar.ui.input_amount.AmountRoute
|
||||||
import com.mob.utsmyanmar.ui.manual_entry.InputManualCardRoute
|
import com.mob.utsmyanmar.ui.manual_entry.InputManualCardRoute
|
||||||
import com.mob.utsmyanmar.ui.notification.NotificationDetailScreen
|
import com.mob.utsmyanmar.ui.notification.NotificationDetailScreen
|
||||||
@ -158,6 +159,11 @@ fun AppNavGraph(
|
|||||||
launchSingleTop = true
|
launchSingleTop = true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
onNavigateHistory = {
|
||||||
|
navController.navigate(Routes.Password.createRoute(Routes.History.route, PasswordType.SYSTEM)) {
|
||||||
|
launchSingleTop = true
|
||||||
|
}
|
||||||
|
},
|
||||||
onNavigateAction = { action ->
|
onNavigateAction = { action ->
|
||||||
when (action) {
|
when (action) {
|
||||||
"Void" -> {
|
"Void" -> {
|
||||||
@ -225,6 +231,24 @@ fun AppNavGraph(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
composable(Routes.History.route) {
|
||||||
|
val sharedViewModel: SharedViewModel = hiltViewModel(activity)
|
||||||
|
val transResultViewModel: TransactionResultViewModel = hiltViewModel(activity)
|
||||||
|
HistoryRoute(
|
||||||
|
sharedViewModel = sharedViewModel,
|
||||||
|
onBack = { navController.popBackStack() },
|
||||||
|
onNavigatePrintReceipt = {
|
||||||
|
transResultViewModel.onEvent(
|
||||||
|
TransactionResultEvent.Start,
|
||||||
|
sharedViewModel
|
||||||
|
)
|
||||||
|
navController.navigate(Routes.PrintReceipt.route) {
|
||||||
|
launchSingleTop = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
composable(Routes.VoidTrace.route) {
|
composable(Routes.VoidTrace.route) {
|
||||||
val voidViewModel: VoidViewModel = hiltViewModel()
|
val voidViewModel: VoidViewModel = hiltViewModel()
|
||||||
val sharedViewModel: SharedViewModel = hiltViewModel(activity)
|
val sharedViewModel: SharedViewModel = hiltViewModel(activity)
|
||||||
|
|||||||
@ -40,6 +40,7 @@ sealed class Routes(val route: String) {
|
|||||||
data object NotificationDetail : Routes("notification_detail/{notificationId}") {
|
data object NotificationDetail : Routes("notification_detail/{notificationId}") {
|
||||||
fun createRoute(id: Int): String = "notification_detail/$id"
|
fun createRoute(id: Int): String = "notification_detail/$id"
|
||||||
}
|
}
|
||||||
|
data object History : Routes("history")
|
||||||
data object Disable : Routes("disable/{message}") {
|
data object Disable : Routes("disable/{message}") {
|
||||||
fun createRoute(message: String): String = "disable/${Uri.encode(message)}"
|
fun createRoute(message: String): String = "disable/${Uri.encode(message)}"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,5 @@
|
|||||||
package com.mob.utsmyanmar.ui.sending_to_host
|
package com.mob.utsmyanmar.ui.sending_to_host
|
||||||
|
|
||||||
import androidx.compose.material3.AlertDialog
|
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TextButton
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
@ -12,19 +8,12 @@ import com.mob.utsmyanmar.viewmodel.SharedViewModel
|
|||||||
import com.mob.utsmyanmar.viewmodel.TransProcessViewModel
|
import com.mob.utsmyanmar.viewmodel.TransProcessViewModel
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import androidx.compose.runtime.getValue
|
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 androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import com.mob.utsmyanmar.model.TransactionStatus
|
import com.mob.utsmyanmar.model.TransactionStatus
|
||||||
import com.mob.utsmyanmar.ui.settlement.SettlementViewModel
|
import com.mob.utsmyanmar.ui.settlement.SettlementViewModel
|
||||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||||
import kotlinx.coroutines.channels.Channel
|
|
||||||
|
|
||||||
private const val MOCK_HOST_DELAY_MS = 2000L
|
private const val MOCK_HOST_DELAY_MS = 2000L
|
||||||
|
|
||||||
@ -43,8 +32,6 @@ fun ProcessingRoute(
|
|||||||
|
|
||||||
val settlementStatus by settlementViewModel.uiState.collectAsStateWithLifecycle()
|
val settlementStatus by settlementViewModel.uiState.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
var showReversalDialog by rememberSaveable { mutableStateOf(false) }
|
|
||||||
var reversalMessage by rememberSaveable { mutableStateOf("") }
|
|
||||||
|
|
||||||
if(sharedViewModel.transactionsType.value == TransactionsType.SETTLEMENT) {
|
if(sharedViewModel.transactionsType.value == TransactionsType.SETTLEMENT) {
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user