feat: add pay information to licence
This commit is contained in:
parent
09f6cd7463
commit
0563c7c8de
@ -30,9 +30,13 @@ public class LicenceModel {
|
|||||||
@Schema(description = "La saison de la licence.", example = "2025")
|
@Schema(description = "La saison de la licence.", example = "2025")
|
||||||
int saison;
|
int saison;
|
||||||
|
|
||||||
@Schema(description = "Nom du médecin sur certificat médical.", example = "M. Jean") // TODO Update for date
|
@Schema(description = "Nom et date du médecin sur certificat médical.", example = "M. Jean¤2025-02-03", format = "<Nom>¤<yyyy-mm-dd>")
|
||||||
String certificate;
|
String certificate;
|
||||||
|
|
||||||
@Schema(description = "Licence validée", example = "true")
|
@Schema(description = "Licence validée", example = "true")
|
||||||
boolean validate;
|
boolean validate;
|
||||||
|
|
||||||
|
@Schema(description = "Licence payer", example = "true")
|
||||||
|
@Column(nullable = false, columnDefinition = "boolean default false")
|
||||||
|
boolean pay = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,18 +20,11 @@ import io.smallrye.mutiny.Uni;
|
|||||||
import io.smallrye.mutiny.unchecked.Unchecked;
|
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 jakarta.ws.rs.core.HttpHeaders;
|
|
||||||
import jakarta.ws.rs.core.MediaType;
|
|
||||||
import jakarta.ws.rs.core.Response;
|
|
||||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||||
import org.hibernate.reactive.mutiny.Mutiny;
|
import org.hibernate.reactive.mutiny.Mutiny;
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@WithSession
|
@WithSession
|
||||||
@ -270,7 +263,7 @@ public class AffiliationService {
|
|||||||
.call(l1 -> l1 != null && l1.stream().anyMatch(l -> l.getSaison() == saison) ?
|
.call(l1 -> l1 != null && l1.stream().anyMatch(l -> l.getSaison() == saison) ?
|
||||||
Uni.createFrom().nullItem() :
|
Uni.createFrom().nullItem() :
|
||||||
Panache.withTransaction(() -> licenceRepository.persist(
|
Panache.withTransaction(() -> licenceRepository.persist(
|
||||||
new LicenceModel(null, m, club.getId(), saison, null, true)))));
|
new LicenceModel(null, m, club.getId(), saison, null, true, false)))));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<?> accept(AffiliationRequestSaveForm form) {
|
public Uni<?> accept(AffiliationRequestSaveForm form) {
|
||||||
|
|||||||
@ -78,6 +78,7 @@ public class LicenceService {
|
|||||||
model.setSaison(form.getSaison());
|
model.setSaison(form.getSaison());
|
||||||
model.setCertificate(form.getCertificate());
|
model.setCertificate(form.getCertificate());
|
||||||
model.setValidate(form.isValidate());
|
model.setValidate(form.isValidate());
|
||||||
|
model.setPay(form.isPay());
|
||||||
return Panache.withTransaction(() -> repository.persist(model)
|
return Panache.withTransaction(() -> repository.persist(model)
|
||||||
.call(m -> m.isValidate() ? Uni.createFrom().item(membreModel)
|
.call(m -> m.isValidate() ? Uni.createFrom().item(membreModel)
|
||||||
.call(genLicenceNumberAndAccountIfNeed())
|
.call(genLicenceNumberAndAccountIfNeed())
|
||||||
@ -88,6 +89,7 @@ public class LicenceService {
|
|||||||
return repository.findById(form.getId()).chain(model -> {
|
return repository.findById(form.getId()).chain(model -> {
|
||||||
model.setCertificate(form.getCertificate());
|
model.setCertificate(form.getCertificate());
|
||||||
model.setValidate(form.isValidate());
|
model.setValidate(form.isValidate());
|
||||||
|
model.setPay(form.isPay());
|
||||||
return Panache.withTransaction(() -> repository.persist(model)
|
return Panache.withTransaction(() -> repository.persist(model)
|
||||||
.call(m -> m.isValidate() ? Mutiny.fetch(m.getMembre())
|
.call(m -> m.isValidate() ? Mutiny.fetch(m.getMembre())
|
||||||
.call(genLicenceNumberAndAccountIfNeed())
|
.call(genLicenceNumberAndAccountIfNeed())
|
||||||
@ -143,6 +145,8 @@ public class LicenceService {
|
|||||||
.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("Impossible de supprimer une licence déjà validée");
|
||||||
|
if (licenceModel.isPay())
|
||||||
|
throw new DBadRequestException("Impossible de supprimer une licence déjà payée");
|
||||||
}))
|
}))
|
||||||
.chain(__ -> Panache.withTransaction(() -> repository.deleteById(id)));
|
.chain(__ -> Panache.withTransaction(() -> repository.deleteById(id)));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,29 +78,38 @@ public class MembreService {
|
|||||||
final static String FIND_NAME_REQUEST = "unaccent(fname) ILIKE unaccent(?1) OR unaccent(lname) ILIKE unaccent(?1) " +
|
final static String FIND_NAME_REQUEST = "unaccent(fname) ILIKE unaccent(?1) OR unaccent(lname) ILIKE unaccent(?1) " +
|
||||||
"OR unaccent(fname || ' ' || lname) ILIKE unaccent(?1) OR unaccent(lname || ' ' || fname) ILIKE unaccent(?1)";
|
"OR unaccent(fname || ' ' || lname) ILIKE unaccent(?1) OR unaccent(lname || ' ' || fname) ILIKE unaccent(?1)";
|
||||||
|
|
||||||
|
private Uni<List<LicenceModel>> getLicenceListe(int licenceRequest, int payState) {
|
||||||
|
Uni<List<LicenceModel>> baseUni;
|
||||||
|
String queryStr = "saison = ?1";
|
||||||
|
if (payState == 0)
|
||||||
|
queryStr += " AND pay = FALSE";
|
||||||
|
if (payState == 1)
|
||||||
|
queryStr += " AND pay = TRUE";
|
||||||
|
if (licenceRequest == 0 || licenceRequest == 1)
|
||||||
|
baseUni = licenceRepository.list(queryStr, Utils.getSaison());
|
||||||
|
else if (licenceRequest == 2)
|
||||||
|
baseUni = licenceRepository.list(queryStr + " AND validate = FALSE", Utils.getSaison());
|
||||||
|
else if (licenceRequest == 5)
|
||||||
|
baseUni = licenceRepository.list(queryStr + " AND validate = FALSE AND LENGTH(certificate) >= 3",
|
||||||
|
Utils.getSaison());
|
||||||
|
else if (licenceRequest == 6)
|
||||||
|
baseUni = licenceRepository.list(queryStr + " AND validate = FALSE AND LENGTH(certificate) <= 2",
|
||||||
|
Utils.getSaison());
|
||||||
|
else if (licenceRequest == 3)
|
||||||
|
baseUni = licenceRepository.list(queryStr + " AND validate = TRUE", Utils.getSaison());
|
||||||
|
else
|
||||||
|
baseUni = Uni.createFrom().item(new ArrayList<>());
|
||||||
|
return baseUni;
|
||||||
|
}
|
||||||
|
|
||||||
public Uni<PageResult<SimpleMembre>> searchAdmin(int limit, int page, String search, String club,
|
public Uni<PageResult<SimpleMembre>> searchAdmin(int limit, int page, String search, String club,
|
||||||
int licenceRequest) {
|
int licenceRequest, int payState) {
|
||||||
if (search == null)
|
if (search == null)
|
||||||
search = "";
|
search = "";
|
||||||
search = "%" + search.replaceAll(" ", "% %") + "%";
|
search = "%" + search.replaceAll(" ", "% %") + "%";
|
||||||
|
|
||||||
String finalSearch = search;
|
String finalSearch = search;
|
||||||
|
Uni<List<LicenceModel>> baseUni = getLicenceListe(licenceRequest, payState);
|
||||||
Uni<List<LicenceModel>> baseUni;
|
|
||||||
if (licenceRequest == 0 || licenceRequest == 1)
|
|
||||||
baseUni = licenceRepository.list("saison = ?1", Utils.getSaison());
|
|
||||||
else if (licenceRequest == 2)
|
|
||||||
baseUni = licenceRepository.list("saison = ?1 AND validate = FALSE", Utils.getSaison());
|
|
||||||
else if (licenceRequest == 5)
|
|
||||||
baseUni = licenceRepository.list("saison = ?1 AND validate = FALSE AND LENGTH(certificate) >= 3",
|
|
||||||
Utils.getSaison());
|
|
||||||
else if (licenceRequest == 6)
|
|
||||||
baseUni = licenceRepository.list("saison = ?1 AND validate = FALSE AND LENGTH(certificate) <= 2",
|
|
||||||
Utils.getSaison());
|
|
||||||
else if (licenceRequest == 3)
|
|
||||||
baseUni = licenceRepository.list("saison = ?1 AND validate = TRUE", Utils.getSaison());
|
|
||||||
else
|
|
||||||
baseUni = Uni.createFrom().item(new ArrayList<>());
|
|
||||||
|
|
||||||
return baseUni
|
return baseUni
|
||||||
.map(l -> l.stream().map(l2 -> l2.getMembre().getId()).toList())
|
.map(l -> l.stream().map(l2 -> l2.getMembre().getId()).toList())
|
||||||
@ -110,7 +119,6 @@ public class MembreService {
|
|||||||
String idf = ((licenceRequest == 0 || licenceRequest == 4) ? "NOT IN" : "IN");
|
String idf = ((licenceRequest == 0 || licenceRequest == 4) ? "NOT IN" : "IN");
|
||||||
|
|
||||||
if (club == null || club.isBlank()) {
|
if (club == null || club.isBlank()) {
|
||||||
LOGGER.info(ids);
|
|
||||||
query = repository.find(
|
query = repository.find(
|
||||||
"id " + idf + " ?2 AND (" + FIND_NAME_REQUEST + ")",
|
"id " + idf + " ?2 AND (" + FIND_NAME_REQUEST + ")",
|
||||||
Sort.ascending("fname", "lname"), finalSearch, ids)
|
Sort.ascending("fname", "lname"), finalSearch, ids)
|
||||||
@ -131,7 +139,7 @@ public class MembreService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uni<PageResult<SimpleMembre>> search(int limit, int page, String search, int licenceRequest,
|
public Uni<PageResult<SimpleMembre>> search(int limit, int page, String search, int licenceRequest, int payState,
|
||||||
String subject) {
|
String subject) {
|
||||||
if (search == null)
|
if (search == null)
|
||||||
search = "";
|
search = "";
|
||||||
@ -139,21 +147,7 @@ public class MembreService {
|
|||||||
|
|
||||||
String finalSearch = search;
|
String finalSearch = search;
|
||||||
|
|
||||||
Uni<List<LicenceModel>> baseUni;
|
Uni<List<LicenceModel>> baseUni = getLicenceListe(licenceRequest, payState);
|
||||||
if (licenceRequest == 0 || licenceRequest == 1)
|
|
||||||
baseUni = licenceRepository.list("saison = ?1", Utils.getSaison());
|
|
||||||
else if (licenceRequest == 2)
|
|
||||||
baseUni = licenceRepository.list("saison = ?1 AND validate = FALSE", Utils.getSaison());
|
|
||||||
else if (licenceRequest == 5)
|
|
||||||
baseUni = licenceRepository.list("saison = ?1 AND validate = FALSE AND LENGTH(certificate) >= 3",
|
|
||||||
Utils.getSaison());
|
|
||||||
else if (licenceRequest == 6)
|
|
||||||
baseUni = licenceRepository.list("saison = ?1 AND validate = FALSE AND LENGTH(certificate) <= 2",
|
|
||||||
Utils.getSaison());
|
|
||||||
else if (licenceRequest == 3)
|
|
||||||
baseUni = licenceRepository.list("saison = ?1 AND validate = TRUE", Utils.getSaison());
|
|
||||||
else
|
|
||||||
baseUni = Uni.createFrom().item(new ArrayList<>());
|
|
||||||
|
|
||||||
return baseUni
|
return baseUni
|
||||||
.map(l -> l.stream().map(l2 -> l2.getMembre().getId()).toList())
|
.map(l -> l.stream().map(l2 -> l2.getMembre().getId()).toList())
|
||||||
|
|||||||
@ -58,12 +58,13 @@ public class MembreAdminEndpoints {
|
|||||||
@Parameter(description = "Page à consulter") @QueryParam("page") Integer page,
|
@Parameter(description = "Page à consulter") @QueryParam("page") Integer page,
|
||||||
@Parameter(description = "Text à rechercher") @QueryParam("search") String search,
|
@Parameter(description = "Text à rechercher") @QueryParam("search") String search,
|
||||||
@Parameter(description = "Club à filter") @QueryParam("club") String club,
|
@Parameter(description = "Club à filter") @QueryParam("club") String club,
|
||||||
@Parameter(description = "Etat de la demande de licence: 0 -> sans demande, 1 -> avec demande ou validée, 2 -> toute les demande non validée, 3 -> validée, 4 -> tout, 5 -> demande complete, 6 -> demande incomplete") @QueryParam("licenceRequest") int licenceRequest) {
|
@Parameter(description = "Etat de la demande de licence: 0 -> sans demande, 1 -> avec demande ou validée, 2 -> toute les demande non validée, 3 -> validée, 4 -> tout, 5 -> demande complete, 6 -> demande incomplete") @QueryParam("licenceRequest") int licenceRequest,
|
||||||
|
@Parameter(description = "Etat du payment: 0 -> non payer, 1 -> payer, 2 -> tout") @QueryParam("payment") int payment) {
|
||||||
if (limit == null)
|
if (limit == null)
|
||||||
limit = 50;
|
limit = 50;
|
||||||
if (page == null || page < 1)
|
if (page == null || page < 1)
|
||||||
page = 1;
|
page = 1;
|
||||||
return membreService.searchAdmin(limit, page - 1, search, club, licenceRequest);
|
return membreService.searchAdmin(limit, page - 1, search, club, licenceRequest, payment);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|||||||
@ -50,12 +50,13 @@ public class MembreClubEndpoints {
|
|||||||
@Parameter(description = "Nombre max de résulta (max 50)") @QueryParam("limit") Integer limit,
|
@Parameter(description = "Nombre max de résulta (max 50)") @QueryParam("limit") Integer limit,
|
||||||
@Parameter(description = "Page à consulter") @QueryParam("page") Integer page,
|
@Parameter(description = "Page à consulter") @QueryParam("page") Integer page,
|
||||||
@Parameter(description = "Text à rechercher") @QueryParam("search") String search,
|
@Parameter(description = "Text à rechercher") @QueryParam("search") String search,
|
||||||
@Parameter(description = "Etat de la demande de licence: 0 -> sans demande, 1 -> avec demande ou validée, 2 -> toute les demande non validée, 3 -> validée, 4 -> tout, 5 -> demande complete, 6 -> demande incomplete") @QueryParam("licenceRequest") int licenceRequest) {
|
@Parameter(description = "Etat de la demande de licence: 0 -> sans demande, 1 -> avec demande ou validée, 2 -> toute les demande non validée, 3 -> validée, 4 -> tout, 5 -> demande complete, 6 -> demande incomplete") @QueryParam("licenceRequest") int licenceRequest,
|
||||||
|
@Parameter(description = "Etat du payment: 0 -> non payer, 1 -> payer, 2 -> tout") @QueryParam("payment") int payment) {
|
||||||
if (limit == null)
|
if (limit == null)
|
||||||
limit = 50;
|
limit = 50;
|
||||||
if (page == null || page < 1)
|
if (page == null || page < 1)
|
||||||
page = 1;
|
page = 1;
|
||||||
return membreService.search(limit, page - 1, search, licenceRequest, securityCtx.getSubject());
|
return membreService.search(limit, page - 1, search, licenceRequest, payment, securityCtx.getSubject());
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
|||||||
@ -22,6 +22,8 @@ public class SimpleLicence {
|
|||||||
String certificate;
|
String certificate;
|
||||||
@Schema(description = "Validation de la licence", example = "true")
|
@Schema(description = "Validation de la licence", example = "true")
|
||||||
boolean validate;
|
boolean validate;
|
||||||
|
@Schema(description = "Licence payer", example = "true")
|
||||||
|
boolean pay;
|
||||||
|
|
||||||
public static SimpleLicence fromModel(LicenceModel model) {
|
public static SimpleLicence fromModel(LicenceModel model) {
|
||||||
if (model == null)
|
if (model == null)
|
||||||
@ -33,6 +35,7 @@ public class SimpleLicence {
|
|||||||
.saison(model.getSaison())
|
.saison(model.getSaison())
|
||||||
.certificate(model.getCertificate())
|
.certificate(model.getCertificate())
|
||||||
.validate(model.isValidate())
|
.validate(model.isValidate())
|
||||||
|
.pay(model.isPay())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,10 +21,14 @@ public class LicenceForm {
|
|||||||
private int saison;
|
private int saison;
|
||||||
|
|
||||||
@FormParam("certificate")
|
@FormParam("certificate")
|
||||||
@Schema(description = "Nom du médecin sur certificat médical.", example = "M. Jean", required = true)
|
@Schema(description = "Nom et date du médecin sur certificat médical.", example = "M. Jean¤2025-02-03", format = "<Nom>¤<yyyy-mm-dd>", required = true)
|
||||||
private String certificate = null;
|
private String certificate = null;
|
||||||
|
|
||||||
@FormParam("validate")
|
@FormParam("validate")
|
||||||
@Schema(description = "Licence validée (seuls les admin pourrons enregistrer cette valeur)", example = "true", required = true)
|
@Schema(description = "Licence validée (seuls les admin pourrons modifier cette valeur)", example = "true", required = true)
|
||||||
private boolean validate;
|
private boolean validate;
|
||||||
|
|
||||||
|
@FormParam("pay")
|
||||||
|
@Schema(description = "Paiement de la licence (seuls les admin pourrons modifier cette valeur)", example = "true", required = true)
|
||||||
|
private boolean pay;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,8 @@ import {apiAxios, errFormater} from "../utils/Tools.js";
|
|||||||
import {toast} from "react-toastify";
|
import {toast} from "react-toastify";
|
||||||
import {SearchBar} from "../components/SearchBar.jsx";
|
import {SearchBar} from "../components/SearchBar.jsx";
|
||||||
import * as XLSX from "xlsx-js-style";
|
import * as XLSX from "xlsx-js-style";
|
||||||
|
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||||
|
import {faEuroSign} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
|
||||||
export function MemberList({source}) {
|
export function MemberList({source}) {
|
||||||
const {hash} = useLocation();
|
const {hash} = useLocation();
|
||||||
@ -23,14 +25,15 @@ export function MemberList({source}) {
|
|||||||
const [clubFilter, setClubFilter] = useState("");
|
const [clubFilter, setClubFilter] = useState("");
|
||||||
const [stateFilter, setStateFilter] = useState(4)
|
const [stateFilter, setStateFilter] = useState(4)
|
||||||
const [lastSearch, setLastSearch] = useState("");
|
const [lastSearch, setLastSearch] = useState("");
|
||||||
|
const [paymentFilter, setPaymentFilter] = useState(2);
|
||||||
|
|
||||||
const setLoading = useLoadingSwitcher()
|
const setLoading = useLoadingSwitcher()
|
||||||
const {data, error, refresh} = useFetch(`/member/find/${source}?page=${page}&licenceRequest=${stateFilter}`, setLoading, 1)
|
const {data, error, refresh} = useFetch(`/member/find/${source}?page=${page}&licenceRequest=${stateFilter}&payment=${paymentFilter}`, setLoading, 1)
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
refresh(`/member/find/${source}?page=${page}&search=${lastSearch}&club=${clubFilter}&licenceRequest=${stateFilter}`);
|
refresh(`/member/find/${source}?page=${page}&search=${lastSearch}&club=${clubFilter}&licenceRequest=${stateFilter}&payment=${paymentFilter}`);
|
||||||
}, [hash, clubFilter, stateFilter]);
|
}, [hash, clubFilter, stateFilter, lastSearch, paymentFilter]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!data)
|
if (!data)
|
||||||
@ -74,7 +77,6 @@ export function MemberList({source}) {
|
|||||||
if (search === lastSearch)
|
if (search === lastSearch)
|
||||||
return;
|
return;
|
||||||
setLastSearch(search);
|
setLastSearch(search);
|
||||||
refresh(`/member/find/${source}?page=${page}&search=${search}&club=${clubFilter}&licenceRequest=${stateFilter}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return <>
|
return <>
|
||||||
@ -102,7 +104,8 @@ export function MemberList({source}) {
|
|||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<FiltreBar showLicenceState={showLicenceState} setShowLicenceState={setShowLicenceState} data={data}
|
<FiltreBar showLicenceState={showLicenceState} setShowLicenceState={setShowLicenceState} data={data}
|
||||||
clubFilter={clubFilter} setClubFilter={setClubFilter} source={source}
|
clubFilter={clubFilter} setClubFilter={setClubFilter} source={source}
|
||||||
stateFilter={stateFilter} setStateFilter={setStateFilter}/>
|
stateFilter={stateFilter} setStateFilter={setStateFilter} paymentFilter={paymentFilter}
|
||||||
|
setPaymentFilter={setPaymentFilter}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -361,7 +364,8 @@ function MakeCentralPanel({data, visibleMember, navigate, showLicenceState, page
|
|||||||
function MakeRow({member, showLicenceState, navigate, source}) {
|
function MakeRow({member, showLicenceState, navigate, source}) {
|
||||||
const rowContent = <>
|
const rowContent = <>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<span className="col-auto">{member.licence_number ? String(member.licence_number).padStart(5, '0') : "-------"}</span>
|
<span className="col-auto">{(member.licence_number ? String(member.licence_number).padStart(5, '0') : "-------") + " "}
|
||||||
|
{(showLicenceState && member.licence != null && member.licence.pay)? <FontAwesomeIcon icon={faEuroSign}/> : <> </>}</span>
|
||||||
<div className="ms-2 col-auto">
|
<div className="ms-2 col-auto">
|
||||||
<div className="fw-bold">{member.fname} {member.lname}</div>
|
<div className="fw-bold">{member.fname} {member.lname}</div>
|
||||||
</div>
|
</div>
|
||||||
@ -386,7 +390,7 @@ function MakeRow({member, showLicenceState, navigate, source}) {
|
|||||||
|
|
||||||
let allClub = []
|
let allClub = []
|
||||||
|
|
||||||
function FiltreBar({showLicenceState, setShowLicenceState, data, clubFilter, setClubFilter, source, stateFilter, setStateFilter}) {
|
function FiltreBar({showLicenceState, setShowLicenceState, data, clubFilter, setClubFilter, source, stateFilter, setStateFilter, paymentFilter, setPaymentFilter}) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!data)
|
if (!data)
|
||||||
return;
|
return;
|
||||||
@ -410,6 +414,14 @@ function FiltreBar({showLicenceState, setShowLicenceState, data, clubFilter, set
|
|||||||
<option value={3}>Licence validée</option>
|
<option value={3}>Licence validée</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<select className="form-select" value={paymentFilter} onChange={event => setPaymentFilter(Number(event.target.value))}
|
||||||
|
hidden={stateFilter === 0 || stateFilter === 4}>
|
||||||
|
<option value={2}>Tout les états de paiement</option>
|
||||||
|
<option value={0}>Sans paiement</option>
|
||||||
|
<option value={1}>Avec paiement</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,8 @@ import {apiAxios, errFormater} from "../utils/Tools.js";
|
|||||||
import {toast} from "react-toastify";
|
import {toast} from "react-toastify";
|
||||||
import {SearchBar} from "../components/SearchBar.jsx";
|
import {SearchBar} from "../components/SearchBar.jsx";
|
||||||
import {ConfirmDialog} from "../components/ConfirmDialog.jsx";
|
import {ConfirmDialog} from "../components/ConfirmDialog.jsx";
|
||||||
|
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||||
|
import {faEuroSign} from "@fortawesome/free-solid-svg-icons";
|
||||||
|
|
||||||
export function ValidateList({source}) {
|
export function ValidateList({source}) {
|
||||||
const {hash} = useLocation();
|
const {hash} = useLocation();
|
||||||
@ -20,16 +22,21 @@ export function ValidateList({source}) {
|
|||||||
const [clubFilter, setClubFilter] = useState("");
|
const [clubFilter, setClubFilter] = useState("");
|
||||||
const [stateFilter, setStateFilter] = useState(2)
|
const [stateFilter, setStateFilter] = useState(2)
|
||||||
const [lastSearch, setLastSearch] = useState("");
|
const [lastSearch, setLastSearch] = useState("");
|
||||||
|
const [paymentFilter, setPaymentFilter] = useState(2);
|
||||||
|
|
||||||
const [selectedMembers, setSelectedMembers] = useState([]);
|
const [selectedMembers, setSelectedMembers] = useState([]);
|
||||||
|
|
||||||
const setLoading = useLoadingSwitcher()
|
const setLoading = useLoadingSwitcher()
|
||||||
const {data, error, refresh} = useFetch(`/member/find/${source}?page=${page}&licenceRequest=${stateFilter}`, setLoading, 1)
|
const {
|
||||||
|
data,
|
||||||
|
error,
|
||||||
|
refresh
|
||||||
|
} = useFetch(`/member/find/${source}?page=${page}&licenceRequest=${stateFilter}&payment=${paymentFilter}`, setLoading, 1)
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
refresh(`/member/find/${source}?page=${page}&search=${lastSearch}&club=${clubFilter}&licenceRequest=${stateFilter}`);
|
refresh(`/member/find/${source}?page=${page}&search=${lastSearch}&club=${clubFilter}&licenceRequest=${stateFilter}&payment=${paymentFilter}`);
|
||||||
}, [hash, clubFilter, stateFilter]);
|
}, [hash, clubFilter, stateFilter, lastSearch, paymentFilter]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!data)
|
if (!data)
|
||||||
@ -70,7 +77,6 @@ export function ValidateList({source}) {
|
|||||||
if (search === lastSearch)
|
if (search === lastSearch)
|
||||||
return;
|
return;
|
||||||
setLastSearch(search);
|
setLastSearch(search);
|
||||||
refresh(`/member/find/${source}?page=${page}&search=${search}&club=${clubFilter}&licenceRequest=${stateFilter}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleValidation = () => {
|
const handleValidation = () => {
|
||||||
@ -92,7 +98,7 @@ export function ValidateList({source}) {
|
|||||||
}
|
}
|
||||||
).then(() => {
|
).then(() => {
|
||||||
setSelectedMembers([]);
|
setSelectedMembers([]);
|
||||||
refresh(`/member/find/${source}?page=${page}&search=${lastSearch}&club=${clubFilter}&licenceRequest=${stateFilter}`);
|
refresh(`/member/find/${source}?page=${page}&search=${lastSearch}&club=${clubFilter}&licenceRequest=${stateFilter}&payment=${paymentFilter}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +125,8 @@ export function ValidateList({source}) {
|
|||||||
<div className="card-header">Filtre</div>
|
<div className="card-header">Filtre</div>
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<FiltreBar data={data} clubFilter={clubFilter} setClubFilter={setClubFilter} source={source}
|
<FiltreBar data={data} clubFilter={clubFilter} setClubFilter={setClubFilter} source={source}
|
||||||
stateFilter={stateFilter} setStateFilter={setStateFilter}/>
|
stateFilter={stateFilter} setStateFilter={setStateFilter} paymentFilter={paymentFilter}
|
||||||
|
setPaymentFilter={setPaymentFilter}/>
|
||||||
</div>
|
</div>
|
||||||
</div>}
|
</div>}
|
||||||
|
|
||||||
@ -128,7 +135,8 @@ export function ValidateList({source}) {
|
|||||||
<button className="btn btn-primary" data-bs-toggle="modal" data-bs-target="#confirm-validation">Valider
|
<button className="btn btn-primary" data-bs-toggle="modal" data-bs-target="#confirm-validation">Valider
|
||||||
les {selectedMembers.length} licences sélectionnée
|
les {selectedMembers.length} licences sélectionnée
|
||||||
</button>
|
</button>
|
||||||
<ConfirmDialog title="Validation des licences" message={"Êtes-vous sûr de vouloir valider les "+selectedMembers.length+" licences ?"}
|
<ConfirmDialog title="Validation des licences"
|
||||||
|
message={"Êtes-vous sûr de vouloir valider les " + selectedMembers.length + " licences ?"}
|
||||||
onConfirm={handleValidation} id="confirm-validation"/>
|
onConfirm={handleValidation} id="confirm-validation"/>
|
||||||
</>}
|
</>}
|
||||||
</div>
|
</div>
|
||||||
@ -223,7 +231,8 @@ function MakeRow({member, source, isChecked, onCheckboxClick, onRowClick}) {
|
|||||||
<input className="form-check-input me-1" type="checkbox" checked={isChecked || false} onChange={() => {
|
<input className="form-check-input me-1" type="checkbox" checked={isChecked || false} onChange={() => {
|
||||||
}}
|
}}
|
||||||
onClick={(e) => onCheckboxClick(e, member.id)}/>
|
onClick={(e) => onCheckboxClick(e, member.id)}/>
|
||||||
<span>{member.licence_number ? String(member.licence_number).padStart(5, '0') : "-------"}</span>
|
<span className="col-auto">{(member.licence_number ? String(member.licence_number).padStart(5, '0') : "-------") + " "}
|
||||||
|
{(member.licence != null && member.licence.pay)? <FontAwesomeIcon icon={faEuroSign}/> : <> </>}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="ms-2 col-auto">
|
<div className="ms-2 col-auto">
|
||||||
<div className="fw-bold">{member.fname} {member.lname}</div>
|
<div className="fw-bold">{member.fname} {member.lname}</div>
|
||||||
@ -251,7 +260,7 @@ function MakeRow({member, source, isChecked, onCheckboxClick, onRowClick}) {
|
|||||||
|
|
||||||
let allClub = []
|
let allClub = []
|
||||||
|
|
||||||
function FiltreBar({data, clubFilter, setClubFilter, source, stateFilter, setStateFilter}) {
|
function FiltreBar({data, clubFilter, setClubFilter, source, stateFilter, setStateFilter, paymentFilter, setPaymentFilter}) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!data)
|
if (!data)
|
||||||
return;
|
return;
|
||||||
@ -268,6 +277,13 @@ function FiltreBar({data, clubFilter, setClubFilter, source, stateFilter, setSta
|
|||||||
<option value={6}>Demande incomplet</option>
|
<option value={6}>Demande incomplet</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<select className="form-select" value={paymentFilter} onChange={event => setPaymentFilter(Number(event.target.value))}>
|
||||||
|
<option value={2}>Tout les états de paiement</option>
|
||||||
|
<option value={0}>Sans paiement</option>
|
||||||
|
<option value={1}>Avec paiement</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import {useLoadingSwitcher} from "../../../hooks/useLoading.jsx";
|
|||||||
import {useFetch} from "../../../hooks/useFetch.js";
|
import {useFetch} from "../../../hooks/useFetch.js";
|
||||||
import {useEffect, useReducer, useState} from "react";
|
import {useEffect, useReducer, useState} from "react";
|
||||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||||
import {faPen} from "@fortawesome/free-solid-svg-icons";
|
import {faEuroSign, faPen} from "@fortawesome/free-solid-svg-icons";
|
||||||
import {AxiosError} from "../../../components/AxiosError.jsx";
|
import {AxiosError} from "../../../components/AxiosError.jsx";
|
||||||
import {apiAxios, errFormater, getSaison} from "../../../utils/Tools.js";
|
import {apiAxios, errFormater, getSaison} from "../../../utils/Tools.js";
|
||||||
import {toast} from "react-toastify";
|
import {toast} from "react-toastify";
|
||||||
@ -66,7 +66,7 @@ export function LicenceCard({userData}) {
|
|||||||
return <div key={index}
|
return <div key={index}
|
||||||
className={"list-group-item d-flex justify-content-between align-items-start list-group-item-" +
|
className={"list-group-item d-flex justify-content-between align-items-start list-group-item-" +
|
||||||
(licence.validate ? "success" : (licence.certificate?.length > 1 ? "warning" : "danger"))}>
|
(licence.validate ? "success" : (licence.certificate?.length > 1 ? "warning" : "danger"))}>
|
||||||
<div className="me-auto">{licence?.saison}-{licence?.saison + 1}</div>
|
<div className="me-auto">{licence?.saison}-{licence?.saison + 1} {(licence.pay) && <FontAwesomeIcon icon={faEuroSign}/>}</div>
|
||||||
<button className="badge btn btn-primary rounded-pill" data-bs-toggle="modal"
|
<button className="badge btn btn-primary rounded-pill" data-bs-toggle="modal"
|
||||||
data-bs-target="#LicenceModal" onClick={_ => setModal(licence)}>
|
data-bs-target="#LicenceModal" onClick={_ => setModal(licence)}>
|
||||||
<FontAwesomeIcon icon={faPen}/></button>
|
<FontAwesomeIcon icon={faPen}/></button>
|
||||||
@ -134,6 +134,7 @@ function ModalContent({licence, dispatch}) {
|
|||||||
const [certificateBy, setCertificateBy] = useState("")
|
const [certificateBy, setCertificateBy] = useState("")
|
||||||
const [certificateDate, setCertificateDate] = useState("")
|
const [certificateDate, setCertificateDate] = useState("")
|
||||||
const [validate, setValidate] = useState(false)
|
const [validate, setValidate] = useState(false)
|
||||||
|
const [pay, setPay] = useState(false)
|
||||||
const [isNew, setNew] = useState(true)
|
const [isNew, setNew] = useState(true)
|
||||||
const setSeason = (event) => {
|
const setSeason = (event) => {
|
||||||
setSaison(Number(event.target.value))
|
setSaison(Number(event.target.value))
|
||||||
@ -147,6 +148,9 @@ function ModalContent({licence, dispatch}) {
|
|||||||
const handleValidateChange = (event) => {
|
const handleValidateChange = (event) => {
|
||||||
setValidate(event.target.value === 'true');
|
setValidate(event.target.value === 'true');
|
||||||
}
|
}
|
||||||
|
const handlePayChange = (event) => {
|
||||||
|
setPay(event.target.value === 'true');
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (licence.id !== -1) {
|
if (licence.id !== -1) {
|
||||||
@ -160,12 +164,14 @@ function ModalContent({licence, dispatch}) {
|
|||||||
setCertificateDate(licence.certificate.split('¤')[1])
|
setCertificateDate(licence.certificate.split('¤')[1])
|
||||||
}
|
}
|
||||||
setValidate(licence.validate)
|
setValidate(licence.validate)
|
||||||
|
setPay(licence.pay);
|
||||||
} else {
|
} else {
|
||||||
setNew(true)
|
setNew(true)
|
||||||
setSaison(getSaison())
|
setSaison(getSaison())
|
||||||
setCertificateBy("")
|
setCertificateBy("")
|
||||||
setCertificateDate("")
|
setCertificateDate("")
|
||||||
setValidate(false)
|
setValidate(false)
|
||||||
|
setPay(false);
|
||||||
}
|
}
|
||||||
}, [licence]);
|
}, [licence]);
|
||||||
|
|
||||||
@ -197,6 +203,8 @@ function ModalContent({licence, dispatch}) {
|
|||||||
<input type="date" className="form-control" placeholder="jj/mm/aaaa" name="certificateDate"
|
<input type="date" className="form-control" placeholder="jj/mm/aaaa" name="certificateDate"
|
||||||
aria-describedby="basic-addon2" value={certificateDate} onChange={handleCertificateDateChange}/>
|
aria-describedby="basic-addon2" value={certificateDate} onChange={handleCertificateDateChange}/>
|
||||||
</div>
|
</div>
|
||||||
|
<RadioGroupeOnOff name="pay" text="Paiement de la licence" value={pay}
|
||||||
|
onChange={handlePayChange}/>
|
||||||
<RadioGroupeOnOff name="validate" text="Validation de la licence" value={validate}
|
<RadioGroupeOnOff name="validate" text="Validation de la licence" value={validate}
|
||||||
onChange={handleValidateChange}/>
|
onChange={handleValidateChange}/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import {useLoadingSwitcher} from "../../../hooks/useLoading.jsx";
|
|||||||
import {useFetch} from "../../../hooks/useFetch.js";
|
import {useFetch} from "../../../hooks/useFetch.js";
|
||||||
import {useEffect, useReducer, useState} from "react";
|
import {useEffect, useReducer, useState} from "react";
|
||||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||||
import {faInfo, faPen} from "@fortawesome/free-solid-svg-icons";
|
import {faEuroSign, faInfo, faPen} from "@fortawesome/free-solid-svg-icons";
|
||||||
import {AxiosError} from "../../../components/AxiosError.jsx";
|
import {AxiosError} from "../../../components/AxiosError.jsx";
|
||||||
import {apiAxios, errFormater, getSaison} from "../../../utils/Tools.js";
|
import {apiAxios, errFormater, getSaison} from "../../../utils/Tools.js";
|
||||||
import {toast} from "react-toastify";
|
import {toast} from "react-toastify";
|
||||||
@ -172,13 +172,16 @@ function ModalContent({licence, dispatch}) {
|
|||||||
<span>Certificat médical</span>
|
<span>Certificat médical</span>
|
||||||
<div className="input-group mb-3 ">
|
<div className="input-group mb-3 ">
|
||||||
<span className="input-group-text" id="basic-addon2">Fait par</span>
|
<span className="input-group-text" id="basic-addon2">Fait par</span>
|
||||||
<input type="text" className="form-control" placeholder="Fait par" name="certificateBy"
|
<input type="text" className="form-control" placeholder="Fait par" name="certificateBy" disabled={licence.validate}
|
||||||
aria-label="Fait par" aria-describedby="basic-addon2" value={certificateBy} onChange={handleCertificateByChange}/>
|
aria-label="Fait par" aria-describedby="basic-addon2" value={certificateBy} onChange={handleCertificateByChange}/>
|
||||||
<span className="input-group-text" id="basic-addon2">, le</span>
|
<span className="input-group-text" id="basic-addon2">, le</span>
|
||||||
<input type="date" className="form-control" placeholder="jj/mm/aaaa" name="certificateDate"
|
<input type="date" className="form-control" placeholder="jj/mm/aaaa" name="certificateDate" disabled={licence.validate}
|
||||||
aria-describedby="basic-addon2" value={certificateDate} onChange={handleCertificateDateChange}/>
|
aria-describedby="basic-addon2" value={certificateDate} onChange={handleCertificateDateChange}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="input-group mb-3 justify-content-md-center">
|
||||||
|
<div>Paiement de la licence: <ColoredText boolean={licence.pay}/></div>
|
||||||
|
</div>
|
||||||
<div className="input-group mb-3 justify-content-md-center">
|
<div className="input-group mb-3 justify-content-md-center">
|
||||||
<div>Validation de la licence: <ColoredText boolean={licence.validate}/></div>
|
<div>Validation de la licence: <ColoredText boolean={licence.validate}/></div>
|
||||||
</div>
|
</div>
|
||||||
@ -187,7 +190,7 @@ function ModalContent({licence, dispatch}) {
|
|||||||
{currentSaison && !licence.validate &&
|
{currentSaison && !licence.validate &&
|
||||||
<button type="submit" className="btn btn-primary" data-bs-dismiss="modal">Enregistrer</button>}
|
<button type="submit" className="btn btn-primary" data-bs-dismiss="modal">Enregistrer</button>}
|
||||||
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
|
<button type="button" className="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
|
||||||
{currentSaison && !licence.validate && licence.id !== -1 &&
|
{currentSaison && !licence.validate && licence.id !== -1 && !licence.pay &&
|
||||||
<button type="button" className="btn btn-danger" data-bs-dismiss="modal"
|
<button type="button" className="btn btn-danger" data-bs-dismiss="modal"
|
||||||
onClick={() => removeLicence(licence.id, dispatch)}>Annuler</button>}
|
onClick={() => removeLicence(licence.id, dispatch)}>Annuler</button>}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user