Fin intégration quinte plus
This commit is contained in:
875
src/main/java/com/pmumali/ch10_multi/service/ServiceMulti.java
Normal file
875
src/main/java/com/pmumali/ch10_multi/service/ServiceMulti.java
Normal file
@@ -0,0 +1,875 @@
|
||||
package com.pmumali.ch10_multi.service;
|
||||
|
||||
import com.pmumali.ch10_multi.model.*;
|
||||
import com.pmumali.ch10_multi.repository.*;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ServiceMulti {
|
||||
|
||||
private final PariMultiRepository pariRepository;
|
||||
private final CourseRepository courseRepository;
|
||||
private final ChevalRepository chevalRepository;
|
||||
private final PaiementMultiRepository paiementRepository;
|
||||
private final ResultatCourseRepository resultatRepository;
|
||||
private final CagnotteMultiRepository cagnotteRepository;
|
||||
private final ParieurRepository parieurRepository;
|
||||
|
||||
private static final Double MISE_BASE = 500.0;
|
||||
private static final Double MISE_MAX = 200 * MISE_BASE;
|
||||
private static final Integer NOMBRE_CHEVAUX_MINIMUM = 10;
|
||||
|
||||
// Coefficients pour le calcul des rapports (Article 5)
|
||||
private static final Map<TypeMulti, Integer> COEFFICIENTS = Map.of(
|
||||
TypeMulti.MULTI_4, 105,
|
||||
TypeMulti.MULTI_5, 21,
|
||||
TypeMulti.MULTI_6, 7,
|
||||
TypeMulti.MULTI_7, 3
|
||||
);
|
||||
|
||||
// Rapports minimum (Article 6)
|
||||
private static final Map<TypeMulti, Double> RAPPORTS_MINIMUM = Map.of(
|
||||
TypeMulti.MULTI_4, 1.6,
|
||||
TypeMulti.MULTI_5, 1.4,
|
||||
TypeMulti.MULTI_6, 1.2,
|
||||
TypeMulti.MULTI_7, 1.1
|
||||
);
|
||||
|
||||
@Transactional
|
||||
public PariMulti placerPari(RequetePariMulti requete) {
|
||||
// Validation de la mise
|
||||
if (requete.getMise() < MISE_BASE) {
|
||||
throw new IllegalArgumentException("La mise doit être au moins " + MISE_BASE + " FCFA");
|
||||
}
|
||||
|
||||
Course course = courseRepository.findById(requete.getCourseId())
|
||||
.orElseThrow(() -> new RuntimeException("Course non trouvée"));
|
||||
|
||||
// Vérification du nombre minimum de chevaux
|
||||
if (course.getNombreChevauxPartants() < NOMBRE_CHEVAUX_MINIMUM) {
|
||||
throw new IllegalArgumentException("La course doit avoir au moins " + NOMBRE_CHEVAUX_MINIMUM + " chevaux partants");
|
||||
}
|
||||
|
||||
List<Cheval> chevaux = chevalRepository.findAllById(requete.getChevalIds());
|
||||
|
||||
// Validation du nombre de chevaux selon le type MULTI
|
||||
validerNombreChevaux(requete.getTypeMulti(), chevaux.size());
|
||||
|
||||
// Vérification des non-partants
|
||||
long nonPartants = chevaux.stream().filter(Cheval::getNonPartant).count();
|
||||
validerNonPartants(requete.getTypeMulti(), nonPartants);
|
||||
|
||||
// Limitation de mise selon l'article 2
|
||||
Double miseEffective = Math.min(requete.getMise(), MISE_MAX);
|
||||
|
||||
Parieur parieur = parieurRepository.findById(requete.getParieurId())
|
||||
.orElseThrow(() -> new RuntimeException("Parieur non trouvé"));
|
||||
|
||||
PariMulti pari = PariMulti.builder()
|
||||
.course(course)
|
||||
.chevauxSelectionnes(chevaux)
|
||||
.mise(miseEffective)
|
||||
.heurePari(LocalDateTime.now())
|
||||
.typeMulti(requete.getTypeMulti())
|
||||
.typeFormule(requete.getTypeFormule())
|
||||
.parieur(parieur)
|
||||
.nombreChevauxBase(requete.getNombreChevauxBase())
|
||||
.build();
|
||||
|
||||
return pariRepository.save(pari);
|
||||
}
|
||||
|
||||
private void validerNombreChevaux(TypeMulti typeMulti, int nombreChevaux) {
|
||||
switch (typeMulti) {
|
||||
case MULTI_4:
|
||||
if (nombreChevaux != 4) throw new IllegalArgumentException("MULTI en 4 nécessite exactement 4 chevaux");
|
||||
break;
|
||||
case MULTI_5:
|
||||
if (nombreChevaux != 5) throw new IllegalArgumentException("MULTI en 5 nécessite exactement 5 chevaux");
|
||||
break;
|
||||
case MULTI_6:
|
||||
if (nombreChevaux != 6) throw new IllegalArgumentException("MULTI en 6 nécessite exactement 6 chevaux");
|
||||
break;
|
||||
case MULTI_7:
|
||||
if (nombreChevaux != 7) throw new IllegalArgumentException("MULTI en 7 nécessite exactement 7 chevaux");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void validerNonPartants(TypeMulti typeMulti, long nonPartants) {
|
||||
switch (typeMulti) {
|
||||
case MULTI_4:
|
||||
if (nonPartants >= 1) throw new IllegalArgumentException("MULTI en 4 ne permet pas de chevaux non-partants");
|
||||
break;
|
||||
case MULTI_5:
|
||||
if (nonPartants >= 2) throw new IllegalArgumentException("MULTI en 5 permet maximum 1 cheval non-partant");
|
||||
break;
|
||||
case MULTI_6:
|
||||
if (nonPartants >= 3) throw new IllegalArgumentException("MULTI en 6 permet maximum 2 chevaux non-partants");
|
||||
break;
|
||||
case MULTI_7:
|
||||
if (nonPartants >= 4) throw new IllegalArgumentException("MULTI en 7 permet maximum 3 chevaux non-partants");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<ReponsePaiementMulti> calculerPaiements(RequeteResultatMulti requete) {
|
||||
ResultatCourse resultat = creerResultat(requete);
|
||||
List<PariMulti> paris = pariRepository.findByCourseId(requete.getCourseId());
|
||||
List<ReponsePaiementMulti> paiements = new ArrayList<>();
|
||||
|
||||
// Vérifier si la course a moins de 10 chevaux (Article 1)
|
||||
if (resultat.getCourse().getNombreChevauxPartants() < NOMBRE_CHEVAUX_MINIMUM) {
|
||||
transfererEnCagnotte(resultat);
|
||||
return paiements;
|
||||
}
|
||||
|
||||
// Calcul de la masse à partager selon l'article 5
|
||||
Double masseAPartager = calculerMasseAPartager(resultat);
|
||||
resultat.setMasseAPartager(masseAPartager);
|
||||
resultatRepository.save(resultat);
|
||||
|
||||
// Gérer les cas de dead-heat si nécessaire
|
||||
TypeDeadHeat typeDeadHeat = detecterDeadHeat(resultat);
|
||||
if (typeDeadHeat != null) {
|
||||
return gererDeadHeat(resultat, typeDeadHeat);
|
||||
}
|
||||
|
||||
// Calcul normal des paiements
|
||||
Map<TypeMulti, List<PariMulti>> parisGagnantsParType = new HashMap<>();
|
||||
Map<TypeMulti, Integer> nombreParisGagnantsParType = new HashMap<>();
|
||||
|
||||
for (PariMulti pari : paris) {
|
||||
ReponsePaiementMulti paiement = calculerPaiementPari(pari, resultat, masseAPartager);
|
||||
if (paiement != null) {
|
||||
paiements.add(paiement);
|
||||
enregistrerPaiement(pari, paiement);
|
||||
|
||||
// Compter les paris gagnants par type
|
||||
TypeMulti typePari = getTypeMultiFromPaiement(paiement.getTypePaiement());
|
||||
parisGagnantsParType.computeIfAbsent(typePari, k -> new ArrayList<>()).add(pari);
|
||||
nombreParisGagnantsParType.put(typePari,
|
||||
nombreParisGagnantsParType.getOrDefault(typePari, 0) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Appliquer les règles de rapport minimum (Article 6)
|
||||
appliquerReglesRapportMinimum(paiements, masseAPartager, nombreParisGagnantsParType);
|
||||
|
||||
return paiements;
|
||||
}
|
||||
|
||||
private ReponsePaiementMulti calculerPaiementPari(PariMulti pari, ResultatCourse resultat, Double masseAPartager) {
|
||||
List<Cheval> chevauxPari = pari.getChevauxSelectionnes();
|
||||
long nonPartants = chevauxPari.stream().filter(Cheval::getNonPartant).count();
|
||||
|
||||
// Article 4: Gestion des non-partants et transformations
|
||||
if (doitEtreRembourse(pari.getTypeMulti(), nonPartants)) {
|
||||
return new ReponsePaiementMulti(pari.getId(), pari.getMise(),
|
||||
TypePaiementMulti.REMBOURSEMENT, "Remboursement selon article 4");
|
||||
}
|
||||
|
||||
// Transformer les paris avec non-partants (Article 4)
|
||||
TypeMulti typeTransforme = transformerPari(pari.getTypeMulti(), nonPartants);
|
||||
List<Cheval> chevauxParticipants = chevauxPari.stream()
|
||||
.filter(cheval -> !cheval.getNonPartant())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Vérifier si les chevaux sont dans les 4 premiers
|
||||
boolean estGagnant = estCombinaisonGagnante(chevauxParticipants, resultat);
|
||||
|
||||
if (estGagnant) {
|
||||
Double montant = calculerMontantPari(typeTransforme, masseAPartager);
|
||||
TypePaiementMulti typePaiement = getTypePaiementFromTypeMulti(typeTransforme);
|
||||
return new ReponsePaiementMulti(pari.getId(), montant, typePaiement,
|
||||
"Paiement MULTI " + typeTransforme + " transformé");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean doitEtreRembourse(TypeMulti typeMulti, long nonPartants) {
|
||||
switch (typeMulti) {
|
||||
case MULTI_4: return nonPartants >= 1;
|
||||
case MULTI_5: return nonPartants >= 2;
|
||||
case MULTI_6: return nonPartants >= 3;
|
||||
case MULTI_7: return nonPartants >= 4;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
private TypeMulti transformerPari(TypeMulti typeOriginal, long nonPartants) {
|
||||
// Article 4: Transformations des paris avec non-partants
|
||||
if (nonPartants == 0) return typeOriginal;
|
||||
|
||||
switch (typeOriginal) {
|
||||
case MULTI_5:
|
||||
return nonPartants == 1 ? TypeMulti.MULTI_4 : typeOriginal;
|
||||
case MULTI_6:
|
||||
if (nonPartants == 1) return TypeMulti.MULTI_5;
|
||||
if (nonPartants == 2) return TypeMulti.MULTI_4;
|
||||
return typeOriginal;
|
||||
case MULTI_7:
|
||||
if (nonPartants == 1) return TypeMulti.MULTI_6;
|
||||
if (nonPartants == 2) return TypeMulti.MULTI_5;
|
||||
if (nonPartants == 3) return TypeMulti.MULTI_4;
|
||||
return typeOriginal;
|
||||
default:
|
||||
return typeOriginal;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean estCombinaisonGagnante(List<Cheval> chevauxPari, ResultatCourse resultat) {
|
||||
// Vérifier si au moins 4 chevaux sont dans les 4 premiers
|
||||
long countDansTop4 = chevauxPari.stream()
|
||||
.filter(cheval -> estDansTop4(cheval, resultat))
|
||||
.count();
|
||||
return countDansTop4 >= 4;
|
||||
}
|
||||
|
||||
private boolean estDansTop4(Cheval cheval, ResultatCourse resultat) {
|
||||
return estDansListe(cheval, resultat.getPremiers()) ||
|
||||
estDansListe(cheval, resultat.getSeconds()) ||
|
||||
estDansListe(cheval, resultat.getTroisiemes()) ||
|
||||
estDansListe(cheval, resultat.getQuatriemes());
|
||||
}
|
||||
|
||||
private boolean estDansListe(Cheval cheval, List<Cheval> liste) {
|
||||
return liste != null && liste.contains(cheval);
|
||||
}
|
||||
|
||||
private Double calculerMontantPari(TypeMulti typeMulti, Double masseAPartager) {
|
||||
// Article 5: Calcul basé sur les coefficients
|
||||
int coefficient = COEFFICIENTS.get(typeMulti);
|
||||
|
||||
// Calcul simplifié - en réalité, il faudrait compter le nombre de paris gagnants
|
||||
return (masseAPartager * 0.25) / coefficient; // 25% de la masse pour chaque type
|
||||
}
|
||||
|
||||
private TypePaiementMulti getTypePaiementFromTypeMulti(TypeMulti typeMulti) {
|
||||
switch (typeMulti) {
|
||||
case MULTI_4: return TypePaiementMulti.MULTI_4;
|
||||
case MULTI_5: return TypePaiementMulti.MULTI_5;
|
||||
case MULTI_6: return TypePaiementMulti.MULTI_6;
|
||||
case MULTI_7: return TypePaiementMulti.MULTI_7;
|
||||
default: return TypePaiementMulti.REMBOURSEMENT;
|
||||
}
|
||||
}
|
||||
|
||||
private TypeMulti getTypeMultiFromPaiement(TypePaiementMulti typePaiement) {
|
||||
switch (typePaiement) {
|
||||
case MULTI_4: return TypeMulti.MULTI_4;
|
||||
case MULTI_5: return TypeMulti.MULTI_5;
|
||||
case MULTI_6: return TypeMulti.MULTI_6;
|
||||
case MULTI_7: return TypeMulti.MULTI_7;
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void appliquerReglesRapportMinimum(List<ReponsePaiementMulti> paiements, Double masseAPartager,
|
||||
Map<TypeMulti, Integer> nombreParisGagnantsParType) {
|
||||
// Article 6: Application des règles de rapport minimum
|
||||
|
||||
// Étape 1: Vérifier MULTI_7
|
||||
Double rapportMulti7 = calculerRapportMoyen(paiements, TypeMulti.MULTI_7);
|
||||
if (rapportMulti7 < RAPPORTS_MINIMUM.get(TypeMulti.MULTI_7)) {
|
||||
ajusterRapportsMulti7(paiements, masseAPartager, nombreParisGagnantsParType);
|
||||
// Recalculer après ajustement
|
||||
rapportMulti7 = RAPPORTS_MINIMUM.get(TypeMulti.MULTI_7);
|
||||
}
|
||||
|
||||
// Étape 2: Vérifier MULTI_6
|
||||
Double rapportMulti6 = calculerRapportMoyen(paiements, TypeMulti.MULTI_6);
|
||||
if (rapportMulti6 < RAPPORTS_MINIMUM.get(TypeMulti.MULTI_6)) {
|
||||
ajusterRapportsMulti6(paiements, masseAPartager, nombreParisGagnantsParType);
|
||||
rapportMulti6 = RAPPORTS_MINIMUM.get(TypeMulti.MULTI_6);
|
||||
}
|
||||
|
||||
// Étape 3: Vérifier MULTI_5
|
||||
Double rapportMulti5 = calculerRapportMoyen(paiements, TypeMulti.MULTI_5);
|
||||
if (rapportMulti5 < RAPPORTS_MINIMUM.get(TypeMulti.MULTI_5)) {
|
||||
ajusterRapportsMulti5(paiements, masseAPartager, nombreParisGagnantsParType);
|
||||
rapportMulti5 = RAPPORTS_MINIMUM.get(TypeMulti.MULTI_5);
|
||||
}
|
||||
|
||||
// Étape 4: Vérifier MULTI_4
|
||||
Double rapportMulti4 = calculerRapportMoyen(paiements, TypeMulti.MULTI_4);
|
||||
if (rapportMulti4 < RAPPORTS_MINIMUM.get(TypeMulti.MULTI_4)) {
|
||||
ajusterRapportsMulti4(paiements, masseAPartager, nombreParisGagnantsParType);
|
||||
}
|
||||
}
|
||||
|
||||
private Double calculerRapportMoyen(List<ReponsePaiementMulti> paiements, TypeMulti typeMulti) {
|
||||
TypePaiementMulti typePaiement = getTypePaiementFromTypeMulti(typeMulti);
|
||||
List<ReponsePaiementMulti> paiementsType = paiements.stream()
|
||||
.filter(p -> p.getTypePaiement() == typePaiement)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (paiementsType.isEmpty()) {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
return paiementsType.stream()
|
||||
.mapToDouble(ReponsePaiementMulti::getMontant)
|
||||
.average()
|
||||
.orElse(0.0);
|
||||
}
|
||||
|
||||
private void ajusterRapportsMulti7(List<ReponsePaiementMulti> paiements, Double masseAPartager,
|
||||
Map<TypeMulti, Integer> nombreParisGagnantsParType) {
|
||||
// Article 6.1: Ajustement MULTI_7
|
||||
TypePaiementMulti typePaiement = getTypePaiementFromTypeMulti(TypeMulti.MULTI_7);
|
||||
int nombreGagnants = nombreParisGagnantsParType.getOrDefault(TypeMulti.MULTI_7, 0);
|
||||
|
||||
if (nombreGagnants > 0) {
|
||||
Double montantTotal = RAPPORTS_MINIMUM.get(TypeMulti.MULTI_7) * nombreGagnants;
|
||||
|
||||
// Ajuster les montants
|
||||
for (ReponsePaiementMulti paiement : paiements) {
|
||||
if (paiement.getTypePaiement() == typePaiement) {
|
||||
paiement.setMontant(RAPPORTS_MINIMUM.get(TypeMulti.MULTI_7));
|
||||
}
|
||||
}
|
||||
|
||||
// Réduire la masse à partager
|
||||
masseAPartager -= montantTotal;
|
||||
}
|
||||
}
|
||||
|
||||
private void ajusterRapportsMulti6(List<ReponsePaiementMulti> paiements, Double masseAPartager,
|
||||
Map<TypeMulti, Integer> nombreParisGagnantsParType) {
|
||||
// Article 6.2: Ajustement MULTI_6
|
||||
TypePaiementMulti typePaiement = getTypePaiementFromTypeMulti(TypeMulti.MULTI_6);
|
||||
int nombreGagnants = nombreParisGagnantsParType.getOrDefault(TypeMulti.MULTI_6, 0);
|
||||
|
||||
if (nombreGagnants > 0) {
|
||||
// Calculer le rapport de base
|
||||
Double rapportBase = masseAPartager / (nombreGagnants * 1 +
|
||||
nombreParisGagnantsParType.getOrDefault(TypeMulti.MULTI_5, 0) * 3 +
|
||||
nombreParisGagnantsParType.getOrDefault(TypeMulti.MULTI_4, 0) * 15);
|
||||
|
||||
// Ajuster les montants
|
||||
for (ReponsePaiementMulti paiement : paiements) {
|
||||
TypeMulti typeMulti = getTypeMultiFromPaiement(paiement.getTypePaiement());
|
||||
if (typeMulti == TypeMulti.MULTI_6) {
|
||||
paiement.setMontant(rapportBase);
|
||||
} else if (typeMulti == TypeMulti.MULTI_5) {
|
||||
paiement.setMontant(rapportBase * 3);
|
||||
} else if (typeMulti == TypeMulti.MULTI_4) {
|
||||
paiement.setMontant(rapportBase * 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ajusterRapportsMulti5(List<ReponsePaiementMulti> paiements, Double masseAPartager,
|
||||
Map<TypeMulti, Integer> nombreParisGagnantsParType) {
|
||||
// Article 6.3: Ajustement MULTI_5
|
||||
TypePaiementMulti typePaiement = getTypePaiementFromTypeMulti(TypeMulti.MULTI_5);
|
||||
int nombreGagnants = nombreParisGagnantsParType.getOrDefault(TypeMulti.MULTI_5, 0);
|
||||
|
||||
if (nombreGagnants > 0) {
|
||||
// Calculer le rapport de base
|
||||
Double rapportBase = masseAPartager / (nombreGagnants * 1 +
|
||||
nombreParisGagnantsParType.getOrDefault(TypeMulti.MULTI_4, 0) * 5);
|
||||
|
||||
// Ajuster les montants
|
||||
for (ReponsePaiementMulti paiement : paiements) {
|
||||
TypeMulti typeMulti = getTypeMultiFromPaiement(paiement.getTypePaiement());
|
||||
if (typeMulti == TypeMulti.MULTI_5) {
|
||||
paiement.setMontant(rapportBase);
|
||||
} else if (typeMulti == TypeMulti.MULTI_4) {
|
||||
paiement.setMontant(rapportBase * 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ajusterRapportsMulti4(List<ReponsePaiementMulti> paiements, Double masseAPartager,
|
||||
Map<TypeMulti, Integer> nombreParisGagnantsParType) {
|
||||
// Article 6.4: Ajustement MULTI_4
|
||||
TypePaiementMulti typePaiement = getTypePaiementFromTypeMulti(TypeMulti.MULTI_4);
|
||||
int nombreGagnants = nombreParisGagnantsParType.getOrDefault(TypeMulti.MULTI_4, 0);
|
||||
|
||||
if (nombreGagnants > 0) {
|
||||
// Calculer le rapport de base
|
||||
Double rapportBase = masseAPartager / nombreGagnants;
|
||||
|
||||
// Forcer le rapport minimum si nécessaire
|
||||
if (rapportBase < RAPPORTS_MINIMUM.get(TypeMulti.MULTI_4)) {
|
||||
rapportBase = RAPPORTS_MINIMUM.get(TypeMulti.MULTI_4);
|
||||
}
|
||||
|
||||
// Ajuster les montants
|
||||
for (ReponsePaiementMulti paiement : paiements) {
|
||||
if (paiement.getTypePaiement() == typePaiement) {
|
||||
paiement.setMontant(rapportBase);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Méthodes pour le calcul des combinaisons (Article 7)
|
||||
public CalculCombinaisonMulti calculerCombinaison(TypeMulti typeMulti, TypeFormuleMulti typeFormule,
|
||||
Integer nombreChevauxTotal, Integer nombreChevauxBase) {
|
||||
Integer nombreCombinaisons = calculerNombreCombinaisons(typeMulti, typeFormule, nombreChevauxTotal, nombreChevauxBase);
|
||||
Double valeurMise = nombreCombinaisons * MISE_BASE;
|
||||
|
||||
return CalculCombinaisonMulti.builder()
|
||||
.typeMulti(typeMulti)
|
||||
.typeFormule(typeFormule)
|
||||
.nombreChevauxTotal(nombreChevauxTotal)
|
||||
.nombreChevauxBase(nombreChevauxBase)
|
||||
.nombreCombinaisons(nombreCombinaisons)
|
||||
.valeurMise(valeurMise)
|
||||
.build();
|
||||
}
|
||||
|
||||
private Integer calculerNombreCombinaisons(TypeMulti typeMulti, TypeFormuleMulti typeFormule,
|
||||
Integer n, Integer p) {
|
||||
if (typeFormule == TypeFormuleMulti.UNITAIRE) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Implémentation des formules de combinaison selon l'article 7
|
||||
switch (typeMulti) {
|
||||
case MULTI_4:
|
||||
return calculerCombinaisonsMulti4(typeFormule, n, p);
|
||||
case MULTI_5:
|
||||
return calculerCombinaisonsMulti5(typeFormule, n, p);
|
||||
case MULTI_6:
|
||||
return calculerCombinaisonsMulti6(typeFormule, n, p);
|
||||
case MULTI_7:
|
||||
return calculerCombinaisonsMulti7(typeFormule, n, p);
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private Integer calculerCombinaisonsMulti4(TypeFormuleMulti typeFormule, Integer n, Integer p) {
|
||||
if (typeFormule == TypeFormuleMulti.CHAMP_TOTAL) {
|
||||
if (p == 3) return n - 3;
|
||||
if (p == 2) return (n - 2) * (n - 3) / 2;
|
||||
if (p == 1) return (n - 1) * (n - 2) * (n - 3) / 6;
|
||||
} else {
|
||||
if (p == 3) return p;
|
||||
if (p == 2) return p * (p - 1) / 2;
|
||||
if (p == 1) return p * (p - 1) * (p - 2) / 6;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private Integer calculerCombinaisonsMulti5(TypeFormuleMulti typeFormule, Integer n, Integer p) {
|
||||
if (typeFormule == TypeFormuleMulti.CHAMP_TOTAL) {
|
||||
if (p == 4) return n - 4;
|
||||
if (p == 3) return (n - 3) * (n - 4) / 2;
|
||||
if (p == 2) return (n - 2) * (n - 3) * (n - 4) / 6;
|
||||
if (p == 1) return (n - 1) * (n - 2) * (n - 3) * (n - 4) / 24;
|
||||
} else {
|
||||
if (p == 4) return p;
|
||||
if (p == 3) return p * (p - 1) / 2;
|
||||
if (p == 2) return p * (p - 1) * (p - 2) / 6;
|
||||
if (p == 1) return p * (p - 1) * (p - 2) * (p - 3) / 24;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private Integer calculerCombinaisonsMulti6(TypeFormuleMulti typeFormule, Integer n, Integer p) {
|
||||
if (typeFormule == TypeFormuleMulti.CHAMP_TOTAL) {
|
||||
if (p == 5) return n - 5;
|
||||
if (p == 4) return (n - 4) * (n - 5) / 2;
|
||||
if (p == 3) return (n - 3) * (n - 4) * (n - 5) / 6;
|
||||
if (p == 2) return (n - 2) * (n - 3) * (n - 4) * (n - 5) / 24;
|
||||
if (p == 1) return (n - 1) * (n - 2) * (n - 3) * (n - 4) * (n - 5) / 120;
|
||||
} else {
|
||||
if (p == 5) return p;
|
||||
if (p == 4) return p * (p - 1) / 2;
|
||||
if (p == 3) return p * (p - 1) * (p - 2) / 6;
|
||||
if (p == 2) return p * (p - 1) * (p - 2) * (p - 3) / 24;
|
||||
if (p == 1) return p * (p - 1) * (p - 2) * (p - 3) * (p - 4) / 120;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private Integer calculerCombinaisonsMulti7(TypeFormuleMulti typeFormule, Integer n, Integer p) {
|
||||
if (typeFormule == TypeFormuleMulti.CHAMP_TOTAL) {
|
||||
if (p == 6) return n - 6;
|
||||
if (p == 5) return (n - 5) * (n - 6) / 2;
|
||||
if (p == 4) return (n - 4) * (n - 5) * (n - 6) / 6;
|
||||
if (p == 3) return (n - 3) * (n - 4) * (n - 5) * (n - 6) / 24;
|
||||
if (p == 2) return (n - 2) * (n - 3) * (n - 4) * (n - 5) * (n - 6) / 120;
|
||||
if (p == 1) return (n - 1) * (n - 2) * (n - 3) * (n - 4) * (n - 5) * (n - 6) / 720;
|
||||
} else {
|
||||
if (p == 6) return p;
|
||||
if (p == 5) return p * (p - 1) / 2;
|
||||
if (p == 4) return p * (p - 1) * (p - 2) / 6;
|
||||
if (p == 3) return p * (p - 1) * (p - 2) * (p - 3) / 24;
|
||||
if (p == 2) return p * (p - 1) * (p - 2) * (p - 3) * (p - 4) / 120;
|
||||
if (p == 1) return p * (p - 1) * (p - 2) * (p - 3) * (p - 4) * (p - 5) / 720;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Gestion des dead-heat (Article 3)
|
||||
private TypeDeadHeat detecterDeadHeat(ResultatCourse resultat) {
|
||||
if (resultat.getPremiers().size() >= 4) return TypeDeadHeat.QUATRE_PREMIERS_OU_PLUS;
|
||||
if (resultat.getPremiers().size() >= 3 && resultat.getQuatriemes().size() >= 1)
|
||||
return TypeDeadHeat.TROIS_PREMIERS_UN_QUATRIEME;
|
||||
if (resultat.getPremiers().size() >= 2 && resultat.getTroisiemes().size() >= 2)
|
||||
return TypeDeadHeat.DEUX_PREMIERS_DEUX_TROISIEMES;
|
||||
if (resultat.getPremiers().size() >= 2 && resultat.getTroisiemes().size() == 1 && resultat.getQuatriemes().size() >= 1)
|
||||
return TypeDeadHeat.DEUX_PREMIERS_UN_TROISIEME_UN_QUATRIEME;
|
||||
if (resultat.getSeconds().size() >= 3)
|
||||
return TypeDeadHeat.TROIS_SECONDS_OU_PLUS;
|
||||
if (resultat.getSeconds().size() >= 2 && resultat.getQuatriemes().size() >= 1)
|
||||
return TypeDeadHeat.DEUX_SECONDS_UN_QUATRIEME;
|
||||
if (resultat.getTroisiemes().size() >= 2)
|
||||
return TypeDeadHeat.DEUX_TROISIEMES_OU_PLUS;
|
||||
if (resultat.getQuatriemes().size() >= 2)
|
||||
return TypeDeadHeat.DEUX_QUATRIEMES_OU_PLUS;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<ReponsePaiementMulti> gererDeadHeat(ResultatCourse resultat, TypeDeadHeat typeDeadHeat) {
|
||||
List<PariMulti> paris = pariRepository.findByCourseId(resultat.getCourse().getId());
|
||||
List<ReponsePaiementMulti> paiements = new ArrayList<>();
|
||||
Double masseAPartager = resultat.getMasseAPartager();
|
||||
|
||||
for (PariMulti pari : paris) {
|
||||
ReponsePaiementMulti paiement = calculerPaiementDeadHeat(pari, resultat, masseAPartager, typeDeadHeat);
|
||||
if (paiement != null) {
|
||||
paiements.add(paiement);
|
||||
enregistrerPaiement(pari, paiement);
|
||||
}
|
||||
}
|
||||
|
||||
return paiements;
|
||||
}
|
||||
|
||||
private ReponsePaiementMulti calculerPaiementDeadHeat(PariMulti pari, ResultatCourse resultat,
|
||||
Double masseAPartager, TypeDeadHeat typeDeadHeat) {
|
||||
// Implémentation spécifique pour chaque type de dead-heat
|
||||
switch (typeDeadHeat) {
|
||||
case QUATRE_PREMIERS_OU_PLUS:
|
||||
return gererDeadHeatQuatrePremiers(pari, resultat, masseAPartager);
|
||||
case TROIS_PREMIERS_UN_QUATRIEME:
|
||||
return gererDeadHeatTroisPremiersUnQuatrieme(pari, resultat, masseAPartager);
|
||||
case DEUX_PREMIERS_DEUX_TROISIEMES:
|
||||
return gererDeadHeatDeuxPremiersDeuxTroisiemes(pari, resultat, masseAPartager);
|
||||
case DEUX_PREMIERS_UN_TROISIEME_UN_QUATRIEME:
|
||||
return gererDeadHeatDeuxPremiersUnTroisiemeUnQuatrieme(pari, resultat, masseAPartager);
|
||||
case TROIS_SECONDS_OU_PLUS:
|
||||
return gererDeadHeatTroisSeconds(pari, resultat, masseAPartager);
|
||||
case DEUX_SECONDS_UN_QUATRIEME:
|
||||
return gererDeadHeatDeuxSecondsUnQuatrieme(pari, resultat, masseAPartager);
|
||||
case DEUX_TROISIEMES_OU_PLUS:
|
||||
return gererDeadHeatDeuxTroisiemes(pari, resultat, masseAPartager);
|
||||
case DEUX_QUATRIEMES_OU_PLUS:
|
||||
return gererDeadHeatDeuxQuatriemes(pari, resultat, masseAPartager);
|
||||
default:
|
||||
return calculerPaiementPari(pari, resultat, masseAPartager);
|
||||
}
|
||||
}
|
||||
|
||||
private ReponsePaiementMulti gererDeadHeatQuatrePremiers(PariMulti pari, ResultatCourse resultat, Double masseAPartager) {
|
||||
// Article 3a: Dead-heat de 4+ chevaux premiers
|
||||
List<Cheval> chevauxPari = pari.getChevauxSelectionnes();
|
||||
|
||||
// Vérifier si tous les chevaux du pari sont parmi les premiers
|
||||
if (chevauxPari.stream().allMatch(cheval -> estDansListe(cheval, resultat.getPremiers()))) {
|
||||
int nombreCombinaisons = calculerNombreCombinaisonsDeadHeat(resultat.getPremiers().size(), 4);
|
||||
Double montant = masseAPartager / nombreCombinaisons;
|
||||
return new ReponsePaiementMulti(pari.getId(), montant,
|
||||
TypePaiementMulti.MULTI_4, "Dead-Heat 4+ premiers");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private ReponsePaiementMulti gererDeadHeatTroisPremiersUnQuatrieme(PariMulti pari, ResultatCourse resultat, Double masseAPartager) {
|
||||
// Article 3b: Dead-heat de 3 premiers + 1+ quatrième
|
||||
List<Cheval> chevauxPari = pari.getChevauxSelectionnes();
|
||||
|
||||
boolean troisPremiersOk = chevauxPari.subList(0, 3).stream()
|
||||
.allMatch(cheval -> estDansListe(cheval, resultat.getPremiers()));
|
||||
boolean quatriemeOk = estDansListe(chevauxPari.get(3), resultat.getQuatriemes());
|
||||
|
||||
if (troisPremiersOk && quatriemeOk) {
|
||||
int nombreCombinaisons = resultat.getPremiers().size() * resultat.getQuatriemes().size();
|
||||
Double montant = (masseAPartager * 0.4) / (nombreCombinaisons * 6); // 40% pour l'ordre exact, 6 permutations
|
||||
return new ReponsePaiementMulti(pari.getId(), montant,
|
||||
TypePaiementMulti.MULTI_4, "Dead-Heat 3 premiers + 1 quatrième");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Implémentations similaires pour les autres types de dead-heat...
|
||||
private ReponsePaiementMulti gererDeadHeatDeuxPremiersDeuxTroisiemes(PariMulti pari, ResultatCourse resultat, Double masseAPartager) {
|
||||
// Article 3c: Implémentation spécifique
|
||||
return calculerPaiementGeneriqueDeadHeat(pari, resultat, masseAPartager, 2.0);
|
||||
}
|
||||
|
||||
private ReponsePaiementMulti gererDeadHeatDeuxPremiersUnTroisiemeUnQuatrieme(PariMulti pari, ResultatCourse resultat, Double masseAPartager) {
|
||||
// Article 3d: Implémentation spécifique
|
||||
return calculerPaiementGeneriqueDeadHeat(pari, resultat, masseAPartager, 4.0);
|
||||
}
|
||||
|
||||
private ReponsePaiementMulti gererDeadHeatTroisSeconds(PariMulti pari, ResultatCourse resultat, Double masseAPartager) {
|
||||
// Article 3e: Implémentation spécifique
|
||||
return calculerPaiementGeneriqueDeadHeat(pari, resultat, masseAPartager, 2.0);
|
||||
}
|
||||
|
||||
private ReponsePaiementMulti gererDeadHeatDeuxSecondsUnQuatrieme(PariMulti pari, ResultatCourse resultat, Double masseAPartager) {
|
||||
// Article 3f: Implémentation spécifique
|
||||
return calculerPaiementGeneriqueDeadHeat(pari, resultat, masseAPartager, 4.0);
|
||||
}
|
||||
|
||||
private ReponsePaiementMulti gererDeadHeatDeuxTroisiemes(PariMulti pari, ResultatCourse resultat, Double masseAPartager) {
|
||||
// Article 3g: Implémentation spécifique
|
||||
return calculerPaiementGeneriqueDeadHeat(pari, resultat, masseAPartager, 4.0);
|
||||
}
|
||||
|
||||
private ReponsePaiementMulti gererDeadHeatDeuxQuatriemes(PariMulti pari, ResultatCourse resultat, Double masseAPartager) {
|
||||
// Article 3h: Implémentation spécifique
|
||||
return calculerPaiementGeneriqueDeadHeat(pari, resultat, masseAPartager, 4.0);
|
||||
}
|
||||
|
||||
private ReponsePaiementMulti calculerPaiementGeneriqueDeadHeat(PariMulti pari, ResultatCourse resultat,
|
||||
Double masseAPartager, Double coefficient) {
|
||||
// Méthode générique pour les dead-heat avec coefficient spécifique
|
||||
List<Cheval> chevauxPari = pari.getChevauxSelectionnes();
|
||||
|
||||
if (chevauxPari.stream().allMatch(cheval ->
|
||||
estDansListe(cheval, resultat.getPremiers()) ||
|
||||
estDansListe(cheval, resultat.getSeconds()) ||
|
||||
estDansListe(cheval, resultat.getTroisiemes()) ||
|
||||
estDansListe(cheval, resultat.getQuatriemes()))) {
|
||||
|
||||
int nombreCombinaisons = compterCombinaisonsGagnantesDeadHeat(resultat);
|
||||
Double montant = (masseAPartager * 0.4) / (nombreCombinaisons * coefficient);
|
||||
return new ReponsePaiementMulti(pari.getId(), montant,
|
||||
TypePaiementMulti.MULTI_4, "Dead-Heat générique");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int calculerNombreCombinaisonsDeadHeat(int nombreChevaux, int prise) {
|
||||
// Calcul des combinaisons C(n, k)
|
||||
if (prise == 0) return 1;
|
||||
if (nombreChevaux < prise) return 0;
|
||||
|
||||
int resultat = 1;
|
||||
for (int i = 1; i <= prise; i++) {
|
||||
resultat = resultat * (nombreChevaux - i + 1) / i;
|
||||
}
|
||||
return resultat;
|
||||
}
|
||||
|
||||
private int compterCombinaisonsGagnantesDeadHeat(ResultatCourse resultat) {
|
||||
// Comptage simplifié des combinaisons gagnantes
|
||||
// Implémentation réelle dépendrait de la structure exacte du dead-heat
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Gestion de la cagnotte (Articles 9 et 10)
|
||||
private void transfererEnCagnotte(ResultatCourse resultat) {
|
||||
CagnotteMulti cagnotte = CagnotteMulti.builder()
|
||||
.montant(resultat.getMasseAPartager())
|
||||
.dateCreation(LocalDateTime.now())
|
||||
.utilisee(false)
|
||||
.courseSourceId(resultat.getCourse().getId())
|
||||
.build();
|
||||
cagnotteRepository.save(cagnotte);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public void utiliserCagnotte(Long cagnotteId, Long courseId) {
|
||||
CagnotteMulti cagnotte = cagnotteRepository.findById(cagnotteId)
|
||||
.orElseThrow(() -> new RuntimeException("Cagnotte non trouvée"));
|
||||
|
||||
if (cagnotte.getUtilisee()) {
|
||||
throw new RuntimeException("Cagnotte déjà utilisée");
|
||||
}
|
||||
|
||||
cagnotte.setUtilisee(true);
|
||||
cagnotte.setDateUtilisation(LocalDateTime.now());
|
||||
cagnotteRepository.save(cagnotte);
|
||||
|
||||
// Ajouter le montant à la masse à partager de la course
|
||||
ResultatCourse resultat = resultatRepository.findByCourseId(courseId);
|
||||
if (resultat != null) {
|
||||
resultat.setMasseAPartager(resultat.getMasseAPartager() + cagnotte.getMontant());
|
||||
resultatRepository.save(resultat);
|
||||
}
|
||||
}
|
||||
|
||||
// Méthodes utilitaires
|
||||
private Double calculerMasseAPartager(ResultatCourse resultat) {
|
||||
// Article 5: MAP = RNET - MREMB - PRELEV
|
||||
return resultat.getRecetteNette() -
|
||||
resultat.getMontantRembourse() -
|
||||
resultat.getPrelevementsLegaux();
|
||||
}
|
||||
|
||||
private ResultatCourse creerResultat(RequeteResultatMulti requete) {
|
||||
Course course = courseRepository.findById(requete.getCourseId())
|
||||
.orElseThrow(() -> new RuntimeException("Course non trouvée"));
|
||||
|
||||
return ResultatCourse.builder()
|
||||
.course(course)
|
||||
.premiers(chevalRepository.findAllById(requete.getPremiersIds()))
|
||||
.seconds(chevalRepository.findAllById(requete.getSecondsIds()))
|
||||
.troisiemes(chevalRepository.findAllById(requete.getTroisiemesIds()))
|
||||
.quatriemes(chevalRepository.findAllById(requete.getQuatriemesIds()))
|
||||
.ordreArrivee(chevalRepository.findAllById(requete.getOrdreArriveeIds()))
|
||||
.recetteNette(requete.getRecetteNette())
|
||||
.prelevementsLegaux(requete.getPrelevementsLegaux())
|
||||
.montantRembourse(0.0)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void enregistrerPaiement(PariMulti pari, ReponsePaiementMulti reponse) {
|
||||
PaiementMulti paiement = PaiementMulti.builder()
|
||||
.pari(pari)
|
||||
.montant(reponse.getMontant())
|
||||
.heurePaiement(LocalDateTime.now())
|
||||
.typePaiement(reponse.getTypePaiement())
|
||||
.build();
|
||||
paiementRepository.save(paiement);
|
||||
}
|
||||
|
||||
// Méthodes supplémentaires pour la gestion des cas particuliers (Article 9)
|
||||
@Transactional
|
||||
public List<ReponsePaiementMulti> gererCasParticuliers(RequeteResultatMulti requete) {
|
||||
ResultatCourse resultat = creerResultat(requete);
|
||||
List<PariMulti> paris = pariRepository.findByCourseId(requete.getCourseId());
|
||||
|
||||
// Article 9: Cas où il n'y a aucune mise sur la combinaison gagnante
|
||||
if (!existeParisGagnants(paris, resultat)) {
|
||||
return appliquerReglesDegradation(resultat, paris);
|
||||
}
|
||||
|
||||
return calculerPaiements(requete);
|
||||
}
|
||||
|
||||
private boolean existeParisGagnants(List<PariMulti> paris, ResultatCourse resultat) {
|
||||
for (PariMulti pari : paris) {
|
||||
if (estCombinaisonGagnante(pari.getChevauxSelectionnes(), resultat)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private List<ReponsePaiementMulti> appliquerReglesDegradation(ResultatCourse resultat, List<PariMulti> paris) {
|
||||
// Article 9: Application des règles de dégradation
|
||||
List<ReponsePaiementMulti> paiements = new ArrayList<>();
|
||||
Double masseAPartager = resultat.getMasseAPartager();
|
||||
|
||||
// Essayer successivement les combinaisons dégradées
|
||||
for (int i = 0; i < 4; i++) {
|
||||
for (PariMulti pari : paris) {
|
||||
ReponsePaiementMulti paiement = calculerPaiementDegrade(pari, resultat, masseAPartager, i);
|
||||
if (paiement != null) {
|
||||
paiements.add(paiement);
|
||||
enregistrerPaiement(pari, paiement);
|
||||
return paiements; // On s'arrête au premier succès
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Si aucune combinaison dégradée ne fonctionne, transférer en cagnotte
|
||||
transfererEnCagnotte(resultat);
|
||||
return paiements;
|
||||
}
|
||||
|
||||
private ReponsePaiementMulti calculerPaiementDegrade(PariMulti pari, ResultatCourse resultat,
|
||||
Double masseAPartager, int niveauDegradation) {
|
||||
// Implémentation des règles de dégradation selon l'article 9
|
||||
List<Cheval> chevauxPari = pari.getChevauxSelectionnes();
|
||||
|
||||
// Vérifier différents patterns de dégradation
|
||||
boolean estGagnant = false;
|
||||
switch (niveauDegradation) {
|
||||
case 0: // 1er, 2ème, 3ème, 5ème
|
||||
estGagnant = estPatternDegrade(chevauxPari, resultat, 0, 1, 2, 4);
|
||||
break;
|
||||
case 1: // 1er, 2ème, 4ème, 5ème
|
||||
estGagnant = estPatternDegrade(chevauxPari, resultat, 0, 1, 3, 4);
|
||||
break;
|
||||
case 2: // 1er, 3ème, 4ème, 5ème
|
||||
estGagnant = estPatternDegrade(chevauxPari, resultat, 0, 2, 3, 4);
|
||||
break;
|
||||
case 3: // 2ème, 3ème, 4ème, 5ème
|
||||
estGagnant = estPatternDegrade(chevauxPari, resultat, 1, 2, 3, 4);
|
||||
break;
|
||||
}
|
||||
|
||||
if (estGagnant) {
|
||||
Double montant = calculerMontantPari(pari.getTypeMulti(), masseAPartager);
|
||||
TypePaiementMulti typePaiement = getTypePaiementFromTypeMulti(pari.getTypeMulti());
|
||||
return new ReponsePaiementMulti(pari.getId(), montant, typePaiement,
|
||||
"Paiement dégradé niveau " + niveauDegradation);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean estPatternDegrade(List<Cheval> chevauxPari, ResultatCourse resultat,
|
||||
int pos1, int pos2, int pos3, int pos4) {
|
||||
// Vérifier un pattern spécifique de dégradation
|
||||
if (resultat.getOrdreArrivee().size() < 5) return false;
|
||||
|
||||
Cheval cheval1 = resultat.getOrdreArrivee().get(pos1);
|
||||
Cheval cheval2 = resultat.getOrdreArrivee().get(pos2);
|
||||
Cheval cheval3 = resultat.getOrdreArrivee().get(pos3);
|
||||
Cheval cheval4 = resultat.getOrdreArrivee().get(pos4);
|
||||
|
||||
return chevauxPari.contains(cheval1) &&
|
||||
chevauxPari.contains(cheval2) &&
|
||||
chevauxPari.contains(cheval3) &&
|
||||
chevauxPari.contains(cheval4);
|
||||
}
|
||||
|
||||
// Méthodes pour les statistiques et rapports
|
||||
public Map<TypeMulti, Integer> getStatistiquesParis(Long courseId) {
|
||||
List<PariMulti> paris = pariRepository.findByCourseId(courseId);
|
||||
return paris.stream()
|
||||
.collect(Collectors.groupingBy(PariMulti::getTypeMulti,
|
||||
Collectors.summingInt(p -> 1)));
|
||||
}
|
||||
|
||||
public Map<TypeFormuleMulti, Integer> getStatistiquesFormules(Long courseId) {
|
||||
List<PariMulti> paris = pariRepository.findByCourseId(courseId);
|
||||
return paris.stream()
|
||||
.collect(Collectors.groupingBy(PariMulti::getTypeFormule,
|
||||
Collectors.summingInt(p -> 1)));
|
||||
}
|
||||
|
||||
public Double getMasseAPartagerCourse(Long courseId) {
|
||||
ResultatCourse resultat = resultatRepository.findByCourseId(courseId);
|
||||
return resultat != null ? resultat.getMasseAPartager() : 0.0;
|
||||
}
|
||||
|
||||
public List<CagnotteMulti> getCagnottesDisponibles() {
|
||||
return cagnotteRepository.findByUtilisee(false);
|
||||
}
|
||||
|
||||
public List<PaiementMulti> getHistoriquePaiementsParieur(Long parieurId) {
|
||||
List<PariMulti> paris = pariRepository.findByParieurId(parieurId);
|
||||
return paris.stream()
|
||||
.flatMap(pari -> paiementRepository.findByPariId(pari.getId()).stream())
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user