Settlement Screen init
This commit is contained in:
parent
767456b29a
commit
af917520b6
@ -0,0 +1,11 @@
|
||||
package com.mob.utsmyanmar.model
|
||||
|
||||
enum class TransactionStatus {
|
||||
ON_SUCCESS,
|
||||
ON_REVERSAL,
|
||||
ON_BATCH_UPLOAD,
|
||||
ON_FAIL,
|
||||
ON_ERROR,
|
||||
ON_SECONDARY,
|
||||
ON_DONE
|
||||
}
|
||||
@ -38,6 +38,7 @@ import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.DrawerValue
|
||||
import androidx.compose.material3.ModalDrawerSheet
|
||||
import androidx.compose.material3.ModalNavigationDrawer
|
||||
import androidx.compose.material3.NavigationDrawerItem
|
||||
@ -85,6 +86,7 @@ fun DashboardScreen2(
|
||||
onNavigateAmount: (String) -> Unit = {},
|
||||
onNavigateSignOn: () -> Unit = {},
|
||||
onNavigateSeeMore: () -> Unit = {},
|
||||
onNavigateSettlement: () -> Unit = {},
|
||||
deviceInfoViewModel: DeviceInfoViewModel = viewModel()
|
||||
) {
|
||||
val deviceInfo by deviceInfoViewModel.uiState.collectAsState()
|
||||
@ -92,7 +94,7 @@ fun DashboardScreen2(
|
||||
LaunchedEffect(Unit) {
|
||||
deviceInfoViewModel.loadDeviceInfo();
|
||||
}
|
||||
val drawerState = rememberDrawerState(initialValue = androidx.compose.material3.DrawerValue.Closed)
|
||||
val drawerState = rememberDrawerState(initialValue = DrawerValue.Closed)
|
||||
val scope = rememberCoroutineScope()
|
||||
val mainHandler = remember { Handler(Looper.getMainLooper()) }
|
||||
var showHostActionDialog by remember { mutableStateOf(false) }
|
||||
@ -301,7 +303,8 @@ fun DashboardScreen2(
|
||||
MenuGrid(
|
||||
onNavigateAmount = onNavigateAmount,
|
||||
onNavigateSignOn = onNavigateSignOn,
|
||||
onNavigateSeeMore = onNavigateSeeMore
|
||||
onNavigateSeeMore = onNavigateSeeMore,
|
||||
onNavigateSettlement = onNavigateSettlement
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -496,7 +499,8 @@ private fun IconCircle(
|
||||
private fun MenuGrid(
|
||||
onNavigateAmount: (String) -> Unit,
|
||||
onNavigateSignOn: () -> Unit,
|
||||
onNavigateSeeMore: () -> Unit
|
||||
onNavigateSeeMore: () -> Unit,
|
||||
onNavigateSettlement: () -> Unit
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(10.dp),
|
||||
@ -520,7 +524,12 @@ private fun MenuGrid(
|
||||
Modifier.weight(1f),
|
||||
onClick = onNavigateSignOn
|
||||
)
|
||||
MenuCard("Settlement", Icons.Default.Wallet, Modifier.weight(1f))
|
||||
MenuCard(
|
||||
"Settlement",
|
||||
Icons.Default.Wallet,
|
||||
Modifier.weight(1f),
|
||||
onClick = onNavigateSettlement
|
||||
)
|
||||
MenuCard(
|
||||
"See More",
|
||||
Icons.Default.GridView,
|
||||
|
||||
@ -23,6 +23,7 @@ import com.mob.utsmyanmar.ui.print_receipt.PrintReceiptScreen
|
||||
import com.mob.utsmyanmar.ui.sign_on.SignOnResultScreen
|
||||
import com.mob.utsmyanmar.ui.sign_on.SignOnRoute
|
||||
import com.mob.utsmyanmar.ui.sending_to_host.SendingToHostRoute
|
||||
import com.mob.utsmyanmar.ui.settlement.SettlementScreen
|
||||
import com.mob.utsmyanmar.ui.transaction_result.TransactionResultRoute
|
||||
import com.mob.utsmyanmar.ui.sale_void.TranDetailPage
|
||||
import com.mob.utsmyanmar.ui.sale_void.VoidViewModel
|
||||
@ -63,6 +64,11 @@ fun AppNavGraph(
|
||||
navController.navigate(Routes.SeeMore.route) {
|
||||
launchSingleTop = true
|
||||
}
|
||||
},
|
||||
onNavigateSettlement = {
|
||||
navController.navigate(Routes.Settlement.route) {
|
||||
launchSingleTop = true
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@ -98,6 +104,24 @@ fun AppNavGraph(
|
||||
)
|
||||
}
|
||||
|
||||
composable(Routes.Settlement.route) {
|
||||
val sharedViewModel: SharedViewModel = hiltViewModel(activity)
|
||||
|
||||
SettlementScreen(
|
||||
sharedViewModel = sharedViewModel,
|
||||
onBack = { navController.popBackStack() },
|
||||
onStartSettlement = {
|
||||
sharedViewModel.transactionsType.value = com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType.SETTLEMENT
|
||||
navController.navigate(Routes.SendingToHost.route) {
|
||||
popUpTo(Routes.Settlement.route) {
|
||||
inclusive = true
|
||||
}
|
||||
launchSingleTop = true
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
composable(
|
||||
route = Routes.VoidTranDetail.route,
|
||||
arguments = listOf(
|
||||
|
||||
@ -8,6 +8,7 @@ sealed class Routes(val route: String) {
|
||||
fun createRoute(action: String): String = "amount/${Uri.encode(action)}"
|
||||
}
|
||||
data object SeeMore : Routes("see_more")
|
||||
data object Settlement : Routes("settlement")
|
||||
data object VoidTrace : Routes("void_trace")
|
||||
data object VoidTranDetail : Routes("void_tran_detail/{trace}") {
|
||||
fun createRoute(trace: String): String = "void_tran_detail/${Uri.encode(trace)}"
|
||||
|
||||
@ -0,0 +1,194 @@
|
||||
package com.mob.utsmyanmar.ui.settlement
|
||||
|
||||
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.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.CardDefaults
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.mob.utsmyanmar.ui.components.appbar.AppBar
|
||||
import com.mob.utsmyanmar.ui.theme.Color
|
||||
import com.mob.utsmyanmar.viewmodel.SharedViewModel
|
||||
import com.utsmyanmar.paylibs.model.PayDetail
|
||||
import com.utsmyanmar.paylibs.utils.POSUtil
|
||||
|
||||
@Composable
|
||||
fun SettlementScreen(
|
||||
sharedViewModel: SharedViewModel,
|
||||
onBack: () -> Unit,
|
||||
onStartSettlement: () -> Unit
|
||||
) {
|
||||
val records by sharedViewModel.getSettlementRecords().observeAsState(emptyList())
|
||||
val totalAmount = records.sumOf { it.amount }
|
||||
|
||||
Scaffold(
|
||||
containerColor = Color.IvoryBeige,
|
||||
topBar = {
|
||||
AppBar(
|
||||
title = "Settlement",
|
||||
icon = Icons.AutoMirrored.Filled.ArrowBack,
|
||||
onIconClick = onBack
|
||||
)
|
||||
}
|
||||
) { paddingValues ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(paddingValues)
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Card(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
colors = CardDefaults.cardColors(containerColor = Color.White)
|
||||
) {
|
||||
Column(modifier = Modifier.padding(18.dp)) {
|
||||
Text(
|
||||
text = "Settlement Summary",
|
||||
color = Color.LegacyRed,
|
||||
fontSize = 18.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
|
||||
SummaryRow("Record Count", records.size.toString())
|
||||
SummaryRow("Total Amount", POSUtil.getInstance().formatAmount(totalAmount))
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Text(
|
||||
text = "Unsettled Records",
|
||||
color = Color.Black,
|
||||
fontSize = 15.sp,
|
||||
fontWeight = FontWeight.SemiBold
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
|
||||
Card(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f),
|
||||
colors = CardDefaults.cardColors(containerColor = Color.White)
|
||||
) {
|
||||
if (records.isEmpty()) {
|
||||
Text(
|
||||
text = "No records available for settlement.",
|
||||
color = Color.Gray,
|
||||
fontSize = 14.sp,
|
||||
modifier = Modifier.padding(18.dp)
|
||||
)
|
||||
} else {
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.spacedBy(0.dp)
|
||||
) {
|
||||
items(records) { record ->
|
||||
SettlementRecordRow(record = record)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Button(
|
||||
onClick = onStartSettlement,
|
||||
enabled = records.isNotEmpty(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(56.dp),
|
||||
colors = ButtonDefaults.buttonColors(
|
||||
containerColor = Color.LegacyRed,
|
||||
contentColor = Color.White
|
||||
)
|
||||
) {
|
||||
Text("Start Settlement")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SummaryRow(
|
||||
label: String,
|
||||
value: String
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text(
|
||||
text = label,
|
||||
color = Color.Gray,
|
||||
fontSize = 13.sp
|
||||
)
|
||||
Text(
|
||||
text = value,
|
||||
color = Color.Black,
|
||||
fontSize = 13.sp,
|
||||
fontWeight = FontWeight.Medium
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SettlementRecordRow(record: PayDetail) {
|
||||
Column(modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp)) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text(
|
||||
text = record.transType.ifBlank { "UNKNOWN" },
|
||||
color = Color.LegacyRed,
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
Text(
|
||||
text = POSUtil.getInstance().formatAmount(record.amount),
|
||||
color = Color.Black,
|
||||
fontSize = 14.sp,
|
||||
fontWeight = FontWeight.SemiBold
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(4.dp))
|
||||
|
||||
Text(
|
||||
text = "Trace ${record.voucherNo.ifBlank { "-" }}",
|
||||
color = Color.Black,
|
||||
fontSize = 12.sp
|
||||
)
|
||||
Text(
|
||||
text = "Card ${record.cardNo.ifBlank { "-" }}",
|
||||
color = Color.Gray,
|
||||
fontSize = 12.sp
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(12.dp))
|
||||
HorizontalDivider(color = Color.Gray.copy(alpha = 0.25f))
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,440 @@
|
||||
package com.mob.utsmyanmar.ui.settlement
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.mob.utsmyanmar.config.Constants
|
||||
import com.mob.utsmyanmar.model.SettlementType
|
||||
import com.mob.utsmyanmar.model.TransactionStatus
|
||||
import com.utsmyanmar.baselib.repo.Repository
|
||||
import com.utsmyanmar.paylibs.Constant
|
||||
import com.utsmyanmar.paylibs.batch_upload.BatchListener
|
||||
import com.utsmyanmar.paylibs.batch_upload.BatchUploadProcess
|
||||
import com.utsmyanmar.paylibs.isobuilder.ISOMode
|
||||
import com.utsmyanmar.paylibs.isobuilder.builderx.ISOMsgX
|
||||
import com.utsmyanmar.paylibs.isobuilder.builderx.ISOVersion
|
||||
import com.utsmyanmar.paylibs.model.MsgField
|
||||
import com.utsmyanmar.paylibs.model.PayDetail
|
||||
import com.utsmyanmar.paylibs.model.SettleData
|
||||
import com.utsmyanmar.paylibs.model.TradeData
|
||||
import com.utsmyanmar.paylibs.network.ISOCallback
|
||||
import com.utsmyanmar.paylibs.network.ISOSocket
|
||||
import com.utsmyanmar.paylibs.utils.MessageType
|
||||
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
||||
import com.utsmyanmar.paylibs.utils.enums.HostName
|
||||
import com.utsmyanmar.paylibs.utils.iso_utils.BitmapConfig
|
||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionType
|
||||
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
||||
import com.utsmyanmar.paylibs.utils.params.Params
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.channels.Channel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.receiveAsFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import sunmi.sunmiui.utils.LogUtil
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
data class SettlementUiState(
|
||||
val saleCount: Int = 0,
|
||||
val saleAmount: Long = 0L,
|
||||
|
||||
val preCount: Int = 0,
|
||||
val preAmount: Long = 0L,
|
||||
|
||||
val refundCount: Int = 0,
|
||||
val refundAmount: Long = 0L,
|
||||
|
||||
val caCount: Int = 0,
|
||||
val caAmount: Long = 0L,
|
||||
|
||||
val settlementType: SettlementType? = null,
|
||||
val isNoData: Boolean = false,
|
||||
val isSentData: Boolean = false,
|
||||
val bottomLayout: Int = 0,
|
||||
|
||||
val status: TransactionStatus? = null,
|
||||
val isLoading: Boolean = false
|
||||
)
|
||||
|
||||
sealed interface SettlementEvent {
|
||||
data class ShowStatus(val status: TransactionStatus) : SettlementEvent
|
||||
}
|
||||
|
||||
@HiltViewModel
|
||||
class SettlementViewModel @Inject constructor(
|
||||
private val repository: Repository
|
||||
) : ViewModel() {
|
||||
|
||||
companion object {
|
||||
private val TAG = SettlementViewModel::class.java.simpleName
|
||||
}
|
||||
|
||||
private var payDetail: PayDetail? = null
|
||||
private var payDetails: List<PayDetail>? = null
|
||||
|
||||
private val deleteTrans = arrayListOf<PayDetail>()
|
||||
|
||||
private var flag = false
|
||||
private var errorFlag = false
|
||||
private var isSecondCall = false
|
||||
private var batchIndex = 0
|
||||
|
||||
private var bitmap = ""
|
||||
|
||||
private val isoMsgX: ISOMsgX =
|
||||
ISOMsgX.ISOMsgXBuilder(
|
||||
ISOVersion.VERSION_1993,
|
||||
ISOMode.BOTH_HEADER_TPDU,
|
||||
HostName.BPC
|
||||
).build()
|
||||
|
||||
private val _uiState = MutableStateFlow(SettlementUiState())
|
||||
val uiState = _uiState.asStateFlow()
|
||||
|
||||
private val _events = Channel<SettlementEvent>(Channel.BUFFERED)
|
||||
val events = _events.receiveAsFlow()
|
||||
|
||||
fun getLastSettlement(voucherNo: String): LiveData<List<PayDetail>> {
|
||||
return repository.getLastSettlement(voucherNo)
|
||||
}
|
||||
|
||||
fun getSettlement(): LiveData<List<PayDetail>> {
|
||||
return repository.getSettlement()
|
||||
}
|
||||
|
||||
fun getSettlementPOS(): LiveData<List<PayDetail>> {
|
||||
return repository.getSettlementPOS()
|
||||
}
|
||||
|
||||
fun getDeleteTrans(batchNo: String): LiveData<List<PayDetail>> {
|
||||
return repository.getDeleteTrans(batchNo)
|
||||
}
|
||||
|
||||
fun getAdditionalSettlementPOS(): LiveData<List<PayDetail>> {
|
||||
return repository.getAdditionalSettlementPOS(
|
||||
SystemParamsOperation.getInstance().getCurrentBatchNum()
|
||||
)
|
||||
}
|
||||
|
||||
fun setPayDetails(list: List<PayDetail>) {
|
||||
payDetails = list
|
||||
}
|
||||
|
||||
fun setSettlementSummary(
|
||||
saleCount: Int,
|
||||
saleAmount: Long,
|
||||
preCount: Int,
|
||||
preAmount: Long,
|
||||
refundCount: Int,
|
||||
refundAmount: Long,
|
||||
caCount: Int,
|
||||
caAmount: Long
|
||||
) {
|
||||
_uiState.update {
|
||||
it.copy(
|
||||
saleCount = saleCount,
|
||||
saleAmount = saleAmount,
|
||||
preCount = preCount,
|
||||
preAmount = preAmount,
|
||||
refundCount = refundCount,
|
||||
refundAmount = refundAmount,
|
||||
caCount = caCount,
|
||||
caAmount = caAmount
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setSettlementType(type: SettlementType) {
|
||||
_uiState.update {
|
||||
it.copy(settlementType = type)
|
||||
}
|
||||
}
|
||||
|
||||
fun updatePayDetail(payDetail: PayDetail) {
|
||||
repository.updatePayDetail(payDetail)
|
||||
}
|
||||
|
||||
private fun insertPayDetail(payDetail: PayDetail) {
|
||||
repository.insertPayDetail(payDetail)
|
||||
}
|
||||
|
||||
private fun updateDB() {
|
||||
payDetails?.forEach { pay ->
|
||||
repository.deletePayDetail(pay)
|
||||
}
|
||||
|
||||
deleteTrans.forEach { pay ->
|
||||
repository.deletePayDetail(pay)
|
||||
}
|
||||
|
||||
payDetails = emptyList()
|
||||
deleteTrans.clear()
|
||||
}
|
||||
|
||||
fun startSettlementProcess() {
|
||||
_uiState.update {
|
||||
it.copy(isLoading = true)
|
||||
}
|
||||
|
||||
SystemParamsOperation.getInstance().getIncrementBatchNo()
|
||||
|
||||
requestOnlineProcessSettlement()
|
||||
}
|
||||
|
||||
fun startPrintSettlementProcess() {
|
||||
// PrintReceipt.getInstance().printSettlementReceiptPOS(...)
|
||||
}
|
||||
|
||||
fun testServiceClass() {
|
||||
LogUtil.d(TAG, "SettlementViewModel works!")
|
||||
}
|
||||
|
||||
private fun requestOnlineProcessSettlement() {
|
||||
val state = _uiState.value
|
||||
|
||||
val hostName = HostName.BPC
|
||||
val field60 = SystemParamsOperation.getInstance().getCurrentBatchNum()
|
||||
|
||||
val sale2Count = state.saleCount + state.preCount
|
||||
val sale2Amount = state.saleAmount + state.preAmount
|
||||
|
||||
val totalSaleCount = String.format(Locale.getDefault(), "%03d", sale2Count)
|
||||
val totalSaleAmount = String.format(Locale.getDefault(), "%010d00", sale2Amount)
|
||||
|
||||
val totalRefundCount = String.format(Locale.getDefault(), "%03d", state.refundCount)
|
||||
val totalRefundAmount = String.format(
|
||||
Locale.getDefault(),
|
||||
"%010d00",
|
||||
if (state.refundAmount == 0L) 0 else state.refundAmount
|
||||
)
|
||||
|
||||
val totalDebitSaleCount = String.format(Locale.getDefault(), "%03d", state.caCount)
|
||||
val totalDebitSaleAmount = String.format(
|
||||
Locale.getDefault(),
|
||||
"%010d00",
|
||||
if (state.caAmount == 0L) 0 else state.caAmount
|
||||
)
|
||||
|
||||
val totalERefundCount = String.format(Locale.getDefault(), "%03d", 0)
|
||||
val totalERefundAmount = String.format(Locale.getDefault(), "%010d00", 0)
|
||||
|
||||
val tradeData = Params.newTrade(true)
|
||||
val currentPayDetail = tradeData.payDetail
|
||||
|
||||
payDetail = currentPayDetail
|
||||
|
||||
bitmap = BitmapConfig.BPC_SETTLEMENT
|
||||
|
||||
currentPayDetail.transType = TransactionsType.SETTLEMENT.name
|
||||
currentPayDetail.transactionType = TransactionType.SETTLEMENT
|
||||
|
||||
if (!flag) {
|
||||
currentPayDetail.processCode = TransactionsType.SETTLEMENT.processCode
|
||||
} else {
|
||||
bitmap = BitmapConfig.BPC_SETTLEMENT_TRAILER
|
||||
currentPayDetail.processCode = "910000"
|
||||
}
|
||||
|
||||
currentPayDetail.batchNo = SystemParamsOperation.getInstance().getCurrentBatchNum()
|
||||
|
||||
currentPayDetail.settleList =
|
||||
"${state.saleCount}:${state.saleAmount}-" +
|
||||
"${state.caCount}:${state.caAmount}-" +
|
||||
"${state.refundCount}:${state.refundAmount}-" +
|
||||
"${state.preCount}:${state.preAmount}"
|
||||
|
||||
val settleData = SettleData(
|
||||
state.saleCount,
|
||||
state.saleAmount,
|
||||
state.preCount,
|
||||
state.preAmount,
|
||||
state.refundCount,
|
||||
state.refundAmount,
|
||||
state.caCount,
|
||||
state.caAmount
|
||||
)
|
||||
|
||||
currentPayDetail.settleDataObj = settleData
|
||||
|
||||
if (hostName == HostName.BPC) {
|
||||
val totalAmount =
|
||||
state.saleAmount + state.preAmount + state.refundAmount + state.caAmount
|
||||
|
||||
val settlementData = if (state.refundAmount != 0L) {
|
||||
val creditTotal = state.saleAmount + state.preAmount + state.caAmount
|
||||
val subTotal = creditTotal - state.refundAmount
|
||||
|
||||
if (subTotal < 0L) {
|
||||
"D" + String.format(Locale.getDefault(), "%012d", kotlin.math.abs(subTotal))
|
||||
} else {
|
||||
"C" + String.format(Locale.getDefault(), "%012d", subTotal)
|
||||
}
|
||||
} else {
|
||||
"C" + String.format(Locale.getDefault(), "%012d", totalAmount)
|
||||
}
|
||||
|
||||
currentPayDetail.settleData = settlementData
|
||||
currentPayDetail.amount = totalAmount
|
||||
} else {
|
||||
currentPayDetail.settleData =
|
||||
totalSaleCount +
|
||||
totalSaleAmount +
|
||||
totalRefundCount +
|
||||
totalRefundAmount +
|
||||
totalDebitSaleCount +
|
||||
totalDebitSaleAmount +
|
||||
totalERefundCount +
|
||||
totalERefundAmount
|
||||
}
|
||||
|
||||
tradeData.payDetail = currentPayDetail
|
||||
tradeData.field60 = field60
|
||||
|
||||
val sendBytes = isoMsgX.buildISOPackets(
|
||||
tradeData,
|
||||
bitmap,
|
||||
MessageType.SETTLEMENT
|
||||
)
|
||||
|
||||
LogUtil.d(TAG, "Starting SETTLEMENT process...")
|
||||
|
||||
ISOSocket.getInstance().enqueue(
|
||||
sendBytes,
|
||||
sendBytes.size,
|
||||
false,
|
||||
object : ISOCallback {
|
||||
|
||||
override fun onReceive(bytes: ByteArray, length: Int) {
|
||||
val responseMap: Map<String, MsgField>? =
|
||||
isoMsgX.parseISOPackets(bytes, length)
|
||||
|
||||
if (responseMap != null) {
|
||||
val resultStr = try {
|
||||
responseMap["F039"]?.dataStr.orEmpty()
|
||||
} catch (e: NullPointerException) {
|
||||
e.printStackTrace()
|
||||
currentPayDetail.isNeedReversal = true
|
||||
return
|
||||
}
|
||||
|
||||
currentPayDetail.tradeAnswerCode = resultStr
|
||||
|
||||
when {
|
||||
resultStr == Constant.ANSWER_CODE_ACCEPT ||
|
||||
resultStr == Constant.ANSWER_CODE_APPROVED -> {
|
||||
currentPayDetail.isNeedReversal = false
|
||||
}
|
||||
|
||||
resultStr == "95" || resultStr == "095" -> {
|
||||
currentPayDetail.isNeedReversal = !flag
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errorFlag = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError(msg: String) {
|
||||
if (msg != Constants.REVERSAL) {
|
||||
if (!isSecondCall) {
|
||||
ISOSocket.getInstance().switchIp()
|
||||
|
||||
postStatus(TransactionStatus.ON_SECONDARY)
|
||||
|
||||
isSecondCall = true
|
||||
requestOnlineProcessSettlement()
|
||||
} else {
|
||||
postStatus(TransactionStatus.ON_ERROR)
|
||||
|
||||
currentPayDetail.isNeedReversal = true
|
||||
isSecondCall = false
|
||||
}
|
||||
} else {
|
||||
postStatus(TransactionStatus.ON_ERROR)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
if (currentPayDetail.isNeedReversal) {
|
||||
flag = true
|
||||
batchUploadProcess()
|
||||
} else {
|
||||
flag = false
|
||||
batchIndex = 0
|
||||
|
||||
updateDB()
|
||||
insertPayDetail(currentPayDetail)
|
||||
|
||||
if (errorFlag) {
|
||||
postStatus(TransactionStatus.ON_ERROR)
|
||||
} else {
|
||||
postStatus(TransactionStatus.ON_SUCCESS)
|
||||
}
|
||||
|
||||
_uiState.update {
|
||||
it.copy(isLoading = false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun batchUploadProcess() {
|
||||
postStatus(TransactionStatus.ON_BATCH_UPLOAD)
|
||||
|
||||
val currentPayDetails = payDetails
|
||||
|
||||
if (currentPayDetails.isNullOrEmpty()) {
|
||||
requestOnlineProcessSettlement()
|
||||
return
|
||||
}
|
||||
|
||||
val uploadPayDetail = currentPayDetails[batchIndex]
|
||||
|
||||
val tradeData = TradeData().apply {
|
||||
payDetail = uploadPayDetail
|
||||
}
|
||||
|
||||
BatchUploadProcess.getInstance()
|
||||
.enqueue(tradeData)
|
||||
.startBatchUpload(object : BatchListener {
|
||||
|
||||
override fun onSuccessBatch() {
|
||||
if (batchIndex < currentPayDetails.size - 1) {
|
||||
LogUtil.d(TAG, "Pay detail size: ${currentPayDetails.size}")
|
||||
LogUtil.d(TAG, "Count value: $batchIndex")
|
||||
|
||||
batchIndex++
|
||||
batchUploadProcess()
|
||||
} else {
|
||||
requestOnlineProcessSettlement()
|
||||
}
|
||||
|
||||
LogUtil.e(TAG, "Batch Upload Success")
|
||||
}
|
||||
|
||||
override fun onFailBatch() {
|
||||
LogUtil.e(TAG, "Batch Upload Fail")
|
||||
postStatus(TransactionStatus.ON_ERROR)
|
||||
|
||||
_uiState.update {
|
||||
it.copy(isLoading = false)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun postStatus(status: TransactionStatus) {
|
||||
_uiState.update {
|
||||
it.copy(status = status)
|
||||
}
|
||||
|
||||
viewModelScope.launch {
|
||||
_events.send(SettlementEvent.ShowStatus(status))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -431,6 +431,10 @@ class SharedViewModel @Inject constructor(
|
||||
return repository.getLastThreeTransactions()
|
||||
}
|
||||
|
||||
fun getSettlementRecords(): LiveData<List<PayDetail>> {
|
||||
return repository.getSettlementPOS()
|
||||
}
|
||||
|
||||
fun getReversalTransaction(voucherNo: String): LiveData<PayDetail> {
|
||||
return repository.getReversalTransaction(voucherNo)
|
||||
}
|
||||
@ -445,6 +449,7 @@ class SharedViewModel @Inject constructor(
|
||||
|
||||
fun saveMockHostResultForTesting() {
|
||||
when (transactionsType.value) {
|
||||
TransactionsType.SETTLEMENT -> saveMockSettlementForTesting()
|
||||
TransactionsType.VOID -> saveMockApprovedVoidForTesting()
|
||||
else -> saveMockApprovedSaleForVoidTesting()
|
||||
}
|
||||
@ -553,6 +558,39 @@ class SharedViewModel @Inject constructor(
|
||||
approvalCode.value = mockApprovalCode
|
||||
}
|
||||
|
||||
fun saveMockSettlementForTesting() {
|
||||
val systemParams = SystemParamsOperation.getInstance()
|
||||
val mockTraceNo = systemParams.incrementSerialNum
|
||||
val mockInvoiceNo = systemParams.incrementInvoiceNum
|
||||
|
||||
val settlementDetail = PayDetail().apply {
|
||||
merchantNo = systemParams.merchantId
|
||||
merchantName = systemParams.merchantName
|
||||
terminalNo = systemParams.terminalId
|
||||
voucherNo = mockTraceNo
|
||||
invoiceNo = mockInvoiceNo
|
||||
batchNo = systemParams.systemParamsSettings.batchNumStart
|
||||
processCode = TransactionsType.SETTLEMENT.processCode
|
||||
transactionType = TransactionType.SETTLEMENT
|
||||
transType = TransactionsType.SETTLEMENT.name
|
||||
currencyCode = systemParams.currencyType.removed0CurrencyCode
|
||||
tradeAnswerCode = "00"
|
||||
tradeResultDes = "MOCK SETTLEMENT APPROVED"
|
||||
TradeDate = SystemDateTime.getMMDD()
|
||||
TradeTime = SystemDateTime.getHHmmss()
|
||||
tradeDateAndTime = SystemDateTime.getMMDDhhmmss()
|
||||
tradeDateTime = SystemDateTime.getYYMMDDhhmmss()
|
||||
transDate = SystemDateTime.getTodayDateFormat()
|
||||
transTime = SystemDateTime.getTodayTimeFormat()
|
||||
isSettle = false
|
||||
isNeedReversal = false
|
||||
isCanceled = false
|
||||
}
|
||||
|
||||
payDetail.value = settlementDetail
|
||||
traceNo.value = mockTraceNo
|
||||
}
|
||||
|
||||
fun enableCardStatusIcon(
|
||||
tapCard: Boolean,
|
||||
tapDevice: Boolean,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user