database add new column

This commit is contained in:
moon 2026-07-01 10:39:26 +06:30
parent 25153bb819
commit f7510c9bad
11 changed files with 185 additions and 65 deletions

View File

@ -55,6 +55,7 @@ import com.mob.utsmyanmar.viewmodel.EmvTransactionProcessViewModel
import com.mob.utsmyanmar.viewmodel.SharedViewModel import com.mob.utsmyanmar.viewmodel.SharedViewModel
import com.mob.utsmyanmar.viewmodel.TransProcessViewModel import com.mob.utsmyanmar.viewmodel.TransProcessViewModel
import com.utsmyanmar.paylibs.model.TradeData import com.utsmyanmar.paylibs.model.TradeData
import com.utsmyanmar.paylibs.model.enums.TransCVM
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
@RequiresApi(Build.VERSION_CODES.N) @RequiresApi(Build.VERSION_CODES.N)
@ -86,9 +87,18 @@ fun AppNavGraph(
} }
composable(Routes.Signature.route) { composable(Routes.Signature.route) {
val sharedViewModel: SharedViewModel = hiltViewModel(activity)
SignaturePad( SignaturePad(
onBack = { navController.popBackStack() }, onBack = { navController.popBackStack() },
onConfirm = { navController.popBackStack() } onConfirm = { _, bitmap ->
sharedViewModel.signBitmap = bitmap
navController.navigate(Routes.TransactionResult.route) {
popUpTo(Routes.Signature.route) {
inclusive = true
}
launchSingleTop = true
}
}
) )
} }
@ -663,6 +673,14 @@ fun AppNavGraph(
launchSingleTop = true launchSingleTop = true
} }
}, },
onNavigateSignature = {
navController.navigate(Routes.Signature.route) {
popUpTo(Routes.Processing.route) {
inclusive = true
}
launchSingleTop = true
}
},
onNavigateMain = { onNavigateMain = {
navController.navigate(Routes.Dashboard.route) { navController.navigate(Routes.Dashboard.route) {
popUpTo(Routes.Dashboard.route) { popUpTo(Routes.Dashboard.route) {

View File

@ -2,21 +2,14 @@ package com.mob.utsmyanmar.ui.sending_to_host
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.mob.utsmyanmar.model.TransResultStatus import com.mob.utsmyanmar.model.TransResultStatus
import com.mob.utsmyanmar.viewmodel.SharedViewModel
import com.mob.utsmyanmar.viewmodel.TransProcessViewModel
import kotlinx.coroutines.delay
import androidx.compose.runtime.getValue
import com.mob.utsmyanmar.ui.transaction_result.TransactionResultState
import com.mob.utsmyanmar.viewmodel.ProcessingTransaction
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import androidx.compose.runtime.collectAsState
import com.mob.utsmyanmar.model.TransactionStatus import com.mob.utsmyanmar.model.TransactionStatus
import com.mob.utsmyanmar.ui.settlement.SettlementViewModel import com.mob.utsmyanmar.ui.settlement.SettlementViewModel
import com.mob.utsmyanmar.viewmodel.SharedViewModel
import com.mob.utsmyanmar.viewmodel.TransProcessViewModel
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType
import kotlinx.coroutines.channels.Channel
private const val MOCK_HOST_DELAY_MS = 2000L private const val MOCK_HOST_DELAY_MS = 2000L
@ -26,6 +19,7 @@ fun ProcessingRoute(
transProcessViewModel: TransProcessViewModel, transProcessViewModel: TransProcessViewModel,
settlementViewModel: SettlementViewModel, settlementViewModel: SettlementViewModel,
onNavigateTransactionResult: () -> Unit, onNavigateTransactionResult: () -> Unit,
onNavigateSignature: () -> Unit,
onNavigateMain: ()-> Unit onNavigateMain: ()-> Unit
) { ) {
@ -60,8 +54,12 @@ fun ProcessingRoute(
when(transStatus) { when(transStatus) {
TransResultStatus.SUCCESS -> { TransResultStatus.SUCCESS -> {
sharedViewModel.payDetail.value = transProcessViewModel.payDetailResult.value sharedViewModel.payDetail.value = transProcessViewModel.payDetailResult.value
if (requiresSignature(sharedViewModel.payDetail.value)) {
onNavigateSignature()
} else {
onNavigateTransactionResult() onNavigateTransactionResult()
} }
}
TransResultStatus.FAIL -> { TransResultStatus.FAIL -> {
sharedViewModel.payDetail.value = transProcessViewModel.payDetailResult.value sharedViewModel.payDetail.value = transProcessViewModel.payDetailResult.value
@ -75,12 +73,6 @@ fun ProcessingRoute(
} }
} }
if(sharedViewModel.transactionsType.value == TransactionsType.SETTLEMENT) { if(sharedViewModel.transactionsType.value == TransactionsType.SETTLEMENT) {
ProcessingScreen(settlementStatus.processingState) ProcessingScreen(settlementStatus.processingState)
} else { } else {
@ -89,3 +81,8 @@ fun ProcessingRoute(
} }
private fun requiresSignature(payDetail: com.utsmyanmar.paylibs.model.PayDetail?): Boolean {
// return payDetail?.transCVM == TransCVM.SIGNATURE && payDetail.isFreeSign == false
return true;
}

View File

@ -1,5 +1,7 @@
package com.mob.utsmyanmar.ui.signature_pad package com.mob.utsmyanmar.ui.signature_pad
import android.graphics.Bitmap
import android.graphics.Paint
import androidx.compose.foundation.Canvas import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectDragGestures import androidx.compose.foundation.gestures.detectDragGestures
@ -29,32 +31,76 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Path import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import com.mob.utsmyanmar.ui.components.appbar.AppBar import com.mob.utsmyanmar.ui.components.appbar.AppBar
import com.mob.utsmyanmar.ui.theme.MOBPOSTheme import com.mob.utsmyanmar.ui.theme.MOBPOSTheme
import android.graphics.Canvas as AndroidCanvas
import android.graphics.Path as AndroidPath
import com.mob.utsmyanmar.ui.theme.Color as AppColor import com.mob.utsmyanmar.ui.theme.Color as AppColor
@Composable @Composable
fun SignaturePad( fun SignaturePad(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
signatureColor: Color = Color.Black, signatureColor: Color = Color.Black,
strokeWidth: Float = 8f,
onBack: () -> Unit = {}, onBack: () -> Unit = {},
onConfirm: () -> Unit = {} onConfirm: (SignatureMode, Bitmap?) -> Unit = { _, _ -> }
) { ) {
val paths = remember { mutableStateListOf<List<Offset>>() } val paths = remember { mutableStateListOf<List<Offset>>() }
val currentPath = remember { mutableStateListOf<Offset>() } val currentPath = remember { mutableStateListOf<Offset>() }
var selectedMode by remember { mutableStateOf(SignatureMode.Manual) } var selectedMode by remember { mutableStateOf(SignatureMode.Manual) }
var canvasSize by remember { mutableStateOf(Size.Zero) }
var strokeWidth: Float = 8f;
fun clearSignature() { fun clearSignature() {
paths.clear() paths.clear()
currentPath.clear() currentPath.clear()
} }
fun buildBitmap(): Bitmap? {
if (selectedMode == SignatureMode.Manual) return null
if (paths.isEmpty() && currentPath.isEmpty()) return null
if (canvasSize.width <= 0f || canvasSize.height <= 0f) return null
val bitmap = Bitmap.createBitmap(
canvasSize.width.toInt(),
canvasSize.height.toInt(),
Bitmap.Config.ARGB_8888
)
val canvas = AndroidCanvas(bitmap)
val paint = Paint().apply {
color = android.graphics.Color.BLACK
style = Paint.Style.STROKE
strokeWidth = strokeWidth
isAntiAlias = true
strokeCap = Paint.Cap.ROUND
strokeJoin = Paint.Join.ROUND
}
fun drawStroke(points: List<Offset>) {
if (points.size < 2) return
val path = AndroidPath().apply {
moveTo(points.first().x, points.first().y)
for (index in 1 until points.size) {
lineTo(points[index].x, points[index].y)
}
}
canvas.drawPath(path, paint)
}
paths.forEach(::drawStroke)
drawStroke(currentPath)
return bitmap
}
Scaffold( Scaffold(
topBar = { topBar = {
AppBar( AppBar(
@ -77,6 +123,9 @@ fun SignaturePad(
.fillMaxWidth() .fillMaxWidth()
.background(Color.White, RoundedCornerShape(16.dp)) .background(Color.White, RoundedCornerShape(16.dp))
.padding(12.dp) .padding(12.dp)
.onSizeChanged { size ->
canvasSize = Size(size.width.toFloat(), size.height.toFloat())
}
.pointerInput(Unit) { .pointerInput(Unit) {
detectDragGestures( detectDragGestures(
onDragStart = { startOffset -> onDragStart = { startOffset ->
@ -163,7 +212,13 @@ fun SignaturePad(
} }
Button( Button(
onClick = onConfirm, onClick = {
val bitmap = buildBitmap()
if (selectedMode == SignatureMode.Digital && bitmap == null) {
return@Button
}
onConfirm(selectedMode, bitmap)
},
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.height(50.dp), .height(50.dp),
@ -179,7 +234,7 @@ fun SignaturePad(
} }
} }
private enum class SignatureMode { enum class SignatureMode {
Manual, Manual,
Digital Digital
} }

View File

@ -316,7 +316,7 @@ class SharedViewModel @Inject constructor(
private fun printReceipt(isMerchantCopy: Boolean) { private fun printReceipt(isMerchantCopy: Boolean) {
PrintXReceipt.getInstance() PrintXReceipt.getInstance()
.printSmileReceipt(payDetail.value, isMerchantCopy, object : PrintXStatus { .printSmileReceipt(payDetail.value, isMerchantCopy, signBitmap, object : PrintXStatus {
override fun onSuccess() { override fun onSuccess() {
@ -351,7 +351,7 @@ class SharedViewModel @Inject constructor(
} }
PrintXReceipt.getInstance() PrintXReceipt.getInstance()
.printSmileReceipt(getPayDetail(), isFirstPrint, object : PrintXStatus { .printSmileReceipt(getPayDetail(), isFirstPrint, signBitmap, object : PrintXStatus {
override fun onSuccess() { override fun onSuccess() {

View File

@ -25,7 +25,7 @@ import com.utsmyanmar.baselib.db.model.RidEntity;
import com.utsmyanmar.paylibs.model.PayDetail; import com.utsmyanmar.paylibs.model.PayDetail;
@Database(entities = {PayDetail.class, ChipAidEntity.class, PayWaveEntity.class, PayPassEntity.class, QuickPassEntity.class, RidEntity.class, MPUCtlsEntity.class, BinEntity.class},version = 12,exportSchema = false) @Database(entities = {PayDetail.class, ChipAidEntity.class, PayWaveEntity.class, PayPassEntity.class, QuickPassEntity.class, RidEntity.class, MPUCtlsEntity.class, BinEntity.class}, version = 13, exportSchema = false)
@TypeConverters({SettleDataConverter.class, TransCVMConverter.class, CardSchemeConverter.class}) @TypeConverters({SettleDataConverter.class, TransCVMConverter.class, CardSchemeConverter.class})
public abstract class AppDatabase extends RoomDatabase { public abstract class AppDatabase extends RoomDatabase {
public static volatile AppDatabase INSTANCE; public static volatile AppDatabase INSTANCE;

View File

@ -1,10 +1,6 @@
package com.utsmyanmar.baselib.di; package com.utsmyanmar.baselib.di;
import static com.utsmyanmar.baselib.db.AppDatabase.INSTANCE;
import android.app.Application; import android.app.Application;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@ -16,8 +12,6 @@ import androidx.room.Room;
import androidx.room.RoomDatabase; import androidx.room.RoomDatabase;
import androidx.room.migration.Migration; import androidx.room.migration.Migration;
import androidx.sqlite.db.SupportSQLiteDatabase; import androidx.sqlite.db.SupportSQLiteDatabase;
import androidx.sqlite.db.SupportSQLiteOpenHelper;
import com.utsmyanmar.baselib.db.AppDatabase; import com.utsmyanmar.baselib.db.AppDatabase;
import com.utsmyanmar.baselib.db.dao.BinDao; import com.utsmyanmar.baselib.db.dao.BinDao;
@ -28,8 +22,6 @@ import com.utsmyanmar.baselib.db.dao.PayPassDao;
import com.utsmyanmar.baselib.db.dao.PayWaveDao; import com.utsmyanmar.baselib.db.dao.PayWaveDao;
import com.utsmyanmar.baselib.db.dao.QuickPassDao; import com.utsmyanmar.baselib.db.dao.QuickPassDao;
import com.utsmyanmar.baselib.db.dao.RidDao; import com.utsmyanmar.baselib.db.dao.RidDao;
import com.utsmyanmar.baselib.util.SecureKeyUtil;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -39,13 +31,12 @@ import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException; import java.security.NoSuchProviderException;
import java.security.UnrecoverableEntryException; import java.security.UnrecoverableEntryException;
import java.security.cert.CertificateException;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import javax.crypto.KeyGenerator; import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
import javax.inject.Provider;
import javax.inject.Singleton; import javax.inject.Singleton;
import java.security.cert.CertificateException;
import dagger.Module; import dagger.Module;
import dagger.Provides; import dagger.Provides;
@ -353,6 +344,14 @@ public class DatabaseModule {
} }
}; };
static final Migration MIGRATION_12_13 = new Migration(12, 13) {
@Override
public void migrate(SupportSQLiteDatabase database) {
database.execSQL("ALTER TABLE paydetail "
+ " ADD COLUMN signatureBlob BLOB");
}
};
private static byte[] getDatabaseKey(Context context) throws KeyStoreException, CertificateException, private static byte[] getDatabaseKey(Context context) throws KeyStoreException, CertificateException,
NoSuchAlgorithmException, IOException, NoSuchProviderException, NoSuchAlgorithmException, IOException, NoSuchProviderException,
InvalidAlgorithmParameterException, UnrecoverableEntryException { InvalidAlgorithmParameterException, UnrecoverableEntryException {
@ -405,6 +404,7 @@ public class DatabaseModule {
.addMigrations(MIGRATION_9_10) .addMigrations(MIGRATION_9_10)
.addMigrations(MIGRATION_10_11) .addMigrations(MIGRATION_10_11)
.addMigrations(MIGRATION_11_12) .addMigrations(MIGRATION_11_12)
.addMigrations(MIGRATION_12_13)
.allowMainThreadQueries() .allowMainThreadQueries()
.addCallback(new RoomDatabase.Callback() { .addCallback(new RoomDatabase.Callback() {
@Override @Override
@ -425,8 +425,6 @@ public class DatabaseModule {
} }
private static boolean isDatabaseFileCorruptOrWrongKey(Application application) { private static boolean isDatabaseFileCorruptOrWrongKey(Application application) {
File dbFile = application.getDatabasePath(DATABASE_NAME); File dbFile = application.getDatabasePath(DATABASE_NAME);
return dbFile.exists() && dbFile.length() > 0; return dbFile.exists() && dbFile.length() > 0;
@ -507,9 +505,13 @@ public class DatabaseModule {
@Provides @Provides
@Singleton @Singleton
public static MPUCtlsDao provideMPUCtlsDao(AppDatabase appDatabase) { return appDatabase.mpuCtlsDao(); } public static MPUCtlsDao provideMPUCtlsDao(AppDatabase appDatabase) {
return appDatabase.mpuCtlsDao();
}
@Provides @Provides
@Singleton @Singleton
public static BinDao provideBinDao(AppDatabase appDatabase) { return appDatabase.binDao(); } public static BinDao provideBinDao(AppDatabase appDatabase) {
return appDatabase.binDao();
}
} }

View File

@ -74,6 +74,7 @@ public class PayDetail implements Serializable {
public String cardOrgCode = ""; // International credit card company code (domain 63.1) public String cardOrgCode = ""; // International credit card company code (domain 63.1)
public String reference = ""; // Remarks public String reference = ""; // Remarks
public String eSignHexData = ""; // Electronic signature hexadecimal data public String eSignHexData = ""; // Electronic signature hexadecimal data
private byte[] signatureBlob; // Signature store as blob type
public int transPlatform; // Supported trading platforms: 0: bank card 1: Alipay 2: WeChat 3: UnionPay wallet public int transPlatform; // Supported trading platforms: 0: bank card 1: Alipay 2: WeChat 3: UnionPay wallet
public int transactionType; // 1: Consumption 2: Consumption cancellation; 3: Return 4. Pre-authorization 5. Pre-authorization cancellation 6. Pre-authorization completed 7. Pre-authorization completed cancellation 8. Settlement 9. Sign-in 10. Sign-out 11. Transaction query public int transactionType; // 1: Consumption 2: Consumption cancellation; 3: Return 4. Pre-authorization 5. Pre-authorization cancellation 6. Pre-authorization completed 7. Pre-authorization completed cancellation 8. Settlement 9. Sign-in 10. Sign-out 11. Transaction query
@ -1359,4 +1360,11 @@ public class PayDetail implements Serializable {
this.currency = currency; this.currency = currency;
} }
public byte[] getSignatureBlob() {
return signatureBlob;
}
public void setSignatureBlob(byte[] signatureBlob) {
this.signatureBlob = signatureBlob;
}
} }

View File

@ -722,8 +722,7 @@ public abstract class BaseXPrint {
sunmiPrinterService.sendRAWData(boldOn(), innerResultCallback); sunmiPrinterService.sendRAWData(boldOn(), innerResultCallback);
sunmiPrinterService.setAlignment(1, innerResultCallback); sunmiPrinterService.setAlignment(1, innerResultCallback);
// default String cvmText;
String cvmText = "NO SIGNATURE REQUIRED";
switch (payDetail.getTransCVM()) { switch (payDetail.getTransCVM()) {
case SIGNATURE: cvmText = "SIGN : -----------------------------"; case SIGNATURE: cvmText = "SIGN : -----------------------------";
break; break;
@ -735,9 +734,10 @@ public abstract class BaseXPrint {
cvmText = "NO SIGNATURE REQUIRED"; cvmText = "NO SIGNATURE REQUIRED";
break; break;
} }
addSignatureBitmap(payDetail);
sunmiPrinterService.printText(cvmText, innerResultCallback); sunmiPrinterService.printText(cvmText, innerResultCallback);
// if (payDetail.getIsFreeSign()) { // if (payDetail.getIsFreeSign()) {
// sunmiPrinterService.printText("NO SIGNATURE REQUIRED", innerResultCallback); // sunmiPrinterService.printText("NO SIGNATURE REQUIRED", innerResultCallback);
// } else { // } else {
@ -948,4 +948,14 @@ public abstract class BaseXPrint {
} }
}; };
private void addSignatureBitmap(PayDetail payDetail) throws RemoteException {
byte[] signatureBlob = payDetail.getSignatureBlob();
if (signatureBlob != null && signatureBlob.length > 0) {
Bitmap signatureBitmap = android.graphics.BitmapFactory.decodeByteArray(signatureBlob, 0, signatureBlob.length);
if (signatureBitmap != null) {
sunmiPrinterService.printBitmap(signatureBitmap, innerResultCallback);
}
}
}
} }

View File

@ -2,6 +2,7 @@ package com.utsmyanmar.paylibs.print.printx;
import com.utsmyanmar.paylibs.model.PayDetail; import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.utils.enums.HostType; import com.utsmyanmar.paylibs.utils.enums.HostType;
import android.graphics.Bitmap;
import java.util.List; import java.util.List;
@ -9,7 +10,7 @@ public interface PrintX {
void printSimple(); void printSimple();
void printSmileReceipt(PayDetail payDetail, boolean isMerchantCopy,PrintXStatus printXStatus); void printSmileReceipt(PayDetail payDetail, boolean isMerchantCopy, Bitmap signBitmap, PrintXStatus printXStatus);
void printISOReceipt(PayDetail payDetail); void printISOReceipt(PayDetail payDetail);

View File

@ -120,7 +120,7 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
@Override @Override
public void printSmileReceipt(PayDetail payDetail, boolean isMerchantCopy,PrintXStatus printXStatus) { public void printSmileReceipt(PayDetail payDetail, boolean isMerchantCopy, Bitmap signBitmap, PrintXStatus printXStatus) {
try { try {
this.callbackStatus = printXStatus; this.callbackStatus = printXStatus;
@ -129,9 +129,9 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
} else if (payDetail.getTransactionType() == TransactionsType.SETTLEMENT.value) { } else if (payDetail.getTransactionType() == TransactionsType.SETTLEMENT.value) {
printSmileSettlementReport(payDetail,printXStatus); printSmileSettlementReport(payDetail,printXStatus);
} else if (payDetail.getICC55() == null || payDetail.getICC55().isEmpty() || payDetail.getAccountType().equals(CardScheme.MPU_CTLS.name)) { } else if (payDetail.getICC55() == null || payDetail.getICC55().isEmpty() || payDetail.getAccountType().equals(CardScheme.MPU_CTLS.name)) {
printSmileMPUReceipt(payDetail, isMerchantCopy); printSmileMPUReceipt(payDetail, isMerchantCopy, signBitmap);
} else if (!payDetail.getICC55().equals("")) { } else if (!payDetail.getICC55().equals("")) {
printSmileEMVReceipt(payDetail, isMerchantCopy); printSmileEMVReceipt(payDetail, isMerchantCopy, signBitmap);
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@ -256,7 +256,7 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
} }
} }
private void printSmileMPUReceipt(PayDetail payDetail, boolean isMerchantCopy) { private void printSmileMPUReceipt(PayDetail payDetail, boolean isMerchantCopy, Bitmap signBitmap) {
try { try {
setHeight(0x12); setHeight(0x12);
@ -268,6 +268,7 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
if (payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_APPROVED) || payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_ACCEPT)) { if (payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_APPROVED) || payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_ACCEPT)) {
printTransFooter(false,payDetail, isMerchantCopy); printTransFooter(false,payDetail, isMerchantCopy);
printSignatureBlock(payDetail, signBitmap);
} else { } else {
String receiptFooter = SystemParamsOperation.getInstance().getReceiptFooter(); String receiptFooter = SystemParamsOperation.getInstance().getReceiptFooter();
sunmiPrinterService.printText("\n", null); sunmiPrinterService.printText("\n", null);
@ -282,7 +283,7 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
} }
} }
private void printSmileEMVReceipt(PayDetail payDetail, boolean isMerchantCopy) { private void printSmileEMVReceipt(PayDetail payDetail, boolean isMerchantCopy, Bitmap signBitmap) {
try { try {
setHeight(0x12); setHeight(0x12);
printLogo(); printLogo();
@ -292,6 +293,7 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
if (payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_APPROVED) || payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_ACCEPT)) { if (payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_APPROVED) || payDetail.getTradeAnswerCode().equals(Constant.ANSWER_CODE_ACCEPT)) {
printTransFooter(false,payDetail, isMerchantCopy); printTransFooter(false,payDetail, isMerchantCopy);
printSignatureBlock(payDetail, signBitmap);
} else { } else {
String receiptFooter = SystemParamsOperation.getInstance().getReceiptFooter(); String receiptFooter = SystemParamsOperation.getInstance().getReceiptFooter();
sunmiPrinterService.setFontSize(textSize, null); sunmiPrinterService.setFontSize(textSize, null);
@ -307,6 +309,32 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
} }
} }
private void printSignatureBlock(PayDetail payDetail, Bitmap signBitmap) {
try {
if (payDetail.getTransCVM() != com.utsmyanmar.paylibs.model.enums.TransCVM.SIGNATURE) {
return;
}
if (signBitmap == null) {
return;
}
Bitmap printableBitmap = signBitmap;
if (printableBitmap.getWidth() > 130) {
double size = 1.0 * printableBitmap.getHeight() * 130 / printableBitmap.getWidth();
int newHeight = (int) size;
printableBitmap = BitmapUtils.scale(printableBitmap, 130, newHeight);
}
sunmiPrinterService.lineWrap(1, innerResultCallback);
sunmiPrinterService.setAlignment(1, innerResultCallback);
sunmiPrinterService.printBitmap(printableBitmap, innerResultCallback);
sunmiPrinterService.lineWrap(1, innerResultCallback);
} catch (RemoteException e) {
e.printStackTrace();
}
}
private void printTransDetailWave(PayDetail payDetail) { private void printTransDetailWave(PayDetail payDetail) {
try { try {

View File

@ -3,6 +3,7 @@ package com.utsmyanmar.paylibs.print.printx;
import com.utsmyanmar.paylibs.model.PayDetail; import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.utils.enums.HostType; import com.utsmyanmar.paylibs.utils.enums.HostType;
import android.graphics.Bitmap;
import java.util.List; import java.util.List;
public class PrintXReceipt { public class PrintXReceipt {
@ -21,8 +22,8 @@ public class PrintXReceipt {
printX.printSimple(); printX.printSimple();
} }
public void printSmileReceipt(PayDetail payDetail,boolean isMerchantCopy,PrintXStatus printXStatus) { public void printSmileReceipt(PayDetail payDetail,boolean isMerchantCopy, Bitmap signBitmap,PrintXStatus printXStatus) {
printX.printSmileReceipt(payDetail,isMerchantCopy,printXStatus); printX.printSmileReceipt(payDetail,isMerchantCopy,signBitmap,printXStatus);
} }
public void printSmileSettlementReport(PayDetail payDetail,PrintXStatus printXStatus) { public void printSmileSettlementReport(PayDetail payDetail,PrintXStatus printXStatus) {