Compare commits
117 Commits
0e269e0bf7
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| dcaa79245c | |||
| 2772e44456 | |||
| 8f0e3c0738 | |||
| 81f6169d41 | |||
| 931c5076b7 | |||
| a328e71035 | |||
| 72f8a27272 | |||
| d3805ea0e7 | |||
| a1e5006e95 | |||
| 2d883ca1da | |||
| d357328e48 | |||
| 2501b998fa | |||
| f9e4b83ad3 | |||
| a7c89dbd73 | |||
| ae087084e9 | |||
| b2ee06d3b9 | |||
| 5afef2bcab | |||
| 3ed44bc044 | |||
| 55d39e02d2 | |||
| d091503f19 | |||
| d5c1273e18 | |||
| ea17989a82 | |||
| eda96d5ed2 | |||
| e8555f7992 | |||
| 3a4e2f160f | |||
| fdd42c6a63 | |||
| 2b84854ef2 | |||
| ddf530ce4c | |||
| fc3bea7f76 | |||
| 286911cf89 | |||
| e67e01640a | |||
| 4bfa6e845d | |||
| e870ffdda0 | |||
| 806ead5b98 | |||
| 378a17ba75 | |||
| ee0a7d87e9 | |||
| 812d873d5d | |||
| d6d9f86254 | |||
| a22225ee7a | |||
| 3cb12826d0 | |||
| 2f390b03e2 | |||
| ed5d73c25f | |||
| 0a368454c4 | |||
| 752f03cba5 | |||
| d857fce71f | |||
| 2fd09af0ea | |||
| d43cdc1a4e | |||
| 8663aa61cf | |||
| 758e02dc5b | |||
| 72b248d09d | |||
| 31315c951a | |||
| ab4d57985c | |||
| 2e846bf801 | |||
| 9954dd002c | |||
| 7dab5b8880 | |||
| b37902466c | |||
| 89d9e04a6f | |||
| e2197d0712 | |||
| 34a6911fa0 | |||
| 172dcdaa67 | |||
| cdd7221e86 | |||
| 952300d063 | |||
| 541d3824f3 | |||
| 4c260b86b9 | |||
| 9018ecef12 | |||
| d749dea6f4 | |||
| 189eb135bb | |||
| 59ba31ae2d | |||
| 197ee0d5b1 | |||
| 3d8597869d | |||
| 4a07eb4ed9 | |||
| d2a7e6cbac | |||
| 78d22b466d | |||
| b419e2f58d | |||
| a5d3973394 | |||
| 4dff0940c1 | |||
| 4b56aa0209 | |||
| eed7a10cfb | |||
| 1cbbde6506 | |||
| e8d5d0fa0c | |||
| eefa77369a | |||
| a5bbc41dfd | |||
| a942798a6c | |||
| 01436ac220 | |||
| 876545630a | |||
| 0150c4fac2 | |||
| cad6d14ba8 | |||
| c456fdae8b | |||
| 4bf07cc8f8 | |||
| a8356c8663 | |||
| c7a2215103 | |||
| 46f543abde | |||
| d8b6f1ad25 | |||
| 9170157dbb | |||
| babbc5d585 | |||
| 51c774a21e | |||
| 9d85b9ae45 | |||
| 0ab0731ebd | |||
| ec48f73d9f | |||
| f98f1bd1ac | |||
| b9d752ac55 | |||
| 13650b27c1 | |||
| 0757ae7198 | |||
| a871b52006 | |||
| 78959fc485 | |||
| 0a91e72c29 | |||
| e3a1d1c50b | |||
| 3933954e09 | |||
| 959e356fb9 | |||
| 3b5955ff31 | |||
| e8ee5811a0 | |||
| 12326fe122 | |||
| 9624ff93f0 | |||
| 5444235512 | |||
| b54eaa2549 | |||
| 6a7af8aea9 | |||
| bc4dbb532f |
@@ -48,7 +48,7 @@ jobs:
|
|||||||
- name: Set up Node.js
|
- name: Set up Node.js
|
||||||
uses: actions/setup-node@v4
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '22'
|
||||||
cache: 'npm'
|
cache: 'npm'
|
||||||
cache-dependency-path: src/main/webapp/package-lock.json
|
cache-dependency-path: src/main/webapp/package-lock.json
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,11 @@ services:
|
|||||||
- default
|
- default
|
||||||
- intra
|
- intra
|
||||||
- nginx
|
- nginx
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "curl", "-f", "https://intra.ffsaf.fr/api" ]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 3
|
||||||
|
|
||||||
ffsaf-db:
|
ffsaf-db:
|
||||||
image: public.ecr.aws/docker/library/postgres:17.2
|
image: public.ecr.aws/docker/library/postgres:17.2
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ public class FrontendForwardingFilter implements ContainerResponseFilter {
|
|||||||
final String path = info.getPath();
|
final String path = info.getPath();
|
||||||
final String address = request.remoteAddress().toString();
|
final String address = request.remoteAddress().toString();
|
||||||
|
|
||||||
LOG.infof("Request %s %s from IP %s", method, path, address);
|
if (!path.equals("/api")) {
|
||||||
|
LOG.infof("Request %s %s from IP %s", method, path, address);
|
||||||
|
}
|
||||||
|
|
||||||
int status = responseContext.getStatus();
|
int status = responseContext.getStatus();
|
||||||
if (status != 404 && !(status == 405 && "GET".equals(requestContext.getMethod()))) {
|
if (status != 404 && !(status == 405 && "GET".equals(requestContext.getMethod()))) {
|
||||||
|
|||||||
48
src/main/java/fr/titionfire/ffsaf/UserInfoProvider.java
Normal file
48
src/main/java/fr/titionfire/ffsaf/UserInfoProvider.java
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package fr.titionfire.ffsaf;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
|
import jakarta.ws.rs.container.ContainerRequestContext;
|
||||||
|
import jakarta.ws.rs.container.ContainerRequestFilter;
|
||||||
|
import jakarta.ws.rs.container.PreMatching;
|
||||||
|
import jakarta.ws.rs.ext.Provider;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
@Provider
|
||||||
|
@PreMatching
|
||||||
|
public class UserInfoProvider implements ContainerRequestFilter {
|
||||||
|
|
||||||
|
private static final List<Locale> SUPPORTED_LANGUAGES = Arrays.asList(
|
||||||
|
Locale.FRENCH,
|
||||||
|
Locale.ENGLISH
|
||||||
|
);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void filter(ContainerRequestContext requestContext) {
|
||||||
|
List<Locale> acceptableLanguages = requestContext.getAcceptableLanguages();
|
||||||
|
Locale selectedLocale = findFirstSupportedLanguage(acceptableLanguages);
|
||||||
|
|
||||||
|
if (selectedLocale == null)
|
||||||
|
selectedLocale = TradService.fallbackLocale;
|
||||||
|
requestContext.setProperty("userLocale", selectedLocale);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Locale findFirstSupportedLanguage(List<Locale> acceptableLanguages) {
|
||||||
|
for (Locale acceptableLanguage : acceptableLanguages) {
|
||||||
|
// Vérifie si la langue est dans la liste des langues supportées
|
||||||
|
if (SUPPORTED_LANGUAGES.contains(acceptableLanguage)) {
|
||||||
|
return acceptableLanguage;
|
||||||
|
}
|
||||||
|
// Vérifie aussi par tag de langue (ex: "fr-FR" -> "fr")
|
||||||
|
String languageTag = acceptableLanguage.getLanguage();
|
||||||
|
for (Locale supportedLanguage : SUPPORTED_LANGUAGES) {
|
||||||
|
if (supportedLanguage.getLanguage().equals(languageTag)) {
|
||||||
|
return supportedLanguage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
64
src/main/java/fr/titionfire/ffsaf/data/model/CardModel.java
Normal file
64
src/main/java/fr/titionfire/ffsaf/data/model/CardModel.java
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package fr.titionfire.ffsaf.data.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.*;
|
||||||
|
import org.hibernate.annotations.CreationTimestamp;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@ToString
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "card")
|
||||||
|
public class CardModel {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
Long id;
|
||||||
|
|
||||||
|
Long comb;
|
||||||
|
Long match;
|
||||||
|
Long category;
|
||||||
|
|
||||||
|
@JsonIgnore
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "competition", referencedColumnName = "id")
|
||||||
|
CompetitionModel competition;
|
||||||
|
|
||||||
|
@JsonProperty("competition")
|
||||||
|
Long competitionId;
|
||||||
|
|
||||||
|
CardType type;
|
||||||
|
String reason;
|
||||||
|
@CreationTimestamp
|
||||||
|
Date date;
|
||||||
|
|
||||||
|
@Column(nullable = false, columnDefinition = "boolean default false")
|
||||||
|
boolean teamCard = false;
|
||||||
|
|
||||||
|
public boolean hasEffect(MatchModel match) {
|
||||||
|
return switch (this.type) {
|
||||||
|
case BLUE -> false;
|
||||||
|
case YELLOW -> Objects.equals(this.match, match.getId());
|
||||||
|
case RED -> Objects.equals(this.category, match.getCategory().getId())
|
||||||
|
|| Objects.equals(this.match, match.getId());
|
||||||
|
case BLACK -> true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum CardType {
|
||||||
|
BLUE,
|
||||||
|
YELLOW,
|
||||||
|
RED,
|
||||||
|
BLACK
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package fr.titionfire.ffsaf.data.model;
|
|
||||||
|
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
|
||||||
import jakarta.persistence.*;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
import lombok.NoArgsConstructor;
|
|
||||||
import lombok.Setter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
@Setter
|
|
||||||
@AllArgsConstructor
|
|
||||||
@NoArgsConstructor
|
|
||||||
@RegisterForReflection
|
|
||||||
|
|
||||||
@Entity
|
|
||||||
@Table(name = "cardboard")
|
|
||||||
public class CardboardModel {
|
|
||||||
|
|
||||||
@Id
|
|
||||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
|
||||||
Long id;
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "comb", referencedColumnName = "id")
|
|
||||||
MembreModel comb;
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "guest_comb", referencedColumnName = "id")
|
|
||||||
CompetitionGuestModel guestComb;
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "match", referencedColumnName = "id")
|
|
||||||
MatchModel match;
|
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY)
|
|
||||||
@JoinColumn(name = "compet", referencedColumnName = "id")
|
|
||||||
CompetitionModel compet;
|
|
||||||
|
|
||||||
int red;
|
|
||||||
int yellow;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package fr.titionfire.ffsaf.data.model;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.utils.Categorie;
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "category_preset")
|
||||||
|
public class CatPresetModel {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
Long id;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "competition", referencedColumnName = "id")
|
||||||
|
CompetitionModel competition;
|
||||||
|
|
||||||
|
String name = "";
|
||||||
|
|
||||||
|
@ElementCollection(fetch = FetchType.EAGER)
|
||||||
|
@CollectionTable(name = "category_preset_catconfig", joinColumns = @JoinColumn(name = "id_preset"))
|
||||||
|
List<CategorieEmbeddable> categories;
|
||||||
|
|
||||||
|
SwordType swordType = SwordType.NONE;
|
||||||
|
ShieldType shieldType = ShieldType.NONE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1 - 1 - Casque
|
||||||
|
* 2 - 2 - Gorgerin
|
||||||
|
* 3 - 4 - Coquille et Protection pelvienne
|
||||||
|
* 4 - 8 - Gant main(s) armée(s)
|
||||||
|
* 5 - 16 - Gant main bouclier
|
||||||
|
* 6 - 32 - Plastron
|
||||||
|
* 7 - 64 - Protection de bras armé(s)
|
||||||
|
* 8 - 128 - Protection de bras de bouclier
|
||||||
|
* 9 - 256 - Protection de jambes
|
||||||
|
* 10 - 512 - Protection de genoux
|
||||||
|
* 11 - 1024 - Protection de coudes
|
||||||
|
* 12 - 2048 - Protection dorsale
|
||||||
|
* 13 - 4096 - Protection de pieds
|
||||||
|
*/
|
||||||
|
int mandatoryProtection1 = 0;
|
||||||
|
int mandatoryProtection2 = 0;
|
||||||
|
|
||||||
|
@ManyToMany(mappedBy = "categoriesInscrites", fetch = FetchType.LAZY)
|
||||||
|
private List<RegisterModel> registers = new ArrayList<>();
|
||||||
|
|
||||||
|
@ManyToMany(mappedBy = "categoriesInscrites", fetch = FetchType.LAZY)
|
||||||
|
private List<CompetitionGuestModel> guest = new ArrayList<>();
|
||||||
|
|
||||||
|
public enum SwordType {
|
||||||
|
NONE,
|
||||||
|
ONE_HAND,
|
||||||
|
TWO_HAND,
|
||||||
|
SABER
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ShieldType {
|
||||||
|
NONE,
|
||||||
|
STANDARD,
|
||||||
|
ROUND,
|
||||||
|
TEARDROP,
|
||||||
|
BUCKLER
|
||||||
|
}
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
|
||||||
|
@Embeddable
|
||||||
|
public static class CategorieEmbeddable {
|
||||||
|
Categorie categorie;
|
||||||
|
long roundDuration;
|
||||||
|
long pauseDuration;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,4 +44,14 @@ public class CategoryModel {
|
|||||||
Integer type;
|
Integer type;
|
||||||
|
|
||||||
String liceName = "1";
|
String liceName = "1";
|
||||||
|
|
||||||
|
@Column(nullable = false, columnDefinition = "boolean default false")
|
||||||
|
boolean treeAreClassement = false;
|
||||||
|
|
||||||
|
@Column(nullable = false, columnDefinition = "boolean default false")
|
||||||
|
boolean fullClassement = false;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.EAGER)
|
||||||
|
@JoinColumn(name = "id_preset", referencedColumnName = "id")
|
||||||
|
CatPresetModel preset;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package fr.titionfire.ffsaf.data.model;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.hibernate.annotations.CreationTimestamp;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "card_team")
|
||||||
|
public class ClubCardModel {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
Long id;
|
||||||
|
|
||||||
|
Long competition;
|
||||||
|
String teamUuid;
|
||||||
|
String teamName;
|
||||||
|
|
||||||
|
CardModel.CardType type;
|
||||||
|
String reason;
|
||||||
|
@CreationTimestamp
|
||||||
|
Date date;
|
||||||
|
|
||||||
|
List<Long> cardIds;
|
||||||
|
}
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
package fr.titionfire.ffsaf.data.model;
|
package fr.titionfire.ffsaf.data.model;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.utils.Categorie;
|
||||||
import fr.titionfire.ffsaf.utils.ResultPrivacy;
|
import fr.titionfire.ffsaf.utils.ResultPrivacy;
|
||||||
|
|
||||||
public interface CombModel {
|
public interface CombModel {
|
||||||
Long getCombId();
|
Long getCombId();
|
||||||
String getName();
|
String getName();
|
||||||
String getName(MembreModel model, ResultPrivacy privacy);
|
String getName(MembreModel model, ResultPrivacy privacy);
|
||||||
|
Categorie getCategorie();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ import lombok.Getter;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@@ -38,7 +43,32 @@ public class CompetitionGuestModel implements CombModel {
|
|||||||
|
|
||||||
String country = "fr";
|
String country = "fr";
|
||||||
|
|
||||||
Integer weight = null;
|
Float weight = null;
|
||||||
|
Float weightReal = null;
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
|
||||||
|
@JoinTable(
|
||||||
|
name = "groupe_membre",
|
||||||
|
joinColumns = @JoinColumn(name = "groupe_id"),
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "membre_id")
|
||||||
|
)
|
||||||
|
List<MembreModel> comb = new ArrayList<>();
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
|
||||||
|
@JoinTable(
|
||||||
|
name = "groupe_guest",
|
||||||
|
joinColumns = @JoinColumn(name = "groupe_id"),
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "guest_id")
|
||||||
|
)
|
||||||
|
List<CompetitionGuestModel> guest = new ArrayList<>();
|
||||||
|
|
||||||
|
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
|
||||||
|
@JoinTable(
|
||||||
|
name = "categories_insc_guest",
|
||||||
|
joinColumns = @JoinColumn(name = "guest_id"),
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "category_id")
|
||||||
|
)
|
||||||
|
List<CatPresetModel> categoriesInscrites = new ArrayList<>();
|
||||||
|
|
||||||
public CompetitionGuestModel(String s) {
|
public CompetitionGuestModel(String s) {
|
||||||
this.fname = s.substring(0, s.indexOf(" "));
|
this.fname = s.substring(0, s.indexOf(" "));
|
||||||
@@ -52,6 +82,8 @@ public class CompetitionGuestModel implements CombModel {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
if (this.isTeam())
|
||||||
|
return this.fname;
|
||||||
return this.fname + " " + this.lname;
|
return this.fname + " " + this.lname;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,4 +91,25 @@ public class CompetitionGuestModel implements CombModel {
|
|||||||
public String getName(MembreModel model, ResultPrivacy privacy) {
|
public String getName(MembreModel model, ResultPrivacy privacy) {
|
||||||
return getName();
|
return getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTeam() {
|
||||||
|
return "__team".equals(this.lname);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInTeam(Object comb_) {
|
||||||
|
if (!this.isTeam())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (comb_ instanceof Long id_) {
|
||||||
|
if (id_ >= 0)
|
||||||
|
return comb.stream().anyMatch(membre -> Objects.equals(membre.getId(), id_));
|
||||||
|
else
|
||||||
|
return guest.stream().anyMatch(guestModel -> Objects.equals(guestModel.getId(), -id_));
|
||||||
|
}
|
||||||
|
return Stream.concat(comb.stream(), guest.stream()).anyMatch(c -> Objects.equals(c, comb_));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Float getWeight2() {
|
||||||
|
return (this.weightReal != null) ? this.weightReal : this.weight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package fr.titionfire.ffsaf.data.model;
|
package fr.titionfire.ffsaf.data.model;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.utils.Categorie;
|
||||||
import fr.titionfire.ffsaf.utils.CompetitionSystem;
|
import fr.titionfire.ffsaf.utils.CompetitionSystem;
|
||||||
import fr.titionfire.ffsaf.utils.RegisterMode;
|
import fr.titionfire.ffsaf.utils.RegisterMode;
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
@@ -58,6 +59,10 @@ public class CompetitionModel {
|
|||||||
@OneToMany(mappedBy = "competition", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
@OneToMany(mappedBy = "competition", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||||
List<CompetitionGuestModel> guests = new ArrayList<>();
|
List<CompetitionGuestModel> guests = new ArrayList<>();
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "competition", fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
|
||||||
|
List<CatPresetModel> catPreset = new ArrayList<>();
|
||||||
|
|
||||||
|
List<Categorie> requiredWeight = new ArrayList<>();
|
||||||
|
|
||||||
List<Long> banMembre = new ArrayList<>();
|
List<Long> banMembre = new ArrayList<>();
|
||||||
|
|
||||||
@@ -67,8 +72,15 @@ public class CompetitionModel {
|
|||||||
@Column(name = "table_")
|
@Column(name = "table_")
|
||||||
List<String> table = new ArrayList<>();
|
List<String> table = new ArrayList<>();
|
||||||
|
|
||||||
|
@Column(columnDefinition = "TEXT")
|
||||||
String data1;
|
String data1;
|
||||||
|
@Column(columnDefinition = "TEXT")
|
||||||
String data2;
|
String data2;
|
||||||
|
@Column(columnDefinition = "TEXT")
|
||||||
String data3;
|
String data3;
|
||||||
|
@Column(columnDefinition = "TEXT")
|
||||||
String data4;
|
String data4;
|
||||||
|
|
||||||
|
@Column(columnDefinition = "TEXT")
|
||||||
|
String config;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class LogModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum ObjectType {
|
public enum ObjectType {
|
||||||
Membre, Affiliation, Licence, Club, Competition, Register
|
Membre, Affiliation, Licence, Club, Competition, Register, Selection
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,10 +63,6 @@ public class MatchModel {
|
|||||||
|
|
||||||
char poule = 'A';
|
char poule = 'A';
|
||||||
|
|
||||||
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
|
|
||||||
@JoinColumn(name = "match", referencedColumnName = "id")
|
|
||||||
List<CardboardModel> cardboard = new ArrayList<>();
|
|
||||||
|
|
||||||
public String getC1Name(MembreModel model, ResultPrivacy privacy) {
|
public String getC1Name(MembreModel model, ResultPrivacy privacy) {
|
||||||
if (c1_id != null)
|
if (c1_id != null)
|
||||||
return c1_id.getName(model, privacy);
|
return c1_id.getName(model, privacy);
|
||||||
@@ -113,7 +109,26 @@ public class MatchModel {
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CombModel getC1() {
|
||||||
|
if (this.c1_id != null)
|
||||||
|
return this.c1_id;
|
||||||
|
if (this.c1_guest != null)
|
||||||
|
return this.c1_guest;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CombModel getC2() {
|
||||||
|
if (this.c2_id != null)
|
||||||
|
return this.c2_id;
|
||||||
|
if (this.c2_guest != null)
|
||||||
|
return this.c2_guest;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isC1(Object comb) {
|
public boolean isC1(Object comb) {
|
||||||
|
if (this.c1_guest != null && this.c1_guest.isInTeam(comb))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (comb instanceof Long id_) {
|
if (comb instanceof Long id_) {
|
||||||
if (id_ >= 0)
|
if (id_ >= 0)
|
||||||
return Objects.equals(this.c1_id != null ? this.c1_id.getId() : null, id_);
|
return Objects.equals(this.c1_id != null ? this.c1_id.getId() : null, id_);
|
||||||
@@ -124,6 +139,9 @@ public class MatchModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isC2(Object comb) {
|
public boolean isC2(Object comb) {
|
||||||
|
if (this.c2_guest != null && this.c2_guest.isInTeam(comb))
|
||||||
|
return true;
|
||||||
|
|
||||||
if (comb instanceof Long id_) {
|
if (comb instanceof Long id_) {
|
||||||
if (id_ >= 0)
|
if (id_ >= 0)
|
||||||
return Objects.equals(this.c2_id != null ? this.c2_id.getId() : null, id_);
|
return Objects.equals(this.c2_id != null ? this.c2_id.getId() : null, id_);
|
||||||
|
|||||||
@@ -72,6 +72,10 @@ public class MembreModel implements LoggableModel, CombModel {
|
|||||||
@Schema(description = "Les licences du membre. (optionnel)")
|
@Schema(description = "Les licences du membre. (optionnel)")
|
||||||
List<LicenceModel> licences;
|
List<LicenceModel> licences;
|
||||||
|
|
||||||
|
@OneToMany(mappedBy = "membre", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
|
||||||
|
@Schema(description = "Les séléctions du membre. (optionnel)")
|
||||||
|
List<SelectionModel> selections;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getObjectName() {
|
public String getObjectName() {
|
||||||
return fname + " " + lname;
|
return fname + " " + lname;
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ import lombok.Setter;
|
|||||||
import org.hibernate.annotations.OnDelete;
|
import org.hibernate.annotations.OnDelete;
|
||||||
import org.hibernate.annotations.OnDeleteAction;
|
import org.hibernate.annotations.OnDeleteAction;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@@ -34,7 +37,8 @@ public class RegisterModel {
|
|||||||
@JoinColumn(name = "id_membre")
|
@JoinColumn(name = "id_membre")
|
||||||
MembreModel membre;
|
MembreModel membre;
|
||||||
|
|
||||||
Integer weight;
|
Float weight;
|
||||||
|
Float weightReal;
|
||||||
int overCategory = 0;
|
int overCategory = 0;
|
||||||
Categorie categorie;
|
Categorie categorie;
|
||||||
|
|
||||||
@@ -46,7 +50,18 @@ public class RegisterModel {
|
|||||||
@Column(nullable = false, columnDefinition = "boolean default false")
|
@Column(nullable = false, columnDefinition = "boolean default false")
|
||||||
boolean lockEdit = false;
|
boolean lockEdit = false;
|
||||||
|
|
||||||
public RegisterModel(CompetitionModel competition, MembreModel membre, Integer weight, int overCategory,
|
@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
|
||||||
|
@JoinTable(
|
||||||
|
name = "categories_insc_comb",
|
||||||
|
joinColumns = {
|
||||||
|
@JoinColumn(name = "id_competition", referencedColumnName = "id_competition"),
|
||||||
|
@JoinColumn(name = "id_membre", referencedColumnName = "id_membre")
|
||||||
|
},
|
||||||
|
inverseJoinColumns = @JoinColumn(name = "category_id")
|
||||||
|
)
|
||||||
|
List<CatPresetModel> categoriesInscrites = new ArrayList<>();
|
||||||
|
|
||||||
|
public RegisterModel(CompetitionModel competition, MembreModel membre, Float weight, int overCategory,
|
||||||
Categorie categorie, ClubModel club) {
|
Categorie categorie, ClubModel club) {
|
||||||
this.id = new RegisterId(competition.getId(), membre.getId());
|
this.id = new RegisterId(competition.getId(), membre.getId());
|
||||||
this.competition = competition;
|
this.competition = competition;
|
||||||
@@ -75,4 +90,10 @@ public class RegisterModel {
|
|||||||
return null;
|
return null;
|
||||||
return Categorie.values()[Math.min(tmp.ordinal() + this.overCategory, Categorie.values().length - 1)];
|
return Categorie.values()[Math.min(tmp.ordinal() + this.overCategory, Categorie.values().length - 1)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Float getWeight2() {
|
||||||
|
if (weightReal != null)
|
||||||
|
return weightReal;
|
||||||
|
return weight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package fr.titionfire.ffsaf.data.model;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.utils.Categorie;
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.*;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "selection")
|
||||||
|
public class SelectionModel implements LoggableModel {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
@Schema(description = "L'identifiant de la séléction.")
|
||||||
|
Long id;
|
||||||
|
|
||||||
|
@ManyToOne(fetch = FetchType.LAZY)
|
||||||
|
@JoinColumn(name = "membre", referencedColumnName = "id")
|
||||||
|
@Schema(description = "Le membre de la séléction. (optionnel)")
|
||||||
|
MembreModel membre;
|
||||||
|
|
||||||
|
@Schema(description = "La saison de la séléction.", examples = "2025")
|
||||||
|
int saison;
|
||||||
|
|
||||||
|
@Schema(description = "Catégorie de la séléction.")
|
||||||
|
Categorie categorie;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjectName() {
|
||||||
|
return "selection " + id.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LogModel.ObjectType getObjectType() {
|
||||||
|
return LogModel.ObjectType.Selection;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,6 +40,14 @@ public class TreeModel {
|
|||||||
@JoinColumn(referencedColumnName = "id")
|
@JoinColumn(referencedColumnName = "id")
|
||||||
TreeModel right;
|
TreeModel right;
|
||||||
|
|
||||||
|
public TreeModel(Long category, Integer level, MatchModel match) {
|
||||||
|
this.category = category;
|
||||||
|
this.level = level;
|
||||||
|
this.match = match;
|
||||||
|
this.left = null;
|
||||||
|
this.right = null;
|
||||||
|
}
|
||||||
|
|
||||||
public List<TreeModel> flat() {
|
public List<TreeModel> flat() {
|
||||||
List<TreeModel> out = new ArrayList<>();
|
List<TreeModel> out = new ArrayList<>();
|
||||||
this.flat(out);
|
this.flat(out);
|
||||||
@@ -55,4 +63,44 @@ public class TreeModel {
|
|||||||
if (this.left != null)
|
if (this.left != null)
|
||||||
this.left.flat(out);
|
this.left.flat(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int death() {
|
||||||
|
int dg = 0;
|
||||||
|
int dd = 0;
|
||||||
|
|
||||||
|
if (this.right != null)
|
||||||
|
dg = this.right.death();
|
||||||
|
|
||||||
|
if (this.left != null)
|
||||||
|
dg = this.left.death();
|
||||||
|
|
||||||
|
return 1 + Math.max(dg, dd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxChildrenAtDepth(int death, int current) {
|
||||||
|
if (current == death)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
int tmp = 0;
|
||||||
|
if (this.right != null)
|
||||||
|
tmp += this.right.getMaxChildrenAtDepth(death, current + 1);
|
||||||
|
|
||||||
|
if (this.left != null)
|
||||||
|
tmp += this.left.getMaxChildrenAtDepth(death, current + 1);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getChildrenAtDepth (int death, int current, List<TreeModel> out) {
|
||||||
|
if (current == death) {
|
||||||
|
out.add(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.right != null)
|
||||||
|
this.right.getChildrenAtDepth(death, current + 1, out);
|
||||||
|
|
||||||
|
if (this.left != null)
|
||||||
|
this.left.getChildrenAtDepth(death, current + 1, out);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package fr.titionfire.ffsaf.data.repository;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.CardModel;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.PanacheRepositoryBase;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
public class CardRepository implements PanacheRepositoryBase<CardModel, Long> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package fr.titionfire.ffsaf.data.repository;
|
package fr.titionfire.ffsaf.data.repository;
|
||||||
|
|
||||||
import fr.titionfire.ffsaf.data.model.CardboardModel;
|
import fr.titionfire.ffsaf.data.model.CatPresetModel;
|
||||||
import io.quarkus.hibernate.reactive.panache.PanacheRepositoryBase;
|
import io.quarkus.hibernate.reactive.panache.PanacheRepositoryBase;
|
||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
public class CardboardRepository implements PanacheRepositoryBase<CardboardModel, Long> {
|
public class CatPresetRepository implements PanacheRepositoryBase<CatPresetModel, Long> {
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package fr.titionfire.ffsaf.data.repository;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.ClubCardModel;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.PanacheRepositoryBase;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
public class ClubCardRepository implements PanacheRepositoryBase<ClubCardModel, Long> {
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,6 +20,9 @@ public class MatchRepository implements PanacheRepositoryBase<MatchModel, Long>
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Uni<Void> create(List<MatchModel> matchModel) {
|
public Uni<Void> create(List<MatchModel> matchModel) {
|
||||||
|
if (matchModel.isEmpty())
|
||||||
|
return Uni.createFrom().voidItem();
|
||||||
|
|
||||||
matchModel.forEach(model -> model.setSystem(CompetitionSystem.INTERNAL));
|
matchModel.forEach(model -> model.setSystem(CompetitionSystem.INTERNAL));
|
||||||
return Panache.withTransaction(() -> this.persist(matchModel)
|
return Panache.withTransaction(() -> this.persist(matchModel)
|
||||||
.call(__ -> this.flush())
|
.call(__ -> this.flush())
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package fr.titionfire.ffsaf.data.repository;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.SelectionModel;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.PanacheRepositoryBase;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
public class SelectionRepository implements PanacheRepositoryBase<SelectionModel, Long> {
|
||||||
|
}
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package fr.titionfire.ffsaf.domain.entity;
|
|
||||||
|
|
||||||
import fr.titionfire.ffsaf.data.model.CardboardModel;
|
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
|
||||||
@RegisterForReflection
|
|
||||||
public class CardboardEntity {
|
|
||||||
long comb_id;
|
|
||||||
long match_id;
|
|
||||||
long compet_id;
|
|
||||||
|
|
||||||
int red;
|
|
||||||
int yellow;
|
|
||||||
|
|
||||||
public static CardboardEntity fromModel(CardboardModel model) {
|
|
||||||
return new CardboardEntity(
|
|
||||||
model.getComb() != null ? model.getComb().getId() : model.getGuestComb().getId() * -1,
|
|
||||||
model.getMatch().getId(),
|
|
||||||
model.getCompet().getId(),
|
|
||||||
model.getRed(), model.getYellow());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package fr.titionfire.ffsaf.domain.entity;
|
package fr.titionfire.ffsaf.domain.entity;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.CatPresetModel;
|
||||||
import fr.titionfire.ffsaf.data.model.CompetitionGuestModel;
|
import fr.titionfire.ffsaf.data.model.CompetitionGuestModel;
|
||||||
import fr.titionfire.ffsaf.data.model.MembreModel;
|
import fr.titionfire.ffsaf.data.model.MembreModel;
|
||||||
import fr.titionfire.ffsaf.data.model.RegisterModel;
|
import fr.titionfire.ffsaf.data.model.RegisterModel;
|
||||||
@@ -9,6 +10,10 @@ import io.quarkus.runtime.annotations.RegisterForReflection;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
@@ -22,7 +27,9 @@ public class CombEntity {
|
|||||||
Genre genre;
|
Genre genre;
|
||||||
String country;
|
String country;
|
||||||
int overCategory;
|
int overCategory;
|
||||||
Integer weight;
|
Float weight;
|
||||||
|
List<CombEntity> teamMembers;
|
||||||
|
List<Long> categoriesInscrites;
|
||||||
|
|
||||||
public static CombEntity fromModel(MembreModel model) {
|
public static CombEntity fromModel(MembreModel model) {
|
||||||
if (model == null)
|
if (model == null)
|
||||||
@@ -31,7 +38,7 @@ public class CombEntity {
|
|||||||
return new CombEntity(model.getId(), model.getLname(), model.getFname(), model.getCategorie(),
|
return new CombEntity(model.getId(), model.getLname(), model.getFname(), model.getCategorie(),
|
||||||
model.getClub() == null ? null : model.getClub().getClubId(),
|
model.getClub() == null ? null : model.getClub().getClubId(),
|
||||||
model.getClub() == null ? "Sans club" : model.getClub().getName(), model.getGenre(), model.getCountry(),
|
model.getClub() == null ? "Sans club" : model.getClub().getName(), model.getGenre(), model.getCountry(),
|
||||||
0, null);
|
0, null, new ArrayList<>(), new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -40,7 +47,18 @@ public class CombEntity {
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
return new CombEntity(model.getId() * -1, model.getLname(), model.getFname(), model.getCategorie(), null,
|
return new CombEntity(model.getId() * -1, model.getLname(), model.getFname(), model.getCategorie(), null,
|
||||||
model.getClub(), model.getGenre(), model.getCountry(), 0, model.getWeight());
|
model.getClub(), model.getGenre(), model.getCountry(), 0,
|
||||||
|
model.getWeight2() != null ? model.getWeight2() : model.getWeight(),
|
||||||
|
Stream.concat(model.getComb().stream().map(CombEntity::fromModel),
|
||||||
|
model.getGuest().stream().map(CombEntity::fromModel)).toList(),
|
||||||
|
new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public CombEntity addCategoriesInscrites(List<CatPresetModel> categoriesInscrites) {
|
||||||
|
if (categoriesInscrites == null)
|
||||||
|
return this;
|
||||||
|
this.categoriesInscrites = categoriesInscrites.stream().map(CatPresetModel::getId).toList();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CombEntity fromModel(RegisterModel registerModel) {
|
public static CombEntity fromModel(RegisterModel registerModel) {
|
||||||
@@ -51,6 +69,8 @@ public class CombEntity {
|
|||||||
return new CombEntity(model.getId(), model.getLname(), model.getFname(), registerModel.getCategorie(),
|
return new CombEntity(model.getId(), model.getLname(), model.getFname(), registerModel.getCategorie(),
|
||||||
registerModel.getClub2() == null ? null : registerModel.getClub2().getClubId(),
|
registerModel.getClub2() == null ? null : registerModel.getClub2().getClubId(),
|
||||||
registerModel.getClub2() == null ? "Sans club" : registerModel.getClub2().getName(), model.getGenre(),
|
registerModel.getClub2() == null ? "Sans club" : registerModel.getClub2().getName(), model.getGenre(),
|
||||||
model.getCountry(), registerModel.getOverCategory(), registerModel.getWeight());
|
model.getCountry(), registerModel.getOverCategory(),
|
||||||
|
registerModel.getWeight2() != null ? registerModel.getWeight2() : registerModel.getWeight(),
|
||||||
|
new ArrayList<>(), new ArrayList<>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import io.quarkus.runtime.annotations.RegisterForReflection;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -23,7 +22,6 @@ public class MatchEntity {
|
|||||||
private Date date;
|
private Date date;
|
||||||
private List<ScoreEmbeddable> scores;
|
private List<ScoreEmbeddable> scores;
|
||||||
private char poule;
|
private char poule;
|
||||||
private List<CardboardEntity> cardboard;
|
|
||||||
|
|
||||||
public static MatchEntity fromModel(MatchModel model) {
|
public static MatchEntity fromModel(MatchModel model) {
|
||||||
if (model == null)
|
if (model == null)
|
||||||
@@ -35,22 +33,6 @@ public class MatchEntity {
|
|||||||
model.getC2_id()),
|
model.getC2_id()),
|
||||||
model.getCategory_ord(), model.isEnd(), model.getCategory().getId(), model.getDate(),
|
model.getCategory_ord(), model.isEnd(), model.getCategory().getId(), model.getDate(),
|
||||||
model.getScores(),
|
model.getScores(),
|
||||||
model.getPoule(),
|
model.getPoule());
|
||||||
(model.getCardboard() == null) ? new ArrayList<>() : model.getCardboard().stream()
|
|
||||||
.map(CardboardEntity::fromModel).toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public int win() {
|
|
||||||
int sum = 0;
|
|
||||||
for (ScoreEmbeddable score : scores) {
|
|
||||||
if (score.getS1() == -1000 || score.getS2() == -1000)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (score.getS1() > score.getS2())
|
|
||||||
sum++;
|
|
||||||
else if (score.getS1() < score.getS2())
|
|
||||||
sum--;
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,184 @@
|
|||||||
|
package fr.titionfire.ffsaf.domain.entity;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.*;
|
||||||
|
import fr.titionfire.ffsaf.utils.ResultPrivacy;
|
||||||
|
import fr.titionfire.ffsaf.utils.ScoreEmbeddable;
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@RegisterForReflection
|
||||||
|
public class MatchModelExtend {
|
||||||
|
final MatchModel match;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
boolean isEnd = false;
|
||||||
|
@Getter
|
||||||
|
List<ScoreEmbeddable> scoresToPrint = new ArrayList<>();
|
||||||
|
@Getter
|
||||||
|
List<ScoreEmbeddable> scoresToCompute = new ArrayList<>();
|
||||||
|
@Getter
|
||||||
|
int win = 0;
|
||||||
|
|
||||||
|
|
||||||
|
public MatchModelExtend(MatchModel match, List<CardModel> cards) {
|
||||||
|
this.match = match;
|
||||||
|
|
||||||
|
List<Long> combIds = extractCombIds(match);
|
||||||
|
List<CardModel> cards2 = cards.stream().filter(c -> combIds.contains(c.getComb()) && c.hasEffect(match))
|
||||||
|
.sorted(Comparator.comparing(CardModel::getType).reversed()).toList();
|
||||||
|
|
||||||
|
|
||||||
|
for (ScoreEmbeddable score : match.getScores()) {
|
||||||
|
if (score.getS1() == -1000 || score.getS2() == -1000)
|
||||||
|
continue;
|
||||||
|
this.scoresToCompute.add(virtualScore(score, cards2, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
calc_win_end(cards2);
|
||||||
|
|
||||||
|
for (ScoreEmbeddable score : match.getScores()) {
|
||||||
|
if (score.getS1() == -1000 || score.getS2() == -1000)
|
||||||
|
continue;
|
||||||
|
this.scoresToPrint.add(virtualScore(score, cards2, true));
|
||||||
|
}
|
||||||
|
if (this.isEnd && this.scoresToPrint.isEmpty()) {
|
||||||
|
this.scoresToPrint.add(virtualScore(new ScoreEmbeddable(0, 0, 0), cards2, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScoreEmbeddable virtualScore(ScoreEmbeddable score, List<CardModel> cards2, boolean toPrint) {
|
||||||
|
if (cards2.size() > 1) {
|
||||||
|
if (!Objects.equals(cards2.get(0).getComb(), cards2.get(1).getComb()))
|
||||||
|
return new ScoreEmbeddable(score.getN_round(), toPrint ? -997 : 0, toPrint ? -997 : 0);
|
||||||
|
}
|
||||||
|
if (!cards2.isEmpty()) {
|
||||||
|
if (isC1(cards2.get(0).getComb()))
|
||||||
|
return new ScoreEmbeddable(score.getN_round(), toPrint ? -997 : 0, 10);
|
||||||
|
else
|
||||||
|
return new ScoreEmbeddable(score.getN_round(), 10, toPrint ? -997 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (score.getS1() < -900 && score.getS2() < -900)
|
||||||
|
return new ScoreEmbeddable(score.getN_round(), toPrint ? score.getS1() : 0, toPrint ? score.getS2() : 0);
|
||||||
|
else if (score.getS1() < -900)
|
||||||
|
return new ScoreEmbeddable(score.getN_round(), toPrint ? score.getS1() : 0, 10);
|
||||||
|
else if (score.getS2() < -900)
|
||||||
|
return new ScoreEmbeddable(score.getN_round(), 10, toPrint ? score.getS2() : 0);
|
||||||
|
|
||||||
|
return new ScoreEmbeddable(score.getN_round(), score.getS1(), score.getS2());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calc_win_end(List<CardModel> cards2) {
|
||||||
|
if (cards2.size() > 1) {
|
||||||
|
if (!Objects.equals(cards2.get(0).getComb(), cards2.get(1).getComb())) {
|
||||||
|
this.win = 0;
|
||||||
|
this.isEnd = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cards2.isEmpty()) {
|
||||||
|
if (match.isC1(cards2.get(0).getComb())) {
|
||||||
|
this.win = -1;
|
||||||
|
} else if (match.isC2(cards2.get(0).getComb())) {
|
||||||
|
this.win = 1;
|
||||||
|
}
|
||||||
|
this.isEnd = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ScoreEmbeddable score : this.scoresToCompute) {
|
||||||
|
if (score.getS1() > score.getS2())
|
||||||
|
win++;
|
||||||
|
else if (score.getS1() < score.getS2())
|
||||||
|
win--;
|
||||||
|
}
|
||||||
|
this.isEnd = match.isEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private List<Long> extractCombIds(MatchModel match) {
|
||||||
|
List<Long> ids = new ArrayList<>();
|
||||||
|
if (match.getC1_id() != null)
|
||||||
|
ids.add(match.getC1_id().getId());
|
||||||
|
if (match.getC2_id() != null)
|
||||||
|
ids.add(match.getC2_id().getId());
|
||||||
|
if (match.getC1_guest() != null)
|
||||||
|
ids.add(match.getC1_guest().getId() * -1);
|
||||||
|
if (match.getC2_guest() != null)
|
||||||
|
ids.add(match.getC2_guest().getId() * -1);
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------- Delegation methods to MatchModel ---------------
|
||||||
|
|
||||||
|
public Long getId() {
|
||||||
|
return match.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MembreModel getC1_id() {
|
||||||
|
return match.getC1_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompetitionGuestModel getC1_guest() {
|
||||||
|
return match.getC1_guest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MembreModel getC2_id() {
|
||||||
|
return match.getC2_id();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompetitionGuestModel getC2_guest() {
|
||||||
|
return match.getC2_guest();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CategoryModel getCategory() {
|
||||||
|
return match.getCategory();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCategory_ord() {
|
||||||
|
return match.getCategory_ord();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getDate() {
|
||||||
|
return match.getDate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public char getPoule() {
|
||||||
|
return match.getPoule();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getC1Name(MembreModel model, ResultPrivacy privacy) {
|
||||||
|
return match.getC1Name(model, privacy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getC2Name(MembreModel model, ResultPrivacy privacy) {
|
||||||
|
return match.getC2Name(model, privacy);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getC2Name() {
|
||||||
|
return match.getC2Name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getC1Name() {
|
||||||
|
return match.getC1Name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isC1(Object comb) {
|
||||||
|
return match.isC1(comb);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isC2(Object comb) {
|
||||||
|
return match.isC2(comb);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CombModel getC1() {
|
||||||
|
return match.getC1();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CombModel getC2() {
|
||||||
|
return match.getC2();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -79,6 +79,9 @@ public class AffiliationService {
|
|||||||
@ConfigProperty(name = "notif.affRequest.mail")
|
@ConfigProperty(name = "notif.affRequest.mail")
|
||||||
List<String> mails;
|
List<String> mails;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
public Uni<List<AffiliationRequestModel>> getAllReq() {
|
public Uni<List<AffiliationRequestModel>> getAllReq() {
|
||||||
return repositoryRequest.listAll();
|
return repositoryRequest.listAll();
|
||||||
}
|
}
|
||||||
@@ -92,7 +95,7 @@ public class AffiliationService {
|
|||||||
return Uni.createFrom().item(affModel)
|
return Uni.createFrom().item(affModel)
|
||||||
.invoke(Unchecked.consumer(model -> {
|
.invoke(Unchecked.consumer(model -> {
|
||||||
if (model.getSaison() != currentSaison && model.getSaison() != currentSaison + 1) {
|
if (model.getSaison() != currentSaison && model.getSaison() != currentSaison + 1) {
|
||||||
throw new DBadRequestException("Saison non valid");
|
throw new DBadRequestException(trad.t("saison.non.valid"));
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.chain(() -> ((affModel.getState_id().charAt(0) == 'W') ? stateIdService.get_rna(
|
.chain(() -> ((affModel.getState_id().charAt(0) == 'W') ? stateIdService.get_rna(
|
||||||
@@ -110,7 +113,7 @@ public class AffiliationService {
|
|||||||
out, affModel.getSaison()))
|
out, affModel.getSaison()))
|
||||||
.onItem().invoke(Unchecked.consumer(count -> {
|
.onItem().invoke(Unchecked.consumer(count -> {
|
||||||
if (count != 0 && unique) {
|
if (count != 0 && unique) {
|
||||||
throw new DBadRequestException("Demande d'affiliation déjà existante");
|
throw new DBadRequestException(trad.t("demande.d.affiliation.deja.existante"));
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
@@ -118,28 +121,28 @@ public class AffiliationService {
|
|||||||
repository.count("club = ?1 and saison = ?2", club, affModel.getSaison())))
|
repository.count("club = ?1 and saison = ?2", club, affModel.getSaison())))
|
||||||
.onItem().invoke(Unchecked.consumer(count -> {
|
.onItem().invoke(Unchecked.consumer(count -> {
|
||||||
if (count != 0) {
|
if (count != 0) {
|
||||||
throw new DBadRequestException("Affiliation déjà existante");
|
throw new DBadRequestException(trad.t("affiliation.deja.existante"));
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.map(o -> affModel)
|
.map(o -> affModel)
|
||||||
.call(model -> ((model.getM1_lincence() != -1) ? combRepository.find("licence",
|
.call(model -> ((model.getM1_lincence() != -1) ? combRepository.find("licence",
|
||||||
model.getM1_lincence()).count().invoke(Unchecked.consumer(count -> {
|
model.getM1_lincence()).count().invoke(Unchecked.consumer(count -> {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
throw new DBadRequestException("Licence membre n°1 inconnue");
|
throw new DBadRequestException(trad.t("licence.membre.n.1.inconnue"));
|
||||||
}
|
}
|
||||||
})) : Uni.createFrom().nullItem())
|
})) : Uni.createFrom().nullItem())
|
||||||
)
|
)
|
||||||
.call(model -> ((model.getM2_lincence() != -1) ? combRepository.find("licence",
|
.call(model -> ((model.getM2_lincence() != -1) ? combRepository.find("licence",
|
||||||
model.getM2_lincence()).count().invoke(Unchecked.consumer(count -> {
|
model.getM2_lincence()).count().invoke(Unchecked.consumer(count -> {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
throw new DBadRequestException("Licence membre n°2 inconnue");
|
throw new DBadRequestException(trad.t("licence.membre.n.2.inconnue"));
|
||||||
}
|
}
|
||||||
})) : Uni.createFrom().nullItem())
|
})) : Uni.createFrom().nullItem())
|
||||||
)
|
)
|
||||||
.call(model -> ((model.getM3_lincence() != -1) ? combRepository.find("licence",
|
.call(model -> ((model.getM3_lincence() != -1) ? combRepository.find("licence",
|
||||||
model.getM3_lincence()).count().invoke(Unchecked.consumer(count -> {
|
model.getM3_lincence()).count().invoke(Unchecked.consumer(count -> {
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
throw new DBadRequestException("Licence membre n°3 inconnue");
|
throw new DBadRequestException(trad.t("licence.membre.n.3.inconnue"));
|
||||||
}
|
}
|
||||||
})) : Uni.createFrom().nullItem())
|
})) : Uni.createFrom().nullItem())
|
||||||
);
|
);
|
||||||
@@ -148,7 +151,7 @@ public class AffiliationService {
|
|||||||
public Uni<?> saveEdit(AffiliationRequestForm form) {
|
public Uni<?> saveEdit(AffiliationRequestForm form) {
|
||||||
return pre_save(form, false)
|
return pre_save(form, false)
|
||||||
.chain(model -> repositoryRequest.findById(form.getId())
|
.chain(model -> repositoryRequest.findById(form.getId())
|
||||||
.onItem().ifNull().failWith(new DNotFoundException("Demande d'affiliation non trouvé"))
|
.onItem().ifNull().failWith(new DNotFoundException(trad.t("demande.d.affiliation.non.trouve")))
|
||||||
.chain(origine -> {
|
.chain(origine -> {
|
||||||
origine.setName(model.getName());
|
origine.setName(model.getName());
|
||||||
origine.setAddress(model.getAddress());
|
origine.setAddress(model.getAddress());
|
||||||
@@ -201,7 +204,7 @@ public class AffiliationService {
|
|||||||
LOGGER.debug(form.toString());
|
LOGGER.debug(form.toString());
|
||||||
|
|
||||||
return repositoryRequest.findById(form.getId())
|
return repositoryRequest.findById(form.getId())
|
||||||
.onItem().ifNull().failWith(new DNotFoundException("Demande d'affiliation non trouvé"))
|
.onItem().ifNull().failWith(new DNotFoundException(trad.t("demande.d.affiliation.non.trouve")))
|
||||||
.map(model -> {
|
.map(model -> {
|
||||||
model.setName(form.getName());
|
model.setName(form.getName());
|
||||||
model.setState_id(form.getState_id());
|
model.setState_id(form.getState_id());
|
||||||
@@ -306,7 +309,7 @@ public class AffiliationService {
|
|||||||
LOGGER.debug(form.toString());
|
LOGGER.debug(form.toString());
|
||||||
|
|
||||||
return repositoryRequest.findById(form.getId())
|
return repositoryRequest.findById(form.getId())
|
||||||
.onItem().ifNull().failWith(new DNotFoundException("Demande d'affiliation non trouvé"))
|
.onItem().ifNull().failWith(new DNotFoundException(trad.t("demande.d.affiliation.non.trouve")))
|
||||||
.chain(req ->
|
.chain(req ->
|
||||||
clubRepository.find("StateId = ?1", form.getState_id()).firstResult()
|
clubRepository.find("StateId = ?1", form.getState_id()).firstResult()
|
||||||
.chain(model -> (model == null) ? acceptNew(form, req) : acceptOld(form, req, model))
|
.chain(model -> (model == null) ? acceptNew(form, req) : acceptOld(form, req, model))
|
||||||
@@ -398,7 +401,7 @@ public class AffiliationService {
|
|||||||
|
|
||||||
public Uni<SimpleReqAffiliation> getRequest(long id) {
|
public Uni<SimpleReqAffiliation> getRequest(long id) {
|
||||||
return repositoryRequest.findById(id).map(SimpleReqAffiliation::fromModel)
|
return repositoryRequest.findById(id).map(SimpleReqAffiliation::fromModel)
|
||||||
.onItem().ifNull().failWith(new DNotFoundException("Demande d'affiliation non trouvé"))
|
.onItem().ifNull().failWith(new DNotFoundException(trad.t("demande.d.affiliation.non.trouve")))
|
||||||
.call(out -> clubRepository.find("StateId = ?1", out.getStateId()).firstResult().invoke(c -> {
|
.call(out -> clubRepository.find("StateId = ?1", out.getStateId()).firstResult().invoke(c -> {
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
out.setClub(c.getId());
|
out.setClub(c.getId());
|
||||||
@@ -422,7 +425,7 @@ public class AffiliationService {
|
|||||||
|
|
||||||
public Uni<List<SimpleAffiliation>> getAffiliation(long id) {
|
public Uni<List<SimpleAffiliation>> getAffiliation(long id) {
|
||||||
return clubRepository.findById(id)
|
return clubRepository.findById(id)
|
||||||
.onItem().ifNull().failWith(new DNotFoundException("Club non trouvé"))
|
.onItem().ifNull().failWith(new DNotFoundException(trad.t("club.non.trouve")))
|
||||||
.call(model -> Mutiny.fetch(model.getAffiliations()))
|
.call(model -> Mutiny.fetch(model.getAffiliations()))
|
||||||
.chain(model -> repositoryRequest.list("state_id = ?1", model.getStateId())
|
.chain(model -> repositoryRequest.list("state_id = ?1", model.getStateId())
|
||||||
.map(reqs -> reqs.stream().map(req ->
|
.map(reqs -> reqs.stream().map(req ->
|
||||||
@@ -434,11 +437,11 @@ public class AffiliationService {
|
|||||||
|
|
||||||
public Uni<SimpleAffiliation> setAffiliation(long id, int saison) {
|
public Uni<SimpleAffiliation> setAffiliation(long id, int saison) {
|
||||||
return clubRepository.findById(id)
|
return clubRepository.findById(id)
|
||||||
.onItem().ifNull().failWith(new DNotFoundException("Club non trouvé"))
|
.onItem().ifNull().failWith(new DNotFoundException(trad.t("club.non.trouve")))
|
||||||
.call(model -> Mutiny.fetch(model.getAffiliations()))
|
.call(model -> Mutiny.fetch(model.getAffiliations()))
|
||||||
.invoke(Unchecked.consumer(club -> {
|
.invoke(Unchecked.consumer(club -> {
|
||||||
if (club.getAffiliations().stream().anyMatch(affiliation -> affiliation.getSaison() == saison)) {
|
if (club.getAffiliations().stream().anyMatch(affiliation -> affiliation.getSaison() == saison)) {
|
||||||
throw new DBadRequestException("Affiliation déjà existante");
|
throw new DBadRequestException(trad.t("affiliation.deja.existante"));
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.chain(club ->
|
.chain(club ->
|
||||||
|
|||||||
@@ -0,0 +1,227 @@
|
|||||||
|
package fr.titionfire.ffsaf.domain.service;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.CardModel;
|
||||||
|
import fr.titionfire.ffsaf.data.model.ClubCardModel;
|
||||||
|
import fr.titionfire.ffsaf.data.model.CompetitionModel;
|
||||||
|
import fr.titionfire.ffsaf.data.model.MatchModel;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.*;
|
||||||
|
import fr.titionfire.ffsaf.rest.exception.DBadRequestException;
|
||||||
|
import fr.titionfire.ffsaf.ws.recv.RCard;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.Panache;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
||||||
|
import io.quarkus.panache.common.Sort;
|
||||||
|
import io.smallrye.mutiny.Uni;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
import jakarta.inject.Inject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
@WithSession
|
||||||
|
@ApplicationScoped
|
||||||
|
public class CardService {
|
||||||
|
@Inject
|
||||||
|
CardRepository cardRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ClubCardRepository clubCardRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RegisterRepository registerRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CompetitionGuestRepository competitionGuestRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
MatchRepository matchRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
|
private static final List<CardModel.CardType> COMPETITION_LEVEL_CARDS = List.of(
|
||||||
|
CardModel.CardType.YELLOW,
|
||||||
|
CardModel.CardType.RED,
|
||||||
|
CardModel.CardType.BLACK
|
||||||
|
);
|
||||||
|
|
||||||
|
private List<Long> extractCombIds(MatchModel match) {
|
||||||
|
List<Long> ids = new ArrayList<>();
|
||||||
|
if (match.getC1_id() != null)
|
||||||
|
ids.add(match.getC1_id().getId());
|
||||||
|
if (match.getC2_id() != null)
|
||||||
|
ids.add(match.getC2_id().getId());
|
||||||
|
if (match.getC1_guest() != null)
|
||||||
|
ids.add(match.getC1_guest().getId() * -1);
|
||||||
|
if (match.getC2_guest() != null)
|
||||||
|
ids.add(match.getC2_guest().getId() * -1);
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<List<CardModel>> getForMatch(MatchModel match) {
|
||||||
|
return cardRepository.list(
|
||||||
|
"competition = ?1 AND (type IN ?2 OR (type = CardType.BLUE AND category = ?4)) AND comb IN ?3",
|
||||||
|
match.getCategory().getCompet(), COMPETITION_LEVEL_CARDS,
|
||||||
|
extractCombIds(match), match.getCategory().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<List<CardModel>> getAll(CompetitionModel competition) {
|
||||||
|
return cardRepository.list("competition = ?1", competition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<RCard.SendCardAdd> checkCanBeAdded(RCard.SendCardAdd card, MatchModel matchModel) {
|
||||||
|
return cardRepository.find("competition = ?1 AND comb = ?2",
|
||||||
|
Sort.descending("type"),
|
||||||
|
matchModel.getCategory().getCompet(), card.combId())
|
||||||
|
.firstResult()
|
||||||
|
.map(card_ -> {
|
||||||
|
if (card.type() == CardModel.CardType.BLUE) {
|
||||||
|
return card_ == null || (card_.getType() == CardModel.CardType.BLUE
|
||||||
|
&& !Objects.equals(card_.getCategory(), matchModel.getCategory().getId()));
|
||||||
|
}
|
||||||
|
if (card.type() == CardModel.CardType.BLACK) {
|
||||||
|
return card_ != null && card_.getType() == CardModel.CardType.RED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return card_ == null || card_.getType().ordinal() < card.type().ordinal();
|
||||||
|
})
|
||||||
|
.chain(b -> {
|
||||||
|
if (b)
|
||||||
|
return Uni.createFrom().item(card);
|
||||||
|
else
|
||||||
|
return Uni.createFrom().failure(new DBadRequestException(trad.t("card.cannot.be.added")));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<List<CardModel>> addTeamCartToNewComb(Long combId, String teamUuid, String teamName,
|
||||||
|
CompetitionModel competition) {
|
||||||
|
return clubCardRepository.list("competition = ?1 AND (teamUuid = ?2 OR teamName = ?3)",
|
||||||
|
Sort.ascending("type"), competition.getId(), teamUuid, teamName)
|
||||||
|
.chain(clubCards -> {
|
||||||
|
Uni<?> queue = Uni.createFrom().voidItem();
|
||||||
|
List<CardModel> addCards = new ArrayList<>();
|
||||||
|
for (ClubCardModel clubCard : clubCards) {
|
||||||
|
CardModel model = new CardModel();
|
||||||
|
model.setCompetition(competition);
|
||||||
|
model.setCompetitionId(competition.getId());
|
||||||
|
model.setComb(combId);
|
||||||
|
model.setTeamCard(true);
|
||||||
|
model.setType(clubCard.getType());
|
||||||
|
model.setDate(clubCard.getDate());
|
||||||
|
|
||||||
|
queue = queue.call(__ -> Panache.withTransaction(() -> cardRepository.persist(model))
|
||||||
|
.invoke(addCards::add)
|
||||||
|
.call(() -> {
|
||||||
|
clubCard.getCardIds().add(model.getId());
|
||||||
|
return Panache.withTransaction(() -> clubCardRepository.persist(clubCard));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
return queue.replaceWith(addCards);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<Void> rmTeamCardFromComb(Long combId, String uuid) {
|
||||||
|
return cardRepository.delete("comb = ?1 AND competition.uuid = ?2 AND teamCard = True", combId, uuid)
|
||||||
|
.replaceWithVoid();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<List<CardModel>> addTeamCard(CompetitionModel competition, String teamUuid, String teamName,
|
||||||
|
CardModel.CardType type, String reason) {
|
||||||
|
return clubCardRepository.find("competition = ?1 AND (teamUuid = ?2 OR teamName = ?3)",
|
||||||
|
Sort.descending("type"), competition.getId(), teamUuid, teamName)
|
||||||
|
.firstResult()
|
||||||
|
.map(card_ -> {
|
||||||
|
if (type == CardModel.CardType.BLACK) {
|
||||||
|
return card_ != null && card_.getType() == CardModel.CardType.RED;
|
||||||
|
}
|
||||||
|
|
||||||
|
return card_ == null || card_.getType().ordinal() < type.ordinal();
|
||||||
|
})
|
||||||
|
.chain(b -> {
|
||||||
|
if (!b)
|
||||||
|
return Uni.createFrom().failure(new DBadRequestException(trad.t("card.cannot.be.added")));
|
||||||
|
|
||||||
|
if (teamUuid != null) {
|
||||||
|
return registerRepository.list("competition = ?1 AND club.clubId = ?2", competition, teamUuid)
|
||||||
|
.map(l -> l.stream().map(r -> r.getMembre().getId()).toList());
|
||||||
|
} else {
|
||||||
|
return competitionGuestRepository.list("competition = ?1 AND club = ?2", competition,
|
||||||
|
teamName)
|
||||||
|
.map(l -> l.stream().map(r -> r.getId() * -1).toList());
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.chain(combIds -> cardRepository.list("competition = ?1 AND comb IN ?2", competition, combIds)
|
||||||
|
.map(cards -> {
|
||||||
|
List<CardModel> newCards = new ArrayList<>();
|
||||||
|
for (Long id : combIds) {
|
||||||
|
Optional<CardModel> optional = cards.stream()
|
||||||
|
.filter(c -> id.equals(c.getComb()) && c.getType() == type).findAny();
|
||||||
|
|
||||||
|
CardModel model = new CardModel();
|
||||||
|
model.setCompetition(competition);
|
||||||
|
model.setCompetitionId(competition.getId());
|
||||||
|
model.setComb(id);
|
||||||
|
model.setTeamCard(true);
|
||||||
|
|
||||||
|
if (optional.isEmpty()) {
|
||||||
|
model.setType(type);
|
||||||
|
} else {
|
||||||
|
model.setType(
|
||||||
|
CardModel.CardType.values()[Math.min(optional.get().getType().ordinal() + 1,
|
||||||
|
CardModel.CardType.BLACK.ordinal())]);
|
||||||
|
}
|
||||||
|
newCards.add(model);
|
||||||
|
}
|
||||||
|
return newCards;
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.call(newCards -> Panache.withTransaction(() -> cardRepository.persist(newCards)))
|
||||||
|
.call(newCards -> {
|
||||||
|
ClubCardModel model = new ClubCardModel();
|
||||||
|
model.setCompetition(competition.getId());
|
||||||
|
model.setTeamUuid(teamUuid);
|
||||||
|
model.setTeamName(teamName);
|
||||||
|
model.setType(type);
|
||||||
|
model.setReason(reason);
|
||||||
|
model.setCardIds(newCards.stream().map(CardModel::getId).toList());
|
||||||
|
|
||||||
|
return Panache.withTransaction(() -> clubCardRepository.persist(model));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<List<CardModel>> recvReturnState(CompetitionModel competition, RCard.SendTeamCardReturnState state) {
|
||||||
|
return clubCardRepository.find("competition = ?1 AND (teamUuid = ?2 OR teamName = ?3) AND type = ?4",
|
||||||
|
competition.getId(), state.teamUuid(), state.teamName(), state.type())
|
||||||
|
.firstResult()
|
||||||
|
.chain(o -> cardRepository.list("id IN ?1", o.getCardIds()))
|
||||||
|
.call(cards -> matchRepository.list("category.compet = ?1 AND category.id IN ?2", competition,
|
||||||
|
state.selectedCategory())
|
||||||
|
.invoke(matches -> {
|
||||||
|
for (CardModel card : cards) {
|
||||||
|
for (MatchModel m : matches.stream()
|
||||||
|
.filter(m -> extractCombIds(m).contains(card.getComb())).toList()) {
|
||||||
|
|
||||||
|
if (state.state() == 1) {
|
||||||
|
card.setCategory(m.getCategory().getId());
|
||||||
|
} else if (state.state() == 2) {
|
||||||
|
card.setCategory(m.getCategory().getId());
|
||||||
|
if (Objects.equals(m.getId(), state.selectedMatch()))
|
||||||
|
card.setMatch(m.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.chain(() -> Panache.withTransaction(() -> cardRepository.persist(cards))));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<List<Long>> rmTeamCard(CompetitionModel competition, String teamUuid, String teamName,
|
||||||
|
CardModel.CardType type) {
|
||||||
|
return clubCardRepository.find("competition = ?1 AND (teamUuid = ?2 OR teamName = ?3) AND type = ?4",
|
||||||
|
competition.getId(), teamUuid, teamName, type)
|
||||||
|
.firstResult()
|
||||||
|
.chain(card -> Uni.createFrom().item(card.getCardIds())
|
||||||
|
.call(() -> Panache.withTransaction(() -> cardRepository.delete("id IN ?1", card.getCardIds())))
|
||||||
|
.call(() -> Panache.withTransaction(() -> clubCardRepository.delete(card))));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,10 +45,13 @@ public class CategoryService {
|
|||||||
@Inject
|
@Inject
|
||||||
CompetitionGuestRepository competitionGuestRepository;
|
CompetitionGuestRepository competitionGuestRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
public Uni<CategoryData> getByIdAdmin(SecurityCtx securityCtx, CompetitionSystem system, Long id) {
|
public Uni<CategoryData> getByIdAdmin(SecurityCtx securityCtx, CompetitionSystem system, Long id) {
|
||||||
return repository.find("systemId = ?1 AND system = ?2", id, system)
|
return repository.find("systemId = ?1 AND system = ?2", id, system)
|
||||||
.firstResult()
|
.firstResult()
|
||||||
.onItem().ifNull().failWith(() -> new RuntimeException("Category not found"))
|
.onItem().ifNull().failWith(() -> new RuntimeException(trad.t("categorie.non.trouver")))
|
||||||
.call(data -> permService.hasAdminViewPerm(securityCtx, data.getCompet()))
|
.call(data -> permService.hasAdminViewPerm(securityCtx, data.getCompet()))
|
||||||
.map(CategoryData::fromModel);
|
.map(CategoryData::fromModel);
|
||||||
}
|
}
|
||||||
@@ -64,7 +67,7 @@ public class CategoryService {
|
|||||||
.chain(o -> {
|
.chain(o -> {
|
||||||
if (o == null) {
|
if (o == null) {
|
||||||
return competRepository.findById(data.getCompet())
|
return competRepository.findById(data.getCompet())
|
||||||
.onItem().ifNull().failWith(() -> new RuntimeException("Competition not found"))
|
.onItem().ifNull().failWith(() -> new RuntimeException(trad.t("competition.not.found")))
|
||||||
.call(o2 -> permService.hasEditPerm(securityCtx, o2))
|
.call(o2 -> permService.hasEditPerm(securityCtx, o2))
|
||||||
.chain(competitionModel -> {
|
.chain(competitionModel -> {
|
||||||
CategoryModel model = new CategoryModel();
|
CategoryModel model = new CategoryModel();
|
||||||
@@ -139,7 +142,7 @@ public class CategoryService {
|
|||||||
.onItem().ifNotNull().call(o2 -> permService.hasEditPerm(securityCtx, o2.getCompet()))
|
.onItem().ifNotNull().call(o2 -> permService.hasEditPerm(securityCtx, o2.getCompet()))
|
||||||
.onItem().ifNull().switchTo(
|
.onItem().ifNull().switchTo(
|
||||||
() -> competRepository.findById(data.getCompet())
|
() -> competRepository.findById(data.getCompet())
|
||||||
.onItem().ifNull().failWith(() -> new RuntimeException("Compet not found"))
|
.onItem().ifNull().failWith(() -> new RuntimeException(trad.t("competition.not.found")))
|
||||||
.call(o -> permService.hasEditPerm(securityCtx, o))
|
.call(o -> permService.hasEditPerm(securityCtx, o))
|
||||||
.map(o -> {
|
.map(o -> {
|
||||||
CategoryModel model = new CategoryModel();
|
CategoryModel model = new CategoryModel();
|
||||||
@@ -256,7 +259,7 @@ public class CategoryService {
|
|||||||
|
|
||||||
public Uni<?> delete(SecurityCtx securityCtx, CompetitionSystem system, Long id) {
|
public Uni<?> delete(SecurityCtx securityCtx, CompetitionSystem system, Long id) {
|
||||||
return repository.find("systemId = ?1 AND system = ?2", id, system).firstResult()
|
return repository.find("systemId = ?1 AND system = ?2", id, system).firstResult()
|
||||||
.onItem().ifNull().failWith(() -> new RuntimeException("Category not found"))
|
.onItem().ifNull().failWith(() -> new RuntimeException(trad.t("categorie.non.trouver")))
|
||||||
.call(o -> permService.hasEditPerm(securityCtx, o.getCompet()))
|
.call(o -> permService.hasEditPerm(securityCtx, o.getCompet()))
|
||||||
.call(o -> Mutiny.fetch(o.getTree())
|
.call(o -> Mutiny.fetch(o.getTree())
|
||||||
.call(o2 -> o2.isEmpty() ? Uni.createFrom().nullItem() :
|
.call(o2 -> o2.isEmpty() ? Uni.createFrom().nullItem() :
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ public class ClubService {
|
|||||||
@Inject
|
@Inject
|
||||||
LoggerService ls;
|
LoggerService ls;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
public SimpleClubModel findByIdOptionalClub(long id) throws Throwable {
|
public SimpleClubModel findByIdOptionalClub(long id) throws Throwable {
|
||||||
return VertxContextSupport.subscribeAndAwait(
|
return VertxContextSupport.subscribeAndAwait(
|
||||||
() -> Panache.withTransaction(() -> repository.findById(id).map(SimpleClubModel::fromModel)));
|
() -> Panache.withTransaction(() -> repository.findById(id).map(SimpleClubModel::fromModel)));
|
||||||
@@ -130,7 +133,7 @@ public class ClubService {
|
|||||||
return combRepository.find("userId = ?1", securityCtx.getSubject()).firstResult()
|
return combRepository.find("userId = ?1", securityCtx.getSubject()).firstResult()
|
||||||
.invoke(Unchecked.consumer(m -> {
|
.invoke(Unchecked.consumer(m -> {
|
||||||
if (m == null || m.getClub() == null)
|
if (m == null || m.getClub() == null)
|
||||||
throw new DNotFoundException("Club non trouvé");
|
throw new DNotFoundException(trad.t("club.non.trouve"));
|
||||||
}))
|
}))
|
||||||
.map(MembreModel::getClub)
|
.map(MembreModel::getClub)
|
||||||
.call(club -> Mutiny.fetch(club.getContact()));
|
.call(club -> Mutiny.fetch(club.getContact()));
|
||||||
@@ -150,7 +153,7 @@ public class ClubService {
|
|||||||
return combRepository.find("userId = ?1", securityCtx.getSubject()).firstResult()
|
return combRepository.find("userId = ?1", securityCtx.getSubject()).firstResult()
|
||||||
.invoke(Unchecked.consumer(m -> {
|
.invoke(Unchecked.consumer(m -> {
|
||||||
if (m == null || m.getClub() == null)
|
if (m == null || m.getClub() == null)
|
||||||
throw new DNotFoundException("Club non trouvé");
|
throw new DNotFoundException(trad.t("club.non.trouve"));
|
||||||
if (!securityCtx.isInClubGroup(m.getClub().getId()))
|
if (!securityCtx.isInClubGroup(m.getClub().getId()))
|
||||||
throw new DForbiddenException();
|
throw new DForbiddenException();
|
||||||
}))
|
}))
|
||||||
@@ -166,7 +169,7 @@ public class ClubService {
|
|||||||
return combRepository.find("userId = ?1", securityCtx.getSubject()).firstResult()
|
return combRepository.find("userId = ?1", securityCtx.getSubject()).firstResult()
|
||||||
.invoke(Unchecked.consumer(m -> {
|
.invoke(Unchecked.consumer(m -> {
|
||||||
if (m == null || m.getClub() == null)
|
if (m == null || m.getClub() == null)
|
||||||
throw new DNotFoundException("Club non trouvé");
|
throw new DNotFoundException(trad.t("club.non.trouve"));
|
||||||
if (!securityCtx.isInClubGroup(m.getClub().getId()))
|
if (!securityCtx.isInClubGroup(m.getClub().getId()))
|
||||||
throw new DForbiddenException();
|
throw new DForbiddenException();
|
||||||
}))
|
}))
|
||||||
@@ -183,7 +186,7 @@ public class ClubService {
|
|||||||
ls.logUpdate("Contact(s)...", club);
|
ls.logUpdate("Contact(s)...", club);
|
||||||
club.setContact(MAPPER.readValue(form.getContact(), typeRef));
|
club.setContact(MAPPER.readValue(form.getContact(), typeRef));
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
throw new DBadRequestException("Erreur de format des contacts");
|
throw new DBadRequestException(trad.t("erreur.de.format.des.contacts"));
|
||||||
}
|
}
|
||||||
|
|
||||||
ls.logChange("Lieux d'entrainements", club.getTraining_location(), form.getTraining_location(),
|
ls.logChange("Lieux d'entrainements", club.getTraining_location(), form.getTraining_location(),
|
||||||
@@ -233,7 +236,7 @@ public class ClubService {
|
|||||||
ls.logUpdate("Contact(s)...", m);
|
ls.logUpdate("Contact(s)...", m);
|
||||||
m.setContact(MAPPER.readValue(input.getContact(), typeRef));
|
m.setContact(MAPPER.readValue(input.getContact(), typeRef));
|
||||||
} catch (JsonProcessingException e) {
|
} catch (JsonProcessingException e) {
|
||||||
throw new DBadRequestException("Erreur de format des contacts");
|
throw new DBadRequestException(trad.t("erreur.de.format.des.contacts"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Panache.withTransaction(() -> repository.persist(m)).call(() -> ls.append());
|
return Panache.withTransaction(() -> repository.persist(m)).call(() -> ls.append());
|
||||||
|
|||||||
@@ -98,12 +98,14 @@ public class CompetPermService {
|
|||||||
map.putIfAbsent(model.getId(), "owner");
|
map.putIfAbsent(model.getId(), "owner");
|
||||||
else if (securityCtx.roleHas("federation_admin"))
|
else if (securityCtx.roleHas("federation_admin"))
|
||||||
map.putIfAbsent(model.getId(), "admin");
|
map.putIfAbsent(model.getId(), "admin");
|
||||||
else if (securityCtx.isInClubGroup(model.getClub().getId()) && (securityCtx.roleHas(
|
else if (securityCtx.isInClubGroup(
|
||||||
"club_president")
|
model.getClub().getId()) && (securityCtx.isClubAdmin()))
|
||||||
|| securityCtx.roleHas("club_respo_intra") || securityCtx.roleHas(
|
|
||||||
"club_secretaire")
|
|
||||||
|| securityCtx.roleHas("club_tresorier")))
|
|
||||||
map.putIfAbsent(model.getId(), "admin");
|
map.putIfAbsent(model.getId(), "admin");
|
||||||
|
else if (model.getAdmin().contains(securityCtx.getSubject()))
|
||||||
|
map.putIfAbsent(model.getId(), "admin");
|
||||||
|
else if (model.getTable().contains(securityCtx.getSubject()))
|
||||||
|
map.putIfAbsent(model.getId(), "table");
|
||||||
|
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}));
|
}));
|
||||||
@@ -182,12 +184,14 @@ public class CompetPermService {
|
|||||||
if (o.getSystem() == CompetitionSystem.SAFCA)
|
if (o.getSystem() == CompetitionSystem.SAFCA)
|
||||||
return hasSafcaViewPerm(securityCtx, o.getId());
|
return hasSafcaViewPerm(securityCtx, o.getId());
|
||||||
|
|
||||||
|
if (o.getAdmin().contains(securityCtx.getSubject()))
|
||||||
|
return Uni.createFrom().nullItem();
|
||||||
|
|
||||||
if (!securityCtx.isInClubGroup(o.getClub().getId())) // Only membre club pass here
|
if (!securityCtx.isInClubGroup(o.getClub().getId())) // Only membre club pass here
|
||||||
throw new DForbiddenException();
|
throw new DForbiddenException();
|
||||||
|
|
||||||
if (o.getSystem() == CompetitionSystem.INTERNAL)
|
if (o.getSystem() == CompetitionSystem.INTERNAL)
|
||||||
if (securityCtx.roleHas("club_president") || securityCtx.roleHas("club_respo_intra")
|
if (securityCtx.isClubAdmin())
|
||||||
|| securityCtx.roleHas("club_secretaire") || securityCtx.roleHas("club_tresorier"))
|
|
||||||
return Uni.createFrom().nullItem();
|
return Uni.createFrom().nullItem();
|
||||||
|
|
||||||
throw new DForbiddenException();
|
throw new DForbiddenException();
|
||||||
|
|||||||
@@ -7,10 +7,7 @@ import fr.titionfire.ffsaf.net2.data.SimpleCompet;
|
|||||||
import fr.titionfire.ffsaf.net2.request.SReqCompet;
|
import fr.titionfire.ffsaf.net2.request.SReqCompet;
|
||||||
import fr.titionfire.ffsaf.net2.request.SReqRegister;
|
import fr.titionfire.ffsaf.net2.request.SReqRegister;
|
||||||
import fr.titionfire.ffsaf.rest.client.dto.NotificationData;
|
import fr.titionfire.ffsaf.rest.client.dto.NotificationData;
|
||||||
import fr.titionfire.ffsaf.rest.data.CompetitionData;
|
import fr.titionfire.ffsaf.rest.data.*;
|
||||||
import fr.titionfire.ffsaf.rest.data.RegisterRequestData;
|
|
||||||
import fr.titionfire.ffsaf.rest.data.SimpleCompetData;
|
|
||||||
import fr.titionfire.ffsaf.rest.data.SimpleRegisterComb;
|
|
||||||
import fr.titionfire.ffsaf.rest.exception.DBadRequestException;
|
import fr.titionfire.ffsaf.rest.exception.DBadRequestException;
|
||||||
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
||||||
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
|
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
|
||||||
@@ -63,6 +60,9 @@ public class CompetitionService {
|
|||||||
@Inject
|
@Inject
|
||||||
CompetitionGuestRepository competitionGuestRepository;
|
CompetitionGuestRepository competitionGuestRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CatPresetRepository catPresetRepository;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ServerCustom serverCustom;
|
ServerCustom serverCustom;
|
||||||
|
|
||||||
@@ -97,21 +97,29 @@ public class CompetitionService {
|
|||||||
@CacheName("have-access")
|
@CacheName("have-access")
|
||||||
Cache cacheNoneAccess;
|
Cache cacheNoneAccess;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
public Uni<CompetitionData> getById(SecurityCtx securityCtx, Long id) {
|
public Uni<CompetitionData> getById(SecurityCtx securityCtx, Long id) {
|
||||||
return permService.hasViewPerm(securityCtx, id).map(CompetitionData::fromModelLight);
|
return permService.hasViewPerm(securityCtx, id).map(cm -> {
|
||||||
|
CompetitionData out = CompetitionData.fromModelLight(cm);
|
||||||
|
if (cm.getAdmin() != null) {
|
||||||
|
out.setCanEditRegisters(cm.getAdmin().stream().anyMatch(u -> u.equals(securityCtx.getSubject())));
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<CompetitionData> getByIdAdmin(SecurityCtx securityCtx, Long id) {
|
public Uni<CompetitionData> getByIdAdmin(SecurityCtx securityCtx, Long id) {
|
||||||
if (id == 0) {
|
if (id == 0) {
|
||||||
return Uni.createFrom()
|
return Uni.createFrom().item(new CompetitionData());
|
||||||
.item(new CompetitionData(null, "", "", "", "", new Date(), new Date(),
|
|
||||||
CompetitionSystem.INTERNAL, RegisterMode.FREE, new Date(), new Date(), true,
|
|
||||||
null, "", "", null, true, "", "", "", ""));
|
|
||||||
}
|
}
|
||||||
return permService.hasAdminViewPerm(securityCtx, id)
|
return permService.hasAdminViewPerm(securityCtx, id)
|
||||||
|
.call(competitionModel -> Mutiny.fetch(competitionModel.getCatPreset()))
|
||||||
.chain(competitionModel -> Mutiny.fetch(competitionModel.getInsc())
|
.chain(competitionModel -> Mutiny.fetch(competitionModel.getInsc())
|
||||||
.chain(insc -> Mutiny.fetch(competitionModel.getGuests())
|
.chain(insc -> Mutiny.fetch(competitionModel.getGuests())
|
||||||
.map(guest -> CompetitionData.fromModel(competitionModel).addInsc(insc, guest))))
|
.map(guest -> CompetitionData.fromModel(competitionModel).addInsc(insc, guest)
|
||||||
|
.addPresets(competitionModel.getCatPreset()))))
|
||||||
.chain(data ->
|
.chain(data ->
|
||||||
vertx.getOrCreateContext().executeBlocking(() -> {
|
vertx.getOrCreateContext().executeBlocking(() -> {
|
||||||
keycloakService.getUser(UUID.fromString(data.getOwner()))
|
keycloakService.getUser(UUID.fromString(data.getOwner()))
|
||||||
@@ -129,6 +137,14 @@ public class CompetitionService {
|
|||||||
out.addAll(cm.stream().map(CompetitionData::fromModelLight).toList());
|
out.addAll(cm.stream().map(CompetitionData::fromModelLight).toList());
|
||||||
out.forEach(competition -> competition.setCanEdit(true));
|
out.forEach(competition -> competition.setCanEdit(true));
|
||||||
}))
|
}))
|
||||||
|
.chain(ids -> repository.list("id NOT IN ?1 AND ?2 IN admin", ids, securityCtx.getSubject())
|
||||||
|
.map(cm -> {
|
||||||
|
out.addAll(cm.stream().map(CompetitionData::fromModelLight).toList());
|
||||||
|
out.forEach(competition -> competition.setCanEditRegisters(true));
|
||||||
|
List<Long> ids2 = new ArrayList<>(ids);
|
||||||
|
ids2.addAll(cm.stream().map(CompetitionModel::getId).toList());
|
||||||
|
return ids2;
|
||||||
|
}))
|
||||||
.call(ids ->
|
.call(ids ->
|
||||||
repository.list("id NOT IN ?1 AND (publicVisible = TRUE OR registerMode IN ?2)", ids,
|
repository.list("id NOT IN ?1 AND (publicVisible = TRUE OR registerMode IN ?2)", ids,
|
||||||
securityCtx.isClubAdmin() ? List.of(RegisterMode.FREE, RegisterMode.HELLOASSO,
|
securityCtx.isClubAdmin() ? List.of(RegisterMode.FREE, RegisterMode.HELLOASSO,
|
||||||
@@ -165,8 +181,9 @@ public class CompetitionService {
|
|||||||
public Uni<List<CompetitionData>> getAllSystemTable(SecurityCtx securityCtx,
|
public Uni<List<CompetitionData>> getAllSystemTable(SecurityCtx securityCtx,
|
||||||
CompetitionSystem system) {
|
CompetitionSystem system) {
|
||||||
return repository.list("system = ?1", system)
|
return repository.list("system = ?1", system)
|
||||||
.chain(l -> Uni.join().all(l.stream().map(cm -> permService.hasTablePerm(securityCtx, cm)).toList())
|
.chain(l -> Uni.join().all(l.stream().map(cm ->
|
||||||
.andCollectFailures())
|
permService.hasTablePerm(securityCtx, cm).onFailure().recoverWithNull()
|
||||||
|
).toList()).andCollectFailures())
|
||||||
.map(l -> l.stream().filter(Objects::nonNull).map(CompetitionData::fromModel).toList());
|
.map(l -> l.stream().filter(Objects::nonNull).map(CompetitionData::fromModel).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,7 +193,7 @@ public class CompetitionService {
|
|||||||
.invoke(Unchecked.consumer(combModel -> {
|
.invoke(Unchecked.consumer(combModel -> {
|
||||||
if (!securityCtx.getRoles().contains("create_compet") && !securityCtx.getRoles()
|
if (!securityCtx.getRoles().contains("create_compet") && !securityCtx.getRoles()
|
||||||
.contains("federation_admin"))
|
.contains("federation_admin"))
|
||||||
throw new DForbiddenException("Vous ne pouvez pas créer de compétition");
|
throw new DForbiddenException(trad.t("vous.ne.pouvez.pas.creer.de.competition"));
|
||||||
}))
|
}))
|
||||||
.map(MembreModel::getClub)
|
.map(MembreModel::getClub)
|
||||||
.chain(clubModel -> {
|
.chain(clubModel -> {
|
||||||
@@ -189,17 +206,21 @@ public class CompetitionService {
|
|||||||
model.setGuests(new ArrayList<>());
|
model.setGuests(new ArrayList<>());
|
||||||
model.setUuid(UUID.randomUUID().toString());
|
model.setUuid(UUID.randomUUID().toString());
|
||||||
model.setOwner(securityCtx.getSubject());
|
model.setOwner(securityCtx.getSubject());
|
||||||
|
model.setCatPreset(new ArrayList<>());
|
||||||
|
|
||||||
copyData(data, model);
|
copyData(data, model);
|
||||||
|
|
||||||
return Panache.withTransaction(() -> repository.persist(model));
|
return Panache.withTransaction(() -> repository.persist(model));
|
||||||
}).map(CompetitionData::fromModel)
|
})
|
||||||
|
.call(model -> syncPreset(data, model))
|
||||||
|
.map(CompetitionData::fromModel)
|
||||||
.call(c -> (c.getSystem() == CompetitionSystem.SAFCA) ? cacheAccess.invalidate(
|
.call(c -> (c.getSystem() == CompetitionSystem.SAFCA) ? cacheAccess.invalidate(
|
||||||
securityCtx.getSubject()) : Uni.createFrom().nullItem())
|
securityCtx.getSubject()) : Uni.createFrom().nullItem())
|
||||||
.call(c -> (c.getSystem() == CompetitionSystem.INTERNAL) ? cacheNoneAccess.invalidate(
|
.call(c -> (c.getSystem() == CompetitionSystem.INTERNAL) ? cacheNoneAccess.invalidate(
|
||||||
securityCtx.getSubject()) : Uni.createFrom().nullItem());
|
securityCtx.getSubject()) : Uni.createFrom().nullItem());
|
||||||
} else {
|
} else {
|
||||||
return permService.hasEditPerm(securityCtx, data.getId())
|
return permService.hasEditPerm(securityCtx, data.getId())
|
||||||
|
.call(model -> Mutiny.fetch(model.getCatPreset()))
|
||||||
.chain(model -> {
|
.chain(model -> {
|
||||||
copyData(data, model);
|
copyData(data, model);
|
||||||
|
|
||||||
@@ -207,7 +228,8 @@ public class CompetitionService {
|
|||||||
keycloakService.getUser(data.getOwner()).map(UserRepresentation::getId).orElse(null))
|
keycloakService.getUser(data.getOwner()).map(UserRepresentation::getId).orElse(null))
|
||||||
.invoke(Unchecked.consumer(newOwner -> {
|
.invoke(Unchecked.consumer(newOwner -> {
|
||||||
if (newOwner == null)
|
if (newOwner == null)
|
||||||
throw new DBadRequestException("User " + data.getOwner() + " not found");
|
throw new DBadRequestException(
|
||||||
|
String.format(trad.t("user.not.found"), data.getOwner()));
|
||||||
if (!newOwner.equals(model.getOwner())) {
|
if (!newOwner.equals(model.getOwner())) {
|
||||||
if (!securityCtx.roleHas("federation_admin")
|
if (!securityCtx.roleHas("federation_admin")
|
||||||
&& !securityCtx.roleHas("safca_super_admin")
|
&& !securityCtx.roleHas("safca_super_admin")
|
||||||
@@ -217,7 +239,9 @@ public class CompetitionService {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.chain(__ -> Panache.withTransaction(() -> repository.persist(model)));
|
.chain(__ -> Panache.withTransaction(() -> repository.persist(model)));
|
||||||
}).map(CompetitionData::fromModel)
|
})
|
||||||
|
.call(model -> syncPreset(data, model))
|
||||||
|
.map(model -> CompetitionData.fromModel(model).addPresets(model.getCatPreset()))
|
||||||
.call(c -> (c.getSystem() == CompetitionSystem.SAFCA) ? cacheAccess.invalidate(
|
.call(c -> (c.getSystem() == CompetitionSystem.SAFCA) ? cacheAccess.invalidate(
|
||||||
securityCtx.getSubject()) : Uni.createFrom().nullItem())
|
securityCtx.getSubject()) : Uni.createFrom().nullItem())
|
||||||
.call(c -> (c.getSystem() == CompetitionSystem.INTERNAL) ? cacheNoneAccess.invalidate(
|
.call(c -> (c.getSystem() == CompetitionSystem.INTERNAL) ? cacheNoneAccess.invalidate(
|
||||||
@@ -225,6 +249,45 @@ public class CompetitionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Uni<?> syncPreset(CompetitionData data, CompetitionModel model) {
|
||||||
|
List<Long> toRemoveId = model.getCatPreset().stream()
|
||||||
|
.map(CatPresetModel::getId)
|
||||||
|
.filter(id -> data.getPresets().stream().noneMatch(preset -> Objects.equals(preset.getId(), id)))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
for (PresetData preset : data.getPresets()) {
|
||||||
|
CatPresetModel presetModel;
|
||||||
|
if (preset.getId() != null && preset.getId() > 0) {
|
||||||
|
presetModel = model.getCatPreset().stream()
|
||||||
|
.filter(p -> p.getId().equals(preset.getId()))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(new CatPresetModel());
|
||||||
|
} else {
|
||||||
|
presetModel = new CatPresetModel();
|
||||||
|
model.getCatPreset().add(presetModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
presetModel.setCompetition(model);
|
||||||
|
presetModel.setName(preset.getName());
|
||||||
|
presetModel.setSwordType(preset.getSword());
|
||||||
|
presetModel.setShieldType(preset.getShield());
|
||||||
|
presetModel.setCategories(preset.getCategories());
|
||||||
|
presetModel.setMandatoryProtection1(preset.getMandatoryProtection1());
|
||||||
|
presetModel.setMandatoryProtection2(preset.getMandatoryProtection2());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove deleted presets
|
||||||
|
model.getCatPreset().removeIf(presetModel -> toRemoveId.contains(presetModel.getId()));
|
||||||
|
|
||||||
|
return Panache.withTransaction(() -> repository.persist(model)
|
||||||
|
.call(__ -> {
|
||||||
|
if (!toRemoveId.isEmpty()) {
|
||||||
|
return catPresetRepository.delete("id IN ?1", toRemoveId);
|
||||||
|
}
|
||||||
|
return Uni.createFrom().nullItem();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
private void copyData(CompetitionData data, CompetitionModel model) {
|
private void copyData(CompetitionData data, CompetitionModel model) {
|
||||||
if (model.getBanMembre() == null)
|
if (model.getBanMembre() == null)
|
||||||
model.setBanMembre(new ArrayList<>());
|
model.setBanMembre(new ArrayList<>());
|
||||||
@@ -238,6 +301,7 @@ public class CompetitionService {
|
|||||||
model.setStartRegister(data.getStartRegister());
|
model.setStartRegister(data.getStartRegister());
|
||||||
model.setEndRegister(data.getEndRegister());
|
model.setEndRegister(data.getEndRegister());
|
||||||
model.setRegisterMode(data.getRegisterMode());
|
model.setRegisterMode(data.getRegisterMode());
|
||||||
|
model.setRequiredWeight(data.getRequiredWeight());
|
||||||
model.setData1(data.getData1());
|
model.setData1(data.getData1());
|
||||||
model.setData2(data.getData2());
|
model.setData2(data.getData2());
|
||||||
model.setData3(data.getData3());
|
model.setData3(data.getData3());
|
||||||
@@ -251,11 +315,18 @@ public class CompetitionService {
|
|||||||
Uni<List<SimpleRegisterComb>> uni = Mutiny.fetch(c.getInsc())
|
Uni<List<SimpleRegisterComb>> uni = Mutiny.fetch(c.getInsc())
|
||||||
.onItem().transformToMulti(Multi.createFrom()::iterable)
|
.onItem().transformToMulti(Multi.createFrom()::iterable)
|
||||||
.onItem().call(combModel -> Mutiny.fetch(combModel.getMembre().getLicences()))
|
.onItem().call(combModel -> Mutiny.fetch(combModel.getMembre().getLicences()))
|
||||||
.map(cm -> SimpleRegisterComb.fromModel(cm, cm.getMembre().getLicences()))
|
.onItem().call(combModel -> Mutiny.fetch(combModel.getCategoriesInscrites()))
|
||||||
|
.map(cm -> SimpleRegisterComb.fromModel(cm, cm.getMembre().getLicences())
|
||||||
|
.setCategorieInscrite(cm.getCategoriesInscrites()))
|
||||||
.collect().asList();
|
.collect().asList();
|
||||||
return uni
|
return uni
|
||||||
.call(l -> Mutiny.fetch(c.getGuests())
|
.call(l -> Mutiny.fetch(c.getGuests())
|
||||||
.map(guest -> guest.stream().map(SimpleRegisterComb::fromModel).toList())
|
.onItem().transformToMulti(Multi.createFrom()::iterable)
|
||||||
|
.filter(g -> !g.isTeam())
|
||||||
|
.onItem().call(guest -> Mutiny.fetch(guest.getCategoriesInscrites()))
|
||||||
|
.map(guest -> SimpleRegisterComb.fromModel(guest)
|
||||||
|
.setCategorieInscrite(guest.getCategoriesInscrites()))
|
||||||
|
.collect().asList()
|
||||||
.invoke(l::addAll));
|
.invoke(l::addAll));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -270,12 +341,17 @@ public class CompetitionService {
|
|||||||
model.getClub()))
|
model.getClub()))
|
||||||
.onItem().transformToMulti(Multi.createFrom()::iterable)
|
.onItem().transformToMulti(Multi.createFrom()::iterable)
|
||||||
.onItem().call(combModel -> Mutiny.fetch(combModel.getMembre().getLicences()))
|
.onItem().call(combModel -> Mutiny.fetch(combModel.getMembre().getLicences()))
|
||||||
.map(combModel -> SimpleRegisterComb.fromModel(combModel, combModel.getMembre().getLicences()))
|
.onItem().call(combModel -> Mutiny.fetch(combModel.getCategoriesInscrites()))
|
||||||
|
.map(combModel -> SimpleRegisterComb.fromModel(combModel, combModel.getMembre().getLicences())
|
||||||
|
.setCategorieInscrite(combModel.getCategoriesInscrites()))
|
||||||
.collect().asList();
|
.collect().asList();
|
||||||
|
|
||||||
return membreService.getByAccountId(securityCtx.getSubject())
|
return membreService.getByAccountId(securityCtx.getSubject())
|
||||||
.chain(model -> registerRepository.find("competition.id = ?1 AND membre = ?2", id, model).firstResult()
|
.chain(model -> registerRepository.find("competition.id = ?1 AND membre = ?2", id, model).firstResult()
|
||||||
.map(rm -> rm == null ? List.of() : List.of(SimpleRegisterComb.fromModel(rm, List.of()))));
|
.call(rm -> rm == null ? Uni.createFrom().voidItem() :
|
||||||
|
Mutiny.fetch(rm.getCategoriesInscrites()))
|
||||||
|
.map(rm -> rm == null ? List.of() : List.of(SimpleRegisterComb.fromModel(rm, List.of())
|
||||||
|
.setCategorieInscrite(rm.getCategoriesInscrites()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<SimpleRegisterComb> addRegisterComb(SecurityCtx securityCtx, Long id, RegisterRequestData data,
|
public Uni<SimpleRegisterComb> addRegisterComb(SecurityCtx securityCtx, Long id, RegisterRequestData data,
|
||||||
@@ -291,8 +367,12 @@ public class CompetitionService {
|
|||||||
c.getBanMembre().remove(combModel.getId());
|
c.getBanMembre().remove(combModel.getId());
|
||||||
return Panache.withTransaction(() -> repository.persist(c));
|
return Panache.withTransaction(() -> repository.persist(c));
|
||||||
})
|
})
|
||||||
.chain(combModel -> updateRegister(data, c, combModel, true)))
|
.chain(combModel -> updateRegister(data, c, combModel, true, false)))
|
||||||
.map(r -> SimpleRegisterComb.fromModel(r, r.getMembre().getLicences()));
|
.call(r -> r.getCompetition().getSystem() == CompetitionSystem.INTERNAL ?
|
||||||
|
sRegister.sendRegisterNoFetch(r.getCompetition().getUuid(), r) : Uni.createFrom()
|
||||||
|
.voidItem())
|
||||||
|
.map(r -> SimpleRegisterComb.fromModel(r, r.getMembre().getLicences())
|
||||||
|
.setCategorieInscrite(r.getCategoriesInscrites()));
|
||||||
} else {
|
} else {
|
||||||
return permService.hasEditPerm(securityCtx, id)
|
return permService.hasEditPerm(securityCtx, id)
|
||||||
.chain(c -> competitionGuestRepository.findById(data.getId() * -1)
|
.chain(c -> competitionGuestRepository.findById(data.getId() * -1)
|
||||||
@@ -303,21 +383,35 @@ public class CompetitionService {
|
|||||||
model.setCompetition(c);
|
model.setCompetition(c);
|
||||||
return model;
|
return model;
|
||||||
}))
|
}))
|
||||||
.chain(model -> {
|
.invoke(model -> {
|
||||||
model.setFname(data.getFname());
|
model.setFname(data.getFname());
|
||||||
model.setLname(data.getLname());
|
if (data.getLname().equals("__team"))
|
||||||
|
model.setLname("_team");
|
||||||
|
else
|
||||||
|
model.setLname(data.getLname());
|
||||||
model.setGenre(data.getGenre());
|
model.setGenre(data.getGenre());
|
||||||
model.setClub(data.getClub());
|
model.setClub(data.getClub());
|
||||||
model.setCountry(data.getCountry());
|
model.setCountry(data.getCountry());
|
||||||
model.setWeight(data.getWeight());
|
model.setWeightReal(data.getWeightReal());
|
||||||
model.setCategorie(data.getCategorie());
|
model.setCategorie(data.getCategorie());
|
||||||
|
if (model.getCompetition().getRequiredWeight().contains(model.getCategorie()))
|
||||||
return Panache.withTransaction(() -> competitionGuestRepository.persist(model))
|
model.setWeight(data.getWeight());
|
||||||
.call(r -> model.getCompetition().getSystem() == CompetitionSystem.INTERNAL ?
|
|
||||||
sRegister.sendRegister(model.getCompetition().getUuid(),
|
|
||||||
r) : Uni.createFrom().voidItem());
|
|
||||||
})
|
})
|
||||||
.map(SimpleRegisterComb::fromModel);
|
.call(g -> Mutiny.fetch(g.getCategoriesInscrites()))
|
||||||
|
.call(g -> catPresetRepository.list("competition = ?1 AND id IN ?2", g.getCompetition(),
|
||||||
|
data.getCategoriesInscrites())
|
||||||
|
.invoke(cats -> {
|
||||||
|
g.getCategoriesInscrites().clear();
|
||||||
|
g.getCategoriesInscrites().addAll(cats);
|
||||||
|
g.getCategoriesInscrites()
|
||||||
|
.removeIf(cat -> cat.getCategories().stream()
|
||||||
|
.noneMatch(e -> e.getCategorie().equals(g.getCategorie())));
|
||||||
|
}))
|
||||||
|
.chain(model -> Panache.withTransaction(() -> competitionGuestRepository.persist(model))
|
||||||
|
.call(r -> model.getCompetition().getSystem() == CompetitionSystem.INTERNAL ?
|
||||||
|
sRegister.sendRegisterNoFetch(model.getCompetition().getUuid(), r)
|
||||||
|
: Uni.createFrom().voidItem()))
|
||||||
|
.map(g -> SimpleRegisterComb.fromModel(g).setCategorieInscrite(g.getCategoriesInscrites()));
|
||||||
}
|
}
|
||||||
if ("club".equals(source))
|
if ("club".equals(source))
|
||||||
return repository.findById(id)
|
return repository.findById(id)
|
||||||
@@ -326,7 +420,7 @@ public class CompetitionService {
|
|||||||
|| !securityCtx.isClubAdmin())
|
|| !securityCtx.isClubAdmin())
|
||||||
throw new DForbiddenException();
|
throw new DForbiddenException();
|
||||||
if (new Date().before(cm.getStartRegister()) || new Date().after(cm.getEndRegister()))
|
if (new Date().before(cm.getStartRegister()) || new Date().after(cm.getEndRegister()))
|
||||||
throw new DBadRequestException("Inscription fermée");
|
throw new DBadRequestException(trad.t("inscription.fermee"));
|
||||||
}))
|
}))
|
||||||
.chain(c -> findComb(data.getLicence(), data.getFname(), data.getLname())
|
.chain(c -> findComb(data.getLicence(), data.getFname(), data.getLname())
|
||||||
.call(combModel -> Mutiny.fetch(combModel.getLicences()))
|
.call(combModel -> Mutiny.fetch(combModel.getLicences()))
|
||||||
@@ -334,40 +428,123 @@ public class CompetitionService {
|
|||||||
if (!securityCtx.isInClubGroup(model.getClub().getId()))
|
if (!securityCtx.isInClubGroup(model.getClub().getId()))
|
||||||
throw new DForbiddenException();
|
throw new DForbiddenException();
|
||||||
if (c.getBanMembre().contains(model.getId()))
|
if (c.getBanMembre().contains(model.getId()))
|
||||||
throw new DForbiddenException(
|
throw new DForbiddenException(trad.t("insc.err1"));
|
||||||
"Vous n'avez pas le droit d'inscrire ce membre (par décision de l'administrateur de la compétition)");
|
|
||||||
}))
|
}))
|
||||||
.chain(combModel -> updateRegister(data, c, combModel, false)))
|
.chain(combModel -> updateRegister(data, c, combModel, false, false)))
|
||||||
.map(r -> SimpleRegisterComb.fromModel(r, r.getMembre().getLicences()));
|
.call(r -> r.getCompetition().getSystem() == CompetitionSystem.INTERNAL ?
|
||||||
|
sRegister.sendRegisterNoFetch(r.getCompetition().getUuid(), r) : Uni.createFrom()
|
||||||
|
.voidItem())
|
||||||
|
.map(r -> SimpleRegisterComb.fromModel(r, r.getMembre().getLicences())
|
||||||
|
.setCategorieInscrite(r.getCategoriesInscrites()));
|
||||||
|
|
||||||
return repository.findById(id)
|
return repository.findById(id)
|
||||||
.invoke(Unchecked.consumer(cm -> {
|
.invoke(Unchecked.consumer(cm -> {
|
||||||
if (cm.getRegisterMode() != RegisterMode.FREE)
|
if (cm.getRegisterMode() != RegisterMode.FREE)
|
||||||
throw new DForbiddenException();
|
throw new DForbiddenException();
|
||||||
if (new Date().before(cm.getStartRegister()) || new Date().after(cm.getEndRegister()))
|
if (new Date().before(cm.getStartRegister()) || new Date().after(cm.getEndRegister()))
|
||||||
throw new DBadRequestException("Inscription fermée");
|
throw new DBadRequestException(trad.t("inscription.fermee"));
|
||||||
}))
|
}))
|
||||||
.chain(c -> membreService.getByAccountId(securityCtx.getSubject())
|
.chain(c -> membreService.getByAccountId(securityCtx.getSubject())
|
||||||
.invoke(Unchecked.consumer(model -> {
|
.invoke(Unchecked.consumer(model -> {
|
||||||
if (c.getBanMembre().contains(model.getId()))
|
if (c.getBanMembre().contains(model.getId()))
|
||||||
throw new DForbiddenException(
|
throw new DForbiddenException(trad.t("insc.err2"));
|
||||||
"Vous n'avez pas le droit de vous inscrire (par décision de l'administrateur de la compétition)");
|
|
||||||
}))
|
}))
|
||||||
.chain(combModel -> updateRegister(data, c, combModel, false)))
|
.chain(combModel -> updateRegister(data, c, combModel, false, false)))
|
||||||
.map(r -> SimpleRegisterComb.fromModel(r, List.of()));
|
.call(r -> r.getCompetition().getSystem() == CompetitionSystem.INTERNAL ?
|
||||||
|
sRegister.sendRegisterNoFetch(r.getCompetition().getUuid(), r) : Uni.createFrom().voidItem())
|
||||||
|
.map(r -> SimpleRegisterComb.fromModel(r, List.of()).setCategorieInscrite(r.getCategoriesInscrites()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<List<SimpleRegisterComb>> addRegistersComb(SecurityCtx securityCtx, Long id,
|
||||||
|
List<RegisterRequestData> datas,
|
||||||
|
String source) {
|
||||||
|
if (!"admin".equals(source))
|
||||||
|
return Uni.createFrom().failure(new DForbiddenException());
|
||||||
|
|
||||||
|
return permService.hasEditPerm(securityCtx, id)
|
||||||
|
.chain(cm -> Multi.createFrom().iterable(datas).onItem().transformToUni(data ->
|
||||||
|
makeImportUpdate(cm, data).onFailure().recoverWithItem(t -> {
|
||||||
|
SimpleRegisterComb errorComb = new SimpleRegisterComb();
|
||||||
|
errorComb.setLicence(-42);
|
||||||
|
errorComb.setFname("ERROR");
|
||||||
|
errorComb.setLname(t.getMessage());
|
||||||
|
return errorComb;
|
||||||
|
})).concatenate().collect().asList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@WithSession
|
||||||
|
public Uni<SimpleRegisterComb> makeImportUpdate(CompetitionModel c, RegisterRequestData data) {
|
||||||
|
if (data.getLicence() == null || data.getLicence() != -1) { // not a guest
|
||||||
|
return findComb(data.getLicence(), data.getFname(), data.getLname())
|
||||||
|
.call(combModel -> Mutiny.fetch(combModel.getLicences()))
|
||||||
|
.call(combModel -> {
|
||||||
|
if (c.getBanMembre() == null)
|
||||||
|
c.setBanMembre(new ArrayList<>());
|
||||||
|
c.getBanMembre().remove(combModel.getId());
|
||||||
|
return Panache.withTransaction(() -> repository.persist(c));
|
||||||
|
})
|
||||||
|
.chain(combModel -> updateRegister(data, c, combModel, true, true))
|
||||||
|
.map(r -> SimpleRegisterComb.fromModel(r, r.getMembre().getLicences())
|
||||||
|
.setCategorieInscrite(r.getCategoriesInscrites()));
|
||||||
|
} else {
|
||||||
|
return findGuestOrInit(data.getFname(), data.getLname(), c)
|
||||||
|
.invoke(Unchecked.consumer(model -> {
|
||||||
|
if (data.getCategorie() == null)
|
||||||
|
throw new DBadRequestException(trad.t("categorie.requise"));
|
||||||
|
model.setCategorie(data.getCategorie());
|
||||||
|
|
||||||
|
if (data.getGenre() == null) {
|
||||||
|
if (model.getGenre() == null)
|
||||||
|
data.setGenre(Genre.NA);
|
||||||
|
} else
|
||||||
|
model.setGenre(data.getGenre());
|
||||||
|
|
||||||
|
if (data.getClub() == null) {
|
||||||
|
if (model.getClub() == null)
|
||||||
|
data.setClub("");
|
||||||
|
} else
|
||||||
|
model.setClub(data.getClub());
|
||||||
|
|
||||||
|
if (data.getCountry() == null) {
|
||||||
|
if (model.getCountry() == null)
|
||||||
|
data.setCountry("FR");
|
||||||
|
} else
|
||||||
|
model.setCountry(data.getCountry());
|
||||||
|
|
||||||
|
if (c.getRequiredWeight().contains(model.getCategorie())) {
|
||||||
|
if (data.getCountry() != null)
|
||||||
|
model.setWeight(data.getWeight());
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.call(g -> Mutiny.fetch(g.getCategoriesInscrites()))
|
||||||
|
.call(g -> catPresetRepository.list("competition = ?1 AND id IN ?2", c,
|
||||||
|
data.getCategoriesInscrites())
|
||||||
|
.invoke(cats -> {
|
||||||
|
g.getCategoriesInscrites().clear();
|
||||||
|
g.getCategoriesInscrites().addAll(cats);
|
||||||
|
g.getCategoriesInscrites().removeIf(cat -> cat.getCategories().stream()
|
||||||
|
.noneMatch(e -> e.getCategorie().equals(g.getCategorie())));
|
||||||
|
}))
|
||||||
|
.chain(model -> Panache.withTransaction(() -> competitionGuestRepository.persist(model))
|
||||||
|
.call(r -> c.getSystem() == CompetitionSystem.INTERNAL ?
|
||||||
|
sRegister.sendRegister(c.getUuid(), r) : Uni.createFrom().voidItem()))
|
||||||
|
.map(g -> SimpleRegisterComb.fromModel(g).setCategorieInscrite(g.getCategoriesInscrites()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Uni<RegisterModel> updateRegister(RegisterRequestData data, CompetitionModel c,
|
private Uni<RegisterModel> updateRegister(RegisterRequestData data, CompetitionModel c,
|
||||||
MembreModel combModel, boolean admin) {
|
MembreModel combModel, boolean admin, boolean append) {
|
||||||
return registerRepository.find("competition = ?1 AND membre = ?2", c, combModel).firstResult()
|
return registerRepository.find("competition = ?1 AND membre = ?2", c, combModel).firstResult()
|
||||||
.onFailure().recoverWithNull()
|
.onFailure().recoverWithNull()
|
||||||
.map(Unchecked.function(r -> {
|
.map(Unchecked.function(r -> {
|
||||||
if (r != null) {
|
if (r != null) {
|
||||||
if (!admin && r.isLockEdit())
|
if (!admin && r.isLockEdit())
|
||||||
throw new DForbiddenException(
|
throw new DForbiddenException(trad.t("insc.err3"));
|
||||||
"Modification bloquée par l'administrateur de la compétition");
|
if (data.getOverCategory() != null || !append)
|
||||||
r.setWeight(data.getWeight());
|
if (data.getOverCategory() == null)
|
||||||
r.setOverCategory(data.getOverCategory());
|
r.setOverCategory(0);
|
||||||
|
else
|
||||||
|
r.setOverCategory(data.getOverCategory());
|
||||||
r.setCategorie(
|
r.setCategorie(
|
||||||
(combModel.getBirth_date() == null) ? combModel.getCategorie() :
|
(combModel.getBirth_date() == null) ? combModel.getCategorie() :
|
||||||
Utils.getCategoryFormBirthDate(combModel.getBirth_date(),
|
Utils.getCategoryFormBirthDate(combModel.getBirth_date(),
|
||||||
@@ -375,50 +552,91 @@ public class CompetitionService {
|
|||||||
int days = Utils.getDaysBeforeCompetition(c.getDate());
|
int days = Utils.getDaysBeforeCompetition(c.getDate());
|
||||||
if (days > -7)
|
if (days > -7)
|
||||||
r.setClub(combModel.getClub());
|
r.setClub(combModel.getClub());
|
||||||
if (admin)
|
if (c.getRequiredWeight().contains(r.getCategorie2()))
|
||||||
|
if (data.getCountry() != null || !append)
|
||||||
|
r.setWeight(data.getWeight());
|
||||||
|
if (admin) {
|
||||||
|
r.setWeightReal(data.getWeightReal());
|
||||||
r.setLockEdit(data.isLockEdit());
|
r.setLockEdit(data.isLockEdit());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
r = new RegisterModel(c, combModel, data.getWeight(), data.getOverCategory(),
|
r = new RegisterModel(c, combModel, data.getWeight(), data.getOverCategory(),
|
||||||
(combModel.getBirth_date() == null) ? combModel.getCategorie() :
|
(combModel.getBirth_date() == null) ? combModel.getCategorie() :
|
||||||
Utils.getCategoryFormBirthDate(combModel.getBirth_date(),
|
Utils.getCategoryFormBirthDate(combModel.getBirth_date(),
|
||||||
c.getDate()),
|
c.getDate()),
|
||||||
(combModel.getClub() == null) ? null : combModel.getClub());
|
(combModel.getClub() == null) ? null : combModel.getClub());
|
||||||
if (admin)
|
if (admin) {
|
||||||
|
r.setWeightReal(data.getWeightReal());
|
||||||
r.setLockEdit(data.isLockEdit());
|
r.setLockEdit(data.isLockEdit());
|
||||||
else
|
} else
|
||||||
r.setLockEdit(false);
|
r.setLockEdit(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c.getSystem() == CompetitionSystem.SAFCA) {
|
if (c.getSystem() == CompetitionSystem.SAFCA) {
|
||||||
SReqRegister.sendIfNeed(serverCustom.clients,
|
SReqRegister.sendIfNeed(serverCustom.clients,
|
||||||
new CompetitionData.SimpleRegister(r.getMembre().getId(),
|
new CompetitionData.SimpleRegister(r.getMembre().getId(),
|
||||||
r.getOverCategory(), r.getWeight(), r.getCategorie(),
|
r.getOverCategory(), r.getWeight2(), r.getCategorie(),
|
||||||
(r.getClub() == null) ? null : r.getClub().getId(),
|
(r.getClub() == null) ? null : r.getClub().getId(),
|
||||||
(r.getClub() == null) ? null : r.getClub().getName()), c.getId());
|
(r.getClub() == null) ? null : r.getClub().getName()), c.getId());
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}))
|
}))
|
||||||
|
.call(r -> Mutiny.fetch(r.getCategoriesInscrites()).chain(__ ->
|
||||||
|
catPresetRepository.list("competition = ?1 AND id IN ?2", c, data.getCategoriesInscrites())
|
||||||
|
.invoke(cats -> {
|
||||||
|
if (data.isQuick()) {
|
||||||
|
cats.removeIf(cat -> r.getCategoriesInscrites().stream()
|
||||||
|
.anyMatch(cp -> cp.equals(cat)));
|
||||||
|
} else {
|
||||||
|
r.getCategoriesInscrites().clear();
|
||||||
|
}
|
||||||
|
r.getCategoriesInscrites().addAll(cats);
|
||||||
|
r.getCategoriesInscrites()
|
||||||
|
.removeIf(cat -> cat.getCategories().stream()
|
||||||
|
.noneMatch(e -> e.getCategorie().equals(r.getCategorie2())));
|
||||||
|
})))
|
||||||
.chain(r -> Panache.withTransaction(() -> registerRepository.persist(r)))
|
.chain(r -> Panache.withTransaction(() -> registerRepository.persist(r)))
|
||||||
.call(r -> c.getSystem() == CompetitionSystem.INTERNAL ?
|
.call(r -> c.getSystem() == CompetitionSystem.INTERNAL ?
|
||||||
sRegister.sendRegister(c.getUuid(), r) : Uni.createFrom().voidItem());
|
sRegister.sendRegister(c.getUuid(), r) : Uni.createFrom().voidItem());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Uni<CompetitionGuestModel> findGuestOrInit(String fname, String lname, CompetitionModel competition) {
|
||||||
|
if (fname == null || lname == null)
|
||||||
|
return Uni.createFrom().failure(new DBadRequestException(trad.t("nom.et.prenom.requis")));
|
||||||
|
return competitionGuestRepository.find(
|
||||||
|
"unaccent(lname) ILIKE unaccent(?1) AND unaccent(fname) ILIKE unaccent(?2) AND competition = ?3",
|
||||||
|
lname, fname, competition).firstResult()
|
||||||
|
.map(guestModel -> {
|
||||||
|
if (guestModel == null) {
|
||||||
|
CompetitionGuestModel model = new CompetitionGuestModel();
|
||||||
|
model.setFname(fname);
|
||||||
|
if (lname.equals("__team"))
|
||||||
|
model.setLname("_team");
|
||||||
|
else
|
||||||
|
model.setLname(lname);
|
||||||
|
model.setCompetition(competition);
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
return guestModel;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private Uni<MembreModel> findComb(Long licence, String fname, String lname) {
|
private Uni<MembreModel> findComb(Long licence, String fname, String lname) {
|
||||||
if (licence != null && licence > 0) {
|
if (licence != null && licence > 0) {
|
||||||
return combRepository.find("licence = ?1", licence).firstResult()
|
return combRepository.find("licence = ?1", licence).firstResult()
|
||||||
.invoke(Unchecked.consumer(combModel -> {
|
.invoke(Unchecked.consumer(combModel -> {
|
||||||
if (combModel == null)
|
if (combModel == null)
|
||||||
throw new DForbiddenException("Licence " + licence + " non trouvé");
|
throw new DForbiddenException(String.format(trad.t("licence.non.trouve"), licence));
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
if (fname == null || lname == null)
|
if (fname == null || lname == null)
|
||||||
return Uni.createFrom().failure(new DBadRequestException("Nom et prénom requis"));
|
return Uni.createFrom().failure(new DBadRequestException(trad.t("nom.et.prenom.requis")));
|
||||||
return combRepository.find("unaccent(lname) ILIKE unaccent(?1) AND unaccent(fname) ILIKE unaccent(?2)",
|
return combRepository.find("unaccent(lname) ILIKE unaccent(?1) AND unaccent(fname) ILIKE unaccent(?2)",
|
||||||
lname,
|
lname,
|
||||||
fname).firstResult()
|
fname).firstResult()
|
||||||
.invoke(Unchecked.consumer(combModel -> {
|
.invoke(Unchecked.consumer(combModel -> {
|
||||||
if (combModel == null)
|
if (combModel == null)
|
||||||
throw new DForbiddenException("Combattant " + fname + " " + lname + " non trouvé");
|
throw new DForbiddenException(String.format(trad.t("combattant.non.trouve"), fname, lname));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -445,12 +663,13 @@ public class CompetitionService {
|
|||||||
|| !securityCtx.isClubAdmin())
|
|| !securityCtx.isClubAdmin())
|
||||||
throw new DForbiddenException();
|
throw new DForbiddenException();
|
||||||
if (new Date().before(cm.getStartRegister()) || new Date().after(cm.getEndRegister()))
|
if (new Date().before(cm.getStartRegister()) || new Date().after(cm.getEndRegister()))
|
||||||
throw new DBadRequestException("Inscription fermée");
|
throw new DBadRequestException(trad.t("inscription.fermee"));
|
||||||
}))
|
}))
|
||||||
.call(cm -> membreService.getById(combId)
|
.call(cm -> membreService.getById(combId)
|
||||||
.invoke(Unchecked.consumer(model -> {
|
.invoke(Unchecked.consumer(model -> {
|
||||||
if (model == null)
|
if (model == null)
|
||||||
throw new DNotFoundException("Membre " + combId + " n'existe pas");
|
throw new DNotFoundException(
|
||||||
|
String.format(trad.t("le.membre.n.existe.pas"), combId));
|
||||||
if (!securityCtx.isInClubGroup(model.getClub().getId()))
|
if (!securityCtx.isInClubGroup(model.getClub().getId()))
|
||||||
throw new DForbiddenException();
|
throw new DForbiddenException();
|
||||||
})))
|
})))
|
||||||
@@ -462,7 +681,7 @@ public class CompetitionService {
|
|||||||
if (cm.getRegisterMode() != RegisterMode.FREE || !Objects.equals(model.getId(), combId))
|
if (cm.getRegisterMode() != RegisterMode.FREE || !Objects.equals(model.getId(), combId))
|
||||||
throw new DForbiddenException();
|
throw new DForbiddenException();
|
||||||
if (new Date().before(cm.getStartRegister()) || new Date().after(cm.getEndRegister()))
|
if (new Date().before(cm.getStartRegister()) || new Date().after(cm.getEndRegister()))
|
||||||
throw new DBadRequestException("Inscription fermée");
|
throw new DBadRequestException(trad.t("inscription.fermee"));
|
||||||
})))
|
})))
|
||||||
.chain(c -> deleteRegister(combId, c, false));
|
.chain(c -> deleteRegister(combId, c, false));
|
||||||
}
|
}
|
||||||
@@ -470,7 +689,7 @@ public class CompetitionService {
|
|||||||
private Uni<Void> deleteRegister(Long combId, CompetitionModel c, boolean admin) {
|
private Uni<Void> deleteRegister(Long combId, CompetitionModel c, boolean admin) {
|
||||||
if (admin && combId < 0) {
|
if (admin && combId < 0) {
|
||||||
return competitionGuestRepository.find("competition = ?1 AND id = ?2", c, combId * -1).firstResult()
|
return competitionGuestRepository.find("competition = ?1 AND id = ?2", c, combId * -1).firstResult()
|
||||||
.onFailure().transform(t -> new DBadRequestException("Combattant non inscrit"))
|
.onFailure().transform(t -> new DBadRequestException(trad.t("combattant.non.inscrit")))
|
||||||
.call(Unchecked.function(
|
.call(Unchecked.function(
|
||||||
model -> Panache.withTransaction(() -> competitionGuestRepository.delete(model))
|
model -> Panache.withTransaction(() -> competitionGuestRepository.delete(model))
|
||||||
.call(r -> c.getSystem() == CompetitionSystem.INTERNAL ?
|
.call(r -> c.getSystem() == CompetitionSystem.INTERNAL ?
|
||||||
@@ -479,10 +698,10 @@ public class CompetitionService {
|
|||||||
.replaceWithVoid();
|
.replaceWithVoid();
|
||||||
}
|
}
|
||||||
return registerRepository.find("competition = ?1 AND membre.id = ?2", c, combId).firstResult()
|
return registerRepository.find("competition = ?1 AND membre.id = ?2", c, combId).firstResult()
|
||||||
.onFailure().transform(t -> new DBadRequestException("Combattant non inscrit"))
|
.onFailure().transform(t -> new DBadRequestException(trad.t("combattant.non.inscrit")))
|
||||||
.call(Unchecked.function(registerModel -> {
|
.call(Unchecked.function(registerModel -> {
|
||||||
if (!admin && registerModel.isLockEdit())
|
if (!admin && registerModel.isLockEdit())
|
||||||
throw new DForbiddenException("Modification bloquée par l'administrateur de la compétition");
|
throw new DForbiddenException(trad.t("insc.err3"));
|
||||||
return Panache.withTransaction(() -> registerRepository.delete(registerModel))
|
return Panache.withTransaction(() -> registerRepository.delete(registerModel))
|
||||||
.call(r -> c.getSystem() == CompetitionSystem.INTERNAL ?
|
.call(r -> c.getSystem() == CompetitionSystem.INTERNAL ?
|
||||||
sRegister.sendRegisterRemove(c.getUuid(), combId) : Uni.createFrom().voidItem());
|
sRegister.sendRegisterRemove(c.getUuid(), combId) : Uni.createFrom().voidItem());
|
||||||
@@ -513,6 +732,64 @@ public class CompetitionService {
|
|||||||
.call(__ -> cache.invalidate(id));
|
.call(__ -> cache.invalidate(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Uni<SimpleCompetData> getInternalData(SecurityCtx securityCtx, Long id) {
|
||||||
|
return permService.hasEditPerm(securityCtx, id)
|
||||||
|
.invoke(Unchecked.consumer(cm -> {
|
||||||
|
if (cm.getSystem() != CompetitionSystem.INTERNAL)
|
||||||
|
throw new DBadRequestException(trad.t("competition.is.not.internal"));
|
||||||
|
}))
|
||||||
|
.chain(competitionModel -> {
|
||||||
|
SimpleCompetData data = SimpleCompetData.fromModel(competitionModel);
|
||||||
|
return vertx.getOrCreateContext().executeBlocking(() -> {
|
||||||
|
if (competitionModel.getAdmin() != null)
|
||||||
|
data.setAdmin(
|
||||||
|
competitionModel.getAdmin().stream().map(uuid -> keycloakService.getUserById(uuid))
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(user -> user.get().getUsername())
|
||||||
|
.toList());
|
||||||
|
if (competitionModel.getTable() != null)
|
||||||
|
data.setTable(
|
||||||
|
competitionModel.getTable().stream().map(uuid -> keycloakService.getUserById(uuid))
|
||||||
|
.filter(Optional::isPresent)
|
||||||
|
.map(user -> user.get().getUsername())
|
||||||
|
.toList());
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<Void> setInternalData(SecurityCtx securityCtx, SimpleCompetData data) {
|
||||||
|
return permService.hasEditPerm(securityCtx, data.getId())
|
||||||
|
.invoke(Unchecked.consumer(cm -> {
|
||||||
|
if (cm.getSystem() != CompetitionSystem.INTERNAL)
|
||||||
|
throw new DBadRequestException(trad.t("competition.is.not.internal"));
|
||||||
|
}))
|
||||||
|
.chain(cm -> vertx.getOrCreateContext().executeBlocking(() -> {
|
||||||
|
ArrayList<String> admin = new ArrayList<>();
|
||||||
|
ArrayList<String> table = new ArrayList<>();
|
||||||
|
for (String username : data.getAdmin()) {
|
||||||
|
Optional<UserRepresentation> opt = keycloakService.getUser(username);
|
||||||
|
if (opt.isEmpty())
|
||||||
|
throw new DBadRequestException(String.format(trad.t("user.not.found"), username));
|
||||||
|
admin.add(opt.get().getId());
|
||||||
|
}
|
||||||
|
for (String username : data.getTable()) {
|
||||||
|
Optional<UserRepresentation> opt = keycloakService.getUser(username);
|
||||||
|
if (opt.isEmpty())
|
||||||
|
throw new DBadRequestException(String.format(trad.t("user.not.found"), username));
|
||||||
|
table.add(opt.get().getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
cm.setAdmin(admin);
|
||||||
|
cm.setTable(table);
|
||||||
|
cm.setConfig(data.getConfigForInternal());
|
||||||
|
|
||||||
|
return cm;
|
||||||
|
}))
|
||||||
|
.chain(cm -> Panache.withTransaction(() -> repository.persist(cm)))
|
||||||
|
.replaceWithVoid();
|
||||||
|
}
|
||||||
|
|
||||||
public Uni<SimpleCompetData> getSafcaData(SecurityCtx securityCtx, Long id) {
|
public Uni<SimpleCompetData> getSafcaData(SecurityCtx securityCtx, Long id) {
|
||||||
return permService.getSafcaConfig(id)
|
return permService.getSafcaConfig(id)
|
||||||
.call(Unchecked.function(o -> {
|
.call(Unchecked.function(o -> {
|
||||||
@@ -549,13 +826,13 @@ public class CompetitionService {
|
|||||||
for (String username : data.getAdmin()) {
|
for (String username : data.getAdmin()) {
|
||||||
Optional<UserRepresentation> opt = keycloakService.getUser(username);
|
Optional<UserRepresentation> opt = keycloakService.getUser(username);
|
||||||
if (opt.isEmpty())
|
if (opt.isEmpty())
|
||||||
throw new DBadRequestException("User " + username + " not found");
|
throw new DBadRequestException(String.format(trad.t("user.not.found"), username));
|
||||||
admin.add(UUID.fromString(opt.get().getId()));
|
admin.add(UUID.fromString(opt.get().getId()));
|
||||||
}
|
}
|
||||||
for (String username : data.getTable()) {
|
for (String username : data.getTable()) {
|
||||||
Optional<UserRepresentation> opt = keycloakService.getUser(username);
|
Optional<UserRepresentation> opt = keycloakService.getUser(username);
|
||||||
if (opt.isEmpty())
|
if (opt.isEmpty())
|
||||||
throw new DBadRequestException("User " + username + " not found");
|
throw new DBadRequestException(String.format(trad.t("user.not.found"), username));
|
||||||
table.add(UUID.fromString(opt.get().getId()));
|
table.add(UUID.fromString(opt.get().getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,6 +858,12 @@ public class CompetitionService {
|
|||||||
.call(__ -> cache.invalidate(data.getId()));
|
.call(__ -> cache.invalidate(data.getId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Uni<List<PresetData>> getPresetsForCompetition(SecurityCtx securityCtx, Long id) {
|
||||||
|
return permService.hasViewPerm(securityCtx, id)
|
||||||
|
.chain(cm -> Mutiny.fetch(cm.getCatPreset()))
|
||||||
|
.map(p -> p.stream().map(PresetData::fromModel).toList());
|
||||||
|
}
|
||||||
|
|
||||||
public Uni<Response> unregisterHelloAsso(NotificationData data) {
|
public Uni<Response> unregisterHelloAsso(NotificationData data) {
|
||||||
if (!data.getState().equals("Refunded"))
|
if (!data.getState().equals("Refunded"))
|
||||||
return Uni.createFrom().item(Response.ok().build());
|
return Uni.createFrom().item(Response.ok().build());
|
||||||
@@ -614,8 +897,8 @@ public class CompetitionService {
|
|||||||
public Uni<Response> registerHelloAsso(NotificationData data) {
|
public Uni<Response> registerHelloAsso(NotificationData data) {
|
||||||
String organizationSlug = data.getOrganizationSlug();
|
String organizationSlug = data.getOrganizationSlug();
|
||||||
String formSlug = data.getFormSlug();
|
String formSlug = data.getFormSlug();
|
||||||
RegisterRequestData req = new RegisterRequestData(null, "", "", null, 0, false, null, Categorie.CADET, Genre.NA,
|
RegisterRequestData req = new RegisterRequestData(null, "", "", null, null, 0, false, new ArrayList<>(), null,
|
||||||
null, "fr");
|
Categorie.CADET, Genre.NA, null, "fr", false);
|
||||||
|
|
||||||
return repository.find("data1 = ?1 AND data2 = ?2", organizationSlug, formSlug).firstResult()
|
return repository.find("data1 = ?1 AND data2 = ?2", organizationSlug, formSlug).firstResult()
|
||||||
.onFailure().recoverWithNull()
|
.onFailure().recoverWithNull()
|
||||||
@@ -649,7 +932,7 @@ public class CompetitionService {
|
|||||||
.call(m -> Panache.withTransaction(() ->
|
.call(m -> Panache.withTransaction(() ->
|
||||||
helloAssoRepository.persist(
|
helloAssoRepository.persist(
|
||||||
new HelloAssoRegisterModel(cm, m, data.getId()))))
|
new HelloAssoRegisterModel(cm, m, data.getId()))))
|
||||||
.chain(m -> updateRegister(req, cm, m, true)))
|
.chain(m -> updateRegister(req, cm, m, true, true)))
|
||||||
.onFailure().recoverWithItem(throwable -> {
|
.onFailure().recoverWithItem(throwable -> {
|
||||||
fail.add("%s %s - licence n°%d".formatted(item.getUser().getLastName(),
|
fail.add("%s %s - licence n°%d".formatted(item.getUser().getLastName(),
|
||||||
item.getUser().getFirstName(), optional.get()));
|
item.getUser().getFirstName(), optional.get()));
|
||||||
|
|||||||
@@ -25,6 +25,11 @@ public class HelloAssoTokenService {
|
|||||||
|
|
||||||
// Récupère un token valide (en le rafraîchissant si nécessaire)
|
// Récupère un token valide (en le rafraîchissant si nécessaire)
|
||||||
public Uni<String> getValidAccessToken() {
|
public Uni<String> getValidAccessToken() {
|
||||||
|
if (clientId == null || clientSecret == null || clientId.isEmpty() || clientSecret.isEmpty() || clientId.equalsIgnoreCase(
|
||||||
|
"null") || clientSecret.equalsIgnoreCase("null")) {
|
||||||
|
LOG.error("Client ID ou Client Secret non configuré pour HelloAsso");
|
||||||
|
return Uni.createFrom().failure(new IllegalStateException("HelloAsso client credentials not configured"));
|
||||||
|
}
|
||||||
if (currentToken == null || currentToken.isExpired()) {
|
if (currentToken == null || currentToken.isExpired()) {
|
||||||
return fetchNewToken(clientId, clientSecret);
|
return fetchNewToken(clientId, clientSecret);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -377,11 +377,19 @@ public class KeycloakService {
|
|||||||
|
|
||||||
|
|
||||||
public Optional<UserRepresentation> getUser(UUID userId) {
|
public Optional<UserRepresentation> getUser(UUID userId) {
|
||||||
UserResource user = keycloak.realm(realm).users().get(userId.toString());
|
return getUserById(userId.toString());
|
||||||
if (user == null)
|
}
|
||||||
|
|
||||||
|
public Optional<UserRepresentation> getUserById(String userId) {
|
||||||
|
try {
|
||||||
|
UserResource user = keycloak.realm(realm).users().get(userId);
|
||||||
|
if (user == null)
|
||||||
|
return Optional.empty();
|
||||||
|
else
|
||||||
|
return Optional.of(user.toRepresentation());
|
||||||
|
} catch (Exception e) {
|
||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
else
|
}
|
||||||
return Optional.of(user.toRepresentation());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String makeLogin(MembreModel model) {
|
private String makeLogin(MembreModel model) {
|
||||||
|
|||||||
@@ -47,6 +47,9 @@ public class LicenceService {
|
|||||||
@Inject
|
@Inject
|
||||||
CheckoutService checkoutService;
|
CheckoutService checkoutService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
public Uni<List<LicenceModel>> getLicence(long id, Consumer<MembreModel> checkPerm) {
|
public Uni<List<LicenceModel>> getLicence(long id, Consumer<MembreModel> checkPerm) {
|
||||||
return combRepository.findById(id).invoke(checkPerm)
|
return combRepository.findById(id).invoke(checkPerm)
|
||||||
.chain(combRepository -> Mutiny.fetch(combRepository.getLicences()));
|
.chain(combRepository -> Mutiny.fetch(combRepository.getLicences()));
|
||||||
@@ -119,7 +122,9 @@ public class LicenceService {
|
|||||||
.call(genLicenceNumberAndAccountIfNeed())
|
.call(genLicenceNumberAndAccountIfNeed())
|
||||||
: Uni.createFrom().nullItem()
|
: Uni.createFrom().nullItem()
|
||||||
))
|
))
|
||||||
.call(licenceModel -> ls.logA(LogModel.ActionType.ADD, membreModel.getObjectName(),
|
.call(licenceModel -> ls.logA(LogModel.ActionType.ADD,
|
||||||
|
"%s (valid=%b, pay=%b, %s)" .formatted(membreModel.getObjectName(), model.isValidate(),
|
||||||
|
model.isPay(), model.getCertificate()),
|
||||||
licenceModel));
|
licenceModel));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@@ -157,7 +162,7 @@ public class LicenceService {
|
|||||||
return repository.list("membre.id IN ?1 AND saison = ?2 AND pay = FALSE", ids, Utils.getSaison())
|
return repository.list("membre.id IN ?1 AND saison = ?2 AND pay = FALSE", ids, Utils.getSaison())
|
||||||
.invoke(Unchecked.consumer(models -> {
|
.invoke(Unchecked.consumer(models -> {
|
||||||
if (models.size() != ids.size())
|
if (models.size() != ids.size())
|
||||||
throw new DBadRequestException("Erreur lors de la sélection des membres");
|
throw new DBadRequestException(trad.t("erreur.lors.de.la.selection.des.membres"));
|
||||||
}))
|
}))
|
||||||
.call(models -> {
|
.call(models -> {
|
||||||
Uni<?> uni = Uni.createFrom().nullItem();
|
Uni<?> uni = Uni.createFrom().nullItem();
|
||||||
@@ -174,7 +179,7 @@ public class LicenceService {
|
|||||||
.call(__ -> checkoutService.canDeleteLicence(id)
|
.call(__ -> checkoutService.canDeleteLicence(id)
|
||||||
.invoke(Unchecked.consumer(b -> {
|
.invoke(Unchecked.consumer(b -> {
|
||||||
if (!b) throw new DBadRequestException(
|
if (!b) throw new DBadRequestException(
|
||||||
"Impossible de supprimer une licence pour laquelle un paiement est en cours");
|
trad.t("licence.rm.err1"));
|
||||||
})))
|
})))
|
||||||
.call(model -> ls.logADelete(model))
|
.call(model -> ls.logADelete(model))
|
||||||
.chain(model -> Panache.withTransaction(() -> repository.delete(model)));
|
.chain(model -> Panache.withTransaction(() -> repository.delete(model)));
|
||||||
@@ -186,7 +191,7 @@ public class LicenceService {
|
|||||||
return repository.find("saison = ?1 AND membre = ?2", Utils.getSaison(), membreModel).count()
|
return repository.find("saison = ?1 AND membre = ?2", Utils.getSaison(), membreModel).count()
|
||||||
.invoke(Unchecked.consumer(count -> {
|
.invoke(Unchecked.consumer(count -> {
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
throw new DBadRequestException("Licence déjà demandée");
|
throw new DBadRequestException(trad.t("licence.deja.demandee"));
|
||||||
})).chain(__ -> combRepository.findById(id).chain(membreModel2 -> {
|
})).chain(__ -> combRepository.findById(id).chain(membreModel2 -> {
|
||||||
LicenceModel model = new LicenceModel();
|
LicenceModel model = new LicenceModel();
|
||||||
model.setClub_id((membreModel2.getClub() == null) ? null : membreModel2.getClub().getId());
|
model.setClub_id((membreModel2.getClub() == null) ? null : membreModel2.getClub().getId());
|
||||||
@@ -215,13 +220,13 @@ public class LicenceService {
|
|||||||
.call(__ -> checkoutService.canDeleteLicence(id)
|
.call(__ -> checkoutService.canDeleteLicence(id)
|
||||||
.invoke(Unchecked.consumer(b -> {
|
.invoke(Unchecked.consumer(b -> {
|
||||||
if (!b) throw new DBadRequestException(
|
if (!b) throw new DBadRequestException(
|
||||||
"Impossible de supprimer une licence pour laquelle un paiement est en cours");
|
trad.t("licence.rm.err1"));
|
||||||
})))
|
})))
|
||||||
.invoke(Unchecked.consumer(licenceModel -> {
|
.invoke(Unchecked.consumer(licenceModel -> {
|
||||||
if (licenceModel.isValidate())
|
if (licenceModel.isValidate())
|
||||||
throw new DBadRequestException("Impossible de supprimer une licence déjà validée");
|
throw new DBadRequestException(trad.t("impossible.de.supprimer.une.licence.deja.validee"));
|
||||||
if (licenceModel.isPay())
|
if (licenceModel.isPay())
|
||||||
throw new DBadRequestException("Impossible de supprimer une licence déjà payée");
|
throw new DBadRequestException(trad.t("impossible.de.supprimer.une.licence.deja.payee"));
|
||||||
}))
|
}))
|
||||||
.call(model -> ls.logADelete(model))
|
.call(model -> ls.logADelete(model))
|
||||||
.chain(__ -> Panache.withTransaction(() -> repository.deleteById(id)));
|
.chain(__ -> Panache.withTransaction(() -> repository.deleteById(id)));
|
||||||
|
|||||||
@@ -7,10 +7,7 @@ import fr.titionfire.ffsaf.data.repository.*;
|
|||||||
import fr.titionfire.ffsaf.net2.ServerCustom;
|
import fr.titionfire.ffsaf.net2.ServerCustom;
|
||||||
import fr.titionfire.ffsaf.net2.data.SimpleCombModel;
|
import fr.titionfire.ffsaf.net2.data.SimpleCombModel;
|
||||||
import fr.titionfire.ffsaf.net2.request.SReqComb;
|
import fr.titionfire.ffsaf.net2.request.SReqComb;
|
||||||
import fr.titionfire.ffsaf.rest.data.MeData;
|
import fr.titionfire.ffsaf.rest.data.*;
|
||||||
import fr.titionfire.ffsaf.rest.data.SimpleLicence;
|
|
||||||
import fr.titionfire.ffsaf.rest.data.SimpleMembre;
|
|
||||||
import fr.titionfire.ffsaf.rest.data.SimpleMembreInOutData;
|
|
||||||
import fr.titionfire.ffsaf.rest.exception.DBadRequestException;
|
import fr.titionfire.ffsaf.rest.exception.DBadRequestException;
|
||||||
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
||||||
import fr.titionfire.ffsaf.rest.exception.DInternalError;
|
import fr.titionfire.ffsaf.rest.exception.DInternalError;
|
||||||
@@ -65,6 +62,9 @@ public class MembreService {
|
|||||||
@Inject
|
@Inject
|
||||||
LoggerService ls;
|
LoggerService ls;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
public SimpleCombModel find(int licence, String np) throws Throwable {
|
public SimpleCombModel find(int licence, String np) throws Throwable {
|
||||||
return VertxContextSupport.subscribeAndAwait(() -> Panache.withTransaction(() ->
|
return VertxContextSupport.subscribeAndAwait(() -> Panache.withTransaction(() ->
|
||||||
repository.find(
|
repository.find(
|
||||||
@@ -180,15 +180,21 @@ public class MembreService {
|
|||||||
|
|
||||||
Sort sort = getSort(order);
|
Sort sort = getSort(order);
|
||||||
if (sort == null)
|
if (sort == null)
|
||||||
return Uni.createFrom().failure(new DInternalError("Erreur lors calcul du trie"));
|
return Uni.createFrom().failure(new DInternalError(trad.t("erreur.lors.calcul.du.trie")));
|
||||||
|
|
||||||
String finalSearch = search;
|
String finalSearch = search;
|
||||||
return getLicenceListe(licenceRequest, payState)
|
return getLicenceListe(licenceRequest, payState)
|
||||||
.map(l -> l.stream().map(l2 -> l2.getMembre().getId()).toList())
|
.chain(l -> {
|
||||||
.chain(ids -> {
|
|
||||||
PanacheQuery<MembreModel> query;
|
PanacheQuery<MembreModel> query;
|
||||||
query = repository.find(queryStr, sort, finalSearch, ids, club).page(Page.ofSize(limit));
|
query = repository.find(queryStr, sort, finalSearch,
|
||||||
return getPageResult(query, limit, page);
|
l.stream().map(l2 -> l2.getMembre().getId()).toList(), club).page(Page.ofSize(limit));
|
||||||
|
return getPageResult(query, limit, page)
|
||||||
|
.call(r -> (r.getResult().isEmpty() || !l.isEmpty() ?
|
||||||
|
Uni.createFrom().item(l) :
|
||||||
|
licenceRepository.list("saison = ?1 AND membre.id IN ?2", Utils.getSaison(),
|
||||||
|
r.getResult().stream().map(SimpleMembre::getId).toList()))
|
||||||
|
.invoke(l2 -> r.setAdditionalData(l2.stream().map(SimpleLicence::fromModel)))
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +205,7 @@ public class MembreService {
|
|||||||
.call(result -> query.count().invoke(result::setResult_count))
|
.call(result -> query.count().invoke(result::setResult_count))
|
||||||
.call(result -> query.pageCount()
|
.call(result -> query.pageCount()
|
||||||
.invoke(Unchecked.consumer(pages -> {
|
.invoke(Unchecked.consumer(pages -> {
|
||||||
if (page > pages) throw new DBadRequestException("Page out of range");
|
if (page > pages) throw new DBadRequestException(trad.t("page.out.of.range"));
|
||||||
}))
|
}))
|
||||||
.invoke(result::setPage_count))
|
.invoke(result::setPage_count))
|
||||||
.call(result -> query.page(Page.of(page, limit)).list()
|
.call(result -> query.page(Page.of(page, limit)).list()
|
||||||
@@ -210,7 +216,7 @@ public class MembreService {
|
|||||||
public Uni<List<SimpleMembreInOutData>> getAllExport(String subject) {
|
public Uni<List<SimpleMembreInOutData>> getAllExport(String subject) {
|
||||||
return repository.find("userId = ?1", subject).firstResult()
|
return repository.find("userId = ?1", subject).firstResult()
|
||||||
.chain(membreModel -> repository.list("club = ?1", membreModel.getClub()))
|
.chain(membreModel -> repository.list("club = ?1", membreModel.getClub()))
|
||||||
.chain(membres -> licenceRepository.list("saison = ?1 AND membre IN ?2", Utils.getSaison(), membres)
|
.chain(membres -> licenceRepository.list("membre IN ?1", membres)
|
||||||
.map(l -> membres.stream().map(m -> SimpleMembreInOutData.fromModel(m, l)).toList()));
|
.map(l -> membres.stream().map(m -> SimpleMembreInOutData.fromModel(m, l)).toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,8 +250,8 @@ public class MembreService {
|
|||||||
for (MembreModel membreModel : membres) {
|
for (MembreModel membreModel : membres) {
|
||||||
if (!Objects.equals(membreModel.getClub(), clubModel.get())) {
|
if (!Objects.equals(membreModel.getClub(), clubModel.get())) {
|
||||||
LOGGER.info("Similar membres found: " + membreModel);
|
LOGGER.info("Similar membres found: " + membreModel);
|
||||||
throw new DForbiddenException(
|
throw new DForbiddenException(String.format(trad.t("le.membre.appartient.pas.a.votre.club"),
|
||||||
"Le membre n°" + membreModel.getLicence() + " n'appartient pas à votre club");
|
membreModel.getLicence()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Uni<Void> uniResult = Uni.createFrom().voidItem();
|
Uni<Void> uniResult = Uni.createFrom().voidItem();
|
||||||
@@ -272,7 +278,8 @@ public class MembreService {
|
|||||||
if (model.getLicence() != null && !model.getLicence().equals(dataIn.getLicence())) {
|
if (model.getLicence() != null && !model.getLicence().equals(dataIn.getLicence())) {
|
||||||
LOGGER.info("Similar membres found: " + model);
|
LOGGER.info("Similar membres found: " + model);
|
||||||
throw new DBadRequestException(
|
throw new DBadRequestException(
|
||||||
"Email '" + model.getEmail() + "' déja utilisé par " + model.getFname() + " " + model.getFname());
|
String.format(trad.t("email.deja.utilise.par"), model.getEmail(),
|
||||||
|
model.getFname(), model.getLname()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StringSimilarity.similarity(model.getLname().toUpperCase(),
|
if (StringSimilarity.similarity(model.getLname().toUpperCase(),
|
||||||
@@ -280,7 +287,8 @@ public class MembreService {
|
|||||||
model.getFname().toUpperCase(), dataIn.getPrenom().toUpperCase()) > 3) {
|
model.getFname().toUpperCase(), dataIn.getPrenom().toUpperCase()) > 3) {
|
||||||
LOGGER.info("Similar membres found: " + model);
|
LOGGER.info("Similar membres found: " + model);
|
||||||
throw new DBadRequestException(
|
throw new DBadRequestException(
|
||||||
"Email '" + model.getEmail() + "' déja utilisé par " + model.getFname() + " " + model.getFname());
|
String.format(trad.t("email.deja.utilise.par"), model.getEmail(),
|
||||||
|
model.getFname(), model.getLname()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,8 +299,8 @@ public class MembreService {
|
|||||||
model.getFname().toUpperCase(), dataIn.getPrenom().toUpperCase()) > 3)) {
|
model.getFname().toUpperCase(), dataIn.getPrenom().toUpperCase()) > 3)) {
|
||||||
LOGGER.info("Similar membres found: " + model);
|
LOGGER.info("Similar membres found: " + model);
|
||||||
throw new DBadRequestException(
|
throw new DBadRequestException(
|
||||||
"Pour enregistrer un nouveau membre, veuillez laisser le champ licence vide. (tentative de changement non-autotiser de nom sur la licence "
|
String.format(trad.t("try.edit.licence"), model.getLicence(), model.getFname(),
|
||||||
+ model.getLicence() + " pour " + model.getFname() + " " + model.getFname() + ")");
|
model.getFname()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ls.logChange("Nom", model.getLname(), dataIn.getNom().toUpperCase(), model);
|
ls.logChange("Nom", model.getLname(), dataIn.getNom().toUpperCase(), model);
|
||||||
@@ -366,7 +374,7 @@ public class MembreService {
|
|||||||
.call(__ -> repository.count("email LIKE ?1 AND id != ?2", membre.getEmail(), id)
|
.call(__ -> repository.count("email LIKE ?1 AND id != ?2", membre.getEmail(), id)
|
||||||
.invoke(Unchecked.consumer(c -> {
|
.invoke(Unchecked.consumer(c -> {
|
||||||
if (c > 0 && !membre.getEmail().isBlank())
|
if (c > 0 && !membre.getEmail().isBlank())
|
||||||
throw new DBadRequestException("Email déjà utilisé");
|
throw new DBadRequestException(trad.t("email.deja.utilise"));
|
||||||
})))
|
})))
|
||||||
.chain(membreModel -> clubRepository.findById(membre.getClub())
|
.chain(membreModel -> clubRepository.findById(membre.getClub())
|
||||||
.map(club -> new Pair<>(membreModel, club)))
|
.map(club -> new Pair<>(membreModel, club)))
|
||||||
@@ -388,7 +396,7 @@ public class MembreService {
|
|||||||
.call(__ -> repository.count("email LIKE ?1 AND id != ?2", membre.getEmail(), id)
|
.call(__ -> repository.count("email LIKE ?1 AND id != ?2", membre.getEmail(), id)
|
||||||
.invoke(Unchecked.consumer(c -> {
|
.invoke(Unchecked.consumer(c -> {
|
||||||
if (c > 0 && !membre.getEmail().isBlank())
|
if (c > 0 && !membre.getEmail().isBlank())
|
||||||
throw new DBadRequestException("Email déjà utilisé");
|
throw new DBadRequestException(trad.t("email.deja.utilise"));
|
||||||
})))
|
})))
|
||||||
.invoke(Unchecked.consumer(membreModel -> {
|
.invoke(Unchecked.consumer(membreModel -> {
|
||||||
if (!securityCtx.isInClubGroup(membreModel.getClub().getId()))
|
if (!securityCtx.isInClubGroup(membreModel.getClub().getId()))
|
||||||
@@ -397,7 +405,7 @@ public class MembreService {
|
|||||||
membre.getLname().toUpperCase()) > 3 || StringSimilarity.similarity(
|
membre.getLname().toUpperCase()) > 3 || StringSimilarity.similarity(
|
||||||
membreModel.getFname().toUpperCase(), membre.getFname().toUpperCase()) > 3) {
|
membreModel.getFname().toUpperCase(), membre.getFname().toUpperCase()) > 3) {
|
||||||
throw new DBadRequestException(
|
throw new DBadRequestException(
|
||||||
"Pour enregistrer un nouveau membre, veuillez utilisez le bouton prévue a cette effet.");
|
trad.t("regiter.new.membre"));
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.invoke(Unchecked.consumer(membreModel -> {
|
.invoke(Unchecked.consumer(membreModel -> {
|
||||||
@@ -406,7 +414,7 @@ public class MembreService {
|
|||||||
else if (securityCtx.roleHas("club_secretaire")) source = RoleAsso.SECRETAIRE;
|
else if (securityCtx.roleHas("club_secretaire")) source = RoleAsso.SECRETAIRE;
|
||||||
else if (securityCtx.roleHas("club_respo_intra")) source = RoleAsso.MEMBREBUREAU;
|
else if (securityCtx.roleHas("club_respo_intra")) source = RoleAsso.MEMBREBUREAU;
|
||||||
if (!membre.getRole().equals(membreModel.getRole()) && membre.getRole().level >= source.level)
|
if (!membre.getRole().equals(membreModel.getRole()) && membre.getRole().level >= source.level)
|
||||||
throw new DForbiddenException("Permission insuffisante");
|
throw new DForbiddenException(trad.t("permission.insuffisante"));
|
||||||
}))
|
}))
|
||||||
.onItem().transform(target -> {
|
.onItem().transform(target -> {
|
||||||
if (!securityCtx.getSubject().equals(target.getUserId())) {
|
if (!securityCtx.getSubject().equals(target.getUserId())) {
|
||||||
@@ -479,7 +487,8 @@ public class MembreService {
|
|||||||
return clubRepository.findById(input.getClub())
|
return clubRepository.findById(input.getClub())
|
||||||
.call(__ -> repository.count("email LIKE ?1", input.getEmail())
|
.call(__ -> repository.count("email LIKE ?1", input.getEmail())
|
||||||
.invoke(Unchecked.consumer(c -> {
|
.invoke(Unchecked.consumer(c -> {
|
||||||
if (c > 0) throw new DBadRequestException("Email déjà utilisé");
|
if (c > 0 && input.getEmail() != null && !input.getEmail().isBlank())
|
||||||
|
throw new DBadRequestException(trad.t("email.deja.utilise"));
|
||||||
})))
|
})))
|
||||||
.chain(clubModel -> {
|
.chain(clubModel -> {
|
||||||
MembreModel model = getMembreModel(input, clubModel);
|
MembreModel model = getMembreModel(input, clubModel);
|
||||||
@@ -495,7 +504,7 @@ public class MembreService {
|
|||||||
return repository.find("userId = ?1", subject).firstResult()
|
return repository.find("userId = ?1", subject).firstResult()
|
||||||
.call(__ -> repository.count("email LIKE ?1", input.getEmail())
|
.call(__ -> repository.count("email LIKE ?1", input.getEmail())
|
||||||
.invoke(Unchecked.consumer(c -> {
|
.invoke(Unchecked.consumer(c -> {
|
||||||
if (c > 0) throw new DBadRequestException("Email déjà utilisé");
|
if (c > 0) throw new DBadRequestException(trad.t("email.deja.utilise"));
|
||||||
})))
|
})))
|
||||||
.call(membreModel ->
|
.call(membreModel ->
|
||||||
repository.count(
|
repository.count(
|
||||||
@@ -503,7 +512,7 @@ public class MembreService {
|
|||||||
input.getLname(), input.getFname(), membreModel.getClub())
|
input.getLname(), input.getFname(), membreModel.getClub())
|
||||||
.invoke(Unchecked.consumer(c -> {
|
.invoke(Unchecked.consumer(c -> {
|
||||||
if (c > 0)
|
if (c > 0)
|
||||||
throw new DBadRequestException("Membre déjà existent");
|
throw new DBadRequestException(trad.t("membre.deja.existent"));
|
||||||
})))
|
})))
|
||||||
.chain(membreModel -> {
|
.chain(membreModel -> {
|
||||||
MembreModel model = getMembreModel(input, membreModel.getClub());
|
MembreModel model = getMembreModel(input, membreModel.getClub());
|
||||||
@@ -536,13 +545,13 @@ public class MembreService {
|
|||||||
.invoke(Unchecked.consumer(membreModel -> {
|
.invoke(Unchecked.consumer(membreModel -> {
|
||||||
if (membreModel.getLicence() != null) {
|
if (membreModel.getLicence() != null) {
|
||||||
throw new DBadRequestException(
|
throw new DBadRequestException(
|
||||||
"Impossible de supprimer un membre qui a déjà un numéro de licence");
|
trad.t("membre.rm.err1"));
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.call(membreModel -> licenceRepository.find("membre = ?1", membreModel).count()
|
.call(membreModel -> licenceRepository.find("membre = ?1", membreModel).count()
|
||||||
.invoke(Unchecked.consumer(l -> {
|
.invoke(Unchecked.consumer(l -> {
|
||||||
if (l > 0)
|
if (l > 0)
|
||||||
throw new DBadRequestException("Impossible de supprimer un membre avec des licences");
|
throw new DBadRequestException(trad.t("membre.rm.err2"));
|
||||||
})))
|
})))
|
||||||
.call(membreModel -> (membreModel.getUserId() != null) ?
|
.call(membreModel -> (membreModel.getUserId() != null) ?
|
||||||
keycloakService.removeAccount(membreModel.getUserId()) : Uni.createFrom().nullItem())
|
keycloakService.removeAccount(membreModel.getUserId()) : Uni.createFrom().nullItem())
|
||||||
@@ -588,10 +597,13 @@ public class MembreService {
|
|||||||
public Uni<MeData> getMembre(String subject) {
|
public Uni<MeData> getMembre(String subject) {
|
||||||
MeData meData = new MeData();
|
MeData meData = new MeData();
|
||||||
return repository.find("userId = ?1", subject).firstResult()
|
return repository.find("userId = ?1", subject).firstResult()
|
||||||
.invoke(meData::setMembre)
|
.invoke(m -> meData.setMembre(m, trad))
|
||||||
.chain(membreModel -> Mutiny.fetch(membreModel.getLicences()))
|
.call(membreModel -> Mutiny.fetch(membreModel.getLicences())
|
||||||
.map(licences -> licences.stream().map(SimpleLicence::fromModel).toList())
|
.map(licences -> licences.stream().map(SimpleLicence::fromModel).toList())
|
||||||
.invoke(meData::setLicences)
|
.invoke(meData::setLicences))
|
||||||
|
.call(membreModel -> Mutiny.fetch(membreModel.getSelections())
|
||||||
|
.map(licences -> licences.stream().map(SimpleSelection::fromModel).toList())
|
||||||
|
.invoke(meData::setSelections))
|
||||||
.map(__ -> meData);
|
.map(__ -> meData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ public class PDFService {
|
|||||||
@ConfigProperty(name = "pdf-maker.sign-file")
|
@ConfigProperty(name = "pdf-maker.sign-file")
|
||||||
String sign_file;
|
String sign_file;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
|
|
||||||
public Uni<Response> getLicencePdf(String subject) {
|
public Uni<Response> getLicencePdf(String subject) {
|
||||||
return getLicencePdf(combRepository.find("userId = ?1", subject).firstResult()
|
return getLicencePdf(combRepository.find("userId = ?1", subject).firstResult()
|
||||||
@@ -58,7 +61,7 @@ public class PDFService {
|
|||||||
LicenceModel licence = m.getLicences().stream()
|
LicenceModel licence = m.getLicences().stream()
|
||||||
.filter(licenceModel -> licenceModel.getSaison() == Utils.getSaison() && licenceModel.isValidate())
|
.filter(licenceModel -> licenceModel.getSaison() == Utils.getSaison() && licenceModel.isValidate())
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElseThrow(() -> new DNotFoundException("Pas de licence pour la saison en cours"));
|
.orElseThrow(() -> new DNotFoundException(trad.t("pas.de.licence.pour.la.saison.en.cours")));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
byte[] buff = make_pdf(m, licence);
|
byte[] buff = make_pdf(m, licence);
|
||||||
@@ -119,7 +122,7 @@ public class PDFService {
|
|||||||
combRepository.find("userId = ?1", subject).firstResult()
|
combRepository.find("userId = ?1", subject).firstResult()
|
||||||
.invoke(Unchecked.consumer(m -> {
|
.invoke(Unchecked.consumer(m -> {
|
||||||
if (m == null || m.getClub() == null)
|
if (m == null || m.getClub() == null)
|
||||||
throw new DNotFoundException("Club non trouvé");
|
throw new DNotFoundException(trad.t("club.non.trouve"));
|
||||||
}))
|
}))
|
||||||
.map(MembreModel::getClub)
|
.map(MembreModel::getClub)
|
||||||
.call(m -> Mutiny.fetch(m.getAffiliations())));
|
.call(m -> Mutiny.fetch(m.getAffiliations())));
|
||||||
@@ -130,7 +133,7 @@ public class PDFService {
|
|||||||
clubRepository.findById(id)
|
clubRepository.findById(id)
|
||||||
.invoke(Unchecked.consumer(m -> {
|
.invoke(Unchecked.consumer(m -> {
|
||||||
if (m == null)
|
if (m == null)
|
||||||
throw new DNotFoundException("Club non trouvé");
|
throw new DNotFoundException(trad.t("club.non.trouve"));
|
||||||
}))
|
}))
|
||||||
.call(m -> Mutiny.fetch(m.getAffiliations())));
|
.call(m -> Mutiny.fetch(m.getAffiliations())));
|
||||||
}
|
}
|
||||||
@@ -141,7 +144,7 @@ public class PDFService {
|
|||||||
.map(Unchecked.function(m -> {
|
.map(Unchecked.function(m -> {
|
||||||
if (m.getAffiliations().stream()
|
if (m.getAffiliations().stream()
|
||||||
.noneMatch(licenceModel -> licenceModel.getSaison() == Utils.getSaison()))
|
.noneMatch(licenceModel -> licenceModel.getSaison() == Utils.getSaison()))
|
||||||
throw new DNotFoundException("Pas d'affiliation pour la saison en cours");
|
throw new DNotFoundException(trad.t("pas.d.affiliation.pour.la.saison.en.cours"));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
byte[] buff = make_pdf(m);
|
byte[] buff = make_pdf(m);
|
||||||
|
|||||||
@@ -2,10 +2,13 @@ package fr.titionfire.ffsaf.domain.service;
|
|||||||
|
|
||||||
import fr.titionfire.ffsaf.data.model.*;
|
import fr.titionfire.ffsaf.data.model.*;
|
||||||
import fr.titionfire.ffsaf.data.repository.*;
|
import fr.titionfire.ffsaf.data.repository.*;
|
||||||
|
import fr.titionfire.ffsaf.domain.entity.MatchModelExtend;
|
||||||
import fr.titionfire.ffsaf.rest.data.ResultCategoryData;
|
import fr.titionfire.ffsaf.rest.data.ResultCategoryData;
|
||||||
import fr.titionfire.ffsaf.rest.exception.DBadRequestException;
|
import fr.titionfire.ffsaf.rest.exception.DBadRequestException;
|
||||||
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
||||||
import fr.titionfire.ffsaf.utils.*;
|
import fr.titionfire.ffsaf.utils.*;
|
||||||
|
import io.quarkus.cache.Cache;
|
||||||
|
import io.quarkus.cache.CacheName;
|
||||||
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
import io.smallrye.mutiny.Multi;
|
import io.smallrye.mutiny.Multi;
|
||||||
@@ -14,6 +17,7 @@ import io.smallrye.mutiny.unchecked.Unchecked;
|
|||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import lombok.Builder;
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
import org.hibernate.reactive.mutiny.Mutiny;
|
import org.hibernate.reactive.mutiny.Mutiny;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@@ -45,7 +49,16 @@ public class ResultService {
|
|||||||
@Inject
|
@Inject
|
||||||
MatchRepository matchRepository;
|
MatchRepository matchRepository;
|
||||||
|
|
||||||
private static final ResourceBundle BUNDLE = ResourceBundle.getBundle("lang.String");
|
@Inject
|
||||||
|
CardRepository cardRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@CacheName("club-classement")
|
||||||
|
Cache cacheClubClassement;
|
||||||
|
private static final HashMap<String, Long> cacheClubClassementExp = new HashMap<>();
|
||||||
|
|
||||||
private static final HashMap<Long, String> combTempIds = new HashMap<>();
|
private static final HashMap<Long, String> combTempIds = new HashMap<>();
|
||||||
|
|
||||||
@@ -93,12 +106,21 @@ public class ResultService {
|
|||||||
|
|
||||||
public Uni<List<Object[]>> getList(SecurityCtx securityCtx) {
|
public Uni<List<Object[]>> getList(SecurityCtx securityCtx) {
|
||||||
return membreService.getByAccountId(securityCtx.getSubject())
|
return membreService.getByAccountId(securityCtx.getSubject())
|
||||||
.chain(m -> registerRepository.list("membre = ?1", m))
|
.chain(m -> registerRepository.list(
|
||||||
|
"membre = ?1 OR (TRUE = ?2 AND membre.club = ?3)",
|
||||||
|
m, securityCtx.isClubAdmin(), m.getClub()))
|
||||||
.onItem().transformToMulti(Multi.createFrom()::iterable)
|
.onItem().transformToMulti(Multi.createFrom()::iterable)
|
||||||
.onItem().call(r -> Mutiny.fetch(r.getCompetition()))
|
.onItem().call(r -> Mutiny.fetch(r.getCompetition()))
|
||||||
.onItem().transform(r -> new Object[]{r.getCompetition().getUuid(), r.getCompetition().getName(),
|
.onItem().transform(RegisterModel::getCompetition)
|
||||||
r.getCompetition().getDate()})
|
.collect().asList()
|
||||||
.collect().asList();
|
.chain(l -> compRepository.list("owner = ?1 OR ?1 IN admin", securityCtx.getSubject())
|
||||||
|
.map(l2 -> Stream.concat(l.stream(), l2.stream()).distinct()
|
||||||
|
.map(c -> new Object[]{c.getUuid(), c.getName(), c.getDate()}).toList())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<HashMap<String, Long>> getCategoryList(String uuid, SecurityCtx securityCtx) {
|
||||||
|
return hasAccess(uuid, securityCtx).chain(__ -> getCategoryList(uuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<HashMap<String, Long>> getCategoryList(String uuid) {
|
public Uni<HashMap<String, Long>> getCategoryList(String uuid) {
|
||||||
@@ -113,39 +135,44 @@ public class ResultService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Uni<ResultCategoryData> getCategory(String uuid, long poule, SecurityCtx securityCtx) {
|
public Uni<ResultCategoryData> getCategory(String uuid, long poule, SecurityCtx securityCtx) {
|
||||||
return hasAccess(uuid, securityCtx).chain(r ->
|
return hasAccess(uuid, securityCtx).chain(membreModel -> getData(uuid, poule, membreModel));
|
||||||
matchRepository.list("category.compet.uuid = ?1 AND category.id = ?2", uuid, poule)
|
|
||||||
.call(list -> list.isEmpty() ? Uni.createFrom().voidItem() :
|
|
||||||
Mutiny.fetch(list.get(0).getCategory().getTree()))
|
|
||||||
.map(list -> getData(list, r.getMembre())));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<ResultCategoryData> getCategory(String uuid, long poule) {
|
public Uni<ResultCategoryData> getCategory(String uuid, long poule) {
|
||||||
|
return getData(uuid, poule, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Uni<ResultCategoryData> getData(String uuid, long poule, MembreModel membreModel) {
|
||||||
|
List<CardModel> cards = new ArrayList<>();
|
||||||
|
|
||||||
return matchRepository.list("category.compet.uuid = ?1 AND category.id = ?2", uuid, poule)
|
return matchRepository.list("category.compet.uuid = ?1 AND category.id = ?2", uuid, poule)
|
||||||
.call(list -> list.isEmpty() ? Uni.createFrom().voidItem() :
|
.call(list -> list.isEmpty() ? Uni.createFrom().voidItem() :
|
||||||
Mutiny.fetch(list.get(0).getCategory().getTree()))
|
Mutiny.fetch(list.get(0).getCategory().getTree()))
|
||||||
.map(list -> getData(list, null));
|
.chain(list -> cardRepository.list("competition.uuid = ?1", uuid).invoke(cards::addAll)
|
||||||
|
.map(c -> list.stream().map(m -> new MatchModelExtend(m, c)).toList()))
|
||||||
|
.map(matchModels -> {
|
||||||
|
ResultCategoryData out = new ResultCategoryData();
|
||||||
|
|
||||||
|
CategoryModel categoryModel = matchModels.get(0).getCategory();
|
||||||
|
out.setName(categoryModel.getName());
|
||||||
|
out.setType(categoryModel.getType());
|
||||||
|
out.setLiceName(categoryModel.getLiceName() == null ? new String[]{} : categoryModel.getLiceName()
|
||||||
|
.split(";"));
|
||||||
|
out.setGenTime(System.currentTimeMillis());
|
||||||
|
out.setTreeIsClassement(categoryModel.isTreeAreClassement());
|
||||||
|
|
||||||
|
getArray2(matchModels, membreModel, out);
|
||||||
|
getTree(categoryModel.getTree(), membreModel, cards, out);
|
||||||
|
getClassementArray(categoryModel, membreModel, cards, out);
|
||||||
|
return out;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResultCategoryData getData(List<MatchModel> matchModels, MembreModel membreModel) {
|
public void getArray2(List<MatchModelExtend> matchModels_, MembreModel membreModel, ResultCategoryData out) {
|
||||||
ResultCategoryData out = new ResultCategoryData();
|
List<MatchModelExtend> matchModels = matchModels_.stream().filter(o -> o.getCategory_ord() >= 0).toList();
|
||||||
|
|
||||||
CategoryModel categoryModel = matchModels.get(0).getCategory();
|
HashMap<Character, List<MatchModelExtend>> matchMap = new HashMap<>();
|
||||||
out.setName(categoryModel.getName());
|
for (MatchModelExtend model : matchModels) {
|
||||||
out.setType(categoryModel.getType());
|
|
||||||
out.setLiceName(categoryModel.getLiceName() == null ? new String[]{} : categoryModel.getLiceName().split(";"));
|
|
||||||
out.setGenTime(System.currentTimeMillis());
|
|
||||||
|
|
||||||
getArray2(matchModels, membreModel, out);
|
|
||||||
getTree(categoryModel.getTree(), membreModel, out);
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getArray2(List<MatchModel> matchModels_, MembreModel membreModel, ResultCategoryData out) {
|
|
||||||
List<MatchModel> matchModels = matchModels_.stream().filter(o -> o.getCategory_ord() >= 0).toList();
|
|
||||||
|
|
||||||
HashMap<Character, List<MatchModel>> matchMap = new HashMap<>();
|
|
||||||
for (MatchModel model : matchModels) {
|
|
||||||
char g = model.getPoule();
|
char g = model.getPoule();
|
||||||
if (!matchMap.containsKey(g))
|
if (!matchMap.containsKey(g))
|
||||||
matchMap.put(g, new ArrayList<>());
|
matchMap.put(g, new ArrayList<>());
|
||||||
@@ -154,7 +181,7 @@ public class ResultService {
|
|||||||
|
|
||||||
matchMap.forEach((c, matchEntities) -> {
|
matchMap.forEach((c, matchEntities) -> {
|
||||||
List<ResultCategoryData.PouleArrayData> matchs = matchEntities.stream()
|
List<ResultCategoryData.PouleArrayData> matchs = matchEntities.stream()
|
||||||
.sorted(Comparator.comparing(MatchModel::getCategory_ord))
|
.sorted(Comparator.comparing(MatchModelExtend::getCategory_ord))
|
||||||
.map(o -> ResultCategoryData.PouleArrayData.fromModel(o, membreModel,
|
.map(o -> ResultCategoryData.PouleArrayData.fromModel(o, membreModel,
|
||||||
ResultPrivacy.REGISTERED_ONLY_NO_DETAILS))
|
ResultPrivacy.REGISTERED_ONLY_NO_DETAILS))
|
||||||
.toList();
|
.toList();
|
||||||
@@ -164,46 +191,26 @@ public class ResultService {
|
|||||||
.distinct()
|
.distinct()
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.map(comb -> {
|
.map(comb -> {
|
||||||
AtomicInteger w = new AtomicInteger(0);
|
CombStat stat = makeStat(matchEntities, comb);
|
||||||
AtomicInteger pointMake = new AtomicInteger(0);
|
return new ResultCategoryData.RankArray(0, comb,
|
||||||
AtomicInteger pointTake = new AtomicInteger(0);
|
comb.getName(membreModel, ResultPrivacy.REGISTERED_ONLY_NO_DETAILS), stat.score, stat.w,
|
||||||
|
stat.pointMake, stat.pointTake, stat.getPointRate());
|
||||||
matchEntities.stream()
|
|
||||||
.filter(m -> m.isEnd() && (m.isC1(comb) || m.isC2(comb)))
|
|
||||||
.forEach(matchModel -> {
|
|
||||||
int win = matchModel.win();
|
|
||||||
if ((matchModel.isC1(comb) && win > 0) || matchModel.isC2(comb) && win < 0)
|
|
||||||
w.getAndIncrement();
|
|
||||||
|
|
||||||
for (ScoreEmbeddable score : matchModel.getScores()) {
|
|
||||||
if (score.getS1() <= -900 || score.getS2() <= -900)
|
|
||||||
continue;
|
|
||||||
if (matchModel.isC1(comb)) {
|
|
||||||
pointMake.addAndGet(score.getS1());
|
|
||||||
pointTake.addAndGet(score.getS2());
|
|
||||||
} else {
|
|
||||||
pointMake.addAndGet(score.getS2());
|
|
||||||
pointTake.addAndGet(score.getS1());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
float pointRate = (pointTake.get() == 0) ? pointMake.get() : (float) pointMake.get() / pointTake.get();
|
|
||||||
|
|
||||||
return new ResultCategoryData.RankArray(0,
|
|
||||||
comb.getName(membreModel, ResultPrivacy.REGISTERED_ONLY_NO_DETAILS), w.get(),
|
|
||||||
pointMake.get(), pointTake.get(), pointRate);
|
|
||||||
})
|
})
|
||||||
|
.filter(r -> r.getPointMake() > 0 || r.getPointTake() > 0)
|
||||||
.sorted(Comparator
|
.sorted(Comparator
|
||||||
.comparing(ResultCategoryData.RankArray::getWin)
|
.comparing(ResultCategoryData.RankArray::getScore)
|
||||||
|
.thenComparing(ResultCategoryData.RankArray::getWin)
|
||||||
.thenComparing(ResultCategoryData.RankArray::getPointRate).reversed())
|
.thenComparing(ResultCategoryData.RankArray::getPointRate).reversed())
|
||||||
.toList();
|
.toList();
|
||||||
out.getMatchs().put(c, matchs);
|
out.getMatchs().put(c, matchs);
|
||||||
|
|
||||||
|
int lastScore = -1;
|
||||||
int lastWin = -1;
|
int lastWin = -1;
|
||||||
float pointRate = 0;
|
float pointRate = 0;
|
||||||
int rank = 0;
|
int rank = 0;
|
||||||
for (ResultCategoryData.RankArray rankArray1 : rankArray) {
|
for (ResultCategoryData.RankArray rankArray1 : rankArray) {
|
||||||
if (rankArray1.getWin() != lastWin || pointRate != rankArray1.getPointRate()) {
|
if (rankArray1.getScore() != lastScore || rankArray1.getWin() != lastWin || pointRate != rankArray1.getPointRate()) {
|
||||||
|
lastScore = rankArray1.getScore();
|
||||||
lastWin = rankArray1.getWin();
|
lastWin = rankArray1.getWin();
|
||||||
pointRate = rankArray1.getPointRate();
|
pointRate = rankArray1.getPointRate();
|
||||||
rank++;
|
rank++;
|
||||||
@@ -214,32 +221,94 @@ public class ResultService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void convertTree(TreeModel src, TreeNode<ResultCategoryData.TreeData> dst, MembreModel membreModel,
|
public void getClassementArray(CategoryModel categoryModel, MembreModel membreModel, List<CardModel> cards,
|
||||||
ResultPrivacy privacy) {
|
ResultCategoryData out) {
|
||||||
dst.setData(ResultCategoryData.TreeData.from(src.getMatch(), membreModel, privacy));
|
if ((categoryModel.getType() & 2) != 0) {
|
||||||
if (src.getLeft() != null) {
|
AtomicInteger rank = new AtomicInteger(0);
|
||||||
dst.setLeft(new TreeNode<>());
|
categoryModel.getTree().stream()
|
||||||
convertTree(src.getLeft(), dst.getLeft(), membreModel, privacy);
|
.filter(t -> t.getLevel() > 0)
|
||||||
}
|
.sorted(Comparator.comparing(TreeModel::getLevel))
|
||||||
if (src.getRight() != null) {
|
.forEach(treeModel -> makeClassementRow(membreModel,
|
||||||
dst.setRight(new TreeNode<>());
|
new MatchModelExtend(treeModel.getMatch(), cards), out, rank));
|
||||||
convertTree(src.getRight(), dst.getRight(), membreModel, privacy);
|
|
||||||
|
categoryModel.getTree().stream()
|
||||||
|
.filter(t -> t.getLevel() <= -10)
|
||||||
|
.sorted(Comparator.comparing(TreeModel::getLevel).reversed())
|
||||||
|
.forEach(treeModel -> makeClassementRow(membreModel,
|
||||||
|
new MatchModelExtend(treeModel.getMatch(), cards), out, rank));
|
||||||
|
} else {
|
||||||
|
for (List<ResultCategoryData.RankArray> list : out.getRankArray().values()) {
|
||||||
|
for (ResultCategoryData.RankArray r : list) {
|
||||||
|
out.getClassement()
|
||||||
|
.add(new ResultCategoryData.ClassementData(r.getRank(), r.getComb(), r.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getTree(List<TreeModel> treeModels, MembreModel membreModel, ResultCategoryData out) {
|
private static void makeClassementRow(MembreModel membreModel, MatchModelExtend m, ResultCategoryData out,
|
||||||
|
AtomicInteger rank) {
|
||||||
|
if (m.isEnd()) {
|
||||||
|
if (m.getWin() > 0) {
|
||||||
|
out.getClassement()
|
||||||
|
.add(new ResultCategoryData.ClassementData(rank.incrementAndGet(), m.getC1(),
|
||||||
|
m.getC1Name(membreModel, ResultPrivacy.REGISTERED_ONLY_NO_DETAILS)));
|
||||||
|
out.getClassement()
|
||||||
|
.add(new ResultCategoryData.ClassementData(rank.incrementAndGet(), m.getC2(),
|
||||||
|
m.getC2Name(membreModel, ResultPrivacy.REGISTERED_ONLY_NO_DETAILS)));
|
||||||
|
} else if (m.getWin() < 0) {
|
||||||
|
out.getClassement()
|
||||||
|
.add(new ResultCategoryData.ClassementData(rank.incrementAndGet(), m.getC2(),
|
||||||
|
m.getC2Name(membreModel, ResultPrivacy.REGISTERED_ONLY_NO_DETAILS)));
|
||||||
|
out.getClassement()
|
||||||
|
.add(new ResultCategoryData.ClassementData(rank.incrementAndGet(), m.getC1(),
|
||||||
|
m.getC1Name(membreModel, ResultPrivacy.REGISTERED_ONLY_NO_DETAILS)));
|
||||||
|
} else {
|
||||||
|
out.getClassement()
|
||||||
|
.add(new ResultCategoryData.ClassementData(rank.incrementAndGet(), m.getC1(),
|
||||||
|
m.getC1Name(membreModel, ResultPrivacy.REGISTERED_ONLY_NO_DETAILS)));
|
||||||
|
out.getClassement()
|
||||||
|
.add(new ResultCategoryData.ClassementData(rank.get(), m.getC2(),
|
||||||
|
m.getC2Name(membreModel, ResultPrivacy.REGISTERED_ONLY_NO_DETAILS)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.getClassement().add(new ResultCategoryData.ClassementData(rank.incrementAndGet(), null, null));
|
||||||
|
out.getClassement().add(new ResultCategoryData.ClassementData(rank.incrementAndGet(), null, null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void convertTree(TreeModel src, TreeNode<ResultCategoryData.TreeData> dst, MembreModel membreModel,
|
||||||
|
ResultPrivacy privacy, List<CardModel> cards) {
|
||||||
|
dst.setData(
|
||||||
|
ResultCategoryData.TreeData.from(new MatchModelExtend(src.getMatch(), cards), src.getLevel(),
|
||||||
|
membreModel, privacy));
|
||||||
|
if (src.getLeft() != null) {
|
||||||
|
dst.setLeft(new TreeNode<>());
|
||||||
|
convertTree(src.getLeft(), dst.getLeft(), membreModel, privacy, cards);
|
||||||
|
}
|
||||||
|
if (src.getRight() != null) {
|
||||||
|
dst.setRight(new TreeNode<>());
|
||||||
|
convertTree(src.getRight(), dst.getRight(), membreModel, privacy, cards);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getTree(List<TreeModel> treeModels, MembreModel membreModel, List<CardModel> cards,
|
||||||
|
ResultCategoryData out) {
|
||||||
ArrayList<TreeNode<ResultCategoryData.TreeData>> trees = new ArrayList<>();
|
ArrayList<TreeNode<ResultCategoryData.TreeData>> trees = new ArrayList<>();
|
||||||
treeModels.stream().filter(t -> t.getLevel() != 0).forEach(treeModel -> {
|
treeModels.stream()
|
||||||
TreeNode<ResultCategoryData.TreeData> root = new TreeNode<>();
|
.filter(t -> t.getLevel() != 0)
|
||||||
convertTree(treeModel, root, membreModel, ResultPrivacy.REGISTERED_ONLY_NO_DETAILS);
|
.sorted(Comparator.comparing(TreeModel::getLevel))
|
||||||
trees.add(root);
|
.forEach(treeModel -> {
|
||||||
});
|
TreeNode<ResultCategoryData.TreeData> root = new TreeNode<>();
|
||||||
|
convertTree(treeModel, root, membreModel, ResultPrivacy.REGISTERED_ONLY_NO_DETAILS, cards);
|
||||||
|
trees.add(root);
|
||||||
|
});
|
||||||
out.setTrees(trees);
|
out.setTrees(trees);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<CombsArrayData> getAllCombArray(String uuid, SecurityCtx securityCtx) {
|
public Uni<CombsArrayData> getAllCombArray(String uuid, SecurityCtx securityCtx) {
|
||||||
return hasAccess(uuid, securityCtx)
|
return hasAccess(uuid, securityCtx)
|
||||||
.chain(r -> getAllCombArray_(uuid, r.getMembre()));
|
.chain(membreModel -> getAllCombArray_(uuid, membreModel));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<CombsArrayData> getAllCombArrayPublic(String uuid) {
|
public Uni<CombsArrayData> getAllCombArrayPublic(String uuid) {
|
||||||
@@ -249,10 +318,13 @@ public class ResultService {
|
|||||||
private Uni<CombsArrayData> getAllCombArray_(String uuid, MembreModel membreModel) {
|
private Uni<CombsArrayData> getAllCombArray_(String uuid, MembreModel membreModel) {
|
||||||
return registerRepository.list("competition.uuid = ?1", uuid)
|
return registerRepository.list("competition.uuid = ?1", uuid)
|
||||||
.chain(registers -> matchRepository.list("category.compet.uuid = ?1", uuid)
|
.chain(registers -> matchRepository.list("category.compet.uuid = ?1", uuid)
|
||||||
.map(matchModels -> new Pair<>(registers, matchModels)))
|
.chain(matchModels -> cardRepository.list("competition.uuid = ?1", uuid)
|
||||||
|
.map(cards -> new Pair<>(registers,
|
||||||
|
matchModels.stream().map(m -> new MatchModelExtend(m, cards)).toList()))))
|
||||||
|
|
||||||
.map(pair -> {
|
.map(pair -> {
|
||||||
List<RegisterModel> registers = pair.getKey();
|
List<RegisterModel> registers = pair.getKey();
|
||||||
List<MatchModel> matchModels = pair.getValue();
|
List<MatchModelExtend> matchModels = pair.getValue();
|
||||||
|
|
||||||
CombsArrayData.CombsArrayDataBuilder builder = CombsArrayData.builder();
|
CombsArrayData.CombsArrayDataBuilder builder = CombsArrayData.builder();
|
||||||
|
|
||||||
@@ -262,12 +334,7 @@ public class ResultService {
|
|||||||
.distinct()
|
.distinct()
|
||||||
.map(comb -> {
|
.map(comb -> {
|
||||||
var builder2 = CombsArrayData.CombsData.builder();
|
var builder2 = CombsArrayData.CombsData.builder();
|
||||||
AtomicInteger w = new AtomicInteger(0);
|
CombStat stat = makeStat(matchModels, comb);
|
||||||
AtomicInteger l = new AtomicInteger(0);
|
|
||||||
AtomicInteger pointMake = new AtomicInteger();
|
|
||||||
AtomicInteger pointTake = new AtomicInteger();
|
|
||||||
|
|
||||||
makeStat(matchModels, comb, w, l, pointMake, pointTake);
|
|
||||||
|
|
||||||
Categorie categorie = null;
|
Categorie categorie = null;
|
||||||
String clubName = null;
|
String clubName = null;
|
||||||
@@ -277,26 +344,25 @@ public class ResultService {
|
|||||||
if (register.isPresent()) {
|
if (register.isPresent()) {
|
||||||
categorie = register.get().getCategorie2();
|
categorie = register.get().getCategorie2();
|
||||||
ClubModel club = register.get().getClub2();
|
ClubModel club = register.get().getClub2();
|
||||||
clubName = (club == null) ? BUNDLE.getString("no.licence") : club.getName();
|
clubName = (club == null) ? trad.t("no.licence") : club.getName();
|
||||||
} else if (comb instanceof CompetitionGuestModel guestModel) {
|
} else if (comb instanceof CompetitionGuestModel guestModel) {
|
||||||
categorie = guestModel.getCategorie();
|
categorie = guestModel.getCategorie();
|
||||||
clubName = guestModel.getClub();
|
clubName = guestModel.getClub();
|
||||||
} else if (comb instanceof MembreModel model) {
|
} else if (comb instanceof MembreModel model) {
|
||||||
categorie = model.getCategorie();
|
categorie = model.getCategorie();
|
||||||
clubName = (model.getClub() == null) ? BUNDLE.getString(
|
clubName = (model.getClub() == null) ? trad.t("no.licence")
|
||||||
"no.licence") : model.getClub().getName();
|
: model.getClub().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder2.cat((categorie == null) ? "---" : categorie.getName(BUNDLE));
|
builder2.cat((categorie == null) ? "---" : categorie.getName(trad));
|
||||||
builder2.name(comb.getName(membreModel, ResultPrivacy.REGISTERED_ONLY));
|
builder2.name(comb.getName(membreModel, ResultPrivacy.REGISTERED_ONLY));
|
||||||
builder2.w(w.get());
|
builder2.w(stat.w);
|
||||||
builder2.l(l.get());
|
builder2.l(stat.l);
|
||||||
builder2.ratioVictoire((l.get() == 0) ? w.get() : (float) w.get() / l.get());
|
builder2.ratioVictoire((stat.l == 0) ? stat.w : (float) stat.w / stat.l);
|
||||||
builder2.club(clubName);
|
builder2.club(clubName);
|
||||||
builder2.pointMake(pointMake.get());
|
builder2.pointMake(stat.pointMake);
|
||||||
builder2.pointTake(pointTake.get());
|
builder2.pointTake(stat.pointTake);
|
||||||
builder2.ratioPoint(
|
builder2.ratioPoint(stat.getPointRate());
|
||||||
(pointTake.get() == 0) ? pointMake.get() : (float) pointMake.get() / pointTake.get());
|
|
||||||
|
|
||||||
return builder2.build();
|
return builder2.build();
|
||||||
})
|
})
|
||||||
@@ -304,71 +370,102 @@ public class ResultService {
|
|||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
builder.nb_insc(combs.size());
|
builder.nb_insc(combs.size());
|
||||||
builder.tt_match((int) matchModels.stream().filter(MatchModel::isEnd).count());
|
builder.tt_match((int) matchModels.stream().filter(MatchModelExtend::isEnd).count());
|
||||||
builder.point(combs.stream().mapToInt(CombsArrayData.CombsData::pointMake).sum());
|
builder.point(matchModels.stream()
|
||||||
|
.filter(MatchModelExtend::isEnd)
|
||||||
|
.flatMap(m -> m.getScoresToCompute().stream())
|
||||||
|
.mapToInt(s -> s.getS1() + s.getS2()).sum());
|
||||||
builder.combs(combs);
|
builder.combs(combs);
|
||||||
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<HashMap<String, String>> getCombList(String uuid, ResultPrivacy privacy) {
|
public Uni<HashMap<String, String>> getCombList(String uuid, SecurityCtx securityCtx) {
|
||||||
|
return hasAccess(uuid, securityCtx)
|
||||||
|
.chain(membreModel -> getCombList(uuid, ResultPrivacy.REGISTERED_ONLY));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<HashMap<String, String>> getCombList(String uuid) {
|
||||||
|
return getCombList(uuid, ResultPrivacy.PUBLIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Uni<HashMap<String, String>> getCombList(String uuid, ResultPrivacy privacy) {
|
||||||
return registerRepository.list("competition.uuid = ?1 AND membre.resultPrivacy <= ?2", uuid, privacy)
|
return registerRepository.list("competition.uuid = ?1 AND membre.resultPrivacy <= ?2", uuid, privacy)
|
||||||
.map(models -> {
|
.map(models -> {
|
||||||
HashMap<String, String> map = new HashMap<>();
|
HashMap<String, String> map = new HashMap<>();
|
||||||
models.forEach(
|
models.forEach(
|
||||||
r -> map.put(Utils.getFullName(r.getMembre()), getCombTempId(r.getMembre().getId())));
|
r -> map.put(r.getMembre().getName(), getCombTempId(r.getMembre().getId())));
|
||||||
return map;
|
return map;
|
||||||
})
|
})
|
||||||
.chain(map -> competitionGuestRepository.list("competition.uuid = ?1", uuid)
|
.chain(map -> competitionGuestRepository.list("competition.uuid = ?1 AND lname != \"__team\"", uuid)
|
||||||
.map(models -> {
|
.map(models -> {
|
||||||
models.forEach(guestModel -> map.put(Utils.getFullName(guestModel),
|
models.forEach(guestModel -> map.put(guestModel.getName(),
|
||||||
getCombTempId(guestModel.getId() * -1)));
|
getCombTempId(guestModel.getId() * -1)));
|
||||||
return map;
|
return map;
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<?> getCombArrayPublic(String uuid, String combTempId, ResultPrivacy privacy) {
|
public Uni<?> getCombArrayPublic(String uuid, String combTempId, SecurityCtx securityCtx) {
|
||||||
|
return hasAccess(uuid, securityCtx)
|
||||||
|
.chain(membreModel -> getCombArrayPublic(uuid, combTempId, ResultPrivacy.REGISTERED_ONLY));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<?> getCombArrayPublic(String uuid, String combTempId) {
|
||||||
|
return getCombArrayPublic(uuid, combTempId, ResultPrivacy.PUBLIC);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Uni<?> getCombArrayPublic(String uuid, String combTempId, ResultPrivacy privacy) {
|
||||||
CombArrayData.CombArrayDataBuilder builder = CombArrayData.builder();
|
CombArrayData.CombArrayDataBuilder builder = CombArrayData.builder();
|
||||||
|
|
||||||
Long id = getCombTempId(combTempId);
|
Long id = getCombTempId(combTempId);
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
return Uni.createFrom().failure(new DForbiddenException("Comb not found"));
|
return Uni.createFrom().failure(new DForbiddenException(trad.t("comb.not.found")));
|
||||||
}
|
}
|
||||||
|
|
||||||
Uni<List<MatchModel>> uni;
|
Uni<List<MatchModelExtend>> uni;
|
||||||
if (id >= 0) {
|
if (id >= 0) {
|
||||||
uni = registerRepository.find("membre.id = ?1 AND competition.uuid = ?2 AND membre.resultPrivacy <= ?3", id,
|
uni = registerRepository.find("membre.id = ?1 AND competition.uuid = ?2 AND membre.resultPrivacy <= ?3", id,
|
||||||
uuid, privacy).firstResult()
|
uuid, privacy).firstResult()
|
||||||
.chain(Unchecked.function(registerModel -> {
|
.chain(Unchecked.function(registerModel -> {
|
||||||
if (registerModel == null)
|
if (registerModel == null)
|
||||||
throw new DBadRequestException("Combattant non inscrit");
|
throw new DBadRequestException(trad.t("combattant.non.inscrit"));
|
||||||
|
|
||||||
builder.name(Utils.getFullName(registerModel.getMembre()));
|
builder.name(Utils.getFullName(registerModel.getMembre()));
|
||||||
builder.club((registerModel.getClub2() == null) ? BUNDLE.getString(
|
builder.club((registerModel.getClub2() == null) ? trad.t("no.licence") :
|
||||||
"no.licence") : registerModel.getClub2().getName());
|
registerModel.getClub2().getName());
|
||||||
builder.cat((registerModel.getCategorie2() == null) ? "---" : registerModel.getCategorie2()
|
builder.cat((registerModel.getCategorie2() == null) ? "---" :
|
||||||
.getName(BUNDLE));
|
registerModel.getCategorie2().getName(trad));
|
||||||
|
|
||||||
return matchRepository.list("category.compet.uuid = ?1 AND (c1_id = ?2 OR c2_id = ?2)", uuid,
|
return matchRepository.list(
|
||||||
registerModel.getMembre());
|
"SELECT DISTINCT m FROM MatchModel m LEFT JOIN m.c1_guest.comb c1g LEFT JOIN m.c2_guest.comb c2g " +
|
||||||
|
"WHERE m.category.compet.uuid = ?1 AND (m.c1_id = ?2 OR m.c2_id = ?2 OR c1g = ?2 OR c2g = ?2)",
|
||||||
|
uuid, registerModel.getMembre())
|
||||||
|
.chain(matchModels -> cardRepository.list("competition.uuid = ?1", uuid)
|
||||||
|
.map(cards -> matchModels.stream().map(m -> new MatchModelExtend(m, cards))
|
||||||
|
.toList()));
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
uni = competitionGuestRepository.find("id = ?1 AND competition.uuid = ?2", -id, uuid).firstResult()
|
uni = competitionGuestRepository.find("id = ?1 AND competition.uuid = ?2", -id, uuid).firstResult()
|
||||||
.chain(guestModel -> {
|
.chain(guestModel -> {
|
||||||
builder.name(Utils.getFullName(guestModel));
|
builder.name(Utils.getFullName(guestModel));
|
||||||
builder.club(guestModel.getClub());
|
builder.club(guestModel.getClub());
|
||||||
builder.cat((guestModel.getCategorie() == null) ? "---" : guestModel.getCategorie()
|
builder.cat(
|
||||||
.getName(BUNDLE));
|
(guestModel.getCategorie() == null) ? "---" : guestModel.getCategorie().getName(trad));
|
||||||
|
|
||||||
return matchRepository.list("category.compet.uuid = ?1 AND (c1_guest = ?2 OR c2_guest = ?2)",
|
return matchRepository.list(
|
||||||
uuid, guestModel);
|
"SELECT DISTINCT m FROM MatchModel m LEFT JOIN m.c1_guest.guest c1g LEFT JOIN m.c2_guest.guest c2g " +
|
||||||
|
"WHERE m.category.compet.uuid = ?1 AND (m.c1_guest = ?2 OR m.c2_guest = ?2 OR c1g = ?2 OR c2g = ?2)",
|
||||||
|
uuid, guestModel)
|
||||||
|
.chain(matchModels -> cardRepository.list("competition.uuid = ?1", uuid)
|
||||||
|
.map(cards -> matchModels.stream().map(m -> new MatchModelExtend(m, cards))
|
||||||
|
.toList()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return uni.invoke(matchModels -> {
|
return uni.invoke(matchModels -> {
|
||||||
List<CategoryModel> pouleModels = matchModels.stream().map(MatchModel::getCategory).distinct()
|
List<CategoryModel> pouleModels = matchModels.stream().map(MatchModelExtend::getCategory).distinct()
|
||||||
.toList();
|
.toList();
|
||||||
List<CombArrayData.MatchsData> matchs = new ArrayList<>();
|
List<CombArrayData.MatchsData> matchs = new ArrayList<>();
|
||||||
|
|
||||||
@@ -376,7 +473,7 @@ public class ResultService {
|
|||||||
AtomicInteger sumPointMake = new AtomicInteger(0);
|
AtomicInteger sumPointMake = new AtomicInteger(0);
|
||||||
AtomicInteger sumPointTake = new AtomicInteger(0);
|
AtomicInteger sumPointTake = new AtomicInteger(0);
|
||||||
|
|
||||||
for (MatchModel matchModel : matchModels) {
|
for (MatchModelExtend matchModel : matchModels) {
|
||||||
if ((matchModel.getC1_id() == null && matchModel.getC1_guest() == null) ||
|
if ((matchModel.getC1_id() == null && matchModel.getC1_guest() == null) ||
|
||||||
(matchModel.getC2_id() == null && matchModel.getC2_guest() == null))
|
(matchModel.getC2_id() == null && matchModel.getC2_guest() == null))
|
||||||
continue;
|
continue;
|
||||||
@@ -385,42 +482,41 @@ public class ResultService {
|
|||||||
builder2.date(matchModel.getDate());
|
builder2.date(matchModel.getDate());
|
||||||
builder2.poule(pouleModels.stream().filter(p -> p.equals(matchModel.getCategory()))
|
builder2.poule(pouleModels.stream().filter(p -> p.equals(matchModel.getCategory()))
|
||||||
.map(CategoryModel::getName).findFirst().orElse(""));
|
.map(CategoryModel::getName).findFirst().orElse(""));
|
||||||
|
builder2.end(matchModel.isEnd());
|
||||||
|
|
||||||
AtomicInteger pointMake = new AtomicInteger();
|
AtomicInteger pointMake = new AtomicInteger();
|
||||||
AtomicInteger pointTake = new AtomicInteger();
|
AtomicInteger pointTake = new AtomicInteger();
|
||||||
|
|
||||||
if (matchModel.isC1(id)) {
|
if (matchModel.isC1(id)) {
|
||||||
builder2.adv(Utils.getFullName(matchModel.getC2_id(), matchModel.getC2_guest()));
|
builder2.adv(matchModel.getC2Name());
|
||||||
if (matchModel.isEnd()) {
|
if (matchModel.isEnd()) {
|
||||||
matchModel.getScores().stream()
|
matchModel.getScoresToCompute()
|
||||||
.filter(s -> s.getS1() > -900 && s.getS2() > -900)
|
|
||||||
.forEach(scoreEntity -> {
|
.forEach(scoreEntity -> {
|
||||||
pointMake.addAndGet(scoreEntity.getS1());
|
pointMake.addAndGet(scoreEntity.getS1());
|
||||||
pointTake.addAndGet(scoreEntity.getS2());
|
pointTake.addAndGet(scoreEntity.getS2());
|
||||||
});
|
});
|
||||||
builder2.score(matchModel.getScores().stream()
|
builder2.score(matchModel.getScoresToPrint().stream()
|
||||||
.map(s -> new Integer[]{s.getS1(), s.getS2()}).toList());
|
.map(s -> new Integer[]{s.getS1(), s.getS2()}).toList());
|
||||||
} else {
|
} else {
|
||||||
builder2.score(new ArrayList<>());
|
builder2.score(new ArrayList<>());
|
||||||
}
|
}
|
||||||
builder2.win(matchModel.win() > 0);
|
builder2.win(matchModel.isEnd() && matchModel.getWin() > 0);
|
||||||
} else {
|
} else {
|
||||||
builder2.adv(Utils.getFullName(matchModel.getC1_id(), matchModel.getC1_guest()));
|
builder2.adv(matchModel.getC1Name());
|
||||||
if (matchModel.isEnd()) {
|
if (matchModel.isEnd()) {
|
||||||
matchModel.getScores().stream()
|
matchModel.getScoresToCompute()
|
||||||
.filter(s -> s.getS1() > -900 && s.getS2() > -900)
|
|
||||||
.forEach(scoreEntity -> {
|
.forEach(scoreEntity -> {
|
||||||
pointMake.addAndGet(scoreEntity.getS2());
|
pointMake.addAndGet(scoreEntity.getS2());
|
||||||
pointTake.addAndGet(scoreEntity.getS1());
|
pointTake.addAndGet(scoreEntity.getS1());
|
||||||
});
|
});
|
||||||
builder2.score(matchModel.getScores().stream()
|
builder2.score(matchModel.getScoresToPrint().stream()
|
||||||
.map(s -> new Integer[]{s.getS2(), s.getS1()}).toList());
|
.map(s -> new Integer[]{s.getS2(), s.getS1()}).toList());
|
||||||
} else {
|
} else {
|
||||||
builder2.score(new ArrayList<>());
|
builder2.score(new ArrayList<>());
|
||||||
}
|
}
|
||||||
builder2.win(matchModel.win() < 0);
|
builder2.win(matchModel.isEnd() && matchModel.getWin() < 0);
|
||||||
}
|
}
|
||||||
|
builder2.eq(matchModel.isEnd() && matchModel.getWin() == 0);
|
||||||
builder2.ratio(
|
builder2.ratio(
|
||||||
(pointTake.get() == 0) ? pointMake.get() : (float) pointMake.get() / pointTake.get());
|
(pointTake.get() == 0) ? pointMake.get() : (float) pointMake.get() / pointTake.get());
|
||||||
|
|
||||||
@@ -464,10 +560,14 @@ public class ResultService {
|
|||||||
@Builder
|
@Builder
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public static record MatchsData(Date date, String poule, String adv, List<Integer[]> score, float ratio,
|
public static record MatchsData(Date date, String poule, String adv, List<Integer[]> score, float ratio,
|
||||||
boolean win) {
|
boolean win, boolean eq, boolean end) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Uni<HashMap<String, Long>> getClubList(String uuid, SecurityCtx securityCtx) {
|
||||||
|
return hasAccess(uuid, securityCtx).chain(__ -> getClubList(uuid));
|
||||||
|
}
|
||||||
|
|
||||||
public Uni<HashMap<String, Long>> getClubList(String uuid) {
|
public Uni<HashMap<String, Long>> getClubList(String uuid) {
|
||||||
return registerRepository.list("competition.uuid = ?1", uuid)
|
return registerRepository.list("competition.uuid = ?1", uuid)
|
||||||
.map(registers -> {
|
.map(registers -> {
|
||||||
@@ -488,55 +588,76 @@ public class ResultService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Uni<ClubArrayData> getClubArray(String uuid, Long id, SecurityCtx securityCtx) {
|
public Uni<ClubArrayData> getClubArray(String uuid, Long id, SecurityCtx securityCtx) {
|
||||||
return hasAccess(uuid, securityCtx).chain(cm_register -> getClubArray2(uuid, id, cm_register.getMembre()));
|
return hasAccess(uuid, securityCtx).chain(membreModel -> getClubArray2(uuid, id, membreModel));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<ClubArrayData> getClubArray2(String uuid, Long id, MembreModel membreModel) {
|
public Uni<ClubArrayData> getClubArray2(String uuid, Long id, MembreModel membreModel) {
|
||||||
if (id < 0) {
|
if (id < 0) {
|
||||||
String clubName = getClubTempId(id);
|
String clubName = getClubTempId(id);
|
||||||
if (clubName == null) {
|
if (clubName == null) {
|
||||||
return Uni.createFrom().failure(new DForbiddenException("Club not found"));
|
return Uni.createFrom().failure(new DForbiddenException(trad.t("club.not.found")));
|
||||||
}
|
}
|
||||||
|
|
||||||
return competitionGuestRepository.list("competition.uuid = ?1 AND club = ?2", uuid, clubName)
|
return competitionGuestRepository.list("competition.uuid = ?1 AND club = ?2", uuid, clubName)
|
||||||
.call(list -> {
|
.call(list -> {
|
||||||
if (list.isEmpty())
|
if (list.isEmpty())
|
||||||
return Uni.createFrom().failure(new DBadRequestException("Club not found"));
|
return Uni.createFrom().failure(new DBadRequestException(trad.t("club.not.found")));
|
||||||
return Uni.createFrom().voidItem();
|
return Uni.createFrom().voidItem();
|
||||||
})
|
})
|
||||||
.chain(guests -> matchRepository.list(
|
.chain(guests -> matchRepository.list(
|
||||||
"category.compet.uuid = ?1 AND (c1_guest IN ?2 OR c2_guest IN ?2)", uuid, guests)
|
"SELECT DISTINCT m FROM MatchModel m LEFT JOIN m.c1_guest.guest c1g LEFT JOIN m.c2_guest.guest c2g " +
|
||||||
.map(matchModels ->
|
"WHERE m.category.compet.uuid = ?1 AND (m.c1_guest IN ?2 OR m.c2_guest IN ?2 OR c1g IN ?2 OR c2g IN ?2)",
|
||||||
getClubArray2(clubName, guests.stream().map(o -> (CombModel) o).toList(),
|
uuid, guests)
|
||||||
matchModels, new ArrayList<>(), membreModel)));
|
|
||||||
|
.chain(mm -> cardRepository.list("competition.uuid = ?1", uuid)
|
||||||
|
.map(cards ->
|
||||||
|
getClubArray2(clubName, guests.stream().map(o -> (CombModel) o).toList(),
|
||||||
|
mm.stream().map(m -> new MatchModelExtend(m, cards)).toList(),
|
||||||
|
new ArrayList<>(), membreModel)
|
||||||
|
)));
|
||||||
} else {
|
} else {
|
||||||
return clubRepository.findById(id).chain(clubModel ->
|
return cardRepository.list("competition.uuid = ?1", uuid)
|
||||||
registerRepository.list("competition.uuid = ?1 AND membre.club = ?2", uuid, clubModel)
|
.chain(cards -> clubRepository.findById(id).chain(clubModel ->
|
||||||
.chain(registers -> matchRepository.list("category.compet.uuid = ?1", uuid)
|
registerRepository.list("competition.uuid = ?1 AND membre.club = ?2", uuid, clubModel)
|
||||||
.map(matchModels ->
|
.chain(registers -> matchRepository.list(
|
||||||
getClubArray2(clubModel.getName(),
|
"SELECT DISTINCT m FROM MatchModel m LEFT JOIN m.c1_guest.comb c1g LEFT JOIN m.c2_guest.comb c2g " +
|
||||||
registers.stream().map(o -> (CombModel) o.getMembre()).toList(),
|
"WHERE m.category.compet.uuid = ?1 AND (m.c1_id IN ?2 OR m.c2_id IN ?2 OR c1g IN ?2 OR c2g IN ?2)",
|
||||||
matchModels, registers, membreModel))));
|
uuid, registers.stream().map(RegisterModel::getMembre).toList())
|
||||||
|
.map(matchModels -> matchModels.stream()
|
||||||
|
.map(m -> new MatchModelExtend(m, cards)))
|
||||||
|
.chain(s -> competitionGuestRepository.list(
|
||||||
|
"competition.uuid = ?1 AND club = ?2", uuid, clubModel.getName())
|
||||||
|
.chain(guests -> matchRepository.list(
|
||||||
|
"SELECT DISTINCT m FROM MatchModel m LEFT JOIN m.c1_guest.guest c1g LEFT JOIN m.c2_guest.guest c2g " +
|
||||||
|
"WHERE m.category.compet.uuid = ?1 AND (m.c1_guest IN ?2 OR m.c2_guest IN ?2 OR c1g IN ?2 OR c2g IN ?2)",
|
||||||
|
uuid, guests)
|
||||||
|
.map(mm -> new Pair<>(guests, Stream.concat(s, mm.stream()
|
||||||
|
.map(m -> new MatchModelExtend(m, cards)))
|
||||||
|
.distinct().toList()))
|
||||||
|
))
|
||||||
|
.map(p ->
|
||||||
|
getClubArray2(clubModel.getName(),
|
||||||
|
Stream.concat(
|
||||||
|
registers.stream().map(RegisterModel::getMembre),
|
||||||
|
p.getKey().stream()
|
||||||
|
).toList(),
|
||||||
|
p.getValue(), registers, membreModel)
|
||||||
|
))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClubArrayData getClubArray2(String name, List<CombModel> combs, List<MatchModel> matchModels,
|
private ClubArrayData getClubArray2(String name, List<CombModel> combs, List<MatchModelExtend> matchModels,
|
||||||
List<RegisterModel> registers, MembreModel membreModel) {
|
List<RegisterModel> registers, MembreModel membreModel) {
|
||||||
ClubArrayData.ClubArrayDataBuilder builder = ClubArrayData.builder();
|
ClubArrayData.ClubArrayDataBuilder builder = ClubArrayData.builder();
|
||||||
builder.name(name);
|
builder.name(name);
|
||||||
builder.nb_insc(combs.size());
|
builder.nb_insc(combs.size());
|
||||||
|
|
||||||
AtomicInteger tt_win = new AtomicInteger(0);
|
ArrayList<Long> win_ids = new ArrayList<>();
|
||||||
AtomicInteger tt_match = new AtomicInteger(0);
|
ArrayList<Long> match_ids = new ArrayList<>();
|
||||||
|
|
||||||
List<ClubArrayData.CombData> combData = combs.stream().map(comb -> {
|
List<ClubArrayData.CombData> combData = combs.stream().map(comb -> {
|
||||||
var builder2 = ClubArrayData.CombData.builder();
|
var builder2 = ClubArrayData.CombData.builder();
|
||||||
AtomicInteger w = new AtomicInteger(0);
|
CombStat stat = makeStat(matchModels, comb);
|
||||||
AtomicInteger l = new AtomicInteger(0);
|
|
||||||
AtomicInteger pointMake = new AtomicInteger();
|
|
||||||
AtomicInteger pointTake = new AtomicInteger();
|
|
||||||
|
|
||||||
makeStat(matchModels, comb, w, l, pointMake, pointTake);
|
|
||||||
|
|
||||||
Categorie categorie = null;
|
Categorie categorie = null;
|
||||||
|
|
||||||
@@ -550,25 +671,25 @@ public class ResultService {
|
|||||||
categorie = model.getCategorie();
|
categorie = model.getCategorie();
|
||||||
}
|
}
|
||||||
|
|
||||||
builder2.cat((categorie == null) ? "---" : categorie.getName(BUNDLE));
|
builder2.cat((categorie == null) ? "---" : categorie.getName(trad));
|
||||||
builder2.name(comb.getName(membreModel, ResultPrivacy.REGISTERED_ONLY));
|
builder2.name(comb.getName(membreModel, ResultPrivacy.REGISTERED_ONLY));
|
||||||
builder2.w(w.get());
|
builder2.w(stat.w);
|
||||||
builder2.l(l.get());
|
builder2.l(stat.l);
|
||||||
builder2.ratioVictoire((l.get() == 0) ? w.get() : (float) w.get() / l.get());
|
builder2.ratioVictoire((stat.l == 0) ? stat.w : (float) stat.w / stat.l);
|
||||||
builder2.pointMake(pointMake.get());
|
builder2.pointMake(stat.pointMake);
|
||||||
builder2.pointTake(pointTake.get());
|
builder2.pointTake(stat.pointTake);
|
||||||
builder2.ratioPoint((pointTake.get() == 0) ? pointMake.get() : (float) pointMake.get() / pointTake.get());
|
builder2.ratioPoint(stat.getPointRate());
|
||||||
|
|
||||||
tt_win.addAndGet(w.get());
|
win_ids.addAll(stat.win_ids);
|
||||||
tt_match.addAndGet(w.get() + l.get());
|
match_ids.addAll(stat.match_ids);
|
||||||
|
|
||||||
return builder2.build();
|
return builder2.build();
|
||||||
})
|
})
|
||||||
.sorted(Comparator.comparing(ClubArrayData.CombData::name))
|
.sorted(Comparator.comparing(ClubArrayData.CombData::name))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
builder.nb_match(tt_match.get());
|
builder.nb_match((int) match_ids.stream().distinct().count());
|
||||||
builder.match_w(tt_win.get());
|
builder.match_w((int) win_ids.stream().distinct().count());
|
||||||
builder.ratioVictoire((float) combData.stream().filter(c -> c.l + c.w != 0)
|
builder.ratioVictoire((float) combData.stream().filter(c -> c.l + c.w != 0)
|
||||||
.mapToDouble(ClubArrayData.CombData::ratioVictoire).average().orElse(0L));
|
.mapToDouble(ClubArrayData.CombData::ratioVictoire).average().orElse(0L));
|
||||||
builder.pointMake(combData.stream().mapToInt(ClubArrayData.CombData::pointMake).sum());
|
builder.pointMake(combData.stream().mapToInt(ClubArrayData.CombData::pointMake).sum());
|
||||||
@@ -580,30 +701,36 @@ public class ResultService {
|
|||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void makeStat(List<MatchModel> matchModels, CombModel comb, AtomicInteger w, AtomicInteger l,
|
private static CombStat makeStat(List<MatchModelExtend> matchModels, CombModel comb) {
|
||||||
AtomicInteger pointMake, AtomicInteger pointTake) {
|
CombStat stat = new CombStat();
|
||||||
matchModels.stream()
|
matchModels.stream()
|
||||||
.filter(m -> m.isEnd() && (m.isC1(comb) || m.isC2(comb)))
|
.filter(m -> m.isEnd() && (m.isC1(comb) || m.isC2(comb)))
|
||||||
.forEach(matchModel -> {
|
.forEach(matchModel -> {
|
||||||
int win = matchModel.win();
|
stat.match_ids.add(matchModel.getId());
|
||||||
if ((matchModel.isC1(comb) && win > 0) || matchModel.isC2(comb) && win < 0) {
|
|
||||||
w.getAndIncrement();
|
int win = matchModel.getWin();
|
||||||
|
if (win == 0) {
|
||||||
|
stat.score += 1;
|
||||||
|
} else if ((matchModel.isC1(comb) && win > 0) || matchModel.isC2(comb) && win < 0) {
|
||||||
|
stat.w++;
|
||||||
|
stat.win_ids.add(matchModel.getId());
|
||||||
|
stat.score += 2;
|
||||||
} else {
|
} else {
|
||||||
l.getAndIncrement();
|
stat.l++;
|
||||||
}
|
}
|
||||||
|
|
||||||
matchModel.getScores().stream()
|
matchModel.getScoresToCompute()
|
||||||
.filter(s -> s.getS1() > -900 && s.getS2() > -900)
|
|
||||||
.forEach(score -> {
|
.forEach(score -> {
|
||||||
if (matchModel.isC1(comb)) {
|
if (matchModel.isC1(comb)) {
|
||||||
pointMake.addAndGet(score.getS1());
|
stat.pointMake += score.getS1();
|
||||||
pointTake.addAndGet(score.getS2());
|
stat.pointTake += score.getS2();
|
||||||
} else {
|
} else {
|
||||||
pointMake.addAndGet(score.getS2());
|
stat.pointMake += score.getS2();
|
||||||
pointTake.addAndGet(score.getS1());
|
stat.pointTake += score.getS1();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
return stat;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Builder
|
@Builder
|
||||||
@@ -617,21 +744,166 @@ public class ResultService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Uni<RegisterModel> hasAccess(String uuid, SecurityCtx securityCtx) {
|
public Uni<List<ClubClassement>> getAllClubArray(String uuid) {
|
||||||
return registerRepository.find("membre.userId = ?1 AND competition.uuid = ?2", securityCtx.getSubject(), uuid)
|
return getAllClubArray(uuid, true);
|
||||||
.firstResult()
|
|
||||||
.invoke(Unchecked.consumer(o -> {
|
|
||||||
if (o == null)
|
|
||||||
throw new DForbiddenException("Access denied");
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Uni<RegisterModel> hasAccess(Long compId, SecurityCtx securityCtx) {
|
public Uni<List<ClubClassement>> getAllClubArray(String uuid, SecurityCtx securityCtx) {
|
||||||
return registerRepository.find("membre.userId = ?1 AND competition.id = ?2", securityCtx.getSubject(), compId)
|
return hasAccess(uuid, securityCtx).chain(membreModel -> getAllClubArray(uuid, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<List<ClubClassement>> getAllClubArray(String uuid, boolean cache) {
|
||||||
|
List<CardModel> cards = new java.util.ArrayList<>();
|
||||||
|
|
||||||
|
return (!cache || cacheClubClassementExp.getOrDefault(uuid, 0L) < System.currentTimeMillis() ?
|
||||||
|
cacheClubClassement.invalidate(uuid).invoke(() -> cacheClubClassementExp.remove(uuid)) :
|
||||||
|
Uni.createFrom().voidItem()
|
||||||
|
).chain(o -> cacheClubClassement.getAsync(uuid, k -> cardRepository.list("competition.uuid = ?1", uuid)
|
||||||
|
.invoke(__ -> System.out.println("Cache miss for club classement with uuid " + uuid))
|
||||||
|
.invoke(cards::addAll)
|
||||||
|
.chain(__ -> matchRepository.list("category.compet.uuid = ?1", uuid))
|
||||||
|
.chain(matchs -> {
|
||||||
|
HashMap<CategoryModel, List<MatchModel>> map = new HashMap<>();
|
||||||
|
for (MatchModel match : matchs) {
|
||||||
|
if (!map.containsKey(match.getCategory()))
|
||||||
|
map.put(match.getCategory(), new java.util.ArrayList<>());
|
||||||
|
map.get(match.getCategory()).add(match);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Multi.createFrom().iterable(map.entrySet())
|
||||||
|
.onItem().call(entry -> Mutiny.fetch(entry.getKey().getTree()))
|
||||||
|
.map(entry -> {
|
||||||
|
ResultCategoryData tmp = new ResultCategoryData();
|
||||||
|
|
||||||
|
getArray2(entry.getValue().stream().map(m -> new MatchModelExtend(m, cards))
|
||||||
|
.toList(),
|
||||||
|
null, tmp);
|
||||||
|
getClassementArray(entry.getKey(), null, cards, tmp);
|
||||||
|
|
||||||
|
return tmp;
|
||||||
|
})
|
||||||
|
.collect().asList();
|
||||||
|
})
|
||||||
|
.map(categoryData -> {
|
||||||
|
HashMap<String, ClubClassement> clubMap = new HashMap<>();
|
||||||
|
|
||||||
|
categoryData.forEach(
|
||||||
|
c -> c.getClassement().stream().map(ResultCategoryData.ClassementData::comb)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.distinct()
|
||||||
|
.map(comb -> {
|
||||||
|
if (comb instanceof MembreModel membreModel2) {
|
||||||
|
return (membreModel2.getClub() != null) ? membreModel2.getClub()
|
||||||
|
.getName() : "";
|
||||||
|
} else if (comb instanceof CompetitionGuestModel guestModel) {
|
||||||
|
return guestModel.getClub();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
})
|
||||||
|
.filter(s -> s != null && !s.isBlank() && !s.equals("Team"))
|
||||||
|
.distinct()
|
||||||
|
.forEach(clubName -> clubMap.putIfAbsent(clubName,
|
||||||
|
new ClubClassement(clubName))));
|
||||||
|
|
||||||
|
categoryData.forEach(c -> c.getClassement().forEach(classementData -> {
|
||||||
|
if (classementData.rank() > 3)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (classementData.comb() != null) {
|
||||||
|
String clubName = "";
|
||||||
|
if (classementData.comb() instanceof MembreModel membreModel2) {
|
||||||
|
clubName = (membreModel2.getClub() != null) ? membreModel2.getClub()
|
||||||
|
.getName() : "";
|
||||||
|
} else if (classementData.comb() instanceof CompetitionGuestModel guestModel) {
|
||||||
|
clubName = guestModel.getClub();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clubName != null && !clubName.isBlank()
|
||||||
|
&& !clubName.equals("Team") && clubMap.containsKey(clubName)) {
|
||||||
|
ClubClassement entity = clubMap.get(clubName);
|
||||||
|
entity.score[classementData.rank() - 1]++;
|
||||||
|
entity.tt_score += 4 - classementData.rank();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return clubMap.values().stream()
|
||||||
|
.sorted(Comparator.comparingInt((ClubClassement c) -> c.tt_score)
|
||||||
|
.thenComparingInt(c -> c.score[0])
|
||||||
|
.thenComparingInt(c -> c.score[1])
|
||||||
|
.thenComparingInt(c -> c.score[2]).reversed())
|
||||||
|
.toList();
|
||||||
|
})
|
||||||
|
.invoke(__ -> cacheClubClassementExp.put(uuid, System.currentTimeMillis() + 60 * 1000L))
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@RegisterForReflection
|
||||||
|
public static class ClubClassement {
|
||||||
|
String name;
|
||||||
|
Integer[] score = new Integer[]{0, 0, 0};
|
||||||
|
int tt_score = 0;
|
||||||
|
|
||||||
|
public ClubClassement(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RegisterForReflection
|
||||||
|
public static class CombStat {
|
||||||
|
public int w;
|
||||||
|
public int l;
|
||||||
|
public int score;
|
||||||
|
public int pointMake;
|
||||||
|
public int pointTake;
|
||||||
|
public ArrayList<Long> win_ids = new ArrayList<>();
|
||||||
|
public ArrayList<Long> match_ids = new ArrayList<>();
|
||||||
|
|
||||||
|
public CombStat() {
|
||||||
|
this.w = 0;
|
||||||
|
this.l = 0;
|
||||||
|
this.score = 0;
|
||||||
|
this.pointMake = 0;
|
||||||
|
this.pointTake = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getPointRate() {
|
||||||
|
return (pointTake == 0) ? pointMake : (float) pointMake / pointTake;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Uni<MembreModel> hasAccess(String uuid, SecurityCtx securityCtx) {
|
||||||
|
return registerRepository.find("membre.userId = ?1 AND competition.uuid = ?2", securityCtx.getSubject(), uuid)
|
||||||
.firstResult()
|
.firstResult()
|
||||||
.invoke(Unchecked.consumer(o -> {
|
.chain(Unchecked.function(o -> {
|
||||||
if (o == null)
|
if (o != null)
|
||||||
throw new DForbiddenException("Access denied");
|
return Uni.createFrom().item(o.getMembre());
|
||||||
|
|
||||||
|
return membreService.getByAccountId(securityCtx.getSubject()).chain(m -> {
|
||||||
|
if (securityCtx.isClubAdmin()) {
|
||||||
|
return registerRepository.count("membre.club = ?2 AND competition.uuid = ?1",
|
||||||
|
uuid, m.getClub()).chain(c -> {
|
||||||
|
if (c > 0) return Uni.createFrom().item(m);
|
||||||
|
|
||||||
|
return compRepository.count("uuid = ?1 AND (owner = ?2 OR ?2 IN admin)",
|
||||||
|
uuid, securityCtx.getSubject())
|
||||||
|
.chain(c2 -> {
|
||||||
|
if (c2 > 0) return Uni.createFrom().item(m);
|
||||||
|
return Uni.createFrom().failure(new DForbiddenException(
|
||||||
|
trad.t("access.denied")));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return compRepository.count("uuid = ?1 AND (owner = ?2 OR ?2 IN admin)", uuid,
|
||||||
|
securityCtx.getSubject())
|
||||||
|
.chain(c2 -> {
|
||||||
|
if (c2 > 0) return Uni.createFrom().item(m);
|
||||||
|
return Uni.createFrom()
|
||||||
|
.failure(new DForbiddenException(trad.t("access.denied")));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package fr.titionfire.ffsaf.domain.service;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.LogModel;
|
||||||
|
import fr.titionfire.ffsaf.data.model.MembreModel;
|
||||||
|
import fr.titionfire.ffsaf.data.model.SelectionModel;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.CombRepository;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.SelectionRepository;
|
||||||
|
import fr.titionfire.ffsaf.rest.data.SimpleSelection;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.Panache;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
||||||
|
import io.smallrye.mutiny.Uni;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
import jakarta.inject.Inject;
|
||||||
|
import org.hibernate.reactive.mutiny.Mutiny;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
@WithSession
|
||||||
|
@ApplicationScoped
|
||||||
|
public class SelectionService {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CombRepository combRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
SelectionRepository repository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
LoggerService ls;
|
||||||
|
|
||||||
|
public Uni<List<SelectionModel>> getSelection(long id, Consumer<MembreModel> checkPerm) {
|
||||||
|
return combRepository.findById(id).invoke(checkPerm)
|
||||||
|
.chain(combRepository -> Mutiny.fetch(combRepository.getSelections()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<SelectionModel> setSelection(long id, SimpleSelection data) {
|
||||||
|
if (data.getId() == -1) {
|
||||||
|
return combRepository.findById(id).chain(membreModel -> {
|
||||||
|
SelectionModel model = new SelectionModel();
|
||||||
|
|
||||||
|
model.setMembre(membreModel);
|
||||||
|
model.setSaison(data.getSaison());
|
||||||
|
model.setCategorie(data.getCategorie());
|
||||||
|
return Panache.withTransaction(() -> repository.persist(model))
|
||||||
|
.call(licenceModel -> ls.logA(LogModel.ActionType.ADD, membreModel.getObjectName(),
|
||||||
|
licenceModel));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return repository.findById(data.getId()).chain(model -> {
|
||||||
|
ls.logChange("Catégorie", model.getCategorie(), data.getCategorie(), model);
|
||||||
|
model.setCategorie(data.getCategorie());
|
||||||
|
return Panache.withTransaction(() -> repository.persist(model))
|
||||||
|
.call(__ -> ls.append());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<Void> deleteSelection(long id) {
|
||||||
|
return repository.findById(id)
|
||||||
|
.call(model -> ls.logADelete(model))
|
||||||
|
.chain(model -> Panache.withTransaction(() -> repository.delete(model)));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package fr.titionfire.ffsaf.domain.service;
|
||||||
|
|
||||||
|
import io.quarkus.websockets.next.WebSocketConnection;
|
||||||
|
import jakarta.enterprise.context.RequestScoped;
|
||||||
|
import jakarta.enterprise.inject.Instance;
|
||||||
|
import jakarta.inject.Inject;
|
||||||
|
import jakarta.ws.rs.container.ContainerRequestContext;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.MissingResourceException;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
@RequestScoped
|
||||||
|
public class TradService {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
Instance<ContainerRequestContext> requestContextInstance;
|
||||||
|
|
||||||
|
public static final Locale fallbackLocale = Locale.FRANCE;
|
||||||
|
|
||||||
|
public String t(String key) {
|
||||||
|
return translate(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String t(String key, WebSocketConnection connection) {
|
||||||
|
List<String> lang = connection.handshakeRequest().headers().get("Accept-Language");
|
||||||
|
Locale userLocale = lang != null && !lang.isEmpty() ? Locale.forLanguageTag(lang.get(0)) : fallbackLocale;
|
||||||
|
return translate(key, userLocale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String translate(String key) {
|
||||||
|
ContainerRequestContext requestContext = requestContextInstance.get();
|
||||||
|
Locale userLocale = (Locale) requestContext.getProperty("userLocale");
|
||||||
|
|
||||||
|
return translate(key, userLocale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String translate(String key, Locale userLocale) {
|
||||||
|
try {
|
||||||
|
ResourceBundle messages = ResourceBundle.getBundle("lang.messages", userLocale);
|
||||||
|
return messages.getString(key);
|
||||||
|
} catch (MissingResourceException e) {
|
||||||
|
try {
|
||||||
|
ResourceBundle fallbackMessages = ResourceBundle.getBundle("lang.messages", fallbackLocale);
|
||||||
|
return fallbackMessages.getString(key);
|
||||||
|
} catch (MissingResourceException ex) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
package fr.titionfire.ffsaf.rest;
|
package fr.titionfire.ffsaf.rest;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
import fr.titionfire.ffsaf.rest.client.SirenService;
|
import fr.titionfire.ffsaf.rest.client.SirenService;
|
||||||
import fr.titionfire.ffsaf.rest.client.StateIdService;
|
import fr.titionfire.ffsaf.rest.client.StateIdService;
|
||||||
import fr.titionfire.ffsaf.rest.data.AssoData;
|
import fr.titionfire.ffsaf.rest.data.AssoData;
|
||||||
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
|
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
|
||||||
import io.smallrye.mutiny.Uni;
|
import io.smallrye.mutiny.Uni;
|
||||||
|
import jakarta.inject.Inject;
|
||||||
import jakarta.ws.rs.*;
|
import jakarta.ws.rs.*;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import org.eclipse.microprofile.openapi.annotations.Operation;
|
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||||
@@ -19,6 +21,9 @@ public class AssoEndpoints {
|
|||||||
@RestClient
|
@RestClient
|
||||||
SirenService sirenService;
|
SirenService sirenService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("state_id/{stateId}")
|
@Path("state_id/{stateId}")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@@ -28,9 +33,9 @@ public class AssoEndpoints {
|
|||||||
stateId).chain(stateIdService::getAssoDataFromUnit)).onFailure().transform(throwable -> {
|
stateId).chain(stateIdService::getAssoDataFromUnit)).onFailure().transform(throwable -> {
|
||||||
if (throwable instanceof WebApplicationException exception) {
|
if (throwable instanceof WebApplicationException exception) {
|
||||||
if (exception.getResponse().getStatus() == 404)
|
if (exception.getResponse().getStatus() == 404)
|
||||||
return new DNotFoundException("Service momentanément indisponible");
|
return new DNotFoundException(trad.t("service.momentanement.indisponible"));
|
||||||
if (exception.getResponse().getStatus() == 400)
|
if (exception.getResponse().getStatus() == 400)
|
||||||
return new DNotFoundException("Asso introuvable");
|
return new DNotFoundException(trad.t("asso.introuvable"));
|
||||||
}
|
}
|
||||||
return throwable;
|
return throwable;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package fr.titionfire.ffsaf.rest;
|
|||||||
import fr.titionfire.ffsaf.data.model.ClubModel;
|
import fr.titionfire.ffsaf.data.model.ClubModel;
|
||||||
import fr.titionfire.ffsaf.domain.service.ClubService;
|
import fr.titionfire.ffsaf.domain.service.ClubService;
|
||||||
import fr.titionfire.ffsaf.domain.service.PDFService;
|
import fr.titionfire.ffsaf.domain.service.PDFService;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
import fr.titionfire.ffsaf.domain.service.VirusScannerService;
|
import fr.titionfire.ffsaf.domain.service.VirusScannerService;
|
||||||
import fr.titionfire.ffsaf.net2.data.SimpleClubModel;
|
import fr.titionfire.ffsaf.net2.data.SimpleClubModel;
|
||||||
import fr.titionfire.ffsaf.rest.data.*;
|
import fr.titionfire.ffsaf.rest.data.*;
|
||||||
@@ -53,6 +54,9 @@ public class ClubEndpoints {
|
|||||||
@ConfigProperty(name = "upload_dir")
|
@ConfigProperty(name = "upload_dir")
|
||||||
String media;
|
String media;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
Consumer<ClubModel> checkPerm = Unchecked.consumer(clubModel -> {
|
Consumer<ClubModel> checkPerm = Unchecked.consumer(clubModel -> {
|
||||||
if (!securityCtx.roleHas("federation_admin") && !securityCtx.isInClubGroup(clubModel.getId()))
|
if (!securityCtx.roleHas("federation_admin") && !securityCtx.isInClubGroup(clubModel.getId()))
|
||||||
throw new DForbiddenException();
|
throw new DForbiddenException();
|
||||||
@@ -84,7 +88,7 @@ public class ClubEndpoints {
|
|||||||
@Operation(summary = "Renvoie les types de contacts pour les clubs", description = "Renvoie la liste des types de " +
|
@Operation(summary = "Renvoie les types de contacts pour les clubs", description = "Renvoie la liste des types de " +
|
||||||
"contacts possibles pour les clubs")
|
"contacts possibles pour les clubs")
|
||||||
public Uni<HashMap<String, String>> getConcatType() {
|
public Uni<HashMap<String, String>> getConcatType() {
|
||||||
return Uni.createFrom().item(Contact.toSite());
|
return Uni.createFrom().item(Contact.toSite(trad));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -125,7 +129,7 @@ public class ClubEndpoints {
|
|||||||
public Uni<SimpleClub> getById(
|
public Uni<SimpleClub> getById(
|
||||||
@Parameter(description = "Identifiant de club") @PathParam("id") long id) {
|
@Parameter(description = "Identifiant de club") @PathParam("id") long id) {
|
||||||
return clubService.getById(id).onItem().invoke(checkPerm).map(SimpleClub::fromModel)
|
return clubService.getById(id).onItem().invoke(checkPerm).map(SimpleClub::fromModel)
|
||||||
.invoke(m -> m.setContactMap(Contact.toSite()));
|
.invoke(m -> m.setContactMap(Contact.toSite(trad)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@@ -218,7 +222,7 @@ public class ClubEndpoints {
|
|||||||
})
|
})
|
||||||
public Uni<SimpleClub> getOfUser() {
|
public Uni<SimpleClub> getOfUser() {
|
||||||
return clubService.getOfUser(securityCtx).map(SimpleClub::fromModel)
|
return clubService.getOfUser(securityCtx).map(SimpleClub::fromModel)
|
||||||
.invoke(m -> m.setContactMap(Contact.toSite()));
|
.invoke(m -> m.setContactMap(Contact.toSite(trad)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
package fr.titionfire.ffsaf.rest;
|
package fr.titionfire.ffsaf.rest;
|
||||||
|
|
||||||
import fr.titionfire.ffsaf.domain.service.CompetitionService;
|
import fr.titionfire.ffsaf.domain.service.CompetitionService;
|
||||||
import fr.titionfire.ffsaf.rest.data.CompetitionData;
|
import fr.titionfire.ffsaf.rest.data.*;
|
||||||
import fr.titionfire.ffsaf.rest.data.RegisterRequestData;
|
|
||||||
import fr.titionfire.ffsaf.rest.data.SimpleCompetData;
|
|
||||||
import fr.titionfire.ffsaf.rest.data.SimpleRegisterComb;
|
|
||||||
import fr.titionfire.ffsaf.utils.SecurityCtx;
|
import fr.titionfire.ffsaf.utils.SecurityCtx;
|
||||||
import io.quarkus.security.Authenticated;
|
import io.quarkus.security.Authenticated;
|
||||||
import io.smallrye.mutiny.Uni;
|
import io.smallrye.mutiny.Uni;
|
||||||
@@ -53,6 +50,16 @@ public class CompetitionEndpoints {
|
|||||||
return service.addRegisterComb(securityCtx, id, data, source);
|
return service.addRegisterComb(securityCtx, id, data, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("{id}/registers/{source}")
|
||||||
|
@Authenticated
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(hidden = true)
|
||||||
|
public Uni<List<SimpleRegisterComb>> addRegistersComb(@PathParam("id") Long id, @PathParam("source") String source,
|
||||||
|
List<RegisterRequestData> data) {
|
||||||
|
return service.addRegistersComb(securityCtx, id, data, source);
|
||||||
|
}
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("{id}/register/{comb_id}/{source}")
|
@Path("{id}/register/{comb_id}/{source}")
|
||||||
@Authenticated
|
@Authenticated
|
||||||
@@ -71,6 +78,21 @@ public class CompetitionEndpoints {
|
|||||||
return service.getSafcaData(securityCtx, id);
|
return service.getSafcaData(securityCtx, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{id}/internalData")
|
||||||
|
@Authenticated
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public Uni<SimpleCompetData> getInternalData(@PathParam("id") Long id) {
|
||||||
|
return service.getInternalData(securityCtx, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{id}/categories")
|
||||||
|
@Authenticated
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public Uni<List<PresetData>> getPresetsForCompetition(@PathParam("id") Long id) {
|
||||||
|
return service.getPresetsForCompetition(securityCtx, id);
|
||||||
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("all")
|
@Path("all")
|
||||||
@@ -95,6 +117,14 @@ public class CompetitionEndpoints {
|
|||||||
return service.setSafcaData(securityCtx, data);
|
return service.setSafcaData(securityCtx, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/internalData")
|
||||||
|
@Authenticated
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public Uni<?> setInternalData(SimpleCompetData data) {
|
||||||
|
return service.setInternalData(securityCtx, data);
|
||||||
|
}
|
||||||
|
|
||||||
@DELETE
|
@DELETE
|
||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
@Authenticated
|
@Authenticated
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ package fr.titionfire.ffsaf.rest;
|
|||||||
|
|
||||||
import fr.titionfire.ffsaf.domain.service.ResultService;
|
import fr.titionfire.ffsaf.domain.service.ResultService;
|
||||||
import fr.titionfire.ffsaf.domain.service.UpdateService;
|
import fr.titionfire.ffsaf.domain.service.UpdateService;
|
||||||
import fr.titionfire.ffsaf.utils.ResultPrivacy;
|
|
||||||
import io.smallrye.mutiny.Uni;
|
import io.smallrye.mutiny.Uni;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
import jakarta.ws.rs.*;
|
import jakarta.ws.rs.*;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Path("api/public/result/{id}")
|
@Path("api/public/result/{id}")
|
||||||
public class ExternalResultEndpoints {
|
public class ExternalResultEndpoints {
|
||||||
@@ -47,7 +47,7 @@ public class ExternalResultEndpoints {
|
|||||||
@Path("/comb/list")
|
@Path("/comb/list")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Uni<HashMap<String, String>> combList() {
|
public Uni<HashMap<String, String>> combList() {
|
||||||
return resultService.getCombList(id, ResultPrivacy.PUBLIC);
|
return resultService.getCombList(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -56,7 +56,7 @@ public class ExternalResultEndpoints {
|
|||||||
public Uni<?> getArray(@QueryParam("comb") String comb) {
|
public Uni<?> getArray(@QueryParam("comb") String comb) {
|
||||||
if (comb.equals("0"))
|
if (comb.equals("0"))
|
||||||
return Uni.createFrom().item("");
|
return Uni.createFrom().item("");
|
||||||
return resultService.getCombArrayPublic(id, comb, ResultPrivacy.PUBLIC);
|
return resultService.getCombArrayPublic(id, comb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -74,6 +74,13 @@ public class ExternalResultEndpoints {
|
|||||||
return resultService.getClubList(id);
|
return resultService.getClubList(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("/club/classement")
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
public Uni<List<ResultService.ClubClassement>> clubClassement() {
|
||||||
|
return resultService.getAllClubArray(id);
|
||||||
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("/club/data")
|
@Path("/club/data")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ public class LicenceEndpoints {
|
|||||||
@RolesAllowed("federation_admin")
|
@RolesAllowed("federation_admin")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
@Operation(summary = "Créer une licence", description = "Créer unr licence en fonction de son identifiant et des " +
|
@Operation(summary = "Créer une licence", description = "Créer une licence en fonction de son identifiant et des " +
|
||||||
"informations fournies dans le formulaire (pour les administrateurs)")
|
"informations fournies dans le formulaire (pour les administrateurs)")
|
||||||
@APIResponses(value = {
|
@APIResponses(value = {
|
||||||
@APIResponse(responseCode = "200", description = "La licence a été mise à jour avec succès"),
|
@APIResponse(responseCode = "200", description = "La licence a été mise à jour avec succès"),
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package fr.titionfire.ffsaf.rest;
|
|||||||
|
|
||||||
import fr.titionfire.ffsaf.domain.service.ResultService;
|
import fr.titionfire.ffsaf.domain.service.ResultService;
|
||||||
import fr.titionfire.ffsaf.rest.data.ResultCategoryData;
|
import fr.titionfire.ffsaf.rest.data.ResultCategoryData;
|
||||||
import fr.titionfire.ffsaf.utils.ResultPrivacy;
|
|
||||||
import fr.titionfire.ffsaf.utils.SecurityCtx;
|
import fr.titionfire.ffsaf.utils.SecurityCtx;
|
||||||
import io.quarkus.security.Authenticated;
|
import io.quarkus.security.Authenticated;
|
||||||
import io.smallrye.mutiny.Uni;
|
import io.smallrye.mutiny.Uni;
|
||||||
@@ -33,7 +32,7 @@ public class ResultEndpoints {
|
|||||||
@GET
|
@GET
|
||||||
@Path("{uuid}/category/list")
|
@Path("{uuid}/category/list")
|
||||||
public Uni<HashMap<String, Long>> getCategoryList(@PathParam("uuid") String uuid) {
|
public Uni<HashMap<String, Long>> getCategoryList(@PathParam("uuid") String uuid) {
|
||||||
return resultService.getCategoryList(uuid);
|
return resultService.getCategoryList(uuid, securityCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -45,7 +44,13 @@ public class ResultEndpoints {
|
|||||||
@GET
|
@GET
|
||||||
@Path("{uuid}/club/list")
|
@Path("{uuid}/club/list")
|
||||||
public Uni<HashMap<String, Long>> getClubList(@PathParam("uuid") String uuid) {
|
public Uni<HashMap<String, Long>> getClubList(@PathParam("uuid") String uuid) {
|
||||||
return resultService.getClubList(uuid);
|
return resultService.getClubList(uuid, securityCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{uuid}/club/classement")
|
||||||
|
public Uni<List<ResultService.ClubClassement>> getClubClassement(@PathParam("uuid") String uuid) {
|
||||||
|
return resultService.getAllClubArray(uuid, securityCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -57,13 +62,13 @@ public class ResultEndpoints {
|
|||||||
@GET
|
@GET
|
||||||
@Path("{uuid}/comb/list")
|
@Path("{uuid}/comb/list")
|
||||||
public Uni<HashMap<String, String>> getCombList(@PathParam("uuid") String uuid) {
|
public Uni<HashMap<String, String>> getCombList(@PathParam("uuid") String uuid) {
|
||||||
return resultService.getCombList(uuid, ResultPrivacy.REGISTERED_ONLY);
|
return resultService.getCombList(uuid, securityCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{uuid}/comb/{id}")
|
@Path("{uuid}/comb/{id}")
|
||||||
public Uni<?> getCombList(@PathParam("uuid") String uuid, @PathParam("id") String id) {
|
public Uni<?> getCombList(@PathParam("uuid") String uuid, @PathParam("id") String id) {
|
||||||
return resultService.getCombArrayPublic(uuid, id, ResultPrivacy.REGISTERED_ONLY);
|
return resultService.getCombArrayPublic(uuid, id, securityCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|||||||
@@ -0,0 +1,85 @@
|
|||||||
|
package fr.titionfire.ffsaf.rest;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.MembreModel;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.SelectionService;
|
||||||
|
import fr.titionfire.ffsaf.rest.data.SimpleSelection;
|
||||||
|
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
||||||
|
import fr.titionfire.ffsaf.utils.SecurityCtx;
|
||||||
|
import io.smallrye.mutiny.Uni;
|
||||||
|
import io.smallrye.mutiny.unchecked.Unchecked;
|
||||||
|
import jakarta.annotation.security.RolesAllowed;
|
||||||
|
import jakarta.inject.Inject;
|
||||||
|
import jakarta.ws.rs.*;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.responses.APIResponses;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
@Path("api/selection")
|
||||||
|
public class SelectionEndpoints {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
SelectionService selectionService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
SecurityCtx securityCtx;
|
||||||
|
|
||||||
|
Consumer<MembreModel> checkPerm = Unchecked.consumer(membreModel -> {
|
||||||
|
if (!securityCtx.roleHas("federation_admin") && !securityCtx.isInClubGroup(membreModel.getClub().getId()))
|
||||||
|
throw new DForbiddenException();
|
||||||
|
});
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{id}")
|
||||||
|
@RolesAllowed({"federation_admin", "club_president", "club_secretaire", "club_tresorier", "club_respo_intra",
|
||||||
|
"ffsaf_selectionneur"})
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(summary = "Renvoie les séléctions d'un membre", description = "Renvoie les séléctions d'un membre en fonction " +
|
||||||
|
"de son identifiant")
|
||||||
|
@APIResponses(value = {
|
||||||
|
@APIResponse(responseCode = "200", description = "La liste des séléctions du membre"),
|
||||||
|
@APIResponse(responseCode = "403", description = "Accès refusé"),
|
||||||
|
@APIResponse(responseCode = "404", description = "Le membre n'existe pas"),
|
||||||
|
@APIResponse(responseCode = "500", description = "Erreur interne du serveur")
|
||||||
|
})
|
||||||
|
public Uni<List<SimpleSelection>> getSelection(@PathParam("id") long id) {
|
||||||
|
return selectionService.getSelection(id, checkPerm)
|
||||||
|
.map(selectionModels -> selectionModels.stream().map(SimpleSelection::fromModel).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("{id}")
|
||||||
|
@RolesAllowed({"federation_admin", "ffsaf_selectionneur"})
|
||||||
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Operation(summary = "Créer une séléction", description = "Créer une séléction en fonction de son identifiant et des " +
|
||||||
|
"informations fournies dans le formulaire (pour les administrateurs)")
|
||||||
|
@APIResponses(value = {
|
||||||
|
@APIResponse(responseCode = "200", description = "La séléction a été mise à jour avec succès"),
|
||||||
|
@APIResponse(responseCode = "403", description = "Accès refusé"),
|
||||||
|
@APIResponse(responseCode = "404", description = "La séléction n'existe pas"),
|
||||||
|
@APIResponse(responseCode = "500", description = "Erreur interne du serveur")
|
||||||
|
})
|
||||||
|
public Uni<SimpleSelection> setSelection(@PathParam("id") long id, SimpleSelection data) {
|
||||||
|
return selectionService.setSelection(id, data).map(SimpleSelection::fromModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("{id}")
|
||||||
|
@RolesAllowed({"federation_admin", "ffsaf_selectionneur"})
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@Operation(summary = "Supprime une séléction", description = "Supprime une séléction en fonction de son identifiant " +
|
||||||
|
"(pour les administrateurs)")
|
||||||
|
@APIResponses(value = {
|
||||||
|
@APIResponse(responseCode = "204", description = "La séléction a été supprimée avec succès"),
|
||||||
|
@APIResponse(responseCode = "403", description = "Accès refusé"),
|
||||||
|
@APIResponse(responseCode = "404", description = "La séléction n'existe pas"),
|
||||||
|
@APIResponse(responseCode = "500", description = "Erreur interne du serveur")
|
||||||
|
})
|
||||||
|
public Uni<?> deleteSelection(@PathParam("id") long id) {
|
||||||
|
return selectionService.deleteSelection(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package fr.titionfire.ffsaf.rest.data;
|
package fr.titionfire.ffsaf.rest.data;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.CatPresetModel;
|
||||||
import fr.titionfire.ffsaf.data.model.CompetitionGuestModel;
|
import fr.titionfire.ffsaf.data.model.CompetitionGuestModel;
|
||||||
import fr.titionfire.ffsaf.data.model.CompetitionModel;
|
import fr.titionfire.ffsaf.data.model.CompetitionModel;
|
||||||
import fr.titionfire.ffsaf.data.model.RegisterModel;
|
import fr.titionfire.ffsaf.data.model.RegisterModel;
|
||||||
@@ -10,6 +11,7 @@ import io.quarkus.runtime.annotations.RegisterForReflection;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
@@ -33,12 +35,23 @@ public class CompetitionData {
|
|||||||
private Long club;
|
private Long club;
|
||||||
private String clubName;
|
private String clubName;
|
||||||
private String owner;
|
private String owner;
|
||||||
private List<SimpleRegister> registers;
|
private List<SimpleRegister> registers; // for SAFCA
|
||||||
private boolean canEdit;
|
private boolean canEdit;
|
||||||
|
private boolean canEditRegisters;
|
||||||
private String data1;
|
private String data1;
|
||||||
private String data2;
|
private String data2;
|
||||||
private String data3;
|
private String data3;
|
||||||
private String data4;
|
private String data4;
|
||||||
|
private String config;
|
||||||
|
private List<PresetData> presets;
|
||||||
|
private List<Categorie> requiredWeight;
|
||||||
|
|
||||||
|
public CompetitionData() {
|
||||||
|
this(null, "", "", "", "", new Date(), new Date(),
|
||||||
|
CompetitionSystem.INTERNAL, RegisterMode.FREE, new Date(), new Date(), true,
|
||||||
|
null, "", "", null, true, true,
|
||||||
|
"", "", "", "", "{}", new ArrayList<>(), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
public static CompetitionData fromModel(CompetitionModel model) {
|
public static CompetitionData fromModel(CompetitionModel model) {
|
||||||
if (model == null)
|
if (model == null)
|
||||||
@@ -47,8 +60,9 @@ public class CompetitionData {
|
|||||||
return new CompetitionData(model.getId(), model.getName(), model.getDescription(), model.getAdresse(),
|
return new CompetitionData(model.getId(), model.getName(), model.getDescription(), model.getAdresse(),
|
||||||
model.getUuid(), model.getDate(), model.getTodate(), model.getSystem(),
|
model.getUuid(), model.getDate(), model.getTodate(), model.getSystem(),
|
||||||
model.getRegisterMode(), model.getStartRegister(), model.getEndRegister(), model.isPublicVisible(),
|
model.getRegisterMode(), model.getStartRegister(), model.getEndRegister(), model.isPublicVisible(),
|
||||||
model.getClub().getId(), model.getClub().getName(), model.getOwner(), null, false,
|
model.getClub().getId(), model.getClub().getName(), model.getOwner(), null, false, false,
|
||||||
model.getData1(), model.getData2(), model.getData3(), model.getData4());
|
model.getData1(), model.getData2(), model.getData3(), model.getData4(), model.getConfig(),
|
||||||
|
new ArrayList<>(), model.getRequiredWeight());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompetitionData fromModelLight(CompetitionModel model) {
|
public static CompetitionData fromModelLight(CompetitionModel model) {
|
||||||
@@ -58,36 +72,42 @@ public class CompetitionData {
|
|||||||
CompetitionData out = new CompetitionData(model.getId(), model.getName(), model.getDescription(),
|
CompetitionData out = new CompetitionData(model.getId(), model.getName(), model.getDescription(),
|
||||||
model.getAdresse(), "", model.getDate(), model.getTodate(), null,
|
model.getAdresse(), "", model.getDate(), model.getTodate(), null,
|
||||||
model.getRegisterMode(), model.getStartRegister(), model.getEndRegister(), model.isPublicVisible(),
|
model.getRegisterMode(), model.getStartRegister(), model.getEndRegister(), model.isPublicVisible(),
|
||||||
null, model.getClub().getName(), "", null, false,
|
null, model.getClub().getName(), "", null, false, false,
|
||||||
"", "", "", "");
|
"", "", "", "", "{}", new ArrayList<>(), model.getRequiredWeight());
|
||||||
|
|
||||||
if (model.getRegisterMode() == RegisterMode.HELLOASSO) {
|
if (model.getRegisterMode() == RegisterMode.HELLOASSO) {
|
||||||
out.setData1(model.getData1());
|
out.setData1(model.getData1());
|
||||||
out.setData2(model.getData2());
|
out.setData2(model.getData2());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompetitionData addInsc(List<RegisterModel> insc, List<CompetitionGuestModel> guests) {
|
public CompetitionData addInsc(List<RegisterModel> insc, List<CompetitionGuestModel> guests) {
|
||||||
this.registers = Stream.concat(
|
this.registers = Stream.concat(
|
||||||
insc.stream()
|
insc.stream()
|
||||||
.map(i -> new SimpleRegister(i.getMembre().getId(), i.getOverCategory(), i.getWeight(),
|
.map(i -> new SimpleRegister(i.getMembre().getId(), i.getOverCategory(), i.getWeight2(),
|
||||||
i.getCategorie(), (i.getClub() == null) ? null : i.getClub().getId(),
|
i.getCategorie(), (i.getClub() == null) ? null : i.getClub().getId(),
|
||||||
(i.getClub() == null) ? null : i.getClub().getName())),
|
(i.getClub() == null) ? null : i.getClub().getName())),
|
||||||
guests.stream()
|
guests.stream()
|
||||||
.map(i -> new SimpleRegister(i.getId() * -1, 0, i.getWeight(),
|
.map(i -> new SimpleRegister(i.getId() * -1, 0, i.getWeight2(),
|
||||||
i.getCategorie(), null, i.getClub()))).toList();
|
i.getCategorie(), null, i.getClub()))).toList();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CompetitionData addPresets(List<CatPresetModel> presets) {
|
||||||
|
this.presets = presets.stream().map(PresetData::fromModel).toList();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public static class SimpleRegister {
|
public static class SimpleRegister {
|
||||||
long id;
|
long id;
|
||||||
int overCategory;
|
int overCategory;
|
||||||
Integer weight;
|
Float weight;
|
||||||
Categorie categorie;
|
Categorie categorie;
|
||||||
Long club;
|
Long club;
|
||||||
String club_str;
|
String club_str;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package fr.titionfire.ffsaf.rest.data;
|
package fr.titionfire.ffsaf.rest.data;
|
||||||
|
|
||||||
import fr.titionfire.ffsaf.data.model.MembreModel;
|
import fr.titionfire.ffsaf.data.model.MembreModel;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
import fr.titionfire.ffsaf.utils.ResultPrivacy;
|
import fr.titionfire.ffsaf.utils.ResultPrivacy;
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -44,20 +45,22 @@ public class MeData {
|
|||||||
private ResultPrivacy resultPrivacy;
|
private ResultPrivacy resultPrivacy;
|
||||||
@Schema(description = "La liste des licences du membre.")
|
@Schema(description = "La liste des licences du membre.")
|
||||||
private List<SimpleLicence> licences;
|
private List<SimpleLicence> licences;
|
||||||
|
@Schema(description = "La liste des séléctions du membre.")
|
||||||
|
private List<SimpleSelection> selections;
|
||||||
|
|
||||||
public void setMembre(MembreModel membreModel) {
|
public void setMembre(MembreModel membreModel, TradService trad) {
|
||||||
this.id = membreModel.getId();
|
this.id = membreModel.getId();
|
||||||
this.lname = membreModel.getLname();
|
this.lname = membreModel.getLname();
|
||||||
this.fname = membreModel.getFname();
|
this.fname = membreModel.getFname();
|
||||||
this.categorie = membreModel.getCategorie() == null ? "catégorie inconnue" : membreModel.getCategorie().getName();
|
this.categorie = membreModel.getCategorie() == null ? trad.t("categorie.inconnue") : membreModel.getCategorie().getName(trad);
|
||||||
this.club = membreModel.getClub() == null ? "Sans club" : membreModel.getClub().getName();
|
this.club = membreModel.getClub() == null ? trad.t("sans.club") : membreModel.getClub().getName();
|
||||||
this.genre = membreModel.getGenre().str;
|
this.genre = membreModel.getGenre().getString(trad);
|
||||||
this.licence = membreModel.getLicence();
|
this.licence = membreModel.getLicence();
|
||||||
this.country = membreModel.getCountry();
|
this.country = membreModel.getCountry();
|
||||||
this.birth_date = membreModel.getBirth_date();
|
this.birth_date = membreModel.getBirth_date();
|
||||||
this.email = membreModel.getEmail();
|
this.email = membreModel.getEmail();
|
||||||
this.role = membreModel.getRole().str;
|
this.role = membreModel.getRole().getString(trad);
|
||||||
this.grade_arbitrage = membreModel.getGrade_arbitrage().str;
|
this.grade_arbitrage = membreModel.getGrade_arbitrage().getString(trad);
|
||||||
this.resultPrivacy = membreModel.getResultPrivacy();
|
this.resultPrivacy = membreModel.getResultPrivacy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
31
src/main/java/fr/titionfire/ffsaf/rest/data/PresetData.java
Normal file
31
src/main/java/fr/titionfire/ffsaf/rest/data/PresetData.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package fr.titionfire.ffsaf.rest.data;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.CatPresetModel;
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
public class PresetData {
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private CatPresetModel.SwordType sword;
|
||||||
|
private CatPresetModel.ShieldType shield;
|
||||||
|
private List<CatPresetModel.CategorieEmbeddable> categories;
|
||||||
|
private int mandatoryProtection1;
|
||||||
|
private int mandatoryProtection2;
|
||||||
|
|
||||||
|
public static PresetData fromModel(CatPresetModel model) {
|
||||||
|
if (model == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new PresetData(model.getId(), model.getName(), model.getSwordType(), model.getShieldType(),
|
||||||
|
model.getCategories(), model.getMandatoryProtection1(), model.getMandatoryProtection2());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@@ -16,9 +18,11 @@ public class RegisterRequestData {
|
|||||||
private String fname;
|
private String fname;
|
||||||
private String lname;
|
private String lname;
|
||||||
|
|
||||||
private Integer weight;
|
private Float weight;
|
||||||
private int overCategory;
|
private Float weightReal;
|
||||||
|
private Integer overCategory;
|
||||||
private boolean lockEdit = false;
|
private boolean lockEdit = false;
|
||||||
|
private List<Long> categoriesInscrites;
|
||||||
|
|
||||||
// for guest registration only
|
// for guest registration only
|
||||||
private Long id = null;
|
private Long id = null;
|
||||||
@@ -26,4 +30,6 @@ public class RegisterRequestData {
|
|||||||
private Genre genre = Genre.NA;
|
private Genre genre = Genre.NA;
|
||||||
private String club = null;
|
private String club = null;
|
||||||
private String country = null;
|
private String country = null;
|
||||||
|
|
||||||
|
private boolean quick = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package fr.titionfire.ffsaf.rest.data;
|
package fr.titionfire.ffsaf.rest.data;
|
||||||
|
|
||||||
import fr.titionfire.ffsaf.data.model.MatchModel;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import fr.titionfire.ffsaf.data.model.CombModel;
|
||||||
import fr.titionfire.ffsaf.data.model.MembreModel;
|
import fr.titionfire.ffsaf.data.model.MembreModel;
|
||||||
|
import fr.titionfire.ffsaf.domain.entity.MatchModelExtend;
|
||||||
import fr.titionfire.ffsaf.utils.ResultPrivacy;
|
import fr.titionfire.ffsaf.utils.ResultPrivacy;
|
||||||
import fr.titionfire.ffsaf.utils.ScoreEmbeddable;
|
import fr.titionfire.ffsaf.utils.ScoreEmbeddable;
|
||||||
import fr.titionfire.ffsaf.utils.TreeNode;
|
import fr.titionfire.ffsaf.utils.TreeNode;
|
||||||
@@ -11,6 +13,7 @@ import lombok.Data;
|
|||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -20,9 +23,11 @@ import java.util.List;
|
|||||||
public class ResultCategoryData {
|
public class ResultCategoryData {
|
||||||
int type;
|
int type;
|
||||||
String name;
|
String name;
|
||||||
|
boolean treeIsClassement;
|
||||||
HashMap<Character, List<PouleArrayData>> matchs = new HashMap<>();
|
HashMap<Character, List<PouleArrayData>> matchs = new HashMap<>();
|
||||||
HashMap<Character, List<RankArray>> rankArray = new HashMap<>();
|
HashMap<Character, List<RankArray>> rankArray = new HashMap<>();
|
||||||
ArrayList<TreeNode<TreeData>> trees;
|
ArrayList<TreeNode<TreeData>> trees;
|
||||||
|
List<ClassementData> classement = new ArrayList<>();
|
||||||
String[] liceName;
|
String[] liceName;
|
||||||
long genTime;
|
long genTime;
|
||||||
|
|
||||||
@@ -31,7 +36,10 @@ public class ResultCategoryData {
|
|||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public static class RankArray {
|
public static class RankArray {
|
||||||
int rank;
|
int rank;
|
||||||
|
@JsonIgnore
|
||||||
|
CombModel comb;
|
||||||
String name;
|
String name;
|
||||||
|
int score;
|
||||||
int win;
|
int win;
|
||||||
int pointMake;
|
int pointMake;
|
||||||
int pointTake;
|
int pointTake;
|
||||||
@@ -39,25 +47,37 @@ public class ResultCategoryData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public record PouleArrayData(String red, boolean red_w, List<Integer[]> score, boolean blue_w, String blue, boolean end) {
|
public record PouleArrayData(String red, boolean red_w, List<Integer[]> score, boolean blue_w, String blue,
|
||||||
public static PouleArrayData fromModel(MatchModel matchModel, MembreModel membreModel, ResultPrivacy privacy) {
|
boolean eq, boolean end, Date date) {
|
||||||
|
public static PouleArrayData fromModel(MatchModelExtend matchModel, MembreModel membreModel,
|
||||||
|
ResultPrivacy privacy) {
|
||||||
return new PouleArrayData(
|
return new PouleArrayData(
|
||||||
matchModel.getC1Name(membreModel, privacy),
|
matchModel.getC1Name(membreModel, privacy),
|
||||||
matchModel.isEnd() && matchModel.win() > 0,
|
matchModel.isEnd() && matchModel.getWin() > 0,
|
||||||
matchModel.isEnd() ?
|
matchModel.isEnd() ?
|
||||||
matchModel.getScores().stream().map(s -> new Integer[]{s.getS1(), s.getS2()}).toList()
|
matchModel.getScoresToPrint().stream().map(s -> new Integer[]{s.getS1(), s.getS2()})
|
||||||
|
.toList()
|
||||||
: new ArrayList<>(),
|
: new ArrayList<>(),
|
||||||
matchModel.isEnd() && matchModel.win() < 0,
|
matchModel.isEnd() && matchModel.getWin() < 0,
|
||||||
matchModel.getC2Name(membreModel, privacy),
|
matchModel.getC2Name(membreModel, privacy),
|
||||||
matchModel.isEnd());
|
matchModel.isEnd() && matchModel.getWin() == 0,
|
||||||
|
matchModel.isEnd(),
|
||||||
|
matchModel.getDate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public static record TreeData(long id, String c1FullName, String c2FullName, List<ScoreEmbeddable> scores,
|
public static record TreeData(long id, String c1FullName, String c2FullName, List<ScoreEmbeddable> scores,
|
||||||
boolean end) {
|
boolean end, int win, int level, Date date) {
|
||||||
public static TreeData from(MatchModel match, MembreModel membreModel, ResultPrivacy privacy) {
|
public static TreeData from(MatchModelExtend match, int level, MembreModel membreModel, ResultPrivacy privacy) {
|
||||||
return new TreeData(match.getId(), match.getC1Name(membreModel, privacy), match.getC2Name(membreModel, privacy), match.getScores(), match.isEnd());
|
return new TreeData(match.getId(), match.getC1Name(membreModel, privacy),
|
||||||
|
match.getC2Name(membreModel, privacy), match.getScoresToPrint(), match.isEnd(), match.getWin(),
|
||||||
|
level, match.getDate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RegisterForReflection
|
||||||
|
public static record ClassementData(int rank, @JsonIgnore CombModel comb, String name) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
package fr.titionfire.ffsaf.rest.data;
|
package fr.titionfire.ffsaf.rest.data;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import fr.titionfire.ffsaf.data.model.CompetitionModel;
|
||||||
import fr.titionfire.ffsaf.net2.data.SimpleCompet;
|
import fr.titionfire.ffsaf.net2.data.SimpleCompet;
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
@@ -25,4 +29,41 @@ public class SimpleCompetData {
|
|||||||
return new SimpleCompetData(compet.id(), compet.show_blason(), compet.show_flag(),
|
return new SimpleCompetData(compet.id(), compet.show_blason(), compet.show_flag(),
|
||||||
new ArrayList<>(), new ArrayList<>());
|
new ArrayList<>(), new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SimpleCompetData fromModel(CompetitionModel competitionModel) {
|
||||||
|
if (competitionModel == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
boolean show_blason = true;
|
||||||
|
boolean show_flag = false;
|
||||||
|
|
||||||
|
if (competitionModel.getConfig() != null) {
|
||||||
|
try {
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
JsonNode rootNode = objectMapper.readTree(competitionModel.getConfig());
|
||||||
|
|
||||||
|
if (rootNode.has("show_blason"))
|
||||||
|
show_blason = rootNode.get("show_blason").asBoolean();
|
||||||
|
if (rootNode.has("show_flag"))
|
||||||
|
show_flag = rootNode.get("show_flag").asBoolean();
|
||||||
|
|
||||||
|
} catch (JsonProcessingException ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SimpleCompetData(competitionModel.getId(), show_blason, show_flag,
|
||||||
|
new ArrayList<>(), new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getConfigForInternal(){
|
||||||
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
JsonNode rootNode = objectMapper.createObjectNode()
|
||||||
|
.put("show_blason", this.show_blason)
|
||||||
|
.put("show_flag", this.show_flag);
|
||||||
|
try {
|
||||||
|
return objectMapper.writeValueAsString(rootNode);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
return "{}";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,14 @@ package fr.titionfire.ffsaf.rest.data;
|
|||||||
|
|
||||||
import fr.titionfire.ffsaf.data.model.LicenceModel;
|
import fr.titionfire.ffsaf.data.model.LicenceModel;
|
||||||
import fr.titionfire.ffsaf.data.model.MembreModel;
|
import fr.titionfire.ffsaf.data.model.MembreModel;
|
||||||
|
import fr.titionfire.ffsaf.utils.Utils;
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -24,7 +28,27 @@ public class SimpleMembreInOutData {
|
|||||||
|
|
||||||
public static SimpleMembreInOutData fromModel(MembreModel membreModel, List<LicenceModel> lc) {
|
public static SimpleMembreInOutData fromModel(MembreModel membreModel, List<LicenceModel> lc) {
|
||||||
LicenceModel currentLicence = lc.stream().filter(l -> l.getMembre().getId().equals(membreModel.getId()))
|
LicenceModel currentLicence = lc.stream().filter(l -> l.getMembre().getId().equals(membreModel.getId()))
|
||||||
.findFirst().orElse(null);
|
.max(Comparator.comparingInt(LicenceModel::getSaison)).orElse(null);
|
||||||
|
|
||||||
|
String certif = null;
|
||||||
|
if (currentLicence != null && currentLicence.getCertificate() != null) {
|
||||||
|
String[] strings = currentLicence.getCertificate().split("¤");
|
||||||
|
if (currentLicence.getSaison() == Utils.getSaison()) {
|
||||||
|
certif = currentLicence.getCertificate();
|
||||||
|
} else if (strings.length > 1) {
|
||||||
|
try {
|
||||||
|
Date date = new SimpleDateFormat("yyyy-MM-dd").parse(strings[1]);
|
||||||
|
Calendar max = Utils.getFirstDateOfSaison();
|
||||||
|
max.add(Calendar.YEAR, -2);
|
||||||
|
|
||||||
|
if (max.getTime().compareTo(date) < 0) {
|
||||||
|
certif = currentLicence.getCertificate();
|
||||||
|
}
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return new SimpleMembreInOutData(
|
return new SimpleMembreInOutData(
|
||||||
membreModel.getLicence(),
|
membreModel.getLicence(),
|
||||||
@@ -33,8 +57,8 @@ public class SimpleMembreInOutData {
|
|||||||
membreModel.getEmail(),
|
membreModel.getEmail(),
|
||||||
membreModel.getGenre().str,
|
membreModel.getGenre().str,
|
||||||
membreModel.getBirth_date(),
|
membreModel.getBirth_date(),
|
||||||
currentLicence != null,
|
currentLicence != null && currentLicence.getSaison() == Utils.getSaison(),
|
||||||
currentLicence == null ? null : currentLicence.getCertificate()
|
certif
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
package fr.titionfire.ffsaf.rest.data;
|
package fr.titionfire.ffsaf.rest.data;
|
||||||
|
|
||||||
import fr.titionfire.ffsaf.data.model.CompetitionGuestModel;
|
import fr.titionfire.ffsaf.data.model.*;
|
||||||
import fr.titionfire.ffsaf.data.model.LicenceModel;
|
|
||||||
import fr.titionfire.ffsaf.data.model.MembreModel;
|
|
||||||
import fr.titionfire.ffsaf.data.model.RegisterModel;
|
|
||||||
import fr.titionfire.ffsaf.net2.data.SimpleClubModel;
|
import fr.titionfire.ffsaf.net2.data.SimpleClubModel;
|
||||||
import fr.titionfire.ffsaf.utils.Categorie;
|
import fr.titionfire.ffsaf.utils.Categorie;
|
||||||
import fr.titionfire.ffsaf.utils.Genre;
|
import fr.titionfire.ffsaf.utils.Genre;
|
||||||
@@ -11,11 +8,14 @@ import fr.titionfire.ffsaf.utils.Utils;
|
|||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public class SimpleRegisterComb {
|
public class SimpleRegisterComb {
|
||||||
private long id;
|
private long id;
|
||||||
@@ -26,10 +26,12 @@ public class SimpleRegisterComb {
|
|||||||
private Categorie categorie;
|
private Categorie categorie;
|
||||||
private SimpleClubModel club;
|
private SimpleClubModel club;
|
||||||
private Integer licence;
|
private Integer licence;
|
||||||
private Integer weight;
|
private Float weight;
|
||||||
|
private Float weightReal;
|
||||||
private int overCategory;
|
private int overCategory;
|
||||||
private boolean hasLicenceActive;
|
private boolean hasLicenceActive;
|
||||||
private boolean lockEdit;
|
private boolean lockEdit;
|
||||||
|
private List<Long> categoriesInscrites;
|
||||||
|
|
||||||
public static SimpleRegisterComb fromModel(RegisterModel register, List<LicenceModel> licences) {
|
public static SimpleRegisterComb fromModel(RegisterModel register, List<LicenceModel> licences) {
|
||||||
MembreModel membreModel = register.getMembre();
|
MembreModel membreModel = register.getMembre();
|
||||||
@@ -37,15 +39,21 @@ public class SimpleRegisterComb {
|
|||||||
membreModel.getGenre(), membreModel.getCountry(),
|
membreModel.getGenre(), membreModel.getCountry(),
|
||||||
(register.getCategorie() == null) ? null : register.getCategorie(),
|
(register.getCategorie() == null) ? null : register.getCategorie(),
|
||||||
SimpleClubModel.fromModel(register.getClub()), membreModel.getLicence(), register.getWeight(),
|
SimpleClubModel.fromModel(register.getClub()), membreModel.getLicence(), register.getWeight(),
|
||||||
register.getOverCategory(),
|
register.getWeightReal(), register.getOverCategory(),
|
||||||
licences.stream().anyMatch(l -> l.isValidate() && l.getSaison() == Utils.getSaison()),
|
licences.stream().anyMatch(l -> l.isValidate() && l.getSaison() == Utils.getSaison()),
|
||||||
register.isLockEdit());
|
register.isLockEdit(), new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SimpleRegisterComb fromModel(CompetitionGuestModel guest) {
|
public static SimpleRegisterComb fromModel(CompetitionGuestModel guest) {
|
||||||
return new SimpleRegisterComb(guest.getId() * -1, guest.getFname(), guest.getLname(),
|
return new SimpleRegisterComb(guest.getId() * -1, guest.getFname(), guest.getLname(),
|
||||||
guest.getGenre(), guest.getCountry(), guest.getCategorie(),
|
guest.getGenre(), guest.getCountry(), guest.getCategorie(),
|
||||||
new SimpleClubModel(null, guest.getClub(), "fr", null),
|
new SimpleClubModel(null, guest.getClub(), "fr", null),
|
||||||
null, guest.getWeight(), 0, false, false);
|
null, guest.getWeight(), guest.getWeightReal(), 0, false, false,
|
||||||
|
new ArrayList<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleRegisterComb setCategorieInscrite(List<CatPresetModel> presets) {
|
||||||
|
this.categoriesInscrites = presets.stream().map(CatPresetModel::getId).toList();
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
package fr.titionfire.ffsaf.rest.data;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.SelectionModel;
|
||||||
|
import fr.titionfire.ffsaf.utils.Categorie;
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.eclipse.microprofile.openapi.annotations.media.Schema;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
public class SimpleSelection {
|
||||||
|
@Schema(description = "ID de la séléction", examples = "1")
|
||||||
|
Long id;
|
||||||
|
@Schema(description = "ID du membre", examples = "1")
|
||||||
|
Long membre;
|
||||||
|
@Schema(description = "Saison de la séléction", examples = "2024")
|
||||||
|
int saison;
|
||||||
|
@Schema(description = "Catégorie de la séléction", examples = "JUNIOR")
|
||||||
|
Categorie categorie;
|
||||||
|
|
||||||
|
public static SimpleSelection fromModel(SelectionModel model) {
|
||||||
|
if (model == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new SimpleSelection.SimpleSelectionBuilder()
|
||||||
|
.id(model.getId())
|
||||||
|
.membre(model.getMembre().getId())
|
||||||
|
.saison(model.getSaison())
|
||||||
|
.categorie(model.getCategorie())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package fr.titionfire.ffsaf.utils;
|
package fr.titionfire.ffsaf.utils;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
@@ -19,7 +20,7 @@ public enum Categorie {
|
|||||||
VETERAN2;
|
VETERAN2;
|
||||||
|
|
||||||
public String getName(ResourceBundle BUNDLE) {
|
public String getName(ResourceBundle BUNDLE) {
|
||||||
return switch (this){
|
return switch (this) {
|
||||||
case SUPER_MINI -> BUNDLE.getString("Cat.SUPER_MINI");
|
case SUPER_MINI -> BUNDLE.getString("Cat.SUPER_MINI");
|
||||||
case MINI_POUSSIN -> BUNDLE.getString("Cat.MINI_POUSSIN");
|
case MINI_POUSSIN -> BUNDLE.getString("Cat.MINI_POUSSIN");
|
||||||
case POUSSIN -> BUNDLE.getString("Cat.POUSSIN");
|
case POUSSIN -> BUNDLE.getString("Cat.POUSSIN");
|
||||||
@@ -34,8 +35,24 @@ public enum Categorie {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getName(TradService tradService) {
|
||||||
|
return switch (this) {
|
||||||
|
case SUPER_MINI -> tradService.translate("Cat.SUPER_MINI");
|
||||||
|
case MINI_POUSSIN -> tradService.translate("Cat.MINI_POUSSIN");
|
||||||
|
case POUSSIN -> tradService.translate("Cat.POUSSIN");
|
||||||
|
case BENJAMIN -> tradService.translate("Cat.BENJAMIN");
|
||||||
|
case MINIME -> tradService.translate("Cat.MINIME");
|
||||||
|
case CADET -> tradService.translate("Cat.CADET");
|
||||||
|
case JUNIOR -> tradService.translate("Cat.JUNIOR");
|
||||||
|
case SENIOR1 -> tradService.translate("Cat.SENIOR1");
|
||||||
|
case SENIOR2 -> tradService.translate("Cat.SENIOR2");
|
||||||
|
case VETERAN1 -> tradService.translate("Cat.VETERAN1");
|
||||||
|
case VETERAN2 -> tradService.translate("Cat.VETERAN2");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return switch (this){
|
return switch (this) {
|
||||||
case SUPER_MINI -> "Super Mini";
|
case SUPER_MINI -> "Super Mini";
|
||||||
case MINI_POUSSIN -> "Mini Poussin";
|
case MINI_POUSSIN -> "Mini Poussin";
|
||||||
case POUSSIN -> "Poussin";
|
case POUSSIN -> "Poussin";
|
||||||
|
|||||||
@@ -1,32 +1,34 @@
|
|||||||
package fr.titionfire.ffsaf.utils;
|
package fr.titionfire.ffsaf.utils;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public enum Contact {
|
public enum Contact {
|
||||||
COURRIEL("Courriel"),
|
COURRIEL,
|
||||||
TELEPHONE("Téléphone"),
|
TELEPHONE,
|
||||||
SITE("Site web"),
|
SITE,
|
||||||
FACEBOOK("Facebook"),
|
FACEBOOK,
|
||||||
INSTAGRAM("Instagram"),
|
INSTAGRAM,
|
||||||
AUTRE("Autre");
|
AUTRE;
|
||||||
|
|
||||||
public String name;
|
public String getName(TradService trad) {
|
||||||
|
return switch (this) {
|
||||||
Contact(String name) {
|
case COURRIEL -> trad.translate("Contact.COURRIEL");
|
||||||
this.name = name;
|
case TELEPHONE -> trad.translate("Contact.TELEPHONE");
|
||||||
|
case SITE -> trad.translate("Contact.SITE");
|
||||||
|
case FACEBOOK -> trad.translate("Contact.FACEBOOK");
|
||||||
|
case INSTAGRAM -> trad.translate("Contact.INSTAGRAM");
|
||||||
|
case AUTRE -> trad.translate("Contact.AUTRE");
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setName(String name) {
|
public static HashMap<String, String> toSite(TradService trad) {
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HashMap<String, String> toSite() {
|
|
||||||
HashMap<String, String> map = new HashMap<>();
|
HashMap<String, String> map = new HashMap<>();
|
||||||
for (Contact contact : Contact.values()) {
|
for (Contact contact : Contact.values()) {
|
||||||
map.put(contact.toString(), contact.name);
|
map.put(contact.toString(), contact.getName(trad));
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package fr.titionfire.ffsaf.utils;
|
package fr.titionfire.ffsaf.utils;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
@@ -27,8 +28,17 @@ public enum Genre {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getString(TradService trad) {
|
||||||
|
return switch (this) {
|
||||||
|
case H -> trad.translate("Genre.Homme");
|
||||||
|
case F -> trad.translate("Genre.Femme");
|
||||||
|
case NA -> trad.translate("Genre.NA");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package fr.titionfire.ffsaf.utils;
|
package fr.titionfire.ffsaf.utils;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
@@ -14,6 +15,14 @@ public enum GradeArbitrage {
|
|||||||
this.str = name;
|
this.str = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getString(TradService trad) {
|
||||||
|
return switch (this) {
|
||||||
|
case NA -> trad.translate("GradeArbitrage.NA");
|
||||||
|
case ASSESSEUR -> trad.translate("GradeArbitrage.ASSESSEUR");
|
||||||
|
case ARBITRE -> trad.translate("GradeArbitrage.ARBITRE");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return str;
|
return str;
|
||||||
|
|||||||
@@ -10,13 +10,14 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public class PageResult<T> {
|
public class PageResult<T> {
|
||||||
@Schema(description = "Le numéro de la page courante.", example = "1")
|
@Schema(description = "Le numéro de la page courante.", examples = "1")
|
||||||
private int page;
|
private int page;
|
||||||
@Schema(description = "Le nombre d'éléments par page.", example = "10")
|
@Schema(description = "Le nombre d'éléments par page.", examples = "10")
|
||||||
private int page_size;
|
private int page_size;
|
||||||
@Schema(description = "Le nombre total de pages.", example = "5")
|
@Schema(description = "Le nombre total de pages.", examples = "5")
|
||||||
private int page_count;
|
private int page_count;
|
||||||
@Schema(description = "Le nombre total d'éléments.", example = "47")
|
@Schema(description = "Le nombre total d'éléments.", examples = "47")
|
||||||
private long result_count;
|
private long result_count;
|
||||||
private List<T> result = new ArrayList<>();
|
private List<T> result = new ArrayList<>();
|
||||||
|
private Object additionalData;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package fr.titionfire.ffsaf.utils;
|
package fr.titionfire.ffsaf.utils;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
@@ -21,6 +22,19 @@ public enum RoleAsso {
|
|||||||
this.level = level;
|
this.level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getString(TradService trad) {
|
||||||
|
return switch (this){
|
||||||
|
case MEMBRE -> trad.translate("RoleAsso.MEMBRE");
|
||||||
|
case PRESIDENT -> trad.translate("RoleAsso.PRESIDENT");
|
||||||
|
case VPRESIDENT -> trad.translate("RoleAsso.VPRESIDENT");
|
||||||
|
case SECRETAIRE -> trad.translate("RoleAsso.SECRETAIRE");
|
||||||
|
case VSECRETAIRE -> trad.translate("RoleAsso.VSECRETAIRE");
|
||||||
|
case TRESORIER -> trad.translate("RoleAsso.TRESORIER");
|
||||||
|
case VTRESORIER -> trad.translate("RoleAsso.VTRESORIER");
|
||||||
|
case MEMBREBUREAU -> trad.translate("RoleAsso.MEMBREBUREAU");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return str;
|
return str;
|
||||||
|
|||||||
@@ -20,6 +20,8 @@ import java.io.*;
|
|||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
@@ -117,6 +119,15 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Calendar getFirstDateOfSaison() {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
|
||||||
|
calendar.set(getSaison(), Calendar.SEPTEMBER, 1, 0, 0, 0);
|
||||||
|
calendar.set(Calendar.MILLISECOND, 0);
|
||||||
|
|
||||||
|
return calendar;
|
||||||
|
}
|
||||||
|
|
||||||
public static Calendar toCalendar(Date date) {
|
public static Calendar toCalendar(Date date) {
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
cal.setTime(date);
|
cal.setTime(date);
|
||||||
@@ -244,15 +255,16 @@ public class Utils {
|
|||||||
FilenameFilter filter = (directory, filename) -> filename.startsWith(id + ".");
|
FilenameFilter filter = (directory, filename) -> filename.startsWith(id + ".");
|
||||||
File[] files = dirFile.listFiles(filter);
|
File[] files = dirFile.listFiles(filter);
|
||||||
if (files != null) {
|
if (files != null) {
|
||||||
for (File f : files) {
|
for (File f2 : files) {
|
||||||
//noinspection ResultOfMethodCallIgnored
|
//noinspection ResultOfMethodCallIgnored
|
||||||
f.delete();
|
f2.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
File f = file.filePath().toFile();
|
Path f = file.filePath();
|
||||||
//noinspection ResultOfMethodCallIgnored
|
System.out.println(f + " -> " + new File(dirFile, id + "." + detectedExtensions[0]));
|
||||||
f.renameTo(new File(dirFile, id + "." + detectedExtensions[0]));
|
Files.copy(f, new File(dirFile, id + "." + detectedExtensions[0]).toPath(),
|
||||||
|
StandardCopyOption.REPLACE_EXISTING);
|
||||||
return "ok";
|
return "ok";
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
|||||||
import fr.titionfire.ffsaf.data.repository.CompetitionRepository;
|
import fr.titionfire.ffsaf.data.repository.CompetitionRepository;
|
||||||
import fr.titionfire.ffsaf.domain.service.CompetPermService;
|
import fr.titionfire.ffsaf.domain.service.CompetPermService;
|
||||||
import fr.titionfire.ffsaf.net2.MessageType;
|
import fr.titionfire.ffsaf.net2.MessageType;
|
||||||
|
import fr.titionfire.ffsaf.rest.data.SimpleCompetData;
|
||||||
import fr.titionfire.ffsaf.utils.SecurityCtx;
|
import fr.titionfire.ffsaf.utils.SecurityCtx;
|
||||||
import fr.titionfire.ffsaf.ws.data.WelcomeInfo;
|
import fr.titionfire.ffsaf.ws.data.WelcomeInfo;
|
||||||
import fr.titionfire.ffsaf.ws.recv.*;
|
import fr.titionfire.ffsaf.ws.recv.*;
|
||||||
@@ -16,6 +17,7 @@ import io.smallrye.mutiny.Uni;
|
|||||||
import io.smallrye.mutiny.unchecked.Unchecked;
|
import io.smallrye.mutiny.unchecked.Unchecked;
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
|
import jakarta.inject.Named;
|
||||||
import jakarta.ws.rs.ForbiddenException;
|
import jakarta.ws.rs.ForbiddenException;
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
@@ -23,6 +25,7 @@ import java.lang.reflect.InvocationTargetException;
|
|||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import static fr.titionfire.ffsaf.net2.Client_Thread.MAPPER;
|
import static fr.titionfire.ffsaf.net2.Client_Thread.MAPPER;
|
||||||
|
|
||||||
@@ -40,10 +43,19 @@ public class CompetitionWS {
|
|||||||
RCategorie rCategorie;
|
RCategorie rCategorie;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
RRegister rRegister;
|
RRegister rRegister;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
RCardboard rCardboard;
|
RCard rCard;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RTeam rTeam;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RState rState;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RPDF rpdf;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
SecurityCtx securityCtx;
|
SecurityCtx securityCtx;
|
||||||
@@ -51,6 +63,15 @@ public class CompetitionWS {
|
|||||||
@Inject
|
@Inject
|
||||||
CompetPermService competPermService;
|
CompetPermService competPermService;
|
||||||
|
|
||||||
|
@SuppressWarnings("CdiInjectionPointsInspection")
|
||||||
|
@Inject
|
||||||
|
OpenConnections connections;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
@Named("notify-executor")
|
||||||
|
Executor notifyExecutor;
|
||||||
|
private static Executor executor;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
CompetitionRepository competitionRepository;
|
CompetitionRepository competitionRepository;
|
||||||
|
|
||||||
@@ -78,7 +99,12 @@ public class CompetitionWS {
|
|||||||
getWSReceiverMethods(RMatch.class, rMatch);
|
getWSReceiverMethods(RMatch.class, rMatch);
|
||||||
getWSReceiverMethods(RCategorie.class, rCategorie);
|
getWSReceiverMethods(RCategorie.class, rCategorie);
|
||||||
getWSReceiverMethods(RRegister.class, rRegister);
|
getWSReceiverMethods(RRegister.class, rRegister);
|
||||||
getWSReceiverMethods(RCardboard.class, rCardboard);
|
getWSReceiverMethods(RCard.class, rCard);
|
||||||
|
getWSReceiverMethods(RTeam.class, rTeam);
|
||||||
|
getWSReceiverMethods(RState.class, rState);
|
||||||
|
getWSReceiverMethods(RPDF.class, rpdf);
|
||||||
|
|
||||||
|
executor = notifyExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnOpen
|
@OnOpen
|
||||||
@@ -95,8 +121,8 @@ public class CompetitionWS {
|
|||||||
.call(cm -> competPermService.hasEditPerm(securityCtx, cm).map(__ -> PermLevel.ADMIN)
|
.call(cm -> competPermService.hasEditPerm(securityCtx, cm).map(__ -> PermLevel.ADMIN)
|
||||||
.onFailure()
|
.onFailure()
|
||||||
.recoverWithUni(competPermService.hasTablePerm(securityCtx, cm).map(__ -> PermLevel.TABLE))
|
.recoverWithUni(competPermService.hasTablePerm(securityCtx, cm).map(__ -> PermLevel.TABLE))
|
||||||
.onFailure()
|
//.onFailure()
|
||||||
.recoverWithUni(competPermService.hasViewPerm(securityCtx, cm).map(__ -> PermLevel.VIEW))
|
//.recoverWithUni(competPermService.hasViewPerm(securityCtx, cm).map(__ -> PermLevel.VIEW))
|
||||||
.invoke(prem -> connection.userData().put(UserData.TypedKey.forString("prem"), prem.toString()))
|
.invoke(prem -> connection.userData().put(UserData.TypedKey.forString("prem"), prem.toString()))
|
||||||
.invoke(prem -> LOGGER.infof("Connection permission: %s", prem))
|
.invoke(prem -> LOGGER.infof("Connection permission: %s", prem))
|
||||||
.onFailure().transform(t -> new ForbiddenException()))
|
.onFailure().transform(t -> new ForbiddenException()))
|
||||||
@@ -105,10 +131,13 @@ public class CompetitionWS {
|
|||||||
waitingResponse.put(connection, new HashMap<>());
|
waitingResponse.put(connection, new HashMap<>());
|
||||||
})
|
})
|
||||||
.map(cm -> {
|
.map(cm -> {
|
||||||
|
SimpleCompetData data = SimpleCompetData.fromModel(cm);
|
||||||
WelcomeInfo welcomeInfo = new WelcomeInfo();
|
WelcomeInfo welcomeInfo = new WelcomeInfo();
|
||||||
|
|
||||||
welcomeInfo.setName(cm.getName());
|
welcomeInfo.setName(cm.getName());
|
||||||
welcomeInfo.setPerm(connection.userData().get(UserData.TypedKey.forString("prem")));
|
welcomeInfo.setPerm(connection.userData().get(UserData.TypedKey.forString("prem")));
|
||||||
|
welcomeInfo.setShow_blason(data.isShow_blason());
|
||||||
|
welcomeInfo.setShow_flag(data.isShow_flag());
|
||||||
|
|
||||||
return new MessageOut(UUID.randomUUID(), "welcomeInfo", MessageType.NOTIFY, welcomeInfo);
|
return new MessageOut(UUID.randomUUID(), "welcomeInfo", MessageType.NOTIFY, welcomeInfo);
|
||||||
});
|
});
|
||||||
@@ -120,6 +149,7 @@ public class CompetitionWS {
|
|||||||
LOGGER.debugf("Active connections: %d", connection.getOpenConnections().size());
|
LOGGER.debugf("Active connections: %d", connection.getOpenConnections().size());
|
||||||
|
|
||||||
waitingResponse.remove(connection);
|
waitingResponse.remove(connection);
|
||||||
|
rState.removeConnection(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
private MessageOut makeReply(MessageIn message, Object data) {
|
private MessageOut makeReply(MessageIn message, Object data) {
|
||||||
@@ -186,7 +216,7 @@ public class CompetitionWS {
|
|||||||
// return Uni.createFrom().item(new Message<>(message.uuid(), message.code(), MessageType.REPLY, "ko"));
|
// return Uni.createFrom().item(new Message<>(message.uuid(), message.code(), MessageType.REPLY, "ko"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uni<Void> sendNotifyToOtherEditor(WebSocketConnection connection, String code, Object data) {
|
public static void sendNotifyToOtherEditor(WebSocketConnection connection, String code, Object data) {
|
||||||
String uuid = connection.pathParam("uuid");
|
String uuid = connection.pathParam("uuid");
|
||||||
|
|
||||||
List<Uni<Void>> queue = new ArrayList<>();
|
List<Uni<Void>> queue = new ArrayList<>();
|
||||||
@@ -198,7 +228,39 @@ public class CompetitionWS {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return Uni.join().all(queue).andCollectFailures().onFailure().recoverWithNull().replaceWithVoid();
|
Uni.join().all(queue)
|
||||||
|
.andCollectFailures()
|
||||||
|
.runSubscriptionOn(executor)
|
||||||
|
.subscribeAsCompletionStage()
|
||||||
|
.whenComplete((v, t) -> {
|
||||||
|
if (t != null) {
|
||||||
|
LOGGER.error("Error sending ws_out message", t);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendNotifyState(WebSocketConnection connection, String code, Object data) {
|
||||||
|
String uuid = connection.pathParam("uuid");
|
||||||
|
|
||||||
|
List<Uni<Void>> queue = new ArrayList<>();
|
||||||
|
queue.add(Uni.createFrom().voidItem()); // For avoid empty queue
|
||||||
|
|
||||||
|
connection.getOpenConnections().forEach(c -> {
|
||||||
|
Boolean s = c.userData().get(UserData.TypedKey.forBoolean("needState"));
|
||||||
|
if (uuid.equals(c.pathParam("uuid")) && s != null && s) {
|
||||||
|
queue.add(c.sendText(new MessageOut(UUID.randomUUID(), code, MessageType.NOTIFY, data)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Uni.join().all(queue)
|
||||||
|
.andCollectFailures()
|
||||||
|
.runSubscriptionOn(executor)
|
||||||
|
.subscribeAsCompletionStage()
|
||||||
|
.whenComplete((v, t) -> {
|
||||||
|
if (t != null) {
|
||||||
|
LOGGER.error("Error sending ws_out message", t);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnError
|
@OnError
|
||||||
|
|||||||
19
src/main/java/fr/titionfire/ffsaf/ws/ExecutorProducer.java
Normal file
19
src/main/java/fr/titionfire/ffsaf/ws/ExecutorProducer.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package fr.titionfire.ffsaf.ws;
|
||||||
|
|
||||||
|
import jakarta.enterprise.inject.Produces;
|
||||||
|
import jakarta.inject.Named;
|
||||||
|
import jakarta.inject.Singleton;
|
||||||
|
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class ExecutorProducer {
|
||||||
|
|
||||||
|
@Produces
|
||||||
|
@Named("notify-executor")
|
||||||
|
public Executor produceNotifyExecutor() {
|
||||||
|
// Créez un pool de threads avec une taille fixe (par exemple, 10 threads)
|
||||||
|
return Executors.newFixedThreadPool(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,4 +8,6 @@ import lombok.Data;
|
|||||||
public class WelcomeInfo {
|
public class WelcomeInfo {
|
||||||
private String name;
|
private String name;
|
||||||
private String perm;
|
private String perm;
|
||||||
|
private boolean show_blason;
|
||||||
|
private boolean show_flag;
|
||||||
}
|
}
|
||||||
|
|||||||
159
src/main/java/fr/titionfire/ffsaf/ws/recv/RCard.java
Normal file
159
src/main/java/fr/titionfire/ffsaf/ws/recv/RCard.java
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
package fr.titionfire.ffsaf.ws.recv;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.CardModel;
|
||||||
|
import fr.titionfire.ffsaf.data.model.MatchModel;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.CardRepository;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.ClubCardRepository;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.CompetitionRepository;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.MatchRepository;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.CardService;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
|
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
||||||
|
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
|
||||||
|
import fr.titionfire.ffsaf.ws.PermLevel;
|
||||||
|
import fr.titionfire.ffsaf.ws.send.SSCard;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.Panache;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import io.quarkus.websockets.next.WebSocketConnection;
|
||||||
|
import io.smallrye.mutiny.Uni;
|
||||||
|
import io.smallrye.mutiny.unchecked.Unchecked;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
import jakarta.inject.Inject;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@WithSession
|
||||||
|
@ApplicationScoped
|
||||||
|
@RegisterForReflection
|
||||||
|
public class RCard {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
MatchRepository matchRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ClubCardRepository clubCardRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CardRepository cardRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CardService cardService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CompetitionRepository competitionRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
|
private Uni<MatchModel> getById(long id, WebSocketConnection connection) {
|
||||||
|
return matchRepository.findById(id)
|
||||||
|
.invoke(Unchecked.consumer(o -> {
|
||||||
|
if (o == null)
|
||||||
|
throw new DNotFoundException(trad.t("matche.non.trouver", connection));
|
||||||
|
if (!o.getCategory().getCompet().getUuid().equals(connection.pathParam("uuid")))
|
||||||
|
throw new DForbiddenException(trad.t("permission.denied", connection));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "getCardForMatch", permission = PermLevel.VIEW)
|
||||||
|
public Uni<List<CardModel>> getCardForMatch(WebSocketConnection connection, Long matchId) {
|
||||||
|
if (matchId == null)
|
||||||
|
return Uni.createFrom().nullItem();
|
||||||
|
return getById(matchId, connection).chain(matchModel -> cardService.getForMatch(matchModel));
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "getAllForTeamNoDetail", permission = PermLevel.VIEW)
|
||||||
|
public Uni<List<SendTeamCards>> getAllForTeamNoDetail(WebSocketConnection connection, Object o) {
|
||||||
|
return competitionRepository.find("uuid", connection.pathParam("uuid")).firstResult()
|
||||||
|
.chain(c -> clubCardRepository.list("competition = ?1", c.getId()))
|
||||||
|
.map(cards -> cards.stream()
|
||||||
|
.map(card -> new SendTeamCards(card.getTeamUuid(), card.getTeamName(), List.of(),
|
||||||
|
card.getType(), card.getReason(), card.getDate()))
|
||||||
|
.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "sendCardAdd", permission = PermLevel.TABLE)
|
||||||
|
public Uni<Void> sendCardAdd(WebSocketConnection connection, SendCardAdd card) {
|
||||||
|
return getById(card.matchId(), connection)
|
||||||
|
.chain(matchModel -> cardService.checkCanBeAdded(card, matchModel)
|
||||||
|
.chain(c -> {
|
||||||
|
CardModel model = new CardModel();
|
||||||
|
model.setComb(card.combId());
|
||||||
|
model.setMatch(card.matchId());
|
||||||
|
model.setCategory(matchModel.getCategory().getId());
|
||||||
|
model.setCompetition(matchModel.getCategory().getCompet());
|
||||||
|
model.setCompetitionId(matchModel.getCategory().getCompet().getId());
|
||||||
|
model.setType(card.type());
|
||||||
|
model.setReason(card.reason());
|
||||||
|
|
||||||
|
return Panache.withTransaction(() -> cardRepository.persist(model));
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.invoke(cardModel -> SSCard.sendCards(connection, List.of(cardModel)))
|
||||||
|
.replaceWithVoid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "sendCardRm", permission = PermLevel.ADMIN)
|
||||||
|
public Uni<Void> sendCardRm(WebSocketConnection connection, SendCardAdd card) {
|
||||||
|
return competitionRepository.find("uuid", connection.pathParam("uuid")).firstResult()
|
||||||
|
.chain(competition -> cardRepository.find(
|
||||||
|
"match IS NULL AND comb = ?1 AND type = ?2 AND competition = ?3 AND match " + (card.matchId() == null ? "IS NULL" : "= " + card.matchId()),
|
||||||
|
card.combId(), card.type(), competition)
|
||||||
|
.firstResult()
|
||||||
|
.invoke(Unchecked.consumer(o -> {
|
||||||
|
if (o == null)
|
||||||
|
throw new DNotFoundException(trad.t("carton.non.trouver", connection));
|
||||||
|
SSCard.sendRmCards(connection, List.of(o.getId()));
|
||||||
|
}))
|
||||||
|
.chain(cardModel -> Panache.withTransaction(() -> cardRepository.delete(cardModel)))
|
||||||
|
)
|
||||||
|
.replaceWithVoid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "applyTeamCards", permission = PermLevel.TABLE)
|
||||||
|
public Uni<Void> applyTeamCards(WebSocketConnection connection, SendTeamCards teamCards) {
|
||||||
|
return competitionRepository.find("uuid", connection.pathParam("uuid")).firstResult()
|
||||||
|
.chain(c -> cardService.addTeamCard(c, teamCards.teamUuid(), teamCards.teamName(), teamCards.type,
|
||||||
|
teamCards.reason()))
|
||||||
|
.invoke(cards -> SSCard.sendTeamCard(connection,
|
||||||
|
new SendTeamCards(teamCards.teamUuid(), teamCards.teamName(), cards, teamCards.type(),
|
||||||
|
teamCards.reason(), new Date())))
|
||||||
|
.replaceWithVoid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "sendTeamCardReturnState", permission = PermLevel.TABLE)
|
||||||
|
public Uni<Void> sendTeamCardReturnState(WebSocketConnection connection, SendTeamCardReturnState state) {
|
||||||
|
if (state.state <= 0 || state.state > 2)
|
||||||
|
return Uni.createFrom().voidItem();
|
||||||
|
|
||||||
|
return competitionRepository.find("uuid", connection.pathParam("uuid")).firstResult()
|
||||||
|
.chain(c -> cardService.recvReturnState(c, state))
|
||||||
|
.invoke(cards -> SSCard.sendCards(connection, cards))
|
||||||
|
.replaceWithVoid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "removeTeamCards", permission = PermLevel.TABLE)
|
||||||
|
public Uni<Void> removeTeamCards(WebSocketConnection connection, SendTeamCards teamCards) {
|
||||||
|
return competitionRepository.find("uuid", connection.pathParam("uuid")).firstResult()
|
||||||
|
.chain(c -> cardService.rmTeamCard(c, teamCards.teamUuid(), teamCards.teamName(), teamCards.type))
|
||||||
|
.invoke(cards -> SSCard.sendRmCards(connection, cards))
|
||||||
|
.invoke(__ -> SSCard.rmTeamCard(connection, teamCards))
|
||||||
|
.replaceWithVoid();
|
||||||
|
}
|
||||||
|
|
||||||
|
@RegisterForReflection
|
||||||
|
public record SendCardAdd(Long matchId, long combId, CardModel.CardType type, String reason) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@RegisterForReflection
|
||||||
|
public record SendTeamCards(String teamUuid, String teamName, List<CardModel> cards, CardModel.CardType type,
|
||||||
|
String reason, Date date) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@RegisterForReflection
|
||||||
|
public record SendTeamCardReturnState(String teamUuid, String teamName, CardModel.CardType type,
|
||||||
|
int state, Long selectedCategory, Long selectedMatch) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
package fr.titionfire.ffsaf.ws.recv;
|
|
||||||
|
|
||||||
import fr.titionfire.ffsaf.data.model.CardboardModel;
|
|
||||||
import fr.titionfire.ffsaf.data.model.MatchModel;
|
|
||||||
import fr.titionfire.ffsaf.data.repository.CardboardRepository;
|
|
||||||
import fr.titionfire.ffsaf.data.repository.MatchRepository;
|
|
||||||
import fr.titionfire.ffsaf.domain.entity.CardboardEntity;
|
|
||||||
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
|
||||||
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
|
|
||||||
import fr.titionfire.ffsaf.ws.PermLevel;
|
|
||||||
import fr.titionfire.ffsaf.ws.send.SSCardboard;
|
|
||||||
import io.quarkus.hibernate.reactive.panache.Panache;
|
|
||||||
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
|
||||||
import io.quarkus.websockets.next.WebSocketConnection;
|
|
||||||
import io.smallrye.mutiny.Uni;
|
|
||||||
import io.smallrye.mutiny.unchecked.Unchecked;
|
|
||||||
import jakarta.enterprise.context.ApplicationScoped;
|
|
||||||
import jakarta.inject.Inject;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
@WithSession
|
|
||||||
@ApplicationScoped
|
|
||||||
@RegisterForReflection
|
|
||||||
public class RCardboard {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
MatchRepository matchRepository;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
CardboardRepository cardboardRepository;
|
|
||||||
|
|
||||||
private Uni<MatchModel> getById(long id, WebSocketConnection connection) {
|
|
||||||
return matchRepository.findById(id)
|
|
||||||
.invoke(Unchecked.consumer(o -> {
|
|
||||||
if (o == null)
|
|
||||||
throw new DNotFoundException("Matche non trouver");
|
|
||||||
if (!o.getCategory().getCompet().getUuid().equals(connection.pathParam("uuid")))
|
|
||||||
throw new DForbiddenException("Permission denied");
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
@WSReceiver(code = "sendCardboardChange", permission = PermLevel.TABLE)
|
|
||||||
public Uni<Void> sendCardboardChange(WebSocketConnection connection, SendCardboard card) {
|
|
||||||
return getById(card.matchId, connection)
|
|
||||||
.chain(matchModel -> cardboardRepository.find("(comb.id = ?1 OR guestComb.id = ?2) AND match.id = ?3",
|
|
||||||
card.combId, card.combId * -1, card.matchId).firstResult()
|
|
||||||
.chain(model -> {
|
|
||||||
if (model != null) {
|
|
||||||
model.setRed(model.getRed() + card.red);
|
|
||||||
model.setYellow(model.getYellow() + card.yellow);
|
|
||||||
return Panache.withTransaction(() -> cardboardRepository.persist(model));
|
|
||||||
}
|
|
||||||
CardboardModel cardboardModel = new CardboardModel();
|
|
||||||
|
|
||||||
cardboardModel.setCompet(matchModel.getCategory().getCompet());
|
|
||||||
cardboardModel.setMatch(matchModel);
|
|
||||||
cardboardModel.setRed(card.red);
|
|
||||||
cardboardModel.setYellow(card.yellow);
|
|
||||||
cardboardModel.setComb(null);
|
|
||||||
cardboardModel.setGuestComb(null);
|
|
||||||
|
|
||||||
if (card.combId >= 0) {
|
|
||||||
if (matchModel.getC1_id() != null && matchModel.getC1_id().getId() == card.combId)
|
|
||||||
cardboardModel.setComb(matchModel.getC1_id());
|
|
||||||
if (matchModel.getC2_id() != null && matchModel.getC2_id().getId() == card.combId)
|
|
||||||
cardboardModel.setComb(matchModel.getC2_id());
|
|
||||||
} else {
|
|
||||||
if (matchModel.getC1_guest() != null && matchModel.getC1_guest()
|
|
||||||
.getId() == card.combId * -1)
|
|
||||||
cardboardModel.setGuestComb(matchModel.getC1_guest());
|
|
||||||
if (matchModel.getC2_guest() != null && matchModel.getC2_guest()
|
|
||||||
.getId() == card.combId * -1)
|
|
||||||
cardboardModel.setGuestComb(matchModel.getC2_guest());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cardboardModel.getComb() == null && cardboardModel.getGuestComb() == null)
|
|
||||||
return Uni.createFrom().nullItem();
|
|
||||||
return Panache.withTransaction(() -> cardboardRepository.persist(cardboardModel));
|
|
||||||
}))
|
|
||||||
.call(model -> SSCardboard.sendCardboard(connection, CardboardEntity.fromModel(model)))
|
|
||||||
.replaceWithVoid();
|
|
||||||
}
|
|
||||||
|
|
||||||
@WSReceiver(code = "getCardboardWithoutThis", permission = PermLevel.VIEW)
|
|
||||||
public Uni<CardboardAllMatch> getCardboardWithoutThis(WebSocketConnection connection, Long matchId) {
|
|
||||||
return getById(matchId, connection)
|
|
||||||
.chain(matchModel -> cardboardRepository.list("compet = ?1 AND match != ?2", matchModel.getCategory().getCompet(), matchModel)
|
|
||||||
.map(models -> {
|
|
||||||
CardboardAllMatch out = new CardboardAllMatch();
|
|
||||||
|
|
||||||
models.stream().filter(c -> (matchModel.getC1_id() != null
|
|
||||||
&& Objects.equals(c.getComb(), matchModel.getC1_id()))
|
|
||||||
|| (matchModel.getC1_guest() != null
|
|
||||||
&& Objects.equals(c.getGuestComb(), matchModel.getC1_guest())))
|
|
||||||
.forEach(c -> {
|
|
||||||
out.c1_yellow += c.getYellow();
|
|
||||||
out.c1_red += c.getRed();
|
|
||||||
});
|
|
||||||
|
|
||||||
models.stream().filter(c -> (matchModel.getC2_id() != null
|
|
||||||
&& Objects.equals(c.getComb(), matchModel.getC2_id()))
|
|
||||||
|| (matchModel.getC2_guest() != null
|
|
||||||
&& Objects.equals(c.getGuestComb(), matchModel.getC2_guest())))
|
|
||||||
.forEach(c -> {
|
|
||||||
out.c2_yellow += c.getYellow();
|
|
||||||
out.c2_red += c.getRed();
|
|
||||||
});
|
|
||||||
|
|
||||||
return out;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
@RegisterForReflection
|
|
||||||
public record SendCardboard(long matchId, long combId, int yellow, int red) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@RegisterForReflection
|
|
||||||
public static class CardboardAllMatch {
|
|
||||||
int c1_yellow = 0;
|
|
||||||
int c1_red = 0;
|
|
||||||
int c2_yellow = 0;
|
|
||||||
int c2_red = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +1,25 @@
|
|||||||
package fr.titionfire.ffsaf.ws.recv;
|
package fr.titionfire.ffsaf.ws.recv;
|
||||||
|
|
||||||
import fr.titionfire.ffsaf.data.model.CategoryModel;
|
import fr.titionfire.ffsaf.data.model.*;
|
||||||
import fr.titionfire.ffsaf.data.model.MatchModel;
|
import fr.titionfire.ffsaf.data.repository.*;
|
||||||
import fr.titionfire.ffsaf.data.model.TreeModel;
|
|
||||||
import fr.titionfire.ffsaf.data.repository.CategoryRepository;
|
|
||||||
import fr.titionfire.ffsaf.data.repository.CompetitionRepository;
|
|
||||||
import fr.titionfire.ffsaf.data.repository.MatchRepository;
|
|
||||||
import fr.titionfire.ffsaf.data.repository.TreeRepository;
|
|
||||||
import fr.titionfire.ffsaf.domain.entity.MatchEntity;
|
import fr.titionfire.ffsaf.domain.entity.MatchEntity;
|
||||||
|
import fr.titionfire.ffsaf.domain.entity.MatchModelExtend;
|
||||||
import fr.titionfire.ffsaf.domain.entity.TreeEntity;
|
import fr.titionfire.ffsaf.domain.entity.TreeEntity;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.CardService;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.ResultService;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
|
import fr.titionfire.ffsaf.rest.data.PresetData;
|
||||||
|
import fr.titionfire.ffsaf.rest.data.ResultCategoryData;
|
||||||
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
||||||
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
|
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
|
||||||
import fr.titionfire.ffsaf.utils.TreeNode;
|
import fr.titionfire.ffsaf.utils.TreeNode;
|
||||||
import fr.titionfire.ffsaf.ws.PermLevel;
|
import fr.titionfire.ffsaf.ws.PermLevel;
|
||||||
import fr.titionfire.ffsaf.ws.send.SSCategorie;
|
import fr.titionfire.ffsaf.ws.send.SSCategorie;
|
||||||
|
import fr.titionfire.ffsaf.ws.send.SSMatch;
|
||||||
import io.quarkus.hibernate.reactive.panache.Panache;
|
import io.quarkus.hibernate.reactive.panache.Panache;
|
||||||
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import io.quarkus.websockets.next.UserData;
|
||||||
import io.quarkus.websockets.next.WebSocketConnection;
|
import io.quarkus.websockets.next.WebSocketConnection;
|
||||||
import io.smallrye.mutiny.Uni;
|
import io.smallrye.mutiny.Uni;
|
||||||
import io.smallrye.mutiny.unchecked.Unchecked;
|
import io.smallrye.mutiny.unchecked.Unchecked;
|
||||||
@@ -25,8 +28,9 @@ import jakarta.inject.Inject;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.reactive.mutiny.Mutiny;
|
import org.hibernate.reactive.mutiny.Mutiny;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@WithSession
|
@WithSession
|
||||||
@ApplicationScoped
|
@ApplicationScoped
|
||||||
@@ -46,13 +50,28 @@ public class RCategorie {
|
|||||||
@Inject
|
@Inject
|
||||||
TreeRepository treeRepository;
|
TreeRepository treeRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CardService cardService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CardRepository cardRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CatPresetRepository catPresetRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ResultService resultService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
private Uni<CategoryModel> getById(long id, WebSocketConnection connection) {
|
private Uni<CategoryModel> getById(long id, WebSocketConnection connection) {
|
||||||
return categoryRepository.findById(id)
|
return categoryRepository.findById(id)
|
||||||
.invoke(Unchecked.consumer(o -> {
|
.invoke(Unchecked.consumer(o -> {
|
||||||
if (o == null)
|
if (o == null)
|
||||||
throw new DNotFoundException("Catégorie non trouver");
|
throw new DNotFoundException(trad.t("categorie.non.trouver", connection));
|
||||||
if (!o.getCompet().getUuid().equals(connection.pathParam("uuid")))
|
if (!o.getCompet().getUuid().equals(connection.pathParam("uuid")))
|
||||||
throw new DForbiddenException("Permission denied");
|
throw new DForbiddenException(trad.t("permission.denied", connection));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,6 +91,9 @@ public class RCategorie {
|
|||||||
fullCategory.setName(cat.getName());
|
fullCategory.setName(cat.getName());
|
||||||
fullCategory.setLiceName(cat.getLiceName());
|
fullCategory.setLiceName(cat.getLiceName());
|
||||||
fullCategory.setType(cat.getType());
|
fullCategory.setType(cat.getType());
|
||||||
|
fullCategory.setTreeAreClassement(cat.isTreeAreClassement());
|
||||||
|
fullCategory.setFullClassement(cat.isFullClassement());
|
||||||
|
fullCategory.setPreset(PresetData.fromModel(cat.getPreset()));
|
||||||
})
|
})
|
||||||
.call(cat -> Mutiny.fetch(cat.getMatchs())
|
.call(cat -> Mutiny.fetch(cat.getMatchs())
|
||||||
.map(matchModels -> matchModels.stream().filter(o -> o.getCategory_ord() >= 0)
|
.map(matchModels -> matchModels.stream().filter(o -> o.getCategory_ord() >= 0)
|
||||||
@@ -80,6 +102,8 @@ public class RCategorie {
|
|||||||
.call(cat -> treeRepository.list("category = ?1 AND level != 0", cat.getId())
|
.call(cat -> treeRepository.list("category = ?1 AND level != 0", cat.getId())
|
||||||
.map(treeModels -> treeModels.stream().map(TreeEntity::fromModel).toList())
|
.map(treeModels -> treeModels.stream().map(TreeEntity::fromModel).toList())
|
||||||
.invoke(fullCategory::setTrees))
|
.invoke(fullCategory::setTrees))
|
||||||
|
.call(cat -> cardService.getAll(cat.getCompet())
|
||||||
|
.invoke(fullCategory::setCards))
|
||||||
.map(__ -> fullCategory);
|
.map(__ -> fullCategory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,20 +118,67 @@ public class RCategorie {
|
|||||||
categoryModel.setTree(new ArrayList<>());
|
categoryModel.setTree(new ArrayList<>());
|
||||||
categoryModel.setType(categorie.type);
|
categoryModel.setType(categorie.type);
|
||||||
categoryModel.setLiceName(categorie.liceName);
|
categoryModel.setLiceName(categorie.liceName);
|
||||||
|
categoryModel.setTreeAreClassement(categorie.treeAreClassement);
|
||||||
|
categoryModel.setFullClassement(categorie.fullClassement);
|
||||||
|
|
||||||
|
if (categorie.preset() != null)
|
||||||
|
return catPresetRepository.findById(categorie.preset().getId())
|
||||||
|
.invoke(categoryModel::setPreset)
|
||||||
|
.chain(__ -> categoryRepository.create(categoryModel));
|
||||||
return categoryRepository.create(categoryModel);
|
return categoryRepository.create(categoryModel);
|
||||||
})
|
})
|
||||||
.call(cat -> SSCategorie.sendAddCategory(connection, cat))
|
.invoke(cat -> SSCategorie.sendAddCategory(connection, cat))
|
||||||
.map(CategoryModel::getId);
|
.map(CategoryModel::getId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "createOrReplaceCategory", permission = PermLevel.ADMIN)
|
||||||
|
public Uni<Long> createOrReplaceCategory(WebSocketConnection connection, JustCategorie categorie) {
|
||||||
|
return matchRepository.list("category.compet.uuid = ?1 AND category.name = ?2", connection.pathParam("uuid"),
|
||||||
|
categorie.name)
|
||||||
|
.chain(existing -> {
|
||||||
|
if (existing.isEmpty())
|
||||||
|
return createCategory(connection, categorie);
|
||||||
|
|
||||||
|
Map<Long, List<MatchModel>> matchesByCategory = existing.stream()
|
||||||
|
.filter(m -> m.getCategory() != null)
|
||||||
|
.collect(Collectors.groupingBy(m -> m.getCategory().getId()));
|
||||||
|
|
||||||
|
for (Map.Entry<Long, List<MatchModel>> entry : matchesByCategory.entrySet()) {
|
||||||
|
Long categoryId = entry.getKey();
|
||||||
|
List<MatchModel> matches = entry.getValue();
|
||||||
|
|
||||||
|
if (matches.stream().noneMatch(m -> !m.getScores().isEmpty() || m.isEnd()))
|
||||||
|
return Panache.withTransaction(() -> updateCategory(connection, categorie, categoryId)
|
||||||
|
.call(__ -> treeRepository.delete("category = ?1", categoryId))
|
||||||
|
.call(__ -> matchRepository.delete("category.id = ?1", categoryId)))
|
||||||
|
.replaceWith(categoryId);
|
||||||
|
}
|
||||||
|
return createCategory(connection, categorie);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@WSReceiver(code = "updateCategory", permission = PermLevel.ADMIN)
|
@WSReceiver(code = "updateCategory", permission = PermLevel.ADMIN)
|
||||||
public Uni<Void> updateCategory(WebSocketConnection connection, JustCategorie categorie) {
|
public Uni<Void> updateCategory(WebSocketConnection connection, JustCategorie categorie) {
|
||||||
return getById(categorie.id, connection)
|
return updateCategory(connection, categorie, categorie.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Uni<Void> updateCategory(WebSocketConnection connection, JustCategorie categorie, Long id) {
|
||||||
|
return getById(id, connection)
|
||||||
|
.call(cat -> {
|
||||||
|
if (categorie.preset() == null) {
|
||||||
|
cat.setPreset(null);
|
||||||
|
return Uni.createFrom().item(cat);
|
||||||
|
} else {
|
||||||
|
return catPresetRepository.findById(categorie.preset().getId())
|
||||||
|
.invoke(cat::setPreset);
|
||||||
|
}
|
||||||
|
})
|
||||||
.chain(cat -> {
|
.chain(cat -> {
|
||||||
cat.setName(categorie.name);
|
cat.setName(categorie.name);
|
||||||
cat.setLiceName(categorie.liceName);
|
cat.setLiceName(categorie.liceName);
|
||||||
cat.setType(categorie.type);
|
cat.setType(categorie.type);
|
||||||
|
cat.setTreeAreClassement(categorie.treeAreClassement);
|
||||||
|
cat.setFullClassement(categorie.fullClassement);
|
||||||
return Panache.withTransaction(() -> categoryRepository.persist(cat));
|
return Panache.withTransaction(() -> categoryRepository.persist(cat));
|
||||||
})
|
})
|
||||||
.call(cat -> {
|
.call(cat -> {
|
||||||
@@ -121,7 +192,7 @@ public class RCategorie {
|
|||||||
Uni<Long> finalUni = uni;
|
Uni<Long> finalUni = uni;
|
||||||
return Panache.withTransaction(() -> finalUni);
|
return Panache.withTransaction(() -> finalUni);
|
||||||
})
|
})
|
||||||
.call(cat -> SSCategorie.sendCategory(connection, cat))
|
.invoke(cat -> SSCategorie.sendCategory(connection, cat))
|
||||||
.replaceWithVoid();
|
.replaceWithVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -202,7 +273,7 @@ public class RCategorie {
|
|||||||
.call(__ -> treeRepository.flush())
|
.call(__ -> treeRepository.flush())
|
||||||
.call(cat -> treeRepository.list("category = ?1 AND level != 0", cat.getId())
|
.call(cat -> treeRepository.list("category = ?1 AND level != 0", cat.getId())
|
||||||
.map(treeModels -> treeModels.stream().map(TreeEntity::fromModel).toList())
|
.map(treeModels -> treeModels.stream().map(TreeEntity::fromModel).toList())
|
||||||
.chain(trees -> SSCategorie.sendTreeCategory(connection, trees)))
|
.invoke(trees -> SSCategorie.sendTreeCategory(connection, trees)))
|
||||||
.replaceWithVoid();
|
.replaceWithVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,14 +283,159 @@ public class RCategorie {
|
|||||||
.call(cat -> Panache.withTransaction(() -> treeRepository.delete("category = ?1", cat.getId())
|
.call(cat -> Panache.withTransaction(() -> treeRepository.delete("category = ?1", cat.getId())
|
||||||
.call(__ -> matchRepository.delete("category = ?1", cat))))
|
.call(__ -> matchRepository.delete("category = ?1", cat))))
|
||||||
.chain(cat -> Panache.withTransaction(() -> categoryRepository.delete(cat)))
|
.chain(cat -> Panache.withTransaction(() -> categoryRepository.delete(cat)))
|
||||||
.call(__ -> SSCategorie.sendDelCategory(connection, id))
|
.invoke(__ -> SSCategorie.sendDelCategory(connection, id))
|
||||||
.replaceWithVoid();
|
.replaceWithVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "listPreset", permission = PermLevel.VIEW)
|
||||||
|
public Uni<List<PresetData>> listPreset(WebSocketConnection connection, Object o) {
|
||||||
|
return catPresetRepository.list("competition.uuid", connection.pathParam("uuid"))
|
||||||
|
.map(presets -> presets.stream().map(PresetData::fromModel).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "createClassementMatchs", permission = PermLevel.TABLE)
|
||||||
|
public Uni<Void> createClassementMatchs(WebSocketConnection connection, Long categoryId) {
|
||||||
|
return getById(categoryId, connection)
|
||||||
|
.call(cat -> {
|
||||||
|
PermLevel perm = PermLevel.valueOf(connection.userData().get(UserData.TypedKey.forString("prem")));
|
||||||
|
if (perm == PermLevel.TABLE) {
|
||||||
|
return matchRepository.list("category = ?1 AND category_ord = -42", cat.getId())
|
||||||
|
.chain(l -> l.stream().anyMatch(MatchModel::isEnd) ?
|
||||||
|
Uni.createFrom().failure(
|
||||||
|
new DForbiddenException(trad.t("err.match.termine", connection))) :
|
||||||
|
Uni.createFrom().voidItem());
|
||||||
|
}
|
||||||
|
return Uni.createFrom().voidItem();
|
||||||
|
})
|
||||||
|
.call(cat -> treeRepository.list("category = ?1 AND level <= -10", cat.getId())
|
||||||
|
.map(l -> l.stream().map(o -> o.getMatch().getId()).toList())
|
||||||
|
.call(__ -> treeRepository.delete("category = ?1 AND level <= -10", cat.getId()))
|
||||||
|
.call(ids -> matchRepository.delete("id IN ?1", ids)))
|
||||||
|
.call(cat -> Mutiny.fetch(cat.getTree()))
|
||||||
|
.call(cat -> {
|
||||||
|
List<MatchModel> toSave = new ArrayList<>();
|
||||||
|
if (!cat.getTree().isEmpty()) {
|
||||||
|
for (TreeModel treeModel : cat.getTree())
|
||||||
|
cleanTree(treeModel, toSave);
|
||||||
|
}
|
||||||
|
return Panache.withTransaction(() -> matchRepository.persist(toSave))
|
||||||
|
.invoke(__ -> SSMatch.sendMatch(connection,
|
||||||
|
toSave.stream().map(MatchEntity::fromModel).toList()));
|
||||||
|
})
|
||||||
|
.chain(cat -> Mutiny.fetch(cat.getMatchs())
|
||||||
|
.chain(list -> cardRepository.list("competition = ?1", cat.getCompet())
|
||||||
|
.map(c -> list.stream().map(m -> new MatchModelExtend(m, c)).toList()))
|
||||||
|
.map(matchModels -> {
|
||||||
|
ResultCategoryData out = new ResultCategoryData();
|
||||||
|
resultService.getArray2(matchModels, null, out);
|
||||||
|
out.getRankArray().remove('-');
|
||||||
|
return out;
|
||||||
|
})
|
||||||
|
.invoke(Unchecked.consumer(result -> {
|
||||||
|
if (result.getRankArray().size() != 2) {
|
||||||
|
throw new DForbiddenException(trad.t("configuration.non.supportee", connection));
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.chain(result -> {
|
||||||
|
List<MatchModel> toSave = new ArrayList<>();
|
||||||
|
List<MatchModel> toCreate = new ArrayList<>();
|
||||||
|
List<TreeModel> toSaveTree = new ArrayList<>();
|
||||||
|
|
||||||
|
int treeSize = 0;
|
||||||
|
List<TreeModel> lastNode = new ArrayList<>();
|
||||||
|
Optional<TreeModel> tree = cat.getTree().stream().filter(t -> t.getLevel() > 0)
|
||||||
|
.min(Comparator.comparing(TreeModel::getLevel));
|
||||||
|
if (tree.isPresent()) {
|
||||||
|
tree.get().getChildrenAtDepth(tree.get().death() - 1, 0, lastNode);
|
||||||
|
treeSize = lastNode.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<List<ResultCategoryData.RankArray>> iterator = result.getRankArray().values()
|
||||||
|
.iterator();
|
||||||
|
List<ResultCategoryData.RankArray> poule1 = iterator.next();
|
||||||
|
List<ResultCategoryData.RankArray> poule2 = iterator.next();
|
||||||
|
|
||||||
|
int maxToMixFill = Math.min(poule1.size(), poule2.size());
|
||||||
|
int maxToMixTreeFill = Math.min(treeSize, maxToMixFill);
|
||||||
|
for (int i = 0; i < maxToMixTreeFill; i++) {
|
||||||
|
CombModel comb1 = poule1.get(i).getComb();
|
||||||
|
CombModel comb2 = poule2.get(treeSize - i - 1).getComb();
|
||||||
|
|
||||||
|
fillMatchComb(lastNode.get(i).getMatch(), comb1, comb2);
|
||||||
|
toSave.add(lastNode.get(i).getMatch());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cat.isFullClassement()) {
|
||||||
|
for (int i = maxToMixTreeFill; i < maxToMixFill; i++) {
|
||||||
|
MatchModel match = new MatchModel();
|
||||||
|
match.setCategory(cat);
|
||||||
|
match.setCategory_ord(-42);
|
||||||
|
match.setEnd(false);
|
||||||
|
|
||||||
|
CombModel comb1 = poule1.get(i).getComb();
|
||||||
|
CombModel comb2 = poule2.get(i).getComb();
|
||||||
|
|
||||||
|
fillMatchComb(match, comb1, comb2);
|
||||||
|
toCreate.add(match);
|
||||||
|
|
||||||
|
toSaveTree.add(new TreeModel(cat.getId(), -10 - i, match));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Panache.withTransaction(() -> matchRepository.persist(toSave)
|
||||||
|
.call(__ -> matchRepository.create(toCreate)))
|
||||||
|
.call(__ -> toSaveTree.isEmpty() ? Uni.createFrom().voidItem()
|
||||||
|
: Panache.withTransaction(() -> treeRepository.persist(toSaveTree)))
|
||||||
|
.map(__ -> Stream.concat(toSave.stream(), toCreate.stream())
|
||||||
|
.map(MatchEntity::fromModel).toList());
|
||||||
|
})
|
||||||
|
)
|
||||||
|
.onFailure().invoke(t -> System.out.println("error: " + t.getMessage()))
|
||||||
|
.invoke(matchEntities -> SSMatch.sendMatch(connection, matchEntities))
|
||||||
|
.call(__ -> treeRepository.list("category = ?1 AND level != 0", categoryId)
|
||||||
|
.map(treeModels -> treeModels.stream().map(TreeEntity::fromModel).toList())
|
||||||
|
.invoke(trees -> SSCategorie.sendTreeCategory(connection, trees)))
|
||||||
|
.replaceWithVoid();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanTree(TreeModel treeModel, List<MatchModel> toSave) {
|
||||||
|
MatchModel model = treeModel.getMatch();
|
||||||
|
if (model != null) {
|
||||||
|
model.setC1_id(null);
|
||||||
|
model.setC1_guest(null);
|
||||||
|
model.setC2_id(null);
|
||||||
|
model.setC2_guest(null);
|
||||||
|
model.setEnd(false);
|
||||||
|
model.setDate(null);
|
||||||
|
model.getScores().clear();
|
||||||
|
|
||||||
|
toSave.add(model);
|
||||||
|
}
|
||||||
|
if (treeModel.getLeft() != null)
|
||||||
|
cleanTree(treeModel.getLeft(), toSave);
|
||||||
|
if (treeModel.getRight() != null)
|
||||||
|
cleanTree(treeModel.getRight(), toSave);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillMatchComb(MatchModel match, CombModel comb1, CombModel comb2) {
|
||||||
|
if (comb1 instanceof MembreModel m)
|
||||||
|
match.setC1_id(m);
|
||||||
|
else if (comb1 instanceof CompetitionGuestModel g)
|
||||||
|
match.setC1_guest(g);
|
||||||
|
|
||||||
|
if (comb2 instanceof MembreModel m)
|
||||||
|
match.setC2_id(m);
|
||||||
|
else if (comb2 instanceof CompetitionGuestModel g)
|
||||||
|
match.setC2_guest(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@RegisterForReflection
|
@RegisterForReflection
|
||||||
public record JustCategorie(long id, String name, int type, String liceName) {
|
public record JustCategorie(long id, String name, int type, String liceName, boolean treeAreClassement,
|
||||||
|
boolean fullClassement, PresetData preset) {
|
||||||
public static JustCategorie from(CategoryModel m) {
|
public static JustCategorie from(CategoryModel m) {
|
||||||
return new JustCategorie(m.getId(), m.getName(), m.getType(), m.getLiceName());
|
return new JustCategorie(m.getId(), m.getName(), m.getType(), m.getLiceName(), m.isTreeAreClassement(),
|
||||||
|
m.isFullClassement(), PresetData.fromModel(m.getPreset()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,7 +450,11 @@ public class RCategorie {
|
|||||||
String name;
|
String name;
|
||||||
int type;
|
int type;
|
||||||
String liceName;
|
String liceName;
|
||||||
|
boolean treeAreClassement = false;
|
||||||
|
boolean fullClassement = false;
|
||||||
|
PresetData preset;
|
||||||
List<TreeEntity> trees = null;
|
List<TreeEntity> trees = null;
|
||||||
List<MatchEntity> matches;
|
List<MatchEntity> matches;
|
||||||
|
List<CardModel> cards;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import fr.titionfire.ffsaf.data.model.*;
|
|||||||
import fr.titionfire.ffsaf.data.repository.*;
|
import fr.titionfire.ffsaf.data.repository.*;
|
||||||
import fr.titionfire.ffsaf.domain.entity.MatchEntity;
|
import fr.titionfire.ffsaf.domain.entity.MatchEntity;
|
||||||
import fr.titionfire.ffsaf.domain.entity.TreeEntity;
|
import fr.titionfire.ffsaf.domain.entity.TreeEntity;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
import fr.titionfire.ffsaf.rest.exception.DForbiddenException;
|
||||||
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
|
import fr.titionfire.ffsaf.rest.exception.DNotFoundException;
|
||||||
import fr.titionfire.ffsaf.utils.ScoreEmbeddable;
|
import fr.titionfire.ffsaf.utils.ScoreEmbeddable;
|
||||||
@@ -44,13 +45,19 @@ public class RMatch {
|
|||||||
@Inject
|
@Inject
|
||||||
CompetitionGuestRepository competitionGuestRepository;
|
CompetitionGuestRepository competitionGuestRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RState rState;
|
||||||
|
|
||||||
private Uni<MatchModel> getById(long id, WebSocketConnection connection) {
|
private Uni<MatchModel> getById(long id, WebSocketConnection connection) {
|
||||||
return matchRepository.findById(id)
|
return matchRepository.findById(id)
|
||||||
.invoke(Unchecked.consumer(o -> {
|
.invoke(Unchecked.consumer(o -> {
|
||||||
if (o == null)
|
if (o == null)
|
||||||
throw new DNotFoundException("Matche non trouver");
|
throw new DNotFoundException(trad.t("matche.non.trouver", connection));
|
||||||
if (!o.getCategory().getCompet().getUuid().equals(connection.pathParam("uuid")))
|
if (!o.getCategory().getCompet().getUuid().equals(connection.pathParam("uuid")))
|
||||||
throw new DForbiddenException("Permission denied");
|
throw new DForbiddenException(trad.t("permission.denied", connection));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,13 +85,13 @@ public class RMatch {
|
|||||||
return categoryRepository.findById(m.categorie)
|
return categoryRepository.findById(m.categorie)
|
||||||
.invoke(Unchecked.consumer(o -> {
|
.invoke(Unchecked.consumer(o -> {
|
||||||
if (o == null)
|
if (o == null)
|
||||||
throw new DNotFoundException("Catégorie non trouver");
|
throw new DNotFoundException(trad.t("categorie.non.trouver", connection));
|
||||||
if (!o.getCompet().getUuid().equals(connection.pathParam("uuid")))
|
if (!o.getCompet().getUuid().equals(connection.pathParam("uuid")))
|
||||||
throw new DForbiddenException("Permission denied");
|
throw new DForbiddenException(trad.t("permission.denied", connection));
|
||||||
}))
|
}))
|
||||||
.chain(categoryModel -> creatMatch(categoryModel, m))
|
.chain(categoryModel -> creatMatch(categoryModel, m))
|
||||||
.chain(mm -> Panache.withTransaction(() -> matchRepository.create(mm)))
|
.chain(mm -> Panache.withTransaction(() -> matchRepository.create(mm)))
|
||||||
.call(mm -> SSMatch.sendMatch(connection, MatchEntity.fromModel(mm)))
|
.invoke(mm -> SSMatch.sendMatch(connection, MatchEntity.fromModel(mm)))
|
||||||
.replaceWithVoid();
|
.replaceWithVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +128,7 @@ public class RMatch {
|
|||||||
mm.setC2_guest(null);
|
mm.setC2_guest(null);
|
||||||
}))
|
}))
|
||||||
.chain(mm -> Panache.withTransaction(() -> matchRepository.persist(mm)))
|
.chain(mm -> Panache.withTransaction(() -> matchRepository.persist(mm)))
|
||||||
.call(mm -> SSMatch.sendMatch(connection, MatchEntity.fromModel(mm)))
|
.invoke(mm -> SSMatch.sendMatch(connection, MatchEntity.fromModel(mm)))
|
||||||
.replaceWithVoid();
|
.replaceWithVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +143,7 @@ public class RMatch {
|
|||||||
m.getCategory_ord()))
|
m.getCategory_ord()))
|
||||||
.invoke(m -> m.setCategory_ord(order.pos))
|
.invoke(m -> m.setCategory_ord(order.pos))
|
||||||
.call(m -> Panache.withTransaction(() -> matchRepository.persist(m)))
|
.call(m -> Panache.withTransaction(() -> matchRepository.persist(m)))
|
||||||
.call(mm -> SSMatch.sendMatchOrder(connection, order))
|
.invoke(mm -> SSMatch.sendMatchOrder(connection, order))
|
||||||
.replaceWithVoid();
|
.replaceWithVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,12 +170,12 @@ public class RMatch {
|
|||||||
.call(mm -> {
|
.call(mm -> {
|
||||||
if (mm.isEnd() && mm.win() != old_win && mm.getCategory_ord() == -42) {
|
if (mm.isEnd() && mm.win() != old_win && mm.getCategory_ord() == -42) {
|
||||||
return updateEndAndTree(mm, new ArrayList<>())
|
return updateEndAndTree(mm, new ArrayList<>())
|
||||||
.call(l -> SSMatch.sendMatch(connection, l));
|
.invoke(l -> SSMatch.sendMatch(connection, l));
|
||||||
}
|
}
|
||||||
return Uni.createFrom().nullItem();
|
return Uni.createFrom().nullItem();
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.call(mm -> SSMatch.sendMatch(connection, MatchEntity.fromModel(mm)))
|
.invoke(mm -> SSMatch.sendMatch(connection, MatchEntity.fromModel(mm)))
|
||||||
.replaceWithVoid();
|
.replaceWithVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,8 +195,9 @@ public class RMatch {
|
|||||||
return Panache.withTransaction(() -> matchRepository.persist(mm));
|
return Panache.withTransaction(() -> matchRepository.persist(mm));
|
||||||
})
|
})
|
||||||
.invoke(mm -> toSend.add(MatchEntity.fromModel(mm)))
|
.invoke(mm -> toSend.add(MatchEntity.fromModel(mm)))
|
||||||
|
.invoke(mm -> rState.setMatchEnd(connection, matchEnd))
|
||||||
.chain(mm -> updateEndAndTree(mm, toSend))
|
.chain(mm -> updateEndAndTree(mm, toSend))
|
||||||
.call(__ -> SSMatch.sendMatch(connection, toSend))
|
.invoke(__ -> SSMatch.sendMatch(connection, toSend))
|
||||||
.replaceWithVoid();
|
.replaceWithVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,8 +285,9 @@ public class RMatch {
|
|||||||
@WSReceiver(code = "deleteMatch", permission = PermLevel.ADMIN)
|
@WSReceiver(code = "deleteMatch", permission = PermLevel.ADMIN)
|
||||||
public Uni<Void> deleteMatch(WebSocketConnection connection, Long idMatch) {
|
public Uni<Void> deleteMatch(WebSocketConnection connection, Long idMatch) {
|
||||||
return getById(idMatch, connection)
|
return getById(idMatch, connection)
|
||||||
.chain(matchModel -> Panache.withTransaction(() -> matchRepository.delete(matchModel)))
|
.map(__ -> idMatch)
|
||||||
.call(__ -> SSMatch.sendDeleteMatch(connection, idMatch))
|
.chain(l -> Panache.withTransaction(() -> matchRepository.delete("id = ?1", l)))
|
||||||
|
.invoke(__ -> SSMatch.sendDeleteMatch(connection, idMatch))
|
||||||
.replaceWithVoid();
|
.replaceWithVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,34 +297,28 @@ public class RMatch {
|
|||||||
return categoryRepository.findById(data.categorie)
|
return categoryRepository.findById(data.categorie)
|
||||||
.invoke(Unchecked.consumer(o -> {
|
.invoke(Unchecked.consumer(o -> {
|
||||||
if (o == null)
|
if (o == null)
|
||||||
throw new DNotFoundException("Catégorie non trouver");
|
throw new DNotFoundException(trad.t("categorie.non.trouver", connection));
|
||||||
if (!o.getCompet().getUuid().equals(connection.pathParam("uuid")))
|
if (!o.getCompet().getUuid().equals(connection.pathParam("uuid")))
|
||||||
throw new DForbiddenException("Permission denied");
|
throw new DForbiddenException(trad.t("permission.denied", connection));
|
||||||
}))
|
}))
|
||||||
.invoke(m -> System.out.println("A00"))
|
|
||||||
.call(cm -> data.matchesToRemove.isEmpty() ? Uni.createFrom().voidItem() :
|
.call(cm -> data.matchesToRemove.isEmpty() ? Uni.createFrom().voidItem() :
|
||||||
(Panache.withTransaction(
|
(Panache.withTransaction(
|
||||||
() -> matchRepository.delete("id IN ?1 AND category = ?2", data.matchesToRemove, cm))
|
() -> matchRepository.delete("id IN ?1 AND category = ?2", data.matchesToRemove, cm))
|
||||||
.call(__ -> SSMatch.sendDeleteMatch(connection, data.matchesToRemove))))
|
.invoke(__ -> SSMatch.sendDeleteMatch(connection, data.matchesToRemove))))
|
||||||
.invoke(m -> System.out.println("A0"))
|
|
||||||
.call(cm -> Panache.withSession(() -> matchRepository.list("id IN ?1 AND category = ?2",
|
.call(cm -> Panache.withSession(() -> matchRepository.list("id IN ?1 AND category = ?2",
|
||||||
Stream.concat(data.matchOrderToUpdate.keySet().stream(),
|
Stream.concat(data.matchOrderToUpdate.keySet().stream(),
|
||||||
data.matchPouleToUpdate.keySet().stream())
|
data.matchPouleToUpdate.keySet().stream())
|
||||||
.distinct().toList(), cm)
|
.distinct().toList(), cm)
|
||||||
.invoke(m -> System.out.println("A " + m.size()))
|
|
||||||
.invoke(matchModels -> matchModels.forEach(model -> {
|
.invoke(matchModels -> matchModels.forEach(model -> {
|
||||||
if (data.matchPouleToUpdate.containsKey(model.getId()))
|
if (data.matchPouleToUpdate.containsKey(model.getId()))
|
||||||
model.setPoule(data.matchPouleToUpdate.get(model.getId()));
|
model.setPoule(data.matchPouleToUpdate.get(model.getId()));
|
||||||
if (data.matchOrderToUpdate.containsKey(model.getId()))
|
if (data.matchOrderToUpdate.containsKey(model.getId()))
|
||||||
model.setCategory_ord(data.matchOrderToUpdate.get(model.getId()));
|
model.setCategory_ord(data.matchOrderToUpdate.get(model.getId()));
|
||||||
}))
|
}))
|
||||||
.invoke(m -> System.out.println("B " + m.size()))
|
|
||||||
.call(mm -> mm.isEmpty() ? Uni.createFrom().voidItem() :
|
.call(mm -> mm.isEmpty() ? Uni.createFrom().voidItem() :
|
||||||
Panache.withTransaction(() -> matchRepository.persist(mm)))
|
Panache.withTransaction(() -> matchRepository.persist(mm)))
|
||||||
.invoke(m -> System.out.println("C"))
|
|
||||||
.invoke(mm -> matches.addAll(mm.stream().map(MatchEntity::fromModel).toList())))
|
.invoke(mm -> matches.addAll(mm.stream().map(MatchEntity::fromModel).toList())))
|
||||||
)
|
)
|
||||||
.invoke(m -> System.out.println("D"))
|
|
||||||
.chain(categoryModel -> {
|
.chain(categoryModel -> {
|
||||||
Uni<List<MatchModel>> uni = Uni.createFrom().item(new ArrayList<>());
|
Uni<List<MatchModel>> uni = Uni.createFrom().item(new ArrayList<>());
|
||||||
for (AddMatch match : data.newMatch)
|
for (AddMatch match : data.newMatch)
|
||||||
@@ -324,12 +327,10 @@ public class RMatch {
|
|||||||
return Panache.withSession(() -> finalUni);
|
return Panache.withSession(() -> finalUni);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.invoke(m -> System.out.println("E"))
|
|
||||||
.chain(mm -> mm.isEmpty() ? Uni.createFrom().voidItem() :
|
.chain(mm -> mm.isEmpty() ? Uni.createFrom().voidItem() :
|
||||||
Panache.withTransaction(() -> matchRepository.create(mm))
|
Panache.withTransaction(() -> matchRepository.create(mm))
|
||||||
.invoke(__ -> matches.addAll(mm.stream().map(MatchEntity::fromModel).toList())))
|
.invoke(__ -> matches.addAll(mm.stream().map(MatchEntity::fromModel).toList())))
|
||||||
.invoke(m -> System.out.println("F"))
|
.invoke(__ -> SSMatch.sendMatch(connection, matches))
|
||||||
.call(__ -> SSMatch.sendMatch(connection, matches))
|
|
||||||
.replaceWithVoid();
|
.replaceWithVoid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
112
src/main/java/fr/titionfire/ffsaf/ws/recv/RPDF.java
Normal file
112
src/main/java/fr/titionfire/ffsaf/ws/recv/RPDF.java
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
package fr.titionfire.ffsaf.ws.recv;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.CardModel;
|
||||||
|
import fr.titionfire.ffsaf.data.model.CategoryModel;
|
||||||
|
import fr.titionfire.ffsaf.data.model.MatchModel;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.CardRepository;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.CategoryRepository;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.CompetitionRepository;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.MatchRepository;
|
||||||
|
import fr.titionfire.ffsaf.domain.entity.MatchModelExtend;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.ResultService;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
|
import fr.titionfire.ffsaf.rest.data.ResultCategoryData;
|
||||||
|
import fr.titionfire.ffsaf.utils.Categorie;
|
||||||
|
import fr.titionfire.ffsaf.ws.PermLevel;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import io.quarkus.websockets.next.WebSocketConnection;
|
||||||
|
import io.smallrye.mutiny.Multi;
|
||||||
|
import io.smallrye.mutiny.Uni;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
import jakarta.inject.Inject;
|
||||||
|
import jakarta.transaction.Transactional;
|
||||||
|
import org.hibernate.reactive.mutiny.Mutiny;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@WithSession
|
||||||
|
@ApplicationScoped
|
||||||
|
@RegisterForReflection
|
||||||
|
public class RPDF {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CompetitionRepository competitionRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
MatchRepository matchRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CardRepository cardRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CategoryRepository categoryRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ResultService resultService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
@WSReceiver(code = "getPodium", permission = PermLevel.VIEW)
|
||||||
|
public Uni<List<PodiumEntity>> getPodium(WebSocketConnection connection, Object o) {
|
||||||
|
List<CardModel> cards = new java.util.ArrayList<>();
|
||||||
|
|
||||||
|
return cardRepository.list("competition.uuid = ?1", connection.pathParam("uuid"))
|
||||||
|
.invoke(cards::addAll)
|
||||||
|
.chain(__ -> matchRepository.list("category.compet.uuid = ?1", connection.pathParam("uuid")))
|
||||||
|
.chain(matchs -> {
|
||||||
|
HashMap<CategoryModel, List<MatchModel>> map = new HashMap<>();
|
||||||
|
for (MatchModel match : matchs) {
|
||||||
|
if (!map.containsKey(match.getCategory()))
|
||||||
|
map.put(match.getCategory(), new java.util.ArrayList<>());
|
||||||
|
map.get(match.getCategory()).add(match);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Multi.createFrom().iterable(map.entrySet())
|
||||||
|
.onItem().call(entry -> Mutiny.fetch(entry.getKey().getTree()))
|
||||||
|
.map(entry -> {
|
||||||
|
ResultCategoryData tmp = new ResultCategoryData();
|
||||||
|
|
||||||
|
double cmoy = entry.getValue().stream().flatMap(m -> Stream.of(m.getC1(), m.getC2()))
|
||||||
|
.filter(c -> c != null && c.getCategorie() != null)
|
||||||
|
.mapToInt(c -> c.getCategorie().ordinal())
|
||||||
|
.average().orElse(0);
|
||||||
|
Categorie categorie_moy = Categorie.values()[(int) Math.ceil(cmoy)];
|
||||||
|
|
||||||
|
resultService.getArray2(
|
||||||
|
entry.getValue().stream().map(m -> new MatchModelExtend(m, cards)).toList(),
|
||||||
|
null, tmp);
|
||||||
|
resultService.getClassementArray(entry.getKey(), null, cards, tmp);
|
||||||
|
|
||||||
|
String source = "";
|
||||||
|
if ((entry.getKey().getType() & 2) != 0) {
|
||||||
|
if (entry.getKey().isTreeAreClassement())
|
||||||
|
source = trad.t("podium.source.classement", connection);
|
||||||
|
else
|
||||||
|
source = trad.t("podium.source.tree", connection);
|
||||||
|
} else if ((entry.getKey().getType() & 1) != 0)
|
||||||
|
source = trad.t("podium.source.poule", connection);
|
||||||
|
|
||||||
|
|
||||||
|
return new PodiumEntity(entry.getKey().getName(), source, categorie_moy,
|
||||||
|
tmp.getClassement());
|
||||||
|
})
|
||||||
|
.collect().asList();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "getPodiumClub", permission = PermLevel.VIEW)
|
||||||
|
public Uni<List<ResultService.ClubClassement>> getPodiumClub(WebSocketConnection connection, Object o) {
|
||||||
|
return resultService.getAllClubArray(connection.pathParam("uuid"), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@RegisterForReflection
|
||||||
|
public static record PodiumEntity(String poule_name, String source, Categorie categorie,
|
||||||
|
List<ResultCategoryData.ClassementData> podium) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import fr.titionfire.ffsaf.ws.PermLevel;
|
|||||||
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
||||||
import io.quarkus.runtime.annotations.RegisterForReflection;
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
import io.quarkus.websockets.next.WebSocketConnection;
|
import io.quarkus.websockets.next.WebSocketConnection;
|
||||||
|
import io.smallrye.mutiny.Multi;
|
||||||
import io.smallrye.mutiny.Uni;
|
import io.smallrye.mutiny.Uni;
|
||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
@@ -24,14 +25,20 @@ public class RRegister {
|
|||||||
|
|
||||||
@WSReceiver(code = "getRegister", permission = PermLevel.TABLE)
|
@WSReceiver(code = "getRegister", permission = PermLevel.TABLE)
|
||||||
public Uni<List<CombEntity>> getRegister(WebSocketConnection connection, Object o) {
|
public Uni<List<CombEntity>> getRegister(WebSocketConnection connection, Object o) {
|
||||||
|
ArrayList<CombEntity> combEntities = new ArrayList<>();
|
||||||
return competitionRepository.find("uuid", connection.pathParam("uuid")).firstResult()
|
return competitionRepository.find("uuid", connection.pathParam("uuid")).firstResult()
|
||||||
.call(cm -> Mutiny.fetch(cm.getInsc()))
|
.call(cm -> Mutiny.fetch(cm.getInsc())
|
||||||
.call(cm -> Mutiny.fetch(cm.getGuests()))
|
.onItem().transformToMulti(Multi.createFrom()::iterable)
|
||||||
.map(cm -> {
|
.call(r -> Mutiny.fetch(r.getCategoriesInscrites()))
|
||||||
ArrayList<CombEntity> combEntities = new ArrayList<>();
|
.map(r -> CombEntity.fromModel(r).addCategoriesInscrites(r.getCategoriesInscrites()))
|
||||||
combEntities.addAll(cm.getInsc().stream().map(CombEntity::fromModel).toList());
|
.collect().asList()
|
||||||
combEntities.addAll(cm.getGuests().stream().map(CombEntity::fromModel).toList());
|
.invoke(combEntities::addAll))
|
||||||
return combEntities;
|
.call(cm -> Mutiny.fetch(cm.getGuests())
|
||||||
});
|
.onItem().transformToMulti(Multi.createFrom()::iterable)
|
||||||
|
.call(r -> Mutiny.fetch(r.getCategoriesInscrites()))
|
||||||
|
.map(r -> CombEntity.fromModel(r).addCategoriesInscrites(r.getCategoriesInscrites()))
|
||||||
|
.collect().asList()
|
||||||
|
.invoke(combEntities::addAll))
|
||||||
|
.replaceWith(combEntities);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
149
src/main/java/fr/titionfire/ffsaf/ws/recv/RState.java
Normal file
149
src/main/java/fr/titionfire/ffsaf/ws/recv/RState.java
Normal file
@@ -0,0 +1,149 @@
|
|||||||
|
package fr.titionfire.ffsaf.ws.recv;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.ws.PermLevel;
|
||||||
|
import fr.titionfire.ffsaf.ws.send.SSState;
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import io.quarkus.websockets.next.UserData;
|
||||||
|
import io.quarkus.websockets.next.WebSocketConnection;
|
||||||
|
import io.smallrye.mutiny.Uni;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
@RegisterForReflection
|
||||||
|
public class RState {
|
||||||
|
|
||||||
|
private static final HashMap<WebSocketConnection, TableState> tableStates = new HashMap<>();
|
||||||
|
|
||||||
|
@WSReceiver(code = "subscribeToState", permission = PermLevel.VIEW)
|
||||||
|
public Uni<List<TableState>> sendCurrentScore(WebSocketConnection connection, Boolean subscribe) {
|
||||||
|
connection.userData().put(UserData.TypedKey.forBoolean("needState"), subscribe);
|
||||||
|
|
||||||
|
if (subscribe) {
|
||||||
|
String uuid = connection.pathParam("uuid");
|
||||||
|
return Uni.createFrom().item(() ->
|
||||||
|
tableStates.values().stream().filter(s -> s.getCompetitionUuid().equals(uuid)).toList()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Uni.createFrom().nullItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "sendState", permission = PermLevel.TABLE)
|
||||||
|
public Uni<Void> sendState(WebSocketConnection connection, TableState tableState) {
|
||||||
|
tableState.setCompetitionUuid(connection.pathParam("uuid"));
|
||||||
|
|
||||||
|
if (tableStates.containsKey(connection))
|
||||||
|
tableState.setId(tableStates.get(connection).getId());
|
||||||
|
if (tableState.getChronoState().isRunning() && tableState.getChronoState().state == 0)
|
||||||
|
tableState.setState(MatchState.IN_PROGRESS);
|
||||||
|
tableStates.put(connection, tableState);
|
||||||
|
SSState.sendStateFull(connection, tableState);
|
||||||
|
return Uni.createFrom().voidItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "sendSelectCategory", permission = PermLevel.TABLE)
|
||||||
|
public Uni<Void> sendSelectCategory(WebSocketConnection connection, Long catId) {
|
||||||
|
TableState tableState = tableStates.get(connection);
|
||||||
|
if (tableState != null) {
|
||||||
|
tableState.setSelectedCategory(catId);
|
||||||
|
tableState.setState(MatchState.NOT_STARTED);
|
||||||
|
SSState.sendStateFull(connection, tableState);
|
||||||
|
}
|
||||||
|
return Uni.createFrom().voidItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "sendSelectMatch", permission = PermLevel.TABLE)
|
||||||
|
public Uni<Void> sendSelectMatch(WebSocketConnection connection, Long matchId) {
|
||||||
|
TableState tableState = tableStates.get(connection);
|
||||||
|
if (tableState != null) {
|
||||||
|
tableState.setSelectedMatch(matchId);
|
||||||
|
tableState.setState(MatchState.NOT_STARTED);
|
||||||
|
SSState.sendStateFull(connection, tableState);
|
||||||
|
}
|
||||||
|
return Uni.createFrom().voidItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "sendCurentChrono", permission = PermLevel.TABLE)
|
||||||
|
public Uni<Void> sendCurentChrono(WebSocketConnection connection, ChronoState chronoState) {
|
||||||
|
TableState tableState = tableStates.get(connection);
|
||||||
|
if (tableState != null) {
|
||||||
|
tableState.setChronoState(chronoState);
|
||||||
|
if (chronoState.isRunning())
|
||||||
|
tableState.setState(MatchState.IN_PROGRESS);
|
||||||
|
SSState.sendStateFull(connection, tableState);
|
||||||
|
}
|
||||||
|
return Uni.createFrom().voidItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "sendLicenceName", permission = PermLevel.TABLE)
|
||||||
|
public Uni<Void> sendCurrentScore(WebSocketConnection connection, String name) {
|
||||||
|
TableState tableState = tableStates.get(connection);
|
||||||
|
if (tableState != null) {
|
||||||
|
tableState.setLiceName(name);
|
||||||
|
SSState.sendStateFull(connection, tableState);
|
||||||
|
}
|
||||||
|
return Uni.createFrom().voidItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
@WSReceiver(code = "sendCurrentScore", permission = PermLevel.TABLE)
|
||||||
|
public Uni<Void> sendCurrentScore(WebSocketConnection connection, ScoreState scoreState) {
|
||||||
|
TableState tableState = tableStates.get(connection);
|
||||||
|
if (tableState != null) {
|
||||||
|
tableState.setScoreState(scoreState);
|
||||||
|
SSState.sendStateFull(connection, tableState);
|
||||||
|
}
|
||||||
|
return Uni.createFrom().voidItem();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeConnection(WebSocketConnection connection) {
|
||||||
|
if (tableStates.containsKey(connection)) {
|
||||||
|
SSState.sendRmStateFull(connection, tableStates.get(connection).getId());
|
||||||
|
tableStates.remove(connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMatchEnd(WebSocketConnection connection, RMatch.MatchEnd matchEnd) {
|
||||||
|
if (tableStates.containsKey(connection)) {
|
||||||
|
TableState tableState = tableStates.get(connection);
|
||||||
|
if (matchEnd.end())
|
||||||
|
tableState.setState(MatchState.ENDED);
|
||||||
|
else
|
||||||
|
tableState.setState(MatchState.IN_PROGRESS);
|
||||||
|
SSState.sendStateFull(connection, tableState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RegisterForReflection
|
||||||
|
public record ChronoState(long time, long startTime, long configTime, long configPause, int state) {
|
||||||
|
public boolean isRunning() {
|
||||||
|
return startTime != 0 || state != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RegisterForReflection
|
||||||
|
public record ScoreState(int scoreRouge, int scoreBleu) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@RegisterForReflection
|
||||||
|
public static class TableState {
|
||||||
|
UUID id = UUID.randomUUID();
|
||||||
|
String competitionUuid;
|
||||||
|
Long selectedCategory;
|
||||||
|
Long selectedMatch;
|
||||||
|
ChronoState chronoState;
|
||||||
|
ScoreState scoreState;
|
||||||
|
String liceName = "???";
|
||||||
|
MatchState state = MatchState.NOT_STARTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum MatchState {
|
||||||
|
NOT_STARTED,
|
||||||
|
IN_PROGRESS,
|
||||||
|
ENDED
|
||||||
|
}
|
||||||
|
}
|
||||||
137
src/main/java/fr/titionfire/ffsaf/ws/recv/RTeam.java
Normal file
137
src/main/java/fr/titionfire/ffsaf/ws/recv/RTeam.java
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
package fr.titionfire.ffsaf.ws.recv;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.CompetitionGuestModel;
|
||||||
|
import fr.titionfire.ffsaf.data.model.RegisterModel;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.CompetitionGuestRepository;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.CompetitionRepository;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.RegisterRepository;
|
||||||
|
import fr.titionfire.ffsaf.domain.entity.CombEntity;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.TradService;
|
||||||
|
import fr.titionfire.ffsaf.utils.Categorie;
|
||||||
|
import fr.titionfire.ffsaf.utils.Genre;
|
||||||
|
import fr.titionfire.ffsaf.utils.Pair;
|
||||||
|
import fr.titionfire.ffsaf.ws.PermLevel;
|
||||||
|
import fr.titionfire.ffsaf.ws.send.SSRegister;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.Panache;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.common.WithSession;
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import io.quarkus.websockets.next.WebSocketConnection;
|
||||||
|
import io.smallrye.mutiny.Uni;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
import jakarta.inject.Inject;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
@WithSession
|
||||||
|
@ApplicationScoped
|
||||||
|
@RegisterForReflection
|
||||||
|
public class RTeam {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
TradService trad;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CompetitionRepository competitionRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
RegisterRepository registerRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CompetitionGuestRepository competitionGuestRepository;
|
||||||
|
|
||||||
|
@WSReceiver(code = "setTeam", permission = PermLevel.ADMIN)
|
||||||
|
public Uni<CombEntity> setTeam(WebSocketConnection connection, TeamData data) {
|
||||||
|
return competitionRepository.find("uuid", connection.pathParam("uuid")).firstResult()
|
||||||
|
.chain(cm -> registerRepository.list("membre.id IN ?1 AND competition = ?2",
|
||||||
|
data.members.stream().filter(id -> id >= 0).toList(), cm)
|
||||||
|
.chain(l -> competitionGuestRepository.list("id IN ?1",
|
||||||
|
data.members.stream().filter(id -> id < 0).map(i -> i * -1).toList())
|
||||||
|
.map(l2 -> new Pair<>(l, l2)))
|
||||||
|
.chain(pair ->
|
||||||
|
competitionGuestRepository.find("fname = ?1 AND lname = ?2 AND competition = ?3",
|
||||||
|
data.name, "__team", cm).firstResult()
|
||||||
|
.chain(team -> {
|
||||||
|
if (pair.getKey().isEmpty() && pair.getValue().isEmpty()) {
|
||||||
|
if (team != null) {
|
||||||
|
CompetitionGuestModel finalTeam1 = team;
|
||||||
|
SSRegister.sendRegisterRemove(connection, finalTeam1.getId() * -1);
|
||||||
|
return Panache.withTransaction(
|
||||||
|
() -> competitionGuestRepository.delete(finalTeam1))
|
||||||
|
.replaceWith((CombEntity) null);
|
||||||
|
} else
|
||||||
|
return Uni.createFrom().item((CombEntity) null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (team == null) {
|
||||||
|
// Create new team
|
||||||
|
team = new CompetitionGuestModel();
|
||||||
|
team.setFname(data.name);
|
||||||
|
team.setLname("__team");
|
||||||
|
team.setCompetition(cm);
|
||||||
|
team.setClub("Team");
|
||||||
|
team.setGenre(Genre.NA);
|
||||||
|
} else {
|
||||||
|
team.getComb().clear();
|
||||||
|
team.getGuest().clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
team.setCategorie(Stream.concat(
|
||||||
|
pair.getKey().stream().map(RegisterModel::getCategorie2),
|
||||||
|
pair.getValue().stream().map(CompetitionGuestModel::getCategorie))
|
||||||
|
.map(Enum::ordinal)
|
||||||
|
.max(Integer::compareTo)
|
||||||
|
.map(i -> Categorie.values()[i]).orElse(Categorie.SENIOR1));
|
||||||
|
|
||||||
|
List<Float> s = Stream.concat(
|
||||||
|
pair.getKey().stream().map(RegisterModel::getWeight),
|
||||||
|
pair.getValue().stream().map(CompetitionGuestModel::getWeight))
|
||||||
|
.filter(Objects::nonNull).toList();
|
||||||
|
if (s.isEmpty()) {
|
||||||
|
team.setWeight(null);
|
||||||
|
} else if (s.size() == 1) {
|
||||||
|
team.setWeight(s.get(0));
|
||||||
|
} else {
|
||||||
|
team.setWeight((float) s.stream().mapToDouble(Float::doubleValue)
|
||||||
|
.average()
|
||||||
|
.orElse(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
team.setCountry(Stream.concat(
|
||||||
|
pair.getKey().stream().map(m -> m.getMembre().getCountry()),
|
||||||
|
pair.getValue().stream().map(CompetitionGuestModel::getCountry))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.map(String::toUpperCase)
|
||||||
|
.collect(Collectors.groupingBy(
|
||||||
|
e -> e, // Classer par élément
|
||||||
|
Collectors.counting() // Compter les occurrences
|
||||||
|
))
|
||||||
|
.entrySet()
|
||||||
|
.stream()
|
||||||
|
.max(Map.Entry.comparingByValue())
|
||||||
|
.map(Map.Entry::getKey)
|
||||||
|
.orElse("FR"));
|
||||||
|
|
||||||
|
team.getComb().addAll(
|
||||||
|
pair.getKey().stream().map(RegisterModel::getMembre).toList());
|
||||||
|
team.getGuest().addAll(pair.getValue());
|
||||||
|
|
||||||
|
CompetitionGuestModel finalTeam = team;
|
||||||
|
return Panache.withTransaction(
|
||||||
|
() -> competitionGuestRepository.persistAndFlush(finalTeam))
|
||||||
|
.map(CombEntity::fromModel);
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
.invoke(combEntity -> {
|
||||||
|
if (combEntity != null)
|
||||||
|
SSRegister.sendRegister(connection, combEntity);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@RegisterForReflection
|
||||||
|
public record TeamData(List<Long> members, String name) {
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package fr.titionfire.ffsaf.ws.send;
|
|||||||
import fr.titionfire.ffsaf.data.model.CompetitionGuestModel;
|
import fr.titionfire.ffsaf.data.model.CompetitionGuestModel;
|
||||||
import fr.titionfire.ffsaf.data.model.RegisterModel;
|
import fr.titionfire.ffsaf.data.model.RegisterModel;
|
||||||
import fr.titionfire.ffsaf.domain.entity.CombEntity;
|
import fr.titionfire.ffsaf.domain.entity.CombEntity;
|
||||||
|
import fr.titionfire.ffsaf.domain.service.CardService;
|
||||||
import fr.titionfire.ffsaf.net2.MessageType;
|
import fr.titionfire.ffsaf.net2.MessageType;
|
||||||
import fr.titionfire.ffsaf.ws.CompetitionWS;
|
import fr.titionfire.ffsaf.ws.CompetitionWS;
|
||||||
import fr.titionfire.ffsaf.ws.MessageOut;
|
import fr.titionfire.ffsaf.ws.MessageOut;
|
||||||
@@ -13,6 +14,7 @@ import io.quarkus.websockets.next.UserData;
|
|||||||
import io.smallrye.mutiny.Uni;
|
import io.smallrye.mutiny.Uni;
|
||||||
import jakarta.enterprise.context.ApplicationScoped;
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
import jakarta.inject.Inject;
|
import jakarta.inject.Inject;
|
||||||
|
import org.hibernate.reactive.mutiny.Mutiny;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@@ -25,16 +27,48 @@ public class SRegister {
|
|||||||
@Inject
|
@Inject
|
||||||
OpenConnections connections;
|
OpenConnections connections;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CardService cardService;
|
||||||
|
|
||||||
public Uni<Void> sendRegister(String uuid, RegisterModel registerModel) {
|
public Uni<Void> sendRegister(String uuid, RegisterModel registerModel) {
|
||||||
return send(uuid, "sendRegister", CombEntity.fromModel(registerModel));
|
return Mutiny.fetch(registerModel.getCategoriesInscrites()).chain(o ->
|
||||||
|
send(uuid, "sendRegister", CombEntity.fromModel(registerModel).addCategoriesInscrites(o))
|
||||||
|
.call(__ -> registerModel.getClub2() == null ? Uni.createFrom().voidItem() :
|
||||||
|
cardService.addTeamCartToNewComb(registerModel.getMembre().getId(),
|
||||||
|
registerModel.getClub2().getClubId(), registerModel.getClub2().getName(),
|
||||||
|
registerModel.getCompetition())
|
||||||
|
.chain(cardModels -> send(uuid, "sendCards", cardModels))));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<Void> sendRegisterNoFetch(String uuid, RegisterModel registerModel) {
|
||||||
|
return send(uuid, "sendRegister",
|
||||||
|
CombEntity.fromModel(registerModel).addCategoriesInscrites(registerModel.getCategoriesInscrites()))
|
||||||
|
.call(__ -> registerModel.getClub2() == null ? Uni.createFrom().voidItem() :
|
||||||
|
cardService.addTeamCartToNewComb(registerModel.getMembre().getId(),
|
||||||
|
registerModel.getClub2().getClubId(), registerModel.getClub2().getName(),
|
||||||
|
registerModel.getCompetition())
|
||||||
|
.chain(cardModels -> send(uuid, "sendCards", cardModels)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<Void> sendRegister(String uuid, CompetitionGuestModel model) {
|
public Uni<Void> sendRegister(String uuid, CompetitionGuestModel model) {
|
||||||
return send(uuid, "sendRegister", CombEntity.fromModel(model));
|
return Mutiny.fetch(model.getCategoriesInscrites()).chain(o ->
|
||||||
|
send(uuid, "sendRegister", CombEntity.fromModel(model).addCategoriesInscrites(o))
|
||||||
|
.call(__ -> cardService.addTeamCartToNewComb(model.getId() * -1,
|
||||||
|
null, model.getClub(), model.getCompetition())
|
||||||
|
.chain(cardModels -> send(uuid, "sendCards", cardModels))));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uni<Void> sendRegisterNoFetch(String uuid, CompetitionGuestModel model) {
|
||||||
|
return send(uuid, "sendRegister",
|
||||||
|
CombEntity.fromModel(model).addCategoriesInscrites(model.getCategoriesInscrites()))
|
||||||
|
.call(__ -> cardService.addTeamCartToNewComb(model.getId() * -1,
|
||||||
|
null, model.getClub(), model.getCompetition())
|
||||||
|
.chain(cardModels -> send(uuid, "sendCards", cardModels)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<Void> sendRegisterRemove(String uuid, Long combId) {
|
public Uni<Void> sendRegisterRemove(String uuid, Long combId) {
|
||||||
return send(uuid, "sendRegisterRemove", combId);
|
return send(uuid, "sendRegisterRemove", combId)
|
||||||
|
.call(__ -> cardService.rmTeamCardFromComb(combId, uuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<Void> send(String uuid, String code, Object data) {
|
public Uni<Void> send(String uuid, String code, Object data) {
|
||||||
|
|||||||
27
src/main/java/fr/titionfire/ffsaf/ws/send/SSCard.java
Normal file
27
src/main/java/fr/titionfire/ffsaf/ws/send/SSCard.java
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
package fr.titionfire.ffsaf.ws.send;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.CardModel;
|
||||||
|
import fr.titionfire.ffsaf.ws.CompetitionWS;
|
||||||
|
import fr.titionfire.ffsaf.ws.recv.RCard;
|
||||||
|
import io.quarkus.websockets.next.WebSocketConnection;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class SSCard {
|
||||||
|
|
||||||
|
public static void sendCards(WebSocketConnection connection, List<CardModel> cardModel) {
|
||||||
|
CompetitionWS.sendNotifyToOtherEditor(connection, "sendCards", cardModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendRmCards(WebSocketConnection connection, List<Long> ids) {
|
||||||
|
CompetitionWS.sendNotifyToOtherEditor(connection, "rmCards", ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendTeamCard(WebSocketConnection connection, RCard.SendTeamCards teamCards) {
|
||||||
|
CompetitionWS.sendNotifyToOtherEditor(connection, "sendTeamCard", teamCards);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void rmTeamCard(WebSocketConnection connection, RCard.SendTeamCards teamCards) {
|
||||||
|
CompetitionWS.sendNotifyToOtherEditor(connection, "rmTeamCard", teamCards);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
package fr.titionfire.ffsaf.ws.send;
|
|
||||||
|
|
||||||
import fr.titionfire.ffsaf.domain.entity.CardboardEntity;
|
|
||||||
import fr.titionfire.ffsaf.ws.CompetitionWS;
|
|
||||||
import io.quarkus.websockets.next.WebSocketConnection;
|
|
||||||
import io.smallrye.mutiny.Uni;
|
|
||||||
|
|
||||||
public class SSCardboard {
|
|
||||||
|
|
||||||
public static Uni<Void> sendCardboard(WebSocketConnection connection, CardboardEntity cardboardEntity) {
|
|
||||||
return CompetitionWS.sendNotifyToOtherEditor(connection, "sendCardboard", cardboardEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,33 +5,32 @@ import fr.titionfire.ffsaf.domain.entity.TreeEntity;
|
|||||||
import fr.titionfire.ffsaf.ws.CompetitionWS;
|
import fr.titionfire.ffsaf.ws.CompetitionWS;
|
||||||
import fr.titionfire.ffsaf.ws.recv.RCategorie;
|
import fr.titionfire.ffsaf.ws.recv.RCategorie;
|
||||||
import io.quarkus.websockets.next.WebSocketConnection;
|
import io.quarkus.websockets.next.WebSocketConnection;
|
||||||
import io.smallrye.mutiny.Uni;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SSCategorie {
|
public class SSCategorie {
|
||||||
|
|
||||||
public static Uni<Void> sendAddCategory(WebSocketConnection connection, CategoryModel category) {
|
public static void sendAddCategory(WebSocketConnection connection, CategoryModel category) {
|
||||||
return SSCategorie.sendAddCategory(connection, RCategorie.JustCategorie.from(category));
|
SSCategorie.sendAddCategory(connection, RCategorie.JustCategorie.from(category));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uni<Void> sendAddCategory(WebSocketConnection connection, RCategorie.JustCategorie justCategorie) {
|
public static void sendAddCategory(WebSocketConnection connection, RCategorie.JustCategorie justCategorie) {
|
||||||
return CompetitionWS.sendNotifyToOtherEditor(connection, "sendAddCategory", justCategorie);
|
CompetitionWS.sendNotifyToOtherEditor(connection, "sendAddCategory", justCategorie);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uni<Void> sendCategory(WebSocketConnection connection, CategoryModel category) {
|
public static void sendCategory(WebSocketConnection connection, CategoryModel category) {
|
||||||
return SSCategorie.sendCategory(connection, RCategorie.JustCategorie.from(category));
|
SSCategorie.sendCategory(connection, RCategorie.JustCategorie.from(category));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uni<Void> sendCategory(WebSocketConnection connection, RCategorie.JustCategorie justCategorie) {
|
public static void sendCategory(WebSocketConnection connection, RCategorie.JustCategorie justCategorie) {
|
||||||
return CompetitionWS.sendNotifyToOtherEditor(connection, "sendCategory", justCategorie);
|
CompetitionWS.sendNotifyToOtherEditor(connection, "sendCategory", justCategorie);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uni<Void> sendTreeCategory(WebSocketConnection connection, List<TreeEntity> treeEntities) {
|
public static void sendTreeCategory(WebSocketConnection connection, List<TreeEntity> treeEntities) {
|
||||||
return CompetitionWS.sendNotifyToOtherEditor(connection, "sendTreeCategory", treeEntities);
|
CompetitionWS.sendNotifyToOtherEditor(connection, "sendTreeCategory", treeEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uni<?> sendDelCategory(WebSocketConnection connection, Long id) {
|
public static void sendDelCategory(WebSocketConnection connection, Long id) {
|
||||||
return CompetitionWS.sendNotifyToOtherEditor(connection, "sendDelCategory", id);
|
CompetitionWS.sendNotifyToOtherEditor(connection, "sendDelCategory", id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,29 +4,28 @@ import fr.titionfire.ffsaf.domain.entity.MatchEntity;
|
|||||||
import fr.titionfire.ffsaf.ws.CompetitionWS;
|
import fr.titionfire.ffsaf.ws.CompetitionWS;
|
||||||
import fr.titionfire.ffsaf.ws.recv.RMatch;
|
import fr.titionfire.ffsaf.ws.recv.RMatch;
|
||||||
import io.quarkus.websockets.next.WebSocketConnection;
|
import io.quarkus.websockets.next.WebSocketConnection;
|
||||||
import io.smallrye.mutiny.Uni;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class SSMatch {
|
public class SSMatch {
|
||||||
|
|
||||||
public static Uni<Void> sendMatch(WebSocketConnection connection, MatchEntity matchEntity) {
|
public static void sendMatch(WebSocketConnection connection, MatchEntity matchEntity) {
|
||||||
return SSMatch.sendMatch(connection, List.of(matchEntity));
|
SSMatch.sendMatch(connection, List.of(matchEntity));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uni<Void> sendMatch(WebSocketConnection connection, List<MatchEntity> matchEntities) {
|
public static void sendMatch(WebSocketConnection connection, List<MatchEntity> matchEntities) {
|
||||||
return CompetitionWS.sendNotifyToOtherEditor(connection, "sendMatch", matchEntities);
|
CompetitionWS.sendNotifyToOtherEditor(connection, "sendMatch", matchEntities);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uni<Void> sendMatchOrder(WebSocketConnection connection, RMatch.MatchOrder matchOrder) {
|
public static void sendMatchOrder(WebSocketConnection connection, RMatch.MatchOrder matchOrder) {
|
||||||
return CompetitionWS.sendNotifyToOtherEditor(connection, "sendMatchOrder", matchOrder);
|
CompetitionWS.sendNotifyToOtherEditor(connection, "sendMatchOrder", matchOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uni<Void> sendDeleteMatch(WebSocketConnection connection, Long l) {
|
public static void sendDeleteMatch(WebSocketConnection connection, Long l) {
|
||||||
return SSMatch.sendDeleteMatch(connection, List.of(l));
|
SSMatch.sendDeleteMatch(connection, List.of(l));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Uni<Void> sendDeleteMatch(WebSocketConnection connection, List<Long> longs) {
|
public static void sendDeleteMatch(WebSocketConnection connection, List<Long> longs) {
|
||||||
return CompetitionWS.sendNotifyToOtherEditor(connection, "sendDeleteMatch", longs);
|
CompetitionWS.sendNotifyToOtherEditor(connection, "sendDeleteMatch", longs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/main/java/fr/titionfire/ffsaf/ws/send/SSRegister.java
Normal file
16
src/main/java/fr/titionfire/ffsaf/ws/send/SSRegister.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package fr.titionfire.ffsaf.ws.send;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.domain.entity.CombEntity;
|
||||||
|
import fr.titionfire.ffsaf.ws.CompetitionWS;
|
||||||
|
import io.quarkus.websockets.next.WebSocketConnection;
|
||||||
|
|
||||||
|
public class SSRegister {
|
||||||
|
|
||||||
|
public static void sendRegister(WebSocketConnection connection, CombEntity combEntity) {
|
||||||
|
CompetitionWS.sendNotifyToOtherEditor(connection, "sendRegister", combEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendRegisterRemove(WebSocketConnection connection, Long combId) {
|
||||||
|
CompetitionWS.sendNotifyToOtherEditor(connection, "sendRegisterRemove", combId);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/main/java/fr/titionfire/ffsaf/ws/send/SSState.java
Normal file
19
src/main/java/fr/titionfire/ffsaf/ws/send/SSState.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package fr.titionfire.ffsaf.ws.send;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.ws.CompetitionWS;
|
||||||
|
import fr.titionfire.ffsaf.ws.recv.RState;
|
||||||
|
import io.quarkus.websockets.next.WebSocketConnection;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class SSState {
|
||||||
|
|
||||||
|
public static void sendStateFull(WebSocketConnection connection, RState.TableState state) {
|
||||||
|
CompetitionWS.sendNotifyState(connection, "sendStateFull", state);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void sendRmStateFull(WebSocketConnection connection, UUID id) {
|
||||||
|
CompetitionWS.sendNotifyState(connection, "rmStateFull", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,6 +8,7 @@ quarkus.hibernate-orm.database.generation=update
|
|||||||
quarkus.hibernate-orm.physical-naming-strategy=fr.titionfire.ffsaf.data.SafcaNamingStrategy
|
quarkus.hibernate-orm.physical-naming-strategy=fr.titionfire.ffsaf.data.SafcaNamingStrategy
|
||||||
|
|
||||||
quarkus.hibernate-orm.dialect=fr.titionfire.ffsaf.data.CustomPostgreSQLDialect
|
quarkus.hibernate-orm.dialect=fr.titionfire.ffsaf.data.CustomPostgreSQLDialect
|
||||||
|
quarkus.datasource.jdbc.reactive.max-size=40
|
||||||
|
|
||||||
quarkus.http.cors.enabled=true
|
quarkus.http.cors.enabled=true
|
||||||
quarkus.quartz.start-mode=forced
|
quarkus.quartz.start-mode=forced
|
||||||
@@ -67,7 +68,7 @@ quarkus.http.auth.permission.public.policy=permit
|
|||||||
quarkus.keycloak.admin-client.server-url=https://auth.safca.fr
|
quarkus.keycloak.admin-client.server-url=https://auth.safca.fr
|
||||||
|
|
||||||
|
|
||||||
quarkus.native.resources.includes=asset/**
|
quarkus.native.resources.includes=asset/**,lang/**
|
||||||
|
|
||||||
# HelloAsso Connector
|
# HelloAsso Connector
|
||||||
helloasso.api=https://api.helloasso.com
|
helloasso.api=https://api.helloasso.com
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
filtre.all=--tout--
|
|
||||||
no.licence=Non licenci\u00E9
|
|
||||||
|
|
||||||
|
|
||||||
# Categories
|
|
||||||
Cat.SUPER_MINI=Super Mini
|
|
||||||
Cat.MINI_POUSSIN=Mini Poussin
|
|
||||||
Cat.POUSSIN= Poussin
|
|
||||||
Cat.BENJAMIN=Benjamin
|
|
||||||
Cat.MINIME=Minime
|
|
||||||
Cat.CADET=Cadet
|
|
||||||
Cat.JUNIOR=Junior
|
|
||||||
Cat.SENIOR1=Senior 1
|
|
||||||
Cat.SENIOR2=Senior 2
|
|
||||||
Cat.VETERAN1=V\u00E9t\u00E9ran 1
|
|
||||||
Cat.VETERAN2=V\u00E9t\u00E9ran 2
|
|
||||||
94
src/main/resources/lang/messages_en.properties
Normal file
94
src/main/resources/lang/messages_en.properties
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
filtre.all=--all--
|
||||||
|
no.licence=Not licensed
|
||||||
|
Cat.SUPER_MINI=Super Mini
|
||||||
|
Cat.MINI_POUSSIN=Mini Chick
|
||||||
|
Cat.POUSSIN=Chick
|
||||||
|
Cat.BENJAMIN=Benjamin
|
||||||
|
Cat.MINIME=Minime
|
||||||
|
Cat.CADET=Cadet
|
||||||
|
Cat.JUNIOR=Junior
|
||||||
|
Cat.SENIOR1=Senior 1
|
||||||
|
Cat.SENIOR2=Senior 2
|
||||||
|
Cat.VETERAN1=Veteran 1
|
||||||
|
Cat.VETERAN2=Veteran 2
|
||||||
|
access.denied=Access denied
|
||||||
|
club.not.found=Club not found
|
||||||
|
combattant.non.inscrit=Fighter not registered
|
||||||
|
comb.not.found=Fighter not found
|
||||||
|
matche.non.trouver=Match not found
|
||||||
|
permission.denied=Permission denied
|
||||||
|
categorie.non.trouver=Category not found
|
||||||
|
|
||||||
|
RoleAsso.MEMBRE=Member
|
||||||
|
RoleAsso.PRESIDENT=President
|
||||||
|
RoleAsso.VPRESIDENT=Vice-President
|
||||||
|
RoleAsso.SECRETAIRE=Secretary
|
||||||
|
RoleAsso.VSECRETAIRE=Vice-Secretary
|
||||||
|
RoleAsso.TRESORIER=Treasurer
|
||||||
|
RoleAsso.VTRESORIER=Vice-Treasurer
|
||||||
|
RoleAsso.MEMBREBUREAU=Board Member
|
||||||
|
|
||||||
|
sans.club=No club
|
||||||
|
categorie.inconnue=Unknown category
|
||||||
|
GradeArbitrage.NA=N/A
|
||||||
|
GradeArbitrage.ASSESSEUR=Assessor
|
||||||
|
GradeArbitrage.ARBITRE=Referee
|
||||||
|
Genre.Homme=Male
|
||||||
|
Genre.Femme=Female
|
||||||
|
Genre.NA=Not defined
|
||||||
|
|
||||||
|
Contact.COURRIEL=Email
|
||||||
|
Contact.TELEPHONE=Phone
|
||||||
|
Contact.SITE=Website
|
||||||
|
Contact.FACEBOOK=Facebook
|
||||||
|
Contact.INSTAGRAM=Instagram
|
||||||
|
Contact.AUTRE=Other
|
||||||
|
|
||||||
|
service.momentanement.indisponible=Service temporarily unavailable
|
||||||
|
asso.introuvable=Association not found
|
||||||
|
erreur.lors.calcul.du.trie=Error during sorting calculation
|
||||||
|
page.out.of.range=Page out of range
|
||||||
|
le.membre.appartient.pas.a.votre.club=Member no. %d does not belong to your club
|
||||||
|
email.deja.utilise.par=Email '%s' already used by %s %s
|
||||||
|
try.edit.licence=To register a new member, please leave the license field blank. (Unauthorized attempt to change the name on license %d for %s %s)
|
||||||
|
email.deja.utilise=Email already in use
|
||||||
|
regiter.new.membre=To register a new member, please use the dedicated button.
|
||||||
|
permission.insuffisante=Insufficient permission
|
||||||
|
membre.deja.existent=Member already exists
|
||||||
|
membre.rm.err1=Cannot delete a member who already has a license number
|
||||||
|
membre.rm.err2=Cannot delete a member with licenses
|
||||||
|
pas.de.licence.pour.la.saison.en.cours=No license for the current season
|
||||||
|
club.non.trouve=Club not found
|
||||||
|
pas.d.affiliation.pour.la.saison.en.cours=No affiliation for the current season
|
||||||
|
erreur.lors.de.la.selection.des.membres=Error during member selection
|
||||||
|
licence.rm.err1=Cannot delete a license for which payment is in progress
|
||||||
|
licence.deja.demandee=License already requested
|
||||||
|
impossible.de.supprimer.une.licence.deja.validee=Cannot delete an already validated license
|
||||||
|
impossible.de.supprimer.une.licence.deja.payee=Cannot delete an already paid license
|
||||||
|
vous.ne.pouvez.pas.creer.de.competition=You cannot create a competition
|
||||||
|
user.not.found=User %s not found
|
||||||
|
inscription.fermee=Registration closed
|
||||||
|
insc.err1=You do not have the right to register this member (by decision of the competition administrator)
|
||||||
|
insc.err2=You do not have the right to register (by decision of the competition administrator)
|
||||||
|
insc.err3=Modification blocked by the competition administrator
|
||||||
|
licence.non.trouve=License %s not found
|
||||||
|
nom.et.prenom.requis=Last name and first name required
|
||||||
|
combattant.non.trouve=Fighter %s %s not found
|
||||||
|
le.membre.n.existe.pas=Member %d does not exist
|
||||||
|
competition.is.not.internal=Competition is not INTERNAL
|
||||||
|
erreur.de.format.des.contacts=Contact format error
|
||||||
|
competition.not.found=Competition not found
|
||||||
|
saison.non.valid=Invalid season
|
||||||
|
demande.d.affiliation.deja.existante=Affiliation request already exists
|
||||||
|
affiliation.deja.existante=Affiliation already exists
|
||||||
|
licence.membre.n.1.inconnue=License member no. 1 unknown
|
||||||
|
licence.membre.n.2.inconnue=License member no. 2 unknown
|
||||||
|
licence.membre.n.3.inconnue=License member no. 3 unknown
|
||||||
|
demande.d.affiliation.non.trouve=Affiliation request not found
|
||||||
|
carton.non.trouver=Card not found
|
||||||
|
card.cannot.be.added=Unable to add the card
|
||||||
|
configuration.non.supportee=Unsupported configuration
|
||||||
|
err.match.termine=Error, a placement match has already been played
|
||||||
|
podium.source.classement=Ranking
|
||||||
|
podium.source.tree=Tournaments
|
||||||
|
podium.source.poule=Pool
|
||||||
90
src/main/resources/lang/messages_fr.properties
Normal file
90
src/main/resources/lang/messages_fr.properties
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
filtre.all=--Tous--
|
||||||
|
no.licence=Non licencié
|
||||||
|
Cat.SUPER_MINI=Super Mini
|
||||||
|
Cat.MINI_POUSSIN=Mini-Poussin
|
||||||
|
Cat.POUSSIN=Poussin
|
||||||
|
Cat.BENJAMIN=Benjamin
|
||||||
|
Cat.MINIME=Minime
|
||||||
|
Cat.CADET=Cadet
|
||||||
|
Cat.JUNIOR=Junior
|
||||||
|
Cat.SENIOR1=Senior 1
|
||||||
|
Cat.SENIOR2=Senior 2
|
||||||
|
Cat.VETERAN1=Vétéran 1
|
||||||
|
Cat.VETERAN2=Vétéran 2
|
||||||
|
access.denied=Accès refusé
|
||||||
|
club.not.found=Club introuvable
|
||||||
|
combattant.non.inscrit=Combattant non inscrit
|
||||||
|
comb.not.found=Combat introuvable
|
||||||
|
matche.non.trouver=Match introuvable
|
||||||
|
permission.denied=Permission refusée
|
||||||
|
categorie.non.trouver=Catégorie introuvable
|
||||||
|
RoleAsso.MEMBRE=Membre
|
||||||
|
RoleAsso.PRESIDENT=Président
|
||||||
|
RoleAsso.VPRESIDENT=Vice-Président
|
||||||
|
RoleAsso.SECRETAIRE=Secrétaire
|
||||||
|
RoleAsso.VSECRETAIRE=Vice-Secrétaire
|
||||||
|
RoleAsso.TRESORIER=Trésorier
|
||||||
|
RoleAsso.VTRESORIER=Vice-Trésorier
|
||||||
|
RoleAsso.MEMBREBUREAU=Membre bureau
|
||||||
|
sans.club=Sans club
|
||||||
|
categorie.inconnue=catégorie inconnue
|
||||||
|
GradeArbitrage.NA=N/A
|
||||||
|
GradeArbitrage.ASSESSEUR=Assesseur
|
||||||
|
GradeArbitrage.ARBITRE=Arbitre
|
||||||
|
Genre.Homme=Homme
|
||||||
|
Genre.Femme=Femme
|
||||||
|
Genre.NA=Non défini
|
||||||
|
Contact.COURRIEL=Courriel
|
||||||
|
Contact.TELEPHONE=Téléphone
|
||||||
|
Contact.SITE=Site web
|
||||||
|
Contact.FACEBOOK=Facebook
|
||||||
|
Contact.INSTAGRAM=Instagram
|
||||||
|
Contact.AUTRE=Autre
|
||||||
|
service.momentanement.indisponible=Service momentanément indisponible
|
||||||
|
asso.introuvable=Association introuvable
|
||||||
|
erreur.lors.calcul.du.trie=Erreur lors du calcul du tri
|
||||||
|
page.out.of.range=Page out of range
|
||||||
|
le.membre.appartient.pas.a.votre.club=Le membre n°%d n'appartient pas à votre club
|
||||||
|
email.deja.utilise.par=L'adresse e-mail '%s' est déjà utilisée par %s %s
|
||||||
|
try.edit.licence=Pour enregistrer un nouveau membre, veuillez laisser le champ licence vide. (Tentative de modification non autorisée du nom sur la licence %d pour %s %s)
|
||||||
|
email.deja.utilise=Adresse e-mail déjà utilisée
|
||||||
|
regiter.new.membre=Pour enregistrer un nouveau membre, veuillez utiliser le bouton prévu à cet effet.
|
||||||
|
permission.insuffisante=Permissions insuffisantes
|
||||||
|
membre.deja.existent=Membre déjà existant
|
||||||
|
membre.rm.err1=Impossible de supprimer un membre qui possède déjà un numéro de licence
|
||||||
|
membre.rm.err2=Impossible de supprimer un membre ayant des licences actives
|
||||||
|
pas.de.licence.pour.la.saison.en.cours=Aucune licence pour la saison en cours
|
||||||
|
club.non.trouve=Club introuvable
|
||||||
|
pas.d.affiliation.pour.la.saison.en.cours=Aucune affiliation pour la saison en cours
|
||||||
|
erreur.lors.de.la.selection.des.membres=Erreur lors de la sélection des membres
|
||||||
|
licence.rm.err1=Impossible de supprimer une licence pour laquelle un paiement est en cours
|
||||||
|
licence.deja.demandee=Licence déjà demandée
|
||||||
|
impossible.de.supprimer.une.licence.deja.validee=Impossible de supprimer une licence déjà validée
|
||||||
|
impossible.de.supprimer.une.licence.deja.payee=Impossible de supprimer une licence déjà payée
|
||||||
|
vous.ne.pouvez.pas.creer.de.competition=Vous n'êtes pas autorisé à créer une compétition
|
||||||
|
user.not.found=Utilisateur %s introuvable
|
||||||
|
inscription.fermee=Inscription fermée
|
||||||
|
insc.err1=Vous n'êtes pas autorisé à inscrire ce membre (décision de l'administrateur de la compétition)
|
||||||
|
insc.err2=Vous n'êtes pas autorisé à vous inscrire (décision de l'administrateur de la compétition)
|
||||||
|
insc.err3=Modification bloquée par l'administrateur de la compétition
|
||||||
|
licence.non.trouve=Licence %s introuvable
|
||||||
|
nom.et.prenom.requis=Nom et prénom obligatoires
|
||||||
|
combattant.non.trouve=Combattant %s %s introuvable
|
||||||
|
le.membre.n.existe.pas=Le membre n°%d n'existe pas
|
||||||
|
competition.is.not.internal=Competition is not INTERNAL
|
||||||
|
erreur.de.format.des.contacts=Format des contacts invalide
|
||||||
|
competition.not.found=Compétition introuvable
|
||||||
|
saison.non.valid=Saison invalide
|
||||||
|
demande.d.affiliation.deja.existante=Une demande d'affiliation existe déjà
|
||||||
|
affiliation.deja.existante=Affiliation déjà existante
|
||||||
|
licence.membre.n.1.inconnue=Licence du membre n°1 inconnue
|
||||||
|
licence.membre.n.2.inconnue=Licence du membre n°2 inconnue
|
||||||
|
licence.membre.n.3.inconnue=Licence du membre n°3 inconnue
|
||||||
|
demande.d.affiliation.non.trouve=Demande d'affiliation introuvable
|
||||||
|
carton.non.trouver=Carton introuvable
|
||||||
|
card.cannot.be.added=Impossible d'ajouter le carton
|
||||||
|
configuration.non.supportee=Configuration non supportée
|
||||||
|
err.match.termine=Erreur, un match de classement a déjà été joué
|
||||||
|
podium.source.classement=Classement
|
||||||
|
podium.source.tree=Tournois
|
||||||
|
podium.source.poule=Poule
|
||||||
5161
src/main/webapp/package-lock.json
generated
5161
src/main/webapp/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -13,36 +13,42 @@
|
|||||||
"@dnd-kit/core": "^6.3.1",
|
"@dnd-kit/core": "^6.3.1",
|
||||||
"@dnd-kit/sortable": "^10.0.0",
|
"@dnd-kit/sortable": "^10.0.0",
|
||||||
"@dnd-kit/utilities": "^3.2.2",
|
"@dnd-kit/utilities": "^3.2.2",
|
||||||
"@fortawesome/fontawesome-svg-core": "^6.5.1",
|
"@fortawesome/fontawesome-svg-core": "^7.3.1",
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.5.1",
|
"@fortawesome/free-brands-svg-icons": "^7.3.1",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.5.1",
|
"@fortawesome/free-regular-svg-icons": "^7.3.1",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.5.1",
|
"@fortawesome/free-solid-svg-icons": "^7.3.1",
|
||||||
"@fortawesome/react-fontawesome": "^0.2.0",
|
"@fortawesome/react-fontawesome": "^3.5.0",
|
||||||
"axios": "^1.6.5",
|
"axios": "1.18.0",
|
||||||
"browser-image-compression": "^2.0.2",
|
"browser-image-compression": "^2.0.2",
|
||||||
|
"i18next": "^26.3.6",
|
||||||
|
"i18next-browser-languagedetector": "^8.2.1",
|
||||||
|
"i18next-http-backend": "^4.0.1",
|
||||||
|
"jspdf": "4.2.1",
|
||||||
|
"jspdf-autotable": "^5.0.8",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
"leaflet": "^1.9.4",
|
"leaflet": "^1.9.4",
|
||||||
"obs-websocket-js": "^5.0.7",
|
"obs-websocket-js": "^5.0.8",
|
||||||
"proj4": "^2.11.0",
|
"proj4": "^2.21.0",
|
||||||
"react": "^18.2.0",
|
"react": "^19.2.8",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^19.2.8",
|
||||||
"react-is": "^19.0.0",
|
"react-i18next": "^17.0.11",
|
||||||
"react-leaflet": "^4.2.1",
|
"react-is": "^19.2.8",
|
||||||
"react-loader-spinner": "^6.1.6",
|
"react-leaflet": "^5.0.0",
|
||||||
"react-router-dom": "^6.21.2",
|
"react-loader-spinner": "^8.0.2",
|
||||||
"react-toastify": "^10.0.4",
|
"react-router-dom": "^7.18.2",
|
||||||
"recharts": "^2.15.1",
|
"react-toastify": "^11.1.0",
|
||||||
"xlsx": "^0.18.5",
|
"recharts": "^3.10.1",
|
||||||
|
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
|
||||||
"xlsx-js-style": "^1.2.0"
|
"xlsx-js-style": "^1.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/react": "^18.2.43",
|
"@types/react": "^19.2.18",
|
||||||
"@types/react-dom": "^18.2.17",
|
"@types/react-dom": "^19.2.4",
|
||||||
"@vitejs/plugin-react": "^4.2.1",
|
"@vitejs/plugin-react": "^6.0.5",
|
||||||
"eslint": "^8.55.0",
|
"eslint": "^9.39.5",
|
||||||
"eslint-plugin-react": "^7.33.2",
|
"eslint-plugin-react": "^7.37.5",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^7.1.1",
|
||||||
"eslint-plugin-react-refresh": "^0.4.5",
|
"eslint-plugin-react-refresh": "^0.5.3",
|
||||||
"vite": "^5.0.8"
|
"vite": "8.0.16"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
|
import i18next from 'https://cdn.jsdelivr.net/npm/i18next@25.7.4/+esm';
|
||||||
|
import i18nextHttpBackend from 'https://cdn.jsdelivr.net/npm/i18next-http-backend@3.0.2/+esm'
|
||||||
|
import i18nextBrowserLanguagedetector from 'https://cdn.jsdelivr.net/npm/i18next-browser-languagedetector@8.2.0/+esm'
|
||||||
|
|
||||||
let apiUrlRoot = "";
|
let apiUrlRoot = "";
|
||||||
const rootDiv = document.getElementById("safca_api_data");
|
const rootDiv = document.getElementById("safca_api_data");
|
||||||
|
|
||||||
const header = `<h4>Résultat de la compétition :</h4>`
|
|
||||||
const backButton = `<a onclick="setSubPage('home')" href="javascript:void(0);">Retour</a>`
|
|
||||||
const cupImg = `<img decoding="async" loading="lazy" width="16" height="16" class="wp-image-1635"
|
const cupImg = `<img decoding="async" loading="lazy" width="16" height="16" class="wp-image-1635"
|
||||||
style="width: 16px;" src="https://intra.ffsaf.fr/img/171891.png"
|
style="width: 16px;" src="https://intra.ffsaf.fr/img/171891.png"
|
||||||
alt="">`
|
alt="">`
|
||||||
|
const cupImg2 = `<img decoding="async" loading="lazy" width="16" height="16" class="wp-image-1635"
|
||||||
|
style="width: 16px;" src="https://intra.ffsaf.fr/img/171892.png"
|
||||||
|
alt="">`
|
||||||
|
|
||||||
|
|
||||||
const voidFunction = () => {
|
const voidFunction = () => {
|
||||||
}
|
}
|
||||||
@@ -13,7 +18,7 @@ let lastRf = 0;
|
|||||||
let rfFonction = voidFunction;
|
let rfFonction = voidFunction;
|
||||||
|
|
||||||
setInterval(() => {
|
setInterval(() => {
|
||||||
rfFonction();
|
// rfFonction();
|
||||||
}, 15000);
|
}, 15000);
|
||||||
|
|
||||||
function setSubPage(name) {
|
function setSubPage(name) {
|
||||||
@@ -34,6 +39,9 @@ function setSubPage(name) {
|
|||||||
case 'club':
|
case 'club':
|
||||||
clubPage(location);
|
clubPage(location);
|
||||||
break;
|
break;
|
||||||
|
case 'clubRank':
|
||||||
|
clubRankPage();
|
||||||
|
break;
|
||||||
case 'all':
|
case 'all':
|
||||||
combsPage();
|
combsPage();
|
||||||
break;
|
break;
|
||||||
@@ -41,18 +49,25 @@ function setSubPage(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function homePage() {
|
function homePage() {
|
||||||
rootDiv.innerHTML = header;
|
rootDiv.innerHTML = `<h4>${i18next.t('résultatDeLaCompétition')} :</h4>`;
|
||||||
|
|
||||||
let content = document.createElement('div');
|
let content = document.createElement('div');
|
||||||
content.innerHTML = `
|
content.innerHTML = `
|
||||||
<ul>
|
<ul>
|
||||||
<li><a onclick="setSubPage('poule')" href="javascript:void(0);">Par poule</a></li>
|
<li><a id="pouleLink" href="javascript:void(0);">${i18next.t('parCatégorie')}</a></li>
|
||||||
<li><a onclick="setSubPage('comb')" href="javascript:void(0);">Par combattant</a></li>
|
<li><a id="combLink" href="javascript:void(0);">${i18next.t('parCombattant')}</a></li>
|
||||||
<li><a onclick="setSubPage('club')" href="javascript:void(0);">Par club</a></li>
|
<li><a id="clubLink" href="javascript:void(0);">${i18next.t('parClub')}</a></li>
|
||||||
<li><a onclick="setSubPage('all')" href="javascript:void(0);">Tous les combattants</a></li>
|
<li><a id="clubClassement" href="javascript:void(0);">${i18next.t('classementClub')}</a></li>
|
||||||
|
<li><a id="allLink" href="javascript:void(0);">${i18next.t('tousLesCombattants')}</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
`
|
`
|
||||||
rootDiv.append(content)
|
rootDiv.append(content)
|
||||||
|
|
||||||
|
document.getElementById('pouleLink').addEventListener('click', () => setSubPage('poule'));
|
||||||
|
document.getElementById('combLink').addEventListener('click', () => setSubPage('comb'));
|
||||||
|
document.getElementById('clubLink').addEventListener('click', () => setSubPage('club'));
|
||||||
|
document.getElementById('clubClassement').addEventListener('click', () => setSubPage('clubRank'));
|
||||||
|
document.getElementById('allLink').addEventListener('click', () => setSubPage('all'));
|
||||||
}
|
}
|
||||||
|
|
||||||
let loadingAnimationStep = 0;
|
let loadingAnimationStep = 0;
|
||||||
@@ -63,7 +78,7 @@ function startLoading(root) {
|
|||||||
element.id = id;
|
element.id = id;
|
||||||
|
|
||||||
const anim = setInterval(() => {
|
const anim = setInterval(() => {
|
||||||
let str = "Chargement";
|
let str = i18next.t('chargement');
|
||||||
for (let i = 0; i < loadingAnimationStep; i++) {
|
for (let i = 0; i < loadingAnimationStep; i++) {
|
||||||
str += ".";
|
str += ".";
|
||||||
}
|
}
|
||||||
@@ -80,23 +95,27 @@ function stopLoading(loading) {
|
|||||||
loading['root'].removeChild(loading['element']);
|
loading['root'].removeChild(loading['element']);
|
||||||
}
|
}
|
||||||
|
|
||||||
function scoreToString(score) {
|
function scorePrint(s1) {
|
||||||
const scorePrint = (s1) => {
|
switch (s1) {
|
||||||
switch (s1) {
|
case -997:
|
||||||
case -997:
|
return i18next.t('disc.');
|
||||||
return "disc.";
|
case -998:
|
||||||
case -998:
|
return i18next.t('abs.');
|
||||||
return "abs.";
|
case -999:
|
||||||
case -999:
|
return i18next.t('for.');
|
||||||
return "for.";
|
case -1000:
|
||||||
case -1000:
|
return "";
|
||||||
return "";
|
default:
|
||||||
default:
|
return String(s1);
|
||||||
return String(s1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return score.map(o => scorePrint(o.at(0)) + "-" + scorePrint(o.at(1))).join(" | ");
|
function scoreToString(score) {
|
||||||
|
if (score.length === 0)
|
||||||
|
return "";
|
||||||
|
if (score.at(0) instanceof Array)
|
||||||
|
return score.map(s => scorePrint(s.at(0)) + "-" + scorePrint(s.at(1))).join(" | ");
|
||||||
|
return score.map(o => scorePrint(o.s1) + "-" + scorePrint(o.s2)).join(" | ");
|
||||||
}
|
}
|
||||||
|
|
||||||
function dateToString(date) {
|
function dateToString(date) {
|
||||||
@@ -111,16 +130,16 @@ function dateToString(date) {
|
|||||||
|
|
||||||
let d = Math.floor((current - date_2) / (1000 * 60 * 60 * 24));
|
let d = Math.floor((current - date_2) / (1000 * 60 * 60 * 24));
|
||||||
if (d === 0)
|
if (d === 0)
|
||||||
return "Aujourd'hui à " + date_.toLocaleTimeString([], {hour: "2-digit", minute: "2-digit"});
|
return i18next.t('aujourdhuià', {time: date_.toLocaleTimeString([], {hour: "2-digit", minute: "2-digit"})});
|
||||||
else if (d === 1)
|
else if (d === 1)
|
||||||
return "Hier à " + date_.toLocaleTimeString([], {hour: "2-digit", minute: "2-digit"});
|
return i18next.t('hierà', {time: date_.toLocaleTimeString([], {hour: "2-digit", minute: "2-digit"})});
|
||||||
else if (d === 2)
|
else if (d === 2)
|
||||||
return "Avant-hier à " + date_.toLocaleTimeString([], {hour: "2-digit", minute: "2-digit"});
|
return i18next.t('avanthierà', {time: date_.toLocaleTimeString([], {hour: "2-digit", minute: "2-digit"})});
|
||||||
else
|
else
|
||||||
return date_.toLocaleDateString();
|
return date_.toLocaleDateString();
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildPouleMenu(isPoule, change_view) {
|
function buildPouleMenu(isPoule, change_view, isClassement = false) {
|
||||||
const menuDiv = document.createElement('div');
|
const menuDiv = document.createElement('div');
|
||||||
menuDiv.id = 'menu';
|
menuDiv.id = 'menu';
|
||||||
menuDiv.style.borderBottom = '1px solid #9EA0A1';
|
menuDiv.style.borderBottom = '1px solid #9EA0A1';
|
||||||
@@ -175,11 +194,11 @@ function buildPouleMenu(isPoule, change_view) {
|
|||||||
return li;
|
return li;
|
||||||
}
|
}
|
||||||
|
|
||||||
const li1 = createTab('Poule', isPoule, function () {
|
const li1 = createTab(i18next.t('poule'), isPoule, function () {
|
||||||
change_view(true);
|
change_view(true);
|
||||||
});
|
});
|
||||||
ul.appendChild(li1);
|
ul.appendChild(li1);
|
||||||
const li2 = createTab('Tournois', !isPoule, function () {
|
const li2 = createTab(isClassement ? i18next.t('classement') : i18next.t('tournois'), !isPoule, function () {
|
||||||
change_view(false);
|
change_view(false);
|
||||||
});
|
});
|
||||||
ul.appendChild(li2);
|
ul.appendChild(li2);
|
||||||
@@ -195,23 +214,23 @@ function buildMatchArray(matchs) {
|
|||||||
<figure class="wp-block-table is-style-stripes" style="font-size: 16px">
|
<figure class="wp-block-table is-style-stripes" style="font-size: 16px">
|
||||||
<table style="width: 800px;overflow: auto"><thead>
|
<table style="width: 800px;overflow: auto"><thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="has-text-align-center" data-align="center">Rouge</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('rouge')}</th>
|
||||||
<th class="has-text-align-center" data-align="center"></th>
|
<th class="has-text-align-center" data-align="center"></th>
|
||||||
<th class="has-text-align-center" data-align="center">Scores</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('scores')}</th>
|
||||||
<th class="has-text-align-center" data-align="center"></th>
|
<th class="has-text-align-center" data-align="center"></th>
|
||||||
<th class="has-text-align-center" data-align="center">Bleu</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('bleu')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Date</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('date')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead><tbody>`
|
</thead><tbody>`
|
||||||
for (const match of matchs) {
|
for (const match of matchs) {
|
||||||
arrayContent += `
|
arrayContent += `
|
||||||
<tr>
|
<tr>
|
||||||
<td class="has-text-align-right" data-align="right">${match.red}</td>
|
<td class="has-text-align-right" data-align="right">${match.red}</td>
|
||||||
<td class="has-text-align-center" data-align="center">${match.red_w ? cupImg : ""}</td>
|
<td class="has-text-align-center" data-align="center">${match.red_w ? cupImg : (match.eq ? cupImg2 : "")}</td>
|
||||||
<td class="has-text-align-center" data-align="center">${scoreToString(match.score)}</td>
|
<td class="has-text-align-center" data-align="center">${scoreToString(match.score)}</td>
|
||||||
<td class="has-text-align-center" data-align="center">${match.blue_w ? cupImg : ""}</td>
|
<td class="has-text-align-center" data-align="center">${match.blue_w ? cupImg : (match.eq ? cupImg2 : "")}</td>
|
||||||
<td class="has-text-align-left" data-align="left">${match.blue}</td>
|
<td class="has-text-align-left" data-align="left">${match.blue}</td>
|
||||||
<td class="has-text-align-center" data-align="center">${dateToString((match.red_w || match.blue_w) ? match.date : null)}</td>
|
<td class="has-text-align-center" data-align="center">${dateToString((match.end) ? match.date : null)}</td>
|
||||||
</tr>`
|
</tr>`
|
||||||
}
|
}
|
||||||
arrayContent += `</tbody></table></figure>`
|
arrayContent += `</tbody></table></figure>`
|
||||||
@@ -225,12 +244,13 @@ function buildRankArray(rankArray) {
|
|||||||
<table style="width: 600px;overflow: auto">
|
<table style="width: 600px;overflow: auto">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="has-text-align-center" data-align="center">Place</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('place')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Nom</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('nom')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Victoire</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('score')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Ratio</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('victoire')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Points marqués</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('ratio')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Points reçus</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('pointsMarqués')}</th>
|
||||||
|
<th class="has-text-align-center" data-align="center">${i18next.t('pointsReçus')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead><tbody>`
|
</thead><tbody>`
|
||||||
for (const row of rankArray) {
|
for (const row of rankArray) {
|
||||||
@@ -238,6 +258,7 @@ function buildRankArray(rankArray) {
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="has-text-align-center" data-align="center">${row.rank}</td>
|
<td class="has-text-align-center" data-align="center">${row.rank}</td>
|
||||||
<td class="has-text-align-left" data-align="left">${row.name}</td>
|
<td class="has-text-align-left" data-align="left">${row.name}</td>
|
||||||
|
<td class="has-text-align-center" data-align="center">${row.score}</td>
|
||||||
<td class="has-text-align-center" data-align="center">${row.win}</td>
|
<td class="has-text-align-center" data-align="center">${row.win}</td>
|
||||||
<td class="has-text-align-center" data-align="center">${row.pointRate.toFixed(3)}</td>
|
<td class="has-text-align-center" data-align="center">${row.pointRate.toFixed(3)}</td>
|
||||||
<td class="has-text-align-center" data-align="center">${row.pointMake}</td>
|
<td class="has-text-align-center" data-align="center">${row.pointMake}</td>
|
||||||
@@ -251,14 +272,45 @@ function buildRankArray(rankArray) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function buildTree(treeData) {
|
function buildTree(treeData) {
|
||||||
return drawGraph(initTree(treeData))
|
return drawGraph(initTree(treeData.filter(d => d.data.level >= 0)))
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildClassementArray(classement) {
|
||||||
|
const classement2 = classement.sort((a, b) => {
|
||||||
|
if (a.rank === b.rank)
|
||||||
|
return a.name.localeCompare(b.name);
|
||||||
|
return a.rank - b.rank;
|
||||||
|
})
|
||||||
|
|
||||||
|
const arrayDiv = document.createElement('div');
|
||||||
|
let arrayContent = `<figure class="wp-block-table is-style-stripes" style="font-size: 16px; margin-top: 2em">
|
||||||
|
<table style="width: 600px;overflow: auto">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th class="has-text-align-center" data-align="center">${i18next.t('place')}</th>
|
||||||
|
<th class="has-text-align-center" data-align="center">${i18next.t('nom')}</th>
|
||||||
|
</tr>
|
||||||
|
</thead><tbody>`
|
||||||
|
for (const row of classement2) {
|
||||||
|
arrayContent += `
|
||||||
|
<tr>
|
||||||
|
<td class="has-text-align-center" data-align="center">${row.rank}</td>
|
||||||
|
<td class="has-text-align-left" data-align="left">${row.name}</td>
|
||||||
|
</tr>`
|
||||||
|
|
||||||
|
}
|
||||||
|
arrayContent += `</tbody></table></figure>`
|
||||||
|
arrayDiv.innerHTML = arrayContent;
|
||||||
|
return arrayDiv;
|
||||||
}
|
}
|
||||||
|
|
||||||
function poulePage(location) {
|
function poulePage(location) {
|
||||||
rootDiv.innerHTML = header + backButton;
|
rootDiv.innerHTML = `<h4>${i18next.t('résultatDeLaCompétition')} :</h4><a id="homeLink" href="javascript:void(0);">${i18next.t('back')}</a>`;
|
||||||
|
document.getElementById('homeLink').addEventListener('click', () => setSubPage('home'));
|
||||||
|
|
||||||
const content = document.createElement('div');
|
const content = document.createElement('div');
|
||||||
content.style.marginTop = '1em';
|
content.style.marginTop = '1em';
|
||||||
content.innerHTML = '<h4>Recherche par poule</h4>';
|
content.innerHTML = `<h4>${i18next.t('rechercheParCatégorie')}</h4>`;
|
||||||
|
|
||||||
const dataContainer = document.createElement('div');
|
const dataContainer = document.createElement('div');
|
||||||
dataContainer.id = 'data-container';
|
dataContainer.id = 'data-container';
|
||||||
@@ -286,7 +338,7 @@ function poulePage(location) {
|
|||||||
for (const g in poule.matchs) {
|
for (const g in poule.matchs) {
|
||||||
if (Object.keys(poule.matchs).length > 1) {
|
if (Object.keys(poule.matchs).length > 1) {
|
||||||
const text = document.createElement('h4');
|
const text = document.createElement('h4');
|
||||||
text.textContent = `Groupe ${g}`;
|
text.textContent = `${i18next.t('poule')} ${g}`;
|
||||||
text.style.marginTop = '2em';
|
text.style.marginTop = '2em';
|
||||||
dataContainer.append(text);
|
dataContainer.append(text);
|
||||||
}
|
}
|
||||||
@@ -297,13 +349,13 @@ function poulePage(location) {
|
|||||||
dataContainer.append(buildTree(poule['trees']));
|
dataContainer.append(buildTree(poule['trees']));
|
||||||
} else {
|
} else {
|
||||||
const change_view = (isPoule) => {
|
const change_view = (isPoule) => {
|
||||||
dataContainer.replaceChildren(buildPouleMenu(isPoule, change_view));
|
dataContainer.replaceChildren(buildPouleMenu(isPoule, change_view, poule['treeIsClassement']));
|
||||||
|
|
||||||
if (isPoule) {
|
if (isPoule) {
|
||||||
for (const g in poule.matchs) {
|
for (const g in poule.matchs) {
|
||||||
if (Object.keys(poule.matchs).length > 1) {
|
if (Object.keys(poule.matchs).length > 1) {
|
||||||
const text = document.createElement('h4');
|
const text = document.createElement('h4');
|
||||||
text.textContent = `Groupe ${g}`;
|
text.textContent = `${i18next.t('poule')} ${g}`;
|
||||||
text.style.marginTop = '2em';
|
text.style.marginTop = '2em';
|
||||||
dataContainer.append(text);
|
dataContainer.append(text);
|
||||||
}
|
}
|
||||||
@@ -312,6 +364,22 @@ function poulePage(location) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dataContainer.append(buildTree(poule['trees']));
|
dataContainer.append(buildTree(poule['trees']));
|
||||||
|
if (poule['treeIsClassement'] && poule['trees'].some(d => d.data.level <= -10)) {
|
||||||
|
dataContainer.append(buildMatchArray(
|
||||||
|
poule['trees'].filter(d => d.data.level < 0).reverse().map(d => ({
|
||||||
|
red: d.data.c1FullName,
|
||||||
|
blue: d.data.c2FullName,
|
||||||
|
score: d.data.scores,
|
||||||
|
end: d.data.end,
|
||||||
|
red_w: d.data.win > 0,
|
||||||
|
blue_w: d.data.win < 0,
|
||||||
|
eq: d.data.win === 0,
|
||||||
|
date: d.data.date,
|
||||||
|
}))));
|
||||||
|
}
|
||||||
|
if (poule['treeIsClassement']){
|
||||||
|
dataContainer.append(buildClassementArray(poule['classement']));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
location[2] = isPoule ? 1 : 2;
|
location[2] = isPoule ? 1 : 2;
|
||||||
@@ -323,7 +391,7 @@ function poulePage(location) {
|
|||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
dataContainer.replaceChildren(new Text("Erreur de chargement de la poule"));
|
dataContainer.replaceChildren(new Text(i18next.t('erreurDeChargementDeLaPoule')));
|
||||||
})
|
})
|
||||||
.finally(() => stopLoading(loading));
|
.finally(() => stopLoading(loading));
|
||||||
}
|
}
|
||||||
@@ -334,8 +402,8 @@ function poulePage(location) {
|
|||||||
.then(poule => {
|
.then(poule => {
|
||||||
const select = document.createElement('select');
|
const select = document.createElement('select');
|
||||||
select.setAttribute('id', poule.id);
|
select.setAttribute('id', poule.id);
|
||||||
select.innerHTML = `<option value="0">--Sélectionner une poule--</option>`;
|
select.innerHTML = `<option value="0">${i18next.t('--sélectionnerUneCatégorie--')}</option>`;
|
||||||
for (const pouleKey of Object.keys(poule).sort()) {
|
for (const pouleKey of Object.keys(poule).sort((a, b) => a.toLocaleLowerCase().localeCompare(b.toLocaleLowerCase()))) {
|
||||||
select.innerHTML += `<option value="${poule[pouleKey]}">${pouleKey}</option>`;
|
select.innerHTML += `<option value="${poule[pouleKey]}">${pouleKey}</option>`;
|
||||||
}
|
}
|
||||||
select.addEventListener('change', e => {
|
select.addEventListener('change', e => {
|
||||||
@@ -356,7 +424,7 @@ function poulePage(location) {
|
|||||||
loadPoule();
|
loadPoule();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => rootDiv.append(new Text("Erreur de chargement des poules")))
|
.catch(() => rootDiv.append(new Text(i18next.t('erreurDeChargementDesCatégories'))))
|
||||||
.finally(() => stopLoading(loading));
|
.finally(() => stopLoading(loading));
|
||||||
|
|
||||||
rfFonction = () => {
|
rfFonction = () => {
|
||||||
@@ -372,28 +440,33 @@ function buildCombView(comb) {
|
|||||||
let arrayContent = `
|
let arrayContent = `
|
||||||
<h3>Info :</h3>
|
<h3>Info :</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Nom Prénom : ${comb.name}</li>
|
<li>${i18next.t('nomPrénom')} : ${comb.name}</li>
|
||||||
<li>Club : ${comb.club}</li>
|
<li>${i18next.t('club')} : ${comb.club}</li>
|
||||||
<li>Catégorie : ${comb.cat}</li>
|
<li>${i18next.t('catégorie')} : ${comb.cat}</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3>Statistique :</h3>
|
<h3>${i18next.t('statistique')} :</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Taux de victoire : ${comb.matchs.length === 0 ? "---" : (comb.totalWin / comb.matchs.length * 100).toFixed(0)}% (${comb.totalWin} sur ${comb.matchs.length})</li>
|
<li>${i18next.t('tauxDeVictoire2', {
|
||||||
<li>Points marqués : ${comb.pointMake}</li>
|
nb: comb.matchs.length === 0 ? "---" : (comb.totalWin / comb.matchs.filter(m => m.end).length * 100).toFixed(0),
|
||||||
<li>Points reçus : ${comb.pointTake}</li>
|
victoires: comb.totalWin,
|
||||||
<li>Ratio du score (point marqué / point reçu): ${comb.pointRatio.toFixed(3)}</li>
|
matchs: comb.matchs.filter(m => m.end).length
|
||||||
|
})}
|
||||||
|
</li>
|
||||||
|
<li>${i18next.t('pointsMarqués2', {nb: comb.pointMake})}</li>
|
||||||
|
<li>${i18next.t('pointsReçus2', {nb: comb.pointTake})}</li>
|
||||||
|
<li>${i18next.t('ratioDuScore2', {nb: comb.pointRatio.toFixed(3)})}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Liste des matchs:</h3>
|
<h3>${i18next.t('listeDesMatchs')}:</h3>
|
||||||
|
|
||||||
<figure class="wp-block-table is-style-stripes" style="font-size: 16px">
|
<figure class="wp-block-table is-style-stripes" style="font-size: 16px">
|
||||||
<table style="width: 700px;overflow: auto"><thead>
|
<table style="width: 700px;overflow: auto"><thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="has-text-align-center" data-align="center">Date</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('date')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Poule</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('poule')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Adversaire</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('adversaire')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Scores</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('scores')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Ratio</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('ratio')}</th>
|
||||||
<th class="has-text-align-center" data-align="center"></th>
|
<th class="has-text-align-center" data-align="center"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead><tbody>`
|
</thead><tbody>`
|
||||||
@@ -404,8 +477,8 @@ function buildCombView(comb) {
|
|||||||
<td class="has-text-align-center" data-align="center">${match.poule}</td>
|
<td class="has-text-align-center" data-align="center">${match.poule}</td>
|
||||||
<td class="has-text-align-center" data-align="center">${match.adv}</td>
|
<td class="has-text-align-center" data-align="center">${match.adv}</td>
|
||||||
<td class="has-text-align-center" data-align="center">${scoreToString(match.score)}</td>
|
<td class="has-text-align-center" data-align="center">${scoreToString(match.score)}</td>
|
||||||
<td class="has-text-align-center" data-align="center">${match.ratio.toFixed(3)}</td>
|
<td class="has-text-align-center" data-align="center">${match.end ? match.ratio.toFixed(3) : ""}</td>
|
||||||
<td class="has-text-align-center" data-align="center">${match.win ? cupImg : ""}</td>
|
<td class="has-text-align-center" data-align="center">${match.win ? cupImg : (match.eq ? cupImg2 : "")}</td>
|
||||||
</tr>`
|
</tr>`
|
||||||
}
|
}
|
||||||
arrayContent += `</tbody></table></figure>`
|
arrayContent += `</tbody></table></figure>`
|
||||||
@@ -414,10 +487,12 @@ function buildCombView(comb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function combPage(location) {
|
function combPage(location) {
|
||||||
rootDiv.innerHTML = header + backButton;
|
rootDiv.innerHTML = `<h4>${i18next.t('résultatDeLaCompétition')} :</h4><a id="homeLink" href="javascript:void(0);">${i18next.t('back')}</a>`;
|
||||||
|
document.getElementById('homeLink').addEventListener('click', () => setSubPage('home'));
|
||||||
|
|
||||||
const content = document.createElement('div');
|
const content = document.createElement('div');
|
||||||
content.style.marginTop = '1em';
|
content.style.marginTop = '1em';
|
||||||
content.innerHTML = '<h4>Recherche par combattant</h4>';
|
content.innerHTML = `<h4>${i18next.t('rechercheParCombattant')}</h4>`;
|
||||||
|
|
||||||
const dataContainer = document.createElement('div');
|
const dataContainer = document.createElement('div');
|
||||||
dataContainer.id = 'data-container';
|
dataContainer.id = 'data-container';
|
||||||
@@ -430,7 +505,7 @@ function combPage(location) {
|
|||||||
console.log(comb);
|
console.log(comb);
|
||||||
dataContainer.replaceChildren(buildCombView(comb));
|
dataContainer.replaceChildren(buildCombView(comb));
|
||||||
})
|
})
|
||||||
.catch(() => dataContainer.replaceChildren(new Text("Erreur de chargement du combattant")))
|
.catch(() => dataContainer.replaceChildren(new Text(i18next.t('erreurDeChargementDuCombattant'))))
|
||||||
.finally(() => stopLoading(loading));
|
.finally(() => stopLoading(loading));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -439,7 +514,7 @@ function combPage(location) {
|
|||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(combs => {
|
.then(combs => {
|
||||||
const select = document.createElement('select');
|
const select = document.createElement('select');
|
||||||
select.innerHTML = `<option value="0">--Sélectionner un combattant--</option>`;
|
select.innerHTML = `<option value="0">${i18next.t('--sélectionnerUnCombattant--')}</option>`;
|
||||||
for (const comb of Object.keys(combs).sort()) {
|
for (const comb of Object.keys(combs).sort()) {
|
||||||
select.innerHTML += `<option value="${combs[comb]}">${comb}</option>`;
|
select.innerHTML += `<option value="${combs[comb]}">${comb}</option>`;
|
||||||
}
|
}
|
||||||
@@ -458,7 +533,7 @@ function combPage(location) {
|
|||||||
loadComb(tmp);
|
loadComb(tmp);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => rootDiv.append(new Text("Erreur de chargement des combattants")))
|
.catch(() => rootDiv.append(new Text(i18next.t('erreurDeChargementDesCombattants'))))
|
||||||
.finally(() => stopLoading(loading));
|
.finally(() => stopLoading(loading));
|
||||||
|
|
||||||
rootDiv.append(content)
|
rootDiv.append(content)
|
||||||
@@ -467,34 +542,34 @@ function combPage(location) {
|
|||||||
function buildClubView(club) {
|
function buildClubView(club) {
|
||||||
const pouleDiv = document.createElement('div');
|
const pouleDiv = document.createElement('div');
|
||||||
let arrayContent = `
|
let arrayContent = `
|
||||||
<h3>Info :</h3>
|
<h3>${i18next.t('info')} :</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Nom : ${club.name}</li>
|
<li>${i18next.t('nom')} : ${club.name}</li>
|
||||||
<li>Nombre d'inscris : ${club.nb_insc}</li>
|
<li>${i18next.t('nombreDinscris')} : ${club.nb_insc}</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3>Statistique :</h3>
|
<h3>${i18next.t('statistique')} :</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Nombre de match disputé : ${club.nb_match}</li>
|
<li>${i18next.t('nombreDeMatchDisputé2', {nb: club.nb_match})}</li>
|
||||||
<li>Nombre de victoires : ${club.match_w}</li>
|
<li>${i18next.t('nombreDeVictoires2', {nb: club.match_w})}</li>
|
||||||
<li>Ratio de victoires moyen : ${club.ratioVictoire.toFixed(3)}</li>
|
<li>${i18next.t('ratioDeVictoiresMoyen2', {nb: club.ratioVictoire.toFixed(3)})}</li>
|
||||||
<li>Points marqués : ${club.pointMake}</li>
|
<li>${i18next.t('pointsMarqués2', {nb: club.pointMake})}</li>
|
||||||
<li>Points reçus : ${club.pointTake}</li>
|
<li>${i18next.t('pointsReçus2', {nb: club.pointTake})}</li>
|
||||||
<li>Ratio de points moyen : ${club.ratioPoint.toFixed(3)}</li>
|
<li>${i18next.t('ratioDePointsMoyen2', {nb: club.ratioPoint.toFixed(3)})}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Liste des menbres :</h3>
|
<h3>${i18next.t('listeDesMenbres')} :</h3>
|
||||||
|
|
||||||
<figure class="wp-block-table is-style-stripes" style="font-size: 16px">
|
<figure class="wp-block-table is-style-stripes" style="font-size: 16px">
|
||||||
<table style="width: 800px;overflow: auto"><thead>
|
<table style="width: 800px;overflow: auto"><thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="has-text-align-center" data-align="center">Catégorie</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('catégorie')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Nom</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('nom')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Victoires</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('victoires')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Défaites</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('défaites')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Ratio victoires</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('ratioVictoires')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Points marqués</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('pointsMarqués')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Points reçus</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('pointsReçus')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Ratio points</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('ratioPoints')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead><tbody>`
|
</thead><tbody>`
|
||||||
for (const comb of club.combs) {
|
for (const comb of club.combs) {
|
||||||
@@ -516,10 +591,12 @@ function buildClubView(club) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function clubPage(location) {
|
function clubPage(location) {
|
||||||
rootDiv.innerHTML = header + backButton;
|
rootDiv.innerHTML = `<h4>${i18next.t('résultatDeLaCompétition')} :</h4><a id="homeLink" href="javascript:void(0);">${i18next.t('back')}</a>`;
|
||||||
|
document.getElementById('homeLink').addEventListener('click', () => setSubPage('home'));
|
||||||
|
|
||||||
const content = document.createElement('div');
|
const content = document.createElement('div');
|
||||||
content.style.marginTop = '1em';
|
content.style.marginTop = '1em';
|
||||||
content.innerHTML = '<h4>Recherche par club</h4>';
|
content.innerHTML = `<h4>${i18next.t('rechercheParClub')}</h4>`;
|
||||||
|
|
||||||
const dataContainer = document.createElement('div');
|
const dataContainer = document.createElement('div');
|
||||||
dataContainer.id = 'data-container';
|
dataContainer.id = 'data-container';
|
||||||
@@ -532,7 +609,7 @@ function clubPage(location) {
|
|||||||
console.log(club);
|
console.log(club);
|
||||||
dataContainer.replaceChildren(buildClubView(club));
|
dataContainer.replaceChildren(buildClubView(club));
|
||||||
})
|
})
|
||||||
.catch(() => dataContainer.replaceChildren(new Text("Erreur de chargement du club")))
|
.catch(() => dataContainer.replaceChildren(new Text(i18next.t('erreurDeChargementDuClub'))))
|
||||||
.finally(() => stopLoading(loading));
|
.finally(() => stopLoading(loading));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,7 +618,7 @@ function clubPage(location) {
|
|||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(clubs => {
|
.then(clubs => {
|
||||||
const select = document.createElement('select');
|
const select = document.createElement('select');
|
||||||
select.innerHTML = `<option value="0">--Sélectionner un club--</option>`;
|
select.innerHTML = `<option value="0">${i18next.t('--sélectionnerUnClub--')}</option>`;
|
||||||
for (const club of Object.keys(clubs).sort()) {
|
for (const club of Object.keys(clubs).sort()) {
|
||||||
select.innerHTML += `<option value="${clubs[club]}">${club}</option>`;
|
select.innerHTML += `<option value="${clubs[club]}">${club}</option>`;
|
||||||
}
|
}
|
||||||
@@ -562,36 +639,90 @@ function clubPage(location) {
|
|||||||
loadComb(tmp);
|
loadComb(tmp);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => rootDiv.append(new Text("Erreur de chargement des clubs")))
|
.catch(() => rootDiv.append(new Text(i18next.t('erreurDeChargementDesClubs'))))
|
||||||
.finally(() => stopLoading(loading));
|
.finally(() => stopLoading(loading));
|
||||||
|
|
||||||
rootDiv.append(content)
|
rootDiv.append(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildClubsView(clubs) {
|
||||||
|
const pouleDiv = document.createElement('div');
|
||||||
|
let arrayContent = `
|
||||||
|
<h3>${i18next.t('classementDesClub')} :</h3>
|
||||||
|
|
||||||
|
<figure class="wp-block-table is-style-stripes" style="font-size: 16px">
|
||||||
|
<table style="width: 1200px;overflow: auto"><thead>
|
||||||
|
<tr>
|
||||||
|
<th class="has-text-align-center" data-align="center">${i18next.t('club')}</th>
|
||||||
|
<th class="has-text-align-center" data-align="center">${i18next.t('1er')}</th>
|
||||||
|
<th class="has-text-align-center" data-align="center">${i18next.t('2eme')}</th>
|
||||||
|
<th class="has-text-align-center" data-align="center">${i18next.t('3eme')}</th>
|
||||||
|
<th class="has-text-align-center" data-align="center">${i18next.t('scores')}</th>
|
||||||
|
</tr>
|
||||||
|
</thead><tbody>`
|
||||||
|
for (const club of clubs) {
|
||||||
|
arrayContent += `
|
||||||
|
<tr>
|
||||||
|
<td class="has-text-align-center" data-align="center">${club.name}</td>
|
||||||
|
<td class="has-text-align-center" data-align="center">${club.score[0]}</td>
|
||||||
|
<td class="has-text-align-center" data-align="center">${club.score[1]}</td>
|
||||||
|
<td class="has-text-align-center" data-align="center">${club.score[2]}</td>
|
||||||
|
<td class="has-text-align-center" data-align="center">${club.tt_score}</td>
|
||||||
|
</tr>`
|
||||||
|
}
|
||||||
|
arrayContent += `</tbody></table></figure>`
|
||||||
|
pouleDiv.innerHTML = arrayContent;
|
||||||
|
return pouleDiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
function clubRankPage() {
|
||||||
|
rootDiv.innerHTML = `<h4>${i18next.t('résultatDeLaCompétition')} :</h4><a id="homeLink" href="javascript:void(0);">${i18next.t('back')}</a>`;
|
||||||
|
document.getElementById('homeLink').addEventListener('click', () => setSubPage('home'));
|
||||||
|
|
||||||
|
const content = document.createElement('div');
|
||||||
|
content.style.marginTop = '1em';
|
||||||
|
|
||||||
|
const dataContainer = document.createElement('div');
|
||||||
|
dataContainer.id = 'data-container';
|
||||||
|
|
||||||
|
const loading = startLoading(content);
|
||||||
|
fetch(`${apiUrlRoot}/club/classement`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(clubs => {
|
||||||
|
console.log(clubs);
|
||||||
|
dataContainer.replaceChildren(buildClubsView(clubs));
|
||||||
|
})
|
||||||
|
.catch(() => dataContainer.replaceChildren(new Text(i18next.t('erreurDeChargementDeLaListe'))))
|
||||||
|
.finally(() => stopLoading(loading));
|
||||||
|
|
||||||
|
content.append(dataContainer);
|
||||||
|
rootDiv.append(content)
|
||||||
|
}
|
||||||
|
|
||||||
function buildCombsView(combs) {
|
function buildCombsView(combs) {
|
||||||
const pouleDiv = document.createElement('div');
|
const pouleDiv = document.createElement('div');
|
||||||
let arrayContent = `
|
let arrayContent = `
|
||||||
<h3>Statistique :</h3>
|
<h3>${i18next.t('statistique')} :</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Nombre d'inscris : ${combs.nb_insc}</li>
|
<li>${i18next.t('nombreDinscris2', {nb: combs.nb_insc})}</li>
|
||||||
<li>Nombre de match disputé : ${combs.tt_match}</li>
|
<li>${i18next.t('nombreDeMatchDisputé2', {nb: combs.tt_match})}</li>
|
||||||
<li>Points marqués : ${combs.point}</li>
|
<li>${i18next.t('pointsMarqués2', {nb: combs.point})}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3>Liste des combattants :</h3>
|
<h3>${i18next.t('listeDesCombattants')} :</h3>
|
||||||
|
|
||||||
<figure class="wp-block-table is-style-stripes" style="font-size: 16px">
|
<figure class="wp-block-table is-style-stripes" style="font-size: 16px">
|
||||||
<table style="width: 1200px;overflow: auto"><thead>
|
<table style="width: 1200px;overflow: auto"><thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="has-text-align-center" data-align="center">Catégorie</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('catégorie')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Club</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('club')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Nom</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('nom')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Victoires</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('victoires')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Défaites</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('défaites')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Ratio victoires</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('ratioVictoires')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Points marqués</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('pointsMarqués')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Points reçus</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('pointsReçus')}</th>
|
||||||
<th class="has-text-align-center" data-align="center">Ratios points</th>
|
<th class="has-text-align-center" data-align="center">${i18next.t('ratiosPoints')}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead><tbody>`
|
</thead><tbody>`
|
||||||
for (const comb of combs.combs) {
|
for (const comb of combs.combs) {
|
||||||
@@ -614,7 +745,9 @@ function buildCombsView(combs) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function combsPage() {
|
function combsPage() {
|
||||||
rootDiv.innerHTML = header + backButton;
|
rootDiv.innerHTML = `<h4>${i18next.t('résultatDeLaCompétition')} :</h4><a id="homeLink" href="javascript:void(0);">${i18next.t('back')}</a>`;
|
||||||
|
document.getElementById('homeLink').addEventListener('click', () => setSubPage('home'));
|
||||||
|
|
||||||
const content = document.createElement('div');
|
const content = document.createElement('div');
|
||||||
content.style.marginTop = '1em';
|
content.style.marginTop = '1em';
|
||||||
|
|
||||||
@@ -628,26 +761,50 @@ function combsPage() {
|
|||||||
console.log(combs);
|
console.log(combs);
|
||||||
dataContainer.replaceChildren(buildCombsView(combs));
|
dataContainer.replaceChildren(buildCombsView(combs));
|
||||||
})
|
})
|
||||||
.catch(() => dataContainer.replaceChildren(new Text("Erreur de chargement de la liste")))
|
.catch(() => dataContainer.replaceChildren(new Text(i18next.t('erreurDeChargementDeLaListe'))))
|
||||||
.finally(() => stopLoading(loading));
|
.finally(() => stopLoading(loading));
|
||||||
|
|
||||||
content.append(dataContainer);
|
content.append(dataContainer);
|
||||||
rootDiv.append(content)
|
rootDiv.append(content)
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener("load", () => {
|
export async function initCompetitionApi(apiUrlRoot_, host) {
|
||||||
let path = document.getElementById('safca_api_script').src;
|
apiUrlRoot = apiUrlRoot_;
|
||||||
const urlParams = new URLSearchParams(new URL(path).search);
|
|
||||||
apiUrlRoot = path.substring(0, path.lastIndexOf('/')) + "/api/public/result/" + urlParams.get("id");
|
const options = {
|
||||||
|
order: ['querystring', 'cookie', 'localStorage', 'sessionStorage', 'navigator', 'htmlTag'],
|
||||||
|
caches: [],
|
||||||
|
}
|
||||||
|
|
||||||
|
const backend = {
|
||||||
|
loadPath: `${host}/locales/{{lng}}/{{ns}}.json`,
|
||||||
|
}
|
||||||
|
|
||||||
|
await i18next
|
||||||
|
.use(i18nextHttpBackend)
|
||||||
|
.use(i18nextBrowserLanguagedetector)
|
||||||
|
.init({
|
||||||
|
supportedLngs: ['fr', 'en'],
|
||||||
|
fallbackLng: 'fr',
|
||||||
|
debug: host.startsWith('http://localhost'),
|
||||||
|
interpolation: {
|
||||||
|
escapeValue: true,
|
||||||
|
},
|
||||||
|
detection: options,
|
||||||
|
backend: backend,
|
||||||
|
ns: ['result'],
|
||||||
|
defaultNS: 'result',
|
||||||
|
})
|
||||||
|
|
||||||
console.log("apiUrlRoot:", apiUrlRoot)
|
console.log("apiUrlRoot:", apiUrlRoot)
|
||||||
|
console.log("FFSAF Competition API initialized.")
|
||||||
|
|
||||||
let hash = window.location.hash.substring(1);
|
let hash = window.location.hash.substring(1);
|
||||||
if (hash.length === 0)
|
if (hash.length === 0)
|
||||||
setSubPage('home');
|
setSubPage('home');
|
||||||
else
|
else
|
||||||
setSubPage(hash);
|
setSubPage(hash);
|
||||||
});
|
}
|
||||||
|
|
||||||
class TreeNode {
|
class TreeNode {
|
||||||
constructor(data) {
|
constructor(data) {
|
||||||
@@ -671,7 +828,7 @@ class TreeNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function initTree(data_in) {
|
function initTree(data_in) {
|
||||||
out = [];
|
let out = [];
|
||||||
for (const din of data_in) {
|
for (const din of data_in) {
|
||||||
out.push(parseTree(din));
|
out.push(parseTree(din));
|
||||||
}
|
}
|
||||||
@@ -818,7 +975,7 @@ function drawGraph(root = []) {
|
|||||||
ctx.textBaseline = 'top';
|
ctx.textBaseline = 'top';
|
||||||
|
|
||||||
for (let i = 0; i < scores.length; i++) {
|
for (let i = 0; i < scores.length; i++) {
|
||||||
const score = scores[i].s1+"-"+scores[i].s2;
|
const score = scorePrint(scores[i].s1) + "-" + scorePrint(scores[i].s2);
|
||||||
const div = (scores.length <= 2) ? 2 : (scores.length >= 4) ? 4 : 3;
|
const div = (scores.length <= 2) ? 2 : (scores.length >= 4) ? 4 : 3;
|
||||||
const text = ctx.measureText(score);
|
const text = ctx.measureText(score);
|
||||||
let dx = (size * 2 - text.width) / 2;
|
let dx = (size * 2 - text.width) / 2;
|
||||||
@@ -896,20 +1053,6 @@ function drawGraph(root = []) {
|
|||||||
if (tree.right != null) drawNode(tree.right, px - size * 2 - size * 8, py + size * 2 * death);
|
if (tree.right != null) drawNode(tree.right, px - size * 2 - size * 8, py + size * 2 * death);
|
||||||
}
|
}
|
||||||
|
|
||||||
function win(scores) {
|
|
||||||
let sum = 0;
|
|
||||||
for (const score of scores) {
|
|
||||||
if (score.s1 === -1000 || score.s2 === -1000)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (score.s1 > score.s2)
|
|
||||||
sum++;
|
|
||||||
else if (score.s1 < score.s2)
|
|
||||||
sum--;
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
}
|
|
||||||
|
|
||||||
let px = max_x;
|
let px = max_x;
|
||||||
let py;
|
let py;
|
||||||
let max_y
|
let max_y
|
||||||
@@ -922,7 +1065,7 @@ function drawGraph(root = []) {
|
|||||||
for (const node of root) {
|
for (const node of root) {
|
||||||
let win_name = "";
|
let win_name = "";
|
||||||
if (node.data.end) {
|
if (node.data.end) {
|
||||||
if (win(node.data.scores) > 0)
|
if (node.data.win > 0)
|
||||||
win_name = (node.data.c1FullName === null) ? "???" : node.data.c1FullName;
|
win_name = (node.data.c1FullName === null) ? "???" : node.data.c1FullName;
|
||||||
else
|
else
|
||||||
win_name = (node.data.c2FullName === null) ? "???" : node.data.c2FullName;
|
win_name = (node.data.c2FullName === null) ? "???" : node.data.c2FullName;
|
||||||
|
|||||||
BIN
src/main/webapp/public/img/171892.png
Normal file
BIN
src/main/webapp/public/img/171892.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
213
src/main/webapp/public/locales/en/cm.json
Normal file
213
src/main/webapp/public/locales/en/cm.json
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
{
|
||||||
|
"--SélectionnerUnCombattant--": "-- Select a fighter --",
|
||||||
|
"--Tous--": "-- All --",
|
||||||
|
"PourLéquipe": "for the team",
|
||||||
|
"actuel": "Current",
|
||||||
|
"administration": "Administration",
|
||||||
|
"adresseDuServeur": "Server address",
|
||||||
|
"afficher": "Show",
|
||||||
|
"ajoutAutomatique": "Automatic addition",
|
||||||
|
"ajouter": "Add",
|
||||||
|
"ajouterDesCombattants": "Add fighters",
|
||||||
|
"ajouterUn": "Add one",
|
||||||
|
"ajouterUneTeam": "Add team",
|
||||||
|
"attention": "Warning",
|
||||||
|
"aucuneConfigurationObs": "No OBS configuration found, please import one",
|
||||||
|
"avertissement": "Warning",
|
||||||
|
"bleu": "Blue",
|
||||||
|
"blue": "Blue",
|
||||||
|
"cardAdded": "Card added",
|
||||||
|
"cardRemoved": "Card removed",
|
||||||
|
"carton": "Card",
|
||||||
|
"cartonDéquipe": "Team's card",
|
||||||
|
"cartonJaune": "Yellow card",
|
||||||
|
"cartonNoir": "Black card",
|
||||||
|
"cartonRouge": "Red card",
|
||||||
|
"catégorie": "Category",
|
||||||
|
"catégorieDâgeMoyenne": "Middle-aged category",
|
||||||
|
"catégorieSélectionnée": "Selected category",
|
||||||
|
"catégoriesVontêtreCréées": "weight categories will be created",
|
||||||
|
"ceCartonEstIssuDunCartonDéquipe": "This card comes from a team card, do you really want to delete it?",
|
||||||
|
"certainsCombattantsNontPasDePoidsRenseigné": "Some fighters do not have a weight listed; they will NOT be included in the categories.",
|
||||||
|
"chrono.+/-...S": "+/- ... s",
|
||||||
|
"chrono.+10S": "+10 s",
|
||||||
|
"chrono.+1S": "+1 s",
|
||||||
|
"chrono.-10S": "-10 s",
|
||||||
|
"chrono.-1S": "-1 s",
|
||||||
|
"chrono.arrêter": "Stop",
|
||||||
|
"chrono.définirLeTemps": "Set time",
|
||||||
|
"chrono.démarrer": "Start",
|
||||||
|
"chrono.editionTemps": "Time editing",
|
||||||
|
"chrono.entrezLeTempsEnS": "Enter time in seconds",
|
||||||
|
"chrono.recapTemps": "Time: {{temps}}, pause: {{pause}}",
|
||||||
|
"chronomètre": "Stopwatch",
|
||||||
|
"classement": "Ranking",
|
||||||
|
"club": "Club",
|
||||||
|
"combattantsCorrespondentAuxSélectionnés": "fighter(s) match the selections above",
|
||||||
|
"compétition": "Competition",
|
||||||
|
"compétitionManager": "Competition manager",
|
||||||
|
"config.obs.dossierDesResources": "Resources folder",
|
||||||
|
"config.obs.motDePasseDuServeur": "Server password",
|
||||||
|
"config.obs.warn1": "/! The password will be stored in plain text; it is recommended to use it only on OBS WebSocket and to change it between each competition",
|
||||||
|
"config.obs.ws": "ws://",
|
||||||
|
"configurationDuNomDeLaZone": "Zone name configuration",
|
||||||
|
"configurationObs": "OBS Configuration",
|
||||||
|
"confirm1": "This match already has results; are you sure you want to delete it?",
|
||||||
|
"confirm2.msg": "Do you really want to change the tournament tree size or the loser matches? This will modify existing matches (including possible deletions)!",
|
||||||
|
"confirm2.title": "Tournament tree change",
|
||||||
|
"confirm3.msg": "Do you really want to remove the {{typeStr}} part from the category? This will delete the matches contained in this part!",
|
||||||
|
"confirm3.title": "Change category type",
|
||||||
|
"confirm4.msg": "Do you really want to delete the category {{name}}. This will delete all associated matches!",
|
||||||
|
"confirm4.title": "Delete category",
|
||||||
|
"confirmer": "Confirm",
|
||||||
|
"conserverUniquementLesMatchsTerminés": "Keep only finished matches",
|
||||||
|
"contre": "vs",
|
||||||
|
"couleur": "Color",
|
||||||
|
"créationDeLaLesCatégories": "Creating the category(ies)",
|
||||||
|
"créerLaPhaseFinaleSilYADesPoules": "Create the final phase if there are groups.",
|
||||||
|
"créerLesMatchesDeClassement": "Create the ranking matches",
|
||||||
|
"créerLesMatchesDeClassement.msg": "Ranking matches have already been set up/played; recreating these matches will delete them all (you will therefore lose any results). Please note down any information you wish to keep.",
|
||||||
|
"créerLesMatchs": "Create matches",
|
||||||
|
"créerToutesLesCatégories": "Create all categories",
|
||||||
|
"date": "Date",
|
||||||
|
"demi-finalesEtFinales": "Semi-finals and finals",
|
||||||
|
"depuisUneCatégoriePrédéfinie": "From a predefined category",
|
||||||
|
"duréePause": "Pause duration",
|
||||||
|
"duréeRound": "Round duration",
|
||||||
|
"editionDeLaCatégorie": "Edit category",
|
||||||
|
"editionDuMatch": "Match edition",
|
||||||
|
"enregister": "Save",
|
||||||
|
"enregistrer": "Save",
|
||||||
|
"epéeBouclier": "Sword and shield",
|
||||||
|
"err1": "A fighter cannot fight themselves!",
|
||||||
|
"err2": "The combat zone name format is invalid. Please separate names with ';'.",
|
||||||
|
"err3": "At least one type (pool or tournament) must be selected.",
|
||||||
|
"erreurLorsDeLaCopieDansLePresse": "Error while copying to clipboard: ",
|
||||||
|
"erreurLorsDeLaCréationDesMatchs": "Error while creating matches: ",
|
||||||
|
"etatDesTablesDeMarque": "State of marque tables",
|
||||||
|
"exporter": "Export",
|
||||||
|
"fermer": "Close",
|
||||||
|
"feuilleVierge": "Blank sheet",
|
||||||
|
"finalesUniquement": "Finals only",
|
||||||
|
"genre": "Gender",
|
||||||
|
"genre.f": "F",
|
||||||
|
"genre.h": "M",
|
||||||
|
"genre.na": "NA",
|
||||||
|
"imprimer": "Print",
|
||||||
|
"individuelle": "Individual",
|
||||||
|
"informationCatégorie": "Category information",
|
||||||
|
"inscrit": "Registered",
|
||||||
|
"jusquauRang": "Up to the rank",
|
||||||
|
"leTournoiServiraDePhaseFinaleAuxPoules": "The tournament will serve as the final phase for the group stage.",
|
||||||
|
"lesCombattantsEnDehors": "Fighters not participating in the tournament will have a ranking match.",
|
||||||
|
"lesCombattantsEnDehors2": "Fighters outside the ranking tournament will have a ranking match",
|
||||||
|
"listeDesCartons": "List of cards",
|
||||||
|
"manche": "Round",
|
||||||
|
"matchPourLesPerdantsDuTournoi": "Match for tournament losers:",
|
||||||
|
"matchTerminé": "Match over",
|
||||||
|
"matches": "Matches",
|
||||||
|
"modeDeCréation": "Creation method",
|
||||||
|
"modifier": "Edit",
|
||||||
|
"msg1": "There are already matches in this pool; what do you want to do with them?",
|
||||||
|
"neRienConserver": "Keep nothing",
|
||||||
|
"no": "No.",
|
||||||
|
"nom": "Name",
|
||||||
|
"nomDeLaZone": "Area name",
|
||||||
|
"nomDeLéquipe": "team name",
|
||||||
|
"nomDesZonesDeCombat": "Combat zone names <1>(separated by ';')</1>",
|
||||||
|
"nombreDeCombattants": "Number of fighters",
|
||||||
|
"nouvelle...": "New...",
|
||||||
|
"obs.préfixDesSources": "Source prefix",
|
||||||
|
"pays": "Country",
|
||||||
|
"personnaliser": "Personalize",
|
||||||
|
"podium": "Podium",
|
||||||
|
"podiumDesClubs": "Club podium",
|
||||||
|
"poids": "Weight",
|
||||||
|
"poule": "Pool",
|
||||||
|
"poulePour": "Pool for: ",
|
||||||
|
"préparation...": "Preparing...",
|
||||||
|
"quoiImprimer?": "What print?",
|
||||||
|
"remplacer": "Replace",
|
||||||
|
"rouge": "Red",
|
||||||
|
"réinitialiser": "Reset",
|
||||||
|
"résultat": "Result",
|
||||||
|
"sansPoule": "No pool",
|
||||||
|
"sauvegarde": "Backup",
|
||||||
|
"sauvegarder": "Save",
|
||||||
|
"score": "Score",
|
||||||
|
"score.err1": "Cannot end a tournament match in a draw.",
|
||||||
|
"score.spe": "Special scores: <br/>-997: disqualified <br/>-998: absent <br/>-999: forfeit",
|
||||||
|
"scores": "Scores",
|
||||||
|
"secrétariatsDeLice": "Ring secretariats",
|
||||||
|
"select.aucunCombattantDisponible": "No fighters available",
|
||||||
|
"select.aucunCombattantSélectionné": "No fighters selected",
|
||||||
|
"select.msg1": "(0 = disabled)",
|
||||||
|
"select.recherche": "Search",
|
||||||
|
"select.sélectionnerDesCombatants": "Select fighters",
|
||||||
|
"select.à": "to",
|
||||||
|
"serveur": "Server",
|
||||||
|
"source": "Source",
|
||||||
|
"suivant": "Next",
|
||||||
|
"supprimer": "Delete",
|
||||||
|
"supprimerUn": "Delete one",
|
||||||
|
"sélectionneLesModesDaffichage": "Select display modes",
|
||||||
|
"sélectionner": "Select",
|
||||||
|
"taille": "Size",
|
||||||
|
"team": "Team",
|
||||||
|
"terminé": "Finished",
|
||||||
|
"texteCopiéDansLePresse": "Text copied to clipboard! Paste it into an HTML tag on your WordPress.",
|
||||||
|
"toast.card.team.error": "Error while editing team card",
|
||||||
|
"toast.card.team.pending": "Editing team card...",
|
||||||
|
"toast.card.team.success": "Team card edited!",
|
||||||
|
"toast.createCategory.error": "Error while creating the category",
|
||||||
|
"toast.createCategory.pending": "Creating category...",
|
||||||
|
"toast.createCategory.success": "Category created!",
|
||||||
|
"toast.deleteCategory.error": "Error while deleting the category",
|
||||||
|
"toast.deleteCategory.pending": "Deleting category...",
|
||||||
|
"toast.deleteCategory.success": "Category deleted!",
|
||||||
|
"toast.matchs.classement.create.error": "Error while creating ranking matches.",
|
||||||
|
"toast.matchs.classement.create.pending": "Creating ranking matches in progress...",
|
||||||
|
"toast.matchs.classement.create.success": "Ranking matches created successfully.",
|
||||||
|
"toast.matchs.create.error": "Error while creating matches.",
|
||||||
|
"toast.matchs.create.pending": "Creating matches in progress...",
|
||||||
|
"toast.matchs.create.success": "Matches created successfully.",
|
||||||
|
"toast.print.error": "Error while preparing print",
|
||||||
|
"toast.print.pending": "Preparing print...",
|
||||||
|
"toast.print.success": "Print ready!",
|
||||||
|
"toast.team.update.error": "Error while updating team",
|
||||||
|
"toast.team.update.pending": "Updating team...",
|
||||||
|
"toast.team.update.success": "Team updated!",
|
||||||
|
"toast.updateCategory.error": "Error while updating the category",
|
||||||
|
"toast.updateCategory.pending": "Updating category...",
|
||||||
|
"toast.updateCategory.success": "Category updated!",
|
||||||
|
"toast.updateMatchScore.error": "Error while updating match score",
|
||||||
|
"toast.updateMatchScore.pending": "Updating match score...",
|
||||||
|
"toast.updateMatchScore.success": "Match score updated!",
|
||||||
|
"toast.updateTrees.error": "Error while updating trees",
|
||||||
|
"toast.updateTrees.init.error": "Error while creating trees",
|
||||||
|
"toast.updateTrees.init.pending": "Creating tournament trees...",
|
||||||
|
"toast.updateTrees.init.success": "Trees created!",
|
||||||
|
"toast.updateTrees.pending": "Updating tournament trees...",
|
||||||
|
"toast.updateTrees.success": "Trees updated!",
|
||||||
|
"tournoi": "Tournament",
|
||||||
|
"tournois": "Tournaments",
|
||||||
|
"tousLesMatchs": "All matches",
|
||||||
|
"toutConserver": "Keep all",
|
||||||
|
"touteLaCatégorie": "The entire category",
|
||||||
|
"toutesLesCatégories": "All categories",
|
||||||
|
"ttm.admin.obs": "Short click: Download resources. Long click: Create OBS configuration",
|
||||||
|
"ttm.admin.scripte": "Copy integration script",
|
||||||
|
"ttm.table.inverserLaPosition": "Reverse fighter positions on this screen",
|
||||||
|
"ttm.table.obs": "Short click: Load configuration and connect.",
|
||||||
|
"ttm.table.pub_aff": "Open public display",
|
||||||
|
"ttm.table.pub_score": "Show scores on public display",
|
||||||
|
"type": "Type",
|
||||||
|
"téléchargement": "Download",
|
||||||
|
"téléchargementEnCours": "Downloading...",
|
||||||
|
"téléchargementTerminé!": "Download completed!",
|
||||||
|
"uneCatégorie": "a category",
|
||||||
|
"uneCatégorieNePeutContenirPlusDe10Combattants": "A category cannot contain more than 10 fighters, please create weight categories.",
|
||||||
|
"valider": "Validate",
|
||||||
|
"zone": "Zone",
|
||||||
|
"zoneDeCombat": "Combat zone"
|
||||||
|
}
|
||||||
664
src/main/webapp/public/locales/en/common.json
Normal file
664
src/main/webapp/public/locales/en/common.json
Normal file
@@ -0,0 +1,664 @@
|
|||||||
|
{
|
||||||
|
"(optionnelle)": "(optional)",
|
||||||
|
"---SansClub---": "--- no club ---",
|
||||||
|
"---TousLesAges---": "--- all ages ---",
|
||||||
|
"---ToutLesClubs---": "--- all clubs ---",
|
||||||
|
"---ToutLesPays---": "--- all countries ---",
|
||||||
|
"---TouteLesCatégories---": "--- all categories ---",
|
||||||
|
"--NonLicencier--": "-- Not licensed --",
|
||||||
|
"--SélectionnerCatégorie--": "-- Select category --",
|
||||||
|
"1Catégorie": "+1 category",
|
||||||
|
"2Catégorie": "+2 categories",
|
||||||
|
"LesModificationsNontEnregistrer": "/!\\ The changes have not yet been saved, click save /!\\",
|
||||||
|
"activer": "Activate",
|
||||||
|
"admin": "Administration",
|
||||||
|
"administrateur": "Administrator",
|
||||||
|
"adresse": "Address",
|
||||||
|
"adresseAdministrative": "Administrative address",
|
||||||
|
"aff.ancienNom": "Former name: {{name}}",
|
||||||
|
"aff.byMembreSim": "By similar member",
|
||||||
|
"aff.byNewMenbre": "By new member",
|
||||||
|
"aff.byNoLicence": "By license number",
|
||||||
|
"aff.info1": "This club has already been affiliated (affiliation no. {{no}})",
|
||||||
|
"aff.membreNo": "Member no. {{no}}",
|
||||||
|
"aff.nomDuClub": "Club name",
|
||||||
|
"aff.raisonDuRefus": "Reason for refusal",
|
||||||
|
"aff.raisonDuRefus.msg": "Please indicate the reason for refusal",
|
||||||
|
"aff.refusConfirm": "Are you sure you want to refuse this request?",
|
||||||
|
"aff.refuserLaDemande": "Refuse the request",
|
||||||
|
"aff.refuserLaDemande.detail": "Are you sure you want to refuse this request?",
|
||||||
|
"aff.submit.error1": "Please enter a valid license number for member {{id}}",
|
||||||
|
"aff.submit.error2": "Please enter a valid license number for member {{id}}",
|
||||||
|
"aff.submit.error3": "Please enter a valid email for member {{id}}",
|
||||||
|
"aff.toast.accept.error": "Failed to accept affiliation",
|
||||||
|
"aff.toast.accept.pending": "Accepting affiliation in progress",
|
||||||
|
"aff.toast.accept.success": "Affiliation accepted successfully 🎉",
|
||||||
|
"aff.toast.del.error": "Failed to delete affiliation request",
|
||||||
|
"aff.toast.del.pending": "Deleting affiliation request in progress",
|
||||||
|
"aff.toast.del.success": "Affiliation request deleted successfully 🎉",
|
||||||
|
"aff.toast.del2.error": "Failed to delete affiliation",
|
||||||
|
"aff.toast.del2.pending": "Deleting affiliation in progress",
|
||||||
|
"aff.toast.del2.success": "Affiliation deleted successfully 🎉",
|
||||||
|
"aff.toast.save.error": "Failed to save affiliation request",
|
||||||
|
"aff.toast.save.pending": "Saving affiliation request in progress",
|
||||||
|
"aff.toast.save.success": "Affiliation request saved successfully 🎉",
|
||||||
|
"aff.toast.save2.error": "Failed to save affiliation",
|
||||||
|
"aff.toast.save2.pending": "Saving affiliation in progress",
|
||||||
|
"aff.toast.save2.success": "Affiliation saved successfully 🎉",
|
||||||
|
"aff_req.appuyerSurRechercher": "Press search to complete",
|
||||||
|
"aff_req.association": "The association",
|
||||||
|
"aff_req.button.cancel": "Cancel my request",
|
||||||
|
"aff_req.button.confirm": "Confirm my affiliation request",
|
||||||
|
"aff_req.button.save": "Save changes",
|
||||||
|
"aff_req.denomination": "Denomination",
|
||||||
|
"aff_req.disposeLicence": "Already has a license",
|
||||||
|
"aff_req.error1": "The role of member {{i}} is required",
|
||||||
|
"aff_req.error2": "The SIRET/RNA format is invalid",
|
||||||
|
"aff_req.nomDeLassociation": "Association name",
|
||||||
|
"aff_req.text1": "Affiliation is annual and valid for one sports season: from September 1st to August 31st of the following year.",
|
||||||
|
"aff_req.text2": "To affiliate, a sports association must meet the following conditions:",
|
||||||
|
"aff_req.text2.li": [
|
||||||
|
"Have its headquarters in France or the Principality of Monaco",
|
||||||
|
"Be constituted in accordance with Chapter 1 of Title II of Book 1 of the Sports Code",
|
||||||
|
"Pursue a purpose that falls within the definition of Article 1 of the Federation's statutes",
|
||||||
|
"Have statutes compatible with the principles of organization and operation of the Federation",
|
||||||
|
"Ensure freedom of opinion and respect for the rights of defense within it, and prohibit any discrimination",
|
||||||
|
"Comply with the rules of supervision, hygiene, and safety established by the Federation's regulations"
|
||||||
|
],
|
||||||
|
"aff_req.text3": "After validation of your request, you will receive a temporary identifier and password to access your FFSAF space",
|
||||||
|
"aff_req.text4": "Note that to finalize your affiliation, you will need to:",
|
||||||
|
"aff_req.text4.li1": "Have at least three licensed members, including the president",
|
||||||
|
"aff_req.text4.li2": "Have paid the fees provided for by the federal regulations",
|
||||||
|
"aff_req.text5": "You can later add publicly visible addresses for your training locations",
|
||||||
|
"aff_req.text6": "Leave blank to make no changes. (If a coat of arms has already been sent with this request, it will be used; otherwise, we will use the one from the previous affiliation)",
|
||||||
|
"aff_req.text7": "Affiliation request sent successfully",
|
||||||
|
"aff_req.text8": "Once your request is validated, you will receive a temporary identifier and password to access your FFSAF space",
|
||||||
|
"aff_req.toast.undo.error": "Failed to cancel affiliation request",
|
||||||
|
"aff_req.toast.undo.pending": "Cancelling affiliation request in progress",
|
||||||
|
"aff_req.toast.undo.success": "Affiliation request cancelled successfully 🎉",
|
||||||
|
"afficherLesCombattantsNonPesés": "Show unweighed fighters",
|
||||||
|
"afficherLétatDesAffiliation": "Display affiliation status",
|
||||||
|
"affiliation": "Affiliation",
|
||||||
|
"affiliationNo": "Affiliation no. {{no}}",
|
||||||
|
"ajout": "Addition",
|
||||||
|
"ajouterUnClub": "Add a club",
|
||||||
|
"ajouterUnMembre": "Add a member",
|
||||||
|
"all_season": "--- all seasons ---",
|
||||||
|
"ans": "years",
|
||||||
|
"arme": "Weapon",
|
||||||
|
"au": "to",
|
||||||
|
"aucun": "None",
|
||||||
|
"aucunMembreSélectionné": "No member selected",
|
||||||
|
"aucuneCatégorieDisponible": "No categories available at this time.",
|
||||||
|
"back": "« back",
|
||||||
|
"blason": "Coat of arms",
|
||||||
|
"bouclier": "Shield",
|
||||||
|
"bureau": "Board",
|
||||||
|
"button.accepter": "Accept",
|
||||||
|
"button.ajouter": "Add",
|
||||||
|
"button.annuler": "Cancel",
|
||||||
|
"button.appliquer": "Apply",
|
||||||
|
"button.confirmer": "Confirm",
|
||||||
|
"button.créer": "Create",
|
||||||
|
"button.enregistrer": "Save",
|
||||||
|
"button.fermer": "Close",
|
||||||
|
"button.modifier": "Edit",
|
||||||
|
"button.refuser": "Refuse",
|
||||||
|
"button.seDésinscrire": "Unsubscribe",
|
||||||
|
"button.suivant": "Next",
|
||||||
|
"button.supprimer": "Delete",
|
||||||
|
"casque": "Helmet",
|
||||||
|
"cat.benjamin": "Benjamin",
|
||||||
|
"cat.cadet": "Cadet",
|
||||||
|
"cat.catégorieInconnue": "Unknown category",
|
||||||
|
"cat.junior": "Junior",
|
||||||
|
"cat.miniPoussin": "Mini Chick",
|
||||||
|
"cat.minime": "Minime",
|
||||||
|
"cat.poussin": "Chick",
|
||||||
|
"cat.senior1": "Senior 1",
|
||||||
|
"cat.senior2": "Senior 2",
|
||||||
|
"cat.superMini": "Super Mini",
|
||||||
|
"cat.vétéran1": "Veteran 1",
|
||||||
|
"cat.vétéran2": "Veteran 2",
|
||||||
|
"categorie": "category",
|
||||||
|
"catégorie": "Category",
|
||||||
|
"catégorieàAjouter": "Category to add",
|
||||||
|
"certificatMédical": "Medical certificate",
|
||||||
|
"champAttendu": "Expected field",
|
||||||
|
"chargement...": "Loading...",
|
||||||
|
"chargerLexcel": "Load Excel",
|
||||||
|
"chargerLexcel.msg": "Please use the file above as a template; do not rename the columns or modify the license numbers.",
|
||||||
|
"choisir...": "Choose...",
|
||||||
|
"club.aff_renew.msg": "Please select 0 to 3 board members to fill out the pre-request. (If a non-board member will become one next year, you can enter them in the next step)",
|
||||||
|
"club.change.status": "To modify the above information, please contact the FFSAF by email.",
|
||||||
|
"club.contact.tt": {
|
||||||
|
"AUTRE": "Other club contact",
|
||||||
|
"COURRIEL": "Club email address<br>Example: contact@ffsaf.fr",
|
||||||
|
"FACEBOOK": "Club Facebook page starting with 'https://www.facebook.com/'<br>Example: https://www.facebook.com/ffmsf",
|
||||||
|
"INSTAGRAM": "Club Instagram account starting with 'https://www.instagram.com/'<br>Example: https://www.instagram.com/ff_msf",
|
||||||
|
"SITE": "Club website with or without 'https://'<br>Example: ffsaf.fr<br>Or https://ffsaf.fr",
|
||||||
|
"TELEPHONE": "Club phone number<br>Example: 06 12 13 78 55"
|
||||||
|
},
|
||||||
|
"club.toast.aff.error": "Failed to load affiliations",
|
||||||
|
"club.toast.aff.pending": "Loading affiliations in progress",
|
||||||
|
"club.toast.aff.success": "Affiliations loaded successfully 🎉",
|
||||||
|
"club.toast.del.error": "Failed to delete club",
|
||||||
|
"club.toast.del.pending": "Deleting club in progress",
|
||||||
|
"club.toast.del.success": "Club deleted successfully 🎉",
|
||||||
|
"club.toast.new.error": "Failed to create club",
|
||||||
|
"club.toast.new.pending": "Creating club in progress",
|
||||||
|
"club.toast.new.success": "Club created successfully 🎉",
|
||||||
|
"club.toast.save.error": "Failed to save club",
|
||||||
|
"club.toast.save.pending": "Saving club in progress",
|
||||||
|
"club.toast.save.success": "Club saved successfully 🎉",
|
||||||
|
"clubExterne": "External club",
|
||||||
|
"club_one": "Club",
|
||||||
|
"club_other": "Clubs",
|
||||||
|
"club_zero": "No club",
|
||||||
|
"colonneDansLeFichier": "Column in the file",
|
||||||
|
"combattant": "fighter",
|
||||||
|
"comp.aff.blason": "Display the club's coat of arms on screens",
|
||||||
|
"comp.aff.flag": "Display the fighter's country on screens",
|
||||||
|
"comp.ajoutRapide": "Quick add",
|
||||||
|
"comp.ajouterUnCombattant": "Add a fighter",
|
||||||
|
"comp.ajouterUnInvité": "Add a guest",
|
||||||
|
"comp.billetterie": "Ticketing",
|
||||||
|
"comp.billetterieHelloasso": "HelloAsso Ticketing",
|
||||||
|
"comp.catégorieNormalisée": "Standardized category",
|
||||||
|
"comp.combattantNonTrouvé": "Fighter not found",
|
||||||
|
"comp.combattantsInscrits": "Registered fighters",
|
||||||
|
"comp.compétitionFuture": "Future competition",
|
||||||
|
"comp.compétitionPassée": "Past competition",
|
||||||
|
"comp.créationCompétition": "Competition creation",
|
||||||
|
"comp.dateDinscription": "Registration date",
|
||||||
|
"comp.editionCompétition": "Competition edition",
|
||||||
|
"comp.error1": "The end date must be after the start date.",
|
||||||
|
"comp.error2": "Please enter the start and end dates of registration.",
|
||||||
|
"comp.error3": "The end date of registration must be after the start date of registration.",
|
||||||
|
"comp.exporterLesInscription": "Export registrations",
|
||||||
|
"comp.ha.emailDeRéceptionDesInscriptionséchoué": "Email for receiving failed registrations",
|
||||||
|
"comp.ha.error1": "Please enter the HelloAsso ticketing URL and associated rates.",
|
||||||
|
"comp.ha.error2": "The HelloAsso ticketing URL is invalid. Please check the URL format.",
|
||||||
|
"comp.ha.error3": "Please enter the email for receiving failed registrations.",
|
||||||
|
"comp.ha.tarifsHelloasso": "HelloAsso rates",
|
||||||
|
"comp.ha.text1": "To ensure good interconnection with HelloAsso, please follow these instructions:",
|
||||||
|
"comp.ha.text2": "<strong>Configure the notification URL:</strong> In order for us to receive a notification for each registration, it is necessary to configure the notification URL of your HelloAsso account to redirect to \"https://intra.ffsaf.fr/api/webhook/ha\". To do this, from the home page of your association on HelloAsso, go to <strong>My account</strong> > <strong>Settings</strong> > <strong>Integrations and API</strong> section Notification and copy-paste <strong>https://intra.ffsaf.fr/api/webhook/ha</strong> in the <strong>My callback URL</strong> field and save.",
|
||||||
|
"comp.ha.text3": "<strong>Copy-paste the exact name of the rates</strong> <em>-separated by semicolons-</em> that will result in automatic registration. All these rates must imperatively require the license number as a mandatory field. To do this, during the configuration of your ticketing at step 3, click on <strong>+ Add information</strong>, enter the exact title <strong>License number</strong>, in <strong>Type of response desired</strong> enter Number, select the rates entered previously and make the information mandatory.",
|
||||||
|
"comp.ha.text4": "<strong>Copy-paste the URL of your ticketing</strong> in the field below. It should look like this: https://www.helloasso.com/associations/__asso-name-on-helloasso__/events/__ticketing-name__",
|
||||||
|
"comp.ha.text5": "HelloAsso ticketing URL",
|
||||||
|
"comp.ha.text6": "If for any reason the automatic registration fails, an email will be sent to this address to inform you",
|
||||||
|
"comp.informationsGénéralesSurLaCompétition": "General information about the competition",
|
||||||
|
"comp.informationsSurLeModeDinscription": "Information on the registration mode",
|
||||||
|
"comp.informationsTechniques": "Technical information",
|
||||||
|
"comp.inscription": "Registration",
|
||||||
|
"comp.inscriptionModeAdministrateur": "Registration - administrator mode",
|
||||||
|
"comp.inscriptionsLibres": "Free registrations",
|
||||||
|
"comp.inscriptionsParLesAdministrateursDeLaCompétition": "Registrations by competition administrators",
|
||||||
|
"comp.inscriptionsParLesResponsablesDeClub": "Registrations by club managers",
|
||||||
|
"comp.inscriptionsSurLaBilletterieHelloasso": "Registrations on the HelloAsso ticketing",
|
||||||
|
"comp.modal.annoncé": "Announced",
|
||||||
|
"comp.modal.information": "Information",
|
||||||
|
"comp.modal.pesé": "Weighed",
|
||||||
|
"comp.modal.poids": "Weight (in kg)",
|
||||||
|
"comp.modal.recherche": "Search*",
|
||||||
|
"comp.modal.surclassement": "Overclassification",
|
||||||
|
"comp.modal.text1": "Guests are reserved for members not licensed by the federation. Fighters registered via this form will not be able to see their results from their profile.",
|
||||||
|
"comp.modal.text2": "Prevent members/clubs from modifying this registration",
|
||||||
|
"comp.modifierLesParticipants": "View/Edit participants",
|
||||||
|
"comp.monInscription": "My registration",
|
||||||
|
"comp.noDeLicence": "License number",
|
||||||
|
"comp.nouvelleCompétition": "New competition",
|
||||||
|
"comp.organisateur": "Organizer",
|
||||||
|
"comp.quiPeutInscrire": "Who can register",
|
||||||
|
"comp.reg.libres": "Free",
|
||||||
|
"comp.reg.parLesAdministrateursDeLaCompétition": "By competition administrators",
|
||||||
|
"comp.reg.parLesResponsablesDeClub": "By club managers",
|
||||||
|
"comp.reg.surLaBilletterieHelloasso": "On the HelloAsso ticketing",
|
||||||
|
"comp.responsablesEtBureauxDesAssociations": "Managers and boards of associations",
|
||||||
|
"comp.sinscrire": "Register",
|
||||||
|
"comp.supprimerLaCompétition": "Delete competition",
|
||||||
|
"comp.supprimerLaCompétition.msg": "Are you sure you want to delete this competition and all associated results?",
|
||||||
|
"comp.surclassement_one": "{{cat}} with 1 overclassification",
|
||||||
|
"comp.surclassement_other": "{{cat}} with {{count}} overclassifications",
|
||||||
|
"comp.surclassement_zero": "{{cat}}",
|
||||||
|
"comp.text2": "Visible to the public (appears in the list of competitions)",
|
||||||
|
"comp.text3": "If not checked, the competition will only be visible to people who can register participants.",
|
||||||
|
"comp.tips": "Tip 1: It is possible to ban a fighter, which will prevent them from being re-registered by any means other than by an administrator of this competition. To do this, click on the small <1/> next to their name.<br/>Tip 2: It is also possible to lock the modifications of their registration from their file, which will prevent it from being modified/deleted by themselves and/or a club manager.",
|
||||||
|
"comp.toast.del.error": "Failed to delete competition",
|
||||||
|
"comp.toast.del.pending": "Deleting competition in progress",
|
||||||
|
"comp.toast.del.success": "Competition deleted successfully 🎉",
|
||||||
|
"comp.toast.params.error": "Failed to update competition parameters",
|
||||||
|
"comp.toast.params.pending": "Updating competition parameters in progress...",
|
||||||
|
"comp.toast.params.success": "Competition parameters updated successfully 🎉",
|
||||||
|
"comp.toast.register.add.error": "Fighter not found",
|
||||||
|
"comp.toast.register.add.pending": "Search in progress",
|
||||||
|
"comp.toast.register.add.success": "Fighter found and added/updated",
|
||||||
|
"comp.toast.register.addMultiple.success_one": "Successful import for 1 fighter",
|
||||||
|
"comp.toast.register.addMultiple.success_other": "Successful import for {{count}} fighters",
|
||||||
|
"comp.toast.register.ban.error": "Error",
|
||||||
|
"comp.toast.register.ban.pending": "Unregistration in progress",
|
||||||
|
"comp.toast.register.ban.success": "Fighter unregistered and banned",
|
||||||
|
"comp.toast.register.del.error": "Error",
|
||||||
|
"comp.toast.register.del.pending": "Unregistration in progress",
|
||||||
|
"comp.toast.register.del.success": "Fighter unregistered",
|
||||||
|
"comp.toast.register.self.add.error": "Error during registration",
|
||||||
|
"comp.toast.register.self.add.pending": "Registration in progress",
|
||||||
|
"comp.toast.register.self.add.success": "Registration completed 🎉",
|
||||||
|
"comp.toast.register.self.del.error": "Error during unregistration",
|
||||||
|
"comp.toast.register.self.del.pending": "Unregistration in progress",
|
||||||
|
"comp.toast.register.self.del.success": "Unregistration completed",
|
||||||
|
"comp.toast.registers.addMultiple.error": "Import failed",
|
||||||
|
"comp.toast.registers.addMultiple.pending": "Import in progress",
|
||||||
|
"comp.toast.registers.addMultiple.success": "Import completed successfully 🎉",
|
||||||
|
"comp.toast.save.error": "Failed to save competition",
|
||||||
|
"comp.toast.save.pending": "Saving competition in progress",
|
||||||
|
"comp.toast.save.success": "Competition saved successfully 🎉",
|
||||||
|
"comp.tousLesMembresDeLaFfsaf": "All FFSAF members",
|
||||||
|
"comp.typeDinscription": "Registration type",
|
||||||
|
"comp.uniquementLesAdministrateursDeLaCompétition": "Only competition administrators",
|
||||||
|
"comp.warn1": "Are you sure you want to unregister and ban this fighter from the competition?\n(You can re-register them later)",
|
||||||
|
"comp.warn2": "Are you sure you want to unregister this fighter?\nThis will not unregister them from the HelloAsso ticketing and will not refund them.",
|
||||||
|
"comp.warn3": "Are you sure you want to unregister this fighter?",
|
||||||
|
"comp.warn4": "Are you sure you want to unregister yourself?",
|
||||||
|
"comp_manage": "Competitions Manager",
|
||||||
|
"competition_one": "Competition",
|
||||||
|
"competition_other": "Competitions",
|
||||||
|
"compte": "Account",
|
||||||
|
"compétition": "Competition",
|
||||||
|
"configuration": "Configuration",
|
||||||
|
"configurationDeLaCatégorie": "Category configuration",
|
||||||
|
"conserverLancienEmail": "Keep the old email",
|
||||||
|
"contactAdministratif": "Administrative contact",
|
||||||
|
"contactInterne": "Internal contact",
|
||||||
|
"contact_one": "Contact",
|
||||||
|
"contact_other": "Contacts",
|
||||||
|
"coquilleProtectionPelvienne": "Shell / Pelvic protection",
|
||||||
|
"date": "Date",
|
||||||
|
"dateDeNaissance": "Date of birth",
|
||||||
|
"days": [
|
||||||
|
"Monday",
|
||||||
|
"Tuesday",
|
||||||
|
"Wednesday",
|
||||||
|
"Thursday",
|
||||||
|
"Friday",
|
||||||
|
"Saturday",
|
||||||
|
"Sunday"
|
||||||
|
],
|
||||||
|
"de": "of",
|
||||||
|
"demandeDaffiliationEnCours": "Affiliation request in progress",
|
||||||
|
"demandeDeLicence": "License request",
|
||||||
|
"demander": "Request",
|
||||||
|
"description": "Description",
|
||||||
|
"dlAff": "Download affiliation certificate",
|
||||||
|
"donnéesAdministratives": "Administrative data",
|
||||||
|
"du": "From",
|
||||||
|
"dun": "of a",
|
||||||
|
"duréePause": "Pause duration",
|
||||||
|
"duréeRound": "Round duration",
|
||||||
|
"définirLidDuCompte": "Define account ID",
|
||||||
|
"editionDeL'affiliation": "Editing affiliation",
|
||||||
|
"editionDeLaDemande": "Editing request",
|
||||||
|
"editionDeLaLicence": "Editing license",
|
||||||
|
"editionDeLaSéléction": "Editing selection",
|
||||||
|
"editionDeLadresse": "Editing address",
|
||||||
|
"email": "Email",
|
||||||
|
"en": "in",
|
||||||
|
"enAttente": "Pending",
|
||||||
|
"erreurDePaiement": "Payment error😕",
|
||||||
|
"erreurDePaiement.detail": "Error message:",
|
||||||
|
"erreurDePaiement.msg": "An error occurred while processing your payment. Please try again later.",
|
||||||
|
"erreurPourLinscription": "Registration error",
|
||||||
|
"espaceAdministration": "Administration space",
|
||||||
|
"f": "F",
|
||||||
|
"faitPar": "Done by",
|
||||||
|
"femme": "Female",
|
||||||
|
"fileImport.variants": {
|
||||||
|
"categorie": [
|
||||||
|
"category",
|
||||||
|
"catégorie",
|
||||||
|
"weight category",
|
||||||
|
"age category"
|
||||||
|
],
|
||||||
|
"club": [
|
||||||
|
"club",
|
||||||
|
"club name",
|
||||||
|
"association",
|
||||||
|
"association name"
|
||||||
|
],
|
||||||
|
"genre": [
|
||||||
|
"gender",
|
||||||
|
"genre",
|
||||||
|
"sex",
|
||||||
|
"civility"
|
||||||
|
],
|
||||||
|
"licence": [
|
||||||
|
"license",
|
||||||
|
"licence",
|
||||||
|
"license number",
|
||||||
|
"license ID",
|
||||||
|
"ID license",
|
||||||
|
"licence no"
|
||||||
|
],
|
||||||
|
"nom": [
|
||||||
|
"last name",
|
||||||
|
"nom",
|
||||||
|
"family name",
|
||||||
|
"surname",
|
||||||
|
"lastname"
|
||||||
|
],
|
||||||
|
"overCategory": [
|
||||||
|
"over category",
|
||||||
|
"surclassement",
|
||||||
|
"category override",
|
||||||
|
"over classification"
|
||||||
|
],
|
||||||
|
"pays": [
|
||||||
|
"country",
|
||||||
|
"pays",
|
||||||
|
"country of residence",
|
||||||
|
"origin country"
|
||||||
|
],
|
||||||
|
"prenom": [
|
||||||
|
"first name",
|
||||||
|
"prénom",
|
||||||
|
"given name",
|
||||||
|
"first given name"
|
||||||
|
],
|
||||||
|
"weight": [
|
||||||
|
"weight",
|
||||||
|
"poids",
|
||||||
|
"weight (kg)",
|
||||||
|
"actual weight",
|
||||||
|
"mass"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"filtre": "Filter",
|
||||||
|
"gantMainBouclier": "Shield hand glove",
|
||||||
|
"gantMainsArmées": "Armed hand(s) glove(s)",
|
||||||
|
"gants": "Gloves",
|
||||||
|
"genre": "Gender",
|
||||||
|
"gestionGroupée": "Group management",
|
||||||
|
"gorgerin": "Gorgerin",
|
||||||
|
"gradeDarbitrage": "Refereeing grade",
|
||||||
|
"h": "M",
|
||||||
|
"home": {
|
||||||
|
"header1": "For licensed members",
|
||||||
|
"header2": "For clubs",
|
||||||
|
"text1": "Here you will find all your information as well as the status of your registration with the federation. You can also download your registration certificate, register for competitions, and consult your results, provided that the organizing club has entered them.<br/><br/>During your first registration, you will receive an email containing your login information; this email will be sent once your license is validated by the secretariat.",
|
||||||
|
"text2": "This is where you can take out federal licenses for your members, where you can request or renew your affiliation, enter your schedules, training locations, and social networks, which will then be displayed on the ffsaf.fr website.<br/>You will also have the possibility to publish registration forms for your competitions and to record the results.<br/><br/>Not yet affiliated with the federation? Click <1>here</1> to make your first request.",
|
||||||
|
"welcome_message": "Welcome to the intranet of the Fédération France Soft Armored Fighting"
|
||||||
|
},
|
||||||
|
"homme": "Male",
|
||||||
|
"horairesD'entraînements": "Training schedules",
|
||||||
|
"importationDuFichier": "Importing the file",
|
||||||
|
"importerDesCombattants": "Import fighters",
|
||||||
|
"importerDesInvités": "Import guests",
|
||||||
|
"information": "Information",
|
||||||
|
"invité": "guest",
|
||||||
|
"keepEmpty": "Leave blank to make no changes.",
|
||||||
|
"le": "the",
|
||||||
|
"licence": "License",
|
||||||
|
"licenceNo": "License no. {{no}}",
|
||||||
|
"lieu": "Place",
|
||||||
|
"lieuxDentraînements": "Training locations",
|
||||||
|
"ligneIgnorée1": "Line ignored: missing name, first name or category.",
|
||||||
|
"ligneIgnorée2": "Line ignored: missing first name or license.",
|
||||||
|
"loading": "Loading...",
|
||||||
|
"me": {
|
||||||
|
"result": {
|
||||||
|
"PRIVATE": "Private (visible only to me)",
|
||||||
|
"PUBLIC": "Public (visible to all)",
|
||||||
|
"REGISTERED_ONLY": "Logged-in members (visible to federation members)",
|
||||||
|
"REGISTERED_ONLY_NO_DETAILS": "Logged-in members - hide details (visible to federation members)"
|
||||||
|
},
|
||||||
|
"toast.settings.error": "Failed to update settings 😕",
|
||||||
|
"toast.settings.pending": "Updating settings in progress...",
|
||||||
|
"toast.settings.success": "Settings updated successfully 🎉"
|
||||||
|
},
|
||||||
|
"me.changerMonMotDePasse": "Change my password",
|
||||||
|
"me.formationDarbitrage": "Refereeing training",
|
||||||
|
"me.paramètresDuCompte": "Account settings",
|
||||||
|
"me.rôleAuSienDuClub": "Role within the club",
|
||||||
|
"me.visibilitéDesRésultats": "Visibility of results",
|
||||||
|
"member_one": "Member",
|
||||||
|
"member_other": "Members",
|
||||||
|
"membre.emailVideàLaLigne": "Empty email on line {{no}}",
|
||||||
|
"membre.emailVérifié": "Email verified",
|
||||||
|
"membre.filtre.inactif": "Show inactive fighters",
|
||||||
|
"membre.filtre.licence": "Show license status",
|
||||||
|
"membre.filtre.licences": [
|
||||||
|
"No request or valid license",
|
||||||
|
"With request or valid license",
|
||||||
|
"Request in progress",
|
||||||
|
"License validated",
|
||||||
|
"All license statuses",
|
||||||
|
"Complete request",
|
||||||
|
"Incomplete request"
|
||||||
|
],
|
||||||
|
"membre.filtre.payement": [
|
||||||
|
"Without payment",
|
||||||
|
"With payment",
|
||||||
|
"All payment statuses"
|
||||||
|
],
|
||||||
|
"membre.identifiant": "Identifier",
|
||||||
|
"membre.import.err1": "Invalid medical certificate date format on line {{no}}",
|
||||||
|
"membre.import.err2": "Invalid medical certificate date format on line {{no}}",
|
||||||
|
"membre.import.err3": "Empty date of birth on line {{no}}",
|
||||||
|
"membre.import.err4": "Invalid date of birth format on line {{no}}",
|
||||||
|
"membre.import.err5": "Invalid email on line {{no}}",
|
||||||
|
"membre.import.errTT_one": "{{count}} error in the file, operation cancelled",
|
||||||
|
"membre.import.errTT_other": "{{count}} errors in the file, operation cancelled",
|
||||||
|
"membre.import.warn_one": "{{count}} medical certificate not filled",
|
||||||
|
"membre.import.warn_other": "{{count}} medical certificates not filled",
|
||||||
|
"membre.info.emailInfo": "The email is used to create an account to log in to the site and must be unique.<br/>For minors, the parents' email can be used multiple times using the following syntax: {'email.parent+<alphanumeric characters>@example.com'}.<br/>Examples: mail.parent+1@example.com, mail.parent+titouan@example.com, mail.parent+cedrique@example.com",
|
||||||
|
"membre.info.error1": "Please select a valid country 😕",
|
||||||
|
"membre.info.error2": "Please select a valid club 😕",
|
||||||
|
"membre.initaccount": "Initialize account",
|
||||||
|
"membre.initaccount.text1": "Enter the account UUID",
|
||||||
|
"membre.initaccount.text2": "Warning: only change a member's ID if you are sure of what you are doing...",
|
||||||
|
"membre.noAccount": "This member does not have an account...",
|
||||||
|
"membre.noAccount.clubMsg": "An account will be created by the federation when their first license is validated",
|
||||||
|
"membre.nomVideàLaLigne": "Empty last name on line {{no}}",
|
||||||
|
"membre.prénomVideàLaLigne": "Empty first name on line {{no}}",
|
||||||
|
"membre.toast.compte.created": "Account created successfully 🎉",
|
||||||
|
"membre.toast.compte.error": "Failed to create account",
|
||||||
|
"membre.toast.compte.pending": "Creating account in progress",
|
||||||
|
"membre.toast.del.error": "Failed to delete account",
|
||||||
|
"membre.toast.del.pending": "Deleting account in progress",
|
||||||
|
"membre.toast.del.success": "Account deleted successfully 🎉",
|
||||||
|
"membre.toast.id.error": "Failed to define identifier",
|
||||||
|
"membre.toast.id.pending": "Defining identifier in progress",
|
||||||
|
"membre.toast.id.success": "Identifier defined successfully 🎉",
|
||||||
|
"membre.toast.licence.ask.del.error": "Failed to delete license request",
|
||||||
|
"membre.toast.licence.ask.del.pending": "Deleting license request in progress",
|
||||||
|
"membre.toast.licence.ask.del.success": "License request deleted successfully 🎉",
|
||||||
|
"membre.toast.licence.ask.error": "Failed to request license",
|
||||||
|
"membre.toast.licence.ask.pending": "Saving license request in progress",
|
||||||
|
"membre.toast.licence.ask.success": "License request saved successfully 🎉",
|
||||||
|
"membre.toast.licence.del.error": "Failed to delete license",
|
||||||
|
"membre.toast.licence.del.pending": "Deleting license in progress",
|
||||||
|
"membre.toast.licence.del.success": "License deleted successfully 🎉",
|
||||||
|
"membre.toast.licence.save.error": "Failed to save license",
|
||||||
|
"membre.toast.licence.save.pending": "Saving license in progress",
|
||||||
|
"membre.toast.licence.save.success": "License saved successfully 🎉",
|
||||||
|
"membre.toast.licences.export.error": "Failed to export licenses",
|
||||||
|
"membre.toast.licences.export.pending": "Exporting licenses in progress",
|
||||||
|
"membre.toast.licences.export.success": "Licenses exported successfully 🎉",
|
||||||
|
"membre.toast.licences.import.error": "Failed to send changes",
|
||||||
|
"membre.toast.licences.import.pending": "Sending changes in progress",
|
||||||
|
"membre.toast.licences.import.success": "Changes sent successfully 🎉",
|
||||||
|
"membre.toast.licences.load.error": "Failed to load licenses",
|
||||||
|
"membre.toast.licences.load.pending": "Loading licenses in progress",
|
||||||
|
"membre.toast.licences.load.success": "Licenses loaded successfully 🎉",
|
||||||
|
"membre.toast.perm.error": "Failed to update permissions 😕",
|
||||||
|
"membre.toast.perm.pending": "Updating permissions in progress...",
|
||||||
|
"membre.toast.perm.success": "Permissions updated successfully 🎉",
|
||||||
|
"membre.toast.save.error": "Failed to update profile 😕",
|
||||||
|
"membre.toast.save.pending": "Updating profile in progress...",
|
||||||
|
"membre.toast.save.success": "Profile updated successfully 🎉",
|
||||||
|
"membre.toast.select.del.error": "Failed to delete selection",
|
||||||
|
"membre.toast.select.del.pending": "Deleting selection in progress",
|
||||||
|
"membre.toast.select.del.success": "Selection deleted successfully 🎉",
|
||||||
|
"membre.toast.select.save.error": "Failed to save selection",
|
||||||
|
"membre.toast.select.save.pending": "Saving selection in progress",
|
||||||
|
"membre.toast.select.save.success": "Selection saved successfully 🎉",
|
||||||
|
"mettreàJours": "Update",
|
||||||
|
"modification": "Modification",
|
||||||
|
"nationalité": "Nationality",
|
||||||
|
"nav": {
|
||||||
|
"account": "My account",
|
||||||
|
"aff_request": "Affiliation request",
|
||||||
|
"club": {
|
||||||
|
"my": "My club"
|
||||||
|
},
|
||||||
|
"competitions": {
|
||||||
|
"results": "My results"
|
||||||
|
},
|
||||||
|
"home": "Home",
|
||||||
|
"login": "Login",
|
||||||
|
"logout": "Logout",
|
||||||
|
"space": "My space",
|
||||||
|
"title": "FFSAF Intranet"
|
||||||
|
},
|
||||||
|
"noLicence": "License no.",
|
||||||
|
"noSiretOuRna": "SIRET or RNA no.",
|
||||||
|
"nom": "Last name",
|
||||||
|
"nombreDeLicences": "Number of licenses",
|
||||||
|
"nombreDeLicencesParCatégorie": "Number of licenses by category for {{saison}}",
|
||||||
|
"non": "No",
|
||||||
|
"nonDéfinie": "Not defined",
|
||||||
|
"nonValidée": "Not validated",
|
||||||
|
"nouveauClub": "New club",
|
||||||
|
"nouveauMembre": "New member",
|
||||||
|
"nouvelEmail": "New email",
|
||||||
|
"numéroDeLaLigneDentête": "Header line number",
|
||||||
|
"numéroDeLigne": "Line number",
|
||||||
|
"ou": "or",
|
||||||
|
"oui": "Yes",
|
||||||
|
"outdated_session": {
|
||||||
|
"login_button": "Log in again",
|
||||||
|
"message": "Your session has expired, please log in again to continue using the application.",
|
||||||
|
"title": "Session expired"
|
||||||
|
},
|
||||||
|
"pageClub": "Club page",
|
||||||
|
"pageMembre": "Member page",
|
||||||
|
"pageNouveauClub": "New club page",
|
||||||
|
"page_info_full": "Line {{line}} to {{tt_line}} (page {{page}} of {{tt_page}})",
|
||||||
|
"page_info_ligne": "{{show}} line(s) displayed out of {{total}}",
|
||||||
|
"paiementDeLaLicence": "License payment",
|
||||||
|
"paiementDesLicences": "License payments",
|
||||||
|
"par": "by",
|
||||||
|
"pasDeLicence": "No license",
|
||||||
|
"payment.ha.info": "HelloAsso's solidarity model guarantees that 100% of your payment will be transferred to the chosen association. You can support the help they provide to associations by leaving a voluntary contribution to HelloAsso at the time of your payment.",
|
||||||
|
"payment.info": "About HelloAsso",
|
||||||
|
"payment.paiementSécurisé": "Secure payment",
|
||||||
|
"payment.payerAvec": "Pay with",
|
||||||
|
"payment.recap": "{{count}} license(s) selected<br/>Total amount to pay: {{total}} €",
|
||||||
|
"paymentDesLicences": "License payments",
|
||||||
|
"paymentDesLicences.msg_one": "Are you sure you want to mark the license as paid?",
|
||||||
|
"paymentDesLicences.msg_other": "Are you sure you want to mark the {{count}} licenses as paid?",
|
||||||
|
"paymentDesLicences.msg_zero": "$t(paymentDesLicences.msg_other)",
|
||||||
|
"paymentOk": "🎉Your payment has been processed successfully.🎉",
|
||||||
|
"paymentOk.msg": "Thank you for your payment. The licenses should be activated within the next hour, provided that the medical certificate is completed.",
|
||||||
|
"pays": "Country",
|
||||||
|
"perm.administrateurDeLaFédération": "Federation administrator",
|
||||||
|
"perm.créerDesCompétion": "Create competitions",
|
||||||
|
"perm.ffsafIntra": "FFSAF intra",
|
||||||
|
"permission": "Permission",
|
||||||
|
"peutSinscrire": "Can register?",
|
||||||
|
"photos": "Photos",
|
||||||
|
"plastron": "Breastplate",
|
||||||
|
"poids": "Weight",
|
||||||
|
"poidsDemandéPour": "Weight required for",
|
||||||
|
"prenom": "First name",
|
||||||
|
"protectionDeBras": "Arm protection",
|
||||||
|
"protectionDeBrasArmé": "Protection of armed arm(s)",
|
||||||
|
"protectionDeBrasDeBouclier": "Shield arm protection",
|
||||||
|
"protectionDeCoudes": "Elbow protection",
|
||||||
|
"protectionDeGenoux": "Knee protection",
|
||||||
|
"protectionDeJambes": "Leg protection",
|
||||||
|
"protectionDePieds": "Foot protection",
|
||||||
|
"protectionDorsale": "Back protector",
|
||||||
|
"protectionObligatoire": "Mandatory protection",
|
||||||
|
"prénomEtNom": "First and last name",
|
||||||
|
"rechercher": "Search",
|
||||||
|
"rechercher...": "Search...",
|
||||||
|
"registration_one": "Registration",
|
||||||
|
"registration_other": "Registrations",
|
||||||
|
"renouveler": "Renew",
|
||||||
|
"renouvellementDeLaffiliation": "Affiliation renewal",
|
||||||
|
"result_one": "Result",
|
||||||
|
"result_other": "Results",
|
||||||
|
"retouràLaListeDeMembres": "Back to member list",
|
||||||
|
"role": "Role",
|
||||||
|
"role.membre": "Member",
|
||||||
|
"role.membreDuBureau": "Board member",
|
||||||
|
"role.président": "President",
|
||||||
|
"role.secrétaire": "Secretary",
|
||||||
|
"role.trésorier": "Treasurer",
|
||||||
|
"role.vise-président": "Vice-President",
|
||||||
|
"role.vise-secrétaire": "Vice-Secretary",
|
||||||
|
"role.vise-trésorier": "Vice-Treasurer",
|
||||||
|
"saison": "Season",
|
||||||
|
"sans": "Without",
|
||||||
|
"secrétariatsDeLice": "Ring secretariats",
|
||||||
|
"selectionner...": "Select...",
|
||||||
|
"shield.buckler": "Buckler",
|
||||||
|
"shield.none": "$t(sans) / $t(nonDéfinie)",
|
||||||
|
"shield.round": "Round",
|
||||||
|
"shield.standard": "Standard",
|
||||||
|
"shield.teardrop": "Teardrop",
|
||||||
|
"siDisponiblePourLaCatégorieDages": "If available for the age category",
|
||||||
|
"siretOuRna": "SIRET or RNA",
|
||||||
|
"stats": "Statistics",
|
||||||
|
"statue": "Statue",
|
||||||
|
"status": "Status",
|
||||||
|
"statuts": "Statutes",
|
||||||
|
"supprimerLeClub": "Delete club",
|
||||||
|
"supprimerLeClub.msg": "Are you sure you want to delete this club?",
|
||||||
|
"supprimerLeCompte": "Delete account",
|
||||||
|
"supprimerLeCompte.msg": "Are you sure you want to delete this account?",
|
||||||
|
"sword.none": "$t(sans) / $t(nonDéfinie)",
|
||||||
|
"sword.oneHand": "One hand sword",
|
||||||
|
"sword.saber": "Saber",
|
||||||
|
"sword.twoHand": "Two hands sword",
|
||||||
|
"sélectionEnéquipeDeFrance": "Selection in the French team",
|
||||||
|
"sélectionner...": "Select...",
|
||||||
|
"toast.edit.error": "Failed to save changes",
|
||||||
|
"toast.edit.pending": "Saving changes in progress",
|
||||||
|
"toast.edit.success": "Changes saved successfully 🎉",
|
||||||
|
"toast.licence.bulk.pay.error": "Failed to mark licenses as paid",
|
||||||
|
"toast.licence.bulk.pay.pending": "Marking licenses as paid in progress",
|
||||||
|
"toast.licence.bulk.pay.success": "Licenses marked as paid successfully 🎉",
|
||||||
|
"toast.licence.bulk.valid.error": "Failed to validate licenses",
|
||||||
|
"toast.licence.bulk.valid.pending": "Validating licenses in progress",
|
||||||
|
"toast.licence.bulk.valid.success": "Licenses validated successfully 🎉",
|
||||||
|
"toast.licence.order.error": "Failed to create order",
|
||||||
|
"toast.licence.order.pending": "Creating order in progress",
|
||||||
|
"toast.licence.order.success": "Order created successfully 🎉",
|
||||||
|
"trie": "Sort",
|
||||||
|
"téléchargerLexcelDesMembres": "Download members' Excel",
|
||||||
|
"téléchargerLexcelDesMembres.info": "To be used as a template to update information",
|
||||||
|
"téléchargéeLaLicence": "Download license",
|
||||||
|
"validationDeLaLicence": "License validation",
|
||||||
|
"validationDesLicences": "License validations",
|
||||||
|
"validerDesLicences": "Validate licenses",
|
||||||
|
"validerLePayement_one": "Validate payment for the selected license",
|
||||||
|
"validerLePayement_other": "Validate payment for the {{count}} selected licenses",
|
||||||
|
"validerLePayement_zero": "$t(validerLePayement_other)",
|
||||||
|
"validerLicence.msg_one": "Are you sure you want to validate the license?",
|
||||||
|
"validerLicence.msg_other": "Are you sure you want to validate the {{count}} licenses?",
|
||||||
|
"validerLicence.msg_zero": "$t(validerLicence.msg_other)",
|
||||||
|
"validerLicence_one": "Validate the selected license",
|
||||||
|
"validerLicence_other": "Validate the {{count}} selected licenses",
|
||||||
|
"validerLicence_zero": "$t(validerLicence_other)",
|
||||||
|
"validée": "Validated",
|
||||||
|
"veuillezAssocierChaqueChampàUneColonneDuFichier": "Please associate each field with a column in the file",
|
||||||
|
"veuillezIndiqueràQuelle": "Please indicate on which line the headers are located in the file",
|
||||||
|
"veuillezMapperLesColonnesSuivantes": "Please map the following columns",
|
||||||
|
"voir/modifierLesParticipants": "View/Edit participants",
|
||||||
|
"voirLesStatues": "View statues",
|
||||||
|
"vousNêtesPasEncoreInscrit": "You are not yet registered or your registration has not yet been entered on the intranet",
|
||||||
|
"à": "at",
|
||||||
|
"étatDeLaDemande": "Request status"
|
||||||
|
}
|
||||||
75
src/main/webapp/public/locales/en/result.json
Normal file
75
src/main/webapp/public/locales/en/result.json
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"--sélectionnerUnClub--": "--Select a club--",
|
||||||
|
"--sélectionnerUnCombattant--": "--Select a fighter--",
|
||||||
|
"--sélectionnerUneCatégorie--": "--Select a category--",
|
||||||
|
"1er": "Gold medal",
|
||||||
|
"2eme": "Silver medal",
|
||||||
|
"3eme": "Bronze medal",
|
||||||
|
"abs.": "abs.",
|
||||||
|
"adversaire": "Opponent",
|
||||||
|
"aujourdhuià": "Today at {{time}}",
|
||||||
|
"avanthierà": "Day before yesterday at {{time}}",
|
||||||
|
"back": "« back",
|
||||||
|
"bleu": "Blue",
|
||||||
|
"catégorie": "Category",
|
||||||
|
"chargement": "Loading",
|
||||||
|
"classement": "Ranking",
|
||||||
|
"classementClub": "Club ranking",
|
||||||
|
"classementDesClub": "Clubs ranking",
|
||||||
|
"classementFinal": "Final ranking",
|
||||||
|
"club": "Club",
|
||||||
|
"combattant": "Fighter",
|
||||||
|
"combattants": "Fighters",
|
||||||
|
"date": "Date",
|
||||||
|
"disc.": "DQ",
|
||||||
|
"défaites": "Losses",
|
||||||
|
"erreurDeChargementDeLaListe": "Error loading the list",
|
||||||
|
"erreurDeChargementDeLaPoule": "Error loading the pool",
|
||||||
|
"erreurDeChargementDesCatégories": "Error loading categories",
|
||||||
|
"erreurDeChargementDesClubs": "Error loading clubs",
|
||||||
|
"erreurDeChargementDesCombattants": "Error loading fighters",
|
||||||
|
"erreurDeChargementDuClub": "Error loading club",
|
||||||
|
"erreurDeChargementDuCombattant": "Error loading fighter",
|
||||||
|
"for.": "forf.",
|
||||||
|
"hierà": "Yesterday at {{time}}",
|
||||||
|
"info": "Info",
|
||||||
|
"listeDesCombattants": "List of fighters",
|
||||||
|
"listeDesMatchs": "List of matches",
|
||||||
|
"listeDesMembres": "List of members",
|
||||||
|
"listeDesMenbres": "List of members",
|
||||||
|
"nom": "Last name",
|
||||||
|
"nomPrénom": "Last name First name",
|
||||||
|
"nombreDeMatchDisputé2": "Number of matches played: {{nb}}",
|
||||||
|
"nombreDeVictoires2": "Number of wins: {{nb}}",
|
||||||
|
"nombreDinscris": "Number of registered",
|
||||||
|
"nombreDinscris2": "Number of registered: {{nb}}",
|
||||||
|
"parCatégorie": "By category",
|
||||||
|
"parClub": "By club",
|
||||||
|
"parCombattant": "By fighter",
|
||||||
|
"place": "Place",
|
||||||
|
"pointsMarqués": "Points scored",
|
||||||
|
"pointsMarqués2": "Points scored: {{nb}}",
|
||||||
|
"pointsReçus": "Points received",
|
||||||
|
"pointsReçus2": "Points received: {{nb}}",
|
||||||
|
"poule": "Pool",
|
||||||
|
"ratio": "Ratio",
|
||||||
|
"ratioDePointsMoyen2": "Average points ratio: {{nb}}",
|
||||||
|
"ratioDeVictoiresMoyen2": "Average win ratio: {{nb}}",
|
||||||
|
"ratioDuScore2": "Score ratio (points scored / points received): {{nb}}",
|
||||||
|
"ratioPoints": "Points ratio",
|
||||||
|
"ratioVictoires": "Win ratio",
|
||||||
|
"ratiosPoints": "Points ratios",
|
||||||
|
"rechercheParCatégorie": "Search by category",
|
||||||
|
"rechercheParClub": "Search by club",
|
||||||
|
"rechercheParCombattant": "Search by fighter",
|
||||||
|
"rouge": "Red",
|
||||||
|
"résultatDeLaCompétition": "Competition result",
|
||||||
|
"score": "Score",
|
||||||
|
"scores": "Scores",
|
||||||
|
"statistique": "Statistics",
|
||||||
|
"tauxDeVictoire2": "Win rate: {{nb}}% ({{victoires}} out of {{matchs}})",
|
||||||
|
"tournois": "Tournaments",
|
||||||
|
"tousLesCombattants": "All fighters",
|
||||||
|
"victoire": "Win",
|
||||||
|
"victoires": "Wins"
|
||||||
|
}
|
||||||
213
src/main/webapp/public/locales/fr/cm.json
Normal file
213
src/main/webapp/public/locales/fr/cm.json
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
{
|
||||||
|
"--SélectionnerUnCombattant--": "-- Sélectionner un combattant --",
|
||||||
|
"--Tous--": "-- Tous --",
|
||||||
|
"PourLéquipe": " pour l'équipe",
|
||||||
|
"actuel": "Actuel",
|
||||||
|
"administration": "Administration",
|
||||||
|
"adresseDuServeur": "Adresse du serveur",
|
||||||
|
"afficher": "Afficher",
|
||||||
|
"ajoutAutomatique": "Ajout automatique",
|
||||||
|
"ajouter": "Ajouter",
|
||||||
|
"ajouterDesCombattants": "Ajouter des combattants",
|
||||||
|
"ajouterUn": "Ajouter un ",
|
||||||
|
"ajouterUneTeam": "Ajouter une équipe",
|
||||||
|
"attention": "Attention",
|
||||||
|
"aucuneConfigurationObs": "Aucune configuration OBS trouvée, veuillez en importer une",
|
||||||
|
"avertissement": "Avertissement",
|
||||||
|
"bleu": "Bleu",
|
||||||
|
"blue": "Blue",
|
||||||
|
"cardAdded": "Carton ajouté",
|
||||||
|
"cardRemoved": "Carton retiré",
|
||||||
|
"carton": "Carton",
|
||||||
|
"cartonDéquipe": "Carton d'équipe",
|
||||||
|
"cartonJaune": "Carton jaune",
|
||||||
|
"cartonNoir": "Carton noir",
|
||||||
|
"cartonRouge": "Carton rouge",
|
||||||
|
"catégorie": "Catégorie",
|
||||||
|
"catégorieDâgeMoyenne": "Catégorie d'âge moyenne",
|
||||||
|
"catégorieSélectionnée": "Catégorie sélectionnée",
|
||||||
|
"catégoriesVontêtreCréées": "catégories de poids vont être créées",
|
||||||
|
"ceCartonEstIssuDunCartonDéquipe": "Ce carton est issu d'un carton d'équipe, voulez-vous vraiment le supprimer ?",
|
||||||
|
"certainsCombattantsNontPasDePoidsRenseigné": "Certains combattants n'ont pas de poids renseigné, ils ne seront PAS insert dans les catégories",
|
||||||
|
"chrono.+/-...S": "+/- ... s",
|
||||||
|
"chrono.+10S": "+10 s",
|
||||||
|
"chrono.+1S": "+1 s",
|
||||||
|
"chrono.-10S": "-10 s",
|
||||||
|
"chrono.-1S": "-1 s",
|
||||||
|
"chrono.arrêter": "Arrêter",
|
||||||
|
"chrono.définirLeTemps": "Définir le temps",
|
||||||
|
"chrono.démarrer": "Démarrer",
|
||||||
|
"chrono.editionTemps": "Edition temps",
|
||||||
|
"chrono.entrezLeTempsEnS": "Entrez le temps en s",
|
||||||
|
"chrono.recapTemps": "Temps: {{temps}}, pause: {{pause}}",
|
||||||
|
"chronomètre": "Chronomètre",
|
||||||
|
"classement": "Classement",
|
||||||
|
"club": "Club",
|
||||||
|
"combattantsCorrespondentAuxSélectionnés": "combattant(s) correspondent aux sélections ci-dessus.",
|
||||||
|
"compétition": "Compétition",
|
||||||
|
"compétitionManager": "Compétition manager",
|
||||||
|
"config.obs.dossierDesResources": "Dossier des resources",
|
||||||
|
"config.obs.motDePasseDuServeur": "Mot de passe du serveur",
|
||||||
|
"config.obs.warn1": "/! Le mot de passe va être stoker en claire, il est recommandé de ne l'utiliser que sur obs websocket et d'en changer entre chaque compétition",
|
||||||
|
"config.obs.ws": "ws://",
|
||||||
|
"configurationDuNomDeLaZone": "Configuration du nom de la zone",
|
||||||
|
"configurationObs": "Configuration OBS",
|
||||||
|
"confirm1": "Ce match a déjà des résultats, êtes-vous sûr de vouloir le supprimer ?",
|
||||||
|
"confirm2.msg": "Voulez-vous vraiment changer la taille de l'arbre du tournoi ou les matchs pour les perdants ? Cela va modifier les matchs existants (incluant des possibles suppressions)!",
|
||||||
|
"confirm2.title": "Changement de l'arbre du tournoi",
|
||||||
|
"confirm3.msg": "Voulez-vous vraiment enlever la partie {{typeStr}} de la catégorie. Cela va supprimer les matchs contenus dans cette partie !",
|
||||||
|
"confirm3.title": "Changement de type de catégorie",
|
||||||
|
"confirm4.msg": "Voulez-vous vraiment supprimer la catégorie {{name}}. Cela va supprimer tous les matchs associés !",
|
||||||
|
"confirm4.title": "Suppression de la catégorie",
|
||||||
|
"confirmer": "Confirmer",
|
||||||
|
"conserverUniquementLesMatchsTerminés": "Conserver uniquement les matchs terminés",
|
||||||
|
"contre": "contre",
|
||||||
|
"couleur": "Couleur",
|
||||||
|
"créationDeLaLesCatégories": "Création de la/les catégories",
|
||||||
|
"créerLaPhaseFinaleSilYADesPoules": "Créer la phase finale s'il y a des poules",
|
||||||
|
"créerLesMatchesDeClassement": "Créer les matches de classement",
|
||||||
|
"créerLesMatchesDeClassement.msg": "Des matches de classement ont déjà été configurer/jouer, la recréation de ces matches vont tous les supprimer (vous perdre donc les résultats s'il y en a). Mercie de noter de votre côté les informations que vous voulez conserver.",
|
||||||
|
"créerLesMatchs": "Créer les matchs",
|
||||||
|
"créerToutesLesCatégories": "Créer toutes les catégories",
|
||||||
|
"date": "Date",
|
||||||
|
"demi-finalesEtFinales": "Demi-finales et finales",
|
||||||
|
"depuisUneCatégoriePrédéfinie": "Depuis une catégorie prédéfinie",
|
||||||
|
"duréePause": "Durée pause",
|
||||||
|
"duréeRound": "Durée round",
|
||||||
|
"editionDeLaCatégorie": "Edition de la catégorie",
|
||||||
|
"editionDuMatch": "Edition du match",
|
||||||
|
"enregister": "Enregister",
|
||||||
|
"enregistrer": "Enregistrer",
|
||||||
|
"epéeBouclier": "Epée bouclier",
|
||||||
|
"err1": "Un combattant ne peut pas s'affronter lui-même !",
|
||||||
|
"err2": "Le format du nom des zones de combat est invalide. Veuillez séparer les noms par des ';'.",
|
||||||
|
"err3": "Au moins un type (poule ou tournoi) doit être sélectionné.",
|
||||||
|
"erreurLorsDeLaCopieDansLePresse": "Erreur lors de la copie dans le presse-papier : ",
|
||||||
|
"erreurLorsDeLaCréationDesMatchs": "Erreur lors de la création des matchs: ",
|
||||||
|
"etatDesTablesDeMarque": "Etat des tables de marque",
|
||||||
|
"exporter": "Exporter",
|
||||||
|
"fermer": "Fermer",
|
||||||
|
"feuilleVierge": "Feuille vierge",
|
||||||
|
"finalesUniquement": "Finales uniquement",
|
||||||
|
"genre": "Genre",
|
||||||
|
"genre.f": "F",
|
||||||
|
"genre.h": "H",
|
||||||
|
"genre.na": "NA",
|
||||||
|
"imprimer": "Imprimer",
|
||||||
|
"individuelle": "Individuelle",
|
||||||
|
"informationCatégorie": "Information catégorie",
|
||||||
|
"inscrit": "Inscrit",
|
||||||
|
"jusquauRang": "Jusqu'au rang",
|
||||||
|
"leTournoiServiraDePhaseFinaleAuxPoules": "Le tournoi servira de phase finale aux poules",
|
||||||
|
"lesCombattantsEnDehors": "Les combattants en dehors du tournoi auront un match de classement",
|
||||||
|
"lesCombattantsEnDehors2": "Les combattants en dehors du tournoi de classement auront un match de classement",
|
||||||
|
"listeDesCartons": "Liste des cartons",
|
||||||
|
"manche": "Manche",
|
||||||
|
"matchPourLesPerdantsDuTournoi": "Match pour les perdants du tournoi:",
|
||||||
|
"matchTerminé": "Match terminé",
|
||||||
|
"matches": "Matches",
|
||||||
|
"modeDeCréation": "Mode de création",
|
||||||
|
"modifier": "Modifier",
|
||||||
|
"msg1": "Il y a déjà des matchs dans cette poule, que voulez-vous faire avec ?",
|
||||||
|
"neRienConserver": "Ne rien conserver",
|
||||||
|
"no": "N°",
|
||||||
|
"nom": "Nom",
|
||||||
|
"nomDeLaZone": "Nom de la zone",
|
||||||
|
"nomDeLéquipe": "Nom de l'équipe",
|
||||||
|
"nomDesZonesDeCombat": "Nom des zones de combat <1>(séparée par des ';')</1>",
|
||||||
|
"nombreDeCombattants": "Nombre de combattants",
|
||||||
|
"nouvelle...": "Nouvelle...",
|
||||||
|
"obs.préfixDesSources": "Préfix des sources",
|
||||||
|
"pays": "Pays",
|
||||||
|
"personnaliser": "Personnaliser",
|
||||||
|
"podium": "Podium",
|
||||||
|
"podiumDesClubs": "Podium des clubs",
|
||||||
|
"poids": "Poids",
|
||||||
|
"poule": "Poule",
|
||||||
|
"poulePour": "Poule pour: ",
|
||||||
|
"préparation...": "Préparation...",
|
||||||
|
"quoiImprimer?": "Quoi imprimer ?",
|
||||||
|
"remplacer": "Remplacer",
|
||||||
|
"rouge": "Rouge",
|
||||||
|
"réinitialiser": "Réinitialiser",
|
||||||
|
"résultat": "Résultat",
|
||||||
|
"sansPoule": "Sans poule",
|
||||||
|
"sauvegarde": "Sauvegarde",
|
||||||
|
"sauvegarder": "Sauvegarder",
|
||||||
|
"score": "Score",
|
||||||
|
"score.err1": "Impossible de terminer un match nul en tournois.",
|
||||||
|
"score.spe": "Score speciaux : <br/>-997 : disqualifié <br/>-998 : absent <br/>-999 : forfait",
|
||||||
|
"scores": "Scores",
|
||||||
|
"secrétariatsDeLice": "Secrétariats de lice",
|
||||||
|
"select.aucunCombattantDisponible": "Aucun combattant disponible",
|
||||||
|
"select.aucunCombattantSélectionné": "Aucun combattant sélectionné",
|
||||||
|
"select.msg1": "(0 = désactivé)",
|
||||||
|
"select.recherche": "Recherche",
|
||||||
|
"select.sélectionnerDesCombatants": "Sélectionner des combatants",
|
||||||
|
"select.à": "à",
|
||||||
|
"serveur": "Serveur",
|
||||||
|
"source": "Source",
|
||||||
|
"suivant": "Suivant",
|
||||||
|
"supprimer": "Supprimer",
|
||||||
|
"supprimerUn": "Supprimer un",
|
||||||
|
"sélectionneLesModesDaffichage": "Sélectionne les modes d'affichage",
|
||||||
|
"sélectionner": "Sélectionner",
|
||||||
|
"taille": "Taille",
|
||||||
|
"team": "Équipe",
|
||||||
|
"terminé": "Terminé",
|
||||||
|
"texteCopiéDansLePresse": "Texte copié dans le presse-papier ! Collez-le dans une balise HTML sur votre WordPress.",
|
||||||
|
"toast.card.team.error": "Erreur lors de la modification du carton d'équipe",
|
||||||
|
"toast.card.team.pending": "Modification du carton d'équipe...",
|
||||||
|
"toast.card.team.success": "Carton d'équipe modifié !",
|
||||||
|
"toast.createCategory.error": "Erreur lors de la création de la catégorie",
|
||||||
|
"toast.createCategory.pending": "Création de la catégorie...",
|
||||||
|
"toast.createCategory.success": "Catégorie créée !",
|
||||||
|
"toast.deleteCategory.error": "Erreur lors de la suppression de la catégorie",
|
||||||
|
"toast.deleteCategory.pending": "Suppression de la catégorie...",
|
||||||
|
"toast.deleteCategory.success": "Catégorie supprimée !",
|
||||||
|
"toast.matchs.classement.create.error": "Erreur lors de la création des matchs de classement.",
|
||||||
|
"toast.matchs.classement.create.pending": "Création des matchs de classement en cours...",
|
||||||
|
"toast.matchs.classement.create.success": "Matchs de classement créés avec succès.",
|
||||||
|
"toast.matchs.create.error": "Erreur lors de la création des matchs.",
|
||||||
|
"toast.matchs.create.pending": "Création des matchs en cours...",
|
||||||
|
"toast.matchs.create.success": "Matchs créés avec succès.",
|
||||||
|
"toast.print.error": "Erreur lors de la génération du PDF",
|
||||||
|
"toast.print.pending": "Génération du PDF en cours...",
|
||||||
|
"toast.print.success": "PDF généré !",
|
||||||
|
"toast.team.update.error": "Erreur lors de la mise à jour de l'équipe",
|
||||||
|
"toast.team.update.pending": "Mise à jour de l'équipe...",
|
||||||
|
"toast.team.update.success": "Équipe mise à jour !",
|
||||||
|
"toast.updateCategory.error": "Erreur lors de la mise à jour de la catégorie",
|
||||||
|
"toast.updateCategory.pending": "Mise à jour de la catégorie...",
|
||||||
|
"toast.updateCategory.success": "Catégorie mise à jour !",
|
||||||
|
"toast.updateMatchScore.error": "Erreur lors de la mise à jour du score du match",
|
||||||
|
"toast.updateMatchScore.pending": "Mise à jour du score du match...",
|
||||||
|
"toast.updateMatchScore.success": "Score du match mis à jour !",
|
||||||
|
"toast.updateTrees.error": "Erreur lors de la mise à jour des arbres",
|
||||||
|
"toast.updateTrees.init.error": "Erreur lors de la création des arbres",
|
||||||
|
"toast.updateTrees.init.pending": "Création des arbres du tournoi...",
|
||||||
|
"toast.updateTrees.init.success": "Arbres créés !",
|
||||||
|
"toast.updateTrees.pending": "Mise à jour des arbres du tournoi...",
|
||||||
|
"toast.updateTrees.success": "Arbres mis à jour !",
|
||||||
|
"tournoi": "Tournoi",
|
||||||
|
"tournois": "Tournois",
|
||||||
|
"tousLesMatchs": "Tous les matchs",
|
||||||
|
"toutConserver": "Tout conserver",
|
||||||
|
"touteLaCatégorie": "Toute la catégorie",
|
||||||
|
"toutesLesCatégories": "Toutes les catégories",
|
||||||
|
"ttm.admin.obs": "Clique court : Télécharger les ressources. Clique long : Créer la configuration obs",
|
||||||
|
"ttm.admin.scripte": "Copier le scripte d'intégration",
|
||||||
|
"ttm.table.inverserLaPosition": "Inverser la position des combattants sur cette écran",
|
||||||
|
"ttm.table.obs": "Clique court : Charger la configuration et se connecter.",
|
||||||
|
"ttm.table.pub_aff": "Ouvrir l'affichage public",
|
||||||
|
"ttm.table.pub_score": "Afficher les scores sur l'affichage public",
|
||||||
|
"type": "Type",
|
||||||
|
"téléchargement": "Téléchargement",
|
||||||
|
"téléchargementEnCours": "Téléchargement en cours...",
|
||||||
|
"téléchargementTerminé!": "Téléchargement terminé !",
|
||||||
|
"uneCatégorie": "une catégorie",
|
||||||
|
"uneCatégorieNePeutContenirPlusDe10Combattants": "Une catégorie ne peut contenir plus de 10 combattants, veuillez créer des catégories de poids.",
|
||||||
|
"valider": "Valider",
|
||||||
|
"zone": "Zone",
|
||||||
|
"zoneDeCombat": "Zone de combat"
|
||||||
|
}
|
||||||
668
src/main/webapp/public/locales/fr/common.json
Normal file
668
src/main/webapp/public/locales/fr/common.json
Normal file
@@ -0,0 +1,668 @@
|
|||||||
|
{
|
||||||
|
"(optionnelle)": "(optionnelle)",
|
||||||
|
"---SansClub---": "--- sans club ---",
|
||||||
|
"---TousLesAges---": "--- tous les ages ---",
|
||||||
|
"---ToutLesClubs---": "--- tous les clubs ---",
|
||||||
|
"---ToutLesPays---": "--- tout les pays ---",
|
||||||
|
"---TouteLesCatégories---": "--- toute les catégories ---",
|
||||||
|
"--NonLicencier--": "-- Non licencier --",
|
||||||
|
"--SélectionnerCatégorie--": "-- Sélectionner catégorie --",
|
||||||
|
"1Catégorie": "+1 catégorie",
|
||||||
|
"2Catégorie": "+2 catégorie",
|
||||||
|
"LesModificationsNontEnregistrer": "/!\\ Les modifications n'ont pas encore été enregistré, cliqué sur enregistrer /!\\",
|
||||||
|
"activer": "Activer",
|
||||||
|
"admin": "Administration",
|
||||||
|
"administrateur": "Administrateur",
|
||||||
|
"adresse": "Adresse",
|
||||||
|
"adresseAdministrative": "Adresse administrative",
|
||||||
|
"aff.ancienNom": "Ancien nom: {{name}}",
|
||||||
|
"aff.byMembreSim": "Par Membre similaire",
|
||||||
|
"aff.byNewMenbre": "Par Nouveau membre",
|
||||||
|
"aff.byNoLicence": "Par n° de licence",
|
||||||
|
"aff.info1": "Ce club a déjà été affilié (affiliation n°{{no}})",
|
||||||
|
"aff.membreNo": "Membre n°{{no}}",
|
||||||
|
"aff.nomDuClub": "Nom du club",
|
||||||
|
"aff.raisonDuRefus": "Raison du refus",
|
||||||
|
"aff.raisonDuRefus.msg": "Veuillez indiquer la raison du refus",
|
||||||
|
"aff.refusConfirm": "Êtes-vous sûr de vouloir refuser cette demande ?",
|
||||||
|
"aff.refuserLaDemande": "Refuser la demande",
|
||||||
|
"aff.refuserLaDemande.detail": "Êtes-vous sûr de vouloir refuser cette demande ?",
|
||||||
|
"aff.submit.error1": "Veuillez saisir un numéro de licence valide pour le membre {{id}}",
|
||||||
|
"aff.submit.error2": "Veuillez saisir un numéro de licence valide pour le membre {{id}}",
|
||||||
|
"aff.submit.error3": "Veuillez saisir un email valide pour le membre {{id}}",
|
||||||
|
"aff.toast.accept.error": "Échec de l'acceptation de l'affiliation",
|
||||||
|
"aff.toast.accept.pending": "Acceptation de l'affiliation en cours",
|
||||||
|
"aff.toast.accept.success": "Affiliation acceptée avec succès 🎉",
|
||||||
|
"aff.toast.del.error": "Échec de la suppression de la demande d'affiliation",
|
||||||
|
"aff.toast.del.pending": "Suppression de la demande d'affiliation en cours",
|
||||||
|
"aff.toast.del.success": "Demande d'affiliation supprimée avec succès 🎉",
|
||||||
|
"aff.toast.del2.error": "Échec de la suppression de l'affiliation",
|
||||||
|
"aff.toast.del2.pending": "Suppression de l'affiliation en cours",
|
||||||
|
"aff.toast.del2.success": "Affiliation supprimée avec succès 🎉",
|
||||||
|
"aff.toast.save.error": "Échec de l'enregistrement de la demande d'affiliation",
|
||||||
|
"aff.toast.save.pending": "Enregistrement de la demande d'affiliation en cours",
|
||||||
|
"aff.toast.save.success": "Demande d'affiliation enregistrée avec succès 🎉",
|
||||||
|
"aff.toast.save2.error": "Échec de l'enregistrement de l'affiliation",
|
||||||
|
"aff.toast.save2.pending": "Enregistrement de l'affiliation en cours",
|
||||||
|
"aff.toast.save2.success": "Affiliation enregistrée avec succès 🎉",
|
||||||
|
"aff_req.appuyerSurRechercher": "Appuyer sur rechercher pour compléter",
|
||||||
|
"aff_req.association": "L'association",
|
||||||
|
"aff_req.button.cancel": "Annuler ma demande",
|
||||||
|
"aff_req.button.confirm": "Confirmer ma demande d'affiliation",
|
||||||
|
"aff_req.button.save": "Enregistrer les modifications",
|
||||||
|
"aff_req.denomination": "Dénomination",
|
||||||
|
"aff_req.disposeLicence": "Dispose déjà d'une licence",
|
||||||
|
"aff_req.error1": "Le rôle du membre {{i}} est obligatoire",
|
||||||
|
"aff_req.error2": "Le format du SIRET/RNA est invalide",
|
||||||
|
"aff_req.nomDeLassociation": "Nom de l'association",
|
||||||
|
"aff_req.text1": "L'affiliation est annuelle et valable pour une saison sportive : du 1er septembre au 31 août de l’année suivante.",
|
||||||
|
"aff_req.text2": "Pour s’affilier, une association sportive doit réunir les conditions suivantes :",
|
||||||
|
"aff_req.text2.li": [
|
||||||
|
"Avoir son siège social en France ou Principauté de Monaco",
|
||||||
|
"Être constituée conformément au chapitre 1er du titre II du livre 1er du Code du Sport",
|
||||||
|
"Poursuivre un objet social entrant dans la définition de l’article 1 des statuts de la Fédération",
|
||||||
|
"Disposer de statuts compatibles avec les principes d’organisation et de fonctionnement de la Fédération",
|
||||||
|
"Assurer en son sein la liberté d’opinion et le respect des droits de la défense, et s’interdire toute discrimination",
|
||||||
|
"Respecter les règles d’encadrement, d’hygiène et de sécurité établies par les règlements de la Fédération"
|
||||||
|
],
|
||||||
|
"aff_req.text3": "Après validation de votre demande, vous recevrez un identifiant et mot de passe provisoire pour accéder à votre espace FFSAF",
|
||||||
|
"aff_req.text4": "Notez que pour finaliser votre affiliation, il vous faudra :",
|
||||||
|
"aff_req.text4.li1": "Disposer d’au moins trois membres licenciés, dont le président",
|
||||||
|
"aff_req.text4.li2": "S'être acquitté des cotisations prévues par les règlements fédéraux",
|
||||||
|
"aff_req.text5": "Vous pourrez par la suite, ajouter des adresses visibles publiquement pour vos lieux d'entrainement",
|
||||||
|
"aff_req.text6": "Laissez vide pour ne rien changer. (Si un blason a déjà été envoyé lors de cette demande, il sera utilisé, sinon nous utiliserons celui de la précédant affiliation)",
|
||||||
|
"aff_req.text7": "Demande d'affiliation envoyée avec succès",
|
||||||
|
"aff_req.text8": "Une fois votre demande validée, vous recevrez un identifiant et mot de passe provisoire pour accéder à votre espace FFSAF",
|
||||||
|
"aff_req.toast.undo.error": "Échec de l'annulation de la demande d'affiliation",
|
||||||
|
"aff_req.toast.undo.pending": "Annulation de la demande d'affiliation en cours",
|
||||||
|
"aff_req.toast.undo.success": "Demande d'affiliation annulée avec succès 🎉",
|
||||||
|
"afficherLesCombattantsNonPesés": "Afficher les combattants non pesés",
|
||||||
|
"afficherLétatDesAffiliation": "Afficher l'état des affiliation",
|
||||||
|
"affiliation": "Affiliation",
|
||||||
|
"affiliationNo": "Affiliation n°{{no}}",
|
||||||
|
"ajout": "Ajout",
|
||||||
|
"ajouterUnClub": "Ajouter un club",
|
||||||
|
"ajouterUnMembre": "Ajouter un membre",
|
||||||
|
"all_season": "--- tout les saisons ---",
|
||||||
|
"ans": "ans",
|
||||||
|
"arme": "Arme",
|
||||||
|
"au": "au",
|
||||||
|
"aucun": "Aucun",
|
||||||
|
"aucunMembreSélectionné": "Aucun membre sélectionné",
|
||||||
|
"aucuneCatégorieDisponible": "Aucune catégorie disponible pour le moment.",
|
||||||
|
"back": "« retour",
|
||||||
|
"blason": "Blason",
|
||||||
|
"bouclier": "Bouclier",
|
||||||
|
"bureau": "Bureau",
|
||||||
|
"button.accepter": "Accepter",
|
||||||
|
"button.ajouter": "Ajouter",
|
||||||
|
"button.annuler": "Annuler",
|
||||||
|
"button.appliquer": "Appliquer",
|
||||||
|
"button.confirmer": "Confirmer",
|
||||||
|
"button.créer": "Créer",
|
||||||
|
"button.enregistrer": "Enregistrer",
|
||||||
|
"button.fermer": "Fermer",
|
||||||
|
"button.modifier": "Modifier",
|
||||||
|
"button.refuser": "Refuser",
|
||||||
|
"button.seDésinscrire": "Se désinscrire",
|
||||||
|
"button.suivant": "Suivant",
|
||||||
|
"button.supprimer": "Supprimer",
|
||||||
|
"casque": "Casque",
|
||||||
|
"cat.benjamin": "Benjamin",
|
||||||
|
"cat.cadet": "Cadet",
|
||||||
|
"cat.catégorieInconnue": "Catégorie inconnue",
|
||||||
|
"cat.junior": "Junior",
|
||||||
|
"cat.miniPoussin": "Mini Poussin",
|
||||||
|
"cat.minime": "Minime",
|
||||||
|
"cat.poussin": "Poussin",
|
||||||
|
"cat.senior1": "Senior 1",
|
||||||
|
"cat.senior2": "Senior 2",
|
||||||
|
"cat.superMini": "Super Mini",
|
||||||
|
"cat.vétéran1": "Vétéran 1",
|
||||||
|
"cat.vétéran2": "Vétéran 2",
|
||||||
|
"categorie": "categorie",
|
||||||
|
"catégorie": "Catégorie",
|
||||||
|
"catégorieàAjouter": "Catégorie à ajouter",
|
||||||
|
"certificatMédical": "Certificat médical",
|
||||||
|
"champAttendu": "Champ attendu",
|
||||||
|
"chargement...": "Chargement...",
|
||||||
|
"chargerLexcel": "Charger l'Excel",
|
||||||
|
"chargerLexcel.msg": "Merci d'utiliser le fichier ci-dessus comme base, ne pas renommer les colonnes ni modifier les n° de licences.",
|
||||||
|
"choisir...": "Choisir...",
|
||||||
|
"club.aff_renew.msg": "Veuillez sélectionner 0 à 3 membres du bureau pour remplir la pré-demande. (Si un membre non-bureau va le devenir l'an prochain, vous pourrez les renseigner à la prochaine étape)",
|
||||||
|
"club.change.status": "Pour modifier les informations ci-dessus, merci de contacter la FFSAF par mail.",
|
||||||
|
"club.contact.tt": {
|
||||||
|
"AUTRE": "Autre contact du club",
|
||||||
|
"COURRIEL": "Adresse e-mail du club<br>Exemple: contact@ffsaf.fr",
|
||||||
|
"FACEBOOK": "Page Facebook du club débutant par 'https://www.facebook.com/'</br>Exemple: https://www.facebook.com/ffmsf",
|
||||||
|
"INSTAGRAM": "Compte Instagram du club débutant par 'https://www.instagram.com/'</br>Exemple: https://www.instagram.com/ff_msf",
|
||||||
|
"SITE": "Site web du club avec ou sans le 'https://'</br>Exemple: ffsaf.fr</br>Ou https://ffsaf.fr",
|
||||||
|
"TELEPHONE": "Numéro de téléphone du club<br>Exemple: 06 12 13 78 55"
|
||||||
|
},
|
||||||
|
"club.toast.aff.error": "Impossible de charger les affiliations",
|
||||||
|
"club.toast.aff.pending": "Chargement des affiliations en cours",
|
||||||
|
"club.toast.aff.success": "Affiliations chargées avec succès 🎉",
|
||||||
|
"club.toast.del.error": "Échec de la suppression du club",
|
||||||
|
"club.toast.del.pending": "Suppression du club en cours",
|
||||||
|
"club.toast.del.success": "Club supprimé avec succès 🎉",
|
||||||
|
"club.toast.new.error": "Échec de la création du club",
|
||||||
|
"club.toast.new.pending": "Création du club en cours",
|
||||||
|
"club.toast.new.success": "Club créé avec succès 🎉",
|
||||||
|
"club.toast.save.error": "Échec de l'enregistrement du club",
|
||||||
|
"club.toast.save.pending": "Enregistrement du club en cours",
|
||||||
|
"club.toast.save.success": "Club enregistré avec succès 🎉",
|
||||||
|
"clubExterne": "Club externe",
|
||||||
|
"club_one": "Club",
|
||||||
|
"club_other": "Clubs",
|
||||||
|
"club_zero": "Sans club",
|
||||||
|
"colonneDansLeFichier": "Colonne dans le fichier",
|
||||||
|
"combattant": "combattant",
|
||||||
|
"comp.aff.blason": "Afficher le blason du club sur les écrans",
|
||||||
|
"comp.aff.flag": "Afficher le pays du combattant sur les écrans",
|
||||||
|
"comp.ajoutRapide": "Ajout rapide",
|
||||||
|
"comp.ajouterUnCombattant": "Ajouter un combattant",
|
||||||
|
"comp.ajouterUnInvité": "Ajouter un invité",
|
||||||
|
"comp.billetterie": "Billetterie",
|
||||||
|
"comp.billetterieHelloasso": "Billetterie HelloAsso",
|
||||||
|
"comp.catégorieNormalisée": "Catégorie normalisée",
|
||||||
|
"comp.combattantNonTrouvé": "Combattant non trouvé",
|
||||||
|
"comp.combattantsInscrits": "Combattants inscrits",
|
||||||
|
"comp.compétitionFuture": "Compétition future",
|
||||||
|
"comp.compétitionPassée": "Compétition passée",
|
||||||
|
"comp.créationCompétition": "Création compétition",
|
||||||
|
"comp.dateDinscription": "Date d'inscription",
|
||||||
|
"comp.editionCompétition": "Edition compétition",
|
||||||
|
"comp.error1": "La date de fin doit être postérieure à la date de début.",
|
||||||
|
"comp.error2": "Veuillez renseigner les dates de début et de fin d'inscription.",
|
||||||
|
"comp.error3": "La date de fin d'inscription doit être postérieure à la date de début d'inscription.",
|
||||||
|
"comp.exporterLesInscription": "Exporter les inscriptions",
|
||||||
|
"comp.ha.emailDeRéceptionDesInscriptionséchoué": "Email de réception des inscriptions échoué",
|
||||||
|
"comp.ha.error1": "Veuillez renseigner l'URL de la billetterie HelloAsso et les tarifs associés.",
|
||||||
|
"comp.ha.error2": "L'URL de la billetterie HelloAsso n'est pas valide. Veuillez vérifier le format de l'URL.",
|
||||||
|
"comp.ha.error3": "Veuillez renseigner l'email de réception des inscriptions échouées.",
|
||||||
|
"comp.ha.tarifsHelloasso": "Tarifs HelloAsso",
|
||||||
|
"comp.ha.text1": "Afin de permettre une bonne interconnexion avec HelloAsso, merci de suivre les instructions suivantes :",
|
||||||
|
"comp.ha.text2": "<strong>Configurer l'url de notification : </strong>afin que nous puissions recevoir une notification à chaque inscription, il est nécessaire de configurer l'url de notification de votre compte HelloAsso pour qu'il redirige vers \"https://intra.ffsaf.fr/api/webhook/ha\". Pour ce faire, depuis la page d'accueil de votre association sur HelloAsso, allez dans <strong>Mon compte</strong> > <strong>Paramètres</strong> > <strong> Intégrations et API</strong> section Notification et copier-coller <strong>https://intra.ffsaf.fr/api/webhook/ha </strong> dans le champ <strong>Mon URL de callback</strong> et enregister.",
|
||||||
|
"comp.ha.text3": "<strong>Copier-coller le nom exacte des tarifs</strong> <em>-sépare par des point-virgules-</em> qui donneront lieux à une inscription automatique. Tous ces tarifs doivent impérativement demander le numéro de licence en champs obligatoire. Pour ce faire, lors de la configuration de votre billetterie à l'étape n°3, cliquer sur <strong>+ Ajouter une information</strong>, saisissez l'intituler exact suivant <strong> Numéro de licence</strong>, dans <strong>Type de réponse souhaitée</strong> rentrer Nombre, sélectionner les tarifs entrés plus précédemment et rendre l'information obligatoire.",
|
||||||
|
"comp.ha.text4": "<strong>Copier-coller l'url de votre billetterie</strong> dans le champs si dessous. Il devrais avoir la forme suivante: https://www.helloasso.com/associations/__nom-asso-sur-helloasso__/evenements/__nom-billetterie__",
|
||||||
|
"comp.ha.text5": "Url de la billetterie HelloAsso",
|
||||||
|
"comp.ha.text6": "Si pour une raison quelconque l'inscription automatique échoue, un email sera envoyé à cette adresse pour vous en informer",
|
||||||
|
"comp.informationsGénéralesSurLaCompétition": "Informations générales sur la compétition",
|
||||||
|
"comp.informationsSurLeModeDinscription": "Informations sur le mode d'inscription",
|
||||||
|
"comp.informationsTechniques": "Informations techniques",
|
||||||
|
"comp.inscription": "Inscription",
|
||||||
|
"comp.inscriptionModeAdministrateur": "Inscription - mode administrateur",
|
||||||
|
"comp.inscriptionsLibres": "Inscriptions libres",
|
||||||
|
"comp.inscriptionsParLesAdministrateursDeLaCompétition": "Inscriptions par les administrateurs de la compétition",
|
||||||
|
"comp.inscriptionsParLesResponsablesDeClub": "Inscriptions par les responsables de club",
|
||||||
|
"comp.inscriptionsSurLaBilletterieHelloasso": "Inscriptions sur la billetterie HelloAsso",
|
||||||
|
"comp.modal.annoncé": "Annoncé",
|
||||||
|
"comp.modal.information": "Information",
|
||||||
|
"comp.modal.pesé": "Pesé",
|
||||||
|
"comp.modal.poids": "Poids (en kg)",
|
||||||
|
"comp.modal.recherche": "Recherche*",
|
||||||
|
"comp.modal.surclassement": "Surclassement",
|
||||||
|
"comp.modal.text1": "Les invités sont réservés aux membres non licenciés par la fédération. Les combattants inscrits via ce formulaire ne pourront pas voir leur résultat depuis leur profil.",
|
||||||
|
"comp.modal.text2": "Empêcher les membres/club de modifier cette inscription",
|
||||||
|
"comp.modifierLesParticipants": "Voir/Modifier les participants",
|
||||||
|
"comp.monInscription": "Mon inscription",
|
||||||
|
"comp.noDeLicence": "N° de licence",
|
||||||
|
"comp.nouvelleCompétition": "Nouvelle compétition",
|
||||||
|
"comp.organisateur": "Organisateur",
|
||||||
|
"comp.quiPeutInscrire": "Qui peut inscrire",
|
||||||
|
"comp.reg.libres": "Libres",
|
||||||
|
"comp.reg.parLesAdministrateursDeLaCompétition": "Par les administrateurs de la compétition",
|
||||||
|
"comp.reg.parLesResponsablesDeClub": "Par les responsables de club",
|
||||||
|
"comp.reg.surLaBilletterieHelloasso": "Sur la billetterie HelloAsso",
|
||||||
|
"comp.responsablesEtBureauxDesAssociations": "Responsables et bureaux des associations",
|
||||||
|
"comp.sinscrire": "S'inscrire",
|
||||||
|
"comp.supprimerLaCompétition": "Supprimer la compétition",
|
||||||
|
"comp.supprimerLaCompétition.msg": "Êtes-vous sûr de vouloir supprimer cette compétition est tout les resultat associer?",
|
||||||
|
"comp.surclassement_one": "{{cat}} avec 1 de surclassement",
|
||||||
|
"comp.surclassement_other": "{{cat}} avec {{count}} de surclassements",
|
||||||
|
"comp.surclassement_zero": "{{cat}}",
|
||||||
|
"comp.text2": "Visible par le public (Apparaît dans la liste des compétitions)",
|
||||||
|
"comp.text3": "Si non coché, la compétition ne sera visible que par les personnes pouvant y inscrire des participants.",
|
||||||
|
"comp.tips": "Tips 1: Il est possible de bannir un combattant, ce qui l'empêchera d'être réinscrit par un autre moyen que par un administrateur de cette compétition. Pour cela, cliquez sur la petite <1/> à côté de son nom.<br/>Tips 2: Il est aussi possible de verrouiller les modifications de son inscription depuis sa fiche, ce qui l'empêchera d'être modifié/supprimé par lui-même et/ou un responsable de club.",
|
||||||
|
"comp.toast.del.error": "Échec de la suppression de la compétition",
|
||||||
|
"comp.toast.del.pending": "Suppression de la compétition en cours",
|
||||||
|
"comp.toast.del.success": "Compétition supprimée avec succès 🎉",
|
||||||
|
"comp.toast.params.error": "Échec de la mise à jours des paramètres de la compétition",
|
||||||
|
"comp.toast.params.pending": "Mise à jours des paramètres de la compétition en cours...",
|
||||||
|
"comp.toast.params.success": "Paramètres de la compétition mis à jours avec succès 🎉",
|
||||||
|
"comp.toast.register.add.error": "Combattant non trouvé",
|
||||||
|
"comp.toast.register.add.pending": "Recherche en cours",
|
||||||
|
"comp.toast.register.add.success": "Combattant trouvé et ajouté/mis à jour",
|
||||||
|
"comp.toast.register.addMultiple.success_one": "Importation réussie pour 1 combattant",
|
||||||
|
"comp.toast.register.addMultiple.success_other": "Importation réussie pour {{count}} combattants",
|
||||||
|
"comp.toast.register.ban.error": "Erreur",
|
||||||
|
"comp.toast.register.ban.pending": "Désinscription en cours",
|
||||||
|
"comp.toast.register.ban.success": "Combattant désinscrit et bannie",
|
||||||
|
"comp.toast.register.del.error": "Erreur",
|
||||||
|
"comp.toast.register.del.pending": "Désinscription en cours",
|
||||||
|
"comp.toast.register.del.success": "Combattant désinscrit",
|
||||||
|
"comp.toast.register.self.add.error": "Erreur lors de l'inscription",
|
||||||
|
"comp.toast.register.self.add.pending": "Inscription en cours",
|
||||||
|
"comp.toast.register.self.add.success": "Inscription réalisée 🎉",
|
||||||
|
"comp.toast.register.self.del.error": "Erreur lors de la désinscription",
|
||||||
|
"comp.toast.register.self.del.pending": "Désinscription en cours",
|
||||||
|
"comp.toast.register.self.del.success": "Désinscription réalisée",
|
||||||
|
"comp.toast.registers.addMultiple.error": "Erreur lors de l'importation des combattants",
|
||||||
|
"comp.toast.registers.addMultiple.pending": "Importation des combattants en cours...",
|
||||||
|
"comp.toast.registers.addMultiple.success": "Importation des combattants réussie 🎉",
|
||||||
|
"comp.toast.save.error": "Échec de l'enregistrement de la compétition",
|
||||||
|
"comp.toast.save.pending": "Enregistrement de la compétition en cours",
|
||||||
|
"comp.toast.save.success": "Compétition enregistrée avec succès 🎉",
|
||||||
|
"comp.tousLesMembresDeLaFfsaf": "Tous les membres de la FFSAF",
|
||||||
|
"comp.typeDinscription": "Type d'inscription",
|
||||||
|
"comp.uniquementLesAdministrateursDeLaCompétition": "Uniquement les administrateurs de la compétition",
|
||||||
|
"comp.warn1": "Êtes-vous sûr de vouloir désinscrire et bannir ce combattant de la compétition?\n(Vous pouvez le réinscrire plus tard)\"",
|
||||||
|
"comp.warn2": "Êtes-vous sûr de vouloir désinscrire ce combattant ?\nCela ne le désinscrira pas de la billetterie HelloAsso et ne le remboursera pas.",
|
||||||
|
"comp.warn3": "Êtes-vous sûr de vouloir désinscrire ce combattant ?",
|
||||||
|
"comp.warn4": "Êtes-vous sûr de vouloir vous désinscrire ?",
|
||||||
|
"comp_manage": "Compétitions Manager",
|
||||||
|
"competition_one": "Compétition",
|
||||||
|
"competition_other": "Compétitions",
|
||||||
|
"compte": "Compte",
|
||||||
|
"compétition": "Compétition",
|
||||||
|
"configuration": "Configuration",
|
||||||
|
"configurationDeLaCatégorie": "Configuration de la catégorie",
|
||||||
|
"conserverLancienEmail": "Conserver l'ancien email",
|
||||||
|
"contactAdministratif": "Contact administratif",
|
||||||
|
"contactInterne": "Contact interne",
|
||||||
|
"contact_one": "Contact",
|
||||||
|
"contact_other": "Contacts",
|
||||||
|
"coquilleProtectionPelvienne": "Coquille / Protection pelvienne",
|
||||||
|
"date": "Date",
|
||||||
|
"dateDeNaissance": "Date de naissance",
|
||||||
|
"days": [
|
||||||
|
"Lundi",
|
||||||
|
"Mardi",
|
||||||
|
"Mercredi",
|
||||||
|
"Jeudi",
|
||||||
|
"Vendredi",
|
||||||
|
"Samedi",
|
||||||
|
"Dimanche"
|
||||||
|
],
|
||||||
|
"de": "de",
|
||||||
|
"demandeDaffiliationEnCours": "Demande d'affiliation en cours",
|
||||||
|
"demandeDeLicence": "Demande de licence ",
|
||||||
|
"demander": "Demander",
|
||||||
|
"description": "Description",
|
||||||
|
"dlAff": "Téléchargée l'attestation d'affiliation",
|
||||||
|
"donnéesAdministratives": "Données administratives",
|
||||||
|
"du": "Du",
|
||||||
|
"dun": "d'un",
|
||||||
|
"duréePause": "Durée pause",
|
||||||
|
"duréeRound": "Durée round",
|
||||||
|
"définirLidDuCompte": "Définir l'id du compte",
|
||||||
|
"editionDeL'affiliation": "Edition de l'affiliation",
|
||||||
|
"editionDeLaDemande": "Edition de la demande ",
|
||||||
|
"editionDeLaLicence": "Edition de la licence",
|
||||||
|
"editionDeLaSéléction": "Edition de la séléction",
|
||||||
|
"editionDeLadresse": "Edition de l'adresse",
|
||||||
|
"email": "Email",
|
||||||
|
"en": "en",
|
||||||
|
"enAttente": "En attente",
|
||||||
|
"erreurDePaiement": "Erreur de paiement😕",
|
||||||
|
"erreurDePaiement.detail": "Message d'erreur :",
|
||||||
|
"erreurDePaiement.msg": "Une erreur est survenue lors du traitement de votre paiement. Veuillez réessayer plus tard.",
|
||||||
|
"erreurPourLinscription": "Erreur pour l'inscription",
|
||||||
|
"espaceAdministration": "Espace administration",
|
||||||
|
"f": "F",
|
||||||
|
"faitPar": "Fait par",
|
||||||
|
"femme": "Femme",
|
||||||
|
"fileImport.variants": {
|
||||||
|
"categorie": [
|
||||||
|
"catégorie",
|
||||||
|
"category",
|
||||||
|
"catégorie de poids",
|
||||||
|
"weight category",
|
||||||
|
"catégorie d'âge"
|
||||||
|
],
|
||||||
|
"club": [
|
||||||
|
"club",
|
||||||
|
"nom du club",
|
||||||
|
"club name",
|
||||||
|
"association",
|
||||||
|
"nom de l'association"
|
||||||
|
],
|
||||||
|
"genre": [
|
||||||
|
"genre",
|
||||||
|
"sexe",
|
||||||
|
"gender",
|
||||||
|
"sex",
|
||||||
|
"civilité"
|
||||||
|
],
|
||||||
|
"licence": [
|
||||||
|
"licence",
|
||||||
|
"n° licence",
|
||||||
|
"num licence",
|
||||||
|
"id licence",
|
||||||
|
"license",
|
||||||
|
"licence id"
|
||||||
|
],
|
||||||
|
"nom": [
|
||||||
|
"nom",
|
||||||
|
"nom de famille",
|
||||||
|
"lastname",
|
||||||
|
"family name",
|
||||||
|
"nom complet"
|
||||||
|
],
|
||||||
|
"overCategory": [
|
||||||
|
"surclassement",
|
||||||
|
"over category",
|
||||||
|
"surcatégorie",
|
||||||
|
"surclassement de catégorie"
|
||||||
|
],
|
||||||
|
"pays": [
|
||||||
|
"pays",
|
||||||
|
"country",
|
||||||
|
"pays de résidence",
|
||||||
|
"pays d'origine"
|
||||||
|
],
|
||||||
|
"prenom": [
|
||||||
|
"prénom",
|
||||||
|
"prenom",
|
||||||
|
"first name",
|
||||||
|
"given name",
|
||||||
|
"prénom usuel"
|
||||||
|
],
|
||||||
|
"weight": [
|
||||||
|
"poids",
|
||||||
|
"weight",
|
||||||
|
"poids (kg)",
|
||||||
|
"poids réel",
|
||||||
|
"masse"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"filtre": "Filtre",
|
||||||
|
"gantMainBouclier": "Gant main de bouclier",
|
||||||
|
"gantMainsArmées": "Gant main(s) armée(s)",
|
||||||
|
"gants": "Gants",
|
||||||
|
"genre": "Genre",
|
||||||
|
"gestionGroupée": "Gestion groupée",
|
||||||
|
"gorgerin": "Gorgerin",
|
||||||
|
"gradeDarbitrage": "Grade d'arbitrage",
|
||||||
|
"h": "H",
|
||||||
|
"home": {
|
||||||
|
"header1": "Pour les licenciés",
|
||||||
|
"header2": "Pour les clubs",
|
||||||
|
"text1": "Vous y retrouverez toutes vos informations ainsi que l'état de votre inscription à la fédération. Vous pouvez également télécharger votre attestation d'inscription, vous inscrire aux compétitions ainsi que consulter vos résultats sous réserve que le club organisateur les ait renseignés.<br/><br/>Lors de votre première inscription, vous recevrez un email contenant vos informations d'identification, ce mail sera envoyé une fois votre licence validée par le secrétariat.",
|
||||||
|
"text2": "C'est ici que vous pouvez prendre les licences fédérales pour vos adhérents, que vous pouvez demander ou renouveler votre affiliation, renseigner vos horaires, lieux d'entraînement et réseaux sociaux qui seront par la suite affichés sur le site ffsaf.fr.<br/>Vous aurez par ailleurs la possibilité de publier des formulaires d'inscriptions pour vos compétitions ainsi que d'enregistrer les résultats.<br/><br/> Vous n'êtes pas encore affilié à la fédération ? Cliquez <1>içi</1> pour faire votre première demande.",
|
||||||
|
"welcome_message": "Bienvenue sur l’intranet de la Fédération France Soft Armored Fighting"
|
||||||
|
},
|
||||||
|
"homme": "Homme",
|
||||||
|
"horairesD'entraînements": "Horaires d'entraînements",
|
||||||
|
"importationDuFichier": "Importation du fichier",
|
||||||
|
"importerDesCombattants": "Importer des combattants",
|
||||||
|
"importerDesInvités": "Importer des invités",
|
||||||
|
"information": "Information",
|
||||||
|
"invité": "invité",
|
||||||
|
"keepEmpty": "Laissez vide pour ne rien changer.",
|
||||||
|
"le": "le",
|
||||||
|
"licence": "Licence",
|
||||||
|
"licenceNo": "Licence n°{{no}}",
|
||||||
|
"lieu": "Lieu",
|
||||||
|
"lieuxDentraînements": "Lieux d'entraînements",
|
||||||
|
"ligneIgnorée1": "Ligne ignorée : nom, prénom ou catégorie manquante.",
|
||||||
|
"ligneIgnorée2": "Ligne ignorée : nom prénom ou licence manquante.",
|
||||||
|
"loading": "Chargement...",
|
||||||
|
"me": {
|
||||||
|
"result": {
|
||||||
|
"PRIVATE": "Privé (visible uniquement par moi)",
|
||||||
|
"PUBLIC": "Public (visible par tous)",
|
||||||
|
"REGISTERED_ONLY": "Membres connectés (visibles par les membres de la fédération)",
|
||||||
|
"REGISTERED_ONLY_NO_DETAILS": "Membres connectés - masquer les détails (visibles par les membres de la fédération)"
|
||||||
|
},
|
||||||
|
"toast.settings.error": "Échec de la mise à jours des paramètres 😕",
|
||||||
|
"toast.settings.pending": "Mise à jours des paramètres en cours...",
|
||||||
|
"toast.settings.success": "Paramètres mis à jours avec succès 🎉"
|
||||||
|
},
|
||||||
|
"me.changerMonMotDePasse": "Changer mon mot de passe",
|
||||||
|
"me.formationDarbitrage": "Formation d'arbitrage",
|
||||||
|
"me.paramètresDuCompte": "Paramètres du compte",
|
||||||
|
"me.rôleAuSienDuClub": "Rôle au sien du club",
|
||||||
|
"me.visibilitéDesRésultats": "Visibilité des résultats",
|
||||||
|
"member_one": "Membre",
|
||||||
|
"member_other": "Membres",
|
||||||
|
"membre.emailVideàLaLigne": "Email vide à la ligne {{no}}",
|
||||||
|
"membre.emailVérifié": "Email vérifié",
|
||||||
|
"membre.filtre.inactif": "Afficher les combattants inactifs",
|
||||||
|
"membre.filtre.licence": "Afficher l'état des licences",
|
||||||
|
"membre.filtre.licences": [
|
||||||
|
"Sans demande ni licence validée",
|
||||||
|
"Avec demande ou licence validée",
|
||||||
|
"Demande en cours",
|
||||||
|
"Licence validée",
|
||||||
|
"Tout les états de licences",
|
||||||
|
"Demande complet",
|
||||||
|
"Demande incomplet"
|
||||||
|
],
|
||||||
|
"membre.filtre.payement": [
|
||||||
|
"Sans paiement",
|
||||||
|
"Avec paiement",
|
||||||
|
"Tout les états de paiement"
|
||||||
|
],
|
||||||
|
"membre.identifiant": "Identifiant",
|
||||||
|
"membre.import.err1": "Format de la date de certificat invalide à la ligne {{no}}",
|
||||||
|
"membre.import.err2": "Format de la date de certificat invalide à la ligne {{no}}",
|
||||||
|
"membre.import.err3": "Date de naissance vide à la ligne {{no}}",
|
||||||
|
"membre.import.err4": "Format de la date de naissance invalide à la ligne {{no}}",
|
||||||
|
"membre.import.err5": "Email invalide à la ligne {{no}}",
|
||||||
|
"membre.import.errTT_one": "{{count}} erreur dans le fichier, opération annulée",
|
||||||
|
"membre.import.errTT_other": "{{count}} erreurs dans le fichier, opération annulée",
|
||||||
|
"membre.import.warn_one": "{{count}} certificat médical non rempli",
|
||||||
|
"membre.import.warn_other": "{{count}} certificats médicaux non remplis",
|
||||||
|
"membre.info.emailInfo": "L'email sert à la création de compte pour se connecter au site et doit être unique.<br/>Pour les mineurs, l'email des parents peut être utilisé plusieurs fois grâce à la syntaxe suivante : {'email.parent+<caractères alphanumériques>@exemple.com'}.<br/>Exemples : mail.parent+1@exemple.com, mail.parent+titouan@exemple.com, mail.parent+cedrique@exemple.com",
|
||||||
|
"membre.info.error1": "Veuillez sélectionner un pays valide 😕",
|
||||||
|
"membre.info.error2": "Veuillez sélectionner un club valide 😕",
|
||||||
|
"membre.initaccount": "Initialiser le compte",
|
||||||
|
"membre.initaccount.text1": "Entré l'UUID du compte",
|
||||||
|
"membre.initaccount.text2": "Attention ne changée l'id d'un membre que si vous êtes sûr de ce que vos faites...",
|
||||||
|
"membre.noAccount": "Ce membre ne dispose pas de compte...",
|
||||||
|
"membre.noAccount.clubMsg": "Un compte sera créé par la fédération lors de la validation de sa première licence",
|
||||||
|
"membre.nomVideàLaLigne": "Nom vide à la ligne {{no}}",
|
||||||
|
"membre.prénomVideàLaLigne": "Prénom vide à la ligne {{no}}",
|
||||||
|
"membre.toast.compte.created": "Compte créé avec succès 🎉",
|
||||||
|
"membre.toast.compte.error": "Échec de la création du compte",
|
||||||
|
"membre.toast.compte.pending": "Création du compte en cours",
|
||||||
|
"membre.toast.del.error": "Échec de la suppression du compte",
|
||||||
|
"membre.toast.del.pending": "Suppression du compte en cours",
|
||||||
|
"membre.toast.del.success": "Compte supprimé avec succès 🎉",
|
||||||
|
"membre.toast.id.error": "Échec de la définition de l'identifient",
|
||||||
|
"membre.toast.id.pending": "Définition de l'identifient en cours",
|
||||||
|
"membre.toast.id.success": "Identifient défini avec succès 🎉",
|
||||||
|
"membre.toast.licence.ask.del.error": "Échec de la suppression de la demande de licence",
|
||||||
|
"membre.toast.licence.ask.del.pending": "Suppression de la demande de licence en cours",
|
||||||
|
"membre.toast.licence.ask.del.success": "Demande de licence supprimée avec succès 🎉",
|
||||||
|
"membre.toast.licence.ask.error": "Échec de la demande de licence",
|
||||||
|
"membre.toast.licence.ask.pending": "Enregistrement de la demande de licence en cours",
|
||||||
|
"membre.toast.licence.ask.success": "Demande de licence enregistrée avec succès 🎉",
|
||||||
|
"membre.toast.licence.del.error": "Échec de la suppression de la licence",
|
||||||
|
"membre.toast.licence.del.pending": "Suppression de la licence en cours",
|
||||||
|
"membre.toast.licence.del.success": "Licence supprimée avec succès 🎉",
|
||||||
|
"membre.toast.licence.save.error": "Échec de l'enregistrement de la licence",
|
||||||
|
"membre.toast.licence.save.pending": "Enregistrement de la licence en cours",
|
||||||
|
"membre.toast.licence.save.success": "Licence enregistrée avec succès 🎉",
|
||||||
|
"membre.toast.licences.export.error": "Échec de l'export des licences",
|
||||||
|
"membre.toast.licences.export.pending": "Export des licences en cours",
|
||||||
|
"membre.toast.licences.export.success": "Licences exportées avec succès 🎉",
|
||||||
|
"membre.toast.licences.import.error": "Échec de l'envoie des changements",
|
||||||
|
"membre.toast.licences.import.pending": "Envoie des changements en cours",
|
||||||
|
"membre.toast.licences.import.success": "Changements envoyés avec succès 🎉",
|
||||||
|
"membre.toast.licences.load.error": "Impossible de charger les licences",
|
||||||
|
"membre.toast.licences.load.pending": "Chargement des licences en cours",
|
||||||
|
"membre.toast.licences.load.success": "Licences chargées avec succès 🎉",
|
||||||
|
"membre.toast.perm.error": "Échec de la mise à jours des permissions 😕",
|
||||||
|
"membre.toast.perm.pending": "Mise à jours des permissions en cours...",
|
||||||
|
"membre.toast.perm.success": "Permission mise à jours avec succès 🎉",
|
||||||
|
"membre.toast.save.error": "Échec de la mise à jours du profil 😕",
|
||||||
|
"membre.toast.save.pending": "Mise à jours du profil en cours...",
|
||||||
|
"membre.toast.save.success": "Profil mis à jours avec succès 🎉",
|
||||||
|
"membre.toast.select.del.error": "Échec de la suppression de la séléction",
|
||||||
|
"membre.toast.select.del.pending": "Suppression de la séléction en cours",
|
||||||
|
"membre.toast.select.del.success": "Séléction supprimée avec succès 🎉",
|
||||||
|
"membre.toast.select.save.error": "Échec de l'enregistrement de la séléction",
|
||||||
|
"membre.toast.select.save.pending": "Enregistrement de la séléction en cours",
|
||||||
|
"membre.toast.select.save.success": "Séléction enregistrée avec succès 🎉",
|
||||||
|
"mettreàJours": "Mettre à jours",
|
||||||
|
"modification": "Modification",
|
||||||
|
"nationalité": "Nationalité",
|
||||||
|
"nav": {
|
||||||
|
"account": "Mon compte",
|
||||||
|
"aff_request": "Demande d'affiliation",
|
||||||
|
"club": {
|
||||||
|
"my": "Mon club"
|
||||||
|
},
|
||||||
|
"competitions": {
|
||||||
|
"results": "Mes résultats"
|
||||||
|
},
|
||||||
|
"home": "Accueil",
|
||||||
|
"login": "Connexion",
|
||||||
|
"logout": "Déconnexion",
|
||||||
|
"space": "Mon espace",
|
||||||
|
"title": "FFSAF Intranet"
|
||||||
|
},
|
||||||
|
"noLicence": "N° Licence",
|
||||||
|
"noSiretOuRna": "N° $t(siretOuRna)",
|
||||||
|
"nom": "Nom",
|
||||||
|
"nombreDeLicences": "Nombre de licences",
|
||||||
|
"nombreDeLicencesParCatégorie": "Nombre de licences par catégorie pour {{saison}}",
|
||||||
|
"non": "Non",
|
||||||
|
"nonDéfinie": "Non définie",
|
||||||
|
"nonValidée": "Non validée",
|
||||||
|
"nouveauClub": "Nouveau club",
|
||||||
|
"nouveauMembre": "Nouveau membre",
|
||||||
|
"nouvelEmail": "Nouvel email",
|
||||||
|
"numéroDeLaLigneDentête": "Numéro de la ligne d'en-tête",
|
||||||
|
"numéroDeLigne": "Numéro de ligne",
|
||||||
|
"ou": "Ou",
|
||||||
|
"oui": "Oui",
|
||||||
|
"outdated_session": {
|
||||||
|
"login_button": "Se reconnecter",
|
||||||
|
"message": "Votre session a expirée, veuillez vous reconnecter pour continuer à utiliser l'application.",
|
||||||
|
"title": "Session expirée"
|
||||||
|
},
|
||||||
|
"pageClub": "Page club",
|
||||||
|
"pageMembre": "Page membre",
|
||||||
|
"pageNouveauClub": "Page nouveau club",
|
||||||
|
"page_info_full": "Ligne {{line}} à {{tt_line}} (page {{page}} sur {{tt_page}})",
|
||||||
|
"page_info_ligne": "{{show}} ligne(s) affichée(s) sur {{total}}",
|
||||||
|
"paiementDeLaLicence": "Paiement de la licence",
|
||||||
|
"paiementDesLicences": "Paiement des licences",
|
||||||
|
"par": "par",
|
||||||
|
"pasDeLicence": "Pas de licence",
|
||||||
|
"payment.ha.info": "Le modèle solidaire de HelloAsso garantit que 100% de votre paiement sera versé à l’association choisie. Vous pouvez soutenir l’aide qu’ils apportent aux associations en laissant une contribution volontaire à HelloAsso au moment de votre paiement.",
|
||||||
|
"payment.info": "A propos de HelloAsso",
|
||||||
|
"payment.paiementSécurisé": "Paiement sécurisé",
|
||||||
|
"payment.payerAvec": "Payer avec",
|
||||||
|
"payment.recap": "{{count}} licence(s) sélectionnée<br/>Total à régler : {{total}} €",
|
||||||
|
"paymentDesLicences": "Payment des licences",
|
||||||
|
"paymentDesLicences.msg_one": "Êtes-vous sûr de vouloir marquer comme payées la licence ?",
|
||||||
|
"paymentDesLicences.msg_other": "Êtes-vous sûr de vouloir marquer comme payées les {{count}} licences ?",
|
||||||
|
"paymentDesLicences.msg_zero": "$t(paymentDesLicences.msg_other)",
|
||||||
|
"paymentOk": "🎉Votre paiement a été traité avec succès.🎉",
|
||||||
|
"paymentOk.msg": "Merci pour votre paiement. Les licences devraient être activées dans l'heure qui vient, à condition que le certificat médical soit rempli.",
|
||||||
|
"pays": "Pays",
|
||||||
|
"perm.administrateurDeLaFédération": "Administrateur de la fédération",
|
||||||
|
"perm.créerDesCompétion": "Créer des compétion",
|
||||||
|
"perm.ffsafIntra": "FFSAF intra",
|
||||||
|
"permission": "Permission",
|
||||||
|
"peutSinscrire": "Peut s'inscrire?",
|
||||||
|
"photos": "Photos",
|
||||||
|
"plastron": "Plastron",
|
||||||
|
"poids": "Poids",
|
||||||
|
"poidsDemandéPour": "Poids demandé pour",
|
||||||
|
"prenom": "Prénom",
|
||||||
|
"protectionDeBras": "Protection de bras",
|
||||||
|
"protectionDeBrasArmé": "Protection de bras armé(s)",
|
||||||
|
"protectionDeBrasDeBouclier": "Protection de bras de bouclier",
|
||||||
|
"protectionDeCoudes": "Protection de coudes",
|
||||||
|
"protectionDeGenoux": "Protection de genoux",
|
||||||
|
"protectionDeJambes": "Protection de jambes",
|
||||||
|
"protectionDePieds": "Protection de pieds",
|
||||||
|
"protectionDorsale": "Protection dorsale",
|
||||||
|
"protectionObligatoire": "Protection obligatoire",
|
||||||
|
"prénomEtNom": "Prénom et nom",
|
||||||
|
"rechercher": "Rechercher",
|
||||||
|
"rechercher...": "Rechercher...",
|
||||||
|
"registration_one": "Inscription",
|
||||||
|
"registration_other": "Inscriptions",
|
||||||
|
"renouveler": "Renouveler",
|
||||||
|
"renouvellementDeLaffiliation": "Renouvellement de l'affiliation",
|
||||||
|
"result_one": "Résultat",
|
||||||
|
"result_other": "Résultats",
|
||||||
|
"retouràLaListeDeMembres": "Retour à la liste de membres",
|
||||||
|
"role": "Rôle",
|
||||||
|
"role.membre": "Membre",
|
||||||
|
"role.membreDuBureau": "Membre du bureau",
|
||||||
|
"role.président": "Président",
|
||||||
|
"role.secrétaire": "Secrétaire",
|
||||||
|
"role.trésorier": "Trésorier",
|
||||||
|
"role.vise-président": "Vise-Président",
|
||||||
|
"role.vise-secrétaire": "Vise-Secrétaire",
|
||||||
|
"role.vise-trésorier": "Vise-Trésorier",
|
||||||
|
"saison": "Saison",
|
||||||
|
"sans": "Sans",
|
||||||
|
"secrétariatsDeLice": "Secrétariats de lice",
|
||||||
|
"selectionner...": "Sélectionner...",
|
||||||
|
"shield.buckler": "Bocle",
|
||||||
|
"shield.none": "$t(sans) / $t(nonDéfinie)",
|
||||||
|
"shield.round": "Rond",
|
||||||
|
"shield.standard": "Standard",
|
||||||
|
"shield.teardrop": "Larme",
|
||||||
|
"siDisponiblePourLaCatégorieDages": "Si disponible pour la catégorie d'ages",
|
||||||
|
"siretOuRna": "SIRET ou RNA",
|
||||||
|
"stats": "Statistiques",
|
||||||
|
"statue": "Statue",
|
||||||
|
"status": "Status",
|
||||||
|
"statuts": "Statuts",
|
||||||
|
"supprimerLeClub": "Supprimer le club",
|
||||||
|
"supprimerLeClub.msg": "Êtes-vous sûr de vouloir supprimer ce club ?",
|
||||||
|
"supprimerLeCompte": "Supprimer le compte",
|
||||||
|
"supprimerLeCompte.msg": "Êtes-vous sûr de vouloir supprimer ce compte ?",
|
||||||
|
"sword.none": "$t(sans) / $t(nonDéfinie)",
|
||||||
|
"sword.oneHand": "Épée une main",
|
||||||
|
"sword.saber": "Sabre",
|
||||||
|
"sword.twoHand": "Épée deux mains",
|
||||||
|
"sélectionEnéquipeDeFrance": "Sélection en équipe de France",
|
||||||
|
"sélectionner...": "Sélectionner...",
|
||||||
|
"toast.edit.error": "Échec de l'enregistrement des modifications",
|
||||||
|
"toast.edit.pending": "Enregistrement des modifications en cours",
|
||||||
|
"toast.edit.success": "Modifications enregistrées avec succès 🎉",
|
||||||
|
"toast.licence.bulk.pay.error": "Échec du marquage des licences comme payées",
|
||||||
|
"toast.licence.bulk.pay.pending": "Marquage des licences comme payées en cours",
|
||||||
|
"toast.licence.bulk.pay.success": "Licences marquées comme payées avec succès 🎉",
|
||||||
|
"toast.licence.bulk.valid.error": "Échec de la validation des licences",
|
||||||
|
"toast.licence.bulk.valid.pending": "Validation des licences en cours",
|
||||||
|
"toast.licence.bulk.valid.success": "Licences validées avec succès 🎉",
|
||||||
|
"toast.licence.order.error": "Échec de le création de la commande",
|
||||||
|
"toast.licence.order.pending": "Création de la commande en cours",
|
||||||
|
"toast.licence.order.success": "Commande créée avec succès 🎉",
|
||||||
|
"trie": "Trie",
|
||||||
|
"téléchargerLexcelDesMembres": "Télécharger l'Excel des membres",
|
||||||
|
"téléchargerLexcelDesMembres.info": "À utiliser comme template pour mettre à jour les informations",
|
||||||
|
"téléchargéeLaLicence": "Téléchargée la licence",
|
||||||
|
"validationDeLaLicence": "Validation de la licence",
|
||||||
|
"validationDesLicences": "Validation des licences",
|
||||||
|
"validerDesLicences": "Valider des licences",
|
||||||
|
"validerLePayement_one": "Valider le payement de la licence sélectionnée",
|
||||||
|
"validerLePayement_other": "Valider le payement des {{count}} licences sélectionnées",
|
||||||
|
"validerLePayement_zero": "$t(validerLePayement_other)",
|
||||||
|
"validerLicence.msg_one": "Êtes-vous sûr de vouloir valider la licence ?",
|
||||||
|
"validerLicence.msg_other": "Êtes-vous sûr de vouloir valider les {{count}} licences ?",
|
||||||
|
"validerLicence.msg_zero": "$t(validerLicence.msg_other)",
|
||||||
|
"validerLicence_one": "Valider la licence sélectionnée",
|
||||||
|
"validerLicence_other": "Valider les {{count}} licences sélectionnées",
|
||||||
|
"validerLicence_zero": "$t(validerLicence_other)",
|
||||||
|
"validée": "Validée",
|
||||||
|
"veuillezAssocierChaqueChampàUneColonneDuFichier": "Veuillez associer chaque champ à une colonne du fichier",
|
||||||
|
"veuillezIndiqueràQuelle": "Veuillez indiquer à quelle ligne se trouvent les en-têtes dans le fichier",
|
||||||
|
"veuillezMapperLesColonnesSuivantes": "Veuillez mapper les colonnes suivantes",
|
||||||
|
"voir/modifierLesParticipants": "Voir/Modifier les participants",
|
||||||
|
"voirLesStatues": "Voir les statues",
|
||||||
|
"vousNêtesPasEncoreInscrit": "Vous n'êtes pas encore inscrit ou votre inscription n'a pas encore été rentrée sur l'intranet",
|
||||||
|
"à": "à",
|
||||||
|
"étatDeLaDemande": "État de la demande"
|
||||||
|
}
|
||||||
75
src/main/webapp/public/locales/fr/result.json
Normal file
75
src/main/webapp/public/locales/fr/result.json
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
{
|
||||||
|
"--sélectionnerUnClub--": "--Sélectionner un club--",
|
||||||
|
"--sélectionnerUnCombattant--": "--Sélectionner un combattant--",
|
||||||
|
"--sélectionnerUneCatégorie--": "--Sélectionner une catégorie--",
|
||||||
|
"1er": "Médaille d'or",
|
||||||
|
"2eme": "Médaille d'argent",
|
||||||
|
"3eme": "Médaille de bronze",
|
||||||
|
"abs.": "abs.",
|
||||||
|
"adversaire": "Adversaire",
|
||||||
|
"aujourdhuià": "Aujourd'hui à {{time}}",
|
||||||
|
"avanthierà": "Avant-hier à {{time}}",
|
||||||
|
"back": "« retour",
|
||||||
|
"bleu": "Bleu",
|
||||||
|
"catégorie": "Catégorie",
|
||||||
|
"chargement": "Chargement",
|
||||||
|
"classement": "Classement",
|
||||||
|
"classementClub": "Classement club",
|
||||||
|
"classementDesClub": "Classement des clubs",
|
||||||
|
"classementFinal": "Classement final",
|
||||||
|
"club": "Club",
|
||||||
|
"combattant": "Combattant",
|
||||||
|
"combattants": "Combattants",
|
||||||
|
"date": "Date",
|
||||||
|
"disc.": "disc.",
|
||||||
|
"défaites": "Défaites",
|
||||||
|
"erreurDeChargementDeLaListe": "Erreur de chargement de la liste",
|
||||||
|
"erreurDeChargementDeLaPoule": "Erreur de chargement de la poule",
|
||||||
|
"erreurDeChargementDesCatégories": "Erreur de chargement des catégories",
|
||||||
|
"erreurDeChargementDesClubs": "Erreur de chargement des clubs",
|
||||||
|
"erreurDeChargementDesCombattants": "Erreur de chargement des combattants",
|
||||||
|
"erreurDeChargementDuClub": "Erreur de chargement du club",
|
||||||
|
"erreurDeChargementDuCombattant": "Erreur de chargement du combattant",
|
||||||
|
"for.": "for.",
|
||||||
|
"hierà": "Hier à {{time}}",
|
||||||
|
"info": "Info",
|
||||||
|
"listeDesCombattants": "Liste des combattants",
|
||||||
|
"listeDesMatchs": "Liste des matchs",
|
||||||
|
"listeDesMembres": "Liste des membres",
|
||||||
|
"listeDesMenbres": "Liste des menbres",
|
||||||
|
"nom": "Nom",
|
||||||
|
"nomPrénom": "Nom Prénom",
|
||||||
|
"nombreDeMatchDisputé2": "Nombre de match disputé : {{nb}}",
|
||||||
|
"nombreDeVictoires2": "Nombre de victoires : {{nb}} ",
|
||||||
|
"nombreDinscris": "Nombre d'inscris",
|
||||||
|
"nombreDinscris2": "Nombre d'inscris : {{nb}}",
|
||||||
|
"parCatégorie": "Par catégorie",
|
||||||
|
"parClub": "Par club",
|
||||||
|
"parCombattant": "Par combattant",
|
||||||
|
"place": "Place",
|
||||||
|
"pointsMarqués": "Points marqués",
|
||||||
|
"pointsMarqués2": "Points marqués : {{nb}}",
|
||||||
|
"pointsReçus": "Points reçus",
|
||||||
|
"pointsReçus2": "Points reçus : {{nb}}",
|
||||||
|
"poule": "Poule",
|
||||||
|
"ratio": "Ratio",
|
||||||
|
"ratioDePointsMoyen2": "Ratio de points moyen : {{nb}}",
|
||||||
|
"ratioDeVictoiresMoyen2": "Ratio de victoires moyen : {{nb}}",
|
||||||
|
"ratioDuScore2": "Ratio du score (point marqué / point reçu): {{nb}}",
|
||||||
|
"ratioPoints": "Ratio points",
|
||||||
|
"ratioVictoires": "Ratio victoires",
|
||||||
|
"ratiosPoints": "Ratios points",
|
||||||
|
"rechercheParCatégorie": "Recherche par catégorie",
|
||||||
|
"rechercheParClub": "Recherche par club",
|
||||||
|
"rechercheParCombattant": "Recherche par combattant",
|
||||||
|
"rouge": "Rouge",
|
||||||
|
"résultatDeLaCompétition": "Résultat de la compétition",
|
||||||
|
"score": "Score",
|
||||||
|
"scores": "Scores",
|
||||||
|
"statistique": "Statistique",
|
||||||
|
"tauxDeVictoire2": "Taux de victoire : {{nb}}% ({{victoires}} sur {{matchs}})",
|
||||||
|
"tournois": "Tournois",
|
||||||
|
"tousLesCombattants": "Tous les combattants",
|
||||||
|
"victoire": "Victoire",
|
||||||
|
"victoires": "Victoires"
|
||||||
|
}
|
||||||
84
src/main/webapp/public/processor-dtmf.js
Normal file
84
src/main/webapp/public/processor-dtmf.js
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
class ProcessorDTMF extends AudioWorkletProcessor {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.sampleRate = sampleRate;
|
||||||
|
this.symbolDuration = 0.03; // 50 ms par symbole
|
||||||
|
this.samplesPerSymbol = Math.floor(this.sampleRate * this.symbolDuration);
|
||||||
|
this.encodeLowPrio = [];
|
||||||
|
this.symbolSamples = [];
|
||||||
|
this.lastBlackStep = 0;
|
||||||
|
this.port.onmessage = (e) => {
|
||||||
|
if (e.data.type === 'encode') {
|
||||||
|
this.symbolSamples.push(...this.encodeSymbols(e.data.symbols));
|
||||||
|
this.symbolSamples.push(...this.encodeBlack(this.sampleRate * 0.02));
|
||||||
|
}
|
||||||
|
if (e.data.type === 'encodeLowPrio') {
|
||||||
|
this.encodeLowPrio.push(e.data.symbols);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
dtmfFrequencies = [
|
||||||
|
[697, 770, 852, 941], // Fréquences basses
|
||||||
|
[1209, 1336, 1477, 1633] // Fréquences hautes
|
||||||
|
];
|
||||||
|
|
||||||
|
encodeSymbols(symbols) {
|
||||||
|
const samples = [];
|
||||||
|
for (const symbol of symbols) {
|
||||||
|
const lf = this.dtmfFrequencies[0][symbol % 4]; // Fréquence basse
|
||||||
|
const hf = this.dtmfFrequencies[1][Math.floor(symbol / 4)]; // Fréquence haute
|
||||||
|
// console.log(`Symbol: ${symbol}, LF: ${lf} Hz, HF: ${hf} Hz`);
|
||||||
|
for (let i = 0; i < this.samplesPerSymbol; i++) {
|
||||||
|
const t = i / this.sampleRate;
|
||||||
|
const t2 = (this.lastBlackStep + i) / this.sampleRate;
|
||||||
|
samples.push(0.5 * Math.sin(2 * Math.PI * lf * t) + 0.5 * Math.sin(2 * Math.PI * hf * t) // Signal DTMF
|
||||||
|
+ Math.sin(2 * Math.PI * 150 * t2) * (0.0625 * (Math.sin(2 * Math.PI * 0.5 * t2) + 1))); // Ajouter un signal à 150 Hz pour le "black"
|
||||||
|
}
|
||||||
|
this.lastBlackStep += this.samplesPerSymbol;
|
||||||
|
|
||||||
|
// ajouter un silence de 10 ms entre les symboles
|
||||||
|
samples.push(...this.encodeBlack(this.sampleRate * 0.01)); // Silence
|
||||||
|
}
|
||||||
|
return samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
encodeBlack(size) {
|
||||||
|
const samples = [];
|
||||||
|
|
||||||
|
for (let i = 0; i < size; i++) {
|
||||||
|
const t = (this.lastBlackStep + i) / this.sampleRate;
|
||||||
|
samples.push(Math.sin(2 * Math.PI * 150 * t) * (0.0625 * (Math.sin(2 * Math.PI * 0.5 * t) + 1))); // Signal à 350 Hz pour le "black"
|
||||||
|
}
|
||||||
|
this.lastBlackStep += size;
|
||||||
|
this.lastBlackStep %= this.sampleRate * 2; // Réinitialiser tous les 2 secondes pour éviter les débordements
|
||||||
|
|
||||||
|
return samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(inputs, outputs, parameters) {
|
||||||
|
const output = outputs[0]; // output est un tableau de canaux (ex: [Float32Array, ...])
|
||||||
|
const channelData = output[0]; // Accéder au premier canal (mono)
|
||||||
|
|
||||||
|
if (this.symbolSamples.length === 0 && this.encodeLowPrio.length > 0) {
|
||||||
|
this.symbolSamples.push(...this.encodeSymbols(this.encodeLowPrio.shift()));
|
||||||
|
this.symbolSamples.push(...this.encodeBlack(this.sampleRate * 0.02));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.symbolSamples.length === 0) {
|
||||||
|
const samples = this.encodeBlack(channelData.length)
|
||||||
|
for (let i = 0; i < channelData.length; i++) {
|
||||||
|
channelData[i] = samples[i] || 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < channelData.length; i++) {
|
||||||
|
channelData[i] = this.symbolSamples.shift() || 0; // Prendre le prochain échantillon ou 0 si vide
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
registerProcessor('dtmf-processor', ProcessorDTMF);
|
||||||
@@ -14,8 +14,8 @@ import {ClubRoot, getClubChildren} from "./pages/club/ClubRoot.jsx";
|
|||||||
import {DemandeAff, DemandeAffOk} from "./pages/DemandeAff.jsx";
|
import {DemandeAff, DemandeAffOk} from "./pages/DemandeAff.jsx";
|
||||||
import {MePage} from "./pages/MePage.jsx";
|
import {MePage} from "./pages/MePage.jsx";
|
||||||
import {CompetitionRoot, getCompetitionChildren} from "./pages/competition/CompetitionRoot.jsx";
|
import {CompetitionRoot, getCompetitionChildren} from "./pages/competition/CompetitionRoot.jsx";
|
||||||
import {FallingLines} from "react-loader-spinner";
|
|
||||||
import {getResultChildren, ResultRoot} from "./pages/result/ResultRoot.jsx";
|
import {getResultChildren, ResultRoot} from "./pages/result/ResultRoot.jsx";
|
||||||
|
import {useTranslation} from "react-i18next";
|
||||||
|
|
||||||
const router = createBrowserRouter([
|
const router = createBrowserRouter([
|
||||||
{
|
{
|
||||||
@@ -79,10 +79,12 @@ const router = createBrowserRouter([
|
|||||||
|
|
||||||
function GetCompetitionMangerLazy() {
|
function GetCompetitionMangerLazy() {
|
||||||
const CMLazy = lazy(() => import('./pages/competition/editor/CompetitionManagerRoot.jsx'))
|
const CMLazy = lazy(() => import('./pages/competition/editor/CompetitionManagerRoot.jsx'))
|
||||||
|
const {t} = useTranslation();
|
||||||
|
|
||||||
return <Suspense
|
return <Suspense
|
||||||
fallback={<div>
|
fallback={<div>
|
||||||
<h1>Compétition manager</h1>
|
<h1>{t("comp_manage")}</h1>
|
||||||
<p>Chargement...</p>
|
<p>{t("loading")}</p>
|
||||||
</div>}>
|
</div>}>
|
||||||
<CMLazy/>
|
<CMLazy/>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
@@ -144,6 +146,7 @@ function Root() {
|
|||||||
function ReAuthMsg() {
|
function ReAuthMsg() {
|
||||||
const {is_authenticated} = useAuth()
|
const {is_authenticated} = useAuth()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
const {t} = useTranslation();
|
||||||
|
|
||||||
const notAuthPaths = [
|
const notAuthPaths = [
|
||||||
/^\/$/s,
|
/^\/$/s,
|
||||||
@@ -161,15 +164,14 @@ function ReAuthMsg() {
|
|||||||
}}>
|
}}>
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<div className="card-header">
|
<div className="card-header">
|
||||||
<h5>Session expirée</h5>
|
<h5>{t("outdated_session.title")}</h5>
|
||||||
</div>
|
</div>
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<p className="card-text">Votre session a expirée, veuillez vous reconnecter pour continuer à
|
<p className="card-text">{t("outdated_session.message")}</p>
|
||||||
utiliser l'application.</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="card-footer">
|
<div className="card-footer">
|
||||||
<button className="btn btn-primary" onClick={() => login()} style={{marginRight: "0.5em"}}>Se reconnecter</button>
|
<button className="btn btn-primary" onClick={() => login()} style={{marginRight: "0.5em"}}>{t("outdated_session.login_button")}</button>
|
||||||
<a className="btn btn-secondary" href="/">Accueil</a>
|
<a className="btn btn-secondary" href="/">{t("nav.home")}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,14 +0,0 @@
|
|||||||
import Keycloak from "keycloak-js";
|
|
||||||
|
|
||||||
const vite_url = import.meta.env.VITE_URL;
|
|
||||||
const client_id = import.meta.env.VITE_CLIENT_ID;
|
|
||||||
|
|
||||||
const keycloak = new Keycloak({
|
|
||||||
url: `${vite_url}/auth-api`,
|
|
||||||
realm: "safca",
|
|
||||||
clientId: client_id,
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default keycloak;
|
|
||||||
115
src/main/webapp/src/assets/CategoryPreset.js
Normal file
115
src/main/webapp/src/assets/CategoryPreset.js
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
const CategoryPreset = [
|
||||||
|
{
|
||||||
|
name: "Épée",
|
||||||
|
sword: "ONE_HAND",
|
||||||
|
shield: "NONE",
|
||||||
|
categories: [
|
||||||
|
{categorie: "MINI_POUSSIN", roundDuration: 30000, pauseDuration: 60000},
|
||||||
|
{categorie: "POUSSIN", roundDuration: 30000, pauseDuration: 60000},
|
||||||
|
{categorie: "BENJAMIN", roundDuration: 45000, pauseDuration: 60000},
|
||||||
|
{categorie: "MINIME", roundDuration: 45000, pauseDuration: 60000},
|
||||||
|
{categorie: "CADET", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
],
|
||||||
|
mandatoryProtection1: 45,
|
||||||
|
mandatoryProtection2: 13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Épée Bouclier",
|
||||||
|
sword: "ONE_HAND",
|
||||||
|
shield: "STANDARD",
|
||||||
|
categories: [
|
||||||
|
{categorie: "SUPER_MINI", roundDuration: 30000, pauseDuration: 60000},
|
||||||
|
{categorie: "MINI_POUSSIN", roundDuration: 30000, pauseDuration: 60000},
|
||||||
|
{categorie: "POUSSIN", roundDuration: 45000, pauseDuration: 60000},
|
||||||
|
{categorie: "BENJAMIN", roundDuration: 45000, pauseDuration: 60000},
|
||||||
|
{categorie: "MINIME", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "CADET", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "JUNIOR", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "SENIOR1", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "SENIOR2", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "VETERAN1", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "VETERAN2", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
],
|
||||||
|
mandatoryProtection1: 45,
|
||||||
|
mandatoryProtection2: 13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Épée Bocle",
|
||||||
|
sword: "ONE_HAND",
|
||||||
|
shield: "BUCKLER",
|
||||||
|
categories: [
|
||||||
|
{categorie: "POUSSIN", roundDuration: 45000, pauseDuration: 60000},
|
||||||
|
{categorie: "BENJAMIN", roundDuration: 45000, pauseDuration: 60000},
|
||||||
|
{categorie: "MINIME", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "CADET", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "JUNIOR", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "SENIOR1", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "SENIOR2", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "VETERAN1", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "VETERAN2", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
],
|
||||||
|
mandatoryProtection1: 45,
|
||||||
|
mandatoryProtection2: 13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Épée Longue",
|
||||||
|
sword: "TWO_HAND",
|
||||||
|
shield: "NONE",
|
||||||
|
categories: [
|
||||||
|
{categorie: "JUNIOR", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "SENIOR1", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "SENIOR2", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "VETERAN1", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "VETERAN2", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
],
|
||||||
|
mandatoryProtection1: 61,
|
||||||
|
mandatoryProtection2: 29
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sabre",
|
||||||
|
sword: "SABER",
|
||||||
|
shield: "NONE",
|
||||||
|
categories: [
|
||||||
|
{categorie: "MINIME", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "CADET", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "JUNIOR", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "SENIOR1", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "SENIOR2", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "VETERAN1", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "VETERAN2", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
],
|
||||||
|
mandatoryProtection1: 47,
|
||||||
|
mandatoryProtection2: 47
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sabre Bocle",
|
||||||
|
sword: "SABER",
|
||||||
|
shield: "BUCKLER",
|
||||||
|
categories: [
|
||||||
|
{categorie: "MINIME", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "CADET", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "JUNIOR", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "SENIOR1", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "SENIOR2", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "VETERAN1", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
{categorie: "VETERAN2", roundDuration: 60000, pauseDuration: 60000},
|
||||||
|
],
|
||||||
|
mandatoryProtection1: 47,
|
||||||
|
mandatoryProtection2: 47
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Profight Léger",
|
||||||
|
sword: "ONE_HAND",
|
||||||
|
shield: "TEARDROP",
|
||||||
|
categories: [
|
||||||
|
{categorie: "SENIOR1", roundDuration: 120000, pauseDuration: 60000},
|
||||||
|
{categorie: "SENIOR2", roundDuration: 120000, pauseDuration: 60000},
|
||||||
|
{categorie: "VETERAN1", roundDuration: 120000, pauseDuration: 60000},
|
||||||
|
{categorie: "VETERAN2", roundDuration: 120000, pauseDuration: 60000},
|
||||||
|
],
|
||||||
|
mandatoryProtection1: 3647,
|
||||||
|
mandatoryProtection2: 3647
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
export default CategoryPreset;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user