Compare commits
No commits in common. "af9a5487b1ea5378d456990cd085e4d0c70be53f" and "2937a747c8dd3bee68ada9659f9c5047fb136514" have entirely different histories.
af9a5487b1
...
2937a747c8
@ -449,9 +449,7 @@ fun DashboardScreen2(
|
|||||||
Spacer(Modifier.height(12.dp))
|
Spacer(Modifier.height(12.dp))
|
||||||
SummaryCard(
|
SummaryCard(
|
||||||
onClickLastSync = onClickLastSync,
|
onClickLastSync = onClickLastSync,
|
||||||
lastSyncTime = dashboardUiState.lastSyncTime,
|
lastSyncTime = dashboardUiState.lastSyncTime
|
||||||
totalSaleCount = dashboardUiState.totalSaleCount,
|
|
||||||
totalSaleAmount = dashboardUiState.totalSaleAmount
|
|
||||||
)
|
)
|
||||||
Spacer(Modifier.height(12.dp))
|
Spacer(Modifier.height(12.dp))
|
||||||
}
|
}
|
||||||
@ -529,9 +527,7 @@ private fun formatRelativeTime(timestamp: Long?, now: Long): String {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun SummaryCard(
|
private fun SummaryCard(
|
||||||
onClickLastSync: () -> Unit,
|
onClickLastSync: () -> Unit,
|
||||||
lastSyncTime: Long?,
|
lastSyncTime: Long?
|
||||||
totalSaleCount: Int,
|
|
||||||
totalSaleAmount: Long
|
|
||||||
) {
|
) {
|
||||||
var now by remember { mutableLongStateOf(System.currentTimeMillis()) }
|
var now by remember { mutableLongStateOf(System.currentTimeMillis()) }
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
@ -558,9 +554,9 @@ private fun SummaryCard(
|
|||||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||||
Column(modifier = Modifier.weight(1f)) {
|
Column(modifier = Modifier.weight(1f)) {
|
||||||
SummaryItem(
|
SummaryItem(
|
||||||
title = "Total Sale",
|
title = "Sales Today",
|
||||||
value = "MMK ${formatAmount(totalSaleAmount)}",
|
value = "MMK 2,000,000",
|
||||||
subtitle = "$totalSaleCount Transactions",
|
subtitle = "47 Transactions",
|
||||||
icon = Icons.Default.BarChart,
|
icon = Icons.Default.BarChart,
|
||||||
iconBg = Color.CrimsonRed
|
iconBg = Color.CrimsonRed
|
||||||
)
|
)
|
||||||
|
|||||||
@ -13,7 +13,5 @@ data class TrnxRecord(
|
|||||||
data class DashboardUiState(
|
data class DashboardUiState(
|
||||||
val recentTransactions: List<TrnxRecord> = emptyList(),
|
val recentTransactions: List<TrnxRecord> = emptyList(),
|
||||||
val lastSyncTime: Long? = null,
|
val lastSyncTime: Long? = null,
|
||||||
val carouselUrls: List<String> = emptyList(),
|
val carouselUrls: List<String> = emptyList()
|
||||||
val totalSaleCount: Int = 0,
|
|
||||||
val totalSaleAmount: Long = 0L
|
|
||||||
)
|
)
|
||||||
|
|||||||
@ -7,7 +7,6 @@ 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.utils.core_utils.SystemParamsOperation
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
||||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
@ -30,16 +29,14 @@ class DashboardViewModel @Inject constructor(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
repository.getLastTenTransactions().asFlow().collect { payDetails ->
|
repository.getLastTenTransactions().asFlow().collect { payDetails ->
|
||||||
_uiState.update {
|
_uiState.update {
|
||||||
it.copy(
|
it.copy(
|
||||||
recentTransactions = payDetails.map { pd -> pd.toRecord() },
|
recentTransactions = payDetails.map { pd -> pd.toRecord() }
|
||||||
totalSaleCount = payDetails.totalSaleCount(),
|
)
|
||||||
totalSaleAmount = payDetails.totalSaleAmount()
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
refreshLastSyncTime()
|
refreshLastSyncTime()
|
||||||
loadCarouselUrls()
|
loadCarouselUrls()
|
||||||
}
|
}
|
||||||
@ -61,48 +58,36 @@ class DashboardViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun PayDetail.toRecord(): TrnxRecord {
|
private fun PayDetail.toRecord(): TrnxRecord {
|
||||||
val baseType = transType?.takeIf { it.isNotBlank() }?.let { formatTypeLabel(it) } ?: "Transaction"
|
val type = transType?.takeIf { it.isNotBlank() }?.let { formatTypeLabel(it) } ?: "Transaction"
|
||||||
val type = if (isCanceled) "Void" else baseType
|
val amount = "MMK ${formatAmount(amount)}"
|
||||||
val amountText = "MMK ${formatAmount(amount)}"
|
val card = CardNo?.takeIf { it.length >= 4 }?.let { "**** ${it.takeLast(4)}" } ?: "----"
|
||||||
val card = CardNo?.takeIf { it.length >= 4 }?.let { "**** ${it.takeLast(4)}" } ?: "----"
|
val dt = buildDateTime(TradeDate, TradeTime)
|
||||||
val dt = buildDateTime(TradeDate, TradeTime)
|
|
||||||
val approved = tradeAnswerCode == "00" || approvalCode?.isNotBlank() == true
|
val approved = tradeAnswerCode == "00" || approvalCode?.isNotBlank() == true
|
||||||
|
|
||||||
return TrnxRecord(
|
return TrnxRecord(
|
||||||
pid = PID ?: 0L,
|
pid = PID ?: 0L,
|
||||||
typeLabel = type,
|
typeLabel = type,
|
||||||
amountDisplay = amountText,
|
amountDisplay= amount,
|
||||||
maskedCard = card,
|
maskedCard = card,
|
||||||
dateTime = dt,
|
dateTime = dt,
|
||||||
isVoided = isCanceled,
|
isVoided = isCanceled,
|
||||||
isApproved = approved
|
isApproved = approved
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun formatAmount(amount: Long): String {
|
fun formatAmount(amount: Long): String {
|
||||||
val scaled = BigDecimal(amount).movePointLeft(2)
|
val scaled = BigDecimal(amount).movePointLeft(2)
|
||||||
return DecimalFormat("#,###.00").format(scaled)
|
return DecimalFormat("#,###.00").format(scaled)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<PayDetail>.totalSaleCount(): Int = count { it.isSaleTransaction() }
|
|
||||||
|
|
||||||
private fun List<PayDetail>.totalSaleAmount(): Long = sumOf {
|
|
||||||
if (it.isSaleTransaction()) it.amount else 0L
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun PayDetail.isSaleTransaction(): Boolean {
|
|
||||||
return transactionType == TransactionsType.SALE.value ||
|
|
||||||
(transactionType == TransactionsType.WAVEPAY.value && qrTransStatus == 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun formatTypeLabel(raw: String): String = when {
|
private fun formatTypeLabel(raw: String): String = when {
|
||||||
raw.contains("SALE", ignoreCase = true) -> "Sale"
|
raw.contains("SALE", ignoreCase = true) -> "Sale"
|
||||||
raw.contains("VOID", ignoreCase = true) -> "Void"
|
raw.contains("VOID", ignoreCase = true) -> "Void"
|
||||||
raw.contains("REFUND", ignoreCase = true) -> "Refund"
|
raw.contains("REFUND", ignoreCase = true) -> "Refund"
|
||||||
raw.contains("SETTLEMENT", ignoreCase = true) -> "Settlement"
|
raw.contains("SETTLEMENT", ignoreCase = true) -> "Settlement"
|
||||||
raw.contains("PRE", ignoreCase = true) -> "Pre-Auth"
|
raw.contains("PRE", ignoreCase = true) -> "Pre-Auth"
|
||||||
raw.contains("CASH", ignoreCase = true) -> "Cash Out"
|
raw.contains("CASH", ignoreCase = true) -> "Cash Out"
|
||||||
raw.contains("WAVE", ignoreCase = true) -> "Wave Pay"
|
raw.contains("WAVE", ignoreCase = true) -> "Wave Pay"
|
||||||
else -> raw.lowercase().replaceFirstChar { it.uppercaseChar() }
|
else -> raw.lowercase().replaceFirstChar { it.uppercaseChar() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,11 +1,8 @@
|
|||||||
package com.mob.utsmyanmar.ui.navigation
|
package com.mob.utsmyanmar.ui.navigation
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.os.Build
|
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.hilt.navigation.compose.hiltViewModel
|
import androidx.hilt.navigation.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
@ -53,7 +50,6 @@ import com.mob.utsmyanmar.viewmodel.TransProcessViewModel
|
|||||||
import com.utsmyanmar.paylibs.model.TradeData
|
import com.utsmyanmar.paylibs.model.TradeData
|
||||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.N)
|
|
||||||
@SuppressLint("ContextCastToActivity")
|
@SuppressLint("ContextCastToActivity")
|
||||||
@Composable
|
@Composable
|
||||||
fun AppNavGraph(
|
fun AppNavGraph(
|
||||||
@ -86,27 +82,10 @@ fun AppNavGraph(
|
|||||||
val transProcessViewModel: TransProcessViewModel = hiltViewModel(activity)
|
val transProcessViewModel: TransProcessViewModel = hiltViewModel(activity)
|
||||||
val dashboardViewModel: DashboardViewModel = hiltViewModel(activity)
|
val dashboardViewModel: DashboardViewModel = hiltViewModel(activity)
|
||||||
val dashboardUiState = dashboardViewModel.uiState.collectAsStateWithLifecycle().value
|
val dashboardUiState = dashboardViewModel.uiState.collectAsStateWithLifecycle().value
|
||||||
val deviceInfoViewModel: DeviceInfoViewModel = hiltViewModel(activity)
|
|
||||||
val deviceInfoUiState = deviceInfoViewModel.uiState.collectAsStateWithLifecycle().value
|
|
||||||
val tmsSetupViewModel: TmsSetupViewModel = hiltViewModel();
|
|
||||||
|
|
||||||
LaunchedEffect(deviceInfoViewModel) {
|
|
||||||
deviceInfoViewModel.loadDeviceInfo()
|
|
||||||
}
|
|
||||||
|
|
||||||
LaunchedEffect(tmsSetupViewModel) {
|
|
||||||
tmsSetupViewModel.onSyncCompleted.collect {
|
|
||||||
dashboardViewModel.refreshLastSyncTime()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transProcessViewModel.resetTransactionStatus()
|
transProcessViewModel.resetTransactionStatus()
|
||||||
DashboardScreen2(
|
DashboardScreen2(
|
||||||
dashboardUiState = dashboardUiState,
|
dashboardUiState = dashboardUiState,
|
||||||
deviceInfo = deviceInfoUiState,
|
|
||||||
onClickLastSync = {
|
|
||||||
tmsSetupViewModel.downloadConfigs()
|
|
||||||
},
|
|
||||||
onNavigateAmount = { action ->
|
onNavigateAmount = { action ->
|
||||||
when (action) {
|
when (action) {
|
||||||
"Sale" -> {
|
"Sale" -> {
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import androidx.lifecycle.viewModelScope
|
|||||||
import com.mob.utsmyanmar.model.sirius.SiriusResponse
|
import com.mob.utsmyanmar.model.sirius.SiriusResponse
|
||||||
import com.mob.utsmyanmar.model.sirius.TMSUpdate
|
import com.mob.utsmyanmar.model.sirius.TMSUpdate
|
||||||
import com.mob.utsmyanmar.model.sirius.ValidityStatus
|
import com.mob.utsmyanmar.model.sirius.ValidityStatus
|
||||||
import com.mob.utsmyanmar.ui.dashboard.DashboardUiState
|
|
||||||
import com.mob.utsmyanmar.utils.tms.TMSSetupsImpl
|
import com.mob.utsmyanmar.utils.tms.TMSSetupsImpl
|
||||||
import com.mob.utsmyanmar.utils.tms.TMSUtil
|
import com.mob.utsmyanmar.utils.tms.TMSUtil
|
||||||
import com.utsmyanmar.baselib.BaseApplication
|
import com.utsmyanmar.baselib.BaseApplication
|
||||||
@ -50,7 +49,6 @@ class TmsSetupViewModel @Inject constructor(
|
|||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
private val _uiState = MutableStateFlow(TmsSetupUiState())
|
private val _uiState = MutableStateFlow(TmsSetupUiState())
|
||||||
private val _dashboardUiState = MutableStateFlow(DashboardUiState())
|
|
||||||
val uiState: StateFlow<TmsSetupUiState> = _uiState.asStateFlow()
|
val uiState: StateFlow<TmsSetupUiState> = _uiState.asStateFlow()
|
||||||
|
|
||||||
private val _navigateToDashboard = MutableSharedFlow<Unit>()
|
private val _navigateToDashboard = MutableSharedFlow<Unit>()
|
||||||
@ -78,15 +76,14 @@ class TmsSetupViewModel @Inject constructor(
|
|||||||
it.copy(isLoading = true, isError = false, statusText = "Connecting to TMS server...")
|
it.copy(isLoading = true, isError = false, statusText = "Connecting to TMS server...")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
val disposable = repository.getParams(buildRequest())
|
val disposable = repository.getParams(buildRequest())
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
{ response ->
|
{ response ->
|
||||||
_uiState.update { it.copy(
|
_uiState.update { it.copy(statusText = "Applying configuration...") }
|
||||||
statusText = "Applying configuration...")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val appResponse = SiriusResponse(
|
val appResponse = SiriusResponse(
|
||||||
serial = response.serial.orEmpty(),
|
serial = response.serial.orEmpty(),
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package com.mob.utsmyanmar.viewmodel
|
package com.mob.utsmyanmar.viewmodel
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import com.mob.utsmyanmar.model.TransResultStatus
|
import com.mob.utsmyanmar.model.TransResultStatus
|
||||||
@ -18,15 +17,13 @@ import com.utsmyanmar.paylibs.utils.PrintStatus
|
|||||||
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
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class TransProcessViewModel @Inject constructor(
|
class TransProcessViewModel @Inject constructor(
|
||||||
private val repository: Repository,
|
private val repository: Repository
|
||||||
@ApplicationContext private val context: Context
|
|
||||||
) : ViewModel(), ProcessingTransaction {
|
) : ViewModel(), ProcessingTransaction {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -187,8 +184,6 @@ class TransProcessViewModel @Inject constructor(
|
|||||||
_payDetailResult.value =
|
_payDetailResult.value =
|
||||||
payDetailRes
|
payDetailRes
|
||||||
|
|
||||||
stampLastSyncTime()
|
|
||||||
|
|
||||||
_transResultStatus.value =
|
_transResultStatus.value =
|
||||||
TransResultStatus.SUCCESS
|
TransResultStatus.SUCCESS
|
||||||
|
|
||||||
@ -257,7 +252,6 @@ class TransProcessViewModel @Inject constructor(
|
|||||||
repository.insertPayDetail(
|
repository.insertPayDetail(
|
||||||
updateCurrentDateAndTime(payResult)
|
updateCurrentDateAndTime(payResult)
|
||||||
)
|
)
|
||||||
stampLastSyncTime()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processRefundDB(payResult: PayDetail) {
|
override fun processRefundDB(payResult: PayDetail) {
|
||||||
@ -272,7 +266,6 @@ class TransProcessViewModel @Inject constructor(
|
|||||||
repository.insertPayDetail(
|
repository.insertPayDetail(
|
||||||
updateCurrentDateAndTime(payResult)
|
updateCurrentDateAndTime(payResult)
|
||||||
)
|
)
|
||||||
stampLastSyncTime()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun processPreVoidDb(payResult: PayDetail) {
|
override fun processPreVoidDb(payResult: PayDetail) {
|
||||||
@ -283,7 +276,6 @@ class TransProcessViewModel @Inject constructor(
|
|||||||
|
|
||||||
|
|
||||||
repository.insertPayDetail(updateCurrentDateAndTime(payResult))
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult))
|
||||||
stampLastSyncTime()
|
|
||||||
}
|
}
|
||||||
override fun processPreCompDb(payResult: PayDetail) {
|
override fun processPreCompDb(payResult: PayDetail) {
|
||||||
if (oldTransPayDetail?.getAmount() == payResult.getAmount()) {
|
if (oldTransPayDetail?.getAmount() == payResult.getAmount()) {
|
||||||
@ -298,7 +290,6 @@ class TransProcessViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
repository.insertPayDetail(updateCurrentDateAndTime(payResult))
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult))
|
||||||
stampLastSyncTime()
|
|
||||||
}
|
}
|
||||||
override fun processPreCompVoidDb(payResult: PayDetail) {
|
override fun processPreCompVoidDb(payResult: PayDetail) {
|
||||||
payDetail?.apply {
|
payDetail?.apply {
|
||||||
@ -306,7 +297,6 @@ class TransProcessViewModel @Inject constructor(
|
|||||||
repository.updatePayDetail(this)
|
repository.updatePayDetail(this)
|
||||||
}
|
}
|
||||||
repository.insertPayDetail(updateCurrentDateAndTime(payResult))
|
repository.insertPayDetail(updateCurrentDateAndTime(payResult))
|
||||||
stampLastSyncTime()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -381,13 +371,6 @@ class TransProcessViewModel @Inject constructor(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun stampLastSyncTime() {
|
|
||||||
context.getSharedPreferences("mobpos_prefs", Context.MODE_PRIVATE)
|
|
||||||
.edit()
|
|
||||||
.putLong("last_sync_time", System.currentTimeMillis())
|
|
||||||
.apply()
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Utils
|
* Utils
|
||||||
*/
|
*/
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user