e signature is now printing on paper

This commit is contained in:
kizzy 2025-12-02 05:10:22 +07:00
parent aa37e14ea4
commit 2f4db87441
12 changed files with 135 additions and 43 deletions

View File

@ -136,7 +136,6 @@ public class MainFragment extends DataBindingFragment {
sharedViewModel.setCardDataExist(false); sharedViewModel.setCardDataExist(false);
sharedViewModel.setTransMenu(null); sharedViewModel.setTransMenu(null);
PrintXReceipt.getInstance().setSignatureBitmap(null);
updateButtonStatus(); updateButtonStatus();
delayFunctionCall(this::checkTerminalStatus); delayFunctionCall(this::checkTerminalStatus);

View File

@ -16,9 +16,11 @@ import com.utsmm.kbz.R;
import com.utsmm.kbz.config.Constants; import com.utsmm.kbz.config.Constants;
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel; import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.print.printx.PrintX; import com.utsmyanmar.paylibs.print.printx.PrintX;
import com.utsmyanmar.paylibs.print.printx.PrintXReceipt; import com.utsmyanmar.paylibs.print.printx.PrintXReceipt;
import com.utsmyanmar.paylibs.utils.LogUtil; import com.utsmyanmar.paylibs.utils.LogUtil;
import com.utsmyanmar.paylibs.utils.print_utils.BitmapUtils;
public class SignatureFragment extends DataBindingFragment { public class SignatureFragment extends DataBindingFragment {
@ -132,6 +134,12 @@ public class SignatureFragment extends DataBindingFragment {
safeNavigateToRouteId(); safeNavigateToRouteId();
} }
private void updateData() {
PayDetail payDetail = sharedViewModel.payDetail.getValue();
payDetail.setESignHexData(BitmapUtils.bitmapToHexString(mSignaturePad.getSignatureBitmap()));
sharedViewModel.payDetail.setValue(payDetail);
}
public class ClickEvent { public class ClickEvent {
@ -140,7 +148,8 @@ public class SignatureFragment extends DataBindingFragment {
// Handle digital signature // Handle digital signature
if (isSigned) { if (isSigned) {
sharedViewModel.signBitmap = mSignaturePad.getSignatureBitmap(); sharedViewModel.signBitmap = mSignaturePad.getSignatureBitmap();
PrintXReceipt.getInstance().setSignatureBitmap(mSignaturePad.getSignatureBitmap());
updateData();
LogUtil.d(TAG, "Digital signature confirmed and stored"); LogUtil.d(TAG, "Digital signature confirmed and stored");
callNextScreen(); callNextScreen();
} else { } else {
@ -149,7 +158,6 @@ public class SignatureFragment extends DataBindingFragment {
} else { } else {
// Handle manual signature on paper // Handle manual signature on paper
sharedViewModel.signBitmap = null; // No digital signature sharedViewModel.signBitmap = null; // No digital signature
PrintXReceipt.getInstance().setSignatureBitmap(null);
LogUtil.d(TAG, "Manual signature on paper selected - no digital signature stored"); LogUtil.d(TAG, "Manual signature on paper selected - no digital signature stored");
callNextScreen(); callNextScreen();
} }

View File

@ -8,7 +8,9 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import com.utsmm.kbz.util.EReceiptUtil;
import com.utsmyanmar.baselib.fragment.DataBindingFragment; import com.utsmyanmar.baselib.fragment.DataBindingFragment;
import com.utsmyanmar.baselib.network.model.e_receipt.EReceiptRequest;
import com.utsmyanmar.baselib.util.DataBindingConfig; import com.utsmyanmar.baselib.util.DataBindingConfig;
import com.utsmyanmar.paylibs.model.PayDetail; import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.model.TradeData; import com.utsmyanmar.paylibs.model.TradeData;
@ -338,6 +340,10 @@ public class SettlementTransactionFragment extends DataBindingFragment implement
private void updateData() { private void updateData() {
sharedViewModel.payDetail.setValue(settlementViewModel.getPayDetail()); sharedViewModel.payDetail.setValue(settlementViewModel.getPayDetail());
EReceiptRequest request = EReceiptUtil.getInstance().generateMPUReceipt(sharedViewModel.payDetail.getValue());
sharedViewModel.pushReceipt(request);
} }
@Override @Override

View File

@ -7,6 +7,8 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel; import androidx.lifecycle.ViewModel;
import com.utsmm.kbz.util.EReceiptUtil;
import com.utsmyanmar.baselib.network.model.e_receipt.EReceiptRequest;
import com.utsmyanmar.baselib.repo.Repository; import com.utsmyanmar.baselib.repo.Repository;
import com.utsmyanmar.paylibs.Constant; import com.utsmyanmar.paylibs.Constant;
import com.utsmyanmar.paylibs.batch_upload.BatchListener; import com.utsmyanmar.paylibs.batch_upload.BatchListener;
@ -499,8 +501,12 @@ public class SettlementViewModel extends ViewModel {
// to leave data for testing // to leave data for testing
// if (settlementType.getValue() == SettlementType.NORMAL) { // if (settlementType.getValue() == SettlementType.NORMAL) {
updateDB(); updateDB();
// } // }
insertPayDetail(payDetail); insertPayDetail(payDetail);
if (errorFlag) { if (errorFlag) {

View File

@ -5,6 +5,7 @@ import com.utsmm.kbz.util.enums.TransResultStatus;
import com.utsmm.kbz.util.tms.TMSUtil; import com.utsmm.kbz.util.tms.TMSUtil;
import com.utsmyanmar.baselib.network.model.e_receipt.EReceiptRequest; import com.utsmyanmar.baselib.network.model.e_receipt.EReceiptRequest;
import com.utsmyanmar.paylibs.model.PayDetail; import com.utsmyanmar.paylibs.model.PayDetail;
import com.utsmyanmar.paylibs.model.SettleData;
import com.utsmyanmar.paylibs.system.BaseErrorCode; import com.utsmyanmar.paylibs.system.BaseErrorCode;
import com.utsmyanmar.paylibs.utils.POSUtil; import com.utsmyanmar.paylibs.utils.POSUtil;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation; import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
@ -30,6 +31,7 @@ public class EReceiptUtil {
private String traceNo; private String traceNo;
private String invoiceNo; private String invoiceNo;
private String serialNum; private String serialNum;
private String batchNumber;
private String packageName; private String packageName;
private EReceiptUtil(){ private EReceiptUtil(){
@ -37,6 +39,7 @@ public class EReceiptUtil {
merchantId = SystemParamsOperation.getInstance().getMerchantId(); merchantId = SystemParamsOperation.getInstance().getMerchantId();
traceNo = SystemParamsOperation.getInstance().getCurrentSerialNum(); traceNo = SystemParamsOperation.getInstance().getCurrentSerialNum();
invoiceNo = SystemParamsOperation.getInstance().getCurrentInvoiceNum(); invoiceNo = SystemParamsOperation.getInstance().getCurrentInvoiceNum();
batchNumber = SystemParamsOperation.getInstance().getCurrentBatchNum();
serialNum = TMSUtil.getInstance().getSerialNumber(); serialNum = TMSUtil.getInstance().getSerialNumber();
packageName = BuildConfig.APPLICATION_ID; packageName = BuildConfig.APPLICATION_ID;
} }
@ -94,38 +97,49 @@ public class EReceiptUtil {
String currentTimeStamp = new java.text.SimpleDateFormat("MMddHHmmss", java.util.Locale.getDefault()) String currentTimeStamp = new java.text.SimpleDateFormat("MMddHHmmss", java.util.Locale.getDefault())
.format(new java.util.Date()); .format(new java.util.Date());
EReceiptRequest request = new EReceiptRequest(); EReceiptRequest request = new EReceiptRequest();
request.setDE2(POSUtil.getInstance().getCardNumMasking(payDetail.getCardNo()));
request.setDE3(convertTransactionType(payDetail.getTransactionType())); request.setDE3(convertTransactionType(payDetail.getTransactionType()));
request.setDE4(amount);
request.setDE7(currentTimeStamp);
request.setDE11(payDetail.getVoucherNo());
request.setDE37(payDetail.getReferNo());
request.setDE38(payDetail.getApprovalCode());
// will check it later for currency code if(payDetail.getTransactionType() == TransactionsType.SETTLEMENT.value) {
request.setDE49("MMK"); SettleData settleData = payDetail.getSettleDataObj();
request.setDE63_01(settleData.getSaleCount()+"");
request.setDE63_02(settleData.getSaleAmount()+"");
request.setDE63_03(settleData.getRefundCount()+"");
request.setDE63_04(settleData.getRefundAmount()+"");
request.setBatchNumber(batchNumber);
request.setDescription("success");
request.setDE39("A");
} else {
request.setDE2(POSUtil.getInstance().getCardNumMasking(payDetail.getCardNo()));
request.setDE4(amount);
request.setDE7(currentTimeStamp);
request.setDE11(payDetail.getVoucherNo());
request.setDE37(payDetail.getReferNo());
request.setDE38(payDetail.getApprovalCode());
// will check it later for currency code
request.setDE49("MMK");
request.setInvoiceNumber(payDetail.getInvoiceNo());
request.setCardLabel("MPU");
if(payDetail.getTradeAnswerCode().equals("000") || payDetail.getTradeAnswerCode().equals("00") ) {
request.setDescription("success");
request.setDE39("A");
} else {
request.setDescription(BaseErrorCode.getErrorMessage(payDetail.getTradeAnswerCode()));
request.setDE39("E");
}
}
request.setDE41(terminalId); request.setDE41(terminalId);
request.setDE42(merchantId); request.setDE42(merchantId);
request.setSerial(serialNum); request.setSerial(serialNum);
request.setAppId(packageName); request.setAppId(packageName);
request.setInvoiceNumber(payDetail.getInvoiceNo());
request.setCardLabel("MPU");
// need to add payment identifier field too
if(payDetail.getTradeAnswerCode().equals("000") || payDetail.getTradeAnswerCode().equals("00")) {
request.setDescription("success");
request.setDE39("A");
} else {
request.setDescription(BaseErrorCode.getErrorMessage(payDetail.getTradeAnswerCode()));
request.setDE39("E");
}
return request; return request;
} }

View File

@ -30,6 +30,8 @@ public class EReceiptRequest {
private String cardLabel; private String cardLabel;
private String batchNumber;
public EReceiptRequest() {} public EReceiptRequest() {}
// GETTERS // GETTERS
@ -113,6 +115,14 @@ public class EReceiptRequest {
public String getCardLabel() { public String getCardLabel() {
return cardLabel; return cardLabel;
} }
public String getBatchNumber() {
return batchNumber;
}
public void setBatchNumber(String batchNumber) {
this.batchNumber = batchNumber;
}
// SETTERS // SETTERS
public void setDE3(String DE3) { public void setDE3(String DE3) {
this.DE3 = DE3; this.DE3 = DE3;

View File

@ -1,5 +1,7 @@
package com.utsmyanmar.paylibs.model; package com.utsmyanmar.paylibs.model;
import android.graphics.Bitmap;
import androidx.room.Embedded; import androidx.room.Embedded;
import androidx.room.Entity; import androidx.room.Entity;
import androidx.room.Ignore; import androidx.room.Ignore;
@ -698,6 +700,8 @@ public class PayDetail implements Serializable {
this.tradeDateTime = tradeDateTime; this.tradeDateTime = tradeDateTime;
} }
public long getAmount() { public long getAmount() {
return this.amount; return this.amount;
} }

View File

@ -80,11 +80,9 @@ public abstract class BaseXPrint {
protected FontEntity fontBold = new FontEntity(DotMatrixFontEnum.CH_SONG_24X24, DotMatrixFontEnum.ASC_SONG_BOLD_16X24); protected FontEntity fontBold = new FontEntity(DotMatrixFontEnum.CH_SONG_24X24, DotMatrixFontEnum.ASC_SONG_BOLD_16X24);
protected FontEntity fontBig = new FontEntity(DotMatrixFontEnum.CH_SONG_24X24, DotMatrixFontEnum.ASC_SONG_12X24, false, true); protected FontEntity fontBig = new FontEntity(DotMatrixFontEnum.CH_SONG_24X24, DotMatrixFontEnum.ASC_SONG_12X24, false, true);
protected Bitmap signatureBitmap;
public void setSignatureBitmap(Bitmap signatureBitmap) {
this.signatureBitmap = signatureBitmap;
}
public static byte[] boldOn() { public static byte[] boldOn() {
byte[] result = new byte[3]; byte[] result = new byte[3];
@ -725,7 +723,7 @@ public abstract class BaseXPrint {
break; break;
} }
addSignatureBitmap(); addSignatureBitmap(payDetail);
printer.appendPrnStr(cvmText, fontBold, AlignEnum.CENTER); printer.appendPrnStr(cvmText, fontBold, AlignEnum.CENTER);
@ -757,8 +755,9 @@ public abstract class BaseXPrint {
} }
private void addSignatureBitmap() { private void addSignatureBitmap(PayDetail payDetail) {
if (signatureBitmap != null) { if (payDetail.getESignHexData() != null) {
Bitmap signatureBitmap = BitmapUtils.hexStringToBitmap(payDetail.getESignHexData());
printer.appendImage(signatureBitmap, AlignEnum.CENTER); printer.appendImage(signatureBitmap, AlignEnum.CENTER);
} }
} }

View File

@ -23,5 +23,4 @@ public interface PrintX {
void printKeyStatus(); void printKeyStatus();
void setSignatureBitmap(Bitmap signatureBitmap);
} }

View File

@ -45,11 +45,6 @@ public class PrintXImpl extends BaseXPrint implements PrintX {
} }
@Override
public void setSignatureBitmap(Bitmap signatureBitmap) {
super.setSignatureBitmap(signatureBitmap);
}
@Override @Override
public void printSimple() { public void printSimple() {

View File

@ -25,9 +25,7 @@ public class PrintXReceipt {
} }
public void setSignatureBitmap(Bitmap signatureBitmap) {
printX.setSignatureBitmap(signatureBitmap);
}
public void printSmileReceipt(PayDetail payDetail,boolean isMerchantCopy,PrintXStatus printXStatus) { public void printSmileReceipt(PayDetail payDetail,boolean isMerchantCopy,PrintXStatus printXStatus) {
printX.printSmileReceipt(payDetail,isMerchantCopy,printXStatus); printX.printSmileReceipt(payDetail,isMerchantCopy,printXStatus);

View File

@ -1,11 +1,14 @@
package com.utsmyanmar.paylibs.utils.print_utils; package com.utsmyanmar.paylibs.utils.print_utils;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Matrix; import android.graphics.Matrix;
import android.graphics.Rect; import android.graphics.Rect;
import android.util.Log; import android.util.Log;
import java.io.ByteArrayOutputStream;
public class BitmapUtils { public class BitmapUtils {
private static final String TAG = "BitmapUtils"; private static final String TAG = "BitmapUtils";
@ -194,4 +197,55 @@ public class BitmapUtils {
} }
return yuv; return yuv;
} }
/**
* Converts a Bitmap to a hexadecimal string
* @param bitmap The bitmap to convert
* @return Hexadecimal string representation
*/
public static String bitmapToHexString(Bitmap bitmap) {
if (bitmap == null) {
return null;
}
// Compress bitmap to byte array
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] bytes = baos.toByteArray();
// Convert bytes to hex string
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xFF & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
/**
* Converts a hexadecimal string back to a Bitmap
* @param hexString The hex string to convert
* @return Bitmap object
*/
public static Bitmap hexStringToBitmap(String hexString) {
if (hexString == null || hexString.length() % 2 != 0) {
return null;
}
// Convert hex string to byte array
int len = hexString.length();
byte[] bytes = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
+ Character.digit(hexString.charAt(i + 1), 16));
}
// Decode byte array to bitmap
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
} }