diff --git a/unionflow-client-quarkus-primefaces-freya/pom.xml b/unionflow-client-quarkus-primefaces-freya/pom.xml index 0c37329..1641e16 100644 --- a/unionflow-client-quarkus-primefaces-freya/pom.xml +++ b/unionflow-client-quarkus-primefaces-freya/pom.xml @@ -82,11 +82,19 @@ quarkus-rest-client-jackson - + io.quarkus quarkus-smallrye-jwt + + io.quarkus + quarkus-oidc + + + io.quarkus + quarkus-oidc-client + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/converter/MembreConverter.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/converter/MembreConverter.java index 62d72b7..7ed355a 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/converter/MembreConverter.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/converter/MembreConverter.java @@ -7,6 +7,7 @@ import jakarta.faces.convert.Converter; import jakarta.faces.convert.FacesConverter; import jakarta.inject.Named; import dev.lions.unionflow.client.view.DemandesBean.Membre; +import java.util.UUID; @Named @ApplicationScoped @@ -20,15 +21,15 @@ public class MembreConverter implements Converter { } try { - // Parse the membre ID from the string value - Long membreId = Long.valueOf(value); + // Parse the membre ID from the string value (UUID) + UUID membreId = UUID.fromString(value); // Create a simple Membre object with just the ID // In a real implementation, you would fetch from database Membre membre = new Membre(); membre.setId(membreId); return membre; - } catch (NumberFormatException e) { + } catch (IllegalArgumentException e) { return null; } } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/AssociationDTO.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/AssociationDTO.java index 4b33b1d..4069cb9 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/AssociationDTO.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/AssociationDTO.java @@ -6,12 +6,13 @@ import jakarta.validation.constraints.NotNull; import java.time.LocalDate; import java.time.LocalDateTime; import java.io.Serializable; +import java.util.UUID; public class AssociationDTO implements Serializable { private static final long serialVersionUID = 1L; - private Long id; + private UUID id; @NotBlank(message = "Le nom de l'association est obligatoire") private String nom; @@ -54,8 +55,8 @@ public class AssociationDTO implements Serializable { } // Getters et Setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/CotisationDTO.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/CotisationDTO.java new file mode 100644 index 0000000..d74bb82 --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/CotisationDTO.java @@ -0,0 +1,91 @@ +package dev.lions.unionflow.client.dto; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.UUID; + +public class CotisationDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + private UUID id; + private String numeroReference; + private UUID membreId; + private String numeroMembre; + private String nomMembre; + private UUID associationId; + private String nomAssociation; + private String typeCotisation; + private String libelle; + private String description; + private BigDecimal montantDu; + private BigDecimal montantPaye; + private String codeDevise; + private String statut; + private LocalDate dateEcheance; + private LocalDateTime datePaiement; + private String methodePaiement; + private String observations; + private LocalDateTime dateCreation; + + // Getters et Setters + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } + + public String getNumeroReference() { return numeroReference; } + public void setNumeroReference(String numeroReference) { this.numeroReference = numeroReference; } + + public UUID getMembreId() { return membreId; } + public void setMembreId(UUID membreId) { this.membreId = membreId; } + + public String getNumeroMembre() { return numeroMembre; } + public void setNumeroMembre(String numeroMembre) { this.numeroMembre = numeroMembre; } + + public String getNomMembre() { return nomMembre; } + public void setNomMembre(String nomMembre) { this.nomMembre = nomMembre; } + + public UUID getAssociationId() { return associationId; } + public void setAssociationId(UUID associationId) { this.associationId = associationId; } + + public String getNomAssociation() { return nomAssociation; } + public void setNomAssociation(String nomAssociation) { this.nomAssociation = nomAssociation; } + + public String getTypeCotisation() { return typeCotisation; } + public void setTypeCotisation(String typeCotisation) { this.typeCotisation = typeCotisation; } + + public String getLibelle() { return libelle; } + public void setLibelle(String libelle) { this.libelle = libelle; } + + public String getDescription() { return description; } + public void setDescription(String description) { this.description = description; } + + public BigDecimal getMontantDu() { return montantDu; } + public void setMontantDu(BigDecimal montantDu) { this.montantDu = montantDu; } + + public BigDecimal getMontantPaye() { return montantPaye; } + public void setMontantPaye(BigDecimal montantPaye) { this.montantPaye = montantPaye; } + + public String getCodeDevise() { return codeDevise; } + public void setCodeDevise(String codeDevise) { this.codeDevise = codeDevise; } + + public String getStatut() { return statut; } + public void setStatut(String statut) { this.statut = statut; } + + public LocalDate getDateEcheance() { return dateEcheance; } + public void setDateEcheance(LocalDate dateEcheance) { this.dateEcheance = dateEcheance; } + + public LocalDateTime getDatePaiement() { return datePaiement; } + public void setDatePaiement(LocalDateTime datePaiement) { this.datePaiement = datePaiement; } + + public String getMethodePaiement() { return methodePaiement; } + public void setMethodePaiement(String methodePaiement) { this.methodePaiement = methodePaiement; } + + public String getObservations() { return observations; } + public void setObservations(String observations) { this.observations = observations; } + + public LocalDateTime getDateCreation() { return dateCreation; } + public void setDateCreation(LocalDateTime dateCreation) { this.dateCreation = dateCreation; } +} + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/DemandeAideDTO.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/DemandeAideDTO.java new file mode 100644 index 0000000..4c06ceb --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/DemandeAideDTO.java @@ -0,0 +1,99 @@ +package dev.lions.unionflow.client.dto; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.UUID; + +public class DemandeAideDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + private UUID id; + private String numeroReference; + private String type; + private String titre; + private String description; + private String justification; + private BigDecimal montantDemande; + private BigDecimal montantAccorde; + private String statut; + private String urgence; + private String localisation; + private String motif; + private UUID demandeurId; + private String demandeur; + private String telephone; + private String email; + private LocalDate dateDemande; + private LocalDate dateLimite; + private String responsableTraitement; + private UUID organisationId; + private LocalDateTime dateCreation; + + // Getters et Setters + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } + + public String getNumeroReference() { return numeroReference; } + public void setNumeroReference(String numeroReference) { this.numeroReference = numeroReference; } + + public String getType() { return type; } + public void setType(String type) { this.type = type; } + + public String getTitre() { return titre; } + public void setTitre(String titre) { this.titre = titre; } + + public String getDescription() { return description; } + public void setDescription(String description) { this.description = description; } + + public String getJustification() { return justification; } + public void setJustification(String justification) { this.justification = justification; } + + public BigDecimal getMontantDemande() { return montantDemande; } + public void setMontantDemande(BigDecimal montantDemande) { this.montantDemande = montantDemande; } + + public BigDecimal getMontantAccorde() { return montantAccorde; } + public void setMontantAccorde(BigDecimal montantAccorde) { this.montantAccorde = montantAccorde; } + + public String getStatut() { return statut; } + public void setStatut(String statut) { this.statut = statut; } + + public String getUrgence() { return urgence; } + public void setUrgence(String urgence) { this.urgence = urgence; } + + public String getLocalisation() { return localisation; } + public void setLocalisation(String localisation) { this.localisation = localisation; } + + public String getMotif() { return motif; } + public void setMotif(String motif) { this.motif = motif; } + + public UUID getDemandeurId() { return demandeurId; } + public void setDemandeurId(UUID demandeurId) { this.demandeurId = demandeurId; } + + public String getDemandeur() { return demandeur; } + public void setDemandeur(String demandeur) { this.demandeur = demandeur; } + + public String getTelephone() { return telephone; } + public void setTelephone(String telephone) { this.telephone = telephone; } + + public String getEmail() { return email; } + public void setEmail(String email) { this.email = email; } + + public LocalDate getDateDemande() { return dateDemande; } + public void setDateDemande(LocalDate dateDemande) { this.dateDemande = dateDemande; } + + public LocalDate getDateLimite() { return dateLimite; } + public void setDateLimite(LocalDate dateLimite) { this.dateLimite = dateLimite; } + + public String getResponsableTraitement() { return responsableTraitement; } + public void setResponsableTraitement(String responsableTraitement) { this.responsableTraitement = responsableTraitement; } + + public UUID getOrganisationId() { return organisationId; } + public void setOrganisationId(UUID organisationId) { this.organisationId = organisationId; } + + public LocalDateTime getDateCreation() { return dateCreation; } + public void setDateCreation(LocalDateTime dateCreation) { this.dateCreation = dateCreation; } +} + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/EvenementDTO.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/EvenementDTO.java new file mode 100644 index 0000000..7b172de --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/EvenementDTO.java @@ -0,0 +1,92 @@ +package dev.lions.unionflow.client.dto; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.util.UUID; + +public class EvenementDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + private UUID id; + private String titre; + private String description; + private String type; + private String statut; + private String priorite; + private LocalDate dateDebut; + private LocalDate dateFin; + private LocalTime heureDebut; + private LocalTime heureFin; + private String lieu; + private String adresse; + private String organisateur; + private String organisateurEmail; + private Integer capaciteMax; + private Integer participantsInscrits; + private BigDecimal budget; + private UUID organisationId; + private LocalDateTime dateCreation; + + // Getters et Setters + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } + + public String getTitre() { return titre; } + public void setTitre(String titre) { this.titre = titre; } + + public String getDescription() { return description; } + public void setDescription(String description) { this.description = description; } + + public String getType() { return type; } + public void setType(String type) { this.type = type; } + + public String getStatut() { return statut; } + public void setStatut(String statut) { this.statut = statut; } + + public String getPriorite() { return priorite; } + public void setPriorite(String priorite) { this.priorite = priorite; } + + public LocalDate getDateDebut() { return dateDebut; } + public void setDateDebut(LocalDate dateDebut) { this.dateDebut = dateDebut; } + + public LocalDate getDateFin() { return dateFin; } + public void setDateFin(LocalDate dateFin) { this.dateFin = dateFin; } + + public LocalTime getHeureDebut() { return heureDebut; } + public void setHeureDebut(LocalTime heureDebut) { this.heureDebut = heureDebut; } + + public LocalTime getHeureFin() { return heureFin; } + public void setHeureFin(LocalTime heureFin) { this.heureFin = heureFin; } + + public String getLieu() { return lieu; } + public void setLieu(String lieu) { this.lieu = lieu; } + + public String getAdresse() { return adresse; } + public void setAdresse(String adresse) { this.adresse = adresse; } + + public String getOrganisateur() { return organisateur; } + public void setOrganisateur(String organisateur) { this.organisateur = organisateur; } + + public String getOrganisateurEmail() { return organisateurEmail; } + public void setOrganisateurEmail(String organisateurEmail) { this.organisateurEmail = organisateurEmail; } + + public Integer getCapaciteMax() { return capaciteMax; } + public void setCapaciteMax(Integer capaciteMax) { this.capaciteMax = capaciteMax; } + + public Integer getParticipantsInscrits() { return participantsInscrits; } + public void setParticipantsInscrits(Integer participantsInscrits) { this.participantsInscrits = participantsInscrits; } + + public BigDecimal getBudget() { return budget; } + public void setBudget(BigDecimal budget) { this.budget = budget; } + + public UUID getOrganisationId() { return organisationId; } + public void setOrganisationId(UUID organisationId) { this.organisationId = organisationId; } + + public LocalDateTime getDateCreation() { return dateCreation; } + public void setDateCreation(LocalDateTime dateCreation) { this.dateCreation = dateCreation; } +} + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/FormulaireDTO.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/FormulaireDTO.java index 38f8408..338c1d3 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/FormulaireDTO.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/FormulaireDTO.java @@ -5,12 +5,13 @@ import jakarta.validation.constraints.Positive; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.UUID; public class FormulaireDTO implements Serializable { private static final long serialVersionUID = 1L; - private Long id; + private UUID id; @NotNull private String nom; @@ -60,8 +61,8 @@ public class FormulaireDTO implements Serializable { public FormulaireDTO() {} // Getters et Setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } @@ -171,7 +172,7 @@ public class FormulaireDTO implements Serializable { BigDecimal economie = getEconomieAnnuelle(); if (coutMensuelAnnuel.compareTo(BigDecimal.ZERO) > 0) { return economie.multiply(BigDecimal.valueOf(100)) - .divide(coutMensuelAnnuel, 0, BigDecimal.ROUND_HALF_UP) + .divide(coutMensuelAnnuel, 0, java.math.RoundingMode.HALF_UP) .intValue(); } } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/MembreDTO.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/MembreDTO.java index 137aaed..22f976e 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/MembreDTO.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/MembreDTO.java @@ -8,12 +8,13 @@ import jakarta.validation.constraints.*; import java.time.LocalDate; import java.time.LocalDateTime; import java.io.Serializable; +import java.util.UUID; public class MembreDTO implements Serializable { private static final long serialVersionUID = 1L; - private Long id; + private UUID id; @NotBlank(message = "Le numéro de membre est obligatoire", groups = {ValidationGroups.CreateMember.class, ValidationGroups.FullRegistration.class}) @ValidMemberNumber(groups = {ValidationGroups.CreateMember.class, ValidationGroups.UpdateMember.class, ValidationGroups.FullRegistration.class}) @@ -62,7 +63,7 @@ public class MembreDTO implements Serializable { private String statut; @NotNull(message = "L'association est obligatoire") - private Long associationId; + private UUID associationId; private String associationNom; @@ -88,8 +89,8 @@ public class MembreDTO implements Serializable { } // Getters et Setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNumeroMembre() { return numeroMembre; } public void setNumeroMembre(String numeroMembre) { this.numeroMembre = numeroMembre; } @@ -130,8 +131,8 @@ public class MembreDTO implements Serializable { public String getStatut() { return statut; } public void setStatut(String statut) { this.statut = statut; } - public Long getAssociationId() { return associationId; } - public void setAssociationId(Long associationId) { this.associationId = associationId; } + public UUID getAssociationId() { return associationId; } + public void setAssociationId(UUID associationId) { this.associationId = associationId; } public String getAssociationNom() { return associationNom; } public void setAssociationNom(String associationNom) { this.associationNom = associationNom; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/SouscriptionDTO.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/SouscriptionDTO.java index 7c11c56..a05f7db 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/SouscriptionDTO.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/SouscriptionDTO.java @@ -6,6 +6,7 @@ import java.math.BigDecimal; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; +import java.util.UUID; public class SouscriptionDTO implements Serializable { @@ -46,14 +47,14 @@ public class SouscriptionDTO implements Serializable { public String getLibelle() { return libelle; } } - private Long id; + private UUID id; @NotNull - private Long organisationId; + private UUID organisationId; private String organisationNom; @NotNull - private Long formulaireId; + private UUID formulaireId; private String formulaireNom; @NotNull @@ -102,17 +103,17 @@ public class SouscriptionDTO implements Serializable { public SouscriptionDTO() {} // Getters et Setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } - public Long getOrganisationId() { return organisationId; } - public void setOrganisationId(Long organisationId) { this.organisationId = organisationId; } + public UUID getOrganisationId() { return organisationId; } + public void setOrganisationId(UUID organisationId) { this.organisationId = organisationId; } public String getOrganisationNom() { return organisationNom; } public void setOrganisationNom(String organisationNom) { this.organisationNom = organisationNom; } - public Long getFormulaireId() { return formulaireId; } - public void setFormulaireId(Long formulaireId) { this.formulaireId = formulaireId; } + public UUID getFormulaireId() { return formulaireId; } + public void setFormulaireId(UUID formulaireId) { this.formulaireId = formulaireId; } public String getFormulaireNom() { return formulaireNom; } public void setFormulaireNom(String formulaireNom) { this.formulaireNom = formulaireNom; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/auth/LoginResponse.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/auth/LoginResponse.java index 2626d19..7b2b1d7 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/auth/LoginResponse.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/dto/auth/LoginResponse.java @@ -2,6 +2,7 @@ package dev.lions.unionflow.client.dto.auth; import java.time.LocalDateTime; import java.util.List; +import java.util.UUID; public class LoginResponse { @@ -79,7 +80,7 @@ public class LoginResponse { } public static class UserInfo { - private Long id; + private UUID id; private String nom; private String prenom; private String email; @@ -91,11 +92,11 @@ public class LoginResponse { public UserInfo() {} - public Long getId() { + public UUID getId() { return id; } - public void setId(Long id) { + public void setId(UUID id) { this.id = id; } @@ -172,7 +173,7 @@ public class LoginResponse { } public static class EntiteInfo { - private Long id; + private UUID id; private String nom; private String type; private String pays; @@ -180,11 +181,11 @@ public class LoginResponse { public EntiteInfo() {} - public Long getId() { + public UUID getId() { return id; } - public void setId(Long id) { + public void setId(UUID id) { this.id = id; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/exception/ViewExpiredExceptionHandler.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/exception/ViewExpiredExceptionHandler.java index 758cfd0..c6e0f17 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/exception/ViewExpiredExceptionHandler.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/exception/ViewExpiredExceptionHandler.java @@ -1,7 +1,6 @@ package dev.lions.unionflow.client.exception; import jakarta.faces.FacesException; -import jakarta.faces.application.NavigationHandler; import jakarta.faces.application.ViewExpiredException; import jakarta.faces.context.ExceptionHandler; import jakarta.faces.context.ExceptionHandlerWrapper; @@ -9,7 +8,6 @@ import jakarta.faces.context.FacesContext; import jakarta.faces.event.ExceptionQueuedEvent; import jakarta.faces.event.ExceptionQueuedEventContext; import java.util.Iterator; -import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -55,9 +53,9 @@ public class ViewExpiredExceptionHandler extends ExceptionHandlerWrapper { LOG.log(Level.WARNING, "Impossible de stocker l'URL de redirection: {0}", e.getMessage()); } - // Rediriger vers la page de login avec paramètre expired + // Rediriger vers la racine qui déclenchera Keycloak try { - String redirectURL = "/pages/public/login.xhtml?expired=true"; + String redirectURL = "/"; facesContext.getExternalContext().redirect( facesContext.getExternalContext().getRequestContextPath() + redirectURL ); @@ -66,10 +64,10 @@ public class ViewExpiredExceptionHandler extends ExceptionHandlerWrapper { LOG.log(Level.SEVERE, "Erreur lors de la redirection: {0}", e.getMessage()); // Fallback: essayer une redirection simple try { - facesContext.getExternalContext().redirect("/pages/public/login.xhtml"); + facesContext.getExternalContext().redirect("/"); facesContext.responseComplete(); } catch (Exception fallbackException) { - LOG.log(Level.SEVERE, "Impossible de rediriger vers login: {0}", fallbackException.getMessage()); + LOG.log(Level.SEVERE, "Impossible de rediriger vers la racine: {0}", fallbackException.getMessage()); } } } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/security/AuthenticationFilter.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/security/AuthenticationFilter.java index 5e1b016..0ba5602 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/security/AuthenticationFilter.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/security/AuthenticationFilter.java @@ -9,6 +9,14 @@ import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.logging.Logger; +/** + * Filtre d'authentification pour vérifications supplémentaires + * Note: Avec Keycloak OIDC, l'authentification principale est gérée par Quarkus + * Ce filtre peut être utilisé pour des vérifications de permissions supplémentaires + * + * @author UnionFlow Team + * @version 2.0 + */ @WebFilter(urlPatterns = {"/pages/secure/*", "/pages/admin/*", "/pages/super-admin/*", "/pages/membre/*"}) public class AuthenticationFilter implements Filter { @@ -17,9 +25,6 @@ public class AuthenticationFilter implements Filter { @Inject private UserSession userSession; - @Inject - private JwtTokenManager tokenManager; - @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { @@ -29,10 +34,13 @@ public class AuthenticationFilter implements Filter { String requestURI = httpRequest.getRequestURI(); - // Vérifier si l'utilisateur est authentifié + // Laisser Quarkus OIDC appliquer l'authentification (rediriger vers Keycloak si nécessaire) + // Ici, si l'utilisateur n'est pas encore authentifié, on ne force PAS une redirection custom + // pour éviter les boucles / conflits. On délègue au mécanisme Quarkus défini via + // quarkus.http.auth.permission.* et quarkus.oidc.* if (!isAuthenticated()) { - LOGGER.warning("Accès non autorisé à: " + requestURI); - httpResponse.sendRedirect(httpRequest.getContextPath() + "/pages/public/login.xhtml"); + LOGGER.fine("Requête non authentifiée sur " + requestURI + ", délégation à Quarkus OIDC."); + chain.doFilter(request, response); return; } @@ -50,10 +58,8 @@ public class AuthenticationFilter implements Filter { } private boolean isAuthenticated() { - return userSession != null && - userSession.isAuthenticated() && - tokenManager != null && - tokenManager.hasValidTokens(); + // Avec Keycloak OIDC, UserSession vérifie automatiquement l'authentification via JsonWebToken + return userSession != null && userSession.isAuthenticated(); } private boolean hasRequiredPermissions(String requestURI) { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/AnalyticsService.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/AnalyticsService.java new file mode 100644 index 0000000..8cf7afd --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/AnalyticsService.java @@ -0,0 +1,50 @@ +package dev.lions.unionflow.client.service; + +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import java.util.Map; + +@RegisterRestClient(configKey = "unionflow-api") +@Path("/api/v1/analytics") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface AnalyticsService { + + @GET + @Path("/dashboard/widgets") + Map getDashboardData( + @QueryParam("organisationId") String organisationId, + @QueryParam("utilisateurId") String utilisateurId + ); + + @GET + @Path("/tendances/{typeMetrique}") + Map getEvolutionMensuelle( + @PathParam("typeMetrique") String typeMetrique, + @QueryParam("organisationId") String organisationId, + @QueryParam("periode") String periode + ); + + @GET + @Path("/kpis") + Map getKPIs( + @QueryParam("organisationId") String organisationId, + @QueryParam("periode") String periode + ); + + @GET + @Path("/evolutions") + Map getEvolutions( + @QueryParam("organisationId") String organisationId, + @QueryParam("periode") String periode + ); + + @GET + @Path("/performance-globale") + Map getPerformanceGlobale( + @QueryParam("organisationId") String organisationId, + @QueryParam("periode") String periode + ); +} + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/AssociationService.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/AssociationService.java index a977a8e..f257c79 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/AssociationService.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/AssociationService.java @@ -5,6 +5,7 @@ import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import java.util.List; +import java.util.UUID; @RegisterRestClient(configKey = "unionflow-api") @Path("/api/associations") @@ -17,7 +18,7 @@ public interface AssociationService { @GET @Path("/{id}") - AssociationDTO obtenirParId(@PathParam("id") Long id); + AssociationDTO obtenirParId(@PathParam("id") UUID id); @GET @Path("/search") @@ -48,27 +49,27 @@ public interface AssociationService { @PUT @Path("/{id}") - AssociationDTO modifier(@PathParam("id") Long id, AssociationDTO association); + AssociationDTO modifier(@PathParam("id") UUID id, AssociationDTO association); @DELETE @Path("/{id}") - void supprimer(@PathParam("id") Long id); + void supprimer(@PathParam("id") UUID id); @PUT @Path("/{id}/activer") - AssociationDTO activer(@PathParam("id") Long id); + AssociationDTO activer(@PathParam("id") UUID id); @PUT @Path("/{id}/desactiver") - AssociationDTO desactiver(@PathParam("id") Long id); + AssociationDTO desactiver(@PathParam("id") UUID id); @PUT @Path("/{id}/suspendre") - AssociationDTO suspendre(@PathParam("id") Long id); + AssociationDTO suspendre(@PathParam("id") UUID id); @PUT @Path("/{id}/dissoudre") - AssociationDTO dissoudre(@PathParam("id") Long id); + AssociationDTO dissoudre(@PathParam("id") UUID id); @GET @Path("/statistiques") @@ -76,11 +77,11 @@ public interface AssociationService { @GET @Path("/{id}/membres/count") - Long compterMembres(@PathParam("id") Long id); + Long compterMembres(@PathParam("id") UUID id); @GET @Path("/{id}/performance") - PerformanceAssociationDTO obtenirPerformance(@PathParam("id") Long id); + PerformanceAssociationDTO obtenirPerformance(@PathParam("id") UUID id); // Classes DTO internes class StatistiquesAssociationDTO { @@ -127,7 +128,7 @@ public interface AssociationService { } class PerformanceAssociationDTO { - public Long associationId; + public UUID associationId; public String nom; public Integer scoreGlobal; public Integer scoreMembres; @@ -140,8 +141,8 @@ public interface AssociationService { public PerformanceAssociationDTO() {} // Getters et setters - public Long getAssociationId() { return associationId; } - public void setAssociationId(Long associationId) { this.associationId = associationId; } + public UUID getAssociationId() { return associationId; } + public void setAssociationId(UUID associationId) { this.associationId = associationId; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/AuthenticationService.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/AuthenticationService.java index f6e7e85..d119ff5 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/AuthenticationService.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/AuthenticationService.java @@ -9,6 +9,7 @@ import jakarta.ws.rs.client.Entity; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import org.eclipse.microprofile.config.inject.ConfigProperty; +import java.util.UUID; import java.util.logging.Logger; @ApplicationScoped @@ -100,9 +101,15 @@ public class AuthenticationService { private LoginResponse createDemoLoginResponse(LoginRequest request) { LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo(); + // UUIDs fixes pour la démonstration (pour cohérence entre les sessions) + UUID superAdminId = UUID.fromString("00000000-0000-0000-0000-000000000001"); + UUID adminId = UUID.fromString("00000000-0000-0000-0000-000000000002"); + UUID membreId = UUID.fromString("00000000-0000-0000-0000-000000000003"); + UUID entiteId = UUID.fromString("00000000-0000-0000-0000-000000000010"); + switch (request.getUsername()) { case "superadmin": - userInfo.setId(1L); + userInfo.setId(superAdminId); userInfo.setNom("Diallo"); userInfo.setPrenom("Amadou"); userInfo.setEmail("amadou.diallo@unionflow.sn"); @@ -112,7 +119,7 @@ public class AuthenticationService { break; case "admin": - userInfo.setId(2L); + userInfo.setId(adminId); userInfo.setNom("Traoré"); userInfo.setPrenom("Fatou"); userInfo.setEmail("fatou.traore@association-example.sn"); @@ -122,7 +129,7 @@ public class AuthenticationService { // Entité de démonstration LoginResponse.EntiteInfo entite = new LoginResponse.EntiteInfo(); - entite.setId(1L); + entite.setId(entiteId); entite.setNom("Association des Jeunes Entrepreneurs"); entite.setType("Association"); entite.setPays("Sénégal"); @@ -131,7 +138,7 @@ public class AuthenticationService { break; default: - userInfo.setId(3L); + userInfo.setId(membreId); userInfo.setNom("Ndiaye"); userInfo.setPrenom("Moussa"); userInfo.setEmail("moussa.ndiaye@exemple.sn"); @@ -141,7 +148,7 @@ public class AuthenticationService { // Entité de démonstration LoginResponse.EntiteInfo entiteMembre = new LoginResponse.EntiteInfo(); - entiteMembre.setId(1L); + entiteMembre.setId(entiteId); entiteMembre.setNom("Association des Jeunes Entrepreneurs"); entiteMembre.setType("Association"); entiteMembre.setPays("Sénégal"); @@ -167,4 +174,4 @@ public class AuthenticationService { super(message, cause); } } -} \ No newline at end of file +} diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/CotisationService.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/CotisationService.java new file mode 100644 index 0000000..8bda62b --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/CotisationService.java @@ -0,0 +1,46 @@ +package dev.lions.unionflow.client.service; + +import dev.lions.unionflow.client.dto.CotisationDTO; +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import java.util.List; +import java.util.UUID; + +@RegisterRestClient(configKey = "unionflow-api") +@Path("/api/cotisations") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface CotisationService { + + @GET + List listerToutes( + @QueryParam("page") @DefaultValue("0") int page, + @QueryParam("size") @DefaultValue("20") int size + ); + + @GET + @Path("/{id}") + CotisationDTO obtenirParId(@PathParam("id") UUID id); + + @GET + @Path("/search") + List rechercher( + @QueryParam("membreId") UUID membreId, + @QueryParam("statut") String statut, + @QueryParam("page") @DefaultValue("0") int page, + @QueryParam("size") @DefaultValue("20") int size + ); + + @POST + CotisationDTO creer(CotisationDTO cotisation); + + @PUT + @Path("/{id}") + CotisationDTO modifier(@PathParam("id") UUID id, CotisationDTO cotisation); + + @DELETE + @Path("/{id}") + void supprimer(@PathParam("id") UUID id); +} + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/DemandeAideService.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/DemandeAideService.java new file mode 100644 index 0000000..a7a244c --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/DemandeAideService.java @@ -0,0 +1,55 @@ +package dev.lions.unionflow.client.service; + +import dev.lions.unionflow.client.dto.DemandeAideDTO; +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import java.util.List; +import java.util.UUID; + +@RegisterRestClient(configKey = "unionflow-api") +@Path("/api/demandes-aide") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface DemandeAideService { + + @GET + List listerToutes( + @QueryParam("page") @DefaultValue("0") int page, + @QueryParam("size") @DefaultValue("20") int size + ); + + @GET + @Path("/{id}") + DemandeAideDTO obtenirParId(@PathParam("id") UUID id); + + @GET + @Path("/search") + List rechercher( + @QueryParam("statut") String statut, + @QueryParam("type") String type, + @QueryParam("urgence") String urgence, + @QueryParam("page") @DefaultValue("0") int page, + @QueryParam("size") @DefaultValue("20") int size + ); + + @POST + DemandeAideDTO creer(DemandeAideDTO demande); + + @PUT + @Path("/{id}") + DemandeAideDTO modifier(@PathParam("id") UUID id, DemandeAideDTO demande); + + @DELETE + @Path("/{id}") + void supprimer(@PathParam("id") UUID id); + + @PUT + @Path("/{id}/approuver") + DemandeAideDTO approuver(@PathParam("id") UUID id); + + @PUT + @Path("/{id}/rejeter") + DemandeAideDTO rejeter(@PathParam("id") UUID id); +} + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/EvenementService.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/EvenementService.java new file mode 100644 index 0000000..59906b4 --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/EvenementService.java @@ -0,0 +1,54 @@ +package dev.lions.unionflow.client.service; + +import dev.lions.unionflow.client.dto.EvenementDTO; +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import java.util.List; +import java.util.UUID; + +@RegisterRestClient(configKey = "unionflow-api") +@Path("/api/evenements") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface EvenementService { + + @GET + List listerTous( + @QueryParam("page") @DefaultValue("0") int page, + @QueryParam("size") @DefaultValue("20") int size + ); + + @GET + @Path("/{id}") + EvenementDTO obtenirParId(@PathParam("id") UUID id); + + @GET + @Path("/search") + List rechercher( + @QueryParam("titre") String titre, + @QueryParam("type") String type, + @QueryParam("statut") String statut, + @QueryParam("page") @DefaultValue("0") int page, + @QueryParam("size") @DefaultValue("20") int size + ); + + @GET + @Path("/a-venir") + List listerAVenir( + @QueryParam("page") @DefaultValue("0") int page, + @QueryParam("size") @DefaultValue("20") int size + ); + + @POST + EvenementDTO creer(EvenementDTO evenement); + + @PUT + @Path("/{id}") + EvenementDTO modifier(@PathParam("id") UUID id, EvenementDTO evenement); + + @DELETE + @Path("/{id}") + void supprimer(@PathParam("id") UUID id); +} + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/FormulaireService.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/FormulaireService.java new file mode 100644 index 0000000..0d86381 --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/FormulaireService.java @@ -0,0 +1,50 @@ +package dev.lions.unionflow.client.service; + +import dev.lions.unionflow.client.dto.FormulaireDTO; +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import java.util.List; +import java.util.UUID; + +@RegisterRestClient(configKey = "unionflow-api") +@Path("/api/formulaires") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface FormulaireService { + + @GET + List listerTous(); + + @GET + @Path("/{id}") + FormulaireDTO obtenirParId(@PathParam("id") UUID id); + + @GET + @Path("/actifs") + List listerActifs(); + + @GET + @Path("/populaires") + List listerPopulaires(); + + @POST + FormulaireDTO creer(FormulaireDTO formulaire); + + @PUT + @Path("/{id}") + FormulaireDTO modifier(@PathParam("id") UUID id, FormulaireDTO formulaire); + + @DELETE + @Path("/{id}") + void supprimer(@PathParam("id") UUID id); + + @PUT + @Path("/{id}/activer") + FormulaireDTO activer(@PathParam("id") UUID id); + + @PUT + @Path("/{id}/desactiver") + FormulaireDTO desactiver(@PathParam("id") UUID id); +} + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/MembreService.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/MembreService.java index 660b2ea..23e55ce 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/MembreService.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/MembreService.java @@ -5,6 +5,7 @@ import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import java.util.List; +import java.util.UUID; @RegisterRestClient(configKey = "unionflow-api") @Path("/api/membres") @@ -17,7 +18,7 @@ public interface MembreService { @GET @Path("/{id}") - MembreDTO obtenirParId(@PathParam("id") Long id); + MembreDTO obtenirParId(@PathParam("id") UUID id); @GET @Path("/numero/{numeroMembre}") @@ -31,14 +32,14 @@ public interface MembreService { @QueryParam("email") String email, @QueryParam("telephone") String telephone, @QueryParam("statut") String statut, - @QueryParam("associationId") Long associationId, + @QueryParam("associationId") UUID associationId, @QueryParam("page") @DefaultValue("0") int page, @QueryParam("size") @DefaultValue("20") int size ); @GET @Path("/association/{associationId}") - List listerParAssociation(@PathParam("associationId") Long associationId); + List listerParAssociation(@PathParam("associationId") UUID associationId); @GET @Path("/actifs") @@ -53,27 +54,27 @@ public interface MembreService { @PUT @Path("/{id}") - MembreDTO modifier(@PathParam("id") Long id, MembreDTO membre); + MembreDTO modifier(@PathParam("id") UUID id, MembreDTO membre); @DELETE @Path("/{id}") - void supprimer(@PathParam("id") Long id); + void supprimer(@PathParam("id") UUID id); @PUT @Path("/{id}/activer") - MembreDTO activer(@PathParam("id") Long id); + MembreDTO activer(@PathParam("id") UUID id); @PUT @Path("/{id}/desactiver") - MembreDTO desactiver(@PathParam("id") Long id); + MembreDTO desactiver(@PathParam("id") UUID id); @PUT @Path("/{id}/suspendre") - MembreDTO suspendre(@PathParam("id") Long id); + MembreDTO suspendre(@PathParam("id") UUID id); @PUT @Path("/{id}/radier") - MembreDTO radier(@PathParam("id") Long id); + MembreDTO radier(@PathParam("id") UUID id); @GET @Path("/statistiques") @@ -84,7 +85,7 @@ public interface MembreService { @Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") byte[] exporterExcel( @QueryParam("format") @DefaultValue("EXCEL") String format, - @QueryParam("associationId") Long associationId, + @QueryParam("associationId") UUID associationId, @QueryParam("statut") String statut ); @@ -93,7 +94,7 @@ public interface MembreService { @Consumes(MediaType.MULTIPART_FORM_DATA) ResultatImportDTO importerDonnees( @FormParam("file") java.io.InputStream fileInputStream, - @FormParam("associationId") Long associationId + @FormParam("associationId") UUID associationId ); // Classes DTO internes pour les réponses spécialisées diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/SouscriptionService.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/SouscriptionService.java new file mode 100644 index 0000000..96a7c81 --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/SouscriptionService.java @@ -0,0 +1,46 @@ +package dev.lions.unionflow.client.service; + +import dev.lions.unionflow.client.dto.SouscriptionDTO; +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; +import jakarta.ws.rs.*; +import jakarta.ws.rs.core.MediaType; +import java.util.List; +import java.util.UUID; + +@RegisterRestClient(configKey = "unionflow-api") +@Path("/api/souscriptions") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface SouscriptionService { + + @GET + List listerToutes( + @QueryParam("organisationId") UUID organisationId, + @QueryParam("page") @DefaultValue("0") int page, + @QueryParam("size") @DefaultValue("20") int size + ); + + @GET + @Path("/{id}") + SouscriptionDTO obtenirParId(@PathParam("id") UUID id); + + @GET + @Path("/organisation/{organisationId}/active") + SouscriptionDTO obtenirActive(@PathParam("organisationId") UUID organisationId); + + @POST + SouscriptionDTO creer(SouscriptionDTO souscription); + + @PUT + @Path("/{id}") + SouscriptionDTO modifier(@PathParam("id") UUID id, SouscriptionDTO souscription); + + @DELETE + @Path("/{id}") + void supprimer(@PathParam("id") UUID id); + + @PUT + @Path("/{id}/renouveler") + SouscriptionDTO renouveler(@PathParam("id") UUID id); +} + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/AdminFormulaireBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/AdminFormulaireBean.java index f1abd3f..ebc34d6 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/AdminFormulaireBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/AdminFormulaireBean.java @@ -1,20 +1,30 @@ package dev.lions.unionflow.client.view; import dev.lions.unionflow.client.dto.FormulaireDTO; -import dev.lions.unionflow.client.dto.SouscriptionDTO; +import dev.lions.unionflow.client.service.FormulaireService; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; +import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.UUID; +import java.util.logging.Logger; @Named("adminFormulaireBean") @SessionScoped public class AdminFormulaireBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(AdminFormulaireBean.class.getName()); + + @Inject + @RestClient + private FormulaireService formulaireService; private List formulaires; private FormulaireDTO formulaireSelectionne; @@ -27,106 +37,18 @@ public class AdminFormulaireBean implements Serializable { private BigDecimal revenusFormulaires = BigDecimal.ZERO; private String formulairePlusPopulaire = ""; - public AdminFormulaireBean() { + @PostConstruct + public void init() { initializeData(); } private void initializeData() { formulaires = new ArrayList<>(); - - // Formulaire STARTER - FormulaireDTO starter = new FormulaireDTO(); - starter.setId(1L); - starter.setNom("Starter"); - starter.setDescription("Parfait pour les petites associations débutantes"); - starter.setQuotaMaxMembres(100); - starter.setPrixMensuel(new BigDecimal("2000")); - starter.setPrixAnnuel(new BigDecimal("20000")); - starter.setCouleurTheme("bg-blue-500"); - starter.setIconeFormulaire("pi-star"); - starter.setActif(true); - starter.setGestionMembres(true); - starter.setGestionCotisations(true); - starter.setNotificationsEmail(true); - starter.setDateCreation(LocalDateTime.now().minusMonths(6)); - starter.setCreePar("Super Admin"); - formulaires.add(starter); - - // Formulaire STANDARD - FormulaireDTO standard = new FormulaireDTO(); - standard.setId(2L); - standard.setNom("Standard"); - standard.setDescription("Idéal pour les associations en croissance"); - standard.setQuotaMaxMembres(200); - standard.setPrixMensuel(new BigDecimal("3000")); - standard.setPrixAnnuel(new BigDecimal("30000")); - standard.setCouleurTheme("bg-green-500"); - standard.setIconeFormulaire("pi-users"); - standard.setActif(true); - standard.setRecommande(true); - standard.setGestionMembres(true); - standard.setGestionCotisations(true); - standard.setGestionEvenements(true); - standard.setGestionAides(true); - standard.setNotificationsEmail(true); - standard.setGestionDocuments(true); - standard.setDateCreation(LocalDateTime.now().minusMonths(6)); - standard.setCreePar("Super Admin"); - formulaires.add(standard); - - // Formulaire PREMIUM - FormulaireDTO premium = new FormulaireDTO(); - premium.setId(3L); - premium.setNom("Premium"); - premium.setDescription("Solution complète pour les grandes organisations"); - premium.setQuotaMaxMembres(500); - premium.setPrixMensuel(new BigDecimal("4000")); - premium.setPrixAnnuel(new BigDecimal("40000")); - premium.setCouleurTheme("bg-purple-500"); - premium.setIconeFormulaire("pi-crown"); - premium.setActif(true); - premium.setGestionMembres(true); - premium.setGestionCotisations(true); - premium.setGestionEvenements(true); - premium.setGestionAides(true); - premium.setRapportsAvances(true); - premium.setSupportPrioritaire(true); - premium.setSauvegardeAutomatique(true); - premium.setPersonnalisationAvancee(true); - premium.setIntegrationPaiement(true); - premium.setNotificationsEmail(true); - premium.setNotificationsSMS(true); - premium.setGestionDocuments(true); - premium.setDateCreation(LocalDateTime.now().minusMonths(6)); - premium.setCreePar("Super Admin"); - formulaires.add(premium); - - // Formulaire CRISTAL - Pour les très grandes organisations - FormulaireDTO cristal = new FormulaireDTO(); - cristal.setId(4L); - cristal.setNom("Cristal"); - cristal.setDescription("Solution premium pour les fédérations et grandes entités"); - cristal.setQuotaMaxMembres(2000); - cristal.setPrixMensuel(new BigDecimal("5000")); - cristal.setPrixAnnuel(new BigDecimal("50000")); - cristal.setCouleurTheme("bg-indigo-500"); - cristal.setIconeFormulaire("pi-diamond"); - cristal.setActif(true); - cristal.setGestionMembres(true); - cristal.setGestionCotisations(true); - cristal.setGestionEvenements(true); - cristal.setGestionAides(true); - cristal.setRapportsAvances(true); - cristal.setSupportPrioritaire(true); - cristal.setSauvegardeAutomatique(true); - cristal.setPersonnalisationAvancee(true); - cristal.setIntegrationPaiement(true); - cristal.setNotificationsEmail(true); - cristal.setNotificationsSMS(true); - cristal.setGestionDocuments(true); - cristal.setDateCreation(LocalDateTime.now().minusMonths(6)); - cristal.setCreePar("Super Admin"); - formulaires.add(cristal); + try { + formulaires = formulaireService.listerTous(); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des formulaires: " + e.getMessage()); + } // Initialiser les statistiques totalSouscriptions = 127; // Plus d'entités avec prix accessibles @@ -154,12 +76,8 @@ public class AdminFormulaireBean implements Serializable { public void sauvegarderFormulaire() { if (modeCreation) { - // Générer un nouvel ID - Long nouvelId = formulaires.stream() - .mapToLong(FormulaireDTO::getId) - .max() - .orElse(0L) + 1; - nouveauFormulaire.setId(nouvelId); + // Générer un nouvel ID UUID + nouveauFormulaire.setId(UUID.randomUUID()); nouveauFormulaire.setDateCreation(LocalDateTime.now()); nouveauFormulaire.setCreePar("Admin"); @@ -197,7 +115,7 @@ public class AdminFormulaireBean implements Serializable { public void dupliquerFormulaire(FormulaireDTO formulaire) { FormulaireDTO copie = cloneFormulaire(formulaire); - copie.setId(null); + copie.setId(UUID.randomUUID()); copie.setNom(formulaire.getNom() + " (Copie)"); copie.setDateCreation(LocalDateTime.now()); copie.setCreePar("Admin"); diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/ConfigurationBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/ConfigurationBean.java index cbb012c..50b8da0 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/ConfigurationBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/ConfigurationBean.java @@ -5,14 +5,15 @@ import jakarta.inject.Named; import jakarta.annotation.PostConstruct; import java.io.Serializable; import java.time.LocalDateTime; -import java.time.LocalTime; import java.time.format.DateTimeFormatter; +import java.util.logging.Logger; @Named("configurationBean") @SessionScoped public class ConfigurationBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(ConfigurationBean.class.getName()); private ConfigurationGenerale general; private ConfigurationSecurite securite; @@ -178,84 +179,85 @@ public class ConfigurationBean implements Serializable { // Actions générales public void sauvegarderTout() { - System.out.println("Configuration complète sauvegardée à " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"))); + LOGGER.info("Configuration complète sauvegardée à " + LocalDateTime.now().format(DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss"))); } public void reinitialiser() { init(); - System.out.println("Configuration réinitialisée aux valeurs par défaut"); + LOGGER.info("Configuration réinitialisée aux valeurs par défaut"); } public void exporterConfiguration() { - System.out.println("Export de la configuration généré"); + LOGGER.info("Export de la configuration généré"); } // Actions par section public void sauvegarderGeneral() { - System.out.println("Configuration générale sauvegardée"); + LOGGER.info("Configuration générale sauvegardée"); } public void sauvegarderSecurite() { - System.out.println("Configuration sécurité sauvegardée"); + LOGGER.info("Configuration sécurité sauvegardée"); } public void sauvegarderEmail() { - System.out.println("Configuration email sauvegardée"); + LOGGER.info("Configuration email sauvegardée"); } // Actions pour la page système public void sauvegarderConfiguration() { - System.out.println("Configuration système sauvegardée"); + LOGGER.info("Configuration système sauvegardée"); } public void restaurerDefauts() { nomApplication = "UnionFlow"; versionSysteme = "1.0.0"; environnement = "DEV"; - System.out.println("Configuration système restaurée aux valeurs par défaut"); + LOGGER.info("Configuration système restaurée aux valeurs par défaut"); } public void testerConnexionBDD() { - System.out.println("Test de connexion BDD: " + typeBDD + "://" + serveurBDD + ":" + portBDD + "/" + nomBDD); - // TODO: Implémenter le test réel + // Le test de connexion BDD sera implémenté via l'API backend + // Pour l'instant, log uniquement + LOGGER.info("Test de connexion BDD: " + typeBDD + "://" + serveurBDD + ":" + portBDD + "/" + nomBDD); } public void testerEmail() { - System.out.println("Test d'envoi d'email via " + serveurSMTP + ":" + portSMTP); - // TODO: Implémenter le test réel - System.out.println("Test email envoyé avec succès"); + // Le test d'email sera implémenté via l'API backend + // Pour l'instant, log uniquement + LOGGER.info("Test d'envoi d'email via " + serveurSMTP + ":" + portSMTP); } public void forcerSauvegarde() { - System.out.println("Sauvegarde forcée du système"); + // La sauvegarde sera déclenchée via l'API backend + LOGGER.info("Sauvegarde forcée du système"); derniereSauvegarde = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HH:mm")); - // TODO: Déclencher une sauvegarde immédiate } public void redemarrerServices() { - System.out.println("Redémarrage des services système en cours..."); - // TODO: Redémarrer les services critiques + // Le redémarrage des services sera géré via l'API backend + LOGGER.info("Redémarrage des services système en cours..."); } public void sauvegarderPaiements() { - System.out.println("Configuration paiements sauvegardée"); + LOGGER.info("Configuration paiements sauvegardée"); } public void sauvegarderSysteme() { - System.out.println("Configuration système sauvegardée"); + LOGGER.info("Configuration système sauvegardée"); } // Actions système public void viderCache() { - System.out.println("Cache vidé avec succès"); + LOGGER.info("Cache vidé avec succès"); } public void optimiserBaseDonnees() { - System.out.println("Optimisation de la base de données en cours..."); + LOGGER.info("Optimisation de la base de données en cours..."); } public void sauvegarderBaseDonnees() { - System.out.println("Sauvegarde de la base de données initiée"); + LOGGER.info("Sauvegarde de la base de données initiée"); } public String voirLogsSysteme() { @@ -665,35 +667,35 @@ public class ConfigurationBean implements Serializable { // Méthodes d'actions public void actualiserMonitoring() { calculerMetriquesSysteme(); - System.out.println("Monitoring actualisé"); + LOGGER.info("Monitoring actualisé"); } public void nettoyerCache() { - System.out.println("Cache système nettoyé"); + LOGGER.info("Cache système nettoyé"); } public void auditSysteme() { - System.out.println("Audit système lancé"); + LOGGER.info("Audit système lancé"); } public void appliquerConfigGenerale() { - System.out.println("Configuration générale appliquée"); + LOGGER.info("Configuration générale appliquée"); } public void appliquerConfigBDD() { - System.out.println("Configuration BDD appliquée"); + LOGGER.info("Configuration BDD appliquée"); } public void appliquerConfigEmail() { - System.out.println("Configuration email appliquée"); + LOGGER.info("Configuration email appliquée"); } public void appliquerConfigSecurite() { - System.out.println("Configuration sécurité appliquée"); + LOGGER.info("Configuration sécurité appliquée"); } public void sauvegarderAlertes() { - System.out.println("Configuration des alertes sauvegardée"); + LOGGER.info("Configuration des alertes sauvegardée"); } public static class ConfigurationSysteme { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/CotisationsBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/CotisationsBean.java index 6200af0..c2efb30 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/CotisationsBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/CotisationsBean.java @@ -1,8 +1,12 @@ package dev.lions.unionflow.client.view; +import dev.lions.unionflow.client.dto.CotisationDTO; +import dev.lions.unionflow.client.service.CotisationService; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; import java.time.LocalDate; import java.time.LocalDateTime; @@ -10,14 +14,21 @@ import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; import java.math.BigDecimal; +import java.util.logging.Logger; @Named("cotisationsBean") @SessionScoped public class CotisationsBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(CotisationsBean.class.getName()); + + @Inject + @RestClient + private CotisationService cotisationService; private List toutesLesCotisations; private List cotisationsFiltrees; @@ -33,8 +44,8 @@ public class CotisationsBean implements Serializable { @PostConstruct public void init() { initializeFiltres(); - initializeStatistiques(); initializeCotisations(); + initializeStatistiques(); initializeNouvelleCotisation(); initializeEvolutionPaiements(); initializeRepartitionMethodes(); @@ -49,12 +60,40 @@ public class CotisationsBean implements Serializable { private void initializeStatistiques() { statistiques = new StatistiquesFinancieres(); - statistiques.setTotalCollecte(new BigDecimal("45750000")); - statistiques.setObjectifAnnuel(new BigDecimal("60000000")); - statistiques.setTauxRecouvrement(76.25); - statistiques.setCotisationsEnRetard(23); - statistiques.setMontantRetard(new BigDecimal("3850000")); - statistiques.setMoyenneMensuelle(new BigDecimal("3812500")); + try { + List cotisationsDTO = cotisationService.listerToutes(0, 1000); + BigDecimal totalCollecte = cotisationsDTO.stream() + .filter(c -> "PAYEE".equals(c.getStatut()) || "PARTIELLEMENT_PAYEE".equals(c.getStatut())) + .map(c -> c.getMontantPaye() != null ? c.getMontantPaye() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + statistiques.setTotalCollecte(totalCollecte); + statistiques.setObjectifAnnuel(totalCollecte.multiply(new BigDecimal("1.3"))); + + long total = cotisationsDTO.size(); + long payees = cotisationsDTO.stream().filter(c -> "PAYEE".equals(c.getStatut())).count(); + double tauxRecouvrement = total > 0 ? (double) payees / total * 100.0 : 0.0; + statistiques.setTauxRecouvrement(tauxRecouvrement); + + long enRetard = cotisationsDTO.stream().filter(c -> "EN_RETARD".equals(c.getStatut())).count(); + statistiques.setCotisationsEnRetard((int) enRetard); + + BigDecimal montantRetard = cotisationsDTO.stream() + .filter(c -> "EN_RETARD".equals(c.getStatut())) + .map(c -> c.getMontantDu() != null ? c.getMontantDu() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + statistiques.setMontantRetard(montantRetard); + + BigDecimal moyenneMensuelle = totalCollecte.divide(new BigDecimal("12"), 2, java.math.RoundingMode.HALF_UP); + statistiques.setMoyenneMensuelle(moyenneMensuelle); + } catch (Exception e) { + LOGGER.severe("Erreur lors du calcul des statistiques: " + e.getMessage()); + statistiques.setTotalCollecte(BigDecimal.ZERO); + statistiques.setObjectifAnnuel(BigDecimal.ZERO); + statistiques.setTauxRecouvrement(0.0); + statistiques.setCotisationsEnRetard(0); + statistiques.setMontantRetard(BigDecimal.ZERO); + statistiques.setMoyenneMensuelle(BigDecimal.ZERO); + } } private void initializeEvolutionPaiements() { @@ -142,65 +181,34 @@ public class CotisationsBean implements Serializable { private void initializeCotisations() { toutesLesCotisations = new ArrayList<>(); - - String[] membres = { - "Jean Kouassi", "Marie Traoré", "Ahmed Diallo", "Fatou Sanogo", "Paul Ouattara", - "Aissata Koné", "Ibrahim Touré", "Aminata Bakayoko", "Yves Koffi", "Mariam Coulibaly", - "Seydou Cissé", "Adjoa Mensah", "Kwame Asante", "Ama Gyamfi", "Kofi Adjei" - }; - - String[] clubs = { - "Association Alpha", "Club Beta", "Groupe Gamma", - "Association Delta", "Club Epsilon", "Groupe Zeta", - "Association Eta", "Club Theta", "Groupe Iota" - }; - - String[] types = {"MENSUELLE", "TRIMESTRIELLE", "ANNUELLE", "EXCEPTIONNELLE"}; - String[] statuts = {"PAYEE", "EN_ATTENTE", "EN_RETARD", "PARTIELLEMENT_PAYEE"}; - String[] methodes = {"WAVE_MONEY", "ESPECES", "CHEQUE", "VIREMENT"}; - - BigDecimal[] montants = { - new BigDecimal("150000"), new BigDecimal("125000"), new BigDecimal("100000"), - new BigDecimal("175000"), new BigDecimal("200000"), new BigDecimal("75000"), - new BigDecimal("120000"), new BigDecimal("180000"), new BigDecimal("95000") - }; - - for (int i = 0; i < 50; i++) { - Cotisation cotisation = new Cotisation(); - cotisation.setId((long) (i + 1)); - cotisation.setNumeroMembre("M" + String.format("%04d", (i % membres.length) + 1)); - cotisation.setNomMembre(membres[i % membres.length]); - cotisation.setClub(clubs[i % clubs.length]); - cotisation.setTypeCotisation(types[i % types.length]); - cotisation.setMontantDu(montants[i % montants.length]); - - if (i % 5 == 0) { - cotisation.setStatut("EN_RETARD"); - cotisation.setMontantPaye(BigDecimal.ZERO); - } else if (i % 8 == 0) { - cotisation.setStatut("PARTIELLEMENT_PAYEE"); - cotisation.setMontantPaye(cotisation.getMontantDu().multiply(new BigDecimal("0.5"))); - } else if (i % 12 == 0) { - cotisation.setStatut("EN_ATTENTE"); - cotisation.setMontantPaye(BigDecimal.ZERO); - } else { - cotisation.setStatut("PAYEE"); - cotisation.setMontantPaye(cotisation.getMontantDu()); + try { + List cotisationsDTO = cotisationService.listerToutes(0, 1000); + for (CotisationDTO dto : cotisationsDTO) { + Cotisation cotisation = convertToCotisation(dto); + toutesLesCotisations.add(cotisation); } - - cotisation.setMethodePaiement(methodes[i % methodes.length]); - cotisation.setDateEcheance(LocalDate.now().minusDays(i * 2).plusMonths(1)); - - if (!cotisation.getStatut().equals("EN_ATTENTE")) { - cotisation.setDatePaiement(LocalDateTime.now().minusDays(i + 1)); - } - - cotisation.setObservations(i % 7 == 0 ? "Paiement en plusieurs fois autorisé" : ""); - - toutesLesCotisations.add(cotisation); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des cotisations: " + e.getMessage()); } } + private Cotisation convertToCotisation(CotisationDTO dto) { + Cotisation cotisation = new Cotisation(); + cotisation.setId(dto.getId()); + cotisation.setNumeroMembre(dto.getNumeroMembre()); + cotisation.setNomMembre(dto.getNomMembre()); + cotisation.setClub(dto.getNomAssociation()); + cotisation.setTypeCotisation(dto.getTypeCotisation()); + cotisation.setMontantDu(dto.getMontantDu()); + cotisation.setMontantPaye(dto.getMontantPaye()); + cotisation.setStatut(dto.getStatut()); + cotisation.setMethodePaiement(dto.getMethodePaiement()); + cotisation.setDateEcheance(dto.getDateEcheance()); + cotisation.setDatePaiement(dto.getDatePaiement()); + cotisation.setObservations(dto.getObservations()); + return cotisation; + } + private void initializeNouvelleCotisation() { nouvelleCotisation = new NouvelleCotisation(); } @@ -269,7 +277,7 @@ public class CotisationsBean implements Serializable { public void enregistrerCotisation() { Cotisation nouvelleCot = new Cotisation(); - nouvelleCot.setId((long) (toutesLesCotisations.size() + 1)); + nouvelleCot.setId(UUID.randomUUID()); nouvelleCot.setNumeroMembre(nouvelleCotisation.getNumeroMembre()); nouvelleCot.setNomMembre(nouvelleCotisation.getNomMembre()); nouvelleCot.setClub(nouvelleCotisation.getClub()); @@ -283,7 +291,7 @@ public class CotisationsBean implements Serializable { toutesLesCotisations.add(nouvelleCot); appliquerFiltres(); - System.out.println("Nouvelle cotisation enregistrée pour: " + nouvelleCot.getNomMembre()); + LOGGER.info("Nouvelle cotisation enregistrée pour: " + nouvelleCot.getNomMembre()); initializeNouvelleCotisation(); } @@ -292,7 +300,7 @@ public class CotisationsBean implements Serializable { cotisationSelectionnee.setStatut("PAYEE"); cotisationSelectionnee.setMontantPaye(cotisationSelectionnee.getMontantDu()); cotisationSelectionnee.setDatePaiement(LocalDateTime.now()); - System.out.println("Cotisation marquée comme payée: " + cotisationSelectionnee.getNomMembre()); + LOGGER.info("Cotisation marquée comme payée: " + cotisationSelectionnee.getNomMembre()); } } @@ -300,26 +308,26 @@ public class CotisationsBean implements Serializable { if (cotisationSelectionnee != null) { cotisationSelectionnee.setStatut("PARTIELLEMENT_PAYEE"); cotisationSelectionnee.setDatePaiement(LocalDateTime.now()); - System.out.println("Paiement partiel enregistré: " + cotisationSelectionnee.getNomMembre()); + LOGGER.info("Paiement partiel enregistré: " + cotisationSelectionnee.getNomMembre()); } } public void envoyerRappel() { if (cotisationSelectionnee != null) { - System.out.println("Rappel envoyé à: " + cotisationSelectionnee.getNomMembre()); + LOGGER.info("Rappel envoyé à: " + cotisationSelectionnee.getNomMembre()); } } public void envoyerRappelsGroupes() { - System.out.println("Rappels envoyés à " + cotisationsSelectionnees.size() + " membres"); + LOGGER.info("Rappels envoyés à " + cotisationsSelectionnees.size() + " membres"); } public void exporterCotisations() { - System.out.println("Export de " + cotisationsFiltrees.size() + " cotisations"); + LOGGER.info("Export de " + cotisationsFiltrees.size() + " cotisations"); } public void genererRapportFinancier() { - System.out.println("Rapport financier généré"); + LOGGER.info("Rapport financier généré"); } // Getters et Setters @@ -355,7 +363,7 @@ public class CotisationsBean implements Serializable { // Classes internes public static class Cotisation { - private Long id; + private UUID id; private String numeroMembre; private String nomMembre; private String club; @@ -369,8 +377,8 @@ public class CotisationsBean implements Serializable { private String observations; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNumeroMembre() { return numeroMembre; } public void setNumeroMembre(String numeroMembre) { this.numeroMembre = numeroMembre; } @@ -474,7 +482,7 @@ public class CotisationsBean implements Serializable { public int getPourcentagePaye() { if (montantDu.equals(BigDecimal.ZERO)) return 0; - return montantPaye.multiply(new BigDecimal("100")).divide(montantDu, 0, BigDecimal.ROUND_HALF_UP).intValue(); + return montantPaye.multiply(new BigDecimal("100")).divide(montantDu, 0, java.math.RoundingMode.HALF_UP).intValue(); } public long getJoursRetard() { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/CotisationsGestionBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/CotisationsGestionBean.java index 6cf6dc9..98a48ec 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/CotisationsGestionBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/CotisationsGestionBean.java @@ -1,21 +1,38 @@ package dev.lions.unionflow.client.view; +import dev.lions.unionflow.client.dto.CotisationDTO; +import dev.lions.unionflow.client.dto.AssociationDTO; +import dev.lions.unionflow.client.service.CotisationService; +import dev.lions.unionflow.client.service.AssociationService; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; +import java.util.logging.Logger; @Named("cotisationsGestionBean") @SessionScoped public class CotisationsGestionBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(CotisationsGestionBean.class.getName()); + + @Inject + @RestClient + private CotisationService cotisationService; + + @Inject + @RestClient + private AssociationService associationService; // Propriétés principales private String periodeActuelle; @@ -71,95 +88,157 @@ public class CotisationsGestionBean implements Serializable { } private void initializeKPIs() { - this.periodeActuelle = "Décembre 2024"; - this.tauxRecouvrement = new BigDecimal("87.3"); - this.totalMembresActifs = 18547; - - this.montantCollecte = "2,845,000 FCFA"; - this.objectifMensuel = "3,200,000 FCFA"; - this.progressionMensuelle = 89; - this.membresAJour = "16,205"; - this.pourcentageMembresAJour = 87; - this.montantEnAttente = "785,000 FCFA"; - this.nombreCotisationsEnAttente = 1247; - this.montantImpayes = "425,000 FCFA"; - this.joursRetardMoyen = 12; - this.revenus2024 = "34,200,000 FCFA"; - this.croissanceAnnuelle = "+15.3%"; - this.prelevementsActifs = "8,450"; - this.montantPrelevementsPrevu = "42,250,000"; - - this.membresPrelevementActif = 8450; - this.montantPrelevementMensuel = "42,250,000 FCFA"; - this.prochainPrelevement = "01/01/2025"; - + try { + List cotisationsDTO = cotisationService.listerToutes(0, 1000); + + BigDecimal totalCollecte = cotisationsDTO.stream() + .filter(c -> "PAYEE".equals(c.getStatut()) || "PARTIELLEMENT_PAYEE".equals(c.getStatut())) + .map(c -> c.getMontantPaye() != null ? c.getMontantPaye() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + long total = cotisationsDTO.size(); + long payees = cotisationsDTO.stream().filter(c -> "PAYEE".equals(c.getStatut())).count(); + double taux = total > 0 ? (double) payees / total * 100.0 : 0.0; + + long enAttente = cotisationsDTO.stream().filter(c -> "EN_ATTENTE".equals(c.getStatut())).count(); + BigDecimal montantAttente = cotisationsDTO.stream() + .filter(c -> "EN_ATTENTE".equals(c.getStatut())) + .map(c -> c.getMontantDu() != null ? c.getMontantDu() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + long enRetard = cotisationsDTO.stream().filter(c -> "EN_RETARD".equals(c.getStatut())).count(); + BigDecimal montantImpayes = cotisationsDTO.stream() + .filter(c -> "EN_RETARD".equals(c.getStatut())) + .map(c -> c.getMontantDu() != null ? c.getMontantDu() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + this.periodeActuelle = LocalDate.now().format(DateTimeFormatter.ofPattern("MMMM yyyy")); + this.tauxRecouvrement = new BigDecimal(String.format("%.1f", taux)); + this.totalMembresActifs = (int) total; + this.montantCollecte = formatMontant(totalCollecte); + this.objectifMensuel = formatMontant(totalCollecte.multiply(new BigDecimal("1.15"))); + this.progressionMensuelle = (int) (taux); + this.membresAJour = String.valueOf(payees); + this.pourcentageMembresAJour = (int) taux; + this.montantEnAttente = formatMontant(montantAttente); + this.nombreCotisationsEnAttente = (int) enAttente; + this.montantImpayes = formatMontant(montantImpayes); + this.joursRetardMoyen = 12; // À calculer depuis les dates + this.revenus2024 = formatMontant(totalCollecte.multiply(new BigDecimal("12"))); + this.croissanceAnnuelle = "+15.3%"; // À calculer + this.prelevementsActifs = "0"; + this.montantPrelevementsPrevu = "0"; + this.membresPrelevementActif = 0; + this.montantPrelevementMensuel = "0 FCFA"; + this.prochainPrelevement = LocalDate.now().plusMonths(1).format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); + } catch (Exception e) { + LOGGER.severe("Erreur lors du calcul des KPIs: " + e.getMessage()); + this.periodeActuelle = LocalDate.now().format(DateTimeFormatter.ofPattern("MMMM yyyy")); + this.tauxRecouvrement = BigDecimal.ZERO; + this.totalMembresActifs = 0; + this.montantCollecte = "0 FCFA"; + this.objectifMensuel = "0 FCFA"; + this.progressionMensuelle = 0; + this.membresAJour = "0"; + this.pourcentageMembresAJour = 0; + this.montantEnAttente = "0 FCFA"; + this.nombreCotisationsEnAttente = 0; + this.montantImpayes = "0 FCFA"; + this.joursRetardMoyen = 0; + this.revenus2024 = "0 FCFA"; + this.croissanceAnnuelle = "0%"; + this.prelevementsActifs = "0"; + this.montantPrelevementsPrevu = "0"; + this.membresPrelevementActif = 0; + this.montantPrelevementMensuel = "0 FCFA"; + this.prochainPrelevement = LocalDate.now().plusMonths(1).format(DateTimeFormatter.ofPattern("dd/MM/yyyy")); + } this.cotisationsSelectionnees = new ArrayList<>(); this.montantTotalSelectionne = "0 FCFA"; } + private String formatMontant(BigDecimal montant) { + if (montant == null) return "0 FCFA"; + return String.format("%,.0f FCFA", montant.doubleValue()); + } + private void initializeFiltres() { this.filtres = new FiltresCotisations(); this.listeOrganisations = new ArrayList<>(); - - // Simulation d'organisations - for (int i = 1; i <= 127; i++) { - Organisation org = new Organisation(); - org.setId((long) i); - org.setNom("Organisation " + i); - listeOrganisations.add(org); + try { + List associations = associationService.listerToutes(); + for (AssociationDTO assoc : associations) { + Organisation org = new Organisation(); + org.setId(assoc.getId()); + org.setNom(assoc.getNom()); + listeOrganisations.add(org); + } + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des organisations: " + e.getMessage()); } } private void initializeData() { this.cotisationsFiltrees = new ArrayList<>(); - - // Simulation de données de cotisations pour les 127 organisations - for (int i = 1; i <= 500; i++) { - CotisationAdmin cotisation = new CotisationAdmin(); - cotisation.setId((long) i); - cotisation.setNomOrganisation("Organisation " + ((i % 127) + 1)); - cotisation.setRegionOrganisation("Région " + ((i % 12) + 1)); - cotisation.setIconeOrganisation("pi-building"); - - cotisation.setNomCompletMembre("Membre " + i); - cotisation.setNumeroMembre("M" + String.format("%06d", i)); - cotisation.setInitialesMembre(getInitiales("Membre " + i)); - cotisation.setTypeMembre(i % 3 == 0 ? "Membre Actif" : "Membre Associé"); - - cotisation.setType(getTypeCotisation(i)); - cotisation.setPeriode(getperiode(i)); - cotisation.setAnnee("2024"); - cotisation.setMontant(new BigDecimal(getMontantCotisation(i))); - cotisation.setStatut(getStatutCotisation(i)); - cotisation.setDateEcheance(LocalDate.now().minusDays(i % 60)); - - if (cotisation.getStatut().equals("PAYE")) { - cotisation.setDatePaiement(cotisation.getDateEcheance().plusDays(i % 10)); - cotisation.setModePaiement(getModePaiement(i)); + try { + List cotisationsDTO = cotisationService.listerToutes(0, 1000); + for (CotisationDTO dto : cotisationsDTO) { + CotisationAdmin cotisation = convertToCotisationAdmin(dto); + cotisationsFiltrees.add(cotisation); } - - cotisationsFiltrees.add(cotisation); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des cotisations: " + e.getMessage()); } } + private CotisationAdmin convertToCotisationAdmin(CotisationDTO dto) { + CotisationAdmin cotisation = new CotisationAdmin(); + cotisation.setId(dto.getId()); + cotisation.setNomOrganisation(dto.getNomAssociation()); + cotisation.setNomCompletMembre(dto.getNomMembre()); + cotisation.setNumeroMembre(dto.getNumeroMembre()); + cotisation.setType(dto.getTypeCotisation()); + cotisation.setMontant(dto.getMontantDu()); + cotisation.setStatut(dto.getStatut()); + cotisation.setDateEcheance(dto.getDateEcheance()); + cotisation.setDatePaiement(dto.getDatePaiement() != null ? dto.getDatePaiement().toLocalDate() : null); + cotisation.setModePaiement(dto.getMethodePaiement()); + if (dto.getNomMembre() != null && !dto.getNomMembre().isEmpty()) { + cotisation.setInitialesMembre(getInitiales(dto.getNomMembre())); + } + return cotisation; + } + private void initializeTopOrganisations() { this.topOrganisations = new ArrayList<>(); - - String[] noms = {"Lions Club Dakar Centre", "Association Thiès Nord", "Groupe Kaolack Est", - "Lions Club Saint-Louis", "Association Louga Centre"}; - int[] taux = {98, 95, 92, 89, 87}; - String[] montants = {"485K", "420K", "380K", "365K", "340K"}; - int[] membres = {156, 134, 128, 145, 120}; - int[] totaux = {160, 145, 140, 165, 135}; - - for (int i = 0; i < noms.length; i++) { - OrganisationPerformante org = new OrganisationPerformante(); - org.setNom(noms[i]); - org.setTauxRecouvrement(taux[i]); - org.setMontantCollecte(montants[i]); - org.setNombreMembresAJour(membres[i]); - org.setTotalMembres(totaux[i]); - topOrganisations.add(org); + try { + List associations = associationService.listerActives(); + List cotisationsDTO = cotisationService.listerToutes(0, 1000); + + for (AssociationDTO assoc : associations.stream().limit(5).collect(Collectors.toList())) { + List cotisationsOrg = cotisationsDTO.stream() + .filter(c -> c.getAssociationId() != null && c.getAssociationId().equals(assoc.getId())) + .collect(Collectors.toList()); + + long total = cotisationsOrg.size(); + long payees = cotisationsOrg.stream().filter(c -> "PAYEE".equals(c.getStatut())).count(); + int taux = total > 0 ? (int) ((double) payees / total * 100.0) : 0; + + BigDecimal montantCollecte = cotisationsOrg.stream() + .filter(c -> "PAYEE".equals(c.getStatut()) || "PARTIELLEMENT_PAYEE".equals(c.getStatut())) + .map(c -> c.getMontantPaye() != null ? c.getMontantPaye() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + OrganisationPerformante org = new OrganisationPerformante(); + org.setNom(assoc.getNom()); + org.setTauxRecouvrement(taux); + org.setMontantCollecte(formatMontant(montantCollecte)); + org.setNombreMembresAJour((int) payees); + org.setTotalMembres((int) total); + topOrganisations.add(org); + } + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des top organisations: " + e.getMessage()); } } @@ -217,95 +296,95 @@ public class CotisationsGestionBean implements Serializable { // Actions principales public void creerCampagne() { - System.out.println("Création de la campagne: " + nouvelleCampagne.getNom()); + LOGGER.info("Création de la campagne: " + nouvelleCampagne.getNom()); // Logique de création de campagne initializeNouvelleCampagne(); // Reset pour nouvelle campagne } public void relancesGroupees() { - System.out.println("Envoi de relances groupées"); + LOGGER.info("Envoi de relances groupées"); } public void exporterTout() { - System.out.println("Export global des cotisations"); + LOGGER.info("Export global des cotisations"); } public void appliquerFiltres() { // Logique de filtrage - System.out.println("Application des filtres"); + LOGGER.info("Application des filtres"); } public void reinitialiserFiltres() { this.filtres = new FiltresCotisations(); - System.out.println("Réinitialisation des filtres"); + LOGGER.info("Réinitialisation des filtres"); } public void exporterExcel() { - System.out.println("Export Excel des cotisations filtrées"); + LOGGER.info("Export Excel des cotisations filtrées"); } // Actions sur cotisations individuelles public void enregistrerPaiement(CotisationAdmin cotisation) { - System.out.println("Enregistrement paiement pour: " + cotisation.getNumeroMembre()); + LOGGER.info("Enregistrement paiement pour: " + cotisation.getNumeroMembre()); } public void genererRecu(CotisationAdmin cotisation) { - System.out.println("Génération reçu pour: " + cotisation.getNumeroMembre()); + LOGGER.info("Génération reçu pour: " + cotisation.getNumeroMembre()); } public void envoyerRappel(CotisationAdmin cotisation) { - System.out.println("Envoi rappel pour: " + cotisation.getNumeroMembre()); + LOGGER.info("Envoi rappel pour: " + cotisation.getNumeroMembre()); } public void voirDetails(CotisationAdmin cotisation) { - System.out.println("Affichage détails pour: " + cotisation.getNumeroMembre()); + LOGGER.info("Affichage détails pour: " + cotisation.getNumeroMembre()); } // Actions groupées public void marquerPayeesGroupees() { - System.out.println("Marquage " + cotisationsSelectionnees.size() + " cotisations comme payées"); + LOGGER.info("Marquage " + cotisationsSelectionnees.size() + " cotisations comme payées"); } public void envoyerRelancesGroupees() { - System.out.println("Envoi relances pour " + cotisationsSelectionnees.size() + " cotisations"); + LOGGER.info("Envoi relances pour " + cotisationsSelectionnees.size() + " cotisations"); } public void genererRecusGroupes() { - System.out.println("Génération reçus pour " + cotisationsSelectionnees.size() + " cotisations"); + LOGGER.info("Génération reçus pour " + cotisationsSelectionnees.size() + " cotisations"); } public void annulerCotisationsGroupees() { - System.out.println("Annulation " + cotisationsSelectionnees.size() + " cotisations"); + LOGGER.info("Annulation " + cotisationsSelectionnees.size() + " cotisations"); } // Wave Money public void lancerPrelevements() { - System.out.println("Lancement des prélèvements Wave Money"); + LOGGER.info("Lancement des prélèvements Wave Money"); } public void testerAPIWave() { - System.out.println("Test de l'API Wave Money"); + LOGGER.info("Test de l'API Wave Money"); } public void voirHistoriquePrelevements() { - System.out.println("Affichage historique des prélèvements"); + LOGGER.info("Affichage historique des prélèvements"); } // Actions rapides public void genererRapportMensuel() { - System.out.println("Génération rapport mensuel"); + LOGGER.info("Génération rapport mensuel"); } public void configurerRelancesAuto() { - System.out.println("Configuration relances automatiques"); + LOGGER.info("Configuration relances automatiques"); } public void gererTypesCotisations() { - System.out.println("Gestion des types de cotisations"); + LOGGER.info("Gestion des types de cotisations"); } public void tableauDeBord() { - System.out.println("Affichage tableau de bord"); + LOGGER.info("Affichage tableau de bord"); } // Getters et Setters @@ -415,7 +494,7 @@ public class CotisationsGestionBean implements Serializable { // Classes internes pour les données public static class CotisationAdmin { - private Long id; + private UUID id; private String nomOrganisation; private String regionOrganisation; private String iconeOrganisation; @@ -433,8 +512,8 @@ public class CotisationsGestionBean implements Serializable { private String modePaiement; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNomOrganisation() { return nomOrganisation; } public void setNomOrganisation(String nomOrganisation) { this.nomOrganisation = nomOrganisation; } @@ -633,11 +712,11 @@ public class CotisationsGestionBean implements Serializable { } public static class Organisation { - private Long id; + private UUID id; private String nom; - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DemandesAideBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DemandesAideBean.java index 4fe591a..f8a7c62 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DemandesAideBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DemandesAideBean.java @@ -1,22 +1,33 @@ package dev.lions.unionflow.client.view; +import dev.lions.unionflow.client.dto.DemandeAideDTO; +import dev.lions.unionflow.client.service.DemandeAideService; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; import java.math.BigDecimal; +import java.util.logging.Logger; @Named("demandesAideBean") @SessionScoped public class DemandesAideBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(DemandesAideBean.class.getName()); + + @Inject + @RestClient + private DemandeAideService demandeAideService; private List toutesLesDemandes; private List demandesFiltrees; @@ -46,10 +57,25 @@ public class DemandesAideBean implements Serializable { private void initializeStatistiques() { statistiques = new StatistiquesDemandes(); - statistiques.setTotalDemandes(156); - statistiques.setDemandesEnAttente(23); - statistiques.setDemandesApprouvees(89); - statistiques.setMontantTotalAide("12 850 000 FCFA"); + try { + List demandesDTO = demandeAideService.listerToutes(0, 1000); + statistiques.setTotalDemandes(demandesDTO.size()); + long enAttente = demandesDTO.stream().filter(d -> "EN_ATTENTE".equals(d.getStatut())).count(); + statistiques.setDemandesEnAttente((int) enAttente); + long approuvees = demandesDTO.stream().filter(d -> "APPROUVEE".equals(d.getStatut())).count(); + statistiques.setDemandesApprouvees((int) approuvees); + BigDecimal montantTotal = demandesDTO.stream() + .filter(d -> d.getMontantAccorde() != null) + .map(DemandeAideDTO::getMontantAccorde) + .reduce(BigDecimal.ZERO, BigDecimal::add); + statistiques.setMontantTotalAide(montantTotal.toString() + " FCFA"); + } catch (Exception e) { + LOGGER.severe("Erreur lors du calcul des statistiques: " + e.getMessage()); + statistiques.setTotalDemandes(0); + statistiques.setDemandesEnAttente(0); + statistiques.setDemandesApprouvees(0); + statistiques.setMontantTotalAide("0 FCFA"); + } } private void initializeEtapesWorkflow() { @@ -101,83 +127,49 @@ public class DemandesAideBean implements Serializable { private void initializeDemandes() { toutesLesDemandes = new ArrayList<>(); - String[] demandeurs = { - "Jean Kouassi", "Marie Traoré", "Ahmed Diallo", "Fatou Sanogo", "Paul Ouattara", - "Aissata Koné", "Ibrahim Touré", "Aminata Bakayoko", "Yves Koffi", "Mariam Coulibaly", - "Seydou Cissé", "Adjoa Mensah", "Kwame Asante", "Ama Gyamfi", "Kofi Adjei", - "Nana Akoto", "Akosua Boateng", "Emmanuel Ofori", "Joyce Owusu", "Stephen Asamoah" - }; - - String[] types = { - "AIDE_MEDICALE", "AIDE_ALIMENTAIRE", "AIDE_EDUCATIVE", "AIDE_LOGEMENT", "AIDE_URGENCE" - }; - - String[] statuts = { - "EN_ATTENTE", "EN_EVALUATION", "APPROUVEE", "REJETEE", "EN_COURS", "TERMINEE" - }; - - String[] urgences = { - "FAIBLE", "NORMALE", "ELEVEE", "CRITIQUE" - }; - - String[] localisations = { - "Zone Urbaine Centre", "Quartier Résidentiel Nord", "Zone Rurale Sud", - "Quartier Populaire Est", "Zone Industrielle Ouest", "Centre-Ville", - "Banlieue Nord", "Périphérie Sud", "Zone Commerciale", "Quartier Administratif" - }; - - String[] motifs = { - "Soins médicaux d'urgence", "Aide alimentaire famille nombreuse", "Frais de scolarité", - "Réparation logement suite inondation", "Urgence médicale enfant", "Soutien alimentaire mensuel", - "Achat fournitures scolaires", "Paiement loyer en retard", "Intervention chirurgicale", - "Aide nutritionnelle nourrisson", "Formation professionnelle", "Réhabilitation habitat", - "Traitement médical chronique", "Complément alimentaire", "Équipement scolaire" - }; - - for (int i = 0; i < 50; i++) { - DemandeAide demande = new DemandeAide(); - demande.setId((long) (i + 1)); - demande.setDemandeur(demandeurs[i % demandeurs.length]); - demande.setTelephone("77 123 45 " + String.format("%02d", (i % 99) + 1)); - demande.setEmail(demandeurs[i % demandeurs.length].toLowerCase().replace(" ", ".") + "@email.com"); - demande.setType(types[i % types.length]); - demande.setStatut(statuts[i % statuts.length]); - demande.setUrgence(urgences[i % urgences.length]); - demande.setLocalisation(localisations[i % localisations.length]); - demande.setMotif(motifs[i % motifs.length]); - demande.setDescription("Description détaillée pour " + motifs[i % motifs.length] + ". Situation nécessitant une évaluation approfondie."); - - // Montants - BigDecimal montantBase = new BigDecimal(50000 + (i * 15000)); - demande.setMontantDemande(montantBase); - - if (demande.getStatut().equals("APPROUVEE") || demande.getStatut().equals("EN_COURS") || demande.getStatut().equals("TERMINEE")) { - demande.setMontantAccorde(montantBase.multiply(new BigDecimal("0.8"))); + try { + List demandesDTO = demandeAideService.listerToutes(0, 1000); + for (DemandeAideDTO dto : demandesDTO) { + DemandeAide demande = convertToDemandeAide(dto); + toutesLesDemandes.add(demande); } - - // Dates - demande.setDateDemande(LocalDate.now().minusDays(i + 1)); - if (i % 4 == 0) { - demande.setDateLimite(LocalDate.now().plusDays(7 + (i % 14))); - } - - // Responsable de traitement - if (!demande.getStatut().equals("EN_ATTENTE")) { - String[] responsables = {"Sarah Mensah", "David Konaté", "Grace Asante", "Michel Diallo", "Rita Kouassi"}; - demande.setResponsableTraitement(responsables[i % responsables.length]); - } - - toutesLesDemandes.add(demande); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des demandes d'aide: " + e.getMessage()); } } + private DemandeAide convertToDemandeAide(DemandeAideDTO dto) { + DemandeAide demande = new DemandeAide(); + demande.setId(dto.getId()); + demande.setDemandeur(dto.getDemandeur()); + demande.setTelephone(dto.getTelephone()); + demande.setEmail(dto.getEmail()); + demande.setType(dto.getType()); + demande.setStatut(dto.getStatut()); + demande.setUrgence(dto.getUrgence()); + demande.setLocalisation(dto.getLocalisation()); + demande.setMotif(dto.getMotif() != null ? dto.getMotif() : dto.getTitre()); + demande.setDescription(dto.getDescription()); + demande.setMontantDemande(dto.getMontantDemande()); + demande.setMontantAccorde(dto.getMontantAccorde()); + demande.setDateDemande(dto.getDateDemande()); + demande.setDateLimite(dto.getDateLimite()); + demande.setResponsableTraitement(dto.getResponsableTraitement()); + return demande; + } + private void initializeDemandesPrioritaires() { - demandesPrioritaires = toutesLesDemandes.stream() - .filter(d -> d.getUrgence().equals("CRITIQUE") || d.getUrgence().equals("ELEVEE")) + try { + List demandesDTO = demandeAideService.rechercher("EN_ATTENTE", null, "CRITIQUE", 0, 6); + demandesPrioritaires = demandesDTO.stream() + .map(this::convertToDemandeAide) .filter(d -> !d.getStatut().equals("TERMINEE") && !d.getStatut().equals("REJETEE")) - .sorted((d1, d2) -> d1.getDateDemande().compareTo(d2.getDateDemande())) .limit(6) .collect(Collectors.toList()); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des demandes prioritaires: " + e.getMessage()); + demandesPrioritaires = new ArrayList<>(); + } } private void initializeNouvelleDemande() { @@ -250,7 +242,7 @@ public class DemandesAideBean implements Serializable { public void creerDemande() { DemandeAide nouvelleDem = new DemandeAide(); - nouvelleDem.setId((long) (toutesLesDemandes.size() + 1)); + nouvelleDem.setId(UUID.randomUUID()); nouvelleDem.setDemandeur(nouvelleDemande.getDemandeur()); nouvelleDem.setTelephone(nouvelleDemande.getTelephone()); nouvelleDem.setEmail(nouvelleDemande.getEmail()); @@ -268,7 +260,7 @@ public class DemandesAideBean implements Serializable { appliquerFiltres(); initializeDemandesPrioritaires(); - System.out.println("Nouvelle demande d'aide créée pour: " + nouvelleDem.getDemandeur()); + LOGGER.info("Nouvelle demande d'aide créée pour: " + nouvelleDem.getDemandeur()); initializeNouvelleDemande(); } @@ -278,7 +270,7 @@ public class DemandesAideBean implements Serializable { if (demandeSelectionnee.getMontantAccorde() == null) { demandeSelectionnee.setMontantAccorde(demandeSelectionnee.getMontantDemande().multiply(new BigDecimal("0.8"))); } - System.out.println("Demande approuvée pour: " + demandeSelectionnee.getDemandeur()); + LOGGER.info("Demande approuvée pour: " + demandeSelectionnee.getDemandeur()); appliquerFiltres(); initializeDemandesPrioritaires(); } @@ -287,7 +279,7 @@ public class DemandesAideBean implements Serializable { public void rejeterDemande() { if (demandeSelectionnee != null) { demandeSelectionnee.setStatut("REJETEE"); - System.out.println("Demande rejetée pour: " + demandeSelectionnee.getDemandeur()); + LOGGER.info("Demande rejetée pour: " + demandeSelectionnee.getDemandeur()); appliquerFiltres(); initializeDemandesPrioritaires(); } @@ -298,13 +290,13 @@ public class DemandesAideBean implements Serializable { } public void envoyerNotification() { - System.out.println("Notification envoyée pour la demande de: " + demandeSelectionnee.getDemandeur()); + LOGGER.info("Notification envoyée pour la demande de: " + demandeSelectionnee.getDemandeur()); } public void dupliquerDemande() { if (demandeSelectionnee != null) { DemandeAide copie = new DemandeAide(); - copie.setId((long) (toutesLesDemandes.size() + 1)); + copie.setId(UUID.randomUUID()); copie.setDemandeur(demandeSelectionnee.getDemandeur()); copie.setTelephone(demandeSelectionnee.getTelephone()); copie.setEmail(demandeSelectionnee.getEmail()); @@ -319,12 +311,12 @@ public class DemandesAideBean implements Serializable { toutesLesDemandes.add(copie); appliquerFiltres(); - System.out.println("Demande dupliquée pour: " + copie.getDemandeur()); + LOGGER.info("Demande dupliquée pour: " + copie.getDemandeur()); } } public void exporterDemandes() { - System.out.println("Export de " + demandesFiltrees.size() + " demandes d'aide"); + LOGGER.info("Export de " + demandesFiltrees.size() + " demandes d'aide"); } // Getters et Setters @@ -357,7 +349,7 @@ public class DemandesAideBean implements Serializable { // Classes internes public static class DemandeAide { - private Long id; + private UUID id; private String demandeur; private String telephone; private String email; @@ -374,8 +366,8 @@ public class DemandesAideBean implements Serializable { private String responsableTraitement; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getDemandeur() { return demandeur; } public void setDemandeur(String demandeur) { this.demandeur = demandeur; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DemandesBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DemandesBean.java index a4e4d60..34a6970 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DemandesBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DemandesBean.java @@ -10,13 +10,16 @@ import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; +import java.util.logging.Logger; @Named("demandeBean") @SessionScoped public class DemandesBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(DemandesBean.class.getName()); private List demandes; private List selectedDemandes; @@ -35,7 +38,7 @@ public class DemandesBean implements Serializable { private LocalDate dateFilter; // Assignation en lot - private Long gestionnaireAssignation; + private UUID gestionnaireAssignation; private String commentaireAssignation; // Statistiques @@ -68,7 +71,7 @@ public class DemandesBean implements Serializable { for (int i = 0; i < objets.length; i++) { Demande demande = new Demande(); - demande.setId((long) (i + 1)); + demande.setId(UUID.fromString(String.format("00000000-0000-0000-0000-%012d", i + 1))); demande.setReference("DEM-2024-" + String.format("%04d", i + 1)); demande.setObjet(objets[i]); demande.setType(types[i]); @@ -97,9 +100,9 @@ public class DemandesBean implements Serializable { private void initializeGestionnaires() { gestionnairesDisponibles = new ArrayList<>(); - gestionnairesDisponibles.add(new Gestionnaire(1L, "Marie Gestionnaire")); - gestionnairesDisponibles.add(new Gestionnaire(2L, "Paul Superviseur")); - gestionnairesDisponibles.add(new Gestionnaire(3L, "Fatou Responsable")); + gestionnairesDisponibles.add(new Gestionnaire(UUID.fromString("00000000-0000-0000-0000-000000000500"), "Marie Gestionnaire")); + gestionnairesDisponibles.add(new Gestionnaire(UUID.fromString("00000000-0000-0000-0000-000000000600"), "Paul Superviseur")); + gestionnairesDisponibles.add(new Gestionnaire(UUID.fromString("00000000-0000-0000-0000-000000000700"), "Fatou Responsable")); } private void initializeNouvelleDemande() { @@ -115,7 +118,7 @@ public class DemandesBean implements Serializable { for (int i = 0; i < noms.length; i++) { if (noms[i].toLowerCase().contains(query.toLowerCase())) { Membre membre = new Membre(); - membre.setId((long) (i + 1)); + membre.setId(UUID.fromString(String.format("00000000-0000-0000-0000-%012d", i + 1))); membre.setNomComplet(noms[i]); membre.setNumeroMembre("M" + String.format("%06d", 1000 + i)); resultats.add(membre); @@ -128,60 +131,60 @@ public class DemandesBean implements Serializable { // Actions public void voirDemande(Demande demande) { this.demandeSelectionnee = demande; - System.out.println("Voir demande: " + demande.getObjet()); + LOGGER.info("Voir demande: " + demande.getObjet()); } public void traiterDemande(Demande demande) { demande.setStatut("EN_COURS"); - System.out.println("Traitement demande: " + demande.getObjet()); + LOGGER.info("Traitement demande: " + demande.getObjet()); } public void approuverDemande(Demande demande) { demande.setStatut("APPROUVEE"); - System.out.println("Demande approuvée: " + demande.getObjet()); + LOGGER.info("Demande approuvée: " + demande.getObjet()); } public void rejeterDemande(Demande demande) { demande.setStatut("REJETEE"); - System.out.println("Demande rejetée: " + demande.getObjet()); + LOGGER.info("Demande rejetée: " + demande.getObjet()); } public void assignerDemande(Demande demande) { - System.out.println("Assigner demande: " + demande.getObjet()); + LOGGER.info("Assigner demande: " + demande.getObjet()); } public void voirPiecesJointes(Demande demande) { - System.out.println("Voir pièces jointes: " + demande.getObjet()); + LOGGER.info("Voir pièces jointes: " + demande.getObjet()); } public void creerDemande() { - System.out.println("Créer nouvelle demande: " + nouvelleDemande.getObjet()); + LOGGER.info("Créer nouvelle demande: " + nouvelleDemande.getObjet()); initializeNouvelleDemande(); } public void effectuerAssignationLot() { - System.out.println("Assignation en lot à gestionnaire ID: " + gestionnaireAssignation); + LOGGER.info("Assignation en lot à gestionnaire ID: " + gestionnaireAssignation); } public void marquerTraitees() { selectedDemandes.forEach(d -> d.setStatut("TRAITEE")); - System.out.println("Marquées comme traitées: " + selectedDemandes.size()); + LOGGER.info("Marquées comme traitées: " + selectedDemandes.size()); } public void exporterSelection() { - System.out.println("Export de " + selectedDemandes.size() + " demandes"); + LOGGER.info("Export de " + selectedDemandes.size() + " demandes"); } public void exporterDemandes() { - System.out.println("Export de toutes les demandes"); + LOGGER.info("Export de toutes les demandes"); } public void actualiser() { - System.out.println("Actualisation des données"); + LOGGER.info("Actualisation des données"); } public void filtrerUrgentes() { - System.out.println("Filtrer les demandes urgentes"); + LOGGER.info("Filtrer les demandes urgentes"); } // Getters et Setters @@ -221,8 +224,8 @@ public class DemandesBean implements Serializable { public LocalDate getDateFilter() { return dateFilter; } public void setDateFilter(LocalDate dateFilter) { this.dateFilter = dateFilter; } - public Long getGestionnaireAssignation() { return gestionnaireAssignation; } - public void setGestionnaireAssignation(Long gestionnaireAssignation) { this.gestionnaireAssignation = gestionnaireAssignation; } + public UUID getGestionnaireAssignation() { return gestionnaireAssignation; } + public void setGestionnaireAssignation(UUID gestionnaireAssignation) { this.gestionnaireAssignation = gestionnaireAssignation; } public String getCommentaireAssignation() { return commentaireAssignation; } public void setCommentaireAssignation(String commentaireAssignation) { this.commentaireAssignation = commentaireAssignation; } @@ -244,7 +247,7 @@ public class DemandesBean implements Serializable { // Classes internes public static class Demande { - private Long id; + private UUID id; private String reference; private String objet; private String type; @@ -261,8 +264,8 @@ public class DemandesBean implements Serializable { private boolean hasPiecesJointes = false; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getReference() { return reference; } public void setReference(String reference) { this.reference = reference; } @@ -396,12 +399,12 @@ public class DemandesBean implements Serializable { } public static class Membre { - private Long id; + private UUID id; private String nomComplet; private String numeroMembre; - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNomComplet() { return nomComplet; } public void setNomComplet(String nomComplet) { this.nomComplet = nomComplet; } @@ -422,7 +425,7 @@ public class DemandesBean implements Serializable { private String priorite; private String description; private LocalDate dateEcheance; - private Long assigneA; + private UUID assigneA; public String getObjet() { return objet; } public void setObjet(String objet) { this.objet = objet; } @@ -439,23 +442,23 @@ public class DemandesBean implements Serializable { public LocalDate getDateEcheance() { return dateEcheance; } public void setDateEcheance(LocalDate dateEcheance) { this.dateEcheance = dateEcheance; } - public Long getAssigneA() { return assigneA; } - public void setAssigneA(Long assigneA) { this.assigneA = assigneA; } + public UUID getAssigneA() { return assigneA; } + public void setAssigneA(UUID assigneA) { this.assigneA = assigneA; } } public static class Gestionnaire { - private Long id; + private UUID id; private String nom; public Gestionnaire() {} - public Gestionnaire(Long id, String nom) { + public Gestionnaire(UUID id, String nom) { this.id = id; this.nom = nom; } - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DocumentsBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DocumentsBean.java index 2148b07..2915145 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DocumentsBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DocumentsBean.java @@ -10,6 +10,8 @@ import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; +import java.util.UUID; +import java.util.logging.Logger; import java.util.stream.Collectors; @Named("documentsBean") @@ -17,6 +19,7 @@ import java.util.stream.Collectors; public class DocumentsBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(DocumentsBean.class.getName()); private List tousLesDocuments; private List documentsFiltres; @@ -32,7 +35,7 @@ public class DocumentsBean implements Serializable { private StatistiquesDocuments statistiques; private String modeAffichage = "GRID"; // GRID ou LIST - private Long dossierActuelId; + private UUID dossierActuelId; @PostConstruct public void init() { @@ -52,94 +55,33 @@ public class DocumentsBean implements Serializable { private void initializeStatistiques() { statistiques = new StatistiquesDocuments(); - statistiques.setTotalDocuments(1847); - statistiques.setTotalDossiers(23); - statistiques.setEspaceUtilise("2.3 GB"); - statistiques.setPartagesMois(156); + try { + // Les statistiques seront calculées depuis les documents réels + // Pour l'instant, initialiser avec des valeurs par défaut + statistiques.setTotalDocuments(tousLesDocuments != null ? tousLesDocuments.size() : 0); + statistiques.setTotalDossiers(dossiersDisponibles != null ? dossiersDisponibles.size() : 0); + statistiques.setEspaceUtilise("0 GB"); + statistiques.setPartagesMois(0); + } catch (Exception e) { + LOGGER.severe("Erreur lors du calcul des statistiques: " + e.getMessage()); + statistiques.setTotalDocuments(0); + statistiques.setTotalDossiers(0); + statistiques.setEspaceUtilise("0 GB"); + statistiques.setPartagesMois(0); + } } private void initializeDossiers() { dossiersAffichage = new ArrayList<>(); dossiersDisponibles = new ArrayList<>(); - - String[] nomsDossiers = { - "Documents Administratifs", "Finances et Comptabilité", "Ressources Humaines", - "Communication", "Formations", "Projets et Actions", "Archives 2023", - "Modèles et Templates", "Rapports Mensuels", "Juridique et Conformité" - }; - - String[] couleurs = { - "blue-500", "green-500", "orange-500", "purple-500", "indigo-500", - "teal-500", "gray-500", "pink-500", "yellow-500", "red-500" - }; - - for (int i = 0; i < nomsDossiers.length; i++) { - Dossier dossier = new Dossier(); - dossier.setId((long) (i + 1)); - dossier.setNom(nomsDossiers[i]); - dossier.setCouleur(couleurs[i % couleurs.length]); - dossier.setNombreDocuments(15 + (i * 8)); - dossier.setDerniereModification(LocalDateTime.now().minusDays(i + 1)); - dossier.setCheminComplet("/" + nomsDossiers[i]); - - dossiersAffichage.add(dossier); - dossiersDisponibles.add(dossier); - } + // Les dossiers seront chargés depuis l'API backend + // Pour l'instant, laisser les listes vides plutôt que des données mockées } private void initializeDocuments() { tousLesDocuments = new ArrayList<>(); - - String[] noms = { - "Règlement Intérieur 2024.pdf", "Budget Prévisionnel Q1.xlsx", "Procès-Verbal AG Mars.docx", - "Guide Nouveau Membre.pdf", "Rapport Activités Janvier.docx", "Factures Fournisseurs Q4.xlsx", - "Statuts Association.pdf", "Plan Communication 2024.pptx", "Formation Leadership.pdf", - "Rapport Financier Annuel.pdf", "Convention Partenariat.docx", "Charte Graphique.pdf", - "Manuel Procédures.docx", "Bilan Social 2023.xlsx", "Certificat Conformité.pdf", - "Guide Utilisateur Plateforme.pdf", "Contrat Assurance.pdf", "Rapport Audit.docx", - "Plan Stratégique 3 ans.pptx", "Inventaire Matériel.xlsx", "Politique RGPD.pdf" - }; - - String[] types = {"PDF", "EXCEL", "WORD", "PDF", "WORD", "EXCEL", "PDF", "POWERPOINT", "PDF", "PDF", "WORD", "PDF", "WORD", "EXCEL", "PDF", "PDF", "PDF", "WORD", "POWERPOINT", "EXCEL", "PDF"}; - String[] categories = {"ADMINISTRATIF", "FINANCIER", "ADMINISTRATIF", "FORMATION", "ADMINISTRATIF", "FINANCIER", "JURIDIQUE", "COMMUNICATION", "FORMATION", "FINANCIER", "JURIDIQUE", "COMMUNICATION", "ADMINISTRATIF", "FINANCIER", "JURIDIQUE", "FORMATION", "JURIDIQUE", "FINANCIER", "ADMINISTRATIF", "ADMINISTRATIF", "JURIDIQUE"}; - String[] statuts = {"VALIDE", "VALIDE", "BROUILLON", "VALIDE", "VALIDE", "ARCHIVE", "VALIDE", "BROUILLON", "VALIDE", "VALIDE", "VALIDE", "VALIDE", "BROUILLON", "ARCHIVE", "VALIDE", "VALIDE", "VALIDE", "VALIDE", "BROUILLON", "VALIDE", "VALIDE"}; - String[] auteurs = {"Marie Kouassi", "Paul Traoré", "Fatou Sanogo", "Jean Ouattara", "Aissata Koné", "Ibrahim Touré", "Aminata Bakayoko", "Yves Koffi", "Mariam Coulibaly", "Seydou Cissé", "Adjoa Mensah"}; - - long[] tailles = {2047000, 845000, 1250000, 3100000, 890000, 1450000, 567000, 2800000, 1900000, 3400000, 780000, 1200000, 1850000, 920000, 450000, 2200000, 890000, 1650000, 4200000, 680000, 750000}; - - for (int i = 0; i < noms.length; i++) { - Document document = new Document(); - document.setId((long) (i + 1)); - document.setNom(noms[i]); - document.setType(types[i]); - document.setCategorie(categories[i]); - document.setStatut(statuts[i]); - document.setAuteur(auteurs[i % auteurs.length]); - document.setTailleBytes(tailles[i]); - document.setDateCreation(LocalDateTime.now().minusDays(i * 3 + 1)); - document.setDateModification(LocalDateTime.now().minusDays(i + 1)); - document.setNombreVues(25 + (i * 7)); - document.setNombreTelecharements(5 + (i * 2)); - - // Description automatique - document.setDescription("Document " + categories[i].toLowerCase() + " - " + noms[i]); - - // Mots-clés automatiques - document.setMotsCles(generateMotsCles(categories[i], types[i])); - - // Dossier parent (certains documents sont à la racine) - if (i % 3 != 0) { - document.setDossierId((long) ((i % dossiersDisponibles.size()) + 1)); - } - - tousLesDocuments.add(document); - } - } - - private String generateMotsCles(String categorie, String type) { - String base = categorie.toLowerCase().replace("_", " "); - String typeClean = type.toLowerCase(); - return base + ", " + typeClean + ", officiel, important"; + // Les documents seront chargés depuis l'API backend + // Pour l'instant, laisser la liste vide plutôt que des données mockées } private void initializeNouveauDocument() { @@ -270,7 +212,7 @@ public class DocumentsBean implements Serializable { public void telechargerNouveauDocument() { Document nouveau = new Document(); - nouveau.setId((long) (tousLesDocuments.size() + 1)); + nouveau.setId(UUID.randomUUID()); nouveau.setNom("Nouveau Document " + (tousLesDocuments.size() + 1)); nouveau.setCategorie(nouveauDocument.getCategorie()); nouveau.setDescription(nouveauDocument.getDescription()); @@ -288,25 +230,25 @@ public class DocumentsBean implements Serializable { tousLesDocuments.add(nouveau); appliquerFiltres(); - System.out.println("Document téléchargé: " + nouveau.getNom()); + LOGGER.info("Document téléchargé: " + nouveau.getNom()); initializeNouveauDocument(); } public void telechargerDocument(Document document) { document.setNombreTelecharements(document.getNombreTelecharements() + 1); - System.out.println("Téléchargement du document: " + document.getNom()); + LOGGER.info("Téléchargement du document: " + document.getNom()); } public void supprimerDocument(Document document) { tousLesDocuments.remove(document); appliquerFiltres(); - System.out.println("Document supprimé: " + document.getNom()); + LOGGER.info("Document supprimé: " + document.getNom()); } public void dupliquerDocument() { if (documentSelectionne != null) { Document copie = new Document(); - copie.setId((long) (tousLesDocuments.size() + 1)); + copie.setId(UUID.randomUUID()); copie.setNom(documentSelectionne.getNom() + " (Copie)"); copie.setType(documentSelectionne.getType()); copie.setCategorie(documentSelectionne.getCategorie()); @@ -323,14 +265,14 @@ public class DocumentsBean implements Serializable { tousLesDocuments.add(copie); appliquerFiltres(); - System.out.println("Document dupliqué: " + copie.getNom()); + LOGGER.info("Document dupliqué: " + copie.getNom()); } } public void archiverDocument() { if (documentSelectionne != null) { documentSelectionne.setStatut("ARCHIVE"); - System.out.println("Document archivé: " + documentSelectionne.getNom()); + LOGGER.info("Document archivé: " + documentSelectionne.getNom()); appliquerFiltres(); } } @@ -339,7 +281,7 @@ public class DocumentsBean implements Serializable { if (documentSelectionne != null) { tousLesDocuments.remove(documentSelectionne); appliquerFiltres(); - System.out.println("Document supprimé définitivement: " + documentSelectionne.getNom()); + LOGGER.info("Document supprimé définitivement: " + documentSelectionne.getNom()); } } @@ -396,12 +338,12 @@ public class DocumentsBean implements Serializable { public String getModeAffichage() { return modeAffichage; } public void setModeAffichage(String modeAffichage) { this.modeAffichage = modeAffichage; } - public Long getDossierActuelId() { return dossierActuelId; } - public void setDossierActuelId(Long dossierActuelId) { this.dossierActuelId = dossierActuelId; } + public UUID getDossierActuelId() { return dossierActuelId; } + public void setDossierActuelId(UUID dossierActuelId) { this.dossierActuelId = dossierActuelId; } // Classes internes public static class Document { - private Long id; + private UUID id; private String nom; private String description; private String type; @@ -409,7 +351,7 @@ public class DocumentsBean implements Serializable { private String statut; private String auteur; private String motsCles; - private Long dossierId; + private UUID dossierId; private long tailleBytes; private LocalDateTime dateCreation; private LocalDateTime dateModification; @@ -418,8 +360,8 @@ public class DocumentsBean implements Serializable { private boolean accesRestreint; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } @@ -442,8 +384,8 @@ public class DocumentsBean implements Serializable { public String getMotsCles() { return motsCles; } public void setMotsCles(String motsCles) { this.motsCles = motsCles; } - public Long getDossierId() { return dossierId; } - public void setDossierId(Long dossierId) { this.dossierId = dossierId; } + public UUID getDossierId() { return dossierId; } + public void setDossierId(UUID dossierId) { this.dossierId = dossierId; } public long getTailleBytes() { return tailleBytes; } public void setTailleBytes(long tailleBytes) { this.tailleBytes = tailleBytes; } @@ -557,7 +499,7 @@ public class DocumentsBean implements Serializable { } public static class Dossier { - private Long id; + private UUID id; private String nom; private String couleur; private int nombreDocuments; @@ -565,8 +507,8 @@ public class DocumentsBean implements Serializable { private String cheminComplet; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } @@ -596,7 +538,7 @@ public class DocumentsBean implements Serializable { private String categorie; private String description; private String motsCles; - private Long dossierId; + private UUID dossierId; private boolean accesRestreint; // Getters et setters @@ -609,8 +551,8 @@ public class DocumentsBean implements Serializable { public String getMotsCles() { return motsCles; } public void setMotsCles(String motsCles) { this.motsCles = motsCles; } - public Long getDossierId() { return dossierId; } - public void setDossierId(Long dossierId) { this.dossierId = dossierId; } + public UUID getDossierId() { return dossierId; } + public void setDossierId(UUID dossierId) { this.dossierId = dossierId; } public boolean isAccesRestreint() { return accesRestreint; } public void setAccesRestreint(boolean accesRestreint) { this.accesRestreint = accesRestreint; } @@ -678,13 +620,13 @@ public class DocumentsBean implements Serializable { public static class NiveauNavigation { private String nom; - private Long dossierId; + private UUID dossierId; // Getters et setters public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } - public Long getDossierId() { return dossierId; } - public void setDossierId(Long dossierId) { this.dossierId = dossierId; } + public UUID getDossierId() { return dossierId; } + public void setDossierId(UUID dossierId) { this.dossierId = dossierId; } } } \ No newline at end of file diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EntitesGestionBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EntitesGestionBean.java index 1a3b302..b491efe 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EntitesGestionBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EntitesGestionBean.java @@ -1,8 +1,12 @@ package dev.lions.unionflow.client.view; +import dev.lions.unionflow.client.dto.AssociationDTO; +import dev.lions.unionflow.client.service.AssociationService; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; import java.time.LocalDate; import java.time.LocalDateTime; @@ -10,13 +14,20 @@ import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; +import java.util.logging.Logger; @Named("entitesGestionBean") @SessionScoped public class EntitesGestionBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(EntitesGestionBean.class.getName()); + + @Inject + @RestClient + private AssociationService associationService; private List toutesLesEntites; private List entitesFiltrees; @@ -42,102 +53,84 @@ public class EntitesGestionBean implements Serializable { private void initializeStatistiques() { statistiques = new Statistiques(); - statistiques.setTotalEntites(127); // Nouvelle stratégie volume - statistiques.setEntitesActives(127); - statistiques.setTotalMembres(18547); // 146 membres/organisation en moyenne - statistiques.setMoyenneMembresParEntite(146); // Moyenne calculée - statistiques.setRevenus("363 000 FCFA"); - statistiques.setSouscriptionsExpirantes(12); - statistiques.setEntitesQuotaAtteint(8); - statistiques.setFormulairePopulaire("Standard"); - statistiques.setTauxRenouvellement(94.2f); - - // Calcul dynamique des statistiques de souscription + try { + List associations = associationService.listerToutes(); + statistiques.setTotalEntites(associations.size()); + long actives = associations.stream().filter(a -> "ACTIVE".equals(a.getStatut())).count(); + statistiques.setEntitesActives((int) actives); + int totalMembres = associations.stream() + .mapToInt(a -> a.getNombreMembres() != null ? a.getNombreMembres() : 0) + .sum(); + statistiques.setTotalMembres(totalMembres); + double moyenne = associations.isEmpty() ? 0 : (double) totalMembres / associations.size(); + statistiques.setMoyenneMembresParEntite((int) moyenne); + statistiques.setRevenus("0 FCFA"); // À calculer depuis les souscriptions + statistiques.setSouscriptionsExpirantes(0); // À calculer + statistiques.setEntitesQuotaAtteint(0); // À calculer + statistiques.setFormulairePopulaire("Standard"); + statistiques.setTauxRenouvellement(94.2f); + } catch (Exception e) { + LOGGER.severe("Erreur lors du calcul des statistiques: " + e.getMessage()); + statistiques.setTotalEntites(0); + statistiques.setEntitesActives(0); + statistiques.setTotalMembres(0); + statistiques.setMoyenneMembresParEntite(0); + } calculerStatistiquesSouscriptions(); } private void initializeEntites() { toutesLesEntites = new ArrayList<>(); - - // Génération de données de test - String[] noms = { - "Association Alpha Centrale", "Club Beta Régional", "Groupe Gamma Local", - "Association Delta Nord", "Club Epsilon Sud", "Groupe Zeta Jeunes", - "Association Eta Ouest", "Club Theta Est", "Groupe Iota Centre", - "Association Kappa Métropole", "Branche Féminine Lambda", "Club Mu Urbain", - "Groupe Jeunes Nu", "Association Xi Rural", "Club Omicron Mixte" - }; - - String[] types = { - "ASSOCIATION", "CLUB", "GROUPE", "ASSOCIATION", "CLUB", "GROUPE_JEUNES", - "ASSOCIATION", "CLUB", "GROUPE", "ASSOCIATION", "BRANCHE", "CLUB", - "GROUPE_JEUNES", "ASSOCIATION", "CLUB" - }; - - String[] regions = { - "REGION_1", "REGION_2", "REGION_3", "REGION_4", "REGION_5", "REGION_1", - "REGION_6", "REGION_7", "REGION_8", "REGION_9", "REGION_1", "REGION_10", - "REGION_2", "REGION_11", "REGION_12" - }; - - String[] statuts = { - "ACTIVE", "ACTIVE", "ACTIVE", "ACTIVE", "ACTIVE", "ACTIVE", - "ACTIVE", "SUSPENDUE", "ACTIVE", "ACTIVE", "ACTIVE", "INACTIVE", - "ACTIVE", "ACTIVE", "ACTIVE" - }; - - int[] nombresMembres = {156, 123, 98, 87, 73, 45, 67, 0, 54, 43, 32, 0, 28, 38, 51}; - - for (int i = 0; i < noms.length; i++) { - Entite entite = new Entite(); - entite.setId((long) (i + 1)); - entite.setNom(noms[i]); - entite.setCodeEntite("ENT" + String.format("%03d", i + 1)); - entite.setType(types[i]); - entite.setRegion(regions[i]); - entite.setStatut(statuts[i]); - entite.setNombreMembres(nombresMembres[i]); - entite.setMembresUtilises(nombresMembres[i]); - entite.setAdresse("Adresse " + noms[i]); - entite.setTelephone("77 123 45 " + String.format("%02d", i + 1)); - entite.setEmail(noms[i].toLowerCase().replace(" ", ".") + "@unionflow.app"); - entite.setDescription("Description de " + noms[i]); - entite.setDerniereActivite(LocalDateTime.now().minusDays(i * 2 + 1)); - - // Définir le forfait selon le nombre de membres - if (nombresMembres[i] <= 100) { - entite.setForfaitSouscrit("Starter"); - entite.setMembresQuota(100); - entite.setMontantMensuel("2 000 FCFA"); - } else if (nombresMembres[i] <= 200) { - entite.setForfaitSouscrit("Standard"); - entite.setMembresQuota(200); - entite.setMontantMensuel("3 000 FCFA"); - } else if (nombresMembres[i] <= 500) { - entite.setForfaitSouscrit("Premium"); - entite.setMembresQuota(500); - entite.setMontantMensuel("4 000 FCFA"); - } else { - entite.setForfaitSouscrit("Cristal"); - entite.setMembresQuota(2000); - entite.setMontantMensuel("5 000 FCFA"); + try { + List associations = associationService.listerToutes(); + for (AssociationDTO dto : associations) { + Entite entite = convertToEntite(dto); + toutesLesEntites.add(entite); } - - // Date d'expiration (varie entre 1 mois et 11 mois) - entite.setDateExpirationSouscription(LocalDate.now().plusMonths(1 + (i % 11))); - - // Administrateur - if (nombresMembres[i] > 0) { - Administrateur admin = new Administrateur(); - admin.setNomComplet("Admin " + (i + 1)); - admin.setEmail("admin" + (i + 1) + "@unionflow.app"); - entite.setAdministrateur(admin); - } - - toutesLesEntites.add(entite); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des entités: " + e.getMessage()); } } + private Entite convertToEntite(AssociationDTO dto) { + Entite entite = new Entite(); + entite.setId(dto.getId()); + entite.setNom(dto.getNom()); + entite.setCodeEntite(dto.getNumeroRegistre()); + entite.setType(dto.getTypeAssociation()); + entite.setRegion(dto.getRegion()); + entite.setStatut(dto.getStatut()); + entite.setNombreMembres(dto.getNombreMembres() != null ? dto.getNombreMembres() : 0); + entite.setMembresUtilises(dto.getNombreMembres() != null ? dto.getNombreMembres() : 0); + entite.setAdresse(dto.getAdresse()); + entite.setTelephone(dto.getTelephone()); + entite.setEmail(dto.getEmail()); + entite.setDescription(dto.getDescription()); + entite.setDerniereActivite(dto.getDateDerniereActivite()); + + // Définir le forfait selon le nombre de membres + int nbMembres = dto.getNombreMembres() != null ? dto.getNombreMembres() : 0; + if (nbMembres <= 100) { + entite.setForfaitSouscrit("Starter"); + entite.setMembresQuota(100); + entite.setMontantMensuel("2 000 FCFA"); + } else if (nbMembres <= 200) { + entite.setForfaitSouscrit("Standard"); + entite.setMembresQuota(200); + entite.setMontantMensuel("3 000 FCFA"); + } else if (nbMembres <= 500) { + entite.setForfaitSouscrit("Premium"); + entite.setMembresQuota(500); + entite.setMontantMensuel("4 000 FCFA"); + } else { + entite.setForfaitSouscrit("Cristal"); + entite.setMembresQuota(2000); + entite.setMontantMensuel("5 000 FCFA"); + } + + return entite; + } + private void initializeNouvelleEntite() { nouvelleEntite = new Entite(); } @@ -229,7 +222,7 @@ public class EntitesGestionBean implements Serializable { } public void creerEntite() { - nouvelleEntite.setId((long) (toutesLesEntites.size() + 1)); + nouvelleEntite.setId(UUID.randomUUID()); nouvelleEntite.setCodeEntite("ENT" + String.format("%03d", toutesLesEntites.size() + 1)); nouvelleEntite.setStatut("ACTIVE"); nouvelleEntite.setNombreMembres(0); @@ -238,7 +231,7 @@ public class EntitesGestionBean implements Serializable { toutesLesEntites.add(nouvelleEntite); appliquerFiltres(); - System.out.println("Nouvelle entité créée: " + nouvelleEntite.getNom()); + LOGGER.info("Nouvelle entité créée: " + nouvelleEntite.getNom()); initializeNouvelleEntite(); } @@ -257,24 +250,24 @@ public class EntitesGestionBean implements Serializable { public void suspendreEntite() { entiteSelectionne.setStatut("SUSPENDUE"); - System.out.println("Entité suspendue: " + entiteSelectionne.getNom()); + LOGGER.info("Entité suspendue: " + entiteSelectionne.getNom()); appliquerFiltres(); } public void reactiverEntite() { entiteSelectionne.setStatut("ACTIVE"); - System.out.println("Entité réactivée: " + entiteSelectionne.getNom()); + LOGGER.info("Entité réactivée: " + entiteSelectionne.getNom()); appliquerFiltres(); } public void supprimerEntite() { toutesLesEntites.remove(entiteSelectionne); - System.out.println("Entité supprimée: " + entiteSelectionne.getNom()); + LOGGER.info("Entité supprimée: " + entiteSelectionne.getNom()); appliquerFiltres(); } public void exporterEntites() { - System.out.println("Export de " + entitesFiltrees.size() + " entités"); + LOGGER.info("Export de " + entitesFiltrees.size() + " entités"); } // Getters et Setters @@ -325,7 +318,7 @@ public class EntitesGestionBean implements Serializable { if (entiteSelectionne != null) { entiteSelectionne.setDateExpirationSouscription(LocalDate.now().plusMonths(12)); entiteSelectionne.setStatutSouscription("ACTIVE"); - System.out.println("Souscription renouvelée pour: " + entiteSelectionne.getNom()); + LOGGER.info("Souscription renouvelée pour: " + entiteSelectionne.getNom()); appliquerFiltres(); } } @@ -350,24 +343,24 @@ public class EntitesGestionBean implements Serializable { entiteSelectionne.setMontantMensuel("5 000 FCFA"); break; } - System.out.println("Forfait upgradé pour: " + entiteSelectionne.getNom()); + LOGGER.info("Forfait upgradé pour: " + entiteSelectionne.getNom()); appliquerFiltres(); } } public void gererQuotas() { - System.out.println("Gestion des quotas pour toutes les entités"); + LOGGER.info("Gestion des quotas pour toutes les entités"); } public void envoyerRelancesSouscriptions() { int compteur = 0; for (Entite entite : toutesLesEntites) { if (entite.isExpirationProche()) { - System.out.println("Relance envoyée à: " + entite.getNom()); + LOGGER.info("Relance envoyée à: " + entite.getNom()); compteur++; } } - System.out.println(compteur + " relances de souscription envoyées"); + LOGGER.info(compteur + " relances de souscription envoyées"); } // Actions groupées @@ -378,7 +371,7 @@ public class EntitesGestionBean implements Serializable { entite.setStatutSouscription("ACTIVE"); compteur++; } - System.out.println(compteur + " souscriptions renouvelées en masse"); + LOGGER.info(compteur + " souscriptions renouvelées en masse"); entitesSelectionnees.clear(); appliquerFiltres(); } @@ -389,7 +382,7 @@ public class EntitesGestionBean implements Serializable { entite.setStatut("SUSPENDUE"); compteur++; } - System.out.println(compteur + " entités suspendues en masse"); + LOGGER.info(compteur + " entités suspendues en masse"); entitesSelectionnees.clear(); appliquerFiltres(); } @@ -400,7 +393,7 @@ public class EntitesGestionBean implements Serializable { entite.setStatut("ACTIVE"); compteur++; } - System.out.println(compteur + " entités réactivées en masse"); + LOGGER.info(compteur + " entités réactivées en masse"); entitesSelectionnees.clear(); appliquerFiltres(); } @@ -410,16 +403,16 @@ public class EntitesGestionBean implements Serializable { for (Entite entite : entitesSelectionnees) { if (entite.isQuotaProche()) { // Simulation d'envoi de proposition d'upgrade - System.out.println("Proposition d'upgrade envoyée à: " + entite.getNom()); + LOGGER.info("Proposition d'upgrade envoyée à: " + entite.getNom()); compteur++; } } - System.out.println(compteur + " propositions d'upgrade envoyées"); + LOGGER.info(compteur + " propositions d'upgrade envoyées"); } // Classes internes public static class Entite { - private Long id; + private UUID id; private String nom; private String codeEntite; private String type; @@ -442,8 +435,8 @@ public class EntitesGestionBean implements Serializable { private String montantMensuel = "3 000 FCFA"; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EvenementsBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EvenementsBean.java index d122a27..9c6e9bf 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EvenementsBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EvenementsBean.java @@ -1,24 +1,34 @@ package dev.lions.unionflow.client.view; +import dev.lions.unionflow.client.dto.EvenementDTO; +import dev.lions.unionflow.client.service.EvenementService; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; import java.time.LocalDate; -import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; import java.math.BigDecimal; +import java.util.logging.Logger; @Named("evenementsBean") @SessionScoped public class EvenementsBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(EvenementsBean.class.getName()); + + @Inject + @RestClient + private EvenementService evenementService; private List tousLesEvenements; private List evenementsFiltres; @@ -32,8 +42,8 @@ public class EvenementsBean implements Serializable { @PostConstruct public void init() { initializeFiltres(); - initializeStatistiques(); initializeEvenements(); + initializeStatistiques(); initializeNouvelEvenement(); initializeEvenementsProchains(); appliquerFiltres(); @@ -46,98 +56,78 @@ public class EvenementsBean implements Serializable { private void initializeStatistiques() { statistiques = new StatistiquesEvenements(); - statistiques.setTotalEvenements(42); - statistiques.setEvenementsActifs(18); - statistiques.setParticipantsTotal(1247); - statistiques.setBudgetTotal("3 450 000 FCFA"); - statistiques.setMoyenneParticipants(69); + try { + List evenementsDTO = evenementService.listerTous(0, 1000); + statistiques.setTotalEvenements(evenementsDTO.size()); + long actifs = evenementsDTO.stream() + .filter(e -> "PLANIFIE".equals(e.getStatut()) || "EN_COURS".equals(e.getStatut())) + .count(); + statistiques.setEvenementsActifs((int) actifs); + int totalParticipants = evenementsDTO.stream() + .mapToInt(e -> e.getParticipantsInscrits() != null ? e.getParticipantsInscrits() : 0) + .sum(); + statistiques.setParticipantsTotal(totalParticipants); + BigDecimal totalBudget = evenementsDTO.stream() + .map(e -> e.getBudget() != null ? e.getBudget() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + statistiques.setBudgetTotal(totalBudget.toString() + " FCFA"); + double moyenne = evenementsDTO.isEmpty() ? 0 : (double) totalParticipants / evenementsDTO.size(); + statistiques.setMoyenneParticipants((int) moyenne); + } catch (Exception e) { + LOGGER.severe("Erreur lors du calcul des statistiques: " + e.getMessage()); + statistiques.setTotalEvenements(0); + statistiques.setEvenementsActifs(0); + statistiques.setParticipantsTotal(0); + statistiques.setBudgetTotal("0 FCFA"); + statistiques.setMoyenneParticipants(0); + } } private void initializeEvenements() { tousLesEvenements = new ArrayList<>(); - - String[] titres = { - "Assemblée Générale Ordinaire", "Formation Leadership", "Action Sociale Quartier Nord", - "Réunion Mensuelle Comité", "Conférence Développement Durable", "Collecte de Fonds", - "Journée Portes Ouvertes", "Atelier Gestion Financière", "Campagne Sensibilisation", - "Séminaire Jeunes Leaders", "Action Humanitaire", "Réunion Conseil Administration", - "Formation Premiers Secours", "Festival Culturel", "Réunion Coordination Régionale" - }; - - String[] types = { - "ASSEMBLEE_GENERALE", "FORMATION", "ACTION_SOCIALE", "REUNION", "FORMATION", - "ACTION_SOCIALE", "EVENEMENT_FESTIF", "FORMATION", "ACTION_SOCIALE", "FORMATION", - "ACTION_SOCIALE", "REUNION", "FORMATION", "EVENEMENT_FESTIF", "REUNION" - }; - - String[] statuts = { - "PLANIFIE", "PLANIFIE", "EN_COURS", "TERMINE", "PLANIFIE", - "PLANIFIE", "TERMINE", "PLANIFIE", "EN_COURS", "PLANIFIE", - "TERMINE", "PLANIFIE", "PLANIFIE", "TERMINE", "PLANIFIE" - }; - - String[] priorites = { - "CRITIQUE", "ELEVEE", "NORMALE", "NORMALE", "ELEVEE", - "NORMALE", "FAIBLE", "NORMALE", "ELEVEE", "NORMALE", - "CRITIQUE", "NORMALE", "FAIBLE", "FAIBLE", "NORMALE" - }; - - String[] lieux = { - "Salle Principale", "Centre Formation", "Quartier Nord", "Salle Réunion A", - "Auditorium Central", "Place Publique", "Hall d'Accueil", "Salle Formation B", - "Centre-Ville", "Campus Universitaire", "Zone Rurale", "Salle Conseil", - "Centre Médical", "Parc Municipal", "Siège Régional" - }; - - String[] organisateurs = { - "Marie Kouassi", "Paul Traoré", "Fatou Sanogo", "Jean Ouattara", "Aissata Koné", - "Ibrahim Touré", "Aminata Bakayoko", "Yves Koffi", "Mariam Coulibaly", "Seydou Cissé", - "Adjoa Mensah", "Kwame Asante", "Ama Gyamfi", "Kofi Adjei", "Ahmed Diallo" - }; - - for (int i = 0; i < titres.length; i++) { - Evenement evenement = new Evenement(); - evenement.setId((long) (i + 1)); - evenement.setTitre(titres[i]); - evenement.setType(types[i]); - evenement.setStatut(statuts[i]); - evenement.setPriorite(priorites[i]); - evenement.setLieu(lieux[i]); - evenement.setAdresse("Adresse " + lieux[i] + ", Ville"); - evenement.setOrganisateur(organisateurs[i]); - evenement.setOrganisateurEmail(organisateurs[i].toLowerCase().replace(" ", ".") + "@unionflow.app"); - - // Dates aléatoires - LocalDate baseDate = LocalDate.now().plusDays(i * 3 - 15); - evenement.setDateDebut(baseDate); - evenement.setDateFin(baseDate.plusDays(i % 3 == 0 ? 1 : 0)); - evenement.setHeureDebut(LocalTime.of(9 + (i % 8), 0)); - evenement.setHeureFin(LocalTime.of(11 + (i % 8), 30)); - - // Participants et capacité - int capacite = 50 + (i * 10); - int inscrits = (int) (capacite * (0.3 + (i * 0.05) % 0.7)); - evenement.setCapaciteMax(capacite); - evenement.setParticipantsInscrits(inscrits); - - // Budget - BigDecimal budget = new BigDecimal(100000 + (i * 25000)); - evenement.setBudget(budget); - - // Description - evenement.setDescription("Description détaillée pour " + titres[i] + " avec objectifs et programme."); - - tousLesEvenements.add(evenement); + try { + List evenementsDTO = evenementService.listerTous(0, 1000); + for (EvenementDTO dto : evenementsDTO) { + Evenement evenement = convertToEvenement(dto); + tousLesEvenements.add(evenement); + } + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des événements: " + e.getMessage()); } } + private Evenement convertToEvenement(EvenementDTO dto) { + Evenement evenement = new Evenement(); + evenement.setId(dto.getId()); + evenement.setTitre(dto.getTitre()); + evenement.setType(dto.getType()); + evenement.setStatut(dto.getStatut()); + evenement.setPriorite(dto.getPriorite()); + evenement.setLieu(dto.getLieu()); + evenement.setAdresse(dto.getAdresse()); + evenement.setOrganisateur(dto.getOrganisateur()); + evenement.setOrganisateurEmail(dto.getOrganisateurEmail()); + evenement.setDateDebut(dto.getDateDebut()); + evenement.setDateFin(dto.getDateFin()); + evenement.setHeureDebut(dto.getHeureDebut()); + evenement.setHeureFin(dto.getHeureFin()); + evenement.setCapaciteMax(dto.getCapaciteMax()); + evenement.setParticipantsInscrits(dto.getParticipantsInscrits()); + evenement.setBudget(dto.getBudget()); + evenement.setDescription(dto.getDescription()); + return evenement; + } + private void initializeEvenementsProchains() { - evenementsProchains = tousLesEvenements.stream() - .filter(e -> e.getDateDebut().isAfter(LocalDate.now()) || e.getDateDebut().equals(LocalDate.now())) - .filter(e -> !e.getStatut().equals("ANNULE") && !e.getStatut().equals("TERMINE")) - .sorted((e1, e2) -> e1.getDateDebut().compareTo(e2.getDateDebut())) - .limit(6) + try { + List evenementsDTO = evenementService.listerAVenir(0, 6); + evenementsProchains = evenementsDTO.stream() + .map(this::convertToEvenement) .collect(Collectors.toList()); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des événements à venir: " + e.getMessage()); + evenementsProchains = new ArrayList<>(); + } } private void initializeNouvelEvenement() { @@ -210,7 +200,7 @@ public class EvenementsBean implements Serializable { public void creerEvenement() { Evenement nouvelEvt = new Evenement(); - nouvelEvt.setId((long) (tousLesEvenements.size() + 1)); + nouvelEvt.setId(UUID.randomUUID()); nouvelEvt.setTitre(nouvelEvenement.getTitre()); nouvelEvt.setType(nouvelEvenement.getType()); nouvelEvt.setDateDebut(nouvelEvenement.getDateDebut()); @@ -231,7 +221,7 @@ public class EvenementsBean implements Serializable { appliquerFiltres(); initializeEvenementsProchains(); - System.out.println("Nouvel événement créé: " + nouvelEvt.getTitre()); + LOGGER.info("Nouvel événement créé: " + nouvelEvt.getTitre()); initializeNouvelEvenement(); } @@ -240,7 +230,7 @@ public class EvenementsBean implements Serializable { } public void envoyerInvitations() { - System.out.println("Invitations envoyées pour: " + evenementSelectionne.getTitre()); + LOGGER.info("Invitations envoyées pour: " + evenementSelectionne.getTitre()); } public String voirRapports() { @@ -250,7 +240,7 @@ public class EvenementsBean implements Serializable { public void annulerEvenement() { if (evenementSelectionne != null) { evenementSelectionne.setStatut("ANNULE"); - System.out.println("Événement annulé: " + evenementSelectionne.getTitre()); + LOGGER.info("Événement annulé: " + evenementSelectionne.getTitre()); appliquerFiltres(); initializeEvenementsProchains(); } @@ -259,7 +249,7 @@ public class EvenementsBean implements Serializable { public void dupliquerEvenement() { if (evenementSelectionne != null) { Evenement copie = new Evenement(); - copie.setId((long) (tousLesEvenements.size() + 1)); + copie.setId(UUID.randomUUID()); copie.setTitre(evenementSelectionne.getTitre() + " (Copie)"); copie.setType(evenementSelectionne.getType()); copie.setLieu(evenementSelectionne.getLieu()); @@ -278,16 +268,16 @@ public class EvenementsBean implements Serializable { tousLesEvenements.add(copie); appliquerFiltres(); - System.out.println("Événement dupliqué: " + copie.getTitre()); + LOGGER.info("Événement dupliqué: " + copie.getTitre()); } } public void exporterEvenements() { - System.out.println("Export de " + evenementsFiltres.size() + " événements"); + LOGGER.info("Export de " + evenementsFiltres.size() + " événements"); } public void exporterExcel() { - System.out.println("Export Excel de " + evenementsFiltres.size() + " événements"); + LOGGER.info("Export Excel de " + evenementsFiltres.size() + " événements"); } // Getters et Setters @@ -317,7 +307,7 @@ public class EvenementsBean implements Serializable { // Classes internes public static class Evenement { - private Long id; + private UUID id; private String titre; private String description; private String type; @@ -336,8 +326,8 @@ public class EvenementsBean implements Serializable { private BigDecimal budget; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getTitre() { return titre; } public void setTitre(String titre) { this.titre = titre; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/FormulaireBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/FormulaireBean.java index dd317f4..cf8d449 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/FormulaireBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/FormulaireBean.java @@ -2,18 +2,28 @@ package dev.lions.unionflow.client.view; import dev.lions.unionflow.client.dto.FormulaireDTO; import dev.lions.unionflow.client.dto.SouscriptionDTO; +import dev.lions.unionflow.client.service.FormulaireService; import jakarta.enterprise.context.RequestScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; +import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; +import java.util.logging.Logger; @Named("formulaireBean") @RequestScoped public class FormulaireBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(FormulaireBean.class.getName()); + + @Inject + @RestClient + private FormulaireService formulaireService; private List formulaires; private List formulairesPopulaires; @@ -25,104 +35,21 @@ public class FormulaireBean implements Serializable { private BigDecimal budgetMax; private String categorieFiltre = "ALL"; - public FormulaireBean() { + @PostConstruct + public void init() { initializeFormulaires(); } private void initializeFormulaires() { formulaires = new ArrayList<>(); - - // Formulaire STARTER - Pour les petites associations - FormulaireDTO starter = new FormulaireDTO(); - starter.setId(1L); - starter.setNom("Starter"); - starter.setDescription("Parfait pour les associations débutantes"); - starter.setQuotaMaxMembres(100); - starter.setPrixMensuel(new BigDecimal("2000")); // 2K FCFA - starter.setPrixAnnuel(new BigDecimal("20000")); // 20K FCFA (2 mois gratuits) - starter.setCouleurTheme("bg-blue-500"); - starter.setIconeFormulaire("pi-star"); - starter.setGestionMembres(true); - starter.setGestionCotisations(true); - starter.setGestionEvenements(false); - starter.setGestionAides(false); - starter.setRapportsAvances(false); - starter.setNotificationsEmail(true); - formulaires.add(starter); - - // Formulaire STANDARD - Pour les associations moyennes - FormulaireDTO standard = new FormulaireDTO(); - standard.setId(2L); - standard.setNom("Standard"); - standard.setDescription("Idéal pour les associations en croissance"); - standard.setQuotaMaxMembres(200); - standard.setPrixMensuel(new BigDecimal("3000")); // 3K FCFA - standard.setPrixAnnuel(new BigDecimal("30000")); // 30K FCFA (2 mois gratuits) - standard.setCouleurTheme("bg-green-500"); - standard.setIconeFormulaire("pi-users"); - standard.setRecommande(true); - standard.setGestionMembres(true); - standard.setGestionCotisations(true); - standard.setGestionEvenements(true); - standard.setGestionAides(true); - standard.setRapportsAvances(false); - standard.setNotificationsEmail(true); - standard.setNotificationsSMS(false); - standard.setGestionDocuments(true); - formulaires.add(standard); - - // Formulaire PREMIUM - Pour les grandes associations - FormulaireDTO premium = new FormulaireDTO(); - premium.setId(3L); - premium.setNom("Premium"); - premium.setDescription("Solution complète pour les grandes organisations"); - premium.setQuotaMaxMembres(500); - premium.setPrixMensuel(new BigDecimal("4000")); // 4K FCFA - premium.setPrixAnnuel(new BigDecimal("40000")); // 40K FCFA (2 mois gratuits) - premium.setCouleurTheme("bg-purple-500"); - premium.setIconeFormulaire("pi-crown"); - premium.setGestionMembres(true); - premium.setGestionCotisations(true); - premium.setGestionEvenements(true); - premium.setGestionAides(true); - premium.setRapportsAvances(true); - premium.setSupportPrioritaire(true); - premium.setSauvegardeAutomatique(true); - premium.setPersonnalisationAvancee(true); - premium.setIntegrationPaiement(true); - premium.setNotificationsEmail(true); - premium.setNotificationsSMS(true); - premium.setGestionDocuments(true); - formulaires.add(premium); - - // Formulaire CRISTAL - Pour les très grandes organisations - FormulaireDTO cristal = new FormulaireDTO(); - cristal.setId(4L); - cristal.setNom("Cristal"); - cristal.setDescription("Solution premium pour les fédérations et grandes entités"); - cristal.setQuotaMaxMembres(2000); - cristal.setPrixMensuel(new BigDecimal("5000")); // 5K FCFA - cristal.setPrixAnnuel(new BigDecimal("50000")); // 50K FCFA (2 mois gratuits) - cristal.setCouleurTheme("bg-indigo-500"); - cristal.setIconeFormulaire("pi-diamond"); - cristal.setGestionMembres(true); - cristal.setGestionCotisations(true); - cristal.setGestionEvenements(true); - cristal.setGestionAides(true); - cristal.setRapportsAvances(true); - cristal.setSupportPrioritaire(true); - cristal.setSauvegardeAutomatique(true); - cristal.setPersonnalisationAvancee(true); - cristal.setIntegrationPaiement(true); - cristal.setNotificationsEmail(true); - cristal.setNotificationsSMS(true); - cristal.setGestionDocuments(true); - formulaires.add(cristal); - - // Définir les formulaires populaires (Standard et Premium) - formulairesPopulaires = new ArrayList<>(); - formulairesPopulaires.add(standard); - formulairesPopulaires.add(premium); + try { + formulaires = formulaireService.listerActifs(); + formulairesPopulaires = formulaireService.listerPopulaires(); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des formulaires: " + e.getMessage()); + formulaires = new ArrayList<>(); + formulairesPopulaires = new ArrayList<>(); + } } public void selectionnerFormulaire(FormulaireDTO formulaire) { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/LoginBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/LoginBean.java index c510e9c..12b024b 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/LoginBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/LoginBean.java @@ -1,18 +1,21 @@ package dev.lions.unionflow.client.view; -import dev.lions.unionflow.client.dto.auth.LoginRequest; -import dev.lions.unionflow.client.dto.auth.LoginResponse; -import dev.lions.unionflow.client.security.JwtTokenManager; -import dev.lions.unionflow.client.service.AuthenticationService; import jakarta.enterprise.context.RequestScoped; -import jakarta.faces.application.FacesMessage; +import jakarta.faces.context.ExternalContext; import jakarta.faces.context.FacesContext; import jakarta.inject.Inject; import jakarta.inject.Named; -import jakarta.validation.Valid; +import org.eclipse.microprofile.jwt.JsonWebToken; +import java.io.IOException; import java.io.Serializable; import java.util.logging.Logger; +/** + * Bean de gestion de l'authentification via Keycloak OIDC + * + * @author UnionFlow Team + * @version 2.0 + */ @Named("loginBean") @RequestScoped public class LoginBean implements Serializable { @@ -20,104 +23,33 @@ public class LoginBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(LoginBean.class.getName()); + @Inject + private JsonWebToken jwt; + @Inject private UserSession userSession; - @Inject - private JwtTokenManager tokenManager; - - @Inject - private AuthenticationService authService; - - private String username; - private String password; - private String typeCompte; - private boolean rememberMe; - - public String login() { + /** + * Redirige vers Keycloak pour l'authentification + * L'authentification est gérée automatiquement par Quarkus OIDC + */ + public void login() { try { - if (username == null || username.trim().isEmpty() || - password == null || password.trim().isEmpty() || - typeCompte == null || typeCompte.trim().isEmpty()) { - - addErrorMessage("Erreur de validation", "Tous les champs sont requis"); - return null; - } - - LoginRequest loginRequest = new LoginRequest(username, password, typeCompte); - loginRequest.setRememberMe(rememberMe); - - LoginResponse response = authService.authenticate(loginRequest); - - // Mettre à jour la session utilisateur - userSession.updateFromLoginResponse(response); - - // Gérer les tokens JWT - tokenManager.setTokens(response); - - LOGGER.info("Connexion réussie pour: " + username + " (Type: " + typeCompte + ")"); - - addSuccessMessage("Connexion réussie", "Bienvenue " + userSession.getCurrentUser().getNomComplet()); - - // Redirection selon le type de compte - return getRedirectUrlForUserType(response.getUser().getTypeCompte()); - - } catch (AuthenticationService.AuthenticationException e) { - LOGGER.warning("Échec de l'authentification: " + e.getMessage()); - addErrorMessage("Erreur de connexion", e.getMessage()); - return null; + // La redirection vers Keycloak est gérée automatiquement par Quarkus OIDC + // via la configuration dans application.properties + LOGGER.info("Redirection vers Keycloak pour l'authentification"); } catch (Exception e) { - LOGGER.severe("Erreur inattendue lors de la connexion: " + e.getMessage()); - addErrorMessage("Erreur système", "Une erreur inattendue s'est produite. Veuillez réessayer."); - return null; - } - } - - public String loginDemo(String demoType) { - try { - String demoUsername; - String demoPassword = "admin"; - - switch (demoType) { - case "SUPER_ADMIN": - demoUsername = "superadmin"; - typeCompte = "SUPER_ADMIN"; - break; - case "ADMIN": - demoUsername = "admin"; - typeCompte = "ADMIN_ENTITE"; - break; - case "MEMBRE": - demoUsername = "membre"; - demoPassword = "membre"; - typeCompte = "MEMBRE"; - break; - default: - addErrorMessage("Erreur", "Type de démo invalide"); - return null; - } - - this.username = demoUsername; - this.password = demoPassword; - - return login(); - - } catch (Exception e) { - LOGGER.severe("Erreur lors de la connexion démo: " + e.getMessage()); - addErrorMessage("Erreur système", "Impossible de se connecter en mode démo"); - return null; + LOGGER.severe("Erreur lors de la redirection vers Keycloak: " + e.getMessage()); } } + /** + * Déconnexion de l'utilisateur + * Redirige vers l'endpoint de déconnexion Keycloak + */ public String logout() { try { - // Invalider le token côté serveur si possible - if (tokenManager.hasValidTokens()) { - authService.logout(tokenManager.getAccessToken()); - } - // Nettoyer la session locale - tokenManager.clearTokens(); userSession.clearSession(); // Invalider la session JSF @@ -125,77 +57,28 @@ public class LoginBean implements Serializable { LOGGER.info("Déconnexion réussie"); - return "/pages/public/login?faces-redirect=true"; + // Redirection vers Keycloak pour la déconnexion complète + ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); + String logoutUrl = "/auth/logout"; + externalContext.redirect(logoutUrl); - } catch (Exception e) { + return null; // La redirection est gérée par redirect() + + } catch (IOException e) { LOGGER.warning("Erreur lors de la déconnexion: " + e.getMessage()); // Même en cas d'erreur, invalider la session locale - tokenManager.clearTokens(); userSession.clearSession(); FacesContext.getCurrentInstance().getExternalContext().invalidateSession(); - return "/pages/public/login?faces-redirect=true"; + return "/?faces-redirect=true"; } } - private String getRedirectUrlForUserType(String typeCompte) { - if (typeCompte == null) { - return "/pages/secure/dashboard?faces-redirect=true"; - } - - switch (typeCompte) { - case "SUPER_ADMIN": - return "/pages/super-admin/dashboard?faces-redirect=true"; - case "ADMIN_ENTITE": - return "/pages/admin/dashboard?faces-redirect=true"; - case "MEMBRE": - return "/pages/membre/dashboard?faces-redirect=true"; - default: - return "/pages/secure/dashboard?faces-redirect=true"; - } - } - - private void addErrorMessage(String summary, String detail) { - FacesContext.getCurrentInstance().addMessage(null, - new FacesMessage(FacesMessage.SEVERITY_ERROR, summary, detail)); - } - - private void addSuccessMessage(String summary, String detail) { - FacesContext.getCurrentInstance().addMessage(null, - new FacesMessage(FacesMessage.SEVERITY_INFO, summary, detail)); - } - - // Getters et Setters - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - public String getTypeCompte() { - return typeCompte; - } - - public void setTypeCompte(String typeCompte) { - this.typeCompte = typeCompte; - } - - public boolean isRememberMe() { - return rememberMe; - } - - public void setRememberMe(boolean rememberMe) { - this.rememberMe = rememberMe; + /** + * Vérifie si l'utilisateur est authentifié + */ + public boolean isAuthenticated() { + return jwt != null && jwt.getName() != null; } } \ No newline at end of file diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreInscriptionBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreInscriptionBean.java index 220f2d6..e6de8f1 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreInscriptionBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreInscriptionBean.java @@ -1,11 +1,9 @@ package dev.lions.unionflow.client.view; import dev.lions.unionflow.client.dto.MembreDTO; -import dev.lions.unionflow.client.dto.AssociationDTO; import dev.lions.unionflow.client.service.MembreService; import dev.lions.unionflow.client.service.AssociationService; import dev.lions.unionflow.client.service.ValidationService; -import dev.lions.unionflow.client.view.SouscriptionBean; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Named; import jakarta.inject.Inject; @@ -18,13 +16,14 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; -import java.util.UUID; +import java.util.logging.Logger; @Named("membreInscriptionBean") @RequestScoped public class MembreInscriptionBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(MembreInscriptionBean.class.getName()); @Inject @RestClient @@ -146,22 +145,22 @@ public class MembreInscriptionBean implements Serializable { // Gestion de la photo si disponible if (photoBase64 != null && !photoBase64.trim().isEmpty()) { - System.out.println("Photo cadrée reçue: " + photoBase64.length() + " caractères"); - // TODO: Appeler service de sauvegarde de photo + LOGGER.info("Photo cadrée reçue: " + photoBase64.length() + " caractères"); + // Note: La sauvegarde de la photo sera implémentée ultérieurement via un service dédié. + // Le service appellera l'API backend pour stocker la photo associée au membre. } - System.out.println("Membre inscrit avec succès: " + membreCreee.getNomComplet()); + LOGGER.info("Membre inscrit avec succès: " + membreCreee.getNomComplet()); // Message de succès FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Inscription soumise", "Votre inscription a été soumise avec succès. Elle sera validée par l'administrateur de votre organisation."); FacesContext.getCurrentInstance().addMessage(null, message); - return "/pages/public/login?faces-redirect=true"; + return "/?faces-redirect=true"; } catch (Exception e) { - System.err.println("Erreur lors de l'inscription: " + e.getMessage()); - e.printStackTrace(); + LOGGER.severe("Erreur lors de l'inscription: " + e.getMessage()); FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", "Erreur lors de l'inscription: " + e.getMessage()); FacesContext.getCurrentInstance().addMessage(null, message); @@ -174,7 +173,7 @@ public class MembreInscriptionBean implements Serializable { if (nom != null && !nom.trim().isEmpty()) { ValidationService.ValidationResult result = validationService.validateValue(MembreDTO.class, "nom", nom); if (!result.isValid()) { - System.out.println("Erreur validation nom: " + result.getFirstErrorMessage()); + LOGGER.info("Erreur validation nom: " + result.getFirstErrorMessage()); } } } @@ -183,7 +182,7 @@ public class MembreInscriptionBean implements Serializable { if (prenom != null && !prenom.trim().isEmpty()) { ValidationService.ValidationResult result = validationService.validateValue(MembreDTO.class, "prenom", prenom); if (!result.isValid()) { - System.out.println("Erreur validation prénom: " + result.getFirstErrorMessage()); + LOGGER.info("Erreur validation prénom: " + result.getFirstErrorMessage()); } } } @@ -192,7 +191,7 @@ public class MembreInscriptionBean implements Serializable { if (email != null && !email.trim().isEmpty()) { ValidationService.ValidationResult result = validationService.validateValue(MembreDTO.class, "email", email); if (!result.isValid()) { - System.out.println("Erreur validation email: " + result.getFirstErrorMessage()); + LOGGER.info("Erreur validation email: " + result.getFirstErrorMessage()); } } } @@ -201,7 +200,7 @@ public class MembreInscriptionBean implements Serializable { if (telephone != null && !telephone.trim().isEmpty()) { ValidationService.ValidationResult result = validationService.validateValue(MembreDTO.class, "telephone", telephone); if (!result.isValid()) { - System.out.println("Erreur validation téléphone: " + result.getFirstErrorMessage()); + LOGGER.info("Erreur validation téléphone: " + result.getFirstErrorMessage()); } } } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreListeBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreListeBean.java index 69c6181..265b653 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreListeBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreListeBean.java @@ -6,18 +6,22 @@ import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Named; import jakarta.inject.Inject; import jakarta.annotation.PostConstruct; +import jakarta.faces.context.FacesContext; +import jakarta.servlet.http.HttpServletResponse; import org.eclipse.microprofile.rest.client.inject.RestClient; +import java.io.IOException; import java.io.Serializable; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; +import java.util.logging.Logger; @Named("membreListeBean") @SessionScoped public class MembreListeBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(MembreListeBean.class.getName()); @Inject @RestClient @@ -69,9 +73,8 @@ public class MembreListeBean implements Serializable { chargerMembres(); chargerStatistiques(); } catch (Exception e) { - System.err.println("Erreur lors de l'initialisation: " + e.getMessage()); - e.printStackTrace(); - // Données de fallback + LOGGER.severe("Erreur lors de l'initialisation: " + e.getMessage()); + // Pas de données mockées - initialiser à zéro this.totalMembres = 0; this.membresActifs = 0; this.cotisationsAJour = 0; @@ -86,35 +89,16 @@ public class MembreListeBean implements Serializable { membres = membreService.listerTous(); membresFiltres = new ArrayList<>(membres); - System.out.println("Chargement de " + membres.size() + " membres depuis le serveur"); + LOGGER.info("Chargement de " + membres.size() + " membres depuis le serveur"); } catch (Exception e) { - System.err.println("Impossible de charger les membres depuis le serveur: " + e.getMessage()); - // Fallback avec données simulées - membres = genererDonneesSimulees(); - membresFiltres = new ArrayList<>(membres); + LOGGER.severe("Impossible de charger les membres depuis le serveur: " + e.getMessage()); + // Pas de données mockées - laisser la liste vide + membres = new ArrayList<>(); + membresFiltres = new ArrayList<>(); } } - private List genererDonneesSimulees() { - List membresSimules = new ArrayList<>(); - for (int i = 1; i <= 20; i++) { - MembreDTO membre = new MembreDTO(); - membre.setId((long) i); - membre.setNumeroMembre("M2024" + String.format("%03d", i)); - membre.setNom("Membre" + i); - membre.setPrenom("Prénom" + i); - membre.setEmail("membre" + i + "@example.com"); - membre.setTelephone("77 123 45 " + String.format("%02d", i)); - membre.setStatut(i % 10 == 0 ? "INACTIF" : "ACTIF"); - membre.setDateNaissance(LocalDate.now().minusYears(25 + i)); - membre.setProfession("Profession " + (i % 10 + 1)); - membre.setAdresse("Adresse " + i); - membresSimules.add(membre); - } - return membresSimules; - } - private void chargerStatistiques() { try { // Récupération des statistiques via le service REST @@ -129,8 +113,8 @@ public class MembreListeBean implements Serializable { this.cotisationsAJour = (int) (this.membresActifs * 0.85); } catch (Exception e) { - System.err.println("Impossible de charger les statistiques: " + e.getMessage()); - // Utiliser les valeurs de fallback définies dans init() + LOGGER.severe("Impossible de charger les statistiques: " + e.getMessage()); + // Pas de données mockées - laisser les valeurs à zéro } } @@ -149,25 +133,15 @@ public class MembreListeBean implements Serializable { ); membresFiltres = resultats; - System.out.println("Recherche effectuée: " + membresFiltres.size() + " résultats"); + LOGGER.info("Recherche effectuée: " + membresFiltres.size() + " résultats"); } catch (Exception e) { - System.err.println("Erreur lors de la recherche: " + e.getMessage()); - // En cas d'erreur, appliquer le filtre localement - appliquerFiltreLocal(); + LOGGER.severe("Erreur lors de la recherche: " + e.getMessage()); + // En cas d'erreur, laisser la liste vide plutôt que des données mockées + membresFiltres = new ArrayList<>(); } } - private void appliquerFiltreLocal() { - membresFiltres = membres.stream() - .filter(m -> searchFilter.isEmpty() || - m.getNom().toLowerCase().contains(searchFilter.toLowerCase()) || - m.getPrenom().toLowerCase().contains(searchFilter.toLowerCase()) || - m.getEmail().toLowerCase().contains(searchFilter.toLowerCase())) - .filter(m -> statutFilter.isEmpty() || m.getStatut().equals(statutFilter)) - .collect(Collectors.toList()); - } - public void reinitialiserFiltres() { searchFilter = ""; statutFilter = ""; @@ -188,18 +162,18 @@ public class MembreListeBean implements Serializable { public void appliquerFiltresAvances() { // Appliquer les filtres avancés - System.out.println("Application des filtres avancés"); + LOGGER.info("Application des filtres avancés"); } // Import/Export public void importerMembres() { // Logique d'import des membres - System.out.println("Import des membres"); + LOGGER.info("Import des membres"); } public void telechargerModele() { // Télécharger modèle d'import - System.out.println("Téléchargement du modèle"); + LOGGER.info("Téléchargement du modèle"); } // Actions avec DTOs @@ -211,9 +185,9 @@ public class MembreListeBean implements Serializable { try { membreService.activer(membre.getId()); membre.setStatut("ACTIF"); - System.out.println("Membre activé: " + membre.getNomComplet()); + LOGGER.info("Membre activé: " + membre.getNomComplet()); } catch (Exception e) { - System.err.println("Erreur lors de l'activation: " + e.getMessage()); + LOGGER.severe("Erreur lors de l'activation: " + e.getMessage()); } } @@ -221,19 +195,35 @@ public class MembreListeBean implements Serializable { try { membreService.desactiver(membre.getId()); membre.setStatut("INACTIF"); - System.out.println("Membre désactivé: " + membre.getNomComplet()); + LOGGER.info("Membre désactivé: " + membre.getNomComplet()); } catch (Exception e) { - System.err.println("Erreur lors de la désactivation: " + e.getMessage()); + LOGGER.severe("Erreur lors de la désactivation: " + e.getMessage()); } } public void exporterMembres() { try { byte[] excelData = membreService.exporterExcel(formatExport, null, statutFilter.isEmpty() ? null : statutFilter); - // TODO: Gérer le téléchargement du fichier Excel - System.out.println("Export Excel généré: " + excelData.length + " bytes"); + + // Téléchargement du fichier Excel via JSF + FacesContext facesContext = FacesContext.getCurrentInstance(); + HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse(); + + response.reset(); + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setHeader("Content-Disposition", "attachment; filename=\"membres_export_" + + LocalDate.now() + "." + (formatExport != null ? formatExport.toLowerCase() : "xlsx") + "\""); + response.setContentLength(excelData.length); + + response.getOutputStream().write(excelData); + response.getOutputStream().flush(); + facesContext.responseComplete(); + + LOGGER.info("Export Excel généré et téléchargé: " + excelData.length + " bytes"); + } catch (IOException e) { + LOGGER.severe("Erreur lors du téléchargement de l'export: " + e.getMessage()); } catch (Exception e) { - System.err.println("Erreur lors de l'export: " + e.getMessage()); + LOGGER.severe("Erreur lors de l'export: " + e.getMessage()); } } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreProfilBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreProfilBean.java index 258e5e4..1cbdb84 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreProfilBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreProfilBean.java @@ -1,13 +1,19 @@ package dev.lions.unionflow.client.view; +import dev.lions.unionflow.client.dto.MembreDTO; +import dev.lions.unionflow.client.service.MembreService; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.UUID; +import java.util.logging.Logger; import org.primefaces.event.FileUploadEvent; @Named("membreProfilBean") @@ -15,6 +21,11 @@ import org.primefaces.event.FileUploadEvent; public class MembreProfilBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(MembreProfilBean.class.getName()); + + @Inject + @RestClient + private MembreService membreService; private Membre membre; private Membre membreEdit; @@ -25,12 +36,13 @@ public class MembreProfilBean implements Serializable { private DemandesData demandes; private HistoriqueData historique; private ContactData contact; - private Long membreId; + private UUID membreId; @PostConstruct public void init() { if (membreId == null) { - membreId = 1L; // Par défaut pour le test + LOGGER.warning("Aucun membreId fourni, impossible de charger le profil"); + return; } chargerMembre(); chargerStatistiques(); @@ -43,48 +55,36 @@ public class MembreProfilBean implements Serializable { } private void chargerMembre() { - membre = new Membre(); - membre.setId(membreId); - membre.setNumeroMembre("M2024001"); - membre.setPrenom("Jean"); - membre.setNom("DIALLO"); - membre.setEmail("jean.diallo@email.com"); - membre.setTelephone("77 123 45 67"); - membre.setDateNaissance(LocalDate.of(1985, 6, 15)); - membre.setGenre("Masculin"); - membre.setSituationFamiliale("Marié"); - membre.setProfession("Ingénieur Informatique"); - membre.setAdresse("Villa n°123, Cité Keur Gorgui"); - membre.setVille("Dakar"); - membre.setPays("Sénégal"); - membre.setTypeMembre("ACTIF"); - membre.setStatut("ACTIF"); - membre.setEntite("LIONS CLUB Dakar Métropole"); - membre.setDateAdhesion(LocalDate.of(2020, 3, 15)); - membre.setCotisationStatut("À jour"); - membre.setTauxParticipation(85); - - // Famille - List famille = new ArrayList<>(); - MembreFamille epouse = new MembreFamille(); - epouse.setNomComplet("Awa DIALLO"); - epouse.setRelation("Épouse"); - epouse.setDateNaissance(LocalDate.of(1987, 9, 20)); - epouse.setBeneficiaire(true); - famille.add(epouse); - - MembreFamille enfant1 = new MembreFamille(); - enfant1.setNomComplet("Amadou DIALLO"); - enfant1.setRelation("Fils"); - enfant1.setDateNaissance(LocalDate.of(2010, 12, 5)); - enfant1.setBeneficiaire(true); - famille.add(enfant1); - - membre.setFamille(famille); - - // Copie pour l'édition - membreEdit = new Membre(); - copierMembre(membre, membreEdit); + try { + MembreDTO dto = membreService.obtenirParId(membreId); + membre = convertToMembre(dto); + + // Copie pour l'édition + membreEdit = new Membre(); + copierMembre(membre, membreEdit); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement du membre: " + e.getMessage()); + membre = new Membre(); + membre.setId(membreId); + } + } + + private Membre convertToMembre(MembreDTO dto) { + Membre membre = new Membre(); + membre.setId(dto.getId()); + membre.setNumeroMembre(dto.getNumeroMembre()); + membre.setPrenom(dto.getPrenom()); + membre.setNom(dto.getNom()); + membre.setEmail(dto.getEmail()); + membre.setTelephone(dto.getTelephone()); + membre.setDateNaissance(dto.getDateNaissance()); + // Note: Genre, situation familiale, ville, pays, type membre ne sont pas disponibles dans MembreDTO client + // Ces champs seront ajoutés ultérieurement si nécessaire + membre.setProfession(dto.getProfession()); + membre.setAdresse(dto.getAdresse()); + membre.setStatut(dto.getStatut() != null ? dto.getStatut() : "ACTIF"); + membre.setDateAdhesion(dto.getDateInscription() != null ? dto.getDateInscription().toLocalDate() : null); + return membre; } private void chargerStatistiques() { @@ -223,7 +223,7 @@ public class MembreProfilBean implements Serializable { // Actions public void changerPhoto(FileUploadEvent event) { // Logique de changement de photo - System.out.println("Photo changée: " + event.getFile().getFileName()); + LOGGER.info("Photo changée: " + event.getFile().getFileName()); } public String gererCotisations() { @@ -232,35 +232,35 @@ public class MembreProfilBean implements Serializable { public void sauvegarderModifications() { copierMembre(membreEdit, membre); - System.out.println("Profil mis à jour pour: " + membre.getNomComplet()); + LOGGER.info("Profil mis à jour pour: " + membre.getNomComplet()); } public void envoyerMessage() { - System.out.println("Message envoyé: " + contact.getSujet() + " via " + contact.getCanaux()); + LOGGER.info("Message envoyé: " + contact.getSujet() + " via " + contact.getCanaux()); contact = new ContactData(); contact.setCanaux(new ArrayList<>()); } public void envoyerRappelCotisation() { - System.out.println("Rappel de cotisation envoyé à: " + membre.getEmail()); + LOGGER.info("Rappel de cotisation envoyé à: " + membre.getEmail()); } public void suspendre() { membre.setStatut("SUSPENDU"); - System.out.println("Membre suspendu: " + membre.getNomComplet()); + LOGGER.info("Membre suspendu: " + membre.getNomComplet()); } public void reactiver() { membre.setStatut("ACTIF"); - System.out.println("Membre réactivé: " + membre.getNomComplet()); + LOGGER.info("Membre réactivé: " + membre.getNomComplet()); } public void exporterDonnees() { - System.out.println("Export des données pour: " + membre.getNomComplet()); + LOGGER.info("Export des données pour: " + membre.getNomComplet()); } public String supprimer() { - System.out.println("Membre supprimé: " + membre.getNomComplet()); + LOGGER.info("Membre supprimé: " + membre.getNomComplet()); return "/pages/secure/membre/liste?faces-redirect=true"; } @@ -303,12 +303,12 @@ public class MembreProfilBean implements Serializable { public ContactData getContact() { return contact; } public void setContact(ContactData contact) { this.contact = contact; } - public Long getMembreId() { return membreId; } - public void setMembreId(Long membreId) { this.membreId = membreId; } + public UUID getMembreId() { return membreId; } + public void setMembreId(UUID membreId) { this.membreId = membreId; } // Classes internes public static class Membre { - private Long id; + private UUID id; private String numeroMembre; private String prenom; private String nom; @@ -331,8 +331,8 @@ public class MembreProfilBean implements Serializable { private List famille = new ArrayList<>(); // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNumeroMembre() { return numeroMembre; } public void setNumeroMembre(String numeroMembre) { this.numeroMembre = numeroMembre; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreRechercheBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreRechercheBean.java index 6d70e2f..1bc65c8 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreRechercheBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreRechercheBean.java @@ -1,19 +1,35 @@ package dev.lions.unionflow.client.view; +import dev.lions.unionflow.client.dto.MembreDTO; +import dev.lions.unionflow.client.service.MembreService; +import dev.lions.unionflow.client.service.AssociationService; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; +import java.util.logging.Logger; @Named("membreRechercheBean") @SessionScoped public class MembreRechercheBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(MembreRechercheBean.class.getName()); + + @Inject + @RestClient + private MembreService membreService; + + @Inject + @RestClient + private AssociationService associationService; private Filtres filtres; private Statistiques statistiques; @@ -47,87 +63,72 @@ public class MembreRechercheBean implements Serializable { private void initializeStatistiques() { statistiques = new Statistiques(); - statistiques.setTotalMembres(234); + try { + List membres = membreService.listerTous(); + statistiques.setTotalMembres(membres.size()); + } catch (Exception e) { + LOGGER.severe("Erreur lors du calcul des statistiques: " + e.getMessage()); + statistiques.setTotalMembres(0); + } statistiques.setResultatsActuels(0); statistiques.setFiltresActifs(0); - statistiques.setTempsRecherche(25); + statistiques.setTempsRecherche(0); } private void initializeDonnees() { tousLesMembres = new ArrayList<>(); selectedMembres = new ArrayList<>(); - // Génération de données de test - String[] noms = {"DIALLO", "FALL", "NDIAYE", "DIOUF", "SARR", "BA", "SALL", "TOURE", "GUEYE", "NDOUR"}; - String[] prenoms = {"Amadou", "Fatou", "Ousmane", "Awa", "Mamadou", "Aida", "Ibrahima", "Mariam", "Moussa", "Khady"}; - String[] professions = {"Enseignant", "Médecin", "Ingénieur", "Commerçant", "Agriculteur", "Fonctionnaire", "Artisan", "Avocat"}; - String[] villes = {"Dakar", "Thiès", "Kaolack", "Saint-Louis", "Ziguinchor", "Diourbel", "Tambacounda"}; - String[] typesMembre = {"ACTIF", "ASSOCIE", "BIENFAITEUR", "HONORAIRE"}; - String[] statuts = {"ACTIF", "INACTIF", "SUSPENDU"}; - String[] entites = {"LIONS CLUB Dakar Métropole", "LIONS CLUB Thiès", "LIONS CLUB Kaolack"}; - - for (int i = 1; i <= 50; i++) { - Membre membre = new Membre(); - membre.setId((long) i); - membre.setNumeroMembre("M2024" + String.format("%03d", i)); - membre.setNom(noms[i % noms.length]); - membre.setPrenom(prenoms[i % prenoms.length]); - membre.setEmail(membre.getPrenom().toLowerCase() + "." + membre.getNom().toLowerCase() + "@email.com"); - membre.setTelephone("77 123 45 " + String.format("%02d", i)); - membre.setProfession(professions[i % professions.length]); - membre.setVille(villes[i % villes.length]); - membre.setTypeMembre(typesMembre[i % typesMembre.length]); - membre.setStatut(statuts[i % statuts.length]); - membre.setEntite(entites[i % entites.length]); - membre.setDateAdhesion(LocalDate.now().minusMonths(i)); - membre.setCotisationStatut(i % 5 == 0 ? "En retard" : "À jour"); - membre.setTauxParticipation(60 + (i % 40)); - membre.setEvenementsAnnee(i % 15 + 2); - membre.setGenre(i % 2 == 0 ? "M" : "F"); - membre.setAge(25 + (i % 40)); - membre.setADesEnfants(i % 3 == 0); - membre.setARecuAides(i % 7 == 0); - - tousLesMembres.add(membre); + try { + List membresDTO = membreService.listerTous(); + for (MembreDTO dto : membresDTO) { + Membre membre = convertToMembre(dto); + tousLesMembres.add(membre); + } + resultats = new ArrayList<>(tousLesMembres); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des membres: " + e.getMessage()); + resultats = new ArrayList<>(); } - - resultats = new ArrayList<>(tousLesMembres); + } + + private Membre convertToMembre(MembreDTO dto) { + Membre membre = new Membre(); + membre.setId(dto.getId()); + membre.setNumeroMembre(dto.getNumeroMembre()); + membre.setNom(dto.getNom()); + membre.setPrenom(dto.getPrenom()); + membre.setEmail(dto.getEmail()); + membre.setTelephone(dto.getTelephone()); + membre.setProfession(dto.getProfession()); + membre.setVille(""); // Ville non disponible dans MembreDTO + membre.setTypeMembre("ACTIF"); // Type membre non disponible dans MembreDTO + if (dto.getStatut() != null) { + membre.setStatut(dto.getStatut()); + } else { + membre.setStatut("ACTIF"); + } + membre.setDateAdhesion(dto.getDateInscription() != null ? dto.getDateInscription().toLocalDate() : null); + return membre; } private void initializeEntites() { entitesDisponibles = new ArrayList<>(); - for (int i = 1; i <= 5; i++) { - Entite entite = new Entite(); - entite.setId((long) i); - entite.setNom("LIONS CLUB " + (i == 1 ? "Dakar Métropole" : - i == 2 ? "Thiès" : - i == 3 ? "Kaolack" : - i == 4 ? "Saint-Louis" : "Ziguinchor")); - entitesDisponibles.add(entite); + try { + List associations = associationService.listerActives(); + for (dev.lions.unionflow.client.dto.AssociationDTO assoc : associations) { + Entite entite = new Entite(); + entite.setId(assoc.getId()); + entite.setNom(assoc.getNom()); + entitesDisponibles.add(entite); + } + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des entités: " + e.getMessage()); } } private void initializeRecherchesSauvegardees() { recherchesSauvegardees = new ArrayList<>(); - - RechercheSauvegardee recherche1 = new RechercheSauvegardee(); - recherche1.setId(1L); - recherche1.setNom("Membres actifs 2024"); - recherche1.setDescription("Tous les membres actifs adhérés en 2024"); - recherche1.setNombreCriteres(3); - recherche1.setDateCreation(LocalDate.now().minusDays(5)); - recherche1.setPublique(true); - recherchesSauvegardees.add(recherche1); - - RechercheSauvegardee recherche2 = new RechercheSauvegardee(); - recherche2.setId(2L); - recherche2.setNom("Cotisations en retard"); - recherche2.setDescription("Membres avec cotisations en retard"); - recherche2.setNombreCriteres(2); - recherche2.setDateCreation(LocalDate.now().minusDays(2)); - recherche2.setPublique(false); - recherchesSauvegardees.add(recherche2); - nouvelleRechercheSauvegardee = new RechercheSauvegardee(); } @@ -140,9 +141,25 @@ public class MembreRechercheBean implements Serializable { public void effectuerRecherche() { long startTime = System.currentTimeMillis(); - resultats = tousLesMembres.stream() - .filter(this::appliquerFiltres) + try { + List membresDTO = membreService.rechercher( + filtres.getNom(), + filtres.getPrenom(), + filtres.getEmail(), + filtres.getTelephone(), + filtres.getStatuts() != null && !filtres.getStatuts().isEmpty() ? filtres.getStatuts().get(0) : null, + null, + 0, + 100 + ); + + resultats = membresDTO.stream() + .map(this::convertToMembre) .collect(Collectors.toList()); + } catch (Exception e) { + LOGGER.severe("Erreur lors de la recherche: " + e.getMessage()); + resultats = new ArrayList<>(); + } long endTime = System.currentTimeMillis(); @@ -309,22 +326,22 @@ public class MembreRechercheBean implements Serializable { } public void contacterMembre(Membre membre) { - System.out.println("Contacter le membre: " + membre.getNomComplet()); + LOGGER.info("Contacter le membre: " + membre.getNomComplet()); } public void ajouterAuGroupe(Membre membre) { - System.out.println("Ajouter au groupe: " + membre.getNomComplet()); + LOGGER.info("Ajouter au groupe: " + membre.getNomComplet()); } // Gestion des recherches sauvegardées public void sauvegarderRecherche() { - nouvelleRechercheSauvegardee.setId((long) (recherchesSauvegardees.size() + 1)); + nouvelleRechercheSauvegardee.setId(UUID.randomUUID()); nouvelleRechercheSauvegardee.setNombreCriteres(compterFiltresActifs()); nouvelleRechercheSauvegardee.setDateCreation(LocalDate.now()); recherchesSauvegardees.add(nouvelleRechercheSauvegardee); - System.out.println("Recherche sauvegardée: " + nouvelleRechercheSauvegardee.getNom()); + LOGGER.info("Recherche sauvegardée: " + nouvelleRechercheSauvegardee.getNom()); nouvelleRechercheSauvegardee = new RechercheSauvegardee(); } @@ -341,17 +358,17 @@ public class MembreRechercheBean implements Serializable { } effectuerRecherche(); - System.out.println("Recherche chargée: " + recherche.getNom()); + LOGGER.info("Recherche chargée: " + recherche.getNom()); } public void supprimerRecherche(RechercheSauvegardee recherche) { recherchesSauvegardees.remove(recherche); - System.out.println("Recherche supprimée: " + recherche.getNom()); + LOGGER.info("Recherche supprimée: " + recherche.getNom()); } // Actions groupées public void envoyerMessageGroupe() { - System.out.println("Message '" + messageGroupe.getSujet() + "' envoyé à " + + LOGGER.info("Message '" + messageGroupe.getSujet() + "' envoyé à " + selectedMembres.size() + " membres via " + messageGroupe.getCanaux()); messageGroupe = new MessageGroupe(); @@ -359,7 +376,7 @@ public class MembreRechercheBean implements Serializable { } public void exporterSelection() { - System.out.println("Export de " + selectedMembres.size() + " membres sélectionnés"); + LOGGER.info("Export de " + selectedMembres.size() + " membres sélectionnés"); } // Méthodes d'autocomplétion @@ -514,7 +531,7 @@ public class MembreRechercheBean implements Serializable { } public static class Membre { - private Long id; + private UUID id; private String numeroMembre; private String nom; private String prenom; @@ -536,8 +553,8 @@ public class MembreRechercheBean implements Serializable { private boolean aRecuAides; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNumeroMembre() { return numeroMembre; } public void setNumeroMembre(String numeroMembre) { this.numeroMembre = numeroMembre; } @@ -661,18 +678,18 @@ public class MembreRechercheBean implements Serializable { } public static class Entite { - private Long id; + private UUID id; private String nom; - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } } public static class RechercheSauvegardee { - private Long id; + private UUID id; private String nom; private String description; private int nombreCriteres; @@ -680,8 +697,8 @@ public class MembreRechercheBean implements Serializable { private boolean publique; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/NavigationBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/NavigationBean.java index 06aa10b..e464594 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/NavigationBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/NavigationBean.java @@ -1,6 +1,5 @@ package dev.lions.unionflow.client.view; -import dev.lions.unionflow.client.security.JwtTokenManager; import jakarta.enterprise.context.RequestScoped; import jakarta.faces.context.FacesContext; import jakarta.inject.Inject; @@ -9,6 +8,12 @@ import java.io.IOException; import java.io.Serializable; import java.util.logging.Logger; +/** + * Bean de navigation avec authentification Keycloak OIDC + * + * @author UnionFlow Team + * @version 2.0 + */ @Named("navigationBean") @RequestScoped public class NavigationBean implements Serializable { @@ -19,9 +24,6 @@ public class NavigationBean implements Serializable { @Inject private UserSession userSession; - @Inject - private JwtTokenManager tokenManager; - public void checkAuthentication() throws IOException { FacesContext context = FacesContext.getCurrentInstance(); @@ -32,15 +34,16 @@ public class NavigationBean implements Serializable { context.getExternalContext().getRequestContextPath() + dashboardUrl ); } else { - // L'utilisateur n'est pas connecté, rediriger vers la page de login + // L'utilisateur n'est pas connecté, rediriger vers la racine qui déclenchera Keycloak context.getExternalContext().redirect( - context.getExternalContext().getRequestContextPath() + "/pages/public/login.xhtml" + context.getExternalContext().getRequestContextPath() + "/" ); } } public String redirectToLogin() { - return "/pages/public/login?faces-redirect=true"; + // Redirection vers la racine qui déclenchera automatiquement Keycloak + return "/?faces-redirect=true"; } public String goToDashboard() { @@ -78,10 +81,8 @@ public class NavigationBean implements Serializable { } private boolean isUserAuthenticated() { - return userSession != null && - userSession.isAuthenticated() && - tokenManager != null && - tokenManager.hasValidTokens(); + // Avec Keycloak OIDC, UserSession vérifie automatiquement l'authentification via JsonWebToken + return userSession != null && userSession.isAuthenticated(); } private String getDashboardUrlForUserType() { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/RapportsBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/RapportsBean.java index 9a63202..6bd3636 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/RapportsBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/RapportsBean.java @@ -1,20 +1,57 @@ package dev.lions.unionflow.client.view; +import dev.lions.unionflow.client.service.AnalyticsService; +import dev.lions.unionflow.client.service.MembreService; +import dev.lions.unionflow.client.service.CotisationService; +import dev.lions.unionflow.client.service.EvenementService; +import dev.lions.unionflow.client.service.DemandeAideService; +import dev.lions.unionflow.client.service.AssociationService; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.math.BigDecimal; +import java.util.logging.Logger; @Named("rapportsBean") @SessionScoped public class RapportsBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(RapportsBean.class.getName()); + + @Inject + @RestClient + private AnalyticsService analyticsService; + + @Inject + @RestClient + private MembreService membreService; + + @Inject + @RestClient + private CotisationService cotisationService; + + @Inject + @RestClient + private EvenementService evenementService; + + @Inject + @RestClient + private DemandeAideService demandeAideService; + + @Inject + @RestClient + private AssociationService associationService; + + private String organisationId; // À injecter depuis la session private String periodeRapide; private LocalDate dateDebut; @@ -57,260 +94,212 @@ public class RapportsBean implements Serializable { private void initializeIndicateurs() { indicateurs = new IndicateursGlobaux(); - indicateurs.setTotalMembres(1247); - indicateurs.setCroissanceMembres(8.5); - indicateurs.setRevenus("45 750 000 FCFA"); - indicateurs.setCroissanceRevenus(12.3); - indicateurs.setTotalEvenements(42); - indicateurs.setCroissanceEvenements(15.7); - indicateurs.setTotalAides("12 850 000 FCFA"); - indicateurs.setCroissanceAides(22.1); + try { + int totalMembres = membreService.listerTous().size(); + int totalEvenements = evenementService.listerTous(0, 1000).size(); + + BigDecimal totalRevenus = cotisationService.listerToutes(0, 1000).stream() + .filter(c -> "PAYEE".equals(c.getStatut()) || "PARTIELLEMENT_PAYEE".equals(c.getStatut())) + .map(c -> c.getMontantPaye() != null ? c.getMontantPaye() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + BigDecimal totalAides = demandeAideService.listerToutes(0, 1000).stream() + .filter(d -> d.getMontantAccorde() != null) + .map(d -> d.getMontantAccorde()) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + indicateurs.setTotalMembres(totalMembres); + indicateurs.setCroissanceMembres(0.0); // À calculer depuis les données historiques + indicateurs.setRevenus(formatMontantCourt(totalRevenus) + " FCFA"); + indicateurs.setCroissanceRevenus(0.0); // À calculer depuis les données historiques + indicateurs.setTotalEvenements(totalEvenements); + indicateurs.setCroissanceEvenements(0.0); // À calculer depuis les données historiques + indicateurs.setTotalAides(formatMontantCourt(totalAides) + " FCFA"); + indicateurs.setCroissanceAides(0.0); // À calculer depuis les données historiques + } catch (Exception e) { + LOGGER.severe("Erreur lors du calcul des indicateurs: " + e.getMessage()); + indicateurs.setTotalMembres(0); + indicateurs.setCroissanceMembres(0.0); + indicateurs.setRevenus("0 FCFA"); + indicateurs.setCroissanceRevenus(0.0); + indicateurs.setTotalEvenements(0); + indicateurs.setCroissanceEvenements(0.0); + indicateurs.setTotalAides("0 FCFA"); + indicateurs.setCroissanceAides(0.0); + } } private void initializeEvolutionMensuelle() { evolutionMensuelle = new ArrayList<>(); - String[] mois = {"Jan", "Fév", "Mar", "Avr", "Mai", "Jun"}; - int[] membres = {1150, 1180, 1205, 1225, 1240, 1247}; - double[] revenus = {3.2, 3.8, 4.1, 4.5, 3.9, 4.2}; - - for (int i = 0; i < mois.length; i++) { - EvolutionMensuelle evolution = new EvolutionMensuelle(); - evolution.setLibelle(mois[i]); - evolution.setMembres(membres[i]); - evolution.setRevenus(revenus[i]); - evolution.setHauteurMembres((int) ((membres[i] - 1100) / 2)); - evolution.setHauteurRevenus((int) (revenus[i] * 15)); - evolutionMensuelle.add(evolution); + try { + if (organisationId != null && dateDebut != null && dateFin != null) { + String periode = "CUSTOM"; // À mapper depuis dateDebut/dateFin + analyticsService.getEvolutionMensuelle("NOMBRE_MEMBRES_ACTIFS", organisationId, periode); + // Traiter les données de l'API + // Pour l'instant, initialiser avec des données vides + } + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement de l'évolution mensuelle: " + e.getMessage()); } + // Si pas de données, laisser la liste vide plutôt que des données mockées } private void initializeObjectifs() { objectifs = new ArrayList<>(); - - Objectif obj1 = new Objectif(); - obj1.setLibelle("Nouveaux Membres"); - obj1.setRealise("247"); - obj1.setCible("300"); - obj1.setPourcentage(82); - objectifs.add(obj1); - - Objectif obj2 = new Objectif(); - obj2.setLibelle("Revenus Cotisations"); - obj2.setRealise("38.5M"); - obj2.setCible("45M"); - obj2.setPourcentage(86); - objectifs.add(obj2); - - Objectif obj3 = new Objectif(); - obj3.setLibelle("Événements Organisés"); - obj3.setRealise("42"); - obj3.setCible("50"); - obj3.setPourcentage(84); - objectifs.add(obj3); - - Objectif obj4 = new Objectif(); - obj4.setLibelle("Aides Accordées"); - obj4.setRealise("156"); - obj4.setCible("200"); - obj4.setPourcentage(78); - objectifs.add(obj4); + try { + int totalMembres = membreService.listerTous().size(); + int totalEvenements = evenementService.listerTous(0, 1000).size(); + int totalDemandes = demandeAideService.listerToutes(0, 1000).size(); + + BigDecimal totalRevenus = cotisationService.listerToutes(0, 1000).stream() + .filter(c -> "PAYEE".equals(c.getStatut()) || "PARTIELLEMENT_PAYEE".equals(c.getStatut())) + .map(c -> c.getMontantPaye() != null ? c.getMontantPaye() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + Objectif obj1 = new Objectif(); + obj1.setLibelle("Nouveaux Membres"); + obj1.setRealise(String.valueOf(totalMembres)); + obj1.setCible(String.valueOf((int) (totalMembres * 1.2))); // Objectif 20% supérieur + obj1.setPourcentage(totalMembres > 0 ? (int) ((double) totalMembres / (totalMembres * 1.2) * 100) : 0); + objectifs.add(obj1); + + Objectif obj2 = new Objectif(); + obj2.setLibelle("Revenus Cotisations"); + obj2.setRealise(formatMontantCourt(totalRevenus)); + obj2.setCible(formatMontantCourt(totalRevenus.multiply(new BigDecimal("1.2")))); + obj2.setPourcentage(83); // À calculer + objectifs.add(obj2); + + Objectif obj3 = new Objectif(); + obj3.setLibelle("Événements Organisés"); + obj3.setRealise(String.valueOf(totalEvenements)); + obj3.setCible(String.valueOf((int) (totalEvenements * 1.2))); + obj3.setPourcentage(totalEvenements > 0 ? (int) ((double) totalEvenements / (totalEvenements * 1.2) * 100) : 0); + objectifs.add(obj3); + + Objectif obj4 = new Objectif(); + obj4.setLibelle("Aides Accordées"); + obj4.setRealise(String.valueOf(totalDemandes)); + obj4.setCible(String.valueOf((int) (totalDemandes * 1.3))); + obj4.setPourcentage(totalDemandes > 0 ? (int) ((double) totalDemandes / (totalDemandes * 1.3) * 100) : 0); + objectifs.add(obj4); + } catch (Exception e) { + LOGGER.severe("Erreur lors du calcul des objectifs: " + e.getMessage()); + } + } + + private String formatMontantCourt(BigDecimal montant) { + if (montant == null) return "0"; + double millions = montant.doubleValue() / 1_000_000.0; + if (millions >= 1) { + return String.format("%.1fM", millions); + } + return String.format("%.0fK", montant.doubleValue() / 1_000.0); } private void initializeRepartitions() { repartitionMembres = new ArrayList<>(); - - RepartitionMembres actifs = new RepartitionMembres(); - actifs.setLibelle("Membres Actifs"); - actifs.setNombre(987); - actifs.setPourcentage(79.2); - actifs.setCouleur("green-500"); - repartitionMembres.add(actifs); - - RepartitionMembres inactifs = new RepartitionMembres(); - inactifs.setLibelle("Membres Inactifs"); - inactifs.setNombre(185); - inactifs.setPourcentage(14.8); - inactifs.setCouleur("orange-500"); - repartitionMembres.add(inactifs); - - RepartitionMembres nouveaux = new RepartitionMembres(); - nouveaux.setLibelle("Nouveaux Membres"); - nouveaux.setNombre(75); - nouveaux.setPourcentage(6.0); - nouveaux.setCouleur("blue-500"); - repartitionMembres.add(nouveaux); + try { + List membres = membreService.listerTous(); + long actifs = membres.stream().filter(m -> "ACTIF".equals(m.getStatut())).count(); + long inactifs = membres.stream().filter(m -> "INACTIF".equals(m.getStatut())).count(); + long total = membres.size(); + + if (total > 0) { + RepartitionMembres actifsRep = new RepartitionMembres(); + actifsRep.setLibelle("Membres Actifs"); + actifsRep.setNombre((int) actifs); + actifsRep.setPourcentage((double) actifs / total * 100.0); + actifsRep.setCouleur("green-500"); + repartitionMembres.add(actifsRep); + + RepartitionMembres inactifsRep = new RepartitionMembres(); + inactifsRep.setLibelle("Membres Inactifs"); + inactifsRep.setNombre((int) inactifs); + inactifsRep.setPourcentage((double) inactifs / total * 100.0); + inactifsRep.setCouleur("orange-500"); + repartitionMembres.add(inactifsRep); + } + } catch (Exception e) { + LOGGER.severe("Erreur lors du calcul de la répartition des membres: " + e.getMessage()); + } sourceRevenus = new ArrayList<>(); - - SourceRevenus cotisations = new SourceRevenus(); - cotisations.setLibelle("Cotisations"); - cotisations.setMontant("28.5M FCFA"); - cotisations.setPourcentage(62.3); - cotisations.setCouleur("blue-500"); - cotisations.setIcon("pi-users"); - sourceRevenus.add(cotisations); - - SourceRevenus evenements = new SourceRevenus(); - evenements.setLibelle("Événements"); - evenements.setMontant("12.8M FCFA"); - evenements.setPourcentage(28.0); - evenements.setCouleur("green-500"); - evenements.setIcon("pi-calendar"); - sourceRevenus.add(evenements); - - SourceRevenus dons = new SourceRevenus(); - dons.setLibelle("Dons & Subventions"); - dons.setMontant("4.4M FCFA"); - dons.setPourcentage(9.7); - dons.setCouleur("purple-500"); - dons.setIcon("pi-heart"); - sourceRevenus.add(dons); + try { + BigDecimal totalRevenus = cotisationService.listerToutes(0, 1000).stream() + .filter(c -> "PAYEE".equals(c.getStatut()) || "PARTIELLEMENT_PAYEE".equals(c.getStatut())) + .map(c -> c.getMontantPaye() != null ? c.getMontantPaye() : BigDecimal.ZERO) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + if (totalRevenus.compareTo(BigDecimal.ZERO) > 0) { + SourceRevenus cotisations = new SourceRevenus(); + cotisations.setLibelle("Cotisations"); + cotisations.setMontant(formatMontantCourt(totalRevenus)); + cotisations.setPourcentage(100.0); // Pour l'instant, uniquement cotisations + cotisations.setCouleur("blue-500"); + cotisations.setIcon("pi-users"); + sourceRevenus.add(cotisations); + } + } catch (Exception e) { + LOGGER.severe("Erreur lors du calcul des sources de revenus: " + e.getMessage()); + } } private void initializeTopEntites() { topEntites = new ArrayList<>(); - - String[] noms = { - "Association Alpha Centrale", "Club Beta Régional", "Groupe Gamma Local", - "Association Delta Nord", "Club Epsilon Sud" - }; - - String[] icons = {"pi-users", "pi-home", "pi-sitemap", "pi-users", "pi-home"}; - int[] scores = {95, 89, 84, 78, 72}; - String[] tendances = {"UP", "UP", "STABLE", "DOWN", "UP"}; - - for (int i = 0; i < noms.length; i++) { - TopEntite entite = new TopEntite(); - entite.setRang(i + 1); - entite.setNom(noms[i]); - entite.setTypeIcon(icons[i]); - entite.setScore(scores[i]); - entite.setTendance(tendances[i]); - topEntites.add(entite); + try { + List associations = associationService.listerActives(); + topEntites = associations.stream() + .sorted((a1, a2) -> { + int m1 = a1.getNombreMembres() != null ? a1.getNombreMembres() : 0; + int m2 = a2.getNombreMembres() != null ? a2.getNombreMembres() : 0; + return Integer.compare(m2, m1); + }) + .limit(5) + .map(a -> { + TopEntite entite = new TopEntite(); + entite.setRang(0); // À calculer + entite.setNom(a.getNom()); + entite.setTypeIcon("pi-users"); + entite.setScore(0); // À calculer depuis les métriques + entite.setTendance("STABLE"); // À calculer + return entite; + }) + .collect(java.util.stream.Collectors.toList()); + + // Assigner les rangs + for (int i = 0; i < topEntites.size(); i++) { + topEntites.get(i).setRang(i + 1); + } + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des top entités: " + e.getMessage()); } } private void initializeKPIs() { kpis = new ArrayList<>(); - - KPI participation = new KPI(); - participation.setLibelle("Taux de Participation"); - participation.setValeur("84%"); - participation.setProgression(84); - participation.setVariation(5.2); - participation.setTendance("UP"); - participation.setIcon("pi-users"); - participation.setCouleur("blue-500"); - kpis.add(participation); - - KPI satisfaction = new KPI(); - satisfaction.setLibelle("Satisfaction Membres"); - satisfaction.setValeur("92%"); - satisfaction.setProgression(92); - satisfaction.setVariation(3.1); - satisfaction.setTendance("UP"); - satisfaction.setIcon("pi-star"); - satisfaction.setCouleur("green-500"); - kpis.add(satisfaction); - - KPI retention = new KPI(); - retention.setLibelle("Taux de Rétention"); - retention.setValeur("88%"); - retention.setProgression(88); - retention.setVariation(-1.8); - retention.setTendance("DOWN"); - retention.setIcon("pi-refresh"); - retention.setCouleur("orange-500"); - kpis.add(retention); - - KPI croissance = new KPI(); - croissance.setLibelle("Croissance Mensuelle"); - croissance.setValeur("2.1%"); - croissance.setProgression(75); - croissance.setVariation(0.8); - croissance.setTendance("UP"); - croissance.setIcon("pi-chart-line"); - croissance.setCouleur("purple-500"); - kpis.add(croissance); + try { + if (organisationId != null && dateDebut != null && dateFin != null) { + String periode = "CUSTOM"; // À mapper depuis dateDebut/dateFin + analyticsService.getKPIs(organisationId, periode); + // Traiter les données de l'API + // Pour l'instant, laisser la liste vide plutôt que des données mockées + } + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des KPIs: " + e.getMessage()); + } } private void initializeAlertes() { alertes = new ArrayList<>(); - - Alerte baisseCotisations = new Alerte(); - baisseCotisations.setTitre("Baisse des Cotisations"); - baisseCotisations.setDescription("Les cotisations ont diminué de 8% ce mois-ci par rapport au mois précédent."); - baisseCotisations.setPriorite("HAUTE"); - baisseCotisations.setSeverite("warning"); - baisseCotisations.setSeveriteCouleur("orange-500"); - baisseCotisations.setIcon("pi-exclamation-triangle"); - baisseCotisations.setDateDetection("Il y a 2 jours"); - alertes.add(baisseCotisations); - - Alerte objectifManque = new Alerte(); - objectifManque.setTitre("Objectif Membres Non Atteint"); - objectifManque.setDescription("L'objectif de nouveaux membres risque de ne pas être atteint ce trimestre."); - objectifManque.setPriorite("MOYENNE"); - objectifManque.setSeverite("info"); - objectifManque.setSeveriteCouleur("blue-500"); - objectifManque.setIcon("pi-info-circle"); - objectifManque.setDateDetection("Il y a 5 jours"); - alertes.add(objectifManque); - - Alerte budgetDepasse = new Alerte(); - budgetDepasse.setTitre("Budget Événements Dépassé"); - budgetDepasse.setDescription("Le budget alloué aux événements a été dépassé de 15% ce mois-ci."); - budgetDepasse.setPriorite("CRITIQUE"); - budgetDepasse.setSeverite("danger"); - budgetDepasse.setSeveriteCouleur("red-500"); - budgetDepasse.setIcon("pi-exclamation-circle"); - budgetDepasse.setDateDetection("Hier"); - alertes.add(budgetDepasse); - - Alerte performance = new Alerte(); - performance.setTitre("Performance Excellente"); - performance.setDescription("Félicitations ! La satisfaction des membres a atteint un niveau record de 92%."); - performance.setPriorite("INFO"); - performance.setSeverite("success"); - performance.setSeveriteCouleur("green-500"); - performance.setIcon("pi-check-circle"); - performance.setDateDetection("Il y a 1 semaine"); - alertes.add(performance); + // Les alertes seront calculées depuis les données réelles + // Pour l'instant, laisser la liste vide plutôt que des données mockées } private void initializeHistoriqueRapports() { historiqueRapports = new ArrayList<>(); - - String[] types = {"FINANCIER", "MEMBRES", "ACTIVITES", "PERFORMANCE", "COMPLET"}; - String[] typesLibelles = {"Rapport Financier", "Rapport Membres", "Rapport Activités", "Rapport Performance", "Rapport Complet"}; - String[] typeIcons = {"pi-dollar", "pi-users", "pi-calendar", "pi-chart-bar", "pi-file"}; - String[] typeCouleurs = {"green-500", "blue-500", "orange-500", "purple-500", "indigo-500"}; - String[] generesPar = {"Marie Kouassi", "Paul Traoré", "Fatou Sanogo", "Jean Ouattara", "Aissata Koné"}; - String[] statuts = {"GENERE", "EN_COURS", "GENERE", "GENERE", "PLANIFIE"}; - - for (int i = 0; i < 15; i++) { - HistoriqueRapport rapport = new HistoriqueRapport(); - rapport.setId((long) (i + 1)); - rapport.setType(types[i % types.length]); - rapport.setTypeLibelle(typesLibelles[i % typesLibelles.length]); - rapport.setTypeIcon(typeIcons[i % typeIcons.length]); - rapport.setTypeCouleur(typeCouleurs[i % typeCouleurs.length]); - rapport.setDateGeneration(LocalDate.now().minusDays(i * 7 + 1)); - rapport.setPeriodeCouverte(getDescriptionPeriode(i)); - rapport.setGenerePar(generesPar[i % generesPar.length]); - rapport.setStatut(statuts[i % statuts.length]); - historiqueRapports.add(rapport); - } - } - - private String getDescriptionPeriode(int index) { - return switch (index % 5) { - case 0 -> "Dernières 4 semaines"; - case 1 -> "Trimestre en cours"; - case 2 -> "6 derniers mois"; - case 3 -> "Année en cours"; - default -> "Période personnalisée"; - }; + // L'historique des rapports sera chargé depuis la base de données + // Pour l'instant, laisser la liste vide plutôt que des données mockées } private void initializeNouveauRapport() { @@ -322,10 +311,10 @@ public class RapportsBean implements Serializable { // Actions public void genererRapport() { - System.out.println("Génération du rapport " + nouveauRapport.getType() + " en format " + nouveauRapport.getFormat()); + LOGGER.info("Génération du rapport " + nouveauRapport.getType() + " en format " + nouveauRapport.getFormat()); HistoriqueRapport nouveauHistorique = new HistoriqueRapport(); - nouveauHistorique.setId((long) (historiqueRapports.size() + 1)); + nouveauHistorique.setId(UUID.randomUUID()); nouveauHistorique.setType(nouveauRapport.getType()); nouveauHistorique.setTypeLibelle(getTypeLibelle(nouveauRapport.getType())); nouveauHistorique.setTypeIcon(getTypeIcon(nouveauRapport.getType())); @@ -389,11 +378,11 @@ public class RapportsBean implements Serializable { } public void telechargerRapport(HistoriqueRapport rapport) { - System.out.println("Téléchargement du rapport: " + rapport.getTypeLibelle()); + LOGGER.info("Téléchargement du rapport: " + rapport.getTypeLibelle()); } public void exporterDonnees() { - System.out.println("Export des données statistiques"); + LOGGER.info("Export des données statistiques"); } // Getters et Setters @@ -656,7 +645,7 @@ public class RapportsBean implements Serializable { } public static class HistoriqueRapport { - private Long id; + private UUID id; private String type; private String typeLibelle; private String typeIcon; @@ -667,8 +656,8 @@ public class RapportsBean implements Serializable { private String statut; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getType() { return type; } public void setType(String type) { this.type = type; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SouscriptionBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SouscriptionBean.java index f89ce07..581e9f9 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SouscriptionBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SouscriptionBean.java @@ -1,20 +1,30 @@ package dev.lions.unionflow.client.view; -import dev.lions.unionflow.client.dto.AssociationDTO; -import dev.lions.unionflow.client.dto.FormulaireDTO; import dev.lions.unionflow.client.dto.SouscriptionDTO; +import dev.lions.unionflow.client.service.SouscriptionService; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; +import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; -import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.UUID; +import java.util.logging.Logger; @Named("souscriptionBean") @SessionScoped public class SouscriptionBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(SouscriptionBean.class.getName()); + + @Inject + @RestClient + private SouscriptionService souscriptionService; + + private UUID organisationId; // À injecter depuis la session private List souscriptionsOrganisation; private SouscriptionDTO souscriptionActive; @@ -31,33 +41,31 @@ public class SouscriptionBean implements Serializable { private boolean alerteQuotaProche = false; private int joursAvantExpiration = 0; - public SouscriptionBean() { - initializeData(); + @PostConstruct + public void init() { + if (organisationId != null) { + initializeData(); + } else { + LOGGER.warning("Aucun organisationId fourni, impossible de charger les souscriptions"); + souscriptionsOrganisation = new ArrayList<>(); + } } private void initializeData() { - // Simulation d'une souscription active pour démonstration - souscriptionActive = new SouscriptionDTO(); - souscriptionActive.setId(1L); - souscriptionActive.setOrganisationId(1L); - souscriptionActive.setOrganisationNom("LIONS CLUB Dakar Métropole"); - souscriptionActive.setFormulaireId(2L); - souscriptionActive.setFormulaireNom("Standard"); - souscriptionActive.setStatut(SouscriptionDTO.StatutSouscription.ACTIVE); - souscriptionActive.setTypeFacturation(SouscriptionDTO.TypeFacturation.ANNUEL); - souscriptionActive.setDateDebut(LocalDate.now().minusMonths(3)); - souscriptionActive.setDateFin(LocalDate.now().plusMonths(9)); - souscriptionActive.setQuotaMaxMembres(200); - souscriptionActive.setMembresActuels(87); - souscriptionActive.setMontantSouscription(new java.math.BigDecimal("30000")); - souscriptionActive.setNotificationExpiration(true); - souscriptionActive.setNotificationQuotaAtteint(true); - - // Calculer les statistiques - updateStatistiques(); - - souscriptionsOrganisation = new ArrayList<>(); - souscriptionsOrganisation.add(souscriptionActive); + try { + souscriptionsOrganisation = souscriptionService.listerToutes(organisationId, 0, 100); + souscriptionActive = souscriptionService.obtenirActive(organisationId); + if (souscriptionActive == null && !souscriptionsOrganisation.isEmpty()) { + souscriptionActive = souscriptionsOrganisation.stream() + .filter(s -> s.getStatut() == SouscriptionDTO.StatutSouscription.ACTIVE) + .findFirst() + .orElse(null); + } + updateStatistiques(); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des souscriptions: " + e.getMessage()); + souscriptionsOrganisation = new ArrayList<>(); + } } private void updateStatistiques() { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SuperAdminBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SuperAdminBean.java index bc8c08d..9a43577 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SuperAdminBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SuperAdminBean.java @@ -1,8 +1,12 @@ package dev.lions.unionflow.client.view; +import dev.lions.unionflow.client.dto.AssociationDTO; +import dev.lions.unionflow.client.service.AssociationService; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; import java.math.BigDecimal; import java.time.LocalDate; @@ -10,12 +14,19 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; +import java.util.UUID; +import java.util.logging.Logger; @Named("superAdminBean") @SessionScoped public class SuperAdminBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(SuperAdminBean.class.getName()); + + @Inject + @RestClient + private AssociationService associationService; private String nomComplet; private String derniereConnexion; @@ -71,31 +82,43 @@ public class SuperAdminBean implements Serializable { } private void initializeKPIs() { - totalEntites = 127; // Ajusté avec la stratégie volume - totalAdministrateurs = 127; - totalMembres = 18547; // Moyenne 146 membres par entité - revenusGlobaux = "363 000 FCFA"; - alertesCount = 8; - croissanceEntites = "12"; - activiteJournaliere = 1247; - - // Initialiser les métriques de souscription - totalSouscriptions = 127; - souscriptionsActives = 127; - souscriptionsExpirantSous30Jours = 12; - tauxConversion = 68.5f; - - // Revenus par forfait - nouvelle grille tarifaire - revenusStarter = new BigDecimal("88000"); // 44 organisations * 2000 FCFA - revenusStandard = new BigDecimal("180000"); // 60 organisations * 3000 FCFA - revenusPremmium = new BigDecimal("80000"); // 20 organisations * 4000 FCFA - revenusCristal = new BigDecimal("15000"); // 3 organisations * 5000 FCFA - - // Métriques système - disponibiliteSysteme = 99.8f; - tempsReponsMoyen = 145; // ms - ticketsSupportOuverts = 8; - satisfactionClient = 4.7f; // /5 + try { + List associations = associationService.listerToutes(); + totalEntites = associations.size(); + totalAdministrateurs = associations.size(); // À calculer depuis les utilisateurs + int totalMembresCalc = associations.stream() + .mapToInt(a -> a.getNombreMembres() != null ? a.getNombreMembres() : 0) + .sum(); + totalMembres = totalMembresCalc; + revenusGlobaux = "0 FCFA"; // À calculer depuis les souscriptions + alertesCount = 0; // À calculer + croissanceEntites = "0"; // À calculer + activiteJournaliere = 0; // À calculer + + // Initialiser les métriques de souscription + totalSouscriptions = 0; // À calculer depuis les souscriptions + souscriptionsActives = 0; // À calculer + souscriptionsExpirantSous30Jours = 0; // À calculer + tauxConversion = 0.0f; // À calculer + + // Revenus par forfait - À calculer depuis les souscriptions + revenusStarter = BigDecimal.ZERO; + revenusStandard = BigDecimal.ZERO; + revenusPremmium = BigDecimal.ZERO; + revenusCristal = BigDecimal.ZERO; + + // Métriques système + disponibiliteSysteme = 99.8f; + tempsReponsMoyen = 145; // ms + ticketsSupportOuverts = 0; // À calculer + satisfactionClient = 4.7f; // /5 + } catch (Exception e) { + LOGGER.severe("Erreur lors du calcul des KPIs: " + e.getMessage()); + totalEntites = 0; + totalAdministrateurs = 0; + totalMembres = 0; + revenusGlobaux = "0 FCFA"; + } } private void initializeAlertes() { @@ -103,7 +126,7 @@ public class SuperAdminBean implements Serializable { // Alertes critiques de souscription Alerte alerte1 = new Alerte(); - alerte1.setId(1L); + alerte1.setId(UUID.fromString("00000000-0000-0000-0000-00000000a001")); alerte1.setTitre("12 souscriptions expirent sous 30 jours"); alerte1.setEntite("Système - Souscriptions"); alerte1.setDate("Aujourd'hui"); @@ -112,7 +135,7 @@ public class SuperAdminBean implements Serializable { alertesRecentes.add(alerte1); Alerte alerte2 = new Alerte(); - alerte2.setId(2L); + alerte2.setId(UUID.fromString("00000000-0000-0000-0000-00000000a002")); alerte2.setTitre("Quota membre atteint"); alerte2.setEntite("Club Sportif Thiès (Standard)"); alerte2.setDate("Il y a 2h"); @@ -121,7 +144,7 @@ public class SuperAdminBean implements Serializable { alertesRecentes.add(alerte2); Alerte alerte3 = new Alerte(); - alerte3.setId(3L); + alerte3.setId(UUID.fromString("00000000-0000-0000-0000-00000000a003")); alerte3.setTitre("Pic d'inscriptions détecté"); alerte3.setEntite("Association des Femmes Kaolack"); alerte3.setDate("Il y a 4h"); @@ -130,7 +153,7 @@ public class SuperAdminBean implements Serializable { alertesRecentes.add(alerte3); Alerte alerte4 = new Alerte(); - alerte4.setId(4L); + alerte4.setId(UUID.fromString("00000000-0000-0000-0000-00000000a004")); alerte4.setTitre("Performance système dégradée"); alerte4.setEntite("Système - Infrastructure"); alerte4.setDate("Il y a 6h"); @@ -139,7 +162,7 @@ public class SuperAdminBean implements Serializable { alertesRecentes.add(alerte4); Alerte alerte5 = new Alerte(); - alerte5.setId(5L); + alerte5.setId(UUID.fromString("00000000-0000-0000-0000-00000000a005")); alerte5.setTitre("Demande d'upgrade Premium"); alerte5.setEntite("Mutuelle Santé Dakar"); alerte5.setDate("Hier"); @@ -148,7 +171,7 @@ public class SuperAdminBean implements Serializable { alertesRecentes.add(alerte5); Alerte alerte6 = new Alerte(); - alerte6.setId(6L); + alerte6.setId(UUID.fromString("00000000-0000-0000-0000-00000000a006")); alerte6.setTitre("8 tickets support en attente"); alerte6.setEntite("Support Client"); alerte6.setDate("Il y a 1h"); @@ -159,18 +182,26 @@ public class SuperAdminBean implements Serializable { private void initializeEntites() { topEntites = new ArrayList<>(); - - String[] noms = {"LIONS CLUB Dakar Métropole", "LIONS CLUB Thiès", "LIONS CLUB Kaolack", "LIONS CLUB Saint-Louis", "LIONS CLUB Ziguinchor"}; - String[] types = {"Club Principal", "Club Régional", "Club Régional", "Club Régional", "Club Régional"}; - int[] membres = {156, 123, 98, 87, 73}; - - for (int i = 0; i < 5; i++) { - Entite entite = new Entite(); - entite.setId((long) (i + 1)); - entite.setNom(noms[i]); - entite.setTypeEntite(types[i]); - entite.setNombreMembres(membres[i]); - topEntites.add(entite); + try { + List associations = associationService.listerActives(); + topEntites = associations.stream() + .sorted((a1, a2) -> { + int m1 = a1.getNombreMembres() != null ? a1.getNombreMembres() : 0; + int m2 = a2.getNombreMembres() != null ? a2.getNombreMembres() : 0; + return Integer.compare(m2, m1); + }) + .limit(5) + .map(a -> { + Entite entite = new Entite(); + entite.setId(a.getId()); + entite.setNom(a.getNom()); + entite.setTypeEntite(a.getTypeAssociation()); + entite.setNombreMembres(a.getNombreMembres() != null ? a.getNombreMembres() : 0); + return entite; + }) + .collect(java.util.stream.Collectors.toList()); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des top entités: " + e.getMessage()); } } @@ -245,7 +276,7 @@ public class SuperAdminBean implements Serializable { for (int i = 0; i < 5; i++) { Activite activite = new Activite(); - activite.setId((long) (i + 1)); + activite.setId(UUID.randomUUID()); activite.setDescription(descriptions[i]); activite.setEntite(entites[i]); activite.setIcone(icones[i]); @@ -320,7 +351,7 @@ public class SuperAdminBean implements Serializable { } public void voirAlerte(Alerte alerte) { - System.out.println("Voir alerte: " + alerte.getTitre()); + LOGGER.info("Voir alerte: " + alerte.getTitre()); } public String voirToutesAlertes() { @@ -332,7 +363,7 @@ public class SuperAdminBean implements Serializable { } public void exporterRapportFinancier() { - System.out.println("Export du rapport financier généré"); + LOGGER.info("Export du rapport financier généré"); } // Getters et Setters @@ -452,7 +483,7 @@ public class SuperAdminBean implements Serializable { // Classes internes public static class Alerte { - private Long id; + private UUID id; private String titre; private String entite; private String date; @@ -460,8 +491,8 @@ public class SuperAdminBean implements Serializable { private String couleur; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getTitre() { return titre; } public void setTitre(String titre) { this.titre = titre; } @@ -480,14 +511,14 @@ public class SuperAdminBean implements Serializable { } public static class Entite { - private Long id; + private UUID id; private String nom; private String typeEntite; private int nombreMembres; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } @@ -532,7 +563,7 @@ public class SuperAdminBean implements Serializable { } public static class Activite { - private Long id; + private UUID id; private String description; private String entite; private String date; @@ -541,8 +572,8 @@ public class SuperAdminBean implements Serializable { private String details; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/UserSession.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/UserSession.java index f08be94..9c09e67 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/UserSession.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/UserSession.java @@ -1,12 +1,21 @@ package dev.lions.unionflow.client.view; -import dev.lions.unionflow.client.dto.auth.LoginResponse; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; +import org.eclipse.microprofile.jwt.JsonWebToken; import java.io.Serializable; +import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.logging.Logger; +/** + * Gestion de la session utilisateur avec Keycloak OIDC + * + * @author UnionFlow Team + * @version 2.0 + */ @Named("userSession") @SessionScoped public class UserSession implements Serializable { @@ -14,6 +23,9 @@ public class UserSession implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(UserSession.class.getName()); + @Inject + private JsonWebToken jwt; + private String username; private boolean authenticated = false; private String typeCompte; @@ -27,39 +39,149 @@ public class UserSession implements Serializable { clearSession(); } - public void updateFromLoginResponse(LoginResponse loginResponse) { - if (loginResponse != null && loginResponse.getUser() != null) { - LoginResponse.UserInfo userInfo = loginResponse.getUser(); - + /** + * Initialise la session depuis le token OIDC Keycloak + * Appelé automatiquement après l'authentification + */ + public void initializeFromOidcToken() { + if (jwt != null && jwt.getName() != null) { this.authenticated = true; - this.username = userInfo.getUsername(); - this.typeCompte = userInfo.getTypeCompte(); - this.roles = userInfo.getRoles(); - this.permissions = userInfo.getPermissions(); + this.username = jwt.getClaim("preferred_username"); + if (this.username == null) { + this.username = jwt.getName(); + } + + // Récupérer les informations du token + String email = jwt.getClaim("email"); + String givenName = jwt.getClaim("given_name"); + String familyName = jwt.getClaim("family_name"); + + // Récupérer les rôles depuis le token + this.roles = extractRolesFromToken(); + this.typeCompte = determineTypeCompte(); // Mettre à jour les informations utilisateur this.currentUser = new CurrentUser(); - this.currentUser.setId(userInfo.getId()); - this.currentUser.setNom(userInfo.getNom()); - this.currentUser.setPrenom(userInfo.getPrenom()); - this.currentUser.setEmail(userInfo.getEmail()); - this.currentUser.setUsername(userInfo.getUsername()); + this.currentUser.setUsername(this.username); + this.currentUser.setEmail(email); + this.currentUser.setPrenom(givenName); + this.currentUser.setNom(familyName); - // Mettre à jour les informations de l'entité - if (userInfo.getEntite() != null) { - this.entite = new EntiteInfo(); - this.entite.setId(userInfo.getEntite().getId()); - this.entite.setNom(userInfo.getEntite().getNom()); - this.entite.setType(userInfo.getEntite().getType()); - this.entite.setPays(userInfo.getEntite().getPays()); - this.entite.setVille(userInfo.getEntite().getVille()); + // Générer un ID depuis le subject du token + String subject = jwt.getSubject(); + if (subject != null) { + try { + this.currentUser.setId(UUID.fromString(subject)); + } catch (IllegalArgumentException e) { + // Si le subject n'est pas un UUID, générer un UUID déterministe + this.currentUser.setId(UUID.nameUUIDFromBytes(subject.getBytes())); + } } - LOGGER.info("Session utilisateur mise à jour pour: " + userInfo.getUsername() + + LOGGER.info("Session utilisateur initialisée depuis Keycloak pour: " + this.username + " (Type: " + typeCompte + ")"); } } + /** + * Extrait les rôles depuis le token JWT + */ + private List extractRolesFromToken() { + List extractedRoles = new ArrayList<>(); + + // Rôles dans "realm_access.roles" + try { + Object realmAccess = jwt.getClaim("realm_access"); + if (realmAccess instanceof java.util.Map) { + @SuppressWarnings("unchecked") + java.util.Map realmMap = (java.util.Map) realmAccess; + Object rolesObj = realmMap.get("roles"); + if (rolesObj instanceof List) { + @SuppressWarnings("unchecked") + List realmRoles = (List) rolesObj; + extractedRoles.addAll(realmRoles); + LOGGER.info("Rôles extraits depuis realm_access.roles: " + realmRoles); + } else { + // Fallback: si realm_access est directement une liste de rôles + if (realmAccess instanceof List) { + @SuppressWarnings("unchecked") + List realmRoles = (List) realmAccess; + extractedRoles.addAll(realmRoles); + LOGGER.info("Rôles extraits depuis realm_access (liste directe): " + realmRoles); + } + } + } else if (realmAccess instanceof List) { + // Fallback: si realm_access est directement une liste de rôles + @SuppressWarnings("unchecked") + List realmRoles = (List) realmAccess; + extractedRoles.addAll(realmRoles); + LOGGER.info("Rôles extraits depuis realm_access (liste): " + realmRoles); + } + } catch (Exception e) { + LOGGER.warning("Erreur lors de l'extraction des rôles realm: " + e.getMessage()); + } + + // Rôles dans "resource_access" + try { + Object resourceAccess = jwt.getClaim("resource_access"); + if (resourceAccess instanceof java.util.Map) { + @SuppressWarnings("unchecked") + java.util.Map resourceMap = (java.util.Map) resourceAccess; + for (Object value : resourceMap.values()) { + if (value instanceof java.util.Map) { + @SuppressWarnings("unchecked") + java.util.Map clientMap = (java.util.Map) value; + Object rolesObj = clientMap.get("roles"); + if (rolesObj instanceof List) { + @SuppressWarnings("unchecked") + List clientRoles = (List) rolesObj; + extractedRoles.addAll(clientRoles); + LOGGER.info("Rôles extraits depuis resource_access: " + clientRoles); + } + } + } + } + } catch (Exception e) { + LOGGER.warning("Erreur lors de l'extraction des rôles client: " + e.getMessage()); + } + + // Fallback: essayer d'extraire les rôles depuis le claim "roles" directement + if (extractedRoles.isEmpty()) { + try { + Object rolesClaim = jwt.getClaim("roles"); + if (rolesClaim instanceof List) { + @SuppressWarnings("unchecked") + List directRoles = (List) rolesClaim; + extractedRoles.addAll(directRoles); + LOGGER.info("Rôles extraits depuis claim 'roles': " + directRoles); + } + } catch (Exception e) { + LOGGER.warning("Erreur lors de l'extraction des rôles depuis claim 'roles': " + e.getMessage()); + } + } + + LOGGER.info("Total des rôles extraits: " + extractedRoles); + return extractedRoles; + } + + /** + * Détermine le type de compte depuis les rôles + */ + private String determineTypeCompte() { + if (roles == null || roles.isEmpty()) { + return "MEMBRE"; + } + + if (roles.contains("SUPER_ADMIN") || roles.contains("super-admin")) { + return "SUPER_ADMIN"; + } + if (roles.contains("ADMIN") || roles.contains("admin") || roles.contains("ADMIN_ENTITE")) { + return "ADMIN_ENTITE"; + } + + return "MEMBRE"; + } + public void clearSession() { this.authenticated = false; this.username = null; @@ -120,7 +242,11 @@ public class UserSession implements Serializable { } public boolean isAuthenticated() { - return authenticated; + // Vérifier via JsonWebToken + if (jwt != null && jwt.getName() != null && !authenticated) { + initializeFromOidcToken(); + } + return authenticated || (jwt != null && jwt.getName() != null); } public void setAuthenticated(boolean authenticated) { @@ -169,7 +295,7 @@ public class UserSession implements Serializable { // Classes internes public static class CurrentUser implements Serializable { - private Long id; + private UUID id; private String nom; private String prenom; private String email; @@ -194,11 +320,11 @@ public class UserSession implements Serializable { } // Getters et Setters - public Long getId() { + public UUID getId() { return id; } - public void setId(Long id) { + public void setId(UUID id) { this.id = id; } @@ -236,7 +362,7 @@ public class UserSession implements Serializable { } public static class EntiteInfo implements Serializable { - private Long id; + private UUID id; private String nom; private String type; private String pays; @@ -254,11 +380,11 @@ public class UserSession implements Serializable { } // Getters et Setters - public Long getId() { + public UUID getId() { return id; } - public void setId(Long id) { + public void setId(UUID id) { this.id = id; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/UtilisateursBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/UtilisateursBean.java index 00142e4..bc78147 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/UtilisateursBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/UtilisateursBean.java @@ -1,21 +1,32 @@ package dev.lions.unionflow.client.view; +import dev.lions.unionflow.client.dto.AssociationDTO; +import dev.lions.unionflow.client.service.AssociationService; import jakarta.enterprise.context.SessionScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; +import org.eclipse.microprofile.rest.client.inject.RestClient; import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.List; +import java.util.UUID; import java.util.stream.Collectors; +import java.util.logging.Logger; @Named("utilisateursBean") @SessionScoped public class UtilisateursBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(UtilisateursBean.class.getName()); + + @Inject + @RestClient + private AssociationService associationService; private List tousLesUtilisateurs; private List utilisateursFiltres; @@ -30,9 +41,9 @@ public class UtilisateursBean implements Serializable { @PostConstruct public void init() { initializeFiltres(); - initializeStatistiques(); initializeOrganisations(); initializeUtilisateurs(); + initializeStatistiques(); initializeNouvelUtilisateur(); appliquerFiltres(); } @@ -44,77 +55,33 @@ public class UtilisateursBean implements Serializable { private void initializeStatistiques() { statistiques = new StatistiquesUtilisateurs(); - statistiques.setTotalUtilisateurs(47); - statistiques.setUtilisateursConnectes(12); - statistiques.setAdministrateurs(8); - statistiques.setUtilisateursDesactives(3); + // Les statistiques seront calculées depuis l'API backend quand elle sera disponible + statistiques.setTotalUtilisateurs(tousLesUtilisateurs != null ? tousLesUtilisateurs.size() : 0); + statistiques.setUtilisateursConnectes(0); + statistiques.setAdministrateurs(0); + statistiques.setUtilisateursDesactives(0); } private void initializeOrganisations() { organisationsDisponibles = new ArrayList<>(); - - Organisation org1 = new Organisation(); - org1.setId(1L); - org1.setNom("Direction Générale"); - organisationsDisponibles.add(org1); - - Organisation org2 = new Organisation(); - org2.setId(2L); - org2.setNom("Services Financiers"); - organisationsDisponibles.add(org2); - - Organisation org3 = new Organisation(); - org3.setId(3L); - org3.setNom("Ressources Humaines"); - organisationsDisponibles.add(org3); - - Organisation org4 = new Organisation(); - org4.setId(4L); - org4.setNom("Communication"); - organisationsDisponibles.add(org4); + try { + List associations = associationService.listerActives(); + for (AssociationDTO assoc : associations) { + Organisation org = new Organisation(); + org.setId(assoc.getId()); + org.setNom(assoc.getNom()); + organisationsDisponibles.add(org); + } + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des organisations: " + e.getMessage()); + } } private void initializeUtilisateurs() { tousLesUtilisateurs = new ArrayList<>(); - - String[] noms = { - "Koffi", "Asante", "Mensah", "Diallo", "Touré", "Koné", "Ouattara", "Traoré", - "Sanogo", "Bakayoko", "Coulibaly", "Cissé", "Gyamfi", "Adjei", "Akoto", - "Boateng", "Ofori", "Owusu", "Asamoah", "Yeboah" - }; - - String[] prenoms = { - "Kwame", "Ama", "Kofi", "Akosua", "Yaw", "Adwoa", "Kweku", "Afia", - "Kwadwo", "Akua", "Yaa", "Kwabena", "Efua", "Kojo", "Ama", - "Kwesi", "Esi", "Kwaku", "Abena", "Fiifi" - }; - - String[] roles = {"USER", "GESTIONNAIRE", "ADMIN", "SUPER_ADMIN"}; - String[] statuts = {"ACTIF", "INACTIF", "SUSPENDU", "ATTENTE"}; - - for (int i = 0; i < 30; i++) { - Utilisateur utilisateur = new Utilisateur(); - utilisateur.setId((long) (i + 1)); - utilisateur.setNom(noms[i % noms.length]); - utilisateur.setPrenom(prenoms[i % prenoms.length]); - utilisateur.setEmail(prenoms[i % prenoms.length].toLowerCase() + "." + - noms[i % noms.length].toLowerCase() + "@unionflow.org"); - utilisateur.setTelephone("+225 " + String.format("%02d", (i % 99) + 1) + " " + - String.format("%02d", (i % 99) + 1) + " " + - String.format("%02d", (i % 99) + 1) + " " + - String.format("%02d", (i % 99) + 1)); - utilisateur.setRole(roles[i % roles.length]); - utilisateur.setStatut(statuts[i % statuts.length]); - utilisateur.setOrganisationId(organisationsDisponibles.get(i % organisationsDisponibles.size()).getId()); - utilisateur.setDateCreation(LocalDateTime.now().minusDays(i + 1)); - - // Dernière connexion variable - if (i % 4 != 0) { // 75% des utilisateurs ont une dernière connexion - utilisateur.setDerniereConnexion(LocalDateTime.now().minusHours(i + 1).minusMinutes(i * 5)); - } - - tousLesUtilisateurs.add(utilisateur); - } + // Les utilisateurs seront chargés depuis l'API backend quand elle sera disponible + // Pour l'instant, retourner une liste vide + LOGGER.info("Initialisation des utilisateurs - API backend non disponible"); } private void initializeNouvelUtilisateur() { @@ -170,38 +137,26 @@ public class UtilisateursBean implements Serializable { } public void creerUtilisateur() { - Utilisateur nouvelUtil = new Utilisateur(); - nouvelUtil.setId((long) (tousLesUtilisateurs.size() + 1)); - nouvelUtil.setNom(nouvelUtilisateur.getNom()); - nouvelUtil.setPrenom(nouvelUtilisateur.getPrenom()); - nouvelUtil.setEmail(nouvelUtilisateur.getEmail()); - nouvelUtil.setTelephone(nouvelUtilisateur.getTelephone()); - nouvelUtil.setRole(nouvelUtilisateur.getRole()); - nouvelUtil.setOrganisationId(nouvelUtilisateur.getOrganisationId()); - nouvelUtil.setStatut("ACTIF"); - nouvelUtil.setDateCreation(LocalDateTime.now()); - - tousLesUtilisateurs.add(nouvelUtil); - appliquerFiltres(); - - System.out.println("Nouvel utilisateur créé: " + nouvelUtil.getNomComplet()); + // À implémenter quand l'API backend sera disponible + LOGGER.info("Création d'utilisateur - API backend non disponible"); initializeNouvelUtilisateur(); } public void activerUtilisateur(Utilisateur utilisateur) { - utilisateur.setStatut("ACTIF"); - System.out.println("Utilisateur activé: " + utilisateur.getNomComplet()); + // À implémenter quand l'API backend sera disponible + LOGGER.info("Activation d'utilisateur - API backend non disponible"); appliquerFiltres(); } public void desactiverUtilisateur(Utilisateur utilisateur) { - utilisateur.setStatut("INACTIF"); - System.out.println("Utilisateur désactivé: " + utilisateur.getNomComplet()); + // À implémenter quand l'API backend sera disponible + LOGGER.info("Désactivation d'utilisateur - API backend non disponible"); appliquerFiltres(); } public void exporterUtilisateurs() { - System.out.println("Export de " + utilisateursFiltres.size() + " utilisateurs"); + // À implémenter quand l'API backend sera disponible + LOGGER.info("Export d'utilisateurs - API backend non disponible"); } // Getters et Setters @@ -231,20 +186,20 @@ public class UtilisateursBean implements Serializable { // Classes internes public static class Utilisateur { - private Long id; + private UUID id; private String nom; private String prenom; private String email; private String telephone; private String role; private String statut; - private Long organisationId; + private UUID organisationId; private LocalDateTime dateCreation; private LocalDateTime derniereConnexion; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } @@ -264,8 +219,8 @@ public class UtilisateursBean implements Serializable { public String getStatut() { return statut; } public void setStatut(String statut) { this.statut = statut; } - public Long getOrganisationId() { return organisationId; } - public void setOrganisationId(Long organisationId) { this.organisationId = organisationId; } + public UUID getOrganisationId() { return organisationId; } + public void setOrganisationId(UUID organisationId) { this.organisationId = organisationId; } public LocalDateTime getDateCreation() { return dateCreation; } public void setDateCreation(LocalDateTime dateCreation) { this.dateCreation = dateCreation; } @@ -320,13 +275,13 @@ public class UtilisateursBean implements Serializable { public String getOrganisationNom() { // Simulation - en réalité, on ferait un lookup dans la base - return switch (organisationId.toString()) { - case "1" -> "Direction Générale"; - case "2" -> "Services Financiers"; - case "3" -> "Ressources Humaines"; - case "4" -> "Communication"; - default -> "Non définie"; - }; + if (organisationId == null) return "Non définie"; + String orgIdStr = organisationId.toString(); + if (orgIdStr.contains("000000000100")) return "Direction Générale"; + if (orgIdStr.contains("000000000200")) return "Services Financiers"; + if (orgIdStr.contains("000000000300")) return "Ressources Humaines"; + if (orgIdStr.contains("000000000400")) return "Communication"; + return "Non définie"; } public String getDateCreationFormatee() { @@ -356,7 +311,7 @@ public class UtilisateursBean implements Serializable { private String email; private String telephone; private String role; - private Long organisationId; + private UUID organisationId; private String motDePasse; private boolean envoyerEmail; @@ -376,8 +331,8 @@ public class UtilisateursBean implements Serializable { public String getRole() { return role; } public void setRole(String role) { this.role = role; } - public Long getOrganisationId() { return organisationId; } - public void setOrganisationId(Long organisationId) { this.organisationId = organisationId; } + public UUID getOrganisationId() { return organisationId; } + public void setOrganisationId(UUID organisationId) { this.organisationId = organisationId; } public String getMotDePasse() { return motDePasse; } public void setMotDePasse(String motDePasse) { this.motDePasse = motDePasse; } @@ -391,7 +346,7 @@ public class UtilisateursBean implements Serializable { private String role; private String statut; private String connexion; - private Long organisation; + private UUID organisation; // Getters et setters public String getRecherche() { return recherche; } @@ -406,8 +361,8 @@ public class UtilisateursBean implements Serializable { public String getConnexion() { return connexion; } public void setConnexion(String connexion) { this.connexion = connexion; } - public Long getOrganisation() { return organisation; } - public void setOrganisation(Long organisation) { this.organisation = organisation; } + public UUID getOrganisation() { return organisation; } + public void setOrganisation(UUID organisation) { this.organisation = organisation; } } public static class StatistiquesUtilisateurs { @@ -431,12 +386,12 @@ public class UtilisateursBean implements Serializable { } public static class Organisation { - private Long id; + private UUID id; private String nom; // Getters et setters - public Long getId() { return id; } - public void setId(Long id) { this.id = id; } + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/error/viewExpired.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/error/viewExpired.xhtml index e6646be..99638d7 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/error/viewExpired.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/error/viewExpired.xhtml @@ -63,7 +63,7 @@ + xmlns:p="http://primefaces.org/ui" + lang="fr"> - - + + + + + + + + - - UnionFlow - Plateforme de Gestion Associative - - - - - - + UnionFlow - Plateforme de Gestion Intégrée pour Mutuelles, Associations et Clubs + + + + + + + + - -
- -
- -
- - -

UnionFlow

-

- Plateforme intégrée de gestion associative
- Moderne • Sécurisée • Intuitive -

- - -
-
-
- -
-
Gestion Membres
-
-
-
- -
-
Cotisations
-
-
-
- -
-
Événements
-
-
-
- -
-
Analytics
-
-
- - -
- + +
+ +
+
+ + + - +
- - -
- - Vérification de l'authentification... -
- - -
- - © 2024 UnionFlow v1.0 - Développé par Lions Dev
- Côte d'Ivoire • Sénégal • Mali -
+
+ + + + + + + + + +
+
+ + +
+
+ UnionFlow +

Plateforme de Gestion Intégrée pour Mutuelles, Associations et Clubs
+ Simplifiez la gestion de votre organisation avec une solution complète et moderne

+ + + + + +
- - - \ No newline at end of file + +
+
+
+
+ 1 +
+ 1 +
+

Gestion des Membres

+
Inscription, profils détaillés, gestion des statuts, historique des adhésions et suivi complet de chaque membre.
+
+
+
+
+ +
+
+
+
+ 2 +
+ 2 +
+

Gestion des Cotisations

+
Types variés (mensuelle, annuelle, adhésion, événement, formation, projet, solidarité), suivi des paiements et rappels automatiques. Paiements sécurisés via Wave (bientôt disponible).
+
+ + +
+
+
+
+
+
+
+ 3 +
+ 3 +
+

Organisation
d'Événements

+
Assemblées générales, réunions, formations, conférences, ateliers, séminaires, événements sociaux avec gestion des inscriptions.
+
+
+
+
+
+
+ +
+
+
+ 4 +
+ 4 +
+

Système de Solidarité

+
Gestion complète des demandes d'aide, propositions, évaluations, suivi des statuts et coordination des actions solidaires.
+
+
+
+
+
+
+ 5 +
+ 5 +
+

Gestion des Organisations

+
Gestion des clubs et unions avec hiérarchie organisationnelle, statistiques détaillées, rapports et vue d'ensemble complète.
+
+
+
+
+
+ +
+
+ 6 +
+ 6 +
+

Analytics & Rapports

+
Tableaux de bord interactifs, KPIs en temps réel, analyses approfondies et rapports personnalisables pour une prise de décision éclairée.
+
+
+
+
+
+
+ + +
+
+ Pourquoi choisir UnionFlow ? +

Une solution pensée pour les mutuelles, associations, clubs et organisations similaires avec sécurité avancée, multi-plateforme et synchronisation temps réel.

+
+
+
+
+

Sécurité

+ 100% + Sécurisé +
    +
  • Connexion sécurisée et centralisée
  • +
  • Contrôle d'accès basé sur les rôles
  • +
  • Protection des données sensibles
  • +
  • Chiffrement des communications
  • +
+
+
+
+
+ RECOMMANDÉ +

Multi-Plateforme

+ 24/7 + Disponible +
    +
  • Application web responsive
  • +
  • Application mobile Flutter
  • +
  • iOS et Android
  • +
  • Accès depuis n'importe où
  • +
+
+
+
+
+

Cloud

+ Cloud + Moderne +
    +
  • Architecture cloud-native
  • +
  • Synchronisation temps réel
  • +
  • Sauvegarde automatique
  • +
  • Scalabilité illimitée
  • +
+
+
+
+
+ + + + + + +
+
+ + + +
+
+ + + + + + + + + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/public/login.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/public/login.xhtml deleted file mode 100644 index 799b2af..0000000 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/public/login.xhtml +++ /dev/null @@ -1,214 +0,0 @@ - - - - Connexion - UnionFlow - - -
- -
-
- -
-
- -
-

UnionFlow

-

- Plateforme de Gestion Associative -

-
- - - -
-
- - -
-
- -
-
Bienvenue !
-
Connectez-vous à votre espace UnionFlow
- - - - - - -
-
- -
-
Session expirée
-
- Votre session a expiré pour des raisons de sécurité. Veuillez vous reconnecter. -
-
-
-
-
-
- - - - - -
- - - - - - - -
- - -
- - - - -
- - -
- - -
- - -
-
- - -
- - Mot de passe oublié ? - -
- - - - - -
-
-
ou essayez en mode démo
-
-
- - -
-
- -
-
- -
-
- -
-
- - -
-
- - Votre organisation n'est pas encore inscrite ? -
-

- Découvrez UnionFlow avec une démonstration personnalisée -

- - Demander une démonstration - -
-
- - -
-
- © 2024 UnionFlow - Développé par Lions Dev -
-
- Aide - - Confidentialité - - Conditions -
-
-
-
-
-
- -
\ No newline at end of file diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/demande.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/demande.xhtml index 753de2a..f014799 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/demande.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/demande.xhtml @@ -32,8 +32,16 @@
- - + + + + + + + + + +
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/liste.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/liste.xhtml index c9716e5..cfb21a7 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/liste.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/liste.xhtml @@ -23,8 +23,14 @@ - - + + + + + + + +
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/renouvellement.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/renouvellement.xhtml index 1288eb1..0186088 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/renouvellement.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/renouvellement.xhtml @@ -24,7 +24,11 @@ - + + + + + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/validation.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/validation.xhtml index e8b6d5c..264b6a7 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/validation.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/validation.xhtml @@ -23,8 +23,16 @@ - - + + + + + + + + + + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/guide.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/guide.xhtml index 4c0c906..79bb347 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/guide.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/guide.xhtml @@ -26,13 +26,17 @@

- - + + + + + + + + + + +
@@ -145,12 +149,18 @@
- - + + + + + + + + + + + +
@@ -171,15 +181,27 @@
- - - + + + + + + + + + + + + + + + + + + + + +
@@ -325,31 +347,37 @@
- + + + + + + +
- - + + + + + + + + + + + + +
- + + + + + + +
@@ -376,7 +404,7 @@ -
+
@@ -395,7 +423,7 @@

Aucun résultat trouvé pour "#{guideBean.termeRecherche}"

-
+ diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/dashboard.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/dashboard.xhtml index c09dd7d..8e9920c 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/dashboard.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/dashboard.xhtml @@ -26,18 +26,27 @@
- - + + + + + + + + + + + + +
-
+ +
@@ -110,6 +119,7 @@
+
@@ -359,11 +369,11 @@
-
-
-
Journal d'activités
-
- + +
+
+
Journal d'activités
+
@@ -372,83 +382,105 @@ - +
-
- - -
- - - - - - - - - - -
-
- - - - -
-
#{activity.titre}
-
#{activity.description}
-
- #{activity.montant} FCFA + + +
+ + + + + + + + + +
-
- - -
- + + + + +
-
#{activity.userNom}
- #{activity.userRole} +
#{activity.titre}
+
#{activity.description}
+ +
+ #{activity.montant} FCFA +
+
-
-
- - - - -
+
+ +
+ +
+
#{activity.userNom}
+ #{activity.userRole} +
+
+
+ + + + + + +
+
+
-
-
Actions rapides
-
-
- -
-
- -
-
- -
-
- + +
+
Actions rapides
+
+
+ + + + + + + +
+
+ + + + + + + +
+
+ + + + + + + +
+
+ + + + + + + +
-
+
Tâches prioritaires
@@ -459,9 +491,11 @@
Valider #{dashboardBean.adhesionsPendantes} adhésions
Demandes en attente de validation
- + + + + +
@@ -470,9 +504,11 @@
Relancer #{dashboardBean.cotisationsRetard} cotisations
Paiements en retard
- + + + + +
@@ -481,9 +517,11 @@
Traiter #{dashboardBean.aidesEnAttente} aides
Demandes d'aide à examiner
- + + + + +
@@ -492,9 +530,11 @@
Organiser prochains événements
#{dashboardBean.evenementsAPlanifier} événements à planifier
- + + + + +
@@ -511,9 +551,13 @@ yearNavigator="true" yearRange="2020:2030"> - + + + + + + + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/inscription.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/inscription.xhtml index 4844ed9..efc7f56 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/inscription.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/inscription.xhtml @@ -177,11 +177,14 @@ #{document} - + + + + + + + + @@ -242,8 +245,13 @@
- + + + + + + +
@@ -358,28 +366,37 @@
- - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml index 98653d3..750342d 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml @@ -23,14 +23,17 @@
- - + + + + + + + + + + +
@@ -94,15 +97,22 @@ - - + + + + + + + + + + + + + + + + @@ -188,33 +198,45 @@
- - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
@@ -228,29 +250,35 @@
- - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
@@ -320,18 +348,27 @@
- - - + + + + + + + + + + + + + + + + + + + + +
@@ -370,14 +407,19 @@
- - + + + + + + + + + + + + +
@@ -408,13 +450,18 @@
- - + + + + + + + + + + + +
@@ -448,17 +495,22 @@
- + + + + +
- + + + + + +
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-icon.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-icon.xhtml new file mode 100644 index 0000000..1292588 --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-icon.xhtml @@ -0,0 +1,32 @@ + + + + + + + + + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-info.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-info.xhtml new file mode 100644 index 0000000..d3fd104 --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-info.xhtml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-primary.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-primary.xhtml new file mode 100644 index 0000000..b14994b --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-primary.xhtml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-secondary.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-secondary.xhtml new file mode 100644 index 0000000..5badd0d --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-secondary.xhtml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-success.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-success.xhtml new file mode 100644 index 0000000..de904f6 --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-success.xhtml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-warning.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-warning.xhtml new file mode 100644 index 0000000..531df4f --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/button-warning.xhtml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/footer.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/footer.xhtml index e5d4b8a..fc498d5 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/footer.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/footer.xhtml @@ -41,7 +41,10 @@ diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/rightpanel.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/rightpanel.xhtml index 0625b3e..90f6537 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/rightpanel.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/rightpanel.xhtml @@ -22,7 +22,12 @@
Mes tâches
- + + + + + +
    diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/application-dev.properties b/unionflow-client-quarkus-primefaces-freya/src/main/resources/application-dev.properties new file mode 100644 index 0000000..bbe50c1 --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/application-dev.properties @@ -0,0 +1,29 @@ +# Configuration UnionFlow Client - Profil Développement +# Ce fichier est chargé automatiquement quand le profil 'dev' est actif + +# Configuration logging pour développement +quarkus.log.category."dev.lions.unionflow".level=DEBUG +quarkus.log.category."jakarta.faces".level=INFO +quarkus.log.category."org.apache.myfaces".level=INFO +quarkus.log.category."org.primefaces".level=INFO + +# Configuration MyFaces pour développement +quarkus.myfaces.project-stage=Development +quarkus.live-reload.instrumentation=true + +# Configuration Keycloak pour développement +%dev.quarkus.oidc.enabled=true +%dev.quarkus.oidc.tls.verification=none +%dev.quarkus.oidc.authentication.redirect-path=/auth/callback +# %dev.quarkus.oidc.authentication.force-redirect-https=false # Not supported in this Quarkus version +%dev.quarkus.security.auth.enabled=true + +# Secret Keycloak pour développement (UNIQUEMENT pour dev local) +# ⚠️ ATTENTION: Ne jamais commiter ce secret en production +# En production, utiliser la variable d'environnement KEYCLOAK_CLIENT_SECRET +%dev.quarkus.oidc.credentials.secret=${KEYCLOAK_CLIENT_SECRET:7dnWMwlabtoyp08F6FIuDxzDPE5VdUF6} + +# Logging OIDC pour debug +%dev.quarkus.log.category."io.quarkus.oidc".level=DEBUG +%dev.quarkus.log.category."io.vertx.ext.auth.oidc".level=DEBUG +%dev.quarkus.log.category."io.quarkus.security".level=DEBUG diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/application-prod.properties b/unionflow-client-quarkus-primefaces-freya/src/main/resources/application-prod.properties new file mode 100644 index 0000000..4db1e6d --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/application-prod.properties @@ -0,0 +1,14 @@ +# Configuration UnionFlow Client - Profil Production +# Ce fichier est chargé automatiquement quand le profil 'prod' est actif + +# Configuration logging pour production +quarkus.log.console.level=WARN + +# Configuration MyFaces pour production +quarkus.myfaces.project-stage=Production +quarkus.myfaces.serialize-state-in-session=true + +# Configuration Keycloak pour production +%prod.quarkus.oidc.tls.verification=required +%prod.quarkus.oidc.authentication.redirect-path=/auth/callback + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/application.properties b/unionflow-client-quarkus-primefaces-freya/src/main/resources/application.properties index 2eccaca..d3020c6 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/application.properties +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/application.properties @@ -3,7 +3,7 @@ quarkus.application.name=unionflow-client quarkus.application.version=1.0.0 # Configuration HTTP -quarkus.http.port=8082 +quarkus.http.port=8086 quarkus.http.host=0.0.0.0 quarkus.http.root-path=/ quarkus.http.so-reuse-port=true @@ -28,7 +28,7 @@ quarkus.myfaces.number-of-views-in-session=50 quarkus.myfaces.number-of-sequential-views-in-session=10 quarkus.myfaces.serialize-state-in-session=false quarkus.myfaces.client-view-state-timeout=3600000 -quarkus.myfaces.view-expired-exception-handler-redirect-page=/pages/public/login.xhtml +quarkus.myfaces.view-expired-exception-handler-redirect-page=/ quarkus.myfaces.check-id-production-mode=false quarkus.myfaces.strict-xhtml-links=false quarkus.myfaces.refresh-transient-build-on-pss=true @@ -36,7 +36,9 @@ quarkus.myfaces.resource-max-time-expires=604800000 quarkus.myfaces.resource-buffer-size=2048 # PrimeFaces Configuration -primefaces.THEME=freya-blue-light +# IMPORTANT: Nous laissons PrimeFaces sans th�me par d�faut et chargeons le th�me Freya via index.xhtml/main-template.xhtml +# pour �viter tout double-chargement (ex: Saga + Freya). +primefaces.THEME=none primefaces.FONT_AWESOME=true primefaces.CLIENT_SIDE_VALIDATION=true primefaces.MOVE_SCRIPTS_TO_BOTTOM=true @@ -51,7 +53,7 @@ omnifaces.CDN_RESOURCE_HANDLER_DISABLED=true omnifaces.COMBINED_RESOURCE_HANDLER_DISABLED=false # Configuration Backend UnionFlow -unionflow.backend.url=${UNIONFLOW_BACKEND_URL:http://localhost:8080} +unionflow.backend.url=${UNIONFLOW_BACKEND_URL:http://localhost:8085} # Configuration REST Client quarkus.rest-client."unionflow-api".url=${unionflow.backend.url} @@ -62,11 +64,46 @@ quarkus.rest-client."unionflow-api".read-timeout=30000 # Gestion des erreurs REST quarkus.rest-client."unionflow-api".providers=dev.lions.unionflow.client.service.RestClientExceptionMapper -# Configuration JWT et Sécurité -unionflow.jwt.secret=${JWT_SECRET:union-flow-secret-key-very-long-and-secure-2024} -unionflow.jwt.issuer=${JWT_ISSUER:unionflow-platform} -unionflow.jwt.expiration-time=${JWT_EXPIRATION:3600} -unionflow.jwt.refresh-expiration-time=${JWT_REFRESH_EXPIRATION:86400} +# Configuration Keycloak OIDC +quarkus.oidc.enabled=true +quarkus.oidc.auth-server-url=https://security.lions.dev/realms/unionflow +quarkus.oidc.client-id=unionflow-client +quarkus.oidc.credentials.secret=${KEYCLOAK_CLIENT_SECRET} +quarkus.oidc.application-type=web-app +quarkus.oidc.authentication.redirect-path=/auth/callback +quarkus.oidc.authentication.restore-path-after-redirect=true +quarkus.oidc.authentication.scopes=openid,profile,email,roles +quarkus.oidc.token.issuer=https://security.lions.dev/realms/unionflow +quarkus.oidc.tls.verification=none +# quarkus.oidc.authentication.force-redirect-https=false # Not supported in this Quarkus version +quarkus.oidc.authentication.cookie-same-site=lax +quarkus.oidc.authentication.java-script-auto-redirect=false +quarkus.oidc.discovery-enabled=true + +# TEMPORAIRE: contourner un access token invalide (claim realm_access dupliqu�e c�t� KC) +# Pour un flux web-app, on peut s'appuyer sur l'ID Token et d�sactiver la v�rification de l'Access Token +# Les deux cl�s ci?dessous couvrent les variantes selon version de Quarkus; l'une sera ignor�e si non support�e. +# Vérification du token activée +# ✅ CORRIGÉ: Le mapper Keycloak problématique a été supprimé (17/11/2025) +# Le scope "roles" gère maintenant correctement realm_access.roles (objet unique) +quarkus.oidc.verify-access-token=true + +# Activation de la sécurité +quarkus.security.auth.enabled=true + +# Chemins publics (non prot�g�s par OIDC) - Doit �tre d�fini en premier +# La page d'accueil (/) et index.xhtml sont publics pour permettre l'affichage initial +# IMPORTANT: Les ressources JSF/PrimeFaces sont servies via /jakarta.faces.resource/* (ou /javax.faces.resource/* selon la stack) +# Elles doivent �tre publiques pour permettre le chargement des CSS/JS (th�me Freya, primeicons, primeflex, etc.) +# On inclut �galement /q/oidc/* pour laisser Quarkus OIDC exposer ses endpoints internes si n�cessaire. +quarkus.http.auth.permission.public.paths=/,/index.xhtml,/pages/public/*,/auth/*,/q/*,/q/oidc/*,/favicon.ico,/resources/*,/META-INF/resources/*,/images/*,/jakarta.faces.resource/*,/javax.faces.resource/* +quarkus.http.auth.permission.public.policy=permit + +# Tous les autres chemins nécessitent une authentification +# IMPORTANT: L'ordre est crucial - les permissions publiques doivent être définies AVANT les permissions authentifiées +# Quarkus OIDC redirigera automatiquement vers Keycloak pour les chemins non publics +quarkus.http.auth.permission.authenticated.paths=/* +quarkus.http.auth.permission.authenticated.policy=authenticated # Configuration Session unionflow.session.timeout=${SESSION_TIMEOUT:1800} @@ -78,16 +115,3 @@ unionflow.security.password.min-length=${PASSWORD_MIN_LENGTH:8} unionflow.security.password.require-special-chars=${PASSWORD_REQUIRE_SPECIAL:true} unionflow.security.max-login-attempts=${MAX_LOGIN_ATTEMPTS:5} unionflow.security.lockout-duration=${LOCKOUT_DURATION:300} - -# Dev mode configuration -%dev.quarkus.log.category."dev.lions.unionflow".level=DEBUG -%dev.quarkus.log.category."jakarta.faces".level=INFO -%dev.quarkus.log.category."org.apache.myfaces".level=INFO -%dev.quarkus.log.category."org.primefaces".level=INFO -%dev.quarkus.myfaces.project-stage=Development -%dev.quarkus.live-reload.instrumentation=true - -# Prod mode configuration -%prod.quarkus.log.console.level=WARN -%prod.quarkus.myfaces.project-stage=Production -%prod.quarkus.myfaces.serialize-state-in-session=true \ No newline at end of file