Compare commits
3 Commits
acc5ec1b70
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4ef19bd4e8 | ||
|
|
c0e5072523 | ||
|
|
4eaca7e1d8 |
4
.idea/deploymentTargetSelector.xml
generated
4
.idea/deploymentTargetSelector.xml
generated
@@ -4,10 +4,10 @@
|
|||||||
<selectionStates>
|
<selectionStates>
|
||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
<DropdownSelection timestamp="2026-02-13T13:45:19.610071900Z">
|
<DropdownSelection timestamp="2026-04-03T13:27:33.582048600Z">
|
||||||
<Target type="DEFAULT_BOOT">
|
<Target type="DEFAULT_BOOT">
|
||||||
<handle>
|
<handle>
|
||||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=5051918437" />
|
<DeviceId pluginId="PhysicalDevice" identifier="serial=5051917024" />
|
||||||
</handle>
|
</handle>
|
||||||
</Target>
|
</Target>
|
||||||
</DropdownSelection>
|
</DropdownSelection>
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import java.util.Properties
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
alias(libs.plugins.android.application)
|
alias(libs.plugins.android.application)
|
||||||
alias(libs.plugins.google.android.libraries.mapsplatform.secrets.gradle.plugin)
|
alias(libs.plugins.google.android.libraries.mapsplatform.secrets.gradle.plugin)
|
||||||
@@ -5,6 +7,13 @@ plugins {
|
|||||||
alias(libs.plugins.kotlin.android)
|
alias(libs.plugins.kotlin.android)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val keystoreProperties = Properties()
|
||||||
|
val keystorePropertiesFile = rootProject.file("local.properties")
|
||||||
|
|
||||||
|
if (keystorePropertiesFile.exists()) {
|
||||||
|
keystoreProperties.load(keystorePropertiesFile.inputStream())
|
||||||
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.example.quiz"
|
namespace = "com.example.quiz"
|
||||||
compileSdk = 34
|
compileSdk = 34
|
||||||
@@ -19,22 +28,37 @@ android {
|
|||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signingConfigs {
|
||||||
|
create("release") {
|
||||||
|
storeFile = file(keystoreProperties["STORE_FILE"] as String)
|
||||||
|
storePassword = keystoreProperties["STORE_PASSWORD"] as String
|
||||||
|
keyAlias = keystoreProperties["KEY_ALIAS"] as String
|
||||||
|
keyPassword = keystoreProperties["KEY_PASSWORD"] as String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
isMinifyEnabled = false
|
isMinifyEnabled = false
|
||||||
|
signingConfig = signingConfigs.getByName("release")
|
||||||
|
|
||||||
proguardFiles(
|
proguardFiles(
|
||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
getDefaultProguardFile("proguard-android-optimize.txt"),
|
||||||
"proguard-rules.pro"
|
"proguard-rules.pro"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = JavaVersion.VERSION_11
|
sourceCompatibility = JavaVersion.VERSION_11
|
||||||
targetCompatibility = JavaVersion.VERSION_11
|
targetCompatibility = JavaVersion.VERSION_11
|
||||||
}
|
}
|
||||||
|
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
viewBinding = true
|
viewBinding = true
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "17"
|
jvmTarget = "17"
|
||||||
}
|
}
|
||||||
@@ -42,35 +66,52 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
|
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
|
||||||
|
|
||||||
implementation(libs.room.runtime)
|
implementation(libs.room.runtime)
|
||||||
annotationProcessor(libs.room.compiler)
|
annotationProcessor(libs.room.compiler)
|
||||||
|
|
||||||
|
implementation("com.github.NaikSoftware:StompProtocolAndroid:1.6.6")
|
||||||
|
|
||||||
|
implementation("io.reactivex.rxjava2:rxjava:2.2.21")
|
||||||
|
implementation("io.reactivex.rxjava2:rxandroid:2.1.1")
|
||||||
|
|
||||||
|
implementation(libs.retrofit)
|
||||||
|
implementation(libs.okhttp)
|
||||||
|
implementation(libs.logging.interceptor)
|
||||||
|
implementation(libs.converter.gson)
|
||||||
|
|
||||||
|
implementation(libs.kotlinx.coroutines.android)
|
||||||
|
|
||||||
|
implementation(libs.hilt.android)
|
||||||
|
annotationProcessor(libs.hilt.compiler)
|
||||||
|
|
||||||
|
implementation(libs.recyclerview.v7)
|
||||||
|
implementation(libs.appcompat)
|
||||||
|
implementation(libs.material)
|
||||||
|
implementation(libs.constraintlayout)
|
||||||
|
|
||||||
|
implementation(libs.printerlibrary)
|
||||||
|
|
||||||
|
implementation(libs.navigation.fragment)
|
||||||
|
implementation(libs.navigation.ui)
|
||||||
|
|
||||||
|
implementation(libs.play.services.maps)
|
||||||
|
|
||||||
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
|
||||||
|
|
||||||
implementation("androidx.camera:camera-camera2:1.2.3")
|
implementation("androidx.camera:camera-camera2:1.2.3")
|
||||||
implementation("androidx.camera:camera-lifecycle:1.2.3")
|
implementation("androidx.camera:camera-lifecycle:1.2.3")
|
||||||
implementation("androidx.camera:camera-view:1.2.3")
|
implementation("androidx.camera:camera-view:1.2.3")
|
||||||
implementation("androidx.camera:camera-core:1.2.3")
|
implementation("androidx.camera:camera-core:1.2.3")
|
||||||
|
|
||||||
implementation("com.google.mlkit:barcode-scanning:17.2.0")
|
implementation("com.google.mlkit:barcode-scanning:17.2.0")
|
||||||
implementation(libs.retrofit)
|
|
||||||
implementation(libs.okhttp)
|
|
||||||
implementation(libs.logging.interceptor)
|
|
||||||
implementation(libs.kotlinx.coroutines.android)
|
|
||||||
implementation(libs.converter.gson)
|
|
||||||
implementation(libs.hilt.android)
|
|
||||||
annotationProcessor(libs.hilt.compiler)
|
|
||||||
implementation(libs.rxjava)
|
|
||||||
implementation(libs.rxandroid)
|
|
||||||
implementation(libs.recyclerview.v7)
|
|
||||||
implementation(libs.appcompat)
|
|
||||||
implementation(libs.material)
|
|
||||||
implementation(libs.google.core)
|
|
||||||
implementation(libs.zxing.android.embedded)
|
implementation(libs.zxing.android.embedded)
|
||||||
implementation(libs.constraintlayout)
|
|
||||||
implementation(libs.navigation.fragment)
|
|
||||||
implementation(libs.navigation.ui)
|
|
||||||
implementation(libs.play.services.maps)
|
|
||||||
implementation(project(":printama"))
|
implementation(project(":printama"))
|
||||||
|
|
||||||
testImplementation(libs.junit)
|
testImplementation(libs.junit)
|
||||||
androidTestImplementation(libs.ext.junit)
|
androidTestImplementation(libs.ext.junit)
|
||||||
androidTestImplementation(libs.espresso.core)
|
androidTestImplementation(libs.espresso.core)
|
||||||
|
implementation("androidx.annotation:annotation:1.7.1")
|
||||||
}
|
}
|
||||||
@@ -14,6 +14,13 @@
|
|||||||
android:usesPermissionFlags="neverForLocation" />
|
android:usesPermissionFlags="neverForLocation" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
||||||
|
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||||
|
|
||||||
|
<uses-permission android:name="com.sunmi.peripheral.printer.permission.PRINTER" />
|
||||||
|
|
||||||
|
<!-- Pour certains modèles -->
|
||||||
|
<uses-permission android:name="android.permission.BIND_PRINTER_SERVICE" />
|
||||||
|
|
||||||
|
|
||||||
<!-- ✅ Location Permissions -->
|
<!-- ✅ Location Permissions -->
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||||
@@ -38,6 +45,10 @@
|
|||||||
<uses-feature android:name="android.hardware.camera" />
|
<uses-feature android:name="android.hardware.camera" />
|
||||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||||
|
|
||||||
|
<queries>
|
||||||
|
<package android:name="woyou.aidlservice.jiuiv5" />
|
||||||
|
</queries>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".PmuHorseBetting"
|
android:name=".PmuHorseBetting"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
@@ -50,10 +61,6 @@
|
|||||||
android:theme="@style/Theme.Quiz"
|
android:theme="@style/Theme.Quiz"
|
||||||
tools:targetApi="31"
|
tools:targetApi="31"
|
||||||
android:usesCleartextTraffic="true">
|
android:usesCleartextTraffic="true">
|
||||||
<activity
|
|
||||||
android:name=".PageQuiz"
|
|
||||||
android:exported="true"
|
|
||||||
android:theme="@style/Theme.Quiz" />
|
|
||||||
<!--
|
<!--
|
||||||
TODO: Before you run your application, you need a Google Maps API key.
|
TODO: Before you run your application, you need a Google Maps API key.
|
||||||
|
|
||||||
@@ -71,7 +78,7 @@
|
|||||||
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".PageQuiz"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:theme="@style/Theme.Quiz">
|
android:theme="@style/Theme.Quiz">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
|
|||||||
337
app/src/main/java/com/example/quiz/AgentDetails.java
Normal file
337
app/src/main/java/com/example/quiz/AgentDetails.java
Normal file
@@ -0,0 +1,337 @@
|
|||||||
|
package com.example.quiz;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.example.quiz.data.adapter.MultiTypeOfBetsAdapter;
|
||||||
|
import com.example.quiz.data.model.Course;
|
||||||
|
import com.example.quiz.data.model.Restriction;
|
||||||
|
import com.example.quiz.data.model.TypeOfBet;
|
||||||
|
import com.example.quiz.data.model.dtos.auth.User;
|
||||||
|
import com.example.quiz.databinding.FragmentAgentDetailsBinding;
|
||||||
|
import com.example.quiz.utils.LoaderDialog;
|
||||||
|
import com.example.quiz.utils.MessageDialog;
|
||||||
|
import com.example.quiz.utils.Result;
|
||||||
|
import com.example.quiz.utils.SharedPrefsHelper;
|
||||||
|
import com.example.quiz.viewModel.AgentViewModel;
|
||||||
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple {@link Fragment} subclass.
|
||||||
|
* Use the {@link AgentDetails#newInstance} factory method to
|
||||||
|
* create an instance of this fragment.
|
||||||
|
*/
|
||||||
|
@AndroidEntryPoint
|
||||||
|
public class AgentDetails extends Fragment {
|
||||||
|
|
||||||
|
// TODO: Rename parameter arguments, choose names that match
|
||||||
|
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||||
|
private String agentId;
|
||||||
|
private FragmentAgentDetailsBinding binding;
|
||||||
|
MultiTypeOfBetsAdapter multiTypeOfBetsAdapter;
|
||||||
|
LogsViewModel logsViewModel;
|
||||||
|
private AgentViewModel agentViewModel;
|
||||||
|
|
||||||
|
private boolean userInteraction = false;
|
||||||
|
|
||||||
|
private User agent;
|
||||||
|
|
||||||
|
private Restriction allowedBetTypes;
|
||||||
|
|
||||||
|
private SharedPrefsHelper prefsHelper;
|
||||||
|
|
||||||
|
private LoaderDialog loaderDialog;
|
||||||
|
|
||||||
|
public AgentDetails() {
|
||||||
|
// Required empty public constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final String AGENT_ID = "agentId";
|
||||||
|
|
||||||
|
// TODO: Rename and change types and number of parameters
|
||||||
|
public static AgentDetails newInstance(User agent) {
|
||||||
|
AgentDetails fragment = new AgentDetails();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putString(AGENT_ID, String.valueOf(agent.getId()));
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
if (getArguments() != null) {
|
||||||
|
agentId = getArguments().getString(AGENT_ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
// Inflate the layout for this fragment
|
||||||
|
binding = FragmentAgentDetailsBinding.inflate(inflater, container, false);
|
||||||
|
agentViewModel = new ViewModelProvider(this).get(AgentViewModel.class);
|
||||||
|
allowedBetTypes = new Restriction();
|
||||||
|
prefsHelper = SharedPrefsHelper.getInstance(getContext());
|
||||||
|
loaderDialog = new LoaderDialog(getContext());
|
||||||
|
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
|
||||||
|
return binding.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
loadAgentDetails(agentId);
|
||||||
|
binding.switchAccess.setOnCheckedChangeListener((compoundButton, b) -> {
|
||||||
|
if(!userInteraction){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String message = b ? "Voulez-vous activer l'accès à l'agent ?" : "Voulez-vous désactiver l'accès à l'agent ?";
|
||||||
|
new AlertDialog.Builder(getContext())
|
||||||
|
.setTitle("Activation de l'accès")
|
||||||
|
.setMessage(message)
|
||||||
|
.setPositiveButton("Oui", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
if(prefsHelper.get("id")== null){
|
||||||
|
MessageDialog.showError(getContext(), "Veuillez vous connecter");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String masterId = prefsHelper.get("id");
|
||||||
|
agentViewModel.setAccess(masterId, agentId, !b).observe(getViewLifecycleOwner(), new Observer<Result<Void>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<Void> voidResult) {
|
||||||
|
switch (voidResult.status){
|
||||||
|
case LOADING:{
|
||||||
|
loaderDialog.show("Chargement des agents");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), voidResult.message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SUCCESS:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
MessageDialog.showSuccess(getContext(), "L'accès a été mis à jour");
|
||||||
|
String logsMessage = !b? "Activation de l'accès du sous agent":"Désactivation de l'accès du sous agent";
|
||||||
|
logsViewModel.insertLog(prefsHelper.get("id"), !b?"ACTIVATION":"DESACTIVATION",message+" "+agent.getCode(), System.currentTimeMillis());
|
||||||
|
loadAgentDetails(agentId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).setNegativeButton("Non", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
dialogInterface.dismiss();
|
||||||
|
}
|
||||||
|
}).show();
|
||||||
|
});
|
||||||
|
binding.btnValidate.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
if(prefsHelper.get("id")== null){
|
||||||
|
MessageDialog.showError(getContext(), "Veuillez vous connecter");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(allowedBetTypes.getAllowedBetTypes() == null || allowedBetTypes.getAllowedBetTypes().isEmpty()){
|
||||||
|
MessageDialog.showError(getContext(), "Veuillez sélectionner au moins un type de paris");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(agent == null){
|
||||||
|
MessageDialog.showError(getContext(), "Veuillez charger les détails de l'agent");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String masterId = prefsHelper.get("id");
|
||||||
|
new AlertDialog.Builder(getContext())
|
||||||
|
.setTitle("Valider la sélection")
|
||||||
|
.setMessage("Êtes-vous sûr de vouloir valider la sélection ?")
|
||||||
|
.setPositiveButton("Oui", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
agentViewModel.setRestrictions(masterId, agentId, allowedBetTypes).observe(getViewLifecycleOwner(), new Observer<Result<Void>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<Void> voidResult) {
|
||||||
|
switch (voidResult.status){
|
||||||
|
case LOADING:{
|
||||||
|
loaderDialog.show("Chargement des agents");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), voidResult.message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SUCCESS:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
logsViewModel.insertLog(prefsHelper.get("id"), "MIS A JOUR PRODUIT", "Mise à jour des types de paris"+" "+agent.getCode()+": "+allowedBetTypes.getAllowedBetTypes().stream().map(Enum::toString).collect(Collectors.joining(",")), System.currentTimeMillis());
|
||||||
|
MessageDialog.showSuccess(getContext(), "Les types de paris ont été mises à jour");
|
||||||
|
loadAgentDetails(agentId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton("Non", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
dialogInterface.dismiss();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadAgentDetails(String slaveId){
|
||||||
|
agentViewModel.getAgentById(slaveId).observe(getViewLifecycleOwner(), new Observer<Result<User>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<User> userResult) {
|
||||||
|
switch (userResult.status){
|
||||||
|
case LOADING:{
|
||||||
|
loaderDialog.show("Chargement des agents");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), userResult.message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SUCCESS:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
agent = userResult.data;
|
||||||
|
binding.txtCode.setText(agent.getCode());
|
||||||
|
String adresse;
|
||||||
|
if(agent.getVille() != null && agent.getAdresse() != null){
|
||||||
|
adresse = agent.getVille()+"; "+agent.getAdresse();
|
||||||
|
}else{
|
||||||
|
adresse = "Pas d'adresse";
|
||||||
|
}
|
||||||
|
binding.txtAdresse.setText(adresse);
|
||||||
|
userInteraction = false;
|
||||||
|
binding.switchAccess.setChecked(agent.getStatut().equals("ACTIF"));
|
||||||
|
userInteraction = true;
|
||||||
|
loadAvailableBets(String.valueOf(agent.getId()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadAvailableBets(String id){
|
||||||
|
agentViewModel.getAvailableBets(id).observe(getViewLifecycleOwner(), new Observer<Result<List<Course.TypeParis>>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<List<Course.TypeParis>> listResult) {
|
||||||
|
switch (listResult.status){
|
||||||
|
case LOADING:{
|
||||||
|
loaderDialog.show("Chargement des paris disponibles");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), listResult.message);
|
||||||
|
}
|
||||||
|
case SUCCESS:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
List<TypeOfBet> types = createTypeOfBetList();
|
||||||
|
multiTypeOfBetsAdapter = new MultiTypeOfBetsAdapter(types);
|
||||||
|
multiTypeOfBetsAdapter.preSelectAvailableBets(listResult.data);
|
||||||
|
binding.betsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
binding.betsRecyclerView.setAdapter(multiTypeOfBetsAdapter);
|
||||||
|
List<Course.TypeParis> selectedTypes = multiTypeOfBetsAdapter.getSelectedItems().stream().map(TypeOfBet::getName).collect(Collectors.toList());
|
||||||
|
allowedBetTypes.setAllowedBetTypes(selectedTypes);
|
||||||
|
multiTypeOfBetsAdapter.setOnItemClickListener(new MultiTypeOfBetsAdapter.onItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(TypeOfBet type, boolean isChecked) {
|
||||||
|
List<Course.TypeParis> selectedTypes = multiTypeOfBetsAdapter.getSelectedItems().stream().map(TypeOfBet::getName).collect(Collectors.toList());
|
||||||
|
allowedBetTypes.setAllowedBetTypes(selectedTypes);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onItemsSelected(List<TypeOfBet> selectedItems) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<TypeOfBet> createTypeOfBetList() {
|
||||||
|
List<TypeOfBet> types = new ArrayList<>();
|
||||||
|
|
||||||
|
// 1. COUPLE GAGNANT
|
||||||
|
TypeOfBet coupleGagnant = new TypeOfBet(
|
||||||
|
"Couple Gagnant", // label
|
||||||
|
Course.TypeParis.COUPLE_GAGNANT, // name
|
||||||
|
2 // numberOfHorse (2 chevaux)
|
||||||
|
);
|
||||||
|
types.add(coupleGagnant);
|
||||||
|
|
||||||
|
// 2. COUPLE PLACE
|
||||||
|
TypeOfBet couplePlace = new TypeOfBet(
|
||||||
|
"Couple Place", // label
|
||||||
|
Course.TypeParis.COUPLE_PLACE, // name
|
||||||
|
2 // numberOfHorse (2 chevaux)
|
||||||
|
);
|
||||||
|
types.add(couplePlace);
|
||||||
|
|
||||||
|
// 3. TIERCE
|
||||||
|
TypeOfBet tierce = new TypeOfBet(
|
||||||
|
"Tiercé", // label
|
||||||
|
Course.TypeParis.TIERCE, // name
|
||||||
|
3 // numberOfHorse (3 chevaux)
|
||||||
|
);
|
||||||
|
types.add(tierce);
|
||||||
|
|
||||||
|
// 4. QUARTE
|
||||||
|
TypeOfBet quarte = new TypeOfBet(
|
||||||
|
"Quarté", // label
|
||||||
|
Course.TypeParis.QUARTE, // name
|
||||||
|
4 // numberOfHorse (4 chevaux)
|
||||||
|
);
|
||||||
|
types.add(quarte);
|
||||||
|
|
||||||
|
// 5. QUINTE (optionnel)
|
||||||
|
TypeOfBet quinte = new TypeOfBet(
|
||||||
|
"Quinté", // label
|
||||||
|
Course.TypeParis.QUINTE, // name
|
||||||
|
5 // numberOfHorse (5 chevaux)
|
||||||
|
);
|
||||||
|
types.add(quinte);
|
||||||
|
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
}
|
||||||
135
app/src/main/java/com/example/quiz/AgentManagement.java
Normal file
135
app/src/main/java/com/example/quiz/AgentManagement.java
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
package com.example.quiz;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.example.quiz.data.adapter.AgentItemAdapter;
|
||||||
|
import com.example.quiz.data.model.dtos.auth.User;
|
||||||
|
import com.example.quiz.databinding.FragmentAgentManagementBinding;
|
||||||
|
import com.example.quiz.utils.AuthNavigator;
|
||||||
|
import com.example.quiz.utils.LoaderDialog;
|
||||||
|
import com.example.quiz.utils.MessageDialog;
|
||||||
|
import com.example.quiz.utils.Result;
|
||||||
|
import com.example.quiz.utils.SessionManager;
|
||||||
|
import com.example.quiz.utils.SharedPrefsHelper;
|
||||||
|
import com.example.quiz.viewModel.AgentViewModel;
|
||||||
|
import com.example.quiz.viewModel.LoginViewModel;
|
||||||
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple {@link Fragment} subclass.
|
||||||
|
* Use the {@link AgentManagement#newInstance} factory method to
|
||||||
|
* create an instance of this fragment.
|
||||||
|
*/
|
||||||
|
@AndroidEntryPoint
|
||||||
|
public class AgentManagement extends Fragment {
|
||||||
|
|
||||||
|
// TODO: Rename parameter arguments, choose names that match
|
||||||
|
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||||
|
|
||||||
|
private FragmentAgentManagementBinding binding;
|
||||||
|
private LoaderDialog loaderDialog;
|
||||||
|
|
||||||
|
private AgentViewModel agentViewModel;
|
||||||
|
SharedPrefsHelper prefsHelper;
|
||||||
|
|
||||||
|
AgentItemAdapter agentItemAdapter;
|
||||||
|
|
||||||
|
AuthNavigator authNavigator;
|
||||||
|
|
||||||
|
public AgentManagement() {
|
||||||
|
// Required empty public constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Rename and change types and number of parameters
|
||||||
|
public static AgentManagement newInstance() {
|
||||||
|
AgentManagement fragment = new AgentManagement();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), SessionManager.newInstance(getContext()),new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
// Inflate the layout for this fragment
|
||||||
|
binding = FragmentAgentManagementBinding.inflate(inflater, container, false);
|
||||||
|
agentViewModel = new ViewModelProvider(this).get(AgentViewModel.class);
|
||||||
|
loaderDialog = new LoaderDialog(getContext());
|
||||||
|
prefsHelper = SharedPrefsHelper.getInstance(getContext());
|
||||||
|
return binding.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
|
||||||
|
AppCompatActivity activity = (AppCompatActivity) getActivity();
|
||||||
|
if(activity != null){
|
||||||
|
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
|
||||||
|
activity.setSupportActionBar(toolbar);
|
||||||
|
|
||||||
|
if (activity.getSupportActionBar() != null) {
|
||||||
|
activity.getSupportActionBar().show();
|
||||||
|
activity.getSupportActionBar().setTitle("Gestion aides");
|
||||||
|
}
|
||||||
|
toolbar.setBackgroundColor(getResources().getColor(R.color.primary_green, null));
|
||||||
|
toolbar.setTitleTextColor(getResources().getColor(R.color.white, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
String agentId = prefsHelper.get("id");
|
||||||
|
if(agentId == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
agentViewModel.getAgents(agentId).observe(getViewLifecycleOwner(), new Observer<Result<List<User>>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<List<User>> listResult) {
|
||||||
|
switch (listResult.status){
|
||||||
|
case LOADING:{
|
||||||
|
loaderDialog.show("Chargement des agents");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), listResult.message);
|
||||||
|
}
|
||||||
|
case SUCCESS:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
agentItemAdapter = new AgentItemAdapter(listResult.data);
|
||||||
|
binding.agentList.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
binding.agentList.setAdapter(agentItemAdapter);
|
||||||
|
agentItemAdapter.setOnItemClickListener(new AgentItemAdapter.onItemClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(User agent) {
|
||||||
|
AgentDetails agentDetails = AgentDetails.newInstance(agent);
|
||||||
|
authNavigator.navigate(agentDetails);
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.example.quiz;
|
package com.example.quiz;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
@@ -88,34 +89,73 @@ public class AnnulationTicket extends Fragment {
|
|||||||
binding.annuleTicketBtn.setOnClickListener(v->{
|
binding.annuleTicketBtn.setOnClickListener(v->{
|
||||||
String reference = binding.referenceTicket.getText().toString();
|
String reference = binding.referenceTicket.getText().toString();
|
||||||
if(reference.isEmpty()){
|
if(reference.isEmpty()){
|
||||||
Toast.makeText(getContext(),"Entrez la référence du ticket", Toast.LENGTH_SHORT).show();
|
MessageDialog.showError(getContext(), "Veuillez donner la reference du ticket");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
viewModel.annulerPari(reference).observe(getViewLifecycleOwner(), new Observer<Result<ParisResponse>>() {
|
viewModel.getPariByNumero(reference).observe(getViewLifecycleOwner(), new Observer<Result<ParisResponse>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(Result<ParisResponse> pariResult) {
|
public void onChanged(Result<ParisResponse> parisResponseResult) {
|
||||||
switch (pariResult.status){
|
switch (parisResponseResult.status){
|
||||||
case LOADING:{
|
case LOADING:{
|
||||||
dialog.show("Annulation du ticket");
|
dialog.show("Recherche du ticket");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ERROR:{
|
case ERROR:{
|
||||||
dialog.dismiss();
|
MessageDialog.showError(getContext(), parisResponseResult.message);
|
||||||
MessageDialog.showError(getContext(), pariResult.message);
|
break;
|
||||||
break;
|
}
|
||||||
}
|
case SUCCESS:{
|
||||||
case SUCCESS:{
|
if(parisResponseResult.data.getNumeroTicket().equals(reference)){
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
MessageDialog.showSuccess(getContext(), "Ticket annulé avec succès");
|
if(parisResponseResult.data.getStatutPari() == ParisResponse.StatutPari.ANNULE){
|
||||||
logsViewModel.insertLog(prefsHelper.get("id"), "ANNULATION TICKET", "Annulation du ticket "+pariResult.data.getNumeroTicket(), System.currentTimeMillis());
|
MessageDialog.showError(getContext(), "Le ticket est déjà annulé");
|
||||||
binding.referenceTicket.setText("");
|
return;
|
||||||
}
|
}
|
||||||
}
|
_showPariDialog(reference);
|
||||||
|
}else{
|
||||||
|
MessageDialog.showError(getContext(), "Le ticket n'existe pas");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _showPariDialog(String ticketReference){
|
||||||
|
new AlertDialog.Builder(getContext())
|
||||||
|
.setTitle("Annulation du ticket")
|
||||||
|
.setMessage("Etes-vous sûr de vouloir annuler le ticket "+ticketReference+" ?")
|
||||||
|
.setCancelable(true)
|
||||||
|
.setNegativeButton("Annuler", (dialog, which) -> {
|
||||||
|
dialog.dismiss();
|
||||||
|
})
|
||||||
|
.setPositiveButton("Confirmer", (annulationDialog, which) -> {
|
||||||
|
viewModel.annulerPari(ticketReference).observe(getViewLifecycleOwner(), new Observer<Result<ParisResponse>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<ParisResponse> pariResult) {
|
||||||
|
switch (pariResult.status){
|
||||||
|
case LOADING:{
|
||||||
|
dialog.show("Annulation du ticket");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR:{
|
||||||
|
dialog.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), pariResult.message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SUCCESS:{
|
||||||
|
dialog.dismiss();
|
||||||
|
MessageDialog.showSuccess(getContext(), "Ticket annulé avec succès");
|
||||||
|
logsViewModel.insertLog(prefsHelper.get("id"), "ANNULATION TICKET", "Annulation du ticket "+pariResult.data.getNumeroTicket(), System.currentTimeMillis());
|
||||||
|
binding.referenceTicket.setText("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).show();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
package com.example.quiz;
|
package com.example.quiz;
|
||||||
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.app.Dialog;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.graphics.ColorMatrix;
|
||||||
|
import android.graphics.ColorMatrixColorFilter;
|
||||||
|
import android.graphics.Paint;
|
||||||
import android.graphics.drawable.ColorDrawable;
|
import android.graphics.drawable.ColorDrawable;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.ActivityResultLauncher;
|
||||||
@@ -15,10 +21,7 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.core.app.ActivityCompat;
|
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
|
||||||
import androidx.lifecycle.LiveData;
|
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.Observer;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
@@ -37,38 +40,49 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.anggastudio.printama.Printama;
|
import com.anggastudio.printama.Printama;
|
||||||
import com.example.quiz.data.model.Course;
|
import com.example.quiz.data.model.Course;
|
||||||
|
import com.example.quiz.data.model.MiseInitiale;
|
||||||
import com.example.quiz.data.model.Pari;
|
import com.example.quiz.data.model.Pari;
|
||||||
import com.example.quiz.data.model.PariMise;
|
import com.example.quiz.data.model.PariMise;
|
||||||
import com.example.quiz.data.model.ParisResponse;
|
import com.example.quiz.data.model.ParisResponse;
|
||||||
import com.example.quiz.data.model.Reunion;
|
|
||||||
import com.example.quiz.data.model.TypeOfBet;
|
import com.example.quiz.data.model.TypeOfBet;
|
||||||
import com.example.quiz.data.model.dtos.PariCourseDto;
|
import com.example.quiz.data.model.dtos.NotifPayload;
|
||||||
import com.example.quiz.data.model.enums.PariStatut;
|
import com.example.quiz.data.remote.StompManager;
|
||||||
import com.example.quiz.databinding.FragmentBetValidationBinding;
|
import com.example.quiz.databinding.FragmentBetValidationBinding;
|
||||||
import com.example.quiz.utils.BluetoothUtils;
|
import com.example.quiz.utils.BluetoothUtils;
|
||||||
import com.example.quiz.utils.LoaderDialog;
|
import com.example.quiz.utils.LoaderDialog;
|
||||||
import com.example.quiz.utils.MessageDialog;
|
import com.example.quiz.utils.MessageDialog;
|
||||||
import com.example.quiz.utils.Result;
|
import com.example.quiz.utils.Result;
|
||||||
import com.example.quiz.utils.SharedPrefsHelper;
|
import com.example.quiz.utils.SharedPrefsHelper;
|
||||||
|
import com.example.quiz.utils.SunmiPrinterManager;
|
||||||
import com.example.quiz.viewModel.LogsViewModel;
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
|
import com.example.quiz.viewModel.PariMiseViewModel;
|
||||||
import com.example.quiz.viewModel.PariViewModel;
|
import com.example.quiz.viewModel.PariViewModel;
|
||||||
import com.example.quiz.viewModel.SharedViewModel;
|
import com.example.quiz.viewModel.SharedViewModel;
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
import com.google.zxing.BarcodeFormat;
|
import com.google.zxing.BarcodeFormat;
|
||||||
import com.google.zxing.MultiFormatWriter;
|
import com.google.zxing.MultiFormatWriter;
|
||||||
import com.google.zxing.WriterException;
|
import com.google.zxing.WriterException;
|
||||||
import com.google.zxing.common.BitMatrix;
|
import com.google.zxing.common.BitMatrix;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.lang.reflect.Type;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Observable;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -82,10 +96,21 @@ public class BetValidation extends Fragment {
|
|||||||
|
|
||||||
FragmentBetValidationBinding binding;
|
FragmentBetValidationBinding binding;
|
||||||
|
|
||||||
|
|
||||||
SharedViewModel shared;
|
SharedViewModel shared;
|
||||||
|
|
||||||
|
|
||||||
|
PariMiseViewModel pariMiseViewModel;
|
||||||
|
|
||||||
|
List<MiseInitiale> misesInitiales;
|
||||||
|
|
||||||
private AlertDialog dialog;
|
private AlertDialog dialog;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
StompManager stompManager;
|
||||||
|
|
||||||
|
SunmiPrinterManager sunmiPrinterManager;
|
||||||
|
|
||||||
private int nombreX;
|
private int nombreX;
|
||||||
|
|
||||||
LogsViewModel logsViewModel;
|
LogsViewModel logsViewModel;
|
||||||
@@ -95,16 +120,20 @@ public class BetValidation extends Fragment {
|
|||||||
|
|
||||||
private long mise;
|
private long mise;
|
||||||
|
|
||||||
|
String mobileName;
|
||||||
|
|
||||||
|
|
||||||
private TypeOfBet typeOfBet;
|
private TypeOfBet typeOfBet;
|
||||||
|
|
||||||
|
MutableLiveData<Boolean> isPrinterReady = new MutableLiveData<>(false);
|
||||||
|
|
||||||
SharedPrefsHelper prefsHelper;
|
SharedPrefsHelper prefsHelper;
|
||||||
|
|
||||||
|
|
||||||
private Course course;
|
private Course course;
|
||||||
|
|
||||||
LoaderDialog loader;
|
|
||||||
|
|
||||||
|
LoaderDialog loader;
|
||||||
|
|
||||||
|
|
||||||
private int coeff;
|
private int coeff;
|
||||||
@@ -117,12 +146,11 @@ public class BetValidation extends Fragment {
|
|||||||
PariViewModel pariViewModel;
|
PariViewModel pariViewModel;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public BetValidation() {
|
public BetValidation() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BetValidation newInstance() {
|
public static BetValidation newInstance() {
|
||||||
BetValidation fragment = new BetValidation();
|
BetValidation fragment = new BetValidation();
|
||||||
Bundle args = new Bundle();
|
Bundle args = new Bundle();
|
||||||
fragment.setArguments(args);
|
fragment.setArguments(args);
|
||||||
@@ -133,8 +161,16 @@ public class BetValidation extends Fragment {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
prefsHelper = SharedPrefsHelper.getInstance(getContext());
|
prefsHelper = SharedPrefsHelper.getInstance(getContext());
|
||||||
|
mobileName = Build.MANUFACTURER;
|
||||||
|
sunmiPrinterManager = SunmiPrinterManager.getInstance(requireContext());
|
||||||
|
if(mobileName.toLowerCase().contains("sunmi")){
|
||||||
|
sunmiPrinterManager.connectPrinter(status ->{
|
||||||
|
isPrinterReady.setValue(status);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
@@ -143,7 +179,7 @@ public class BetValidation extends Fragment {
|
|||||||
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
|
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
|
||||||
binding.coeff.setText(String.valueOf(1));
|
binding.coeff.setText(String.valueOf(1));
|
||||||
coeff = Integer.parseInt(binding.coeff.getText().toString());
|
coeff = Integer.parseInt(binding.coeff.getText().toString());
|
||||||
binding.coeff.addTextChangedListener(new TextWatcher(){
|
binding.coeff.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||||
|
|
||||||
@@ -151,11 +187,11 @@ public class BetValidation extends Fragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||||
if(charSequence.toString().isEmpty()){
|
if (charSequence.toString().isEmpty()) {
|
||||||
binding.coeff.setError("Le coefficient est obligatoire");
|
binding.coeff.setError("Le coefficient est obligatoire");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(Integer.parseInt(charSequence.toString())<1){
|
if (Integer.parseInt(charSequence.toString()) < 1) {
|
||||||
binding.coeff.setError("Le coefficient doit être supérieur ou égal à 1 ");
|
binding.coeff.setError("Le coefficient doit être supérieur ou égal à 1 ");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -176,7 +212,7 @@ public class BetValidation extends Fragment {
|
|||||||
binding.gridNumbers.removeAllViews();
|
binding.gridNumbers.removeAllViews();
|
||||||
int columns = 8;
|
int columns = 8;
|
||||||
grid.setColumnCount(columns);
|
grid.setColumnCount(columns);
|
||||||
if(shared.selectedCourse.getValue() != null){
|
if (shared.selectedCourse.getValue() != null) {
|
||||||
for (int i = 1; i <= shared.selectedCourse.getValue().getNombrePartants(); i++) {
|
for (int i = 1; i <= shared.selectedCourse.getValue().getNombrePartants(); i++) {
|
||||||
createNumberItem(String.valueOf(i));
|
createNumberItem(String.valueOf(i));
|
||||||
grid.addView(createNumberItem(String.valueOf(i)));
|
grid.addView(createNumberItem(String.valueOf(i)));
|
||||||
@@ -185,7 +221,6 @@ public class BetValidation extends Fragment {
|
|||||||
createNumberItem("X");
|
createNumberItem("X");
|
||||||
grid.addView(createNumberItem("X"));
|
grid.addView(createNumberItem("X"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private TextView createNumberItem(String horse) {
|
private TextView createNumberItem(String horse) {
|
||||||
TextView textView = new TextView(requireContext());
|
TextView textView = new TextView(requireContext());
|
||||||
textView.setText(horse);
|
textView.setText(horse);
|
||||||
@@ -197,53 +232,53 @@ public class BetValidation extends Fragment {
|
|||||||
textView.setWidth(80);
|
textView.setWidth(80);
|
||||||
textView.setHeight(100);
|
textView.setHeight(100);
|
||||||
textView.setGravity(Gravity.CENTER);
|
textView.setGravity(Gravity.CENTER);
|
||||||
textView.setBackgroundResource(Objects.equals(horse, "X") ?R.drawable.x_background: R.drawable.number_background);
|
textView.setBackgroundResource(Objects.equals(horse, "X") ? R.drawable.x_background : R.drawable.number_background);
|
||||||
if(!Objects.equals(horse, "X") && shared.selectedCourse.getValue().getNonPartants() != null && shared.selectedCourse.getValue().getNonPartants().contains(Integer.valueOf(horse))){
|
if (!Objects.equals(horse, "X") && shared.selectedCourse.getValue().getNonPartants() != null && shared.selectedCourse.getValue().getNonPartants().contains(Integer.valueOf(horse))) {
|
||||||
textView.setTextColor(getResources().getColor(R.color.white));
|
textView.setTextColor(getResources().getColor(R.color.white));
|
||||||
textView.setBackgroundResource(R.drawable.number_background_grey);
|
textView.setBackgroundResource(R.drawable.number_background_grey);
|
||||||
}
|
}
|
||||||
textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
|
||||||
textView.setOnClickListener(v -> {
|
textView.setOnClickListener(v -> {
|
||||||
if(!Objects.equals(horse, "X") && shared.selectedCourse.getValue().getNonPartants() != null && shared.selectedCourse.getValue().getNonPartants().contains(Integer.valueOf(horse))){
|
if (!Objects.equals(horse, "X") && shared.selectedCourse.getValue().getNonPartants() != null && shared.selectedCourse.getValue().getNonPartants().contains(Integer.valueOf(horse))) {
|
||||||
Toast.makeText(getContext(), "Ce cheval n'est pas partant", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Ce cheval n'est pas partant", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final List<String> horses = new ArrayList<>(selectedHorses.getValue());
|
final List<String> horses = new ArrayList<>(selectedHorses.getValue());
|
||||||
if(horses.size() >= shared.typeOfBet.getValue().getNumberOfHorse() && horse.equals("X")){
|
if (horses.size() >= shared.typeOfBet.getValue().getNumberOfHorse() && horse.equals("X")) {
|
||||||
Toast.makeText(getContext(), "Vous ne pouvez plus sélectionner X", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Vous ne pouvez plus sélectionner X", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(_notClickable(horses) && horse.equals("X")){
|
if (_notClickable(horses) && horse.equals("X")) {
|
||||||
Toast.makeText(getContext(), "Vous ne pouvez plus sélectionner X", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Vous ne pouvez plus sélectionner X", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (horses.contains(horse) && !horse.equals("X")) {
|
if (horses.contains(horse) && !horse.equals("X")) {
|
||||||
horses.remove(horse);
|
horses.remove(horse);
|
||||||
selectedHorses.setValue(horses);
|
selectedHorses.setValue(horses);
|
||||||
v.setSelected(false);
|
v.setSelected(false);
|
||||||
v.setBackgroundResource(R.drawable.number_background);
|
v.setBackgroundResource(R.drawable.number_background);
|
||||||
} else {
|
} else {
|
||||||
horses.add(horse);
|
horses.add(horse);
|
||||||
selectedHorses.setValue(horses);
|
selectedHorses.setValue(horses);
|
||||||
v.setSelected(true);
|
v.setSelected(true);
|
||||||
v.setBackgroundResource(R.drawable.number_selected_background);
|
v.setBackgroundResource(R.drawable.number_selected_background);
|
||||||
}
|
}
|
||||||
String combinationText = selectedHorses.getValue().stream()
|
String combinationText = selectedHorses.getValue().stream()
|
||||||
.map(h -> h)
|
.map(h -> h)
|
||||||
.collect(Collectors.joining("-"));
|
.collect(Collectors.joining("-"));
|
||||||
binding.combination.setText( combinationText);
|
binding.combination.setText(combinationText);
|
||||||
});
|
});
|
||||||
return textView;
|
return textView;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
boolean _notClickable(List<String> selectedHorses){
|
boolean _notClickable(List<String> selectedHorses) {
|
||||||
int numberOfElement = 0;
|
int numberOfElement = 0;
|
||||||
if(shared.typeOfBet.getValue().getNumberOfHorse() < 2){
|
if (shared.typeOfBet.getValue().getNumberOfHorse() < 2) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for(String horse: selectedHorses){
|
for (String horse : selectedHorses) {
|
||||||
numberOfElement = horse.equals("X")?numberOfElement+1:numberOfElement;
|
numberOfElement = horse.equals("X") ? numberOfElement + 1 : numberOfElement;
|
||||||
}
|
}
|
||||||
nombreX = numberOfElement;
|
nombreX = numberOfElement;
|
||||||
return numberOfElement == shared.typeOfBet.getValue().getNumberOfHorse() - 1;
|
return numberOfElement == shared.typeOfBet.getValue().getNumberOfHorse() - 1;
|
||||||
@@ -253,20 +288,54 @@ public class BetValidation extends Fragment {
|
|||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
|
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
|
||||||
|
pariMiseViewModel = new ViewModelProvider(this).get(PariMiseViewModel.class);
|
||||||
|
pariMiseViewModel.getBetInitMise().observe(
|
||||||
|
getViewLifecycleOwner(),
|
||||||
|
result -> {
|
||||||
|
switch (result.status) {
|
||||||
|
case LOADING: {
|
||||||
|
loader.show("Chargement des mise");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SUCCESS: {
|
||||||
|
misesInitiales = result.data;
|
||||||
|
loader.dismiss();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR: {
|
||||||
|
loader.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), result.message);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (shared.selectedCourse.getValue() != null) {
|
||||||
|
stompManager.subscribe("courses/" + shared.selectedCourse.getValue().getId(), json -> {
|
||||||
|
Type type = new TypeToken<NotifPayload<Course>>() {
|
||||||
|
}.getType();
|
||||||
|
NotifPayload<Course> notif = new Gson().fromJson(json, type);
|
||||||
|
Course updatedCourse = notif.getPayload();
|
||||||
|
if (shared.selectedCourse.getValue().getId() == updatedCourse.getId()) {
|
||||||
|
shared.setSelectedCourse(updatedCourse);
|
||||||
|
setupNumberGrid(binding.gridNumbers);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
setSelectedTypeOfBetImage();
|
setSelectedTypeOfBetImage();
|
||||||
pariViewModel = new ViewModelProvider(this).get(PariViewModel.class);
|
pariViewModel = new ViewModelProvider(this).get(PariViewModel.class);
|
||||||
typeOfBet = shared.typeOfBet.getValue();
|
typeOfBet = shared.typeOfBet.getValue();
|
||||||
course = shared.selectedCourse.getValue();
|
course = shared.selectedCourse.getValue();
|
||||||
AppCompatActivity activity = (AppCompatActivity) getActivity();
|
AppCompatActivity activity = (AppCompatActivity) getActivity();
|
||||||
if(activity != null){
|
if (activity != null) {
|
||||||
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
|
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
|
||||||
toolbar.setBackgroundColor( getResources().getColor(R.color.primary_green));
|
toolbar.setBackgroundColor(getResources().getColor(R.color.primary_green));
|
||||||
activity.setSupportActionBar(toolbar);
|
activity.setSupportActionBar(toolbar);
|
||||||
if(activity.getSupportActionBar() != null){
|
if (activity.getSupportActionBar() != null) {
|
||||||
activity.getSupportActionBar().setTitle("Pari "+shared.selectedCourse.getValue().getNom());
|
activity.getSupportActionBar().setTitle("Pari " + shared.selectedCourse.getValue().getNom());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setupNumberGrid(binding.gridNumbers);
|
setupNumberGrid(binding.gridNumbers);
|
||||||
binding.paymentType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
binding.paymentType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||||
@Override
|
@Override
|
||||||
@@ -291,28 +360,28 @@ public class BetValidation extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onChanged(List<String> horses) {
|
public void onChanged(List<String> horses) {
|
||||||
calculateMise(horses);
|
calculateMise(horses);
|
||||||
if(shared.typeOfBet.getValue().getNumberOfHorse() > 2 && horses.size() >= shared.typeOfBet.getValue().getNumberOfHorse()){
|
if (shared.typeOfBet.getValue().getNumberOfHorse() > 2 && horses.size() >= shared.typeOfBet.getValue().getNumberOfHorse()) {
|
||||||
binding.order.setVisibility(View.VISIBLE);
|
binding.order.setVisibility(View.VISIBLE);
|
||||||
}else{
|
} else {
|
||||||
binding.order.setVisibility(View.GONE);
|
binding.order.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
if(horses.contains("X")){
|
if (horses.contains("X")) {
|
||||||
if(selectedHorses.getValue().size() == shared.typeOfBet.getValue().getNumberOfHorse()){
|
if (selectedHorses.getValue().size() == shared.typeOfBet.getValue().getNumberOfHorse()) {
|
||||||
binding.elargie.setVisibility(View.VISIBLE);
|
binding.elargie.setVisibility(View.VISIBLE);
|
||||||
binding.elargie.setText("Champ total");
|
binding.elargie.setText("Champ total");
|
||||||
return;
|
return;
|
||||||
}else{
|
} else {
|
||||||
if(selectedHorses.getValue().size() > shared.typeOfBet.getValue().getNumberOfHorse()){
|
if (selectedHorses.getValue().size() > shared.typeOfBet.getValue().getNumberOfHorse()) {
|
||||||
binding.elargie.setVisibility(View.VISIBLE);
|
binding.elargie.setVisibility(View.VISIBLE);
|
||||||
binding.elargie.setText("Champ partiel");
|
binding.elargie.setText("Champ partiel");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(horses.size() > shared.typeOfBet.getValue().getNumberOfHorse()){
|
if (horses.size() > shared.typeOfBet.getValue().getNumberOfHorse()) {
|
||||||
binding.elargie.setVisibility(View.VISIBLE);
|
binding.elargie.setVisibility(View.VISIBLE);
|
||||||
binding.elargie.setText("Elargi");
|
binding.elargie.setText("Elargi");
|
||||||
}else{
|
} else {
|
||||||
binding.elargie.setVisibility(View.GONE);
|
binding.elargie.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -322,24 +391,24 @@ public class BetValidation extends Fragment {
|
|||||||
calculateMise(selectedHorses.getValue());
|
calculateMise(selectedHorses.getValue());
|
||||||
});
|
});
|
||||||
|
|
||||||
binding.betValidateBtn.setOnClickListener(v->{
|
binding.betValidateBtn.setOnClickListener(v -> {
|
||||||
if(binding.paymentType.getSelectedItem().toString().equals("Orange Money") && binding.phoneNumber.getText().toString().isEmpty()){
|
if (binding.paymentType.getSelectedItem().toString().equals("Orange Money") && binding.phoneNumber.getText().toString().isEmpty()) {
|
||||||
Toast.makeText(getContext(), "Veuillez entrer un numéro de téléphone", Toast.LENGTH_SHORT).show();
|
MessageDialog.showError(getContext(), "Veuillez saisir le numéro de téléphone");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(shared.typeOfBet == null || shared.selectedCourse == null){
|
if (shared.typeOfBet == null || shared.selectedCourse == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int required = typeOfBet.getNumberOfHorse();
|
int required = typeOfBet.getNumberOfHorse();
|
||||||
if(selectedHorses.getValue().size() < required){
|
if (Objects.requireNonNull(selectedHorses.getValue()).size() < required) {
|
||||||
Toast.makeText(getContext(), "Veuillez sélectionner au moins"+required+" chevaux", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Veuillez sélectionner au moins" + required + " chevaux", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.mise == 0){
|
if (this.mise == 0) {
|
||||||
Toast.makeText(getContext(), "Pari non valide", Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), "Pari non valide", Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -357,61 +426,63 @@ public class BetValidation extends Fragment {
|
|||||||
"XOF",
|
"XOF",
|
||||||
"Pari"
|
"Pari"
|
||||||
);
|
);
|
||||||
|
if (dialog != null && dialog.isShowing()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
_showPariDialog(pari);
|
_showPariDialog(pari);
|
||||||
});
|
});
|
||||||
|
|
||||||
binding.backBtn.setOnClickListener(v->{
|
binding.backBtn.setOnClickListener(v -> {
|
||||||
getActivity().onBackPressed();
|
getActivity().onBackPressed();
|
||||||
});
|
});
|
||||||
|
|
||||||
binding.deleteBtn.setOnClickListener(v->{
|
binding.deleteBtn.setOnClickListener(v -> {
|
||||||
_initializeToZero();
|
_initializeToZero();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String _getCombinaison() {
|
||||||
String _getCombinaison(){
|
if (selectedHorses.getValue().contains("X") && shared.typeOfBet.getValue().getNumberOfHorse() < selectedHorses.getValue().size()) {
|
||||||
if(selectedHorses.getValue().contains("X") && shared.typeOfBet.getValue().getNumberOfHorse() < selectedHorses.getValue().size()){
|
|
||||||
String first = selectedHorses.getValue().subList(0, shared.typeOfBet.getValue().getNumberOfHorse()).stream()
|
String first = selectedHorses.getValue().subList(0, shared.typeOfBet.getValue().getNumberOfHorse()).stream()
|
||||||
.map(String::valueOf)
|
.map(String::valueOf)
|
||||||
.collect(Collectors.joining(","));
|
.collect(Collectors.joining(","));
|
||||||
String last = selectedHorses.getValue().subList(shared.typeOfBet.getValue().getNumberOfHorse(), selectedHorses.getValue().size()).stream()
|
String last = selectedHorses.getValue().subList(shared.typeOfBet.getValue().getNumberOfHorse(), selectedHorses.getValue().size()).stream()
|
||||||
.map(String::valueOf)
|
.map(String::valueOf)
|
||||||
.collect(Collectors.joining(","));
|
.collect(Collectors.joining(","));
|
||||||
return first+",R,"+last;
|
return first + ",R," + last;
|
||||||
}else{
|
} else {
|
||||||
return selectedHorses.getValue().stream().map(String::valueOf).collect(Collectors.joining(","));
|
return selectedHorses.getValue().stream().map(String::valueOf).collect(Collectors.joining(","));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> _getFormule(){
|
List<String> _getFormule() {
|
||||||
List<String> combinaison = selectedHorses.getValue();
|
List<String> combinaison = selectedHorses.getValue();
|
||||||
if(!combinaison.contains("X")){
|
if (!combinaison.contains("X")) {
|
||||||
if(!order){
|
if (!order) {
|
||||||
return List.of("UNITAIRE");
|
return List.of("UNITAIRE");
|
||||||
}else{
|
} else {
|
||||||
return List.of("FORMULE_COMPLETE");
|
return List.of("FORMULE_COMPLETE");
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
if(shared.typeOfBet.getValue().getNumberOfHorse() < selectedHorses.getValue().size()){
|
if (shared.typeOfBet.getValue().getNumberOfHorse() < selectedHorses.getValue().size()) {
|
||||||
if(order){
|
if (order) {
|
||||||
return List.of("CHAMP_X", "FORMULE_COMPLETE");
|
return List.of("CHAMP_X", "FORMULE_COMPLETE");
|
||||||
}else{
|
} else {
|
||||||
return List.of("CHAMP_X");
|
return List.of("CHAMP_X");
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
if(order){
|
if (order) {
|
||||||
return List.of("CHAMP_TOTAL", "FORMULE_COMPLETE");
|
return List.of("CHAMP_TOTAL", "FORMULE_COMPLETE");
|
||||||
}else{
|
} else {
|
||||||
return List.of("CHAMP_TOTAL");
|
return List.of("CHAMP_TOTAL");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setSelectedTypeOfBetImage(){
|
private void setSelectedTypeOfBetImage() {
|
||||||
switch (shared.typeOfBet.getValue().getName()){
|
switch (shared.typeOfBet.getValue().getName()) {
|
||||||
case COUPLE_PLACE:
|
case COUPLE_PLACE:
|
||||||
binding.icTypeOfBet.setImageResource(R.drawable.ic_couple_place);
|
binding.icTypeOfBet.setImageResource(R.drawable.ic_couple_place);
|
||||||
break;
|
break;
|
||||||
@@ -431,35 +502,41 @@ public class BetValidation extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void printPari(ParisResponse pari) throws WriterException {
|
public void printPari(ParisResponse pari) throws WriterException {
|
||||||
try {
|
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
|
||||||
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
|
Bitmap barcode = generateBarcodeBitmap(pari.getNumeroTicket(), 384, 100);
|
||||||
Bitmap barcode = generateBarcodeBitmap(pari.getNumeroTicket(), 384, 100);
|
StringBuilder tspl = new StringBuilder();
|
||||||
StringBuilder tspl = new StringBuilder();
|
tspl.append("Bamako").append("\n");
|
||||||
Printama printama = Printama.with(getContext());
|
tspl.append(shared.selectedCourse.getValue().getNom()).append("\n");
|
||||||
|
OffsetDateTime dateTime = OffsetDateTime.parse(shared.selectedCourse.getValue().getHeureDepartPrevue());
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
|
||||||
|
String formattedDate = dateTime.format(formatter);
|
||||||
|
tspl.append(formattedDate).append("\n");
|
||||||
|
tspl.append("Course ").append(String.valueOf(shared.selectedCourse.getValue().getId())).append("\n");
|
||||||
|
tspl.append(sunmiPrinterManager.separationText()+ "\n");
|
||||||
|
boolean isElargie = selectedHorses.getValue().size() > shared.typeOfBet.getValue().getNumberOfHorse();
|
||||||
|
String typePari = pari.getTypesParisMises().get(0).getTypePari();
|
||||||
|
tspl.append(isElargie ? typePari + "/Elargie" : typePari).append("\n");
|
||||||
|
tspl.append(order ? "COMBINAISON COMPLETE" + "\n" : "");
|
||||||
|
String combinationText = formatLineWithNumbers(selectedHorses.getValue().stream().map(String::valueOf).toArray(String[]::new), "-") ;
|
||||||
|
tspl.append(combinationText).append("\n");
|
||||||
|
tspl.append("COEF: ").append(String.valueOf(coeff)).append(".0");
|
||||||
|
tspl.append("\n").append(sunmiPrinterManager.separationText()).append("\n");
|
||||||
|
tspl.append("MONTANT: ").append(pari.getTypesParisMises().get(0).getMiseTotale()).append(" XOF");
|
||||||
|
tspl.append("\n").append(sunmiPrinterManager.separationText()).append("\n");
|
||||||
|
tspl.append("AGENT: ").append(prefsHelper.get("code")).append("\n");
|
||||||
|
tspl.append("DATE: ").append(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss").format(LocalDateTime.now())).append("\n");
|
||||||
|
if(mobileName.toLowerCase().contains("sunmi")){
|
||||||
|
String pariText = tspl.toString();
|
||||||
|
if(!sunmiPrinterManager.printPari(resizeToPrinterWidth(bitmap, 384), barcode, pari.getNumeroTicket(), pariText)){
|
||||||
|
MessageDialog.showError(getContext(), "Erreur d'impression");
|
||||||
|
prefsHelper.save("noPrintId", String.valueOf(pari.getId()));
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
_initializeToZero();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tspl.append("Bamako").append("\n");
|
try {
|
||||||
tspl.append(shared.selectedCourse.getValue().getNom()).append("\n");
|
|
||||||
OffsetDateTime dateTime = OffsetDateTime.parse(shared.selectedCourse.getValue().getHeureDepartPrevue());
|
|
||||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
|
|
||||||
String formattedDate = dateTime.format(formatter);
|
|
||||||
tspl.append(formattedDate).append("\n");
|
|
||||||
tspl.append("Course ").append(String.valueOf(shared.selectedCourse.getValue().getId())).append("\n");
|
|
||||||
tspl.append(shared.selectedCourse.getValue().getTypesParisOuverts().get(0)).append("\n");
|
|
||||||
tspl.append(printama.lineSeparator()+"\n");
|
|
||||||
boolean isElargie = selectedHorses.getValue().size()>shared.typeOfBet.getValue().getNumberOfHorse();
|
|
||||||
String typePari = pari.getTypesParisMises().get(0).getTypePari();
|
|
||||||
tspl.append(isElargie?typePari+"/Elargie":typePari).append("\n");
|
|
||||||
tspl.append(order?"COMBINAISON COMPLETE"+"\n":"");
|
|
||||||
String combinationText = selectedHorses.getValue().stream()
|
|
||||||
.map(String::valueOf)
|
|
||||||
.collect(Collectors.joining("-"));
|
|
||||||
tspl.append(combinationText).append("\n");
|
|
||||||
tspl.append("COEF: ").append(String.valueOf(coeff)).append(".0");
|
|
||||||
tspl.append("\n").append(printama.lineSeparator()).append("\n");
|
|
||||||
tspl.append("MONTANT: ").append(pari.getTypesParisMises().get(0).getMiseTotale()).append(" XOF");
|
|
||||||
tspl.append("\n").append(printama.lineSeparator()).append("\n");
|
|
||||||
tspl.append("AGENT: ").append(prefsHelper.get("code")).append("\n");
|
|
||||||
tspl.append("DATE: ").append(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss").format(LocalDateTime.now())).append("\n");
|
|
||||||
if (BluetoothUtils.needsBluetoothPermissions()) {
|
if (BluetoothUtils.needsBluetoothPermissions()) {
|
||||||
if (!BluetoothUtils.hasBluetoothPermission(requireContext())) {
|
if (!BluetoothUtils.hasBluetoothPermission(requireContext())) {
|
||||||
// Demande la permission si non accordée
|
// Demande la permission si non accordée
|
||||||
@@ -470,8 +547,28 @@ public class BetValidation extends Fragment {
|
|||||||
|
|
||||||
// 2️⃣ Permission OK, on peut afficher la liste
|
// 2️⃣ Permission OK, on peut afficher la liste
|
||||||
|
|
||||||
Printama.with(getContext()).printTextBuilder(tspl, bitmap, pari.getNumeroTicket(), barcode);
|
Printama.with(getContext()).printTextBuilder(tspl, bitmap, pari.getNumeroTicket(), barcode, new Printama.PrintCallback() {
|
||||||
_initializeToZero();
|
@Override
|
||||||
|
public void onResult(boolean success, String errorMessage) {
|
||||||
|
if (!success) {
|
||||||
|
new android.app.AlertDialog.Builder(getContext())
|
||||||
|
.setTitle("Impréssion pari")
|
||||||
|
.setMessage("Voulez-vous rééimprimer ce ticket?")
|
||||||
|
.setPositiveButton("Oui", (dialog, which) -> {
|
||||||
|
try {
|
||||||
|
printPari(pari);
|
||||||
|
} catch (WriterException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.setNegativeButton("Non", (dialog, which) -> {
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
_initializeToZero();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
Toast.makeText(requireContext(),
|
Toast.makeText(requireContext(),
|
||||||
"Permission Bluetooth non accordée", Toast.LENGTH_SHORT).show();
|
"Permission Bluetooth non accordée", Toast.LENGTH_SHORT).show();
|
||||||
@@ -479,36 +576,103 @@ public class BetValidation extends Fragment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String formatLineWithNumbers(String[] numbers, String separator) {
|
||||||
|
StringBuilder currentLine = new StringBuilder();
|
||||||
|
StringBuilder finalOutput = new StringBuilder();
|
||||||
|
List<String> formatted = new ArrayList<>();
|
||||||
|
int requiredHorse = shared.typeOfBet.getValue().getNumberOfHorse();
|
||||||
|
if(Arrays.stream(numbers).map(String::valueOf).collect(Collectors.toList()).contains("X")){
|
||||||
|
if(numbers.length <= requiredHorse){
|
||||||
|
return Arrays.stream(numbers).map(String::valueOf).collect(Collectors.joining("-")).toString();
|
||||||
|
}
|
||||||
|
List<String> firstPart = Arrays.stream(numbers).limit(requiredHorse).map(String::valueOf).collect(Collectors.toList());
|
||||||
|
List<String> secondPart = Arrays.stream(numbers).skip(requiredHorse).map(String::valueOf).collect(Collectors.toList());
|
||||||
|
formatted.addAll(firstPart);
|
||||||
|
formatted.add("R");
|
||||||
|
formatted.addAll(secondPart);
|
||||||
|
}else{
|
||||||
|
formatted = Arrays.stream(numbers).map(String::valueOf).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (String number : formatted) {
|
||||||
|
String element = (currentLine.length() == 0 ? "":separator) + number;
|
||||||
|
|
||||||
|
// Si l'ajout dépasse la largeur max, on termine la ligne et on recommence
|
||||||
|
if (currentLine.length() + element.length() > sunmiPrinterManager.getMaxChar()) {
|
||||||
|
finalOutput.append(currentLine.toString()).append("\n");
|
||||||
|
currentLine = new StringBuilder(number);
|
||||||
|
} else {
|
||||||
|
currentLine.append(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentLine.length() > 0) {
|
||||||
|
finalOutput.append(currentLine.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalOutput.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressLint({"MissingInflatedId", "SetTextI18n"})
|
@SuppressLint({"MissingInflatedId", "SetTextI18n"})
|
||||||
void _showPariDialog(Pari pari){
|
void _showPariDialog(Pari pari) {
|
||||||
LayoutInflater inflater = getLayoutInflater();
|
LayoutInflater inflater = getLayoutInflater();
|
||||||
View view = inflater.inflate(R.layout.pari_confirmation, null);
|
View view = inflater.inflate(R.layout.pari_confirmation, null);
|
||||||
TextView numero_course = (TextView) view.findViewById(R.id.alert_course_numero);
|
TextView numero_course = (TextView) view.findViewById(R.id.alert_course_numero);
|
||||||
numero_course.setText("Numero Course: "+String.valueOf(shared.selectedCourse.getValue().getId()));
|
numero_course.setText("Numero Course: " + String.valueOf(shared.selectedCourse.getValue().getId()));
|
||||||
TextView alert_pari_type = (TextView) view.findViewById(R.id.alert_pari_type);
|
TextView alert_pari_type = (TextView) view.findViewById(R.id.alert_pari_type);
|
||||||
alert_pari_type.setText(String.valueOf(shared.typeOfBet.getValue().getName()));
|
alert_pari_type.setText(String.valueOf(shared.typeOfBet.getValue().getName()));
|
||||||
TextView is_elargie = (TextView) view.findViewById(R.id.alert_is_elargie);
|
TextView is_elargie = (TextView) view.findViewById(R.id.alert_is_elargie);
|
||||||
is_elargie.setText(selectedHorses.getValue().size() > shared.typeOfBet.getValue().getNumberOfHorse()?"CE":"SI");
|
is_elargie.setText(selectedHorses.getValue().size() > shared.typeOfBet.getValue().getNumberOfHorse() ? "CE" : "SI");
|
||||||
TextView alert_combinaison = (TextView) view.findViewById(R.id.alert_combinaison);
|
TextView alert_combinaison = (TextView) view.findViewById(R.id.alert_combinaison);
|
||||||
alert_combinaison.setText(selectedHorses.getValue().stream()
|
alert_combinaison.setText(selectedHorses.getValue().stream()
|
||||||
.map(String::valueOf)
|
.map(String::valueOf)
|
||||||
.collect(Collectors.joining("-")));
|
.collect(Collectors.joining("-")));
|
||||||
TextView aler_coeff = (TextView) view.findViewById(R.id.alert_coeff);
|
TextView aler_coeff = (TextView) view.findViewById(R.id.alert_coeff);
|
||||||
aler_coeff.setText("Coef:"+String.valueOf(coeff));
|
aler_coeff.setText("Coef:" + String.valueOf(coeff));
|
||||||
TextView alert_montant = (TextView) view.findViewById(R.id.alert_montant);
|
TextView alert_montant = (TextView) view.findViewById(R.id.alert_montant);
|
||||||
alert_montant.setText("Montant: "+String.valueOf(pari.getTypesParisMises().get(0).getMiseTotale())+" CFA");
|
alert_montant.setText("Montant: " + String.valueOf(pari.getTypesParisMises().get(0).getMiseTotale()) + " CFA");
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||||
builder.setView(view);
|
builder.setView(view);
|
||||||
builder.setCancelable(false);
|
builder.setCancelable(false);
|
||||||
|
|
||||||
dialog = builder.create();
|
dialog = builder.create();
|
||||||
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||||
|
|
||||||
view.findViewById(R.id.alert_validate).setOnClickListener(v->{
|
view.findViewById(R.id.alert_validate).setOnClickListener(v -> {
|
||||||
pariViewModel.createPari(pari).observe(getViewLifecycleOwner(),new Observer<Result<ParisResponse>>() {
|
if(mobileName.toLowerCase().contains("sunmi")){
|
||||||
|
if(isPrinterReady.getValue() != null && !isPrinterReady.getValue()){
|
||||||
|
sunmiPrinterManager.connectPrinter(status ->{
|
||||||
|
isPrinterReady.setValue(status);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
switch (sunmiPrinterManager.printerStatus()){
|
||||||
|
case 2:{
|
||||||
|
MessageDialog.showError(getContext(), "L'imprimante n'est pas connectée!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 3:{
|
||||||
|
MessageDialog.showError(getContext(), "L'imprimante n'est pas disponible!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 4:{
|
||||||
|
MessageDialog.showError(getContext(), "Veuillez insérer du papier dans l'imprimante, SVP!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
MessageDialog.showError(getContext(), "Suchauffe iminante de l'imprimante, Veuillez laisser reposer!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case 6: {
|
||||||
|
MessageDialog.showError(getContext(), "Le capot est ouvert, veuillez fermer SVP!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pariViewModel.createPari(pari).observe(getViewLifecycleOwner(), new Observer<Result<ParisResponse>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(Result<ParisResponse> pariResult) {
|
public void onChanged(Result<ParisResponse> pariResult) {
|
||||||
switch (pariResult.status){
|
switch (pariResult.status) {
|
||||||
case ERROR:
|
case ERROR:
|
||||||
loader.dismiss();
|
loader.dismiss();
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
@@ -520,8 +684,8 @@ public class BetValidation extends Fragment {
|
|||||||
case SUCCESS:
|
case SUCCESS:
|
||||||
try {
|
try {
|
||||||
loader.dismiss();
|
loader.dismiss();
|
||||||
|
logsViewModel.insertLog(prefsHelper.get("id"), "BET", "Création du pari " + pariResult.data.getNumeroTicket() + ", type de paris: " + pariResult.data.getTypesParisMises().get(0).getTypePari() + ", combinaison:" + selectedHorses.getValue().stream().map(String::valueOf).collect(Collectors.joining("-")), System.currentTimeMillis());
|
||||||
printPari(pariResult.data);
|
printPari(pariResult.data);
|
||||||
logsViewModel.insertLog(prefsHelper.get("id"), "BET", "Création du pari "+pariResult.data.getNumeroTicket()+" type de paris: "+pariResult.data.getTypesParisMises().get(0).getTypePari(), System.currentTimeMillis());
|
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
MessageDialog.showSuccess(getContext(), "Pari créé avec succès");
|
MessageDialog.showSuccess(getContext(), "Pari créé avec succès");
|
||||||
} catch (WriterException e) {
|
} catch (WriterException e) {
|
||||||
@@ -540,7 +704,7 @@ public class BetValidation extends Fragment {
|
|||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _initializeToZero(){
|
void _initializeToZero() {
|
||||||
selectedHorses.setValue(List.of());
|
selectedHorses.setValue(List.of());
|
||||||
binding.combination.setText("");
|
binding.combination.setText("");
|
||||||
binding.order.setChecked(false);
|
binding.order.setChecked(false);
|
||||||
@@ -551,78 +715,148 @@ public class BetValidation extends Fragment {
|
|||||||
setupNumberGrid(binding.gridNumbers);
|
setupNumberGrid(binding.gridNumbers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void calculateMise(List<String> selectedHorses){
|
public void calculateMise(List<String> selectedHorses) {
|
||||||
_notClickable(selectedHorses);
|
_notClickable(selectedHorses);
|
||||||
int nombreChevauxSelectionnes = selectedHorses.size();
|
int nombreChevauxSelectionnes = selectedHorses.size();
|
||||||
long mise = 0;
|
long mise = 0;
|
||||||
int nonPartants = 0;
|
int nonPartants = 0;
|
||||||
if(shared.typeOfBet.getValue() == null || shared.selectedCourse.getValue() == null){
|
if (shared.typeOfBet.getValue() == null || shared.selectedCourse.getValue() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(shared.selectedCourse.getValue().getNonPartants() != null){
|
if (shared.selectedCourse.getValue().getNonPartants() != null) {
|
||||||
nonPartants = shared.selectedCourse.getValue().getNonPartants().size();
|
nonPartants = shared.selectedCourse.getValue().getNonPartants().size();
|
||||||
}
|
}
|
||||||
int typeOfBetHorses = shared.typeOfBet.getValue().getNumberOfHorse();
|
int typeOfBetHorses = shared.typeOfBet.getValue().getNumberOfHorse();
|
||||||
int partants = shared.selectedCourse.getValue().getNombrePartants();
|
int partants = shared.selectedCourse.getValue().getNombrePartants();
|
||||||
if(shared.typeOfBet.getValue().getNumberOfHorse() > nombreChevauxSelectionnes){
|
Course.TypeParis courseName = shared.typeOfBet.getValue().getName();
|
||||||
binding.mise.setText(mise+" CFA");
|
if (shared.typeOfBet.getValue().getNumberOfHorse() > nombreChevauxSelectionnes) {
|
||||||
|
binding.mise.setText(mise + " CFA");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(typeOfBetHorses == 2){
|
MiseInitiale miseModel = misesInitiales.stream()
|
||||||
mise = 500;
|
.filter(miseInitiale -> miseInitiale.getTypePari().equals(courseName))
|
||||||
}else{
|
.findFirst()
|
||||||
if(typeOfBetHorses == 5){
|
.orElse(null);
|
||||||
mise = 300;
|
if (miseModel == null) {
|
||||||
}else{
|
MessageDialog.showError(getContext(), "Erreur lors de l'initialisation de la mise");
|
||||||
mise = 200;
|
_initializeToZero();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mise = miseModel.getMiseInitialeMin();
|
||||||
|
|
||||||
|
Course.TypeParis typePari = shared.typeOfBet.getValue().getName();
|
||||||
|
boolean estCoupleGagnantOuPlace = typePari.equals(Course.TypeParis.COUPLE_GAGNANT) || typePari.equals(Course.TypeParis.COUPLE_PLACE);
|
||||||
|
Log.d("TYPE_PARI", typePari.toString());
|
||||||
|
|
||||||
|
if (estCoupleGagnantOuPlace) {
|
||||||
|
// Pour COUPLE_GAGNANT ou COUPLE_PLACE: coefficient < 200
|
||||||
|
if (coeff > 200) {
|
||||||
|
// Erreur: coefficient trop élevé
|
||||||
|
MessageDialog.showError(getContext(), "Le coefficient doit être au plus 200 pour " + typePari.toString());
|
||||||
|
_initializeToZero();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Pour les autres types: coefficient <= 20
|
||||||
|
if (coeff > 20) {
|
||||||
|
// Erreur: coefficient trop élevé
|
||||||
|
MessageDialog.showError(getContext(), "Le coefficient doit être inférieur ou égal à 20 pour " + typePari.toString());
|
||||||
|
_initializeToZero();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mise = mise * coeff;
|
mise = mise * coeff;
|
||||||
if(nombreX>0){
|
if (nombreX > 0) {
|
||||||
if(nombreChevauxSelectionnes == typeOfBetHorses){
|
if (nombreChevauxSelectionnes == typeOfBetHorses) {
|
||||||
mise = mise * _calculateArrangement((partants - (typeOfBetHorses-nombreX) - nonPartants), nombreX);
|
mise = mise * _calculateArrangement((partants - (typeOfBetHorses - nombreX) - nonPartants), nombreX);
|
||||||
}else{
|
} else {
|
||||||
if(nombreChevauxSelectionnes - typeOfBetHorses < nombreX || nombreChevauxSelectionnes - typeOfBetHorses==1){
|
if (nombreChevauxSelectionnes - typeOfBetHorses < nombreX || nombreChevauxSelectionnes - typeOfBetHorses == 1) {
|
||||||
mise = 0;
|
mise = 0;
|
||||||
this.mise = mise;
|
this.mise = mise;
|
||||||
binding.mise.setText(mise+" CFA");
|
binding.mise.setText(mise + " CFA");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mise = mise * _calculateArrangement(nombreChevauxSelectionnes - typeOfBetHorses , nombreX);
|
mise = mise * _calculateArrangement(nombreChevauxSelectionnes - typeOfBetHorses, nombreX);
|
||||||
}
|
}
|
||||||
if(order){
|
if (order) {
|
||||||
mise = mise * _calculateArrangement(typeOfBetHorses, (typeOfBetHorses-nombreX));
|
mise = mise * _calculateArrangement(typeOfBetHorses, (typeOfBetHorses - nombreX));
|
||||||
}
|
}
|
||||||
this.mise = mise;
|
this.mise = mise;
|
||||||
binding.mise.setText(mise+" CFA");
|
binding.mise.setText(mise + " CFA");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!order){
|
if (!order) {
|
||||||
mise = mise * _calculateCombinaison(nombreChevauxSelectionnes, typeOfBetHorses);
|
mise = mise * _calculateCombinaison(nombreChevauxSelectionnes, typeOfBetHorses);
|
||||||
}else{
|
} else {
|
||||||
mise = mise * _calculateArrangement(nombreChevauxSelectionnes, typeOfBetHorses);
|
mise = mise * _calculateArrangement(nombreChevauxSelectionnes, typeOfBetHorses);
|
||||||
}
|
}
|
||||||
this.mise = mise;
|
this.mise = mise;
|
||||||
binding.mise.setText(mise+" CFA");
|
binding.mise.setText(mise + " CFA");
|
||||||
}
|
}
|
||||||
|
|
||||||
Long _calculateArrangement(int n, int k){
|
Long _calculateArrangement(int n, int k) {
|
||||||
return _calculateFactorial(n) / _calculateFactorial(n-k);
|
return _calculateFactorial(n) / _calculateFactorial(n - k);
|
||||||
}
|
}
|
||||||
|
|
||||||
Long _calculateCombinaison(int n, int k){
|
Long _calculateCombinaison(int n, int k) {
|
||||||
return _calculateFactorial(n) / (_calculateFactorial(k) * _calculateFactorial(n - k));
|
return _calculateFactorial(n) / (_calculateFactorial(k) * _calculateFactorial(n - k));
|
||||||
}
|
}
|
||||||
|
|
||||||
Long _calculateFactorial(int n){
|
Long _calculateFactorial(int n) {
|
||||||
long f = 1;
|
long f = 1;
|
||||||
if(n == 0){
|
if (n == 0) {
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
for(int i = 1; i <=n; i++){
|
for (int i = 1; i <= n; i++) {
|
||||||
f *= i;
|
f *= i;
|
||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Bitmap resizeToPrinterWidth(Bitmap originalBitmap, int printerWidthPx) {
|
||||||
|
int originalWidth = originalBitmap.getWidth();
|
||||||
|
int originalHeight = originalBitmap.getHeight();
|
||||||
|
int newHeight = (originalHeight * printerWidthPx) / originalWidth;
|
||||||
|
|
||||||
|
// 1. Redimensionner sans filtre (conserve les contours nets)
|
||||||
|
Bitmap scaledBitmap = Bitmap.createScaledBitmap(originalBitmap,
|
||||||
|
printerWidthPx,
|
||||||
|
newHeight,
|
||||||
|
false);
|
||||||
|
|
||||||
|
// 2. Créer un bitmap ARGB_8888 (meilleure qualité que RGB_565)
|
||||||
|
Bitmap result = Bitmap.createBitmap(printerWidthPx, newHeight, Bitmap.Config.ARGB_8888);
|
||||||
|
Canvas canvas = new Canvas(result);
|
||||||
|
canvas.drawColor(Color.WHITE);
|
||||||
|
|
||||||
|
// 3. Dessiner avec un Paint qui préserve les couleurs
|
||||||
|
Paint paint = new Paint();
|
||||||
|
paint.setAntiAlias(false); // Pas d'anti-aliasing (évite le flou)
|
||||||
|
canvas.drawBitmap(scaledBitmap, 0, 0, paint);
|
||||||
|
|
||||||
|
// 4. Seuillage intelligent pour garder les détails
|
||||||
|
for (int x = 0; x < result.getWidth(); x++) {
|
||||||
|
for (int y = 0; y < result.getHeight(); y++) {
|
||||||
|
int pixel = result.getPixel(x, y);
|
||||||
|
int r = Color.red(pixel);
|
||||||
|
int g = Color.green(pixel);
|
||||||
|
int b = Color.blue(pixel);
|
||||||
|
|
||||||
|
// Calculer la luminosité
|
||||||
|
int gray = (r + g + b) / 3;
|
||||||
|
|
||||||
|
// Seuil adaptatif : si c'est sombre, deviens noir
|
||||||
|
if (gray < 130) { // Seuil à 200 pour garder les gris clairs
|
||||||
|
result.setPixel(x, y, Color.BLACK);
|
||||||
|
} else {
|
||||||
|
result.setPixel(x, y, Color.WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -636,6 +870,7 @@ public class BetValidation extends Fragment {
|
|||||||
}
|
}
|
||||||
return bmp;
|
return bmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String generate12Digits() {
|
public static String generate12Digits() {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
@@ -651,4 +886,10 @@ public class BetValidation extends Fragment {
|
|||||||
super.onDestroyView();
|
super.onDestroyView();
|
||||||
binding = null;
|
binding = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
stompManager.disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -18,11 +18,17 @@ import com.example.quiz.viewModel.LoginViewModel;
|
|||||||
import com.example.quiz.viewModel.LogsViewModel;
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple {@link Fragment} subclass.
|
* A simple {@link Fragment} subclass.
|
||||||
* Use the {@link Caisse#newInstance} factory method to
|
* Use the {@link Caisse#newInstance} factory method to
|
||||||
* create an instance of this fragment.
|
* create an instance of this fragment.
|
||||||
*/
|
*/
|
||||||
|
@AndroidEntryPoint
|
||||||
public class Caisse extends Fragment {
|
public class Caisse extends Fragment {
|
||||||
|
|
||||||
FragmentCaisseBinding binding;
|
FragmentCaisseBinding binding;
|
||||||
@@ -47,14 +53,13 @@ public class Caisse extends Fragment {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
sessionManager = SessionManager.newInstance(getContext());
|
sessionManager = SessionManager.newInstance(getContext());
|
||||||
FragmentManager fragmentManager = getParentFragmentManager();
|
|
||||||
authNavigator = new AuthNavigator(getContext(),fragmentManager, sessionManager,new ViewModelProvider(requireActivity()).get(LoginViewModel.class), new ViewModelProvider(requireActivity()).get(LogsViewModel.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
binding = FragmentCaisseBinding.inflate(inflater, container, false);
|
binding = FragmentCaisseBinding.inflate(inflater, container, false);
|
||||||
|
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), sessionManager,new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
|
||||||
return binding.getRoot();
|
return binding.getRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
package com.example.quiz;
|
package com.example.quiz;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.Observer;
|
||||||
@@ -11,15 +17,20 @@ import androidx.lifecycle.ViewModelProvider;
|
|||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.anggastudio.printama.Printama;
|
||||||
import com.example.quiz.data.adapter.LastBetsAdapter;
|
import com.example.quiz.data.adapter.LastBetsAdapter;
|
||||||
|
import com.example.quiz.data.model.Course;
|
||||||
import com.example.quiz.data.model.Pari;
|
import com.example.quiz.data.model.Pari;
|
||||||
import com.example.quiz.data.model.ParisResponse;
|
import com.example.quiz.data.model.ParisResponse;
|
||||||
import com.example.quiz.databinding.FragmentDerniersParisBinding;
|
import com.example.quiz.databinding.FragmentDerniersParisBinding;
|
||||||
|
import com.example.quiz.utils.BluetoothUtils;
|
||||||
import com.example.quiz.utils.LoaderDialog;
|
import com.example.quiz.utils.LoaderDialog;
|
||||||
import com.example.quiz.utils.MessageDialog;
|
import com.example.quiz.utils.MessageDialog;
|
||||||
import com.example.quiz.utils.Result;
|
import com.example.quiz.utils.Result;
|
||||||
@@ -27,8 +38,18 @@ import com.example.quiz.utils.SharedPrefsHelper;
|
|||||||
import com.example.quiz.viewModel.LogsViewModel;
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
import com.example.quiz.viewModel.PariViewModel;
|
import com.example.quiz.viewModel.PariViewModel;
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
import com.google.zxing.BarcodeFormat;
|
||||||
|
import com.google.zxing.MultiFormatWriter;
|
||||||
|
import com.google.zxing.WriterException;
|
||||||
|
import com.google.zxing.common.BitMatrix;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
@@ -45,13 +66,18 @@ public class DerniersParis extends Fragment {
|
|||||||
|
|
||||||
LogsViewModel logsViewModel;
|
LogsViewModel logsViewModel;
|
||||||
|
|
||||||
|
|
||||||
LoaderDialog loader;
|
LoaderDialog loader;
|
||||||
|
|
||||||
SharedPrefsHelper prefsHelper;
|
SharedPrefsHelper prefsHelper;
|
||||||
PariViewModel viewModel;
|
PariViewModel viewModel;
|
||||||
|
|
||||||
|
AlertDialog dialog;
|
||||||
|
|
||||||
LastBetsAdapter adapter;
|
LastBetsAdapter adapter;
|
||||||
|
|
||||||
|
Map<String, Integer> listProduits = Map.of("QUINTE", 5, "QUARTE", 4, "TIERCE", 3, "COUPLE_GAGNANT", 2, "COUPLE_PLACE", 2);
|
||||||
|
|
||||||
public DerniersParis() {
|
public DerniersParis() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
@@ -70,6 +96,7 @@ public class DerniersParis extends Fragment {
|
|||||||
prefsHelper = SharedPrefsHelper.getInstance(getContext());
|
prefsHelper = SharedPrefsHelper.getInstance(getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
@@ -84,29 +111,203 @@ public class DerniersParis extends Fragment {
|
|||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
binding.lastBetsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
binding.lastBetsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
viewModel = new ViewModelProvider(this).get(PariViewModel.class);
|
viewModel = new ViewModelProvider(this).get(PariViewModel.class);
|
||||||
viewModel.getDerniersParis(prefsHelper.get("id")).observe(getViewLifecycleOwner(), new Observer<Result<List<ParisResponse>>>() {
|
_getLastBets();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _getLastBets(){
|
||||||
|
viewModel.getDerniersParis(prefsHelper.get("id")).observe(getViewLifecycleOwner(), new Observer<Result<List<ParisResponse>>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<List<ParisResponse>> listResult) {
|
||||||
|
switch (listResult.status){
|
||||||
|
case LOADING:
|
||||||
|
loader.show("Chargement des derniers paris");
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
loader.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), listResult.message);
|
||||||
|
break;
|
||||||
|
case SUCCESS:
|
||||||
|
loader.dismiss();
|
||||||
|
if(adapter == null){
|
||||||
|
adapter = new LastBetsAdapter(listResult.data);
|
||||||
|
}else{
|
||||||
|
adapter.setData(listResult.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
logsViewModel.insertLog(prefsHelper.get("id"), "LAST BETS", "Affichage derniers paris", System.currentTimeMillis());
|
||||||
|
adapter.setPariClickListener(new LastBetsAdapter.onPariClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onItemClick(ParisResponse pari) {
|
||||||
|
if(pari.getStatutPari() != null && pari.getStatutPari() != ParisResponse.StatutPari.ENREGISTRE){
|
||||||
|
MessageDialog.showError(getContext(), "Ce pari ne peut pas être réimprimé!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_showPariDialog(pari);
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onItemCancel(ParisResponse pari) {
|
||||||
|
if(pari.getStatutPari() != null && pari.getStatutPari() != ParisResponse.StatutPari.ENREGISTRE){
|
||||||
|
MessageDialog.showError(getContext(), "Ce pari ne peut pas être annulé");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_cancelConfirmationDialog(pari);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
binding.lastBetsRecyclerView.setAdapter(adapter);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cancelConfirmationDialog(ParisResponse pari){
|
||||||
|
new AlertDialog.Builder(getContext())
|
||||||
|
.setTitle("Annulation du pari")
|
||||||
|
.setMessage("Êtes-vous sûr de vouloir annuler le pari "+pari.getNumeroTicket()+" ?")
|
||||||
|
.setPositiveButton("Oui", (cancelDialog, which) -> {
|
||||||
|
_cancelPari(pari);
|
||||||
|
cancelDialog.dismiss();
|
||||||
|
})
|
||||||
|
.setNegativeButton("Non", (cancelDialog, which) -> {
|
||||||
|
cancelDialog.dismiss();
|
||||||
|
}).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _cancelPari(ParisResponse pari){
|
||||||
|
viewModel.annulerPari(pari.getNumeroTicket()).observe(getViewLifecycleOwner(), new Observer<Result<ParisResponse>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(Result<List<ParisResponse>> listResult) {
|
public void onChanged(Result<ParisResponse> result) {
|
||||||
switch (listResult.status){
|
switch (result.status){
|
||||||
case LOADING:
|
case LOADING:
|
||||||
loader.show("Chargement des derniers paris");
|
loader.show("Annulation du pari");
|
||||||
break;
|
break;
|
||||||
case ERROR:
|
case ERROR:
|
||||||
loader.dismiss();
|
loader.dismiss();
|
||||||
MessageDialog.showError(getContext(), listResult.message);
|
MessageDialog.showError(getContext(), result.message);
|
||||||
break;
|
break;
|
||||||
case SUCCESS:
|
case SUCCESS:
|
||||||
loader.dismiss();
|
loader.dismiss();
|
||||||
adapter = new LastBetsAdapter(listResult.data, pari -> {
|
MessageDialog.showSuccess(getContext(), "Pari annulé avec succès");
|
||||||
});
|
_getLastBets();
|
||||||
logsViewModel.insertLog(prefsHelper.get("id"), "LAST BETS", "Affichage derniers paris", System.currentTimeMillis());
|
|
||||||
binding.lastBetsRecyclerView.setAdapter(adapter);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressLint({"MissingInflatedId", "SetTextI18n"})
|
||||||
|
void _showPariDialog(ParisResponse pari){
|
||||||
|
LayoutInflater inflater = getLayoutInflater();
|
||||||
|
View view = inflater.inflate(R.layout.pari_confirmation, null);
|
||||||
|
TextView numero_course = (TextView) view.findViewById(R.id.alert_course_numero);
|
||||||
|
numero_course.setText("Numero Course: "+String.valueOf(pari.getCourseId()));
|
||||||
|
TextView alert_pari_type = (TextView) view.findViewById(R.id.alert_pari_type);
|
||||||
|
alert_pari_type.setText(String.valueOf(pari.getTypesParisMises().get(0).getTypePari()));
|
||||||
|
TextView is_elargie = (TextView) view.findViewById(R.id.alert_is_elargie);
|
||||||
|
List<String> selectedHorses = Arrays.stream(pari.getCombinaison().split(","))
|
||||||
|
.map(String::trim)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
is_elargie.setText(selectedHorses.size() > listProduits.get(pari.getTypesParisMises().get(0).getTypePari())?"CE":"SI");
|
||||||
|
TextView alert_combinaison = (TextView) view.findViewById(R.id.alert_combinaison);
|
||||||
|
alert_combinaison.setText(selectedHorses.stream()
|
||||||
|
.map(String::valueOf)
|
||||||
|
.collect(Collectors.joining("-")));
|
||||||
|
TextView aler_coeff = (TextView) view.findViewById(R.id.alert_coeff);
|
||||||
|
aler_coeff.setText("Coef:"+String.valueOf(pari.getCoefficient()));
|
||||||
|
TextView alert_montant = (TextView) view.findViewById(R.id.alert_montant);
|
||||||
|
alert_montant.setText("Montant: "+String.valueOf(pari.getTypesParisMises().get(0).getMiseTotale())+" CFA");
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||||
|
builder.setView(view);
|
||||||
|
builder.setCancelable(false);
|
||||||
|
dialog = builder.create();
|
||||||
|
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
|
||||||
|
|
||||||
|
view.findViewById(R.id.alert_validate).setOnClickListener(v->{
|
||||||
|
try {
|
||||||
|
_printPari(pari);
|
||||||
|
dialog.dismiss();
|
||||||
|
} catch (WriterException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
view.findViewById(R.id.alert_cancel).setOnClickListener(v -> {
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
dialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void _printPari(ParisResponse pari) throws WriterException {
|
||||||
|
try {
|
||||||
|
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
|
||||||
|
Bitmap barcode = generateBarcodeBitmap(pari.getNumeroTicket(), 384, 100);
|
||||||
|
StringBuilder tspl = new StringBuilder();
|
||||||
|
Printama printama = Printama.with(getContext());
|
||||||
|
tspl.append("Bamako").append("\n");
|
||||||
|
tspl.append(pari.getCourseNom()).append("\n");
|
||||||
|
OffsetDateTime dateTime = OffsetDateTime.parse(pari.getHeureDepartPrevue() != null ? pari.getHeureDepartPrevue() : OffsetDateTime.now().toString());
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
|
||||||
|
String formattedDate = dateTime.format(formatter);
|
||||||
|
tspl.append(formattedDate).append("\n");
|
||||||
|
tspl.append("Course ").append(String.valueOf(pari.getCourseId())).append("\n");
|
||||||
|
tspl.append(printama.lineSeparator()+"\n");
|
||||||
|
List<String> selectedHorses = Arrays.stream(pari.getCombinaison().split(",")).collect(Collectors.toList());
|
||||||
|
boolean isElargie = selectedHorses.size()> listProduits.get(pari.getTypesParisMises().get(0).getTypePari());
|
||||||
|
String typePari = pari.getTypesParisMises().get(0).getTypePari();
|
||||||
|
tspl.append(isElargie?typePari+"/Elargie":typePari).append("\n");
|
||||||
|
tspl.append(pari.getFormules().contains("FORMULE_COMPLETE") ?"COMBINAISON COMPLETE"+"\n":"");
|
||||||
|
String combinationText = selectedHorses.stream()
|
||||||
|
.map(String::valueOf)
|
||||||
|
.collect(Collectors.joining("-"));
|
||||||
|
tspl.append(combinationText).append("\n");
|
||||||
|
tspl.append("COEF: ").append(String.valueOf(pari.getCoefficient()));
|
||||||
|
tspl.append("\n").append(printama.lineSeparator()).append("\n");
|
||||||
|
tspl.append("MONTANT: ").append(pari.getMiseTotale()).append(" XOF");
|
||||||
|
tspl.append("\n").append(printama.lineSeparator()).append("\n");
|
||||||
|
tspl.append("AGENT: ").append(pari.getAgentCode()).append("\n");
|
||||||
|
tspl.append("DATE: ").append(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss").format(OffsetDateTime.parse(pari.getDateHeurePrise()))).append("\n");
|
||||||
|
if (BluetoothUtils.needsBluetoothPermissions()) {
|
||||||
|
if (!BluetoothUtils.hasBluetoothPermission(requireContext())) {
|
||||||
|
// Demande la permission si non accordée
|
||||||
|
BluetoothUtils.requestBluetoothPermission(requireActivity());
|
||||||
|
return; // arrête ici, la popup va apparaître
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2️⃣ Permission OK, on peut afficher la liste
|
||||||
|
|
||||||
|
Printama.with(getContext()).printTextBuilder(tspl, bitmap, pari.getNumeroTicket(), barcode, new Printama.PrintCallback() {
|
||||||
|
@Override
|
||||||
|
public void onResult(boolean success, String errorMessage) {
|
||||||
|
if(!success){
|
||||||
|
MessageDialog.showError(getContext(), errorMessage);
|
||||||
|
}else{
|
||||||
|
MessageDialog.showSuccess(getContext(), "Pari imprimé avec succès");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
Toast.makeText(requireContext(),
|
||||||
|
"Permission Bluetooth non accordée", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Bitmap generateBarcodeBitmap(String contents, int width, int height) throws WriterException {
|
||||||
|
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.CODE_128, width, height);
|
||||||
|
Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||||
|
for (int x = 0; x < width; x++) {
|
||||||
|
for (int y = 0; y < height; y++) {
|
||||||
|
bmp.setPixel(x, y, bitMatrix.get(x, y) ? android.graphics.Color.BLACK : android.graphics.Color.WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import androidx.lifecycle.Observer;
|
|||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.recyclerview.widget.GridLayoutManager;
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
@@ -29,6 +30,7 @@ import com.anggastudio.printama.Printama;
|
|||||||
import com.example.quiz.data.adapter.BetsAdapter;
|
import com.example.quiz.data.adapter.BetsAdapter;
|
||||||
import com.example.quiz.data.model.Course;
|
import com.example.quiz.data.model.Course;
|
||||||
import com.example.quiz.data.model.PagedModel;
|
import com.example.quiz.data.model.PagedModel;
|
||||||
|
import com.example.quiz.data.remote.StompManager;
|
||||||
import com.example.quiz.databinding.FragmentListOFBettingBinding;
|
import com.example.quiz.databinding.FragmentListOFBettingBinding;
|
||||||
import com.example.quiz.utils.AuthNavigator;
|
import com.example.quiz.utils.AuthNavigator;
|
||||||
import com.example.quiz.utils.BluetoothUtils;
|
import com.example.quiz.utils.BluetoothUtils;
|
||||||
@@ -46,6 +48,8 @@ import java.time.LocalDateTime;
|
|||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,15 +60,15 @@ import dagger.hilt.android.AndroidEntryPoint;
|
|||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
public class ListOFBets extends Fragment {
|
public class ListOFBets extends Fragment {
|
||||||
|
|
||||||
FragmentListOFBettingBinding binding;
|
FragmentListOFBettingBinding binding;
|
||||||
|
|
||||||
LoaderDialog loader;
|
LoaderDialog loader;
|
||||||
|
|
||||||
private SharedViewModel shared;
|
private SharedViewModel shared;
|
||||||
|
|
||||||
private CourseViewModel viewModel;
|
private CourseViewModel viewModel;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
StompManager stompManager;
|
||||||
|
|
||||||
AuthNavigator authNavigator;
|
AuthNavigator authNavigator;
|
||||||
|
|
||||||
private BetsAdapter adapter;
|
private BetsAdapter adapter;
|
||||||
@@ -85,31 +89,8 @@ public class ListOFBets extends Fragment {
|
|||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
SessionManager sessionManager = SessionManager.newInstance(getContext());
|
SessionManager sessionManager = SessionManager.newInstance(getContext());
|
||||||
FragmentManager fragmentManager = getParentFragmentManager();
|
FragmentManager fragmentManager = getParentFragmentManager();
|
||||||
authNavigator = new AuthNavigator(getContext(), fragmentManager, sessionManager, new ViewModelProvider(requireActivity()).get(LoginViewModel.class), new ViewModelProvider(requireActivity()).get(LogsViewModel.class));
|
|
||||||
requestPermission();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestPermission(){
|
|
||||||
Pref.init(getContext());
|
|
||||||
if (BluetoothUtils.needsBluetoothPermissions()) {
|
|
||||||
if (!BluetoothUtils.hasBluetoothPermission(getContext())) {
|
|
||||||
// Demande la permission si non accordée
|
|
||||||
BluetoothUtils.requestBluetoothPermission(requireActivity());
|
|
||||||
return; // arrête ici, la popup va apparaître
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2️⃣ Permission OK, on peut afficher la liste
|
|
||||||
try {
|
|
||||||
Printama printama = Printama.with(getContext());
|
|
||||||
if(!printama.isConnected()){
|
|
||||||
BluetoothUtils.showPrinterList(getContext(), requireActivity());
|
|
||||||
}
|
|
||||||
} catch (SecurityException e) {
|
|
||||||
Toast.makeText(getContext(),
|
|
||||||
"Permission Bluetooth non accordée", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
@@ -121,7 +102,7 @@ public class ListOFBets extends Fragment {
|
|||||||
binding.recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
binding.recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
||||||
binding.recyclerView.setAdapter(adapter);
|
binding.recyclerView.setAdapter(adapter);
|
||||||
viewModel = new ViewModelProvider(this).get(CourseViewModel.class);
|
viewModel = new ViewModelProvider(this).get(CourseViewModel.class);
|
||||||
|
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), SessionManager.newInstance(getContext()),new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
|
||||||
|
|
||||||
|
|
||||||
/*viewModel.bets.observe(getViewLifecycleOwner(), bets -> {
|
/*viewModel.bets.observe(getViewLifecycleOwner(), bets -> {
|
||||||
@@ -173,8 +154,13 @@ public class ListOFBets extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
MenuHost menuHost = requireActivity();
|
|
||||||
|
|
||||||
|
stompManager.subscribe("courses", json->{
|
||||||
|
requireActivity().runOnUiThread(this::observe);
|
||||||
|
Log.d("STOMP", json);
|
||||||
|
});
|
||||||
|
|
||||||
|
MenuHost menuHost = requireActivity();
|
||||||
// 🔹 On enlève d'abord les anciens menu providers si ce fragment est recréé
|
// 🔹 On enlève d'abord les anciens menu providers si ce fragment est recréé
|
||||||
menuHost.invalidateMenu();
|
menuHost.invalidateMenu();
|
||||||
|
|
||||||
@@ -222,4 +208,10 @@ public class ListOFBets extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
stompManager.disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,9 +7,11 @@ import androidx.annotation.Nullable;
|
|||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -18,18 +20,33 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.example.quiz.data.adapter.TypeOfBetAdapter;
|
import com.example.quiz.data.adapter.TypeOfBetAdapter;
|
||||||
import com.example.quiz.data.model.Course;
|
import com.example.quiz.data.model.Course;
|
||||||
|
import com.example.quiz.data.model.PariMise;
|
||||||
import com.example.quiz.data.model.TypeOfBet;
|
import com.example.quiz.data.model.TypeOfBet;
|
||||||
|
import com.example.quiz.data.model.dtos.NotifPayload;
|
||||||
|
import com.example.quiz.data.remote.StompManager;
|
||||||
import com.example.quiz.databinding.FragmentListOfTypeOfBetsBinding;
|
import com.example.quiz.databinding.FragmentListOfTypeOfBetsBinding;
|
||||||
import com.example.quiz.utils.AuthNavigator;
|
import com.example.quiz.utils.AuthNavigator;
|
||||||
|
import com.example.quiz.utils.LoaderDialog;
|
||||||
|
import com.example.quiz.utils.MessageDialog;
|
||||||
|
import com.example.quiz.utils.Result;
|
||||||
import com.example.quiz.utils.SessionManager;
|
import com.example.quiz.utils.SessionManager;
|
||||||
|
import com.example.quiz.utils.SharedPrefsHelper;
|
||||||
|
import com.example.quiz.viewModel.AgentViewModel;
|
||||||
import com.example.quiz.viewModel.LoginViewModel;
|
import com.example.quiz.viewModel.LoginViewModel;
|
||||||
import com.example.quiz.viewModel.LogsViewModel;
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
|
import com.example.quiz.viewModel.PariMiseViewModel;
|
||||||
import com.example.quiz.viewModel.SharedViewModel;
|
import com.example.quiz.viewModel.SharedViewModel;
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
@@ -44,13 +61,25 @@ public class ListOfTypeOfBets extends Fragment {
|
|||||||
|
|
||||||
private FragmentListOfTypeOfBetsBinding binding;
|
private FragmentListOfTypeOfBetsBinding binding;
|
||||||
|
|
||||||
|
|
||||||
SessionManager sessionManager;
|
SessionManager sessionManager;
|
||||||
AuthNavigator authNavigator;
|
AuthNavigator authNavigator;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
StompManager stompManager;
|
||||||
|
|
||||||
private SharedViewModel shared;
|
private SharedViewModel shared;
|
||||||
|
|
||||||
|
|
||||||
private TypeOfBetAdapter adapter;
|
private TypeOfBetAdapter adapter;
|
||||||
|
|
||||||
|
private SharedPrefsHelper prefsHelper;
|
||||||
|
|
||||||
|
private AgentViewModel agentViewModel;
|
||||||
|
|
||||||
|
private LoaderDialog loaderDialog;
|
||||||
|
|
||||||
|
|
||||||
public ListOfTypeOfBets() {
|
public ListOfTypeOfBets() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
@@ -65,28 +94,74 @@ public class ListOfTypeOfBets extends Fragment {
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
sessionManager = SessionManager.newInstance(getContext());
|
sessionManager = SessionManager.newInstance(getContext());
|
||||||
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), sessionManager, new ViewModelProvider(this).get(LoginViewModel.class), new ViewModelProvider(this).get(LogsViewModel.class));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
binding = FragmentListOfTypeOfBetsBinding.inflate(inflater, container, false);
|
binding = FragmentListOfTypeOfBetsBinding.inflate(inflater, container, false);
|
||||||
|
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), SessionManager.newInstance(getContext()),new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
|
||||||
|
prefsHelper = SharedPrefsHelper.getInstance(getContext());
|
||||||
|
loaderDialog = new LoaderDialog(getContext());
|
||||||
|
agentViewModel = new ViewModelProvider(this).get(AgentViewModel.class);
|
||||||
return binding.getRoot();
|
return binding.getRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
if(prefsHelper.get("id") == null){
|
||||||
|
MessageDialog.showError(getContext(), "Veuillez vous connecter");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
agentViewModel.getAvailableBets(prefsHelper.get("id")).observe(getViewLifecycleOwner(), new Observer<Result<List<Course.TypeParis>>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<List<Course.TypeParis>> listResult) {
|
||||||
|
switch (listResult.status){
|
||||||
|
case LOADING:{
|
||||||
|
loaderDialog.show("Chargement des types de paris");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), listResult.message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SUCCESS:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
syncAuthorizedBets(listResult.data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void syncAuthorizedBets(List<Course.TypeParis> authorizedBets){
|
||||||
binding.typeOfBetRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
binding.typeOfBetRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
// ViewModels
|
|
||||||
//viewModel = new ViewModelProvider(this).get(BetViewModel.class);
|
|
||||||
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
|
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
|
||||||
|
// Observers
|
||||||
|
if(shared.selectedCourse.getValue() == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Course sCourse = shared.selectedCourse.getValue();
|
||||||
|
if(sCourse != null){
|
||||||
|
stompManager.subscribe("courses/"+sCourse.getId(), json->{
|
||||||
|
requireActivity().runOnUiThread(()->{
|
||||||
|
Type type = new TypeToken<NotifPayload<Course>>(){}.getType();
|
||||||
|
NotifPayload<Course> notif = new Gson().fromJson(json, type);
|
||||||
|
Course updatedCourse = notif.getPayload();
|
||||||
|
if(sCourse.getId() == updatedCourse.getId()){
|
||||||
|
shared.setSelectedCourse(updatedCourse);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ⚡ Initialiser l’adapter UNE SEULE FOIS
|
// ⚡ Initialiser l’adapter UNE SEULE FOIS
|
||||||
adapter = new TypeOfBetAdapter(new ArrayList<>());
|
adapter = new TypeOfBetAdapter(new ArrayList<>());
|
||||||
binding.typeOfBetRecyclerView.setAdapter(adapter);
|
binding.typeOfBetRecyclerView.setAdapter(adapter);
|
||||||
List<Course.TypeParis> betType = shared.selectedCourse.getValue().getTypesParisOuverts();
|
List<Course.TypeParis> betType = sCourse.getTypesParisOuverts();
|
||||||
List<TypeOfBet> useList = new ArrayList<>();
|
List<TypeOfBet> useList = new ArrayList<>();
|
||||||
if(betType.contains(Course.TypeParis.QUINTE)){
|
if(betType.contains(Course.TypeParis.QUINTE)){
|
||||||
useList.add(new TypeOfBet("Quinte", Course.TypeParis.QUINTE, 5));
|
useList.add(new TypeOfBet("Quinte", Course.TypeParis.QUINTE, 5));
|
||||||
@@ -97,14 +172,15 @@ public class ListOfTypeOfBets extends Fragment {
|
|||||||
if(betType.contains(Course.TypeParis.TIERCE)){
|
if(betType.contains(Course.TypeParis.TIERCE)){
|
||||||
useList.add(new TypeOfBet("Tierce", Course.TypeParis.TIERCE, 3));
|
useList.add(new TypeOfBet("Tierce", Course.TypeParis.TIERCE, 3));
|
||||||
}
|
}
|
||||||
if(betType.contains(Course.TypeParis.COUPLE_PLACE)){
|
if(betType.contains(Course.TypeParis.COUPLE_PLACE)){
|
||||||
useList.add(new TypeOfBet("Couple Place", Course.TypeParis.COUPLE_PLACE, 2));
|
useList.add(new TypeOfBet("Couple Place", Course.TypeParis.COUPLE_PLACE, 2));
|
||||||
}
|
}
|
||||||
if(betType.contains(Course.TypeParis.COUPLE_PLACE)){
|
if(betType.contains(Course.TypeParis.COUPLE_PLACE)){
|
||||||
useList.add(new TypeOfBet("Couple Gagnant", Course.TypeParis.COUPLE_GAGNANT, 2));
|
useList.add(new TypeOfBet("Couple Gagnant", Course.TypeParis.COUPLE_GAGNANT, 2));
|
||||||
}
|
}
|
||||||
AtomicReference<TypeOfBet> typeOfBet = new AtomicReference<>();
|
AtomicReference<TypeOfBet> typeOfBet = new AtomicReference<>();
|
||||||
adapter.setTypes(useList);
|
List<TypeOfBet> availableTypeOfBets = useList.stream().filter(type -> authorizedBets.contains(type.getName())).collect(Collectors.toList());
|
||||||
|
adapter.setTypes(availableTypeOfBets);
|
||||||
adapter.setOnItemClickListener(type -> {
|
adapter.setOnItemClickListener(type -> {
|
||||||
typeOfBet.set(type);
|
typeOfBet.set(type);
|
||||||
});
|
});
|
||||||
@@ -133,4 +209,10 @@ public class ListOfTypeOfBets extends Fragment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
stompManager.disconnect();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -19,11 +19,14 @@ import com.example.quiz.utils.SharedPrefsHelper;
|
|||||||
import com.example.quiz.viewModel.LoginViewModel;
|
import com.example.quiz.viewModel.LoginViewModel;
|
||||||
import com.example.quiz.viewModel.LogsViewModel;
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple {@link Fragment} subclass.
|
* A simple {@link Fragment} subclass.
|
||||||
* Use the {@link Login#newInstance} factory method to
|
* Use the {@link Login#newInstance} factory method to
|
||||||
* create an instance of this fragment.
|
* create an instance of this fragment.
|
||||||
*/
|
*/
|
||||||
|
@AndroidEntryPoint
|
||||||
public class Login extends Fragment {
|
public class Login extends Fragment {
|
||||||
|
|
||||||
|
|
||||||
@@ -52,6 +55,7 @@ public class Login extends Fragment {
|
|||||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
binding = FragmentLoginBinding.inflate(inflater, container, false);
|
binding = FragmentLoginBinding.inflate(inflater, container, false);
|
||||||
|
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), SessionManager.newInstance(getContext()),new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
|
||||||
return binding.getRoot();
|
return binding.getRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +64,6 @@ public class Login extends Fragment {
|
|||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
SessionManager sessionManager = SessionManager.newInstance(getContext());
|
SessionManager sessionManager = SessionManager.newInstance(getContext());
|
||||||
FragmentManager fragmentManager = getParentFragmentManager();
|
FragmentManager fragmentManager = getParentFragmentManager();
|
||||||
authNavigator = new AuthNavigator(getContext(), fragmentManager, sessionManager, new ViewModelProvider(requireActivity()).get(LoginViewModel.class), new ViewModelProvider(requireActivity()).get(LogsViewModel.class));
|
|
||||||
AppCompatActivity activity = (AppCompatActivity) getActivity();
|
AppCompatActivity activity = (AppCompatActivity) getActivity();
|
||||||
if(activity != null){
|
if(activity != null){
|
||||||
activity.getSupportActionBar().hide();
|
activity.getSupportActionBar().hide();
|
||||||
|
|||||||
@@ -1,17 +1,26 @@
|
|||||||
package com.example.quiz;
|
package com.example.quiz;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import com.anggastudio.printama.Pref;
|
||||||
|
import com.anggastudio.printama.Printama;
|
||||||
import com.example.quiz.utils.AuthNavigator;
|
import com.example.quiz.utils.AuthNavigator;
|
||||||
|
import com.example.quiz.utils.BluetoothUtils;
|
||||||
|
import com.example.quiz.utils.MessageDialog;
|
||||||
import com.example.quiz.utils.SessionManager;
|
import com.example.quiz.utils.SessionManager;
|
||||||
import com.example.quiz.utils.SharedPrefsHelper;
|
import com.example.quiz.utils.SunmiPrinterManager;
|
||||||
import com.example.quiz.viewModel.LoginViewModel;
|
import com.example.quiz.viewModel.LoginViewModel;
|
||||||
import com.example.quiz.viewModel.LogsViewModel;
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
import androidx.navigation.NavController;
|
import androidx.navigation.NavController;
|
||||||
import androidx.navigation.Navigation;
|
import androidx.navigation.Navigation;
|
||||||
@@ -20,6 +29,11 @@ import androidx.navigation.ui.NavigationUI;
|
|||||||
|
|
||||||
import com.example.quiz.databinding.ActivityPageQuizBinding;
|
import com.example.quiz.databinding.ActivityPageQuizBinding;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
@@ -32,6 +46,11 @@ public class PageQuiz extends AppCompatActivity {
|
|||||||
AuthNavigator authNavigator;
|
AuthNavigator authNavigator;
|
||||||
private SessionManager sessionManager;
|
private SessionManager sessionManager;
|
||||||
|
|
||||||
|
String mobileName;
|
||||||
|
|
||||||
|
|
||||||
|
private Set<Class<?>> exemptedFragment = new HashSet<>();
|
||||||
|
|
||||||
private Handler handler = new Handler();
|
private Handler handler = new Handler();
|
||||||
private Runnable checkRunnable;
|
private Runnable checkRunnable;
|
||||||
|
|
||||||
@@ -41,12 +60,15 @@ public class PageQuiz extends AppCompatActivity {
|
|||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
exemptedFragment.add(ServerConfig.class);
|
||||||
|
exemptedFragment.add(Logs.class);
|
||||||
sessionManager = SessionManager.newInstance(this);
|
sessionManager = SessionManager.newInstance(this);
|
||||||
|
mobileName = Build.MANUFACTURER;
|
||||||
binding = ActivityPageQuizBinding.inflate(getLayoutInflater());
|
binding = ActivityPageQuizBinding.inflate(getLayoutInflater());
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
|
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
|
||||||
viewModel = new ViewModelProvider(this).get(LoginViewModel.class);
|
viewModel = new ViewModelProvider(this).get(LoginViewModel.class);
|
||||||
authNavigator = new AuthNavigator(this, getSupportFragmentManager(), sessionManager, viewModel, logsViewModel);
|
authNavigator = new AuthNavigator(this, getSupportFragmentManager(), sessionManager, viewModel, logsViewModel, this);
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
binding.toolbar.setBackgroundColor(Color.parseColor("#501C5A29"));
|
binding.toolbar.setBackgroundColor(Color.parseColor("#501C5A29"));
|
||||||
}
|
}
|
||||||
@@ -117,19 +139,107 @@ public class PageQuiz extends AppCompatActivity {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean dispatchTouchEvent(MotionEvent ev) {
|
||||||
|
View touchedView = findTouchedView(ev);
|
||||||
|
Fragment currentFragment = getCurrentFragment();
|
||||||
|
if(currentFragment != null && exemptedFragment.contains(currentFragment.getClass())){
|
||||||
|
return super.dispatchTouchEvent(ev);
|
||||||
|
}
|
||||||
|
if(touchedView!=null && "tag_pin_exempt".equals(touchedView.getTag())){
|
||||||
|
return super.dispatchTouchEvent(ev);
|
||||||
|
}
|
||||||
|
if (authNavigator.isSessionExpired()) {
|
||||||
|
authNavigator.showPinDialog(() -> {
|
||||||
|
authNavigator.updatedLastExpiredDate();
|
||||||
|
});
|
||||||
|
return false; // Consomme l'événement pour ne pas le propager
|
||||||
|
}
|
||||||
|
authNavigator.updatedLastExpiredDate();
|
||||||
|
return super.dispatchTouchEvent(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Fragment getCurrentFragment() {
|
||||||
|
FragmentManager fm = getSupportFragmentManager();
|
||||||
|
// Méthode 1: Par conteneur
|
||||||
|
Fragment fragment = fm.findFragmentById(R.id.nav_host_fragment_content_main);
|
||||||
|
|
||||||
|
// Méthode 2: Par tag si vous utilisez des tags
|
||||||
|
if (fragment == null) {
|
||||||
|
fragment = fm.findFragmentByTag("current_fragment");
|
||||||
|
}
|
||||||
|
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
private View findTouchedView(MotionEvent ev) {
|
||||||
|
float x = ev.getRawX();
|
||||||
|
float y = ev.getRawY();
|
||||||
|
|
||||||
|
View rootView = getWindow().getDecorView().getRootView();
|
||||||
|
return findViewAtPosition(rootView, (int) x, (int) y);
|
||||||
|
}
|
||||||
|
|
||||||
|
private View findViewAtPosition(View view, int x, int y) {
|
||||||
|
if (view == null) return null;
|
||||||
|
|
||||||
|
int[] location = new int[2];
|
||||||
|
view.getLocationOnScreen(location);
|
||||||
|
|
||||||
|
int left = location[0];
|
||||||
|
int top = location[1];
|
||||||
|
int right = left + view.getWidth();
|
||||||
|
int bottom = top + view.getHeight();
|
||||||
|
|
||||||
|
if (x >= left && x <= right && y >= top && y <= bottom) {
|
||||||
|
if (view instanceof ViewGroup) {
|
||||||
|
ViewGroup group = (ViewGroup) view;
|
||||||
|
for (int i = group.getChildCount() - 1; i >= 0; i--) {
|
||||||
|
View child = group.getChildAt(i);
|
||||||
|
View found = findViewAtPosition(child, x, y);
|
||||||
|
if (found != null) return found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkPermission(){
|
||||||
|
Pref.init(this);
|
||||||
|
if (BluetoothUtils.needsBluetoothPermissions()) {
|
||||||
|
if (!BluetoothUtils.hasBluetoothPermission(this)) {
|
||||||
|
// Demande la permission si non accordée
|
||||||
|
BluetoothUtils.requestBluetoothPermission(this);
|
||||||
|
return; // arrête ici, la popup va apparaître
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2️⃣ Permission OK, on peut afficher la liste
|
||||||
|
try {
|
||||||
|
Printama printama = Printama.with(this);
|
||||||
|
if(printama.getConnectedPrinter() == null){
|
||||||
|
BluetoothUtils.showPrinterList(this, this);
|
||||||
|
}
|
||||||
|
} catch (SecurityException e) {
|
||||||
|
MessageDialog.showError(this, "Permission refusée");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onResume() {
|
protected void onResume() {
|
||||||
|
if(!mobileName.toLowerCase().contains("sunmi")){
|
||||||
|
checkPermission();
|
||||||
|
}
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
||||||
handler = new Handler(Looper.getMainLooper());
|
handler = new Handler(Looper.getMainLooper());
|
||||||
|
|
||||||
checkRunnable = new Runnable() {
|
checkRunnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (sessionManager.isExpired()) {
|
if (sessionManager.isExpired()) {
|
||||||
if (!authNavigator.dialogIsShowing()) {
|
if (!authNavigator.dialogIsShowing()) {
|
||||||
authNavigator.showPinDialog(() -> {
|
authNavigator.showPinDialog(() -> {
|
||||||
sessionManager.updateLastExpiredDate();
|
authNavigator.updatedLastExpiredDate();
|
||||||
handler.postDelayed(checkRunnable, 1);
|
handler.postDelayed(checkRunnable, 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package com.example.quiz;
|
package com.example.quiz;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
@@ -17,7 +19,9 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
@@ -41,6 +45,7 @@ import java.net.NetworkInterface;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
@@ -61,6 +66,8 @@ public class ServerConfig extends Fragment {
|
|||||||
|
|
||||||
PointDeVenteAdapter pointDeVenteAdapter;
|
PointDeVenteAdapter pointDeVenteAdapter;
|
||||||
|
|
||||||
|
TpeResponse existingTpe;
|
||||||
|
|
||||||
PointDeVente pdv = null;
|
PointDeVente pdv = null;
|
||||||
|
|
||||||
private PointDeVenteViewModel pointDeVenteViewModel;
|
private PointDeVenteViewModel pointDeVenteViewModel;
|
||||||
@@ -100,9 +107,66 @@ public class ServerConfig extends Fragment {
|
|||||||
toolbar.setTitle("Configuration du terminal");
|
toolbar.setTitle("Configuration du terminal");
|
||||||
toolbar.setBackgroundColor( getResources().getColor(R.color.primary_green));
|
toolbar.setBackgroundColor( getResources().getColor(R.color.primary_green));
|
||||||
}
|
}
|
||||||
|
if(sharedPrefsHelper.get("terminalId") != null){
|
||||||
|
viewModel.getTpeById(sharedPrefsHelper.get("terminalId")).observe(getViewLifecycleOwner(), new Observer<Result<TpeResponse>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<TpeResponse> tpeResult) {
|
||||||
|
switch (tpeResult.status){
|
||||||
|
case LOADING:
|
||||||
|
loader.show("Chargement du TPE");
|
||||||
|
break;
|
||||||
|
case SUCCESS:
|
||||||
|
loader.dismiss();
|
||||||
|
existingTpe = tpeResult.data;
|
||||||
|
if( existingTpe != null && Objects.equals(sharedPrefsHelper.get("terminalId"), String.valueOf(existingTpe.getId()))){
|
||||||
|
_checkPdv(existingTpe);
|
||||||
|
return;
|
||||||
|
}else{
|
||||||
|
MessageDialog.showError(getContext(), "Ce TPE n'est pas encore configuré");
|
||||||
|
_startAutocomplete();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR:
|
||||||
|
loader.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), "Erreur lors du chargement du TPE");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_startAutocomplete();
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
|
void _startAutocomplete(){
|
||||||
pointDeVenteAdapter = new PointDeVenteAdapter();
|
pointDeVenteAdapter = new PointDeVenteAdapter();
|
||||||
RecyclerView recyclerView = binding.pointRecyclerView;
|
RecyclerView recyclerView = binding.pointRecyclerView;
|
||||||
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||||
|
binding.getRoot().setOnTouchListener((v, event) -> {
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
||||||
|
// Vérifier si le clic est en dehors de l'autocomplete
|
||||||
|
if (binding.autocompleteContainer.getVisibility() == View.VISIBLE && !binding.pointDeVente.isEnabled()) {
|
||||||
|
int[] location = new int[2];
|
||||||
|
binding.autocompleteContainer.getLocationOnScreen(location);
|
||||||
|
Rect rect = new Rect(
|
||||||
|
location[0],
|
||||||
|
location[1],
|
||||||
|
location[0] + binding.autocompleteContainer.getWidth(),
|
||||||
|
location[1] + binding.autocompleteContainer.getHeight()
|
||||||
|
);
|
||||||
|
|
||||||
|
int x = (int) event.getRawX();
|
||||||
|
int y = (int) event.getRawY();
|
||||||
|
|
||||||
|
if (!rect.contains(x, y)) {
|
||||||
|
binding.autocompleteContainer.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
binding.pointDeVente.addTextChangedListener(new TextWatcher() {
|
binding.pointDeVente.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||||
@@ -112,7 +176,7 @@ public class ServerConfig extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
|
||||||
if(!isUserTap) return;
|
if(!isUserTap) return;
|
||||||
if(charSequence.toString().isEmpty() || charSequence.toString().length()==0){
|
if(charSequence.toString().isEmpty() || !binding.pointDeVente.isEnabled()){
|
||||||
recyclerView.setVisibility(View.GONE);
|
recyclerView.setVisibility(View.GONE);
|
||||||
binding.autocompleteContainer.setVisibility(View.GONE);
|
binding.autocompleteContainer.setVisibility(View.GONE);
|
||||||
return;
|
return;
|
||||||
@@ -157,7 +221,34 @@ public class ServerConfig extends Fragment {
|
|||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
super.onViewCreated(view, savedInstanceState);
|
}
|
||||||
|
|
||||||
|
void _checkPdv(Tpe eTpe){
|
||||||
|
binding.numeroSerie.setText(eTpe.getNumeroSerie());
|
||||||
|
binding.brand.setText(eTpe.getTypeTerminal());
|
||||||
|
binding.model.setText(eTpe.getModeleAppareil());
|
||||||
|
binding.type.setText(eTpe.getTypeTerminal());
|
||||||
|
pointDeVenteViewModel.getPointDeVenteById(String.valueOf(eTpe.getPointDeVenteId())).observe(getViewLifecycleOwner(), new Observer<Result<PointDeVente>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<PointDeVente> pointDeVenteResult) {
|
||||||
|
switch (pointDeVenteResult.status){
|
||||||
|
case LOADING:
|
||||||
|
loader.show("Chargement du point de vente");
|
||||||
|
break;
|
||||||
|
case SUCCESS:
|
||||||
|
loader.dismiss();
|
||||||
|
binding.pointDeVente.setEnabled(false);
|
||||||
|
binding.pointDeVente.setText(pointDeVenteResult.data.getNom());
|
||||||
|
binding.validate.setClickable(false);
|
||||||
|
MessageDialog.showSuccess(getContext(), "Ce tpe est déjà configuré");
|
||||||
|
break;
|
||||||
|
case ERROR:
|
||||||
|
loader.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), "Erreur lors du chargement du point de vente");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -6,19 +6,30 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import com.example.quiz.databinding.FragmentSettingsBinding;
|
import com.example.quiz.databinding.FragmentSettingsBinding;
|
||||||
|
import com.example.quiz.utils.AuthNavigator;
|
||||||
|
import com.example.quiz.utils.SessionManager;
|
||||||
|
import com.example.quiz.utils.SharedPrefsHelper;
|
||||||
|
import com.example.quiz.viewModel.LoginViewModel;
|
||||||
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple {@link Fragment} subclass.
|
* A simple {@link Fragment} subclass.
|
||||||
* Use the {@link Settings#newInstance} factory method to
|
* Use the {@link Settings#newInstance} factory method to
|
||||||
* create an instance of this fragment.
|
* create an instance of this fragment.
|
||||||
*/
|
*/
|
||||||
|
@AndroidEntryPoint
|
||||||
public class Settings extends Fragment {
|
public class Settings extends Fragment {
|
||||||
|
|
||||||
// TODO: Rename parameter arguments, choose names that match
|
// TODO: Rename parameter arguments, choose names that match
|
||||||
@@ -28,6 +39,10 @@ public class Settings extends Fragment {
|
|||||||
|
|
||||||
FragmentSettingsBinding binding;
|
FragmentSettingsBinding binding;
|
||||||
|
|
||||||
|
AuthNavigator authNavigator;
|
||||||
|
|
||||||
|
SharedPrefsHelper prefsHelper;
|
||||||
|
|
||||||
public Settings() {
|
public Settings() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
}
|
}
|
||||||
@@ -42,14 +57,16 @@ public class Settings extends Fragment {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
prefsHelper = SharedPrefsHelper.getInstance(getContext());
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||||
Bundle savedInstanceState) {
|
Bundle savedInstanceState) {
|
||||||
binding = FragmentSettingsBinding.inflate(inflater, container, false);
|
binding = FragmentSettingsBinding.inflate(inflater, container, false);
|
||||||
// Inflate the layout for this fragment
|
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), SessionManager.newInstance(getContext()),new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
|
||||||
return binding.getRoot();
|
return binding.getRoot();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +74,16 @@ public class Settings extends Fragment {
|
|||||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState){
|
public void onViewCreated(@NonNull View view, Bundle savedInstanceState){
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
AppCompatActivity activity = (AppCompatActivity) getActivity();
|
AppCompatActivity activity = (AppCompatActivity) getActivity();
|
||||||
|
if(prefsHelper.get("isSupAgent") == null){
|
||||||
|
binding.agentManagement.setVisibility(View.GONE);
|
||||||
|
}else{
|
||||||
|
String isSubAgent = prefsHelper.get("isSupAgent");
|
||||||
|
if(isSubAgent.equals("true")){
|
||||||
|
binding.agentManagement.setVisibility(View.GONE);
|
||||||
|
}else{
|
||||||
|
binding.agentManagement.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
}
|
||||||
if(activity != null){
|
if(activity != null){
|
||||||
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
|
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
|
||||||
activity.setSupportActionBar(toolbar);
|
activity.setSupportActionBar(toolbar);
|
||||||
@@ -92,6 +119,25 @@ public class Settings extends Fragment {
|
|||||||
.commit();
|
.commit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
binding.changePin.setOnClickListener(new View.OnClickListener(){
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
UpdatePin updatePin = UpdatePin.newInstance();
|
||||||
|
authNavigator.navigate(updatePin);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
binding.agentManagement.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
AgentManagement agentManagement = AgentManagement.newInstance();
|
||||||
|
authNavigator.navigate(agentManagement);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
binding.logout.setOnClickListener(v -> {
|
||||||
|
authNavigator.logOut();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,15 @@ package com.example.quiz;
|
|||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.DatePickerDialog;
|
import android.app.DatePickerDialog;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.lifecycle.LifecycleOwner;
|
import androidx.lifecycle.LifecycleOwner;
|
||||||
@@ -19,6 +23,8 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.anggastudio.printama.Printama;
|
||||||
|
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
|
||||||
import com.example.quiz.databinding.FragmentSoldBinding;
|
import com.example.quiz.databinding.FragmentSoldBinding;
|
||||||
import com.example.quiz.utils.LoaderDialog;
|
import com.example.quiz.utils.LoaderDialog;
|
||||||
import com.example.quiz.utils.MessageDialog;
|
import com.example.quiz.utils.MessageDialog;
|
||||||
@@ -27,7 +33,10 @@ import com.example.quiz.utils.SharedPrefsHelper;
|
|||||||
import com.example.quiz.viewModel.LogsViewModel;
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
import com.example.quiz.viewModel.PariViewModel;
|
import com.example.quiz.viewModel.PariViewModel;
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
import com.google.zxing.WriterException;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
@@ -116,9 +125,9 @@ public class Sold extends Fragment {
|
|||||||
getContext(),
|
getContext(),
|
||||||
(view, year, month, dayOfMonth) -> {
|
(view, year, month, dayOfMonth) -> {
|
||||||
String date = year + "-" + _reformatDateForDate(month + 1) + "-" + _reformatDateForDate(dayOfMonth);
|
String date = year + "-" + _reformatDateForDate(month + 1) + "-" + _reformatDateForDate(dayOfMonth);
|
||||||
pariViewModel.getSoldeByDay(prefsHelper.get("id"), date).observe(getViewLifecycleOwner(), new Observer<Result<Double>>() {
|
pariViewModel.getSoldeByDay(prefsHelper.get("id"), date).observe(getViewLifecycleOwner(), new Observer<Result<SoldeResponse>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(Result<Double> doubleResult) {
|
public void onChanged(Result<SoldeResponse> doubleResult) {
|
||||||
switch (doubleResult.status){
|
switch (doubleResult.status){
|
||||||
case LOADING:{
|
case LOADING:{
|
||||||
dialog.show("Solde du jour");
|
dialog.show("Solde du jour");
|
||||||
@@ -131,7 +140,12 @@ public class Sold extends Fragment {
|
|||||||
}
|
}
|
||||||
case SUCCESS:{
|
case SUCCESS:{
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
_showSold(doubleResult.data);
|
|
||||||
|
try {
|
||||||
|
_showSold(doubleResult.data, date);
|
||||||
|
} catch (WriterException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
logsViewModel.insertLog(prefsHelper.get("id"), "SOLDE JOUR", "Solde du "+date, System.currentTimeMillis());
|
logsViewModel.insertLog(prefsHelper.get("id"), "SOLDE JOUR", "Solde du "+date, System.currentTimeMillis());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -147,12 +161,38 @@ public class Sold extends Fragment {
|
|||||||
datePickerDialog.show();
|
datePickerDialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showSold(double solde){
|
void _showSold(SoldeResponse soldeResponse, String date) throws WriterException {
|
||||||
new AlertDialog.Builder(getContext())
|
try {
|
||||||
.setTitle("Solde")
|
int solde = soldeResponse.getMontantParis() - soldeResponse.getMontantAnnulations() - soldeResponse.getMontantPaiements();
|
||||||
.setMessage("Solde la course "+solde)
|
new AlertDialog.Builder(getContext())
|
||||||
.setPositiveButton("Ok", (dialog, which)->{
|
.setTitle("Solde")
|
||||||
dialog.dismiss();
|
.setMessage("Solde la course "+solde)
|
||||||
}).show();
|
.setNeutralButton("Ok", (dialog, which)->{
|
||||||
|
dialog.dismiss();
|
||||||
|
})
|
||||||
|
.setPositiveButton("Imprimer", (dialog, which)->{
|
||||||
|
Printama printama = Printama.with(getContext());
|
||||||
|
Bitmap logo = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
|
||||||
|
String title = "SOLDE AU "+date;
|
||||||
|
StringBuilder text = new StringBuilder();
|
||||||
|
text.append("VENTES HIPPIQUES: ").append(String.valueOf(soldeResponse.getMontantParis())).append(" XOF").append("\n");
|
||||||
|
text.append("NBR. PAIEMENTS: ").append(soldeResponse.getNombrePaiements()).append("\n");
|
||||||
|
text.append("PAIEMENTS: ").append(String.valueOf(soldeResponse.getMontantPaiements())).append(" XOF").append("\n");
|
||||||
|
text.append("NBR. ANNULATIONS: ").append(soldeResponse.getNombreAnnulations()).append("\n");
|
||||||
|
text.append("ANNULATIONS: ").append(String.valueOf(soldeResponse.getMontantAnnulations())).append(" XOF").append("\n");
|
||||||
|
text.append(printama.lineSeparator()).append("\n");
|
||||||
|
text.append("SOLDE: ").append(String.valueOf(solde)).append(" XOF").append("\n");
|
||||||
|
text.append(printama.lineSeparator()).append("\n");
|
||||||
|
text.append("AGENT : ").append(prefsHelper.get("code")).append("\n");
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
|
||||||
|
String now = formatter.format(LocalDateTime.now());
|
||||||
|
text.append("DATE : ").append(now).append("\n");
|
||||||
|
printama.printSold(logo, title, text);
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
}catch (SecurityException e){
|
||||||
|
MessageDialog.showError(getContext(), "Erreur lors de l'affichage du solde");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,14 @@
|
|||||||
package com.example.quiz;
|
package com.example.quiz;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.lifecycle.Observer;
|
import androidx.lifecycle.Observer;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
@@ -14,6 +18,8 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.anggastudio.printama.Printama;
|
||||||
|
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
|
||||||
import com.example.quiz.databinding.FragmentSoldByCourseBinding;
|
import com.example.quiz.databinding.FragmentSoldByCourseBinding;
|
||||||
import com.example.quiz.utils.LoaderDialog;
|
import com.example.quiz.utils.LoaderDialog;
|
||||||
import com.example.quiz.utils.MessageDialog;
|
import com.example.quiz.utils.MessageDialog;
|
||||||
@@ -21,6 +27,10 @@ import com.example.quiz.utils.Result;
|
|||||||
import com.example.quiz.utils.SharedPrefsHelper;
|
import com.example.quiz.utils.SharedPrefsHelper;
|
||||||
import com.example.quiz.viewModel.LogsViewModel;
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
import com.example.quiz.viewModel.PariViewModel;
|
import com.example.quiz.viewModel.PariViewModel;
|
||||||
|
import com.google.zxing.WriterException;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint;
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
@@ -78,9 +88,9 @@ public class SoldByCourse extends Fragment {
|
|||||||
binding.etRaceNumber.setError("Veuillez entrer un numéro de course");
|
binding.etRaceNumber.setError("Veuillez entrer un numéro de course");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pariViewModel.getSoldeByCourse(prefsHelper.get("id"), binding.etRaceNumber.getText().toString()).observe(getViewLifecycleOwner(), new Observer<Result<Double>>() {
|
pariViewModel.getSoldeByCourse(prefsHelper.get("id"), binding.etRaceNumber.getText().toString()).observe(getViewLifecycleOwner(), new Observer<Result<SoldeResponse>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(Result<Double> doubleResult) {
|
public void onChanged(Result<SoldeResponse> doubleResult) {
|
||||||
switch (doubleResult.status){
|
switch (doubleResult.status){
|
||||||
case LOADING:{
|
case LOADING:{
|
||||||
loader.show("Chargement du solde");
|
loader.show("Chargement du solde");
|
||||||
@@ -93,7 +103,11 @@ public class SoldByCourse extends Fragment {
|
|||||||
}
|
}
|
||||||
case SUCCESS:{
|
case SUCCESS:{
|
||||||
loader.dismiss();
|
loader.dismiss();
|
||||||
_showPariDialog(doubleResult.data);
|
try {
|
||||||
|
_showPariDialog(doubleResult.data, binding.etRaceNumber.getText().toString());
|
||||||
|
} catch (WriterException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
logsViewModel.insertLog(prefsHelper.get("id"), "SOLDE COURSE", "Solde de la course "+binding.etRaceNumber.getText(), System.currentTimeMillis());
|
logsViewModel.insertLog(prefsHelper.get("id"), "SOLDE COURSE", "Solde de la course "+binding.etRaceNumber.getText(), System.currentTimeMillis());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -103,14 +117,38 @@ public class SoldByCourse extends Fragment {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showPariDialog(double solde){
|
void _showPariDialog(SoldeResponse soldeResponse, String numero) throws WriterException {
|
||||||
new AlertDialog.Builder(getContext())
|
try {
|
||||||
.setTitle("Solde")
|
int solde = soldeResponse.getMontantParis() - soldeResponse.getMontantAnnulations() - soldeResponse.getMontantPaiements();
|
||||||
.setMessage("Solde la course "+solde)
|
new AlertDialog.Builder(getContext())
|
||||||
.setPositiveButton("Ok", (dialog, which) -> {
|
.setTitle("Solde")
|
||||||
binding.etRaceNumber.setText("");
|
.setMessage("Solde la course "+solde)
|
||||||
dialog.dismiss();
|
.setNeutralButton("Ok", (dialog, which) -> {
|
||||||
})
|
binding.etRaceNumber.setText("");
|
||||||
.show();
|
dialog.dismiss();
|
||||||
|
})
|
||||||
|
.setPositiveButton("Imprimer", (dialog, which)->{
|
||||||
|
Printama printama = Printama.with(getContext());
|
||||||
|
Bitmap logo = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
|
||||||
|
String title = "SOLDE DE LA COURSE "+numero;
|
||||||
|
StringBuilder text = new StringBuilder();
|
||||||
|
text.append("VENTES HIPPIQUES: ").append(String.valueOf(soldeResponse.getMontantParis())).append(" XOF").append("\n");
|
||||||
|
text.append("NBR. PAIEMENTS: ").append(soldeResponse.getNombrePaiements()).append("\n");
|
||||||
|
text.append("PAIEMENTS: ").append(String.valueOf(soldeResponse.getMontantPaiements())).append(" XOF").append("\n");
|
||||||
|
text.append("NBR. ANNULATIONS: ").append(soldeResponse.getNombreAnnulations()).append("\n");
|
||||||
|
text.append("ANNULATIONS: ").append(String.valueOf(soldeResponse.getMontantAnnulations())).append(" XOF").append("\n");
|
||||||
|
text.append(printama.lineSeparator()).append("\n");
|
||||||
|
text.append("SOLDE: ").append(String.valueOf(solde)).append(" XOF").append("\n");
|
||||||
|
text.append(printama.lineSeparator()).append("\n");
|
||||||
|
text.append("AGENT : ").append(prefsHelper.get("code")).append("\n");
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
|
||||||
|
String now = formatter.format(LocalDateTime.now());
|
||||||
|
text.append("DATE : ").append(now).append("\n");
|
||||||
|
printama.printSold(logo, title, text);
|
||||||
|
})
|
||||||
|
.show();
|
||||||
|
}catch (SecurityException e){
|
||||||
|
MessageDialog.showError(getContext(), "Erreur lors de l'affichage du solde");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
24
app/src/main/java/com/example/quiz/StompModule.java
Normal file
24
app/src/main/java/com/example/quiz/StompModule.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package com.example.quiz;
|
||||||
|
|
||||||
|
import com.example.quiz.data.remote.NotificationHelper;
|
||||||
|
import com.example.quiz.data.remote.StompManager;
|
||||||
|
import com.example.quiz.data.remote.TokenManager;
|
||||||
|
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import dagger.Module;
|
||||||
|
import dagger.Provides;
|
||||||
|
import dagger.hilt.InstallIn;
|
||||||
|
import dagger.hilt.components.SingletonComponent;
|
||||||
|
|
||||||
|
@Module
|
||||||
|
@InstallIn(SingletonComponent.class)
|
||||||
|
public class StompModule {
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
public StompManager provideStompManager(TokenManager tokenManager,
|
||||||
|
NotificationHelper notificationHelper) {
|
||||||
|
return new StompManager(tokenManager, notificationHelper);
|
||||||
|
}
|
||||||
|
}
|
||||||
137
app/src/main/java/com/example/quiz/UpdatePin.java
Normal file
137
app/src/main/java/com/example/quiz/UpdatePin.java
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
package com.example.quiz;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.example.quiz.data.model.dtos.auth.User;
|
||||||
|
import com.example.quiz.databinding.FragmentUpdatePinBinding;
|
||||||
|
import com.example.quiz.utils.AuthNavigator;
|
||||||
|
import com.example.quiz.utils.LoaderDialog;
|
||||||
|
import com.example.quiz.utils.MessageDialog;
|
||||||
|
import com.example.quiz.utils.Result;
|
||||||
|
import com.example.quiz.utils.SessionManager;
|
||||||
|
import com.example.quiz.viewModel.LoginViewModel;
|
||||||
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple {@link Fragment} subclass.
|
||||||
|
* Use the {@link UpdatePin#newInstance} factory method to
|
||||||
|
* create an instance of this fragment.
|
||||||
|
*/
|
||||||
|
@AndroidEntryPoint
|
||||||
|
public class UpdatePin extends Fragment {
|
||||||
|
|
||||||
|
// TODO: Rename parameter arguments, choose names that match
|
||||||
|
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||||
|
|
||||||
|
// TODO: Rename and change types of parameters
|
||||||
|
FragmentUpdatePinBinding binding;
|
||||||
|
|
||||||
|
String oldPin;
|
||||||
|
String newPin;
|
||||||
|
String confirmation;
|
||||||
|
|
||||||
|
LogsViewModel logsViewModel;
|
||||||
|
|
||||||
|
AuthNavigator authNavigator;
|
||||||
|
|
||||||
|
LoginViewModel viewModel;
|
||||||
|
|
||||||
|
LoaderDialog loaderDialog;
|
||||||
|
|
||||||
|
public UpdatePin() {
|
||||||
|
// Required empty public constructor
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Rename and change types and number of parameters
|
||||||
|
public static UpdatePin newInstance() {
|
||||||
|
UpdatePin fragment = new UpdatePin();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
fragment.setArguments(args);
|
||||||
|
return fragment;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
viewModel = new ViewModelProvider(this).get(LoginViewModel.class);
|
||||||
|
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
|
||||||
|
loaderDialog = new LoaderDialog(getContext());
|
||||||
|
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), new SessionManager(getContext()), new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class),this);
|
||||||
|
// Inflate the layout for this fragment
|
||||||
|
binding = FragmentUpdatePinBinding.inflate(inflater, container, false);
|
||||||
|
|
||||||
|
return binding.getRoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
binding.validate.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
oldPin = binding.oldPin.getText().toString();
|
||||||
|
newPin = binding.newPin.getText().toString();
|
||||||
|
confirmation = binding.pinConfirmation.getText().toString();
|
||||||
|
if(oldPin.length()<4 || newPin.length()<4 || confirmation.length()<4){
|
||||||
|
MessageDialog.showError(getContext(), "Le pin doit au mois avoir 4 Caractères!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!newPin.equals(confirmation)){
|
||||||
|
MessageDialog.showError(getContext(), "Les pins ne sont pas identiques!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
viewModel.changePin(oldPin, newPin).observe(getViewLifecycleOwner(), new Observer<Result<User>>(){
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<User> userResult) {
|
||||||
|
switch (userResult.status){
|
||||||
|
case LOADING:{
|
||||||
|
loaderDialog.show("Mis à jour du pin");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), userResult.message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SUCCESS:{
|
||||||
|
loaderDialog.dismiss();
|
||||||
|
|
||||||
|
MessageDialog.showSuccess(getContext(), "Pin mis à jour avec succès");
|
||||||
|
logsViewModel.insertLog(String.valueOf(userResult.data.getId()), "MIS A JOUR PIN", "Mise à jour du pin", System.currentTimeMillis());
|
||||||
|
SessionManager sessionManager = new SessionManager(getContext());
|
||||||
|
authNavigator.showPinDialog(()->{
|
||||||
|
sessionManager.updateLastExpiredDate();
|
||||||
|
getParentFragmentManager().popBackStack();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
binding.cancel.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
getParentFragmentManager().popBackStack();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,26 +1,59 @@
|
|||||||
package com.example.quiz;
|
package com.example.quiz;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.graphics.Color;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.lifecycle.Observer;
|
||||||
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.example.quiz.data.model.ParisResponse;
|
||||||
|
import com.example.quiz.data.model.enums.PariStatut;
|
||||||
import com.example.quiz.databinding.FragmentWinTicketBinding;
|
import com.example.quiz.databinding.FragmentWinTicketBinding;
|
||||||
|
import com.example.quiz.utils.LoaderDialog;
|
||||||
|
import com.example.quiz.utils.MessageDialog;
|
||||||
|
import com.example.quiz.utils.Result;
|
||||||
|
import com.example.quiz.utils.SharedPrefsHelper;
|
||||||
|
import com.example.quiz.viewModel.LogsViewModel;
|
||||||
|
import com.example.quiz.viewModel.PariViewModel;
|
||||||
import com.google.android.material.appbar.MaterialToolbar;
|
import com.google.android.material.appbar.MaterialToolbar;
|
||||||
|
|
||||||
|
import org.w3c.dom.Text;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
import dagger.hilt.android.AndroidEntryPoint;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple {@link Fragment} subclass.
|
* A simple {@link Fragment} subclass.
|
||||||
* Use the {@link WinTicket#newInstance} factory method to
|
* Use the {@link WinTicket#newInstance} factory method to
|
||||||
* create an instance of this fragment.
|
* create an instance of this fragment.
|
||||||
*/
|
*/
|
||||||
|
@AndroidEntryPoint
|
||||||
public class WinTicket extends Fragment {
|
public class WinTicket extends Fragment {
|
||||||
|
|
||||||
FragmentWinTicketBinding binding;
|
FragmentWinTicketBinding binding;
|
||||||
|
|
||||||
|
PariViewModel pariViewModel;
|
||||||
|
|
||||||
|
LogsViewModel logsViewModel;
|
||||||
|
|
||||||
|
SharedPrefsHelper sharedPrefsHelper;
|
||||||
|
|
||||||
|
LoaderDialog loader;
|
||||||
|
|
||||||
|
|
||||||
public WinTicket() {
|
public WinTicket() {
|
||||||
// Required empty public constructor
|
// Required empty public constructor
|
||||||
@@ -48,6 +81,10 @@ public class WinTicket extends Fragment {
|
|||||||
@Override
|
@Override
|
||||||
public void onViewCreated(View view, Bundle savedInstanceState) {
|
public void onViewCreated(View view, Bundle savedInstanceState) {
|
||||||
super.onViewCreated(view, savedInstanceState);
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
pariViewModel = new ViewModelProvider(this).get(PariViewModel.class);
|
||||||
|
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
|
||||||
|
sharedPrefsHelper = SharedPrefsHelper.getInstance(getContext());
|
||||||
|
loader = new LoaderDialog(getContext());
|
||||||
binding.winTicketBtnBack.setOnClickListener(v -> {
|
binding.winTicketBtnBack.setOnClickListener(v -> {
|
||||||
getActivity().onBackPressed();
|
getActivity().onBackPressed();
|
||||||
});
|
});
|
||||||
@@ -58,6 +95,173 @@ public class WinTicket extends Fragment {
|
|||||||
});
|
});
|
||||||
scannerDialog.show(getParentFragmentManager(), "scanner");
|
scannerDialog.show(getParentFragmentManager(), "scanner");
|
||||||
});
|
});
|
||||||
|
binding.winTicketVerificationBtn.setOnClickListener(v -> {
|
||||||
|
String reference = binding.referenceTicket.getText().toString();
|
||||||
|
if(reference.isEmpty()){
|
||||||
|
MessageDialog.showError(getContext(), "Veuillez donner la reference du ticket");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pariViewModel.getPariByNumero(reference).observe(getViewLifecycleOwner(), new Observer<Result<ParisResponse>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<ParisResponse> parisResponseResult) {
|
||||||
|
switch (parisResponseResult.status){
|
||||||
|
case LOADING:{
|
||||||
|
loader.show("Recherche du ticket");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR:{
|
||||||
|
MessageDialog.showError(getContext(), parisResponseResult.message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SUCCESS:{
|
||||||
|
if(parisResponseResult.data.getNumeroTicket().equals(reference)){
|
||||||
|
loader.dismiss();
|
||||||
|
_showDialog(parisResponseResult.data);
|
||||||
|
}else{
|
||||||
|
MessageDialog.showError(getContext(), "Le ticket n'existe pas");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n")
|
||||||
|
void _showDialog(ParisResponse pari){
|
||||||
|
LayoutInflater inflater = getLayoutInflater();
|
||||||
|
View view = inflater.inflate(R.layout.pay_confirmation_layout, null);
|
||||||
|
TextView statut = (TextView) view.findViewById(R.id.tv_statut);
|
||||||
|
statut.setText("Statut: "+String.valueOf(pari.getStatutPari()));
|
||||||
|
TextView dateHeure = (TextView) view.findViewById(R.id.tv_date_heure);
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
|
||||||
|
dateHeure.setText(formatter.format(LocalDateTime.now()));
|
||||||
|
TextView numeroCourse = (TextView) view.findViewById(R.id.tv_numero_course);
|
||||||
|
numeroCourse.setText(String.valueOf(pari.getCourseNumero()));
|
||||||
|
TextView nomCourse = (TextView) view.findViewById(R.id.tv_nom_course);
|
||||||
|
nomCourse.setText(pari.getCourseNom());
|
||||||
|
TextView numeroTicket = (TextView) view.findViewById(R.id.tv_numero_ticket);
|
||||||
|
numeroTicket.setText(pari.getNumeroTicket());
|
||||||
|
TextView datePrise = (TextView) view.findViewById(R.id.tv_date_prise);
|
||||||
|
datePrise.setText(formatter.format(OffsetDateTime.parse(pari.getDateHeurePrise())));
|
||||||
|
TextView combinaison = (TextView) view.findViewById(R.id.tv_combinaison);
|
||||||
|
combinaison.setText(pari.getCombinaison());
|
||||||
|
TextView montant = (TextView) view.findViewById(R.id.tv_montant);
|
||||||
|
LinearLayout montantLayout = (LinearLayout) view.findViewById(R.id.tv_montant_layout);
|
||||||
|
Button confirmer = (Button) view.findViewById(R.id.btn_confirmer);
|
||||||
|
LinearLayout notesLayout = (LinearLayout) view.findViewById(R.id.notes_layout);
|
||||||
|
TextView notes = (TextView) view.findViewById(R.id.notes);
|
||||||
|
|
||||||
|
TextView messageStatut = (TextView) view.findViewById(R.id.tv_message_statut);
|
||||||
|
switch (pari.getStatutPari()){
|
||||||
|
case GAGNANT:{
|
||||||
|
messageStatut.setText("Veuillez confirmer le paiement de ce pari");
|
||||||
|
montant.setText(pari.getGainCalcule()+" CFA");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case A_REMBOURSER:{
|
||||||
|
messageStatut.setText("Veuillez confirmer le remboursement de ce pari");
|
||||||
|
montant.setText(pari.getMiseTotale()+" CFA");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PAYE:{
|
||||||
|
messageStatut.setText("Ce pari a déjà été payé");
|
||||||
|
montant.setText(pari.getGainCalcule()+" CFA");
|
||||||
|
notesLayout.setVisibility(View.VISIBLE);
|
||||||
|
notes.setText(pari.getNotes());
|
||||||
|
confirmer.setVisibility(View.GONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
montantLayout.setVisibility(View.GONE);
|
||||||
|
statut.setTextColor(Color.parseColor("#cf1c08"));
|
||||||
|
messageStatut.setVisibility(View.GONE);
|
||||||
|
confirmer.setVisibility(View.GONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
|
||||||
|
builder.setView(view);
|
||||||
|
AlertDialog dialog = builder.create();
|
||||||
|
Button annuler = (Button) view.findViewById(R.id.btn_annuler);
|
||||||
|
annuler.setOnClickListener(v -> {
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
confirmer.setOnClickListener(v -> {
|
||||||
|
switch (pari.getStatutPari()){
|
||||||
|
case A_REMBOURSER:{
|
||||||
|
pariViewModel.rembourserPari(pari.getNumeroTicket()).observe(getViewLifecycleOwner(), new Observer<Result<ParisResponse>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<ParisResponse> pariResponseResult) {
|
||||||
|
switch (pariResponseResult.status){
|
||||||
|
case LOADING: {
|
||||||
|
loader.show("Remboursement en cours");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR: {
|
||||||
|
loader.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), pariResponseResult.message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SUCCESS: {
|
||||||
|
loader.dismiss();
|
||||||
|
if(sharedPrefsHelper.get("id") == null){
|
||||||
|
MessageDialog.showError(getContext(), "Erreur de connexion");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logsViewModel.insertLog(sharedPrefsHelper.get("id"), "REMBOURSEMENT TICKET", "Remboursement du ticket numéro "+ pari.getNumeroTicket()+" montant "+pari.getMiseTotale(), System.currentTimeMillis());
|
||||||
|
MessageDialog.showSuccess(getContext(), "Remboursement effectué avec succès");
|
||||||
|
binding.referenceTicket.setText("");
|
||||||
|
dialog.dismiss();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GAGNANT:{
|
||||||
|
pariViewModel.payerPari(pari.getNumeroTicket()).observe(getViewLifecycleOwner(), new Observer<Result<ParisResponse>>() {
|
||||||
|
@Override
|
||||||
|
public void onChanged(Result<ParisResponse> pariResponseResult) {
|
||||||
|
switch (pariResponseResult.status){
|
||||||
|
case LOADING: {
|
||||||
|
loader.show("Paiement en cours");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ERROR: {
|
||||||
|
loader.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), pariResponseResult.message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SUCCESS: {
|
||||||
|
loader.dismiss();
|
||||||
|
if(sharedPrefsHelper.get("id") == null){
|
||||||
|
MessageDialog.showError(getContext(), "Erreur de connexion");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
logsViewModel.insertLog(sharedPrefsHelper.get("id"), "PAIEMENT TICKET", "Paiement du ticket numéro "+ pari.getNumeroTicket()+" montant "+pari.getGainCalcule(), System.currentTimeMillis());
|
||||||
|
binding.referenceTicket.setText("");
|
||||||
|
MessageDialog.showSuccess(getContext(), "Paiement effectué avec succès");
|
||||||
|
dialog.dismiss();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
dialog.dismiss();
|
||||||
|
MessageDialog.showError(getContext(), "Action non comprise pour ce ticket");
|
||||||
|
binding.referenceTicket.setText("");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,94 @@
|
|||||||
|
package com.example.quiz.data.adapter;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.ImageButton;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.example.quiz.R;
|
||||||
|
import com.example.quiz.data.model.dtos.auth.User;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class AgentItemAdapter extends RecyclerView.Adapter<AgentItemAdapter.AgentItemViewHolder> {
|
||||||
|
private List<User> agents = new ArrayList<>();
|
||||||
|
public AgentItemAdapter(){
|
||||||
|
|
||||||
|
}
|
||||||
|
public AgentItemAdapter(List<User> agents) {
|
||||||
|
this.agents = agents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface onItemClickListener{
|
||||||
|
void onItemClick(User agent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private onItemClickListener listener;
|
||||||
|
public void setOnItemClickListener(onItemClickListener listener){
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static class AgentItemViewHolder extends RecyclerView.ViewHolder{
|
||||||
|
TextView txtCode, txtDate, txtAdresse;
|
||||||
|
ImageButton details;
|
||||||
|
public AgentItemViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
txtCode = itemView.findViewById(R.id.txtCode);
|
||||||
|
txtDate = itemView.findViewById(R.id.txtDate);
|
||||||
|
txtAdresse = itemView.findViewById(R.id.txtAdresse);
|
||||||
|
details = itemView.findViewById(R.id.details);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return agents.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public AgentItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext())
|
||||||
|
.inflate(R.layout.agent_item, parent, false);
|
||||||
|
return new AgentItemViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull AgentItemViewHolder holder, int position) {
|
||||||
|
User agent = agents.get(position);
|
||||||
|
holder.txtCode.setText(agent.getCode());
|
||||||
|
if(agent.getDateEmbauche() == null){
|
||||||
|
holder.txtDate.setText("Pas de date");
|
||||||
|
}else{
|
||||||
|
LocalDate date = LocalDate.parse(agent.getDateEmbauche());
|
||||||
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
|
||||||
|
holder.txtDate.setText(dateTimeFormatter.format(date));
|
||||||
|
}
|
||||||
|
if(agent.getVille() == null || agent.getAdresse() == null){
|
||||||
|
holder.txtAdresse.setText("Pas d'adresse");
|
||||||
|
}else{
|
||||||
|
String address = agent.getVille()+"; "+agent.getAdresse();
|
||||||
|
holder.txtAdresse.setText(address);
|
||||||
|
}
|
||||||
|
holder.details.setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if(listener != null){
|
||||||
|
listener.onItemClick(agent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,9 +1,16 @@
|
|||||||
package com.example.quiz.data.adapter;
|
package com.example.quiz.data.adapter;
|
||||||
|
|
||||||
|
import static java.security.AccessController.getContext;
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.AdapterView;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
@@ -17,21 +24,23 @@ import java.util.List;
|
|||||||
public class LastBetsAdapter extends RecyclerView.Adapter<LastBetsAdapter.LastBetsViewHolder> {
|
public class LastBetsAdapter extends RecyclerView.Adapter<LastBetsAdapter.LastBetsViewHolder> {
|
||||||
|
|
||||||
private List<ParisResponse> listeParis = new ArrayList<>(); // évite les NPE
|
private List<ParisResponse> listeParis = new ArrayList<>(); // évite les NPE
|
||||||
private OnBetClick onBetClick; // peut être null si tu veux
|
|
||||||
|
|
||||||
public interface OnBetClick {
|
private onPariClickListener listener;
|
||||||
|
|
||||||
|
public interface onPariClickListener {
|
||||||
void onItemClick(ParisResponse pari);
|
void onItemClick(ParisResponse pari);
|
||||||
|
|
||||||
|
void onItemCancel(ParisResponse pari);
|
||||||
}
|
}
|
||||||
|
|
||||||
public LastBetsAdapter(List<ParisResponse> listeParis, OnBetClick onBetClick) {
|
public void setPariClickListener(onPariClickListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LastBetsAdapter(List<ParisResponse> listeParis) {
|
||||||
if (listeParis != null) this.listeParis = listeParis;
|
if (listeParis != null) this.listeParis = listeParis;
|
||||||
this.onBetClick = onBetClick;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Constructeur vide utile si tu veux créer puis setData ensuite
|
|
||||||
public LastBetsAdapter(OnBetClick onBetClick) {
|
|
||||||
this.onBetClick = onBetClick;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setData(List<ParisResponse> newList) {
|
public void setData(List<ParisResponse> newList) {
|
||||||
if (newList == null) {
|
if (newList == null) {
|
||||||
@@ -77,10 +86,44 @@ public class LastBetsAdapter extends RecyclerView.Adapter<LastBetsAdapter.LastBe
|
|||||||
|
|
||||||
// Mise (défensif)
|
// Mise (défensif)
|
||||||
holder.mise.setText("Mise: " + pari.getMiseTotale() + " CFA");
|
holder.mise.setText("Mise: " + pari.getMiseTotale() + " CFA");
|
||||||
|
holder.tvStatut.setText(pari.getStatutPari() != null ? String.valueOf(pari.getStatutPari()) : "Pas de statut");
|
||||||
|
switch (pari.getStatutPari()){
|
||||||
|
case ANNULE:{
|
||||||
|
holder.tvStatut.setTextColor(Color.RED);
|
||||||
|
holder.btnAnnuler.setVisibility(View.GONE);
|
||||||
|
holder.btnImprimer.setVisibility(View.GONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PAYE:{
|
||||||
|
holder.tvStatut.setTextColor(Color.GREEN);
|
||||||
|
holder.btnAnnuler.setVisibility(View.GONE);
|
||||||
|
holder.btnImprimer.setVisibility(View.GONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ENREGISTRE:{
|
||||||
|
holder.tvStatut.setTextColor(Color.YELLOW);
|
||||||
|
holder.btnAnnuler.setVisibility(View.VISIBLE);
|
||||||
|
holder.btnImprimer.setVisibility(View.VISIBLE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:{
|
||||||
|
holder.tvStatut.setTextColor(Color.BLACK);
|
||||||
|
holder.btnAnnuler.setVisibility(View.GONE);
|
||||||
|
holder.btnImprimer.setVisibility(View.GONE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// click listener défensif
|
holder.btnAnnuler.setOnClickListener(v -> {
|
||||||
holder.itemView.setOnClickListener(v -> {
|
if (listener != null) {
|
||||||
if (onBetClick != null) onBetClick.onItemClick(pari);
|
listener.onItemCancel(pari);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
holder.btnImprimer.setOnClickListener(v -> {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onItemClick(pari);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +133,8 @@ public class LastBetsAdapter extends RecyclerView.Adapter<LastBetsAdapter.LastBe
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class LastBetsViewHolder extends RecyclerView.ViewHolder {
|
public static class LastBetsViewHolder extends RecyclerView.ViewHolder {
|
||||||
TextView betType, horses, course, mise, refenceTicket, typeOfCourse;
|
TextView betType, horses, course, mise, refenceTicket, typeOfCourse, tvStatut;
|
||||||
|
Button btnAnnuler, btnImprimer;;
|
||||||
|
|
||||||
public LastBetsViewHolder(@NonNull View itemView) {
|
public LastBetsViewHolder(@NonNull View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
@@ -100,6 +144,9 @@ public class LastBetsAdapter extends RecyclerView.Adapter<LastBetsAdapter.LastBe
|
|||||||
mise = itemView.findViewById(R.id.last_bet_mise);
|
mise = itemView.findViewById(R.id.last_bet_mise);
|
||||||
refenceTicket = itemView.findViewById(R.id.reference_ticket);
|
refenceTicket = itemView.findViewById(R.id.reference_ticket);
|
||||||
typeOfCourse = itemView.findViewById(R.id.type_of_course);
|
typeOfCourse = itemView.findViewById(R.id.type_of_course);
|
||||||
|
btnAnnuler = itemView.findViewById(R.id.btn_annuler);
|
||||||
|
btnImprimer = itemView.findViewById(R.id.btn_imprimer);
|
||||||
|
tvStatut = itemView.findViewById(R.id.tv_statut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,149 @@
|
|||||||
|
package com.example.quiz.data.adapter;
|
||||||
|
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import com.example.quiz.R;
|
||||||
|
import com.example.quiz.data.model.Course;
|
||||||
|
import com.example.quiz.data.model.TypeOfBet;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class MultiTypeOfBetsAdapter extends RecyclerView.Adapter<MultiTypeOfBetsAdapter.TypeOfBetViewHolder> {
|
||||||
|
private List<TypeOfBet> types;
|
||||||
|
private Set<Integer> selectedPositions = new HashSet<>();
|
||||||
|
private onItemClickListener listener;
|
||||||
|
|
||||||
|
public interface onItemClickListener {
|
||||||
|
void onItemClick(TypeOfBet type, boolean isChecked);
|
||||||
|
void onItemsSelected(List<TypeOfBet> selectedItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnItemClickListener(onItemClickListener listener) {
|
||||||
|
this.listener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MultiTypeOfBetsAdapter(List<TypeOfBet> types) {
|
||||||
|
this.types = types;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Méthode pour pré-sélectionner les paris (rendue publique)
|
||||||
|
public void preSelectAvailableBets(List<Course.TypeParis> preselectedTypes) {
|
||||||
|
selectedPositions.clear();
|
||||||
|
for (int i = 0; i < types.size(); i++) {
|
||||||
|
if (preselectedTypes.contains(types.get(i).getName())) {
|
||||||
|
selectedPositions.add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypes(List<TypeOfBet> types) {
|
||||||
|
this.types = types;
|
||||||
|
selectedPositions.clear();
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
@Override
|
||||||
|
public TypeOfBetViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||||
|
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.multi_type_of_bet_item, parent, false);
|
||||||
|
return new TypeOfBetViewHolder(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NonNull TypeOfBetViewHolder holder, int position) {
|
||||||
|
TypeOfBet type = types.get(position);
|
||||||
|
holder.type_of_bet_name.setText(type.getLabel());
|
||||||
|
|
||||||
|
boolean isSelected = selectedPositions.contains(position);
|
||||||
|
holder.checkBox.setChecked(isSelected);
|
||||||
|
|
||||||
|
if (isSelected) {
|
||||||
|
holder.itemView.setBackgroundResource(R.drawable.item_gradient_bg_selected);
|
||||||
|
} else {
|
||||||
|
holder.itemView.setBackgroundResource(R.drawable.item_gradient_bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.itemView.setOnClickListener(v -> {
|
||||||
|
toggleSelection(position, type);
|
||||||
|
});
|
||||||
|
|
||||||
|
holder.checkBox.setOnClickListener(v -> {
|
||||||
|
toggleSelection(position, type);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleSelection(int position, TypeOfBet type) {
|
||||||
|
boolean isCurrentlySelected = selectedPositions.contains(position);
|
||||||
|
|
||||||
|
if (isCurrentlySelected) {
|
||||||
|
selectedPositions.remove(position);
|
||||||
|
} else {
|
||||||
|
selectedPositions.add(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onItemClick(type, !isCurrentlySelected);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
notifyItemChanged(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return types.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TypeOfBet> getSelectedItems() {
|
||||||
|
List<TypeOfBet> selectedItems = new ArrayList<>();
|
||||||
|
for (Integer position : selectedPositions) {
|
||||||
|
if (position >= 0 && position < types.size()) {
|
||||||
|
selectedItems.add(types.get(position));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selectedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSelected(int position) {
|
||||||
|
return selectedPositions.contains(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void selectAll() {
|
||||||
|
selectedPositions.clear();
|
||||||
|
for (int i = 0; i < types.size(); i++) {
|
||||||
|
selectedPositions.add(i);
|
||||||
|
}
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deselectAll() {
|
||||||
|
selectedPositions.clear();
|
||||||
|
notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSelectedCount() {
|
||||||
|
return selectedPositions.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TypeOfBetViewHolder extends RecyclerView.ViewHolder {
|
||||||
|
TextView type_of_bet_name;
|
||||||
|
CheckBox checkBox;
|
||||||
|
|
||||||
|
public TypeOfBetViewHolder(@NonNull View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
type_of_bet_name = itemView.findViewById(R.id.tv_bet_name);
|
||||||
|
checkBox = itemView.findViewById(R.id.checkbox_bet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.example.quiz.data.model;
|
package com.example.quiz.data.model;
|
||||||
|
|
||||||
import com.example.quiz.data.model.enums.CourseType;
|
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
package com.example.quiz.data.model;
|
||||||
|
|
||||||
|
public class MiseInitiale {
|
||||||
|
private Long id;
|
||||||
|
private Course.TypeParis typePari;
|
||||||
|
private Long miseInitialeMin;
|
||||||
|
private Long miseInitialeMax;
|
||||||
|
private boolean actif;
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(Long id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Course.TypeParis getTypePari() {
|
||||||
|
return typePari;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTypePari(Course.TypeParis typePari) {
|
||||||
|
this.typePari = typePari;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getMiseInitialeMin() {
|
||||||
|
return miseInitialeMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMiseInitialeMin(Long miseInitialeMin) {
|
||||||
|
this.miseInitialeMin = miseInitialeMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getMiseInitialeMax() {
|
||||||
|
return miseInitialeMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMiseInitialeMax(Long miseInitialeMax) {
|
||||||
|
this.miseInitialeMax = miseInitialeMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActif() {
|
||||||
|
return actif;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActif(boolean actif) {
|
||||||
|
this.actif = actif;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.example.quiz.data.model;
|
package com.example.quiz.data.model;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ParisResponse implements Serializable {
|
public class ParisResponse implements Serializable {
|
||||||
@@ -58,7 +59,10 @@ public class ParisResponse implements Serializable {
|
|||||||
PAYE,
|
PAYE,
|
||||||
ANNULE,
|
ANNULE,
|
||||||
PERDANT,
|
PERDANT,
|
||||||
GAGNANT
|
GAGNANT,
|
||||||
|
A_REMBOURSER,
|
||||||
|
REMBOURSE,
|
||||||
|
ECHEC_CACUL
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================= INNER CLASS =================
|
// ================= INNER CLASS =================
|
||||||
@@ -67,7 +71,7 @@ public class ParisResponse implements Serializable {
|
|||||||
|
|
||||||
public long getId() { return id; }
|
public long getId() { return id; }
|
||||||
public String getNumeroTicket() { return numeroTicket; }
|
public String getNumeroTicket() { return numeroTicket; }
|
||||||
public String getDateHeurePrise() { return dateHeurePrise; }
|
public String getDateHeurePrise() { return dateHeurePrise; }
|
||||||
public String getQrPayload() { return qrPayload; }
|
public String getQrPayload() { return qrPayload; }
|
||||||
public long getCourseId() { return courseId; }
|
public long getCourseId() { return courseId; }
|
||||||
public String getCourseNom() { return courseNom; }
|
public String getCourseNom() { return courseNom; }
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package com.example.quiz.data.model;
|
||||||
|
|
||||||
|
public class ResponseError {
|
||||||
|
private String message;
|
||||||
|
private int status;
|
||||||
|
|
||||||
|
private String timestamp;
|
||||||
|
|
||||||
|
public ResponseError(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMessage(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatus() {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus(int status) {
|
||||||
|
this.status = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTimestamp() {
|
||||||
|
return timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimestamp(String timestamp) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.example.quiz.data.model;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class Restriction {
|
||||||
|
private List<Course.TypeParis> allowedBetTypes;
|
||||||
|
|
||||||
|
public Restriction(){}
|
||||||
|
|
||||||
|
public List<Course.TypeParis> getAllowedBetTypes() {
|
||||||
|
return allowedBetTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllowedBetTypes(List<Course.TypeParis> allowedBetTypes) {
|
||||||
|
this.allowedBetTypes = allowedBetTypes;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package com.example.quiz.data.model.dtos;
|
||||||
|
|
||||||
|
public class NotifPayload<T> {
|
||||||
|
private NotifType type;
|
||||||
|
private String entity;
|
||||||
|
private Long entityId;
|
||||||
|
private T payload;
|
||||||
|
|
||||||
|
public NotifPayload() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public NotifType getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(NotifType type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEntity() {
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntity(String entity) {
|
||||||
|
this.entity = entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getEntityId() {
|
||||||
|
return entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEntityId(Long entityId) {
|
||||||
|
this.entityId = entityId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public T getPayload() {
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPayload(T payload) {
|
||||||
|
this.payload = payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum NotifType {
|
||||||
|
COURSE_CREATED,
|
||||||
|
COURSE_UPDATED,
|
||||||
|
COURSE_CANCELLED,
|
||||||
|
COURSE_REPORTED,
|
||||||
|
COURSE_CLOSED_FOR_BETTING,
|
||||||
|
RUNNER_DECLARED_NON_PARTANT
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,6 +8,8 @@ public class Agent {
|
|||||||
private String phone;
|
private String phone;
|
||||||
private String zone;
|
private String zone;
|
||||||
private String fonction;
|
private String fonction;
|
||||||
|
|
||||||
|
private boolean subAgent;
|
||||||
public Agent(){}
|
public Agent(){}
|
||||||
|
|
||||||
public Long getId() {
|
public Long getId() {
|
||||||
@@ -65,4 +67,12 @@ public class Agent {
|
|||||||
public void setFonction(String fonction) {
|
public void setFonction(String fonction) {
|
||||||
this.fonction = fonction;
|
this.fonction = fonction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSubAgent() {
|
||||||
|
return subAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSubAgent(boolean subAgent) {
|
||||||
|
this.subAgent = subAgent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.example.quiz.data.model.dtos.auth;
|
||||||
|
|
||||||
|
public class ChangePin {
|
||||||
|
private String oldPin;
|
||||||
|
private String newPin;
|
||||||
|
|
||||||
|
public ChangePin() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOldPin() {
|
||||||
|
return oldPin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOldPin(String oldPin) {
|
||||||
|
this.oldPin = oldPin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getNewPin() {
|
||||||
|
return newPin;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNewPin(String newPin) {
|
||||||
|
this.newPin = newPin;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.example.quiz.data.model.dtos.paris;
|
||||||
|
|
||||||
|
public class CancelParisPaylaod {
|
||||||
|
private String statutPari;
|
||||||
|
|
||||||
|
public CancelParisPaylaod(String statutPari) {
|
||||||
|
this.statutPari = statutPari;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStatutPari() {
|
||||||
|
return statutPari;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatutPari(String statutPari) {
|
||||||
|
this.statutPari = statutPari;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.example.quiz.data.model.dtos.paris;
|
||||||
|
|
||||||
|
public class SoldeResponse {
|
||||||
|
private int montantParis;
|
||||||
|
private int nombrePaiements;
|
||||||
|
private int montantPaiements;
|
||||||
|
private int nombreAnnulations;
|
||||||
|
private int montantAnnulations;
|
||||||
|
|
||||||
|
// Getters et setters
|
||||||
|
|
||||||
|
public int getMontantParis() {
|
||||||
|
return montantParis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMontantParis(int montantParis) {
|
||||||
|
this.montantParis = montantParis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNombrePaiements() {
|
||||||
|
return nombrePaiements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNombrePaiements(int nombrePaiements) {
|
||||||
|
this.nombrePaiements = nombrePaiements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMontantPaiements() {
|
||||||
|
return montantPaiements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMontantPaiements(int montantPaiements) {
|
||||||
|
this.montantPaiements = montantPaiements;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNombreAnnulations() {
|
||||||
|
return nombreAnnulations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNombreAnnulations(int nombreAnnulations) {
|
||||||
|
this.nombreAnnulations = nombreAnnulations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMontantAnnulations() {
|
||||||
|
return montantAnnulations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMontantAnnulations(int montantAnnulations) {
|
||||||
|
this.montantAnnulations = montantAnnulations;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package com.example.quiz.data.model.enums;
|
|
||||||
|
|
||||||
public enum CourseType {
|
|
||||||
TIERCE,
|
|
||||||
QUARTE,
|
|
||||||
QUINTE
|
|
||||||
}
|
|
||||||
@@ -20,7 +20,7 @@ import retrofit2.converter.gson.GsonConverterFactory;
|
|||||||
@Module
|
@Module
|
||||||
@InstallIn(SingletonComponent.class)
|
@InstallIn(SingletonComponent.class)
|
||||||
public class ApiClient {
|
public class ApiClient {
|
||||||
private static final String BASE_URL = "https://boxer-adapting-bluegill.ngrok-free.app/api/";
|
private static final String BASE_URL = "https://alr.pmu.ml/api/";
|
||||||
|
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|||||||
@@ -1,21 +1,29 @@
|
|||||||
package com.example.quiz.data.remote;
|
package com.example.quiz.data.remote;
|
||||||
|
|
||||||
import com.example.quiz.data.model.Course;
|
import com.example.quiz.data.model.Course;
|
||||||
|
import com.example.quiz.data.model.MiseInitiale;
|
||||||
import com.example.quiz.data.model.PagedModel;
|
import com.example.quiz.data.model.PagedModel;
|
||||||
import com.example.quiz.data.model.Pari;
|
import com.example.quiz.data.model.Pari;
|
||||||
|
import com.example.quiz.data.model.PariMise;
|
||||||
import com.example.quiz.data.model.ParisResponse;
|
import com.example.quiz.data.model.ParisResponse;
|
||||||
import com.example.quiz.data.model.PointDeVente;
|
import com.example.quiz.data.model.PointDeVente;
|
||||||
|
import com.example.quiz.data.model.Restriction;
|
||||||
import com.example.quiz.data.model.Reunion;
|
import com.example.quiz.data.model.Reunion;
|
||||||
import com.example.quiz.data.model.Tpe;
|
import com.example.quiz.data.model.Tpe;
|
||||||
|
import com.example.quiz.data.model.dtos.auth.ChangePin;
|
||||||
import com.example.quiz.data.model.dtos.auth.LoginPayload;
|
import com.example.quiz.data.model.dtos.auth.LoginPayload;
|
||||||
import com.example.quiz.data.model.dtos.auth.LoginResponse;
|
import com.example.quiz.data.model.dtos.auth.LoginResponse;
|
||||||
import com.example.quiz.data.model.TpeResponse;
|
import com.example.quiz.data.model.TpeResponse;
|
||||||
|
import com.example.quiz.data.model.dtos.auth.User;
|
||||||
|
import com.example.quiz.data.model.dtos.paris.CancelParisPaylaod;
|
||||||
|
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.http.Body;
|
import retrofit2.http.Body;
|
||||||
import retrofit2.http.GET;
|
import retrofit2.http.GET;
|
||||||
|
import retrofit2.http.PATCH;
|
||||||
import retrofit2.http.POST;
|
import retrofit2.http.POST;
|
||||||
import retrofit2.http.PUT;
|
import retrofit2.http.PUT;
|
||||||
import retrofit2.http.Path;
|
import retrofit2.http.Path;
|
||||||
@@ -26,7 +34,7 @@ public interface ApiService {
|
|||||||
Call<List<Reunion>> getReunions(@Path("date") String date);
|
Call<List<Reunion>> getReunions(@Path("date") String date);
|
||||||
|
|
||||||
@GET("courses")
|
@GET("courses")
|
||||||
Call<PagedModel<Course>> getCourses(@Query("reunionDate") String reunionDate);
|
Call<PagedModel<Course>> getCourses(@Query("reunionDate") String reunionDate, @Query("statut") String statut);
|
||||||
|
|
||||||
@POST("paris")
|
@POST("paris")
|
||||||
Call<ParisResponse> createPari(@Body Pari pari);
|
Call<ParisResponse> createPari(@Body Pari pari);
|
||||||
@@ -37,18 +45,53 @@ public interface ApiService {
|
|||||||
@GET("paris/agent/{agentId}/today")
|
@GET("paris/agent/{agentId}/today")
|
||||||
Call<List<ParisResponse>> derniersParis(@Path("agentId") String agentId);
|
Call<List<ParisResponse>> derniersParis(@Path("agentId") String agentId);
|
||||||
|
|
||||||
@PUT("pari/annuler/{numeroTicket}")
|
@PATCH("paris/numero/{numeroTicket}/cancel")
|
||||||
Call<ParisResponse> annulerPari(@Path("numeroTicket") String numeroTicket);
|
Call<ParisResponse> annulerPari(@Path("numeroTicket") String numeroTicket);
|
||||||
|
@PATCH("paris/numero/{numeroTicket}/rembourser")
|
||||||
|
Call<ParisResponse> rembourserPari(@Path("numeroTicket") String numeroTicket);
|
||||||
|
|
||||||
|
@PATCH("paris/numero/{numeroTicket}/pay")
|
||||||
|
Call<ParisResponse> payerPari(@Path("numeroTicket") String numeroTicket);
|
||||||
|
|
||||||
|
|
||||||
|
@GET("paris/numero/{numeroTicket}")
|
||||||
|
Call<ParisResponse> getPariByNumero(@Path("numeroTicket") String numeroTicket);
|
||||||
|
|
||||||
@GET("paris/agent/{agentId}/solde/course/{courseId}")
|
@GET("paris/agent/{agentId}/solde/course/{courseId}")
|
||||||
Call<Double> getSoldeByCourse(@Path("agentId") String createdBy, @Path("courseId") String courseId);
|
Call<SoldeResponse> getSoldeByCourse(@Path("agentId") String createdBy, @Path("courseId") String courseId);
|
||||||
|
|
||||||
@GET("paris/agent/{agentId}/solde")
|
@GET("paris/agent/{agentId}/solde")
|
||||||
Call<Double> getSoldeByDay(@Path("agentId") String agentId, @Query("date") String day);
|
Call<SoldeResponse> getSoldeByDay(@Path("agentId") String agentId, @Query("date") String day);
|
||||||
|
|
||||||
@POST("terminaux")
|
@POST("terminaux")
|
||||||
Call<TpeResponse> createTpe(@Body Tpe tpe);
|
Call<TpeResponse> createTpe(@Body Tpe tpe);
|
||||||
|
|
||||||
|
@GET("terminaux/{id}")
|
||||||
|
Call<TpeResponse> getTpeById(@Path("id") String id);
|
||||||
|
|
||||||
@GET("points-de-vente")
|
@GET("points-de-vente")
|
||||||
Call<PagedModel<PointDeVente>> getPointsDeVente(@Query("nom") String nom);
|
Call<PagedModel<PointDeVente>> getPointsDeVente(@Query("nom") String nom);
|
||||||
|
|
||||||
|
@GET("points-de-vente/{id}")
|
||||||
|
Call<PointDeVente> getPointDeVenteById(@Path("id") String id);
|
||||||
|
|
||||||
|
@PATCH("agents/me/pin")
|
||||||
|
Call<User> changePin(@Body ChangePin pin);
|
||||||
|
|
||||||
|
@GET("config/mise-initiale")
|
||||||
|
Call<List<MiseInitiale>> getBetInitMise();
|
||||||
|
|
||||||
|
@GET("agents/byMaster/{masterId}")
|
||||||
|
Call<List<User>> getAgentsByMaster(@Path("masterId") String masterId);
|
||||||
|
@GET("agents/{agentId}")
|
||||||
|
Call<User> getAgent(@Path("agentId") String agentId);
|
||||||
|
@GET("agents/{agentId}/available-bets")
|
||||||
|
Call<List<Course.TypeParis>> getAvailableBets(@Path("agentId") String agentId);
|
||||||
|
|
||||||
|
@PATCH("agents/{masterId}/slaves/{slaveId}/access")
|
||||||
|
Call<Void> setAccess(@Path("masterId") String masterId, @Path("slaveId") String slaveId, @Query("block") boolean access);
|
||||||
|
|
||||||
|
@POST("agents/{masterId}/slaves/{slaveId}/available-bets")
|
||||||
|
Call<Void> setRestrictions(@Path("masterId") String masterId, @Path("slaveId") String slaveId, @Body Restriction restrictions);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
package com.example.quiz.data.remote;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import androidx.core.app.NotificationCompat;
|
||||||
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
|
|
||||||
|
import com.example.quiz.R;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class NotificationHelper {
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
|
private static final String CHANNEL_ID = "socket_channel";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public NotificationHelper(@ApplicationContext Context context) {
|
||||||
|
this.context = context;
|
||||||
|
createChannel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createChannel() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
NotificationChannel channel = new NotificationChannel(
|
||||||
|
CHANNEL_ID,
|
||||||
|
"Socket Notifications",
|
||||||
|
NotificationManager.IMPORTANCE_HIGH
|
||||||
|
);
|
||||||
|
channel.setDescription("Notifications des messages du socket");
|
||||||
|
NotificationManager manager =
|
||||||
|
context.getSystemService(NotificationManager.class);
|
||||||
|
if (manager != null) manager.createNotificationChannel(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
|
public void showNotification(String title, String message) {
|
||||||
|
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
|
||||||
|
.setSmallIcon(R.drawable.ic_notification)
|
||||||
|
.setContentTitle(title)
|
||||||
|
.setContentText(message)
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
|
.setAutoCancel(true);
|
||||||
|
|
||||||
|
NotificationManagerCompat manager = NotificationManagerCompat.from(context);
|
||||||
|
manager.notify((int) System.currentTimeMillis(), builder.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
package com.example.quiz.data.remote;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import okhttp3.Request;
|
|
||||||
import okhttp3.Response;
|
|
||||||
import okhttp3.WebSocket;
|
|
||||||
import okhttp3.WebSocketListener;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public class SocketManager {
|
|
||||||
|
|
||||||
private final OkHttpClient client;
|
|
||||||
private final TokenManager tokenManager;
|
|
||||||
private WebSocket webSocket;
|
|
||||||
private boolean isConnected = false;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public SocketManager(OkHttpClient client, TokenManager tokenManager) {
|
|
||||||
this.client = client;
|
|
||||||
this.tokenManager = tokenManager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void connect() {
|
|
||||||
|
|
||||||
String token = tokenManager.getToken();
|
|
||||||
|
|
||||||
if (token == null) {
|
|
||||||
Log.d("SOCKET", "Token null → no connection");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isConnected) return;
|
|
||||||
|
|
||||||
Request request = new Request.Builder()
|
|
||||||
.url("ws://boxer-adapting-bluegill.ngrok-free.app/ws")
|
|
||||||
.addHeader("Authorization", "Bearer " + token)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
webSocket = client.newWebSocket(request, new WebSocketListener() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onOpen(WebSocket webSocket, Response response) {
|
|
||||||
isConnected = true;
|
|
||||||
Log.d("SOCKET", "Connected");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMessage(WebSocket webSocket, String text) {
|
|
||||||
Log.d("SOCKET", "Message: " + text);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
|
|
||||||
isConnected = false;
|
|
||||||
Log.e("SOCKET", "Error: " + t.getMessage());
|
|
||||||
|
|
||||||
// tentative de reconnexion
|
|
||||||
reconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClosed(WebSocket webSocket, int code, String reason) {
|
|
||||||
isConnected = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void reconnect() {
|
|
||||||
disconnect();
|
|
||||||
connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void disconnect() {
|
|
||||||
if (webSocket != null) {
|
|
||||||
webSocket.close(1000, "Closing");
|
|
||||||
webSocket = null;
|
|
||||||
}
|
|
||||||
isConnected = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
285
app/src/main/java/com/example/quiz/data/remote/StompManager.java
Normal file
285
app/src/main/java/com/example/quiz/data/remote/StompManager.java
Normal file
@@ -0,0 +1,285 @@
|
|||||||
|
package com.example.quiz.data.remote;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.example.quiz.data.model.Course;
|
||||||
|
import com.example.quiz.data.model.dtos.NotifPayload;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
|
import io.reactivex.disposables.Disposable;
|
||||||
|
import io.reactivex.schedulers.Schedulers;
|
||||||
|
import ua.naiksoftware.stomp.Stomp;
|
||||||
|
import ua.naiksoftware.stomp.StompClient;
|
||||||
|
import ua.naiksoftware.stomp.dto.StompHeader;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class StompManager {
|
||||||
|
|
||||||
|
private final TokenManager tokenManager;
|
||||||
|
private final NotificationHelper notificationHelper;
|
||||||
|
|
||||||
|
private StompClient stompClient;
|
||||||
|
private boolean isConnected = false;
|
||||||
|
|
||||||
|
// Map topic -> liste de listeners
|
||||||
|
private final Map<String, List<Consumer<String>>> topicListeners = new HashMap<>();
|
||||||
|
|
||||||
|
// Gestion des Disposables RxJava
|
||||||
|
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
|
// Map pour stocker les subscriptions par topic
|
||||||
|
private final Map<String, Disposable> topicSubscriptions = new HashMap<>();
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public StompManager(TokenManager tokenManager,
|
||||||
|
NotificationHelper notificationHelper) {
|
||||||
|
this.tokenManager = tokenManager;
|
||||||
|
this.notificationHelper = notificationHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------- Connexion --------------------
|
||||||
|
public synchronized void connect() {
|
||||||
|
if (isConnected) return;
|
||||||
|
|
||||||
|
String token = tokenManager.getToken();
|
||||||
|
if (token == null) {
|
||||||
|
Log.e("STOMP", "No token available");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// URL de connexion WebSocket
|
||||||
|
String url = "wss://alr.pmu.ml/ws";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Créer le client STOMP
|
||||||
|
stompClient = Stomp.over(Stomp.ConnectionProvider.OKHTTP, url);
|
||||||
|
|
||||||
|
// Ajouter les headers d'authentification
|
||||||
|
List<StompHeader> headers = new ArrayList<>();
|
||||||
|
headers.add(new StompHeader("Authorization", "Bearer " + token));
|
||||||
|
|
||||||
|
// Observer la connexion et stocker le Disposable
|
||||||
|
Disposable lifecycleDisposable = stompClient.lifecycle()
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(lifecycleEvent -> {
|
||||||
|
switch (lifecycleEvent.getType()) {
|
||||||
|
case OPENED:
|
||||||
|
isConnected = true;
|
||||||
|
Log.d("STOMP", "Connected to WebSocket");
|
||||||
|
resubscribeAll();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLOSED:
|
||||||
|
isConnected = false;
|
||||||
|
Log.d("STOMP", "Disconnected from WebSocket");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ERROR:
|
||||||
|
isConnected = false;
|
||||||
|
Log.e("STOMP", "Error: " + lifecycleEvent.getException());
|
||||||
|
reconnect();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, throwable -> {
|
||||||
|
Log.e("STOMP", "Lifecycle error", throwable);
|
||||||
|
isConnected = false;
|
||||||
|
reconnect();
|
||||||
|
});
|
||||||
|
|
||||||
|
compositeDisposable.add(lifecycleDisposable);
|
||||||
|
|
||||||
|
// Se connecter
|
||||||
|
stompClient.connect(headers);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("STOMP", "Connection error", e);
|
||||||
|
reconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------- Souscription aux topics --------------------
|
||||||
|
public synchronized void subscribe(String topic, Consumer<String> listener) {
|
||||||
|
// Ajouter le listener
|
||||||
|
topicListeners.computeIfAbsent(topic, k -> new ArrayList<>()).add(listener);
|
||||||
|
|
||||||
|
// Si déjà connecté, souscrire immédiatement
|
||||||
|
if (isConnected && stompClient != null) {
|
||||||
|
subscribeToTopic(topic);
|
||||||
|
} else {
|
||||||
|
connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void subscribeToTopic(String topic) {
|
||||||
|
if (stompClient == null) return;
|
||||||
|
|
||||||
|
// Si déjà abonné à ce topic, ne pas souscrire à nouveau
|
||||||
|
if (topicSubscriptions.containsKey(topic)) {
|
||||||
|
Log.d("STOMP", "Already subscribed to " + topic);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Formater le topic correctement
|
||||||
|
String destination = topic.startsWith("/topic/") ? topic : "/topic/" + topic;
|
||||||
|
|
||||||
|
Log.d("STOMP", "Subscribing to " + destination);
|
||||||
|
|
||||||
|
Disposable subscription = stompClient.topic(destination)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
stompMessage -> {
|
||||||
|
String payload = stompMessage.getPayload();
|
||||||
|
Log.d("STOMP", "Message on " + destination + ": " + payload);
|
||||||
|
|
||||||
|
// Notifier les listeners
|
||||||
|
List<Consumer<String>> listeners = topicListeners.get(topic);
|
||||||
|
if (listeners != null) {
|
||||||
|
for (Consumer<String> listener : listeners) {
|
||||||
|
try {
|
||||||
|
listener.accept(payload);
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("STOMP", "Listener error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String notif = "";
|
||||||
|
Type type = new TypeToken<NotifPayload<Course>>(){}.getType();
|
||||||
|
NotifPayload<Course> notifCourse = new Gson().fromJson(payload, type);
|
||||||
|
Course updatedCourse = notifCourse.getPayload();
|
||||||
|
switch (notifCourse.getType()){
|
||||||
|
case COURSE_CREATED:
|
||||||
|
notif = "Nouvelle course "+updatedCourse.getNom()+" créée";
|
||||||
|
break;
|
||||||
|
case COURSE_UPDATED:
|
||||||
|
notif = "Course "+updatedCourse.getNom()+" modifiée";
|
||||||
|
break;
|
||||||
|
case COURSE_CANCELLED:
|
||||||
|
notif = "Course "+updatedCourse.getNom()+" annulée";
|
||||||
|
break;
|
||||||
|
case COURSE_REPORTED:
|
||||||
|
notif = "Course "+updatedCourse.getNom()+" reportée";
|
||||||
|
break;
|
||||||
|
case COURSE_CLOSED_FOR_BETTING:
|
||||||
|
notif = "Course "+updatedCourse.getNom()+" fermée aux paris!";
|
||||||
|
break;
|
||||||
|
case RUNNER_DECLARED_NON_PARTANT:
|
||||||
|
notif = "Non partants déclarés pour la course "+updatedCourse.getNom();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Notification
|
||||||
|
notificationHelper.showNotification(topic, notif);
|
||||||
|
},
|
||||||
|
throwable -> {
|
||||||
|
Log.e("STOMP", "Error on " + destination, throwable);
|
||||||
|
// Nettoyer en cas d'erreur
|
||||||
|
topicSubscriptions.remove(topic);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
topicSubscriptions.put(topic, subscription);
|
||||||
|
compositeDisposable.add(subscription);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resubscribeAll() {
|
||||||
|
if (stompClient == null) return;
|
||||||
|
|
||||||
|
// Nettoyer les anciennes subscriptions
|
||||||
|
for (Disposable disposable : topicSubscriptions.values()) {
|
||||||
|
if (disposable != null && !disposable.isDisposed()) {
|
||||||
|
disposable.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
topicSubscriptions.clear();
|
||||||
|
|
||||||
|
// Resouscrire à tous les topics
|
||||||
|
for (String topic : topicListeners.keySet()) {
|
||||||
|
subscribeToTopic(topic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------- Envoi de messages --------------------
|
||||||
|
public void sendMessage(String destination, Object payload) {
|
||||||
|
if (!isConnected || stompClient == null) {
|
||||||
|
Log.e("STOMP", "Not connected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String dest = destination.startsWith("/app/") ? destination : "/app/" + destination;
|
||||||
|
|
||||||
|
Disposable sendDisposable = stompClient.send(dest, payload.toString())
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(
|
||||||
|
() -> Log.d("STOMP", "Message sent to " + dest),
|
||||||
|
throwable -> Log.e("STOMP", "Error sending to " + dest, throwable)
|
||||||
|
);
|
||||||
|
|
||||||
|
compositeDisposable.add(sendDisposable);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendToCourses(Object payload) {
|
||||||
|
sendMessage("/app/courses", payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------- Désabonnement --------------------
|
||||||
|
public synchronized void unsubscribe(String topic, Consumer<String> listener) {
|
||||||
|
if (topicListeners.containsKey(topic)) {
|
||||||
|
topicListeners.get(topic).remove(listener);
|
||||||
|
|
||||||
|
if (topicListeners.get(topic).isEmpty()) {
|
||||||
|
topicListeners.remove(topic);
|
||||||
|
|
||||||
|
// Si plus de listeners, annuler la souscription STOMP
|
||||||
|
Disposable subscription = topicSubscriptions.remove(topic);
|
||||||
|
if (subscription != null && !subscription.isDisposed()) {
|
||||||
|
subscription.dispose();
|
||||||
|
compositeDisposable.remove(subscription);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------------- Déconnexion --------------------
|
||||||
|
public synchronized void disconnect() {
|
||||||
|
// Nettoyer toutes les subscriptions RxJava
|
||||||
|
compositeDisposable.clear();
|
||||||
|
topicSubscriptions.clear();
|
||||||
|
|
||||||
|
if (stompClient != null) {
|
||||||
|
stompClient.disconnect();
|
||||||
|
stompClient = null;
|
||||||
|
}
|
||||||
|
isConnected = false;
|
||||||
|
topicListeners.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reconnect() {
|
||||||
|
disconnect();
|
||||||
|
// Réessayer après délai
|
||||||
|
new android.os.Handler().postDelayed(() -> {
|
||||||
|
Log.d("STOMP", "Attempting to reconnect...");
|
||||||
|
connect();
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// À appeler dans le cycle de vie du fragment/activity
|
||||||
|
public void onCleanup() {
|
||||||
|
disconnect();
|
||||||
|
compositeDisposable.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,16 +11,13 @@ public class TokenManager {
|
|||||||
private static final String PREF_NAME = "auth_pref";
|
private static final String PREF_NAME = "auth_pref";
|
||||||
private static final String KEY_TOKEN = "auth_token";
|
private static final String KEY_TOKEN = "auth_token";
|
||||||
|
|
||||||
SocketManager socketManager;
|
|
||||||
private SharedPreferences sharedPreferences;
|
private SharedPreferences sharedPreferences;
|
||||||
@Inject
|
@Inject
|
||||||
public TokenManager(@ApplicationContext Context context, SocketManager socketManager) {
|
public TokenManager(@ApplicationContext Context context) {
|
||||||
this.sharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
this.sharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
|
||||||
this.socketManager = socketManager;
|
|
||||||
}
|
}
|
||||||
public void saveToken(String token){
|
public void saveToken(String token){
|
||||||
sharedPreferences.edit().putString(KEY_TOKEN, token).apply();
|
sharedPreferences.edit().putString(KEY_TOKEN, token).apply();
|
||||||
socketManager.reconnect();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getToken(){
|
public String getToken(){
|
||||||
|
|||||||
@@ -0,0 +1,166 @@
|
|||||||
|
package com.example.quiz.data.repository;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.quiz.data.model.Course;
|
||||||
|
import com.example.quiz.data.model.ResponseError;
|
||||||
|
import com.example.quiz.data.model.Restriction;
|
||||||
|
import com.example.quiz.data.model.dtos.auth.User;
|
||||||
|
import com.example.quiz.data.remote.ApiService;
|
||||||
|
import com.example.quiz.utils.Result;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
public class AgentRepository {
|
||||||
|
private ApiService apiService;
|
||||||
|
@Inject
|
||||||
|
public AgentRepository(ApiService apiService) {
|
||||||
|
this.apiService = apiService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<List<User>>> getAgents(String agentId) {
|
||||||
|
MutableLiveData<Result<List<User>>> liveAgents = new MutableLiveData<>();
|
||||||
|
liveAgents.setValue(Result.loading());
|
||||||
|
apiService.getAgentsByMaster(agentId).enqueue(new Callback<List<User>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull Call<List<User>> call, @NonNull Response<List<User>> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
liveAgents.postValue(Result.success(response.body()));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
liveAgents.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NonNull Call<List<User>> call, @NonNull Throwable throwable) {
|
||||||
|
liveAgents.postValue(Result.error(throwable.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return liveAgents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<User>> getAgentById(String agentId) {
|
||||||
|
MutableLiveData<Result<User>> liveAgent = new MutableLiveData<>();
|
||||||
|
liveAgent.setValue(Result.loading());
|
||||||
|
apiService.getAgent(agentId).enqueue(new Callback<User>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull Call<User> call, @NonNull Response<User> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
liveAgent.postValue(Result.success(response.body()));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
liveAgent.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NonNull Call<User> call, @NonNull Throwable throwable) {
|
||||||
|
liveAgent.postValue(Result.error(throwable.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return liveAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<List<Course.TypeParis>>> getAvailableBets(String agentId) {
|
||||||
|
MutableLiveData<Result<List<Course.TypeParis>>> liveAvailableBets = new MutableLiveData<>();
|
||||||
|
liveAvailableBets.setValue(Result.loading());
|
||||||
|
apiService.getAvailableBets(agentId).enqueue(new Callback<List<Course.TypeParis>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull Call<List<Course.TypeParis>> call, @NonNull Response<List<Course.TypeParis>> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
liveAvailableBets.postValue(Result.success(response.body()));
|
||||||
|
} else {
|
||||||
|
try{
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
liveAvailableBets.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
}catch (Exception e){
|
||||||
|
liveAvailableBets.postValue(Result.error(e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NonNull Call<List<Course.TypeParis>> call, @NonNull Throwable throwable) {
|
||||||
|
liveAvailableBets.postValue(Result.error(throwable.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return liveAvailableBets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<Void>> setAccess(String masterId, String slaveId, boolean access) {
|
||||||
|
MutableLiveData<Result<Void>> liveSetAccess = new MutableLiveData<>();
|
||||||
|
liveSetAccess.setValue(Result.loading());
|
||||||
|
apiService.setAccess(masterId, slaveId, access).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull Call<Void> call, @NonNull Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
liveSetAccess.postValue(Result.success(null));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
liveSetAccess.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable throwable) {
|
||||||
|
liveSetAccess.postValue(Result.error(throwable.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return liveSetAccess;
|
||||||
|
};
|
||||||
|
|
||||||
|
public LiveData<Result<Void>> setRestrictions(String masterId, String slaveId, Restriction restrictions) {
|
||||||
|
MutableLiveData<Result<Void>> liveSetRestrictions = new MutableLiveData<>();
|
||||||
|
liveSetRestrictions.setValue(Result.loading());
|
||||||
|
apiService.setRestrictions(masterId, slaveId, restrictions).enqueue(new Callback<Void>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(@NonNull Call<Void> call, @NonNull Response<Void> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
liveSetRestrictions.postValue(Result.success(null));
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
liveSetRestrictions.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable throwable) {
|
||||||
|
liveSetRestrictions.postValue(Result.error(throwable.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return liveSetRestrictions;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,10 +7,10 @@ import androidx.lifecycle.MutableLiveData;
|
|||||||
|
|
||||||
import com.example.quiz.data.model.Course;
|
import com.example.quiz.data.model.Course;
|
||||||
import com.example.quiz.data.model.PagedModel;
|
import com.example.quiz.data.model.PagedModel;
|
||||||
|
import com.example.quiz.data.model.ResponseError;
|
||||||
import com.example.quiz.data.remote.ApiService;
|
import com.example.quiz.data.remote.ApiService;
|
||||||
import com.example.quiz.utils.Result;
|
import com.example.quiz.utils.Result;
|
||||||
|
import com.google.gson.Gson;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -20,6 +20,7 @@ import retrofit2.Response;
|
|||||||
|
|
||||||
public class CourseRepository {
|
public class CourseRepository {
|
||||||
private ApiService apiService;
|
private ApiService apiService;
|
||||||
|
private final Course.Statut OPENED_STATUT = Course.Statut.OUVERT;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CourseRepository(ApiService apiService) {
|
public CourseRepository(ApiService apiService) {
|
||||||
@@ -29,13 +30,20 @@ public class CourseRepository {
|
|||||||
public LiveData<Result<PagedModel<Course>>> getCourses(String reunionDate) {
|
public LiveData<Result<PagedModel<Course>>> getCourses(String reunionDate) {
|
||||||
MutableLiveData<Result<PagedModel<Course>>> liveCourses = new MutableLiveData<Result<PagedModel<Course>>>();
|
MutableLiveData<Result<PagedModel<Course>>> liveCourses = new MutableLiveData<Result<PagedModel<Course>>>();
|
||||||
liveCourses.setValue(Result.loading());
|
liveCourses.setValue(Result.loading());
|
||||||
apiService.getCourses(reunionDate).enqueue(new Callback<PagedModel<Course>>() {
|
apiService.getCourses(reunionDate,String.valueOf(OPENED_STATUT)).enqueue(new Callback<PagedModel<Course>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<PagedModel<Course>> call, Response<PagedModel<Course>> response) {
|
public void onResponse(Call<PagedModel<Course>> call, Response<PagedModel<Course>> response) {
|
||||||
if(response.isSuccessful()){
|
if(response.isSuccessful()){
|
||||||
liveCourses.postValue(Result.success(response.body()));
|
liveCourses.postValue(Result.success(response.body()));
|
||||||
}else{
|
}else{
|
||||||
liveCourses.postValue(Result.error(response.message()));
|
try{
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
liveCourses.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,17 @@ import android.util.Log;
|
|||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.quiz.data.model.ResponseError;
|
||||||
|
import com.example.quiz.data.model.dtos.auth.ChangePin;
|
||||||
import com.example.quiz.data.model.dtos.auth.LoginPayload;
|
import com.example.quiz.data.model.dtos.auth.LoginPayload;
|
||||||
import com.example.quiz.data.model.dtos.auth.LoginResponse;
|
import com.example.quiz.data.model.dtos.auth.LoginResponse;
|
||||||
|
import com.example.quiz.data.model.dtos.auth.User;
|
||||||
import com.example.quiz.data.remote.ApiService;
|
import com.example.quiz.data.remote.ApiService;
|
||||||
import com.example.quiz.data.remote.TokenManager;
|
import com.example.quiz.data.remote.TokenManager;
|
||||||
import com.example.quiz.utils.Result;
|
import com.example.quiz.utils.Result;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -20,6 +26,7 @@ import retrofit2.Response;
|
|||||||
public class LoginRepository {
|
public class LoginRepository {
|
||||||
private ApiService apiService;
|
private ApiService apiService;
|
||||||
private TokenManager tokenManager;
|
private TokenManager tokenManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public LoginRepository(ApiService apiService, TokenManager tokenManager) {
|
public LoginRepository(ApiService apiService, TokenManager tokenManager) {
|
||||||
this.tokenManager = tokenManager;
|
this.tokenManager = tokenManager;
|
||||||
@@ -34,18 +41,54 @@ public class LoginRepository {
|
|||||||
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
|
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
|
||||||
if(response.isSuccessful()){
|
if(response.isSuccessful()){
|
||||||
liveLogin.postValue(Result.success(response.body()));
|
liveLogin.postValue(Result.success(response.body()));
|
||||||
Log.d("TOKEN", response.body().getToken());
|
|
||||||
tokenManager.saveToken(response.body().getToken());
|
tokenManager.saveToken(response.body().getToken());
|
||||||
}else{
|
}else{
|
||||||
liveLogin.postValue(Result.error(response.message()));
|
try {
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
liveLogin.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call<LoginResponse> call, Throwable throwable) {
|
public void onFailure(Call<LoginResponse> call, Throwable throwable) {
|
||||||
liveLogin.postValue(Result.error(throwable.getMessage()));
|
liveLogin.postValue(Result.error(throwable.toString()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return liveLogin;
|
return liveLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<User>> changePin(String oldPin, String newPin){
|
||||||
|
MutableLiveData<Result<User>> liveUser = new MutableLiveData<Result<User>>();
|
||||||
|
liveUser.setValue(Result.loading());
|
||||||
|
ChangePin changePin = new ChangePin();
|
||||||
|
changePin.setOldPin(oldPin);
|
||||||
|
changePin.setNewPin(newPin);
|
||||||
|
apiService.changePin(changePin).enqueue(new Callback<User>(){
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<User> call, Response<User> response) {
|
||||||
|
if(response.isSuccessful()) {
|
||||||
|
liveUser.postValue(Result.success(response.body()));
|
||||||
|
}else {
|
||||||
|
try {
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
liveUser.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<User> call, Throwable throwable) {
|
||||||
|
liveUser.postValue(Result.error(throwable.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return liveUser;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package com.example.quiz.data.repository;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.quiz.data.model.MiseInitiale;
|
||||||
|
import com.example.quiz.data.model.PariMise;
|
||||||
|
import com.example.quiz.data.model.ResponseError;
|
||||||
|
import com.example.quiz.data.remote.ApiService;
|
||||||
|
import com.example.quiz.data.remote.TokenManager;
|
||||||
|
import com.example.quiz.utils.Result;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import retrofit2.Call;
|
||||||
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
|
public class PariMiseRepository {
|
||||||
|
private ApiService apiService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public PariMiseRepository(ApiService apiService, TokenManager tokenManager) {
|
||||||
|
this.apiService = apiService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<List<MiseInitiale>>> getBetInitMise() {
|
||||||
|
MutableLiveData<Result<List<MiseInitiale>>> livePariMise = new MutableLiveData<Result<List<MiseInitiale>>>();
|
||||||
|
livePariMise.setValue(Result.loading());
|
||||||
|
apiService.getBetInitMise().enqueue(new Callback<List<MiseInitiale>>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<List<MiseInitiale>> call, Response<List<MiseInitiale>> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
livePariMise.postValue(Result.success(response.body()));
|
||||||
|
}else{
|
||||||
|
try{
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
livePariMise.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<List<MiseInitiale>> call, Throwable throwable) {
|
||||||
|
livePariMise.postValue(Result.error(throwable.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return livePariMise;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,8 +8,12 @@ import androidx.lifecycle.MutableLiveData;
|
|||||||
|
|
||||||
import com.example.quiz.data.model.Pari;
|
import com.example.quiz.data.model.Pari;
|
||||||
import com.example.quiz.data.model.ParisResponse;
|
import com.example.quiz.data.model.ParisResponse;
|
||||||
|
import com.example.quiz.data.model.ResponseError;
|
||||||
|
import com.example.quiz.data.model.dtos.paris.CancelParisPaylaod;
|
||||||
|
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
|
||||||
import com.example.quiz.data.remote.ApiService;
|
import com.example.quiz.data.remote.ApiService;
|
||||||
import com.example.quiz.utils.Result;
|
import com.example.quiz.utils.Result;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -42,13 +46,10 @@ public class PariRepository {
|
|||||||
} else {
|
} else {
|
||||||
// On récupère l'erreur exacte envoyée par le backend
|
// On récupère l'erreur exacte envoyée par le backend
|
||||||
try {
|
try {
|
||||||
Map<String, String> errorBody = Collections.emptyMap();
|
String error = response.errorBody().string();
|
||||||
if(response.errorBody() != null){
|
Gson gson = new Gson();
|
||||||
errorBody = (Map<String, String>) response.errorBody();
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
}
|
pariResponse.postValue(Result.error(errorResponse.getMessage()));
|
||||||
Log.d("PariRepository", response.errorBody().toString());
|
|
||||||
pariResponse.postValue(Result.error(errorBody.get("message")));
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
pariResponse.postValue(Result.error("Erreur serveur"));
|
pariResponse.postValue(Result.error("Erreur serveur"));
|
||||||
}
|
}
|
||||||
@@ -74,10 +75,10 @@ public class PariRepository {
|
|||||||
derniersParis.postValue(Result.success(response.body()));
|
derniersParis.postValue(Result.success(response.body()));
|
||||||
}else{
|
}else{
|
||||||
try{
|
try{
|
||||||
String errorBody = response.errorBody() != null ?
|
String error = response.errorBody().string();
|
||||||
response.errorBody().string() : "Erreur inconnue";
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
derniersParis.postValue(Result.error(errorBody));
|
derniersParis.postValue(Result.error(errorResponse.getMessage()));
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
derniersParis.postValue(Result.error(e.getMessage()));
|
derniersParis.postValue(Result.error(e.getMessage()));
|
||||||
}
|
}
|
||||||
@@ -93,6 +94,60 @@ public class PariRepository {
|
|||||||
return derniersParis;
|
return derniersParis;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<ParisResponse>> payTicket(String numeroTicket){
|
||||||
|
MutableLiveData<Result<ParisResponse>> pariResponse = new MutableLiveData<>();
|
||||||
|
pariResponse.setValue(Result.loading());
|
||||||
|
apiService.payerPari(numeroTicket).enqueue(new Callback<ParisResponse>(){
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ParisResponse> call, Response<ParisResponse> response) {
|
||||||
|
if(response.isSuccessful()){
|
||||||
|
pariResponse.postValue(Result.success(response.body()));
|
||||||
|
}else{
|
||||||
|
try{
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
pariResponse.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
}catch (Exception e){
|
||||||
|
pariResponse.postValue(Result.error(e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ParisResponse> call, Throwable throwable) {
|
||||||
|
pariResponse.postValue(Result.error(throwable.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return pariResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<ParisResponse>> rembourserTicket(String numeroTicket){
|
||||||
|
MutableLiveData<Result<ParisResponse>> pariResponse = new MutableLiveData<>();
|
||||||
|
pariResponse.setValue(Result.loading());
|
||||||
|
apiService.rembourserPari(numeroTicket).enqueue(new Callback<ParisResponse>(){
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ParisResponse> call, Response<ParisResponse> response) {
|
||||||
|
if(response.isSuccessful()){
|
||||||
|
pariResponse.postValue(Result.success(response.body()));
|
||||||
|
}else{
|
||||||
|
try{
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
pariResponse.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
}catch (Exception e){
|
||||||
|
pariResponse.postValue(Result.error(e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ParisResponse> call, Throwable throwable) {
|
||||||
|
pariResponse.postValue(Result.error(throwable.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return pariResponse;
|
||||||
|
}
|
||||||
|
|
||||||
public LiveData<Result<ParisResponse>> annulerPari(String numeroTicket){
|
public LiveData<Result<ParisResponse>> annulerPari(String numeroTicket){
|
||||||
MutableLiveData<Result<ParisResponse>> pariResponse = new MutableLiveData<>();
|
MutableLiveData<Result<ParisResponse>> pariResponse = new MutableLiveData<>();
|
||||||
pariResponse.setValue(Result.loading());
|
pariResponse.setValue(Result.loading());
|
||||||
@@ -103,10 +158,10 @@ public class PariRepository {
|
|||||||
pariResponse.postValue(Result.success(response.body()));
|
pariResponse.postValue(Result.success(response.body()));
|
||||||
}else{
|
}else{
|
||||||
try{
|
try{
|
||||||
String errorBody = response.errorBody() != null ?
|
String error = response.errorBody().string();
|
||||||
response.errorBody().string() : "Erreur inconnue";
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
pariResponse.postValue(Result.error(errorBody));
|
pariResponse.postValue(Result.error(errorResponse.getMessage()));
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
pariResponse.postValue(Result.error(e.getMessage()));
|
pariResponse.postValue(Result.error(e.getMessage()));
|
||||||
}
|
}
|
||||||
@@ -121,17 +176,20 @@ public class PariRepository {
|
|||||||
return pariResponse;
|
return pariResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<Result<Double>> getSoldeByCourse(String agentId, String courseId){
|
public LiveData<Result<SoldeResponse>> getSoldeByCourse(String agentId, String courseId){
|
||||||
MutableLiveData<Result<Double>> solde = new MutableLiveData<>();
|
MutableLiveData<Result<SoldeResponse>> solde = new MutableLiveData<>();
|
||||||
solde.setValue(Result.loading());
|
solde.setValue(Result.loading());
|
||||||
apiService.getSoldeByCourse(agentId, courseId).enqueue(new Callback<Double>() {
|
apiService.getSoldeByCourse(agentId, courseId).enqueue(new Callback<SoldeResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<Double> call, Response<Double> response) {
|
public void onResponse(Call<SoldeResponse> call, Response<SoldeResponse> response) {
|
||||||
if(response.isSuccessful()){
|
if(response.isSuccessful()){
|
||||||
solde.postValue(Result.success(response.body()));
|
solde.postValue(Result.success(response.body()));
|
||||||
}else{
|
}else{
|
||||||
try{
|
try{
|
||||||
solde.postValue(Result.error(response.errorBody().string()));
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
solde.postValue(Result.error(errorResponse.getMessage()));
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
solde.postValue(Result.error(e.getMessage()));
|
solde.postValue(Result.error(e.getMessage()));
|
||||||
}
|
}
|
||||||
@@ -139,24 +197,27 @@ public class PariRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call<Double> call, Throwable throwable) {
|
public void onFailure(Call<SoldeResponse> call, Throwable throwable) {
|
||||||
solde.postValue(Result.error(throwable.getMessage()));
|
solde.postValue(Result.error(throwable.getMessage()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return solde;
|
return solde;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<Result<Double>> getSoldeByDay(String agentId, String day){
|
public LiveData<Result<SoldeResponse>> getSoldeByDay(String agentId, String day){
|
||||||
MutableLiveData<Result<Double>> solde = new MutableLiveData<>();
|
MutableLiveData<Result<SoldeResponse>> solde = new MutableLiveData<>();
|
||||||
solde.setValue(Result.loading());
|
solde.setValue(Result.loading());
|
||||||
apiService.getSoldeByDay(agentId, day).enqueue(new Callback<Double>() {
|
apiService.getSoldeByDay(agentId, day).enqueue(new Callback<SoldeResponse>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<Double> call, Response<Double> response) {
|
public void onResponse(Call<SoldeResponse> call, Response<SoldeResponse> response) {
|
||||||
if(response.isSuccessful()){
|
if(response.isSuccessful()){
|
||||||
solde.postValue(Result.success(response.body()));
|
solde.postValue(Result.success(response.body()));
|
||||||
}else{
|
}else{
|
||||||
try {
|
try {
|
||||||
solde.postValue(Result.error(response.errorBody().string()));
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
solde.postValue(Result.error(errorResponse.getMessage()));
|
||||||
}catch (Exception e){
|
}catch (Exception e){
|
||||||
solde.postValue(Result.error(e.getMessage()));
|
solde.postValue(Result.error(e.getMessage()));
|
||||||
}
|
}
|
||||||
@@ -164,11 +225,39 @@ public class PariRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onFailure(Call<Double> call, Throwable throwable) {
|
public void onFailure(Call<SoldeResponse> call, Throwable throwable) {
|
||||||
solde.postValue(Result.error(throwable.getMessage()));
|
solde.postValue(Result.error(throwable.getMessage()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return solde;
|
return solde;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<ParisResponse>> getPariByNumero(String numeroTicket) {
|
||||||
|
MutableLiveData<Result<ParisResponse>> pari = new MutableLiveData<>();
|
||||||
|
pari.setValue(Result.loading());
|
||||||
|
apiService.getPariByNumero(numeroTicket).enqueue(new Callback<ParisResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<ParisResponse> call, Response<ParisResponse> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
pari.postValue(Result.success(response.body()));
|
||||||
|
}else{
|
||||||
|
try {
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
pari.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
}catch (Exception e){
|
||||||
|
pari.postValue(Result.error(e.getMessage()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<ParisResponse> call, Throwable throwable) {
|
||||||
|
pari.postValue(Result.error(throwable.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return pari;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,14 @@ import androidx.lifecycle.MutableLiveData;
|
|||||||
|
|
||||||
import com.example.quiz.data.model.PagedModel;
|
import com.example.quiz.data.model.PagedModel;
|
||||||
import com.example.quiz.data.model.PointDeVente;
|
import com.example.quiz.data.model.PointDeVente;
|
||||||
|
import com.example.quiz.data.model.ResponseError;
|
||||||
import com.example.quiz.data.remote.ApiService;
|
import com.example.quiz.data.remote.ApiService;
|
||||||
import com.example.quiz.utils.Result;
|
import com.example.quiz.utils.Result;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import retrofit2.*;
|
import retrofit2.*;
|
||||||
@@ -36,18 +40,14 @@ public class PointDeVenteRepository {
|
|||||||
if (response.isSuccessful() && response.body() != null) {
|
if (response.isSuccessful() && response.body() != null) {
|
||||||
result.postValue(Result.success(response.body()));
|
result.postValue(Result.success(response.body()));
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
String errorMessage = "Erreur inconnue";
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (response.errorBody() != null) {
|
String error = response.errorBody().string();
|
||||||
errorMessage = response.errorBody().string();
|
Gson gson = new Gson();
|
||||||
}
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
} catch (Exception e) {
|
result.postValue(Result.error(errorResponse.getMessage()));
|
||||||
errorMessage = e.getMessage();
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
result.postValue(Result.error(errorMessage));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,4 +62,33 @@ public class PointDeVenteRepository {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public LiveData<Result<PointDeVente>> getPointDeVenteById(String id) {
|
||||||
|
MutableLiveData<Result<PointDeVente>> result = new MutableLiveData<>();
|
||||||
|
result.setValue(Result.loading());
|
||||||
|
apiService.getPointDeVenteById(id).enqueue(new Callback<PointDeVente>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<PointDeVente> call, Response<PointDeVente> response) {
|
||||||
|
if(response.isSuccessful()){
|
||||||
|
result.postValue(Result.success(response.body()));
|
||||||
|
}else{
|
||||||
|
try {
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
result.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<PointDeVente> call, Throwable throwable) {
|
||||||
|
result.postValue(Result.error(throwable.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ package com.example.quiz.data.repository;
|
|||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
|
import com.example.quiz.data.model.ResponseError;
|
||||||
import com.example.quiz.data.model.Tpe;
|
import com.example.quiz.data.model.Tpe;
|
||||||
import com.example.quiz.data.model.TpeResponse;
|
import com.example.quiz.data.model.TpeResponse;
|
||||||
import com.example.quiz.data.remote.ApiService;
|
import com.example.quiz.data.remote.ApiService;
|
||||||
import com.example.quiz.utils.Result;
|
import com.example.quiz.utils.Result;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@@ -33,7 +35,43 @@ public class TpeRepository {
|
|||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
tpeLiveData.postValue(Result.success(response.body()));
|
tpeLiveData.postValue(Result.success(response.body()));
|
||||||
} else {
|
} else {
|
||||||
tpeLiveData.postValue(Result.error(response.message()));
|
try{
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
tpeLiveData.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFailure(Call<TpeResponse> call, Throwable throwable) {
|
||||||
|
tpeLiveData.postValue(Result.error(throwable.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return tpeLiveData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public LiveData<Result<TpeResponse>> getTpeById(String id) {
|
||||||
|
MutableLiveData<Result<TpeResponse>> tpeLiveData = new MutableLiveData<>();
|
||||||
|
tpeLiveData.setValue(Result.loading());
|
||||||
|
apiService.getTpeById(id).enqueue(new Callback<TpeResponse>() {
|
||||||
|
@Override
|
||||||
|
public void onResponse(Call<TpeResponse> call, Response<TpeResponse> response) {
|
||||||
|
if (response.isSuccessful()) {
|
||||||
|
tpeLiveData.postValue(Result.success(response.body()));
|
||||||
|
} else {
|
||||||
|
try{
|
||||||
|
String error = response.errorBody().string();
|
||||||
|
Gson gson = new Gson();
|
||||||
|
ResponseError errorResponse = gson.fromJson(error, ResponseError.class);
|
||||||
|
tpeLiveData.postValue(Result.error(errorResponse.getMessage()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,21 +28,24 @@ public class AuthNavigator {
|
|||||||
|
|
||||||
private FragmentManager fragmentManager;
|
private FragmentManager fragmentManager;
|
||||||
|
|
||||||
private TokenManager tokenManager;
|
|
||||||
private final SessionManager sessionManager;
|
private final SessionManager sessionManager;
|
||||||
LoginViewModel viewModel;
|
private LoginViewModel viewModel;
|
||||||
LogsViewModel logsViewModel;
|
private LogsViewModel logsViewModel;
|
||||||
|
private LifecycleOwner lifecycleOwner;
|
||||||
|
|
||||||
|
|
||||||
private Dialog dialog;
|
private Dialog dialog;
|
||||||
|
|
||||||
SharedPrefsHelper prefsHelper;
|
SharedPrefsHelper prefsHelper;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public AuthNavigator(Context context,
|
public AuthNavigator(Context context,
|
||||||
FragmentManager fragmentManager,
|
FragmentManager fragmentManager,
|
||||||
SessionManager sessionManager,
|
SessionManager sessionManager,
|
||||||
LoginViewModel viewModel,
|
LoginViewModel viewModel,
|
||||||
LogsViewModel logsViewModel) {
|
LogsViewModel logsViewModel,
|
||||||
|
LifecycleOwner lifecycleOwner) {
|
||||||
this.viewModel = viewModel;
|
this.viewModel = viewModel;
|
||||||
this.logsViewModel = logsViewModel;
|
this.logsViewModel = logsViewModel;
|
||||||
this.prefsHelper = SharedPrefsHelper.getInstance(context);
|
this.prefsHelper = SharedPrefsHelper.getInstance(context);
|
||||||
@@ -50,6 +53,7 @@ public class AuthNavigator {
|
|||||||
this.context = context;
|
this.context = context;
|
||||||
dialog = new Dialog(context);
|
dialog = new Dialog(context);
|
||||||
this.sessionManager = sessionManager;
|
this.sessionManager = sessionManager;
|
||||||
|
this.lifecycleOwner = lifecycleOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void navigate(Fragment destinationFragment) {
|
public void navigate(Fragment destinationFragment) {
|
||||||
@@ -57,14 +61,15 @@ public class AuthNavigator {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (sessionManager.isExpired()) {
|
if (sessionManager.isExpired()) {
|
||||||
showPinDialog(() -> {
|
if(!dialogIsShowing()){
|
||||||
sessionManager.updateLastExpiredDate();
|
showPinDialog(() -> {
|
||||||
fragmentManager.beginTransaction()
|
sessionManager.updateLastExpiredDate();
|
||||||
.replace(R.id.nav_host_fragment_content_main, destinationFragment)
|
fragmentManager.beginTransaction()
|
||||||
.addToBackStack(null)
|
.replace(R.id.nav_host_fragment_content_main, destinationFragment)
|
||||||
.commit();
|
.addToBackStack(null)
|
||||||
});
|
.commit();
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
fragmentManager.beginTransaction()
|
fragmentManager.beginTransaction()
|
||||||
.replace(R.id.nav_host_fragment_content_main, destinationFragment)
|
.replace(R.id.nav_host_fragment_content_main, destinationFragment)
|
||||||
@@ -98,12 +103,15 @@ public class AuthNavigator {
|
|||||||
pin.setError("Le pin doit contenir minimum quatre chiffres!");
|
pin.setError("Le pin doit contenir minimum quatre chiffres!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(prefsHelper.get("terminalId") == null){
|
||||||
|
MessageDialog.showError(context, "Terminal non trouvé");
|
||||||
|
}
|
||||||
LoginPayload loginPayload = new LoginPayload(
|
LoginPayload loginPayload = new LoginPayload(
|
||||||
code.getText().toString(),
|
code.getText().toString(),
|
||||||
pin.getText().toString(),
|
pin.getText().toString(),
|
||||||
Long.valueOf(prefsHelper.get("terminalId"))
|
Long.valueOf(prefsHelper.get("terminalId"))
|
||||||
);
|
);
|
||||||
viewModel.login(loginPayload).observe((LifecycleOwner) context, new Observer<Result<LoginResponse>>() {
|
viewModel.login(loginPayload).observe(lifecycleOwner, new Observer<Result<LoginResponse>>() {
|
||||||
@Override
|
@Override
|
||||||
public void onChanged(Result<LoginResponse> loginResponseResult) {
|
public void onChanged(Result<LoginResponse> loginResponseResult) {
|
||||||
switch (loginResponseResult.status){
|
switch (loginResponseResult.status){
|
||||||
@@ -136,12 +144,38 @@ public class AuthNavigator {
|
|||||||
return dialog.isShowing();
|
return dialog.isShowing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSessionExpired(){
|
||||||
|
return sessionManager.isExpired();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void updatedLastExpiredDate(){
|
||||||
|
sessionManager.updateLastExpiredDate();
|
||||||
|
}
|
||||||
|
|
||||||
private void loginSuccess(LoginResponse loginResponse){
|
private void loginSuccess(LoginResponse loginResponse){
|
||||||
|
String terminalId = prefsHelper.get("terminalId");
|
||||||
|
if(terminalId == null){
|
||||||
|
MessageDialog.showError(context, "Terminal non trouvé");
|
||||||
|
return;
|
||||||
|
}
|
||||||
prefsHelper.save("id", String.valueOf(loginResponse.getUser().getId()));
|
prefsHelper.save("id", String.valueOf(loginResponse.getUser().getId()));
|
||||||
prefsHelper.save("firstName", loginResponse.getUser().getPrenom());
|
prefsHelper.save("firstName", loginResponse.getUser().getPrenom());
|
||||||
prefsHelper.save("lastName", loginResponse.getUser().getNom());
|
prefsHelper.save("lastName", loginResponse.getUser().getNom());
|
||||||
prefsHelper.save("profile", loginResponse.getUser().getFonction());
|
prefsHelper.save("profile", loginResponse.getUser().getFonction());
|
||||||
prefsHelper.save("code", loginResponse.getUser().getCode());
|
prefsHelper.save("code", loginResponse.getUser().getCode());
|
||||||
|
String isSupAgent = loginResponse.getUser().isSubAgent() ? "true" : "false";
|
||||||
|
prefsHelper.save("isSupAgent", isSupAgent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void logOut (){
|
||||||
|
prefsHelper.save("id", null);
|
||||||
|
prefsHelper.save("firstName", null);
|
||||||
|
prefsHelper.save("lastName", null);
|
||||||
|
prefsHelper.save("profile", null);
|
||||||
|
prefsHelper.save("code", null);
|
||||||
|
prefsHelper.save("isSupAgent", null);
|
||||||
|
sessionManager.setToExpire();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,10 @@ public class SessionManager {
|
|||||||
lastExpiredDate = LocalDateTime.now();
|
lastExpiredDate = LocalDateTime.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setToExpire(){
|
||||||
|
lastExpiredDate = null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isExpired() {
|
public boolean isExpired() {
|
||||||
if (lastExpiredDate == null) {
|
if (lastExpiredDate == null) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -0,0 +1,275 @@
|
|||||||
|
package com.example.quiz.utils;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.sunmi.peripheral.printer.InnerPrinterCallback;
|
||||||
|
import com.sunmi.peripheral.printer.InnerPrinterManager;
|
||||||
|
import com.sunmi.peripheral.printer.InnerResultCallback;
|
||||||
|
import com.sunmi.peripheral.printer.SunmiPrinterService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
public class SunmiPrinterManager {
|
||||||
|
|
||||||
|
private static final String TAG = "SunmiPrinterManager";
|
||||||
|
private static SunmiPrinterManager instance;
|
||||||
|
|
||||||
|
private static final int MAX_CHAR_2_INCH = 32;
|
||||||
|
private static Context context;
|
||||||
|
|
||||||
|
private SunmiPrinterService sunmiPrinter;
|
||||||
|
|
||||||
|
private SunmiPrinterManager() {}
|
||||||
|
|
||||||
|
public static SunmiPrinterManager getInstance(Context ctx) {
|
||||||
|
if (instance == null) {
|
||||||
|
instance = new SunmiPrinterManager();
|
||||||
|
context = ctx.getApplicationContext();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 🔌 Bind UNE SEULE FOIS
|
||||||
|
public void connectPrinter(Consumer<Boolean> status) {
|
||||||
|
Log.d("######", "Point d'entrée printer");
|
||||||
|
try {
|
||||||
|
InnerPrinterManager.getInstance().bindService(context, new InnerPrinterCallback() {
|
||||||
|
@Override
|
||||||
|
protected void onConnected(SunmiPrinterService service) {
|
||||||
|
Log.d("######", "Connecté printer");
|
||||||
|
sunmiPrinter = service;
|
||||||
|
status.accept(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDisconnected() {
|
||||||
|
Log.d("######", "Déconnecté printer");
|
||||||
|
sunmiPrinter = null;
|
||||||
|
status.accept(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "#################Erreur bindService"+String.valueOf(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ✅ simple check
|
||||||
|
|
||||||
|
// 🖨️ Impression robuste
|
||||||
|
public void printText(String text, PrinterListener listener) {
|
||||||
|
try {
|
||||||
|
sunmiPrinter.printText(text + "\n", new InnerResultCallback() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRunResult(boolean isSuccess) {
|
||||||
|
if(!isSuccess){
|
||||||
|
try {
|
||||||
|
throw new Exception("Impression", new Throwable("Erreur lors d'impression!"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReturnString(String result) {
|
||||||
|
// rarement utile
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRaiseException(int code, String msg) {
|
||||||
|
listener.onError(msg);
|
||||||
|
listener.onResult(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPrintResult(int code, String msg) {
|
||||||
|
listener.onResult(code);
|
||||||
|
listener.onError(msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (listener != null) {
|
||||||
|
listener.onError(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxChar(){
|
||||||
|
return MAX_CHAR_2_INCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean printPari(Bitmap logo, Bitmap barcode, String numeroTicket, String text){
|
||||||
|
try{
|
||||||
|
printSimpleImage(logo);
|
||||||
|
printTextSimple("\n"+separationText()+"\n");
|
||||||
|
printSimpleImage(barcode);
|
||||||
|
setAlignment(1, new PrinterListener() {
|
||||||
|
@Override
|
||||||
|
public void onResult(int code) {
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onError(String errorMessage) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
printTextSimple(numeroTicket);
|
||||||
|
printTextSimple("\n"+separationText()+"\n");
|
||||||
|
setAlignment(0, new PrinterListener() {
|
||||||
|
@Override
|
||||||
|
public void onResult(int code) {}
|
||||||
|
@Override
|
||||||
|
public void onError(String errorMessage) {}
|
||||||
|
});
|
||||||
|
printTextSimple(text);
|
||||||
|
printTextSimple("\n"+separationText()+"\n");
|
||||||
|
setAlignment(1, new PrinterListener() {
|
||||||
|
@Override
|
||||||
|
public void onResult(int code) {}
|
||||||
|
@Override
|
||||||
|
public void onError(String errorMessage) {}
|
||||||
|
});
|
||||||
|
printTextSimple("Powered by PMU-MALI");
|
||||||
|
printTextSimple("\n"+separationText()+"\n");
|
||||||
|
printTextSimple(" ");
|
||||||
|
printTextSimple(" ");
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String separationText(){
|
||||||
|
return "-".repeat(MAX_CHAR_2_INCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void printSimpleImage(Bitmap bitmap){
|
||||||
|
printImage(bitmap, new PrinterListener() {
|
||||||
|
@Override
|
||||||
|
public void onResult(int code) {
|
||||||
|
Log.d(TAG, "Print OK");
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onError(String errorMessage) {
|
||||||
|
Log.e(TAG, errorMessage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// version simple
|
||||||
|
public void printTextSimple(String text) {
|
||||||
|
printText(text, new PrinterListener() {
|
||||||
|
@Override
|
||||||
|
public void onResult(int code) {
|
||||||
|
Log.d(TAG, "Print OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(String errorMessage) {
|
||||||
|
Log.e(TAG, errorMessage);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dans SunmiPrinterManager.java
|
||||||
|
|
||||||
|
public void setAlignment(int alignment, PrinterListener listener) {
|
||||||
|
try {
|
||||||
|
// Appel au SDK Sunmi : 0=gauche, 1=centre, 2=droite
|
||||||
|
sunmiPrinter.setAlignment(alignment, new InnerResultCallback() {
|
||||||
|
@Override
|
||||||
|
public void onRunResult(boolean isSuccess) throws RemoteException {
|
||||||
|
if(!isSuccess){
|
||||||
|
try {
|
||||||
|
throw new Exception("Alignement", new Throwable("L'alignement n'a pas pu être défini"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReturnString(String result) throws RemoteException {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRaiseException(int code, String msg) throws RemoteException {
|
||||||
|
listener.onError(msg);
|
||||||
|
listener.onResult(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPrintResult(int code, String msg) throws RemoteException {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (listener != null) listener.onError(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printImage(Bitmap bitmap, PrinterListener listener){
|
||||||
|
try {
|
||||||
|
// La plupart des imprimantes Sunmi utilisent cette méthode
|
||||||
|
// Le paramètre '0' correspond généralement à l'alignement (0 = gauche)
|
||||||
|
sunmiPrinter.printBitmap(bitmap, new InnerResultCallback() {
|
||||||
|
@Override
|
||||||
|
public void onRunResult(boolean isSuccess) {
|
||||||
|
if(!isSuccess){
|
||||||
|
try {
|
||||||
|
throw new Exception("Impression", new Throwable("Erreur lors d'impression d'une image!"));
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReturnString(String result) {
|
||||||
|
// Pas utile
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRaiseException(int code, String msg) {
|
||||||
|
Log.e(TAG, "onRaiseException: "+String.valueOf(code));
|
||||||
|
listener.onResult(code);
|
||||||
|
listener.onError(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPrintResult(int code, String msg) {
|
||||||
|
Log.e(TAG, "onPrintResult: "+String.valueOf(code));
|
||||||
|
listener.onResult(code);
|
||||||
|
listener.onError(msg);
|
||||||
|
}
|
||||||
|
// N'oublie pas les autres callbacks vides (onRunResult, etc.)
|
||||||
|
});
|
||||||
|
} catch (Exception e) {
|
||||||
|
listener.onError(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public int printerStatus(){
|
||||||
|
try {
|
||||||
|
return sunmiPrinter.updatePrinterState();
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface PrinterListener {
|
||||||
|
void onResult(int code);
|
||||||
|
void onError(String errorMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.example.quiz.viewModel;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.quiz.data.model.Course;
|
||||||
|
import com.example.quiz.data.model.Restriction;
|
||||||
|
import com.example.quiz.data.model.dtos.auth.User;
|
||||||
|
import com.example.quiz.data.repository.AgentRepository;
|
||||||
|
import com.example.quiz.utils.Result;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class AgentViewModel extends ViewModel {
|
||||||
|
private final AgentRepository agentRepository;
|
||||||
|
|
||||||
|
private LiveData<Result<List<User>>> agents;
|
||||||
|
|
||||||
|
private LiveData<Result<User>> agentDetails;
|
||||||
|
|
||||||
|
private LiveData<Result<List<Course.TypeParis>>> availableBets;
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public AgentViewModel(AgentRepository agentRepository) {
|
||||||
|
this.agentRepository = agentRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<List<User>>> getAgents(String agentId) {
|
||||||
|
agents = agentRepository.getAgents(agentId);
|
||||||
|
return agents;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<User>> getAgentById(String agentId) {
|
||||||
|
agentDetails = agentRepository.getAgentById(agentId);
|
||||||
|
return agentDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<List<Course.TypeParis>>> getAvailableBets(String agentId) {
|
||||||
|
availableBets = agentRepository.getAvailableBets(agentId);
|
||||||
|
return availableBets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<Void>> setAccess(String masterId, String slaveId, boolean access) {
|
||||||
|
return agentRepository.setAccess(masterId, slaveId, access);
|
||||||
|
};
|
||||||
|
|
||||||
|
public LiveData<Result<Void>> setRestrictions(String masterId, String slaveId, Restriction restrictions) {
|
||||||
|
return agentRepository.setRestrictions(masterId, slaveId, restrictions);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
package com.example.quiz.viewModel;
|
package com.example.quiz.viewModel;
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.MutableLiveData;
|
||||||
import androidx.lifecycle.ViewModel;
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.quiz.data.model.dtos.auth.ChangePin;
|
||||||
import com.example.quiz.data.model.dtos.auth.LoginPayload;
|
import com.example.quiz.data.model.dtos.auth.LoginPayload;
|
||||||
import com.example.quiz.data.model.dtos.auth.LoginResponse;
|
import com.example.quiz.data.model.dtos.auth.LoginResponse;
|
||||||
|
import com.example.quiz.data.model.dtos.auth.User;
|
||||||
import com.example.quiz.data.repository.LoginRepository;
|
import com.example.quiz.data.repository.LoginRepository;
|
||||||
import com.example.quiz.utils.Result;
|
import com.example.quiz.utils.Result;
|
||||||
|
|
||||||
@@ -16,6 +19,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel;
|
|||||||
public class LoginViewModel extends ViewModel {
|
public class LoginViewModel extends ViewModel {
|
||||||
LoginRepository loginRepository;
|
LoginRepository loginRepository;
|
||||||
|
|
||||||
|
LiveData<Result<User>> user = new MutableLiveData<>();
|
||||||
@Inject
|
@Inject
|
||||||
public LoginViewModel(LoginRepository loginRepository) {
|
public LoginViewModel(LoginRepository loginRepository) {
|
||||||
this.loginRepository = loginRepository;
|
this.loginRepository = loginRepository;
|
||||||
@@ -24,4 +28,9 @@ public class LoginViewModel extends ViewModel {
|
|||||||
public LiveData<Result<LoginResponse>> login(LoginPayload loginPayload){
|
public LiveData<Result<LoginResponse>> login(LoginPayload loginPayload){
|
||||||
return loginRepository.login(loginPayload);
|
return loginRepository.login(loginPayload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<User>> changePin(String oldPin, String newPin){
|
||||||
|
user = loginRepository.changePin(oldPin, newPin);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
package com.example.quiz.viewModel;
|
||||||
|
|
||||||
|
public class NotificationViewModel {
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package com.example.quiz.viewModel;
|
||||||
|
|
||||||
|
import androidx.lifecycle.LiveData;
|
||||||
|
import androidx.lifecycle.ViewModel;
|
||||||
|
|
||||||
|
import com.example.quiz.data.model.MiseInitiale;
|
||||||
|
import com.example.quiz.data.model.PariMise;
|
||||||
|
import com.example.quiz.data.repository.PariMiseRepository;
|
||||||
|
import com.example.quiz.utils.Result;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
public class PariMiseViewModel extends ViewModel {
|
||||||
|
|
||||||
|
private final PariMiseRepository pariMiseRepository;
|
||||||
|
|
||||||
|
private LiveData<Result<List<MiseInitiale>>> pariMise;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public PariMiseViewModel(PariMiseRepository pariMiseRepository) {
|
||||||
|
this.pariMiseRepository = pariMiseRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<List<MiseInitiale>>> getBetInitMise() {
|
||||||
|
this.pariMise = pariMiseRepository.getBetInitMise();
|
||||||
|
return this.pariMise;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModel;
|
|||||||
|
|
||||||
import com.example.quiz.data.model.Pari;
|
import com.example.quiz.data.model.Pari;
|
||||||
import com.example.quiz.data.model.ParisResponse;
|
import com.example.quiz.data.model.ParisResponse;
|
||||||
|
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
|
||||||
import com.example.quiz.data.repository.PariRepository;
|
import com.example.quiz.data.repository.PariRepository;
|
||||||
import com.example.quiz.utils.Result;
|
import com.example.quiz.utils.Result;
|
||||||
|
|
||||||
@@ -23,9 +24,16 @@ public class PariViewModel extends ViewModel {
|
|||||||
|
|
||||||
private LiveData<Result<ParisResponse>> pariAnnule;
|
private LiveData<Result<ParisResponse>> pariAnnule;
|
||||||
|
|
||||||
private LiveData<Result<Double>> solde;
|
private LiveData<Result<ParisResponse>> pariPaye;
|
||||||
|
|
||||||
private LiveData<Result<Double>> soldeByDay;
|
|
||||||
|
private LiveData<Result<ParisResponse>> pariByNumero;
|
||||||
|
|
||||||
|
private LiveData<Result<SoldeResponse>> solde;
|
||||||
|
|
||||||
|
private LiveData<Result<SoldeResponse>> soldeByDay;
|
||||||
|
|
||||||
|
private LiveData<Result<ParisResponse>> pariRembourse;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public PariViewModel(PariRepository repository){
|
public PariViewModel(PariRepository repository){
|
||||||
@@ -47,13 +55,28 @@ public class PariViewModel extends ViewModel {
|
|||||||
return pariAnnule;
|
return pariAnnule;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<Result<Double>> getSoldeByCourse(String agentId, String courseId){
|
public LiveData<Result<SoldeResponse>> getSoldeByCourse(String agentId, String courseId){
|
||||||
solde = pariRepository.getSoldeByCourse(agentId, courseId);
|
solde = pariRepository.getSoldeByCourse(agentId, courseId);
|
||||||
return solde;
|
return solde;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LiveData<Result<Double>> getSoldeByDay(String agentId, String day){
|
public LiveData<Result<SoldeResponse>> getSoldeByDay(String agentId, String day){
|
||||||
soldeByDay = pariRepository.getSoldeByDay(agentId, day);
|
soldeByDay = pariRepository.getSoldeByDay(agentId, day);
|
||||||
return soldeByDay;
|
return soldeByDay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<ParisResponse>> getPariByNumero(String numeroTicket){
|
||||||
|
pariByNumero = pariRepository.getPariByNumero(numeroTicket);
|
||||||
|
return pariByNumero;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<ParisResponse>> payerPari(String numeroTicket){
|
||||||
|
pariPaye = pariRepository.payTicket(numeroTicket);
|
||||||
|
return pariPaye;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<ParisResponse>> rembourserPari(String numeroTicket){
|
||||||
|
pariRembourse = pariRepository.rembourserTicket(numeroTicket);
|
||||||
|
return pariRembourse;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ public class PointDeVenteViewModel extends ViewModel {
|
|||||||
private final PointDeVenteRepository pointDeVenteRepository;
|
private final PointDeVenteRepository pointDeVenteRepository;
|
||||||
private LiveData<Result<PagedModel<PointDeVente>>> pointsDeVente;
|
private LiveData<Result<PagedModel<PointDeVente>>> pointsDeVente;
|
||||||
|
|
||||||
|
private LiveData<Result<PointDeVente>> pointDeVenteById;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public PointDeVenteViewModel(PointDeVenteRepository pointDeVenteRepository){
|
public PointDeVenteViewModel(PointDeVenteRepository pointDeVenteRepository){
|
||||||
this.pointDeVenteRepository = pointDeVenteRepository;
|
this.pointDeVenteRepository = pointDeVenteRepository;
|
||||||
@@ -26,4 +28,9 @@ public class PointDeVenteViewModel extends ViewModel {
|
|||||||
this.pointsDeVente = pointDeVenteRepository.getPointsDeVente(search);
|
this.pointsDeVente = pointDeVenteRepository.getPointsDeVente(search);
|
||||||
return this.pointsDeVente;
|
return this.pointsDeVente;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<PointDeVente>> getPointDeVenteById(String id) {
|
||||||
|
pointDeVenteById = pointDeVenteRepository.getPointDeVenteById(id);
|
||||||
|
return pointDeVenteById;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ public class TpeViewModel extends ViewModel {
|
|||||||
|
|
||||||
private LiveData<Result<TpeResponse>> tpeLiveData;
|
private LiveData<Result<TpeResponse>> tpeLiveData;
|
||||||
|
|
||||||
|
private LiveData<Result<TpeResponse>> tpeByIdLiveData;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TpeViewModel(TpeRepository repository){
|
public TpeViewModel(TpeRepository repository){
|
||||||
this.tpeRepository = repository;
|
this.tpeRepository = repository;
|
||||||
@@ -27,4 +29,9 @@ public class TpeViewModel extends ViewModel {
|
|||||||
tpeLiveData = tpeRepository.createTpe(tpe);
|
tpeLiveData = tpeRepository.createTpe(tpe);
|
||||||
return tpeLiveData;
|
return tpeLiveData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public LiveData<Result<TpeResponse>> getTpeById(String id){
|
||||||
|
tpeByIdLiveData = tpeRepository.getTpeById(id);
|
||||||
|
return tpeByIdLiveData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
app/src/main/res/drawable/agent_item_border_rounded.xml
Normal file
8
app/src/main/res/drawable/agent_item_border_rounded.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<solid android:color="@color/transparent" />
|
||||||
|
<corners android:radius="12dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="#E2E8F0" />
|
||||||
|
</shape>
|
||||||
8
app/src/main/res/drawable/circle_bg_light.xml
Normal file
8
app/src/main/res/drawable/circle_bg_light.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="#F0F0F0" />
|
||||||
|
<size
|
||||||
|
android:width="48dp"
|
||||||
|
android:height="48dp" />
|
||||||
|
</shape>
|
||||||
8
app/src/main/res/drawable/decorative_dot.xml
Normal file
8
app/src/main/res/drawable/decorative_dot.xml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="oval">
|
||||||
|
<solid android:color="@color/primary_green" />
|
||||||
|
<size
|
||||||
|
android:width="6dp"
|
||||||
|
android:height="6dp" />
|
||||||
|
</shape>
|
||||||
10
app/src/main/res/drawable/ic_bet.xml
Normal file
10
app/src/main/res/drawable/ic_bet.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM12,7c-2.76,0 -5,2.24 -5,5s2.24,5 5,5 5,-2.24 5,-5 -2.24,-5 -5,-5z" />
|
||||||
|
</vector>
|
||||||
13
app/src/main/res/drawable/ic_check.xml
Normal file
13
app/src/main/res/drawable/ic_check.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="20dp"
|
||||||
|
android:height="20dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M4,12.611L8.923,17.5L20,6.5"
|
||||||
|
android:strokeLineJoin="round"
|
||||||
|
android:strokeWidth="2"
|
||||||
|
android:fillColor="#00000000"
|
||||||
|
android:strokeColor="#000000"
|
||||||
|
android:strokeLineCap="round"/>
|
||||||
|
</vector>
|
||||||
10
app/src/main/res/drawable/ic_location_small.xml
Normal file
10
app/src/main/res/drawable/ic_location_small.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="16dp"
|
||||||
|
android:height="16dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#9CA3AF"
|
||||||
|
android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z" />
|
||||||
|
</vector>
|
||||||
12
app/src/main/res/drawable/ic_notification.xml
Normal file
12
app/src/main/res/drawable/ic_notification.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="300dp"
|
||||||
|
android:height="300dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:pathData="M14.958,19.003C14.72,20.421 13.486,21.501 12,21.501C10.576,21.501 9.384,20.509 9.077,19.178L9.042,19.003L14.958,19.003ZM12,2.004C16.142,2.004 19.5,5.362 19.5,9.504L19.5,13.502L20.918,16.662C20.973,16.785 21.002,16.917 21.002,17.051C21.002,17.576 20.576,18.001 20.052,18.001L3.952,18.001C3.818,18.001 3.686,17.973 3.564,17.919C3.085,17.704 2.871,17.142 3.085,16.663L4.5,13.503L4.5,9.491L4.505,9.241C4.644,5.21 7.956,2.004 12,2.004ZM10.5,9.5L8.5,9.5L8.398,9.507C8.032,9.557 7.75,9.87 7.75,10.25C7.75,10.63 8.032,10.943 8.398,10.993L8.5,11L9.208,11L7.849,13.378L7.803,13.473C7.622,13.921 7.916,14.427 8.395,14.493L8.5,14.5L10.5,14.5L10.602,14.493C10.968,14.443 11.25,14.13 11.25,13.75C11.25,13.37 10.968,13.057 10.602,13.007L10.5,13L9.792,13L11.151,10.622L11.197,10.527C11.378,10.079 11.084,9.573 10.605,9.507L10.5,9.5ZM15,6.5L12.5,6.5L12.398,6.507C12.032,6.557 11.75,6.87 11.75,7.25C11.75,7.63 12.032,7.943 12.398,7.993L12.5,8L13.725,8L11.844,11.386L11.8,11.481C11.625,11.928 11.919,12.428 12.395,12.493L12.5,12.5L15,12.5L15.102,12.493C15.468,12.443 15.75,12.13 15.75,11.75C15.75,11.37 15.468,11.057 15.102,11.007L15,11L13.775,11L15.656,7.614L15.7,7.519C15.875,7.072 15.581,6.572 15.105,6.507L15,6.5Z"
|
||||||
|
android:strokeWidth="1"
|
||||||
|
android:fillColor="#212121"
|
||||||
|
android:fillType="nonZero"
|
||||||
|
android:strokeColor="#0b9602"/>
|
||||||
|
</vector>
|
||||||
276
app/src/main/res/drawable/logo_svg.xml
Normal file
276
app/src/main/res/drawable/logo_svg.xml
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="150dp"
|
||||||
|
android:height="150dp"
|
||||||
|
android:viewportWidth="225"
|
||||||
|
android:viewportHeight="225">
|
||||||
|
<path
|
||||||
|
android:pathData="M162,76C169.1,75.16 173.27,76.11 178.98,80.43C179.73,81.03 180.48,81.63 181.25,82.25C182.78,83.42 184.3,84.59 185.83,85.77C186.9,86.6 186.9,86.6 187.98,87.46C189.77,88.82 191.57,90.09 193.45,91.32C196,93 196,93 197.5,94.56C199.69,96.66 202.27,97.73 205,99C205,99.99 205,100.98 205,102C206.65,102.33 208.3,102.66 210,103C210.08,105.25 210.14,107.5 210.19,109.75C210.24,111.63 210.24,111.63 210.29,113.55C210,117 210,117 209.06,119.36C205.72,122.01 201.97,122.05 197.81,122.5C191.42,123.21 185.31,124.06 180,128C179.67,128.99 179.34,129.98 179,131C181.31,132.98 183.62,134.96 186,137C185.51,137.99 185.51,137.99 185,139C183.35,138.67 181.7,138.34 180,138C179.67,137.01 179.34,136.02 179,135C176.5,133.78 176.5,133.78 174,133C173.55,133.66 173.09,134.32 172.63,135C172.09,135.66 171.55,136.32 171,137C170.34,137 169.68,137 169,137C168.92,137.93 168.84,138.86 168.75,139.81C168,143 168,143 165.94,144.88C165.3,145.25 164.66,145.62 164,146C163.01,145.51 163.01,145.51 162,145C161.01,145.33 160.02,145.66 159,146C156,146 156,146 153.94,144.38C151.74,141.69 150.91,139.33 150,136C148.93,136.19 147.85,136.37 146.75,136.56C143.6,136.93 141.9,137.04 139,136C138.51,133.03 138.51,133.03 138,130C134.45,131.4 134.45,131.4 131,133C129.46,133.07 127.92,133.08 126.38,133.06C125.15,133.05 125.15,133.05 123.9,133.04C123.27,133.02 122.65,133.01 122,133C122,132.01 122,131.02 122,130C120.51,130.49 120.51,130.49 119,131C112.29,131.62 107.1,130.83 101,128C98.47,125.47 98.67,124.58 98.63,121.06C98.71,114.63 99.24,98.76 104,94C105.69,93.93 107.38,93.92 109.06,93.94C109.98,93.95 110.9,93.96 111.85,93.96C112.56,93.98 113.27,93.99 114,94C112.87,100.89 111.69,107.77 110.37,114.63C109.9,117.26 109.9,117.26 110,121C113.3,121 116.6,121 120,121C121.59,117.73 122.29,114.62 122.82,111.06C122.97,110.15 123.11,109.23 123.26,108.29C123.54,106.39 123.81,104.48 124.06,102.57C125.17,95.78 125.17,95.78 127.64,93.46C130.04,92.04 132.17,91 135,91C135,90.34 135,89.68 135,89C139.62,86.78 142.77,85.62 148,86C148.33,85.01 148.66,84.02 149,83C154.71,83.43 158.41,85.84 163,89C162.75,88.16 162.75,88.16 162.5,87.3C161.68,83.55 161.94,79.82 162,76ZM164,106C162.46,108.41 161.9,109.5 162.46,112.36C162.76,113.15 163.06,113.94 163.38,114.75C163.67,115.55 163.97,116.35 164.27,117.17C164.51,117.78 164.75,118.38 165,119C165.33,119 165.66,119 166,119C165.67,114.71 165.34,110.42 165,106C164.67,106 164.34,106 164,106ZM131,122C129.02,124.97 129.02,124.97 127,128C127.99,128.49 127.99,128.49 129,129C130.65,127.68 132.3,126.36 134,125C133.01,124.01 132.02,123.02 131,122Z"
|
||||||
|
android:fillColor="#F5F01A"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M162,76C169.1,75.16 173.27,76.11 178.98,80.43C179.73,81.03 180.48,81.63 181.25,82.25C182.78,83.42 184.3,84.59 185.83,85.77C186.9,86.6 186.9,86.6 187.98,87.46C189.77,88.82 191.57,90.09 193.45,91.32C196,93 196,93 197.5,94.56C199.69,96.66 202.27,97.73 205,99C205,99.99 205,100.98 205,102C206.65,102.33 208.3,102.66 210,103C210.08,105.25 210.14,107.5 210.19,109.75C210.24,111.63 210.24,111.63 210.29,113.55C210,117 210,117 209.06,119.36C205.72,122.01 201.97,122.05 197.81,122.5C191.28,123.22 185.54,124.25 180,128C179.67,128.66 179.34,129.32 179,130C174.13,129.58 172.21,127.55 169,124C168.49,123.61 167.97,123.22 167.44,122.82C165.18,119.96 165,116.71 164.56,113.19C164.39,112.14 164.39,112.14 164.21,111.07C163.71,107.2 163.83,104.7 165.96,101.49C166.64,100.67 167.31,99.85 168,99C172.47,100.42 176.71,102.11 181,104C180.02,101.99 179.01,99.99 178,98C177.55,97.1 177.55,97.1 177.09,96.18C174.94,92.15 172.74,89.6 169,87C168.67,87.99 168.34,88.98 168,90C166.68,90 165.36,90 164,90C163.67,90.66 163.34,91.32 163,92C162.08,86.61 161.91,81.46 162,76Z"
|
||||||
|
android:fillColor="#F3EE18"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M169,87C169.99,87.33 170.98,87.66 172,88C172,88.66 172,89.32 172,90C172.6,90.21 173.2,90.41 173.81,90.63C176.83,92.52 177.56,94.8 179,98C179.66,98.99 180.32,99.98 181,101C181,101.99 181,102.98 181,104C175.72,103.48 172.43,101.75 168,99C167.73,99.7 167.46,100.4 167.19,101.13C166,104 166,104 164.19,106.75C162.68,110.88 163.34,112.79 164.95,116.78C168.38,124.01 172.84,127.62 179.45,131.89C182.35,133.77 184.05,135.07 186,138C183.52,138.49 183.52,138.49 181,139C180.77,138.38 180.55,137.76 180.31,137.13C178.62,134.39 177.01,133.95 174,133C173.55,133.66 173.09,134.32 172.63,135C172.09,135.66 171.55,136.32 171,137C170.34,137 169.68,137 169,137C168.92,137.93 168.84,138.86 168.75,139.81C168,143 168,143 165.94,144.88C165.3,145.25 164.66,145.62 164,146C163.34,145.67 162.68,145.34 162,145C160.51,145.49 160.51,145.49 159,146C156,146 156,146 153.94,144.38C151.74,141.69 150.91,139.33 150,136C148.93,136.19 147.85,136.37 146.75,136.56C143.6,136.93 141.9,137.04 139,136C136.7,122.89 136.7,122.89 138,119C141.96,119.33 145.92,119.66 150,120C149,124 149,124 147,127C145.51,127.49 145.51,127.49 144,128C143.67,128.66 143.34,129.32 143,130C145.31,129.34 147.62,128.68 150,128C150.12,127.24 150.25,126.47 150.38,125.69C151,123 151,123 153,120C153.24,117.43 153.24,117.43 152,115C148.53,113.13 148.53,113.13 145,112C145.49,107.54 145.49,107.54 146,103C146.66,103 147.32,103 148,103C148.33,102.01 148.66,101.02 149,100C151.45,97.46 152.75,97.02 156.31,96.75C159.92,96.99 163.43,97.42 167,98C167,96.68 167,95.36 167,94C166.01,93.34 165.02,92.68 164,92C164,91.34 164,90.68 164,90C164.64,89.88 165.28,89.75 165.94,89.63C166.62,89.42 167.3,89.21 168,89C168.33,88.34 168.66,87.68 169,87Z"
|
||||||
|
android:fillColor="#AF1505"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M64.5,93.9C66.02,93.92 66.02,93.92 67.56,93.94C68.57,93.95 69.59,93.96 70.63,93.96C71.8,93.98 71.8,93.98 73,94C73.2,95.2 73.41,96.41 73.62,97.65C73.89,99.22 74.17,100.8 74.44,102.38C74.57,103.17 74.71,103.96 74.85,104.78C75.51,109.01 75.51,109.01 77,113C77.28,112.42 77.55,111.85 77.84,111.26C85.9,94.83 85.9,94.83 91.18,92.74C94.01,92.81 96.28,93.28 99,94C97.68,102.27 96.15,110.49 94.44,118.69C94.22,119.77 94,120.85 93.77,121.97C93.55,122.99 93.34,124.02 93.12,125.07C92.83,126.46 92.83,126.46 92.54,127.87C92,130 92,130 91,131C88.33,131.14 85.68,131.04 83,131C81.46,127.92 82.63,125.65 83.44,122.38C83.72,121.19 84.01,120 84.31,118.77C84.54,117.86 84.76,116.94 85,116C84.13,117.62 84.13,117.62 83.24,119.28C82.45,120.69 81.67,122.09 80.88,123.5C80.5,124.22 80.12,124.93 79.73,125.67C79.34,126.34 78.95,127.02 78.55,127.72C78.21,128.35 77.86,128.98 77.51,129.62C76,131 76,131 70,131C69.01,125.72 68.02,120.44 67,115C66.05,119.89 66.05,119.89 65.12,124.78C64.11,129.89 64.11,129.89 63,131C61.48,131.07 59.96,131.08 58.44,131.06C57.61,131.05 56.78,131.04 55.93,131.04C55.3,131.02 54.66,131.01 54,131C54.79,126.69 55.58,122.37 56.38,118.06C56.6,116.85 56.82,115.64 57.05,114.39C60.8,94.05 60.8,94.05 64.5,93.9Z"
|
||||||
|
android:fillColor="#0F390F"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M106.29,93.9C107.66,93.92 107.66,93.92 109.06,93.94C109.98,93.95 110.9,93.96 111.85,93.96C112.56,93.98 113.27,93.99 114,94C112.87,100.89 111.69,107.77 110.37,114.63C109.9,117.26 109.9,117.26 110,121C113.3,121 116.6,121 120,121C121.43,117.65 122.41,114.5 123.07,110.92C123.24,109.99 123.42,109.06 123.6,108.1C123.86,106.66 123.86,106.66 124.13,105.19C124.31,104.21 124.49,103.23 124.68,102.22C125.12,99.81 125.56,97.41 126,95C129.3,95 132.6,95 136,95C135.6,101.94 134.63,108.64 133.25,115.44C133.11,116.22 132.96,117 132.81,117.8C131.98,121.68 131.43,123.57 128.56,126.43C121.93,130.5 116.77,131.92 109,131C105.14,130 101.87,128.87 99,126C97.4,115.75 100.49,104.89 103,95C104,94 104,94 106.29,93.9Z"
|
||||||
|
android:fillColor="#10370D"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M28,94C31.21,93.91 34.42,93.86 37.63,93.81C38.53,93.79 39.43,93.76 40.36,93.74C46.61,93.67 51.05,94.35 55.88,98.69C57.54,102.11 57.65,105.31 57,109C54.98,112.75 53.55,114.64 50,117C47.26,117.46 44.57,117.83 41.81,118.13C41.06,118.21 40.31,118.3 39.54,118.39C37.69,118.6 35.85,118.8 34,119C33.01,122.96 32.02,126.92 31,131C27.7,131 24.4,131 21,131C21.69,123.59 23.01,116.41 24.5,109.13C24.84,107.44 24.84,107.44 25.18,105.71C26.86,97.42 26.86,97.42 28,94ZM36,103C35.67,104.98 35.34,106.96 35,109C36.62,109.05 38.25,109.09 39.88,109.13C40.78,109.15 41.68,109.17 42.62,109.2C45.19,109.24 45.19,109.24 47,107C46.67,105.68 46.34,104.36 46,103C42.7,103 39.4,103 36,103Z"
|
||||||
|
android:fillColor="#0F380E"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M185,88C190.11,88.85 193.86,90.77 197.5,94.56C199.69,96.66 202.27,97.73 205,99C205,99.99 205,100.98 205,102C207.48,102.5 207.48,102.5 210,103C210.08,105.25 210.14,107.5 210.19,109.75C210.24,111.63 210.24,111.63 210.29,113.55C210,117 210,117 209.06,119.36C205.72,122.01 201.97,122.05 197.81,122.5C191.28,123.22 185.54,124.25 180,128C179.67,128.66 179.34,129.32 179,130C178.34,130 177.68,130 177,130C177.31,129.4 177.62,128.8 177.94,128.19C179.1,125.91 179.1,125.91 180,123C182.56,121.31 182.56,121.31 185,120C184.87,118.92 184.87,118.92 184.75,117.82C183.76,107.8 184.31,98.03 185,88Z"
|
||||||
|
android:fillColor="#EDD617"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M155,119C159.23,119.6 162.35,122.05 165.75,124.44C166.35,124.85 166.95,125.25 167.57,125.67C169.09,126.73 170.55,127.86 172,129C172,129.66 172,130.32 172,131C172.66,131 173.32,131 174,131C173.19,133.44 173.19,133.44 172,136C171.01,136.33 170.02,136.66 169,137C168.92,137.93 168.84,138.86 168.75,139.81C168,143 168,143 165.94,144.88C165.3,145.25 164.66,145.62 164,146C163.34,145.67 162.68,145.34 162,145C161.01,145.33 160.02,145.66 159,146C158.67,145.01 158.34,144.02 158,143C156.68,143 155.36,143 154,143C150.62,134.35 152.4,127.57 155,119Z"
|
||||||
|
android:fillColor="#ADAD1E"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M169,87C169.99,87.33 170.98,87.66 172,88C172,88.66 172,89.32 172,90C172.6,90.21 173.2,90.41 173.81,90.63C176.83,92.52 177.56,94.8 179,98C179.99,99.49 179.99,99.49 181,101C181,101.99 181,102.98 181,104C175.72,103.48 172.43,101.75 168,99C167.71,99.78 167.42,100.57 167.13,101.38C166,104 166,104 164,106C162.68,106 161.36,106 160,106C160.13,106.59 160.27,107.18 160.4,107.79C161.31,111.85 162.21,115.91 163,120C162.01,120 161.02,120 160,120C159.51,118.51 159.51,118.51 159,117C156.98,116.27 156.98,116.27 155,116C155,115.34 155,114.68 155,114C154.34,114 153.68,114 153,114C153,113.34 153,112.68 153,112C152.34,112 151.68,112 151,112C151,110.35 151,108.7 151,107C150.01,106.67 149.02,106.34 148,106C150.08,98.82 150.08,98.82 153,97C157.77,96.63 162.29,97.23 167,98C167,96.68 167,95.36 167,94C166.01,93.34 165.02,92.68 164,92C164,91.34 164,90.68 164,90C164.64,89.88 165.28,89.75 165.94,89.63C166.62,89.42 167.3,89.21 168,89C168.33,88.34 168.66,87.68 169,87Z"
|
||||||
|
android:fillColor="#CA0503"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M195,94C198.3,95.65 201.6,97.3 205,99C205,99.99 205,100.98 205,102C207.48,102.5 207.48,102.5 210,103C210.08,105.25 210.14,107.5 210.19,109.75C210.24,111.63 210.24,111.63 210.29,113.55C210,117 210,117 209.06,119.36C205.72,122.01 201.97,122.05 197.81,122.5C191.28,123.22 185.54,124.25 180,128C179.67,128.66 179.34,129.32 179,130C178.34,130 177.68,130 177,130C178.74,125.81 180.76,124.62 184.76,122.75C188.29,121.57 191.3,121.74 195,122C196.25,117.16 196.15,112.4 196.13,107.44C196.13,106.59 196.13,105.74 196.14,104.86C196.13,103.63 196.13,103.63 196.13,102.37C196.13,101.63 196.13,100.88 196.13,100.12C196.04,97.66 196.04,97.66 195,94Z"
|
||||||
|
android:fillColor="#B18518"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M176,92C176.99,92.33 177.98,92.66 179,93C179.33,94.65 179.66,96.3 180,98C180.99,98.33 181.98,98.66 183,99C183,100.98 183,102.96 183,105C182.03,105.29 181.06,105.58 180.06,105.88C176.89,106.64 176.89,106.64 176,109C175.93,111.14 175.92,113.29 175.94,115.44C175.95,116.59 175.96,117.74 175.96,118.93C175.98,119.95 175.99,120.96 176,122C176,122.99 176,123.98 176,125C177.32,125.33 178.64,125.66 180,126C179.01,127.32 178.02,128.64 177,130C173.17,128.44 170.82,125.97 168,123C167.34,122.34 166.68,121.68 166,121C165.42,118.39 164.98,115.89 164.63,113.25C164.51,112.55 164.39,111.84 164.26,111.12C163.73,107.2 163.73,104.84 165.96,101.48C166.63,100.66 167.31,99.84 168,99C172.47,100.42 176.71,102.11 181,104C179.46,100.86 177.94,97.91 176,95C176,94.01 176,93.02 176,92Z"
|
||||||
|
android:fillColor="#E8E81C"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M138,119C141.96,119.33 145.92,119.66 150,120C149,124 149,124 147,127C146.01,127.33 145.02,127.66 144,128C143.67,128.66 143.34,129.32 143,130C145.31,129.34 147.62,128.68 150,128C150,129.32 150,130.64 150,132C148.68,132.33 147.36,132.66 146,133C148.97,133.49 148.97,133.49 152,134C154,139.63 154,139.63 154,143C155.32,143.33 156.64,143.66 158,144C157.01,144.66 156.02,145.32 155,146C152.36,142.87 151.16,139.91 150,136C148.93,136.19 147.85,136.37 146.75,136.56C143.6,136.93 141.9,137.04 139,136C136.7,122.89 136.7,122.89 138,119Z"
|
||||||
|
android:fillColor="#29420C"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M169,87C169.99,87.33 170.98,87.66 172,88C172,88.66 172,89.32 172,90C172.6,90.21 173.2,90.41 173.81,90.63C176.83,92.52 177.56,94.8 179,98C179.99,99.49 179.99,99.49 181,101C181,101.99 181,102.98 181,104C175.72,103.48 172.43,101.75 168,99C167.34,100.65 166.68,102.3 166,104C165.67,102.68 165.34,101.36 165,100C160.38,100 155.76,100 151,100C151.66,99.01 152.32,98.02 153,97C157.77,96.63 162.29,97.23 167,98C167,96.68 167,95.36 167,94C166.01,93.34 165.02,92.68 164,92C164,91.34 164,90.68 164,90C164.64,89.88 165.28,89.75 165.94,89.63C166.62,89.42 167.3,89.21 168,89C168.33,88.34 168.66,87.68 169,87Z"
|
||||||
|
android:fillColor="#B81403"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M149,83C155.06,83.3 158.51,86.28 163,90C162.67,90.66 162.34,91.32 162,92C161.34,91.67 160.68,91.34 160,91C160,90.34 160,89.68 160,89C157.52,88.5 157.52,88.5 155,88C155,87.34 155,86.68 155,86C154.01,86 153.02,86 152,86C151.67,86.66 151.34,87.32 151,88C149.35,88 147.7,88 146,88C145.67,88.99 145.34,89.98 145,91C143.68,91 142.36,91 141,91C141,92.65 141,94.3 141,96C140.01,96.33 139.02,96.66 138,97C137.89,97.59 137.78,98.19 137.67,98.8C136.43,105.3 134.81,111.64 133,118C131.99,114.83 132.06,112.69 132.78,109.45C132.96,108.61 133.14,107.76 133.33,106.89C133.53,106.02 133.73,105.15 133.94,104.25C134.13,103.36 134.33,102.47 134.53,101.56C135.01,99.37 135.5,97.19 136,95C133.03,95 130.06,95 127,95C130.09,91.91 130.92,91.55 135,91C135,90.34 135,89.68 135,89C139.62,86.78 142.77,85.62 148,86C148.33,85.01 148.66,84.02 149,83Z"
|
||||||
|
android:fillColor="#D8DE3A"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M193,93C195.38,94.76 195.98,95.91 196.69,98.81C198.35,114.98 198.35,114.98 195,122C192.69,122 190.38,122 188,122C188.33,121.34 188.66,120.68 189,120C189.66,120 190.32,120 191,120C190.67,111.75 190.34,103.5 190,95C190.99,95 191.98,95 193,95C193,94.34 193,93.68 193,93Z"
|
||||||
|
android:fillColor="#DBB213"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M168,99C170.02,99.6 172.02,100.27 174,101C174.33,101.66 174.66,102.32 175,103C173.68,103 172.36,103 171,103C171.33,103.66 171.66,104.32 172,105C172.08,106.38 172.11,107.75 172.1,109.13C172.09,109.94 172.09,110.74 172.09,111.57C172.08,112.42 172.07,113.26 172.06,114.13C172.06,114.97 172.05,115.82 172.05,116.7C172.04,118.8 172.02,120.9 172,123C170.68,123 169.36,123 168,123C165.17,120.17 165.14,117.07 164.63,113.25C164.51,112.55 164.39,111.84 164.26,111.12C163.73,107.2 163.73,104.84 165.96,101.48C166.63,100.66 167.31,99.84 168,99Z"
|
||||||
|
android:fillColor="#D5CB20"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M149,100C150,103 150,103 149,106C149.99,106 150.98,106 152,106C151.67,107.98 151.34,109.96 151,112C151.66,112 152.32,112 153,112C153,112.66 153,113.32 153,114C153.66,114 154.32,114 155,114C155.33,114.66 155.66,115.32 156,116C157.32,116 158.64,116 160,116C160,116.99 160,117.98 160,119C158.35,119 156.7,119 155,119C154.88,119.8 154.75,120.61 154.63,121.44C153.88,125.66 152.95,129.82 152,134C148.37,133.67 144.74,133.34 141,133C141,132.67 141,132.34 141,132C143.97,132 146.94,132 150,132C149.94,130.95 149.88,129.9 149.81,128.81C150.01,124.73 150.95,123.39 153,120C153.33,117.33 153.33,117.33 152,115C148.53,113.13 148.53,113.13 145,112C145.33,109.03 145.66,106.06 146,103C146.66,103 147.32,103 148,103C148.33,102.01 148.66,101.02 149,100Z"
|
||||||
|
android:fillColor="#BC1703"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M199,98C200.65,98 202.3,98 204,98C204.33,99.32 204.66,100.64 205,102C206.65,102.33 208.3,102.66 210,103C210.08,105.25 210.14,107.5 210.19,109.75C210.22,111 210.26,112.26 210.29,113.55C209.98,117.2 209.76,118.61 207,121C204.3,121.61 204.3,121.61 201.31,121.75C200.32,121.81 199.32,121.86 198.3,121.92C197.54,121.95 196.78,121.97 196,122C197,120 197,120 200.06,118.88C201.52,118.44 201.52,118.44 203,118C204.15,113.06 204.54,108.04 205,103C204.34,103 203.68,103 203,103C202.9,102.36 202.79,101.72 202.69,101.06C202.35,100.04 202.35,100.04 202,99C201.01,98.67 200.02,98.34 199,98Z"
|
||||||
|
android:fillColor="#AE5E0F"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M187,130C187.56,130.19 188.11,130.37 188.69,130.56C191.45,131.08 193.25,130.56 196,130C198.67,129.91 201.32,129.95 204,130C203.67,131.65 203.34,133.3 203,135C203.99,135 204.98,135 206,135C206.33,133.35 206.66,131.7 207,130C207.66,130 208.32,130 209,130C208.67,132.31 208.34,134.62 208,137C200.74,137 193.48,137 186,137C186.33,134.69 186.66,132.38 187,130ZM194,132C195,134 195,134 195,134Z"
|
||||||
|
android:fillColor="#0A1607"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M145,112C151.75,113.75 151.75,113.75 154,116C153.63,120.33 151.9,124.13 150,128C147,130 147,130 143,130C143.33,129.01 143.66,128.02 144,127C144.99,126.67 145.98,126.34 147,126C148.71,123 148.71,123 150,120C148.45,120.06 148.45,120.06 146.88,120.13C143.13,120 140.46,119.35 137,118C137.33,117.34 137.66,116.68 138,116C139.65,116 141.3,116 143,116C143,115.34 143,114.68 143,114C143.66,114 144.32,114 145,114C145,113.34 145,112.68 145,112Z"
|
||||||
|
android:fillColor="#F4D542"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M80,108C80.66,108.33 81.32,108.66 82,109C77.89,117.51 77.89,117.51 74.19,119.56C73.47,119.71 72.74,119.85 72,120C72,121.32 72,122.64 72,124C72,125.67 72,127.33 72,129C76.13,127.51 77.3,125.19 79.25,121.38C79.77,120.37 80.29,119.37 80.83,118.34C81.21,117.57 81.6,116.79 82,116C82.66,116 83.32,116 84,116C81.96,121.35 79.63,126.53 76,131C72.63,131.63 72.63,131.63 70,131C69.66,129.44 69.33,127.88 69,126.31C68.81,125.44 68.63,124.57 68.44,123.68C68.01,121.06 67.92,118.64 68,116C68.99,116 69.98,116 71,116C73.69,113.56 73.69,113.56 76,111C76.33,111.66 76.66,112.32 77,113C77.99,111.35 78.98,109.7 80,108Z"
|
||||||
|
android:fillColor="#0C320A"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M131,118C132.32,119.65 133.64,121.3 135,123C135.33,121.68 135.66,120.36 136,119C136.66,119 137.32,119 138,119C138,122.3 138,125.6 138,129C132.46,132.77 128.66,133.54 122,133C122.76,129.16 122.76,129.16 124.94,127.69C125.96,127.35 125.96,127.35 127,127C127.66,127.33 128.32,127.66 129,128C130.32,127.01 131.64,126.02 133,125C132.34,124.01 131.68,123.02 131,122C131,120.68 131,119.36 131,118Z"
|
||||||
|
android:fillColor="#E1E438"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M185,88C189.51,88.53 192.35,90.37 196,93C193,95 193,95 191,96C191,103.92 191,111.84 191,120C190.01,119.67 189.02,119.34 188,119C188,110 188,101 188,92C187.02,90.98 186.02,89.98 185,89C185,88.67 185,88.34 185,88Z"
|
||||||
|
android:fillColor="#E8C512"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M28,94C31.21,93.91 34.42,93.86 37.63,93.81C38.53,93.79 39.43,93.76 40.36,93.74C45.66,93.68 49.46,93.93 54,97C54.99,98.49 54.99,98.49 56,100C55.24,99.69 54.47,99.38 53.69,99.06C50.2,97.68 47.5,96.88 43.77,96.9C42.57,96.91 42.57,96.91 41.34,96.91C40.5,96.92 39.67,96.93 38.81,96.94C37.55,96.94 37.55,96.94 36.25,96.95C34.17,96.96 32.08,96.98 30,97C29.81,98.46 29.62,99.92 29.44,101.38C29.33,102.19 29.23,103 29.12,103.84C28.82,106.05 28.82,106.05 30,108C29.34,108 28.68,108 28,108C28,109.32 28,110.64 28,112C27.01,112 26.02,112 25,112C25.12,110.5 25.24,109 25.38,107.5C25.44,106.66 25.51,105.83 25.59,104.97C26.11,101.22 27.04,97.66 28,94Z"
|
||||||
|
android:fillColor="#0A2509"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M200,99C200.66,99 201.32,99 202,99C202.33,100.32 202.66,101.64 203,103C203.66,103 204.32,103 205,103C205.03,104.73 205.05,106.46 205.06,108.19C205.07,109.15 205.09,110.11 205.1,111.11C205,113.86 204.62,116.32 204,119C202.35,119 200.7,119 199,119C198.97,116.04 198.95,113.08 198.94,110.13C198.93,109.28 198.92,108.44 198.91,107.57C198.91,106.77 198.91,105.96 198.9,105.13C198.9,104.39 198.89,103.65 198.89,102.88C199,101 199,101 200,99Z"
|
||||||
|
android:fillColor="#BE720B"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M106.29,93.9C107.66,93.92 107.66,93.92 109.06,93.94C109.98,93.95 110.9,93.96 111.85,93.96C112.56,93.98 113.27,93.99 114,94C112.07,106.67 112.07,106.67 110,112C108.8,108.47 109.2,105.87 109.94,102.25C110.13,101.27 110.33,100.28 110.53,99.27C110.68,98.52 110.84,97.77 111,97C108.03,96.5 108.03,96.5 105,96C104.71,97.58 104.42,99.17 104.13,100.75C103.94,101.74 103.76,102.74 103.57,103.76C103.18,105.96 102.83,108.16 102.49,110.37C102.25,111.98 102.25,111.98 102,113.63C101.78,115.13 101.78,115.13 101.56,116.66C101.38,117.43 101.19,118.21 101,119C100.34,119.33 99.68,119.66 99,120C100.76,94.14 100.76,94.14 106.29,93.9Z"
|
||||||
|
android:fillColor="#092107"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M162,76C164.97,76 167.94,76 171,76C170.01,76.33 169.02,76.66 168,77C168,79.64 168,82.28 168,85C168.99,85.33 169.98,85.66 171,86C170.01,86.5 170.01,86.5 169,87C168.67,87.99 168.34,88.98 168,90C166.68,90 165.36,90 164,90C163.67,90.66 163.34,91.32 163,92C162.08,86.59 161.92,81.49 162,76Z"
|
||||||
|
android:fillColor="#CAB737"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M88,139C89.98,139 91.96,139 94,139C94.33,139.66 94.66,140.32 95,141C96.65,141 98.3,141 100,141C100.33,140.34 100.66,139.68 101,139C101.33,139.66 101.66,140.32 102,141C102.99,141 103.98,141 105,141C105,140.34 105,139.68 105,139C105.66,139 106.32,139 107,139C107,139.66 107,140.32 107,141C108.32,141.33 109.64,141.66 111,142C110.01,143.49 110.01,143.49 109,145C106.05,145.22 103.32,145.28 100.38,145.19C99.57,145.17 98.77,145.16 97.95,145.15C95.96,145.11 93.98,145.06 92,145C92,144.34 92,143.68 92,143C91.34,143 90.68,143 90,143C90,143.66 90,144.32 90,145C89.01,144.67 88.02,144.34 87,144C87.33,142.35 87.66,140.7 88,139ZM96,142C97,144 97,144 97,144Z"
|
||||||
|
android:fillColor="#010101"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M163,126C167.71,125.83 167.71,125.83 170.31,127.38C170.87,127.91 171.43,128.45 172,129C172,129.66 172,130.32 172,131C172.66,131 173.32,131 174,131C173,134 173,134 170,136C169.01,136 168.02,136 167,136C167,135.34 167,134.68 167,134C166.34,134 165.68,134 165,134C165.33,135.98 165.66,137.96 166,140C165.01,140.49 165.01,140.49 164,141C162.68,136.04 162.91,131.09 163,126Z"
|
||||||
|
android:fillColor="#B9BC16"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M80,114C80.66,114.33 81.32,114.66 82,115C81.43,118.9 80.31,121.54 78.13,124.81C77.61,125.6 77.1,126.39 76.57,127.21C76.05,127.8 75.53,128.39 75,129C74.01,129 73.02,129 72,129C71.38,126.69 71.38,126.69 71,124C71.66,123.01 72.32,122.02 73,121C72.34,120.67 71.68,120.34 71,120C73.74,117.26 76.55,115.79 80,114Z"
|
||||||
|
android:fillColor="#103C10"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M172,76C172,77.65 172,79.3 172,81C173.32,81 174.64,81 176,81C176,81.66 176,82.32 176,83C176.99,83.33 177.98,83.66 179,84C178.34,85.32 177.68,86.64 177,88C176.34,88 175.68,88 175,88C175.33,89.32 175.66,90.64 176,92C172.52,90.61 171.52,89.37 170,86C169.34,85.67 168.68,85.34 168,85C168,82.36 168,79.72 168,77C171,76 171,76 172,76Z"
|
||||||
|
android:fillColor="#F2DE29"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M85,110C86.32,110 87.64,110 89,110C87.68,116.27 86.36,122.54 85,129C86.65,128.67 88.3,128.34 90,128C90.33,124.37 90.66,120.74 91,117C91.99,117 92.98,117 94,117C93.59,121.97 93.2,126.45 91,131C88.36,131 85.72,131 83,131C81.15,127.31 83.41,122.91 84.41,119.07C85.26,115.98 85.26,115.98 84,113C84.33,112.01 84.66,111.02 85,110Z"
|
||||||
|
android:fillColor="#051F05"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M172,77C177.38,79.91 182.18,83.24 187,87C183.38,90 183.38,90 180,90C178.31,91.44 178.31,91.44 177,93C176.34,91.35 175.68,89.7 175,88C175.66,88 176.32,88 177,88C176.67,87.01 176.34,86.02 176,85C176.66,84.67 177.32,84.34 178,84C177.34,83.67 176.68,83.34 176,83C176,82.34 176,81.68 176,81C174.68,81 173.36,81 172,81C172,79.68 172,78.36 172,77Z"
|
||||||
|
android:fillColor="#F4F019"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M50,116C50,116.33 50,116.66 50,117C44.72,117.66 39.44,118.32 34,119C33.01,122.96 32.02,126.92 31,131C27.7,131 24.4,131 21,131C21,129.68 21,128.36 21,127C21.66,127 22.32,127 23,127C23,127.66 23,128.32 23,129C25.31,129 27.62,129 30,129C30.05,128.4 30.1,127.79 30.15,127.17C30.22,126.37 30.3,125.57 30.38,124.75C30.44,123.96 30.51,123.17 30.59,122.36C31.04,119.76 31.4,118.12 33,116C35.64,115.36 35.64,115.36 38.81,115.19C39.85,115.12 40.89,115.05 41.96,114.98C44.8,115 47.25,115.33 50,116Z"
|
||||||
|
android:fillColor="#051E05"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M90.85,93.35C93.63,93.37 96.26,93.56 99,94C97.81,101.37 96.52,108.69 95,116C94.34,116 93.68,116 93,116C93.48,113.04 93.96,110.08 94.44,107.13C94.57,106.28 94.71,105.44 94.85,104.57C94.98,103.77 95.11,102.96 95.25,102.13C95.37,101.39 95.49,100.65 95.61,99.88C96,98 96,98 97,96C92.85,95.85 92.85,95.85 89,97C86.49,100.09 84.72,103.42 83,107C82,104 82,104 82.83,101.52C86.61,94.32 86.61,94.32 90.85,93.35Z"
|
||||||
|
android:fillColor="#061F05"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M155,131C159.92,135.18 159.92,135.18 160.31,139.31C160.16,140.64 160.16,140.64 160,142C160.99,142 161.98,142 163,142C162.67,142.99 162.34,143.98 162,145C161.01,145.33 160.02,145.66 159,146C158.67,145.01 158.34,144.02 158,143C156.68,143 155.36,143 154,143C153.58,141.57 153.19,140.13 152.81,138.69C152.59,137.89 152.37,137.09 152.14,136.26C152,134 152,134 153.45,132.21C153.96,131.81 154.47,131.41 155,131Z"
|
||||||
|
android:fillColor="#868815"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M148,128C148.66,128 149.32,128 150,128C150,129.32 150,130.64 150,132C148.68,132.33 147.36,132.66 146,133C148.97,133.49 148.97,133.49 152,134C154,139.63 154,139.63 154,143C155.32,143.33 156.64,143.66 158,144C157.01,144.66 156.02,145.32 155,146C152.36,142.87 151.16,139.91 150,136C148.93,136.19 147.85,136.37 146.75,136.56C143.6,136.93 141.9,137.04 139,136C138.44,134.06 138.44,134.06 138,132C139.58,130.42 141.38,130.65 143.56,130.44C144.8,130.31 144.8,130.31 146.07,130.18C147.02,130.09 147.02,130.09 148,130C148,129.34 148,128.68 148,128Z"
|
||||||
|
android:fillColor="#71290E"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M193,93C196.36,96.05 196.77,98.59 197,103C197.51,117 197.51,117 195,121C194.34,120.67 193.68,120.34 193,120C193.08,118.81 193.17,117.61 193.25,116.38C194.04,104.67 194.04,104.67 193,93Z"
|
||||||
|
android:fillColor="#D3A012"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M169,125C174.97,128.69 180.75,132.32 186,137C185.67,137.66 185.34,138.32 185,139C183.35,138.67 181.7,138.34 180,138C179.67,137.01 179.34,136.02 179,135C178.4,134.88 177.8,134.75 177.19,134.63C173.99,133.71 172.94,131.63 171,129C170.02,127.98 169.03,126.97 168,126C168.33,125.67 168.66,125.34 169,125Z"
|
||||||
|
android:fillColor="#992A0C"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M21,139C23.31,139 25.62,139 28,139C28,139.66 28,140.32 28,141C30.64,141 33.28,141 36,141C35.67,142.32 35.34,143.64 35,145C33.56,145.05 32.13,145.09 30.69,145.13C29.89,145.15 29.09,145.17 28.26,145.2C26,145 26,145 23,143C23,143.66 23,144.32 23,145C22.01,144.67 21.02,144.34 20,144C20.33,142.35 20.66,140.7 21,139Z"
|
||||||
|
android:fillColor="#010101"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M149,83C155.06,83.3 158.51,86.28 163,90C162.67,90.66 162.34,91.32 162,92C161.34,91.67 160.68,91.34 160,91C160,90.34 160,89.68 160,89C157.52,88.5 157.52,88.5 155,88C155,87.34 155,86.68 155,86C154.01,86 153.02,86 152,86C151.67,86.66 151.34,87.32 151,88C146.71,89.3 142.43,89.08 138,89C140.55,86.65 141.71,86.02 145.25,85.81C146.61,85.91 146.61,85.91 148,86C148.33,85.01 148.66,84.02 149,83Z"
|
||||||
|
android:fillColor="#F3F265"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M155,119C158.87,119.57 161.08,121.49 164,124C161.24,123.48 158.67,122.89 156,122C156.16,122.72 156.33,123.44 156.5,124.19C156.98,126.86 157.08,129.29 157,132C155.68,132 154.36,132 153,132C152.67,132.66 152.34,133.32 152,134C152.45,128.73 153.08,123.98 155,119Z"
|
||||||
|
android:fillColor="#957B13"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M143,114C147.46,114.99 147.46,114.99 152,116C151.67,117.65 151.34,119.3 151,121C149.04,120.72 147.08,120.42 145.13,120.13C143.49,119.88 143.49,119.88 141.82,119.63C139,119 139,119 137,117C138,116 138,116 140.56,115.94C141.77,115.97 141.77,115.97 143,116C143,115.34 143,114.68 143,114Z"
|
||||||
|
android:fillColor="#D3D629"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M185,88C189.51,88.53 192.35,90.37 196,93C193,95 193,95 191,96C191,98.64 191,101.28 191,104C189.5,102.94 189.5,102.94 188,101C187.81,97.44 187.81,97.44 188,94C188.23,91.88 188.23,91.88 186.5,90.44C186.01,89.96 185.51,89.49 185,89C185,88.67 185,88.34 185,88Z"
|
||||||
|
android:fillColor="#E6C313"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M82,116C82.66,116 83.32,116 84,116C81.96,121.35 79.63,126.53 76,131C72.63,131.63 72.63,131.63 70,131C69.67,128.03 69.34,125.06 69,122C69.99,122.5 69.99,122.5 71,123C71.63,126.06 71.63,126.06 72,129C76.13,127.51 77.3,125.19 79.25,121.38C79.77,120.37 80.29,119.37 80.83,118.34C81.21,117.57 81.6,116.79 82,116Z"
|
||||||
|
android:fillColor="#041E04"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M154,119C155.88,124.22 153.52,128.89 152,134C148.37,133.67 144.74,133.34 141,133C141,132.67 141,132.34 141,132C143.97,132 146.94,132 150,132C149.92,130.97 149.84,129.94 149.75,128.88C150.04,124.41 151.29,122.48 154,119Z"
|
||||||
|
android:fillColor="#A11C05"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M207,102C207.99,102.33 208.98,102.66 210,103C210.08,105.25 210.14,107.5 210.19,109.75C210.22,111 210.26,112.26 210.29,113.55C209.98,117.2 209.76,118.61 207,121C204.3,121.61 204.3,121.61 201.31,121.75C200.32,121.81 199.32,121.86 198.3,121.92C197.54,121.95 196.78,121.97 196,122C196.33,121.34 196.66,120.68 197,120C199.32,119.61 201.62,119.49 203.97,119.34C204.64,119.23 205.31,119.12 206,119C207.53,115.93 207.1,112.73 207.06,109.38C207.06,108.67 207.05,107.96 207.05,107.23C207.04,105.49 207.02,103.74 207,102Z"
|
||||||
|
android:fillColor="#7A3D0F"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M184,107C184.99,107 185.98,107 187,107C187.33,111.95 187.66,116.9 188,122C185.69,123.32 183.38,124.64 181,126C180.67,125.01 180.34,124.02 180,123C181.65,122.01 183.3,121.02 185,120C184.67,115.71 184.34,111.42 184,107Z"
|
||||||
|
android:fillColor="#EDE023"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M176,92C176.99,92.33 177.98,92.66 179,93C179.33,94.65 179.66,96.3 180,98C180.99,98.33 181.98,98.66 183,99C183,100.98 183,102.96 183,105C180.69,105.33 178.38,105.66 176,106C176,105.34 176,104.68 176,104C174.68,103.67 173.36,103.34 172,103C178.75,102.88 178.75,102.88 181,104C179.46,100.86 177.94,97.91 176,95C176,94.01 176,93.02 176,92Z"
|
||||||
|
android:fillColor="#F6D52F"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M64.5,93.9C66.02,93.92 66.02,93.92 67.56,93.94C68.57,93.95 69.59,93.96 70.63,93.96C71.8,93.98 71.8,93.98 73,94C73.33,96.97 73.66,99.94 74,103C73.01,103.5 73.01,103.5 72,104C71.67,101.36 71.34,98.72 71,96C68.36,96.33 65.72,96.66 63,97C62.67,98.98 62.34,100.96 62,103C61.34,102.67 60.68,102.34 60,102C61.01,94.04 61.01,94.04 64.5,93.9Z"
|
||||||
|
android:fillColor="#061F05"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M39,139C40.33,139.33 41.67,139.67 43,140C44.08,140.19 44.08,140.19 45.19,140.38C46.08,140.68 46.08,140.68 47,141C47.33,141.99 47.66,142.98 48,144C44.22,145.84 42.05,146.16 38,145C37.67,144.01 37.34,143.02 37,142C37.66,141.01 38.32,140.02 39,139Z"
|
||||||
|
android:fillColor="#010101"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M61,139C61.99,139 62.98,139 64,139C64,139.66 64,140.32 64,141C66.31,141 68.62,141 71,141C71,141.66 71,142.32 71,143C71.99,143.33 72.98,143.66 74,144C73.67,144.66 73.34,145.32 73,146C72.31,145.93 71.63,145.86 70.92,145.78C70.02,145.69 69.12,145.6 68.19,145.5C67.29,145.41 66.4,145.31 65.48,145.22C62.92,144.96 62.92,144.96 60,145C60,144.34 60,143.68 60,143C60.66,143 61.32,143 62,143C61.67,141.68 61.34,140.36 61,139Z"
|
||||||
|
android:fillColor="#010001"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M174,120C174.66,120 175.32,120 176,120C176.14,120.64 176.29,121.28 176.44,121.94C176.81,123.98 176.81,123.98 178,125C178.66,125.33 179.32,125.66 180,126C179.01,127.32 178.02,128.64 177,130C174.51,128.8 172.32,127.55 170,126C171.15,123.53 172.05,121.95 174,120Z"
|
||||||
|
android:fillColor="#EEDE2B"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M168,99C170.02,99.6 172.02,100.27 174,101C174.33,101.66 174.66,102.32 175,103C172.69,103 170.38,103 168,103C166.65,107.06 166.44,111.04 167.63,115.19C168.14,117.67 167.18,118.83 166,121C165.55,118.46 165.14,115.92 164.75,113.38C164.62,112.66 164.49,111.95 164.36,111.21C163.78,107.26 163.69,104.87 165.95,101.48C166.63,100.66 167.3,99.84 168,99Z"
|
||||||
|
android:fillColor="#C59431"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M164,92C165.32,92.66 166.64,93.32 168,94C167.67,95.65 167.34,97.3 167,99C165.57,98.84 165.57,98.84 164.11,98.68C162.86,98.56 161.6,98.44 160.31,98.31C159.07,98.18 157.83,98.06 156.55,97.93C152.7,98.01 151.05,98.73 148,101C148.33,100.01 148.66,99.02 149,98C149.66,98 150.32,98 151,98C151,97.01 151,96.02 151,95C158.43,95.99 158.43,95.99 166,97C166,96.01 166,95.02 166,94C165.34,94 164.68,94 164,94C164,93.34 164,92.68 164,92Z"
|
||||||
|
android:fillColor="#F7CA36"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M145,121C146.65,121 148.3,121 150,121C148.51,125.7 148.51,125.7 145.94,127.19C145.3,127.46 144.66,127.72 144,128C143.67,128.66 143.34,129.32 143,130C144.98,129.67 146.96,129.34 149,129C148.67,129.66 148.34,130.32 148,131C145.69,131 143.38,131 141,131C141,129.68 141,128.36 141,127C141.66,127 142.32,127 143,127C143.66,125.02 144.32,123.04 145,121Z"
|
||||||
|
android:fillColor="#4C5D09"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M171,106C171.33,106 171.66,106 172,106C172,111.61 172,117.22 172,123C171.34,123.33 170.68,123.66 170,124C168.46,120.92 169.13,117.79 169.38,114.44C169.42,113.74 169.46,113.04 169.51,112.32C169.87,107.13 169.87,107.13 171,106Z"
|
||||||
|
android:fillColor="#D9DC14"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M76,139C77.65,139 79.3,139 81,139C81,139.66 81,140.32 81,141C82.32,141 83.64,141 85,141C85.33,141.99 85.66,142.98 86,144C82.59,144.78 79.49,145.1 76,145C76,143.02 76,141.04 76,139ZM78,140C79,144 79,144 79,144Z"
|
||||||
|
android:fillColor="#020102"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M64,121C64.33,121 64.66,121 65,121C64.86,122.48 64.71,123.96 64.56,125.44C64.48,126.26 64.4,127.08 64.32,127.93C64,130 64,130 63,131C61.48,131.07 59.96,131.08 58.44,131.06C57.61,131.05 56.78,131.04 55.93,131.04C55.3,131.02 54.66,131.01 54,131C54.33,128.69 54.66,126.38 55,124C55.66,124 56.32,124 57,124C56.67,125.65 56.34,127.3 56,129C57.65,129 59.3,129 61,129C61.99,126.36 62.98,123.72 64,121Z"
|
||||||
|
android:fillColor="#031C03"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M169,87C169.99,87.33 170.98,87.66 172,88C172,88.66 172,89.32 172,90C172.64,90.23 173.28,90.45 173.94,90.69C176,92 176,92 176.75,94.63C176.87,95.8 176.87,95.8 177,97C176.09,96.2 175.18,95.39 174.25,94.56C171.9,92.59 170.13,91.36 167,91C167,91.66 167,92.32 167,93C166.01,92.67 165.02,92.34 164,92C164,91.34 164,90.68 164,90C164.64,89.88 165.28,89.75 165.94,89.63C166.96,89.32 166.96,89.32 168,89C168.33,88.34 168.66,87.68 169,87Z"
|
||||||
|
android:fillColor="#AD2102"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M165,134C165.66,134 166.32,134 167,134C167,134.66 167,135.32 167,136C168.65,135.34 170.3,134.68 172,134C171.67,134.99 171.34,135.98 171,137C170.34,137 169.68,137 169,137C168.92,137.93 168.84,138.86 168.75,139.81C168,143 168,143 165.94,144.88C164.98,145.43 164.98,145.43 164,146C163.67,145.34 163.34,144.68 163,144C163.66,144 164.32,144 165,144C165,140.7 165,137.4 165,134Z"
|
||||||
|
android:fillColor="#979926"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M131,118C132.32,119.65 133.64,121.3 135,123C135.33,121.68 135.66,120.36 136,119C136.66,119 137.32,119 138,119C138,122.3 138,125.6 138,129C137.34,129 136.68,129 136,129C135.73,128.4 135.46,127.8 135.19,127.19C134.13,124.96 134.13,124.96 132.38,123.5C131,122 131,122 131,118Z"
|
||||||
|
android:fillColor="#C9D23D"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M134,111C134.33,111 134.66,111 135,111C135,112.65 135,114.3 135,116C135.76,115.63 136.53,115.26 137.31,114.88C138.2,114.59 139.09,114.3 140,114C140.99,114.66 141.98,115.32 143,116C141.58,116.34 141.58,116.34 140.13,116.69C136.81,117.69 136.81,117.69 135.63,120.63C135.42,121.41 135.21,122.19 135,123C133,122 133,122 132.25,120.38C131.89,116.96 132.95,114.23 134,111Z"
|
||||||
|
android:fillColor="#F3F22E"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M167,91C169.63,91 169.63,91 173,92C175.31,94.47 177.17,97.16 179,100C178.67,100.66 178.34,101.32 178,102C176.68,101.34 175.36,100.68 174,100C174,98.35 174,96.7 174,95C171.69,94.34 169.38,93.68 167,93C167,92.34 167,91.68 167,91Z"
|
||||||
|
android:fillColor="#C90407"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M153,97C156.75,96.71 160.1,97.01 163.81,97.56C166.89,98.29 166.89,98.29 169,97C167.93,99.92 167.22,101.78 165,104C165,102.68 165,101.36 165,100C160.38,100 155.76,100 151,100C151.66,99.01 152.32,98.02 153,97Z"
|
||||||
|
android:fillColor="#AC2303"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M48,139C49.08,139.49 49.08,139.49 50.19,140C53.02,141.01 55.03,141.17 58,141C58,142.32 58,143.64 58,145C56.72,145.06 55.44,145.12 54.13,145.19C53.41,145.22 52.69,145.26 51.95,145.29C51.3,145.2 50.66,145.1 50,145C48,142 48,142 48,139Z"
|
||||||
|
android:fillColor="#010001"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M156,122C156.99,122 157.98,122 159,122C159,122.99 159,123.98 159,125C159.66,125.33 160.32,125.66 161,126C160.01,127.49 160.01,127.49 159,129C159.32,132.64 159.32,132.64 160,136C159.01,135.34 158.02,134.68 157,134C156.49,131.18 156.49,131.18 156.31,127.88C156.25,126.78 156.18,125.68 156.11,124.55C156.06,123.29 156.06,123.29 156,122Z"
|
||||||
|
android:fillColor="#999E18"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M199,103C201.35,106.52 201.38,108.51 201.63,112.69C201.7,113.87 201.77,115.05 201.85,116.26C201.9,117.17 201.95,118.07 202,119C201.01,119 200.02,119 199,119C199,113.72 199,108.44 199,103Z"
|
||||||
|
android:fillColor="#C6800F"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M47,104C47.66,104 48.32,104 49,104C49.33,104.99 49.66,105.98 50,107C49.34,107 48.68,107 48,107C47.67,107.99 47.34,108.98 47,110C44.12,110.96 42.3,111.11 39.31,111.06C38.1,111.05 38.1,111.05 36.86,111.04C35.94,111.02 35.94,111.02 35,111C35,110.34 35,109.68 35,109C35.7,108.97 36.4,108.95 37.12,108.92C38.03,108.87 38.94,108.81 39.88,108.75C40.78,108.7 41.68,108.66 42.62,108.61C45.17,108.24 45.17,108.24 46.32,105.95C46.66,104.99 46.66,104.99 47,104Z"
|
||||||
|
android:fillColor="#072707"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M172,76C172,78.97 172,81.94 172,85C170.68,85 169.36,85 168,85C168,82.36 168,79.72 168,77C171,76 171,76 172,76Z"
|
||||||
|
android:fillColor="#D8D817"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M166,126C168.44,126.81 168.44,126.81 171,128C171.33,128.99 171.66,129.98 172,131C172.66,131 173.32,131 174,131C173.67,131.99 173.34,132.98 173,134C170.44,135.19 170.44,135.19 168,136C168.33,134.02 168.66,132.04 169,130C168.01,129.34 167.02,128.68 166,128C166,127.34 166,126.68 166,126Z"
|
||||||
|
android:fillColor="#DBC032"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M178,132C181.91,133.27 183.79,134.51 186,138C183.63,138.63 183.63,138.63 181,139C178.64,136.64 178.51,135.22 178,132Z"
|
||||||
|
android:fillColor="#8B180E"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M160,106C161.32,106 162.64,106 164,106C163.81,106.52 163.63,107.03 163.44,107.56C162.85,110.86 163.43,113.72 164,117C161,115 161,115 160.49,112.84C160.43,112.02 160.37,111.21 160.31,110.38C160.25,109.56 160.18,108.74 160.11,107.9C160.08,107.27 160.04,106.65 160,106Z"
|
||||||
|
android:fillColor="#AA1913"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M80,108C80.66,108.33 81.32,108.66 82,109C79.53,113.46 79.53,113.46 77,118C76.01,117.67 75.02,117.34 74,117C74,115.35 74,113.7 74,112C74.66,111.67 75.32,111.34 76,111C76.33,111.66 76.66,112.32 77,113C77.99,111.35 78.98,109.7 80,108Z"
|
||||||
|
android:fillColor="#072706"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M172,77C176.47,79.5 180.77,82.11 185,85C182,86 182,86 178.81,84.56C177.88,84.05 176.96,83.53 176,83C176,82.34 176,81.68 176,81C174.68,81 173.36,81 172,81C172,79.68 172,78.36 172,77Z"
|
||||||
|
android:fillColor="#EFEE61"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M165,128C166.94,128.31 166.94,128.31 169,129C169.33,129.99 169.66,130.98 170,132C168.56,134.19 168.56,134.19 167,136C167,135.34 167,134.68 167,134C166.34,134 165.68,134 165,134C165,132.02 165,130.04 165,128Z"
|
||||||
|
android:fillColor="#CBCD1A"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M185,88C189.51,88.53 192.35,90.37 196,93C194,94 194,94 191.06,93.25C188.25,92.1 186.84,91.35 185,89C185,88.67 185,88.34 185,88Z"
|
||||||
|
android:fillColor="#DAC742"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M180,84C183.46,85.49 183.46,85.49 187,87C185.68,87.99 184.36,88.98 183,90C181.68,89.34 180.36,88.68 179,88C179.33,86.68 179.66,85.36 180,84Z"
|
||||||
|
android:fillColor="#F4F02D"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M163,77C163.99,77 164.98,77 166,77C165.67,80.96 165.34,84.92 165,89C164.67,89 164.34,89 164,89C163.02,84.95 162.92,81.16 163,77Z"
|
||||||
|
android:fillColor="#B6B91B"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M151,135C153.62,138.06 154,138.73 154,143C155.32,143.33 156.64,143.66 158,144C157.01,144.66 156.02,145.32 155,146C151.85,142.58 151.44,139.56 151,135Z"
|
||||||
|
android:fillColor="#46430F"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M68,108C70,111.75 70,111.75 70,114C68.35,114.33 66.7,114.66 65,115C65,113.35 65,111.7 65,110C65.99,110 66.98,110 68,110C68,109.34 68,108.68 68,108Z"
|
||||||
|
android:fillColor="#052503"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M153,85C157.4,85.5 159.71,87.09 163,90C162.67,90.66 162.34,91.32 162,92C161.34,91.67 160.68,91.34 160,91C160,90.34 160,89.68 160,89C158.35,88.67 156.7,88.34 155,88C155,87.34 155,86.68 155,86C154.34,85.67 153.68,85.34 153,85Z"
|
||||||
|
android:fillColor="#EBE749"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M172,81C173.32,81 174.64,81 176,81C175.67,82.98 175.34,84.96 175,87C174.01,87 173.02,87 172,87C172,85.02 172,83.04 172,81Z"
|
||||||
|
android:fillColor="#E7E81D"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M155,119C158.87,119.57 161.08,121.49 164,124C159.54,123.01 159.54,123.01 155,122C155,121.01 155,120.02 155,119Z"
|
||||||
|
android:fillColor="#C47B29"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M155,131C155.66,131.33 156.32,131.66 157,132C157,132.66 157,133.32 157,134C156.34,134 155.68,134 155,134C155,134.99 155,135.98 155,137C154.01,137 153.02,137 152,137C152.38,134.56 152.38,134.56 153,132C153.66,131.67 154.32,131.34 155,131Z"
|
||||||
|
android:fillColor="#7A8815"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M148,124C148.63,125.88 148.63,125.88 149,128C148.34,128.66 147.68,129.32 147,130C145.68,130 144.36,130 143,130C143.33,129.01 143.66,128.02 144,127C144.99,126.67 145.98,126.34 147,126C147.33,125.34 147.66,124.68 148,124Z"
|
||||||
|
android:fillColor="#D8DF49"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M141,119C143.97,119.33 146.94,119.66 150,120C150,120.33 150,120.66 150,121C148.35,121 146.7,121 145,121C145,121.99 145,122.98 145,124C144.34,124 143.68,124 143,124C142.67,123.34 142.34,122.68 142,122C141.34,122 140.68,122 140,122C140.33,121.01 140.66,120.02 141,119Z"
|
||||||
|
android:fillColor="#394F07"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M135,89C136.32,89.33 137.64,89.66 139,90C139,90.66 139,91.32 139,92C136.03,92.66 133.06,93.32 130,94C130,93.34 130,92.68 130,92C131.65,91.67 133.3,91.34 135,91C135,90.34 135,89.68 135,89Z"
|
||||||
|
android:fillColor="#F3F576"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M166,77C166.66,77 167.32,77 168,77C168,79.64 168,82.28 168,85C167.01,84.34 166.02,83.68 165,83C165.33,81.02 165.66,79.04 166,77Z"
|
||||||
|
android:fillColor="#CBC920"/>
|
||||||
|
<path
|
||||||
|
android:pathData="M111,143C111.33,143.66 111.66,144.32 112,145C111.34,144.67 110.68,144.34 110,144C110.33,143.67 110.66,143.34 111,143Z"
|
||||||
|
android:fillColor="#040000"/>
|
||||||
|
</vector>
|
||||||
5
app/src/main/res/drawable/rounded_button_red.xml
Normal file
5
app/src/main/res/drawable/rounded_button_red.xml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid android:color="@color/colorRed"/> <!-- couleur verte -->
|
||||||
|
<corners android:radius="5dp"/> <!-- coins arrondis -->
|
||||||
|
</shape>
|
||||||
128
app/src/main/res/layout/agent_item.xml
Normal file
128
app/src/main/res/layout/agent_item.xml
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@drawable/agent_item_border_rounded"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_margin="2sp"
|
||||||
|
android:paddingStart="16dp"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:paddingEnd="16dp"
|
||||||
|
android:paddingBottom="12dp">
|
||||||
|
|
||||||
|
<!-- Code -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_weight="1">
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_weight="0.8"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
>
|
||||||
|
<View
|
||||||
|
android:layout_width="12dp"
|
||||||
|
android:layout_height="12dp"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:layout_marginEnd="8sp"
|
||||||
|
android:background="@drawable/decorative_dot" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtCode"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:fontFamily="sans-serif-medium"
|
||||||
|
android:text="0001-l2"
|
||||||
|
android:textColor="#1A1A2E"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/details"
|
||||||
|
android:layout_width="25sp"
|
||||||
|
android:layout_height="25sp"
|
||||||
|
android:background="@drawable/agent_item_border_rounded"
|
||||||
|
android:layout_gravity="center_vertical"
|
||||||
|
android:src="@drawable/ic_chevron_right"/>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Contenu principal : date et adresse en horizontal avec space between -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:weightSum="1"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<!-- Date avec icône -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0.35"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
android:src="@drawable/ic_calendar"
|
||||||
|
app:tint="@color/primary_green" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtDate"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="12 mars 2024"
|
||||||
|
android:textColor="#4A5568"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Adresse avec icône -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="0.65"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="16dp"
|
||||||
|
android:layout_height="16dp"
|
||||||
|
android:src="@drawable/ic_location_small"
|
||||||
|
app:tint="@color/primary_green" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtAdresse"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="7dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:text="Badalabougou sema, Bamako, Mali"
|
||||||
|
android:textColor="#4A5568"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
@@ -10,7 +11,7 @@
|
|||||||
android:layout_width="64dp"
|
android:layout_width="64dp"
|
||||||
android:layout_height="64dp"
|
android:layout_height="64dp"
|
||||||
android:src="@android:drawable/ic_delete"
|
android:src="@android:drawable/ic_delete"
|
||||||
android:tint="#F44336"/>
|
app:tint="#F44336" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/txtMessage"
|
android:id="@+id/txtMessage"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
@@ -10,7 +11,8 @@
|
|||||||
android:layout_width="64dp"
|
android:layout_width="64dp"
|
||||||
android:layout_height="64dp"
|
android:layout_height="64dp"
|
||||||
android:src="@android:drawable/checkbox_on_background"
|
android:src="@android:drawable/checkbox_on_background"
|
||||||
android:tint="#4CAF50"/>
|
android:outlineSpotShadowColor="#4CAF50"
|
||||||
|
/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/txtMessage"
|
android:id="@+id/txtMessage"
|
||||||
|
|||||||
178
app/src/main/res/layout/fragment_agent_details.xml
Normal file
178
app/src/main/res/layout/fragment_agent_details.xml
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/background_gray">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<!-- Card pour les infos de l'agent -->
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
app:cardCornerRadius="12dp"
|
||||||
|
app:cardElevation="4dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_weight="1"
|
||||||
|
>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Détail de l'agent"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_green"
|
||||||
|
android:layout_weight="0.7"/>
|
||||||
|
<Switch
|
||||||
|
android:id="@+id/switch_access"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:ignore="UseSwitchCompatOrMaterialXml" />
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text="Code: "
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/secondary_yellow" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtCode"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:text=""
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/secondary_yellow" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Adresse: "
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/secondary_yellow" />
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/txtAdresse"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text=""
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/secondary_yellow" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Bouton d'accès avec icône -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Accès agent :"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/btn_access_toggle"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:clickable="true"
|
||||||
|
android:focusable="true"
|
||||||
|
android:padding="12dp"
|
||||||
|
android:background="?attr/selectableItemBackgroundBorderless" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<!-- Card pour les paris disponibles -->
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
|
app:cardCornerRadius="12dp"
|
||||||
|
app:cardElevation="4dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingVertical="16dp"
|
||||||
|
android:paddingHorizontal="3dp"
|
||||||
|
>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Paris disponibles"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_green"
|
||||||
|
android:layout_marginBottom="12dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Sélectionnez les paris :"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/secondary_yellow"
|
||||||
|
android:layout_marginBottom="8dp" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/betsRecyclerView"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
<!-- Bouton de validation -->
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btn_validate"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:text="Valider la sélection"
|
||||||
|
android:textSize="16sp"
|
||||||
|
app:cornerRadius="28dp"
|
||||||
|
app:icon="@drawable/ic_check"
|
||||||
|
app:iconGravity="textStart" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
21
app/src/main/res/layout/fragment_agent_management.xml
Normal file
21
app/src/main/res/layout/fragment_agent_management.xml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".AgentManagement">
|
||||||
|
|
||||||
|
<!-- TODO: Update blank fragment layout -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingTop="12dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/agentList"
|
||||||
|
android:layout_marginHorizontal="13sp"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
</androidx.recyclerview.widget.RecyclerView>
|
||||||
|
</LinearLayout>
|
||||||
|
</FrameLayout>
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:drawableStart="@drawable/hashtag"
|
android:drawableStart="@drawable/hashtag"
|
||||||
android:background="@drawable/edittext_outline_white"
|
android:background="@drawable/edittext_outline_white"
|
||||||
android:inputType="number"
|
android:inputType="text"
|
||||||
/>
|
/>
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/scan_ticket_btn"
|
android:id="@+id/scan_ticket_btn"
|
||||||
|
|||||||
@@ -54,20 +54,20 @@
|
|||||||
android:text="ANNULER TICKET"
|
android:text="ANNULER TICKET"
|
||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
android:textColor="#FFFFFF"/>
|
android:textColor="#FFFFFF"/>
|
||||||
<Button
|
<!-- <Button-->
|
||||||
android:id="@+id/report_btn"
|
<!-- android:id="@+id/report_btn"-->
|
||||||
android:layout_width="match_parent"
|
<!-- android:layout_width="match_parent"-->
|
||||||
android:layout_height="57dp"
|
<!-- android:layout_height="57dp"-->
|
||||||
android:textSize="21sp"
|
<!-- android:textSize="21sp"-->
|
||||||
android:textAlignment="textStart"
|
<!-- android:textAlignment="textStart"-->
|
||||||
android:layout_marginVertical="4sp"
|
<!-- android:layout_marginVertical="4sp"-->
|
||||||
android:background="@drawable/rounded_button_green"
|
<!-- android:background="@drawable/rounded_button_green"-->
|
||||||
android:fontFamily="sans-serif-medium"
|
<!-- android:fontFamily="sans-serif-medium"-->
|
||||||
android:backgroundTint="@color/primary_green"
|
<!-- android:backgroundTint="@color/primary_green"-->
|
||||||
android:drawableLeft="@drawable/tpe"
|
<!-- android:drawableLeft="@drawable/tpe"-->
|
||||||
android:text="RAPPORTS"
|
<!-- android:text="RAPPORTS"-->
|
||||||
android:textAllCaps="false"
|
<!-- android:textAllCaps="false"-->
|
||||||
android:textColor="#FFFFFF"/>
|
<!-- android:textColor="#FFFFFF"/>-->
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/last_bets_btn"
|
android:id="@+id/last_bets_btn"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -68,7 +68,7 @@
|
|||||||
android:textColor="#FFFFFF"/>
|
android:textColor="#FFFFFF"/>
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/settings"
|
android:id="@+id/settings"
|
||||||
android:tag="@id/tag_pin_exempt"
|
android:tag="tag_pin_exempt"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="57dp"
|
android:layout_height="57dp"
|
||||||
android:textSize="23sp"
|
android:textSize="23sp"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<FrameLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@@ -212,23 +213,28 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="30sp"
|
android:layout_marginTop="30sp"
|
||||||
android:gravity="center">
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/cancel"
|
android:id="@+id/cancel"
|
||||||
android:layout_width="200dp"
|
android:layout_width="0dp"
|
||||||
android:layout_marginRight="3sp"
|
|
||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
android:background="@color/primary_red"
|
android:background="@color/primary_red"
|
||||||
android:text="@string/cancel"/>
|
android:text="@string/cancel"/>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/validate"
|
android:id="@+id/validate"
|
||||||
android:layout_marginLeft="3sp"
|
android:layout_width="0dp"
|
||||||
android:layout_width="200dp"
|
|
||||||
android:layout_height="40dp"
|
android:layout_height="40dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
android:background="@color/primary_green"
|
android:background="@color/primary_green"
|
||||||
android:text="@string/validate"/>
|
android:text="@string/validate"/>
|
||||||
</LinearLayout>
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|||||||
@@ -12,19 +12,19 @@
|
|||||||
android:gravity="start"
|
android:gravity="start"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:visibility="visible">
|
android:visibility="visible">
|
||||||
<Button
|
<!-- <Button-->
|
||||||
android:id="@+id/agent"
|
<!-- android:id="@+id/agent"-->
|
||||||
android:layout_width="match_parent"
|
<!-- android:layout_width="match_parent"-->
|
||||||
android:layout_height="60dp"
|
<!-- android:layout_height="60dp"-->
|
||||||
android:textSize="21sp"
|
<!-- android:textSize="21sp"-->
|
||||||
android:textAlignment="center"
|
<!-- android:textAlignment="center"-->
|
||||||
android:layout_marginVertical="4sp"
|
<!-- android:layout_marginVertical="4sp"-->
|
||||||
android:background="@drawable/rounded_button_green"
|
<!-- android:background="@drawable/rounded_button_green"-->
|
||||||
android:fontFamily="sans-serif-medium"
|
<!-- android:fontFamily="sans-serif-medium"-->
|
||||||
android:backgroundTint="@color/primary_green"
|
<!-- android:backgroundTint="@color/primary_green"-->
|
||||||
android:text="@string/agents_setting"
|
<!-- android:text="@string/agents_setting"-->
|
||||||
android:textAllCaps="false"
|
<!-- android:textAllCaps="false"-->
|
||||||
android:textColor="#FFFFFF"/>
|
<!-- android:textColor="#FFFFFF"/>-->
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/change_pin"
|
android:id="@+id/change_pin"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -40,6 +40,7 @@
|
|||||||
android:textColor="#FFFFFF"/>
|
android:textColor="#FFFFFF"/>
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/server_config"
|
android:id="@+id/server_config"
|
||||||
|
android:tag="tag_pin_exempt"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="60dp"
|
android:layout_height="60dp"
|
||||||
android:textSize="21sp"
|
android:textSize="21sp"
|
||||||
@@ -66,6 +67,7 @@
|
|||||||
android:textColor="#FFFFFF"/>
|
android:textColor="#FFFFFF"/>
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/logs"
|
android:id="@+id/logs"
|
||||||
|
android:tag="tag_pin_exempt"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="60dp"
|
android:layout_height="60dp"
|
||||||
android:textSize="21sp"
|
android:textSize="21sp"
|
||||||
|
|||||||
130
app/src/main/res/layout/fragment_update_pin.xml
Normal file
130
app/src/main/res/layout/fragment_update_pin.xml
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:context=".UpdatePin">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:paddingHorizontal="10sp"
|
||||||
|
android:paddingTop="30sp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="100sp"
|
||||||
|
android:layout_height="100sp"
|
||||||
|
android:src="@android:drawable/ic_lock_idle_lock"
|
||||||
|
android:padding="10sp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
app:tint="@color/primary_green">
|
||||||
|
|
||||||
|
</ImageView>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="40sp"
|
||||||
|
android:text="Changer pin"
|
||||||
|
android:layout_marginBottom="20sp"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_green">
|
||||||
|
</TextView>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_marginBottom="10sp">
|
||||||
|
<TextView
|
||||||
|
android:layout_marginBottom="7sp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Ancien pin"
|
||||||
|
android:textSize="16sp"
|
||||||
|
tools:ignore="HardcodedText"/>
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/old_pin"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:hint="2343234"
|
||||||
|
android:drawablePadding="5dp"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:drawableStart="@drawable/hashtag"
|
||||||
|
android:background="@drawable/edittext_outline_white"
|
||||||
|
android:inputType="numberPassword" />
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_marginBottom="10sp">
|
||||||
|
<TextView
|
||||||
|
android:layout_marginBottom="7sp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Nouveau pin"
|
||||||
|
android:textSize="16sp"
|
||||||
|
tools:ignore="HardcodedText"/>
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/new_pin"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:hint="2343234"
|
||||||
|
android:drawablePadding="5dp"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:drawableStart="@drawable/hashtag"
|
||||||
|
android:background="@drawable/edittext_outline_white"
|
||||||
|
android:inputType="numberPassword"/>
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_marginBottom="10sp">
|
||||||
|
<TextView
|
||||||
|
android:layout_marginBottom="7sp"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Confirmation pin"
|
||||||
|
android:textSize="16sp"
|
||||||
|
tools:ignore="HardcodedText"/>
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/pin_confirmation"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:hint="2343234"
|
||||||
|
android:drawablePadding="5dp"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:drawableStart="@drawable/hashtag"
|
||||||
|
android:background="@drawable/edittext_outline_white"
|
||||||
|
android:inputType="numberPassword" />
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_marginTop="35sp"
|
||||||
|
android:showDividers="middle"
|
||||||
|
android:dividerPadding="10sp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
<Button
|
||||||
|
android:id="@+id/cancel"
|
||||||
|
android:layout_width="150sp"
|
||||||
|
android:layout_marginEnd="5sp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/cancel"
|
||||||
|
android:background="@drawable/rounded_button_red">
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
android:id="@+id/validate"
|
||||||
|
android:layout_width="150sp"
|
||||||
|
android:layout_marginStart="5sp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/validate"
|
||||||
|
android:background="@drawable/rounded_button_green">
|
||||||
|
</Button>
|
||||||
|
</LinearLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:drawableStart="@drawable/hashtag"
|
android:drawableStart="@drawable/hashtag"
|
||||||
android:background="@drawable/edittext_outline_white"
|
android:background="@drawable/edittext_outline_white"
|
||||||
android:inputType="number"
|
android:inputType="text"
|
||||||
/>
|
/>
|
||||||
<ImageButton
|
<ImageButton
|
||||||
android:id="@+id/scan_ticket_btn"
|
android:id="@+id/scan_ticket_btn"
|
||||||
|
|||||||
@@ -13,10 +13,10 @@
|
|||||||
android:padding="18dp"
|
android:padding="18dp"
|
||||||
android:background="@drawable/course_item_border">
|
android:background="@drawable/course_item_border">
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="horizontal"
|
||||||
android:layout_gravity="center_vertical">
|
android:layout_gravity="start">
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="50dp"
|
android:layout_width="50dp"
|
||||||
android:layout_height="50dp"
|
android:layout_height="50dp"
|
||||||
@@ -24,14 +24,15 @@
|
|||||||
</ImageView>
|
</ImageView>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/tvName"
|
android:id="@+id/tvName"
|
||||||
|
android:text="GP SANGARE"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textSize="18sp"
|
android:textSize="16sp"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textFontWeight="500"
|
android:textFontWeight="500"
|
||||||
android:fontFamily="sans-serif-medium">
|
android:fontFamily="sans-serif-medium">
|
||||||
|
|||||||
@@ -2,18 +2,30 @@
|
|||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="12dp"
|
android:padding="8dp"
|
||||||
android:layout_marginVertical="10dp"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@color/white">
|
android:background="@color/white">
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:gravity="center_vertical"
|
android:gravity="end">
|
||||||
android:layout_marginBottom="8dp">
|
<TextView
|
||||||
|
android:id="@+id/tv_statut"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Statut"
|
||||||
|
android:textSize="20sp">
|
||||||
|
</TextView>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Première ligne : Course et Type -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/last_bet_course"
|
android:id="@+id/last_bet_course"
|
||||||
@@ -21,14 +33,13 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="Course: 5"
|
android:text="Course: 5"
|
||||||
android:textSize="16sp"
|
android:textSize="14sp"
|
||||||
android:gravity="start"
|
android:padding="2dp" />
|
||||||
android:padding="4dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.divider.MaterialDivider
|
<com.google.android.material.divider.MaterialDivider
|
||||||
android:layout_width="1dp"
|
android:layout_width="1dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="16dp"
|
||||||
android:layout_marginHorizontal="8dp"
|
android:layout_marginHorizontal="4dp"
|
||||||
app:dividerColor="@color/black" />
|
app:dividerColor="@color/black" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -37,24 +48,18 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="QUARTE + TIERCE"
|
android:text="QUARTE + TIERCE"
|
||||||
android:textSize="16sp"
|
android:textSize="12sp"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
android:padding="4dp" />
|
android:padding="2dp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<com.google.android.material.divider.MaterialDivider
|
<!-- Deuxième ligne : Référence et Type de pari -->
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="1dp"
|
|
||||||
android:layout_marginBottom="5dp"
|
|
||||||
app:dividerColor="@color/black"/>
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:layout_marginBottom="3dp">
|
android:layout_marginTop="2dp">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/reference_ticket"
|
android:id="@+id/reference_ticket"
|
||||||
@@ -62,14 +67,13 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="12573829288"
|
android:text="12573829288"
|
||||||
android:textSize="16sp"
|
android:textSize="12sp"
|
||||||
android:gravity="start"
|
android:padding="2dp" />
|
||||||
android:padding="4dp" />
|
|
||||||
|
|
||||||
<com.google.android.material.divider.MaterialDivider
|
<com.google.android.material.divider.MaterialDivider
|
||||||
android:layout_width="1dp"
|
android:layout_width="1dp"
|
||||||
android:layout_height="24dp"
|
android:layout_height="16dp"
|
||||||
android:layout_marginHorizontal="8dp"
|
android:layout_marginHorizontal="4dp"
|
||||||
app:dividerColor="@color/black" />
|
app:dividerColor="@color/black" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
@@ -78,25 +82,70 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="TIERCE"
|
android:text="TIERCE"
|
||||||
android:textSize="16sp"
|
android:textSize="13sp"
|
||||||
android:textFontWeight="900"
|
android:textStyle="bold"
|
||||||
android:gravity="end"
|
android:gravity="end"
|
||||||
android:padding="4dp" />
|
android:padding="2dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Troisième ligne : Chevaux et Mise -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:layout_marginTop="2dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/last_bet_horses"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Horses: 3-7-9"
|
||||||
|
android:textSize="13sp"
|
||||||
|
android:padding="2dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/last_bet_mise"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Mise: 500 CFA"
|
||||||
|
android:textSize="13sp"
|
||||||
|
android:padding="2dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Séparateur avant le dropdown -->
|
||||||
|
<com.google.android.material.divider.MaterialDivider
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginVertical="6dp"
|
||||||
|
app:dividerColor="@color/black" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_annuler"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:background="@drawable/rounded_button_red"
|
||||||
|
android:text="Annuler" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_imprimer"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:background="@drawable/rounded_button_green"
|
||||||
|
android:text="Imprimer" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<TextView
|
|
||||||
android:id="@+id/last_bet_horses"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Horses: 3-7-9"
|
|
||||||
android:textSize="16sp"
|
|
||||||
android:layout_marginTop="4dp"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/last_bet_mise"
|
</LinearLayout>
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="Mise: 500 CFA"
|
|
||||||
android:textSize="16sp"
|
|
||||||
android:layout_marginTop="4dp"/>
|
|
||||||
</LinearLayout>
|
|
||||||
78
app/src/main/res/layout/multi_type_of_bet_item.xml
Normal file
78
app/src/main/res/layout/multi_type_of_bet_item.xml
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="8dp">
|
||||||
|
|
||||||
|
<androidx.cardview.widget.CardView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:cardCornerRadius="12dp"
|
||||||
|
app:cardElevation="2dp"
|
||||||
|
app:cardBackgroundColor="@android:color/white">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:background="?selectableItemBackground">
|
||||||
|
|
||||||
|
<!-- Icône avec cercle de fond -->
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:background="@drawable/circle_bg_light">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/iv_bet_icon"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_centerInParent="true"
|
||||||
|
android:src="@drawable/bet_item_icon"
|
||||||
|
app:tint="@color/primary_green" />
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
<!-- Texte -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_bet_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Type de pari"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="#333333" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_bet_description"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Description"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="#999999"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- CheckBox -->
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/checkbox_bet"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:buttonTint="@color/primary_green" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.cardview.widget.CardView>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
283
app/src/main/res/layout/pay_confirmation_layout.xml
Normal file
283
app/src/main/res/layout/pay_confirmation_layout.xml
Normal file
@@ -0,0 +1,283 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
app:cardElevation="8dp"
|
||||||
|
app:cardBackgroundColor="@android:color/white">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="20dp">
|
||||||
|
|
||||||
|
<!-- En-tête avec statut -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginBottom="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_statut"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Statut: ENREGISTRÉ"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_green" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_date_heure"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Date et heure"
|
||||||
|
android:textSize="12sp"
|
||||||
|
android:textColor="@color/colorAccent" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Séparateur -->
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="@color/login_background"
|
||||||
|
android:layout_marginBottom="16dp" />
|
||||||
|
|
||||||
|
<!-- Numéro de la course -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginBottom="12dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Numéro course :"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_green" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_numero_course"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="5"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/primary_green" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Nom de la course -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginBottom="12dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Nom course :"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_green" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_nom_course"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="Prix de l'Arc de Triomphe"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/primary_green" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Numéro Ticket -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginBottom="12dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="N° Ticket :"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_green" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_numero_ticket"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="T-2024-001234"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/primary_green"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Date de prise -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginBottom="12dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Date prise :"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_green" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_date_prise"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="15/03/2024 14:30"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/primary_green" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Combinaison -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginBottom="12dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Combinaison :"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_green" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_combinaison"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="5 - 8 - 12 - 15"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/primary_green"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/notes_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:visibility="gone"
|
||||||
|
android:layout_marginBottom="12sp"
|
||||||
|
android:layout_gravity="start">
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/notes"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="2 ordres, 6 desordres"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/primary_green"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Montant -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/tv_montant_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_marginBottom="20dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="100dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Montant :"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_green" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_montant"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="1 000 FCFA"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:textColor="@color/primary_green" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Séparateur -->
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:background="@color/background_gray"
|
||||||
|
android:layout_marginBottom="16dp" />
|
||||||
|
|
||||||
|
<!-- Message dynamique selon statut -->
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_message_statut"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Veuillez confirmer l'enregistrement de ce pari"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:textColor="@color/primary_green"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginBottom="20dp"
|
||||||
|
android:padding="5dp"
|
||||||
|
android:background="@color/green_opacity_30"
|
||||||
|
android:visibility="visible" />
|
||||||
|
|
||||||
|
<!-- Boutons Confirmer et Annuler -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btn_annuler"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginEnd="8dp"
|
||||||
|
android:text="Annuler"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:cornerRadius="8dp"
|
||||||
|
style="@style/Widget.Material3.Button.OutlinedButton" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/btn_confirmer"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:text="Confirmer"
|
||||||
|
android:textSize="14sp"
|
||||||
|
app:cornerRadius="8dp"
|
||||||
|
style="@style/Widget.Material3.Button" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
@@ -35,7 +35,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="45dp"
|
android:layout_height="45dp"
|
||||||
android:hint="@string/code_message"
|
android:hint="@string/code_message"
|
||||||
android:inputType="number"
|
android:inputType="text"
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
android:layout_marginVertical="13sp"
|
android:layout_marginVertical="13sp"
|
||||||
android:textFontWeight="600"
|
android:textFontWeight="600"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
<background android:drawable="@color/white" />
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
<foreground android:drawable="@drawable/logo_svg" />
|
||||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
<monochrome android:drawable="@drawable/logo_svg" />
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<background android:drawable="@drawable/ic_launcher_background" />
|
<background android:drawable="@color/white"/>
|
||||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
<foreground android:drawable="@drawable/logo_svg"/>
|
||||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
<monochrome android:drawable="@drawable/logo_svg" />
|
||||||
</adaptive-icon>
|
</adaptive-icon>
|
||||||
@@ -4,4 +4,9 @@
|
|||||||
<item>Espèce</item>
|
<item>Espèce</item>
|
||||||
<item>Orange Money</item>
|
<item>Orange Money</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
<string-array name="action_options">
|
||||||
|
<item>Imprimer</item>
|
||||||
|
<item>Annuler</item>
|
||||||
|
</string-array>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -10,6 +10,7 @@
|
|||||||
<color name="text_color">#333333</color>
|
<color name="text_color">#333333</color>
|
||||||
<color name="green_opacity_30">#501C5A29</color>
|
<color name="green_opacity_30">#501C5A29</color>
|
||||||
<color name="red_opacity_10">#50C31617</color>
|
<color name="red_opacity_10">#50C31617</color>
|
||||||
|
<color name="background_gray">#F5F5F5</color>
|
||||||
<color name="text_light_grey">#e8e8e8</color>
|
<color name="text_light_grey">#e8e8e8</color>
|
||||||
<color name="transparent">#00000000</color>
|
<color name="transparent">#00000000</color>
|
||||||
<color name="white">#ffffff</color>
|
<color name="white">#ffffff</color>
|
||||||
|
|||||||
@@ -19,4 +19,4 @@ android.enableJetifier=true
|
|||||||
# Enables namespacing of each library's R class so that its R class includes only the
|
# Enables namespacing of each library's R class so that its R class includes only the
|
||||||
# resources declared in the library itself and none from the library's dependencies,
|
# resources declared in the library itself and none from the library's dependencies,
|
||||||
# thereby reducing the size of the R class for that library
|
# thereby reducing the size of the R class for that library
|
||||||
android.nonTransitiveRClass=true
|
android.nonTransitiveRClass=true
|
||||||
|
|||||||
@@ -14,12 +14,16 @@ navigationUi = "2.6.0"
|
|||||||
googleAndroidLibrariesMapsplatformSecretsGradlePlugin = "2.0.1"
|
googleAndroidLibrariesMapsplatformSecretsGradlePlugin = "2.0.1"
|
||||||
okhttp = "4.12.0"
|
okhttp = "4.12.0"
|
||||||
playServicesMaps = "18.1.0"
|
playServicesMaps = "18.1.0"
|
||||||
|
printerlibrary = "1.0.23"
|
||||||
recyclerviewV7 = "28.0.0"
|
recyclerviewV7 = "28.0.0"
|
||||||
retrofit = "2.11.0"
|
retrofit = "2.11.0"
|
||||||
rxandroid = "1.2.1"
|
rxandroid = "1.2.1"
|
||||||
|
rxandroidVersion = "2.1.1"
|
||||||
rxjava = "1.3.8"
|
rxjava = "1.3.8"
|
||||||
kotlin = "1.9.24"
|
kotlin = "1.9.24"
|
||||||
coreKtx = "1.17.0"
|
coreKtx = "1.17.0"
|
||||||
|
rxjavaVersion = "2.2.21"
|
||||||
|
stompprotocolandroid = "1.6.6"
|
||||||
swiperefreshlayout = "1.1.0"
|
swiperefreshlayout = "1.1.0"
|
||||||
core = "1.5.0"
|
core = "1.5.0"
|
||||||
fragmentTesting = "1.6.2"
|
fragmentTesting = "1.6.2"
|
||||||
@@ -52,6 +56,7 @@ navigation-fragment = { group = "androidx.navigation", name = "navigation-fragme
|
|||||||
navigation-ui = { group = "androidx.navigation", name = "navigation-ui", version.ref = "navigationUi" }
|
navigation-ui = { group = "androidx.navigation", name = "navigation-ui", version.ref = "navigationUi" }
|
||||||
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
|
||||||
play-services-maps = { group = "com.google.android.gms", name = "play-services-maps", version.ref = "playServicesMaps" }
|
play-services-maps = { group = "com.google.android.gms", name = "play-services-maps", version.ref = "playServicesMaps" }
|
||||||
|
printerlibrary = { module = "com.sunmi:printerlibrary", version.ref = "printerlibrary" }
|
||||||
recyclerview-v7 = { module = "com.android.support:recyclerview-v7", version.ref = "recyclerviewV7" }
|
recyclerview-v7 = { module = "com.android.support:recyclerview-v7", version.ref = "recyclerviewV7" }
|
||||||
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
|
retrofit = { module = "com.squareup.retrofit2:retrofit", version.ref = "retrofit" }
|
||||||
room-compiler = { module = "androidx.room:room-compiler", version.ref = "roomCommonJvm" }
|
room-compiler = { module = "androidx.room:room-compiler", version.ref = "roomCommonJvm" }
|
||||||
@@ -59,6 +64,9 @@ room-runtime = { module = "androidx.room:room-runtime", version.ref = "roomCommo
|
|||||||
rxandroid = { module = "io.reactivex:rxandroid", version.ref = "rxandroid" }
|
rxandroid = { module = "io.reactivex:rxandroid", version.ref = "rxandroid" }
|
||||||
rxjava = { module = "io.reactivex:rxjava", version.ref = "rxjava" }
|
rxjava = { module = "io.reactivex:rxjava", version.ref = "rxjava" }
|
||||||
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||||
|
rxjava2-rxandroid = { module = "io.reactivex.rxjava2:rxandroid", version.ref = "rxandroidVersion" }
|
||||||
|
stompprotocolandroid = { module = "com.github.NaikSoftware:StompProtocolAndroid", version.ref = "stompprotocolandroid" }
|
||||||
|
rxjava2-rxjava = { module = "io.reactivex.rxjava2:rxjava", version.ref = "rxjavaVersion" }
|
||||||
swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version.ref = "swiperefreshlayout" }
|
swiperefreshlayout = { module = "androidx.swiperefreshlayout:swiperefreshlayout", version.ref = "swiperefreshlayout" }
|
||||||
core = { module = "androidx.test:core", version.ref = "core" }
|
core = { module = "androidx.test:core", version.ref = "core" }
|
||||||
fragment-testing = { module = "androidx.fragment:fragment-testing", version.ref = "fragmentTesting" }
|
fragment-testing = { module = "androidx.fragment:fragment-testing", version.ref = "fragmentTesting" }
|
||||||
|
|||||||
BIN
key_store.jks
Normal file
BIN
key_store.jks
Normal file
Binary file not shown.
@@ -25,6 +25,7 @@ import com.anggastudio.printama.constants.PW;
|
|||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Printama is a lightweight Android library for printing text and bitmaps to ESC/POS Bluetooth
|
* Printama is a lightweight Android library for printing text and bitmaps to ESC/POS Bluetooth
|
||||||
@@ -280,6 +281,8 @@ public class Printama {
|
|||||||
Pref.setBoolean(Pref.IS_PRINTER_3INCH, is3inches);
|
Pref.setBoolean(Pref.IS_PRINTER_3INCH, is3inches);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static boolean is3inchesPrinter() {
|
public static boolean is3inchesPrinter() {
|
||||||
return Pref.getBoolean(Pref.IS_PRINTER_3INCH);
|
return Pref.getBoolean(Pref.IS_PRINTER_3INCH);
|
||||||
}
|
}
|
||||||
@@ -311,6 +314,27 @@ public class Printama {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAllPaperStatusCommands(){
|
||||||
|
_printama.connect(printama -> {
|
||||||
|
_util.testAllPaperStatusCommands();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkPaperStatus(Consumer<String> status){
|
||||||
|
_printama.connect(printama -> {
|
||||||
|
String paperStatus = _util.checkPaperStatus();
|
||||||
|
status.accept(paperStatus);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void isQueued(Consumer<Integer> status){
|
||||||
|
_printama.connect(printama -> {
|
||||||
|
int isQueued = _util.isQueued();
|
||||||
|
status.accept(isQueued);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean isConnected() {
|
public boolean isConnected() {
|
||||||
return _util.isConnected();
|
return _util.isConnected();
|
||||||
}
|
}
|
||||||
@@ -356,22 +380,62 @@ public class Printama {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void printTextBuilder(StringBuilder text, Bitmap bitmap, String numeroTicket,Bitmap barCode){
|
|
||||||
|
public void printTextBuilder(StringBuilder text, Bitmap bitmap, String numeroTicket, Bitmap barCode, PrintCallback callback) {
|
||||||
|
_printama.connect(printama -> {
|
||||||
|
try {
|
||||||
|
_util.resetPrinter();
|
||||||
|
_util.setBold();
|
||||||
|
_util.printImage(bitmap);
|
||||||
|
_util.printText(printama.lineSeparator() + "\n");
|
||||||
|
_util.setBold();
|
||||||
|
_util.printImage(barCode);
|
||||||
|
_util.setBold();
|
||||||
|
_util.setNormalText();
|
||||||
|
_util.setAlign(PA.CENTER);
|
||||||
|
_util.printText(numeroTicket);
|
||||||
|
_util.printText("\n" + printama.lineSeparator() + "\n");
|
||||||
|
_util.setBold();
|
||||||
|
_util.setNormalText();
|
||||||
|
_util.setAlign(0);
|
||||||
|
_util.setAlign(PA.LEFT);
|
||||||
|
_util.printText(text.toString());
|
||||||
|
_util.printText(printama.lineSeparator() + "\n");
|
||||||
|
_util.setBold();
|
||||||
|
_util.setNormalText();
|
||||||
|
_util.setAlign(PA.CENTER);
|
||||||
|
_util.printText("Powered by PMU-MALI");
|
||||||
|
_util.printText("\n" + printama.lineSeparator() + "\n");
|
||||||
|
_util.printText("\n\n\n");
|
||||||
|
printama.feedPaper();
|
||||||
|
printama.close();
|
||||||
|
if (callback != null) callback.onResult(true, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
if (callback != null) callback.onResult(false, e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}, error -> {
|
||||||
|
if (callback != null) callback.onResult(false, error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface PrintCallback{
|
||||||
|
void onResult(boolean success, String errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void printSold(Bitmap bitmap, String title, StringBuilder text){
|
||||||
_printama.connect(printama -> {
|
_printama.connect(printama -> {
|
||||||
_util.resetPrinter();
|
_util.resetPrinter();
|
||||||
_util.setBold();
|
_util.setBold();
|
||||||
_util.printImage(bitmap);
|
_util.printImage(bitmap);
|
||||||
_util.printText(printama.lineSeparator()+"\n");
|
_util.printText(lineSeparator());
|
||||||
_util.setBold();
|
|
||||||
_util.printImage(barCode);
|
|
||||||
_util.setBold();
|
|
||||||
_util.setNormalText();
|
|
||||||
_util.setAlign(PA.CENTER);
|
_util.setAlign(PA.CENTER);
|
||||||
_util.printText(numeroTicket);
|
|
||||||
_util.printText("\n"+printama.lineSeparator()+"\n");
|
|
||||||
_util.setBold();
|
_util.setBold();
|
||||||
|
_util.printText(title+"\n");
|
||||||
|
_util.setNormalText();
|
||||||
|
_util.printText(lineSeparator()+"\n");
|
||||||
_util.setNormalText();
|
_util.setNormalText();
|
||||||
_util.setAlign(0);
|
|
||||||
_util.setAlign(PA.LEFT);
|
_util.setAlign(PA.LEFT);
|
||||||
_util.printText(text.toString());
|
_util.printText(text.toString());
|
||||||
_util.printText(printama.lineSeparator()+"\n");
|
_util.printText(printama.lineSeparator()+"\n");
|
||||||
@@ -380,6 +444,7 @@ public class Printama {
|
|||||||
_util.setAlign(PA.CENTER);
|
_util.setAlign(PA.CENTER);
|
||||||
_util.printText("Powered by PMU-MALI");
|
_util.printText("Powered by PMU-MALI");
|
||||||
_util.printText("\n"+printama.lineSeparator()+"\n");
|
_util.printText("\n"+printama.lineSeparator()+"\n");
|
||||||
|
_util.printText("\n\n\n");
|
||||||
printama.feedPaper();
|
printama.feedPaper();
|
||||||
printama.close();
|
printama.close();
|
||||||
});
|
});
|
||||||
@@ -522,7 +587,19 @@ public class Printama {
|
|||||||
//----------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
public void printText(String text) {
|
public void printText(String text) {
|
||||||
printText(text, PA.LEFT);
|
_printama.connect((printama)->{
|
||||||
|
_util.printText(text);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void myPrintText(String text, Consumer<String> callback) {
|
||||||
|
_printama.connect(printama -> {
|
||||||
|
if(_util.printText(text)){
|
||||||
|
callback.accept("L'impression a été effectuée avec succès");
|
||||||
|
}else{
|
||||||
|
callback.accept("L'impression a échoué");
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -676,6 +753,8 @@ public class Printama {
|
|||||||
return spaces.toString();
|
return spaces.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------
|
||||||
// COLUMN FORMATTERS
|
// COLUMN FORMATTERS
|
||||||
//----------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import com.anggastudio.printama.constants.PW;
|
|||||||
import com.anggastudio.printama.util.StrUtil;
|
import com.anggastudio.printama.util.StrUtil;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -54,6 +55,7 @@ class PrinterUtil {
|
|||||||
private final BluetoothDevice printer;
|
private final BluetoothDevice printer;
|
||||||
private BluetoothSocket btSocket = null;
|
private BluetoothSocket btSocket = null;
|
||||||
private OutputStream btOutputStream = null;
|
private OutputStream btOutputStream = null;
|
||||||
|
private InputStream btInputStream = null;
|
||||||
private boolean is3InchPrinter;
|
private boolean is3InchPrinter;
|
||||||
|
|
||||||
PrinterUtil(BluetoothDevice printer) {
|
PrinterUtil(BluetoothDevice printer) {
|
||||||
@@ -67,6 +69,7 @@ class PrinterUtil {
|
|||||||
btSocket = socket;
|
btSocket = socket;
|
||||||
try {
|
try {
|
||||||
btOutputStream = socket.getOutputStream();
|
btOutputStream = socket.getOutputStream();
|
||||||
|
btInputStream = socket.getInputStream();
|
||||||
successListener.onConnected();
|
successListener.onConnected();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
failedListener.onFailed();
|
failedListener.onFailed();
|
||||||
@@ -80,8 +83,27 @@ class PrinterUtil {
|
|||||||
}).execute(printer);
|
}).execute(printer);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isConnected() {
|
boolean isConnected() {
|
||||||
return btSocket != null && btSocket.isConnected();
|
if (btSocket == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Tester la connexion en vérifiant le flux d'entrée
|
||||||
|
if (btSocket.isConnected()) {
|
||||||
|
// Vérifier si le flux est accessible
|
||||||
|
InputStream inputStream = btSocket.getInputStream();
|
||||||
|
// Tenter de lire avec un timeout très court
|
||||||
|
if (inputStream.available() >= 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Exception signifie que la connexion est perdue
|
||||||
|
Log.e("Bluetooth", "Socket non connecté: " + e.getMessage());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void finish() {
|
void finish() {
|
||||||
@@ -122,12 +144,25 @@ class PrinterUtil {
|
|||||||
String s = StrUtil.encodeNonAscii(text);
|
String s = StrUtil.encodeNonAscii(text);
|
||||||
btOutputStream.write(s.getBytes());
|
btOutputStream.write(s.getBytes());
|
||||||
return true;
|
return true;
|
||||||
} catch (IOException e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String textTest(String text){
|
||||||
|
try{
|
||||||
|
String s = StrUtil.encodeNonAscii(text);
|
||||||
|
btOutputStream.write(s.getBytes());
|
||||||
|
btOutputStream.flush();
|
||||||
|
int available = btInputStream.available();
|
||||||
|
return String.valueOf(available);
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
return "Erreur: "+e.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean printTextBuilder(StringBuilder text){
|
boolean printTextBuilder(StringBuilder text){
|
||||||
try {
|
try {
|
||||||
String tspl = ""+ text + "\r\n";
|
String tspl = ""+ text + "\r\n";
|
||||||
@@ -140,6 +175,61 @@ class PrinterUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vérifie si l'imprimante a une opération en attente ou en cours
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* 0 = Aucune opération (imprimante prête)
|
||||||
|
* 1 = Opération en cours d'impression
|
||||||
|
* 2 = Opération en attente (buffer plein)
|
||||||
|
* -1 = Erreur / impossible de déterminer
|
||||||
|
*/
|
||||||
|
public int isQueued() {
|
||||||
|
try {
|
||||||
|
// Vider le buffer d'entrée avant d'envoyer la commande
|
||||||
|
while (btInputStream != null && btInputStream.available() > 0) {
|
||||||
|
btInputStream.read();
|
||||||
|
}
|
||||||
|
// Commande DLE EOT 1 - Statut en temps réel
|
||||||
|
byte[] command = new byte[]{0x10, 0x04, 0x01};
|
||||||
|
btOutputStream.write(command);
|
||||||
|
btOutputStream.flush();
|
||||||
|
|
||||||
|
// Attendre 100ms pour la réponse
|
||||||
|
Thread.sleep(100);
|
||||||
|
|
||||||
|
// Lire la réponse (1 octet)
|
||||||
|
if (btInputStream != null && btInputStream.available() > 0) {
|
||||||
|
byte[] response = new byte[1];
|
||||||
|
int bytesRead = btInputStream.read(response);
|
||||||
|
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
byte status = response[0];
|
||||||
|
|
||||||
|
// Bit 1 (0x02) = Imprimante en cours d'impression
|
||||||
|
if ((status & 0x02) != 0) {
|
||||||
|
return 1; // Opération en cours
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bit 3 (0x08) = Buffer plein / attente
|
||||||
|
if ((status & 0x08) != 0) {
|
||||||
|
return 2; // Opération en attente
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; // Aucune opération
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pas de réponse
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e(TAG, "Erreur isQueued: " + e.getMessage());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setNormalizedForAll(){
|
void setNormalizedForAll(){
|
||||||
printUnicode(NORMALIZED_FOR_ALL);
|
printUnicode(NORMALIZED_FOR_ALL);
|
||||||
}
|
}
|
||||||
@@ -243,6 +333,191 @@ class PrinterUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAllPaperStatusCommands() {
|
||||||
|
// Liste des commandes à tester
|
||||||
|
int[][] commands = {
|
||||||
|
{0x1D, 0x72, 0x01}, // GS r 1 - Standard paper status
|
||||||
|
{0x10, 0x04, 0x01}, // DLE EOT 1 - Real-time status
|
||||||
|
{0x10, 0x04, 0x04}, // DLE EOT 4 - Paper sensor status
|
||||||
|
{0x1B, 0x76, 0x00}, // ESC v 0 - Paper sensor
|
||||||
|
{0x1D, 0x61, 0x01}, // GS a 1 - Enable real-time mode
|
||||||
|
{0x1D, 0x49, 0x01}, // GS I 1 - Printer ID
|
||||||
|
{0x1B, 0x69, 0x00} // ESC i 0 - Printer status
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < commands.length; i++) {
|
||||||
|
try {
|
||||||
|
Log.e("TEST", "========================================");
|
||||||
|
Log.e("TEST", "Test commande " + i + ": " + bytesToHex(commands[i]));
|
||||||
|
|
||||||
|
// Nettoyer buffer
|
||||||
|
while (btInputStream.available() > 0) {
|
||||||
|
btInputStream.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Envoyer commande
|
||||||
|
byte[] cmd = new byte[commands[i].length];
|
||||||
|
for (int j = 0; j < commands[i].length; j++) {
|
||||||
|
cmd[j] = (byte) commands[i][j];
|
||||||
|
}
|
||||||
|
btOutputStream.write(cmd);
|
||||||
|
btOutputStream.flush();
|
||||||
|
|
||||||
|
// Attendre réponse
|
||||||
|
Thread.sleep(300);
|
||||||
|
|
||||||
|
// Lire réponse
|
||||||
|
byte[] response = new byte[16];
|
||||||
|
int totalRead = 0;
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
while (totalRead < response.length && System.currentTimeMillis() - startTime < 1000) {
|
||||||
|
if (btInputStream.available() > 0) {
|
||||||
|
int read = btInputStream.read(response, totalRead, response.length - totalRead);
|
||||||
|
if (read > 0) {
|
||||||
|
totalRead += read;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Thread.sleep(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (totalRead > 0) {
|
||||||
|
Log.e("TEST", "✓ RÉPONSE REÇUE ! " + totalRead + " octets");
|
||||||
|
StringBuilder hex = new StringBuilder();
|
||||||
|
for (int j = 0; j < totalRead; j++) {
|
||||||
|
hex.append(String.format("%02X ", response[j]));
|
||||||
|
}
|
||||||
|
Log.e("TEST", " Hex: " + hex.toString());
|
||||||
|
|
||||||
|
// Interpréter la réponse selon la commande
|
||||||
|
if (i == 0 && totalRead >= 1) { // GS r 1
|
||||||
|
interpretGS_r1(response[0]);
|
||||||
|
} else if (i == 1 && totalRead >= 1) { // DLE EOT 1
|
||||||
|
interpretDLE_EOT_1(response[0]);
|
||||||
|
} else if (i == 2 && totalRead >= 1) { // DLE EOT 4
|
||||||
|
interpretDLE_EOT_4(response[0]);
|
||||||
|
} else if (i == 5 && totalRead >= 1) { // GS I 1
|
||||||
|
Log.e("TEST", " ID Imprimante: " + new String(response, 0, totalRead));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.e("TEST", "✗ AUCUNE RÉPONSE");
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("TEST", "Erreur commande " + i, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void interpretGS_r1(byte status) {
|
||||||
|
Log.e("TEST", "Interprétation GS r 1:");
|
||||||
|
Log.e("TEST", " Bit 0 (couvercle): " + ((status & 0x01) != 0 ? "OUVERT" : "FERMÉ"));
|
||||||
|
Log.e("TEST", " Bit 2 (papier): " + ((status & 0x04) != 0 ? "FAIBLE" : "OK"));
|
||||||
|
Log.e("TEST", " Bit 5 (papier): " + ((status & 0x20) != 0 ? "VIDE" : "OK"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void interpretDLE_EOT_1(byte status) {
|
||||||
|
Log.e("TEST", "Interprétation DLE EOT 1:");
|
||||||
|
Log.e("TEST", " Bit 2 (papier): " + ((status & 0x04) != 0 ? "VIDE" : "OK"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void interpretDLE_EOT_4(byte status) {
|
||||||
|
Log.e("TEST", "Interprétation DLE EOT 4:");
|
||||||
|
Log.e("TEST", " Bit 0 (couvercle): " + ((status & 0x01) != 0 ? "OUVERT" : "FERMÉ"));
|
||||||
|
Log.e("TEST", " Bit 2 (papier): " + ((status & 0x04) != 0 ? "FAIBLE" : "OK"));
|
||||||
|
Log.e("TEST", " Bit 5 (papier): " + ((status & 0x20) != 0 ? "VIDE" : "OK"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private String bytesToHex(int[] bytes) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int b : bytes) {
|
||||||
|
sb.append(String.format("%02X ", b));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrinterPaperStatus() {
|
||||||
|
try{
|
||||||
|
byte[] command = new byte[]{0x10, 0x04, 0x04};
|
||||||
|
btOutputStream.write(command);
|
||||||
|
btOutputStream.flush();
|
||||||
|
Thread.sleep(300);
|
||||||
|
int status = btInputStream.read();
|
||||||
|
return String.valueOf(status);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String checkPaperStatus() {
|
||||||
|
try {
|
||||||
|
// 1. Envoyer la commande d'activation ASB
|
||||||
|
byte[] cmd = {0x1D, 0x61, (byte) 0xFF};
|
||||||
|
btOutputStream.write(cmd);
|
||||||
|
btOutputStream.flush();
|
||||||
|
|
||||||
|
// 2. Attendre un peu plus longtemps pour la réponse
|
||||||
|
Thread.sleep(500);
|
||||||
|
|
||||||
|
// 3. Lire tout ce qui est disponible dans le buffer
|
||||||
|
int available = btInputStream.available();
|
||||||
|
if (available > 0) {
|
||||||
|
byte[] buffer = new byte[available];
|
||||||
|
btInputStream.read(buffer);
|
||||||
|
|
||||||
|
// On convertit le buffer en une chaîne lisible (Hex)
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (byte b : buffer) {
|
||||||
|
sb.append(String.format("%02X ", b));
|
||||||
|
}
|
||||||
|
return "Status: " + sb.toString();
|
||||||
|
} else {
|
||||||
|
return "0 (Aucune réponse)";
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return "Erreur: " + e.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private int readStatusByte(int timeoutMs) throws IOException, InterruptedException {
|
||||||
|
long start = System.currentTimeMillis();
|
||||||
|
|
||||||
|
// petite attente initiale (important en Bluetooth)
|
||||||
|
Thread.sleep(50);
|
||||||
|
|
||||||
|
while (System.currentTimeMillis() - start < timeoutMs) {
|
||||||
|
|
||||||
|
int available = btInputStream.available();
|
||||||
|
Log.e("AVAILABLE", "STATUS: "+String.valueOf(available) );
|
||||||
|
if (available > 0) {
|
||||||
|
byte[] buffer = new byte[available];
|
||||||
|
int read = btInputStream.read(buffer);
|
||||||
|
if (read > 0) {
|
||||||
|
int value = buffer[0] & 0xFF;
|
||||||
|
|
||||||
|
Log.d("Printama", "Raw bytes: " + bytesToHex(buffer, read));
|
||||||
|
|
||||||
|
return value; // on prend le premier byte
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.sleep(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String bytesToHex(byte[] bytes, int length) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
sb.append(String.format("%02X ", bytes[i]));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
boolean printImage(Bitmap bitmap, int width) {
|
boolean printImage(Bitmap bitmap, int width) {
|
||||||
return printImage(PA.CENTER, bitmap, width);
|
return printImage(PA.CENTER, bitmap, width);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:padding="20dp"
|
android:padding="20dp"
|
||||||
android:text="Choose Printer"
|
android:text="Choisir une imprimante"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
android:layout_margin="20dp"
|
android:layout_margin="20dp"
|
||||||
android:backgroundTint="@color/colorGray5"
|
android:backgroundTint="@color/colorGray5"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="Test"
|
android:text="Tester"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@
|
|||||||
android:layout_marginBottom="20dp"
|
android:layout_marginBottom="20dp"
|
||||||
android:backgroundTint="@color/colorGray5"
|
android:backgroundTint="@color/colorGray5"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="Save"
|
android:text="Valider"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:padding="20dp"
|
android:padding="20dp"
|
||||||
android:text="Choose Printer"
|
android:text="Choissez une imprimante"
|
||||||
android:textColor="@color/colorBlack"
|
android:textColor="@color/colorBlack"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
android:textColor="@color/colorBlack"
|
android:textColor="@color/colorBlack"
|
||||||
android:textSize="14sp"
|
android:textSize="14sp"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
tools:text="No paired Bluetooth printers found.\n\nTap the button below to open Bluetooth settings and pair a printer."
|
tools:text="Aucune imprimante Bluetooth jumelée trouvée.\n\nAppuyez sur le bouton ci-dessous pour ouvrir les paramètres Bluetooth et jumeler une imprimante."
|
||||||
tools:visibility="visible" />
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
@@ -61,7 +61,7 @@
|
|||||||
android:layout_marginRight="2dp"
|
android:layout_marginRight="2dp"
|
||||||
android:backgroundTint="@color/colorGray5"
|
android:backgroundTint="@color/colorGray5"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="Test"
|
android:text="Tester"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:backgroundTint="@color/colorGray5"
|
android:backgroundTint="@color/colorGray5"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="Save"
|
android:text="Valider"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ dependencyResolutionManagement {
|
|||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
maven{
|
||||||
|
url = uri("https://jitpack.io")
|
||||||
|
content {
|
||||||
|
includeGroup("com.github.NaikSoftware")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user