Compare commits
4 Commits
2323562270
...
43c903c9ee
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
43c903c9ee | ||
|
|
23a4ebfb64 | ||
|
|
962bfbc6c5 | ||
|
|
2093fb214a |
@ -40,8 +40,8 @@ android {
|
||||
dimension = "env"
|
||||
applicationIdSuffix = ".uat"
|
||||
versionNameSuffix = "-UAT"
|
||||
versionCode = 17
|
||||
versionName = "3.5"
|
||||
versionCode = 19
|
||||
versionName = "3.7"
|
||||
buildConfigField("String", "ENV", "\"UAT\"")
|
||||
resValue("string", "app_name", "MOB-UAT")
|
||||
}
|
||||
|
||||
@ -19,3 +19,18 @@
|
||||
* show reversal status in trans records
|
||||
* error_slip_print 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
|
||||
@ -23,6 +23,7 @@
|
||||
<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.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
@ -43,6 +44,11 @@
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.MOBPOS">
|
||||
<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" />
|
||||
<activity
|
||||
android:name="com.mob.utsmyanmar.MainActivity"
|
||||
|
||||
@ -75,7 +75,7 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
private fun scheduleSettlementAlarm() {
|
||||
if (!SystemParamsOperation.getInstance().isAutoSettlement()) {
|
||||
SettlementScheduler.schedule(this)
|
||||
SettlementScheduler.cancel(this)
|
||||
return
|
||||
}
|
||||
|
||||
@ -91,6 +91,7 @@ class MainActivity : ComponentActivity() {
|
||||
)
|
||||
)
|
||||
}
|
||||
SettlementScheduler.scheduleFallback(this)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
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)
|
||||
}
|
||||
}
|
||||
@ -11,6 +11,7 @@ import java.util.Calendar
|
||||
|
||||
object SettlementScheduler {
|
||||
private const val FALLBACK_ALERT_TIME = "23:30:00"
|
||||
private const val REQUEST_CODE = 100
|
||||
|
||||
fun schedule(context: Context): Boolean {
|
||||
if (!SystemParamsOperation.getInstance().isAutoSettlement()) {
|
||||
@ -24,15 +25,49 @@ object SettlementScheduler {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
|
||||
!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
|
||||
}
|
||||
|
||||
val configuredTime = parseTime(
|
||||
// SystemParamsOperation.getInstance().clearBatchTime
|
||||
"21:35:00"
|
||||
) ?: parseTime(FALLBACK_ALERT_TIME)!!
|
||||
val alarmManager =
|
||||
context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
|
||||
val calendar = Calendar.getInstance().apply {
|
||||
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(
|
||||
SystemParamsOperation.getInstance().clearBatchTime
|
||||
// "15:45:00"
|
||||
) ?: parseTime(FALLBACK_ALERT_TIME) ?: return null
|
||||
|
||||
return Calendar.getInstance().apply {
|
||||
set(Calendar.HOUR_OF_DAY, configuredTime.first)
|
||||
set(Calendar.MINUTE, configuredTime.second)
|
||||
set(Calendar.SECOND, configuredTime.third)
|
||||
@ -42,30 +77,18 @@ object SettlementScheduler {
|
||||
add(Calendar.DAY_OF_MONTH, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun alarmPendingIntent(context: Context): PendingIntent {
|
||||
val intent = Intent(context, AlarmReceiver::class.java)
|
||||
|
||||
val intent = Intent(
|
||||
return PendingIntent.getBroadcast(
|
||||
context,
|
||||
AlarmReceiver::class.java
|
||||
)
|
||||
|
||||
|
||||
val pendingIntent = PendingIntent.getBroadcast(
|
||||
context,
|
||||
100,
|
||||
REQUEST_CODE,
|
||||
intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT or
|
||||
PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
|
||||
|
||||
alarmManager.setExactAndAllowWhileIdle(
|
||||
AlarmManager.RTC_WAKEUP,
|
||||
calendar.timeInMillis,
|
||||
pendingIntent
|
||||
)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun parseTime(value: String): Triple<Int, Int, Int>? {
|
||||
|
||||
@ -3,6 +3,8 @@ package com.mob.utsmyanmar.ui.dashboard
|
||||
import android.os.Build
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import androidmads.library.qrgenearator.QRGContents
|
||||
import androidmads.library.qrgenearator.QRGEncoder
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
@ -46,6 +48,7 @@ import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
@ -264,7 +267,7 @@ fun DashboardScreen2(
|
||||
)
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
Text(
|
||||
text = "Released on : 21-Jul-26",
|
||||
text = "Released on : 06-Sep-2026",
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = Color.Gray,
|
||||
modifier = Modifier.padding(horizontal = 16.dp)
|
||||
@ -359,6 +362,38 @@ fun DashboardScreen2(
|
||||
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))
|
||||
Text(
|
||||
text = "v${BuildConfig.VERSION_NAME}",
|
||||
|
||||
@ -436,7 +436,14 @@ fun AppNavGraph(
|
||||
SettlementScreen(
|
||||
sharedViewModel = sharedViewModel,
|
||||
settlementViewMode = settlementViewMode,
|
||||
onBack = { navController.popBackStack(Routes.Dashboard.route,false) },
|
||||
onBack = {
|
||||
onAutoSettlementHandled()
|
||||
if (!navController.popBackStack(Routes.Dashboard.route, false)) {
|
||||
navController.navigate(Routes.Dashboard.route) {
|
||||
launchSingleTop = true
|
||||
}
|
||||
}
|
||||
},
|
||||
autoStartSettlement = autoSettlementRequested,
|
||||
onStartSettlement = {
|
||||
sharedViewModel.transactionsType.value = TransactionsType.SETTLEMENT
|
||||
|
||||
@ -87,6 +87,7 @@ fun TransactionResultScreen(
|
||||
transactionId = state.payDetail?.referNo.toString()
|
||||
)
|
||||
|
||||
if (!state.isSuccess) {
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
Button(
|
||||
@ -101,6 +102,7 @@ fun TransactionResultScreen(
|
||||
) {
|
||||
Text("Continue")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,5 +6,6 @@ data class TransactionResultState(
|
||||
val title: String = "Transaction Result",
|
||||
val message: String = "",
|
||||
val isLoading: Boolean = false,
|
||||
val isSuccess: Boolean = false,
|
||||
val payDetail: PayDetail? = null
|
||||
)
|
||||
|
||||
@ -113,7 +113,8 @@ class TransactionResultViewModel @Inject constructor(
|
||||
|
||||
_state.value = _state.value.copy(
|
||||
title = title,
|
||||
message = message
|
||||
message = message,
|
||||
isSuccess = isSuccess
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -897,7 +897,7 @@ public abstract class BaseXPrint {
|
||||
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);
|
||||
if (payDetail.getTransactionType() == TransactionsType.WAVEPAY.value && payDetail.getQrTransStatus() == 1) {
|
||||
sunmiPrinterService.printColumnsString(new String[]{"TRACE NO :" + traceNum, "INV NO: " + invoiceNo}, new int[]{2, 2}, new int[]{0, 2}, innerResultCallback);
|
||||
sunmiPrinterService.printColumnsString(new String[]{"TRC 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) {
|
||||
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)) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user