auto settlement

This commit is contained in:
moon 2026-08-20 23:18:59 +06:30
parent 5bb07df9e3
commit d011b46345
15 changed files with 388 additions and 76 deletions

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="temurin-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">

View File

@ -20,6 +20,9 @@
<uses-permission android:name="com.sunmi.perm.CONTACTLESS_CARD" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.CAMERA" />

View File

@ -1,41 +1,108 @@
package com.mob.utsmyanmar
import android.Manifest
import android.app.AlarmManager
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.annotation.RequiresApi
import androidx.annotation.RequiresPermission
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.navigation.compose.rememberNavController
import com.mob.utsmyanmar.auto_settlement.SettlementScheduler
import com.mob.utsmyanmar.ui.navigation.AppNavGraph
import com.mob.utsmyanmar.ui.theme.MOBPOSTheme
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class MainActivity : ComponentActivity() {
@RequiresPermission(Manifest.permission.SCHEDULE_EXACT_ALARM)
@RequiresApi(Build.VERSION_CODES.N)
private var autoSettlementRequested by mutableStateOf(false)
private var exactAlarmSettingsOpened = false
override fun onCreate(savedInstanceState: Bundle?) {
SettlementScheduler.schedule(this)
// installSplashScreen()
super.onCreate(savedInstanceState)
autoSettlementRequested = intent?.getBooleanExtra("AUTO_SETTLEMENT", false) == true
requestNotificationPermission()
scheduleSettlementAlarm()
enableEdgeToEdge()
hideSystemBars()
// window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
setContent {
MOBPOSTheme {
val navController = rememberNavController()
AppNavGraph(navController = navController)
AppNavGraph(
navController = navController,
autoSettlementRequested = autoSettlementRequested,
onAutoSettlementHandled = { autoSettlementRequested = false }
)
}
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
if (intent.getBooleanExtra("AUTO_SETTLEMENT", false)) {
autoSettlementRequested = true
}
}
override fun onResume() {
super.onResume()
scheduleSettlementAlarm()
}
private fun requestNotificationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED
) {
requestPermissions(
arrayOf(Manifest.permission.POST_NOTIFICATIONS),
NOTIFICATION_PERMISSION_REQUEST_CODE
)
}
}
private fun scheduleSettlementAlarm() {
if (!SystemParamsOperation.getInstance().isAutoSettlement()) {
SettlementScheduler.schedule(this)
return
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val alarmManager = getSystemService(AlarmManager::class.java)
if (!alarmManager.canScheduleExactAlarms()) {
if (!exactAlarmSettingsOpened) {
exactAlarmSettingsOpened = true
startActivity(
Intent(
Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM,
Uri.parse("package:$packageName")
)
)
}
return
}
}
exactAlarmSettingsOpened = false
SettlementScheduler.schedule(this)
}
private companion object {
const val NOTIFICATION_PERMISSION_REQUEST_CODE = 1003
}
private fun hideSystemBars() {
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
windowInsetsController.hide(WindowInsetsCompat.Type.navigationBars())

View File

@ -4,22 +4,32 @@ import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import androidx.core.content.ContextCompat
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
import dagger.hilt.android.AndroidEntryPoint
import sunmi.sunmiui.utils.LogUtil
@AndroidEntryPoint
class AlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
val serviceIntent = Intent(context, AutoSettleService::class.java)
val appContext = context ?: return
// Exact alarms are one-shot, so keep the next daily alarm alive before
// starting the foreground service.
if (!SettlementScheduler.schedule(appContext)) {
LogUtil.e(AlarmReceiver::class.java.simpleName, "Unable to reschedule settlement alarm")
}
val systemParams = SystemParamsOperation.getInstance()
if (!systemParams.isAutoSettlement() || !systemParams.settlementStatus) {
LogUtil.d(AlarmReceiver::class.java.simpleName, "Auto settlement is disabled")
return
}
val serviceIntent = Intent(appContext, AutoSettleService::class.java)
LogUtil.d(AlarmReceiver::class.java.simpleName, "Alert service")
if (context != null) {
ContextCompat.startForegroundService(
context,
serviceIntent
)
}
ContextCompat.startForegroundService(appContext, serviceIntent)
LogUtil.d(AlarmReceiver::class.java.simpleName, "Foreground service")
}

View File

@ -3,13 +3,16 @@ package com.mob.utsmyanmar.auto_settlement
import android.annotation.SuppressLint
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.app.Service
import android.content.Intent
import android.media.AudioAttributes
import android.media.Ringtone
import android.media.RingtoneManager
import android.os.Build
import android.os.Handler
import android.os.IBinder
import androidx.annotation.RequiresApi
import android.os.Looper
import androidx.core.app.NotificationCompat
import com.mob.utsmyanmar.MainActivity
import com.mob.utsmyanmar.R
@ -21,8 +24,24 @@ import sunmi.sunmiui.utils.LogUtil
class AutoSettleService : Service() {
companion object {
const val CHANNEL_ID = "auto_settlement_channel"
const val NOTIFICATION_ID = 1001
private const val FOREGROUND_CHANNEL_ID = "auto_settlement_foreground_channel"
private const val ALERT_CHANNEL_ID = "auto_settlement_alert_channel"
private const val NOTIFICATION_ID = 1001
private const val ALERT_NOTIFICATION_ID = 1002
private const val ALERT_SOUND_DURATION_MS = 3_000L
}
private val mainHandler = Handler(Looper.getMainLooper())
private var alertRingtone: Ringtone? = null
private val stopServiceRunnable = Runnable {
alertRingtone?.stop()
alertRingtone = null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
stopForeground(STOP_FOREGROUND_REMOVE)
} else {
stopForeground(true)
}
stopSelf()
}
override fun onCreate() {
@ -31,60 +50,130 @@ class AutoSettleService : Service() {
startForegroundNotification()
}
@RequiresApi(Build.VERSION_CODES.N)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (!SystemParamsOperation.getInstance().settlementStatus) {
val systemParams = SystemParamsOperation.getInstance()
if (!systemParams.isAutoSettlement() || !systemParams.settlementStatus) {
stopSelf()
return START_NOT_STICKY
}
showSettlementAlert()
playAlertSound()
launchSettlement()
stopForeground(STOP_FOREGROUND_REMOVE)
stopSelf()
mainHandler.removeCallbacks(stopServiceRunnable)
mainHandler.postDelayed(stopServiceRunnable, ALERT_SOUND_DURATION_MS)
return START_NOT_STICKY
}
override fun onBind(intent: Intent?): IBinder? = null
override fun onDestroy() {
mainHandler.removeCallbacks(stopServiceRunnable)
alertRingtone?.stop()
alertRingtone = null
super.onDestroy()
}
@SuppressLint("ForegroundServiceType")
private fun startForegroundNotification() {
LogUtil.d(AutoSettleService::class.java.simpleName, "foreground noti called")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
FOREGROUND_CHANNEL_ID,
"AUTO SETTLEMENT",
NotificationManager.IMPORTANCE_HIGH
)
channel.description = "Auto Settlement notification"
channel.enableVibration(true)
channel.setSound(
RingtoneManager.getDefaultUri(
RingtoneManager.TYPE_NOTIFICATION
), AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()
NotificationManager.IMPORTANCE_LOW
)
channel.description = "Auto Settlement service status"
val manager = getSystemService(NotificationManager::class.java)
manager?.createNotificationChannel(channel)
}
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
val notification = NotificationCompat.Builder(this, FOREGROUND_CHANNEL_ID)
.setSmallIcon(R.drawable.logo_mob)
.setContentTitle("Auto Settlement")
.setContentText("Processing...")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setContentText("Preparing settlement reminder...")
.setPriority(NotificationCompat.PRIORITY_LOW)
.setOngoing(true)
.build()
startForeground(NOTIFICATION_ID, notification)
}
private fun showSettlementAlert() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
ALERT_CHANNEL_ID,
"AUTO SETTLEMENT ALERT",
NotificationManager.IMPORTANCE_HIGH
).apply {
description = "Daily settlement reminder"
enableVibration(true)
setSound(
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION),
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build()
)
}
getSystemService(NotificationManager::class.java)?.createNotificationChannel(channel)
}
val pendingIntent = PendingIntent.getActivity(
this,
ALERT_NOTIFICATION_ID,
settlementIntent(),
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
val notification = NotificationCompat.Builder(this, ALERT_CHANNEL_ID)
.setSmallIcon(R.drawable.logo_mob)
.setContentTitle("Settlement Reminder")
.setContentText("Daily settlement is due. Tap to open settlement.")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_REMINDER)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setVibrate(longArrayOf(0, 250, 150, 250))
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build()
getSystemService(NotificationManager::class.java)
?.notify(ALERT_NOTIFICATION_ID, notification)
}
private fun playAlertSound() {
alertRingtone?.stop()
alertRingtone = RingtoneManager.getRingtone(
this,
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
)?.apply {
audioAttributes = AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build()
play()
}
}
private fun launchSettlement() {
val intent = Intent(this, MainActivity::class.java).apply {
runCatching {
startActivity(settlementIntent())
}.onFailure {
LogUtil.e(
AutoSettleService::class.java.simpleName,
"Unable to open settlement screen: ${it.message}"
)
}
}
private fun settlementIntent(): Intent = Intent(this, MainActivity::class.java).apply {
addFlags(
Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
Intent.FLAG_ACTIVITY_NEW_TASK or
Intent.FLAG_ACTIVITY_SINGLE_TOP or
Intent.FLAG_ACTIVITY_CLEAR_TOP
)
putExtra("AUTO_SETTLEMENT", true)
}
startActivity(intent)
}
}

View File

@ -1,26 +1,42 @@
package com.mob.utsmyanmar.auto_settlement
import android.Manifest
import android.annotation.SuppressLint
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import androidx.annotation.RequiresPermission
import android.os.Build
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
import java.util.Calendar
object SettlementScheduler {
private const val FALLBACK_ALERT_TIME = "01:10:00"
@RequiresPermission(Manifest.permission.SCHEDULE_EXACT_ALARM)
fun schedule(context: Context) {
fun schedule(context: Context): Boolean {
if (!SystemParamsOperation.getInstance().isAutoSettlement()) {
cancel(context)
return false
}
val alarmManager =
context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
!alarmManager.canScheduleExactAlarms()
) {
return false
}
val configuredTime = parseTime(
// SystemParamsOperation.getInstance().clearBatchTime
"23:05:00"
) ?: parseTime(FALLBACK_ALERT_TIME)!!
val calendar = Calendar.getInstance().apply {
// Auto settlement time
set(Calendar.HOUR_OF_DAY, 1)
set(Calendar.MINUTE, 10)
set(Calendar.SECOND, 0)
set(Calendar.HOUR_OF_DAY, configuredTime.first)
set(Calendar.MINUTE, configuredTime.second)
set(Calendar.SECOND, configuredTime.third)
set(Calendar.MILLISECOND, 0)
if (before(Calendar.getInstance())) {
add(Calendar.DAY_OF_MONTH, 1)
@ -28,11 +44,6 @@ object SettlementScheduler {
}
val alarmManager =
context.getSystemService(Context.ALARM_SERVICE)
as AlarmManager
val intent = Intent(
context,
AlarmReceiver::class.java
@ -53,6 +64,20 @@ object SettlementScheduler {
calendar.timeInMillis,
pendingIntent
)
return true
}
private fun parseTime(value: String): Triple<Int, Int, Int>? {
val parts = value.trim().split(":")
if (parts.size !in 2..3) return null
val hour = parts[0].toIntOrNull() ?: return null
val minute = parts[1].toIntOrNull() ?: return null
val second = if (parts.size == 3) parts[2].toIntOrNull() ?: return null else 0
if (hour !in 0..23 || minute !in 0..59 || second !in 0..59) return null
return Triple(hour, minute, second)
}

View File

@ -16,6 +16,7 @@ import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.navArgument
import com.mob.utsmyanmar.ui.cardwaiting.CardWaitingScreen
import com.mob.utsmyanmar.ui.cardwaiting.CardWaitingViewModel
@ -65,9 +66,31 @@ import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
@SuppressLint("ContextCastToActivity")
@Composable
fun AppNavGraph(
navController: NavHostController
navController: NavHostController,
autoSettlementRequested: Boolean = false,
onAutoSettlementHandled: () -> Unit = {}
) {
val activity = LocalContext.current as ComponentActivity
val currentBackStackEntry by navController.currentBackStackEntryAsState()
val currentRoute = currentBackStackEntry?.destination?.route
LaunchedEffect(autoSettlementRequested, currentRoute) {
if (!autoSettlementRequested ||
currentRoute == null ||
currentRoute == Routes.TmsSetup.route
) return@LaunchedEffect
if (currentRoute == Routes.Settlement.route) {
return@LaunchedEffect
}
if (currentRoute == Routes.Password.route) {
onAutoSettlementHandled()
return@LaunchedEffect
}
navController.navigate(Routes.Settlement.route) {
launchSingleTop = true
}
}
NavHost(
navController = navController,
@ -78,7 +101,9 @@ fun AppNavGraph(
TmsSetupRoute(
viewModel = tmsSetupViewModel,
onNavigateDashboard = {
navController.navigate(Routes.Dashboard.route) {
navController.navigate(
if (autoSettlementRequested) Routes.Settlement.route else Routes.Dashboard.route
) {
popUpTo(Routes.TmsSetup.route) {
inclusive = true
}
@ -412,6 +437,7 @@ fun AppNavGraph(
sharedViewModel = sharedViewModel,
settlementViewMode = settlementViewMode,
onBack = { navController.popBackStack(Routes.Dashboard.route,false) },
autoStartSettlement = autoSettlementRequested,
onStartSettlement = {
sharedViewModel.transactionsType.value = TransactionsType.SETTLEMENT
navController.navigate(Routes.Processing.route) {
@ -420,6 +446,9 @@ fun AppNavGraph(
}
launchSingleTop = true
}
if (autoSettlementRequested) {
onAutoSettlementHandled()
}
}
)
}

View File

@ -38,11 +38,17 @@ fun SettlementScreen(
sharedViewModel: SharedViewModel,
settlementViewMode: SettlementViewModel,
onBack: () -> Unit,
onStartSettlement: () -> Unit
onStartSettlement: () -> Unit,
autoStartSettlement: Boolean = false
) {
val records by settlementViewMode.getSettlementPOS().observeAsState(emptyList())
val totalAmount = records.sumOf { it.amount }
LaunchedEffect(autoStartSettlement, records) {
if (autoStartSettlement && records.isNotEmpty()) {
onStartSettlement()
}
}
Scaffold(
containerColor = Color.IvoryBeige,

View File

@ -5,4 +5,5 @@ sealed interface TransactionResultEvent {
data object BackClick: TransactionResultEvent
data object RetryPrint: TransactionResultEvent
data object PrintLater: TransactionResultEvent
data object Continue: TransactionResultEvent
}

View File

@ -51,6 +51,9 @@ fun TransactionResultRoute(
canGoBack = canGoBack,
onEvent = {
viewModel.onEvent(it, sharedViewModel)
},
onContinue = {
viewModel.onEvent(TransactionResultEvent.Continue, sharedViewModel)
}
)
}

View File

@ -36,6 +36,7 @@ fun TransactionResultScreen(
state: TransactionResultState,
canGoBack: Boolean,
onEvent: (TransactionResultEvent) -> Unit,
onContinue: () -> Unit,
) {
BackHandler(enabled = canGoBack) {
onEvent(TransactionResultEvent.BackClick)
@ -70,11 +71,8 @@ fun TransactionResultScreen(
Spacer(modifier = Modifier.height(6.dp))
Text(
text = state.message.ifBlank { "Your payment has been processed successfully." },
color = Color.Gray,
style = MaterialTheme.typography.bodyMedium,
textAlign = TextAlign.Center
ReasonCard(
reason = state.message.ifBlank { "Your payment has been processed successfully." }
)
Spacer(modifier = Modifier.height(28.dp))
@ -89,6 +87,50 @@ fun TransactionResultScreen(
transactionId = state.payDetail?.referNo.toString()
)
Spacer(modifier = Modifier.height(24.dp))
Button(
onClick = onContinue,
modifier = Modifier
.fillMaxWidth()
.height(56.dp),
colors = ButtonDefaults.buttonColors(
containerColor = Color.LegacyRed,
contentColor = Color.White
)
) {
Text("Continue")
}
}
}
}
@Composable
private fun ReasonCard(reason: String) {
Card(
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(containerColor = Color.White)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 18.dp, vertical = 14.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "Reason",
color = Color.Gray,
style = MaterialTheme.typography.labelLarge
)
Spacer(modifier = Modifier.height(6.dp))
Text(
text = reason,
color = Color.Black,
style = MaterialTheme.typography.titleMedium,
textAlign = TextAlign.Center
)
}
}
}
@ -323,5 +365,6 @@ fun PreviewTransactionResultScreen() {
),
canGoBack = true,
onEvent = {},
onContinue = {},
)
}

View File

@ -14,6 +14,7 @@ import com.utsmyanmar.paylibs.model.PayDetail
import com.utsmyanmar.paylibs.print.PaperRollStatusCallback
import com.utsmyanmar.paylibs.print.PrintHelper
import com.utsmyanmar.paylibs.utils.PrintStatus
import com.utsmyanmar.paylibs.utils.POSUtil
import com.utsmyanmar.paylibs.utils.core_utils.ByteUtil
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
@ -24,6 +25,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.receiveAsFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.Job
import sunmi.sunmiui.utils.LogUtil
import javax.inject.Inject
@ -44,6 +46,7 @@ class TransactionResultViewModel @Inject constructor(
val uiEvent = _uiEvent.receiveAsFlow()
private var started = false
private var resultTimeoutJob: Job? = null
fun onEvent(
event: TransactionResultEvent,
@ -52,11 +55,16 @@ class TransactionResultViewModel @Inject constructor(
when (event) {
TransactionResultEvent.Start -> {
started = false
resultTimeoutJob?.cancel()
start(sharedViewModel)
}
TransactionResultEvent.BackClick -> isCardInside()
TransactionResultEvent.RetryPrint -> startPrintProcess(sharedViewModel, false)
TransactionResultEvent.PrintLater -> isCardInside()
TransactionResultEvent.Continue -> {
resultTimeoutJob?.cancel()
navigateMain()
}
}
}
@ -99,7 +107,7 @@ class TransactionResultViewModel @Inject constructor(
val message = when {
isSuccess -> "Transaction approved"
payDetail?.tradeAnswerCode?.isNotBlank() == true -> payDetail.tradeAnswerCode
payDetail != null -> failureReason(payDetail)
else -> "Transaction failed"
}
@ -109,8 +117,20 @@ class TransactionResultViewModel @Inject constructor(
)
}
private fun failureReason(payDetail: PayDetail): String {
val responseCode = payDetail.tradeAnswerCode.orEmpty().trim()
val resultDescription = payDetail.tradeResultDes.orEmpty().trim()
if (resultDescription.isNotBlank() && !resultDescription.equals(responseCode, ignoreCase = true)) {
return resultDescription
}
if (responseCode.isBlank()) return "Transaction failed"
return POSUtil.getInstance().getResponse(responseCode)
}
private fun startResultTimeout(sharedViewModel: SharedViewModel) {
viewModelScope.launch {
resultTimeoutJob = viewModelScope.launch {
delay(RESULT_TIMEOUT)
val payDetail = sharedViewModel.payDetail.value
@ -128,7 +148,6 @@ class TransactionResultViewModel @Inject constructor(
if (SystemParamsOperation.getInstance().isPrintErrorSlip) {
startPrintProcess(sharedViewModel, false)
}
isCardInside()
}
transactionType == TransactionsType.SETTLEMENT -> {
@ -138,12 +157,10 @@ class TransactionResultViewModel @Inject constructor(
"Configs are updated"
)
)
navigateMain()
}
isWavePayNonSuccessTransaction(transactionType, payDetail) -> {
startPrintProcess(sharedViewModel, false)
navigateMain()
}
else -> {

View File

@ -3,6 +3,7 @@ package com.mob.utsmyanmar.utils.tms
import com.google.gson.Gson
import com.mob.utsmyanmar.model.sirius.SiriusResponse
import com.mob.utsmyanmar.model.sirius.TMSUpdate
import com.mob.utsmyanmar.auto_settlement.SettlementScheduler
import com.utsmyanmar.baselib.BaseApplication
import com.utsmyanmar.baselib.emv.EmvParamOperation
import com.utsmyanmar.baselib.network.model.sirius.SiriusHost
@ -159,6 +160,7 @@ class TMSSetupsImpl : TMSSetups {
"cash_advance_enable" -> ops.cashAdvanceStatus = parseBoolean(data)
"refund_enable" -> ops.refundStatus = parseBoolean(data)
"settlement_enable" -> ops.settlementStatus = parseBoolean(data)
"auto_settlement" -> ops.setAutoSettlement(parseBoolean(data))
"system_password" -> ops.systemPassword = data.take(6).ifEmpty { data }
"settlement_password" -> ops.settlementPassword = data.take(6).ifEmpty { data }
"setting_password" -> ops.settingPassword = data.take(6).ifEmpty { data }
@ -226,6 +228,7 @@ class TMSSetupsImpl : TMSSetups {
}
}
ops.carouselUrls = imgUrls.joinToString(",")
SettlementScheduler.schedule(BaseApplication.getInstance().applicationContext)
}
override fun initParams(json: String) {

View File

@ -409,6 +409,17 @@ public class SystemParamsOperation {
return params.getSettlementStatus();
}
public boolean isAutoSettlement() {
SystemParamsSettings params = getSystemParamsSettings();
return params.isAutoSettlement();
}
public void setAutoSettlement(boolean enabled) {
SystemParamsSettings params = getSystemParamsSettings();
params.setAutoSettlement(enabled);
saveSystemParamsSettings(params);
}
public String getCarouselUrls() {
SystemParamsSettings params = getSystemParamsSettings();
return params.getCarouselUrls();

View File

@ -220,6 +220,8 @@ public class SystemParamsSettings implements Serializable {
private boolean settlementStatus = true;
private boolean autoSettlement = false;
private boolean isNeedSettlement = false;
private boolean manualEntryStatus = true;
@ -566,6 +568,8 @@ public class SystemParamsSettings implements Serializable {
protected boolean getSettlementStatus() { return settlementStatus; }
protected void setSettlementStatus(boolean status) { this.settlementStatus = status; }
protected boolean isAutoSettlement() { return autoSettlement; }
protected void setAutoSettlement(boolean enabled) { this.autoSettlement = enabled; }
protected void setUserRole(int role){ this.user_role = role;}
protected int getUserRole(){ return user_role;}