auto width printReceiptScreen dot
This commit is contained in:
parent
81920acc8c
commit
7ccf393793
@ -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
|
||||||
@ -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,18 +33,24 @@ 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.PathEffect
|
||||||
|
import androidx.compose.ui.graphics.StrokeCap
|
||||||
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.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 kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -59,9 +66,32 @@ fun PrintReceiptScreen(
|
|||||||
sharedViewModel: SharedViewModel,
|
sharedViewModel: SharedViewModel,
|
||||||
onPrint: () -> Unit,
|
onPrint: () -> Unit,
|
||||||
onDone: () -> Unit,
|
onDone: () -> Unit,
|
||||||
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()
|
||||||
@ -246,7 +273,7 @@ fun ReceiptPreview(
|
|||||||
ReceiptRow("Amount", POSUtil.getInstance().getDecimalAmountSeparatorFormat(state.payDetail?.amount?:0))
|
ReceiptRow("Amount", POSUtil.getInstance().getDecimalAmountSeparatorFormat(state.payDetail?.amount?:0))
|
||||||
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("Date", state.payDetail?.transDate.toString() )
|
||||||
ReceiptRow("Time", state.payDetail?.transTime.toString())
|
ReceiptRow("Time", state.payDetail?.transTime.toString())
|
||||||
ReceiptRow("Ref No", state.payDetail?.referNo.toString())
|
ReceiptRow("Ref No", state.payDetail?.referNo.toString())
|
||||||
@ -292,25 +319,62 @@ 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 = "2023-10-27"
|
||||||
|
transTime = "10:30:00"
|
||||||
|
referNo = "123456789012"
|
||||||
|
transType = "SALE"
|
||||||
|
tradeAnswerCode = "00"
|
||||||
|
}
|
||||||
|
|
||||||
|
val sampleState = TransactionResultState(
|
||||||
|
payDetail = samplePayDetail
|
||||||
|
)
|
||||||
|
|
||||||
|
MOBPOSTheme {
|
||||||
|
PrintReceiptContent(
|
||||||
|
state = sampleState,
|
||||||
|
isReprint = false,
|
||||||
onPrint = {},
|
onPrint = {},
|
||||||
onDone = {},
|
onDone = {},
|
||||||
onPrintFinished = {}
|
onPrintFinished = {},
|
||||||
|
onSetPrintStatus = {},
|
||||||
|
onResetReprint = {}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user