feat: add affiliation request save
This commit is contained in:
parent
b0232cd7b7
commit
9615660101
@ -0,0 +1,43 @@
|
|||||||
|
package fr.titionfire.ffsaf.data.model;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.annotations.RegisterForReflection;
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@RegisterForReflection
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "affiliation_request")
|
||||||
|
public class AffiliationRequestModel {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
Long id;
|
||||||
|
|
||||||
|
String name;
|
||||||
|
String siren;
|
||||||
|
String RNA;
|
||||||
|
String address;
|
||||||
|
|
||||||
|
String president_lname;
|
||||||
|
String president_fname;
|
||||||
|
String president_email;
|
||||||
|
int president_lincence;
|
||||||
|
|
||||||
|
String tresorier_lname;
|
||||||
|
String tresorier_fname;
|
||||||
|
String tresorier_email;
|
||||||
|
int tresorier_lincence;
|
||||||
|
|
||||||
|
String secretaire_lname;
|
||||||
|
String secretaire_fname;
|
||||||
|
String secretaire_email;
|
||||||
|
int secretaire_lincence;
|
||||||
|
|
||||||
|
int saison;
|
||||||
|
}
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
package fr.titionfire.ffsaf.data.repository;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.AffiliationRequestModel;
|
||||||
|
import io.quarkus.hibernate.reactive.panache.PanacheRepositoryBase;
|
||||||
|
import jakarta.enterprise.context.ApplicationScoped;
|
||||||
|
|
||||||
|
@ApplicationScoped
|
||||||
|
public class AffiliationRequestRepository implements PanacheRepositoryBase<AffiliationRequestModel, Long> {
|
||||||
|
}
|
||||||
@ -0,0 +1,60 @@
|
|||||||
|
package fr.titionfire.ffsaf.domain.service;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.AffiliationRequestModel;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.AffiliationRequestRepository;
|
||||||
|
import fr.titionfire.ffsaf.data.repository.CombRepository;
|
||||||
|
import fr.titionfire.ffsaf.rest.from.AffiliationRequestForm;
|
||||||
|
import fr.titionfire.ffsaf.utils.Utils;
|
||||||
|
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.eclipse.microprofile.config.inject.ConfigProperty;
|
||||||
|
|
||||||
|
@WithSession
|
||||||
|
@ApplicationScoped
|
||||||
|
public class AffiliationService {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
CombRepository combRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AffiliationRequestRepository repository;
|
||||||
|
|
||||||
|
@ConfigProperty(name = "upload_dir")
|
||||||
|
String media;
|
||||||
|
|
||||||
|
public Uni<String> save(AffiliationRequestForm form) {
|
||||||
|
AffiliationRequestModel affModel = form.toModel();
|
||||||
|
affModel.setSaison(Utils.getSaison());
|
||||||
|
|
||||||
|
return Uni.createFrom().item(affModel)
|
||||||
|
.call(model -> ((model.getPresident_lincence() != 0) ? combRepository.find("licence",
|
||||||
|
model.getPresident_lincence()).count().invoke(count -> {
|
||||||
|
if (count == 0) {
|
||||||
|
throw new IllegalArgumentException("Licence président inconnue");
|
||||||
|
}
|
||||||
|
}) : Uni.createFrom().nullItem())
|
||||||
|
)
|
||||||
|
.call(model -> ((model.getTresorier_lincence() != 0) ? combRepository.find("licence",
|
||||||
|
model.getTresorier_lincence()).count().invoke(count -> {
|
||||||
|
if (count == 0) {
|
||||||
|
throw new IllegalArgumentException("Licence trésorier inconnue");
|
||||||
|
}
|
||||||
|
}) : Uni.createFrom().nullItem())
|
||||||
|
)
|
||||||
|
.call(model -> ((model.getSecretaire_lincence() != 0) ? combRepository.find("licence",
|
||||||
|
model.getSecretaire_lincence()).count().invoke(count -> {
|
||||||
|
if (count == 0) {
|
||||||
|
throw new IllegalArgumentException("Licence secrétaire inconnue");
|
||||||
|
}
|
||||||
|
}) : Uni.createFrom().nullItem())
|
||||||
|
).chain(model -> Panache.withTransaction(() -> repository.persist(model)))
|
||||||
|
.call(model -> Uni.createFrom().future(Utils.replacePhoto(model.getId(), form.getLogo(), media,
|
||||||
|
"aff_request/logo")))
|
||||||
|
.call(model -> Uni.createFrom().future(Utils.replacePhoto(model.getId(), form.getStatus(), media,
|
||||||
|
"aff_request/status")))
|
||||||
|
.map(__ -> "Ok");
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
package fr.titionfire.ffsaf.rest;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.rest.from.AffiliationRequestForm;
|
||||||
|
import io.smallrye.mutiny.Uni;
|
||||||
|
import jakarta.ws.rs.*;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
@Path("api/affiliation")
|
||||||
|
public class AffiliationEndpoints {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("save")
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
public Uni<String> saveAffRequest(AffiliationRequestForm form) {
|
||||||
|
System.out.println(form);
|
||||||
|
return Uni.createFrom().item("OK");
|
||||||
|
}
|
||||||
|
/*@POST
|
||||||
|
@Path("affiliation")
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
public Uni<String> saveAffRequest(AffiliationRequestForm form) {
|
||||||
|
System.out.println(form);
|
||||||
|
return service.save(form);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
@ -1,28 +1,53 @@
|
|||||||
package fr.titionfire.ffsaf.rest;
|
package fr.titionfire.ffsaf.rest;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.domain.service.AffiliationService;
|
||||||
import fr.titionfire.ffsaf.rest.client.SirenService;
|
import fr.titionfire.ffsaf.rest.client.SirenService;
|
||||||
import fr.titionfire.ffsaf.rest.data.UniteLegaleRoot;
|
import fr.titionfire.ffsaf.rest.data.UniteLegaleRoot;
|
||||||
|
import fr.titionfire.ffsaf.rest.from.AffiliationRequestForm;
|
||||||
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 jodd.net.MimeTypes;
|
||||||
|
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||||
import org.eclipse.microprofile.rest.client.inject.RestClient;
|
import org.eclipse.microprofile.rest.client.inject.RestClient;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
@Path("api/asso")
|
@Path("api/asso")
|
||||||
public class AssoEndpoints {
|
public class AssoEndpoints {
|
||||||
|
|
||||||
@RestClient
|
@RestClient
|
||||||
SirenService sirenService;
|
SirenService sirenService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
AffiliationService service;
|
||||||
|
|
||||||
|
@ConfigProperty(name = "upload_dir")
|
||||||
|
String media;
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("siren/{siren}")
|
@Path("siren/{siren}")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Uni<UniteLegaleRoot> getInfoSiren(@PathParam("siren") String siren) {
|
public Uni<UniteLegaleRoot> getInfoSiren(@PathParam("siren") String siren) {
|
||||||
return sirenService.get_unite(siren).onFailure().transform(throwable -> {
|
return sirenService.get_unite(siren).onFailure().transform(throwable -> {
|
||||||
if (throwable instanceof WebApplicationException exception){
|
if (throwable instanceof WebApplicationException exception) {
|
||||||
if (exception.getResponse().getStatus() == 400)
|
if (exception.getResponse().getStatus() == 400)
|
||||||
return new BadRequestException("Not found");
|
return new BadRequestException("Not found");
|
||||||
}
|
}
|
||||||
return throwable;
|
return throwable;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("affiliation")
|
||||||
|
@Produces(MediaType.TEXT_PLAIN)
|
||||||
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
||||||
|
public Uni<String> saveAffRequest(AffiliationRequestForm form) {
|
||||||
|
return service.save(form);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import fr.titionfire.ffsaf.rest.from.FullMemberForm;
|
|||||||
import fr.titionfire.ffsaf.utils.GroupeUtils;
|
import fr.titionfire.ffsaf.utils.GroupeUtils;
|
||||||
import fr.titionfire.ffsaf.utils.PageResult;
|
import fr.titionfire.ffsaf.utils.PageResult;
|
||||||
import fr.titionfire.ffsaf.utils.Pair;
|
import fr.titionfire.ffsaf.utils.Pair;
|
||||||
|
import fr.titionfire.ffsaf.utils.Utils;
|
||||||
import io.quarkus.oidc.IdToken;
|
import io.quarkus.oidc.IdToken;
|
||||||
import io.quarkus.security.Authenticated;
|
import io.quarkus.security.Authenticated;
|
||||||
import io.quarkus.security.identity.SecurityIdentity;
|
import io.quarkus.security.identity.SecurityIdentity;
|
||||||
@ -58,8 +59,10 @@ public class CombEndpoints {
|
|||||||
@Path("/find/admin")
|
@Path("/find/admin")
|
||||||
@RolesAllowed({"federation_admin"})
|
@RolesAllowed({"federation_admin"})
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Uni<PageResult<SimpleMembre>> getFindAdmin(@QueryParam("limit") Integer limit, @QueryParam("page") Integer page,
|
public Uni<PageResult<SimpleMembre>> getFindAdmin(@QueryParam("limit") Integer limit,
|
||||||
@QueryParam("search") String search, @QueryParam("club") String club) {
|
@QueryParam("page") Integer page,
|
||||||
|
@QueryParam("search") String search,
|
||||||
|
@QueryParam("club") String club) {
|
||||||
if (limit == null)
|
if (limit == null)
|
||||||
limit = 50;
|
limit = 50;
|
||||||
if (page == null || page < 1)
|
if (page == null || page < 1)
|
||||||
@ -71,7 +74,8 @@ public class CombEndpoints {
|
|||||||
@Path("/find/club")
|
@Path("/find/club")
|
||||||
@RolesAllowed({"club_president", "club_secretaire", "club_respo_intra"})
|
@RolesAllowed({"club_president", "club_secretaire", "club_respo_intra"})
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public Uni<PageResult<SimpleMembre>> getFindClub(@QueryParam("limit") Integer limit, @QueryParam("page") Integer page,
|
public Uni<PageResult<SimpleMembre>> getFindClub(@QueryParam("limit") Integer limit,
|
||||||
|
@QueryParam("page") Integer page,
|
||||||
@QueryParam("search") String search) {
|
@QueryParam("search") String search) {
|
||||||
if (limit == null)
|
if (limit == null)
|
||||||
limit = 50;
|
limit = 50;
|
||||||
@ -99,7 +103,8 @@ public class CombEndpoints {
|
|||||||
if (!out.equals("OK")) throw new InternalError("Fail to update data: " + out);
|
if (!out.equals("OK")) throw new InternalError("Fail to update data: " + out);
|
||||||
})).chain(() -> {
|
})).chain(() -> {
|
||||||
if (input.getPhoto_data().length > 0)
|
if (input.getPhoto_data().length > 0)
|
||||||
return Uni.createFrom().future(replacePhoto(id, input.getPhoto_data())).invoke(Unchecked.consumer(out -> {
|
return Uni.createFrom().future(Utils.replacePhoto(id, input.getPhoto_data(), media, "ppMembre"
|
||||||
|
)).invoke(Unchecked.consumer(out -> {
|
||||||
if (!out.equals("OK")) throw new InternalError("Fail to get MimeType " + out);
|
if (!out.equals("OK")) throw new InternalError("Fail to get MimeType " + out);
|
||||||
}));
|
}));
|
||||||
else
|
else
|
||||||
@ -117,7 +122,8 @@ public class CombEndpoints {
|
|||||||
if (id == null) throw new InternalError("Fail to creat member data");
|
if (id == null) throw new InternalError("Fail to creat member data");
|
||||||
})).call(id -> {
|
})).call(id -> {
|
||||||
if (input.getPhoto_data().length > 0)
|
if (input.getPhoto_data().length > 0)
|
||||||
return Uni.createFrom().future(replacePhoto(id, input.getPhoto_data()));
|
return Uni.createFrom().future(Utils.replacePhoto(id, input.getPhoto_data(), media, "ppMembre"
|
||||||
|
));
|
||||||
else
|
else
|
||||||
return Uni.createFrom().nullItem();
|
return Uni.createFrom().nullItem();
|
||||||
});
|
});
|
||||||
@ -134,7 +140,8 @@ public class CombEndpoints {
|
|||||||
if (!out.equals("OK")) throw new InternalError("Fail to update data: " + out);
|
if (!out.equals("OK")) throw new InternalError("Fail to update data: " + out);
|
||||||
})).chain(() -> {
|
})).chain(() -> {
|
||||||
if (input.getPhoto_data().length > 0)
|
if (input.getPhoto_data().length > 0)
|
||||||
return Uni.createFrom().future(replacePhoto(id, input.getPhoto_data())).invoke(Unchecked.consumer(out -> {
|
return Uni.createFrom().future(Utils.replacePhoto(id, input.getPhoto_data(), media, "ppMembre"
|
||||||
|
)).invoke(Unchecked.consumer(out -> {
|
||||||
if (!out.equals("OK")) throw new InternalError("Fail to get MimeType " + out);
|
if (!out.equals("OK")) throw new InternalError("Fail to get MimeType " + out);
|
||||||
}));
|
}));
|
||||||
else
|
else
|
||||||
@ -153,38 +160,13 @@ public class CombEndpoints {
|
|||||||
if (id == null) throw new InternalError("Fail to creat member data");
|
if (id == null) throw new InternalError("Fail to creat member data");
|
||||||
})).call(id -> {
|
})).call(id -> {
|
||||||
if (input.getPhoto_data().length > 0)
|
if (input.getPhoto_data().length > 0)
|
||||||
return Uni.createFrom().future(replacePhoto(id, input.getPhoto_data()));
|
return Uni.createFrom().future(Utils.replacePhoto(id, input.getPhoto_data(), media, "ppMembre"
|
||||||
|
));
|
||||||
else
|
else
|
||||||
return Uni.createFrom().nullItem();
|
return Uni.createFrom().nullItem();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Future<String> replacePhoto(long id, byte[] input) {
|
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
|
||||||
try (InputStream is = new BufferedInputStream(new ByteArrayInputStream(input))) {
|
|
||||||
String mimeType = URLConnection.guessContentTypeFromStream(is);
|
|
||||||
String[] detectedExtensions = MimeTypes.findExtensionsByMimeTypes(mimeType, false);
|
|
||||||
if (detectedExtensions.length == 0)
|
|
||||||
throw new IOException("Fail to detect file extension for MIME type " + mimeType);
|
|
||||||
|
|
||||||
FilenameFilter filter = (directory, filename) -> filename.startsWith(String.valueOf(id));
|
|
||||||
File[] files = new File(media, "ppMembre").listFiles(filter);
|
|
||||||
if (files != null) {
|
|
||||||
for (File file : files) {
|
|
||||||
//noinspection ResultOfMethodCallIgnored
|
|
||||||
file.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String extension = "." + detectedExtensions[0];
|
|
||||||
Files.write(new File(media, "ppMembre/" + id + extension).toPath(), input);
|
|
||||||
return "OK";
|
|
||||||
} catch (IOException e) {
|
|
||||||
return e.getMessage();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}/photo")
|
@Path("{id}/photo")
|
||||||
@RolesAllowed({"federation_admin", "club_president", "club_secretaire", "club_respo_intra"})
|
@RolesAllowed({"federation_admin", "club_president", "club_secretaire", "club_respo_intra"})
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
package fr.titionfire.ffsaf.rest.from;
|
package fr.titionfire.ffsaf.rest.from;
|
||||||
|
|
||||||
|
import fr.titionfire.ffsaf.data.model.AffiliationRequestModel;
|
||||||
import jakarta.ws.rs.FormParam;
|
import jakarta.ws.rs.FormParam;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
@ -28,4 +29,59 @@ public class AffiliationRequestForm {
|
|||||||
@FormParam("logo")
|
@FormParam("logo")
|
||||||
@PartType(MediaType.APPLICATION_OCTET_STREAM)
|
@PartType(MediaType.APPLICATION_OCTET_STREAM)
|
||||||
private byte[] logo = new byte[0];
|
private byte[] logo = new byte[0];
|
||||||
|
|
||||||
|
@FormParam("president-nom")
|
||||||
|
private String president_lname = null;
|
||||||
|
@FormParam("president-prenom")
|
||||||
|
private String president_fname = null;
|
||||||
|
@FormParam("president-mail")
|
||||||
|
private String president_email = null;
|
||||||
|
@FormParam("president-licence")
|
||||||
|
private String president_lincence = null;
|
||||||
|
|
||||||
|
@FormParam("tresorier-nom")
|
||||||
|
private String tresorier_lname = null;
|
||||||
|
@FormParam("tresorier-prenom")
|
||||||
|
private String tresorier_fname = null;
|
||||||
|
@FormParam("tresorier-mail")
|
||||||
|
private String tresorier_email = null;
|
||||||
|
@FormParam("tresorier-licence")
|
||||||
|
private String tresorier_lincence = null;
|
||||||
|
|
||||||
|
@FormParam("secretaire-nom")
|
||||||
|
private String secretaire_lname = null;
|
||||||
|
@FormParam("secretaire-prenom")
|
||||||
|
private String secretaire_fname = null;
|
||||||
|
@FormParam("secretaire-mail")
|
||||||
|
private String secretaire_email = null;
|
||||||
|
@FormParam("secretaire-licence")
|
||||||
|
private String secretaire_lincence = null;
|
||||||
|
|
||||||
|
public AffiliationRequestModel toModel() {
|
||||||
|
AffiliationRequestModel model = new AffiliationRequestModel();
|
||||||
|
model.setName(this.getName());
|
||||||
|
model.setSiren(this.getSiren());
|
||||||
|
model.setRNA(this.getRna());
|
||||||
|
model.setAddress(this.getAdresse());
|
||||||
|
|
||||||
|
model.setPresident_lname(this.getPresident_lname());
|
||||||
|
model.setPresident_fname(this.getPresident_fname());
|
||||||
|
model.setPresident_email(this.getPresident_email());
|
||||||
|
model.setPresident_lincence((this.getPresident_lincence() == null || this.getPresident_lincence().isBlank())
|
||||||
|
? 0 : Integer.parseInt(this.getPresident_lincence()));
|
||||||
|
|
||||||
|
model.setTresorier_lname(this.getTresorier_lname());
|
||||||
|
model.setTresorier_fname(this.getTresorier_fname());
|
||||||
|
model.setTresorier_email(this.getTresorier_email());
|
||||||
|
model.setTresorier_lincence((this.getPresident_lincence() == null || this.getPresident_lincence().isBlank())
|
||||||
|
? 0 : Integer.parseInt(this.getTresorier_lincence()));
|
||||||
|
|
||||||
|
model.setSecretaire_lname(this.getSecretaire_lname());
|
||||||
|
model.setSecretaire_fname(this.getSecretaire_fname());
|
||||||
|
model.setSecretaire_email(this.getSecretaire_email());
|
||||||
|
model.setSecretaire_lincence((this.getPresident_lincence() == null || this.getPresident_lincence().isBlank())
|
||||||
|
? 0 : Integer.parseInt(this.getSecretaire_lincence()));
|
||||||
|
|
||||||
|
return model;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,14 @@
|
|||||||
package fr.titionfire.ffsaf.utils;
|
package fr.titionfire.ffsaf.utils;
|
||||||
|
|
||||||
|
import jodd.net.MimeTypes;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.net.URLConnection;
|
||||||
|
import java.nio.file.Files;
|
||||||
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.Future;
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
|
|
||||||
@ -19,4 +26,35 @@ public class Utils {
|
|||||||
return calendar.get(Calendar.YEAR) - 1;
|
return calendar.get(Calendar.YEAR) - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Future<String> replacePhoto(long id, byte[] input, String media, String dir) {
|
||||||
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
|
try (InputStream is = new BufferedInputStream(new ByteArrayInputStream(input))) {
|
||||||
|
String mimeType = URLConnection.guessContentTypeFromStream(is);
|
||||||
|
String[] detectedExtensions = MimeTypes.findExtensionsByMimeTypes(mimeType, false);
|
||||||
|
if (detectedExtensions.length == 0)
|
||||||
|
throw new IOException("Fail to detect file extension for MIME type " + mimeType);
|
||||||
|
|
||||||
|
File dirFile = new File(media, dir);
|
||||||
|
if (!dirFile.exists())
|
||||||
|
if (dirFile.mkdirs())
|
||||||
|
throw new IOException("Fail to create directory " + dir);
|
||||||
|
|
||||||
|
FilenameFilter filter = (directory, filename) -> filename.startsWith(String.valueOf(id));
|
||||||
|
File[] files = dirFile.listFiles(filter);
|
||||||
|
if (files != null) {
|
||||||
|
for (File file : files) {
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
file.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String extension = "." + detectedExtensions[0];
|
||||||
|
Files.write(new File(dirFile, id + extension).toPath(), input);
|
||||||
|
return "OK";
|
||||||
|
} catch (IOException e) {
|
||||||
|
return e.getMessage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,28 +31,35 @@ export function DemandeAff() {
|
|||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
const formData = new FormData(event.target)
|
const formData = new FormData(event.target)
|
||||||
toast.promise(
|
toast.promise(
|
||||||
apiAxios.post(`asso/affiliation`, formData),
|
apiAxios.post(`asso/affiliation`, formData, { headers: {'Accept': '*/*'}}),
|
||||||
{
|
{
|
||||||
pending: "Enregistrement de la demande d'affiliation en cours",
|
pending: "Enregistrement de la demande d'affiliation en cours",
|
||||||
success: "Demande d'affiliation enregistrée avec succès 🎉",
|
success: "Demande d'affiliation enregistrée avec succès 🎉",
|
||||||
error: "Échec de la demande d'affiliation 😕"
|
error: "Échec de la demande d'affiliation 😕"
|
||||||
}
|
}
|
||||||
).then(_ => {
|
).then(_ => {
|
||||||
navigate("/affiliation/ok")
|
// navigate("/affiliation/ok")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
<h1>Demande d'affiliation</h1>
|
<h1>Demande d'affiliation</h1>
|
||||||
<p>L'affiliation est annuelle et valable pour une saison sportive : du 1er septembre au 31 août de l’année suivante.</p>
|
<p>L'affiliation est annuelle et valable pour une saison sportive : du 1er septembre au 31 août de l’année
|
||||||
|
suivante.</p>
|
||||||
Pour s’affilier, une association sportive doit réunir les conditions suivantes :
|
Pour s’affilier, une association sportive doit réunir les conditions suivantes :
|
||||||
<ul>
|
<ul>
|
||||||
<li>Avoir son siège social en France ou Principauté de Monaco</li>
|
<li>Avoir son siège social en France ou Principauté de Monaco</li>
|
||||||
<li>Être constituée conformément au chapitre 1er du titre II du livre 1er du Code du Sport</li>
|
<li>Être constituée conformément au chapitre 1er du titre II du livre 1er du Code du Sport</li>
|
||||||
<li>Poursuivre un objet social entrant dans la définition de l’article 1 des statuts de la Fédération</li>
|
<li>Poursuivre un objet social entrant dans la définition de l’article 1 des statuts de la Fédération</li>
|
||||||
<li>Disposer de statuts compatibles avec les principes d’organisation et de fonctionnement de la Fédération</li>
|
<li>Disposer de statuts compatibles avec les principes d’organisation et de fonctionnement de la
|
||||||
<li>Assurer en son sein la liberté d’opinion et le respect des droits de la défense, et s’interdire toute discrimination</li>
|
Fédération
|
||||||
<li>Respecter les règles d’encadrement, d’hygiène et de sécurité établies par les règlements de la Fédération</li>
|
</li>
|
||||||
|
<li>Assurer en son sein la liberté d’opinion et le respect des droits de la défense, et s’interdire toute
|
||||||
|
discrimination
|
||||||
|
</li>
|
||||||
|
<li>Respecter les règles d’encadrement, d’hygiène et de sécurité établies par les règlements de la
|
||||||
|
Fédération
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div className="card mb-4">
|
<div className="card mb-4">
|
||||||
@ -68,16 +75,20 @@ export function DemandeAff() {
|
|||||||
<MembreInfo role="secretaire"/>
|
<MembreInfo role="secretaire"/>
|
||||||
|
|
||||||
<div className="mb-3">
|
<div className="mb-3">
|
||||||
<p>Après validation de votre demande, vous recevrez un login et mot de passe provisoire pour accéder à votre espace FFSAF</p>
|
<p>Après validation de votre demande, vous recevrez un login et mot de passe provisoire pour
|
||||||
|
accéder à votre espace FFSAF</p>
|
||||||
Notez que pour finaliser votre affiliation, il vous faudra :
|
Notez que pour finaliser votre affiliation, il vous faudra :
|
||||||
<ul>
|
<ul>
|
||||||
<li>Disposer d’au moins trois membres licenciés, dont le président, le trésorier et le secrétaire</li>
|
<li>Disposer d’au moins trois membres licenciés, dont le président, le trésorier et le
|
||||||
|
secrétaire
|
||||||
|
</li>
|
||||||
<li>S'être acquitté des cotisations prévues par les règlements fédéraux</li>
|
<li>S'être acquitté des cotisations prévues par les règlements fédéraux</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="d-grid gap-2 d-md-flex justify-content-md-center">
|
<div className="d-grid gap-2 d-md-flex justify-content-md-center">
|
||||||
<button type="submit" className="btn btn-primary">Confirmer ma demande d'affiliation</button>
|
<button type="submit" className="btn btn-primary">Confirmer ma demande d'affiliation
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -113,7 +124,8 @@ function AssoInfo() {
|
|||||||
return <>
|
return <>
|
||||||
<div className="input-group mb-3">
|
<div className="input-group mb-3">
|
||||||
<span className="input-group-text" id="basic-addon1">Nom de l'association*</span>
|
<span className="input-group-text" id="basic-addon1">Nom de l'association*</span>
|
||||||
<input type="text" className="form-control" placeholder="Nom de l'association" name="name" aria-label="Nom de l'association"
|
<input type="text" className="form-control" placeholder="Nom de l'association" name="name"
|
||||||
|
aria-label="Nom de l'association"
|
||||||
aria-describedby="basic-addon1" required/>
|
aria-describedby="basic-addon1" required/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -121,24 +133,29 @@ function AssoInfo() {
|
|||||||
<span className="input-group-text">N° SIREN*</span>
|
<span className="input-group-text">N° SIREN*</span>
|
||||||
<input type="number" className="form-control" placeholder="siren" name="siren" required value={siren}
|
<input type="number" className="form-control" placeholder="siren" name="siren" required value={siren}
|
||||||
onChange={e => setSiren(e.target.value)}/>
|
onChange={e => setSiren(e.target.value)}/>
|
||||||
<button className="btn btn-outline-secondary" type="button" id="button-addon2" onClick={fetchSiren}>Rechercher</button>
|
<button className="btn btn-outline-secondary" type="button" id="button-addon2"
|
||||||
|
onClick={fetchSiren}>Rechercher
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="input-group mb-3">
|
<div className="input-group mb-3">
|
||||||
<span className="input-group-text" id="basic-addon1">Dénomination</span>
|
<span className="input-group-text" id="basic-addon1">Dénomination</span>
|
||||||
<input type="text" className="form-control" placeholder="Appuyer sur rechercher pour compléter" aria-label="Dénomination"
|
<input type="text" className="form-control" placeholder="Appuyer sur rechercher pour compléter"
|
||||||
|
aria-label="Dénomination"
|
||||||
aria-describedby="basic-addon1" disabled value={denomination} readOnly/>
|
aria-describedby="basic-addon1" disabled value={denomination} readOnly/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="input-group mb-3">
|
<div className="input-group mb-3">
|
||||||
<span className="input-group-text" id="basic-addon1">RNA</span>
|
<span className="input-group-text" id="basic-addon1">RNA</span>
|
||||||
<input type="text" className="form-control" placeholder="RNA" aria-label="RNA" aria-describedby="basic-addon1"
|
<input type="text" className="form-control" placeholder="RNA" aria-label="RNA"
|
||||||
|
aria-describedby="basic-addon1"
|
||||||
disabled={!rnaEnable} name="rna" value={rna} onChange={e => setRna(e.target.value)}/>
|
disabled={!rnaEnable} name="rna" value={rna} onChange={e => setRna(e.target.value)}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="input-group mb-3">
|
<div className="input-group mb-3">
|
||||||
<span className="input-group-text" id="basic-addon1">Adresse*</span>
|
<span className="input-group-text" id="basic-addon1">Adresse*</span>
|
||||||
<input type="text" className="form-control" placeholder="Adresse" aria-label="Adresse" aria-describedby="basic-addon1"
|
<input type="text" className="form-control" placeholder="Adresse" aria-label="Adresse"
|
||||||
|
aria-describedby="basic-addon1"
|
||||||
required value={adresse} name="adresse" onChange={e => setAdresse(e.target.value)}/>
|
required value={adresse} name="adresse" onChange={e => setAdresse(e.target.value)}/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -149,7 +166,8 @@ function AssoInfo() {
|
|||||||
|
|
||||||
<div className="input-group mb-3">
|
<div className="input-group mb-3">
|
||||||
<label className="input-group-text" htmlFor="logo">Logo*</label>
|
<label className="input-group-text" htmlFor="logo">Logo*</label>
|
||||||
<input type="file" className="form-control" id="logo" name="logo" accept=".jpg,.jpeg,.gif,.png,.svg" required/>
|
<input type="file" className="form-control" id="logo" name="logo" accept=".jpg,.jpeg,.gif,.png,.svg"
|
||||||
|
required/>
|
||||||
</div>
|
</div>
|
||||||
</>;
|
</>;
|
||||||
}
|
}
|
||||||
@ -159,19 +177,29 @@ function MembreInfo({role}) {
|
|||||||
<div className="col-sm-3">
|
<div className="col-sm-3">
|
||||||
<div className="form-floating">
|
<div className="form-floating">
|
||||||
<input type="text" className="form-control" id="floatingInput" placeholder="Nom" name={role + "-nom"}/>
|
<input type="text" className="form-control" id="floatingInput" placeholder="Nom" name={role + "-nom"}/>
|
||||||
<label htmlFor="floatingInput">Nom*</label>
|
<label htmlFor="floatingInput">Nom</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-sm-3">
|
<div className="col-sm-3">
|
||||||
<div className="form-floating">
|
<div className="form-floating">
|
||||||
<input type="text" className="form-control" id="floatingInput" placeholder="Prénom" name={role + "-prenom"}/>
|
<input type="text" className="form-control" id="floatingInput" placeholder="Prénom"
|
||||||
<label htmlFor="floatingInput">Prénom*</label>
|
name={role + "-prenom"}/>
|
||||||
|
<label htmlFor="floatingInput">Prénom</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-sm-5">
|
<div className="col-sm-5">
|
||||||
<div className="form-floating">
|
<div className="form-floating">
|
||||||
<input type="email" className="form-control" id="floatingInput" placeholder="name@example.com" name={role + "-mail"}/>
|
<input type="email" className="form-control" id="floatingInput" placeholder="name@example.com"
|
||||||
<label htmlFor="floatingInput">Email*</label>
|
name={role + "-mail"}/>
|
||||||
|
<label htmlFor="floatingInput">Email</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-sm-3">
|
||||||
|
<div>OU</div>
|
||||||
|
<div className="form-floating">
|
||||||
|
<input type="number" className="form-control" id="floatingInput" placeholder="N° Licence"
|
||||||
|
name={role + "-licence"}/>
|
||||||
|
<label htmlFor="floatingInput">N° Licence</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -181,7 +209,8 @@ export function DemandeAffOk() {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-green-800 text-4xl">Demande d'affiliation envoyée avec succès</h1>
|
<h1 className="text-green-800 text-4xl">Demande d'affiliation envoyée avec succès</h1>
|
||||||
<p>Une fois votre demande validée, vous recevrez un login et mot de passe provisoire pour accéder à votre espace FFSAF</p>
|
<p>Une fois votre demande validée, vous recevrez un login et mot de passe provisoire pour accéder à votre
|
||||||
|
espace FFSAF</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user