auto settlement
This commit is contained in:
parent
5bb07df9e3
commit
d011b46345
@ -1,6 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
<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" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|||||||
@ -19,7 +19,10 @@
|
|||||||
<uses-permission android:name="com.sunmi.perm.SECURITY" />
|
<uses-permission android:name="com.sunmi.perm.SECURITY" />
|
||||||
<uses-permission android:name="com.sunmi.perm.CONTACTLESS_CARD" />
|
<uses-permission android:name="com.sunmi.perm.CONTACTLESS_CARD" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<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" />
|
||||||
|
<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" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
|
||||||
|
|||||||
@ -1,41 +1,108 @@
|
|||||||
package com.mob.utsmyanmar
|
package com.mob.utsmyanmar
|
||||||
|
|
||||||
import android.Manifest
|
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.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.provider.Settings
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
import androidx.activity.compose.setContent
|
import androidx.activity.compose.setContent
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
import androidx.annotation.RequiresApi
|
|
||||||
import androidx.annotation.RequiresPermission
|
|
||||||
import androidx.core.view.WindowCompat
|
import androidx.core.view.WindowCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.WindowInsetsControllerCompat
|
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 androidx.navigation.compose.rememberNavController
|
||||||
import com.mob.utsmyanmar.auto_settlement.SettlementScheduler
|
import com.mob.utsmyanmar.auto_settlement.SettlementScheduler
|
||||||
import com.mob.utsmyanmar.ui.navigation.AppNavGraph
|
import com.mob.utsmyanmar.ui.navigation.AppNavGraph
|
||||||
import com.mob.utsmyanmar.ui.theme.MOBPOSTheme
|
import com.mob.utsmyanmar.ui.theme.MOBPOSTheme
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MainActivity : ComponentActivity() {
|
class MainActivity : ComponentActivity() {
|
||||||
@RequiresPermission(Manifest.permission.SCHEDULE_EXACT_ALARM)
|
private var autoSettlementRequested by mutableStateOf(false)
|
||||||
@RequiresApi(Build.VERSION_CODES.N)
|
private var exactAlarmSettingsOpened = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
SettlementScheduler.schedule(this)
|
|
||||||
// installSplashScreen()
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
autoSettlementRequested = intent?.getBooleanExtra("AUTO_SETTLEMENT", false) == true
|
||||||
|
requestNotificationPermission()
|
||||||
|
scheduleSettlementAlarm()
|
||||||
enableEdgeToEdge()
|
enableEdgeToEdge()
|
||||||
hideSystemBars()
|
hideSystemBars()
|
||||||
// window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
// window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
|
||||||
setContent {
|
setContent {
|
||||||
MOBPOSTheme {
|
MOBPOSTheme {
|
||||||
val navController = rememberNavController()
|
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() {
|
private fun hideSystemBars() {
|
||||||
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
|
val windowInsetsController = WindowCompat.getInsetsController(window, window.decorView)
|
||||||
windowInsetsController.hide(WindowInsetsCompat.Type.navigationBars())
|
windowInsetsController.hide(WindowInsetsCompat.Type.navigationBars())
|
||||||
|
|||||||
@ -4,22 +4,32 @@ import android.content.BroadcastReceiver
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import sunmi.sunmiui.utils.LogUtil
|
import sunmi.sunmiui.utils.LogUtil
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class AlarmReceiver : BroadcastReceiver() {
|
class AlarmReceiver : BroadcastReceiver() {
|
||||||
override fun onReceive(context: Context?, intent: Intent?) {
|
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")
|
LogUtil.d(AlarmReceiver::class.java.simpleName, "Alert service")
|
||||||
|
|
||||||
if (context != null) {
|
ContextCompat.startForegroundService(appContext, serviceIntent)
|
||||||
ContextCompat.startForegroundService(
|
|
||||||
context,
|
|
||||||
serviceIntent
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
LogUtil.d(AlarmReceiver::class.java.simpleName, "Foreground service")
|
LogUtil.d(AlarmReceiver::class.java.simpleName, "Foreground service")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,13 +3,16 @@ package com.mob.utsmyanmar.auto_settlement
|
|||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.NotificationChannel
|
import android.app.NotificationChannel
|
||||||
import android.app.NotificationManager
|
import android.app.NotificationManager
|
||||||
|
import android.app.PendingIntent
|
||||||
import android.app.Service
|
import android.app.Service
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.media.AudioAttributes
|
import android.media.AudioAttributes
|
||||||
|
import android.media.Ringtone
|
||||||
import android.media.RingtoneManager
|
import android.media.RingtoneManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.os.Handler
|
||||||
import android.os.IBinder
|
import android.os.IBinder
|
||||||
import androidx.annotation.RequiresApi
|
import android.os.Looper
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import com.mob.utsmyanmar.MainActivity
|
import com.mob.utsmyanmar.MainActivity
|
||||||
import com.mob.utsmyanmar.R
|
import com.mob.utsmyanmar.R
|
||||||
@ -21,8 +24,24 @@ import sunmi.sunmiui.utils.LogUtil
|
|||||||
class AutoSettleService : Service() {
|
class AutoSettleService : Service() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val CHANNEL_ID = "auto_settlement_channel"
|
private const val FOREGROUND_CHANNEL_ID = "auto_settlement_foreground_channel"
|
||||||
const val NOTIFICATION_ID = 1001
|
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() {
|
override fun onCreate() {
|
||||||
@ -31,60 +50,130 @@ class AutoSettleService : Service() {
|
|||||||
startForegroundNotification()
|
startForegroundNotification()
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(Build.VERSION_CODES.N)
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||||
if (!SystemParamsOperation.getInstance().settlementStatus) {
|
val systemParams = SystemParamsOperation.getInstance()
|
||||||
|
if (!systemParams.isAutoSettlement() || !systemParams.settlementStatus) {
|
||||||
stopSelf()
|
stopSelf()
|
||||||
return START_NOT_STICKY
|
return START_NOT_STICKY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
showSettlementAlert()
|
||||||
|
playAlertSound()
|
||||||
launchSettlement()
|
launchSettlement()
|
||||||
stopForeground(STOP_FOREGROUND_REMOVE)
|
mainHandler.removeCallbacks(stopServiceRunnable)
|
||||||
stopSelf()
|
mainHandler.postDelayed(stopServiceRunnable, ALERT_SOUND_DURATION_MS)
|
||||||
|
|
||||||
return START_NOT_STICKY
|
return START_NOT_STICKY
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBind(intent: Intent?): IBinder? = null
|
override fun onBind(intent: Intent?): IBinder? = null
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
mainHandler.removeCallbacks(stopServiceRunnable)
|
||||||
|
alertRingtone?.stop()
|
||||||
|
alertRingtone = null
|
||||||
|
super.onDestroy()
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("ForegroundServiceType")
|
@SuppressLint("ForegroundServiceType")
|
||||||
private fun startForegroundNotification() {
|
private fun startForegroundNotification() {
|
||||||
LogUtil.d(AutoSettleService::class.java.simpleName, "foreground noti called")
|
LogUtil.d(AutoSettleService::class.java.simpleName, "foreground noti called")
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
val channel = NotificationChannel(
|
val channel = NotificationChannel(
|
||||||
CHANNEL_ID,
|
FOREGROUND_CHANNEL_ID,
|
||||||
"AUTO SETTLEMENT",
|
"AUTO SETTLEMENT",
|
||||||
NotificationManager.IMPORTANCE_HIGH
|
NotificationManager.IMPORTANCE_LOW
|
||||||
)
|
|
||||||
channel.description = "Auto Settlement notification"
|
|
||||||
channel.enableVibration(true)
|
|
||||||
channel.setSound(
|
|
||||||
RingtoneManager.getDefaultUri(
|
|
||||||
RingtoneManager.TYPE_NOTIFICATION
|
|
||||||
), AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_NOTIFICATION).build()
|
|
||||||
)
|
)
|
||||||
|
channel.description = "Auto Settlement service status"
|
||||||
val manager = getSystemService(NotificationManager::class.java)
|
val manager = getSystemService(NotificationManager::class.java)
|
||||||
manager?.createNotificationChannel(channel)
|
manager?.createNotificationChannel(channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
val notification = NotificationCompat.Builder(this, CHANNEL_ID)
|
val notification = NotificationCompat.Builder(this, FOREGROUND_CHANNEL_ID)
|
||||||
.setSmallIcon(R.drawable.logo_mob)
|
.setSmallIcon(R.drawable.logo_mob)
|
||||||
.setContentTitle("Auto Settlement")
|
.setContentTitle("Auto Settlement")
|
||||||
.setContentText("Processing...")
|
.setContentText("Preparing settlement reminder...")
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
.setPriority(NotificationCompat.PRIORITY_LOW)
|
||||||
|
.setOngoing(true)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
startForeground(NOTIFICATION_ID, notification)
|
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() {
|
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(
|
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)
|
putExtra("AUTO_SETTLEMENT", true)
|
||||||
}
|
}
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,26 +1,42 @@
|
|||||||
package com.mob.utsmyanmar.auto_settlement
|
package com.mob.utsmyanmar.auto_settlement
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.AlarmManager
|
import android.app.AlarmManager
|
||||||
import android.app.PendingIntent
|
import android.app.PendingIntent
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.annotation.RequiresPermission
|
import android.os.Build
|
||||||
|
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
|
|
||||||
object SettlementScheduler {
|
object SettlementScheduler {
|
||||||
|
private const val FALLBACK_ALERT_TIME = "01:10:00"
|
||||||
|
|
||||||
@RequiresPermission(Manifest.permission.SCHEDULE_EXACT_ALARM)
|
fun schedule(context: Context): Boolean {
|
||||||
fun schedule(context: Context) {
|
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 {
|
val calendar = Calendar.getInstance().apply {
|
||||||
|
set(Calendar.HOUR_OF_DAY, configuredTime.first)
|
||||||
// Auto settlement time
|
set(Calendar.MINUTE, configuredTime.second)
|
||||||
set(Calendar.HOUR_OF_DAY, 1)
|
set(Calendar.SECOND, configuredTime.third)
|
||||||
set(Calendar.MINUTE, 10)
|
set(Calendar.MILLISECOND, 0)
|
||||||
set(Calendar.SECOND, 0)
|
|
||||||
|
|
||||||
|
|
||||||
if (before(Calendar.getInstance())) {
|
if (before(Calendar.getInstance())) {
|
||||||
add(Calendar.DAY_OF_MONTH, 1)
|
add(Calendar.DAY_OF_MONTH, 1)
|
||||||
@ -28,11 +44,6 @@ object SettlementScheduler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val alarmManager =
|
|
||||||
context.getSystemService(Context.ALARM_SERVICE)
|
|
||||||
as AlarmManager
|
|
||||||
|
|
||||||
|
|
||||||
val intent = Intent(
|
val intent = Intent(
|
||||||
context,
|
context,
|
||||||
AlarmReceiver::class.java
|
AlarmReceiver::class.java
|
||||||
@ -53,6 +64,20 @@ object SettlementScheduler {
|
|||||||
calendar.timeInMillis,
|
calendar.timeInMillis,
|
||||||
pendingIntent
|
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import androidx.navigation.NavHostController
|
|||||||
import androidx.navigation.NavType
|
import androidx.navigation.NavType
|
||||||
import androidx.navigation.compose.NavHost
|
import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
|
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||||
import androidx.navigation.navArgument
|
import androidx.navigation.navArgument
|
||||||
import com.mob.utsmyanmar.ui.cardwaiting.CardWaitingScreen
|
import com.mob.utsmyanmar.ui.cardwaiting.CardWaitingScreen
|
||||||
import com.mob.utsmyanmar.ui.cardwaiting.CardWaitingViewModel
|
import com.mob.utsmyanmar.ui.cardwaiting.CardWaitingViewModel
|
||||||
@ -65,9 +66,31 @@ import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
|
|||||||
@SuppressLint("ContextCastToActivity")
|
@SuppressLint("ContextCastToActivity")
|
||||||
@Composable
|
@Composable
|
||||||
fun AppNavGraph(
|
fun AppNavGraph(
|
||||||
navController: NavHostController
|
navController: NavHostController,
|
||||||
|
autoSettlementRequested: Boolean = false,
|
||||||
|
onAutoSettlementHandled: () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
val activity = LocalContext.current as ComponentActivity
|
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(
|
NavHost(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
@ -78,7 +101,9 @@ fun AppNavGraph(
|
|||||||
TmsSetupRoute(
|
TmsSetupRoute(
|
||||||
viewModel = tmsSetupViewModel,
|
viewModel = tmsSetupViewModel,
|
||||||
onNavigateDashboard = {
|
onNavigateDashboard = {
|
||||||
navController.navigate(Routes.Dashboard.route) {
|
navController.navigate(
|
||||||
|
if (autoSettlementRequested) Routes.Settlement.route else Routes.Dashboard.route
|
||||||
|
) {
|
||||||
popUpTo(Routes.TmsSetup.route) {
|
popUpTo(Routes.TmsSetup.route) {
|
||||||
inclusive = true
|
inclusive = true
|
||||||
}
|
}
|
||||||
@ -412,6 +437,7 @@ fun AppNavGraph(
|
|||||||
sharedViewModel = sharedViewModel,
|
sharedViewModel = sharedViewModel,
|
||||||
settlementViewMode = settlementViewMode,
|
settlementViewMode = settlementViewMode,
|
||||||
onBack = { navController.popBackStack(Routes.Dashboard.route,false) },
|
onBack = { navController.popBackStack(Routes.Dashboard.route,false) },
|
||||||
|
autoStartSettlement = autoSettlementRequested,
|
||||||
onStartSettlement = {
|
onStartSettlement = {
|
||||||
sharedViewModel.transactionsType.value = TransactionsType.SETTLEMENT
|
sharedViewModel.transactionsType.value = TransactionsType.SETTLEMENT
|
||||||
navController.navigate(Routes.Processing.route) {
|
navController.navigate(Routes.Processing.route) {
|
||||||
@ -420,6 +446,9 @@ fun AppNavGraph(
|
|||||||
}
|
}
|
||||||
launchSingleTop = true
|
launchSingleTop = true
|
||||||
}
|
}
|
||||||
|
if (autoSettlementRequested) {
|
||||||
|
onAutoSettlementHandled()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,11 +38,17 @@ fun SettlementScreen(
|
|||||||
sharedViewModel: SharedViewModel,
|
sharedViewModel: SharedViewModel,
|
||||||
settlementViewMode: SettlementViewModel,
|
settlementViewMode: SettlementViewModel,
|
||||||
onBack: () -> Unit,
|
onBack: () -> Unit,
|
||||||
onStartSettlement: () -> Unit
|
onStartSettlement: () -> Unit,
|
||||||
|
autoStartSettlement: Boolean = false
|
||||||
) {
|
) {
|
||||||
val records by settlementViewMode.getSettlementPOS().observeAsState(emptyList())
|
val records by settlementViewMode.getSettlementPOS().observeAsState(emptyList())
|
||||||
val totalAmount = records.sumOf { it.amount }
|
val totalAmount = records.sumOf { it.amount }
|
||||||
|
|
||||||
|
LaunchedEffect(autoStartSettlement, records) {
|
||||||
|
if (autoStartSettlement && records.isNotEmpty()) {
|
||||||
|
onStartSettlement()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Scaffold(
|
Scaffold(
|
||||||
containerColor = Color.IvoryBeige,
|
containerColor = Color.IvoryBeige,
|
||||||
|
|||||||
@ -5,4 +5,5 @@ sealed interface TransactionResultEvent {
|
|||||||
data object BackClick: TransactionResultEvent
|
data object BackClick: TransactionResultEvent
|
||||||
data object RetryPrint: TransactionResultEvent
|
data object RetryPrint: TransactionResultEvent
|
||||||
data object PrintLater: TransactionResultEvent
|
data object PrintLater: TransactionResultEvent
|
||||||
|
data object Continue: TransactionResultEvent
|
||||||
}
|
}
|
||||||
@ -51,6 +51,9 @@ fun TransactionResultRoute(
|
|||||||
canGoBack = canGoBack,
|
canGoBack = canGoBack,
|
||||||
onEvent = {
|
onEvent = {
|
||||||
viewModel.onEvent(it, sharedViewModel)
|
viewModel.onEvent(it, sharedViewModel)
|
||||||
|
},
|
||||||
|
onContinue = {
|
||||||
|
viewModel.onEvent(TransactionResultEvent.Continue, sharedViewModel)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,6 +36,7 @@ fun TransactionResultScreen(
|
|||||||
state: TransactionResultState,
|
state: TransactionResultState,
|
||||||
canGoBack: Boolean,
|
canGoBack: Boolean,
|
||||||
onEvent: (TransactionResultEvent) -> Unit,
|
onEvent: (TransactionResultEvent) -> Unit,
|
||||||
|
onContinue: () -> Unit,
|
||||||
) {
|
) {
|
||||||
BackHandler(enabled = canGoBack) {
|
BackHandler(enabled = canGoBack) {
|
||||||
onEvent(TransactionResultEvent.BackClick)
|
onEvent(TransactionResultEvent.BackClick)
|
||||||
@ -70,11 +71,8 @@ fun TransactionResultScreen(
|
|||||||
|
|
||||||
Spacer(modifier = Modifier.height(6.dp))
|
Spacer(modifier = Modifier.height(6.dp))
|
||||||
|
|
||||||
Text(
|
ReasonCard(
|
||||||
text = state.message.ifBlank { "Your payment has been processed successfully." },
|
reason = state.message.ifBlank { "Your payment has been processed successfully." }
|
||||||
color = Color.Gray,
|
|
||||||
style = MaterialTheme.typography.bodyMedium,
|
|
||||||
textAlign = TextAlign.Center
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Spacer(modifier = Modifier.height(28.dp))
|
Spacer(modifier = Modifier.height(28.dp))
|
||||||
@ -89,6 +87,50 @@ fun TransactionResultScreen(
|
|||||||
transactionId = state.payDetail?.referNo.toString()
|
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,
|
canGoBack = true,
|
||||||
onEvent = {},
|
onEvent = {},
|
||||||
|
onContinue = {},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import com.utsmyanmar.paylibs.model.PayDetail
|
|||||||
import com.utsmyanmar.paylibs.print.PaperRollStatusCallback
|
import com.utsmyanmar.paylibs.print.PaperRollStatusCallback
|
||||||
import com.utsmyanmar.paylibs.print.PrintHelper
|
import com.utsmyanmar.paylibs.print.PrintHelper
|
||||||
import com.utsmyanmar.paylibs.utils.PrintStatus
|
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.ByteUtil
|
||||||
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
|
||||||
@ -24,6 +25,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.receiveAsFlow
|
import kotlinx.coroutines.flow.receiveAsFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
import sunmi.sunmiui.utils.LogUtil
|
import sunmi.sunmiui.utils.LogUtil
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@ -44,6 +46,7 @@ class TransactionResultViewModel @Inject constructor(
|
|||||||
val uiEvent = _uiEvent.receiveAsFlow()
|
val uiEvent = _uiEvent.receiveAsFlow()
|
||||||
|
|
||||||
private var started = false
|
private var started = false
|
||||||
|
private var resultTimeoutJob: Job? = null
|
||||||
|
|
||||||
fun onEvent(
|
fun onEvent(
|
||||||
event: TransactionResultEvent,
|
event: TransactionResultEvent,
|
||||||
@ -52,11 +55,16 @@ class TransactionResultViewModel @Inject constructor(
|
|||||||
when (event) {
|
when (event) {
|
||||||
TransactionResultEvent.Start -> {
|
TransactionResultEvent.Start -> {
|
||||||
started = false
|
started = false
|
||||||
|
resultTimeoutJob?.cancel()
|
||||||
start(sharedViewModel)
|
start(sharedViewModel)
|
||||||
}
|
}
|
||||||
TransactionResultEvent.BackClick -> isCardInside()
|
TransactionResultEvent.BackClick -> isCardInside()
|
||||||
TransactionResultEvent.RetryPrint -> startPrintProcess(sharedViewModel, false)
|
TransactionResultEvent.RetryPrint -> startPrintProcess(sharedViewModel, false)
|
||||||
TransactionResultEvent.PrintLater -> isCardInside()
|
TransactionResultEvent.PrintLater -> isCardInside()
|
||||||
|
TransactionResultEvent.Continue -> {
|
||||||
|
resultTimeoutJob?.cancel()
|
||||||
|
navigateMain()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +107,7 @@ class TransactionResultViewModel @Inject constructor(
|
|||||||
|
|
||||||
val message = when {
|
val message = when {
|
||||||
isSuccess -> "Transaction approved"
|
isSuccess -> "Transaction approved"
|
||||||
payDetail?.tradeAnswerCode?.isNotBlank() == true -> payDetail.tradeAnswerCode
|
payDetail != null -> failureReason(payDetail)
|
||||||
else -> "Transaction failed"
|
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) {
|
private fun startResultTimeout(sharedViewModel: SharedViewModel) {
|
||||||
viewModelScope.launch {
|
resultTimeoutJob = viewModelScope.launch {
|
||||||
delay(RESULT_TIMEOUT)
|
delay(RESULT_TIMEOUT)
|
||||||
|
|
||||||
val payDetail = sharedViewModel.payDetail.value
|
val payDetail = sharedViewModel.payDetail.value
|
||||||
@ -128,7 +148,6 @@ class TransactionResultViewModel @Inject constructor(
|
|||||||
if (SystemParamsOperation.getInstance().isPrintErrorSlip) {
|
if (SystemParamsOperation.getInstance().isPrintErrorSlip) {
|
||||||
startPrintProcess(sharedViewModel, false)
|
startPrintProcess(sharedViewModel, false)
|
||||||
}
|
}
|
||||||
isCardInside()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
transactionType == TransactionsType.SETTLEMENT -> {
|
transactionType == TransactionsType.SETTLEMENT -> {
|
||||||
@ -138,12 +157,10 @@ class TransactionResultViewModel @Inject constructor(
|
|||||||
"Configs are updated"
|
"Configs are updated"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
navigateMain()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isWavePayNonSuccessTransaction(transactionType, payDetail) -> {
|
isWavePayNonSuccessTransaction(transactionType, payDetail) -> {
|
||||||
startPrintProcess(sharedViewModel, false)
|
startPrintProcess(sharedViewModel, false)
|
||||||
navigateMain()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package com.mob.utsmyanmar.utils.tms
|
|||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
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.auto_settlement.SettlementScheduler
|
||||||
import com.utsmyanmar.baselib.BaseApplication
|
import com.utsmyanmar.baselib.BaseApplication
|
||||||
import com.utsmyanmar.baselib.emv.EmvParamOperation
|
import com.utsmyanmar.baselib.emv.EmvParamOperation
|
||||||
import com.utsmyanmar.baselib.network.model.sirius.SiriusHost
|
import com.utsmyanmar.baselib.network.model.sirius.SiriusHost
|
||||||
@ -159,6 +160,7 @@ class TMSSetupsImpl : TMSSetups {
|
|||||||
"cash_advance_enable" -> ops.cashAdvanceStatus = parseBoolean(data)
|
"cash_advance_enable" -> ops.cashAdvanceStatus = parseBoolean(data)
|
||||||
"refund_enable" -> ops.refundStatus = parseBoolean(data)
|
"refund_enable" -> ops.refundStatus = parseBoolean(data)
|
||||||
"settlement_enable" -> ops.settlementStatus = parseBoolean(data)
|
"settlement_enable" -> ops.settlementStatus = parseBoolean(data)
|
||||||
|
"auto_settlement" -> ops.setAutoSettlement(parseBoolean(data))
|
||||||
"system_password" -> ops.systemPassword = data.take(6).ifEmpty { data }
|
"system_password" -> ops.systemPassword = data.take(6).ifEmpty { data }
|
||||||
"settlement_password" -> ops.settlementPassword = data.take(6).ifEmpty { data }
|
"settlement_password" -> ops.settlementPassword = data.take(6).ifEmpty { data }
|
||||||
"setting_password" -> ops.settingPassword = 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(",")
|
ops.carouselUrls = imgUrls.joinToString(",")
|
||||||
|
SettlementScheduler.schedule(BaseApplication.getInstance().applicationContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun initParams(json: String) {
|
override fun initParams(json: String) {
|
||||||
|
|||||||
@ -409,6 +409,17 @@ public class SystemParamsOperation {
|
|||||||
return params.getSettlementStatus();
|
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() {
|
public String getCarouselUrls() {
|
||||||
SystemParamsSettings params = getSystemParamsSettings();
|
SystemParamsSettings params = getSystemParamsSettings();
|
||||||
return params.getCarouselUrls();
|
return params.getCarouselUrls();
|
||||||
|
|||||||
@ -220,6 +220,8 @@ public class SystemParamsSettings implements Serializable {
|
|||||||
|
|
||||||
private boolean settlementStatus = true;
|
private boolean settlementStatus = true;
|
||||||
|
|
||||||
|
private boolean autoSettlement = false;
|
||||||
|
|
||||||
private boolean isNeedSettlement = false;
|
private boolean isNeedSettlement = false;
|
||||||
|
|
||||||
private boolean manualEntryStatus = true;
|
private boolean manualEntryStatus = true;
|
||||||
@ -566,6 +568,8 @@ public class SystemParamsSettings implements Serializable {
|
|||||||
protected boolean getSettlementStatus() { return settlementStatus; }
|
protected boolean getSettlementStatus() { return settlementStatus; }
|
||||||
|
|
||||||
protected void setSettlementStatus(boolean status) { this.settlementStatus = status; }
|
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 void setUserRole(int role){ this.user_role = role;}
|
||||||
|
|
||||||
protected int getUserRole(){ return user_role;}
|
protected int getUserRole(){ return user_role;}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user