gestion des formats de tickets!

This commit is contained in:
OnlyPapy98
2026-02-16 10:16:49 +01:00
parent 2fc21fd433
commit acc5ec1b70
92 changed files with 3903 additions and 905 deletions

View File

@@ -4,7 +4,6 @@ import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
@@ -13,9 +12,13 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.example.quiz.data.model.Pari;
import com.example.quiz.data.model.ParisResponse;
import com.example.quiz.databinding.FragmentAnnulationTicketBinding;
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 dagger.hilt.android.AndroidEntryPoint;
@@ -30,8 +33,15 @@ public class AnnulationTicket extends Fragment {
FragmentAnnulationTicketBinding binding;
SharedPrefsHelper prefsHelper;
LogsViewModel logsViewModel;
PariViewModel viewModel;
LoaderDialog dialog;
public AnnulationTicket() {
// Required empty public constructor
}
@@ -53,6 +63,9 @@ public class AnnulationTicket extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentAnnulationTicketBinding.inflate(inflater, container, false);
prefsHelper = SharedPrefsHelper.getInstance(getContext());
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
dialog = new LoaderDialog(getContext());
return binding.getRoot();
}
@@ -78,20 +91,23 @@ public class AnnulationTicket extends Fragment {
Toast.makeText(getContext(),"Entrez la référence du ticket", Toast.LENGTH_SHORT).show();
return;
}
viewModel.annulerPari(reference).observe(getViewLifecycleOwner(), new Observer<Result<Pari>>() {
viewModel.annulerPari(reference).observe(getViewLifecycleOwner(), new Observer<Result<ParisResponse>>() {
@Override
public void onChanged(Result<Pari> pariResult) {
public void onChanged(Result<ParisResponse> pariResult) {
switch (pariResult.status){
case LOADING:{
Toast.makeText(getContext(), "Chargement...", Toast.LENGTH_SHORT).show();
dialog.show("Annulation du ticket");
break;
}
case ERROR:{
Toast.makeText(getContext(), pariResult.message, Toast.LENGTH_SHORT).show();
dialog.dismiss();
MessageDialog.showError(getContext(), pariResult.message);
break;
}
case SUCCESS:{
Toast.makeText(getContext(), "Ticket annulé avec succès", Toast.LENGTH_SHORT).show();
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("");
}
}

View File

@@ -38,14 +38,19 @@ import android.widget.Toast;
import com.anggastudio.printama.Printama;
import com.example.quiz.data.model.Course;
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.Reunion;
import com.example.quiz.data.model.TypeOfBet;
import com.example.quiz.data.model.dtos.PariCourseDto;
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.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.example.quiz.viewModel.SharedViewModel;
import com.google.android.material.appbar.MaterialToolbar;
@@ -54,7 +59,10 @@ import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
@@ -80,6 +88,8 @@ public class BetValidation extends Fragment {
private int nombreX;
LogsViewModel logsViewModel;
private boolean order;
@@ -90,10 +100,13 @@ public class BetValidation extends Fragment {
SharedPrefsHelper prefsHelper;
private Reunion reunion;
private Course course;
LoaderDialog loader;
private int coeff;
private ActivityResultLauncher<Intent> enableBluetoothLauncher;
@@ -126,6 +139,8 @@ public class BetValidation extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentBetValidationBinding.inflate(inflater, container, false);
loader = new LoaderDialog(getContext());
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
binding.coeff.setText(String.valueOf(1));
coeff = Integer.parseInt(binding.coeff.getText().toString());
binding.coeff.addTextChangedListener(new TextWatcher(){
@@ -162,7 +177,7 @@ public class BetValidation extends Fragment {
int columns = 8;
grid.setColumnCount(columns);
if(shared.selectedCourse.getValue() != null){
for (int i = 1; i <= shared.selectedCourse.getValue().getPartants(); i++) {
for (int i = 1; i <= shared.selectedCourse.getValue().getNombrePartants(); i++) {
createNumberItem(String.valueOf(i));
grid.addView(createNumberItem(String.valueOf(i)));
}
@@ -183,8 +198,16 @@ public class BetValidation extends Fragment {
textView.setHeight(100);
textView.setGravity(Gravity.CENTER);
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))){
textView.setTextColor(getResources().getColor(R.color.white));
textView.setBackgroundResource(R.drawable.number_background_grey);
}
textView.setTextAlignment(View.TEXT_ALIGNMENT_CENTER);
textView.setOnClickListener(v -> {
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();
return;
}
final List<String> horses = new ArrayList<>(selectedHorses.getValue());
if(horses.size() >= shared.typeOfBet.getValue().getNumberOfHorse() && horse.equals("X")){
Toast.makeText(getContext(), "Vous ne pouvez plus sélectionner X", Toast.LENGTH_SHORT).show();
@@ -233,7 +256,6 @@ public class BetValidation extends Fragment {
setSelectedTypeOfBetImage();
pariViewModel = new ViewModelProvider(this).get(PariViewModel.class);
typeOfBet = shared.typeOfBet.getValue();
reunion = shared.selectedReunion.getValue();
course = shared.selectedCourse.getValue();
AppCompatActivity activity = (AppCompatActivity) getActivity();
if(activity != null){
@@ -306,7 +328,7 @@ public class BetValidation extends Fragment {
return;
}
if(shared.typeOfBet == null || shared.selectedReunion.getValue() == null || shared.selectedCourse == null){
if(shared.typeOfBet == null || shared.selectedCourse == null){
return;
}
@@ -322,20 +344,18 @@ public class BetValidation extends Fragment {
return;
}
Pari pari = new Pari(
generate12Digits(),
shared.typeOfBet.getValue().getName(),
mise,
DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss").format(LocalDateTime.now()),
true,
true,
new PariCourseDto(shared.selectedCourse.getValue().getId()),
selectedHorses.getValue(),
order?new ArrayList<String>(): selectedHorses.getValue(),
!order,
"MULTI_4",
prefsHelper.get("code")
OffsetDateTime.now(ZoneOffset.UTC).toString(),
Long.valueOf(course.getId()),
Long.valueOf(prefsHelper.get("id")),
Long.valueOf(prefsHelper.get("terminalId")),
Long.valueOf(prefsHelper.get("pointDeVenteId")),
List.of(new PariMise(String.valueOf(shared.typeOfBet.getValue().getName()), mise)),
_getFormule(),
_getCombinaison(),
coeff,
"XOF",
"Pari"
);
_showPariDialog(pari);
});
@@ -349,64 +369,107 @@ public class BetValidation extends Fragment {
});
}
String _getCombinaison(){
if(selectedHorses.getValue().contains("X") && shared.typeOfBet.getValue().getNumberOfHorse() < selectedHorses.getValue().size()){
String first = selectedHorses.getValue().subList(0, shared.typeOfBet.getValue().getNumberOfHorse()).stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
String last = selectedHorses.getValue().subList(shared.typeOfBet.getValue().getNumberOfHorse(), selectedHorses.getValue().size()).stream()
.map(String::valueOf)
.collect(Collectors.joining(","));
return first+",R,"+last;
}else{
return selectedHorses.getValue().stream().map(String::valueOf).collect(Collectors.joining(","));
}
}
List<String> _getFormule(){
List<String> combinaison = selectedHorses.getValue();
if(!combinaison.contains("X")){
if(!order){
return List.of("UNITAIRE");
}else{
return List.of("FORMULE_COMPLETE");
}
}else{
if(shared.typeOfBet.getValue().getNumberOfHorse() < selectedHorses.getValue().size()){
if(order){
return List.of("CHAMP_X", "FORMULE_COMPLETE");
}else{
return List.of("CHAMP_X");
}
}else{
if(order){
return List.of("CHAMP_TOTAL", "FORMULE_COMPLETE");
}else{
return List.of("CHAMP_TOTAL");
}
}
}
}
private void setSelectedTypeOfBetImage(){
switch (shared.typeOfBet.getValue().getName()){
case "COUPLE_PLACE":
case COUPLE_PLACE:
binding.icTypeOfBet.setImageResource(R.drawable.ic_couple_place);
break;
case "COUPLE_GAGNANT":
case COUPLE_GAGNANT:
binding.icTypeOfBet.setImageResource(R.drawable.ic_couple_gagnant);
break;
case "TIERCE":
case TIERCE:
binding.icTypeOfBet.setImageResource(R.drawable.ic_tierce);
break;
case "QUARTE":
case QUARTE:
binding.icTypeOfBet.setImageResource(R.drawable.ic_quarte);
break;
case "QUINTE":
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);
StringBuilder tspl = new StringBuilder();
tspl.append("Bamako").append("\n");
tspl.append(shared.selectedCourse.getValue().getNom()).append("\n");
LocalDateTime dateTime = LocalDateTime.parse(shared.selectedCourse.getValue().getDateDepartCourse());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
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().getType()).append("\n");
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(pari.getMise()).append(" XOF\n");
tspl.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.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
public 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(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.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);
_initializeToZero();
} catch (SecurityException e) {
@@ -423,7 +486,7 @@ public class BetValidation extends Fragment {
TextView numero_course = (TextView) view.findViewById(R.id.alert_course_numero);
numero_course.setText("Numero Course: "+String.valueOf(shared.selectedCourse.getValue().getId()));
TextView alert_pari_type = (TextView) view.findViewById(R.id.alert_pari_type);
alert_pari_type.setText(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);
is_elargie.setText(selectedHorses.getValue().size() > shared.typeOfBet.getValue().getNumberOfHorse()?"CE":"SI");
TextView alert_combinaison = (TextView) view.findViewById(R.id.alert_combinaison);
@@ -433,7 +496,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(pari.getMise())+" CFA");
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);
@@ -442,21 +505,28 @@ public class BetValidation extends Fragment {
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
view.findViewById(R.id.alert_validate).setOnClickListener(v->{
pariViewModel.createPari(pari).observe(getViewLifecycleOwner(),new Observer<Result<Pari>>() {
pariViewModel.createPari(pari).observe(getViewLifecycleOwner(),new Observer<Result<ParisResponse>>() {
@Override
public void onChanged(Result<Pari> pariResult) {
public void onChanged(Result<ParisResponse> pariResult) {
switch (pariResult.status){
case ERROR:
Toast.makeText(getContext(), pariResult.message, Toast.LENGTH_SHORT).show();
loader.dismiss();
dialog.dismiss();
MessageDialog.showError(getContext(), pariResult.message);
break;
case LOADING:
Toast.makeText(getContext(), "En cours", Toast.LENGTH_SHORT).show();
loader.show("Prise de pari");
break;
case SUCCESS:
try {
printPari(pari);
loader.dismiss();
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();
MessageDialog.showSuccess(getContext(), "Pari créé avec succès");
} catch (WriterException e) {
loader.dismiss();
MessageDialog.showError(getContext(), e.getMessage());
throw new RuntimeException(e);
}
break;
@@ -485,11 +555,15 @@ public class BetValidation extends Fragment {
_notClickable(selectedHorses);
int nombreChevauxSelectionnes = selectedHorses.size();
long mise = 0;
int nonPartants = 0;
if(shared.typeOfBet.getValue() == null || shared.selectedCourse.getValue() == null){
return;
}
if(shared.selectedCourse.getValue().getNonPartants() != null){
nonPartants = shared.selectedCourse.getValue().getNonPartants().size();
}
int typeOfBetHorses = shared.typeOfBet.getValue().getNumberOfHorse();
int partants = shared.selectedCourse.getValue().getPartants();
int partants = shared.selectedCourse.getValue().getNombrePartants();
if(shared.typeOfBet.getValue().getNumberOfHorse() > nombreChevauxSelectionnes){
binding.mise.setText(mise+" CFA");
return;
@@ -505,15 +579,15 @@ public class BetValidation extends Fragment {
}
mise = mise * coeff;
if(nombreX>0){
if(nombreChevauxSelectionnes - typeOfBetHorses == 1){
mise = 0;
this.mise = mise;
binding.mise.setText(mise+" CFA");
return;
}
if(nombreChevauxSelectionnes == typeOfBetHorses){
mise = mise * _calculateArrangement((partants - (typeOfBetHorses-nombreX)), nombreX);
mise = mise * _calculateArrangement((partants - (typeOfBetHorses-nombreX) - nonPartants), nombreX);
}else{
if(nombreChevauxSelectionnes - typeOfBetHorses < nombreX || nombreChevauxSelectionnes - typeOfBetHorses==1){
mise = 0;
this.mise = mise;
binding.mise.setText(mise+" CFA");
return;
}
mise = mise * _calculateArrangement(nombreChevauxSelectionnes - typeOfBetHorses , nombreX);
}
if(order){

View File

@@ -4,12 +4,18 @@ import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.quiz.databinding.FragmentCaisseBinding;
import com.example.quiz.utils.AuthNavigator;
import com.example.quiz.utils.SessionManager;
import com.example.quiz.viewModel.LoginViewModel;
import com.example.quiz.viewModel.LogsViewModel;
import com.google.android.material.appbar.MaterialToolbar;
/**
@@ -21,6 +27,10 @@ public class Caisse extends Fragment {
FragmentCaisseBinding binding;
AuthNavigator authNavigator;
SessionManager sessionManager;
public Caisse() {
// Required empty public constructor
}
@@ -36,6 +46,9 @@ public class Caisse extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
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
@@ -52,39 +65,23 @@ public class Caisse extends Fragment {
@Override
public void onClick(View v) {
Sold sold = Sold.newInstance();
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, sold)
.addToBackStack(null)
.commit();
authNavigator.navigate(sold);
}
});
binding.winTicketBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
WinTicket winTicket = WinTicket.newInstance();
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, winTicket)
.addToBackStack(null)
.commit();
authNavigator.navigate(winTicket);
}
});
binding.cancelTicketBtn.setOnClickListener(v -> {
AnnulationTicket annulationTicket = AnnulationTicket.newInstance();
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, annulationTicket)
.addToBackStack(null)
.commit();
authNavigator.navigate(annulationTicket);
});
binding.lastBetsBtn.setOnClickListener(v -> {
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, DerniersParis.newInstance())
.addToBackStack(null)
.commit();
authNavigator.navigate(DerniersParis.newInstance());
});
}

View File

@@ -18,9 +18,13 @@ import android.widget.Toast;
import com.example.quiz.data.adapter.LastBetsAdapter;
import com.example.quiz.data.model.Pari;
import com.example.quiz.data.model.ParisResponse;
import com.example.quiz.databinding.FragmentDerniersParisBinding;
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;
@@ -38,6 +42,11 @@ import dagger.hilt.android.AndroidEntryPoint;
public class DerniersParis extends Fragment {
FragmentDerniersParisBinding binding;
LogsViewModel logsViewModel;
LoaderDialog loader;
SharedPrefsHelper prefsHelper;
PariViewModel viewModel;
@@ -65,6 +74,8 @@ public class DerniersParis extends Fragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentDerniersParisBinding.inflate(inflater, container, false);
loader = new LoaderDialog(getContext());
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
return binding.getRoot();
}
@@ -73,20 +84,24 @@ public class DerniersParis extends Fragment {
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<Result<List<Pari>>>() {
viewModel.getDerniersParis(prefsHelper.get("id")).observe(getViewLifecycleOwner(), new Observer<Result<List<ParisResponse>>>() {
@Override
public void onChanged(Result<List<Pari>> listResult) {
public void onChanged(Result<List<ParisResponse>> listResult) {
switch (listResult.status){
case LOADING:
Toast.makeText(getContext(), "En cours", Toast.LENGTH_SHORT).show();
loader.show("Chargement des derniers paris");
break;
case ERROR:
Toast.makeText(getContext(), listResult.message, Toast.LENGTH_SHORT).show();
loader.dismiss();
MessageDialog.showError(getContext(), listResult.message);
break;
case SUCCESS:
loader.dismiss();
adapter = new LastBetsAdapter(listResult.data, pari -> {
});
logsViewModel.insertLog(prefsHelper.get("id"), "LAST BETS", "Affichage derniers paris", System.currentTimeMillis());
binding.lastBetsRecyclerView.setAdapter(adapter);
break;
}
}
});

View File

@@ -24,14 +24,26 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import com.anggastudio.printama.Pref;
import com.anggastudio.printama.Printama;
import com.example.quiz.data.adapter.BetsAdapter;
import com.example.quiz.data.model.Course;
import com.example.quiz.data.model.PagedModel;
import com.example.quiz.databinding.FragmentListOFBettingBinding;
import com.example.quiz.utils.AuthNavigator;
import com.example.quiz.utils.BluetoothUtils;
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.CourseViewModel;
import com.example.quiz.viewModel.LoginViewModel;
import com.example.quiz.viewModel.LogsViewModel;
import com.example.quiz.viewModel.SharedViewModel;
import com.google.android.material.appbar.MaterialToolbar;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import dagger.hilt.android.AndroidEntryPoint;
@@ -47,12 +59,17 @@ public class ListOFBets extends Fragment {
FragmentListOFBettingBinding binding;
LoaderDialog loader;
private SharedViewModel shared;
private CourseViewModel viewModel;
AuthNavigator authNavigator;
private BetsAdapter adapter;
private AppCompatActivity activity;
@@ -66,15 +83,41 @@ public class ListOFBets extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SessionManager 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));
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
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentListOFBettingBinding.inflate(inflater, container, false);
loader = new LoaderDialog(getContext());
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
adapter = new BetsAdapter(shared);
adapter = new BetsAdapter();
binding.recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
binding.recyclerView.setAdapter(adapter);
viewModel = new ViewModelProvider(this).get(CourseViewModel.class);
@@ -100,25 +143,26 @@ public class ListOFBets extends Fragment {
}
public void observe(){
viewModel.getCourses(String.valueOf(shared.selectedReunion.getValue().getId())).observe(getViewLifecycleOwner(), new Observer<Result<List<Course>>>() {
String day = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(LocalDateTime.now());
viewModel.getCourses(day).observe(getViewLifecycleOwner(), new Observer<Result<PagedModel<Course>>>() {
@Override
public void onChanged(Result<List<Course>> result) {
public void onChanged(Result<PagedModel<Course>> result) {
switch (result.status){
case LOADING:
Toast.makeText(getContext(), "Loading", Toast.LENGTH_SHORT).show();
loader.show("Chargement des courses");
break;
case SUCCESS:
adapter.setBets(result.data);
loader.dismiss();
adapter.setBets(result.data.getContent());
adapter.setOnItemClickListener(course ->{
shared.setSelectedCourse(course);
FragmentManager fragmentManager = getParentFragmentManager();
ListOfTypeOfBets typeOfBets = ListOfTypeOfBets.newInstance();
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, typeOfBets)
.addToBackStack(null)
.commit();
authNavigator.navigate(typeOfBets);
});
break;
case ERROR:
loader.dismiss();
MessageDialog.showError(getContext(), result.message);
break;
}
}
@@ -169,6 +213,9 @@ public class ListOFBets extends Fragment {
AppCompatActivity activity = (AppCompatActivity) getActivity();
if(activity != null){
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
activity.getSupportActionBar().show();
toolbar.setBackgroundColor( getResources().getColor(R.color.primary_green));
toolbar.setTitleTextColor(getResources().getColor(R.color.white, null));
activity.setSupportActionBar(toolbar);
if(activity.getSupportActionBar() != null){
activity.getSupportActionBar().setTitle("Liste des courses");

View File

@@ -29,12 +29,18 @@ import com.example.quiz.data.adapter.ReunionAdapter;
import com.example.quiz.data.model.Reunion;
import com.example.quiz.databinding.FragmentListOfReunionsBinding;
import com.example.quiz.utils.BluetoothUtils;
import com.example.quiz.utils.LoaderDialog;
import com.example.quiz.utils.MessageDialog;
import com.example.quiz.utils.Result;
import com.example.quiz.viewModel.ReunionViewModel;
import com.example.quiz.viewModel.SharedViewModel;
import com.google.android.material.appbar.MaterialToolbar;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import dagger.hilt.android.AndroidEntryPoint;
@@ -52,6 +58,8 @@ public class ListOfReunions extends Fragment {
ReunionAdapter adapter;
LoaderDialog loader;
ReunionViewModel reunionViewModel;
@@ -99,6 +107,7 @@ public class ListOfReunions extends Fragment {
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentListOfReunionsBinding.inflate(inflater, container, false);
loader = new LoaderDialog(getContext());
adapter = new ReunionAdapter();
binding.reunionsList.setLayoutManager(new LinearLayoutManager(getContext()));
binding.reunionsList.setAdapter(adapter);
@@ -113,14 +122,17 @@ public class ListOfReunions extends Fragment {
}
public void observeReunions(){
reunionViewModel.getReunions().observe(getViewLifecycleOwner(), new Observer<Result<List<Reunion>>>() {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
String formattedDate = sdf.format(new Date());
reunionViewModel.getReunions(formattedDate).observe(getViewLifecycleOwner(), new Observer<Result<List<Reunion>>>() {
@Override
public void onChanged(Result<List<Reunion>> result) {
switch (result.status) {
case LOADING:
Toast.makeText(getContext(), "Loading", Toast.LENGTH_SHORT).show();
loader.show("Chargement des réunions");
break;
case SUCCESS:
loader.dismiss();
adapter.setReunions(result.data);
adapter.setOnItemClickListener(reunion->{
shared.setSelectedReunion(reunion);
@@ -133,7 +145,9 @@ public class ListOfReunions extends Fragment {
});
break;
case ERROR:
Toast.makeText(getContext(), result.message, Toast.LENGTH_SHORT).show();
loader.dismiss();
MessageDialog.showError(getContext(), result.message);
break;
}
}
});

View File

@@ -7,11 +7,9 @@ import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModel;
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;
@@ -19,14 +17,19 @@ import android.widget.Button;
import android.widget.Toast;
import com.example.quiz.data.adapter.TypeOfBetAdapter;
import com.example.quiz.data.model.Course;
import com.example.quiz.data.model.TypeOfBet;
import com.example.quiz.databinding.FragmentListOfTypeOfBetsBinding;
import com.example.quiz.utils.AuthNavigator;
import com.example.quiz.utils.SessionManager;
import com.example.quiz.viewModel.LoginViewModel;
import com.example.quiz.viewModel.LogsViewModel;
import com.example.quiz.viewModel.SharedViewModel;
import com.google.android.material.appbar.MaterialToolbar;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.concurrent.atomic.AtomicReference;
import dagger.hilt.android.AndroidEntryPoint;
@@ -41,6 +44,9 @@ public class ListOfTypeOfBets extends Fragment {
private FragmentListOfTypeOfBetsBinding binding;
SessionManager sessionManager;
AuthNavigator authNavigator;
private SharedViewModel shared;
private TypeOfBetAdapter adapter;
@@ -58,6 +64,8 @@ public class ListOfTypeOfBets extends Fragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sessionManager = SessionManager.newInstance(getContext());
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), sessionManager, new ViewModelProvider(this).get(LoginViewModel.class), new ViewModelProvider(this).get(LogsViewModel.class));
}
@Override
@@ -77,68 +85,39 @@ public class ListOfTypeOfBets extends Fragment {
// ⚡ Initialiser ladapter UNE SEULE FOIS
adapter = new TypeOfBetAdapter(new ArrayList<>());
adapter.setOnItemClickListener(type -> shared.setTypeOfBet(type));
binding.typeOfBetRecyclerView.setAdapter(adapter);
List<TypeOfBet> types = List.of(
new TypeOfBet(
"Couple placé",
"COUPLE_PLACE",
2
),
new TypeOfBet(
"Couple gagnant",
"COUPLE_GAGNANT",
2
),
new TypeOfBet(
"Tierce",
"TIERCE",
3
),
new TypeOfBet(
"Quarte +",
"QUARTE",
4
),
new TypeOfBet(
"Quinte +",
"QUINTE",
5
)
);
String betType = shared.selectedCourse.getValue().getType();
Log.d("BET_TYPE", betType);
List<Course.TypeParis> betType = shared.selectedCourse.getValue().getTypesParisOuverts();
List<TypeOfBet> useList = new ArrayList<>();
if(betType.toLowerCase().startsWith("quinte")){
useList = types.stream()
.filter(bet -> !bet.getName().toLowerCase().contains("quarte"))
.collect(Collectors.toList());
if(betType.contains(Course.TypeParis.QUINTE)){
useList.add(new TypeOfBet("Quinte", Course.TypeParis.QUINTE, 5));
}
if(betType.toLowerCase().startsWith("quarte")){
useList = types.subList(0, 4);
if(betType.contains(Course.TypeParis.QUARTE)){
useList.add(new TypeOfBet("Quarte", Course.TypeParis.QUARTE, 4));
}
if(betType.toLowerCase().startsWith("tierce")){
useList = types.subList(0, 3);
}
if(betType.toLowerCase().contains("couple")){
useList = types.subList(0, 2);
if(betType.contains(Course.TypeParis.TIERCE)){
useList.add(new TypeOfBet("Tierce", Course.TypeParis.TIERCE, 3));
}
if(betType.contains(Course.TypeParis.COUPLE_PLACE)){
useList.add(new TypeOfBet("Couple Place", Course.TypeParis.COUPLE_PLACE, 2));
}
if(betType.contains(Course.TypeParis.COUPLE_PLACE)){
useList.add(new TypeOfBet("Couple Gagnant", Course.TypeParis.COUPLE_GAGNANT, 2));
}
AtomicReference<TypeOfBet> typeOfBet = new AtomicReference<>();
adapter.setTypes(useList);
adapter.setOnItemClickListener(type -> {
shared.setTypeOfBet(type);
typeOfBet.set(type);
});
Button btnValidate = binding.btnValidate;
btnValidate.setOnClickListener(v->{
if(shared.typeOfBet.getValue() == null){
if(typeOfBet.get() == null){
Toast.makeText(getContext(),"Aucun Type de jeu choisi", Toast.LENGTH_SHORT).show();
return;
}
FragmentManager fragmentManager = getParentFragmentManager();
shared.setTypeOfBet(typeOfBet.get());
BetValidation betValidation = BetValidation.newInstance();
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, betValidation)
.addToBackStack(null)
.commit();
authNavigator.navigate(betValidation);
});
}

View File

@@ -6,13 +6,18 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.ViewModelProvider;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.quiz.databinding.FragmentLoginBinding;
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;
/**
* A simple {@link Fragment} subclass.
@@ -21,6 +26,8 @@ import com.example.quiz.utils.SharedPrefsHelper;
*/
public class Login extends Fragment {
private AuthNavigator authNavigator;
private SharedPrefsHelper prefsHelper;
public Login() {
// Required empty public constructor
@@ -51,6 +58,9 @@ public class Login extends Fragment {
@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SessionManager 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));
AppCompatActivity activity = (AppCompatActivity) getActivity();
if(activity != null){
activity.getSupportActionBar().hide();
@@ -63,14 +73,9 @@ public class Login extends Fragment {
binding.loginButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
prefsHelper = SharedPrefsHelper.getInstance(getContext());
FragmentManager fragmentManager = getParentFragmentManager();
ListOfReunions reunions = ListOfReunions.newInstance("");
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, reunions)
.addToBackStack(null)
.commit();
ListOFBets bets = ListOFBets.newInstance();
authNavigator.navigate(bets);
}
});
@@ -78,9 +83,17 @@ public class Login extends Fragment {
@Override
public void onClick(View v) {
Caisse caisse = Caisse.newInstance();
authNavigator.navigate(caisse);
}
});
binding.settings.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Settings settings = Settings.newInstance();
FragmentManager fragmentManager = getParentFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, caisse)
.replace(R.id.nav_host_fragment_content_main, settings)
.addToBackStack(null)
.commit();
}

View File

@@ -0,0 +1,118 @@
package com.example.quiz;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
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 android.widget.Toast;
import com.example.quiz.data.adapter.LogsAdapter;
import com.example.quiz.data.dao.UserActivityLogDao;
import com.example.quiz.data.database.DatabaseClient;
import com.example.quiz.databinding.FragmentLogsBinding;
import com.example.quiz.utils.LoaderDialog;
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 Logs#newInstance} factory method to
* create an instance of this fragment.
*/
@AndroidEntryPoint
public class Logs extends Fragment {
FragmentLogsBinding binding;
LogsViewModel viewModel;
private LogsAdapter adapter;
LoaderDialog loader;
public Logs() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static Logs newInstance() {
Logs fragment = new Logs();
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) {
binding = FragmentLogsBinding.inflate(inflater, container, false);
loader = new LoaderDialog(getContext());
adapter = new LogsAdapter();
binding.recyclerLogs.setLayoutManager(new LinearLayoutManager(getContext()));
binding.recyclerLogs.setAdapter(adapter);
// Inflate the layout for this fragment
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
AppCompatActivity activity = (AppCompatActivity) getActivity();
if (activity != null) {
if(activity.getSupportActionBar() != null){
activity.getSupportActionBar().setTitle("Historique");
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
toolbar.setBackgroundColor(getResources().getColor(R.color.primary_green));
toolbar.setTitleTextColor(getResources().getColor(R.color.white));
}
}
viewModel = new ViewModelProvider(this).get(LogsViewModel.class);
// Observer les logs
viewModel.getTodayLogs().observe(getViewLifecycleOwner(), new Observer<List<com.example.quiz.data.entity.Logs>>() {
@Override
public void onChanged(List<com.example.quiz.data.entity.Logs> logs) {
loader.show("Chargement des logs");
if(logs != null){
loader.dismiss();
adapter.setLogs(logs);
}else{
loader.dismiss();
showErrorAlert("Erreur", "Impossible de charger les logs");
}
}
});
}
private void showErrorAlert(String title, String message) {
new AlertDialog.Builder(requireContext())
.setTitle(title)
.setMessage(message)
.setCancelable(true)
.setPositiveButton("OK", (dialog, which) -> dialog.dismiss())
.show();
}
}

View File

@@ -1,28 +1,17 @@
package com.example.quiz;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import com.example.quiz.data.model.dtos.auth.LoginPayload;
import com.example.quiz.data.model.dtos.auth.LoginResponse;
import com.example.quiz.utils.Result;
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.google.android.material.snackbar.Snackbar;
import com.example.quiz.viewModel.LogsViewModel;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Looper;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
@@ -37,129 +26,121 @@ import dagger.hilt.android.AndroidEntryPoint;
public class PageQuiz extends AppCompatActivity {
LoginViewModel viewModel;
LogsViewModel logsViewModel;
AuthNavigator authNavigator;
private SessionManager sessionManager;
private AlertDialog dialog;
private Handler handler = new Handler();
private Runnable checkRunnable;
private AppBarConfiguration appBarConfiguration;
private ActivityPageQuizBinding binding;
private SharedPrefsHelper prefsHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sessionManager = SessionManager.newInstance(this);
binding = ActivityPageQuizBinding.inflate(getLayoutInflater());
_showPinDialog();
setContentView(binding.getRoot());
sessionManager = new SessionManager();
prefsHelper = SharedPrefsHelper.getInstance(getApplicationContext());
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
viewModel = new ViewModelProvider(this).get(LoginViewModel.class);
authNavigator = new AuthNavigator(this, getSupportFragmentManager(), sessionManager, viewModel, logsViewModel);
setSupportActionBar(binding.toolbar);
binding.toolbar.setBackgroundColor(Color.parseColor("#501C5A29"));
binding.fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAnchorView(R.id.fab)
.setAction("Action", null).show();
}
});
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
// void _showPinDialog(){
// LayoutInflater inflater = getLayoutInflater();
// View view = inflater.inflate(R.layout.pin_view, null);
//
// AlertDialog.Builder builder = new AlertDialog.Builder(this);
// builder.setView(view);
// builder.setCancelable(true);
//
// dialog = builder.create();
// dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
//
// view.findViewById(R.id.cancel).setOnClickListener(v -> dialog.dismiss());
//// Bouton OK
// view.findViewById(R.id.pin_validate).setOnClickListener(v -> {
// TextView pin = view.findViewById(R.id.pin);
// if(pin.getText().toString().isEmpty()){
// pin.setError("Entrez le pin!");
// return;
// }
// if(pin.getText().toString().length() < 4){
// pin.setError("Le pin doit contenir minimum quatre chiffres!");
// return;
// }
// LoginPayload loginPayload = new LoginPayload(
// pin.getText().toString()
// );
// viewModel.login(loginPayload).observe(this, new Observer<Result<LoginResponse>>() {
// @Override
// public void onChanged(Result<LoginResponse> loginResponseResult) {
// switch (loginResponseResult.status){
// case LOADING:
// view.findViewById(R.id.pin_validate).setEnabled(false);
// view.findViewById(R.id.pin_validate).setAlpha(0.5f);
// break;
// case ERROR:
// Toast.makeText(getApplicationContext(), loginResponseResult.message, Toast.LENGTH_SHORT).show();
// view.findViewById(R.id.pin_validate).setEnabled(true);
// view.findViewById(R.id.pin_validate).setAlpha(1f);
// break;
// case SUCCESS:
// loginSuccess(loginResponseResult.data);
// logsViewModel.insertLog(prefsHelper.get("id"), "LOGIN","Authentification sur l'appareil", System.currentTimeMillis());
// sessionManager.updateLastExpiredDate();
// dialog.dismiss();
// view.findViewById(R.id.pin_validate).setEnabled(true);
// view.findViewById(R.id.pin_validate).setAlpha(1f);
// break;
// }
// }
// });
// });
//
// dialog.show();
// }
//
//
// 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());
// }
if (dialog != null && dialog.isShowing()) {
return super.dispatchTouchEvent(ev);
}
if(sessionManager.isExpired()){
_showPinDialog();
return true;
}
sessionManager.updateLastExpiredDate();
return super.dispatchTouchEvent(ev);
}
void _showPinDialog(){
LayoutInflater inflater = getLayoutInflater();
View view = inflater.inflate(R.layout.pin_view, null);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(view);
builder.setCancelable(false);
dialog = builder.create();
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
// Bouton OK
view.findViewById(R.id.pin_validate).setOnClickListener(v -> {
TextView pin = view.findViewById(R.id.pin);
if(pin.getText().toString().isEmpty()){
pin.setError("Entrez le pin!");
return;
}
if(pin.getText().toString().length() != 5){
pin.setError("Le pin doit contenir 5 chiffres!");
return;
}
LoginPayload loginPayload = new LoginPayload(
pin.getText().toString()
);
viewModel.login(loginPayload).observe(this, new Observer<Result<LoginResponse>>() {
@Override
public void onChanged(Result<LoginResponse> loginResponseResult) {
switch (loginResponseResult.status){
case LOADING:
Toast.makeText(getApplicationContext(), "Loading",Toast.LENGTH_SHORT).show();
break;
case ERROR:
pin.setError("Pin incorrect");
break;
case SUCCESS:
loginSuccess(loginResponseResult.data);
sessionManager.updateLastExpiredDate();
dialog.dismiss();
break;
}
}
});
});
dialog.show();
}
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
protected void onResume() {
super.onResume();
handler = new Handler();
handler = new Handler(Looper.getMainLooper());
checkRunnable = new Runnable() {
@Override
public void run() {
if (sessionManager.isExpired()) {
if(dialog != null && !dialog.isShowing()){
_showPinDialog();
if (!authNavigator.dialogIsShowing()) {
authNavigator.showPinDialog(() -> {
sessionManager.updateLastExpiredDate();
handler.postDelayed(checkRunnable, 1);
});
}
} else {
handler.postDelayed(this, 10); // check every second
// Replanifie le check toutes les secondes
handler.postDelayed(this, 1);
}
}
};
handler.postDelayed(checkRunnable, 10);
handler.postDelayed(checkRunnable, 1);
}
@Override

View File

@@ -0,0 +1,275 @@
package com.example.quiz;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
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.provider.Settings;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.quiz.data.adapter.PointDeVenteAdapter;
import com.example.quiz.data.model.PagedModel;
import com.example.quiz.data.model.PointDeVente;
import com.example.quiz.data.model.Tpe;
import com.example.quiz.data.model.TpeResponse;
import com.example.quiz.databinding.FragmentServerConfigBinding;
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.PointDeVenteViewModel;
import com.example.quiz.viewModel.TpeViewModel;
import com.google.android.material.appbar.MaterialToolbar;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import dagger.hilt.android.AndroidEntryPoint;
/**
* A simple {@link Fragment} subclass.
* Use the {@link ServerConfig#newInstance} factory method to
* create an instance of this fragment.
*/
@AndroidEntryPoint
public class ServerConfig extends Fragment {
FragmentServerConfigBinding binding;
private TpeViewModel viewModel;
private SharedPrefsHelper sharedPrefsHelper;
private boolean isUserTap = true;
PointDeVenteAdapter pointDeVenteAdapter;
PointDeVente pdv = null;
private PointDeVenteViewModel pointDeVenteViewModel;
LoaderDialog loader;
public ServerConfig() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static ServerConfig newInstance() {
ServerConfig fragment = new ServerConfig();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedPrefsHelper = SharedPrefsHelper.getInstance(getContext());
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentServerConfigBinding.inflate(inflater, container, false);
viewModel = new ViewModelProvider(this).get(TpeViewModel.class);
pointDeVenteViewModel = new ViewModelProvider(this).get(PointDeVenteViewModel.class);
loader = new LoaderDialog(getContext());
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
AppCompatActivity activity = (AppCompatActivity) getActivity();
if(activity != null){
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
toolbar.setTitle("Configuration du terminal");
toolbar.setBackgroundColor( getResources().getColor(R.color.primary_green));
}
pointDeVenteAdapter = new PointDeVenteAdapter();
RecyclerView recyclerView = binding.pointRecyclerView;
recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
binding.pointDeVente.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if(!isUserTap) return;
if(charSequence.toString().isEmpty() || charSequence.toString().length()==0){
recyclerView.setVisibility(View.GONE);
binding.autocompleteContainer.setVisibility(View.GONE);
return;
}
pointDeVenteViewModel.setPointsDeVente(charSequence.toString()).observe(getViewLifecycleOwner(), new Observer<Result<PagedModel<PointDeVente>>>() {
@Override
public void onChanged(Result<PagedModel<PointDeVente>> pagedModelResult) {
switch (pagedModelResult.status){
case LOADING:
binding.autocompleteContainer.setVisibility(View.VISIBLE);
binding.loader.setVisibility(View.VISIBLE);
break;
case SUCCESS:
binding.autocompleteContainer.setVisibility(View.VISIBLE);
binding.loader.setVisibility(View.GONE);
List<PointDeVente> pointsDeVente = pagedModelResult.data.getContent();
recyclerView.setVisibility(View.VISIBLE);
pointDeVenteAdapter.setPoints(pointsDeVente);
recyclerView.setAdapter(pointDeVenteAdapter);
pointDeVenteAdapter.setOnItemClickListener((PointDeVente pointDeVente)->{
pdv = pointDeVente;
isUserTap = false;
binding.pointDeVente.setText(pointDeVente.getNom());
isUserTap = true;
binding.autocompleteContainer.setVisibility(View.GONE);
binding.loader.setVisibility(View.GONE);
});
break;
case ERROR:
binding.autocompleteContainer.setVisibility(View.GONE);
binding.loader.setVisibility(View.GONE);
MessageDialog.showError(getContext(), "Erreur lors du chargement des points de vente");
break;
}
}
});
}
@Override
public void afterTextChanged(Editable editable) {
}
});
super.onViewCreated(view, savedInstanceState);
}
@Override
public void onResume() {
String serialNumber = Settings.Secure.getString(getContext().getContentResolver(), Settings.Secure.ANDROID_ID);
binding.numeroSerie.setText(serialNumber);
binding.brand.setText(Build.BRAND);
binding.model.setText(Build.MODEL);
binding.type.setText("POS");
binding.validate.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(pdv == null){
MessageDialog.showError(getContext(), "Veuillez sélectionner un point de vente");
return;
}
Tpe tpe = new Tpe();
tpe.setNumeroSerie(serialNumber);
tpe.setVersionOs(Build.VERSION.RELEASE);
tpe.setVersionLogicielle(getAppVersion(getContext()));
tpe.setPlateforme("PMU_BET");
tpe.setSystemeExploitation("Android");
tpe.setPointDeVenteId(pdv.getId());
tpe.setAdresseIp(getLocalIpAddress());
tpe.setModeleAppareil(Build.MODEL);
tpe.setTypeTerminal("POS/"+Build.BRAND);
tpe.setStatut("ACTIF");
viewModel.createTpe(tpe).observe(getViewLifecycleOwner(), new Observer<Result<TpeResponse>>() {
@Override
public void onChanged(Result<TpeResponse> tpeResult) {
switch (tpeResult.status){
case LOADING:
loader.show("Création du TPE");
break;
case SUCCESS:
loader.dismiss();
MessageDialog.showSuccess(getContext(), "TPE configuré avec succès!");
sharedPrefsHelper.save("terminalId", String.valueOf(tpeResult.data.getId()));
sharedPrefsHelper.save("pointDeVenteId", String.valueOf(tpeResult.data.getPointDeVenteId()));
break;
case ERROR:
loader.dismiss();
MessageDialog.showError(getContext(), "Erreur lors de la configuration du TPE");
break;
}
}
});
}
});
binding.cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (getActivity() != null) {
getActivity().getSupportFragmentManager().popBackStack();
}
}
});
super.onResume();
}
public String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress();
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return "0.0.0.0";
}
public static String getAppVersion(Context context) {
try {
return context.getPackageManager()
.getPackageInfo(context.getPackageName(), 0)
.versionName;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
return "Version inconnue";
}
}
public static String getMacAddress() {
try {
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for (NetworkInterface nif : interfaces) {
if (!nif.getName().equalsIgnoreCase("wlan0")) continue;
byte[] macBytes = nif.getHardwareAddress();
if (macBytes == null) return "N/A";
StringBuilder res1 = new StringBuilder();
for (byte b : macBytes) {
res1.append(String.format("%02X:", b));
}
if (res1.length() > 0) res1.deleteCharAt(res1.length() - 1);
return res1.toString();
}
} catch (Exception ex) {
ex.printStackTrace();
}
return "N/A";
}
}

View File

@@ -0,0 +1,98 @@
package com.example.quiz;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.quiz.databinding.FragmentSettingsBinding;
import com.google.android.material.appbar.MaterialToolbar;
/**
* A simple {@link Fragment} subclass.
* Use the {@link Settings#newInstance} factory method to
* create an instance of this fragment.
*/
public class Settings 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
FragmentSettingsBinding binding;
public Settings() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static Settings newInstance() {
Settings fragment = new Settings();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
binding = FragmentSettingsBinding.inflate(inflater, container, false);
// Inflate the layout for this fragment
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, 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("Choisissez une action à effectuer");
}
toolbar.setBackgroundColor(getResources().getColor(R.color.primary_green, null));
toolbar.setTitleTextColor(getResources().getColor(R.color.white, null));
}
binding.logs.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Logs logs = Logs.newInstance();
FragmentManager fragmentManager = getParentFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, logs)
.addToBackStack(null)
.commit();
}
});
binding.serverConfig.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ServerConfig serverConfig = ServerConfig.newInstance();
FragmentManager fragmentManager = getParentFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, serverConfig)
.addToBackStack(null)
.commit();
}
});
}
}

View File

@@ -20,8 +20,11 @@ import android.view.ViewGroup;
import android.widget.Toast;
import com.example.quiz.databinding.FragmentSoldBinding;
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;
@@ -39,8 +42,11 @@ public class Sold extends Fragment {
FragmentSoldBinding binding;
LoaderDialog dialog;
PariViewModel pariViewModel;
SharedPrefsHelper prefsHelper;
LogsViewModel logsViewModel;
public Sold() {
// Required empty public constructor
@@ -73,6 +79,8 @@ public class Sold extends Fragment {
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding = FragmentSoldBinding.inflate(inflater, container, false);
dialog = new LoaderDialog(getContext());
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
return binding.getRoot();
}
@@ -95,27 +103,36 @@ public class Sold extends Fragment {
});
}
String _reformatDateForDate(int num){
if(num<10){
return "0"+num;
}
return String.valueOf(num);
}
void _showCalendar(){
Calendar calendar = Calendar.getInstance();
DatePickerDialog datePickerDialog = new DatePickerDialog(
getContext(),
(view, year, month, dayOfMonth) -> {
String date = year + "-" + (month + 1) + "-" + dayOfMonth;
pariViewModel.getSoldeByDay(prefsHelper.get("code"), date).observe(getViewLifecycleOwner(), new Observer<Result<Double>>() {
String date = year + "-" + _reformatDateForDate(month + 1) + "-" + _reformatDateForDate(dayOfMonth);
pariViewModel.getSoldeByDay(prefsHelper.get("id"), date).observe(getViewLifecycleOwner(), new Observer<Result<Double>>() {
@Override
public void onChanged(Result<Double> doubleResult) {
switch (doubleResult.status){
case LOADING:{
Toast.makeText(getContext(), "En cours", Toast.LENGTH_SHORT).show();
dialog.show("Solde du jour");
break;
}
case ERROR:{
Log.d("Response", doubleResult.message);
dialog.dismiss();
MessageDialog.showError(getContext(), doubleResult.message);
break;
}
case SUCCESS:{
dialog.dismiss();
_showSold(doubleResult.data);
logsViewModel.insertLog(prefsHelper.get("id"), "SOLDE JOUR", "Solde du "+date, System.currentTimeMillis());
break;
}
}

View File

@@ -15,8 +15,11 @@ import android.view.ViewGroup;
import android.widget.Toast;
import com.example.quiz.databinding.FragmentSoldByCourseBinding;
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 dagger.hilt.android.AndroidEntryPoint;
@@ -32,6 +35,10 @@ public class SoldByCourse extends Fragment {
FragmentSoldByCourseBinding binding;
LoaderDialog loader;
LogsViewModel logsViewModel;
PariViewModel pariViewModel;
SharedPrefsHelper prefsHelper;
@@ -56,33 +63,38 @@ public class SoldByCourse extends Fragment {
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding = FragmentSoldByCourseBinding.inflate(inflater, container, false);
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
return binding.getRoot();
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
pariViewModel = new ViewModelProvider(this).get(PariViewModel.class);
loader = new LoaderDialog(getContext());
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;
}
pariViewModel.getSoldeByCourse(prefsHelper.get("code"), binding.etRaceNumber.getText().toString()).observe(getViewLifecycleOwner(), new Observer<Result<Double>>() {
pariViewModel.getSoldeByCourse(prefsHelper.get("id"), binding.etRaceNumber.getText().toString()).observe(getViewLifecycleOwner(), new Observer<Result<Double>>() {
@Override
public void onChanged(Result<Double> doubleResult) {
switch (doubleResult.status){
case LOADING:{
Toast.makeText(getContext(), "Chargement..", Toast.LENGTH_SHORT).show();
loader.show("Chargement du solde");
break;
}
case ERROR:{
Toast.makeText(getContext(), doubleResult.message, Toast.LENGTH_SHORT).show();
loader.dismiss();
MessageDialog.showError(getContext(), doubleResult.message);
break;
}
case SUCCESS:{
loader.dismiss();
_showPariDialog(doubleResult.data);
logsViewModel.insertLog(prefsHelper.get("id"), "SOLDE COURSE", "Solde de la course "+binding.etRaceNumber.getText(), System.currentTimeMillis());
break;
}
}

View File

@@ -0,0 +1,28 @@
package com.example.quiz.data;
import android.os.AsyncTask;
import com.example.quiz.data.dao.UserActivityLogDao;
import com.example.quiz.data.entity.Logs;
import java.util.concurrent.Executors;
public class ActivityLogger {
public static UserActivityLogDao dao;
public static void init(UserActivityLogDao iDao){
dao = iDao;
}
public static void log(String userId, String activity, String description, Long timestamp){
Executors.newSingleThreadExecutor().execute(()->{
Logs userLog = new Logs();
userLog.setUserId(userId);
userLog.setAction(activity);
userLog.setDescription(description);
userLog.setTimestamp(timestamp);
dao.insertLog(userLog);
});
}
}

View File

@@ -14,7 +14,9 @@ import com.example.quiz.data.model.Course;
import com.example.quiz.viewModel.SharedViewModel;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
@@ -22,10 +24,8 @@ public class BetsAdapter extends RecyclerView.Adapter<BetsAdapter.BetViewHolder>
private List<Course> bets = new ArrayList<>();
private onItemClickListener listener;
private SharedViewModel shared;
public BetsAdapter(SharedViewModel shared) {
this.shared = shared;
public BetsAdapter() {
}
public interface onItemClickListener {
@@ -52,18 +52,14 @@ public class BetsAdapter extends RecyclerView.Adapter<BetsAdapter.BetViewHolder>
@Override
public void onBindViewHolder(@NonNull BetViewHolder holder, int position) {
Course bet = bets.get(position);
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")
));
OffsetDateTime dateTime = OffsetDateTime.parse(bet.getHeureDepartPrevue());
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm");
String formattedDate = dateTime.format(formatter);
holder.tvDate.setText(formattedDate);
holder.tvName.setText(bet.getNom());
if (shared != null && shared.selectedReunion.getValue() != null) {
holder.tvReunion.setText(shared.selectedReunion.getValue().getNom());
}
String reunion = "Reunion "+bet.getReunionNumero();
holder.tvReunion.setText(reunion);
holder.itemView.setOnClickListener(v -> {
if (listener != null) listener.onItemClick(bet);

View File

@@ -9,19 +9,21 @@ import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.example.quiz.R;
import com.example.quiz.data.model.Pari;
import com.example.quiz.data.model.ParisResponse;
import java.util.ArrayList;
import java.util.List;
public class LastBetsAdapter extends RecyclerView.Adapter<LastBetsAdapter.LastBetsViewHolder> {
private List<Pari> 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 {
void onItemClick(Pari pari);
void onItemClick(ParisResponse pari);
}
public LastBetsAdapter(List<Pari> listeParis, OnBetClick onBetClick) {
public LastBetsAdapter(List<ParisResponse> listeParis, OnBetClick onBetClick) {
if (listeParis != null) this.listeParis = listeParis;
this.onBetClick = onBetClick;
}
@@ -31,7 +33,7 @@ public class LastBetsAdapter extends RecyclerView.Adapter<LastBetsAdapter.LastBe
this.onBetClick = onBetClick;
}
public void setData(List<Pari> newList) {
public void setData(List<ParisResponse> newList) {
if (newList == null) {
this.listeParis = new ArrayList<>();
} else {
@@ -40,7 +42,7 @@ public class LastBetsAdapter extends RecyclerView.Adapter<LastBetsAdapter.LastBe
notifyDataSetChanged();
}
public void addItem(Pari pari) {
public void addItem(ParisResponse pari) {
if (pari == null) return;
this.listeParis.add(pari);
notifyItemInserted(listeParis.size() - 1);
@@ -60,38 +62,21 @@ public class LastBetsAdapter extends RecyclerView.Adapter<LastBetsAdapter.LastBe
@Override
public void onBindViewHolder(@NonNull LastBetsViewHolder holder, int position) {
Pari pari = listeParis.get(position);
ParisResponse pari = listeParis.get(position);
if (pari == null) return;
holder.typeOfCourse.setText(pari.getCourse().getType());
holder.typeOfCourse.setText(pari.getCourseNom());
holder.refenceTicket.setText(pari.getNumeroTicket());
// Type (défensif : vérifie null)
holder.betType.setText(pari.getTypePari() != null ? pari.getTypePari() : "-");
holder.betType.setText(pari.getFormules().size()>0 ? pari.getFormules().get(0):"Pas de formule");
// Course (défensif : course peut être null)
if (pari.getCourse() != null) {
holder.course.setText("Course: " + pari.getCourse().getId());
} else {
holder.course.setText("Course: -");
}
holder.course.setText("Course: " + pari.getCourseId());
// 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<String> 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 : -");
}
holder.horses.setText(pari.getCombinaison());
// Mise (défensif)
holder.mise.setText("Mise: " + pari.getMise() + " CFA");
holder.mise.setText("Mise: " + pari.getMiseTotale() + " CFA");
// click listener défensif
holder.itemView.setOnClickListener(v -> {

View File

@@ -0,0 +1,63 @@
package com.example.quiz.data.adapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.example.quiz.R;
import com.example.quiz.data.entity.Logs;
import org.jspecify.annotations.NonNull;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
public class LogsAdapter extends RecyclerView.Adapter<LogsAdapter.LogViewHolder> {
private List<Logs> logs = new ArrayList<>();
public void setLogs(List<Logs> logs) {
this.logs = logs;
notifyDataSetChanged();
}
@NonNull
@Override
public LogViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_log, parent, false);
return new LogViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull LogViewHolder holder, int position) {
Logs log = logs.get(position);
holder.textAction.setText(log.getAction());
holder.textDescription.setText(log.getDescription());
SimpleDateFormat sdf = new SimpleDateFormat("dd MMM yyyy • HH:mm", Locale.getDefault());
holder.textDate.setText(sdf.format(new Date(log.getTimestamp())));
}
@Override
public int getItemCount() {
return logs.size();
}
static class LogViewHolder extends RecyclerView.ViewHolder {
TextView textAction, textDescription, textDate;
public LogViewHolder(@NonNull View itemView) {
super(itemView);
textAction = itemView.findViewById(R.id.textAction);
textDescription = itemView.findViewById(R.id.textDescription);
textDate = itemView.findViewById(R.id.textDate);
}
}
}

View File

@@ -0,0 +1,78 @@
package com.example.quiz.data.adapter;
import android.util.Log;
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.PointDeVente;
import java.util.ArrayList;
import java.util.List;
public class PointDeVenteAdapter extends RecyclerView.Adapter<PointDeVenteAdapter.ViewHolder> {
private List<PointDeVente> points = new ArrayList<>();
private OnItemClickListener listener;
public PointDeVenteAdapter(){
}
// Interface pour gérer le clic sur un item
public interface OnItemClickListener {
void onItemClick(PointDeVente point);
}
public void setOnItemClickListener(OnItemClickListener listener) {
this.listener = listener;
}
public void setPoints(List<PointDeVente> points) {
this.points = points;
notifyDataSetChanged();
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_point_de_vente, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
PointDeVente point = points.get(position);
holder.txtNom.setText(point.getNom());
String adresse = point.getVille()+", "+point.getAdresse();
holder.txtAdresse.setText(adresse);
holder.itemView.setOnClickListener(v -> {
if (listener != null) listener.onItemClick(point);
});
}
@Override
public int getItemCount() {
return points.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {
TextView txtNom;
TextView txtAdresse;
public ViewHolder(@NonNull View itemView) {
super(itemView);
txtNom = itemView.findViewById(R.id.txtNom);
txtAdresse = itemView.findViewById(R.id.txtAdresse);
}
}
}

View File

@@ -0,0 +1,20 @@
package com.example.quiz.data.dao;
import androidx.lifecycle.LiveData;
import androidx.room.Dao;
import androidx.room.Insert;
import androidx.room.Query;
import com.example.quiz.data.entity.Logs;
import java.util.List;
@Dao
public interface UserActivityLogDao {
@Insert
void insertLog(Logs log);
@Query(" SELECT * FROM user_activity_logs WHERE date(timestamp / 1000, 'unixepoch', 'localtime') = date('now', 'localtime') ORDER BY timestamp DESC ")
LiveData<List<Logs>> getTodayLogs();
}

View File

@@ -0,0 +1,30 @@
package com.example.quiz.data.database;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
import com.example.quiz.data.dao.UserActivityLogDao;
import com.example.quiz.data.entity.Logs;
@Database(entities = {Logs.class}, version = 3, exportSchema = false)
public abstract class AppDataBase extends RoomDatabase {
private static AppDataBase instance;
public abstract UserActivityLogDao logsDao();
public static synchronized AppDataBase getInstance(Context context) {
if (instance == null) {
instance = Room.databaseBuilder(
context.getApplicationContext(),
AppDataBase.class,
"app-db"
).fallbackToDestructiveMigration() // optionnel
.build();
}
return instance;
}
}

View File

@@ -0,0 +1,34 @@
package com.example.quiz.data.database;
import android.content.Context;
import androidx.room.Room;
public class DatabaseClient {
private static DatabaseClient instance;
private AppDataBase appDatabase;
private Context context;
private DatabaseClient(Context context) {
this.context = context;
appDatabase = Room.databaseBuilder(context,
AppDataBase.class, "QuizDB")
.fallbackToDestructiveMigration()
.build();
}
public static synchronized DatabaseClient getInstance(Context context) {
if (instance == null) {
instance = new DatabaseClient(context);
}
return instance;
}
public AppDataBase getAppDatabase() {
return appDatabase;
}
}

View File

@@ -0,0 +1,33 @@
package com.example.quiz.data.database;
import android.content.Context;
import androidx.room.Room;
import com.example.quiz.data.dao.UserActivityLogDao;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
import dagger.hilt.InstallIn;
import dagger.hilt.android.qualifiers.ApplicationContext;
import dagger.hilt.components.SingletonComponent;
@Module
@InstallIn(SingletonComponent.class)
public class DatabaseModule {
@Provides
@Singleton
public static AppDataBase provideDatabase(@ApplicationContext Context context) {
return Room.databaseBuilder(context, AppDataBase.class, "QuizDB")
.fallbackToDestructiveMigration()
.build();
}
@Provides
public static UserActivityLogDao provideUserActivityLogDao(AppDataBase db) {
return db.logsDao(); // ton DAO
}
}

View File

@@ -0,0 +1,59 @@
package com.example.quiz.data.entity;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity(tableName = "user_activity_logs")
public class Logs {
@PrimaryKey(autoGenerate = true)
private int id;
private String userId;
private String action;
private String description;
private Long timestamp;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return id;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public Long getTimestamp() {
return timestamp;
}
public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}
}

View File

@@ -8,117 +8,75 @@ import java.util.List;
public class Course {
private int id;
private String type;
private String numero;
private long id;
private long hippodromeId;
private long reunionNumero;
private String reunionDate;
private String nom;
private String lieu;
private String dateDepartCourse;
private int reunionId;
private String particularite;
private int partants;
private String statut;
private int nombreChevauxInscrits;
public Course(int id, String type, String numero, String nom, String lieu, String dateDepartCourse, int reunionId, String particularite, int partants, String statut, int nombreChevauxInscrits) {
this.id = id;
this.type = type;
this.numero = numero;
this.nom = nom;
this.lieu = lieu;
this.dateDepartCourse = dateDepartCourse;
this.reunionId = reunionId;
this.particularite = particularite;
this.partants = partants;
this.statut = statut;
this.nombreChevauxInscrits = nombreChevauxInscrits;
private int numero;
private String heureDepartPrevue;
private boolean bettingOpen;
private String bettingClosedAt;
private String discipline;
private int distanceMetres;
private String categorie;
private int nombrePartants;
private Statut statut;
private boolean annulee;
private boolean reporteeMemeJour;
private boolean reporteeAutreJour;
private boolean incidentTechnique;
private List<Integer> nonPartants;
private List<TypeParis> typesParisOuverts;
// ===== ENUMS =====
public enum Statut {
BROUILLON,
VALIDE,
OUVERT,
FERME,
RESULTAT_PROVISOIRE,
RESULTAT_OFFICIEL,
REGLEE,
ANNULEE
}
public int getId() {
return id;
public enum TypeParis {
COUPLE_GAGNANT,
COUPLE_PLACE,
TIERCE,
QUARTE,
QUINTE
}
public void setId(int id) {
this.id = id;
}
// ===== GETTERS & SETTERS =====
public String getType() {
return type;
}
public void setType(String stype) {
this.type = stype;
}
public String getNumero() {
return numero;
}
public void setNumero(String numero) {
this.numero = numero;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getLieu() {
return lieu;
}
public void setLieu(String lieu) {
this.lieu = lieu;
}
public String getDateDepartCourse() {
return dateDepartCourse;
}
public void setDateDepartCourse(String dateDepartCourse) {
this.dateDepartCourse = dateDepartCourse;
}
public int getReunionId() {
return reunionId;
}
public void setReunionId(int reunionId) {
this.reunionId = reunionId;
}
public String getParticularite() {
return particularite;
}
public void setParticularite(String particularite) {
this.particularite = particularite;
}
public int getPartants() {
return partants;
}
public void setPartants(int partants) {
this.partants = partants;
}
public String getStatut() {
return statut;
}
public void setStatut(String statut) {
this.statut = statut;
}
public int getNombreChevauxInscrits() {
return nombreChevauxInscrits;
}
public void setNombreChevauxInscrits(int nombreChevauxInscrits) {
this.nombreChevauxInscrits = nombreChevauxInscrits;
}
public long getId() { return id; }
public long getHippodromeId() { return hippodromeId; }
public long getReunionNumero() { return reunionNumero; }
public String getReunionDate() { return reunionDate; }
public String getNom() { return nom; }
public int getNumero() { return numero; }
public String getHeureDepartPrevue() { return heureDepartPrevue; }
public boolean isBettingOpen() { return bettingOpen; }
public String getBettingClosedAt() { return bettingClosedAt; }
public String getDiscipline() { return discipline; }
public int getDistanceMetres() { return distanceMetres; }
public String getCategorie() { return categorie; }
public int getNombrePartants() { return nombrePartants; }
public Statut getStatut() { return statut; }
public boolean isAnnulee() { return annulee; }
public boolean isReporteeMemeJour() { return reporteeMemeJour; }
public boolean isReporteeAutreJour() { return reporteeAutreJour; }
public boolean isIncidentTechnique() { return incidentTechnique; }
public List<Integer> getNonPartants() { return nonPartants; }
public List<TypeParis> getTypesParisOuverts() { return typesParisOuverts; }
}

View File

@@ -0,0 +1,62 @@
package com.example.quiz.data.model;
import com.example.quiz.data.model.enums.Pageable;
import java.util.List;
public class PagedModel<T> {
private Long totalPages;
private Long totalElements;
private Pageable pageable;
private Long numberOfElements;
private Long size;
private List<T> content;
public Long getTotalPages() {
return totalPages;
}
public void setTotalPages(Long totalPages) {
this.totalPages = totalPages;
}
public Long getTotalElements() {
return totalElements;
}
public void setTotalElements(Long totalElements) {
this.totalElements = totalElements;
}
public Pageable getPageable() {
return pageable;
}
public void setPageable(Pageable pageable) {
this.pageable = pageable;
}
public Long getNumberOfElements() {
return numberOfElements;
}
public void setNumberOfElements(Long numberOfElements) {
this.numberOfElements = numberOfElements;
}
public Long getSize() {
return size;
}
public void setSize(Long size) {
this.size = size;
}
public List<T> getContent() {
return content;
}
public void setContent(List<T> content) {
this.content = content;
}
}

View File

@@ -4,129 +4,51 @@ import com.example.quiz.data.model.enums.PariStatut;
import java.util.List;
import java.util.Map;
import java.util.List;
import java.util.List;
public class Pari {
private String numeroTicket;
private String typePari;
private double mise;
private String datePari;
private boolean estPaye;
private boolean estRembourse;
private PariCourseDto course;
private List<String> chevauxSelectionnes;
private List<String> ordrePredit;
private boolean validationOrdreExact;
private String typeMulti;
private String createdBy;
private String dateHeurePrise; // ISO String
private long courseId;
private long agentId;
private long terminalId;
private long pointDeVenteId;
public Pari(String numeroTicket, String typePari, double mise, String datePari, boolean estPaye, boolean estRembourse, PariCourseDto course, List<String> chevauxSelectionnes, List<String> ordrePredit, boolean validationOrdreExact, String typeMulti, String createdBy) {
this.numeroTicket = numeroTicket;
this.typePari = typePari;
this.mise = mise;
this.datePari = datePari;
this.estPaye = estPaye;
this.estRembourse = estRembourse;
this.course = course;
this.chevauxSelectionnes = chevauxSelectionnes;
this.ordrePredit = ordrePredit;
this.validationOrdreExact = validationOrdreExact;
this.typeMulti = typeMulti;
this.createdBy = createdBy;
private List<PariMise> typesParisMises;
private List<String> formules;
private String combinaison;
private double coefficient;
private String devise;
private String notes;
public Pari(String dateHeurePrise, long courseId, long agentId, long terminalId, long pointDeVenteId, List<PariMise> typesParisMises, List<String> formules, String combinaison, double coefficient, String devise, String notes) {
this.dateHeurePrise = dateHeurePrise;
this.courseId = courseId;
this.agentId = agentId;
this.terminalId = terminalId;
this.pointDeVenteId = pointDeVenteId;
this.typesParisMises = typesParisMises;
this.formules = formules;
this.combinaison = combinaison;
this.coefficient = coefficient;
this.devise = devise;
this.notes = notes;
}
public String getNumeroTicket() {
return numeroTicket;
}
public String getDateHeurePrise() { return dateHeurePrise; }
public long getCourseId() { return courseId; }
public long getAgentId() { return agentId; }
public long getTerminalId() { return terminalId; }
public long getPointDeVenteId() { return pointDeVenteId; }
public List<PariMise> getTypesParisMises() { return typesParisMises; }
public List<String> getFormules() { return formules; }
public String getCombinaison() { return combinaison; }
public double getCoefficient() { return coefficient; }
public String getDevise() { return devise; }
public String getNotes() { return notes; }
public void setNumeroTicket(String numeroTicket) {
this.numeroTicket = numeroTicket;
}
public String getTypePari() {
return typePari;
}
public void setTypePari(String typePari) {
this.typePari = typePari;
}
public double getMise() {
return mise;
}
public void setMise(double mise) {
this.mise = mise;
}
public String getDatePari() {
return datePari;
}
public void setDatePari(String datePari) {
this.datePari = datePari;
}
public boolean isEstPaye() {
return estPaye;
}
public void setEstPaye(boolean estPaye) {
this.estPaye = estPaye;
}
public boolean isEstRembourse() {
return estRembourse;
}
public void setEstRembourse(boolean estRembourse) {
this.estRembourse = estRembourse;
}
public PariCourseDto getCourse() {
return course;
}
public void setCourse(PariCourseDto course) {
this.course = course;
}
public List<String> getChevauxSelectionnes() {
return chevauxSelectionnes;
}
public void setChevauxSelectionnes(List<String> chevauxSelectionnes) {
this.chevauxSelectionnes = chevauxSelectionnes;
}
public List<String> getOrdrePredit() {
return ordrePredit;
}
public void setOrdrePredit(List<String> ordrePredit) {
this.ordrePredit = ordrePredit;
}
public boolean isValidationOrdreExact() {
return validationOrdreExact;
}
public void setValidationOrdreExact(boolean validationOrdreExact) {
this.validationOrdreExact = validationOrdreExact;
}
public String getTypeMulti() {
return typeMulti;
}
public void setTypeMulti(String typeMulti) {
this.typeMulti = typeMulti;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
// ===== INNER CLASS =====
}

View File

@@ -0,0 +1,19 @@
package com.example.quiz.data.model;
public class PariMise {
private String typePari;
private long miseTotale;
public PariMise(String typePari, long miseTotale) {
this.typePari = typePari;
this.miseTotale = miseTotale;
}
public String getTypePari() {
return typePari;
}
public long getMiseTotale() {
return miseTotale;
}
}

View File

@@ -0,0 +1,100 @@
package com.example.quiz.data.model;
import java.io.Serializable;
import java.util.List;
public class ParisResponse implements Serializable {
private long id;
private String numeroTicket;
private String dateHeurePrise;
private String qrPayload;
private long courseId;
private String courseNom;
private int courseNumero;
private String hippodromeNom;
private long reunionNumero;
private String reunionDate;
private String heureDepartPrevue;
private int nombrePartants;
private List<Integer> nonPartants;
private long agentId;
private String agentCode;
private String agentNom;
private long terminalId;
private String terminalNumeroSerie;
private long pointDeVenteId;
private String pointDeVenteCode;
private String pointDeVenteNom;
private List<PariMise> typesParisMises;
private long miseTotale;
private List<String> formules;
private double coefficient;
private String combinaison;
private StatutPari statutPari;
private long gainCalcule;
private String devise;
private String dateReglement;
private String datePaiement;
private String notes;
// ================= ENUM =================
public enum StatutPari {
ENREGISTRE,
VALIDE,
PAYE,
ANNULE,
PERDANT,
GAGNANT
}
// ================= INNER CLASS =================
// ================= GETTERS =================
public long getId() { return id; }
public String getNumeroTicket() { return numeroTicket; }
public String getDateHeurePrise() { return dateHeurePrise; }
public String getQrPayload() { return qrPayload; }
public long getCourseId() { return courseId; }
public String getCourseNom() { return courseNom; }
public int getCourseNumero() { return courseNumero; }
public String getHippodromeNom() { return hippodromeNom; }
public long getReunionNumero() { return reunionNumero; }
public String getReunionDate() { return reunionDate; }
public String getHeureDepartPrevue() { return heureDepartPrevue; }
public int getNombrePartants() { return nombrePartants; }
public List<Integer> getNonPartants() { return nonPartants; }
public long getAgentId() { return agentId; }
public String getAgentCode() { return agentCode; }
public String getAgentNom() { return agentNom; }
public long getTerminalId() { return terminalId; }
public String getTerminalNumeroSerie() { return terminalNumeroSerie; }
public long getPointDeVenteId() { return pointDeVenteId; }
public String getPointDeVenteCode() { return pointDeVenteCode; }
public String getPointDeVenteNom() { return pointDeVenteNom; }
public List<PariMise> getTypesParisMises() { return typesParisMises; }
public long getMiseTotale() { return miseTotale; }
public List<String> getFormules() { return formules; }
public double getCoefficient() { return coefficient; }
public String getCombinaison() { return combinaison; }
public StatutPari getStatutPari() { return statutPari; }
public long getGainCalcule() { return gainCalcule; }
public String getDevise() { return devise; }
public String getDateReglement() { return dateReglement; }
public String getDatePaiement() { return datePaiement; }
public String getNotes() { return notes; }
}

View File

@@ -0,0 +1,92 @@
package com.example.quiz.data.model;
public class PointDeVente {
private Long id;
private String code;
private String nom;
private String adresse;
private String ville;
private String latitude;
private String longitude;
private PointStatus statut;
public PointDeVente(Long id, String code, String nom, String adresse, String ville, String latitude, String longitude, PointStatus statut) {
this.id = id;
this.code = code;
this.nom = nom;
this.adresse = adresse;
this.ville = ville;
this.latitude = latitude;
this.longitude = longitude;
this.statut = statut;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getAdresse() {
return adresse;
}
public void setAdresse(String adresse) {
this.adresse = adresse;
}
public String getVille() {
return ville;
}
public void setVille(String ville) {
this.ville = ville;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public PointStatus getStatut() {
return statut;
}
public void setStatut(PointStatus statut) {
this.statut = statut;
}
public enum PointStatus {
ACTIF,
INACTIF
}
}

View File

@@ -0,0 +1,114 @@
package com.example.quiz.data.model;
public class Tpe {
private String numeroSerie;
private long pointDeVenteId;
private String statut;
private String versionLogicielle;
private String typeTerminal;
private String plateforme;
private String modeleAppareil;
private String systemeExploitation;
private String versionOs;
private String adresseIp;
private String adresseMac;
private String journalSession;
public Tpe() {}
public String getNumeroSerie() {
return numeroSerie;
}
public void setNumeroSerie(String numeroSerie) {
this.numeroSerie = numeroSerie;
}
public long getPointDeVenteId() {
return pointDeVenteId;
}
public void setPointDeVenteId(long pointDeVenteId) {
this.pointDeVenteId = pointDeVenteId;
}
public String getStatut() {
return statut;
}
public void setStatut(String statut) {
this.statut = statut;
}
public String getVersionLogicielle() {
return versionLogicielle;
}
public void setVersionLogicielle(String versionLogicielle) {
this.versionLogicielle = versionLogicielle;
}
public String getTypeTerminal() {
return typeTerminal;
}
public void setTypeTerminal(String typeTerminal) {
this.typeTerminal = typeTerminal;
}
public String getPlateforme() {
return plateforme;
}
public void setPlateforme(String plateforme) {
this.plateforme = plateforme;
}
public String getModeleAppareil() {
return modeleAppareil;
}
public void setModeleAppareil(String modeleAppareil) {
this.modeleAppareil = modeleAppareil;
}
public String getSystemeExploitation() {
return systemeExploitation;
}
public void setSystemeExploitation(String systemeExploitation) {
this.systemeExploitation = systemeExploitation;
}
public String getVersionOs() {
return versionOs;
}
public void setVersionOs(String versionOs) {
this.versionOs = versionOs;
}
public String getAdresseIp() {
return adresseIp;
}
public void setAdresseIp(String adresseIp) {
this.adresseIp = adresseIp;
}
public String getAdresseMac() {
return adresseMac;
}
public void setAdresseMac(String adresseMac) {
this.adresseMac = adresseMac;
}
public String getJournalSession() {
return journalSession;
}
public void setJournalSession(String journalSession) {
this.journalSession = journalSession;
}
}

View File

@@ -0,0 +1,51 @@
package com.example.quiz.data.model;
public class TpeResponse extends Tpe {
private long id;
private String derniereConnexion;
private String derniereConnexionAgent;
private String derniereDeconnexionAgent;
private boolean assigned;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getDerniereConnexion() {
return derniereConnexion;
}
public void setDerniereConnexion(String derniereConnexion) {
this.derniereConnexion = derniereConnexion;
}
public String getDerniereConnexionAgent() {
return derniereConnexionAgent;
}
public void setDerniereConnexionAgent(String derniereConnexionAgent) {
this.derniereConnexionAgent = derniereConnexionAgent;
}
public String getDerniereDeconnexionAgent() {
return derniereDeconnexionAgent;
}
public void setDerniereDeconnexionAgent(String derniereDeconnexionAgent) {
this.derniereDeconnexionAgent = derniereDeconnexionAgent;
}
public boolean isAssigned() {
return assigned;
}
public void setAssigned(boolean assigned) {
this.assigned = assigned;
}
}

View File

@@ -3,10 +3,10 @@ package com.example.quiz.data.model;
public class TypeOfBet {
private String label;
private String name;
private Course.TypeParis name;
private int numberOfHorse;
public TypeOfBet(String label, String name, int numberOfHorse) {
public TypeOfBet(String label, Course.TypeParis name, int numberOfHorse) {
this.label = label;
this.name = name;
this.numberOfHorse = numberOfHorse;
@@ -20,11 +20,11 @@ public class TypeOfBet {
this.label = label;
}
public String getName() {
public Course.TypeParis getName() {
return name;
}
public void setName(String name) {
public void setName(Course.TypeParis name) {
this.name = name;
}

View File

@@ -0,0 +1,68 @@
package com.example.quiz.data.model.dtos.auth;
public class Agent {
private Long id;
private String code;
private String nom;
private String prenom;
private String phone;
private String zone;
private String fonction;
public Agent(){}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getZone() {
return zone;
}
public void setZone(String zone) {
this.zone = zone;
}
public String getFonction() {
return fonction;
}
public void setFonction(String fonction) {
this.fonction = fonction;
}
}

View File

@@ -1,10 +1,31 @@
package com.example.quiz.data.model.dtos.auth;
public class LoginPayload {
private String pin;
public LoginPayload(String pin) {
private String code;
private String pin;
private Long terminalId;
public LoginPayload(String code, String pin, Long terminalId) {
this.code = code;
this.pin = pin;
this.terminalId = terminalId;
}
public Long getTerminalId() {
return terminalId;
}
public void setTerminalId(Long terminalId) {
this.terminalId = terminalId;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getPin() {

View File

@@ -1,237 +1,27 @@
package com.example.quiz.data.model.dtos.auth;
public class LoginResponse {
private int id;
private String code;
private String profile;
private String principalCode;
private String caisseProfile;
private String statut;
private String zone;
private String kiosk;
private String fonction;
private String dateEmbauche;
private String derniereConnexion;
private String nom;
private String prenom;
private String autresNom;
private String dateNaissance;
private String lieuNaissance;
private String ville;
private String adresse;
private String cni;
private double limiteInferieure;
private double limiteSuperieure;
private double limiteParTransaction;
private String autreAdresse1;
private String token;
private Agent agent;
public LoginResponse(int id, String code, String profile, String principalCode, String caisseProfile, String statut, String zone, String kiosk, String fonction, String dateEmbauche, String derniereConnexion, String nom, String prenom, String autresNom, String dateNaissance, String lieuNaissance, String ville, String adresse, String cni, double limiteInferieure, double limiteSuperieure, double limiteParTransaction, String autreAdresse1) {
this.id = id;
this.code = code;
this.profile = profile;
this.principalCode = principalCode;
this.caisseProfile = caisseProfile;
this.statut = statut;
this.zone = zone;
this.kiosk = kiosk;
this.fonction = fonction;
this.dateEmbauche = dateEmbauche;
this.derniereConnexion = derniereConnexion;
this.nom = nom;
this.prenom = prenom;
this.autresNom = autresNom;
this.dateNaissance = dateNaissance;
this.lieuNaissance = lieuNaissance;
this.ville = ville;
this.adresse = adresse;
this.cni = cni;
this.limiteInferieure = limiteInferieure;
this.limiteSuperieure = limiteSuperieure;
this.limiteParTransaction = limiteParTransaction;
this.autreAdresse1 = autreAdresse1;
public LoginResponse(String token, Agent agent) {
this.token = token;
this.agent = agent;
}
public int getId() {
return id;
public Agent getUser() {
return agent;
}
public void setId(int id) {
this.id = id;
public void setUser(Agent agent) {
this.agent = agent;
}
public String getCode() {
return code;
public String getToken() {
return token;
}
public void setCode(String code) {
this.code = code;
}
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
public String getPrincipalCode() {
return principalCode;
}
public void setPrincipalCode(String principalCode) {
this.principalCode = principalCode;
}
public String getCaisseProfile() {
return caisseProfile;
}
public void setCaisseProfile(String caisseProfile) {
this.caisseProfile = caisseProfile;
}
public String getStatut() {
return statut;
}
public void setStatut(String statut) {
this.statut = statut;
}
public String getZone() {
return zone;
}
public void setZone(String zone) {
this.zone = zone;
}
public String getKiosk() {
return kiosk;
}
public void setKiosk(String kiosk) {
this.kiosk = kiosk;
}
public String getFonction() {
return fonction;
}
public void setFonction(String fonction) {
this.fonction = fonction;
}
public String getDateEmbauche() {
return dateEmbauche;
}
public void setDateEmbauche(String dateEmbauche) {
this.dateEmbauche = dateEmbauche;
}
public String getDerniereConnexion() {
return derniereConnexion;
}
public void setDerniereConnexion(String derniereConnexion) {
this.derniereConnexion = derniereConnexion;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getAutresNom() {
return autresNom;
}
public void setAutresNom(String autresNom) {
this.autresNom = autresNom;
}
public String getDateNaissance() {
return dateNaissance;
}
public void setDateNaissance(String dateNaissance) {
this.dateNaissance = dateNaissance;
}
public String getLieuNaissance() {
return lieuNaissance;
}
public void setLieuNaissance(String lieuNaissance) {
this.lieuNaissance = lieuNaissance;
}
public String getVille() {
return ville;
}
public void setVille(String ville) {
this.ville = ville;
}
public String getAdresse() {
return adresse;
}
public void setAdresse(String adresse) {
this.adresse = adresse;
}
public String getCni() {
return cni;
}
public void setCni(String cni) {
this.cni = cni;
}
public double getLimiteInferieure() {
return limiteInferieure;
}
public void setLimiteInferieure(double limiteInferieure) {
this.limiteInferieure = limiteInferieure;
}
public double getLimiteSuperieure() {
return limiteSuperieure;
}
public void setLimiteSuperieure(double limiteSuperieure) {
this.limiteSuperieure = limiteSuperieure;
}
public double getLimiteParTransaction() {
return limiteParTransaction;
}
public void setLimiteParTransaction(double limiteParTransaction) {
this.limiteParTransaction = limiteParTransaction;
}
public String getAutreAdresse1() {
return autreAdresse1;
}
public void setAutreAdresse1(String autreAdresse1) {
this.autreAdresse1 = autreAdresse1;
public void setToken(String token) {
this.token = token;
}
}

View File

@@ -0,0 +1,237 @@
package com.example.quiz.data.model.dtos.auth;
public class User {
private int id;
private String code;
private String profile;
private String principalCode;
private String caisseProfile;
private String statut;
private String zone;
private String kiosk;
private String fonction;
private String dateEmbauche;
private String derniereConnexion;
private String nom;
private String prenom;
private String autresNom;
private String dateNaissance;
private String lieuNaissance;
private String ville;
private String adresse;
private String cni;
private double limiteInferieure;
private double limiteSuperieure;
private double limiteParTransaction;
private String autreAdresse1;
public User(int id, String code, String profile, String principalCode, String caisseProfile, String statut, String zone, String kiosk, String fonction, String dateEmbauche, String derniereConnexion, String nom, String prenom, String autresNom, String dateNaissance, String lieuNaissance, String ville, String adresse, String cni, double limiteInferieure, double limiteSuperieure, double limiteParTransaction, String autreAdresse1){
this.id = id;
this.code = code;
this.profile = profile;
this.principalCode = principalCode;
this.caisseProfile = caisseProfile;
this.statut = statut;
this.zone = zone;
this.kiosk = kiosk;
this.fonction = fonction;
this.dateEmbauche = dateEmbauche;
this.derniereConnexion = derniereConnexion;
this.nom = nom;
this.prenom = prenom;
this.autresNom = autresNom;
this.dateNaissance = dateNaissance;
this.lieuNaissance = lieuNaissance;
this.ville = ville;
this.adresse = adresse;
this.cni = cni;
this.limiteInferieure = limiteInferieure;
this.limiteSuperieure = limiteSuperieure;
this.limiteParTransaction = limiteParTransaction;
this.autreAdresse1 = autreAdresse1;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getProfile() {
return profile;
}
public void setProfile(String profile) {
this.profile = profile;
}
public String getPrincipalCode() {
return principalCode;
}
public void setPrincipalCode(String principalCode) {
this.principalCode = principalCode;
}
public String getCaisseProfile() {
return caisseProfile;
}
public void setCaisseProfile(String caisseProfile) {
this.caisseProfile = caisseProfile;
}
public String getStatut() {
return statut;
}
public void setStatut(String statut) {
this.statut = statut;
}
public String getZone() {
return zone;
}
public void setZone(String zone) {
this.zone = zone;
}
public String getKiosk() {
return kiosk;
}
public void setKiosk(String kiosk) {
this.kiosk = kiosk;
}
public String getFonction() {
return fonction;
}
public void setFonction(String fonction) {
this.fonction = fonction;
}
public String getDateEmbauche() {
return dateEmbauche;
}
public void setDateEmbauche(String dateEmbauche) {
this.dateEmbauche = dateEmbauche;
}
public String getDerniereConnexion() {
return derniereConnexion;
}
public void setDerniereConnexion(String derniereConnexion) {
this.derniereConnexion = derniereConnexion;
}
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getPrenom() {
return prenom;
}
public void setPrenom(String prenom) {
this.prenom = prenom;
}
public String getAutresNom() {
return autresNom;
}
public void setAutresNom(String autresNom) {
this.autresNom = autresNom;
}
public String getDateNaissance() {
return dateNaissance;
}
public void setDateNaissance(String dateNaissance) {
this.dateNaissance = dateNaissance;
}
public String getLieuNaissance() {
return lieuNaissance;
}
public void setLieuNaissance(String lieuNaissance) {
this.lieuNaissance = lieuNaissance;
}
public String getVille() {
return ville;
}
public void setVille(String ville) {
this.ville = ville;
}
public String getAdresse() {
return adresse;
}
public void setAdresse(String adresse) {
this.adresse = adresse;
}
public String getCni() {
return cni;
}
public void setCni(String cni) {
this.cni = cni;
}
public double getLimiteInferieure() {
return limiteInferieure;
}
public void setLimiteInferieure(double limiteInferieure) {
this.limiteInferieure = limiteInferieure;
}
public double getLimiteSuperieure() {
return limiteSuperieure;
}
public void setLimiteSuperieure(double limiteSuperieure) {
this.limiteSuperieure = limiteSuperieure;
}
public double getLimiteParTransaction() {
return limiteParTransaction;
}
public void setLimiteParTransaction(double limiteParTransaction) {
this.limiteParTransaction = limiteParTransaction;
}
public String getAutreAdresse1() {
return autreAdresse1;
}
public void setAutreAdresse1(String autreAdresse1) {
this.autreAdresse1 = autreAdresse1;
}
}

View File

@@ -0,0 +1,38 @@
package com.example.quiz.data.model.enums;
import java.io.Serializable;
public class Pageable implements Serializable {
private boolean unpaged;
private boolean paged;
private int pageNumber;
private int pageSize;
private long offset; // ⚠️ long obligatoire
private Sort sort;
public boolean isUnpaged() {
return unpaged;
}
public boolean isPaged() {
return paged;
}
public int getPageNumber() {
return pageNumber;
}
public int getPageSize() {
return pageSize;
}
public long getOffset() {
return offset;
}
public Sort getSort() {
return sort;
}
}

View File

@@ -0,0 +1,23 @@
package com.example.quiz.data.model.enums;
import java.io.Serializable;
public class Sort implements Serializable {
private boolean unsorted;
private boolean sorted;
private boolean empty;
public boolean isUnsorted() {
return unsorted;
}
public boolean isSorted() {
return sorted;
}
public boolean isEmpty() {
return empty;
}
}

View File

@@ -20,7 +20,14 @@ import retrofit2.converter.gson.GsonConverterFactory;
@Module
@InstallIn(SingletonComponent.class)
public class ApiClient {
private static final String BASE_URL = "https://boxer-adapting-bluegill.ngrok-free.app/api/v1/";
private static final String BASE_URL = "https://boxer-adapting-bluegill.ngrok-free.app/api/";
@Provides
@Singleton
public AuthInterceptor provideInterceptor(TokenManager tokenManager){
return new AuthInterceptor(tokenManager);
}
@Provides
@Singleton
@@ -37,9 +44,10 @@ public class ApiClient {
@Provides
@Singleton
public OkHttpClient provideOkHttpClient(HttpLoggingInterceptor loggingInterceptor){
public OkHttpClient provideOkHttpClient(HttpLoggingInterceptor loggingInterceptor, AuthInterceptor authInterceptor){
return new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.addInterceptor(authInterceptor)
.connectTimeout(240, TimeUnit.SECONDS)
.readTimeout(240, TimeUnit.SECONDS)
.build();

View File

@@ -1,10 +1,15 @@
package com.example.quiz.data.remote;
import com.example.quiz.data.model.Course;
import com.example.quiz.data.model.PagedModel;
import com.example.quiz.data.model.Pari;
import com.example.quiz.data.model.ParisResponse;
import com.example.quiz.data.model.PointDeVente;
import com.example.quiz.data.model.Reunion;
import com.example.quiz.data.model.Tpe;
import com.example.quiz.data.model.dtos.auth.LoginPayload;
import com.example.quiz.data.model.dtos.auth.LoginResponse;
import com.example.quiz.data.model.TpeResponse;
import java.util.List;
@@ -17,28 +22,33 @@ import retrofit2.http.Path;
import retrofit2.http.Query;
public interface ApiService {
@GET("reunions")
Call<List<Reunion>> getReunions();
@GET("reunions/date/{date}")
Call<List<Reunion>> getReunions(@Path("date") String date);
@GET("courses/reunion/{reunionId}")
Call<List<Course>> getCourses(@Path("reunionId") String reunionId);
@GET("courses")
Call<PagedModel<Course>> getCourses(@Query("reunionDate") String reunionDate);
@POST("pari")
Call<Pari> createPari(@Body Pari pari);
@POST("paris")
Call<ParisResponse> createPari(@Body Pari pari);
@POST("auth/agent/login")
Call<LoginResponse> login(@Body LoginPayload loginPayload);
@GET("pari/created-by/{created-by}/today")
Call<List<Pari>> derniersParis(@Path("created-by") String createdBy);
@GET("paris/agent/{agentId}/today")
Call<List<ParisResponse>> derniersParis(@Path("agentId") String agentId);
@PUT("pari/annuler/{numeroTicket}")
Call<Pari> annulerPari(@Path("numeroTicket") String numeroTicket);
Call<ParisResponse> annulerPari(@Path("numeroTicket") String numeroTicket);
@GET("pari/solde/{createdBy}/course/{courseId}")
Call<Double> getSoldeByCourse(@Path("createdBy") String createdBy, @Path("courseId") String courseId);
@GET("paris/agent/{agentId}/solde/course/{courseId}")
Call<Double> getSoldeByCourse(@Path("agentId") String createdBy, @Path("courseId") String courseId);
@GET("pari/solde/{createdBy}")
Call<Double> getSoldeByDay(@Path("createdBy") String createdBy, @Query("date") String day);
@GET("paris/agent/{agentId}/solde")
Call<Double> getSoldeByDay(@Path("agentId") String agentId, @Query("date") String day);
@POST("terminaux")
Call<TpeResponse> createTpe(@Body Tpe tpe);
@GET("points-de-vente")
Call<PagedModel<PointDeVente>> getPointsDeVente(@Query("nom") String nom);
}

View File

@@ -0,0 +1,35 @@
package com.example.quiz.data.remote;
import androidx.annotation.NonNull;
import java.io.IOException;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class AuthInterceptor implements Interceptor {
private final TokenManager tokenManager;
public AuthInterceptor(TokenManager tokenManager) {
this.tokenManager = tokenManager;
}
@NonNull
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
String token = tokenManager.getToken();
if (token != null) {
Request newRequest = originalRequest.newBuilder()
.addHeader("Authorization", "Bearer " + token)
.build();
return chain.proceed(newRequest);
}
return chain.proceed(originalRequest);
}
}

View File

@@ -0,0 +1,85 @@
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;
}
}

View File

@@ -0,0 +1,33 @@
package com.example.quiz.data.remote;
import android.content.Context;
import android.content.SharedPreferences;
import javax.inject.Inject;
import dagger.hilt.android.qualifiers.ApplicationContext;
public class TokenManager {
private static final String PREF_NAME = "auth_pref";
private static final String KEY_TOKEN = "auth_token";
SocketManager socketManager;
private SharedPreferences sharedPreferences;
@Inject
public TokenManager(@ApplicationContext Context context, SocketManager socketManager) {
this.sharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);
this.socketManager = socketManager;
}
public void saveToken(String token){
sharedPreferences.edit().putString(KEY_TOKEN, token).apply();
socketManager.reconnect();
}
public String getToken(){
return sharedPreferences.getString(KEY_TOKEN, null);
}
public void clearToken(){
sharedPreferences.edit().remove(KEY_TOKEN).apply();
}
}

View File

@@ -6,6 +6,7 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.example.quiz.data.model.Course;
import com.example.quiz.data.model.PagedModel;
import com.example.quiz.data.remote.ApiService;
import com.example.quiz.utils.Result;
@@ -25,12 +26,12 @@ public class CourseRepository {
this.apiService = apiService;
}
public LiveData<Result<List<Course>>> getCourses(String reunionId) {
MutableLiveData<Result<List<Course>>> liveCourses = new MutableLiveData<Result<List<Course>>>();
public LiveData<Result<PagedModel<Course>>> getCourses(String reunionDate) {
MutableLiveData<Result<PagedModel<Course>>> liveCourses = new MutableLiveData<Result<PagedModel<Course>>>();
liveCourses.setValue(Result.loading());
apiService.getCourses(reunionId).enqueue(new Callback<List<Course>>() {
apiService.getCourses(reunionDate).enqueue(new Callback<PagedModel<Course>>() {
@Override
public void onResponse(Call<List<Course>> call, Response<List<Course>> response) {
public void onResponse(Call<PagedModel<Course>> call, Response<PagedModel<Course>> response) {
if(response.isSuccessful()){
liveCourses.postValue(Result.success(response.body()));
}else{
@@ -39,7 +40,7 @@ public class CourseRepository {
}
@Override
public void onFailure(Call<List<Course>> call, Throwable throwable) {
public void onFailure(Call<PagedModel<Course>> call, Throwable throwable) {
liveCourses.postValue(Result.error(throwable.getMessage()));
}
});

View File

@@ -1,11 +1,14 @@
package com.example.quiz.data.repository;
import android.util.Log;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.example.quiz.data.model.dtos.auth.LoginPayload;
import com.example.quiz.data.model.dtos.auth.LoginResponse;
import com.example.quiz.data.remote.ApiService;
import com.example.quiz.data.remote.TokenManager;
import com.example.quiz.utils.Result;
import javax.inject.Inject;
@@ -16,8 +19,10 @@ import retrofit2.Response;
public class LoginRepository {
private ApiService apiService;
private TokenManager tokenManager;
@Inject
public LoginRepository(ApiService apiService) {
public LoginRepository(ApiService apiService, TokenManager tokenManager) {
this.tokenManager = tokenManager;
this.apiService = apiService;
}
@@ -29,6 +34,8 @@ public class LoginRepository {
public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
if(response.isSuccessful()){
liveLogin.postValue(Result.success(response.body()));
Log.d("TOKEN", response.body().getToken());
tokenManager.saveToken(response.body().getToken());
}else{
liveLogin.postValue(Result.error(response.message()));
}

View File

@@ -7,10 +7,13 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.example.quiz.data.model.Pari;
import com.example.quiz.data.model.ParisResponse;
import com.example.quiz.data.remote.ApiService;
import com.example.quiz.utils.Result;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
@@ -26,23 +29,25 @@ public class PariRepository {
this.apiService = apiService;
}
public LiveData<Result<Pari>> createPari(Pari pari) {
MutableLiveData<Result<Pari>> pariResponse = new MutableLiveData<>();
public LiveData<Result<ParisResponse>> createPari(Pari pari) {
MutableLiveData<Result<ParisResponse>> pariResponse = new MutableLiveData<>();
pariResponse.setValue(Result.loading());
apiService.createPari(pari).enqueue(new Callback<Pari>() {
apiService.createPari(pari).enqueue(new Callback<ParisResponse>() {
@Override
public void onResponse(Call<Pari> call, Response<Pari> response) {
public void onResponse(Call<ParisResponse> call, Response<ParisResponse> response) {
if (response.isSuccessful() && response.body() != null) {
pariResponse.postValue(Result.success(response.body()));
} else {
// On récupère l'erreur exacte envoyée par le backend
try {
String errorBody = response.errorBody() != null ?
response.errorBody().string() : "Erreur inconnue";
pariResponse.postValue(Result.error(errorBody));
Map<String, String> errorBody = Collections.emptyMap();
if(response.errorBody() != null){
errorBody = (Map<String, String>) response.errorBody();
}
Log.d("PariRepository", response.errorBody().toString());
pariResponse.postValue(Result.error(errorBody.get("message")));
} catch (Exception e) {
pariResponse.postValue(Result.error("Erreur serveur"));
@@ -51,7 +56,7 @@ public class PariRepository {
}
@Override
public void onFailure(Call<Pari> call, Throwable t) {
public void onFailure(Call<ParisResponse> call, Throwable t) {
pariResponse.postValue(Result.error(t.getMessage()));
}
});
@@ -59,12 +64,12 @@ public class PariRepository {
return pariResponse;
}
public LiveData<Result<List<Pari>>> derniersParis(String createdBy){
MutableLiveData<Result<List<Pari>>> derniersParis = new MutableLiveData<>();
public LiveData<Result<List<ParisResponse>>> derniersParis(String agentId){
MutableLiveData<Result<List<ParisResponse>>> derniersParis = new MutableLiveData<>();
derniersParis.setValue(Result.loading());
apiService.derniersParis(createdBy).enqueue(new Callback<List<Pari>>() {
apiService.derniersParis(agentId).enqueue(new Callback<List<ParisResponse>>() {
@Override
public void onResponse(Call<List<Pari>> call, Response<List<Pari>> response) {
public void onResponse(Call<List<ParisResponse>> call, Response<List<ParisResponse>> response) {
if(response.isSuccessful() && response.body() != null){
derniersParis.postValue(Result.success(response.body()));
}else{
@@ -80,7 +85,7 @@ public class PariRepository {
}
@Override
public void onFailure(Call<List<Pari>> call, Throwable throwable) {
public void onFailure(Call<List<ParisResponse>> call, Throwable throwable) {
derniersParis.postValue(Result.error(throwable.getMessage()));
}
});
@@ -88,12 +93,12 @@ public class PariRepository {
return derniersParis;
}
public LiveData<Result<Pari>> annulerPari(String numeroTicket){
MutableLiveData<Result<Pari>> pariResponse = new MutableLiveData<>();
public LiveData<Result<ParisResponse>> annulerPari(String numeroTicket){
MutableLiveData<Result<ParisResponse>> pariResponse = new MutableLiveData<>();
pariResponse.setValue(Result.loading());
apiService.annulerPari(numeroTicket).enqueue(new Callback<Pari>(){
apiService.annulerPari(numeroTicket).enqueue(new Callback<ParisResponse>(){
@Override
public void onResponse(Call<Pari> call, Response<Pari> response) {
public void onResponse(Call<ParisResponse> call, Response<ParisResponse> response) {
if(response.isSuccessful()){
pariResponse.postValue(Result.success(response.body()));
}else{
@@ -109,17 +114,17 @@ public class PariRepository {
}
@Override
public void onFailure(Call<Pari> call, Throwable throwable) {
public void onFailure(Call<ParisResponse> call, Throwable throwable) {
pariResponse.postValue(Result.error(throwable.getMessage()));
}
});
return pariResponse;
}
public LiveData<Result<Double>> getSoldeByCourse(String createdBy, String courseId){
public LiveData<Result<Double>> getSoldeByCourse(String agentId, String courseId){
MutableLiveData<Result<Double>> solde = new MutableLiveData<>();
solde.setValue(Result.loading());
apiService.getSoldeByCourse(createdBy, courseId).enqueue(new Callback<Double>() {
apiService.getSoldeByCourse(agentId, courseId).enqueue(new Callback<Double>() {
@Override
public void onResponse(Call<Double> call, Response<Double> response) {
if(response.isSuccessful()){
@@ -141,10 +146,10 @@ public class PariRepository {
return solde;
}
public LiveData<Result<Double>> getSoldeByDay(String createdBy, String day){
public LiveData<Result<Double>> getSoldeByDay(String agentId, String day){
MutableLiveData<Result<Double>> solde = new MutableLiveData<>();
solde.setValue(Result.loading());
apiService.getSoldeByDay(createdBy, day).enqueue(new Callback<Double>() {
apiService.getSoldeByDay(agentId, day).enqueue(new Callback<Double>() {
@Override
public void onResponse(Call<Double> call, Response<Double> response) {
if(response.isSuccessful()){

View File

@@ -0,0 +1,65 @@
package com.example.quiz.data.repository;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.example.quiz.data.model.PagedModel;
import com.example.quiz.data.model.PointDeVente;
import com.example.quiz.data.remote.ApiService;
import com.example.quiz.utils.Result;
import javax.inject.Inject;
import retrofit2.*;
public class PointDeVenteRepository {
private ApiService apiService;
@Inject
public PointDeVenteRepository(ApiService apiService) {
this.apiService = apiService;
}
public LiveData<Result<PagedModel<PointDeVente>>> getPointsDeVente(String nom) {
MutableLiveData<Result<PagedModel<PointDeVente>>> result = new MutableLiveData<>();
result.setValue(Result.loading());
apiService.getPointsDeVente(nom)
.clone()
.enqueue(new Callback<PagedModel<PointDeVente>>() {
@Override
public void onResponse(Call<PagedModel<PointDeVente>> call,
Response<PagedModel<PointDeVente>> response) {
if (response.isSuccessful() && response.body() != null) {
result.postValue(Result.success(response.body()));
} else {
String errorMessage = "Erreur inconnue";
try {
if (response.errorBody() != null) {
errorMessage = response.errorBody().string();
}
} catch (Exception e) {
errorMessage = e.getMessage();
}
result.postValue(Result.error(errorMessage));
}
}
@Override
public void onFailure(Call<PagedModel<PointDeVente>> call, Throwable t) {
result.postValue(Result.error(
t.getMessage() != null ? t.getMessage() : "Erreur réseau"
));
}
});
return result;
}
}

View File

@@ -4,10 +4,10 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.example.quiz.data.model.Reunion;
import com.example.quiz.data.remote.ApiClient;
import com.example.quiz.data.remote.ApiService;
import com.example.quiz.utils.Result;
import com.google.android.gms.common.api.Api;
import java.util.List;
@@ -25,10 +25,10 @@ public class ReunionRepository {
this.apiService = apiService;
}
public LiveData<Result<List<Reunion>>> getReunions(){
public LiveData<Result<List<Reunion>>> getReunions(String date){
MutableLiveData<Result<List<Reunion>>> liveReunionsData = new MutableLiveData<>();
liveReunionsData.setValue(Result.loading());
apiService.getReunions().enqueue(new Callback<List<Reunion>>() {
apiService.getReunions(date).enqueue(new Callback<List<Reunion>>() {
@Override
public void onResponse(Call<List<Reunion>> call, Response<List<Reunion>> response) {
if(response.isSuccessful()){

View File

@@ -0,0 +1,47 @@
package com.example.quiz.data.repository;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.example.quiz.data.model.Tpe;
import com.example.quiz.data.model.TpeResponse;
import com.example.quiz.data.remote.ApiService;
import com.example.quiz.utils.Result;
import javax.inject.Inject;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class TpeRepository {
private ApiService apiService;
@Inject
public TpeRepository(ApiService apiService) {
this.apiService = apiService;
}
public LiveData<Result<TpeResponse>> createTpe(Tpe tpe) {
MutableLiveData<Result<TpeResponse>> tpeLiveData = new MutableLiveData<>();
tpeLiveData.setValue(Result.loading());
apiService.createTpe(tpe).enqueue(new Callback<TpeResponse>() {
@Override
public void onResponse(Call<TpeResponse> call, Response<TpeResponse> response) {
if (response.isSuccessful()) {
tpeLiveData.postValue(Result.success(response.body()));
} else {
tpeLiveData.postValue(Result.error(response.message()));
}
}
@Override
public void onFailure(Call<TpeResponse> call, Throwable throwable) {
tpeLiveData.postValue(Result.error(throwable.getMessage()));
}
});
return tpeLiveData;
}
}

View File

@@ -0,0 +1,147 @@
package com.example.quiz.utils;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelStoreOwner;
import com.example.quiz.R;
import com.example.quiz.data.model.dtos.auth.LoginPayload;
import com.example.quiz.data.model.dtos.auth.LoginResponse;
import com.example.quiz.data.remote.TokenManager;
import com.example.quiz.viewModel.LoginViewModel;
import com.example.quiz.viewModel.LogsViewModel;
import javax.inject.Inject;
public class AuthNavigator {
private final Context context;
private FragmentManager fragmentManager;
private TokenManager tokenManager;
private final SessionManager sessionManager;
LoginViewModel viewModel;
LogsViewModel logsViewModel;
private Dialog dialog;
SharedPrefsHelper prefsHelper;
public AuthNavigator(Context context,
FragmentManager fragmentManager,
SessionManager sessionManager,
LoginViewModel viewModel,
LogsViewModel logsViewModel) {
this.viewModel = viewModel;
this.logsViewModel = logsViewModel;
this.prefsHelper = SharedPrefsHelper.getInstance(context);
this.fragmentManager = fragmentManager;
this.context = context;
dialog = new Dialog(context);
this.sessionManager = sessionManager;
}
public void navigate(Fragment destinationFragment) {
if(destinationFragment== null){
return;
}
if (sessionManager.isExpired()) {
showPinDialog(() -> {
sessionManager.updateLastExpiredDate();
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, destinationFragment)
.addToBackStack(null)
.commit();
});
} else {
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, destinationFragment)
.addToBackStack(null)
.commit();
}
}
public void showPinDialog(Runnable onSuccess) {
View view = LayoutInflater.from(context).inflate(R.layout.pin_view, null);
dialog.setContentView(view);
dialog.setCancelable(true);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
view.findViewById(R.id.cancel).setOnClickListener(v -> dialog.dismiss());
view.findViewById(R.id.pin_validate)
.setOnClickListener(v -> {
TextView code = view.findViewById(R.id.code);
TextView pin = view.findViewById(R.id.pin);
if(code.getText().toString().isEmpty()){
pin.setError("Entrez le code!");
return;
}
if(pin.getText().toString().isEmpty()){
pin.setError("Entrez le pin!");
return;
}
if(pin.getText().toString().length() < 4){
pin.setError("Le pin doit contenir minimum quatre chiffres!");
return;
}
LoginPayload loginPayload = new LoginPayload(
code.getText().toString(),
pin.getText().toString(),
Long.valueOf(prefsHelper.get("terminalId"))
);
viewModel.login(loginPayload).observe((LifecycleOwner) context, new Observer<Result<LoginResponse>>() {
@Override
public void onChanged(Result<LoginResponse> loginResponseResult) {
switch (loginResponseResult.status){
case LOADING:
view.findViewById(R.id.pin_validate).setEnabled(false);
view.findViewById(R.id.pin_validate).setAlpha(0.5f);
break;
case ERROR:
MessageDialog.showError(context, loginResponseResult.message);
view.findViewById(R.id.pin_validate).setEnabled(true);
view.findViewById(R.id.pin_validate).setAlpha(1f);
break;
case SUCCESS:
loginSuccess(loginResponseResult.data);
logsViewModel.insertLog(prefsHelper.get("id"), "LOGIN","Authentification sur l'appareil", System.currentTimeMillis());
sessionManager.updateLastExpiredDate();
dialog.dismiss();
view.findViewById(R.id.pin_validate).setEnabled(true);
view.findViewById(R.id.pin_validate).setAlpha(1f);
onSuccess.run();
break;
}
}
});
});
dialog.show();
}
public boolean dialogIsShowing(){
return dialog.isShowing();
}
private void loginSuccess(LoginResponse loginResponse){
prefsHelper.save("id", String.valueOf(loginResponse.getUser().getId()));
prefsHelper.save("firstName", loginResponse.getUser().getPrenom());
prefsHelper.save("lastName", loginResponse.getUser().getNom());
prefsHelper.save("profile", loginResponse.getUser().getFonction());
prefsHelper.save("code", loginResponse.getUser().getCode());
}
}

View File

@@ -0,0 +1,36 @@
package com.example.quiz.utils;
import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import com.example.quiz.R;
public class LoaderDialog {
private Dialog dialog;
private TextView loaderText;
public LoaderDialog(Context context) {
dialog = new Dialog(context);
View view = LayoutInflater.from(context).inflate(R.layout.dowload_loader, null);
loaderText = view.findViewById(R.id.loaderText);
dialog.setContentView(view);
dialog.setCancelable(false); // Empêche fermeture en cliquant dehors
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
}
public void show(String message) {
loaderText.setText(message);
dialog.show();
}
public void dismiss() {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}

View File

@@ -0,0 +1,53 @@
package com.example.quiz.utils;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.lifecycle.Observer;
import com.example.quiz.R;
import com.example.quiz.data.model.dtos.auth.LoginResponse;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
public class MessageDialog {
public static void showSuccess(Context context, String message) {
Dialog dialog = new Dialog(context);
View view = LayoutInflater.from(context).inflate(R.layout.dialog_success, null);
TextView txtMessage = view.findViewById(R.id.txtMessage);
Button btnOk = view.findViewById(R.id.btnOk);
txtMessage.setText(message);
btnOk.setOnClickListener(v -> dialog.dismiss());
dialog.setContentView(view);
dialog.setCancelable(true);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
dialog.show();
}
public static void showError(Context context, String message) {
Dialog dialog = new Dialog(context);
View view = LayoutInflater.from(context).inflate(R.layout.dialog_error, null);
TextView txtMessage = view.findViewById(R.id.txtMessage);
Button btnOk = view.findViewById(R.id.btnOk);
txtMessage.setText(message);
btnOk.setOnClickListener(v -> dialog.dismiss());
dialog.setContentView(view);
dialog.setCancelable(true);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
dialog.show();
}
}

View File

@@ -1,5 +1,8 @@
package com.example.quiz.utils;
import android.content.Context;
import android.os.Bundle;
import java.time.Duration;
import java.time.LocalDateTime;
@@ -7,9 +10,22 @@ public class SessionManager {
// 10 minutes en millisecondes
private static final long sessionExpiredTime = 10 * 60 * 1000;
private static SessionManager instance;
private LocalDateTime lastExpiredDate;
public SessionManager() {}
public SessionManager(Context context) {
if(lastExpiredDate != null){
updateLastExpiredDate();
}
}
public static SessionManager newInstance(Context context) {
if(instance == null){
instance = new SessionManager(context.getApplicationContext());
}
return instance;
}
public void updateLastExpiredDate() {
lastExpiredDate = LocalDateTime.now();

View File

@@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;
import com.example.quiz.data.model.Course;
import com.example.quiz.data.model.PagedModel;
import com.example.quiz.data.repository.CourseRepository;
import com.example.quiz.utils.Result;
@@ -17,17 +18,15 @@ import dagger.hilt.android.lifecycle.HiltViewModel;
public class CourseViewModel extends ViewModel {
private final CourseRepository courseRepository;
private LiveData<Result<List<Course>>> courses;
private LiveData<Result<PagedModel<Course>>> courses;
@Inject
public CourseViewModel(CourseRepository courseRepository){
this.courseRepository = courseRepository;
}
public LiveData<Result<List<Course>>> getCourses(String reunionId){
if(courses == null){
courses = courseRepository.getCourses(reunionId);
}
public LiveData<Result<PagedModel<Course>>> getCourses(String reunionDate){
courses = courseRepository.getCourses(reunionDate);
return courses;
}
}

View File

@@ -0,0 +1,41 @@
package com.example.quiz.viewModel;
import android.util.Log;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
import com.example.quiz.data.ActivityLogger;
import com.example.quiz.data.dao.UserActivityLogDao;
import com.example.quiz.data.database.DatabaseClient;
import com.example.quiz.data.entity.Logs;
import java.util.List;
import java.util.concurrent.Executors;
import javax.inject.Inject;
import dagger.hilt.android.lifecycle.HiltViewModel;
@HiltViewModel
public class LogsViewModel extends ViewModel {
private MutableLiveData<List<Logs>> todayLogs = new MutableLiveData<List<Logs>>(null);
private UserActivityLogDao dao;
@Inject
public LogsViewModel(UserActivityLogDao dao) {
this.dao = dao;
ActivityLogger.init(dao);
}
public LiveData<List<Logs>> getTodayLogs() {
return dao.getTodayLogs();
}
public void insertLog(String userId, String action, String description, Long timestamp){
ActivityLogger.log(userId, action, description, timestamp);
}
}

View File

@@ -4,6 +4,7 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;
import com.example.quiz.data.model.Pari;
import com.example.quiz.data.model.ParisResponse;
import com.example.quiz.data.repository.PariRepository;
import com.example.quiz.utils.Result;
@@ -16,11 +17,11 @@ import dagger.hilt.android.lifecycle.HiltViewModel;
@HiltViewModel
public class PariViewModel extends ViewModel {
private final PariRepository pariRepository;
private LiveData<Result<Pari>> pari;
private LiveData<Result<ParisResponse>> pari;
private LiveData<Result<List<Pari>>> derniersParis;
private LiveData<Result<List<ParisResponse>>> derniersParis;
private LiveData<Result<Pari>> pariAnnule;
private LiveData<Result<ParisResponse>> pariAnnule;
private LiveData<Result<Double>> solde;
@@ -31,38 +32,28 @@ public class PariViewModel extends ViewModel {
this.pariRepository = repository;
}
public LiveData<Result<Pari>> createPari(Pari pari){
if(this.pari == null){
this.pari = pariRepository.createPari(pari);
}
public LiveData<Result<ParisResponse>> createPari(Pari pari){
this.pari = pariRepository.createPari(pari);
return this.pari;
}
public LiveData<Result<List<Pari>>> getDerniersParis(String createdBy){
if(derniersParis == null){
derniersParis = pariRepository.derniersParis(createdBy);
}
return pariRepository.derniersParis(createdBy);
public LiveData<Result<List<ParisResponse>>> getDerniersParis(String agentId){
derniersParis = pariRepository.derniersParis(agentId);
return pariRepository.derniersParis(agentId);
}
public LiveData<Result<Pari>> annulerPari(String numeroTicket){
if(pariAnnule == null){
pariAnnule = pariRepository.annulerPari(numeroTicket);
}
public LiveData<Result<ParisResponse>> annulerPari(String numeroTicket){
pariAnnule = pariRepository.annulerPari(numeroTicket);
return pariAnnule;
}
public LiveData<Result<Double>> getSoldeByCourse(String createdBy, String courseId){
if(solde == null){
solde = pariRepository.getSoldeByCourse(createdBy, courseId);
}
public LiveData<Result<Double>> getSoldeByCourse(String agentId, String courseId){
solde = pariRepository.getSoldeByCourse(agentId, courseId);
return solde;
}
public LiveData<Result<Double>> getSoldeByDay(String createdBy, String day){
if(soldeByDay == null){
soldeByDay = pariRepository.getSoldeByDay(createdBy, day);
}
public LiveData<Result<Double>> getSoldeByDay(String agentId, String day){
soldeByDay = pariRepository.getSoldeByDay(agentId, day);
return soldeByDay;
}
}

View File

@@ -0,0 +1,29 @@
package com.example.quiz.viewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;
import com.example.quiz.data.model.PagedModel;
import com.example.quiz.data.model.PointDeVente;
import com.example.quiz.data.repository.PointDeVenteRepository;
import com.example.quiz.utils.Result;
import javax.inject.Inject;
import dagger.hilt.android.lifecycle.HiltViewModel;
@HiltViewModel
public class PointDeVenteViewModel extends ViewModel {
private final PointDeVenteRepository pointDeVenteRepository;
private LiveData<Result<PagedModel<PointDeVente>>> pointsDeVente;
@Inject
public PointDeVenteViewModel(PointDeVenteRepository pointDeVenteRepository){
this.pointDeVenteRepository = pointDeVenteRepository;
}
public LiveData<Result<PagedModel<PointDeVente>>> setPointsDeVente(String search){
this.pointsDeVente = pointDeVenteRepository.getPointsDeVente(search);
return this.pointsDeVente;
}
}

View File

@@ -24,9 +24,9 @@ public class ReunionViewModel extends ViewModel {
this.reunionRepository = reunionRepository;
}
public LiveData<Result<List<Reunion>>> getReunions() {
public LiveData<Result<List<Reunion>>> getReunions(String date) {
if (reunions == null) {
reunions = reunionRepository.getReunions();
reunions = reunionRepository.getReunions(date);
}
return reunions;
}

View File

@@ -0,0 +1,30 @@
package com.example.quiz.viewModel;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.ViewModel;
import com.example.quiz.data.model.Tpe;
import com.example.quiz.data.model.TpeResponse;
import com.example.quiz.data.repository.TpeRepository;
import com.example.quiz.utils.Result;
import javax.inject.Inject;
import dagger.hilt.android.lifecycle.HiltViewModel;
@HiltViewModel
public class TpeViewModel extends ViewModel {
private TpeRepository tpeRepository;
private LiveData<Result<TpeResponse>> tpeLiveData;
@Inject
public TpeViewModel(TpeRepository repository){
this.tpeRepository = repository;
}
public LiveData<Result<TpeResponse>> createTpe(Tpe tpe){
tpeLiveData = tpeRepository.createTpe(tpe);
return tpeLiveData;
}
}