Added Cashier Fragment and test pay M70 from M50

This commit is contained in:
Ahmed Al-Omairi 2025-08-28 00:54:53 +03:00
parent b901527872
commit 7bc7f21c2e
10 changed files with 279 additions and 2 deletions

View File

@ -38,7 +38,7 @@
android:name="BUGLY_APPID" android:name="BUGLY_APPID"
android:value="b2d80aa171" /> android:value="b2d80aa171" />
<!-- <service android:name="org.eclipse.paho.android.service.MqttService" />--> <!-- <service android:name="org.eclipse.paho.android.service.MqttService" />-->
<service android:name="org.eclipse.paho.android.service.MqttService" /> <!-- <service android:name="org.eclipse.paho.android.service.MqttService" />-->
<activity <activity
android:name="com.dspread.pos.ui.main.MainActivity" android:name="com.dspread.pos.ui.main.MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"

View File

@ -196,6 +196,14 @@ public class BaseAppViewModel extends BaseViewModel implements WebSocketManager.
onPaymentUpdated(json.toString())); onPaymentUpdated(json.toString()));
}).start(); }).start();
break;
case "redirect":
new Thread(() -> {
new Handler(Looper.getMainLooper()).post(() ->
onPaymentRedirected(json.toString()));
}).start();
break; break;
case "ping": case "ping":
// Handle ping requests // Handle ping requests
@ -213,6 +221,7 @@ public class BaseAppViewModel extends BaseViewModel implements WebSocketManager.
/** /**
* Handle ping requests from server * Handle ping requests from server
*/ */
@ -285,6 +294,11 @@ public class BaseAppViewModel extends BaseViewModel implements WebSocketManager.
// Override in child classes for specific update handling // Override in child classes for specific update handling
} }
protected void onPaymentRedirected(String paymentRedirectData) {
Log.d("BaseAppViewModel", "onPaymentUpdated: " + paymentRedirectData);
// Override in child classes for specific update handling
}
// Add a public ViewModel method // Add a public ViewModel method
protected void showLoading() { protected void showLoading() {
showDialog(); showDialog();

View File

@ -0,0 +1,66 @@
package com.dspread.pos.ui.cashier;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.viewmodel.CreationExtras;
import com.dspread.pos.common.base.BaseFragment;
import com.dspread.pos.TitleProviderListener;
import com.dspread.pos.ui.main.MainActivity;
import com.dspread.pos.ui.main.MainViewModel;
import com.dspread.pos.ui.mulberry.MulberryViewModel;
import com.dspread.pos_android_app.R;
import com.dspread.pos_android_app.databinding.FragmentCashierBinding;
import com.dspread.pos_android_app.BR;
public class CashierFragment extends BaseFragment<FragmentCashierBinding, CashierViewModel >
implements TitleProviderListener{
@Override
public void initViewObservable() {
// Observe item click events
// Handle fragment navigation
// Observe payment info LiveData
viewModel.getPaymentInfo().observe(getViewLifecycleOwner(), paymentInfo -> {
if (paymentInfo != null) {
Log.d("CashierFragment", "Payment Info Updated: " + paymentInfo);
}
});
// Observe payment status LiveData
viewModel.getPaymentStatus().observe(getViewLifecycleOwner(), paymentStatus -> {
Log.d("CashierFragment", "Payment Status Updated: " + paymentStatus);
});
}
@Override
public String getTitle() {
return "Cashier";
}
@Override
public int initContentView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return R.layout.fragment_cashier;
}
@Override
public int initVariableId() {
return BR.viewModel;
}
@NonNull
@Override
public CreationExtras getDefaultViewModelCreationExtras() {
return super.getDefaultViewModelCreationExtras();
}
}

View File

@ -0,0 +1,101 @@
package com.dspread.pos.ui.cashier;
import android.app.Application;
import android.graphics.Bitmap;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.databinding.ObservableField;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.dspread.pos.common.base.BaseAppViewModel;
import com.dspread.pos.data.local.PreferencesManager;
import org.json.JSONException;
import org.json.JSONObject;
public class CashierViewModel extends BaseAppViewModel {
// Enum to represent payment status
public enum PaymentStatus {
WAITING, SUCCESS, FAILED
}
private static final String TAG = "CashierVM";
// LiveData to hold payment information
private final MutableLiveData<String> paymentInfo = new MutableLiveData<>();
public LiveData<String> getPaymentInfo() {
return paymentInfo;
}
public ObservableField<String> amount = new ObservableField<>("0.00");
public ObservableField<String> currencyCode = new ObservableField<>("RUB");
// LiveData to track payment status
private final MutableLiveData<PaymentStatus> paymentStatus = new MutableLiveData<>(PaymentStatus.WAITING);
public LiveData<PaymentStatus> getPaymentStatus() {
return paymentStatus;
}
public final ObservableField<Integer> mainLogo = new ObservableField<>();
public final ObservableField<Bitmap> mainLogoBitmap = new ObservableField<>();
public CashierViewModel(@NonNull Application application) {
super(application);
}
public void printReceipt() {
String amountValue = amount.get();
String currencyCodeValue = currencyCode.get();
if (amountValue != null && currencyCodeValue != null) {
Log.d(TAG, "Printing Receipt: " + amountValue + " " + currencyCodeValue);
// Simulate printing logic here
// For example, send the payment info to a printer service
} else {
Log.d(TAG, "No payment info to print");
}
}
@Override
protected void onPaymentRedirected(String jsonString) {
Log.d(TAG, "onPaymentRedirected - processing redirect payment");
Log.d(TAG, "jsonString" + jsonString);
try {
JSONObject results = new JSONObject(jsonString);
PreferencesManager prefs = PreferencesManager.getInstance(getApplication());
prefs.saveString("lastPaymentRedirectResults", jsonString);
// Update amount and currency
amount.set(results.optString("amount", "0.00"));
currencyCode.set(results.optString("currencySymbol", "RUB"));;
String status = results.optString("status", "");
switch (status) {
case "success":
Log.d(TAG, "Redirect Payment Success");
paymentStatus.setValue(PaymentStatus.SUCCESS);
break;
case "failed":
Log.d(TAG, "Redirect Payment Failed");
paymentStatus.setValue(PaymentStatus.FAILED);
break;
default:
Log.w(TAG, "Unknown JSON type: " + status);
paymentStatus.setValue(PaymentStatus.WAITING);
}
} catch (JSONException e) {
Log.e(TAG, "Error parsing JSON", e);
// paymentStatus.setValue(PaymentStatus.FAILED);
}
}
}

View File

@ -17,6 +17,7 @@ import com.dspread.pos.common.manager.FragmentCacheManager;
import com.dspread.pos.TitleProviderListener; import com.dspread.pos.TitleProviderListener;
import com.dspread.pos.common.manager.ScreensaverManager; import com.dspread.pos.common.manager.ScreensaverManager;
import com.dspread.pos.posAPI.POS; import com.dspread.pos.posAPI.POS;
import com.dspread.pos.ui.cashier.CashierFragment;
import com.dspread.pos.ui.home.HomeFragment; import com.dspread.pos.ui.home.HomeFragment;
import com.dspread.pos.ui.mulberry.MulberryFragment; import com.dspread.pos.ui.mulberry.MulberryFragment;
import com.dspread.pos.ui.printer.PrinterHelperFragment; import com.dspread.pos.ui.printer.PrinterHelperFragment;
@ -148,6 +149,8 @@ public class MainViewModel extends BaseViewModel {
return new PrinterHelperFragment(); return new PrinterHelperFragment();
case R.id.nav_scan: case R.id.nav_scan:
return new ScanFragment(); return new ScanFragment();
case R.id.nav_cashier:
return new CashierFragment();
case R.id.nav_mulberry: case R.id.nav_mulberry:
return new MulberryFragment(); return new MulberryFragment();
} }

View File

@ -250,6 +250,10 @@ public class PaymentViewModel extends BaseAppViewModel {
public BindingCommand continueTxnsCommand = new BindingCommand(new BindingAction() { public BindingCommand continueTxnsCommand = new BindingCommand(new BindingAction() {
@Override @Override
public void call() { public void call() {
// paymentData.put("status", "failed");
// sendWebSocketMessage(paymentData.toString());
// titleText.set("Payment"); // titleText.set("Payment");
// stopLoading(); // stopLoading();
// showPinpad.set(false); // showPinpad.set(false);
@ -278,7 +282,7 @@ public class PaymentViewModel extends BaseAppViewModel {
paymentData.put("amount", amountDouble); paymentData.put("amount", amountDouble);
paymentData.put("currencySymbol", currencySymbol); paymentData.put("currencySymbol", currencySymbol);
paymentData.put("id", "01723060202412010160"); paymentData.put("id", "01723060202412010160");
paymentData.put("status", "success");
Log.d(TAG, "call: this is M50 maybe"); Log.d(TAG, "call: this is M50 maybe");
sendWebSocketMessage(paymentData.toString()); sendWebSocketMessage(paymentData.toString());

View File

@ -0,0 +1,82 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<import type="android.view.View" />
<!-- Import the PaymentStatus enum -->
<import type="com.dspread.pos.ui.cashier.CashierViewModel.PaymentStatus" />
<variable
name="viewModel"
type="com.dspread.pos.ui.cashier.CashierViewModel" />
</data>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="16dp">
<!-- Waiting State -->
<LinearLayout
android:id="@+id/waitingLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:visibility="@{viewModel.paymentStatus == PaymentStatus.WAITING ? View.VISIBLE : View.GONE}">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Please tap or scan QR code on M50 pinpad"
android:textSize="18sp"
android:textStyle="bold"
android:gravity="center" />
</LinearLayout>
<!-- Success State -->
<LinearLayout
android:id="@+id/successLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:visibility="@{viewModel.paymentStatus == PaymentStatus.SUCCESS ? View.VISIBLE : View.GONE}">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{viewModel.amount + ` ` + viewModel.currencyCode}"
android:textSize="24sp"
android:textStyle="bold"
android:gravity="center" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Print Receipt"
android:onClick="@{() -> viewModel.printReceipt()}"
android:layout_marginTop="16dp" />
</LinearLayout>
<!-- Failed State -->
<LinearLayout
android:id="@+id/failedLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:visibility="@{viewModel.paymentStatus == PaymentStatus.FAILED ? View.VISIBLE : View.GONE}">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Payment Failed. Please try again."
android:textSize="18sp"
android:textStyle="bold"
android:gravity="center" />
</LinearLayout>
</LinearLayout>
</layout>

View File

@ -32,6 +32,11 @@
android:icon="@drawable/scan" android:icon="@drawable/scan"
android:title="@string/scan" android:title="@string/scan"
/> />
<item
android:id="@+id/nav_cashier"
android:icon="@drawable/scan"
android:title="@string/cashier"
/>
<item <item
android:id="@+id/nav_setting" android:id="@+id/nav_setting"

View File

@ -545,4 +545,5 @@
<string name="send_receipt">Print Receipt</string> <string name="send_receipt">Print Receipt</string>
<string name="connect_warnning">Pls connect your devices first!</string> <string name="connect_warnning">Pls connect your devices first!</string>
<string name="no_device">No device</string> <string name="no_device">No device</string>
<string name="cashier">Cashier</string>
</resources> </resources>

View File

@ -545,5 +545,6 @@
<string name="send_receipt">Print Receipt</string> <string name="send_receipt">Print Receipt</string>
<string name="connect_warnning">Pls connect your devices first!</string> <string name="connect_warnning">Pls connect your devices first!</string>
<string name="no_device">No device</string> <string name="no_device">No device</string>
<string name="cashier">Cashier</string>
</resources> </resources>