Compare commits
3 Commits
48add55380
...
38bc26d821
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38bc26d821 | ||
|
|
887af67ae7 | ||
|
|
782dde479a |
@ -18,7 +18,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.mob.utsmyanmar"
|
applicationId = "com.mob.utsmyanmar"
|
||||||
minSdk = 23
|
minSdk = 25
|
||||||
//noinspection OldTargetApi
|
//noinspection OldTargetApi
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
@ -43,8 +43,8 @@ android {
|
|||||||
dimension = "env"
|
dimension = "env"
|
||||||
applicationIdSuffix = ".uat"
|
applicationIdSuffix = ".uat"
|
||||||
versionNameSuffix = "-UAT"
|
versionNameSuffix = "-UAT"
|
||||||
versionCode = 10
|
versionCode = 11
|
||||||
versionName = "2.8"
|
versionName = "2.9"
|
||||||
buildConfigField("String", "ENV", "\"UAT\"")
|
buildConfigField("String", "ENV", "\"UAT\"")
|
||||||
resValue("string", "app_name", "MOB-UAT")
|
resValue("string", "app_name", "MOB-UAT")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package com.mob.utsmyanmar.ui.cardwaiting
|
|||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.foundation.BorderStroke
|
import androidx.compose.foundation.BorderStroke
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@ -38,7 +39,9 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.draw.rotate
|
import androidx.compose.ui.draw.rotate
|
||||||
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
@ -134,16 +137,16 @@ private fun CardWaitingScreenContent(
|
|||||||
Text(
|
Text(
|
||||||
text = "AMOUNT TO PAY",
|
text = "AMOUNT TO PAY",
|
||||||
color = Color.Black,
|
color = Color.Black,
|
||||||
style = MaterialTheme.typography.labelSmall
|
style = MaterialTheme.typography.titleMedium,
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(6.dp))
|
Spacer(modifier = Modifier.height(6.dp))
|
||||||
|
|
||||||
Row(verticalAlignment = Alignment.Bottom) {
|
// Row(verticalAlignment = Alignment.Bottom) {
|
||||||
Text(
|
Text(
|
||||||
text = amount,
|
text = amount,
|
||||||
color = Color.LegacyRed,
|
color = Color.LegacyRed,
|
||||||
style = MaterialTheme.typography.displayMedium
|
style = MaterialTheme.typography.displayLarge
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.width(6.dp))
|
Spacer(modifier = Modifier.width(6.dp))
|
||||||
@ -151,16 +154,16 @@ private fun CardWaitingScreenContent(
|
|||||||
Text(
|
Text(
|
||||||
text = "MMK",
|
text = "MMK",
|
||||||
color = Color.LegacyRed,
|
color = Color.LegacyRed,
|
||||||
style = MaterialTheme.typography.labelSmall,
|
style = MaterialTheme.typography.displaySmall.copy(fontWeight = FontWeight.Medium),
|
||||||
modifier = Modifier.padding(bottom = 6.dp)
|
modifier = Modifier.padding(bottom = 6.dp)
|
||||||
)
|
)
|
||||||
}
|
// }
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(32.dp))
|
// Spacer(modifier = Modifier.height(32.dp))
|
||||||
|
|
||||||
ContactlessCircle(isLoading = uiState.isLoading)
|
ContactlessCircle(isLoading = uiState.isLoading)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(24.dp))
|
// Spacer(modifier = Modifier.height(24.dp))
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = when {
|
text = when {
|
||||||
@ -206,12 +209,9 @@ private fun CardWaitingScreenContent(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
|
|
||||||
InsertCardRow(onMockClick = onMockClick)
|
InsertCardRow(onMockClick = onMockClick)
|
||||||
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
Spacer(modifier = Modifier.height(18.dp))
|
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = uiState.alertMessage,
|
text = uiState.alertMessage,
|
||||||
color = Color.Black,
|
color = Color.Black,
|
||||||
@ -219,23 +219,13 @@ private fun CardWaitingScreenContent(
|
|||||||
textAlign = TextAlign.Center,
|
textAlign = TextAlign.Center,
|
||||||
lineHeight = 16.sp
|
lineHeight = 16.sp
|
||||||
)
|
)
|
||||||
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
Spacer(modifier = Modifier.height(18.dp))
|
|
||||||
|
|
||||||
// StatusPanel(uiState = uiState)
|
|
||||||
|
|
||||||
Spacer(modifier = Modifier.weight(1f))
|
Spacer(modifier = Modifier.weight(1f))
|
||||||
|
|
||||||
ManualEntryAction(onManualEntryClick = onManualEntryClick)
|
ManualEntryAction(onManualEntryClick = onManualEntryClick)
|
||||||
|
Spacer(modifier = Modifier.height(10.dp))
|
||||||
Spacer(modifier = Modifier.height(18.dp))
|
|
||||||
|
|
||||||
CardLogoRow()
|
CardLogoRow()
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(34.dp))
|
Spacer(modifier = Modifier.height(34.dp))
|
||||||
|
|
||||||
PoweredByMob()
|
PoweredByMob()
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(12.dp))
|
Spacer(modifier = Modifier.height(12.dp))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -301,7 +291,8 @@ private fun InsertCardRow(onMockClick: ()->Unit) {
|
|||||||
painter = painterResource(id = R.drawable.ic_insert_card),
|
painter = painterResource(id = R.drawable.ic_insert_card),
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
tint = Color.LegacyRed,
|
tint = Color.LegacyRed,
|
||||||
modifier = Modifier.size(28.dp)
|
modifier = Modifier
|
||||||
|
.size(28.dp)
|
||||||
.clickable(onClick = onMockClick)
|
.clickable(onClick = onMockClick)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -395,13 +386,49 @@ private fun CardLogoRow() {
|
|||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.height(42.dp)
|
.height(42.dp)
|
||||||
.padding(horizontal = 14.dp),
|
.padding(horizontal = 14.dp),
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
Text("VISA", style = MaterialTheme.typography.titleLarge)
|
CardLogo(
|
||||||
Text("MC", style = MaterialTheme.typography.titleMedium)
|
icon = painterResource(R.drawable.logo_visa),
|
||||||
Text("MPU", style = MaterialTheme.typography.titleLarge)
|
name = "visa",
|
||||||
Text("UnionPay", style = MaterialTheme.typography.labelMedium)
|
)
|
||||||
|
CardLogo(
|
||||||
|
icon = painterResource(R.drawable.logo_master),
|
||||||
|
name = "master",
|
||||||
|
)
|
||||||
|
CardLogo(
|
||||||
|
icon = painterResource(R.drawable.logo_mpu),
|
||||||
|
name = "master",
|
||||||
|
)
|
||||||
|
CardLogo(
|
||||||
|
icon = painterResource(R.drawable.logo_union_pay),
|
||||||
|
name = "master",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun CardLogo(
|
||||||
|
icon: Painter,
|
||||||
|
name: String,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Surface(
|
||||||
|
modifier = modifier,
|
||||||
|
shape = RoundedCornerShape(4.dp),
|
||||||
|
color = Color.White
|
||||||
|
) {
|
||||||
|
Box(
|
||||||
|
modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Image(
|
||||||
|
painter = icon,
|
||||||
|
contentDescription = name,
|
||||||
|
modifier = Modifier.height(30.dp)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -104,7 +104,9 @@ fun SummaryCard(
|
|||||||
onClickLastSync: () -> Unit,
|
onClickLastSync: () -> Unit,
|
||||||
lastSyncTime: Long?,
|
lastSyncTime: Long?,
|
||||||
totalSaleCount: Int,
|
totalSaleCount: Int,
|
||||||
totalSaleAmount: Long
|
totalSaleAmount: Long,
|
||||||
|
settlementStatusText: String,
|
||||||
|
settlementDateTimeText: String
|
||||||
) {
|
) {
|
||||||
var now by remember { mutableLongStateOf(System.currentTimeMillis()) }
|
var now by remember { mutableLongStateOf(System.currentTimeMillis()) }
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
@ -145,8 +147,8 @@ fun SummaryCard(
|
|||||||
|
|
||||||
SummaryItem(
|
SummaryItem(
|
||||||
title = "Settlement",
|
title = "Settlement",
|
||||||
value = "Completed",
|
value = settlementStatusText,
|
||||||
subtitle = "Today 11:00 PM",
|
subtitle = settlementDateTimeText,
|
||||||
icon = Icons.Default.Check,
|
icon = Icons.Default.Check,
|
||||||
iconBg = Color.CrimsonRed
|
iconBg = Color.CrimsonRed
|
||||||
)
|
)
|
||||||
|
|||||||
@ -394,7 +394,9 @@ fun DashboardScreen2(
|
|||||||
onClickLastSync = onClickLastSync,
|
onClickLastSync = onClickLastSync,
|
||||||
lastSyncTime = dashboardUiState.lastSyncTime,
|
lastSyncTime = dashboardUiState.lastSyncTime,
|
||||||
totalSaleCount = dashboardUiState.totalSaleCount,
|
totalSaleCount = dashboardUiState.totalSaleCount,
|
||||||
totalSaleAmount = dashboardUiState.totalSaleAmount
|
totalSaleAmount = dashboardUiState.totalSaleAmount,
|
||||||
|
settlementStatusText = dashboardUiState.settlementStatusText,
|
||||||
|
settlementDateTimeText = dashboardUiState.settlementDateTimeText
|
||||||
)
|
)
|
||||||
Spacer(Modifier.height(12.dp))
|
Spacer(Modifier.height(12.dp))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,5 +15,7 @@ data class DashboardUiState(
|
|||||||
val lastSyncTime: Long? = null,
|
val lastSyncTime: Long? = null,
|
||||||
val carouselUrls: List<String> = emptyList(),
|
val carouselUrls: List<String> = emptyList(),
|
||||||
val totalSaleCount: Int = 0,
|
val totalSaleCount: Int = 0,
|
||||||
val totalSaleAmount: Long = 0L
|
val totalSaleAmount: Long = 0L,
|
||||||
|
val settlementStatusText: String = "Pending",
|
||||||
|
val settlementDateTimeText: String = "--/-- --:--"
|
||||||
)
|
)
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import androidx.lifecycle.asFlow
|
|||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.utsmyanmar.baselib.repo.Repository
|
import com.utsmyanmar.baselib.repo.Repository
|
||||||
import com.utsmyanmar.paylibs.model.PayDetail
|
import com.utsmyanmar.paylibs.model.PayDetail
|
||||||
|
import com.utsmyanmar.paylibs.system.SystemDateTime
|
||||||
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
||||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
@ -17,6 +18,7 @@ import kotlinx.coroutines.flow.update
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.text.DecimalFormat
|
import java.text.DecimalFormat
|
||||||
|
import java.util.Calendar
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@ -31,11 +33,23 @@ class DashboardViewModel @Inject constructor(
|
|||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
repository.getLastTenTransactions().asFlow().collect { payDetails ->
|
repository.getLastTenTransactions().asFlow().collect { payDetails ->
|
||||||
|
val latestSettlement = payDetails.lastOrNull {
|
||||||
|
it.transactionType == TransactionsType.SETTLEMENT.value
|
||||||
|
}
|
||||||
|
val isCurrentBusinessSettlement = latestSettlement?.isCurrentBusinessSettlement() == true
|
||||||
_uiState.update {
|
_uiState.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
recentTransactions = payDetails.map { pd -> pd.toRecord() },
|
recentTransactions = payDetails.map { pd -> pd.toRecord() },
|
||||||
totalSaleCount = payDetails.totalSaleCount(),
|
totalSaleCount = payDetails.totalSaleCount(),
|
||||||
totalSaleAmount = payDetails.totalSaleAmount()
|
totalSaleAmount = payDetails.totalSaleAmount(),
|
||||||
|
settlementStatusText = if (isCurrentBusinessSettlement) {
|
||||||
|
"Completed"
|
||||||
|
} else {
|
||||||
|
"Pending"
|
||||||
|
},
|
||||||
|
settlementDateTimeText = latestSettlement
|
||||||
|
?.let { buildDateTime(it.TradeDate, it.TradeTime) }
|
||||||
|
?: "--/-- --:--"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -112,3 +126,18 @@ private fun buildDateTime(date: String?, time: String?): String {
|
|||||||
val t = (time ?: "").padStart(6, '0')
|
val t = (time ?: "").padStart(6, '0')
|
||||||
return "${d.take(2)}/${d.drop(2).take(2)} ${t.take(2)}:${t.drop(2).take(2)}"
|
return "${d.take(2)}/${d.drop(2).take(2)} ${t.take(2)}:${t.drop(2).take(2)}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun PayDetail.isCurrentBusinessSettlement(): Boolean {
|
||||||
|
if (transactionType != TransactionsType.SETTLEMENT.value) return false
|
||||||
|
if (TradeDate != SystemDateTime.getMMDD()) return false
|
||||||
|
|
||||||
|
val now = Calendar.getInstance()
|
||||||
|
val cutoff = Calendar.getInstance().apply {
|
||||||
|
set(Calendar.HOUR_OF_DAY, 23)
|
||||||
|
set(Calendar.MINUTE, 0)
|
||||||
|
set(Calendar.SECOND, 0)
|
||||||
|
set(Calendar.MILLISECOND, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return now.before(cutoff)
|
||||||
|
}
|
||||||
|
|||||||
@ -56,7 +56,13 @@ fun InputAmount(
|
|||||||
val supportingText = "Enter the amount to continue"
|
val supportingText = "Enter the amount to continue"
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = { AppBar(title = "Amount", icon = Icons.AutoMirrored.Rounded.ArrowBack, onIconClick = onBackClick) },
|
topBar = {
|
||||||
|
AppBar(
|
||||||
|
title = "Amount",
|
||||||
|
icon = Icons.AutoMirrored.Rounded.ArrowBack,
|
||||||
|
onIconClick = onBackClick
|
||||||
|
)
|
||||||
|
},
|
||||||
containerColor = Color.IvoryBeige
|
containerColor = Color.IvoryBeige
|
||||||
) { paddingValues ->
|
) { paddingValues ->
|
||||||
|
|
||||||
@ -74,7 +80,8 @@ fun InputAmount(
|
|||||||
.weight(2f),
|
.weight(2f),
|
||||||
) {
|
) {
|
||||||
Card(
|
Card(
|
||||||
modifier = Modifier.align(Alignment.CenterEnd)
|
modifier = Modifier
|
||||||
|
.align(Alignment.CenterEnd)
|
||||||
.clickable(enabled = true) {
|
.clickable(enabled = true) {
|
||||||
amount = amount.dropLast(1)
|
amount = amount.dropLast(1)
|
||||||
},
|
},
|
||||||
@ -102,26 +109,28 @@ fun InputAmount(
|
|||||||
)
|
)
|
||||||
Spacer(modifier = Modifier.height(8.dp))
|
Spacer(modifier = Modifier.height(8.dp))
|
||||||
|
|
||||||
Row(
|
// Row(
|
||||||
modifier = Modifier.align(Alignment.CenterHorizontally),
|
// modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||||
verticalAlignment = Alignment.Bottom
|
// verticalAlignment = Alignment.Bottom
|
||||||
) {
|
// ) {
|
||||||
if (prefixLabel.isNotBlank()) {
|
|
||||||
Text(
|
|
||||||
text = prefixLabel,
|
|
||||||
color = Color.LegacyRed,
|
|
||||||
style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Medium),
|
|
||||||
modifier = Modifier.padding(end = 10.dp, bottom = 6.dp)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
text = formatAmount(amount.ifEmpty { "0" }),
|
text = formatAmount(amount.ifEmpty { "0" }),
|
||||||
color = Color.LegacyRed,
|
color = Color.LegacyRed,
|
||||||
style = MaterialTheme.typography.displayLarge
|
style = MaterialTheme.typography.displayLarge
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (prefixLabel.isNotBlank()) {
|
||||||
|
Text(
|
||||||
|
text = prefixLabel,
|
||||||
|
color = Color.LegacyRed,
|
||||||
|
style = MaterialTheme.typography.displaySmall.copy(fontWeight = FontWeight.Medium),
|
||||||
|
modifier = Modifier.padding(end = 10.dp, bottom = 6.dp)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(14.dp))
|
Spacer(modifier = Modifier.height(14.dp))
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
@ -178,7 +187,8 @@ fun InputAmount(
|
|||||||
onClick = {
|
onClick = {
|
||||||
if (amount.isNotEmpty()) {
|
if (amount.isNotEmpty()) {
|
||||||
onChargeClick(amount)
|
onChargeClick(amount)
|
||||||
} },
|
}
|
||||||
|
},
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.height(56.dp),
|
.height(56.dp),
|
||||||
|
|||||||
@ -1,13 +1,18 @@
|
|||||||
package com.mob.utsmyanmar.ui.print_receipt
|
package com.mob.utsmyanmar.ui.print_receipt
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.activity.compose.BackHandler
|
|
||||||
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.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.layout.*
|
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.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
@ -20,8 +25,10 @@ import androidx.compose.material3.Text
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
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
|
||||||
@ -32,15 +39,19 @@ 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.theme.Color
|
import com.mob.utsmyanmar.ui.theme.Color
|
||||||
import com.mob.utsmyanmar.ui.transaction_result.TransactionResultEvent
|
|
||||||
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.print.PrintReceipt
|
|
||||||
import com.utsmyanmar.paylibs.utils.POSUtil
|
import com.utsmyanmar.paylibs.utils.POSUtil
|
||||||
|
import com.utsmyanmar.paylibs.utils.PrintStatus
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlin.time.Duration.Companion.milliseconds
|
||||||
|
|
||||||
|
private enum class ReceiptCopy(val label: String) {
|
||||||
|
MERCHANT("MERCHANT COPY"),
|
||||||
|
CUSTOMER("CUSTOMER COPY")
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun PrintReceiptScreen(
|
fun PrintReceiptScreen(
|
||||||
@ -50,12 +61,59 @@ fun PrintReceiptScreen(
|
|||||||
onDone: () -> Unit
|
onDone: () -> Unit
|
||||||
) {
|
) {
|
||||||
val state by transactionResultViewModel.state.collectAsStateWithLifecycle()
|
val state by transactionResultViewModel.state.collectAsStateWithLifecycle()
|
||||||
val scope = rememberCoroutineScope();
|
val scope = rememberCoroutineScope()
|
||||||
val receiptOffsetY = remember {
|
val receiptOffsetY = remember { Animatable(0f) }
|
||||||
Animatable(0f);
|
val animationDuration = 5000
|
||||||
}
|
val merchant_copy_autoprint = true
|
||||||
val animationDuration = 3000;
|
val customer_copy_autoprint = false
|
||||||
|
var currentCopy by remember { mutableStateOf(ReceiptCopy.MERCHANT) }
|
||||||
|
var nextCopy by remember { mutableStateOf(ReceiptCopy.CUSTOMER) }
|
||||||
|
var isPrinting by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
|
suspend fun animatePrint() {
|
||||||
|
receiptOffsetY.animateTo(
|
||||||
|
targetValue = -1500f,
|
||||||
|
animationSpec = tween(durationMillis = animationDuration, easing = FastOutSlowInEasing)
|
||||||
|
)
|
||||||
|
delay(1000.milliseconds)
|
||||||
|
receiptOffsetY.animateTo(
|
||||||
|
targetValue = 0f,
|
||||||
|
animationSpec = tween(durationMillis = 0, easing = FastOutSlowInEasing)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isReprintMode() = sharedViewModel.isReprint.value == true
|
||||||
|
|
||||||
|
fun doPrint(copy: ReceiptCopy, onFinished: () -> Unit) {
|
||||||
|
val reprint = isReprintMode()
|
||||||
|
val actualCopy = if (reprint && copy == ReceiptCopy.MERCHANT) ReceiptCopy.CUSTOMER else copy
|
||||||
|
currentCopy = actualCopy
|
||||||
|
sharedViewModel.setPrintStatus(
|
||||||
|
if (actualCopy == ReceiptCopy.MERCHANT) PrintStatus.FIRST_PRINT else PrintStatus.SECOND_PRINT
|
||||||
|
)
|
||||||
|
onPrint()
|
||||||
|
scope.launch {
|
||||||
|
isPrinting = true
|
||||||
|
animatePrint()
|
||||||
|
isPrinting = false
|
||||||
|
nextCopy = if (reprint) ReceiptCopy.CUSTOMER
|
||||||
|
else if (actualCopy == ReceiptCopy.MERCHANT) ReceiptCopy.CUSTOMER else ReceiptCopy.MERCHANT
|
||||||
|
onFinished()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
val reprint = isReprintMode()
|
||||||
|
if (reprint) {
|
||||||
|
currentCopy = ReceiptCopy.CUSTOMER
|
||||||
|
nextCopy = ReceiptCopy.CUSTOMER
|
||||||
|
}
|
||||||
|
sharedViewModel.isReprint.value = false
|
||||||
|
when {
|
||||||
|
merchant_copy_autoprint && !reprint -> doPrint(ReceiptCopy.MERCHANT) { }
|
||||||
|
customer_copy_autoprint -> doPrint(ReceiptCopy.CUSTOMER) { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
@ -74,6 +132,7 @@ fun PrintReceiptScreen(
|
|||||||
|
|
||||||
ReceiptPreview(
|
ReceiptPreview(
|
||||||
state = state,
|
state = state,
|
||||||
|
copyLabel = currentCopy.label,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(rememberScrollState())
|
||||||
@ -106,6 +165,7 @@ fun PrintReceiptScreen(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
.height(50.dp),
|
.height(50.dp),
|
||||||
|
enabled = !isPrinting,
|
||||||
colors = ButtonDefaults.buttonColors(
|
colors = ButtonDefaults.buttonColors(
|
||||||
containerColor = Color.LegacyRed,
|
containerColor = Color.LegacyRed,
|
||||||
contentColor = Color.White,
|
contentColor = Color.White,
|
||||||
@ -114,35 +174,7 @@ fun PrintReceiptScreen(
|
|||||||
),
|
),
|
||||||
shape = RoundedCornerShape(12.dp),
|
shape = RoundedCornerShape(12.dp),
|
||||||
onClick = {
|
onClick = {
|
||||||
onPrint()
|
doPrint(nextCopy) { }
|
||||||
// try {
|
|
||||||
// PrintReceipt.getInstance().printNow()
|
|
||||||
// scope.launch {
|
|
||||||
// launch {
|
|
||||||
// receiptOffsetY.animateTo(
|
|
||||||
// targetValue = -1500f,
|
|
||||||
// animationSpec = tween(
|
|
||||||
// durationMillis = animationDuration,
|
|
||||||
// easing = FastOutSlowInEasing
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// delay(5000)
|
|
||||||
// launch {
|
|
||||||
// receiptOffsetY.animateTo(
|
|
||||||
// targetValue = 0f,
|
|
||||||
// animationSpec = tween(
|
|
||||||
// durationMillis = 0,
|
|
||||||
// easing = FastOutSlowInEasing
|
|
||||||
// )
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } catch (e: Exception) {
|
|
||||||
//
|
|
||||||
// Log.d("PrintReceipt", "error with $e")
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Text(
|
Text(
|
||||||
@ -160,6 +192,7 @@ fun PrintReceiptScreen(
|
|||||||
@Composable
|
@Composable
|
||||||
fun ReceiptPreview(
|
fun ReceiptPreview(
|
||||||
state: TransactionResultState,
|
state: TransactionResultState,
|
||||||
|
copyLabel: String,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
@ -184,6 +217,12 @@ fun ReceiptPreview(
|
|||||||
text = "Transaction Receipt",
|
text = "Transaction Receipt",
|
||||||
style = MaterialTheme.typography.bodyMedium
|
style = MaterialTheme.typography.bodyMedium
|
||||||
)
|
)
|
||||||
|
Spacer(modifier = Modifier.height(4.dp))
|
||||||
|
Text(
|
||||||
|
text = copyLabel,
|
||||||
|
style = MaterialTheme.typography.labelLarge,
|
||||||
|
color = Color.Gray
|
||||||
|
)
|
||||||
Spacer(modifier = Modifier.height(16.dp))
|
Spacer(modifier = Modifier.height(16.dp))
|
||||||
ReceiptDivider()
|
ReceiptDivider()
|
||||||
ReceiptRow("Merchant", state.payDetail?.merchantName.toString() )
|
ReceiptRow("Merchant", state.payDetail?.merchantName.toString() )
|
||||||
|
|||||||
15
app/src/main/res/drawable/logo_master.xml
Normal file
15
app/src/main/res/drawable/logo_master.xml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="152.4dp"
|
||||||
|
android:height="108dp"
|
||||||
|
android:viewportWidth="152.4"
|
||||||
|
android:viewportHeight="108">
|
||||||
|
<path
|
||||||
|
android:pathData="M60.4,25.7h31.5v56.6h-31.5z"
|
||||||
|
android:fillColor="#FF5F00"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M62.4,54c0,-11 5.1,-21.5 13.7,-28.3c-15.6,-12.3 -38.3,-9.6 -50.6,6.1C13.3,47.4 16,70 31.7,82.3c13.1,10.3 31.4,10.3 44.5,0C67.5,75.5 62.4,65 62.4,54z"
|
||||||
|
android:fillColor="#EB001B"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M134.4,54c0,19.9 -16.1,36 -36,36c-8.1,0 -15.9,-2.7 -22.2,-7.7c15.6,-12.3 18.3,-34.9 6,-50.6c-1.8,-2.2 -3.8,-4.3 -6,-6c15.6,-12.3 38.3,-9.6 50.5,6.1C131.7,38.1 134.4,45.9 134.4,54z"
|
||||||
|
android:fillColor="#F79E1B"/>
|
||||||
|
</vector>
|
||||||
BIN
app/src/main/res/drawable/logo_mpu.png
Normal file
BIN
app/src/main/res/drawable/logo_mpu.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 59 KiB |
18
app/src/main/res/drawable/logo_union_pay.xml
Normal file
18
app/src/main/res/drawable/logo_union_pay.xml
Normal file
File diff suppressed because one or more lines are too long
18
app/src/main/res/drawable/logo_visa.xml
Normal file
18
app/src/main/res/drawable/logo_visa.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="800dp"
|
||||||
|
android:height="800dp"
|
||||||
|
android:viewportWidth="750"
|
||||||
|
android:viewportHeight="471">
|
||||||
|
<path
|
||||||
|
android:pathData="M278.2,334.23l33.36,-195.76h53.36l-33.38,195.76H278.2L278.2,334.23z"
|
||||||
|
android:fillColor="#0E4595"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M524.31,142.69c-10.57,-3.97 -27.14,-8.22 -47.82,-8.22c-52.72,0 -89.86,26.55 -90.18,64.6c-0.3,28.13 26.51,43.82 46.75,53.19c20.77,9.6 27.75,15.72 27.65,24.28c-0.13,13.12 -16.59,19.12 -31.92,19.12c-21.35,0 -32.7,-2.97 -50.22,-10.27l-6.88,-3.11l-7.49,43.82c12.46,5.47 35.51,10.2 59.44,10.44c56.09,0 92.5,-26.25 92.92,-66.88c0.2,-22.27 -14.02,-39.22 -44.8,-53.19c-18.65,-9.06 -30.07,-15.1 -29.95,-24.27c0,-8.14 9.67,-16.84 30.56,-16.84c17.45,-0.27 30.09,3.53 39.94,7.5l4.78,2.26L524.31,142.69"
|
||||||
|
android:fillColor="#0E4595"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M661.61,138.46h-41.23c-12.77,0 -22.33,3.49 -27.94,16.23l-79.24,179.4h56.03c0,0 9.16,-24.12 11.23,-29.42c6.12,0 60.56,0.08 68.34,0.08c1.6,6.85 6.49,29.33 6.49,29.33h49.51L661.61,138.46L661.61,138.46zM596.2,264.87c4.41,-11.28 21.26,-54.72 21.26,-54.72c-0.31,0.52 4.38,-11.33 7.07,-18.68l3.61,16.88c0,0 10.22,46.73 12.35,56.53h-44.29V264.87L596.2,264.87z"
|
||||||
|
android:fillColor="#0E4595"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M45.88,138.46L45.2,142.54C66.29,147.64 85.13,155.03 101.62,164.23L148.97,333.91L205.42,333.85L289.43,138.46L232.9,138.46L180.66,271.96L175.1,244.83C174.84,243.99 174.56,243.15 174.27,242.31L156.11,154.99C152.88,142.6 143.51,138.9 131.92,138.46L45.88,138.46z"
|
||||||
|
android:fillColor="#0e4595"/>
|
||||||
|
</vector>
|
||||||
@ -12,7 +12,7 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk = 23
|
minSdk = 25
|
||||||
//noinspection ExpiredTargetSdkVersion
|
//noinspection ExpiredTargetSdkVersion
|
||||||
targetSdk = 30
|
targetSdk = 30
|
||||||
|
|
||||||
|
|||||||
@ -6,7 +6,7 @@ android {
|
|||||||
compileSdk = 34
|
compileSdk = 34
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk = 23
|
minSdk = 25
|
||||||
//noinspection ExpiredTargetSdkVersion
|
//noinspection ExpiredTargetSdkVersion
|
||||||
targetSdk = 30
|
targetSdk = 30
|
||||||
|
|
||||||
|
|||||||
@ -7,8 +7,8 @@ android {
|
|||||||
compileSdk = 34
|
compileSdk = 34
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk = 23
|
minSdk = 25
|
||||||
targetSdk = 30
|
targetSdk = 36
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
|
|
||||||
|
|||||||
@ -7,8 +7,8 @@ android {
|
|||||||
compileSdk = 34
|
compileSdk = 34
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk = 23
|
minSdk = 25
|
||||||
targetSdk = 30
|
targetSdk = 36
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
consumerProguardFiles "consumer-rules.pro"
|
consumerProguardFiles "consumer-rules.pro"
|
||||||
|
|||||||
@ -7,7 +7,7 @@ android {
|
|||||||
compileSdk = 34
|
compileSdk = 34
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk = 23
|
minSdk = 25
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
consumerProguardFiles("consumer-rules.pro")
|
consumerProguardFiles("consumer-rules.pro")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user