Version avec integration slave master
This commit is contained in:
331
app/src/main/java/com/example/quiz/AgentDetails.java
Normal file
331
app/src/main/java/com/example/quiz/AgentDetails.java
Normal file
@@ -0,0 +1,331 @@
|
||||
package com.example.quiz;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.example.quiz.data.adapter.MultiTypeOfBetsAdapter;
|
||||
import com.example.quiz.data.model.Course;
|
||||
import com.example.quiz.data.model.Restriction;
|
||||
import com.example.quiz.data.model.TypeOfBet;
|
||||
import com.example.quiz.data.model.dtos.auth.User;
|
||||
import com.example.quiz.databinding.FragmentAgentDetailsBinding;
|
||||
import com.example.quiz.utils.LoaderDialog;
|
||||
import com.example.quiz.utils.MessageDialog;
|
||||
import com.example.quiz.utils.Result;
|
||||
import com.example.quiz.utils.SharedPrefsHelper;
|
||||
import com.example.quiz.viewModel.AgentViewModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
* Use the {@link AgentDetails#newInstance} factory method to
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
public class AgentDetails extends Fragment {
|
||||
|
||||
// TODO: Rename parameter arguments, choose names that match
|
||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||
private String agentId;
|
||||
private FragmentAgentDetailsBinding binding;
|
||||
MultiTypeOfBetsAdapter multiTypeOfBetsAdapter;
|
||||
private AgentViewModel agentViewModel;
|
||||
|
||||
private boolean userInteraction = false;
|
||||
|
||||
private User agent;
|
||||
|
||||
private Restriction allowedBetTypes;
|
||||
|
||||
private SharedPrefsHelper prefsHelper;
|
||||
|
||||
private LoaderDialog loaderDialog;
|
||||
|
||||
public AgentDetails() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
private static final String AGENT_ID = "agentId";
|
||||
|
||||
// TODO: Rename and change types and number of parameters
|
||||
public static AgentDetails newInstance(User agent) {
|
||||
AgentDetails fragment = new AgentDetails();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(AGENT_ID, String.valueOf(agent.getId()));
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
if (getArguments() != null) {
|
||||
agentId = getArguments().getString(AGENT_ID);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
binding = FragmentAgentDetailsBinding.inflate(inflater, container, false);
|
||||
agentViewModel = new ViewModelProvider(this).get(AgentViewModel.class);
|
||||
allowedBetTypes = new Restriction();
|
||||
prefsHelper = SharedPrefsHelper.getInstance(getContext());
|
||||
loaderDialog = new LoaderDialog(getContext());
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
loadAgentDetails(agentId);
|
||||
binding.switchAccess.setOnCheckedChangeListener((compoundButton, b) -> {
|
||||
if(!userInteraction){
|
||||
return;
|
||||
}
|
||||
String message = b ? "Voulez-vous activer l'accès à l'agent ?" : "Voulez-vous désactiver l'accès à l'agent ?";
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setTitle("Activation de l'accès")
|
||||
.setMessage(message)
|
||||
.setPositiveButton("Oui", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
if(prefsHelper.get("id")== null){
|
||||
MessageDialog.showError(getContext(), "Veuillez vous connecter");
|
||||
return;
|
||||
}
|
||||
String masterId = prefsHelper.get("id");
|
||||
agentViewModel.setAccess(masterId, agentId, !b).observe(getViewLifecycleOwner(), new Observer<Result<Void>>() {
|
||||
@Override
|
||||
public void onChanged(Result<Void> voidResult) {
|
||||
switch (voidResult.status){
|
||||
case LOADING:{
|
||||
loaderDialog.show("Chargement des agents");
|
||||
break;
|
||||
}
|
||||
case ERROR:{
|
||||
loaderDialog.dismiss();
|
||||
MessageDialog.showError(getContext(), voidResult.message);
|
||||
break;
|
||||
}
|
||||
case SUCCESS:{
|
||||
loaderDialog.dismiss();
|
||||
MessageDialog.showSuccess(getContext(), "L'accès a été mis à jour");
|
||||
loadAgentDetails(agentId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}).setNegativeButton("Non", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
dialogInterface.dismiss();
|
||||
}
|
||||
}).show();
|
||||
});
|
||||
binding.btnValidate.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
if(prefsHelper.get("id")== null){
|
||||
MessageDialog.showError(getContext(), "Veuillez vous connecter");
|
||||
return;
|
||||
}
|
||||
if(allowedBetTypes.getAllowedBetTypes() == null || allowedBetTypes.getAllowedBetTypes().isEmpty()){
|
||||
MessageDialog.showError(getContext(), "Veuillez sélectionner au moins un type de paris");
|
||||
return;
|
||||
}
|
||||
if(agent == null){
|
||||
MessageDialog.showError(getContext(), "Veuillez charger les détails de l'agent");
|
||||
return;
|
||||
}
|
||||
String masterId = prefsHelper.get("id");
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setTitle("Valider la sélection")
|
||||
.setMessage("Êtes-vous sûr de vouloir valider la sélection ?")
|
||||
.setPositiveButton("Oui", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
agentViewModel.setRestrictions(masterId, agentId, allowedBetTypes).observe(getViewLifecycleOwner(), new Observer<Result<Void>>() {
|
||||
@Override
|
||||
public void onChanged(Result<Void> voidResult) {
|
||||
switch (voidResult.status){
|
||||
case LOADING:{
|
||||
loaderDialog.show("Chargement des agents");
|
||||
break;
|
||||
}
|
||||
case ERROR:{
|
||||
loaderDialog.dismiss();
|
||||
MessageDialog.showError(getContext(), voidResult.message);
|
||||
break;
|
||||
}
|
||||
case SUCCESS:{
|
||||
loaderDialog.dismiss();
|
||||
MessageDialog.showSuccess(getContext(), "Les types de paris ont été mises à jour");
|
||||
loadAgentDetails(agentId);
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
.setNegativeButton("Non", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
dialogInterface.dismiss();
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadAgentDetails(String slaveId){
|
||||
agentViewModel.getAgentById(slaveId).observe(getViewLifecycleOwner(), new Observer<Result<User>>() {
|
||||
@Override
|
||||
public void onChanged(Result<User> userResult) {
|
||||
switch (userResult.status){
|
||||
case LOADING:{
|
||||
loaderDialog.show("Chargement des agents");
|
||||
break;
|
||||
}
|
||||
case ERROR:{
|
||||
loaderDialog.dismiss();
|
||||
MessageDialog.showError(getContext(), userResult.message);
|
||||
break;
|
||||
}
|
||||
case SUCCESS:{
|
||||
loaderDialog.dismiss();
|
||||
agent = userResult.data;
|
||||
binding.txtCode.setText(agent.getCode());
|
||||
String adresse;
|
||||
if(agent.getVille() != null && agent.getAdresse() != null){
|
||||
adresse = agent.getVille()+"; "+agent.getAdresse();
|
||||
}else{
|
||||
adresse = "Pas d'adresse";
|
||||
}
|
||||
binding.txtAdresse.setText(adresse);
|
||||
userInteraction = false;
|
||||
binding.switchAccess.setChecked(agent.getStatut().equals("ACTIF"));
|
||||
userInteraction = true;
|
||||
loadAvailableBets(String.valueOf(agent.getId()));
|
||||
break;
|
||||
}
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadAvailableBets(String id){
|
||||
agentViewModel.getAvailableBets(id).observe(getViewLifecycleOwner(), new Observer<Result<List<Course.TypeParis>>>() {
|
||||
@Override
|
||||
public void onChanged(Result<List<Course.TypeParis>> listResult) {
|
||||
switch (listResult.status){
|
||||
case LOADING:{
|
||||
loaderDialog.show("Chargement des paris disponibles");
|
||||
break;
|
||||
}
|
||||
case ERROR:{
|
||||
loaderDialog.dismiss();
|
||||
MessageDialog.showError(getContext(), listResult.message);
|
||||
}
|
||||
case SUCCESS:{
|
||||
loaderDialog.dismiss();
|
||||
List<TypeOfBet> types = createTypeOfBetList();
|
||||
multiTypeOfBetsAdapter = new MultiTypeOfBetsAdapter(types);
|
||||
multiTypeOfBetsAdapter.preSelectAvailableBets(listResult.data);
|
||||
binding.betsRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
binding.betsRecyclerView.setAdapter(multiTypeOfBetsAdapter);
|
||||
List<Course.TypeParis> selectedTypes = multiTypeOfBetsAdapter.getSelectedItems().stream().map(TypeOfBet::getName).collect(Collectors.toList());
|
||||
allowedBetTypes.setAllowedBetTypes(selectedTypes);
|
||||
multiTypeOfBetsAdapter.setOnItemClickListener(new MultiTypeOfBetsAdapter.onItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(TypeOfBet type, boolean isChecked) {
|
||||
List<Course.TypeParis> selectedTypes = multiTypeOfBetsAdapter.getSelectedItems().stream().map(TypeOfBet::getName).collect(Collectors.toList());
|
||||
allowedBetTypes.setAllowedBetTypes(selectedTypes);
|
||||
}
|
||||
@Override
|
||||
public void onItemsSelected(List<TypeOfBet> selectedItems) {
|
||||
}
|
||||
});
|
||||
}
|
||||
default:{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private List<TypeOfBet> createTypeOfBetList() {
|
||||
List<TypeOfBet> types = new ArrayList<>();
|
||||
|
||||
// 1. COUPLE GAGNANT
|
||||
TypeOfBet coupleGagnant = new TypeOfBet(
|
||||
"Couple Gagnant", // label
|
||||
Course.TypeParis.COUPLE_GAGNANT, // name
|
||||
2 // numberOfHorse (2 chevaux)
|
||||
);
|
||||
types.add(coupleGagnant);
|
||||
|
||||
// 2. COUPLE PLACE
|
||||
TypeOfBet couplePlace = new TypeOfBet(
|
||||
"Couple Place", // label
|
||||
Course.TypeParis.COUPLE_PLACE, // name
|
||||
2 // numberOfHorse (2 chevaux)
|
||||
);
|
||||
types.add(couplePlace);
|
||||
|
||||
// 3. TIERCE
|
||||
TypeOfBet tierce = new TypeOfBet(
|
||||
"Tiercé", // label
|
||||
Course.TypeParis.TIERCE, // name
|
||||
3 // numberOfHorse (3 chevaux)
|
||||
);
|
||||
types.add(tierce);
|
||||
|
||||
// 4. QUARTE
|
||||
TypeOfBet quarte = new TypeOfBet(
|
||||
"Quarté", // label
|
||||
Course.TypeParis.QUARTE, // name
|
||||
4 // numberOfHorse (4 chevaux)
|
||||
);
|
||||
types.add(quarte);
|
||||
|
||||
// 5. QUINTE (optionnel)
|
||||
TypeOfBet quinte = new TypeOfBet(
|
||||
"Quinté", // label
|
||||
Course.TypeParis.QUINTE, // name
|
||||
5 // numberOfHorse (5 chevaux)
|
||||
);
|
||||
types.add(quinte);
|
||||
|
||||
return types;
|
||||
}
|
||||
}
|
||||
135
app/src/main/java/com/example/quiz/AgentManagement.java
Normal file
135
app/src/main/java/com/example/quiz/AgentManagement.java
Normal file
@@ -0,0 +1,135 @@
|
||||
package com.example.quiz;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.example.quiz.data.adapter.AgentItemAdapter;
|
||||
import com.example.quiz.data.model.dtos.auth.User;
|
||||
import com.example.quiz.databinding.FragmentAgentManagementBinding;
|
||||
import com.example.quiz.utils.AuthNavigator;
|
||||
import com.example.quiz.utils.LoaderDialog;
|
||||
import com.example.quiz.utils.MessageDialog;
|
||||
import com.example.quiz.utils.Result;
|
||||
import com.example.quiz.utils.SessionManager;
|
||||
import com.example.quiz.utils.SharedPrefsHelper;
|
||||
import com.example.quiz.viewModel.AgentViewModel;
|
||||
import com.example.quiz.viewModel.LoginViewModel;
|
||||
import com.example.quiz.viewModel.LogsViewModel;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
* Use the {@link AgentManagement#newInstance} factory method to
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
public class AgentManagement extends Fragment {
|
||||
|
||||
// TODO: Rename parameter arguments, choose names that match
|
||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||
|
||||
private FragmentAgentManagementBinding binding;
|
||||
private LoaderDialog loaderDialog;
|
||||
|
||||
private AgentViewModel agentViewModel;
|
||||
SharedPrefsHelper prefsHelper;
|
||||
|
||||
AgentItemAdapter agentItemAdapter;
|
||||
|
||||
AuthNavigator authNavigator;
|
||||
|
||||
public AgentManagement() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
// TODO: Rename and change types and number of parameters
|
||||
public static AgentManagement newInstance() {
|
||||
AgentManagement fragment = new AgentManagement();
|
||||
Bundle args = new Bundle();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), SessionManager.newInstance(getContext()),new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
// Inflate the layout for this fragment
|
||||
binding = FragmentAgentManagementBinding.inflate(inflater, container, false);
|
||||
agentViewModel = new ViewModelProvider(this).get(AgentViewModel.class);
|
||||
loaderDialog = new LoaderDialog(getContext());
|
||||
prefsHelper = SharedPrefsHelper.getInstance(getContext());
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
|
||||
AppCompatActivity activity = (AppCompatActivity) getActivity();
|
||||
if(activity != null){
|
||||
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
|
||||
activity.setSupportActionBar(toolbar);
|
||||
|
||||
if (activity.getSupportActionBar() != null) {
|
||||
activity.getSupportActionBar().show();
|
||||
activity.getSupportActionBar().setTitle("Gestion aides");
|
||||
}
|
||||
toolbar.setBackgroundColor(getResources().getColor(R.color.primary_green, null));
|
||||
toolbar.setTitleTextColor(getResources().getColor(R.color.white, null));
|
||||
}
|
||||
|
||||
String agentId = prefsHelper.get("id");
|
||||
if(agentId == null){
|
||||
return;
|
||||
}
|
||||
agentViewModel.getAgents(agentId).observe(getViewLifecycleOwner(), new Observer<Result<List<User>>>() {
|
||||
@Override
|
||||
public void onChanged(Result<List<User>> listResult) {
|
||||
switch (listResult.status){
|
||||
case LOADING:{
|
||||
loaderDialog.show("Chargement des agents");
|
||||
break;
|
||||
}
|
||||
case ERROR:{
|
||||
loaderDialog.dismiss();
|
||||
MessageDialog.showError(getContext(), listResult.message);
|
||||
}
|
||||
case SUCCESS:{
|
||||
loaderDialog.dismiss();
|
||||
agentItemAdapter = new AgentItemAdapter(listResult.data);
|
||||
binding.agentList.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
binding.agentList.setAdapter(agentItemAdapter);
|
||||
agentItemAdapter.setOnItemClickListener(new AgentItemAdapter.onItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(User agent) {
|
||||
AgentDetails agentDetails = AgentDetails.newInstance(agent);
|
||||
authNavigator.navigate(agentDetails);
|
||||
}});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -37,13 +37,16 @@ import android.widget.Toast;
|
||||
|
||||
import com.anggastudio.printama.Printama;
|
||||
import com.example.quiz.data.model.Course;
|
||||
import com.example.quiz.data.model.MiseInitiale;
|
||||
import com.example.quiz.data.model.Pari;
|
||||
import com.example.quiz.data.model.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.NotifPayload;
|
||||
import com.example.quiz.data.model.dtos.PariCourseDto;
|
||||
import com.example.quiz.data.model.enums.PariStatut;
|
||||
import com.example.quiz.data.remote.StompManager;
|
||||
import com.example.quiz.databinding.FragmentBetValidationBinding;
|
||||
import com.example.quiz.utils.BluetoothUtils;
|
||||
import com.example.quiz.utils.LoaderDialog;
|
||||
@@ -51,14 +54,18 @@ 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.PariMiseViewModel;
|
||||
import com.example.quiz.viewModel.PariViewModel;
|
||||
import com.example.quiz.viewModel.SharedViewModel;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.MultiFormatWriter;
|
||||
import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.OffsetDateTime;
|
||||
@@ -69,6 +76,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
/**
|
||||
@@ -84,8 +94,15 @@ public class BetValidation extends Fragment {
|
||||
|
||||
SharedViewModel shared;
|
||||
|
||||
PariMiseViewModel pariMiseViewModel;
|
||||
|
||||
List<MiseInitiale> misesInitiales;
|
||||
|
||||
private AlertDialog dialog;
|
||||
|
||||
@Inject
|
||||
StompManager stompManager;
|
||||
|
||||
private int nombreX;
|
||||
|
||||
LogsViewModel logsViewModel;
|
||||
@@ -253,6 +270,40 @@ public class BetValidation extends Fragment {
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
|
||||
pariMiseViewModel = new ViewModelProvider(this).get(PariMiseViewModel.class);
|
||||
pariMiseViewModel.getBetInitMise().observe(
|
||||
getViewLifecycleOwner(),
|
||||
result->{
|
||||
switch (result.status){
|
||||
case LOADING: {
|
||||
loader.show("Chargement des mise");
|
||||
break;
|
||||
}
|
||||
case SUCCESS: {
|
||||
misesInitiales = result.data;
|
||||
loader.dismiss();
|
||||
break;
|
||||
}
|
||||
case ERROR: {
|
||||
loader.dismiss();
|
||||
MessageDialog.showError(getContext(), result.message);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
);
|
||||
if(shared.selectedCourse.getValue() != null){
|
||||
stompManager.subscribe("courses/"+shared.selectedCourse.getValue().getId(), json->{
|
||||
Type type = new TypeToken<NotifPayload<Course>>(){}.getType();
|
||||
NotifPayload<Course> notif = new Gson().fromJson(json, type);
|
||||
Course updatedCourse = notif.getPayload();
|
||||
if(shared.selectedCourse.getValue().getId() == updatedCourse.getId()){
|
||||
shared.setSelectedCourse(updatedCourse);
|
||||
setupNumberGrid(binding.gridNumbers);
|
||||
}
|
||||
});
|
||||
}
|
||||
setSelectedTypeOfBetImage();
|
||||
pariViewModel = new ViewModelProvider(this).get(PariViewModel.class);
|
||||
typeOfBet = shared.typeOfBet.getValue();
|
||||
@@ -266,7 +317,6 @@ public class BetValidation extends Fragment {
|
||||
activity.getSupportActionBar().setTitle("Pari "+shared.selectedCourse.getValue().getNom());
|
||||
}
|
||||
}
|
||||
|
||||
setupNumberGrid(binding.gridNumbers);
|
||||
binding.paymentType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
@@ -323,8 +373,32 @@ public class BetValidation extends Fragment {
|
||||
});
|
||||
|
||||
binding.betValidateBtn.setOnClickListener(v->{
|
||||
if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
||||
// TODO: Consider calling
|
||||
// ActivityCompat#requestPermissions
|
||||
// here to request the missing permissions, and then overriding
|
||||
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
|
||||
// int[] grantResults)
|
||||
// to handle the case where the user grants the permission. See the documentation
|
||||
// for ActivityCompat#requestPermissions for more details.
|
||||
return;
|
||||
}
|
||||
int paperStatus = Printama.with(getContext()).checkPaperStatus();
|
||||
Log.d("PAPER_STATUS", String.valueOf(paperStatus));
|
||||
switch (paperStatus){
|
||||
case 2 :{
|
||||
MessageDialog.showError(getContext(), "Le papier d'impression est vide");
|
||||
return;
|
||||
}
|
||||
case 1:{
|
||||
MessageDialog.showError(getContext(), "Le papier d'impression est presque vide");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if(binding.paymentType.getSelectedItem().toString().equals("Orange Money") && binding.phoneNumber.getText().toString().isEmpty()){
|
||||
Toast.makeText(getContext(), "Veuillez entrer un numéro de téléphone", Toast.LENGTH_SHORT).show();
|
||||
MessageDialog.showError(getContext(), "Veuillez saisir le numéro de téléphone");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -444,7 +518,6 @@ public class BetValidation extends Fragment {
|
||||
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();
|
||||
@@ -564,19 +637,44 @@ public class BetValidation extends Fragment {
|
||||
}
|
||||
int typeOfBetHorses = shared.typeOfBet.getValue().getNumberOfHorse();
|
||||
int partants = shared.selectedCourse.getValue().getNombrePartants();
|
||||
Course.TypeParis courseName = shared.typeOfBet.getValue().getName();
|
||||
if(shared.typeOfBet.getValue().getNumberOfHorse() > nombreChevauxSelectionnes){
|
||||
binding.mise.setText(mise+" CFA");
|
||||
return;
|
||||
}
|
||||
if(typeOfBetHorses == 2){
|
||||
mise = 500;
|
||||
}else{
|
||||
if(typeOfBetHorses == 5){
|
||||
mise = 300;
|
||||
}else{
|
||||
mise = 200;
|
||||
MiseInitiale miseModel = misesInitiales.stream()
|
||||
.filter(miseInitiale-> miseInitiale.getTypePari().equals(courseName))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
if(miseModel == null){
|
||||
MessageDialog.showError(getContext(), "Erreur lors de l'initialisation de la mise");
|
||||
_initializeToZero();
|
||||
return;
|
||||
}
|
||||
mise = miseModel.getMiseInitialeMin();
|
||||
|
||||
Course.TypeParis typePari = shared.typeOfBet.getValue().getName();
|
||||
boolean estCoupleGagnantOuPlace = typePari.equals(Course.TypeParis.COUPLE_GAGNANT) || typePari.equals(Course.TypeParis.COUPLE_PLACE);
|
||||
Log.d("TYPE_PARI", typePari.toString());
|
||||
|
||||
if (estCoupleGagnantOuPlace) {
|
||||
// Pour COUPLE_GAGNANT ou COUPLE_PLACE: coefficient < 200
|
||||
if (coeff > 200) {
|
||||
// Erreur: coefficient trop élevé
|
||||
MessageDialog.showError(getContext(),"Le coefficient doit être au plus 200 pour "+typePari.toString());
|
||||
_initializeToZero();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// Pour les autres types: coefficient <= 20
|
||||
if (coeff > 20) {
|
||||
// Erreur: coefficient trop élevé
|
||||
MessageDialog.showError(getContext(), "Le coefficient doit être inférieur ou égal à 20 pour "+typePari.toString());
|
||||
_initializeToZero();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mise = mise * coeff;
|
||||
if(nombreX>0){
|
||||
if(nombreChevauxSelectionnes == typeOfBetHorses){
|
||||
@@ -651,4 +749,10 @@ public class BetValidation extends Fragment {
|
||||
super.onDestroyView();
|
||||
binding = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
stompManager.disconnect();
|
||||
}
|
||||
}
|
||||
@@ -18,11 +18,17 @@ import com.example.quiz.viewModel.LoginViewModel;
|
||||
import com.example.quiz.viewModel.LogsViewModel;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
* Use the {@link Caisse#newInstance} factory method to
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
public class Caisse extends Fragment {
|
||||
|
||||
FragmentCaisseBinding binding;
|
||||
@@ -47,14 +53,13 @@ public class Caisse extends Fragment {
|
||||
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
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
binding = FragmentCaisseBinding.inflate(inflater, container, false);
|
||||
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), sessionManager,new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ 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.data.remote.StompManager;
|
||||
import com.example.quiz.databinding.FragmentListOFBettingBinding;
|
||||
import com.example.quiz.utils.AuthNavigator;
|
||||
import com.example.quiz.utils.BluetoothUtils;
|
||||
@@ -46,6 +47,8 @@ import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
/**
|
||||
@@ -56,15 +59,15 @@ import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
@AndroidEntryPoint
|
||||
public class ListOFBets extends Fragment {
|
||||
|
||||
FragmentListOFBettingBinding binding;
|
||||
|
||||
LoaderDialog loader;
|
||||
|
||||
private SharedViewModel shared;
|
||||
|
||||
private CourseViewModel viewModel;
|
||||
|
||||
@Inject
|
||||
StompManager stompManager;
|
||||
|
||||
AuthNavigator authNavigator;
|
||||
|
||||
private BetsAdapter adapter;
|
||||
@@ -85,31 +88,8 @@ public class ListOFBets extends Fragment {
|
||||
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,
|
||||
@@ -121,7 +101,7 @@ public class ListOFBets extends Fragment {
|
||||
binding.recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
|
||||
binding.recyclerView.setAdapter(adapter);
|
||||
viewModel = new ViewModelProvider(this).get(CourseViewModel.class);
|
||||
|
||||
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), SessionManager.newInstance(getContext()),new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
|
||||
|
||||
|
||||
/*viewModel.bets.observe(getViewLifecycleOwner(), bets -> {
|
||||
@@ -173,8 +153,12 @@ public class ListOFBets extends Fragment {
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
MenuHost menuHost = requireActivity();
|
||||
|
||||
stompManager.subscribe("courses", json->{
|
||||
requireActivity().runOnUiThread(this::observe);
|
||||
});
|
||||
|
||||
MenuHost menuHost = requireActivity();
|
||||
// 🔹 On enlève d'abord les anciens menu providers si ce fragment est recréé
|
||||
menuHost.invalidateMenu();
|
||||
|
||||
@@ -222,4 +206,10 @@ public class ListOFBets extends Fragment {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
stompManager.disconnect();
|
||||
}
|
||||
}
|
||||
@@ -7,9 +7,11 @@ import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
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;
|
||||
@@ -18,18 +20,33 @@ import android.widget.Toast;
|
||||
|
||||
import com.example.quiz.data.adapter.TypeOfBetAdapter;
|
||||
import com.example.quiz.data.model.Course;
|
||||
import com.example.quiz.data.model.PariMise;
|
||||
import com.example.quiz.data.model.TypeOfBet;
|
||||
import com.example.quiz.data.model.dtos.NotifPayload;
|
||||
import com.example.quiz.data.remote.StompManager;
|
||||
import com.example.quiz.databinding.FragmentListOfTypeOfBetsBinding;
|
||||
import com.example.quiz.utils.AuthNavigator;
|
||||
import com.example.quiz.utils.LoaderDialog;
|
||||
import com.example.quiz.utils.MessageDialog;
|
||||
import com.example.quiz.utils.Result;
|
||||
import com.example.quiz.utils.SessionManager;
|
||||
import com.example.quiz.utils.SharedPrefsHelper;
|
||||
import com.example.quiz.viewModel.AgentViewModel;
|
||||
import com.example.quiz.viewModel.LoginViewModel;
|
||||
import com.example.quiz.viewModel.LogsViewModel;
|
||||
import com.example.quiz.viewModel.PariMiseViewModel;
|
||||
import com.example.quiz.viewModel.SharedViewModel;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
@@ -44,13 +61,25 @@ public class ListOfTypeOfBets extends Fragment {
|
||||
|
||||
private FragmentListOfTypeOfBetsBinding binding;
|
||||
|
||||
|
||||
SessionManager sessionManager;
|
||||
AuthNavigator authNavigator;
|
||||
|
||||
@Inject
|
||||
StompManager stompManager;
|
||||
|
||||
private SharedViewModel shared;
|
||||
|
||||
|
||||
private TypeOfBetAdapter adapter;
|
||||
|
||||
private SharedPrefsHelper prefsHelper;
|
||||
|
||||
private AgentViewModel agentViewModel;
|
||||
|
||||
private LoaderDialog loaderDialog;
|
||||
|
||||
|
||||
public ListOfTypeOfBets() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
@@ -65,28 +94,74 @@ public class ListOfTypeOfBets extends Fragment {
|
||||
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
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
binding = FragmentListOfTypeOfBetsBinding.inflate(inflater, container, false);
|
||||
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), SessionManager.newInstance(getContext()),new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
|
||||
prefsHelper = SharedPrefsHelper.getInstance(getContext());
|
||||
loaderDialog = new LoaderDialog(getContext());
|
||||
agentViewModel = new ViewModelProvider(this).get(AgentViewModel.class);
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
if(prefsHelper.get("id") == null){
|
||||
MessageDialog.showError(getContext(), "Veuillez vous connecter");
|
||||
return;
|
||||
}
|
||||
agentViewModel.getAvailableBets(prefsHelper.get("id")).observe(getViewLifecycleOwner(), new Observer<Result<List<Course.TypeParis>>>() {
|
||||
@Override
|
||||
public void onChanged(Result<List<Course.TypeParis>> listResult) {
|
||||
switch (listResult.status){
|
||||
case LOADING:{
|
||||
loaderDialog.show("Chargement des types de paris");
|
||||
break;
|
||||
}
|
||||
case ERROR:{
|
||||
loaderDialog.dismiss();
|
||||
MessageDialog.showError(getContext(), listResult.message);
|
||||
break;
|
||||
}
|
||||
case SUCCESS:{
|
||||
loaderDialog.dismiss();
|
||||
syncAuthorizedBets(listResult.data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void syncAuthorizedBets(List<Course.TypeParis> authorizedBets){
|
||||
binding.typeOfBetRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
|
||||
// ViewModels
|
||||
//viewModel = new ViewModelProvider(this).get(BetViewModel.class);
|
||||
shared = new ViewModelProvider(requireActivity()).get(SharedViewModel.class);
|
||||
// Observers
|
||||
if(shared.selectedCourse.getValue() == null){
|
||||
return;
|
||||
}
|
||||
Course sCourse = shared.selectedCourse.getValue();
|
||||
if(sCourse != null){
|
||||
stompManager.subscribe("courses/"+sCourse.getId(), json->{
|
||||
requireActivity().runOnUiThread(()->{
|
||||
Type type = new TypeToken<NotifPayload<Course>>(){}.getType();
|
||||
NotifPayload<Course> notif = new Gson().fromJson(json, type);
|
||||
Course updatedCourse = notif.getPayload();
|
||||
if(sCourse.getId() == updatedCourse.getId()){
|
||||
shared.setSelectedCourse(updatedCourse);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ⚡ Initialiser l’adapter UNE SEULE FOIS
|
||||
adapter = new TypeOfBetAdapter(new ArrayList<>());
|
||||
binding.typeOfBetRecyclerView.setAdapter(adapter);
|
||||
List<Course.TypeParis> betType = shared.selectedCourse.getValue().getTypesParisOuverts();
|
||||
List<Course.TypeParis> betType = sCourse.getTypesParisOuverts();
|
||||
List<TypeOfBet> useList = new ArrayList<>();
|
||||
if(betType.contains(Course.TypeParis.QUINTE)){
|
||||
useList.add(new TypeOfBet("Quinte", Course.TypeParis.QUINTE, 5));
|
||||
@@ -97,14 +172,15 @@ public class ListOfTypeOfBets extends Fragment {
|
||||
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);
|
||||
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<>();
|
||||
List<TypeOfBet> availableTypeOfBets = useList.stream().filter(type -> authorizedBets.contains(type.getName())).collect(Collectors.toList());
|
||||
adapter.setTypes(availableTypeOfBets);
|
||||
adapter.setOnItemClickListener(type -> {
|
||||
typeOfBet.set(type);
|
||||
});
|
||||
@@ -133,4 +209,10 @@ public class ListOfTypeOfBets extends Fragment {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
stompManager.disconnect();
|
||||
}
|
||||
}
|
||||
@@ -19,11 +19,14 @@ import com.example.quiz.utils.SharedPrefsHelper;
|
||||
import com.example.quiz.viewModel.LoginViewModel;
|
||||
import com.example.quiz.viewModel.LogsViewModel;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
* Use the {@link Login#newInstance} factory method to
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
public class Login extends Fragment {
|
||||
|
||||
|
||||
@@ -52,6 +55,7 @@ public class Login extends Fragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
binding = FragmentLoginBinding.inflate(inflater, container, false);
|
||||
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), SessionManager.newInstance(getContext()),new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@@ -60,7 +64,6 @@ public class Login extends Fragment {
|
||||
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();
|
||||
|
||||
@@ -2,12 +2,14 @@ package com.example.quiz;
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
|
||||
import com.anggastudio.printama.Pref;
|
||||
import com.anggastudio.printama.Printama;
|
||||
import com.example.quiz.utils.AuthNavigator;
|
||||
import com.example.quiz.utils.BluetoothUtils;
|
||||
import com.example.quiz.utils.MessageDialog;
|
||||
import com.example.quiz.utils.SessionManager;
|
||||
import com.example.quiz.utils.SharedPrefsHelper;
|
||||
import com.example.quiz.viewModel.LoginViewModel;
|
||||
import com.example.quiz.viewModel.LogsViewModel;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
@@ -20,6 +22,8 @@ import androidx.navigation.ui.NavigationUI;
|
||||
|
||||
import com.example.quiz.databinding.ActivityPageQuizBinding;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -46,7 +50,7 @@ public class PageQuiz extends AppCompatActivity {
|
||||
setContentView(binding.getRoot());
|
||||
logsViewModel = new ViewModelProvider(this).get(LogsViewModel.class);
|
||||
viewModel = new ViewModelProvider(this).get(LoginViewModel.class);
|
||||
authNavigator = new AuthNavigator(this, getSupportFragmentManager(), sessionManager, viewModel, logsViewModel);
|
||||
authNavigator = new AuthNavigator(this, getSupportFragmentManager(), sessionManager, viewModel, logsViewModel, this);
|
||||
setSupportActionBar(binding.toolbar);
|
||||
binding.toolbar.setBackgroundColor(Color.parseColor("#501C5A29"));
|
||||
}
|
||||
@@ -117,12 +121,32 @@ public class PageQuiz extends AppCompatActivity {
|
||||
// }
|
||||
|
||||
|
||||
private void checkPermission(){
|
||||
Pref.init(this);
|
||||
if (BluetoothUtils.needsBluetoothPermissions()) {
|
||||
if (!BluetoothUtils.hasBluetoothPermission(this)) {
|
||||
// Demande la permission si non accordée
|
||||
BluetoothUtils.requestBluetoothPermission(this);
|
||||
return; // arrête ici, la popup va apparaître
|
||||
}
|
||||
}
|
||||
|
||||
// 2️⃣ Permission OK, on peut afficher la liste
|
||||
try {
|
||||
Printama printama = Printama.with(this);
|
||||
if(printama.getConnectedPrinter() == null){
|
||||
BluetoothUtils.showPrinterList(this, this);
|
||||
}
|
||||
} catch (SecurityException e) {
|
||||
MessageDialog.showError(this, "Permission refusée");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
checkPermission();
|
||||
super.onResume();
|
||||
|
||||
handler = new Handler(Looper.getMainLooper());
|
||||
|
||||
checkRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
@@ -6,19 +6,30 @@ 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.FragmentSettingsBinding;
|
||||
import com.example.quiz.utils.AuthNavigator;
|
||||
import com.example.quiz.utils.SessionManager;
|
||||
import com.example.quiz.utils.SharedPrefsHelper;
|
||||
import com.example.quiz.viewModel.LoginViewModel;
|
||||
import com.example.quiz.viewModel.LogsViewModel;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
* Use the {@link Settings#newInstance} factory method to
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
public class Settings extends Fragment {
|
||||
|
||||
// TODO: Rename parameter arguments, choose names that match
|
||||
@@ -28,6 +39,10 @@ public class Settings extends Fragment {
|
||||
|
||||
FragmentSettingsBinding binding;
|
||||
|
||||
AuthNavigator authNavigator;
|
||||
|
||||
SharedPrefsHelper prefsHelper;
|
||||
|
||||
public Settings() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
@@ -42,14 +57,16 @@ public class Settings extends Fragment {
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
prefsHelper = SharedPrefsHelper.getInstance(getContext());
|
||||
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
|
||||
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), SessionManager.newInstance(getContext()),new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class), this);
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@@ -57,6 +74,16 @@ public class Settings extends Fragment {
|
||||
public void onViewCreated(@NonNull View view, Bundle savedInstanceState){
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
AppCompatActivity activity = (AppCompatActivity) getActivity();
|
||||
if(prefsHelper.get("isSupAgent") == null){
|
||||
binding.agentManagement.setVisibility(View.GONE);
|
||||
}else{
|
||||
String isSubAgent = prefsHelper.get("isSupAgent");
|
||||
if(isSubAgent.equals("true")){
|
||||
binding.agentManagement.setVisibility(View.GONE);
|
||||
}else{
|
||||
binding.agentManagement.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
if(activity != null){
|
||||
MaterialToolbar toolbar = activity.findViewById(R.id.toolbar);
|
||||
activity.setSupportActionBar(toolbar);
|
||||
@@ -92,6 +119,21 @@ public class Settings extends Fragment {
|
||||
.commit();
|
||||
}
|
||||
});
|
||||
binding.changePin.setOnClickListener(new View.OnClickListener(){
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
UpdatePin updatePin = UpdatePin.newInstance();
|
||||
authNavigator.navigate(updatePin);
|
||||
}
|
||||
});
|
||||
|
||||
binding.agentManagement.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
AgentManagement agentManagement = AgentManagement.newInstance();
|
||||
authNavigator.navigate(agentManagement);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -2,11 +2,15 @@ package com.example.quiz;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.DatePickerDialog;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
@@ -19,6 +23,8 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.anggastudio.printama.Printama;
|
||||
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
|
||||
import com.example.quiz.databinding.FragmentSoldBinding;
|
||||
import com.example.quiz.utils.LoaderDialog;
|
||||
import com.example.quiz.utils.MessageDialog;
|
||||
@@ -28,6 +34,8 @@ import com.example.quiz.viewModel.LogsViewModel;
|
||||
import com.example.quiz.viewModel.PariViewModel;
|
||||
import com.google.android.material.appbar.MaterialToolbar;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Calendar;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
@@ -116,9 +124,9 @@ public class Sold extends Fragment {
|
||||
getContext(),
|
||||
(view, year, month, dayOfMonth) -> {
|
||||
String date = year + "-" + _reformatDateForDate(month + 1) + "-" + _reformatDateForDate(dayOfMonth);
|
||||
pariViewModel.getSoldeByDay(prefsHelper.get("id"), date).observe(getViewLifecycleOwner(), new Observer<Result<Double>>() {
|
||||
pariViewModel.getSoldeByDay(prefsHelper.get("id"), date).observe(getViewLifecycleOwner(), new Observer<Result<SoldeResponse>>() {
|
||||
@Override
|
||||
public void onChanged(Result<Double> doubleResult) {
|
||||
public void onChanged(Result<SoldeResponse> doubleResult) {
|
||||
switch (doubleResult.status){
|
||||
case LOADING:{
|
||||
dialog.show("Solde du jour");
|
||||
@@ -131,7 +139,8 @@ public class Sold extends Fragment {
|
||||
}
|
||||
case SUCCESS:{
|
||||
dialog.dismiss();
|
||||
_showSold(doubleResult.data);
|
||||
|
||||
_showSold(doubleResult.data, date);
|
||||
logsViewModel.insertLog(prefsHelper.get("id"), "SOLDE JOUR", "Solde du "+date, System.currentTimeMillis());
|
||||
break;
|
||||
}
|
||||
@@ -147,12 +156,44 @@ public class Sold extends Fragment {
|
||||
datePickerDialog.show();
|
||||
}
|
||||
|
||||
void _showSold(double solde){
|
||||
void _showSold(SoldeResponse soldeResponse, String date){
|
||||
int solde = soldeResponse.getMontantParis() - soldeResponse.getMontantAnnulations() - soldeResponse.getMontantPaiements();
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setTitle("Solde")
|
||||
.setMessage("Solde la course "+solde)
|
||||
.setPositiveButton("Ok", (dialog, which)->{
|
||||
.setNeutralButton("Ok", (dialog, which)->{
|
||||
dialog.dismiss();
|
||||
}).show();
|
||||
})
|
||||
.setPositiveButton("Imprimer", (dialog, which)->{
|
||||
if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
||||
// TODO: Consider calling
|
||||
// ActivityCompat#requestPermissions
|
||||
// here to request the missing permissions, and then overriding
|
||||
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
|
||||
// int[] grantResults)
|
||||
// to handle the case where the user grants the permission. See the documentation
|
||||
// for ActivityCompat#requestPermissions for more details.
|
||||
return;
|
||||
}
|
||||
Printama printama = Printama.with(getContext());
|
||||
Bitmap logo = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
|
||||
String title = "SOLDE AU "+date;
|
||||
StringBuilder text = new StringBuilder();
|
||||
text.append("VENTES HIPPIQUES: ").append(String.valueOf(soldeResponse.getMontantParis())).append(" XOF").append("\n");
|
||||
text.append("NBR. PAIEMENTS: ").append(soldeResponse.getNombrePaiements()).append("\n");
|
||||
text.append("PAIEMENTS: ").append(String.valueOf(soldeResponse.getMontantPaiements())).append(" XOF").append("\n");
|
||||
text.append("NBR. ANNULATIONS: ").append(soldeResponse.getNombreAnnulations()).append("\n");
|
||||
text.append("ANNULATIONS: ").append(String.valueOf(soldeResponse.getMontantAnnulations())).append(" XOF").append("\n");
|
||||
text.append(printama.lineSeparator()).append("\n");
|
||||
text.append("SOLDE: ").append(String.valueOf(solde)).append(" XOF").append("\n");
|
||||
text.append(printama.lineSeparator()).append("\n");
|
||||
text.append("AGENT : ").append(prefsHelper.get("code")).append("\n");
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
|
||||
String now = formatter.format(LocalDateTime.now());
|
||||
text.append("DATE : ").append(now).append("\n");
|
||||
printama.printSold(logo, title, text);
|
||||
})
|
||||
.show();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,14 @@
|
||||
package com.example.quiz;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
@@ -14,6 +18,8 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.anggastudio.printama.Printama;
|
||||
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
|
||||
import com.example.quiz.databinding.FragmentSoldByCourseBinding;
|
||||
import com.example.quiz.utils.LoaderDialog;
|
||||
import com.example.quiz.utils.MessageDialog;
|
||||
@@ -22,6 +28,9 @@ import com.example.quiz.utils.SharedPrefsHelper;
|
||||
import com.example.quiz.viewModel.LogsViewModel;
|
||||
import com.example.quiz.viewModel.PariViewModel;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
/**
|
||||
@@ -78,9 +87,9 @@ public class SoldByCourse extends Fragment {
|
||||
binding.etRaceNumber.setError("Veuillez entrer un numéro de course");
|
||||
return;
|
||||
}
|
||||
pariViewModel.getSoldeByCourse(prefsHelper.get("id"), binding.etRaceNumber.getText().toString()).observe(getViewLifecycleOwner(), new Observer<Result<Double>>() {
|
||||
pariViewModel.getSoldeByCourse(prefsHelper.get("id"), binding.etRaceNumber.getText().toString()).observe(getViewLifecycleOwner(), new Observer<Result<SoldeResponse>>() {
|
||||
@Override
|
||||
public void onChanged(Result<Double> doubleResult) {
|
||||
public void onChanged(Result<SoldeResponse> doubleResult) {
|
||||
switch (doubleResult.status){
|
||||
case LOADING:{
|
||||
loader.show("Chargement du solde");
|
||||
@@ -93,7 +102,7 @@ public class SoldByCourse extends Fragment {
|
||||
}
|
||||
case SUCCESS:{
|
||||
loader.dismiss();
|
||||
_showPariDialog(doubleResult.data);
|
||||
_showPariDialog(doubleResult.data, binding.etRaceNumber.getText().toString());
|
||||
logsViewModel.insertLog(prefsHelper.get("id"), "SOLDE COURSE", "Solde de la course "+binding.etRaceNumber.getText(), System.currentTimeMillis());
|
||||
break;
|
||||
}
|
||||
@@ -103,14 +112,44 @@ public class SoldByCourse extends Fragment {
|
||||
});
|
||||
}
|
||||
|
||||
void _showPariDialog(double solde){
|
||||
void _showPariDialog(SoldeResponse soldeResponse, String numero){
|
||||
int solde = soldeResponse.getMontantParis() - soldeResponse.getMontantAnnulations() - soldeResponse.getMontantPaiements();
|
||||
new AlertDialog.Builder(getContext())
|
||||
.setTitle("Solde")
|
||||
.setMessage("Solde la course "+solde)
|
||||
.setPositiveButton("Ok", (dialog, which) -> {
|
||||
.setNeutralButton("Ok", (dialog, which) -> {
|
||||
binding.etRaceNumber.setText("");
|
||||
dialog.dismiss();
|
||||
})
|
||||
.setPositiveButton("Imprimer", (dialog, which)->{
|
||||
if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
||||
// TODO: Consider calling
|
||||
// ActivityCompat#requestPermissions
|
||||
// here to request the missing permissions, and then overriding
|
||||
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
|
||||
// int[] grantResults)
|
||||
// to handle the case where the user grants the permission. See the documentation
|
||||
// for ActivityCompat#requestPermissions for more details.
|
||||
return;
|
||||
}
|
||||
Printama printama = Printama.with(getContext());
|
||||
Bitmap logo = BitmapFactory.decodeResource(getResources(), R.drawable.pmu_logo);
|
||||
String title = "SOLDE DE LA COURSE "+numero;
|
||||
StringBuilder text = new StringBuilder();
|
||||
text.append("VENTES HIPPIQUES: ").append(String.valueOf(soldeResponse.getMontantParis())).append(" XOF").append("\n");
|
||||
text.append("NBR. PAIEMENTS: ").append(soldeResponse.getNombrePaiements()).append("\n");
|
||||
text.append("PAIEMENTS: ").append(String.valueOf(soldeResponse.getMontantPaiements())).append(" XOF").append("\n");
|
||||
text.append("NBR. ANNULATIONS: ").append(soldeResponse.getNombreAnnulations()).append("\n");
|
||||
text.append("ANNULATIONS: ").append(String.valueOf(soldeResponse.getMontantAnnulations())).append(" XOF").append("\n");
|
||||
text.append(printama.lineSeparator()).append("\n");
|
||||
text.append("SOLDE: ").append(String.valueOf(solde)).append(" XOF").append("\n");
|
||||
text.append(printama.lineSeparator()).append("\n");
|
||||
text.append("AGENT : ").append(prefsHelper.get("code")).append("\n");
|
||||
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
|
||||
String now = formatter.format(LocalDateTime.now());
|
||||
text.append("DATE : ").append(now).append("\n");
|
||||
printama.printSold(logo, title, text);
|
||||
})
|
||||
.show();
|
||||
}
|
||||
}
|
||||
24
app/src/main/java/com/example/quiz/StompModule.java
Normal file
24
app/src/main/java/com/example/quiz/StompModule.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.example.quiz;
|
||||
|
||||
import com.example.quiz.data.remote.NotificationHelper;
|
||||
import com.example.quiz.data.remote.StompManager;
|
||||
import com.example.quiz.data.remote.TokenManager;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import dagger.hilt.InstallIn;
|
||||
import dagger.hilt.components.SingletonComponent;
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent.class)
|
||||
public class StompModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public StompManager provideStompManager(TokenManager tokenManager,
|
||||
NotificationHelper notificationHelper) {
|
||||
return new StompManager(tokenManager, notificationHelper);
|
||||
}
|
||||
}
|
||||
132
app/src/main/java/com/example/quiz/UpdatePin.java
Normal file
132
app/src/main/java/com/example/quiz/UpdatePin.java
Normal file
@@ -0,0 +1,132 @@
|
||||
package com.example.quiz;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.example.quiz.data.model.dtos.auth.User;
|
||||
import com.example.quiz.databinding.FragmentUpdatePinBinding;
|
||||
import com.example.quiz.utils.AuthNavigator;
|
||||
import com.example.quiz.utils.LoaderDialog;
|
||||
import com.example.quiz.utils.MessageDialog;
|
||||
import com.example.quiz.utils.Result;
|
||||
import com.example.quiz.utils.SessionManager;
|
||||
import com.example.quiz.viewModel.LoginViewModel;
|
||||
import com.example.quiz.viewModel.LogsViewModel;
|
||||
|
||||
import dagger.hilt.android.AndroidEntryPoint;
|
||||
|
||||
/**
|
||||
* A simple {@link Fragment} subclass.
|
||||
* Use the {@link UpdatePin#newInstance} factory method to
|
||||
* create an instance of this fragment.
|
||||
*/
|
||||
@AndroidEntryPoint
|
||||
public class UpdatePin extends Fragment {
|
||||
|
||||
// TODO: Rename parameter arguments, choose names that match
|
||||
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
|
||||
|
||||
// TODO: Rename and change types of parameters
|
||||
FragmentUpdatePinBinding binding;
|
||||
|
||||
String oldPin;
|
||||
String newPin;
|
||||
String confirmation;
|
||||
|
||||
AuthNavigator authNavigator;
|
||||
|
||||
LoginViewModel viewModel;
|
||||
|
||||
LoaderDialog loaderDialog;
|
||||
|
||||
public UpdatePin() {
|
||||
// Required empty public constructor
|
||||
}
|
||||
|
||||
// TODO: Rename and change types and number of parameters
|
||||
public static UpdatePin newInstance() {
|
||||
UpdatePin fragment = new UpdatePin();
|
||||
Bundle args = new Bundle();
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
viewModel = new ViewModelProvider(this).get(LoginViewModel.class);
|
||||
loaderDialog = new LoaderDialog(getContext());
|
||||
authNavigator = new AuthNavigator(getContext(), getParentFragmentManager(), new SessionManager(getContext()), new ViewModelProvider(this).get(LoginViewModel.class),new ViewModelProvider(this).get(LogsViewModel.class),this);
|
||||
// Inflate the layout for this fragment
|
||||
binding = FragmentUpdatePinBinding.inflate(inflater, container, false);
|
||||
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
binding.validate.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
oldPin = binding.oldPin.getText().toString();
|
||||
newPin = binding.newPin.getText().toString();
|
||||
confirmation = binding.pinConfirmation.getText().toString();
|
||||
if(oldPin.length()<4 || newPin.length()<4 || confirmation.length()<4){
|
||||
MessageDialog.showError(getContext(), "Le pin doit au mois avoir 4 Caractères!");
|
||||
return;
|
||||
}
|
||||
if(!newPin.equals(confirmation)){
|
||||
MessageDialog.showError(getContext(), "Les pins ne sont pas identiques!");
|
||||
return;
|
||||
}
|
||||
viewModel.changePin(oldPin, newPin).observe(getViewLifecycleOwner(), new Observer<Result<User>>(){
|
||||
|
||||
@Override
|
||||
public void onChanged(Result<User> userResult) {
|
||||
switch (userResult.status){
|
||||
case LOADING:{
|
||||
loaderDialog.show("Mis à jour du pin");
|
||||
break;
|
||||
}
|
||||
case ERROR:{
|
||||
loaderDialog.dismiss();
|
||||
MessageDialog.showError(getContext(), userResult.message);
|
||||
break;
|
||||
}
|
||||
case SUCCESS:{
|
||||
loaderDialog.dismiss();
|
||||
MessageDialog.showSuccess(getContext(), "Pin mis à jour avec succès");
|
||||
SessionManager sessionManager = new SessionManager(getContext());
|
||||
authNavigator.showPinDialog(()->{
|
||||
sessionManager.updateLastExpiredDate();
|
||||
getParentFragmentManager().popBackStack();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
binding.cancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getParentFragmentManager().popBackStack();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.example.quiz.data.adapter;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.quiz.R;
|
||||
import com.example.quiz.data.model.dtos.auth.User;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public class AgentItemAdapter extends RecyclerView.Adapter<AgentItemAdapter.AgentItemViewHolder> {
|
||||
private List<User> agents = new ArrayList<>();
|
||||
public AgentItemAdapter(){
|
||||
|
||||
}
|
||||
public AgentItemAdapter(List<User> agents) {
|
||||
this.agents = agents;
|
||||
}
|
||||
|
||||
public interface onItemClickListener{
|
||||
void onItemClick(User agent);
|
||||
}
|
||||
|
||||
private onItemClickListener listener;
|
||||
public void setOnItemClickListener(onItemClickListener listener){
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
|
||||
static class AgentItemViewHolder extends RecyclerView.ViewHolder{
|
||||
TextView txtCode, txtDate, txtAdresse;
|
||||
ImageButton details;
|
||||
public AgentItemViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
txtCode = itemView.findViewById(R.id.txtCode);
|
||||
txtDate = itemView.findViewById(R.id.txtDate);
|
||||
txtAdresse = itemView.findViewById(R.id.txtAdresse);
|
||||
details = itemView.findViewById(R.id.details);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return agents.size();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public AgentItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext())
|
||||
.inflate(R.layout.agent_item, parent, false);
|
||||
return new AgentItemViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull AgentItemViewHolder holder, int position) {
|
||||
User agent = agents.get(position);
|
||||
holder.txtCode.setText(agent.getCode());
|
||||
if(agent.getDateEmbauche() == null){
|
||||
holder.txtDate.setText("Pas de date");
|
||||
}else{
|
||||
LocalDate date = LocalDate.parse(agent.getDateEmbauche());
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
|
||||
holder.txtDate.setText(dateTimeFormatter.format(date));
|
||||
}
|
||||
if(agent.getVille() == null || agent.getAdresse() == null){
|
||||
holder.txtAdresse.setText("Pas d'adresse");
|
||||
}else{
|
||||
String address = agent.getVille()+"; "+agent.getAdresse();
|
||||
holder.txtAdresse.setText(address);
|
||||
}
|
||||
holder.details.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if(listener != null){
|
||||
listener.onItemClick(agent);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
package com.example.quiz.data.adapter;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.example.quiz.R;
|
||||
import com.example.quiz.data.model.Course;
|
||||
import com.example.quiz.data.model.TypeOfBet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class MultiTypeOfBetsAdapter extends RecyclerView.Adapter<MultiTypeOfBetsAdapter.TypeOfBetViewHolder> {
|
||||
private List<TypeOfBet> types;
|
||||
private Set<Integer> selectedPositions = new HashSet<>();
|
||||
private onItemClickListener listener;
|
||||
|
||||
public interface onItemClickListener {
|
||||
void onItemClick(TypeOfBet type, boolean isChecked);
|
||||
void onItemsSelected(List<TypeOfBet> selectedItems);
|
||||
}
|
||||
|
||||
public void setOnItemClickListener(onItemClickListener listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
public MultiTypeOfBetsAdapter(List<TypeOfBet> types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
// Méthode pour pré-sélectionner les paris (rendue publique)
|
||||
public void preSelectAvailableBets(List<Course.TypeParis> preselectedTypes) {
|
||||
selectedPositions.clear();
|
||||
for (int i = 0; i < types.size(); i++) {
|
||||
if (preselectedTypes.contains(types.get(i).getName())) {
|
||||
selectedPositions.add(i);
|
||||
}
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void setTypes(List<TypeOfBet> types) {
|
||||
this.types = types;
|
||||
selectedPositions.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public TypeOfBetViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.multi_type_of_bet_item, parent, false);
|
||||
return new TypeOfBetViewHolder(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull TypeOfBetViewHolder holder, int position) {
|
||||
TypeOfBet type = types.get(position);
|
||||
holder.type_of_bet_name.setText(type.getLabel());
|
||||
|
||||
boolean isSelected = selectedPositions.contains(position);
|
||||
holder.checkBox.setChecked(isSelected);
|
||||
|
||||
if (isSelected) {
|
||||
holder.itemView.setBackgroundResource(R.drawable.item_gradient_bg_selected);
|
||||
} else {
|
||||
holder.itemView.setBackgroundResource(R.drawable.item_gradient_bg);
|
||||
}
|
||||
|
||||
holder.itemView.setOnClickListener(v -> {
|
||||
toggleSelection(position, type);
|
||||
});
|
||||
|
||||
holder.checkBox.setOnClickListener(v -> {
|
||||
toggleSelection(position, type);
|
||||
});
|
||||
}
|
||||
|
||||
private void toggleSelection(int position, TypeOfBet type) {
|
||||
boolean isCurrentlySelected = selectedPositions.contains(position);
|
||||
|
||||
if (isCurrentlySelected) {
|
||||
selectedPositions.remove(position);
|
||||
} else {
|
||||
selectedPositions.add(position);
|
||||
}
|
||||
|
||||
if (listener != null) {
|
||||
listener.onItemClick(type, !isCurrentlySelected);
|
||||
}
|
||||
|
||||
|
||||
notifyItemChanged(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return types.size();
|
||||
}
|
||||
|
||||
public List<TypeOfBet> getSelectedItems() {
|
||||
List<TypeOfBet> selectedItems = new ArrayList<>();
|
||||
for (Integer position : selectedPositions) {
|
||||
if (position >= 0 && position < types.size()) {
|
||||
selectedItems.add(types.get(position));
|
||||
}
|
||||
}
|
||||
return selectedItems;
|
||||
}
|
||||
|
||||
public boolean isSelected(int position) {
|
||||
return selectedPositions.contains(position);
|
||||
}
|
||||
|
||||
public void selectAll() {
|
||||
selectedPositions.clear();
|
||||
for (int i = 0; i < types.size(); i++) {
|
||||
selectedPositions.add(i);
|
||||
}
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void deselectAll() {
|
||||
selectedPositions.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public int getSelectedCount() {
|
||||
return selectedPositions.size();
|
||||
}
|
||||
|
||||
public class TypeOfBetViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView type_of_bet_name;
|
||||
CheckBox checkBox;
|
||||
|
||||
public TypeOfBetViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
type_of_bet_name = itemView.findViewById(R.id.tv_bet_name);
|
||||
checkBox = itemView.findViewById(R.id.checkbox_bet);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
package com.example.quiz.data.model;
|
||||
|
||||
import com.example.quiz.data.model.enums.CourseType;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.example.quiz.data.model;
|
||||
|
||||
public class MiseInitiale {
|
||||
private Long id;
|
||||
private Course.TypeParis typePari;
|
||||
private Long miseInitialeMin;
|
||||
private Long miseInitialeMax;
|
||||
private boolean actif;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Course.TypeParis getTypePari() {
|
||||
return typePari;
|
||||
}
|
||||
|
||||
public void setTypePari(Course.TypeParis typePari) {
|
||||
this.typePari = typePari;
|
||||
}
|
||||
|
||||
public Long getMiseInitialeMin() {
|
||||
return miseInitialeMin;
|
||||
}
|
||||
|
||||
public void setMiseInitialeMin(Long miseInitialeMin) {
|
||||
this.miseInitialeMin = miseInitialeMin;
|
||||
}
|
||||
|
||||
public Long getMiseInitialeMax() {
|
||||
return miseInitialeMax;
|
||||
}
|
||||
|
||||
public void setMiseInitialeMax(Long miseInitialeMax) {
|
||||
this.miseInitialeMax = miseInitialeMax;
|
||||
}
|
||||
|
||||
public boolean isActif() {
|
||||
return actif;
|
||||
}
|
||||
|
||||
public void setActif(boolean actif) {
|
||||
this.actif = actif;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.example.quiz.data.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Restriction {
|
||||
private List<Course.TypeParis> allowedBetTypes;
|
||||
|
||||
public Restriction(){}
|
||||
|
||||
public List<Course.TypeParis> getAllowedBetTypes() {
|
||||
return allowedBetTypes;
|
||||
}
|
||||
|
||||
public void setAllowedBetTypes(List<Course.TypeParis> allowedBetTypes) {
|
||||
this.allowedBetTypes = allowedBetTypes;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.example.quiz.data.model.dtos;
|
||||
|
||||
public class NotifPayload<T> {
|
||||
private NotifType type;
|
||||
private String entity;
|
||||
private Long entityId;
|
||||
private T payload;
|
||||
|
||||
public NotifPayload() {
|
||||
}
|
||||
|
||||
public NotifType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(NotifType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getEntity() {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public void setEntity(String entity) {
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
public Long getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public void setEntityId(Long entityId) {
|
||||
this.entityId = entityId;
|
||||
}
|
||||
|
||||
public T getPayload() {
|
||||
return payload;
|
||||
}
|
||||
|
||||
public void setPayload(T payload) {
|
||||
this.payload = payload;
|
||||
}
|
||||
|
||||
public enum NotifType {
|
||||
COURSE_CREATED,
|
||||
COURSE_UPDATED,
|
||||
COURSE_CANCELLED,
|
||||
COURSE_REPORTED,
|
||||
COURSE_CLOSED_FOR_BETTING,
|
||||
RUNNER_DECLARED_NON_PARTANT
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ public class Agent {
|
||||
private String phone;
|
||||
private String zone;
|
||||
private String fonction;
|
||||
|
||||
private boolean subAgent;
|
||||
public Agent(){}
|
||||
|
||||
public Long getId() {
|
||||
@@ -65,4 +67,12 @@ public class Agent {
|
||||
public void setFonction(String fonction) {
|
||||
this.fonction = fonction;
|
||||
}
|
||||
|
||||
public boolean isSubAgent() {
|
||||
return subAgent;
|
||||
}
|
||||
|
||||
public void setSubAgent(boolean subAgent) {
|
||||
this.subAgent = subAgent;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.example.quiz.data.model.dtos.auth;
|
||||
|
||||
public class ChangePin {
|
||||
private String oldPin;
|
||||
private String newPin;
|
||||
|
||||
public ChangePin() {
|
||||
}
|
||||
|
||||
public String getOldPin() {
|
||||
return oldPin;
|
||||
}
|
||||
|
||||
public void setOldPin(String oldPin) {
|
||||
this.oldPin = oldPin;
|
||||
}
|
||||
|
||||
public String getNewPin() {
|
||||
return newPin;
|
||||
}
|
||||
|
||||
public void setNewPin(String newPin) {
|
||||
this.newPin = newPin;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.example.quiz.data.model.dtos.paris;
|
||||
|
||||
public class CancelParisPaylaod {
|
||||
private String statutPari;
|
||||
|
||||
public CancelParisPaylaod(String statutPari) {
|
||||
this.statutPari = statutPari;
|
||||
}
|
||||
|
||||
public String getStatutPari() {
|
||||
return statutPari;
|
||||
}
|
||||
|
||||
public void setStatutPari(String statutPari) {
|
||||
this.statutPari = statutPari;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.example.quiz.data.model.dtos.paris;
|
||||
|
||||
public class SoldeResponse {
|
||||
private int montantParis;
|
||||
private int nombrePaiements;
|
||||
private int montantPaiements;
|
||||
private int nombreAnnulations;
|
||||
private int montantAnnulations;
|
||||
|
||||
// Getters et setters
|
||||
|
||||
public int getMontantParis() {
|
||||
return montantParis;
|
||||
}
|
||||
|
||||
public void setMontantParis(int montantParis) {
|
||||
this.montantParis = montantParis;
|
||||
}
|
||||
|
||||
public int getNombrePaiements() {
|
||||
return nombrePaiements;
|
||||
}
|
||||
|
||||
public void setNombrePaiements(int nombrePaiements) {
|
||||
this.nombrePaiements = nombrePaiements;
|
||||
}
|
||||
|
||||
public int getMontantPaiements() {
|
||||
return montantPaiements;
|
||||
}
|
||||
|
||||
public void setMontantPaiements(int montantPaiements) {
|
||||
this.montantPaiements = montantPaiements;
|
||||
}
|
||||
|
||||
public int getNombreAnnulations() {
|
||||
return nombreAnnulations;
|
||||
}
|
||||
|
||||
public void setNombreAnnulations(int nombreAnnulations) {
|
||||
this.nombreAnnulations = nombreAnnulations;
|
||||
}
|
||||
|
||||
public int getMontantAnnulations() {
|
||||
return montantAnnulations;
|
||||
}
|
||||
|
||||
public void setMontantAnnulations(int montantAnnulations) {
|
||||
this.montantAnnulations = montantAnnulations;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package com.example.quiz.data.model.enums;
|
||||
|
||||
public enum CourseType {
|
||||
TIERCE,
|
||||
QUARTE,
|
||||
QUINTE
|
||||
}
|
||||
@@ -1,21 +1,29 @@
|
||||
package com.example.quiz.data.remote;
|
||||
|
||||
import com.example.quiz.data.model.Course;
|
||||
import com.example.quiz.data.model.MiseInitiale;
|
||||
import com.example.quiz.data.model.PagedModel;
|
||||
import com.example.quiz.data.model.Pari;
|
||||
import com.example.quiz.data.model.PariMise;
|
||||
import com.example.quiz.data.model.ParisResponse;
|
||||
import com.example.quiz.data.model.PointDeVente;
|
||||
import com.example.quiz.data.model.Restriction;
|
||||
import com.example.quiz.data.model.Reunion;
|
||||
import com.example.quiz.data.model.Tpe;
|
||||
import com.example.quiz.data.model.dtos.auth.ChangePin;
|
||||
import com.example.quiz.data.model.dtos.auth.LoginPayload;
|
||||
import com.example.quiz.data.model.dtos.auth.LoginResponse;
|
||||
import com.example.quiz.data.model.TpeResponse;
|
||||
import com.example.quiz.data.model.dtos.auth.User;
|
||||
import com.example.quiz.data.model.dtos.paris.CancelParisPaylaod;
|
||||
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.Body;
|
||||
import retrofit2.http.GET;
|
||||
import retrofit2.http.PATCH;
|
||||
import retrofit2.http.POST;
|
||||
import retrofit2.http.PUT;
|
||||
import retrofit2.http.Path;
|
||||
@@ -26,7 +34,7 @@ public interface ApiService {
|
||||
Call<List<Reunion>> getReunions(@Path("date") String date);
|
||||
|
||||
@GET("courses")
|
||||
Call<PagedModel<Course>> getCourses(@Query("reunionDate") String reunionDate);
|
||||
Call<PagedModel<Course>> getCourses(@Query("reunionDate") String reunionDate, @Query("statut") String statut);
|
||||
|
||||
@POST("paris")
|
||||
Call<ParisResponse> createPari(@Body Pari pari);
|
||||
@@ -37,18 +45,39 @@ public interface ApiService {
|
||||
@GET("paris/agent/{agentId}/today")
|
||||
Call<List<ParisResponse>> derniersParis(@Path("agentId") String agentId);
|
||||
|
||||
@PUT("pari/annuler/{numeroTicket}")
|
||||
Call<ParisResponse> annulerPari(@Path("numeroTicket") String numeroTicket);
|
||||
@PATCH("paris/numero/{numeroTicket}/statut")
|
||||
Call<ParisResponse> annulerPari(@Path("numeroTicket") String numeroTicket,
|
||||
@Body() CancelParisPaylaod cancelParisPaylaod);
|
||||
|
||||
@GET("paris/agent/{agentId}/solde/course/{courseId}")
|
||||
Call<Double> getSoldeByCourse(@Path("agentId") String createdBy, @Path("courseId") String courseId);
|
||||
Call<SoldeResponse> getSoldeByCourse(@Path("agentId") String createdBy, @Path("courseId") String courseId);
|
||||
|
||||
@GET("paris/agent/{agentId}/solde")
|
||||
Call<Double> getSoldeByDay(@Path("agentId") String agentId, @Query("date") String day);
|
||||
Call<SoldeResponse> 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);
|
||||
|
||||
@PATCH("agents/me/pin")
|
||||
Call<User> changePin(@Body ChangePin pin);
|
||||
|
||||
@GET("config/mise-initiale")
|
||||
Call<List<MiseInitiale>> getBetInitMise();
|
||||
|
||||
@GET("agents/byMaster/{masterId}")
|
||||
Call<List<User>> getAgentsByMaster(@Path("masterId") String masterId);
|
||||
@GET("agents/{agentId}")
|
||||
Call<User> getAgent(@Path("agentId") String agentId);
|
||||
@GET("agents/{agentId}/available-bets")
|
||||
Call<List<Course.TypeParis>> getAvailableBets(@Path("agentId") String agentId);
|
||||
|
||||
@PATCH("agents/{masterId}/slaves/{slaveId}/access")
|
||||
Call<Void> setAccess(@Path("masterId") String masterId, @Path("slaveId") String slaveId, @Query("block") boolean access);
|
||||
|
||||
@POST("agents/{masterId}/slaves/{slaveId}/available-bets")
|
||||
Call<Void> setRestrictions(@Path("masterId") String masterId, @Path("slaveId") String slaveId, @Body Restriction restrictions);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.example.quiz.data.remote;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
import com.example.quiz.R;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext;
|
||||
|
||||
@Singleton
|
||||
public class NotificationHelper {
|
||||
|
||||
private final Context context;
|
||||
private static final String CHANNEL_ID = "socket_channel";
|
||||
|
||||
@Inject
|
||||
public NotificationHelper(@ApplicationContext Context context) {
|
||||
this.context = context;
|
||||
createChannel();
|
||||
}
|
||||
|
||||
private void createChannel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
NotificationChannel channel = new NotificationChannel(
|
||||
CHANNEL_ID,
|
||||
"Socket Notifications",
|
||||
NotificationManager.IMPORTANCE_HIGH
|
||||
);
|
||||
channel.setDescription("Notifications des messages du socket");
|
||||
NotificationManager manager =
|
||||
context.getSystemService(NotificationManager.class);
|
||||
if (manager != null) manager.createNotificationChannel(channel);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressLint("MissingPermission")
|
||||
public void showNotification(String title, String message) {
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
|
||||
.setSmallIcon(R.drawable.ic_notification)
|
||||
.setContentTitle(title)
|
||||
.setContentText(message)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
.setAutoCancel(true);
|
||||
|
||||
NotificationManagerCompat manager = NotificationManagerCompat.from(context);
|
||||
manager.notify((int) System.currentTimeMillis(), builder.build());
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package com.example.quiz.data.remote;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.WebSocket;
|
||||
import okhttp3.WebSocketListener;
|
||||
|
||||
@Singleton
|
||||
public class SocketManager {
|
||||
|
||||
private final OkHttpClient client;
|
||||
private final TokenManager tokenManager;
|
||||
private WebSocket webSocket;
|
||||
private boolean isConnected = false;
|
||||
|
||||
@Inject
|
||||
public SocketManager(OkHttpClient client, TokenManager tokenManager) {
|
||||
this.client = client;
|
||||
this.tokenManager = tokenManager;
|
||||
}
|
||||
|
||||
public synchronized void connect() {
|
||||
|
||||
String token = tokenManager.getToken();
|
||||
|
||||
if (token == null) {
|
||||
Log.d("SOCKET", "Token null → no connection");
|
||||
return;
|
||||
}
|
||||
|
||||
if (isConnected) return;
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url("ws://boxer-adapting-bluegill.ngrok-free.app/ws")
|
||||
.addHeader("Authorization", "Bearer " + token)
|
||||
.build();
|
||||
|
||||
webSocket = client.newWebSocket(request, new WebSocketListener() {
|
||||
|
||||
@Override
|
||||
public void onOpen(WebSocket webSocket, Response response) {
|
||||
isConnected = true;
|
||||
Log.d("SOCKET", "Connected");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMessage(WebSocket webSocket, String text) {
|
||||
Log.d("SOCKET", "Message: " + text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
|
||||
isConnected = false;
|
||||
Log.e("SOCKET", "Error: " + t.getMessage());
|
||||
|
||||
// tentative de reconnexion
|
||||
reconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClosed(WebSocket webSocket, int code, String reason) {
|
||||
isConnected = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public synchronized void reconnect() {
|
||||
disconnect();
|
||||
connect();
|
||||
}
|
||||
|
||||
public synchronized void disconnect() {
|
||||
if (webSocket != null) {
|
||||
webSocket.close(1000, "Closing");
|
||||
webSocket = null;
|
||||
}
|
||||
isConnected = false;
|
||||
}
|
||||
}
|
||||
285
app/src/main/java/com/example/quiz/data/remote/StompManager.java
Normal file
285
app/src/main/java/com/example/quiz/data/remote/StompManager.java
Normal file
@@ -0,0 +1,285 @@
|
||||
package com.example.quiz.data.remote;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.example.quiz.data.model.Course;
|
||||
import com.example.quiz.data.model.dtos.NotifPayload;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.CompositeDisposable;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import ua.naiksoftware.stomp.Stomp;
|
||||
import ua.naiksoftware.stomp.StompClient;
|
||||
import ua.naiksoftware.stomp.dto.StompHeader;
|
||||
|
||||
@Singleton
|
||||
public class StompManager {
|
||||
|
||||
private final TokenManager tokenManager;
|
||||
private final NotificationHelper notificationHelper;
|
||||
|
||||
private StompClient stompClient;
|
||||
private boolean isConnected = false;
|
||||
|
||||
// Map topic -> liste de listeners
|
||||
private final Map<String, List<Consumer<String>>> topicListeners = new HashMap<>();
|
||||
|
||||
// Gestion des Disposables RxJava
|
||||
private final CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
|
||||
// Map pour stocker les subscriptions par topic
|
||||
private final Map<String, Disposable> topicSubscriptions = new HashMap<>();
|
||||
|
||||
@Inject
|
||||
public StompManager(TokenManager tokenManager,
|
||||
NotificationHelper notificationHelper) {
|
||||
this.tokenManager = tokenManager;
|
||||
this.notificationHelper = notificationHelper;
|
||||
}
|
||||
|
||||
// -------------------- Connexion --------------------
|
||||
public synchronized void connect() {
|
||||
if (isConnected) return;
|
||||
|
||||
String token = tokenManager.getToken();
|
||||
if (token == null) {
|
||||
Log.e("STOMP", "No token available");
|
||||
return;
|
||||
}
|
||||
|
||||
// URL de connexion WebSocket
|
||||
String url = "wss://boxer-adapting-bluegill.ngrok-free.app/ws";
|
||||
|
||||
try {
|
||||
// Créer le client STOMP
|
||||
stompClient = Stomp.over(Stomp.ConnectionProvider.OKHTTP, url);
|
||||
|
||||
// Ajouter les headers d'authentification
|
||||
List<StompHeader> headers = new ArrayList<>();
|
||||
headers.add(new StompHeader("Authorization", "Bearer " + token));
|
||||
|
||||
// Observer la connexion et stocker le Disposable
|
||||
Disposable lifecycleDisposable = stompClient.lifecycle()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(lifecycleEvent -> {
|
||||
switch (lifecycleEvent.getType()) {
|
||||
case OPENED:
|
||||
isConnected = true;
|
||||
Log.d("STOMP", "Connected to WebSocket");
|
||||
resubscribeAll();
|
||||
break;
|
||||
|
||||
case CLOSED:
|
||||
isConnected = false;
|
||||
Log.d("STOMP", "Disconnected from WebSocket");
|
||||
break;
|
||||
|
||||
case ERROR:
|
||||
isConnected = false;
|
||||
Log.e("STOMP", "Error: " + lifecycleEvent.getException());
|
||||
reconnect();
|
||||
break;
|
||||
}
|
||||
}, throwable -> {
|
||||
Log.e("STOMP", "Lifecycle error", throwable);
|
||||
isConnected = false;
|
||||
reconnect();
|
||||
});
|
||||
|
||||
compositeDisposable.add(lifecycleDisposable);
|
||||
|
||||
// Se connecter
|
||||
stompClient.connect(headers);
|
||||
|
||||
} catch (Exception e) {
|
||||
Log.e("STOMP", "Connection error", e);
|
||||
reconnect();
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------- Souscription aux topics --------------------
|
||||
public synchronized void subscribe(String topic, Consumer<String> listener) {
|
||||
// Ajouter le listener
|
||||
topicListeners.computeIfAbsent(topic, k -> new ArrayList<>()).add(listener);
|
||||
|
||||
// Si déjà connecté, souscrire immédiatement
|
||||
if (isConnected && stompClient != null) {
|
||||
subscribeToTopic(topic);
|
||||
} else {
|
||||
connect();
|
||||
}
|
||||
}
|
||||
|
||||
private void subscribeToTopic(String topic) {
|
||||
if (stompClient == null) return;
|
||||
|
||||
// Si déjà abonné à ce topic, ne pas souscrire à nouveau
|
||||
if (topicSubscriptions.containsKey(topic)) {
|
||||
Log.d("STOMP", "Already subscribed to " + topic);
|
||||
return;
|
||||
}
|
||||
|
||||
// Formater le topic correctement
|
||||
String destination = topic.startsWith("/topic/") ? topic : "/topic/" + topic;
|
||||
|
||||
Log.d("STOMP", "Subscribing to " + destination);
|
||||
|
||||
Disposable subscription = stompClient.topic(destination)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
stompMessage -> {
|
||||
String payload = stompMessage.getPayload();
|
||||
Log.d("STOMP", "Message on " + destination + ": " + payload);
|
||||
|
||||
// Notifier les listeners
|
||||
List<Consumer<String>> listeners = topicListeners.get(topic);
|
||||
if (listeners != null) {
|
||||
for (Consumer<String> listener : listeners) {
|
||||
try {
|
||||
listener.accept(payload);
|
||||
} catch (Exception e) {
|
||||
Log.e("STOMP", "Listener error", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
String notif = "";
|
||||
Type type = new TypeToken<NotifPayload<Course>>(){}.getType();
|
||||
NotifPayload<Course> notifCourse = new Gson().fromJson(payload, type);
|
||||
Course updatedCourse = notifCourse.getPayload();
|
||||
switch (notifCourse.getType()){
|
||||
case COURSE_CREATED:
|
||||
notif = "Nouvelle course "+updatedCourse.getNom()+" créée";
|
||||
break;
|
||||
case COURSE_UPDATED:
|
||||
notif = "Course "+updatedCourse.getNom()+" modifiée";
|
||||
break;
|
||||
case COURSE_CANCELLED:
|
||||
notif = "Course "+updatedCourse.getNom()+" annulée";
|
||||
break;
|
||||
case COURSE_REPORTED:
|
||||
notif = "Course "+updatedCourse.getNom()+" reportée";
|
||||
break;
|
||||
case COURSE_CLOSED_FOR_BETTING:
|
||||
notif = "Course "+updatedCourse.getNom()+" fermée aux paris!";
|
||||
break;
|
||||
case RUNNER_DECLARED_NON_PARTANT:
|
||||
notif = "Non partants déclarés pour la course "+updatedCourse.getNom();
|
||||
break;
|
||||
}
|
||||
// Notification
|
||||
notificationHelper.showNotification(topic, notif);
|
||||
},
|
||||
throwable -> {
|
||||
Log.e("STOMP", "Error on " + destination, throwable);
|
||||
// Nettoyer en cas d'erreur
|
||||
topicSubscriptions.remove(topic);
|
||||
}
|
||||
);
|
||||
|
||||
topicSubscriptions.put(topic, subscription);
|
||||
compositeDisposable.add(subscription);
|
||||
}
|
||||
|
||||
private void resubscribeAll() {
|
||||
if (stompClient == null) return;
|
||||
|
||||
// Nettoyer les anciennes subscriptions
|
||||
for (Disposable disposable : topicSubscriptions.values()) {
|
||||
if (disposable != null && !disposable.isDisposed()) {
|
||||
disposable.dispose();
|
||||
}
|
||||
}
|
||||
topicSubscriptions.clear();
|
||||
|
||||
// Resouscrire à tous les topics
|
||||
for (String topic : topicListeners.keySet()) {
|
||||
subscribeToTopic(topic);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------- Envoi de messages --------------------
|
||||
public void sendMessage(String destination, Object payload) {
|
||||
if (!isConnected || stompClient == null) {
|
||||
Log.e("STOMP", "Not connected");
|
||||
return;
|
||||
}
|
||||
|
||||
String dest = destination.startsWith("/app/") ? destination : "/app/" + destination;
|
||||
|
||||
Disposable sendDisposable = stompClient.send(dest, payload.toString())
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(
|
||||
() -> Log.d("STOMP", "Message sent to " + dest),
|
||||
throwable -> Log.e("STOMP", "Error sending to " + dest, throwable)
|
||||
);
|
||||
|
||||
compositeDisposable.add(sendDisposable);
|
||||
}
|
||||
|
||||
public void sendToCourses(Object payload) {
|
||||
sendMessage("/app/courses", payload);
|
||||
}
|
||||
|
||||
// -------------------- Désabonnement --------------------
|
||||
public synchronized void unsubscribe(String topic, Consumer<String> listener) {
|
||||
if (topicListeners.containsKey(topic)) {
|
||||
topicListeners.get(topic).remove(listener);
|
||||
|
||||
if (topicListeners.get(topic).isEmpty()) {
|
||||
topicListeners.remove(topic);
|
||||
|
||||
// Si plus de listeners, annuler la souscription STOMP
|
||||
Disposable subscription = topicSubscriptions.remove(topic);
|
||||
if (subscription != null && !subscription.isDisposed()) {
|
||||
subscription.dispose();
|
||||
compositeDisposable.remove(subscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------- Déconnexion --------------------
|
||||
public synchronized void disconnect() {
|
||||
// Nettoyer toutes les subscriptions RxJava
|
||||
compositeDisposable.clear();
|
||||
topicSubscriptions.clear();
|
||||
|
||||
if (stompClient != null) {
|
||||
stompClient.disconnect();
|
||||
stompClient = null;
|
||||
}
|
||||
isConnected = false;
|
||||
topicListeners.clear();
|
||||
}
|
||||
|
||||
private void reconnect() {
|
||||
disconnect();
|
||||
// Réessayer après délai
|
||||
new android.os.Handler().postDelayed(() -> {
|
||||
Log.d("STOMP", "Attempting to reconnect...");
|
||||
connect();
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
// À appeler dans le cycle de vie du fragment/activity
|
||||
public void onCleanup() {
|
||||
disconnect();
|
||||
compositeDisposable.dispose();
|
||||
}
|
||||
}
|
||||
@@ -11,16 +11,13 @@ public class TokenManager {
|
||||
private static final String PREF_NAME = "auth_pref";
|
||||
private static final String KEY_TOKEN = "auth_token";
|
||||
|
||||
SocketManager socketManager;
|
||||
private SharedPreferences sharedPreferences;
|
||||
@Inject
|
||||
public TokenManager(@ApplicationContext Context context, SocketManager socketManager) {
|
||||
public TokenManager(@ApplicationContext Context context) {
|
||||
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(){
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
package com.example.quiz.data.repository;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.example.quiz.data.model.Course;
|
||||
import com.example.quiz.data.model.Restriction;
|
||||
import com.example.quiz.data.model.dtos.auth.User;
|
||||
import com.example.quiz.data.remote.ApiService;
|
||||
import com.example.quiz.utils.Result;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class AgentRepository {
|
||||
private ApiService apiService;
|
||||
@Inject
|
||||
public AgentRepository(ApiService apiService) {
|
||||
this.apiService = apiService;
|
||||
}
|
||||
|
||||
public LiveData<Result<List<User>>> getAgents(String agentId) {
|
||||
MutableLiveData<Result<List<User>>> liveAgents = new MutableLiveData<>();
|
||||
liveAgents.setValue(Result.loading());
|
||||
apiService.getAgentsByMaster(agentId).enqueue(new Callback<List<User>>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<User>> call, @NonNull Response<List<User>> response) {
|
||||
if (response.isSuccessful()) {
|
||||
liveAgents.postValue(Result.success(response.body()));
|
||||
} else {
|
||||
liveAgents.postValue(Result.error(response.message()));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<User>> call, @NonNull Throwable throwable) {
|
||||
liveAgents.postValue(Result.error(throwable.getMessage()));
|
||||
}
|
||||
});
|
||||
return liveAgents;
|
||||
}
|
||||
|
||||
public LiveData<Result<User>> getAgentById(String agentId) {
|
||||
MutableLiveData<Result<User>> liveAgent = new MutableLiveData<>();
|
||||
liveAgent.setValue(Result.loading());
|
||||
apiService.getAgent(agentId).enqueue(new Callback<User>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<User> call, @NonNull Response<User> response) {
|
||||
if (response.isSuccessful()) {
|
||||
liveAgent.postValue(Result.success(response.body()));
|
||||
} else {
|
||||
liveAgent.postValue(Result.error(response.message()));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<User> call, @NonNull Throwable throwable) {
|
||||
liveAgent.postValue(Result.error(throwable.getMessage()));
|
||||
}
|
||||
});
|
||||
return liveAgent;
|
||||
}
|
||||
|
||||
public LiveData<Result<List<Course.TypeParis>>> getAvailableBets(String agentId) {
|
||||
MutableLiveData<Result<List<Course.TypeParis>>> liveAvailableBets = new MutableLiveData<>();
|
||||
liveAvailableBets.setValue(Result.loading());
|
||||
apiService.getAvailableBets(agentId).enqueue(new Callback<List<Course.TypeParis>>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<List<Course.TypeParis>> call, @NonNull Response<List<Course.TypeParis>> response) {
|
||||
if (response.isSuccessful()) {
|
||||
liveAvailableBets.postValue(Result.success(response.body()));
|
||||
} else {
|
||||
liveAvailableBets.postValue(Result.error(response.message()));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<List<Course.TypeParis>> call, @NonNull Throwable throwable) {
|
||||
liveAvailableBets.postValue(Result.error(throwable.getMessage()));
|
||||
}
|
||||
});
|
||||
return liveAvailableBets;
|
||||
}
|
||||
|
||||
public LiveData<Result<Void>> setAccess(String masterId, String slaveId, boolean access) {
|
||||
MutableLiveData<Result<Void>> liveSetAccess = new MutableLiveData<>();
|
||||
liveSetAccess.setValue(Result.loading());
|
||||
apiService.setAccess(masterId, slaveId, access).enqueue(new Callback<Void>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Void> call, @NonNull Response<Void> response) {
|
||||
if (response.isSuccessful()) {
|
||||
liveSetAccess.postValue(Result.success(null));
|
||||
} else {
|
||||
liveSetAccess.postValue(Result.error(response.message()));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable throwable) {
|
||||
liveSetAccess.postValue(Result.error(throwable.getMessage()));
|
||||
}
|
||||
});
|
||||
return liveSetAccess;
|
||||
};
|
||||
|
||||
public LiveData<Result<Void>> setRestrictions(String masterId, String slaveId, Restriction restrictions) {
|
||||
MutableLiveData<Result<Void>> liveSetRestrictions = new MutableLiveData<>();
|
||||
liveSetRestrictions.setValue(Result.loading());
|
||||
apiService.setRestrictions(masterId, slaveId, restrictions).enqueue(new Callback<Void>() {
|
||||
@Override
|
||||
public void onResponse(@NonNull Call<Void> call, @NonNull Response<Void> response) {
|
||||
if (response.isSuccessful()) {
|
||||
liveSetRestrictions.postValue(Result.success(null));
|
||||
} else {
|
||||
liveSetRestrictions.postValue(Result.error(response.message()));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(@NonNull Call<Void> call, @NonNull Throwable throwable) {
|
||||
liveSetRestrictions.postValue(Result.error(throwable.getMessage()));
|
||||
}
|
||||
});
|
||||
return liveSetRestrictions;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,8 +10,6 @@ import com.example.quiz.data.model.PagedModel;
|
||||
import com.example.quiz.data.remote.ApiService;
|
||||
import com.example.quiz.utils.Result;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import retrofit2.Call;
|
||||
@@ -20,6 +18,7 @@ import retrofit2.Response;
|
||||
|
||||
public class CourseRepository {
|
||||
private ApiService apiService;
|
||||
private final Course.Statut OPENED_STATUT = Course.Statut.OUVERT;
|
||||
|
||||
@Inject
|
||||
public CourseRepository(ApiService apiService) {
|
||||
@@ -29,11 +28,25 @@ public class CourseRepository {
|
||||
public LiveData<Result<PagedModel<Course>>> getCourses(String reunionDate) {
|
||||
MutableLiveData<Result<PagedModel<Course>>> liveCourses = new MutableLiveData<Result<PagedModel<Course>>>();
|
||||
liveCourses.setValue(Result.loading());
|
||||
apiService.getCourses(reunionDate).enqueue(new Callback<PagedModel<Course>>() {
|
||||
apiService.getCourses(reunionDate,String.valueOf(OPENED_STATUT)).enqueue(new Callback<PagedModel<Course>>() {
|
||||
@Override
|
||||
public void onResponse(Call<PagedModel<Course>> call, Response<PagedModel<Course>> response) {
|
||||
if(response.isSuccessful()){
|
||||
liveCourses.postValue(Result.success(response.body()));
|
||||
// PagedModel<Course> openedPagesCourses = new PagedModel<>();
|
||||
// List<Course> listOfCourses = new ArrayList<>();
|
||||
// for(Course course: response.body().getContent()){
|
||||
// if(course.getStatut().equals(OPENED_STATUT)){
|
||||
// listOfCourses.add(course);
|
||||
// }
|
||||
// }
|
||||
//// openedPagesCourses.setTotalPages(response.body().getTotalPages());
|
||||
//// openedPagesCourses.setTotalElements(response.body().getTotalElements());
|
||||
//// openedPagesCourses.setPageable(response.body().getPageable());
|
||||
//// openedPagesCourses.setNumberOfElements(response.body().getNumberOfElements());
|
||||
//// openedPagesCourses.setSize(response.body().getSize());
|
||||
//// openedPagesCourses.setContent(listOfCourses);
|
||||
// liveCourses.postValue(Result.success(response.body()));
|
||||
}else{
|
||||
liveCourses.postValue(Result.error(response.message()));
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@ import android.util.Log;
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.example.quiz.data.model.dtos.auth.ChangePin;
|
||||
import com.example.quiz.data.model.dtos.auth.LoginPayload;
|
||||
import com.example.quiz.data.model.dtos.auth.LoginResponse;
|
||||
import com.example.quiz.data.model.dtos.auth.User;
|
||||
import com.example.quiz.data.remote.ApiService;
|
||||
import com.example.quiz.data.remote.TokenManager;
|
||||
import com.example.quiz.utils.Result;
|
||||
@@ -20,6 +22,7 @@ import retrofit2.Response;
|
||||
public class LoginRepository {
|
||||
private ApiService apiService;
|
||||
private TokenManager tokenManager;
|
||||
|
||||
@Inject
|
||||
public LoginRepository(ApiService apiService, TokenManager tokenManager) {
|
||||
this.tokenManager = tokenManager;
|
||||
@@ -37,15 +40,38 @@ public class LoginRepository {
|
||||
Log.d("TOKEN", response.body().getToken());
|
||||
tokenManager.saveToken(response.body().getToken());
|
||||
}else{
|
||||
liveLogin.postValue(Result.error(response.message()));
|
||||
liveLogin.postValue(Result.error(response.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<LoginResponse> call, Throwable throwable) {
|
||||
liveLogin.postValue(Result.error(throwable.getMessage()));
|
||||
liveLogin.postValue(Result.error(throwable.toString()));
|
||||
}
|
||||
});
|
||||
return liveLogin;
|
||||
}
|
||||
|
||||
public LiveData<Result<User>> changePin(String oldPin, String newPin){
|
||||
MutableLiveData<Result<User>> liveUser = new MutableLiveData<Result<User>>();
|
||||
liveUser.setValue(Result.loading());
|
||||
ChangePin changePin = new ChangePin();
|
||||
changePin.setOldPin(oldPin);
|
||||
changePin.setNewPin(newPin);
|
||||
apiService.changePin(changePin).enqueue(new Callback<User>(){
|
||||
@Override
|
||||
public void onResponse(Call<User> call, Response<User> response) {
|
||||
if(response.isSuccessful()) {
|
||||
liveUser.postValue(Result.success(response.body()));
|
||||
}else {
|
||||
liveUser.postValue(Result.error(response.message()));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(Call<User> call, Throwable throwable) {
|
||||
liveUser.postValue(Result.error(throwable.getMessage()));
|
||||
}
|
||||
});
|
||||
return liveUser;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.example.quiz.data.repository;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.example.quiz.data.model.MiseInitiale;
|
||||
import com.example.quiz.data.model.PariMise;
|
||||
import com.example.quiz.data.remote.ApiService;
|
||||
import com.example.quiz.data.remote.TokenManager;
|
||||
import com.example.quiz.utils.Result;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
public class PariMiseRepository {
|
||||
private ApiService apiService;
|
||||
|
||||
@Inject
|
||||
public PariMiseRepository(ApiService apiService, TokenManager tokenManager) {
|
||||
this.apiService = apiService;
|
||||
}
|
||||
|
||||
public LiveData<Result<List<MiseInitiale>>> getBetInitMise() {
|
||||
MutableLiveData<Result<List<MiseInitiale>>> livePariMise = new MutableLiveData<Result<List<MiseInitiale>>>();
|
||||
livePariMise.setValue(Result.loading());
|
||||
apiService.getBetInitMise().enqueue(new Callback<List<MiseInitiale>>() {
|
||||
@Override
|
||||
public void onResponse(Call<List<MiseInitiale>> call, Response<List<MiseInitiale>> response) {
|
||||
if (response.isSuccessful()) {
|
||||
livePariMise.postValue(Result.success(response.body()));
|
||||
}else{
|
||||
livePariMise.postValue(Result.error(response.message()));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void onFailure(Call<List<MiseInitiale>> call, Throwable throwable) {
|
||||
livePariMise.postValue(Result.error(throwable.getMessage()));
|
||||
}
|
||||
});
|
||||
return livePariMise;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.example.quiz.data.model.Pari;
|
||||
import com.example.quiz.data.model.ParisResponse;
|
||||
import com.example.quiz.data.model.dtos.paris.CancelParisPaylaod;
|
||||
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
|
||||
import com.example.quiz.data.remote.ApiService;
|
||||
import com.example.quiz.utils.Result;
|
||||
|
||||
@@ -96,7 +98,8 @@ public class PariRepository {
|
||||
public LiveData<Result<ParisResponse>> annulerPari(String numeroTicket){
|
||||
MutableLiveData<Result<ParisResponse>> pariResponse = new MutableLiveData<>();
|
||||
pariResponse.setValue(Result.loading());
|
||||
apiService.annulerPari(numeroTicket).enqueue(new Callback<ParisResponse>(){
|
||||
CancelParisPaylaod cancelParisPaylaod = new CancelParisPaylaod("ANNULE");
|
||||
apiService.annulerPari(numeroTicket, cancelParisPaylaod).enqueue(new Callback<ParisResponse>(){
|
||||
@Override
|
||||
public void onResponse(Call<ParisResponse> call, Response<ParisResponse> response) {
|
||||
if(response.isSuccessful()){
|
||||
@@ -121,12 +124,12 @@ public class PariRepository {
|
||||
return pariResponse;
|
||||
}
|
||||
|
||||
public LiveData<Result<Double>> getSoldeByCourse(String agentId, String courseId){
|
||||
MutableLiveData<Result<Double>> solde = new MutableLiveData<>();
|
||||
public LiveData<Result<SoldeResponse>> getSoldeByCourse(String agentId, String courseId){
|
||||
MutableLiveData<Result<SoldeResponse>> solde = new MutableLiveData<>();
|
||||
solde.setValue(Result.loading());
|
||||
apiService.getSoldeByCourse(agentId, courseId).enqueue(new Callback<Double>() {
|
||||
apiService.getSoldeByCourse(agentId, courseId).enqueue(new Callback<SoldeResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<Double> call, Response<Double> response) {
|
||||
public void onResponse(Call<SoldeResponse> call, Response<SoldeResponse> response) {
|
||||
if(response.isSuccessful()){
|
||||
solde.postValue(Result.success(response.body()));
|
||||
}else{
|
||||
@@ -139,19 +142,19 @@ public class PariRepository {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<Double> call, Throwable throwable) {
|
||||
public void onFailure(Call<SoldeResponse> call, Throwable throwable) {
|
||||
solde.postValue(Result.error(throwable.getMessage()));
|
||||
}
|
||||
});
|
||||
return solde;
|
||||
}
|
||||
|
||||
public LiveData<Result<Double>> getSoldeByDay(String agentId, String day){
|
||||
MutableLiveData<Result<Double>> solde = new MutableLiveData<>();
|
||||
public LiveData<Result<SoldeResponse>> getSoldeByDay(String agentId, String day){
|
||||
MutableLiveData<Result<SoldeResponse>> solde = new MutableLiveData<>();
|
||||
solde.setValue(Result.loading());
|
||||
apiService.getSoldeByDay(agentId, day).enqueue(new Callback<Double>() {
|
||||
apiService.getSoldeByDay(agentId, day).enqueue(new Callback<SoldeResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<Double> call, Response<Double> response) {
|
||||
public void onResponse(Call<SoldeResponse> call, Response<SoldeResponse> response) {
|
||||
if(response.isSuccessful()){
|
||||
solde.postValue(Result.success(response.body()));
|
||||
}else{
|
||||
@@ -164,7 +167,7 @@ public class PariRepository {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<Double> call, Throwable throwable) {
|
||||
public void onFailure(Call<SoldeResponse> call, Throwable throwable) {
|
||||
solde.postValue(Result.error(throwable.getMessage()));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -28,21 +28,24 @@ public class AuthNavigator {
|
||||
|
||||
private FragmentManager fragmentManager;
|
||||
|
||||
private TokenManager tokenManager;
|
||||
private final SessionManager sessionManager;
|
||||
LoginViewModel viewModel;
|
||||
LogsViewModel logsViewModel;
|
||||
private LoginViewModel viewModel;
|
||||
private LogsViewModel logsViewModel;
|
||||
private LifecycleOwner lifecycleOwner;
|
||||
|
||||
|
||||
private Dialog dialog;
|
||||
|
||||
SharedPrefsHelper prefsHelper;
|
||||
|
||||
|
||||
|
||||
public AuthNavigator(Context context,
|
||||
FragmentManager fragmentManager,
|
||||
SessionManager sessionManager,
|
||||
LoginViewModel viewModel,
|
||||
LogsViewModel logsViewModel) {
|
||||
LogsViewModel logsViewModel,
|
||||
LifecycleOwner lifecycleOwner) {
|
||||
this.viewModel = viewModel;
|
||||
this.logsViewModel = logsViewModel;
|
||||
this.prefsHelper = SharedPrefsHelper.getInstance(context);
|
||||
@@ -50,6 +53,7 @@ public class AuthNavigator {
|
||||
this.context = context;
|
||||
dialog = new Dialog(context);
|
||||
this.sessionManager = sessionManager;
|
||||
this.lifecycleOwner = lifecycleOwner;
|
||||
}
|
||||
|
||||
public void navigate(Fragment destinationFragment) {
|
||||
@@ -98,12 +102,15 @@ public class AuthNavigator {
|
||||
pin.setError("Le pin doit contenir minimum quatre chiffres!");
|
||||
return;
|
||||
}
|
||||
if(prefsHelper.get("terminalId") == null){
|
||||
MessageDialog.showError(context, "Terminal non trouvé");
|
||||
}
|
||||
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>>() {
|
||||
viewModel.login(loginPayload).observe(lifecycleOwner, new Observer<Result<LoginResponse>>() {
|
||||
@Override
|
||||
public void onChanged(Result<LoginResponse> loginResponseResult) {
|
||||
switch (loginResponseResult.status){
|
||||
@@ -137,11 +144,18 @@ public class AuthNavigator {
|
||||
}
|
||||
|
||||
private void loginSuccess(LoginResponse loginResponse){
|
||||
String terminalId = prefsHelper.get("terminalId");
|
||||
if(terminalId == null){
|
||||
MessageDialog.showError(context, "Terminal non trouvé");
|
||||
return;
|
||||
}
|
||||
prefsHelper.save("id", String.valueOf(loginResponse.getUser().getId()));
|
||||
prefsHelper.save("firstName", loginResponse.getUser().getPrenom());
|
||||
prefsHelper.save("lastName", loginResponse.getUser().getNom());
|
||||
prefsHelper.save("profile", loginResponse.getUser().getFonction());
|
||||
prefsHelper.save("code", loginResponse.getUser().getCode());
|
||||
String isSupAgent = loginResponse.getUser().isSubAgent() ? "true" : "false";
|
||||
prefsHelper.save("isSupAgent", isSupAgent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.example.quiz.viewModel;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import com.example.quiz.data.model.Course;
|
||||
import com.example.quiz.data.model.Restriction;
|
||||
import com.example.quiz.data.model.dtos.auth.User;
|
||||
import com.example.quiz.data.repository.AgentRepository;
|
||||
import com.example.quiz.utils.Result;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||
|
||||
@HiltViewModel
|
||||
public class AgentViewModel extends ViewModel {
|
||||
private final AgentRepository agentRepository;
|
||||
|
||||
private LiveData<Result<List<User>>> agents;
|
||||
|
||||
private LiveData<Result<User>> agentDetails;
|
||||
|
||||
private LiveData<Result<List<Course.TypeParis>>> availableBets;
|
||||
|
||||
|
||||
@Inject
|
||||
public AgentViewModel(AgentRepository agentRepository) {
|
||||
this.agentRepository = agentRepository;
|
||||
}
|
||||
|
||||
public LiveData<Result<List<User>>> getAgents(String agentId) {
|
||||
agents = agentRepository.getAgents(agentId);
|
||||
return agents;
|
||||
}
|
||||
|
||||
public LiveData<Result<User>> getAgentById(String agentId) {
|
||||
agentDetails = agentRepository.getAgentById(agentId);
|
||||
return agentDetails;
|
||||
}
|
||||
|
||||
public LiveData<Result<List<Course.TypeParis>>> getAvailableBets(String agentId) {
|
||||
availableBets = agentRepository.getAvailableBets(agentId);
|
||||
return availableBets;
|
||||
}
|
||||
|
||||
public LiveData<Result<Void>> setAccess(String masterId, String slaveId, boolean access) {
|
||||
return agentRepository.setAccess(masterId, slaveId, access);
|
||||
};
|
||||
|
||||
public LiveData<Result<Void>> setRestrictions(String masterId, String slaveId, Restriction restrictions) {
|
||||
return agentRepository.setRestrictions(masterId, slaveId, restrictions);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.example.quiz.viewModel;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import com.example.quiz.data.model.dtos.auth.ChangePin;
|
||||
import com.example.quiz.data.model.dtos.auth.LoginPayload;
|
||||
import com.example.quiz.data.model.dtos.auth.LoginResponse;
|
||||
import com.example.quiz.data.model.dtos.auth.User;
|
||||
import com.example.quiz.data.repository.LoginRepository;
|
||||
import com.example.quiz.utils.Result;
|
||||
|
||||
@@ -16,6 +19,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||
public class LoginViewModel extends ViewModel {
|
||||
LoginRepository loginRepository;
|
||||
|
||||
LiveData<Result<User>> user = new MutableLiveData<>();
|
||||
@Inject
|
||||
public LoginViewModel(LoginRepository loginRepository) {
|
||||
this.loginRepository = loginRepository;
|
||||
@@ -24,4 +28,9 @@ public class LoginViewModel extends ViewModel {
|
||||
public LiveData<Result<LoginResponse>> login(LoginPayload loginPayload){
|
||||
return loginRepository.login(loginPayload);
|
||||
}
|
||||
|
||||
public LiveData<Result<User>> changePin(String oldPin, String newPin){
|
||||
user = loginRepository.changePin(oldPin, newPin);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package com.example.quiz.viewModel;
|
||||
|
||||
public class NotificationViewModel {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.example.quiz.viewModel;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.ViewModel;
|
||||
|
||||
import com.example.quiz.data.model.MiseInitiale;
|
||||
import com.example.quiz.data.model.PariMise;
|
||||
import com.example.quiz.data.repository.PariMiseRepository;
|
||||
import com.example.quiz.utils.Result;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel;
|
||||
|
||||
@HiltViewModel
|
||||
public class PariMiseViewModel extends ViewModel {
|
||||
|
||||
private final PariMiseRepository pariMiseRepository;
|
||||
|
||||
private LiveData<Result<List<MiseInitiale>>> pariMise;
|
||||
|
||||
@Inject
|
||||
public PariMiseViewModel(PariMiseRepository pariMiseRepository) {
|
||||
this.pariMiseRepository = pariMiseRepository;
|
||||
}
|
||||
|
||||
public LiveData<Result<List<MiseInitiale>>> getBetInitMise() {
|
||||
this.pariMise = pariMiseRepository.getBetInitMise();
|
||||
return this.pariMise;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import androidx.lifecycle.ViewModel;
|
||||
|
||||
import com.example.quiz.data.model.Pari;
|
||||
import com.example.quiz.data.model.ParisResponse;
|
||||
import com.example.quiz.data.model.dtos.paris.SoldeResponse;
|
||||
import com.example.quiz.data.repository.PariRepository;
|
||||
import com.example.quiz.utils.Result;
|
||||
|
||||
@@ -23,9 +24,9 @@ public class PariViewModel extends ViewModel {
|
||||
|
||||
private LiveData<Result<ParisResponse>> pariAnnule;
|
||||
|
||||
private LiveData<Result<Double>> solde;
|
||||
private LiveData<Result<SoldeResponse>> solde;
|
||||
|
||||
private LiveData<Result<Double>> soldeByDay;
|
||||
private LiveData<Result<SoldeResponse>> soldeByDay;
|
||||
|
||||
@Inject
|
||||
public PariViewModel(PariRepository repository){
|
||||
@@ -47,12 +48,12 @@ public class PariViewModel extends ViewModel {
|
||||
return pariAnnule;
|
||||
}
|
||||
|
||||
public LiveData<Result<Double>> getSoldeByCourse(String agentId, String courseId){
|
||||
public LiveData<Result<SoldeResponse>> getSoldeByCourse(String agentId, String courseId){
|
||||
solde = pariRepository.getSoldeByCourse(agentId, courseId);
|
||||
return solde;
|
||||
}
|
||||
|
||||
public LiveData<Result<Double>> getSoldeByDay(String agentId, String day){
|
||||
public LiveData<Result<SoldeResponse>> getSoldeByDay(String agentId, String day){
|
||||
soldeByDay = pariRepository.getSoldeByDay(agentId, day);
|
||||
return soldeByDay;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user