Compare commits

..

9 Commits

Author SHA1 Message Date
moon
2323562270 fixed yestarday only date for filters 2026-08-26 00:04:33 +06:30
moon
c45c8adf65 Fixed ReprintAnyTransactions and new keyboard layout 2026-08-25 23:34:00 +06:30
moon
2ca1b5eee0 change date format 00/00/00 to 00/00/0000 2026-08-25 23:00:42 +06:30
moon
bb9db73182 disable next btn if amount is 0 2026-08-25 22:42:18 +06:30
moon
59153170bf - prefix in void, refund and cash adv 2026-08-25 22:39:45 +06:30
moon
726310a779 jcb logo align 2026-08-25 22:15:37 +06:30
moon
209279b847 JCB logo added 2026-08-25 21:46:33 +06:30
moon
7ccf393793 auto width printReceiptScreen dot 2026-08-25 21:37:47 +06:30
moon
81920acc8c receipt fix 2026-08-25 14:20:40 +06:30
21 changed files with 363 additions and 117 deletions

View File

@ -40,8 +40,8 @@ android {
dimension = "env" dimension = "env"
applicationIdSuffix = ".uat" applicationIdSuffix = ".uat"
versionNameSuffix = "-UAT" versionNameSuffix = "-UAT"
versionCode = 15 versionCode = 17
versionName = "3.3" versionName = "3.5"
buildConfigField("String", "ENV", "\"UAT\"") buildConfigField("String", "ENV", "\"UAT\"")
resValue("string", "app_name", "MOB-UAT") resValue("string", "app_name", "MOB-UAT")
} }

View File

@ -38,3 +38,6 @@ Mark intentional simplifications with a ponytail: comment. If the shortcut has a
Not lazy about: understanding the problem (read it fully and trace the real flow before picking a rung, a small diff you don't understand is just laziness dressed up as efficiency), input validation at trust boundaries, error handling that prevents data loss, security, accessibility, the calibration real hardware needs (the platform is never the spec ideal, a clock drifts, a sensor reads off), anything explicitly requested. Lazy code without its check is unfinished: non-trivial logic leaves ONE runnable check behind, the smallest thing that fails if the logic breaks (an assert-based demo/self-check or one small test file; no frameworks, no fixtures). Trivial one-liners need no test. Not lazy about: understanding the problem (read it fully and trace the real flow before picking a rung, a small diff you don't understand is just laziness dressed up as efficiency), input validation at trust boundaries, error handling that prevents data loss, security, accessibility, the calibration real hardware needs (the platform is never the spec ideal, a clock drifts, a sensor reads off), anything explicitly requested. Lazy code without its check is unfinished: non-trivial logic leaves ONE runnable check behind, the smallest thing that fails if the logic breaks (an assert-based demo/self-check or one small test file; no frameworks, no fixtures). Trivial one-liners need no test.
(Yes, this file also applies to agents working on the ponytail repo itself. Especially to them.) (Yes, this file also applies to agents working on the ponytail repo itself. Especially to them.)
### Don't Do This
- don't run ./grdlew

View File

@ -29,7 +29,7 @@ object SettlementScheduler {
val configuredTime = parseTime( val configuredTime = parseTime(
// SystemParamsOperation.getInstance().clearBatchTime // SystemParamsOperation.getInstance().clearBatchTime
"10:50:00" "21:35:00"
) ?: parseTime(FALLBACK_ALERT_TIME)!! ) ?: parseTime(FALLBACK_ALERT_TIME)!!
val calendar = Calendar.getInstance().apply { val calendar = Calendar.getInstance().apply {

View File

@ -389,6 +389,10 @@ private fun CardLogoRow() {
horizontalArrangement = Arrangement.SpaceEvenly, horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically verticalAlignment = Alignment.CenterVertically
) { ) {
CardLogo(
icon = painterResource(R.drawable.logo_mpu),
name = "master",
)
CardLogo( CardLogo(
icon = painterResource(R.drawable.logo_visa), icon = painterResource(R.drawable.logo_visa),
name = "visa", name = "visa",
@ -398,12 +402,12 @@ private fun CardLogoRow() {
name = "master", name = "master",
) )
CardLogo( CardLogo(
icon = painterResource(R.drawable.logo_mpu), icon = painterResource(R.drawable.logo_union_pay),
name = "master", name = "union",
) )
CardLogo( CardLogo(
icon = painterResource(R.drawable.logo_union_pay), icon = painterResource(R.drawable.logo_jcb),
name = "master", name = "jcb",
) )
} }
} }

View File

@ -61,10 +61,8 @@ class CardWaitingViewModel(
retryCounter = 0 retryCounter = 0
fallbackCounter = SystemParamsOperation.getInstance().fallbackCounter fallbackCounter = SystemParamsOperation.getInstance().fallbackCounter
fallbackEnabled = SystemParamsOperation.getInstance().fallbackEnabled fallbackEnabled = SystemParamsOperation.getInstance().fallbackEnabled
val isSaleTransaction = sharedViewModel.transactionsType.value == TransactionsType.SALE
_uiState.update { _uiState.update {
it.copy(canGoBack = !isSaleTransaction) it.copy(canGoBack = true)
} }
if (sharedViewModel.transactionsType.value == TransactionsType.REFUND) { if (sharedViewModel.transactionsType.value == TransactionsType.REFUND) {

View File

@ -23,8 +23,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.mob.utsmyanmar.ui.theme.Color import com.mob.utsmyanmar.ui.theme.Color
import com.mob.utsmyanmar.utils.convertDateString
import com.utsmyanmar.paylibs.model.PayDetail import com.utsmyanmar.paylibs.model.PayDetail
import com.utsmyanmar.paylibs.utils.POSUtil
@Composable @Composable
internal fun HistoryTransactionCard( internal fun HistoryTransactionCard(
@ -54,7 +54,7 @@ internal fun HistoryTransactionCard(
style = MaterialTheme.typography.titleSmall style = MaterialTheme.typography.titleSmall
) )
Text( Text(
text = POSUtil.getInstance().formatAmount(payDetail.amount), text = displayAmountWithSign(payDetail),
style = MaterialTheme.typography.titleSmall style = MaterialTheme.typography.titleSmall
) )
} }
@ -62,7 +62,7 @@ internal fun HistoryTransactionCard(
Text("Trace ${payDetail.voucherNo.ifBlank { "-" }}", style = MaterialTheme.typography.bodySmall) Text("Trace ${payDetail.voucherNo.ifBlank { "-" }}", style = MaterialTheme.typography.bodySmall)
Text("RRN ${payDetail.referNo.ifBlank { "-" }}", style = MaterialTheme.typography.bodySmall, color = Color.Gray) Text("RRN ${payDetail.referNo.ifBlank { "-" }}", style = MaterialTheme.typography.bodySmall, color = Color.Gray)
Text( Text(
"${payDetail.transDate} ${payDetail.transTime}", "${convertDateString(payDetail.transDate)} ${payDetail.transTime}",
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = Color.Gray color = Color.Gray
) )
@ -85,13 +85,13 @@ internal fun HistoryTransactionDetailCard(payDetail: PayDetail) {
color = Color.LegacyRed, color = Color.LegacyRed,
style = MaterialTheme.typography.titleMedium style = MaterialTheme.typography.titleMedium
) )
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("Date", payDetail.tradeDate)
SummaryLine("Time", payDetail.tradeTime) SummaryLine("Time", payDetail.tradeTime)
SummaryLine("Amount", displayAmountWithSign(payDetail))
SummaryLine("Trace No", payDetail.voucherNo)
// SummaryLine("Card No", payDetail.cardNo)
SummaryLine("Reference No", payDetail.referNo)
SummaryLine("Approval Code", payDetail.approvalCode.orEmpty())
SummaryLine("Status", displayTransactionStatus(payDetail)) SummaryLine("Status", displayTransactionStatus(payDetail))
} }
} }

View File

@ -46,6 +46,7 @@ internal fun displayTransactionTitle(payDetail: PayDetail): String {
internal fun isValidForReprint(payDetail: PayDetail): Boolean { internal fun isValidForReprint(payDetail: PayDetail): Boolean {
if (payDetail.transactionType == TransactionsType.SETTLEMENT.value) return false 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) { if (payDetail.transactionType == TransactionsType.WAVEPAY.value && payDetail.qrTransStatus != 1) {
return false return false
} }
@ -59,14 +60,8 @@ internal fun filterReprintAnyTransactions(
transactions: List<PayDetail>, transactions: List<PayDetail>,
hostType: HostType hostType: HostType
): List<PayDetail> { ): List<PayDetail> {
val yesterday = POSUtil.getInstance().yesterdayDate
val dateFormat = SimpleDateFormat("dd/MM/yy", Locale.getDefault())
return transactions.filter { pay -> return transactions.filter { pay ->
val transDate = parseTransDate(pay.transDate, dateFormat) ?: return@filter false if (!isValidForReprint(pay)) 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) { when (hostType) {
HostType.MPU -> HostType.MPU ->
@ -91,10 +86,7 @@ internal fun filterDetailReportTransactions(
transactions: List<PayDetail>, transactions: List<PayDetail>,
hostType: HostType hostType: HostType
): List<PayDetail> { ): List<PayDetail> {
val yesterday = POSUtil.getInstance().yesterdayDate
return transactions.filter { pay -> 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.REVERSAL.value) return@filter false
if (pay.transactionType == TransactionsType.SETTLEMENT.value) return@filter false if (pay.transactionType == TransactionsType.SETTLEMENT.value) return@filter false
@ -117,10 +109,20 @@ internal fun filterDetailReportTransactions(
} }
} }
internal fun displayAmountWithSign(payDetail: PayDetail): String {
val prefix = if (payDetail.transactionType == TransactionsType.VOID.value ||
payDetail.transactionType == TransactionsType.REFUND.value ||
payDetail.transactionType == TransactionsType.WAVEPAY_REFUND.value ||
payDetail.transactionType == TransactionsType.CASH_OUT.value
) "-" else ""
return prefix + POSUtil.getInstance().formatAmount(payDetail.amount)
}
internal fun detailReportSignedAmount(payDetail: PayDetail): Long { internal fun detailReportSignedAmount(payDetail: PayDetail): Long {
val isNegative = payDetail.transactionType == TransactionsType.VOID.value || val isNegative = payDetail.transactionType == TransactionsType.VOID.value ||
payDetail.transactionType == TransactionsType.REFUND.value || payDetail.transactionType == TransactionsType.REFUND.value ||
payDetail.transactionType == TransactionsType.WAVEPAY_REFUND.value payDetail.transactionType == TransactionsType.WAVEPAY_REFUND.value ||
payDetail.transactionType == TransactionsType.CASH_OUT.value
return if (isNegative) -payDetail.amount else payDetail.amount return if (isNegative) -payDetail.amount else payDetail.amount
} }

View File

@ -2,7 +2,6 @@ package com.mob.utsmyanmar.ui.history_functions
import com.utsmyanmar.paylibs.model.PayDetail import com.utsmyanmar.paylibs.model.PayDetail
import com.utsmyanmar.paylibs.model.SettleData import com.utsmyanmar.paylibs.model.SettleData
import com.utsmyanmar.paylibs.utils.POSUtil
import com.utsmyanmar.paylibs.utils.enums.HostType import com.utsmyanmar.paylibs.utils.enums.HostType
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
import java.text.ParseException import java.text.ParseException
@ -31,9 +30,7 @@ internal fun buildSummarySettleData(
start: Date, start: Date,
end: Date, end: Date,
): SettleData { ): SettleData {
val dateFormat = SimpleDateFormat("dd/MM/yy", Locale.getDefault())
val dateTimeFormat = SimpleDateFormat("dd/MM/yy HH:mm", Locale.getDefault()) val dateTimeFormat = SimpleDateFormat("dd/MM/yy HH:mm", Locale.getDefault())
val yesterday = POSUtil.getInstance().yesterdayDate
val wave = SummaryCounter() val wave = SummaryCounter()
val waveRefund = SummaryCounter() val waveRefund = SummaryCounter()
@ -47,14 +44,6 @@ internal fun buildSummarySettleData(
val refund = SummaryCounter() val refund = SummaryCounter()
for (pay in transactions) { for (pay in transactions) {
val transDate = try {
dateFormat.parse(pay.transDate)
} catch (_: ParseException) {
continue
} ?: continue
if (yesterday.after(transDate)) continue
val currentDate = try { val currentDate = try {
dateTimeFormat.parse("${pay.transDate} ${pay.transTime}") dateTimeFormat.parse("${pay.transDate} ${pay.transTime}")
} catch (_: ParseException) { } catch (_: ParseException) {

View File

@ -1,8 +1,13 @@
package com.mob.utsmyanmar.ui.history_functions 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.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth 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.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack 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.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
@ -23,12 +37,27 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier 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 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.Color
import com.mob.utsmyanmar.ui.theme.MOBPOSTheme
import com.utsmyanmar.paylibs.model.PayDetail import com.utsmyanmar.paylibs.model.PayDetail
import com.utsmyanmar.paylibs.utils.enums.HostType 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 @Composable
fun ReprintAnyTransactionScreen( fun ReprintAnyTransactionScreen(
viewModel: HistoryViewModel, viewModel: HistoryViewModel,
@ -38,6 +67,7 @@ fun ReprintAnyTransactionScreen(
) { ) {
val allTransactions by viewModel.getTransactionHistory().observeAsState(emptyList()) val allTransactions by viewModel.getTransactionHistory().observeAsState(emptyList())
var searchQuery by remember { mutableStateOf("") } var searchQuery by remember { mutableStateOf("") }
var isFocused by remember { mutableStateOf(false) }
val filtered = remember(allTransactions, hostType, searchQuery) { val filtered = remember(allTransactions, hostType, searchQuery) {
val base = filterReprintAnyTransactions(allTransactions, hostType) val base = filterReprintAnyTransactions(allTransactions, hostType)
@ -47,10 +77,32 @@ fun ReprintAnyTransactionScreen(
Scaffold( Scaffold(
containerColor = Color.IvoryBeige, containerColor = Color.IvoryBeige,
topBar = { topBar = {
AppBar( TopAppBar(
title = "Transactions", title = {
icon = Icons.AutoMirrored.Filled.ArrowBack, Column {
onIconClick = onBack 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 -> ) { paddingValues ->
@ -58,37 +110,154 @@ fun ReprintAnyTransactionScreen(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.padding(paddingValues) .padding(paddingValues)
.padding(16.dp) .padding(horizontal = 16.dp)
) { ) {
OutlinedTextField( SearchInputBox(
value = searchQuery, query = searchQuery,
onValueChange = { searchQuery = it }, isFocused = isFocused,
modifier = Modifier.fillMaxWidth(), onFocus = { isFocused = true }
label = { Text("Trace (6) or RRN (12)") },
singleLine = 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()) { if (filtered.isEmpty()) {
Box( Box(
modifier = Modifier.fillMaxSize(), modifier = Modifier.weight(1f),
contentAlignment = Alignment.Center 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 { } else {
LazyColumn( LazyColumn(
modifier = Modifier.fillMaxSize(), modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(8.dp) verticalArrangement = Arrangement.spacedBy(8.dp)
) { ) {
items(filtered, key = { "${it.voucherNo}_${it.referNo}_${it.PID}" }) { payDetail -> items(filtered, key = { "${it.voucherNo}_${it.referNo}_${it.PID}" }) { payDetail ->
HistoryTransactionCard(payDetail) { HistoryTransactionCard(payDetail) {
isFocused = false
onReprintTransaction(prepareReprintPayDetail(payDetail)) 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)
}
}
} }
} }
} }

View File

@ -171,16 +171,16 @@ fun InputAmount(
Text("Cancel") Text("Cancel")
} }
val isAmountValid = amount.toDoubleOrNull()?.let { it > 0.0 } == true
Button( Button(
onClick = { onClick = {
if (amount.isNotEmpty()) {
onChargeClick(amount) onChargeClick(amount)
}
}, },
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.height(56.dp), .height(56.dp),
enabled = amount.isNotEmpty(), enabled = isAmountValid,
shape = RoundedCornerShape(8.dp), shape = RoundedCornerShape(8.dp),
colors = ButtonDefaults.buttonColors( colors = ButtonDefaults.buttonColors(
containerColor = Color.LegacyRed, containerColor = Color.LegacyRed,

View File

@ -3,6 +3,7 @@ package com.mob.utsmyanmar.ui.print_receipt
import androidx.compose.animation.core.Animatable import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.FastOutSlowInEasing import androidx.compose.animation.core.FastOutSlowInEasing
import androidx.compose.animation.core.tween import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
@ -32,20 +33,26 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.mob.utsmyanmar.ui.components.appbar.AppBar import com.mob.utsmyanmar.ui.components.appbar.AppBar
import com.mob.utsmyanmar.ui.history_functions.displayTransactionStatus import com.mob.utsmyanmar.ui.history_functions.displayTransactionStatus
import com.mob.utsmyanmar.ui.history_functions.displayTransactionTitle import com.mob.utsmyanmar.ui.history_functions.displayTransactionTitle
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.Color
import com.mob.utsmyanmar.ui.theme.MOBPOSTheme
import com.mob.utsmyanmar.ui.transaction_result.TransactionResultState import com.mob.utsmyanmar.ui.transaction_result.TransactionResultState
import com.mob.utsmyanmar.ui.transaction_result.TransactionResultViewModel import com.mob.utsmyanmar.ui.transaction_result.TransactionResultViewModel
import com.mob.utsmyanmar.utils.convertDateString
import com.mob.utsmyanmar.viewmodel.SharedViewModel import com.mob.utsmyanmar.viewmodel.SharedViewModel
import com.utsmyanmar.paylibs.model.PayDetail
import com.utsmyanmar.paylibs.utils.POSUtil import com.utsmyanmar.paylibs.utils.POSUtil
import com.utsmyanmar.paylibs.utils.PrintStatus import com.utsmyanmar.paylibs.utils.PrintStatus
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
private enum class ReceiptCopy(val label: String) { private enum class ReceiptCopy(val label: String) {
@ -62,6 +69,29 @@ fun PrintReceiptScreen(
onPrintFinished: () -> Unit, onPrintFinished: () -> Unit,
) { ) {
val state by transactionResultViewModel.state.collectAsStateWithLifecycle() val state by transactionResultViewModel.state.collectAsStateWithLifecycle()
val isReprint = sharedViewModel.isReprint.value ?: false
PrintReceiptContent(
state = state,
isReprint = isReprint,
onPrint = onPrint,
onDone = onDone,
onPrintFinished = onPrintFinished,
onSetPrintStatus = { sharedViewModel.setPrintStatus(it) },
onResetReprint = { sharedViewModel.isReprint.value = false },
)
}
@Composable
fun PrintReceiptContent(
state: TransactionResultState,
isReprint: Boolean,
onPrint: () -> Unit,
onDone: () -> Unit,
onPrintFinished: () -> Unit,
onSetPrintStatus: (PrintStatus) -> Unit,
onResetReprint: () -> Unit
) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val receiptOffsetY = remember { Animatable(0f) } val receiptOffsetY = remember { Animatable(0f) }
val merchant_copy_autoprint = true val merchant_copy_autoprint = true
@ -82,14 +112,11 @@ fun PrintReceiptScreen(
) )
} }
fun isReprintMode() = sharedViewModel.isReprint.value == true
fun doPrint(copy: ReceiptCopy, onFinished: (printFinished: ReceiptCopy) -> Unit) { fun doPrint(copy: ReceiptCopy, onFinished: (printFinished: ReceiptCopy) -> Unit) {
val reprint = isReprintMode() val actualCopy = if (isReprint && copy == ReceiptCopy.MERCHANT) ReceiptCopy.CUSTOMER else copy
val actualCopy = if (reprint && copy == ReceiptCopy.MERCHANT) ReceiptCopy.CUSTOMER else copy
currentCopy = actualCopy currentCopy = actualCopy
sharedViewModel.setPrintStatus( onSetPrintStatus(
if (actualCopy == ReceiptCopy.MERCHANT) if (actualCopy == ReceiptCopy.MERCHANT)
PrintStatus.FIRST_PRINT PrintStatus.FIRST_PRINT
else else
@ -100,7 +127,7 @@ fun PrintReceiptScreen(
isPrinting = true isPrinting = true
animatePrint() animatePrint()
isPrinting = false isPrinting = false
val upcomingCopy = if (reprint) ReceiptCopy.CUSTOMER val upcomingCopy = if (isReprint) ReceiptCopy.CUSTOMER
else if (actualCopy == ReceiptCopy.MERCHANT) ReceiptCopy.CUSTOMER else if (actualCopy == ReceiptCopy.MERCHANT) ReceiptCopy.CUSTOMER
else ReceiptCopy.CUSTOMER else ReceiptCopy.CUSTOMER
@ -112,14 +139,13 @@ fun PrintReceiptScreen(
} }
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
val reprint = isReprintMode() if (isReprint) {
if (reprint) {
currentCopy = ReceiptCopy.CUSTOMER currentCopy = ReceiptCopy.CUSTOMER
nextCopy = ReceiptCopy.CUSTOMER nextCopy = ReceiptCopy.CUSTOMER
} }
sharedViewModel.isReprint.value = false onResetReprint()
when { when {
merchant_copy_autoprint && !reprint -> doPrint(ReceiptCopy.MERCHANT) { } merchant_copy_autoprint && !isReprint -> doPrint(ReceiptCopy.MERCHANT) { }
customer_copy_autoprint -> doPrint(ReceiptCopy.CUSTOMER) { } customer_copy_autoprint -> doPrint(ReceiptCopy.CUSTOMER) { }
} }
} }
@ -209,6 +235,7 @@ fun ReceiptPreview(
copyLabel: String, copyLabel: String,
modifier: Modifier = Modifier modifier: Modifier = Modifier
) { ) {
val isPreview = LocalInspectionMode.current
Column( Column(
modifier = modifier modifier = modifier
.fillMaxWidth() .fillMaxWidth()
@ -239,17 +266,21 @@ fun ReceiptPreview(
) )
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
ReceiptDivider() ReceiptDivider()
ReceiptRow("Merchant", state.payDetail?.merchantName.toString() ) ReceiptRow("Date", convertDateString(state.payDetail?.transDate.toString()))
ReceiptRow("Terminal ID", state.payDetail?.terminalNo.toString() ) ReceiptRow("Time", state.payDetail?.transTime.toString())
ReceiptRow("Merchant Name", state.payDetail?.merchantName.toString())
ReceiptRow("TID", state.payDetail?.terminalNo.toString())
ReceiptRow("Trace No", state.payDetail?.voucherNo.toString()) ReceiptRow("Trace No", state.payDetail?.voucherNo.toString())
ReceiptRow("Transaction", state.payDetail?.let(::displayTransactionTitle).orEmpty()) ReceiptRow("Ref No", state.payDetail?.referNo.toString())
ReceiptRow("Amount", POSUtil.getInstance().getDecimalAmountSeparatorFormat(state.payDetail?.amount?:0)) ReceiptRow("Approval Code", state.payDetail?.approvalCode.toString())
ReceiptRow("Transaction Type", state.payDetail?.let(::displayTransactionTitle).orEmpty())
ReceiptRow("Amount", POSUtil.getInstance().getDecimalAmountSeparatorFormat(state.payDetail?.amount?:0).let { amt ->
val prefix = POSUtil.getInstance().checkMinusSign(state.payDetail?.transactionType ?: 0)
if (prefix.isEmpty() && (state.payDetail?.transactionType ?: 0) == TransactionsType.CASH_OUT.value) "-$amt" else "$prefix$amt"
})
ReceiptRow("Card Type", state.payDetail?.accountType.toString()) ReceiptRow("Card Type", state.payDetail?.accountType.toString())
ReceiptRow("Card No", state.payDetail?.cardNo.toString()) ReceiptRow("Card No", state.payDetail?.cardNo.toString())
ReceiptRow("Status", state.payDetail?.let(::displayTransactionStatus).orEmpty()) ReceiptRow("Status", if (isPreview) "SUCCESS" else state.payDetail?.let(::displayTransactionStatus).orEmpty())
ReceiptRow("Date", state.payDetail?.transDate.toString() )
ReceiptRow("Time", state.payDetail?.transTime.toString())
ReceiptRow("Ref No", state.payDetail?.referNo.toString())
ReceiptDivider() ReceiptDivider()
Spacer(modifier = Modifier.height(8.dp)) Spacer(modifier = Modifier.height(8.dp))
Text( Text(
@ -292,25 +323,63 @@ fun ReceiptRow(
@Composable @Composable
fun ReceiptDivider() { fun ReceiptDivider() {
Text( Canvas(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.padding(vertical = 10.dp), .padding(vertical = 10.dp)
text = "--------------------------------", .height(2.dp)
color = Color.Gray ) {
// Convert dp to pixels so it scales perfectly on all screen sizes
val dotRadius = 1.5.dp.toPx()
val dotSpacing = 6.dp.toPx()
val totalWidth = size.width
var currentX = 0f
// Loop across the width of the screen and draw individual circles
while (currentX < totalWidth) {
drawCircle(
color = Color.Gray,
radius = dotRadius,
center = Offset(x = currentX, y = size.height / 2)
) )
// Move X forward by the size of the dot + the space we want
currentX += (dotRadius * 2) + dotSpacing
}
}
} }
@Preview(showBackground = true, showSystemUi = true) @P2Preview
@P3Preview
@Composable @Composable
fun PreviewPrintReceiptScreen() { private fun PrintReceiptScreenPreview() {
MaterialTheme { val samplePayDetail = PayDetail().apply {
PrintReceiptScreen( merchantName = "Sample Merchant"
sharedViewModel = hiltViewModel(), terminalNo = "12345678"
transactionResultViewModel = hiltViewModel(), voucherNo = "000001"
amount = 100000
cardNo = "1234********5678"
transDate = "25-08-26"
transTime = "10:30:00"
referNo = "123456789012"
transType = "SALE"
tradeAnswerCode = "00"
approvalCode = "123456"
}
val sampleState = TransactionResultState(
payDetail = samplePayDetail
)
MOBPOSTheme {
PrintReceiptContent(
state = sampleState,
isReprint = false,
onPrint = {}, onPrint = {},
onDone = {}, onDone = {},
onPrintFinished = {} onPrintFinished = {},
onSetPrintStatus = {},
onResetReprint = {}
) )
} }
} }

View File

@ -28,6 +28,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import com.mob.utsmyanmar.ui.components.appbar.AppBar import com.mob.utsmyanmar.ui.components.appbar.AppBar
import com.mob.utsmyanmar.ui.theme.Color import com.mob.utsmyanmar.ui.theme.Color
import com.mob.utsmyanmar.utils.convertDateString
import com.utsmyanmar.paylibs.model.PayDetail import com.utsmyanmar.paylibs.model.PayDetail
import com.utsmyanmar.paylibs.utils.POSUtil import com.utsmyanmar.paylibs.utils.POSUtil
@ -126,19 +127,18 @@ private fun TransactionDetailsCard(transaction: PayDetail) {
verticalArrangement = Arrangement.spacedBy(10.dp) verticalArrangement = Arrangement.spacedBy(10.dp)
) { ) {
Text( Text(
text = "Previous Sale", text = "Void Sale",
color = Color.LegacyRed, color = Color.LegacyRed,
fontWeight = FontWeight.Bold, fontWeight = FontWeight.Bold,
fontSize = 16.sp fontSize = 16.sp
) )
DetailRow("Date", convertDateString(transaction.transDate))
DetailRow("Trace", transaction.voucherNo)
DetailRow("Amount", POSUtil.getInstance().formatAmount(transaction.amount))
DetailRow("Card No", transaction.cardNo)
DetailRow("Reference", transaction.referNo)
DetailRow("Approval", transaction.approvalCode.orEmpty())
DetailRow("Date", transaction.transDate)
DetailRow("Time", transaction.transTime) DetailRow("Time", transaction.transTime)
DetailRow("Amount", POSUtil.getInstance().formatAmount(transaction.amount))
DetailRow("Trace No", transaction.voucherNo)
DetailRow("Reference No", transaction.referNo)
DetailRow("Approval Code", transaction.approvalCode.orEmpty())
// DetailRow("Card No", transaction.cardNo)
} }
} }
} }

View File

@ -24,7 +24,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.mob.utsmyanmar.ui.preview.P2Preview import com.mob.utsmyanmar.ui.preview.P2Preview
import com.mob.utsmyanmar.ui.theme.Color import com.mob.utsmyanmar.ui.theme.Color
import com.mob.utsmyanmar.utils.toFormattedDate import com.mob.utsmyanmar.utils.convertDateString
import com.mob.utsmyanmar.utils.toFormattedTime import com.mob.utsmyanmar.utils.toFormattedTime
import com.utsmyanmar.paylibs.model.PayDetail import com.utsmyanmar.paylibs.model.PayDetail
import com.utsmyanmar.paylibs.print.PrintReceipt import com.utsmyanmar.paylibs.print.PrintReceipt
@ -82,7 +82,7 @@ fun TransactionResultScreen(
Spacer(modifier = Modifier.height(16.dp)) Spacer(modifier = Modifier.height(16.dp))
InfoCard( InfoCard(
date = "${state.payDetail?.transDate?.toFormattedDate()}", date = convertDateString(state.payDetail?.transDate.toString()),
time = "${state.payDetail?.transTime?.toFormattedTime()}", time = "${state.payDetail?.transTime?.toFormattedTime()}",
transactionId = state.payDetail?.referNo.toString() transactionId = state.payDetail?.referNo.toString()
) )

View File

@ -2,6 +2,7 @@ package com.mob.utsmyanmar.utils
import android.annotation.SuppressLint import android.annotation.SuppressLint
@SuppressLint("DefaultLocale") @SuppressLint("DefaultLocale")
fun Long?.formatAmount(): String { fun Long?.formatAmount(): String {
val amount = (this ?: 0L) / 100.0 val amount = (this ?: 0L) / 100.0
@ -18,3 +19,7 @@ fun String?.maskCardNumber(): String {
} }
return maskedPan.toString() return maskedPan.toString()
} }
fun convertDateString(dateStr: String): String {
return dateStr.replace(Regex("/(\\d{2})$"), "/20$1")
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

View File

@ -575,7 +575,7 @@ public class PrintReceipt {
String receiptFooter = SystemParamsOperation.getInstance().getReceiptFooter(); String receiptFooter = SystemParamsOperation.getInstance().getReceiptFooter();
String finalVersion = SystemParamsOperation.getInstance().getFinalVersion(); // String finalVersion = SystemParamsOperation.getInstance().getFinalVersion();
sunmiPrinterService.sendRAWData(boldOn(), null); sunmiPrinterService.sendRAWData(boldOn(), null);
sunmiPrinterService.setAlignment(1, null); sunmiPrinterService.setAlignment(1, null);
@ -596,7 +596,7 @@ public class PrintReceipt {
} else { } else {
sunmiPrinterService.printText("***** CUSTOMER COPY *****" + "\n", null); sunmiPrinterService.printText("***** CUSTOMER COPY *****" + "\n", null);
} }
sunmiPrinterService.printText(finalVersion + "\n", null); // sunmiPrinterService.printText(finalVersion + "\n", null);
sunmiPrinterService.printText(receiptFooter + "\n", null); sunmiPrinterService.printText(receiptFooter + "\n", null);
} catch (RemoteException e) { } catch (RemoteException e) {

View File

@ -155,6 +155,11 @@ public class PrintUtils {
} }
} }
public String toFullYearDate(String dateStr) {
if (TextUtils.isEmpty(dateStr)) return dateStr;
return dateStr.replaceFirst("/(\\d{2})$", "/20$1");
}
public String getFormatTransactionTime(String transTime) { public String getFormatTransactionTime(String transTime) {
if (!TextUtils.equals("", transTime)) { if (!TextUtils.equals("", transTime)) {
return transTime.substring(0, 2) + ":" + transTime.substring(2, 4) + ":" + transTime.substring(4, 6); return transTime.substring(0, 2) + ":" + transTime.substring(2, 4) + ":" + transTime.substring(4, 6);

View File

@ -202,11 +202,11 @@ public abstract class BaseXPrint {
try { try {
String receiptFooter = SystemParamsOperation.getInstance().getReceiptFooter(); String receiptFooter = SystemParamsOperation.getInstance().getReceiptFooter();
String finalVersion = SystemParamsOperation.getInstance().getFinalVersion(); // String finalVersion = SystemParamsOperation.getInstance().getFinalVersion();
sunmiPrinterService.setFontSize(textSize, innerResultCallback); sunmiPrinterService.setFontSize(textSize, innerResultCallback);
// sunmiPrinterService.printText("***** MERCHANT COPY *****" + "\n", innerResultCallback); // sunmiPrinterService.printText("***** MERCHANT COPY *****" + "\n", innerResultCallback);
sunmiPrinterService.printText(finalVersion + "\n", innerResultCallback); // sunmiPrinterService.printText(finalVersion + "\n", innerResultCallback);
sunmiPrinterService.printText(receiptFooter + "\n", innerResultCallback); sunmiPrinterService.printText(receiptFooter + "\n", innerResultCallback);
} catch (RemoteException e) { } catch (RemoteException e) {
e.printStackTrace(); e.printStackTrace();
@ -267,6 +267,7 @@ public abstract class BaseXPrint {
} }
sunmiPrinterService.printText("REF NUM : " + payDetail.getReferNo() + "\n", innerResultCallback); sunmiPrinterService.printText("REF NUM : " + payDetail.getReferNo() + "\n", innerResultCallback);
sunmiPrinterService.printText("TRACE NO : " + payDetail.getVoucherNo() + "\n", innerResultCallback); sunmiPrinterService.printText("TRACE NO : " + payDetail.getVoucherNo() + "\n", innerResultCallback);
sunmiPrinterService.printText("APR CODE : " + payDetail.getApprovalCode() + "\n", innerResultCallback);
// sunmiPrinterService.printColumnsString(new String[]{"REF NUM", ":" + payDetail.getReferNo()}, new int[]{1, 2}, new int[]{0, 0}, innerResultCallback); // sunmiPrinterService.printColumnsString(new String[]{"REF NUM", ":" + payDetail.getReferNo()}, new int[]{1, 2}, new int[]{0, 0}, innerResultCallback);
// sunmiPrinterService.printColumnsString(new String[]{"TRACE No", ":" + payDetail.getVoucherNo()}, new int[]{1, 2}, new int[]{0, 0}, innerResultCallback); // sunmiPrinterService.printColumnsString(new String[]{"TRACE No", ":" + payDetail.getVoucherNo()}, new int[]{1, 2}, new int[]{0, 0}, innerResultCallback);
@ -375,7 +376,7 @@ public abstract class BaseXPrint {
try { try {
sunmiPrinterService.setFontSize(20, innerResultCallback); sunmiPrinterService.setFontSize(20, innerResultCallback);
sunmiPrinterService.setAlignment(0, innerResultCallback); sunmiPrinterService.setAlignment(0, innerResultCallback);
sunmiPrinterService.printColumnsString(new String[]{"DATE :" + payDetail.getTransDate(), "TIME: " + payDetail.getTransTime()}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback); sunmiPrinterService.printColumnsString(new String[]{"DATE :" + PrintUtils.getInstance().toFullYearDate(payDetail.getTransDate()), "TIME: " + payDetail.getTransTime()}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback);
if(Objects.equals(payDetail.getAccountType(), CardScheme.MPU_CTLS.name) || Objects.equals(payDetail.getAccountType(), CardScheme.UPI.name) ) { if(Objects.equals(payDetail.getAccountType(), CardScheme.MPU_CTLS.name) || Objects.equals(payDetail.getAccountType(), CardScheme.UPI.name) ) {
hostName = HOST_NAME_MPU; hostName = HOST_NAME_MPU;
} else { } else {
@ -636,7 +637,7 @@ public abstract class BaseXPrint {
for (PayDetail pay: lists) { for (PayDetail pay: lists) {
boolean isNeedMinusSign = pay.getTransactionType() == TransactionsType.VOID.value || pay.getTransactionType() == TransactionsType.REFUND.value || pay.getTransactionType() == TransactionsType.WAVEPAY_REFUND.value || pay.getTransactionType() == TransactionsType.PRE_AUTH_COMPLETE_VOID.value; boolean isNeedMinusSign = pay.getTransactionType() == TransactionsType.VOID.value || pay.getTransactionType() == TransactionsType.REFUND.value || pay.getTransactionType() == TransactionsType.WAVEPAY_REFUND.value || pay.getTransactionType() == TransactionsType.PRE_AUTH_COMPLETE_VOID.value || pay.getTransactionType() == TransactionsType.CASH_OUT.value;
if(hostType == HostType.MPU || hostType == HostType.VISA_MASTER) { if(hostType == HostType.MPU || hostType == HostType.VISA_MASTER) {
sunmiPrinterService.printColumnsString(new String[]{pay.getAccountType() , PrintUtils.getInstance().maskCardNumberPciDss(pay.getCardNo())}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback); sunmiPrinterService.printColumnsString(new String[]{pay.getAccountType() , PrintUtils.getInstance().maskCardNumberPciDss(pay.getCardNo())}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback);
@ -718,7 +719,7 @@ public abstract class BaseXPrint {
String receiptFooter = SystemParamsOperation.getInstance().getReceiptFooter(); String receiptFooter = SystemParamsOperation.getInstance().getReceiptFooter();
String finalVersion = SystemParamsOperation.getInstance().getFinalVersion(); // String finalVersion = SystemParamsOperation.getInstance().getFinalVersion();
sunmiPrinterService.sendRAWData(boldOn(), innerResultCallback); sunmiPrinterService.sendRAWData(boldOn(), innerResultCallback);
sunmiPrinterService.setAlignment(1, innerResultCallback); sunmiPrinterService.setAlignment(1, innerResultCallback);
@ -761,7 +762,7 @@ public abstract class BaseXPrint {
} else { } else {
sunmiPrinterService.printText("***** CUSTOMER COPY *****" + "\n", innerResultCallback); sunmiPrinterService.printText("***** CUSTOMER COPY *****" + "\n", innerResultCallback);
} }
sunmiPrinterService.printText(finalVersion + "\n", innerResultCallback); // sunmiPrinterService.printText(finalVersion + "\n", innerResultCallback);
sunmiPrinterService.printText(receiptFooter + "\n", innerResultCallback); sunmiPrinterService.printText(receiptFooter + "\n", innerResultCallback);
} catch (RemoteException e) { } catch (RemoteException e) {
@ -894,7 +895,7 @@ public abstract class BaseXPrint {
try { try {
sunmiPrinterService.setFontSize(18, innerResultCallback); sunmiPrinterService.setFontSize(18, innerResultCallback);
sunmiPrinterService.setAlignment(0, innerResultCallback); sunmiPrinterService.setAlignment(0, innerResultCallback);
sunmiPrinterService.printColumnsString(new String[]{"DATE :" + payDetail.getTransDate(), "TIME: " + payDetail.getTransTime()}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback); sunmiPrinterService.printColumnsString(new String[]{"DATE :" + PrintUtils.getInstance().toFullYearDate(payDetail.getTransDate()), "TIME: " + payDetail.getTransTime()}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback);
if (payDetail.getTransactionType() == TransactionsType.WAVEPAY.value && payDetail.getQrTransStatus() == 1) { if (payDetail.getTransactionType() == TransactionsType.WAVEPAY.value && payDetail.getQrTransStatus() == 1) {
sunmiPrinterService.printColumnsString(new String[]{"TRACE NO :" + traceNum, "INV NO: " + invoiceNo}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback); sunmiPrinterService.printColumnsString(new String[]{"TRACE NO :" + traceNum, "INV NO: " + invoiceNo}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback);
} else if (!payDetail.getTransType().equals(SETTLEMENT) && !payDetail.getTransType().equals(SUMMARY) && payDetail.getTransactionType() != TransactionsType.WAVEPAY_REFUND.value && payDetail.getTransactionType() != TransactionsType.WAVEPAY.value) { } else if (!payDetail.getTransType().equals(SETTLEMENT) && !payDetail.getTransType().equals(SUMMARY) && payDetail.getTransactionType() != TransactionsType.WAVEPAY_REFUND.value && payDetail.getTransactionType() != TransactionsType.WAVEPAY.value) {

View File

@ -48,14 +48,14 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
opts.inJustDecodeBounds = true; opts.inJustDecodeBounds = true;
// Step 1: Only read dimensions first // Step 1: Only read dimensions first
BitmapFactory.decodeResource(resources, R.drawable.mob_print_logo, opts); BitmapFactory.decodeResource(resources, R.drawable.logo_mob_receipt, opts);
// Step 2: Calculate sample size so width <= 384px // Step 2: Calculate sample size so width <= 384px
opts.inSampleSize = calculateInSampleSize(opts, 384, 384); opts.inSampleSize = calculateInSampleSize(opts, 384, 384);
opts.inJustDecodeBounds = false; opts.inJustDecodeBounds = false;
// Step 3: Decode scaled-down bitmap // Step 3: Decode scaled-down bitmap
bitmap = BitmapFactory.decodeResource(resources, R.drawable.mob_print_logo, opts); bitmap = BitmapFactory.decodeResource(resources, R.drawable.logo_mob_receipt, opts);
} }
@Override @Override
@ -172,6 +172,7 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
try { try {
setHeight(0x12); setHeight(0x12);
printLogo(); printLogo();
sunmiPrinterService.lineWrap(1, innerResultCallback);
printMerchantHeader(); printMerchantHeader();
printTransHeader(payDetail); printTransHeader(payDetail);
printTransDetailWave(payDetail); printTransDetailWave(payDetail);

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB