Fix amount on UI and receipt, add redirect if M50
This commit is contained in:
parent
70f58bf95b
commit
b901527872
|
@ -190,7 +190,12 @@ public class BaseAppViewModel extends BaseViewModel implements WebSocketManager.
|
||||||
}).start();
|
}).start();
|
||||||
break;
|
break;
|
||||||
case "payment":
|
case "payment":
|
||||||
onPaymentUpdated(json.toString());
|
new Thread(() -> {
|
||||||
|
|
||||||
|
new Handler(Looper.getMainLooper()).post(() ->
|
||||||
|
onPaymentUpdated(json.toString()));
|
||||||
|
}).start();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "ping":
|
case "ping":
|
||||||
// Handle ping requests
|
// Handle ping requests
|
||||||
|
@ -206,6 +211,8 @@ public class BaseAppViewModel extends BaseViewModel implements WebSocketManager.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle ping requests from server
|
* Handle ping requests from server
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -9,6 +9,7 @@ import android.os.RemoteException;
|
||||||
import com.action.printerservice.PrintStyle;
|
import com.action.printerservice.PrintStyle;
|
||||||
import com.action.printerservice.barcode.Barcode1D;
|
import com.action.printerservice.barcode.Barcode1D;
|
||||||
import com.action.printerservice.barcode.Barcode2D;
|
import com.action.printerservice.barcode.Barcode2D;
|
||||||
|
import com.dspread.pos.data.local.PreferencesManager;
|
||||||
import com.dspread.pos.utils.DeviceUtils;
|
import com.dspread.pos.utils.DeviceUtils;
|
||||||
import com.dspread.pos.utils.QRCodeUtil;
|
import com.dspread.pos.utils.QRCodeUtil;
|
||||||
import com.dspread.pos.utils.TRACE;
|
import com.dspread.pos.utils.TRACE;
|
||||||
|
@ -18,6 +19,10 @@ import com.dspread.print.device.PrinterInitListener;
|
||||||
import com.dspread.print.device.bean.PrintLineStyle;
|
import com.dspread.print.device.bean.PrintLineStyle;
|
||||||
import com.dspread.print.widget.PrintLine;
|
import com.dspread.print.widget.PrintLine;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class PrinterHelper {
|
public class PrinterHelper {
|
||||||
protected PrinterDevice mPrinter;
|
protected PrinterDevice mPrinter;
|
||||||
public static PrinterHelper printerCommand;
|
public static PrinterHelper printerCommand;
|
||||||
|
@ -210,6 +215,142 @@ public class PrinterHelper {
|
||||||
mPrinter.print(context);
|
mPrinter.print(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void printReceipt(Context context,
|
||||||
|
PreferencesManager prefs,
|
||||||
|
double amount,
|
||||||
|
String currencySymbol,
|
||||||
|
String paymentMethod,
|
||||||
|
String printingReciptQRcode,
|
||||||
|
String printingReciptURL) throws RemoteException {
|
||||||
|
|
||||||
|
|
||||||
|
mPrinter.setPrinterSpeed(5);
|
||||||
|
mPrinter.setPrinterDensity(2);
|
||||||
|
|
||||||
|
// Handle logos - supports both resource IDs and file paths
|
||||||
|
int mainLogoRes = prefs.getInt("main_logo", -1);
|
||||||
|
if (mainLogoRes == -1) {
|
||||||
|
// Load from file path
|
||||||
|
String path = prefs.getString("main_logo_path", null);
|
||||||
|
if (path != null) {
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeFile(path);
|
||||||
|
if (bitmap != null) {
|
||||||
|
mPrinter.addBitmap(bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Regular resource ID - convert resource ID to Bitmap
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), mainLogoRes);
|
||||||
|
if (bitmap != null) {
|
||||||
|
mPrinter.addBitmap(bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// mPrinter.addPrintLintStyle(new PrintLineStyle(PrintStyle.FontStyle.BOLD, PrintLine.CENTER, 20));
|
||||||
|
|
||||||
|
// if (bitmap == null) {
|
||||||
|
// throw new IllegalArgumentException("Bitmap cannot be null");
|
||||||
|
// }
|
||||||
|
// mPrinter.printBitmap(context, bitmap);
|
||||||
|
// mPrinter.addBitmap(bitmap);
|
||||||
|
// mPrinter.addText("АО Альфа-Банк");
|
||||||
|
|
||||||
|
// mPrinter.setLineSpace(8);
|
||||||
|
|
||||||
|
mPrinter.addPrintLintStyle(new PrintLineStyle(PrintStyle.FontStyle.NORMAL, PrintLine.CENTER, 14));
|
||||||
|
// mPrinter.addText("ИНН 1234567890");
|
||||||
|
// mPrinter.setLineSpace(8);
|
||||||
|
|
||||||
|
// mPrinter.addText("8 800 550-91-23");
|
||||||
|
// mPrinter.setLineSpace(8);
|
||||||
|
// ================== ADDRESS ==================
|
||||||
|
// mPrinter.addText("г. Волгоград, пр. Ленина, д. 92");
|
||||||
|
// ================== RECEIPT DETAILS ==================
|
||||||
|
mPrinter.addText("ЧЕК №" + 123465);
|
||||||
|
mPrinter.addText("Кассир: Иванов И.И.");
|
||||||
|
SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy", Locale.getDefault());
|
||||||
|
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
|
||||||
|
|
||||||
|
Date currentDate = new Date();
|
||||||
|
|
||||||
|
// Get separated date and time strings
|
||||||
|
String dateString = dateFormat.format(currentDate);
|
||||||
|
String timeString = timeFormat.format(currentDate);
|
||||||
|
|
||||||
|
mPrinter.addTexts(
|
||||||
|
new String[]{dateString, timeString}, // Actual date and time values
|
||||||
|
new int[]{1, 1}, // Equal column width
|
||||||
|
new int[]{PrintStyle.Alignment.NORMAL, PrintStyle.Alignment.ALIGN_OPPOSITE},
|
||||||
|
new int[]{PrintStyle.FontStyle.BOLD, PrintStyle.FontStyle.BOLD},
|
||||||
|
14 // Font size
|
||||||
|
);
|
||||||
|
mPrinter.addText("------------------------------");
|
||||||
|
// ================== ITEMS ==================
|
||||||
|
mPrinter.addTexts(
|
||||||
|
new String[]{"1. Тест Документ", String.format("%.2f %s", amount, currencySymbol)},
|
||||||
|
new int[]{2, 1}, // Left column wider than right
|
||||||
|
new int[]{PrintStyle.Alignment.CENTER, PrintStyle.Alignment.ALIGN_OPPOSITE}
|
||||||
|
);
|
||||||
|
|
||||||
|
mPrinter.addTexts(
|
||||||
|
new String[]{" НДС 20%", "= " + String.format("%.2f %s", amount * 0.2, currencySymbol)},
|
||||||
|
new int[]{2, 1},
|
||||||
|
new int[]{PrintStyle.Alignment.NORMAL, PrintStyle.Alignment.ALIGN_OPPOSITE}
|
||||||
|
);
|
||||||
|
// ================== TOTALS ==================
|
||||||
|
mPrinter.addText("--------------------------------");
|
||||||
|
mPrinter.addPrintLintStyle(new PrintLineStyle(PrintStyle.FontStyle.BOLD, PrintLine.CENTER, 28));
|
||||||
|
mPrinter.addTexts(
|
||||||
|
new String[]{"ИТОГО:", String.format("%.2f %s", amount, currencySymbol)},
|
||||||
|
new int[]{1, 1}, // Equal column width
|
||||||
|
new int[]{PrintStyle.Alignment.NORMAL, PrintStyle.Alignment.ALIGN_OPPOSITE},
|
||||||
|
new int[]{PrintStyle.FontStyle.NORMAL, PrintStyle.FontStyle.BOLD}, 28
|
||||||
|
);
|
||||||
|
|
||||||
|
mPrinter.addPrintLintStyle(new PrintLineStyle(PrintStyle.FontStyle.NORMAL, PrintLine.CENTER, 14));
|
||||||
|
|
||||||
|
mPrinter.addTexts(
|
||||||
|
new String[]{"Форма расчета:", paymentMethod },
|
||||||
|
new int[]{1, 1}, // Equal column width
|
||||||
|
new int[]{PrintStyle.Alignment.NORMAL, PrintStyle.Alignment.ALIGN_OPPOSITE}
|
||||||
|
);
|
||||||
|
|
||||||
|
// ================== FISCAL DATA ==================
|
||||||
|
mPrinter.addText("--------------------------------");
|
||||||
|
|
||||||
|
// ================== QR CODE AND CONTACTS ==================
|
||||||
|
// mPrinter.addBarCode(context, Barcode1D.CODE_128.name(), 400, 100, "datexpay.ru", PrintLine.CENTER);
|
||||||
|
mPrinter.addQRCode(280, Barcode2D.QR_CODE.name(), printingReciptQRcode, PrintLine.CENTER);
|
||||||
|
mPrinter.addPrintLintStyle(new PrintLineStyle(PrintStyle.FontStyle.NORMAL, PrintLine.CENTER, 14));
|
||||||
|
mPrinter.addText(printingReciptURL);
|
||||||
|
|
||||||
|
// mPrinter.addBitmap(mulberry);
|
||||||
|
|
||||||
|
// Handle logos - supports both resource IDs and file paths
|
||||||
|
int footerLogoRes = prefs.getInt("footer_logo", -1);
|
||||||
|
if (footerLogoRes == -1) {
|
||||||
|
// Load from file path
|
||||||
|
String path = prefs.getString("footer_logo_path", null);
|
||||||
|
if (path != null) {
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeFile(path);
|
||||||
|
if (bitmap != null) {
|
||||||
|
mPrinter.addBitmap(bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Regular resource ID - convert resource ID to Bitmap
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), footerLogoRes);
|
||||||
|
if (bitmap != null) {
|
||||||
|
mPrinter.addBitmap(bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mPrinter.setFooter(80);
|
||||||
|
//Print the document
|
||||||
|
mPrinter.print(context);
|
||||||
|
}
|
||||||
|
|
||||||
public void getPrinterStatus() throws RemoteException {
|
public void getPrinterStatus() throws RemoteException {
|
||||||
mPrinter.getPrinterStatus();
|
mPrinter.getPrinterStatus();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.dspread.pos.ui.home;
|
package com.dspread.pos.ui.home;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
@ -9,6 +11,7 @@ import androidx.lifecycle.LiveData;
|
||||||
|
|
||||||
import com.dspread.pos.common.base.BaseAppViewModel;
|
import com.dspread.pos.common.base.BaseAppViewModel;
|
||||||
import com.dspread.pos.utils.CurrencySymbolUtils;
|
import com.dspread.pos.utils.CurrencySymbolUtils;
|
||||||
|
import com.dspread.pos.utils.PosParameters;
|
||||||
import com.dspread.pos.utils.TRACE;
|
import com.dspread.pos.utils.TRACE;
|
||||||
import com.dspread.pos_android_app.R;
|
import com.dspread.pos_android_app.R;
|
||||||
|
|
||||||
|
@ -21,7 +24,8 @@ public class HomeViewModel extends BaseAppViewModel {
|
||||||
public ObservableField<String> amount = new ObservableField<>("0.00");
|
public ObservableField<String> amount = new ObservableField<>("0.00");
|
||||||
public ObservableField<String> currencyCode = new ObservableField<>("RUB");
|
public ObservableField<String> currencyCode = new ObservableField<>("RUB");
|
||||||
public SingleLiveEvent<Long> paymentStartEvent = new SingleLiveEvent<>();
|
public SingleLiveEvent<Long> paymentStartEvent = new SingleLiveEvent<>();
|
||||||
|
public final ObservableField<Integer> mainLogo = new ObservableField<>();
|
||||||
|
public final ObservableField<Bitmap> mainLogoBitmap = new ObservableField<>();
|
||||||
public StringBuilder amountBuilder = new StringBuilder();
|
public StringBuilder amountBuilder = new StringBuilder();
|
||||||
private static final int MAX_DIGITS = 12; // Maximum amount digits
|
private static final int MAX_DIGITS = 12; // Maximum amount digits
|
||||||
|
|
||||||
|
@ -32,9 +36,44 @@ public class HomeViewModel extends BaseAppViewModel {
|
||||||
currencyCode.set(symbolForCurrency); // Set symbol
|
currencyCode.set(symbolForCurrency); // Set symbol
|
||||||
// currencyCode.set(prefs.getString("CurrencyCode", "RUB"));
|
// currencyCode.set(prefs.getString("CurrencyCode", "RUB"));
|
||||||
Log.d("HomeViewModel", "symbolForCurrency: " + symbolForCurrency );
|
Log.d("HomeViewModel", "symbolForCurrency: " + symbolForCurrency );
|
||||||
|
// Handle logos - supports both resource IDs and file paths
|
||||||
|
int mainLogoRes = prefs.getInt("main_logo", -1);
|
||||||
|
if (mainLogoRes == -1) {
|
||||||
|
// Load from file path
|
||||||
|
String path = prefs.getString("main_logo_path", null);
|
||||||
|
if (path != null) {
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeFile(path);
|
||||||
|
if (bitmap != null) {
|
||||||
|
// Use a custom binding adapter to set bitmap
|
||||||
|
mainLogoBitmap.set(bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Regular resource ID
|
||||||
|
mainLogo.set(mainLogoRes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onConfigurationUpdated() {
|
||||||
|
int mainLogoRes = prefs.getInt("main_logo", -1);
|
||||||
|
if (mainLogoRes == -1) {
|
||||||
|
// Load from file path
|
||||||
|
String path = prefs.getString("main_logo_path", null);
|
||||||
|
if (path != null) {
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeFile(path);
|
||||||
|
if (bitmap != null) {
|
||||||
|
// Use a custom binding adapter to set bitmap
|
||||||
|
mainLogoBitmap.set(bitmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Regular resource ID
|
||||||
|
mainLogo.set(mainLogoRes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Update amount display
|
// Update amount display
|
||||||
private void updateAmountDisplay() {
|
private void updateAmountDisplay() {
|
||||||
if (amountBuilder.length() == 0) {
|
if (amountBuilder.length() == 0) {
|
||||||
|
@ -42,7 +81,7 @@ public class HomeViewModel extends BaseAppViewModel {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String amountStr = amountBuilder.toString();
|
String amountStr = amountBuilder.toString();
|
||||||
// Convert to display an amount with two decimal places
|
// Convert to display an amount with two decimal places
|
||||||
if (amountStr.length() == 1) {
|
if (amountStr.length() == 1) {
|
||||||
|
|
|
@ -341,7 +341,7 @@ public class MulberryViewModel extends BaseAppViewModel {
|
||||||
|
|
||||||
public void onItemClick(MulberryItemViewModel item) {
|
public void onItemClick(MulberryItemViewModel item) {
|
||||||
Log.d(TAG, "Navigation item clicked: " + item.title.get());
|
Log.d(TAG, "Navigation item clicked: " + item.title.get());
|
||||||
sendWebSocketMessage("Navigation item clicked: " + item.title.get());
|
// sendWebSocketMessage("{\"type\":\"message\", \"content\": \"Navigation item clicked\" }");
|
||||||
|
|
||||||
if (item.fragmentId != null) {
|
if (item.fragmentId != null) {
|
||||||
navigateToFragment.setValue(item.fragmentId);
|
navigateToFragment.setValue(item.fragmentId);
|
||||||
|
|
|
@ -49,6 +49,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
import me.goldze.mvvmhabit.base.BaseActivity;
|
import me.goldze.mvvmhabit.base.BaseActivity;
|
||||||
import me.goldze.mvvmhabit.utils.SPUtils;
|
import me.goldze.mvvmhabit.utils.SPUtils;
|
||||||
|
@ -61,7 +62,7 @@ import com.dspread.pos_android_app.databinding.WaitingForCardBinding; // Generat
|
||||||
|
|
||||||
|
|
||||||
public class PaymentActivity extends BaseActivity<ActivityPaymentBinding, PaymentViewModel> implements PaymentServiceCallback {
|
public class PaymentActivity extends BaseActivity<ActivityPaymentBinding, PaymentViewModel> implements PaymentServiceCallback {
|
||||||
|
|
||||||
private String amount;
|
private String amount;
|
||||||
private String transactionTypeString;
|
private String transactionTypeString;
|
||||||
private String cashbackAmounts;
|
private String cashbackAmounts;
|
||||||
|
@ -78,7 +79,7 @@ public class PaymentActivity extends BaseActivity<ActivityPaymentBinding, Paymen
|
||||||
public int initContentView(Bundle savedInstanceState) {
|
public int initContentView(Bundle savedInstanceState) {
|
||||||
return R.layout.activity_payment;
|
return R.layout.activity_payment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int initVariableId() {
|
public int initVariableId() {
|
||||||
return BR.viewModel;
|
return BR.viewModel;
|
||||||
|
@ -87,14 +88,33 @@ public class PaymentActivity extends BaseActivity<ActivityPaymentBinding, Paymen
|
||||||
private WaitingForCardBinding waitingBinding; // Changed from ActivityWaitingForCardBinding
|
private WaitingForCardBinding waitingBinding; // Changed from ActivityWaitingForCardBinding
|
||||||
private WaitingForCardViewModel waitingViewModel;
|
private WaitingForCardViewModel waitingViewModel;
|
||||||
|
|
||||||
|
private boolean QRMood = false;
|
||||||
|
private boolean FaceIDMood = false;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initData() {
|
public void initData() {
|
||||||
|
// Debug current locale
|
||||||
|
Locale currentLocale = getResources().getConfiguration().locale;
|
||||||
|
Log.d("LanguageDebug", "Current locale: " + currentLocale.getLanguage());
|
||||||
|
Log.d("LanguageDebug", "Current country: " + currentLocale.getCountry());
|
||||||
|
|
||||||
|
// Check available locales
|
||||||
|
Locale[] availableLocales = Locale.getAvailableLocales();
|
||||||
|
for (Locale locale : availableLocales) {
|
||||||
|
if (locale.getLanguage().equals("ru")) {
|
||||||
|
Log.d("LanguageDebug", "Russian locale available: " + locale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Test string retrieval
|
||||||
|
String testString = getString(R.string.menu_payment);
|
||||||
|
Log.d("LanguageDebug", "Retrieved string: " + testString);
|
||||||
|
|
||||||
logFileConfig = LogFileConfig.getInstance(this);
|
logFileConfig = LogFileConfig.getInstance(this);
|
||||||
QPOSCallbackManager.getInstance().registerPaymentCallback(this);
|
QPOSCallbackManager.getInstance().registerPaymentCallback(this);
|
||||||
binding.setVariable(BR.viewModel, viewModel);
|
binding.setVariable(BR.viewModel, viewModel);
|
||||||
viewModel.setmContext(this);
|
viewModel.setmContext(this);
|
||||||
binding.pinpadEditText.setText("");
|
binding.pinpadEditText.setText("");
|
||||||
viewModel.titleText.set("Оплата");
|
viewModel.titleText.set(getString(R.string.menu_payment));
|
||||||
Intent intent = getIntent();
|
Intent intent = getIntent();
|
||||||
if (intent != null) {
|
if (intent != null) {
|
||||||
amount = intent.getStringExtra("amount");
|
amount = intent.getStringExtra("amount");
|
||||||
|
@ -139,6 +159,41 @@ public class PaymentActivity extends BaseActivity<ActivityPaymentBinding, Paymen
|
||||||
startTransaction();
|
startTransaction();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void simulatePaymentAfterDelay() {
|
||||||
|
boolean isTestMode = true; // Set this to false when not testing
|
||||||
|
if (isTestMode) {
|
||||||
|
// Use runOnUiThread to ensure we're on the main thread
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
new android.os.Handler().postDelayed(
|
||||||
|
new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
TRACE.d("SIMULATION: Simulating successful payment");
|
||||||
|
String mockTlv = "9A03240515" + // Transaction date: 2024-05-15
|
||||||
|
"9C00" + // Transaction type
|
||||||
|
"5F2A0156" + // Currency code: 156 (CNY)
|
||||||
|
"9F0206000000001000" + // Amount: 10.00
|
||||||
|
"95050000000000" + // TVR
|
||||||
|
"9F3403000000" + // CVM results
|
||||||
|
"9F270100"; // CID data
|
||||||
|
|
||||||
|
// Simulate the onRequestBatchData callback
|
||||||
|
onRequestBatchData(mockTlv);
|
||||||
|
|
||||||
|
// Enable print button
|
||||||
|
binding.btnSendReceipt.setEnabled(true);
|
||||||
|
binding.btnSendReceipt.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
200 // 10 second delay
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private String generatePaymentData() {
|
private String generatePaymentData() {
|
||||||
// Generate payment data for QR code
|
// Generate payment data for QR code
|
||||||
// Create JSON structure with relevant payment info
|
// Create JSON structure with relevant payment info
|
||||||
|
@ -207,12 +262,26 @@ public class PaymentActivity extends BaseActivity<ActivityPaymentBinding, Paymen
|
||||||
startTransaction();
|
startTransaction();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Observe QR mode
|
||||||
|
viewModel.getQrMode().observe(this, qrEnabled -> {
|
||||||
|
QRMood = Boolean.TRUE.equals(qrEnabled);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Observe FaceID mode
|
||||||
|
viewModel.getFaceIDMode().observe(this, faceIDEnabled -> {
|
||||||
|
FaceIDMood = Boolean.TRUE.equals(faceIDEnabled);
|
||||||
|
});
|
||||||
|
|
||||||
//Stop DoTrade
|
//Stop DoTrade
|
||||||
viewModel.StopReadingCard.observe(this, aBoolean -> {
|
viewModel.StopReadingCard.observe(this, aBoolean -> {
|
||||||
Log.d("PaymentAct", "StopReadingCard: " + aBoolean);
|
Log.d("PaymentAct", "StopReadingCard: " + aBoolean);
|
||||||
if (aBoolean) {
|
if (aBoolean) {
|
||||||
// Unregister the callback
|
// Unregister the callback
|
||||||
QPOSCallbackManager.getInstance().unregisterPaymentCallback();
|
// QPOSCallbackManager.getInstance().unregisterPaymentCallback();
|
||||||
|
POS.getInstance().cancelTrade();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Add this observer for receipt content
|
// Add this observer for receipt content
|
||||||
|
@ -456,12 +525,20 @@ public class PaymentActivity extends BaseActivity<ActivityPaymentBinding, Paymen
|
||||||
public void onRequestTransactionResult(QPOSService.TransactionResult transactionResult) {
|
public void onRequestTransactionResult(QPOSService.TransactionResult transactionResult) {
|
||||||
TRACE.d("onRequestTransactionResult()" + transactionResult.toString());
|
TRACE.d("onRequestTransactionResult()" + transactionResult.toString());
|
||||||
isChangePin = false;
|
isChangePin = false;
|
||||||
runOnUiThread(() -> {
|
|
||||||
String msg = HandleTxnsResultUtils.getTransactionResultMessage(transactionResult, PaymentActivity.this);
|
if (QRMood || FaceIDMood){
|
||||||
if (!msg.isEmpty()) {
|
simulatePaymentAfterDelay();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
runOnUiThread(() -> {
|
||||||
|
String msg = HandleTxnsResultUtils.getTransactionResultMessage(transactionResult, PaymentActivity.this);
|
||||||
|
if (!msg.isEmpty()) {
|
||||||
viewModel.setTransactionFailed(msg);
|
viewModel.setTransactionFailed(msg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -556,6 +633,7 @@ public class PaymentActivity extends BaseActivity<ActivityPaymentBinding, Paymen
|
||||||
TRACE.d("onTradeCancelled");
|
TRACE.d("onTradeCancelled");
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
// viewModel.setTransactionFailed("Transaction is canceled!");
|
// viewModel.setTransactionFailed("Transaction is canceled!");
|
||||||
|
finish();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,9 @@ import android.widget.TextView;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.databinding.ObservableBoolean;
|
import androidx.databinding.ObservableBoolean;
|
||||||
import androidx.databinding.ObservableField;
|
import androidx.databinding.ObservableField;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
import com.dspread.pos.common.base.BaseAppViewModel;
|
import com.dspread.pos.common.base.BaseAppViewModel;
|
||||||
import com.dspread.pos.common.http.RetrofitClient;
|
import com.dspread.pos.common.http.RetrofitClient;
|
||||||
|
@ -37,6 +40,7 @@ import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.functions.Consumer;
|
import io.reactivex.functions.Consumer;
|
||||||
|
@ -70,6 +74,10 @@ public class PaymentViewModel extends BaseAppViewModel {
|
||||||
public SingleLiveEvent<Boolean> isOnlineSuccess = new SingleLiveEvent();
|
public SingleLiveEvent<Boolean> isOnlineSuccess = new SingleLiveEvent();
|
||||||
public SingleLiveEvent<Boolean> isContinueTrx = new SingleLiveEvent();
|
public SingleLiveEvent<Boolean> isContinueTrx = new SingleLiveEvent();
|
||||||
public SingleLiveEvent<Boolean> StopReadingCard = new SingleLiveEvent();
|
public SingleLiveEvent<Boolean> StopReadingCard = new SingleLiveEvent();
|
||||||
|
|
||||||
|
// Add these for QR and FaceID modes
|
||||||
|
private final MutableLiveData<Boolean> qrMode = new MutableLiveData<>(false);
|
||||||
|
private final MutableLiveData<Boolean> faceIDMode = new MutableLiveData<>(false);
|
||||||
public ObservableBoolean showPinpad = new ObservableBoolean(false);
|
public ObservableBoolean showPinpad = new ObservableBoolean(false);
|
||||||
public ObservableBoolean showResultStatus = new ObservableBoolean(false);
|
public ObservableBoolean showResultStatus = new ObservableBoolean(false);
|
||||||
public ObservableField<String> receiptContent = new ObservableField<>();
|
public ObservableField<String> receiptContent = new ObservableField<>();
|
||||||
|
@ -81,6 +89,30 @@ public class PaymentViewModel extends BaseAppViewModel {
|
||||||
this.mContext = mContext;
|
this.mContext = mContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Public getters for the LiveData
|
||||||
|
public LiveData<Boolean> getQrMode() {
|
||||||
|
return qrMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Boolean> getFaceIDMode() {
|
||||||
|
return faceIDMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Methods to set the modes
|
||||||
|
public void setQrMode(boolean enabled) {
|
||||||
|
qrMode.setValue(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFaceIDMode(boolean enabled) {
|
||||||
|
faceIDMode.setValue(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset both modes to false (call this when activity starts)
|
||||||
|
public void resetModes() {
|
||||||
|
qrMode.setValue(false);
|
||||||
|
faceIDMode.setValue(false);
|
||||||
|
}
|
||||||
|
|
||||||
public void simulateSuccessfulPayment() {
|
public void simulateSuccessfulPayment() {
|
||||||
Log.d("PaymentVM", "simulateSuccessfulPayment ... ");
|
Log.d("PaymentVM", "simulateSuccessfulPayment ... ");
|
||||||
setTransactionSuccess("Simulated successful payment");
|
setTransactionSuccess("Simulated successful payment");
|
||||||
|
@ -117,8 +149,9 @@ public class PaymentViewModel extends BaseAppViewModel {
|
||||||
case "success":
|
case "success":
|
||||||
Log.d(TAG, "QR Payment Success");
|
Log.d(TAG, "QR Payment Success");
|
||||||
// Unregister callback through the activity
|
// Unregister callback through the activity
|
||||||
StopReadingCard.setValue(true);// This will trigger the activity to unregister
|
setQrMode(true);
|
||||||
simulateSuccessfulPayment();
|
StopReadingCard.setValue(true);
|
||||||
|
// simulateSuccessfulPayment();
|
||||||
break;
|
break;
|
||||||
case "failed":
|
case "failed":
|
||||||
Log.d(TAG, "QR Payment Failed");
|
Log.d(TAG, "QR Payment Failed");
|
||||||
|
@ -127,11 +160,11 @@ public class PaymentViewModel extends BaseAppViewModel {
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Log.w(TAG, "Unknown JSON type: " + status);
|
Log.w(TAG, "Unknown JSON type: " + status);
|
||||||
StopReadingCard.setValue(true);// This will trigger the activity to unregister
|
// StopReadingCard.setValue(true);// This will trigger the activity to unregister
|
||||||
}
|
}
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
Log.e("PaymentVM", "Error parsing JSON", e);
|
Log.e("PaymentVM", "Error parsing JSON", e);
|
||||||
StopReadingCard.setValue(true); // This will trigger the activity to unregister
|
// StopReadingCard.setValue(true); // This will trigger the activity to unregister
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +207,7 @@ public class PaymentViewModel extends BaseAppViewModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAmount(String newAmount) {
|
public void setAmount(String newAmount) {
|
||||||
amount.set("¥" + newAmount);
|
amount.set( newAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setWaitingStatus(boolean isWaitings){
|
public void setWaitingStatus(boolean isWaitings){
|
||||||
|
@ -202,6 +235,18 @@ public class PaymentViewModel extends BaseAppViewModel {
|
||||||
loadingText.set("");
|
loadingText.set("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Double convertCentsToDollars(String amountValue) {
|
||||||
|
if (amountValue == null || amountValue.isEmpty()) {
|
||||||
|
return 0.0; // Default value if the input is null or empty
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Double.parseDouble(amountValue) / 100.0; // Convert cents to dollars
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return 0.0; // Default value if parsing fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public BindingCommand continueTxnsCommand = new BindingCommand(new BindingAction() {
|
public BindingCommand continueTxnsCommand = new BindingCommand(new BindingAction() {
|
||||||
@Override
|
@Override
|
||||||
public void call() {
|
public void call() {
|
||||||
|
@ -219,31 +264,79 @@ public class PaymentViewModel extends BaseAppViewModel {
|
||||||
public BindingCommand sendReceiptCommand = new BindingCommand(new BindingAction() {
|
public BindingCommand sendReceiptCommand = new BindingCommand(new BindingAction() {
|
||||||
@Override
|
@Override
|
||||||
public void call() {
|
public void call() {
|
||||||
isPrinting.set(true);
|
String CurrentID = SPUtils.getInstance().getString("posID");
|
||||||
PrinterManager instance = PrinterManager.getInstance();
|
|
||||||
PrinterDevice mPrinter = instance.getPrinter();
|
// Extract the String value from the ObservableField
|
||||||
PrinterHelper.getInstance().setPrinter(mPrinter);
|
String amountValue = amount != null ? amount.get() : "0";
|
||||||
PrinterHelper.getInstance().initPrinter(mContext);
|
String currencySymbol = SPUtils.getInstance().getString("symbolForCurrency", "$");
|
||||||
TRACE.i("bitmap = "+receiptBitmap);
|
// Convert the amount from cents to dollars using the utility function
|
||||||
new Handler().postDelayed(() -> {
|
Double amountDouble = convertCentsToDollars(amountValue);
|
||||||
try {
|
|
||||||
PrinterHelper.getInstance().printBitmap(getApplication(),receiptBitmap);
|
if (Objects.equals(CurrentID, "01534090202502210065")){
|
||||||
} catch (RemoteException e) {
|
com.alibaba.fastjson.JSONObject paymentData = new com.alibaba.fastjson.JSONObject();
|
||||||
throw new RuntimeException(e);
|
paymentData.put("type", "redirect");
|
||||||
|
paymentData.put("amount", amountDouble);
|
||||||
|
paymentData.put("currencySymbol", currencySymbol);
|
||||||
|
paymentData.put("id", "01723060202412010160");
|
||||||
|
|
||||||
|
Log.d(TAG, "call: this is M50 maybe");
|
||||||
|
sendWebSocketMessage(paymentData.toString());
|
||||||
|
|
||||||
|
|
||||||
|
}else {
|
||||||
|
isPrinting.set(true);
|
||||||
|
PrinterManager instance = PrinterManager.getInstance();
|
||||||
|
PrinterDevice mPrinter = instance.getPrinter();
|
||||||
|
PrinterHelper.getInstance().setPrinter(mPrinter);
|
||||||
|
PrinterHelper.getInstance().initPrinter(mContext);
|
||||||
|
|
||||||
|
Boolean isQR = getQrMode().getValue();
|
||||||
|
Boolean isFaceID = getFaceIDMode().getValue();
|
||||||
|
|
||||||
|
String paymentMethod;
|
||||||
|
if (isQR != null && isQR) {
|
||||||
|
paymentMethod = "QR Code";
|
||||||
|
} else if (isFaceID != null && isFaceID) {
|
||||||
|
paymentMethod = "Face ID";
|
||||||
|
} else {
|
||||||
|
paymentMethod = "Крата";
|
||||||
}
|
}
|
||||||
PrinterHelper.getInstance().getmPrinter().setPrintListener(new PrintListener() {
|
TRACE.i("bitmap = " + receiptBitmap);
|
||||||
@Override
|
|
||||||
public void printResult(boolean b, String s, PrinterDevice.ResultType resultType) {
|
|
||||||
if(b){
|
new Handler().postDelayed(() -> {
|
||||||
ToastUtils.showShort("Print Finished!");
|
try {
|
||||||
}else {
|
// PrinterHelper.getInstance().printBitmap(getApplication(),receiptBitmap);
|
||||||
ToastUtils.showShort("Print Result: "+s);
|
assert amountValue != null;
|
||||||
}
|
PrinterHelper.getInstance().printReceipt(
|
||||||
isPrinting.set(false);
|
getApplication(), prefs,
|
||||||
finish();
|
amountDouble,
|
||||||
|
currencySymbol,
|
||||||
|
paymentMethod,
|
||||||
|
"String printingReciptQRcode",
|
||||||
|
"www.mulberrypos.ru"
|
||||||
|
);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
});
|
PrinterHelper.getInstance().getmPrinter().setPrintListener(new PrintListener() {
|
||||||
},100);
|
@Override
|
||||||
|
public void printResult(boolean b, String s, PrinterDevice.ResultType resultType) {
|
||||||
|
if (b) {
|
||||||
|
// ToastUtils.showShort("Print Finished!");
|
||||||
|
Log.d(TAG, "printResult: Finished");
|
||||||
|
} else {
|
||||||
|
// ToastUtils.showShort("Print Result: "+s);
|
||||||
|
Log.d(TAG, "printResult: Result" + s);
|
||||||
|
|
||||||
|
}
|
||||||
|
isPrinting.set(false);
|
||||||
|
// finish();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 100);
|
||||||
|
|
||||||
|
} // else if not M50
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,23 @@ public class WaitingForCardViewModel extends BaseViewModel {
|
||||||
|
|
||||||
|
|
||||||
public void setAmount(String amount) {
|
public void setAmount(String amount) {
|
||||||
this.amount.set(amount);
|
Double amountDouble = convertCentsToDollars(amount);
|
||||||
|
this.amount.set(String.valueOf(amountDouble));
|
||||||
}
|
}
|
||||||
public void setCurrencySymbol(String symbol) {
|
public void setCurrencySymbol(String symbol) {
|
||||||
this.currencySymbol.set(symbol);
|
this.currencySymbol.set(symbol);
|
||||||
}
|
}
|
||||||
|
public static Double convertCentsToDollars(String amountValue) {
|
||||||
|
if (amountValue == null || amountValue.isEmpty()) {
|
||||||
|
return 0.0; // Default value if the input is null or empty
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return Double.parseDouble(amountValue) / 100.0; // Convert cents to dollars
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return 0.0; // Default value if parsing fails
|
||||||
|
}
|
||||||
|
}
|
||||||
public void generateQRCode(String paymentData) {
|
public void generateQRCode(String paymentData) {
|
||||||
try {
|
try {
|
||||||
Bitmap qrCode = QRCodeGenerator.generateQRCode(paymentData, 500, 500);
|
Bitmap qrCode = QRCodeGenerator.generateQRCode(paymentData, 500, 500);
|
||||||
|
|
|
@ -169,13 +169,13 @@ public class ConnectionSettingsFragment extends BaseFragment<FragmentConnectionS
|
||||||
// 1. Update app configuration
|
// 1. Update app configuration
|
||||||
// 2. Restart activity to apply changes
|
// 2. Restart activity to apply changes
|
||||||
Log.d("RESTART", "updateAppLanguage: " + languageCode);
|
Log.d("RESTART", "updateAppLanguage: " + languageCode);
|
||||||
// Locale locale = new Locale(languageCode);
|
Locale locale = new Locale(languageCode);
|
||||||
// Locale.setDefault(locale);
|
Locale.setDefault(locale);
|
||||||
// Configuration config = new Configuration();
|
Configuration config = new Configuration();
|
||||||
// config.locale = locale;
|
config.locale = locale;
|
||||||
// getResources().updateConfiguration(config, getResources().getDisplayMetrics());
|
getResources().updateConfiguration(config, getResources().getDisplayMetrics());
|
||||||
//
|
|
||||||
// // Restart activity
|
// Restart activity
|
||||||
// Intent refresh = new Intent(getActivity(), getActivity().getClass());
|
// Intent refresh = new Intent(getActivity(), getActivity().getClass());
|
||||||
// startActivity(refresh);
|
// startActivity(refresh);
|
||||||
// getActivity().finish();
|
// getActivity().finish();
|
||||||
|
@ -183,6 +183,7 @@ public class ConnectionSettingsFragment extends BaseFragment<FragmentConnectionS
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return "Settings";
|
return "Settings" ;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
package com.dspread.pos.utils;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.Resources;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class LocaleHelper {
|
||||||
|
private static final String TAG = "LocaleHelper";
|
||||||
|
|
||||||
|
public static Context setLocale(Context context, String languageCode) {
|
||||||
|
Log.d(TAG, "Setting locale to: " + languageCode);
|
||||||
|
|
||||||
|
Locale locale = new Locale(languageCode);
|
||||||
|
Locale.setDefault(locale);
|
||||||
|
|
||||||
|
Resources resources = context.getResources();
|
||||||
|
Configuration configuration = new Configuration(resources.getConfiguration());
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
||||||
|
configuration.setLocale(locale);
|
||||||
|
} else {
|
||||||
|
configuration.locale = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
return context.createConfigurationContext(configuration);
|
||||||
|
} else {
|
||||||
|
resources.updateConfiguration(configuration, resources.getDisplayMetrics());
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getLanguage(Context context) {
|
||||||
|
Configuration config = context.getResources().getConfiguration();
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||||
|
return config.getLocales().get(0).getLanguage();
|
||||||
|
} else {
|
||||||
|
return config.locale.getLanguage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
<variable
|
<variable
|
||||||
name="viewModel"
|
name="viewModel"
|
||||||
type="com.dspread.pos.ui.home.HomeViewModel" />
|
type="com.dspread.pos.ui.home.HomeViewModel" />
|
||||||
|
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
@ -17,13 +18,13 @@
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/logoImage"
|
android:id="@+id/logoImage"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="110dp"
|
android:layout_height="100dp"
|
||||||
|
|
||||||
android:paddingLeft="20dp"
|
android:paddingLeft="20dp"
|
||||||
android:paddingRight="20dp"
|
android:paddingRight="20dp"
|
||||||
android:scaleType="fitCenter"
|
android:scaleType="fitCenter"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
android:src="@drawable/am_mulberry_logo_wide_color"
|
android:src="@{viewModel.mainLogoBitmap}"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
Loading…
Reference in New Issue