Compare commits

..

No commits in common. "43c903c9eeb461d70933f0d63a750dbdfc79491d" and "2323562270f92700e95df3dd152d1d3531ad3c53" have entirely different histories.

12 changed files with 46 additions and 153 deletions

View File

@ -40,8 +40,8 @@ android {
dimension = "env" dimension = "env"
applicationIdSuffix = ".uat" applicationIdSuffix = ".uat"
versionNameSuffix = "-UAT" versionNameSuffix = "-UAT"
versionCode = 19 versionCode = 17
versionName = "3.7" versionName = "3.5"
buildConfigField("String", "ENV", "\"UAT\"") buildConfigField("String", "ENV", "\"UAT\"")
resValue("string", "app_name", "MOB-UAT") resValue("string", "app_name", "MOB-UAT")
} }

View File

@ -19,18 +19,3 @@
* show reversal status in trans records * show reversal status in trans records
* error_slip_print enable/disable in tms * error_slip_print enable/disable in tms
* auto_settlement enable/disable in tms * auto_settlement enable/disable in tms
### version 3.5
* "always with you" in mob receipt logo
* "..." full width in both P2 and P3 preview screens
* JCB logo added in Card Capture Screen
* "-" in void, refund and cash adv amounts
* disable sale button if amount is 0 or 0.00
* changed date formats to dd/mm/yy to dd/mm/yyyy
* changed keyboard design in reprint any transactions
### version 3.6
* qr for user manual
### version 3.7
* auto-settlement for both P2 and P3

View File

@ -23,7 +23,6 @@
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
@ -44,11 +43,6 @@
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.MOBPOS"> android:theme="@style/Theme.MOBPOS">
<receiver android:name=".auto_settlement.AlarmReceiver" android:exported="false"/> <receiver android:name=".auto_settlement.AlarmReceiver" android:exported="false"/>
<receiver android:name=".auto_settlement.BootReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service android:name=".auto_settlement.AutoSettleService" android:exported="false" android:foregroundServiceType="dataSync" /> <service android:name=".auto_settlement.AutoSettleService" android:exported="false" android:foregroundServiceType="dataSync" />
<activity <activity
android:name="com.mob.utsmyanmar.MainActivity" android:name="com.mob.utsmyanmar.MainActivity"

View File

@ -75,7 +75,7 @@ class MainActivity : ComponentActivity() {
private fun scheduleSettlementAlarm() { private fun scheduleSettlementAlarm() {
if (!SystemParamsOperation.getInstance().isAutoSettlement()) { if (!SystemParamsOperation.getInstance().isAutoSettlement()) {
SettlementScheduler.cancel(this) SettlementScheduler.schedule(this)
return return
} }
@ -91,7 +91,6 @@ class MainActivity : ComponentActivity() {
) )
) )
} }
SettlementScheduler.scheduleFallback(this)
return return
} }
} }

View File

@ -1,16 +0,0 @@
package com.mob.utsmyanmar.auto_settlement
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import sunmi.sunmiui.utils.LogUtil
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action != Intent.ACTION_BOOT_COMPLETED) return
val appContext = context ?: return
LogUtil.d(BootReceiver::class.java.simpleName, "Boot completed, rescheduling settlement alarm")
SettlementScheduler.schedule(appContext)
}
}

View File

@ -11,7 +11,6 @@ import java.util.Calendar
object SettlementScheduler { object SettlementScheduler {
private const val FALLBACK_ALERT_TIME = "23:30:00" private const val FALLBACK_ALERT_TIME = "23:30:00"
private const val REQUEST_CODE = 100
fun schedule(context: Context): Boolean { fun schedule(context: Context): Boolean {
if (!SystemParamsOperation.getInstance().isAutoSettlement()) { if (!SystemParamsOperation.getInstance().isAutoSettlement()) {
@ -25,49 +24,15 @@ object SettlementScheduler {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
!alarmManager.canScheduleExactAlarms() !alarmManager.canScheduleExactAlarms()
) { ) {
return scheduleFallback(context)
}
val calendar = nextAlarmCalendar() ?: return false
val pendingIntent = alarmPendingIntent(context)
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
pendingIntent
)
return true
}
fun scheduleFallback(context: Context): Boolean {
if (!SystemParamsOperation.getInstance().isAutoSettlement()) {
cancel(context)
return false return false
} }
val alarmManager =
context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val calendar = nextAlarmCalendar() ?: return false
val pendingIntent = alarmPendingIntent(context)
alarmManager.setAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
pendingIntent
)
return true
}
private fun nextAlarmCalendar(): Calendar? {
val configuredTime = parseTime( val configuredTime = parseTime(
SystemParamsOperation.getInstance().clearBatchTime // SystemParamsOperation.getInstance().clearBatchTime
// "15:45:00" "21:35:00"
) ?: parseTime(FALLBACK_ALERT_TIME) ?: return null ) ?: parseTime(FALLBACK_ALERT_TIME)!!
return Calendar.getInstance().apply { val calendar = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, configuredTime.first) set(Calendar.HOUR_OF_DAY, configuredTime.first)
set(Calendar.MINUTE, configuredTime.second) set(Calendar.MINUTE, configuredTime.second)
set(Calendar.SECOND, configuredTime.third) set(Calendar.SECOND, configuredTime.third)
@ -77,18 +42,30 @@ object SettlementScheduler {
add(Calendar.DAY_OF_MONTH, 1) add(Calendar.DAY_OF_MONTH, 1)
} }
} }
}
private fun alarmPendingIntent(context: Context): PendingIntent {
val intent = Intent(context, AlarmReceiver::class.java)
return PendingIntent.getBroadcast( val intent = Intent(
context, context,
REQUEST_CODE, AlarmReceiver::class.java
)
val pendingIntent = PendingIntent.getBroadcast(
context,
100,
intent, intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_UPDATE_CURRENT or
PendingIntent.FLAG_IMMUTABLE PendingIntent.FLAG_IMMUTABLE
) )
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
pendingIntent
)
return true
} }
private fun parseTime(value: String): Triple<Int, Int, Int>? { private fun parseTime(value: String): Triple<Int, Int, Int>? {

View File

@ -3,8 +3,6 @@ package com.mob.utsmyanmar.ui.dashboard
import android.os.Build import android.os.Build
import android.os.Handler import android.os.Handler
import android.os.Looper import android.os.Looper
import androidmads.library.qrgenearator.QRGContents
import androidmads.library.qrgenearator.QRGEncoder
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
@ -48,7 +46,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
@ -267,7 +264,7 @@ fun DashboardScreen2(
) )
Spacer(modifier = Modifier.height(10.dp)) Spacer(modifier = Modifier.height(10.dp))
Text( Text(
text = "Released on : 06-Sep-2026", text = "Released on : 21-Jul-26",
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
color = Color.Gray, color = Color.Gray,
modifier = Modifier.padding(horizontal = 16.dp) modifier = Modifier.padding(horizontal = 16.dp)
@ -362,38 +359,6 @@ fun DashboardScreen2(
trailingIcon = {}, trailingIcon = {},
) )
Spacer(modifier = Modifier.height(16.dp))
val adUrl = "https://www.mobmyanmar.com/"
val qrBitmap = remember {
runCatching {
val encoder = QRGEncoder(adUrl, null, QRGContents.Type.TEXT, 256)
encoder.colorBlack = android.graphics.Color.BLACK
encoder.colorWhite = android.graphics.Color.WHITE
encoder.bitmap.asImageBitmap()
}.getOrNull()
}
qrBitmap?.let { bitmap ->
Column(
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 16.dp)
) {
Image(
bitmap = bitmap,
contentDescription = "Scan for User Guide",
modifier = Modifier.size(150.dp)
)
Spacer(modifier = Modifier.height(4.dp))
Text(
text = "Scan for Offers",
style = MaterialTheme.typography.labelSmall,
color = Color.Gray
)
}
}
Spacer(modifier = Modifier.height(8.dp))
Spacer(modifier = Modifier.weight(1f)) Spacer(modifier = Modifier.weight(1f))
Text( Text(
text = "v${BuildConfig.VERSION_NAME}", text = "v${BuildConfig.VERSION_NAME}",

View File

@ -436,14 +436,7 @@ fun AppNavGraph(
SettlementScreen( SettlementScreen(
sharedViewModel = sharedViewModel, sharedViewModel = sharedViewModel,
settlementViewMode = settlementViewMode, settlementViewMode = settlementViewMode,
onBack = { onBack = { navController.popBackStack(Routes.Dashboard.route,false) },
onAutoSettlementHandled()
if (!navController.popBackStack(Routes.Dashboard.route, false)) {
navController.navigate(Routes.Dashboard.route) {
launchSingleTop = true
}
}
},
autoStartSettlement = autoSettlementRequested, autoStartSettlement = autoSettlementRequested,
onStartSettlement = { onStartSettlement = {
sharedViewModel.transactionsType.value = TransactionsType.SETTLEMENT sharedViewModel.transactionsType.value = TransactionsType.SETTLEMENT

View File

@ -87,7 +87,6 @@ fun TransactionResultScreen(
transactionId = state.payDetail?.referNo.toString() transactionId = state.payDetail?.referNo.toString()
) )
if (!state.isSuccess) {
Spacer(modifier = Modifier.height(24.dp)) Spacer(modifier = Modifier.height(24.dp))
Button( Button(
@ -102,7 +101,6 @@ fun TransactionResultScreen(
) { ) {
Text("Continue") Text("Continue")
} }
}
} }
} }

View File

@ -6,6 +6,5 @@ data class TransactionResultState(
val title: String = "Transaction Result", val title: String = "Transaction Result",
val message: String = "", val message: String = "",
val isLoading: Boolean = false, val isLoading: Boolean = false,
val isSuccess: Boolean = false,
val payDetail: PayDetail? = null val payDetail: PayDetail? = null
) )

View File

@ -113,8 +113,7 @@ class TransactionResultViewModel @Inject constructor(
_state.value = _state.value.copy( _state.value = _state.value.copy(
title = title, title = title,
message = message, message = message
isSuccess = isSuccess
) )
} }

View File

@ -897,7 +897,7 @@ public abstract class BaseXPrint {
sunmiPrinterService.setAlignment(0, innerResultCallback); sunmiPrinterService.setAlignment(0, innerResultCallback);
sunmiPrinterService.printColumnsString(new String[]{"DATE :" + PrintUtils.getInstance().toFullYearDate(payDetail.getTransDate()), "TIME: " + payDetail.getTransTime()}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback); sunmiPrinterService.printColumnsString(new String[]{"DATE :" + PrintUtils.getInstance().toFullYearDate(payDetail.getTransDate()), "TIME: " + payDetail.getTransTime()}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback);
if (payDetail.getTransactionType() == TransactionsType.WAVEPAY.value && payDetail.getQrTransStatus() == 1) { if (payDetail.getTransactionType() == TransactionsType.WAVEPAY.value && payDetail.getQrTransStatus() == 1) {
sunmiPrinterService.printColumnsString(new String[]{"TRC NO:" + traceNum, "INV NO: " + invoiceNo}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback); sunmiPrinterService.printColumnsString(new String[]{"TRACE NO :" + traceNum, "INV NO: " + invoiceNo}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback);
} else if (!payDetail.getTransType().equals(SETTLEMENT) && !payDetail.getTransType().equals(SUMMARY) && payDetail.getTransactionType() != TransactionsType.WAVEPAY_REFUND.value && payDetail.getTransactionType() != TransactionsType.WAVEPAY.value) { } else if (!payDetail.getTransType().equals(SETTLEMENT) && !payDetail.getTransType().equals(SUMMARY) && payDetail.getTransactionType() != TransactionsType.WAVEPAY_REFUND.value && payDetail.getTransactionType() != TransactionsType.WAVEPAY.value) {
sunmiPrinterService.printColumnsString(new String[]{"BTH NO :" + batchNum, "INV NO: " + invoiceNo}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback); sunmiPrinterService.printColumnsString(new String[]{"BTH NO :" + batchNum, "INV NO: " + invoiceNo}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback);
} else if (payDetail.getTransType().equals(SUMMARY)) { } else if (payDetail.getTransType().equals(SUMMARY)) {