fix for refund decimal in summary and detail reports

This commit is contained in:
MooN 2025-12-23 23:03:15 +06:30
parent bbabe9b824
commit 83af914911
3 changed files with 59 additions and 42 deletions

View File

@ -17,9 +17,6 @@ public class DownloadUtil {
private static final String TAG = DownloadUtil.class.getSimpleName(); private static final String TAG = DownloadUtil.class.getSimpleName();
// ==============================
// CALLBACK INTERFACE
// ==============================
public interface DownloadCallback { public interface DownloadCallback {
void onDownloadSuccess(String path); void onDownloadSuccess(String path);
} }
@ -29,21 +26,21 @@ public class DownloadUtil {
// ============================== // ==============================
public static void downloadCertificateRx(String url, public static void downloadCertificateRx(String url,
String dynamicFilename, String dynamicFilename,
String timestamp,
String signature,
DownloadCallback callback) { DownloadCallback callback) {
Observable.fromCallable(() -> downloadCert(url, dynamicFilename)) Observable.fromCallable(() ->
.subscribeOn(Schedulers.io()) // download on background thread downloadCert(url, dynamicFilename, timestamp, signature)
.observeOn(AndroidSchedulers.mainThread()) // callback on main thread )
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(path -> { .subscribe(path -> {
if (path != null) { if (callback != null) {
LogUtil.d(TAG, "Certificate saved at: " + path); callback.onDownloadSuccess(path);
if (callback != null) callback.onDownloadSuccess(path);
} else {
LogUtil.e(TAG, "Certificate download failed.");
if (callback != null) callback.onDownloadSuccess(null);
} }
}, error -> { }, error -> {
error.printStackTrace(); LogUtil.e(TAG, "Download error : " + error);
if (callback != null) callback.onDownloadSuccess(null); if (callback != null) callback.onDownloadSuccess(null);
}); });
} }
@ -51,62 +48,71 @@ public class DownloadUtil {
// ============================== // ==============================
// ACTUAL DOWNLOAD LOGIC // ACTUAL DOWNLOAD LOGIC
// ============================== // ==============================
public static String downloadCert(String url, String dynamicFilename) { private static String downloadCert(String url,
try { String dynamicFilename,
OkHttpClient client = new OkHttpClient(); String timestamp,
Request request = new Request.Builder().url(url).build(); String signature) {
LogUtil.d(TAG, "cert timestamp => " + timestamp);
LogUtil.d(TAG, "cert signature => " + signature);
Response response = client.newCall(request).execute(); OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
.readTimeout(30, java.util.concurrent.TimeUnit.SECONDS)
.build();
if (!response.isSuccessful()) { Request request = new Request.Builder()
.url(url)
.addHeader("x-timestamp", timestamp)
.addHeader("x-api-key", signature)
.build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful() || response.body() == null) {
LogUtil.e(TAG, "Download failed: " + response.code()); LogUtil.e(TAG, "Download failed: " + response.code());
return null; return null;
} }
// Detect extension (MIME or URL fallback)
String contentType = response.header("Content-Type", ""); String contentType = response.header("Content-Type", "");
String ext = getExtensionFromContentType(contentType); String ext = getExtensionFromContentType(contentType);
if (ext.isEmpty()) ext = getExtensionFromUrl(url); if (ext.isEmpty()) ext = getExtensionFromUrl(url);
if (ext.isEmpty()) ext = ".bin"; // final fallback if (ext.isEmpty()) ext = ".bin";
// build dynamic filename
String filename = dynamicFilename + ext; String filename = dynamicFilename + ext;
byte[] data = response.body().bytes(); byte[] data = response.body().bytes();
String savedPath = saveFile(filename, data);
return savedPath; return saveFile(filename, data);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); LogUtil.e(TAG, "Download exception : " + e);
return null; return null;
} }
} }
// ============================== // ==============================
// SAVE FILE TO INTERNAL STORAGE // SAVE FILE
// ============================== // ==============================
private static String saveFile(String filename, byte[] data) { private static String saveFile(String filename, byte[] data) {
try { try {
File dir = MyApplication.getInstance().getFilesDir(); File dir = MyApplication.getInstance().getFilesDir();
File file = new File(dir, filename); File file = new File(dir, filename);
FileOutputStream fos = new FileOutputStream(file); try (FileOutputStream fos = new FileOutputStream(file)) {
fos.write(data); fos.write(data);
fos.flush(); fos.flush();
fos.close(); }
return file.getAbsolutePath(); return file.getAbsolutePath();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); LogUtil.e(TAG, "File save failed : " + e);
return null; return null;
} }
} }
// ============================== // ==============================
// MIME TYPE EXTENSION // MIME EXTENSION
// ============================== // ==============================
private static String getExtensionFromContentType(String contentType) { private static String getExtensionFromContentType(String contentType) {
if (contentType == null) return ""; if (contentType == null) return "";
@ -120,15 +126,12 @@ public class DownloadUtil {
case "application/octet-stream": case "application/octet-stream":
return ".pem"; return ".pem";
case "application/x-pkcs12": case "application/x-pkcs12":
return ".pkcs12"; return ".p12";
default: default:
return ""; return "";
} }
} }
// ==============================
// URL EXTENSION PARSER
// ==============================
private static String getExtensionFromUrl(String url) { private static String getExtensionFromUrl(String url) {
if (url == null) return ""; if (url == null) return "";
int lastDot = url.lastIndexOf('.'); int lastDot = url.lastIndexOf('.');
@ -136,3 +139,4 @@ public class DownloadUtil {
return url.substring(lastDot); return url.substring(lastDot);
} }
} }

View File

@ -11,6 +11,7 @@ import com.utsmyanmar.baselib.network.model.sirius.SiriusMerchant;
import com.utsmyanmar.baselib.network.model.sirius.SiriusProperty; import com.utsmyanmar.baselib.network.model.sirius.SiriusProperty;
import com.utsmyanmar.baselib.network.model.sirius.SiriusResponse; import com.utsmyanmar.baselib.network.model.sirius.SiriusResponse;
import com.utsmyanmar.baselib.network.model.sirius.SiriusTerminal; import com.utsmyanmar.baselib.network.model.sirius.SiriusTerminal;
import com.utsmyanmar.baselib.util.EReceiptHelper;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation; import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsSettings; import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsSettings;
import com.utsmyanmar.paylibs.utils.enums.CurrencyType; import com.utsmyanmar.paylibs.utils.enums.CurrencyType;
@ -34,6 +35,9 @@ public class TMSSetupsImpl implements TMSSetups{
private static final String JCB = "JCB"; private static final String JCB = "JCB";
private static final String VISA = "VISA"; private static final String VISA = "VISA";
private static final String MASTERCARD = "MASTERCARD"; private static final String MASTERCARD = "MASTERCARD";
private static final String E_RECEIPT_SECRET = com.utsmyanmar.baselib.BuildConfig.ERECEIPT_SECRET;
String timestamp = String.valueOf(System.currentTimeMillis());
String signature = generateSignature(E_RECEIPT_SECRET, timestamp);
private CurrencyType currencyTextToCurrencyType(String currencyTxt) { private CurrencyType currencyTextToCurrencyType(String currencyTxt) {
@ -630,7 +634,9 @@ public class TMSSetupsImpl implements TMSSetups{
// String url = tmsAddress+"/file/download?filePath="+data; // String url = tmsAddress+"/file/download?filePath="+data;
String url = tmsAddress+"/api/v1/file/download?filePath="+data; //for local String url = tmsAddress+"/api/v1/file/download?filePath="+data; //for local
DownloadUtil.downloadCertificateRx(url, "certificate_file", path -> {
DownloadUtil.downloadCertificateRx(url, "certificate_file", timestamp, signature, path -> {
if(path != null){ if(path != null){
SystemParamsOperation.getInstance().setCertFilePath(path); SystemParamsOperation.getInstance().setCertFilePath(path);
LogUtil.d(TAG, "Cert file path saved in SystemParams => " + path); LogUtil.d(TAG, "Cert file path saved in SystemParams => " + path);
@ -651,7 +657,7 @@ public class TMSSetupsImpl implements TMSSetups{
} }
// String url = tmsAddress+"/file/download?filePath="+data; // String url = tmsAddress+"/file/download?filePath="+data;
String url = tmsAddress+"/api/v1/file/download?filePath="+data; //for local String url = tmsAddress+"/api/v1/file/download?filePath="+data; //for local
DownloadUtil.downloadCertificateRx(url, "certificate_client", path -> { DownloadUtil.downloadCertificateRx(url, "certificate_client" , timestamp, signature, path -> {
if(path != null){ if(path != null){
SystemParamsOperation.getInstance().setCertClientFilePath(path); SystemParamsOperation.getInstance().setCertClientFilePath(path);
LogUtil.d(TAG, "Cert client file path saved in SystemParams => " + path); LogUtil.d(TAG, "Cert client file path saved in SystemParams => " + path);
@ -668,6 +674,12 @@ public class TMSSetupsImpl implements TMSSetups{
SystemParamsOperation.getInstance().setCarouselUrls(convertToString(imgUrls)); SystemParamsOperation.getInstance().setCarouselUrls(convertToString(imgUrls));
} }
private static String generateSignature(String apiSecret, String timestamp) {
String bodyString = "";
String dataToHash = bodyString + apiSecret + timestamp;
return EReceiptHelper.sha256(dataToHash);
}
private String convertToString(ArrayList<String> list) { private String convertToString(ArrayList<String> list) {

View File

@ -537,7 +537,7 @@ public abstract class BaseXPrint {
} }
if (settleData.getWaveRefundCount() > 0) { if (settleData.getWaveRefundCount() > 0) {
// printColumnString("QR REFUND", settleData.getWaveRefundCount(), settleData.getWaveRefundAmount(), true); // printColumnString("QR REFUND", settleData.getWaveRefundCount(), settleData.getWaveRefundAmount(), true);
printer.appendPrnStr( "QR REFUND " + countStringFormat(settleData.getWaveRefundCount()) + " " + "MMK" , PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getWaveRefundCount(), isQrDecimalEnabled) , fontNormal, false); printer.appendPrnStr( "QR REFUND " + countStringFormat(settleData.getWaveRefundCount()) + " " + "MMK" , PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getWaveRefundAmount(), isQrDecimalEnabled) , fontNormal, false);
} }
dashBreak(); dashBreak();
// printColumnString("TOTAL", totalCount, totalAmount, false); // printColumnString("TOTAL", totalCount, totalAmount, false);
@ -572,7 +572,7 @@ public abstract class BaseXPrint {
} }
if (settleData.getWaveRefundCount() > 0){ if (settleData.getWaveRefundCount() > 0){
// printColumnString("QR REFUND", settleData.getWaveRefundCount(), settleData.getWaveRefundAmount(), true); // printColumnString("QR REFUND", settleData.getWaveRefundCount(), settleData.getWaveRefundAmount(), true);
printer.appendPrnStr( "QR REFUND " + countStringFormat(settleData.getWaveRefundCount()) + " " + "MMK" , PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getWaveRefundCount(), isQrDecimalEnabled) , fontNormal, false); printer.appendPrnStr( "QR REFUND " + countStringFormat(settleData.getWaveRefundCount()) + " " + "MMK" , PrintUtils.getInstance().getSeparatorNumberFormat(settleData.getWaveRefundAmount(), isQrDecimalEnabled) , fontNormal, false);
} }
dashBreak(); dashBreak();
// printColumnString("TOTAL", totalCount, totalAmount, false); // printColumnString("TOTAL", totalCount, totalAmount, false);
@ -697,7 +697,8 @@ public abstract class BaseXPrint {
print2ColumnsString("**/**", ""); print2ColumnsString("**/**", "");
print2ColumnsString(pay.getTransType().replace("_", " "), pay.getVoucherNo()); print2ColumnsString(pay.getTransType().replace("_", " "), pay.getVoucherNo());
if (pay.getTransactionType() == TransactionsType.MMQR_REFUND.value) { if (pay.getTransactionType() == TransactionsType.MMQR_REFUND.value) {
print2ColumnsString(pay.getReferNo() + "(RRN)", isNeedMinusSign ? "-" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled) : "" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled)); print2ColumnsString(pay.getReferNo() + "(RRN)", "");
print2ColumnsString(isNeedMinusSign ? "-" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled) : "" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled), "");
} else { } else {
print2ColumnsString(pay.getQrTransId(), ""); print2ColumnsString(pay.getQrTransId(), "");
print2ColumnsString(isNeedMinusSign ? "-" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled) : "" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled) , ""); print2ColumnsString(isNeedMinusSign ? "-" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled) : "" + PrintUtils.getInstance().getSeparatorNumberFormat(pay.getAmount(), isDecimalEnabled) , "");