diff --git a/app/src/main/java/com/utsmm/kbz/ui/core_ui/InputAmountFragment.java b/app/src/main/java/com/utsmm/kbz/ui/core_ui/InputAmountFragment.java index 4a40527..69e9d8b 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/core_ui/InputAmountFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/core_ui/InputAmountFragment.java @@ -72,7 +72,7 @@ public class InputAmountFragment extends DataBindingFragment implements DataBind super.onViewCreated(view, savedInstanceState); - setUpTimer(); +// setUpTimer(); setupBackButtonPressDetection(this); } diff --git a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundFragment.java b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundFragment.java index 375a954..1a376c7 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/QRRefundFragment.java @@ -132,7 +132,13 @@ public class QRRefundFragment extends DataBindingFragment { List filteredList = new ArrayList<>(); for(PayDetail item: originalList){ - if(item.getReferNo() != null && item.getReferNo().contains(keyword)){ + + boolean match = + (item.getReferNo() != null && item.getReferNo().contains(keyword)) || + (item.getInvoiceNo() != null && item.getInvoiceNo().contains(keyword)) || + (item.getVoucherNo() != null && item.getVoucherNo().contains(keyword)); + + if(match){ filteredList.add(item); } } @@ -140,4 +146,5 @@ public class QRRefundFragment extends DataBindingFragment { updateList(filteredList); } + } diff --git a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/RefundCertificateManager.java b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/RefundCertificateManager.java index 929a47d..c52245d 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/qr_pay/RefundCertificateManager.java +++ b/app/src/main/java/com/utsmm/kbz/ui/qr_pay/RefundCertificateManager.java @@ -1,13 +1,12 @@ package com.utsmm.kbz.ui.qr_pay; - -import android.util.Log; - import com.utsmm.kbz.util.DownloadUtil; import com.utsmyanmar.baselib.util.EReceiptHelper; import com.utsmyanmar.paylibs.utils.LogUtil; import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation; +import java.util.concurrent.atomic.AtomicBoolean; + import javax.inject.Inject; import javax.inject.Singleton; @@ -15,55 +14,94 @@ import javax.inject.Singleton; public class RefundCertificateManager { private static final String TAG = RefundCertificateManager.class.getSimpleName(); - private static final String CERTIFICATE_FILENAME = "refund_client_certificate"; - private static final String CERTIFICATE_CLIENT = "refund_client_certificate"; -// String tmsAddress = SystemParamsOperation.getInstance().getTmsAddress(); //for uat - String tmsAddress = SystemParamsOperation.getInstance().getTmsAddress() + "/api/v1"; - String downloadAddress = tmsAddress + "/file/download?filePath="; - String certificate_url = SystemParamsOperation.getInstance().getCertificateUrl(); + private static final String E_RECEIPT_SECRET = + com.utsmyanmar.baselib.BuildConfig.ERECEIPT_SECRET; - String certificate_client = SystemParamsOperation.getInstance().getCertificateClientUrl(); - private static final String E_RECEIPT_SECRET = com.utsmyanmar.baselib.BuildConfig.ERECEIPT_SECRET; - String timestamp = String.valueOf(System.currentTimeMillis()); + // Prevent duplicate parallel downloads + private final AtomicBoolean isUpdating = new AtomicBoolean(false); @Inject - public RefundCertificateManager(){} - public void updateCertificateFiles(){ + public RefundCertificateManager() { + } - String signature = generateSignature(timestamp); + /** + * Download & refresh refund certificates. + * Safe to call multiple times. + */ + public void updateCertificateFiles() { - DownloadUtil.downloadCertificateRx( - downloadAddress + certificate_url, - CERTIFICATE_FILENAME, - timestamp, - signature, - path -> { - if(path != null){ - SystemParamsOperation.getInstance().setCertClientFilePath(path); - LogUtil.d(TAG, "Cert file path saved in SystemParams => " + path); - }else{ - LogUtil.e(TAG, "Failed to download certificate file"); + if (!isUpdating.compareAndSet(false, true)) { + LogUtil.d(TAG, "Certificate update already in progress"); + return; + } + + try { + String tmsAddress = SystemParamsOperation.getInstance().getTmsAddress(); + if (tmsAddress == null || tmsAddress.trim().isEmpty()) { + LogUtil.e(TAG, "TMS address is empty"); + return; + } + + String downloadBase = + tmsAddress.trim() + "/api/v1/file/download?filePath="; + + String certUrl = + SystemParamsOperation.getInstance().getCertificateUrl(); + String clientCertUrl = + SystemParamsOperation.getInstance().getCertificateClientUrl(); + + if (certUrl == null || clientCertUrl == null) { + LogUtil.e(TAG, "Certificate URLs are missing"); + return; + } + + String timestamp = String.valueOf(System.currentTimeMillis()); + String signature = generateSignature(timestamp); + + LogUtil.d(TAG, "Download base => " + downloadBase); + LogUtil.d(TAG, "Cert URL => " + certUrl); + LogUtil.d(TAG, "Client Cert URL => " + clientCertUrl); + + // ---------- CA CERT ---------- + DownloadUtil.downloadCertificateRx( + downloadBase + certUrl, + "refund_ca_" + timestamp, // IMPORTANT: unique filename + timestamp, + signature, + path -> { + if (path != null) { + SystemParamsOperation.getInstance() + .setCertFilePath(path); + LogUtil.d(TAG, "CA cert saved => " + path); + } else { + LogUtil.e(TAG, "Failed to download CA cert"); + } } - } - ); - DownloadUtil.downloadCertificateRx( - downloadAddress + certificate_client, - CERTIFICATE_CLIENT, - timestamp, - signature, - path -> { - if(path != null){ - SystemParamsOperation.getInstance().setCertClientFilePath(path); - LogUtil.d(TAG, "Cert client file path saved in SystemParams => " + path); - }else{ - LogUtil.e(TAG, "Failed to download certificate client file"); + ); + + // ---------- CLIENT CERT ---------- + DownloadUtil.downloadCertificateRx( + downloadBase + clientCertUrl, + "refund_client_" + timestamp, // IMPORTANT: unique filename + timestamp, + signature, + path -> { + if (path != null) { + SystemParamsOperation.getInstance() + .setCertClientFilePath(path); + LogUtil.d(TAG, "Client cert saved => " + path); + } else { + LogUtil.e(TAG, "Failed to download client cert"); + } } - } - ); + ); + + } finally { + isUpdating.set(false); + } } private static String generateSignature(String timestamp) { - LogUtil.d(TAG, "timestamp " + timestamp); String bodyString = "{}"; String dataToHash = bodyString + E_RECEIPT_SECRET + timestamp; return EReceiptHelper.sha256(dataToHash); diff --git a/app/src/main/java/com/utsmm/kbz/ui/settings/HostConfigFragment.java b/app/src/main/java/com/utsmm/kbz/ui/settings/HostConfigFragment.java index 690acc6..30a48c1 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/settings/HostConfigFragment.java +++ b/app/src/main/java/com/utsmm/kbz/ui/settings/HostConfigFragment.java @@ -1,34 +1,12 @@ package com.utsmm.kbz.ui.settings; -import static androidx.databinding.DataBindingUtil.getBinding; - -import static com.utsmyanmar.baselib.BaseApplication.sunmiPrinterService; - -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Typeface; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.core.content.res.ResourcesCompat; -import androidx.fragment.app.Fragment; import androidx.lifecycle.ViewModelProvider; -import androidx.recyclerview.widget.LinearLayoutManager; - -import android.os.RemoteException; -import android.text.TextUtils; -import android.util.Log; -import android.view.LayoutInflater; import android.view.View; -import android.view.ViewGroup; -import com.nexgo.oaf.apiv3.APIProxy; -import com.nexgo.oaf.apiv3.DeviceEngine; -import com.nexgo.oaf.apiv3.DeviceInfo; -import com.nexgo.oaf.apiv3.SdkResult; -import com.nexgo.oaf.apiv3.device.printer.AlignEnum; -import com.nexgo.oaf.apiv3.device.printer.GrayLevelEnum; import com.nexgo.oaf.apiv3.device.printer.Printer; import com.utsmm.kbz.BR; import com.utsmm.kbz.R; @@ -37,15 +15,7 @@ import com.utsmm.kbz.databinding.FragmentHostConfigBinding; import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel; import com.utsmyanmar.baselib.fragment.DataBindingFragment; import com.utsmyanmar.baselib.util.DataBindingConfig; -import com.utsmyanmar.baselib.util.DialogCallback; -import com.utsmyanmar.paylibs.PayLibsUtils; -import com.utsmyanmar.paylibs.print.PaperRollStatusCallback; -import com.utsmyanmar.paylibs.print.PrintHelper; -import com.utsmyanmar.paylibs.utils.LogUtil; -import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation; -import com.utsmyanmar.paylibs.utils.print_utils.BitmapUtils; -import java.util.Objects; public class HostConfigFragment extends DataBindingFragment { diff --git a/app/src/main/java/com/utsmm/kbz/ui/settings/HostConfigViewModel.java b/app/src/main/java/com/utsmm/kbz/ui/settings/HostConfigViewModel.java index 3c60f7f..3766ecd 100644 --- a/app/src/main/java/com/utsmm/kbz/ui/settings/HostConfigViewModel.java +++ b/app/src/main/java/com/utsmm/kbz/ui/settings/HostConfigViewModel.java @@ -2,9 +2,12 @@ package com.utsmm.kbz.ui.settings; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; + +import com.utsmm.kbz.BuildConfig; import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation; public class HostConfigViewModel extends ViewModel { + public String appVersion = BuildConfig.VERSION_NAME; public MutableLiveData merchantName = new MutableLiveData<>(); public MutableLiveData merchantPhone = new MutableLiveData<>(); diff --git a/app/src/main/java/com/utsmm/kbz/util/DownloadUtil.java b/app/src/main/java/com/utsmm/kbz/util/DownloadUtil.java index 7213747..dcc5b3b 100644 --- a/app/src/main/java/com/utsmm/kbz/util/DownloadUtil.java +++ b/app/src/main/java/com/utsmm/kbz/util/DownloadUtil.java @@ -52,8 +52,8 @@ public class DownloadUtil { String dynamicFilename, String timestamp, String signature) { - LogUtil.d(TAG, "cert timestamp => " + timestamp); - LogUtil.d(TAG, "cert signature => " + signature); +// LogUtil.d(TAG, "cert timestamp => " + timestamp); +// LogUtil.d(TAG, "cert signature => " + signature); OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(30, java.util.concurrent.TimeUnit.SECONDS) @@ -126,7 +126,7 @@ public class DownloadUtil { case "application/octet-stream": return ".pem"; case "application/x-pkcs12": - return ".p12"; + return ".p12"; default: return ""; } diff --git a/app/src/main/java/com/utsmm/kbz/util/tms/TMSSetupsImpl.java b/app/src/main/java/com/utsmm/kbz/util/tms/TMSSetupsImpl.java index 5353b21..ae3265e 100644 --- a/app/src/main/java/com/utsmm/kbz/util/tms/TMSSetupsImpl.java +++ b/app/src/main/java/com/utsmm/kbz/util/tms/TMSSetupsImpl.java @@ -639,6 +639,7 @@ public class TMSSetupsImpl implements TMSSetups{ continue; } SystemParamsOperation.getInstance().setCertificateClientUrl(data); + } else if (TextUtils.equals(name, "certificate_password")) { SystemParamsOperation.getInstance().setCertificatePassword(data); @@ -649,7 +650,7 @@ public class TMSSetupsImpl implements TMSSetups{ } private static String generateSignature(String apiSecret, String timestamp) { - String bodyString = ""; + String bodyString = "{}"; String dataToHash = bodyString + apiSecret + timestamp; return EReceiptHelper.sha256(dataToHash); } diff --git a/app/src/main/res/layout/fragment_dashboard_screen.xml b/app/src/main/res/layout/fragment_dashboard_screen.xml index 19b3d86..d9db004 100644 --- a/app/src/main/res/layout/fragment_dashboard_screen.xml +++ b/app/src/main/res/layout/fragment_dashboard_screen.xml @@ -81,6 +81,7 @@ app:layout_constraintHorizontal_bias="1.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/bannerCard" + android:paddingBottom="32dp" app:layout_constraintVertical_bias="1.0"> + tools:text="********************************************************"/> + + + diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/di/DatabaseModule.java b/baselib/src/main/java/com/utsmyanmar/baselib/di/DatabaseModule.java index c1a210b..65fb5be 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/di/DatabaseModule.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/di/DatabaseModule.java @@ -449,11 +449,14 @@ public class DatabaseModule { DemoQRApiService demoQRApiService, KPayApiService kPayApiService, KPayRefundApiService kPayRefundApiService, - EReceiptApiService eReceiptApiService + EReceiptApiService eReceiptApiService, + Provider kPayRefundApiProvider ) { return new com.utsmyanmar.baselib.repo.Repository(payDetailDao, siriusApiService, emvDetailDao, - payWaveRepository, demoQRApiService, kPayApiService, kPayRefundApiService, eReceiptApiService); + payWaveRepository, demoQRApiService, kPayApiService, kPayRefundApiService, eReceiptApiService, + kPayRefundApiProvider + ); } @Provides diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java b/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java index b97f7c6..7be62a0 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/di/NetworkModule.java @@ -54,6 +54,7 @@ import dagger.hilt.InstallIn; import dagger.hilt.android.qualifiers.ApplicationContext; import dagger.hilt.components.SingletonComponent; import hu.akarnokd.rxjava3.retrofit.RxJava3CallAdapterFactory; +import okhttp3.ConnectionPool; import okhttp3.OkHttpClient; import okhttp3.logging.HttpLoggingInterceptor; import retrofit2.Retrofit; @@ -389,7 +390,6 @@ public class NetworkModule { //@Reusable //@KPayRefundRetrofit @Provides -@Singleton @KPayRefundRetrofit public Retrofit provideKPayRefundRetrofit(@ApplicationContext Context context) { @@ -408,7 +408,9 @@ public Retrofit provideKPayRefundRetrofit(@ApplicationContext Context context) { Security.addProvider(new BouncyCastleProvider()); String clientPath = SystemParamsOperation.getInstance().getCertClientFilePath(); + LogUtil.d("cert", "ca client path => " + clientPath); String caPath = SystemParamsOperation.getInstance().getCertFilePath(); + LogUtil.d("cert", "capath => " + caPath); if (TextUtils.isEmpty(clientPath) || TextUtils.isEmpty(caPath)) { LogUtil.e("RefundCert", "Certificate files missing."); @@ -450,6 +452,7 @@ public Retrofit provideKPayRefundRetrofit(@ApplicationContext Context context) { .sslSocketFactory(sslContext.getSocketFactory(), x509TrustManager) .addInterceptor(interceptor) .hostnameVerifier((h, s) -> true) + .connectionPool(new ConnectionPool(0, 1, TimeUnit.SECONDS)) .build(); return new Retrofit.Builder() @@ -475,7 +478,6 @@ public Retrofit provideKPayRefundRetrofit(@ApplicationContext Context context) { @Provides - @Singleton public KPayRefundApiService provideKPayRefundApiService(@KPayRefundRetrofit Retrofit retrofit) { return retrofit.create(KPayRefundApiService.class); } diff --git a/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java b/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java index b1947e2..4654e73 100644 --- a/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java +++ b/baselib/src/main/java/com/utsmyanmar/baselib/repo/Repository.java @@ -46,6 +46,7 @@ import java.util.List; import javax.inject.Inject; +import javax.inject.Provider; import io.reactivex.rxjava3.core.Completable; import io.reactivex.rxjava3.core.Flowable; @@ -64,9 +65,11 @@ public class Repository { private DemoQRApiService demoQRApiService; private KPayRefundApiService kPayRefundApiService; + private Provider kPayRefundApiProvider; + private EReceiptApiService eReceiptApiService; @Inject - public Repository(PayDetailDao payDetailDao, SiriusApiService siriusApiService, EmvDetailDao emvDetailDao, PayWaveRepository payWaveRepository, DemoQRApiService demoQRApiService, KPayApiService kPayApiService, KPayRefundApiService kPayRefundApiService, EReceiptApiService eReceiptApiService) { + public Repository(PayDetailDao payDetailDao, SiriusApiService siriusApiService, EmvDetailDao emvDetailDao, PayWaveRepository payWaveRepository, DemoQRApiService demoQRApiService, KPayApiService kPayApiService, KPayRefundApiService kPayRefundApiService, EReceiptApiService eReceiptApiService, Provider kPayRefundApiProvider) { this.payDetailDao = payDetailDao; this.siriusApiService = siriusApiService; this.emvDetailDao = emvDetailDao; @@ -74,6 +77,7 @@ public class Repository { this.demoQRApiService = demoQRApiService; this.kPayApiService = kPayApiService; this.kPayRefundApiService = kPayRefundApiService; + this.kPayRefundApiProvider = kPayRefundApiProvider; this.eReceiptApiService = eReceiptApiService; } @@ -92,7 +96,8 @@ public class Repository { } public Observable kPayRefund(KPayRefund.RefundRequest request) { - return kPayRefundApiService.refundRequest(request); +// return kPayRefundApiService.refundRequest(request); + return kPayRefundApiProvider.get().refundRequest(request); } public Observable demoQRGenerate(DemoQRRequest demoQRRequest) { return demoQRApiService.qrRequest(demoQRRequest); diff --git a/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/BaseXPrint.java b/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/BaseXPrint.java index f5a740a..1c06b98 100644 --- a/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/BaseXPrint.java +++ b/paylibs/src/main/java/com/utsmyanmar/paylibs/print/printx/BaseXPrint.java @@ -740,13 +740,13 @@ public abstract class BaseXPrint { for (PayDetail pay : lists) { - printString("Trans Id: " + pay.getQrTransId()); - printString("Status : " + pay.getTC()); + printString("Trans Id:" + pay.getQrTransId()); + printString("Status :" + pay.getTC()); // printString("Date : " + PrintUtils.getInstance().formatTimestamp(Long.parseLong(pay.getTradeDateAndTime()))); - printString("Date : " + pay.getTransDate()); - printString("Time : " + pay.getTransTime()); + printString("Date :" + pay.getTransDate()); + printString("Time :" + pay.getTransTime()); - printString("Amount : " + "MMK " + PrintUtils.getInstance().getSeparatorOnlyNumberFormat(pay.getAmount())); + printString("Amount :" + "MMK " + PrintUtils.getInstance().getSeparatorOnlyNumberFormat(pay.getAmount())); if (pay.getTransactionType() == TransactionsType.MMQR_REFUND.value) { refundTotal += pay.getAmount(); @@ -1109,7 +1109,7 @@ public abstract class BaseXPrint { printer.appendPrnStr("Secondary Port: " + secHostSecIp[1], fontNormal, AlignEnum.LEFT, false); printer.appendPrnStr("Currency Code : " + sp.getCurrencyType(), fontNormal, AlignEnum.LEFT, false); lineBreak(); - printer.appendPrnStr("App Version : " + getAppVersion(), fontNormal, AlignEnum.LEFT, false); + printer.appendPrnStr("App Version : " + getAppVersion(), fontNormal, AlignEnum.LEFT, false); } }