package fr.titionfire.ffsaf.rest; import fr.titionfire.ffsaf.domain.service.MembreService; import fr.titionfire.ffsaf.rest.data.SimpleMembre; import fr.titionfire.ffsaf.rest.data.SimpleMembreInOutData; import fr.titionfire.ffsaf.rest.exception.DInternalError; import fr.titionfire.ffsaf.rest.from.FullMemberForm; import fr.titionfire.ffsaf.utils.PageResult; import fr.titionfire.ffsaf.utils.SecurityCtx; import fr.titionfire.ffsaf.utils.Utils; 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.config.inject.ConfigProperty; import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; import org.eclipse.microprofile.openapi.annotations.tags.Tag; import java.util.List; @Tag(name = "Membre club", description = "Gestion des membres (pour les clubs)") @RolesAllowed({"club_president", "club_secretaire", "club_respo_intra"}) @Path("api/member") public class MembreClubEndpoints { @Inject MembreService membreService; @ConfigProperty(name = "upload_dir") String media; @Inject SecurityCtx securityCtx; @GET @Path("/find/club") @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Recherche des membres par critères", description = "Recherche des membres en " + "fonction de critères tels que le nom, le prénom, etc.") @APIResponses(value = { @APIResponse(responseCode = "200", description = "La liste des membres correspondant aux critères de recherche"), @APIResponse(responseCode = "500", description = "Erreur interne du serveur") }) public Uni> getFindClub( @Parameter(description = "Nombre max de résulta (max 50)") @QueryParam("limit") Integer limit, @Parameter(description = "Page à consulter") @QueryParam("page") Integer page, @Parameter(description = "Text à rechercher") @QueryParam("search") String search, @Parameter(description = "Catégorie à filter") @QueryParam("categorie") String categorie, @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, @Parameter(description = "Ordre") @QueryParam("order") String order) { if (limit == null) limit = 50; if (page == null || page < 1) page = 1; return membreService.search(limit, page - 1, search, licenceRequest, payment, order, categorie, securityCtx.getSubject()); } @GET @Path("club/export") @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Exporte les membres du club", description = "Exporte les membres du club") @APIResponses(value = { @APIResponse(responseCode = "200", description = "Les membres du club ont été exportés avec succès"), @APIResponse(responseCode = "403", description = "Accès refusé"), @APIResponse(responseCode = "500", description = "Erreur interne du serveur") }) public Uni> exportMembre() { return membreService.getAllExport(securityCtx.getSubject()); } @PUT @Path("club/import") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @Operation(summary = "Importer les membres du club", description = "Importer tout ou en partie les membres du club") @APIResponses(value = { @APIResponse(responseCode = "200", description = "Les membres du club ont été importés avec succès"), @APIResponse(responseCode = "403", description = "Accès refusé"), @APIResponse(responseCode = "500", description = "Erreur interne du serveur") }) public Uni importMembre(List dataIn) { System.out.println("importMembre"); return membreService.allImporte(securityCtx.getSubject(), dataIn); } @PUT @Path("club/{id}") @Produces(MediaType.TEXT_PLAIN) @Consumes(MediaType.MULTIPART_FORM_DATA) @Operation(summary = "Met à jour les informations d'un membre en fonction de son identifiant", description = "Met à jour les informations d'un membre en fonction de son identifiant") @APIResponses(value = { @APIResponse(responseCode = "200", description = "Le membre a été mis à jour avec succès"), @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 setMembre( @Parameter(description = "Identifiant de membre") @PathParam("id") long id, FullMemberForm input) { return membreService.update(id, input, securityCtx) .invoke(Unchecked.consumer(out -> { if (!out.equals("OK")) throw new InternalError("Fail to update data: " + out); })).chain(() -> { if (input.getPhoto_data().length > 0) return Uni.createFrom().future(Utils.replacePhoto(id, input.getPhoto_data(), media, "ppMembre" )).invoke(Unchecked.consumer(out -> { if (!out.equals("OK")) throw new DInternalError("Impossible de reconnaitre le fichier: " + out); })); else return Uni.createFrom().nullItem(); }); } @POST @Path("club") @Produces(MediaType.TEXT_PLAIN) @Consumes(MediaType.MULTIPART_FORM_DATA) @Operation(summary = "Ajoute un nouveau membre", description = "Ajoute un nouveau membre avec les informations " + "fournies dans le formulaire") @APIResponses(value = { @APIResponse(responseCode = "200", description = "Le membre a été ajouté avec succès"), @APIResponse(responseCode = "400", description = "Les données envoyées sont invalides"), @APIResponse(responseCode = "500", description = "Erreur interne du serveur") }) public Uni addMembre(FullMemberForm input) { return membreService.add(input, securityCtx.getSubject()) .invoke(Unchecked.consumer(id -> { if (id == null) throw new InternalError("Fail to creat member data"); })).call(id -> { if (input.getPhoto_data().length > 0) return Uni.createFrom().future(Utils.replacePhoto(id, input.getPhoto_data(), media, "ppMembre" )); else return Uni.createFrom().nullItem(); }); } @DELETE @Path("club/{id}") @Produces(MediaType.TEXT_PLAIN) @Operation(summary = "Supprime un membre en fonction de son identifiant", description = "Supprime " + "un membre en fonction de son identifiant, ainsi que toutes les informations associées") @APIResponses(value = { @APIResponse(responseCode = "204", description = "Le membre a été supprimé avec succès"), @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 deleteMembre( @Parameter(description = "Identifiant de membre") @PathParam("id") long id) { return membreService.delete(id, securityCtx); } }