diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index e6d5073..d56072f 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -43,6 +43,11 @@ android {
dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
implementation(libs.swiperefreshlayout)
+ implementation("androidx.camera:camera-camera2:1.2.3")
+ implementation("androidx.camera:camera-lifecycle:1.2.3")
+ implementation("androidx.camera:camera-view:1.2.3")
+ implementation("androidx.camera:camera-core:1.2.3")
+ implementation("com.google.mlkit:barcode-scanning:17.2.0")
implementation(libs.retrofit)
implementation(libs.okhttp)
implementation(libs.logging.interceptor)
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8e54420..ca0b953 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -6,6 +6,9 @@
+
+
+
@@ -62,6 +65,7 @@
android:name="com.google.android.geo.API_KEY"
android:value="YOUR_API_KEY" />
+
{
getActivity().onBackPressed();
});
+
+ binding.scanTicketBtn.setOnClickListener(v -> {
+ ScannerDialog scannerDialog = new ScannerDialog();
+ scannerDialog.setOnBarcodeScannedListener(code -> {
+ binding.referenceTicket.setText(code);
+ });
+ scannerDialog.show(getParentFragmentManager(), "scanner");
+ });
+
+ binding.annuleTicketBtn.setOnClickListener(v->{
+ String reference = binding.referenceTicket.getText().toString();
+ if(reference.isEmpty()){
+ Toast.makeText(getContext(),"Entrez la référence du ticket", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ viewModel.annulerPari(reference).observe(getViewLifecycleOwner(), new Observer>() {
+ @Override
+ public void onChanged(Result pariResult) {
+ switch (pariResult.status){
+ case LOADING:{
+ Toast.makeText(getContext(), "Chargement...", Toast.LENGTH_SHORT).show();
+ break;
+ }
+ case ERROR:{
+ Toast.makeText(getContext(), pariResult.message, Toast.LENGTH_SHORT).show();
+ break;
+ }
+ case SUCCESS:{
+ Toast.makeText(getContext(), "Ticket annulé avec succès", Toast.LENGTH_SHORT).show();
+ binding.referenceTicket.setText("");
+ }
+ }
+ }
+ });
+ });
}
@Override
diff --git a/app/src/main/java/com/example/quiz/BetValidation.java b/app/src/main/java/com/example/quiz/BetValidation.java
index 1b00d98..985998b 100644
--- a/app/src/main/java/com/example/quiz/BetValidation.java
+++ b/app/src/main/java/com/example/quiz/BetValidation.java
@@ -45,6 +45,7 @@ import com.example.quiz.data.model.enums.PariStatut;
import com.example.quiz.databinding.FragmentBetValidationBinding;
import com.example.quiz.utils.BluetoothUtils;
import com.example.quiz.utils.Result;
+import com.example.quiz.utils.SharedPrefsHelper;
import com.example.quiz.viewModel.PariViewModel;
import com.example.quiz.viewModel.SharedViewModel;
import com.google.android.material.appbar.MaterialToolbar;
@@ -77,20 +78,24 @@ public class BetValidation extends Fragment {
private AlertDialog dialog;
+ private int nombreX;
+
private boolean order;
+ private long mise;
+
private TypeOfBet typeOfBet;
+ SharedPrefsHelper prefsHelper;
+
private Reunion reunion;
private Course course;
private int coeff;
- private int mise;
-
private ActivityResultLauncher enableBluetoothLauncher;
@@ -114,6 +119,7 @@ public class BetValidation extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ prefsHelper = SharedPrefsHelper.getInstance(getContext());
}
@Override
@@ -139,8 +145,8 @@ public class BetValidation extends Fragment {
return;
}
coeff = Integer.parseInt(charSequence.toString());
- calculateMise(selectedHorses.getValue().size());
- binding.mise.setText(String.valueOf(mise+" CFA"));
+ calculateMise(selectedHorses.getValue());
+
}
@Override
@@ -180,7 +186,15 @@ public class BetValidation extends Fragment {
textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
textView.setOnClickListener(v -> {
final List horses = new ArrayList<>(selectedHorses.getValue());
- if (horses.contains(horse)) {
+ if(horses.size() >= shared.typeOfBet.getValue().getNumberOfHorse() && horse.equals("X")){
+ Toast.makeText(getContext(), "Vous ne pouvez plus sélectionner X", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ if(_notClickable(horses) && horse.equals("X")){
+ Toast.makeText(getContext(), "Vous ne pouvez plus sélectionner X", Toast.LENGTH_SHORT).show();
+ return;
+ }
+ if (horses.contains(horse) && !horse.equals("X")) {
horses.remove(horse);
selectedHorses.setValue(horses);
v.setSelected(false);
@@ -196,15 +210,27 @@ public class BetValidation extends Fragment {
.collect(Collectors.joining("-"));
binding.combination.setText( combinationText);
});
-
-
return textView;
}
+
+ boolean _notClickable(List selectedHorses){
+ int numberOfElement = 0;
+ if(shared.typeOfBet.getValue().getNumberOfHorse() < 2){
+ return true;
+ }
+ for(String horse: selectedHorses){
+ numberOfElement = horse.equals("X")?numberOfElement+1:numberOfElement;
+ }
+ nombreX = numberOfElement;
+ return numberOfElement == shared.typeOfBet.getValue().getNumberOfHorse() - 1;
+ }
+
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
+ setSelectedTypeOfBetImage();
pariViewModel = new ViewModelProvider(this).get(PariViewModel.class);
typeOfBet = shared.typeOfBet.getValue();
reunion = shared.selectedReunion.getValue();
@@ -241,8 +267,12 @@ public class BetValidation extends Fragment {
selectedHorses.observe(getViewLifecycleOwner(), new Observer>() {
@Override
public void onChanged(List horses) {
- calculateMise(horses.size());
- binding.mise.setText(String.valueOf(mise+" CFA"));
+ calculateMise(horses);
+ if(horses.size() > shared.typeOfBet.getValue().getNumberOfHorse()){
+ binding.elargie.setVisibility(View.VISIBLE);
+ }else{
+ binding.elargie.setVisibility(View.GONE);
+ }
if(shared.typeOfBet.getValue().getNumberOfHorse() > 2 && horses.size() >= shared.typeOfBet.getValue().getNumberOfHorse()){
binding.order.setVisibility(View.VISIBLE);
}else{
@@ -252,8 +282,7 @@ public class BetValidation extends Fragment {
});
binding.order.setOnCheckedChangeListener((buttonView, isChecked) -> {
order = isChecked;
- calculateMise(selectedHorses.getValue().size());
- binding.mise.setText(String.valueOf(mise+" CFA"));
+ calculateMise(selectedHorses.getValue());
});
binding.betValidateBtn.setOnClickListener(v->{
@@ -274,10 +303,10 @@ public class BetValidation extends Fragment {
}
+
Pari pari = new Pari(
generate12Digits(),
shared.typeOfBet.getValue().getName(),
- "GAGNANT",
mise,
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss").format(LocalDateTime.now()),
true,
@@ -285,25 +314,11 @@ public class BetValidation extends Fragment {
new PariCourseDto(shared.selectedCourse.getValue().getId()),
selectedHorses.getValue(),
order?new ArrayList(): selectedHorses.getValue(),
- order,
- "MULTI_4"
+ !order,
+ "MULTI_4",
+ prefsHelper.get("code")
);
- pariViewModel.createPari(pari).observe(getViewLifecycleOwner(),new Observer>() {
- @Override
- public void onChanged(Result pariResult) {
- switch (pariResult.status){
- case ERROR:
- Toast.makeText(getContext(), pariResult.message, Toast.LENGTH_SHORT).show();
- break;
- case LOADING:
- Toast.makeText(getContext(), "En cours", Toast.LENGTH_SHORT).show();
- break;
- case SUCCESS:
- _showPariDialog(pariResult.data);
- break;
- }
- }
- });
+ _showPariDialog(pari);
});
binding.backBtn.setOnClickListener(v->{
@@ -315,6 +330,26 @@ public class BetValidation extends Fragment {
});
}
+ private void setSelectedTypeOfBetImage(){
+ switch (shared.typeOfBet.getValue().getName()){
+ case "COUPLE_PLACE":
+ binding.icTypeOfBet.setImageResource(R.drawable.ic_couple_place);
+ break;
+ case "COUPLE_GAGNANT":
+ binding.icTypeOfBet.setImageResource(R.drawable.ic_couple_gagnant);
+ break;
+ case "TIERCE":
+ binding.icTypeOfBet.setImageResource(R.drawable.ic_tierce);
+ break;
+ case "QUARTE":
+ binding.icTypeOfBet.setImageResource(R.drawable.ic_quarte);
+ break;
+ case "QUINTE":
+ binding.icTypeOfBet.setImageResource(R.drawable.ic_quinte_plus);
+ break;
+ }
+ }
+
public void printPari(Pari pari) throws WriterException {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
Bitmap barcode = generateBarcodeBitmap(pari.getNumeroTicket(), 384, 100);
@@ -332,15 +367,16 @@ public class BetValidation extends Fragment {
tspl.append("--------------------------------\n");
boolean isElargie = selectedHorses.getValue().size()>shared.typeOfBet.getValue().getNumberOfHorse();
tspl.append(isElargie?pari.getTypePari()+"/Elargie":pari.getTypePari()).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: "+String.valueOf(coeff)).append(".0").append("\n");
tspl.append("--------------------------------\n");
- tspl.append("MONTANT: ").append(mise).append(" XOF\n");
+ tspl.append("MONTANT: ").append(pari.getMise()).append(" XOF\n");
tspl.append("-------------------------------\n");
- tspl.append("AGENT: ").append(" 3332\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.hasBluetoothPermission(requireContext())) {
@@ -378,7 +414,7 @@ public class BetValidation extends Fragment {
TextView aler_coeff = (TextView) view.findViewById(R.id.alert_coeff);
aler_coeff.setText("Coef:"+String.valueOf(coeff));
TextView alert_montant = (TextView) view.findViewById(R.id.alert_montant);
- alert_montant.setText("Montant: "+String.valueOf(mise)+" CFA");
+ alert_montant.setText("Montant: "+String.valueOf(pari.getMise())+" CFA");
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setView(view);
builder.setCancelable(false);
@@ -387,22 +423,35 @@ public class BetValidation extends Fragment {
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);
- }
+ pariViewModel.createPari(pari).observe(getViewLifecycleOwner(),new Observer>() {
+ @Override
+ public void onChanged(Result pariResult) {
+ switch (pariResult.status){
+ case ERROR:
+ Toast.makeText(getContext(), pariResult.message, Toast.LENGTH_SHORT).show();
+ break;
+ case LOADING:
+ Toast.makeText(getContext(), "En cours", Toast.LENGTH_SHORT).show();
+ break;
+ case SUCCESS:
+ try {
+ printPari(pari);
+ dialog.dismiss();
+ } catch (WriterException e) {
+ throw new RuntimeException(e);
+ }
+ break;
+ }
+ }
+ });
});
view.findViewById(R.id.alert_cancel).setOnClickListener(v -> {
dialog.dismiss();
});
-
+ dialog.show();
}
void _initializeToZero(){
- mise = 0;
- binding.mise.setText(String.valueOf(mise+" CFA"));
selectedHorses.setValue(List.of());
binding.combination.setText("");
binding.order.setChecked(false);
@@ -413,56 +462,67 @@ public class BetValidation extends Fragment {
setupNumberGrid(binding.gridNumbers);
}
- public void calculateMise(int nombreChevauxSelectionnes){
- if(typeOfBet.getNumberOfHorse() == 1){
- if(nombreChevauxSelectionnes==1){
+ public void calculateMise(List selectedHorses){
+ _notClickable(selectedHorses);
+ int nombreChevauxSelectionnes = selectedHorses.size();
+ long mise = 0;
+ if(shared.typeOfBet.getValue() == null || shared.selectedCourse.getValue() == null){
+ return;
+ }
+ int typeOfBetHorses = shared.typeOfBet.getValue().getNumberOfHorse();
+ int partants = shared.selectedCourse.getValue().getPartants();
+ if(shared.typeOfBet.getValue().getNumberOfHorse() > nombreChevauxSelectionnes){
+ binding.mise.setText(mise+" CFA");
+ return;
+ }
+ if(typeOfBetHorses == 2){
+ mise = 500;
+ }else{
+ if(typeOfBetHorses == 5){
mise = 300;
+ }else{
+ mise = 200;
}
}
- if(typeOfBet.getNumberOfHorse() == 2){
- if(nombreChevauxSelectionnes == 2){
- mise = 400;
+ mise = mise * coeff;
+ if(nombreX>0){
+ if(nombreChevauxSelectionnes == typeOfBetHorses){
+ mise = mise * _calculateArrangement((partants - (typeOfBetHorses-nombreX)), nombreX);
+ }else{
+ mise = mise * _calculateArrangement(nombreChevauxSelectionnes - typeOfBetHorses , nombreX);
}
- if(nombreChevauxSelectionnes > 2){
- mise = 400 + (nombreChevauxSelectionnes - 2)*300;
+ if(order){
+ mise = mise * _calculateArrangement(typeOfBetHorses, (typeOfBetHorses-nombreX));
}
+ this.mise = mise;
+ binding.mise.setText(mise+" CFA");
+ return;
}
- if(typeOfBet.getNumberOfHorse() == 3){
- if(nombreChevauxSelectionnes == 3){
- mise = 500;
- }
- if(nombreChevauxSelectionnes > 3){
- mise = 500 + (nombreChevauxSelectionnes - 3)*500;
- }
+ mise = mise * _calculateCombinaison(nombreChevauxSelectionnes, typeOfBetHorses);
+ if(order){
+ mise = mise * _calculateArrangement(nombreChevauxSelectionnes, typeOfBetHorses);
}
- if(typeOfBet.getNumberOfHorse() == 4){
- if(nombreChevauxSelectionnes == 4){
- mise = 600;
- }
- if(nombreChevauxSelectionnes > 4){
- mise = 600 + (nombreChevauxSelectionnes - 4)*600;
- }
- }
- if(typeOfBet.getNumberOfHorse() == 5){
- if(nombreChevauxSelectionnes == 5){
- mise = 1200;
- }
- if(nombreChevauxSelectionnes > 5){
- mise = 1200 + (nombreChevauxSelectionnes - 5)*1200;
- }
- }
- mise = order?mise * coeff * _calculateFactorial(shared.typeOfBet.getValue().getNumberOfHorse()):mise * coeff;
+ this.mise = mise;
+ binding.mise.setText(mise+" CFA");
}
- Integer _calculateFactorial(int n){
- int f = 1;
+ Long _calculateArrangement(int n, int k){
+ return _calculateFactorial(n) / _calculateFactorial(n-k);
+ }
+
+ Long _calculateCombinaison(int n, int k){
+ return _calculateFactorial(n) / (_calculateFactorial(k) * _calculateFactorial(n - k));
+ }
+
+ Long _calculateFactorial(int n){
+ long f = 1;
if(n == 0){
- return f;
+ return f;
}
for(int i = 1; i <=n; i++){
f *= i;
}
- return f;
+ return f;
}
diff --git a/app/src/main/java/com/example/quiz/Caisse.java b/app/src/main/java/com/example/quiz/Caisse.java
index e6da450..9ba77fc 100644
--- a/app/src/main/java/com/example/quiz/Caisse.java
+++ b/app/src/main/java/com/example/quiz/Caisse.java
@@ -78,6 +78,14 @@ public class Caisse extends Fragment {
.addToBackStack(null)
.commit();
});
+
+ binding.lastBetsBtn.setOnClickListener(v -> {
+ getActivity().getSupportFragmentManager()
+ .beginTransaction()
+ .replace(R.id.nav_host_fragment_content_main, DerniersParis.newInstance())
+ .addToBackStack(null)
+ .commit();
+ });
}
@Override
diff --git a/app/src/main/java/com/example/quiz/DerniersParis.java b/app/src/main/java/com/example/quiz/DerniersParis.java
new file mode 100644
index 0000000..98c5ea6
--- /dev/null
+++ b/app/src/main/java/com/example/quiz/DerniersParis.java
@@ -0,0 +1,105 @@
+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 androidx.recyclerview.widget.RecyclerView;
+
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Toast;
+
+import com.example.quiz.data.adapter.LastBetsAdapter;
+import com.example.quiz.data.model.Pari;
+import com.example.quiz.databinding.FragmentDerniersParisBinding;
+import com.example.quiz.utils.Result;
+import com.example.quiz.utils.SharedPrefsHelper;
+import com.example.quiz.viewModel.PariViewModel;
+import com.google.android.material.appbar.MaterialToolbar;
+
+import java.util.List;
+
+import dagger.hilt.android.AndroidEntryPoint;
+
+/**
+ * A simple {@link Fragment} subclass.
+ * Use the {@link DerniersParis#newInstance} factory method to
+ * create an instance of this fragment.
+ */
+
+@AndroidEntryPoint
+public class DerniersParis extends Fragment {
+
+ FragmentDerniersParisBinding binding;
+ SharedPrefsHelper prefsHelper;
+ PariViewModel viewModel;
+
+ LastBetsAdapter adapter;
+
+ public DerniersParis() {
+ // Required empty public constructor
+ }
+
+ // TODO: Rename and change types and number of parameters
+ public static DerniersParis newInstance() {
+ DerniersParis fragment = new DerniersParis();
+ Bundle args = new Bundle();
+ fragment.setArguments(args);
+ return fragment;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ prefsHelper = SharedPrefsHelper.getInstance(getContext());
+ }
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ binding = FragmentDerniersParisBinding.inflate(inflater, container, false);
+ return binding.getRoot();
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ binding.lastBetsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
+ viewModel = new ViewModelProvider(this).get(PariViewModel.class);
+ viewModel.getDerniersParis(prefsHelper.get("code")).observe(getViewLifecycleOwner(), new Observer>>() {
+ @Override
+ public void onChanged(Result> listResult) {
+ switch (listResult.status){
+ case LOADING:
+ Toast.makeText(getContext(), "En cours", Toast.LENGTH_SHORT).show();
+ break;
+ case ERROR:
+ Toast.makeText(getContext(), listResult.message, Toast.LENGTH_SHORT).show();
+ break;
+ case SUCCESS:
+ adapter = new LastBetsAdapter(listResult.data, pari -> {
+ });
+ binding.lastBetsRecyclerView.setAdapter(adapter);
+ }
+ }
+ });
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ AppCompatActivity activity = (AppCompatActivity) getActivity();
+ if(activity!=null){
+ MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
+ activity.setSupportActionBar(toolbar);
+ toolbar.setTitle("Derniers Paris");
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/quiz/ListOfTypeOfBets.java b/app/src/main/java/com/example/quiz/ListOfTypeOfBets.java
index 74461cd..2d4209d 100644
--- a/app/src/main/java/com/example/quiz/ListOfTypeOfBets.java
+++ b/app/src/main/java/com/example/quiz/ListOfTypeOfBets.java
@@ -92,17 +92,17 @@ public class ListOfTypeOfBets extends Fragment {
),
new TypeOfBet(
"Tierce",
- "TRIPLET",
+ "TIERCE",
3
),
new TypeOfBet(
"Quarte +",
- "QUARTE_PLUS",
+ "QUARTE",
4
),
new TypeOfBet(
"Quinte +",
- "QUINTE_PLUS",
+ "QUINTE",
5
)
);
@@ -129,7 +129,7 @@ public class ListOfTypeOfBets extends Fragment {
});
Button btnValidate = binding.btnValidate;
btnValidate.setOnClickListener(v->{
- if(shared.typeOfBet == null){
+ if(shared.typeOfBet.getValue() == null){
Toast.makeText(getContext(),"Aucun Type de jeu choisi", Toast.LENGTH_SHORT).show();
return;
}
diff --git a/app/src/main/java/com/example/quiz/PageQuiz.java b/app/src/main/java/com/example/quiz/PageQuiz.java
index a7f444b..c23a956 100644
--- a/app/src/main/java/com/example/quiz/PageQuiz.java
+++ b/app/src/main/java/com/example/quiz/PageQuiz.java
@@ -135,10 +135,12 @@ public class PageQuiz extends AppCompatActivity {
private void loginSuccess(LoginResponse loginResponse){
+ prefsHelper.save("id", String.valueOf(loginResponse.getId()));
prefsHelper.save("firstName", loginResponse.getPrenom());
prefsHelper.save("lastName", loginResponse.getNom());
prefsHelper.save("profile", loginResponse.getProfile());
prefsHelper.save("limit", String.valueOf(loginResponse.getLimiteSuperieure()));
+ prefsHelper.save("code", loginResponse.getCode());
}
@Override
diff --git a/app/src/main/java/com/example/quiz/ScannerDialog.java b/app/src/main/java/com/example/quiz/ScannerDialog.java
new file mode 100644
index 0000000..5efcc83
--- /dev/null
+++ b/app/src/main/java/com/example/quiz/ScannerDialog.java
@@ -0,0 +1,137 @@
+package com.example.quiz;
+
+import android.annotation.SuppressLint;
+import android.content.pm.PackageManager;
+import android.media.Image;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.Manifest;
+import android.widget.Toast;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.camera.core.CameraSelector;
+import androidx.camera.core.ImageAnalysis;
+import androidx.camera.core.Preview;
+import androidx.camera.lifecycle.ProcessCameraProvider;
+import androidx.camera.view.PreviewView;
+import androidx.core.content.ContextCompat;
+import androidx.fragment.app.DialogFragment;
+
+import com.example.quiz.databinding.FragmentScanBinding;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.mlkit.vision.barcode.BarcodeScanner;
+import com.google.mlkit.vision.barcode.BarcodeScanning;
+import com.google.mlkit.vision.barcode.common.Barcode;
+import com.google.mlkit.vision.common.InputImage;
+
+
+
+public class ScannerDialog extends DialogFragment {
+ private PreviewView previewView;
+ private ProcessCameraProvider cameraProvider;
+
+ public interface OnBarcodeScannedListener {
+ void onBarcodeScanned(String code);
+ }
+
+ private OnBarcodeScannedListener listener;
+
+ private FragmentScanBinding binding;
+
+ public void setOnBarcodeScannedListener(OnBarcodeScannedListener listener){
+ this.listener = listener;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ binding = FragmentScanBinding.inflate(inflater, container, false);
+ return binding.getRoot();
+ }
+
+ @Override
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ previewView = view.findViewById(R.id.cameraPreview);
+
+ if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA)
+ != PackageManager.PERMISSION_GRANTED) {
+ requestPermissions(new String[]{Manifest.permission.CAMERA}, 1001);
+ } else {
+ startCamera();
+ }
+
+ view.findViewById(R.id.closeScanDialog).setOnClickListener(v -> dismiss());
+ }
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
+ @NonNull int[] grantResults) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (requestCode == 1001 && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
+ startCamera();
+ } else {
+ Toast.makeText(getContext(), "Permission caméra refusée", Toast.LENGTH_SHORT).show();
+ dismiss();
+ }
+ }
+
+ private void startCamera() {
+ final ListenableFuture cameraProviderFuture =
+ ProcessCameraProvider.getInstance(getContext());
+
+ cameraProviderFuture.addListener(() -> {
+ try {
+ cameraProvider = cameraProviderFuture.get();
+ bindPreviewAndScanner();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }, ContextCompat.getMainExecutor(getContext()));
+ }
+
+ private void bindPreviewAndScanner() {
+ cameraProvider.unbindAll();
+
+ Preview preview = new Preview.Builder().build();
+ CameraSelector selector = CameraSelector.DEFAULT_BACK_CAMERA;
+ preview.setSurfaceProvider(previewView.getSurfaceProvider());
+
+ ImageAnalysis analysis = new ImageAnalysis.Builder()
+ .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
+ .build();
+
+ analysis.setAnalyzer(ContextCompat.getMainExecutor(getContext()), imageProxy -> {
+ @SuppressLint("UnsafeOptInUsageError")
+ Image mediaImage = imageProxy.getImage();
+ if (mediaImage != null) {
+ InputImage inputImage = InputImage.fromMediaImage(mediaImage, imageProxy.getImageInfo().getRotationDegrees());
+
+ BarcodeScanner scanner = BarcodeScanning.getClient();
+
+ scanner.process(inputImage)
+ .addOnSuccessListener(barcodes -> {
+ for (Barcode b : barcodes) {
+ String value = b.getRawValue();
+ if (value != null && listener != null) {
+ listener.onBarcodeScanned(value);
+ dismiss(); // Fermer le dialog après scan
+ scanner.close();
+ imageProxy.close();
+ cameraProvider.unbindAll();
+ return;
+ }
+ }
+ })
+ .addOnFailureListener(Throwable::printStackTrace)
+ .addOnCompleteListener(task -> imageProxy.close());
+ }
+ });
+
+ cameraProvider.bindToLifecycle(this, selector, preview, analysis);
+ }
+}
diff --git a/app/src/main/java/com/example/quiz/Sold.java b/app/src/main/java/com/example/quiz/Sold.java
index 18b4bb3..49eb1d8 100644
--- a/app/src/main/java/com/example/quiz/Sold.java
+++ b/app/src/main/java/com/example/quiz/Sold.java
@@ -9,26 +9,39 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.Observer;
+import androidx.lifecycle.ViewModelProvider;
+import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.example.quiz.databinding.FragmentSoldBinding;
+import com.example.quiz.utils.Result;
+import com.example.quiz.utils.SharedPrefsHelper;
+import com.example.quiz.viewModel.PariViewModel;
import com.google.android.material.appbar.MaterialToolbar;
import java.util.Calendar;
+import dagger.hilt.android.AndroidEntryPoint;
+
/**
* A simple {@link Fragment} subclass.
* Use the {@link Sold#newInstance} factory method to
* create an instance of this fragment.
*/
+@AndroidEntryPoint
public class Sold extends Fragment {
FragmentSoldBinding binding;
+ PariViewModel pariViewModel;
+ SharedPrefsHelper prefsHelper;
+
public Sold() {
// Required empty public constructor
}
@@ -44,6 +57,7 @@ public class Sold extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ prefsHelper = SharedPrefsHelper.getInstance(getContext());
AppCompatActivity activity = (AppCompatActivity) getActivity();
if(activity != null){
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
@@ -66,6 +80,7 @@ public class Sold extends Fragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
+ pariViewModel = new ViewModelProvider(this).get(PariViewModel.class);
binding.btnByCourse.setOnClickListener(v -> {
FragmentManager fragmentManager = getParentFragmentManager();
SoldByCourse soldByCourse = SoldByCourse.newInstance();
@@ -86,14 +101,26 @@ public class Sold extends Fragment {
DatePickerDialog datePickerDialog = new DatePickerDialog(
getContext(),
(view, year, month, dayOfMonth) -> {
- String date = dayOfMonth + "/" + (month + 1) + "/" + year;
- //Toast.makeText(getContext(), date, Toast.LENGTH_SHORT).show();
- new AlertDialog.Builder(getContext())
- .setTitle("Solde")
- .setMessage("Solde la course 3000CFA")
- .setPositiveButton("Ok", (dialog, which)->{
- dialog.dismiss();
- }).show();
+ String date = year + "-" + (month + 1) + "-" + dayOfMonth;
+ pariViewModel.getSoldeByDay(prefsHelper.get("code"), date).observe(getViewLifecycleOwner(), new Observer>() {
+ @Override
+ public void onChanged(Result doubleResult) {
+ switch (doubleResult.status){
+ case LOADING:{
+ Toast.makeText(getContext(), "En cours", Toast.LENGTH_SHORT).show();
+ break;
+ }
+ case ERROR:{
+ Log.d("Response", doubleResult.message);
+ break;
+ }
+ case SUCCESS:{
+ _showSold(doubleResult.data);
+ break;
+ }
+ }
+ }
+ });
},
calendar.get(Calendar.YEAR),
calendar.get(Calendar.MONTH),
@@ -102,4 +129,13 @@ public class Sold extends Fragment {
datePickerDialog.show();
}
+
+ void _showSold(double solde){
+ new AlertDialog.Builder(getContext())
+ .setTitle("Solde")
+ .setMessage("Solde la course "+solde)
+ .setPositiveButton("Ok", (dialog, which)->{
+ dialog.dismiss();
+ }).show();
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/quiz/SoldByCourse.java b/app/src/main/java/com/example/quiz/SoldByCourse.java
index 2e17394..859f5e3 100644
--- a/app/src/main/java/com/example/quiz/SoldByCourse.java
+++ b/app/src/main/java/com/example/quiz/SoldByCourse.java
@@ -6,26 +6,35 @@ 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 android.widget.Toast;
import com.example.quiz.databinding.FragmentSoldByCourseBinding;
+import com.example.quiz.utils.Result;
+import com.example.quiz.utils.SharedPrefsHelper;
+import com.example.quiz.viewModel.PariViewModel;
+
+import dagger.hilt.android.AndroidEntryPoint;
/**
* A simple {@link Fragment} subclass.
* Use the {@link SoldByCourse#newInstance} factory method to
* create an instance of this fragment.
*/
+
+@AndroidEntryPoint
public class SoldByCourse extends Fragment {
FragmentSoldByCourseBinding binding;
- // TODO: Rename parameter arguments, choose names that match
- // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
- private static final String ARG_PARAM1 = "param1";
- private static final String ARG_PARAM2 = "param2";
+ PariViewModel pariViewModel;
+
+ SharedPrefsHelper prefsHelper;
public static SoldByCourse newInstance() {
@@ -39,6 +48,7 @@ public class SoldByCourse extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ prefsHelper = SharedPrefsHelper.getInstance(getContext());
}
@Override
@@ -52,19 +62,43 @@ public class SoldByCourse extends Fragment {
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
+ pariViewModel = new ViewModelProvider(this).get(PariViewModel.class);
+
binding.btnCheckBalance.setOnClickListener(v -> {
if(binding.etRaceNumber.getText().toString().isEmpty()){
binding.etRaceNumber.setError("Veuillez entrer un numéro de course");
return;
}
- new AlertDialog.Builder(getContext())
- .setTitle("Solde")
- .setMessage("Solde la course 3000CFA")
- .setPositiveButton("Ok", (dialog, which) -> {
- binding.etRaceNumber.setText("");
- dialog.dismiss();
- })
- .show();
+ pariViewModel.getSoldeByCourse(prefsHelper.get("code"), binding.etRaceNumber.getText().toString()).observe(getViewLifecycleOwner(), new Observer>() {
+ @Override
+ public void onChanged(Result doubleResult) {
+ switch (doubleResult.status){
+ case LOADING:{
+ Toast.makeText(getContext(), "Chargement..", Toast.LENGTH_SHORT).show();
+ break;
+ }
+ case ERROR:{
+ Toast.makeText(getContext(), doubleResult.message, Toast.LENGTH_SHORT).show();
+ break;
+ }
+ case SUCCESS:{
+ _showPariDialog(doubleResult.data);
+ break;
+ }
+ }
+ }
+ });
});
}
+
+ void _showPariDialog(double solde){
+ new AlertDialog.Builder(getContext())
+ .setTitle("Solde")
+ .setMessage("Solde la course "+solde)
+ .setPositiveButton("Ok", (dialog, which) -> {
+ binding.etRaceNumber.setText("");
+ dialog.dismiss();
+ })
+ .show();
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/quiz/WinTicket.java b/app/src/main/java/com/example/quiz/WinTicket.java
index 6530dcc..7a3aacc 100644
--- a/app/src/main/java/com/example/quiz/WinTicket.java
+++ b/app/src/main/java/com/example/quiz/WinTicket.java
@@ -51,6 +51,13 @@ public class WinTicket extends Fragment {
binding.winTicketBtnBack.setOnClickListener(v -> {
getActivity().onBackPressed();
});
+ binding.scanTicketBtn.setOnClickListener(v ->{
+ ScannerDialog scannerDialog = new ScannerDialog();
+ scannerDialog.setOnBarcodeScannedListener(code -> {
+ binding.referenceTicket.setText(code);
+ });
+ scannerDialog.show(getParentFragmentManager(), "scanner");
+ });
}
@Override
diff --git a/app/src/main/java/com/example/quiz/data/adapter/BetsAdapter.java b/app/src/main/java/com/example/quiz/data/adapter/BetsAdapter.java
index 626ae41..8a3c088 100644
--- a/app/src/main/java/com/example/quiz/data/adapter/BetsAdapter.java
+++ b/app/src/main/java/com/example/quiz/data/adapter/BetsAdapter.java
@@ -14,6 +14,8 @@ import com.example.quiz.data.model.Course;
import com.example.quiz.viewModel.SharedViewModel;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
public class BetsAdapter extends RecyclerView.Adapter {
@@ -51,7 +53,12 @@ public class BetsAdapter extends RecyclerView.Adapter
public void onBindViewHolder(@NonNull BetViewHolder holder, int position) {
Course bet = bets.get(position);
- holder.tvDate.setText(String.valueOf(bet.getDateDepartCourse()));
+ holder.tvDate.setText(LocalDateTime.parse(
+ bet.getDateDepartCourse(),
+ DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")
+ ).format(
+ DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss")
+ ));
holder.tvName.setText(bet.getNom());
if (shared != null && shared.selectedReunion.getValue() != null) {
diff --git a/app/src/main/java/com/example/quiz/data/adapter/LastBetsAdapter.java b/app/src/main/java/com/example/quiz/data/adapter/LastBetsAdapter.java
new file mode 100644
index 0000000..e85434b
--- /dev/null
+++ b/app/src/main/java/com/example/quiz/data/adapter/LastBetsAdapter.java
@@ -0,0 +1,120 @@
+package com.example.quiz.data.adapter;
+
+import android.text.TextUtils;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import androidx.annotation.NonNull;
+import androidx.recyclerview.widget.RecyclerView;
+import com.example.quiz.R;
+import com.example.quiz.data.model.Pari;
+import java.util.ArrayList;
+import java.util.List;
+
+public class LastBetsAdapter extends RecyclerView.Adapter {
+
+ private List listeParis = new ArrayList<>(); // évite les NPE
+ private OnBetClick onBetClick; // peut être null si tu veux
+
+ public interface OnBetClick {
+ void onItemClick(Pari pari);
+ }
+
+ public LastBetsAdapter(List listeParis, OnBetClick onBetClick) {
+ 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 newList) {
+ if (newList == null) {
+ this.listeParis = new ArrayList<>();
+ } else {
+ this.listeParis = newList;
+ }
+ notifyDataSetChanged();
+ }
+
+ public void addItem(Pari pari) {
+ if (pari == null) return;
+ this.listeParis.add(pari);
+ notifyItemInserted(listeParis.size() - 1);
+ }
+
+ public void clear() {
+ this.listeParis.clear();
+ notifyDataSetChanged();
+ }
+
+ @NonNull
+ @Override
+ public LastBetsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
+ View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.last_bets_item, parent, false);
+ return new LastBetsViewHolder(view);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull LastBetsViewHolder holder, int position) {
+ Pari pari = listeParis.get(position);
+ if (pari == null) return;
+
+ holder.typeOfCourse.setText(pari.getCourse().getType());
+ holder.refenceTicket.setText(pari.getNumeroTicket());
+
+ // Type (défensif : vérifie null)
+ holder.betType.setText(pari.getTypePari() != null ? pari.getTypePari() : "-");
+
+ // Course (défensif : course peut être null)
+ if (pari.getCourse() != null) {
+ holder.course.setText("Course: " + pari.getCourse().getId());
+ } else {
+ holder.course.setText("Course: -");
+ }
+
+ // Chevaux : join en toute sécurité (gère Integer list ou String list)
+ List> chevaux = pari.getChevauxSelectionnes();
+ if (chevaux != null && !chevaux.isEmpty()) {
+ // convertir en strings
+ List str = new ArrayList<>(chevaux.size());
+ for (Object o : chevaux) {
+ str.add(String.valueOf(o));
+ }
+ // TextUtils.join est compatible avec tous les niveaux API
+ holder.horses.setText("Chevaux : " + TextUtils.join("-", str));
+ } else {
+ holder.horses.setText("Chevaux : -");
+ }
+
+ // Mise (défensif)
+ holder.mise.setText("Mise: " + pari.getMise() + " CFA");
+
+ // click listener défensif
+ holder.itemView.setOnClickListener(v -> {
+ if (onBetClick != null) onBetClick.onItemClick(pari);
+ });
+ }
+
+ @Override
+ public int getItemCount() {
+ return (listeParis != null) ? listeParis.size() : 0;
+ }
+
+ public static class LastBetsViewHolder extends RecyclerView.ViewHolder {
+ TextView betType, horses, course, mise, refenceTicket, typeOfCourse;
+
+ public LastBetsViewHolder(@NonNull View itemView) {
+ super(itemView);
+ betType = itemView.findViewById(R.id.last_bet_type);
+ course = itemView.findViewById(R.id.last_bet_course);
+ horses = itemView.findViewById(R.id.last_bet_horses);
+ mise = itemView.findViewById(R.id.last_bet_mise);
+ refenceTicket = itemView.findViewById(R.id.reference_ticket);
+ typeOfCourse = itemView.findViewById(R.id.type_of_course);
+ }
+ }
+}
diff --git a/app/src/main/java/com/example/quiz/data/model/Pari.java b/app/src/main/java/com/example/quiz/data/model/Pari.java
index e191aa9..f50ef19 100644
--- a/app/src/main/java/com/example/quiz/data/model/Pari.java
+++ b/app/src/main/java/com/example/quiz/data/model/Pari.java
@@ -7,7 +7,6 @@ import java.util.Map;
public class Pari {
private String numeroTicket;
private String typePari;
- private String typeFormule;
private double mise;
private String datePari;
private boolean estPaye;
@@ -18,10 +17,11 @@ public class Pari {
private boolean validationOrdreExact;
private String typeMulti;
- public Pari(String numeroTicket, String typePari, String typeFormule, double mise, String datePari, boolean estPaye, boolean estRembourse, PariCourseDto course, List chevauxSelectionnes, List ordrePredit, boolean validationOrdreExact, String typeMulti) {
+ private String createdBy;
+
+ public Pari(String numeroTicket, String typePari, double mise, String datePari, boolean estPaye, boolean estRembourse, PariCourseDto course, List chevauxSelectionnes, List ordrePredit, boolean validationOrdreExact, String typeMulti, String createdBy) {
this.numeroTicket = numeroTicket;
this.typePari = typePari;
- this.typeFormule = typeFormule;
this.mise = mise;
this.datePari = datePari;
this.estPaye = estPaye;
@@ -31,6 +31,7 @@ public class Pari {
this.ordrePredit = ordrePredit;
this.validationOrdreExact = validationOrdreExact;
this.typeMulti = typeMulti;
+ this.createdBy = createdBy;
}
public String getNumeroTicket() {
@@ -49,14 +50,6 @@ public class Pari {
this.typePari = typePari;
}
- public String getTypeFormule() {
- return typeFormule;
- }
-
- public void setTypeFormule(String typeFormule) {
- this.typeFormule = typeFormule;
- }
-
public double getMise() {
return mise;
}
@@ -128,4 +121,12 @@ public class Pari {
public void setTypeMulti(String typeMulti) {
this.typeMulti = typeMulti;
}
+
+ public String getCreatedBy() {
+ return createdBy;
+ }
+
+ public void setCreatedBy(String createdBy) {
+ this.createdBy = createdBy;
+ }
}
diff --git a/app/src/main/java/com/example/quiz/data/model/dtos/PariCourseDto.java b/app/src/main/java/com/example/quiz/data/model/dtos/PariCourseDto.java
index 8086a9e..79cc03b 100644
--- a/app/src/main/java/com/example/quiz/data/model/dtos/PariCourseDto.java
+++ b/app/src/main/java/com/example/quiz/data/model/dtos/PariCourseDto.java
@@ -3,10 +3,43 @@ package com.example.quiz.data.model.dtos;
public class PariCourseDto {
private int id;
+ private String nom;
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ private String type;
+
+
+
public PariCourseDto(int id) {
this.id = id;
}
+ public PariCourseDto(String nom) {
+ this.nom = nom;
+ }
+
+
+ public PariCourseDto(int id, String nom, String type) {
+ this.id = id;
+ this.nom = nom;
+ this.type = type;
+ }
+
+ public String getNom() {
+ return nom;
+ }
+
+ public void setNom(String nom) {
+ this.nom = nom;
+ }
+
public int getId() {
return id;
}
diff --git a/app/src/main/java/com/example/quiz/data/remote/ApiClient.java b/app/src/main/java/com/example/quiz/data/remote/ApiClient.java
index 32df308..aa89401 100644
--- a/app/src/main/java/com/example/quiz/data/remote/ApiClient.java
+++ b/app/src/main/java/com/example/quiz/data/remote/ApiClient.java
@@ -20,7 +20,7 @@ import retrofit2.converter.gson.GsonConverterFactory;
@Module
@InstallIn(SingletonComponent.class)
public class ApiClient {
- private static final String BASE_URL = "https://970b6b1c025c.ngrok-free.app/api/v1/";
+ private static final String BASE_URL = "https://boxer-adapting-bluegill.ngrok-free.app/api/v1/";
@Provides
@Singleton
diff --git a/app/src/main/java/com/example/quiz/data/remote/ApiService.java b/app/src/main/java/com/example/quiz/data/remote/ApiService.java
index 588a813..2752a2a 100644
--- a/app/src/main/java/com/example/quiz/data/remote/ApiService.java
+++ b/app/src/main/java/com/example/quiz/data/remote/ApiService.java
@@ -12,7 +12,9 @@ import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
+import retrofit2.http.PUT;
import retrofit2.http.Path;
+import retrofit2.http.Query;
public interface ApiService {
@GET("reunions")
@@ -26,4 +28,17 @@ public interface ApiService {
@POST("auth/agent/login")
Call login(@Body LoginPayload loginPayload);
+
+ @GET("pari/created-by/{created-by}/today")
+ Call> derniersParis(@Path("created-by") String createdBy);
+
+ @PUT("pari/annuler/{numeroTicket}")
+ Call annulerPari(@Path("numeroTicket") String numeroTicket);
+
+ @GET("pari/solde/{createdBy}/course/{courseId}")
+ Call getSoldeByCourse(@Path("createdBy") String createdBy, @Path("courseId") String courseId);
+
+ @GET("pari/solde/{createdBy}")
+ Call getSoldeByDay(@Path("createdBy") String createdBy, @Query("date") String day);
+
}
diff --git a/app/src/main/java/com/example/quiz/data/repository/PariRepository.java b/app/src/main/java/com/example/quiz/data/repository/PariRepository.java
index 41763eb..9f1fa4b 100644
--- a/app/src/main/java/com/example/quiz/data/repository/PariRepository.java
+++ b/app/src/main/java/com/example/quiz/data/repository/PariRepository.java
@@ -10,6 +10,8 @@ import com.example.quiz.data.model.Pari;
import com.example.quiz.data.remote.ApiService;
import com.example.quiz.utils.Result;
+import java.util.List;
+
import javax.inject.Inject;
import retrofit2.Call;
@@ -57,5 +59,111 @@ public class PariRepository {
return pariResponse;
}
+ public LiveData>> derniersParis(String createdBy){
+ MutableLiveData>> derniersParis = new MutableLiveData<>();
+ derniersParis.setValue(Result.loading());
+ apiService.derniersParis(createdBy).enqueue(new Callback>() {
+ @Override
+ public void onResponse(Call> call, Response> response) {
+ if(response.isSuccessful() && response.body() != null){
+ derniersParis.postValue(Result.success(response.body()));
+ }else{
+ try{
+ String errorBody = response.errorBody() != null ?
+ response.errorBody().string() : "Erreur inconnue";
+
+ derniersParis.postValue(Result.error(errorBody));
+ }catch (Exception e){
+ derniersParis.postValue(Result.error(e.getMessage()));
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(Call> call, Throwable throwable) {
+ derniersParis.postValue(Result.error(throwable.getMessage()));
+ }
+ });
+
+ return derniersParis;
+ }
+
+ public LiveData> annulerPari(String numeroTicket){
+ MutableLiveData> pariResponse = new MutableLiveData<>();
+ pariResponse.setValue(Result.loading());
+ apiService.annulerPari(numeroTicket).enqueue(new Callback(){
+ @Override
+ public void onResponse(Call call, Response response) {
+ if(response.isSuccessful()){
+ pariResponse.postValue(Result.success(response.body()));
+ }else{
+ try{
+ String errorBody = response.errorBody() != null ?
+ response.errorBody().string() : "Erreur inconnue";
+
+ pariResponse.postValue(Result.error(errorBody));
+ }catch (Exception e){
+ pariResponse.postValue(Result.error(e.getMessage()));
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable throwable) {
+ pariResponse.postValue(Result.error(throwable.getMessage()));
+ }
+ });
+ return pariResponse;
+ }
+
+ public LiveData> getSoldeByCourse(String createdBy, String courseId){
+ MutableLiveData> solde = new MutableLiveData<>();
+ solde.setValue(Result.loading());
+ apiService.getSoldeByCourse(createdBy, courseId).enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if(response.isSuccessful()){
+ solde.postValue(Result.success(response.body()));
+ }else{
+ try{
+ solde.postValue(Result.error(response.errorBody().string()));
+ }catch (Exception e){
+ solde.postValue(Result.error(e.getMessage()));
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable throwable) {
+ solde.postValue(Result.error(throwable.getMessage()));
+ }
+ });
+ return solde;
+ }
+
+ public LiveData> getSoldeByDay(String createdBy, String day){
+ MutableLiveData> solde = new MutableLiveData<>();
+ solde.setValue(Result.loading());
+ apiService.getSoldeByDay(createdBy, day).enqueue(new Callback() {
+ @Override
+ public void onResponse(Call call, Response response) {
+ if(response.isSuccessful()){
+ solde.postValue(Result.success(response.body()));
+ }else{
+ try {
+ solde.postValue(Result.error(response.errorBody().string()));
+ }catch (Exception e){
+ solde.postValue(Result.error(e.getMessage()));
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(Call call, Throwable throwable) {
+ solde.postValue(Result.error(throwable.getMessage()));
+ }
+ });
+ return solde;
+ }
}
diff --git a/app/src/main/java/com/example/quiz/viewModel/PariViewModel.java b/app/src/main/java/com/example/quiz/viewModel/PariViewModel.java
index 05902f7..e87163d 100644
--- a/app/src/main/java/com/example/quiz/viewModel/PariViewModel.java
+++ b/app/src/main/java/com/example/quiz/viewModel/PariViewModel.java
@@ -7,6 +7,8 @@ import com.example.quiz.data.model.Pari;
import com.example.quiz.data.repository.PariRepository;
import com.example.quiz.utils.Result;
+import java.util.List;
+
import javax.inject.Inject;
import dagger.hilt.android.lifecycle.HiltViewModel;
@@ -16,6 +18,14 @@ public class PariViewModel extends ViewModel {
private final PariRepository pariRepository;
private LiveData> pari;
+ private LiveData>> derniersParis;
+
+ private LiveData> pariAnnule;
+
+ private LiveData> solde;
+
+ private LiveData> soldeByDay;
+
@Inject
public PariViewModel(PariRepository repository){
this.pariRepository = repository;
@@ -27,4 +37,32 @@ public class PariViewModel extends ViewModel {
}
return this.pari;
}
+
+ public LiveData>> getDerniersParis(String createdBy){
+ if(derniersParis == null){
+ derniersParis = pariRepository.derniersParis(createdBy);
+ }
+ return pariRepository.derniersParis(createdBy);
+ }
+
+ public LiveData> annulerPari(String numeroTicket){
+ if(pariAnnule == null){
+ pariAnnule = pariRepository.annulerPari(numeroTicket);
+ }
+ return pariAnnule;
+ }
+
+ public LiveData> getSoldeByCourse(String createdBy, String courseId){
+ if(solde == null){
+ solde = pariRepository.getSoldeByCourse(createdBy, courseId);
+ }
+ return solde;
+ }
+
+ public LiveData> getSoldeByDay(String createdBy, String day){
+ if(soldeByDay == null){
+ soldeByDay = pariRepository.getSoldeByDay(createdBy, day);
+ }
+ return soldeByDay;
+ }
}
diff --git a/app/src/main/res/drawable/ic_couple_gagnant.xml b/app/src/main/res/drawable/ic_couple_gagnant.xml
new file mode 100644
index 0000000..54be57e
--- /dev/null
+++ b/app/src/main/res/drawable/ic_couple_gagnant.xml
@@ -0,0 +1,540 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_couple_place.xml b/app/src/main/res/drawable/ic_couple_place.xml
new file mode 100644
index 0000000..b65258f
--- /dev/null
+++ b/app/src/main/res/drawable/ic_couple_place.xml
@@ -0,0 +1,657 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_quarte.xml b/app/src/main/res/drawable/ic_quarte.xml
new file mode 100644
index 0000000..5d6a987
--- /dev/null
+++ b/app/src/main/res/drawable/ic_quarte.xml
@@ -0,0 +1,435 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_quinte_plus.xml b/app/src/main/res/drawable/ic_quinte_plus.xml
new file mode 100644
index 0000000..fa8b2d4
--- /dev/null
+++ b/app/src/main/res/drawable/ic_quinte_plus.xml
@@ -0,0 +1,213 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable/ic_tierce.xml b/app/src/main/res/drawable/ic_tierce.xml
new file mode 100644
index 0000000..37bc562
--- /dev/null
+++ b/app/src/main/res/drawable/ic_tierce.xml
@@ -0,0 +1,297 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_annulation_ticket.xml b/app/src/main/res/layout/fragment_annulation_ticket.xml
index 4c0efe9..d6ff4c3 100644
--- a/app/src/main/res/layout/fragment_annulation_ticket.xml
+++ b/app/src/main/res/layout/fragment_annulation_ticket.xml
@@ -21,6 +21,7 @@
android:textColor="@color/primary_green">
-
+ android:layout_height="match_parent"
+ android:background="@color/login_background"
+ android:id="@+id/login_container"
+ tools:context=".BetValidation">
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:layout_height="match_parent"
+ android:background="@color/gray"
+ android:paddingHorizontal="5dp"
+ android:layout_above="@+id/bottom_buttons">
-
-
+ android:paddingBottom="30dp">
+ android:layout_marginTop="5dp"
+ android:layout_marginBottom="5dp"
+ android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ android:padding="12dp"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:background="@android:color/white"
+ android:elevation="4dp"
+ android:layout_marginBottom="14dp">
-
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+
+
-
+
+
-
-
+
+
-
-
+
-
+ android:orientation="vertical">
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+ android:layout_margin="4dp"
+ android:layout_weight="1"
+ android:backgroundTint="@android:color/holo_red_light"
+ android:text="@string/delete"
+ android:textColor="@color/white" />
+
-
+
+
diff --git a/app/src/main/res/layout/fragment_derniers_paris.xml b/app/src/main/res/layout/fragment_derniers_paris.xml
new file mode 100644
index 0000000..a6f928e
--- /dev/null
+++ b/app/src/main/res/layout/fragment_derniers_paris.xml
@@ -0,0 +1,14 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_scan.xml b/app/src/main/res/layout/fragment_scan.xml
new file mode 100644
index 0000000..aedeb52
--- /dev/null
+++ b/app/src/main/res/layout/fragment_scan.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/fragment_win_ticket.xml b/app/src/main/res/layout/fragment_win_ticket.xml
index de6a9b0..716a572 100644
--- a/app/src/main/res/layout/fragment_win_ticket.xml
+++ b/app/src/main/res/layout/fragment_win_ticket.xml
@@ -21,6 +21,7 @@
android:textColor="@color/primary_green">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+