Merge branch 'merge-latest' into fix_

This commit is contained in:
MooN 2025-12-04 10:37:09 +06:30
commit c18704f031
50 changed files with 2955 additions and 8 deletions

File diff suppressed because one or more lines are too long

View File

@ -15,6 +15,7 @@
<option value="$PROJECT_DIR$/ecr" />
<option value="$PROJECT_DIR$/ecr-service-lib" />
<option value="$PROJECT_DIR$/mpulib" />
<option value="$PROJECT_DIR$/nexdlkey-lib" />
<option value="$PROJECT_DIR$/nexsdk-lib" />
<option value="$PROJECT_DIR$/paylibs" />
<option value="$PROJECT_DIR$/paysdk-lib" />

View File

@ -188,6 +188,7 @@ dependencies {
implementation project(path: ':qrgen-lib')
//// implementation project(path: ':samlSirius')
implementation project(path: ':ecr')
implementation project(path: ':nexdlkey-lib')
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2' // 1.1.2

View File

@ -16,18 +16,25 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.WindowManager;
import android.widget.Toast;
import com.google.android.material.appbar.MaterialToolbar;
import com.google.android.material.navigation.NavigationView;
import com.nexgo.downloadkey.downloadflow.DownloadFEntity;
import com.nexgo.downloadkey.downloadflow.DownloadFlow;
import com.nexgo.downloadkey.downloadflow.DownloadFlowProcessListener;
import com.nexgo.downloadkey.downloadflow.DownloadFlowResultEntity;
import com.nexgo.downloadkey.downloadflow.DownloadResult;
import com.utsmyanmar.baselib.repo.Repository;
import com.utsmyanmar.baselib.ui.AnimationDialog;
import com.utsmyanmar.checkxread.sdk.NexGoSDK;
import com.utsmyanmar.ecr.ECRHelper;
import com.utsmyanmar.paylibs.Constant;
import com.utsmyanmar.paylibs.print.printx.PrintXReceipt;
import com.utsmyanmar.paylibs.utils.POSUtil;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmyanmar.paylibs.utils.enums.TransMenu;
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
@ -126,6 +133,8 @@ public class MainActivity extends AppCompatActivity implements
initSpecialBackHandlingFragments();
}
private void initViewModels() {
sharedViewModel = new ViewModelProvider(this).get(SharedViewModel.class);
}

View File

@ -1,18 +1,24 @@
package com.utsmm.kbz.ui;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.Navigation;
import com.google.gson.Gson;
import com.google.gson.stream.MalformedJsonException;
import com.utsmm.kbz.config.Constants;
import com.nexgo.downloadkey.downloadflow.DownloadFEntity;
import com.nexgo.downloadkey.downloadflow.DownloadFlow;
import com.nexgo.downloadkey.downloadflow.DownloadFlowProcessListener;
import com.nexgo.downloadkey.downloadflow.DownloadFlowResultEntity;
import com.nexgo.downloadkey.downloadflow.DownloadResult;
import com.utsmyanmar.baselib.emv.EmvParamOperation;
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
import com.utsmyanmar.baselib.network.model.sirius.SiriusError;
@ -204,6 +210,16 @@ public class SettingsFragment extends DataBindingFragment {
}
}
public void onInjectKeyClick() {
try {
LogUtil.d(TAG, "Inject Key clicked");
Navigation.findNavController(requireActivity(), R.id.nav_host_fragment)
.navigate(R.id.action_nav_settings_to_injectKeyFragment);
} catch (Exception e) {
LogUtil.e(TAG, "Error navigating to inject key: " + e.getMessage());
}
}
public void onDemoClick() {
try {
boolean newValue = !SystemParamsOperation.getInstance().getDemoStatus();

View File

@ -315,6 +315,7 @@ public class SharedViewModel extends ViewModel {
public void startPrintReceipt(boolean isFirstPrint) {
/*
* First Print is Merchant Copy..

View File

@ -0,0 +1,193 @@
package com.utsmm.kbz.ui.settings;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.nexgo.downloadkey.downloadflow.DownloadFEntity;
import com.nexgo.downloadkey.downloadflow.DownloadFlow;
import com.nexgo.downloadkey.downloadflow.DownloadFlowProcessListener;
import com.nexgo.downloadkey.downloadflow.DownloadFlowResultEntity;
import com.nexgo.downloadkey.downloadflow.DownloadResult;
import com.utsmyanmar.baselib.fragment.DataBindingFragment;
import com.utsmyanmar.baselib.util.DataBindingConfig;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmm.kbz.BR;
import com.utsmm.kbz.R;
import com.utsmm.kbz.databinding.FragmentInjectKeyBinding;
import com.utsmyanmar.paylibs.utils.LogUtil;
import com.utsmm.kbz.util.tms.TMSUtil;
public class InjectKeyFragment extends DataBindingFragment {
private static final String TAG = InjectKeyFragment.class.getSimpleName();
// Data binding will handle view access automatically
private FragmentInjectKeyBinding binding;
// Key injection variables
private DownloadFlow mDownloadFlow;
private int keyIndexTmp = 8; // Default key index
@Override
protected void initViewModel() {
// No specific viewmodels needed for this fragment
}
@Override
protected DataBindingConfig getDataBindingConfig() {
// This is the key method that links the XML and fragment properly
return new DataBindingConfig(R.layout.fragment_inject_key, 0, null)
.addBindingParam(BR.click, new ClickEvent());
}
@Override
protected int currentId() {
return R.id.injectKeyFragment;
}
@Override
protected int hostId() {
return R.id.nav_host_fragment;
}
@Override
protected int routeId() {
return 0;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
try {
// Get the binding from the base class - this is automatically created
binding = (FragmentInjectKeyBinding) mBinding;
updateConfigurationInfo();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onResume() {
super.onResume();
setToolBarTitleWithBackIcon("Inject Key");
}
private void updateConfigurationInfo() {
String terminalId = SystemParamsOperation.getInstance().getTerminalId();
binding.terminalIdValue.setText(terminalId != null && !terminalId.isEmpty() ?
terminalId : "Not configured");
// Update Merchant ID
String merchantId = SystemParamsOperation.getInstance().getMerchantId();
binding.merchantIdValue.setText(merchantId != null && !merchantId.isEmpty() ?
merchantId : "Not configured");
// Update Serial Number
String serialNo = TMSUtil.getInstance().getSerialNumber();
binding.serialNumberValue.setText(serialNo != null && !serialNo.isEmpty() ?
serialNo : "Not configured");
}
private void loadKeyFromKeyPOS() {
try {
if (TextUtils.isEmpty(binding.etKeyIndex.getText())) {
Toast.makeText(getContext(), "Please input key index", Toast.LENGTH_SHORT).show();
return;
}
String keyIndexText = binding.etKeyIndex.getText().toString().trim();
try {
keyIndexTmp = Integer.parseInt(keyIndexText);
} catch (NumberFormatException e) {
Toast.makeText(getContext(), "Invalid key index format", Toast.LENGTH_SHORT).show();
return;
}
showLoadingDialog("Loading key...");
mDownloadFlow = DownloadFlow.getInstance();
String terminalId = SystemParamsOperation.getInstance().getTerminalId();
String merchantId = SystemParamsOperation.getInstance().getMerchantId();
String serialNo = TMSUtil.getInstance().getSerialNumber();
// Validate configuration
if (TextUtils.isEmpty(terminalId) || TextUtils.isEmpty(merchantId) || TextUtils.isEmpty(serialNo)) {
dismissLoadingDialog();
showDeclineDialog("Please configure Terminal ID, Merchant ID first in TMS Configuration");
return;
}
final DownloadFEntity downloadFEntity = new DownloadFEntity();
downloadFEntity.setSn(serialNo.getBytes());
downloadFEntity.setMid(merchantId.getBytes());
downloadFEntity.setTid(terminalId.getBytes());
downloadFEntity.setTmkIndex(keyIndexTmp);
downloadFEntity.setPort(0);
downloadFEntity.setTimeOut(10);
int result = mDownloadFlow.startLoadKey(getActivity(), downloadFEntity, onDownloadFlowProcessListener);
if (result != DownloadResult.Success) {
dismissLoadingDialog();
showDeclineDialog("Failed to start key injection process");
LogUtil.e(TAG, "Failed to start key injection, result: " + result);
}
} catch (Exception e) {
dismissLoadingDialog();
LogUtil.e(TAG, "Error in key injection: " + e.getMessage());
showDeclineDialog("Error occurred during key injection: " + e.getMessage());
}
}
private DownloadFlowProcessListener onDownloadFlowProcessListener = new DownloadFlowProcessListener() {
@Override
public void onFinish(int ret, DownloadFlowResultEntity downloadFlowResultEntity) {
try {
dismissLoadingDialog();
if (ret == DownloadResult.Success) {
// Show success dialog with key index
showSuccessDialog("Key injection successful!\nKey Index: " + keyIndexTmp);
LogUtil.d(TAG, "Key injection successful for index: " + keyIndexTmp);
} else {
// Show decline dialog
showDeclineDialog("Key injection failed!\nError code: " + ret);
LogUtil.e(TAG, "Key injection failed with error code: " + ret);
}
} catch (Exception e) {
LogUtil.e(TAG, "Error handling injection result: " + e.getMessage());
showDeclineDialog("Error processing injection result");
}
}
};
// ClickEvent class for data binding - this is the proper pattern
public class ClickEvent {
public void onInjectKeyClick() {
try {
LogUtil.d(TAG, "Inject key button clicked");
loadKeyFromKeyPOS();
} catch (Exception e) {
LogUtil.e(TAG, "Error in inject key click: " + e.getMessage());
showDeclineDialog("Error occurred: " + e.getMessage());
}
}
}
}

View File

@ -143,25 +143,38 @@ public class EReceiptUtil {
EReceiptRequest request = new EReceiptRequest();
request.setDE3(convertTransactionType(payDetail.getTransactionType()));
request.setDE7(currentTimeStamp);
request.setDE11(payDetail.getVoucherNo());
if(payDetail.getTransactionType() == TransactionsType.SETTLEMENT.value) {
SettleData settleData = payDetail.getSettleDataObj();
long totalAmt = settleData.getSaleAmount() + settleData.getRefundAmount() + settleData.getPreAuthCompAmount() + settleData.getCashAdvanceAmount();
double realTotalAmount = totalAmt / 100.0;
String totalAmount = df.format(realTotalAmount);
request.setDE4(totalAmount);
request.setDE63_01(settleData.getSaleCount()+"");
request.setDE63_02(settleData.getSaleAmount()+"");
request.setDE63_03(settleData.getRefundCount()+"");
request.setDE63_04(settleData.getRefundAmount()+"");
request.setDE63_05(settleData.getPreAuthCompCount()+"");
request.setDE63_06(settleData.getPreAuthCompAmount()+"");
request.setDE63_07(settleData.getCashAdvanceCount()+"");
request.setDE63_08(settleData.getCashAdvanceAmount()+"");
invoiceNo = SystemParamsOperation.getInstance().getIncrementInvoiceNum();
request.setBatchNumber(batchNumber);
request.setInvoiceNumber(invoiceNo);
request.setDescription("success");
request.setDE39("A");
request.setDE37("0000");
request.setDE49("MMK");
} 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());

View File

@ -310,6 +310,80 @@
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/injectKeyCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground"
android:onClick="@{()->click.onInjectKeyClick()}"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="16dp"
app:cardElevation="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="20dp">
<androidx.cardview.widget.CardView
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginEnd="16dp"
app:cardBackgroundColor="@color/colorPrimary"
app:cardCornerRadius="24dp"
app:cardElevation="0dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center"
android:src="@drawable/ic_key_index"
app:tint="@color/white" />
</androidx.cardview.widget.CardView>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/rubik_medium"
android:text="Inject Key"
android:textColor="@color/colorTextTitle"
android:textSize="18sp"
android:textStyle="bold"
tools:fontFamily="sans-serif-medium" />
<TextView
android:id="@+id/injectKeyText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:fontFamily="@font/rubik_regular"
android:text="Click to inject"
android:textColor="@color/colorTextContent"
android:textSize="14sp"
tools:fontFamily="sans-serif" />
</LinearLayout>
<ImageView
android:layout_width="20dp"
android:layout_height="20dp"
android:src="@drawable/ic_right_arrow"
app:tint="@color/colorPrimary" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- &lt;!&ndash; Demo Mode Card &ndash;&gt;-->

View File

@ -65,6 +65,9 @@
<action
android:id="@+id/action_nav_settings_to_hostConfigFragment"
app:destination="@id/hostConfigFragment"/>
<action
android:id="@+id/action_nav_settings_to_injectKeyFragment"
app:destination="@id/injectKeyFragment" />
</fragment>
@ -297,6 +300,12 @@
android:name="com.utsmm.kbz.ui.settings.ConfigSettingsFragment"
android:label="ConfigSettingsFragment" />
<fragment
android:id="@+id/injectKeyFragment"
android:name="com.utsmm.kbz.ui.settings.InjectKeyFragment"
android:label="InjectKeyFragment"
tools:layout="@layout/fragment_inject_key" />
<fragment
tools:layout="@layout/fragment_password_screen"
android:id="@+id/inputPasswordFragment"

View File

@ -86,6 +86,7 @@ dependencies {
implementation project(path: ':paysdk-lib')
implementation project(path: ':nexsdk-lib')
implementation project(path: ':xpay')
implementation project(path: ':nexdlkey-lib')
// implementation 'com.sunmi:printerlibrary:1.0.9'
implementation 'com.sunmi:printerlibrary:1.0.23'

View File

@ -21,6 +21,10 @@ public class EReceiptRequest {
private String DE63_02;
private String DE63_03;
private String DE63_04;
private String DE63_05;
private String DE63_06;
private String DE63_07;
private String DE63_08;
private String serial;
private String appId;
@ -120,6 +124,32 @@ public class EReceiptRequest {
return batchNumber;
}
public String getDE63_05() {
return DE63_05;
}
public String getDE63_06() {
return DE63_06;
}
public String getDE63_07() {
return DE63_07;
}
public String getDE63_08() {
return DE63_08;
}
public void setDE63_05(String DE63_05) {
this.DE63_05 = DE63_05;
}
public void setDE63_06(String DE63_06) {
this.DE63_06 = DE63_06;
}
public void setDE63_07(String DE63_07) {
this.DE63_07 = DE63_07;
}
public void setDE63_08(String DE63_08) {
this.DE63_08 = DE63_08;
}
public void setBatchNumber(String batchNumber) {
this.batchNumber = batchNumber;
}

0
gradlew vendored Normal file → Executable file
View File

View File

@ -0,0 +1,2 @@
configurations.maybeCreate("default")
artifacts.add("default", file('nexgo-sdk-dlkey-1.0.2.aar'))

View File

@ -0,0 +1 @@
i/jars/classes.jar

View File

@ -0,0 +1 @@
o/nexgo-sdk-dlkey-1.0.2-runtime

View File

@ -0,0 +1 @@
o/nexgo-sdk-dlkey-1.0.2

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nexgo.downloadkey"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="21"
android:targetSdkVersion="26" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true" >
</application>
</manifest>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">downloadkey</string>
</resources>

View File

@ -0,0 +1 @@
i/AndroidManifest.xml

View File

@ -0,0 +1 @@
o/nexgo-sdk-dlkey-1.0.2-api.jar

View File

@ -0,0 +1 @@
o/com.nexgo.downloadkey-r.txt

View File

@ -0,0 +1 @@
o/com.nexgo.downloadkey

View File

@ -0,0 +1 @@
o/nexgo-sdk-dlkey-1.0.2-runtime.jar

Binary file not shown.

View File

@ -63,6 +63,7 @@ dependencies {
// implementation project(path:':PayLib-release-1.4.58')
implementation project(path: ':nexsdk-lib')
implementation project(path: ':paysdk-lib')
implementation project(path: ':nexdlkey-lib')
// implementation project(path: ':sunmiui-lib')
testImplementation 'junit:junit:4.13.2'

View File

@ -9,6 +9,7 @@ import android.os.Build;
import android.os.RemoteException;
import android.text.TextUtils;
import com.nexgo.oaf.apiv3.SdkResult;
import com.nexgo.oaf.apiv3.device.printer.AlignEnum;
import com.nexgo.oaf.apiv3.device.printer.DotMatrixFontEnum;
import com.nexgo.oaf.apiv3.device.printer.FontEntity;
@ -847,6 +848,11 @@ public abstract class BaseXPrint {
}
protected void startPrintNex() {
if(printer.getStatus() != SdkResult.Success) {
callbackStatus.onFailure();
}
printer.startPrint(true, new OnPrintListener() {
@Override
public void onPrintResult(final int retCode) {

View File

@ -123,7 +123,7 @@ public class SignOnProcess {
SystemParamsOperation.getInstance().saveKeyPIK(encryptedPIK, kcv);
int res = PayLibNex.getInstance().deviceEngine.getPinPad().writeWKey(9, WorkKeyTypeEnum.PINKEY,encryptedPIK,encryptedPIK.length);
int res = PayLibNex.getInstance().deviceEngine.getPinPad().writeWKey(tmkIndex, WorkKeyTypeEnum.PINKEY,encryptedPIK,encryptedPIK.length);
// int res = PayLibsUtils.getInstance().securityOptV2.saveCiphertextKey(AidlConstantsV2.Security.KEY_TYPE_PIK, encryptedPIK, null, tmkIndex, AidlConstantsV2.Security.KEY_ALG_TYPE_3DES, 11);
// resultCode = res;
if (res < 0) {
@ -170,7 +170,7 @@ public class SignOnProcess {
}
LogUtil.d(TAG, "TMK Index:" + tmkIndex);
int res = PayLibNex.getInstance().deviceEngine.getPinPad().writeWKey(9, WorkKeyTypeEnum.PINKEY,encryptedPIK,encryptedPIK.length);
int res = PayLibNex.getInstance().deviceEngine.getPinPad().writeWKey(tmkIndex, WorkKeyTypeEnum.PINKEY,encryptedPIK,encryptedPIK.length);
// int res = PayLibsUtils.getInstance().securityOptV2.saveCiphertextKey(AidlConstantsV2.Security.KEY_TYPE_PIK, encryptedPIK, null, tmkIndex, AidlConstantsV2.Security.KEY_ALG_TYPE_3DES, 11);
resultCode = res;
if (res < 0) {

View File

@ -33,3 +33,4 @@ include ':xpay'
include ':ecr'
include ':ecr-service-lib'
include ':qrgen-lib'
include ':nexdlkey-lib'