fix injection

This commit is contained in:
moon 2026-03-31 00:12:05 +06:30
parent d143e49e4b
commit f63f10e834
5 changed files with 260 additions and 642 deletions

View File

@ -4,25 +4,18 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.os.Bundle; import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
import android.os.RemoteException; import android.os.RemoteException;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.util.TypedValue;
import android.view.View; import android.view.View;
import android.view.Gravity;
import android.widget.Toast; import android.widget.Toast;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.appcompat.widget.AppCompatButton;
import androidx.core.content.ContextCompat;
import com.denzcoskun.imageslider.ImageSlider; import com.denzcoskun.imageslider.ImageSlider;
import com.denzcoskun.imageslider.constants.ScaleTypes; import com.denzcoskun.imageslider.constants.ScaleTypes;
@ -65,6 +58,7 @@ import com.utsmm.kbz.ui.core_viewmodel.TMSProcessViewModel;
import com.utsmm.kbz.util.Connectivity; import com.utsmm.kbz.util.Connectivity;
import com.utsmm.kbz.util.CurrencySelectionHelper;
import com.utsmm.kbz.util.dialog.AlertXDialog; import com.utsmm.kbz.util.dialog.AlertXDialog;
import com.utsmm.kbz.util.enums.SettlementType; import com.utsmm.kbz.util.enums.SettlementType;
import com.utsmm.kbz.util.ecr.CoreUtils; import com.utsmm.kbz.util.ecr.CoreUtils;
@ -77,7 +71,6 @@ import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@ -107,13 +100,7 @@ public class MainFragment extends DataBindingFragment {
private final ArrayList<SlideModel> imgList = new ArrayList<>(); private final ArrayList<SlideModel> imgList = new ArrayList<>();
private Observer<PayDetail> observeLastTrans; private Observer<PayDetail> observeLastTrans;
private PayDetail lastPay; private PayDetail lastPay;
private boolean cardPrimaryHostCached = false; private CurrencySelectionHelper currencySelectionHelper;
private String cardPrimaryHostName = "";
private String cardPrimaryTid = "";
private String cardPrimaryMid = "";
private String cardPrimaryIp = "";
private String cardPrimarySecIp = "";
private CurrencyType cardPrimaryCurrency = CurrencyType.MMK;
@Inject @Inject
EmvParamOperation emvParamOperation; EmvParamOperation emvParamOperation;
@ -138,6 +125,7 @@ public class MainFragment extends DataBindingFragment {
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class); sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
mainViewModel = getFragmentScopeViewModel(MainViewModel.class); mainViewModel = getFragmentScopeViewModel(MainViewModel.class);
tmsProcessViewModel = getFragmentScopeViewModel(TMSProcessViewModel.class); tmsProcessViewModel = getFragmentScopeViewModel(TMSProcessViewModel.class);
currencySelectionHelper = new CurrencySelectionHelper(this, sharedViewModel);
// Initialize ModernECRManager // Initialize ModernECRManager
// ModernECRFactory factory = new ModernECRFactory(requireContext(), sharedViewModel); // ModernECRFactory factory = new ModernECRFactory(requireContext(), sharedViewModel);
@ -446,43 +434,11 @@ public class MainFragment extends DataBindingFragment {
} }
private void showCurrencyChooserForCardSale() { private void showCurrencyChooserForCardSale() {
List<String> currencies = getAvailableCardSaleCurrencies(); currencySelectionHelper.showCardCurrencyChooser(this::startCardSaleFlow);
if (currencies.isEmpty()) {
applyCardCurrencyAndHost("MMK");
startCardSaleFlow();
return;
}
if (currencies.size() == 1) {
applyCardCurrencyAndHost(currencies.get(0));
startCardSaleFlow();
return;
}
showCurrencyPickerDialog("Choose Currency", currencies, currency -> {
applyCardCurrencyAndHost(currency);
startCardSaleFlow();
});
} }
private void showCurrencyChooserForSignOn() { private void showCurrencyChooserForSignOn() {
List<String> currencies = getAvailableCardSaleCurrencies(); currencySelectionHelper.showCardCurrencyChooser(this::navigateToSignOn);
if (currencies.isEmpty()) {
applyCardCurrencyAndHost("MMK");
navigateToSignOn();
return;
}
if (currencies.size() == 1) {
applyCardCurrencyAndHost(currencies.get(0));
navigateToSignOn();
return;
}
showCurrencyPickerDialog("Choose Currency", currencies, currency -> {
applyCardCurrencyAndHost(currency);
navigateToSignOn();
});
} }
private void navigateToSignOn() { private void navigateToSignOn() {
@ -490,178 +446,6 @@ public class MainFragment extends DataBindingFragment {
safeNavigateToRouteId(); safeNavigateToRouteId();
} }
private List<String> getAvailableCardSaleCurrencies() {
cachePrimaryCardHostIfNeeded();
LinkedHashSet<String> values = new LinkedHashSet<>();
if (cardPrimaryCurrency != null && !TextUtils.isEmpty(cardPrimaryCurrency.name)) {
values.add(normalizeCurrency(cardPrimaryCurrency.name));
}
if (!SystemParamsOperation.getInstance().getDuelCurrencyStatus()) {
return new ArrayList<>(values);
}
String secondaryCurrency = normalizeCurrency(SystemParamsOperation.getInstance().getThirdHostCurrency());
if (!TextUtils.isEmpty(SystemParamsOperation.getInstance().getThirdHostName()) && !TextUtils.isEmpty(secondaryCurrency)) {
values.add(secondaryCurrency);
}
return new ArrayList<>(values);
}
private void applyCardCurrencyAndHost(String selectedCurrency) {
cachePrimaryCardHostIfNeeded();
String selected = normalizeCurrency(selectedCurrency);
String secondaryCurrency = normalizeCurrency(SystemParamsOperation.getInstance().getThirdHostCurrency());
boolean dualCurrencyEnabled = SystemParamsOperation.getInstance().getDuelCurrencyStatus();
boolean useSecondaryCardHost = dualCurrencyEnabled
&& !TextUtils.isEmpty(SystemParamsOperation.getInstance().getThirdHostName())
&& !TextUtils.isEmpty(secondaryCurrency)
&& secondaryCurrency.equals(selected);
if (useSecondaryCardHost) {
SystemParamsOperation.getInstance().setHostName(SystemParamsOperation.getInstance().getThirdHostName());
SystemParamsOperation.getInstance().setTerminalId(SystemParamsOperation.getInstance().getThirdHostTerminalId());
SystemParamsOperation.getInstance().setMerchantId(SystemParamsOperation.getInstance().getThirdHostMerchantId());
SystemParamsOperation.getInstance().setIpAddress(SystemParamsOperation.getInstance().getThirdHostIpAddress());
SystemParamsOperation.getInstance().setSecIpAddress(SystemParamsOperation.getInstance().getThirdHostSecIpAddress());
} else {
SystemParamsOperation.getInstance().setHostName(cardPrimaryHostName);
SystemParamsOperation.getInstance().setTerminalId(cardPrimaryTid);
SystemParamsOperation.getInstance().setMerchantId(cardPrimaryMid);
SystemParamsOperation.getInstance().setIpAddress(cardPrimaryIp);
SystemParamsOperation.getInstance().setSecIpAddress(cardPrimarySecIp);
}
CurrencyType currencyType = useSecondaryCardHost ? toCurrencyType(selected) : cardPrimaryCurrency;
SystemParamsOperation.getInstance().setCurrencyType(currencyType);
sharedViewModel.set_currencyText(currencyType.name);
}
private void cachePrimaryCardHostIfNeeded() {
if (cardPrimaryHostCached) {
return;
}
cardPrimaryHostName = SystemParamsOperation.getInstance().getHostName();
cardPrimaryTid = SystemParamsOperation.getInstance().getTerminalId();
cardPrimaryMid = SystemParamsOperation.getInstance().getMerchantId();
cardPrimaryIp = SystemParamsOperation.getInstance().getIpAddress();
cardPrimarySecIp = SystemParamsOperation.getInstance().getSecIpAddress();
CurrencyType activeCurrency = SystemParamsOperation.getInstance().getCurrencyType();
cardPrimaryCurrency = activeCurrency == null ? CurrencyType.MMK : activeCurrency;
cardPrimaryHostCached = true;
}
private void showCurrencyPickerDialog(String title, List<String> currencies, CurrencySelectCallback callback) {
LinearLayout root = new LinearLayout(requireContext());
root.setOrientation(LinearLayout.VERTICAL);
root.setPadding(dp(20), dp(20), dp(20), dp(12));
TextView tvTitle = new TextView(requireContext());
tvTitle.setText(title);
tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
tvTitle.setTextColor(ContextCompat.getColor(requireContext(), R.color.colorTextTitle));
tvTitle.setPadding(0, 0, 0, dp(16));
root.addView(tvTitle);
final AlertDialog[] dialogHolder = new AlertDialog[1];
for (String currency : currencies) {
AppCompatButton button = new AppCompatButton(requireContext());
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
dp(56)
);
lp.bottomMargin = dp(10);
button.setLayoutParams(lp);
button.setAllCaps(false);
button.setText(currency);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
button.setGravity(Gravity.CENTER);
button.setBackgroundResource(R.drawable.bg_rounded_btn_cv);
button.setTextColor(ContextCompat.getColor(requireContext(), R.color.white));
button.setOnClickListener(v -> {
if (dialogHolder[0] != null) {
dialogHolder[0].dismiss();
}
callback.onSelected(currency);
});
root.addView(button);
}
AppCompatButton cancel = new AppCompatButton(requireContext());
LinearLayout.LayoutParams cancelLp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
dp(52)
);
cancel.setLayoutParams(cancelLp);
cancel.setAllCaps(false);
cancel.setText("Cancel");
cancel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
cancel.setBackgroundResource(R.drawable.bg_rounded_btn_cancel_cv);
cancel.setTextColor(ContextCompat.getColor(requireContext(), R.color.colorPrimary));
cancel.setOnClickListener(v -> {
if (dialogHolder[0] != null) {
dialogHolder[0].dismiss();
}
});
root.addView(cancel);
AlertDialog dialog = new AlertDialog.Builder(requireContext())
.setView(root)
.create();
dialogHolder[0] = dialog;
dialog.show();
}
private int dp(int value) {
return Math.round(value * requireContext().getResources().getDisplayMetrics().density);
}
private interface CurrencySelectCallback {
void onSelected(String currency);
}
private CurrencyType toCurrencyType(String value) {
String normalized = normalizeCurrency(value);
try {
return CurrencyType.valueOf(normalized);
} catch (Exception ignored) {
return CurrencyType.MMK;
}
}
private String normalizeCurrency(String raw) {
if (TextUtils.isEmpty(raw)) {
return "";
}
String value = raw.trim().toUpperCase();
switch (value) {
case "104":
case "MMK":
return "MMK";
case "840":
case "USD":
return "USD";
case "156":
case "CNY":
case "RMB":
return "CNY";
case "764":
case "THB":
return "THB";
case "643":
case "RUB":
return "RUB";
default:
return value;
}
}
private void processBatch() { private void processBatch() {
calculateLastTransaction(); calculateLastTransaction();

View File

@ -2,25 +2,16 @@ package com.utsmm.kbz.ui.dashboard;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.View; import android.view.View;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.AppCompatButton;
import androidx.core.content.ContextCompat;
import com.utsmm.kbz.util.enums.SettlementType; import com.utsmm.kbz.util.enums.SettlementType;
import com.utsmyanmar.baselib.fragment.DataBindingFragment; import com.utsmyanmar.baselib.fragment.DataBindingFragment;
import com.utsmyanmar.baselib.util.DataBindingConfig; import com.utsmyanmar.baselib.util.DataBindingConfig;
import com.utsmyanmar.paylibs.utils.LogUtil; import com.utsmyanmar.paylibs.utils.LogUtil;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation; import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmyanmar.paylibs.utils.enums.CurrencyType;
import com.utsmyanmar.paylibs.utils.enums.TransMenu; import com.utsmyanmar.paylibs.utils.enums.TransMenu;
import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType; import com.utsmyanmar.paylibs.utils.iso_utils.TransactionsType;
import com.utsmm.kbz.BR; import com.utsmm.kbz.BR;
@ -30,28 +21,21 @@ import com.utsmm.kbz.config.Constants;
import com.utsmm.kbz.config.data.model.Features; import com.utsmm.kbz.config.data.model.Features;
import com.utsmm.kbz.ui.adapters.MainAdapter; import com.utsmm.kbz.ui.adapters.MainAdapter;
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel; import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
import com.utsmm.kbz.util.CurrencySelectionHelper;
import com.utsmm.kbz.util.tms.TMSUtil; import com.utsmm.kbz.util.tms.TMSUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
public class DashboardTransFragment extends DataBindingFragment { public class DashboardTransFragment extends DataBindingFragment {
private MainViewModel mainViewModel; private MainViewModel mainViewModel;
private SharedViewModel sharedViewModel; private SharedViewModel sharedViewModel;
private CurrencySelectionHelper currencySelectionHelper;
private ArrayList<Features> featuresList = new ArrayList<>(); private ArrayList<Features> featuresList = new ArrayList<>();
MainAdapter mainAdapter; MainAdapter mainAdapter;
private boolean cardPrimaryHostCached = false;
private String cardPrimaryHostName = "";
private String cardPrimaryTid = "";
private String cardPrimaryMid = "";
private String cardPrimaryIp = "";
private String cardPrimarySecIp = "";
private CurrencyType cardPrimaryCurrency = CurrencyType.MMK;
private static final int hostId = Constants.NAV_HOST_ID; private static final int hostId = Constants.NAV_HOST_ID;
private int routeId; private int routeId;
@ -76,6 +60,7 @@ public class DashboardTransFragment extends DataBindingFragment {
protected void initViewModel() { protected void initViewModel() {
mainViewModel = getFragmentScopeViewModel(MainViewModel.class); mainViewModel = getFragmentScopeViewModel(MainViewModel.class);
sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class); sharedViewModel = getFragmentScopeViewModel(SharedViewModel.class);
currencySelectionHelper = new CurrencySelectionHelper(this, sharedViewModel);
} }
@Override @Override
@ -288,195 +273,7 @@ public class DashboardTransFragment extends DataBindingFragment {
} }
private void showCurrencyChooserForCardFlow(Runnable onSelected) { private void showCurrencyChooserForCardFlow(Runnable onSelected) {
List<String> currencies = getAvailableCardSaleCurrencies(); currencySelectionHelper.showCardCurrencyChooser(onSelected);
if (currencies.isEmpty()) {
applyCardCurrencyAndHost("MMK");
onSelected.run();
return;
}
if (currencies.size() == 1) {
applyCardCurrencyAndHost(currencies.get(0));
onSelected.run();
return;
}
showCurrencyPickerDialog("Choose Currency", currencies, currency -> {
applyCardCurrencyAndHost(currency);
onSelected.run();
});
}
private List<String> getAvailableCardSaleCurrencies() {
cachePrimaryCardHostIfNeeded();
LinkedHashSet<String> values = new LinkedHashSet<>();
if (cardPrimaryCurrency != null && !TextUtils.isEmpty(cardPrimaryCurrency.name)) {
values.add(normalizeCurrency(cardPrimaryCurrency.name));
}
if (!SystemParamsOperation.getInstance().getDuelCurrencyStatus()) {
return new ArrayList<>(values);
}
String secondaryCurrency = normalizeCurrency(SystemParamsOperation.getInstance().getThirdHostCurrency());
if (!TextUtils.isEmpty(SystemParamsOperation.getInstance().getThirdHostName()) && !TextUtils.isEmpty(secondaryCurrency)) {
values.add(secondaryCurrency);
}
return new ArrayList<>(values);
}
private void applyCardCurrencyAndHost(String selectedCurrency) {
cachePrimaryCardHostIfNeeded();
String selected = normalizeCurrency(selectedCurrency);
String secondaryCurrency = normalizeCurrency(SystemParamsOperation.getInstance().getThirdHostCurrency());
boolean dualCurrencyEnabled = SystemParamsOperation.getInstance().getDuelCurrencyStatus();
boolean useSecondaryCardHost = dualCurrencyEnabled
&& !TextUtils.isEmpty(SystemParamsOperation.getInstance().getThirdHostName())
&& !TextUtils.isEmpty(secondaryCurrency)
&& secondaryCurrency.equals(selected);
if (useSecondaryCardHost) {
SystemParamsOperation.getInstance().setHostName(SystemParamsOperation.getInstance().getThirdHostName());
SystemParamsOperation.getInstance().setTerminalId(SystemParamsOperation.getInstance().getThirdHostTerminalId());
SystemParamsOperation.getInstance().setMerchantId(SystemParamsOperation.getInstance().getThirdHostMerchantId());
SystemParamsOperation.getInstance().setIpAddress(SystemParamsOperation.getInstance().getThirdHostIpAddress());
SystemParamsOperation.getInstance().setSecIpAddress(SystemParamsOperation.getInstance().getThirdHostSecIpAddress());
} else {
SystemParamsOperation.getInstance().setHostName(cardPrimaryHostName);
SystemParamsOperation.getInstance().setTerminalId(cardPrimaryTid);
SystemParamsOperation.getInstance().setMerchantId(cardPrimaryMid);
SystemParamsOperation.getInstance().setIpAddress(cardPrimaryIp);
SystemParamsOperation.getInstance().setSecIpAddress(cardPrimarySecIp);
}
CurrencyType currencyType = useSecondaryCardHost ? toCurrencyType(selected) : cardPrimaryCurrency;
SystemParamsOperation.getInstance().setCurrencyType(currencyType);
sharedViewModel.set_currencyText(currencyType.name);
}
private void cachePrimaryCardHostIfNeeded() {
if (cardPrimaryHostCached) {
return;
}
cardPrimaryHostName = SystemParamsOperation.getInstance().getHostName();
cardPrimaryTid = SystemParamsOperation.getInstance().getTerminalId();
cardPrimaryMid = SystemParamsOperation.getInstance().getMerchantId();
cardPrimaryIp = SystemParamsOperation.getInstance().getIpAddress();
cardPrimarySecIp = SystemParamsOperation.getInstance().getSecIpAddress();
CurrencyType activeCurrency = SystemParamsOperation.getInstance().getCurrencyType();
cardPrimaryCurrency = activeCurrency == null ? CurrencyType.MMK : activeCurrency;
cardPrimaryHostCached = true;
}
private CurrencyType toCurrencyType(String value) {
String normalized = normalizeCurrency(value);
try {
return CurrencyType.valueOf(normalized);
} catch (Exception ignored) {
return CurrencyType.MMK;
}
}
private String normalizeCurrency(String raw) {
if (TextUtils.isEmpty(raw)) {
return "";
}
String value = raw.trim().toUpperCase();
switch (value) {
case "104":
case "MMK":
return "MMK";
case "840":
case "USD":
return "USD";
case "156":
case "CNY":
case "RMB":
return "CNY";
case "764":
case "THB":
return "THB";
case "643":
case "RUB":
return "RUB";
default:
return value;
}
}
private void showCurrencyPickerDialog(String title, List<String> currencies, CurrencySelectCallback callback) {
LinearLayout root = new LinearLayout(requireContext());
root.setOrientation(LinearLayout.VERTICAL);
root.setPadding(dp(20), dp(20), dp(20), dp(12));
TextView tvTitle = new TextView(requireContext());
tvTitle.setText(title);
tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
tvTitle.setTextColor(ContextCompat.getColor(requireContext(), R.color.colorTextTitle));
tvTitle.setPadding(0, 0, 0, dp(16));
root.addView(tvTitle);
final AlertDialog[] dialogHolder = new AlertDialog[1];
for (String currency : currencies) {
AppCompatButton button = new AppCompatButton(requireContext());
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
dp(56)
);
lp.bottomMargin = dp(10);
button.setLayoutParams(lp);
button.setAllCaps(false);
button.setText(currency);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
button.setGravity(Gravity.CENTER);
button.setBackgroundResource(R.drawable.bg_rounded_btn_cv);
button.setTextColor(ContextCompat.getColor(requireContext(), R.color.white));
button.setOnClickListener(v -> {
if (dialogHolder[0] != null) {
dialogHolder[0].dismiss();
}
callback.onSelected(currency);
});
root.addView(button);
}
AppCompatButton cancel = new AppCompatButton(requireContext());
LinearLayout.LayoutParams cancelLp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
dp(52)
);
cancel.setLayoutParams(cancelLp);
cancel.setAllCaps(false);
cancel.setText("Cancel");
cancel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
cancel.setBackgroundResource(R.drawable.bg_rounded_btn_cancel_cv);
cancel.setTextColor(ContextCompat.getColor(requireContext(), R.color.colorPrimary));
cancel.setOnClickListener(v -> {
if (dialogHolder[0] != null) {
dialogHolder[0].dismiss();
}
});
root.addView(cancel);
AlertDialog dialog = new AlertDialog.Builder(requireContext())
.setView(root)
.create();
dialogHolder[0] = dialog;
dialog.show();
}
private int dp(int value) {
return Math.round(value * requireContext().getResources().getDisplayMetrics().density);
}
private interface CurrencySelectCallback {
void onSelected(String currency);
} }
} }

View File

@ -3,7 +3,6 @@ package com.utsmm.kbz.ui.settings;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.View; import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Toast; import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
@ -16,16 +15,12 @@ import com.nexgo.downloadkey.downloadflow.DownloadFlowResultEntity;
import com.nexgo.downloadkey.downloadflow.DownloadResult; import com.nexgo.downloadkey.downloadflow.DownloadResult;
import com.utsmyanmar.baselib.fragment.DataBindingFragment; import com.utsmyanmar.baselib.fragment.DataBindingFragment;
import com.utsmyanmar.baselib.util.DataBindingConfig; import com.utsmyanmar.baselib.util.DataBindingConfig;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmm.kbz.BR; import com.utsmm.kbz.BR;
import com.utsmm.kbz.R; import com.utsmm.kbz.R;
import com.utsmm.kbz.databinding.FragmentInjectKeyBinding; import com.utsmm.kbz.databinding.FragmentInjectKeyBinding;
import com.utsmyanmar.paylibs.utils.LogUtil; import com.utsmyanmar.paylibs.utils.LogUtil;
import com.utsmm.kbz.util.tms.TMSUtil; import com.utsmm.kbz.util.tms.TMSUtil;
import java.util.ArrayList;
import java.util.List;
public class InjectKeyFragment extends DataBindingFragment { public class InjectKeyFragment extends DataBindingFragment {
private static final String TAG = InjectKeyFragment.class.getSimpleName(); private static final String TAG = InjectKeyFragment.class.getSimpleName();
@ -36,8 +31,6 @@ public class InjectKeyFragment extends DataBindingFragment {
// Key injection variables // Key injection variables
private DownloadFlow mDownloadFlow; private DownloadFlow mDownloadFlow;
private int keyIndexTmp = 8; // Default key index private int keyIndexTmp = 8; // Default key index
private final List<HostSelectionItem> hostSelectionItems = new ArrayList<>();
private HostSelectionItem selectedHostSelectionItem;
@Override @Override
protected void initViewModel() { protected void initViewModel() {
@ -90,50 +83,9 @@ public class InjectKeyFragment extends DataBindingFragment {
} }
private void updateConfigurationInfo() { private void updateConfigurationInfo() {
setupHostSelection();
binding.serialNumberValue.setText(getDisplayValue(TMSUtil.getInstance().getSerialNumber())); binding.serialNumberValue.setText(getDisplayValue(TMSUtil.getInstance().getSerialNumber()));
} }
private void setupHostSelection() {
hostSelectionItems.clear();
String primaryTerminalId = SystemParamsOperation.getInstance().getTerminalId();
String primaryMerchantId = SystemParamsOperation.getInstance().getMerchantId();
String secondaryTerminalId = SystemParamsOperation.getInstance().getThirdHostTerminalId();
String secondaryMerchantId = SystemParamsOperation.getInstance().getThirdHostMerchantId();
hostSelectionItems.add(new HostSelectionItem("Primary Host", primaryTerminalId, primaryMerchantId));
if (!TextUtils.isEmpty(secondaryTerminalId) || !TextUtils.isEmpty(secondaryMerchantId)) {
hostSelectionItems.add(new HostSelectionItem("Secondary Host", secondaryTerminalId, secondaryMerchantId));
}
ArrayAdapter<HostSelectionItem> hostAdapter = new ArrayAdapter<>(
requireContext(),
android.R.layout.simple_list_item_1,
hostSelectionItems
);
binding.actvHostSelection.setAdapter(hostAdapter);
if (!hostSelectionItems.isEmpty()) {
HostSelectionItem defaultSelection = hostSelectionItems.get(0);
binding.actvHostSelection.setText(defaultSelection.toString(), false);
applyHostSelection(defaultSelection);
}
binding.actvHostSelection.setOnItemClickListener((parent, view, position, id) -> {
if (position >= 0 && position < hostSelectionItems.size()) {
applyHostSelection(hostSelectionItems.get(position));
}
});
}
private void applyHostSelection(@NonNull HostSelectionItem selectionItem) {
selectedHostSelectionItem = selectionItem;
binding.terminalIdValue.setText(getDisplayValue(selectionItem.terminalId));
binding.merchantIdValue.setText(getDisplayValue(selectionItem.merchantId));
}
private String getDisplayValue(String value) { private String getDisplayValue(String value) {
return !TextUtils.isEmpty(value) ? value : "Not configured"; return !TextUtils.isEmpty(value) ? value : "Not configured";
} }
@ -158,21 +110,18 @@ public class InjectKeyFragment extends DataBindingFragment {
mDownloadFlow = DownloadFlow.getInstance(); mDownloadFlow = DownloadFlow.getInstance();
String terminalId = selectedHostSelectionItem != null ? selectedHostSelectionItem.terminalId : null;
String merchantId = selectedHostSelectionItem != null ? selectedHostSelectionItem.merchantId : null;
String serialNo = TMSUtil.getInstance().getSerialNumber(); String serialNo = TMSUtil.getInstance().getSerialNumber();
// Validate configuration if (TextUtils.isEmpty(serialNo)) {
if (TextUtils.isEmpty(terminalId) || TextUtils.isEmpty(merchantId) || TextUtils.isEmpty(serialNo)) {
dismissLoadingDialog(); dismissLoadingDialog();
showDeclineDialog("Please configure the selected Terminal ID and Merchant ID first in TMS Configuration"); showDeclineDialog("Serial number is not configured");
return; return;
} }
final DownloadFEntity downloadFEntity = new DownloadFEntity(); final DownloadFEntity downloadFEntity = new DownloadFEntity();
downloadFEntity.setSn(serialNo.getBytes()); downloadFEntity.setSn(serialNo.getBytes());
downloadFEntity.setMid(merchantId.getBytes()); downloadFEntity.setMid(null);
downloadFEntity.setTid(terminalId.getBytes()); downloadFEntity.setTid(null);
downloadFEntity.setTmkIndex(keyIndexTmp); downloadFEntity.setTmkIndex(keyIndexTmp);
downloadFEntity.setPort(0); downloadFEntity.setPort(0);
downloadFEntity.setTimeOut(10); downloadFEntity.setTimeOut(10);
@ -213,28 +162,6 @@ public class InjectKeyFragment extends DataBindingFragment {
} }
}; };
private static class HostSelectionItem {
private final String label;
private final String terminalId;
private final String merchantId;
private HostSelectionItem(String label, String terminalId, String merchantId) {
this.label = label;
this.terminalId = terminalId;
this.merchantId = merchantId;
}
@NonNull
@Override
public String toString() {
return label;
}
private static String getSummaryValue(String value) {
return TextUtils.isEmpty(value) ? "Not configured" : value;
}
}
// ClickEvent class for data binding - this is the proper pattern // ClickEvent class for data binding - this is the proper pattern
public class ClickEvent { public class ClickEvent {

View File

@ -0,0 +1,245 @@
package com.utsmm.kbz.util;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.AppCompatButton;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import com.utsmm.kbz.R;
import com.utsmm.kbz.ui.core_viewmodel.SharedViewModel;
import com.utsmyanmar.paylibs.utils.core_utils.SystemParamsOperation;
import com.utsmyanmar.paylibs.utils.enums.CurrencyType;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
public class CurrencySelectionHelper {
private final Fragment fragment;
private final SharedViewModel sharedViewModel;
private boolean primaryHostCached = false;
private String primaryHostName = "";
private String primaryTid = "";
private String primaryMid = "";
private String primaryIp = "";
private String primarySecIp = "";
private CurrencyType primaryCurrency = CurrencyType.MMK;
public CurrencySelectionHelper(Fragment fragment, SharedViewModel sharedViewModel) {
this.fragment = fragment;
this.sharedViewModel = sharedViewModel;
}
public void showCardCurrencyChooser(Runnable onSelected) {
showCardCurrencyChooser(onSelected, null);
}
public void showCardCurrencyChooser(Runnable onSelected, Runnable onCancelled) {
List<String> currencies = getAvailableCardCurrencies();
if (currencies.isEmpty()) {
applyCardCurrencyAndHost("MMK");
onSelected.run();
return;
}
if (currencies.size() == 1) {
applyCardCurrencyAndHost(currencies.get(0));
onSelected.run();
return;
}
showCurrencyPickerDialog("Choose Currency", currencies, currency -> {
applyCardCurrencyAndHost(currency);
onSelected.run();
}, onCancelled);
}
private List<String> getAvailableCardCurrencies() {
cachePrimaryCardHostIfNeeded();
LinkedHashSet<String> values = new LinkedHashSet<>();
if (primaryCurrency != null && !TextUtils.isEmpty(primaryCurrency.name)) {
values.add(normalizeCurrency(primaryCurrency.name));
}
if (!SystemParamsOperation.getInstance().getDuelCurrencyStatus()) {
return new ArrayList<>(values);
}
String secondaryCurrency = normalizeCurrency(SystemParamsOperation.getInstance().getThirdHostCurrency());
if (!TextUtils.isEmpty(SystemParamsOperation.getInstance().getThirdHostName()) && !TextUtils.isEmpty(secondaryCurrency)) {
values.add(secondaryCurrency);
}
return new ArrayList<>(values);
}
private void applyCardCurrencyAndHost(String selectedCurrency) {
cachePrimaryCardHostIfNeeded();
String selected = normalizeCurrency(selectedCurrency);
String secondaryCurrency = normalizeCurrency(SystemParamsOperation.getInstance().getThirdHostCurrency());
boolean dualCurrencyEnabled = SystemParamsOperation.getInstance().getDuelCurrencyStatus();
boolean useSecondaryCardHost = dualCurrencyEnabled
&& !TextUtils.isEmpty(SystemParamsOperation.getInstance().getThirdHostName())
&& !TextUtils.isEmpty(secondaryCurrency)
&& secondaryCurrency.equals(selected);
if (useSecondaryCardHost) {
SystemParamsOperation.getInstance().setHostName(SystemParamsOperation.getInstance().getThirdHostName());
SystemParamsOperation.getInstance().setTerminalId(SystemParamsOperation.getInstance().getThirdHostTerminalId());
SystemParamsOperation.getInstance().setMerchantId(SystemParamsOperation.getInstance().getThirdHostMerchantId());
SystemParamsOperation.getInstance().setIpAddress(SystemParamsOperation.getInstance().getThirdHostIpAddress());
SystemParamsOperation.getInstance().setSecIpAddress(SystemParamsOperation.getInstance().getThirdHostSecIpAddress());
} else {
SystemParamsOperation.getInstance().setHostName(primaryHostName);
SystemParamsOperation.getInstance().setTerminalId(primaryTid);
SystemParamsOperation.getInstance().setMerchantId(primaryMid);
SystemParamsOperation.getInstance().setIpAddress(primaryIp);
SystemParamsOperation.getInstance().setSecIpAddress(primarySecIp);
}
CurrencyType currencyType = useSecondaryCardHost ? toCurrencyType(selected) : primaryCurrency;
SystemParamsOperation.getInstance().setCurrencyType(currencyType);
if (sharedViewModel != null) {
sharedViewModel.set_currencyText(currencyType.name);
}
}
private void cachePrimaryCardHostIfNeeded() {
if (primaryHostCached) {
return;
}
primaryHostName = SystemParamsOperation.getInstance().getHostName();
primaryTid = SystemParamsOperation.getInstance().getTerminalId();
primaryMid = SystemParamsOperation.getInstance().getMerchantId();
primaryIp = SystemParamsOperation.getInstance().getIpAddress();
primarySecIp = SystemParamsOperation.getInstance().getSecIpAddress();
CurrencyType activeCurrency = SystemParamsOperation.getInstance().getCurrencyType();
primaryCurrency = activeCurrency == null ? CurrencyType.MMK : activeCurrency;
primaryHostCached = true;
}
private CurrencyType toCurrencyType(String value) {
String normalized = normalizeCurrency(value);
try {
return CurrencyType.valueOf(normalized);
} catch (Exception ignored) {
return CurrencyType.MMK;
}
}
private String normalizeCurrency(String raw) {
if (TextUtils.isEmpty(raw)) {
return "";
}
String value = raw.trim().toUpperCase();
switch (value) {
case "104":
case "MMK":
return "MMK";
case "840":
case "USD":
return "USD";
case "156":
case "CNY":
case "RMB":
return "CNY";
case "764":
case "THB":
return "THB";
case "643":
case "RUB":
return "RUB";
default:
return value;
}
}
private void showCurrencyPickerDialog(
String title,
List<String> currencies,
CurrencySelectCallback callback,
Runnable onCancelled
) {
LinearLayout root = new LinearLayout(fragment.requireContext());
root.setOrientation(LinearLayout.VERTICAL);
root.setPadding(dp(20), dp(20), dp(20), dp(12));
TextView tvTitle = new TextView(fragment.requireContext());
tvTitle.setText(title);
tvTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20);
tvTitle.setTextColor(ContextCompat.getColor(fragment.requireContext(), R.color.colorTextTitle));
tvTitle.setPadding(0, 0, 0, dp(16));
root.addView(tvTitle);
final AlertDialog[] dialogHolder = new AlertDialog[1];
for (String currency : currencies) {
AppCompatButton button = new AppCompatButton(fragment.requireContext());
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
dp(56)
);
lp.bottomMargin = dp(10);
button.setLayoutParams(lp);
button.setAllCaps(false);
button.setText(currency);
button.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18);
button.setGravity(Gravity.CENTER);
button.setBackgroundResource(R.drawable.bg_rounded_btn_cv);
button.setTextColor(ContextCompat.getColor(fragment.requireContext(), R.color.white));
button.setOnClickListener(v -> {
if (dialogHolder[0] != null) {
dialogHolder[0].dismiss();
}
callback.onSelected(currency);
});
root.addView(button);
}
AppCompatButton cancel = new AppCompatButton(fragment.requireContext());
LinearLayout.LayoutParams cancelLp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
dp(52)
);
cancel.setLayoutParams(cancelLp);
cancel.setAllCaps(false);
cancel.setText("Cancel");
cancel.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
cancel.setBackgroundResource(R.drawable.bg_rounded_btn_cancel_cv);
cancel.setTextColor(ContextCompat.getColor(fragment.requireContext(), R.color.colorPrimary));
cancel.setOnClickListener(v -> {
if (dialogHolder[0] != null) {
dialogHolder[0].dismiss();
}
if (onCancelled != null) {
onCancelled.run();
}
});
root.addView(cancel);
AlertDialog dialog = new AlertDialog.Builder(fragment.requireContext())
.setView(root)
.create();
dialogHolder[0] = dialog;
dialog.show();
}
private int dp(int value) {
return Math.round(value * fragment.requireContext().getResources().getDisplayMetrics().density);
}
private interface CurrencySelectCallback {
void onSelected(String currency);
}
}

View File

@ -101,6 +101,7 @@
android:textSize="14sp" android:textSize="14sp"
tools:fontFamily="sans-serif" /> tools:fontFamily="sans-serif" />
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -129,84 +130,6 @@
</androidx.cardview.widget.CardView> </androidx.cardview.widget.CardView>
<!-- Host Selection Card -->
<androidx.cardview.widget.CardView
android:id="@+id/hostSelectionCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
app:cardBackgroundColor="@color/white"
app:cardCornerRadius="16dp"
app:cardElevation="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/rubik_medium"
android:text="Host Selection"
android:textColor="@color/colorTextTitle"
android:textSize="16sp"
android:textStyle="bold"
tools:fontFamily="sans-serif-medium" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:layout_marginBottom="12dp"
android:fontFamily="@font/rubik_regular"
android:text="Select Terminal Id and MerchantId to preview before key injection"
android:textColor="@color/colorTextContent"
android:textSize="14sp"
tools:fontFamily="sans-serif" />
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Select Host"
app:endIconMode="dropdown_menu"
app:boxBackgroundMode="outline"
app:boxCornerRadiusBottomEnd="8dp"
app:boxCornerRadiusBottomStart="8dp"
app:boxCornerRadiusTopEnd="8dp"
app:boxCornerRadiusTopStart="8dp"
app:boxStrokeColor="@color/colorPrimary">
<com.google.android.material.textfield.MaterialAutoCompleteTextView
android:id="@+id/actvHostSelection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="@font/rubik_regular"
android:inputType="none"
android:focusable="false"
android:clickable="true"
android:textColor="@color/colorTextTitle"
android:textSize="16sp"
android:paddingLeft="16sp"
tools:fontFamily="sans-serif" />
</com.google.android.material.textfield.TextInputLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:fontFamily="@font/rubik_regular"
android:text="UI only: current key injection still uses the active TMS configuration."
android:textColor="@color/colorTextContent"
android:textSize="12sp"
tools:fontFamily="sans-serif" />
</LinearLayout>
</androidx.cardview.widget.CardView>
<!-- Current Configuration Info Card --> <!-- Current Configuration Info Card -->
<androidx.cardview.widget.CardView <androidx.cardview.widget.CardView
android:id="@+id/configInfoCard" android:id="@+id/configInfoCard"
@ -233,69 +156,11 @@
android:textStyle="bold" android:textStyle="bold"
tools:fontFamily="sans-serif-medium" /> tools:fontFamily="sans-serif-medium" />
<!-- Terminal ID -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="@font/rubik_regular"
android:text="Terminal ID:"
android:textColor="@color/colorTextContent"
android:textSize="14sp"
tools:fontFamily="sans-serif" />
<TextView
android:id="@+id/terminalIdValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/rubik_medium"
android:text="Not configured"
android:textColor="@color/colorTextTitle"
android:textSize="14sp"
tools:fontFamily="sans-serif-medium" />
</LinearLayout>
<!-- Merchant ID -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:fontFamily="@font/rubik_regular"
android:text="Merchant ID:"
android:textColor="@color/colorTextContent"
android:textSize="14sp"
tools:fontFamily="sans-serif" />
<TextView
android:id="@+id/merchantIdValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/rubik_medium"
android:text="Not configured"
android:textColor="@color/colorTextTitle"
android:textSize="14sp"
tools:fontFamily="sans-serif-medium" />
</LinearLayout>
<!-- Serial Number --> <!-- Serial Number -->
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="12dp"
android:orientation="horizontal"> android:orientation="horizontal">
<TextView <TextView