Refactoring - Version OK
This commit is contained in:
@@ -82,11 +82,19 @@
|
||||
<artifactId>quarkus-rest-client-jackson</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Sécurité JWT -->
|
||||
<!-- Sécurité JWT et OIDC (Keycloak) -->
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-smallrye-jwt</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-oidc</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-oidc-client</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Configuration -->
|
||||
<dependency>
|
||||
|
||||
@@ -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<Membre> {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<String, Object> getDashboardData(
|
||||
@QueryParam("organisationId") String organisationId,
|
||||
@QueryParam("utilisateurId") String utilisateurId
|
||||
);
|
||||
|
||||
@GET
|
||||
@Path("/tendances/{typeMetrique}")
|
||||
Map<String, Object> getEvolutionMensuelle(
|
||||
@PathParam("typeMetrique") String typeMetrique,
|
||||
@QueryParam("organisationId") String organisationId,
|
||||
@QueryParam("periode") String periode
|
||||
);
|
||||
|
||||
@GET
|
||||
@Path("/kpis")
|
||||
Map<String, Object> getKPIs(
|
||||
@QueryParam("organisationId") String organisationId,
|
||||
@QueryParam("periode") String periode
|
||||
);
|
||||
|
||||
@GET
|
||||
@Path("/evolutions")
|
||||
Map<String, Object> getEvolutions(
|
||||
@QueryParam("organisationId") String organisationId,
|
||||
@QueryParam("periode") String periode
|
||||
);
|
||||
|
||||
@GET
|
||||
@Path("/performance-globale")
|
||||
Map<String, Object> getPerformanceGlobale(
|
||||
@QueryParam("organisationId") String organisationId,
|
||||
@QueryParam("periode") String periode
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<CotisationDTO> 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<CotisationDTO> 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);
|
||||
}
|
||||
|
||||
@@ -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<DemandeAideDTO> 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<DemandeAideDTO> 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);
|
||||
}
|
||||
|
||||
@@ -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<EvenementDTO> 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<EvenementDTO> 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<EvenementDTO> 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);
|
||||
}
|
||||
|
||||
@@ -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<FormulaireDTO> listerTous();
|
||||
|
||||
@GET
|
||||
@Path("/{id}")
|
||||
FormulaireDTO obtenirParId(@PathParam("id") UUID id);
|
||||
|
||||
@GET
|
||||
@Path("/actifs")
|
||||
List<FormulaireDTO> listerActifs();
|
||||
|
||||
@GET
|
||||
@Path("/populaires")
|
||||
List<FormulaireDTO> 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);
|
||||
}
|
||||
|
||||
@@ -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<MembreDTO> listerParAssociation(@PathParam("associationId") Long associationId);
|
||||
List<MembreDTO> 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
|
||||
|
||||
@@ -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<SouscriptionDTO> 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);
|
||||
}
|
||||
|
||||
@@ -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<FormulaireDTO> 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");
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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<Cotisation> toutesLesCotisations;
|
||||
private List<Cotisation> 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<CotisationDTO> 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<CotisationDTO> 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() {
|
||||
|
||||
@@ -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<CotisationDTO> 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<AssociationDTO> 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<CotisationDTO> 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<AssociationDTO> associations = associationService.listerActives();
|
||||
List<CotisationDTO> cotisationsDTO = cotisationService.listerToutes(0, 1000);
|
||||
|
||||
for (AssociationDTO assoc : associations.stream().limit(5).collect(Collectors.toList())) {
|
||||
List<CotisationDTO> 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; }
|
||||
|
||||
@@ -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<DemandeAide> toutesLesDemandes;
|
||||
private List<DemandeAide> 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<DemandeAideDTO> 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<DemandeAideDTO> 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<DemandeAideDTO> 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; }
|
||||
|
||||
@@ -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<Demande> demandes;
|
||||
private List<Demande> 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; }
|
||||
|
||||
@@ -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<Document> tousLesDocuments;
|
||||
private List<Document> 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; }
|
||||
}
|
||||
}
|
||||
@@ -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<Entite> toutesLesEntites;
|
||||
private List<Entite> 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<AssociationDTO> 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<AssociationDTO> 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; }
|
||||
|
||||
@@ -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<Evenement> tousLesEvenements;
|
||||
private List<Evenement> 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<EvenementDTO> 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<EvenementDTO> 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<EvenementDTO> 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; }
|
||||
|
||||
@@ -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<FormulaireDTO> formulaires;
|
||||
private List<FormulaireDTO> 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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<MembreDTO> genererDonneesSimulees() {
|
||||
List<MembreDTO> 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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<MembreFamille> 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<MembreFamille> 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; }
|
||||
|
||||
@@ -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<MembreDTO> 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<MembreDTO> 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<dev.lions.unionflow.client.dto.AssociationDTO> 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<MembreDTO> 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; }
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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<dev.lions.unionflow.client.dto.MembreDTO> 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<dev.lions.unionflow.client.dto.AssociationDTO> 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; }
|
||||
|
||||
@@ -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<SouscriptionDTO> 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() {
|
||||
|
||||
@@ -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<AssociationDTO> 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<AssociationDTO> 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; }
|
||||
|
||||
@@ -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<String> extractRolesFromToken() {
|
||||
List<String> 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<String, Object> realmMap = (java.util.Map<String, Object>) realmAccess;
|
||||
Object rolesObj = realmMap.get("roles");
|
||||
if (rolesObj instanceof List) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> realmRoles = (List<String>) 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<String> realmRoles = (List<String>) 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<String> realmRoles = (List<String>) 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<String, Object> resourceMap = (java.util.Map<String, Object>) resourceAccess;
|
||||
for (Object value : resourceMap.values()) {
|
||||
if (value instanceof java.util.Map) {
|
||||
@SuppressWarnings("unchecked")
|
||||
java.util.Map<String, Object> clientMap = (java.util.Map<String, Object>) value;
|
||||
Object rolesObj = clientMap.get("roles");
|
||||
if (rolesObj instanceof List) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> clientRoles = (List<String>) 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<String> directRoles = (List<String>) 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Utilisateur> tousLesUtilisateurs;
|
||||
private List<Utilisateur> 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<AssociationDTO> 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; }
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
<h:form>
|
||||
<p:button value="Se reconnecter"
|
||||
icon="pi pi-sign-in"
|
||||
outcome="/pages/public/login"
|
||||
outcome="/"
|
||||
styleClass="ui-button-primary ui-button-lg" />
|
||||
<p:button value="Page d'accueil"
|
||||
icon="pi pi-home"
|
||||
|
||||
@@ -3,171 +3,381 @@
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
lang="fr">
|
||||
|
||||
<f:view>
|
||||
<f:event type="preRenderView" listener="#{navigationBean.checkAuthentication}" />
|
||||
<h:head>
|
||||
<f:facet name="first">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<link rel="icon" href="#{request.contextPath}/resources/freya-layout/images/favicon.ico" type="image/x-icon" />
|
||||
</f:facet>
|
||||
|
||||
<h:head>
|
||||
<title>UnionFlow - Plateforme de Gestion Associative</title>
|
||||
<h:outputStylesheet name="freya-layout/css/primeflex.min.css"/>
|
||||
<h:outputStylesheet name="freya-layout/css/primeicons.css"/>
|
||||
<h:outputStylesheet name="primefaces-freya-blue-light/theme.css"/>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
||||
}
|
||||
|
||||
.hero-container {
|
||||
background: rgba(255, 255, 255, 0.95);
|
||||
backdrop-filter: blur(10px);
|
||||
border-radius: 20px;
|
||||
padding: 60px;
|
||||
box-shadow: 0 30px 80px rgba(0,0,0,0.3);
|
||||
text-align: center;
|
||||
max-width: 600px;
|
||||
border: 1px solid rgba(255,255,255,0.2);
|
||||
}
|
||||
|
||||
.logo-animation {
|
||||
font-size: 5rem;
|
||||
margin-bottom: 24px;
|
||||
animation: pulse 2s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0% { transform: scale(1); }
|
||||
100% { transform: scale(1.05); }
|
||||
}
|
||||
|
||||
.hero-title {
|
||||
font-size: 3rem;
|
||||
font-weight: 700;
|
||||
margin-bottom: 16px;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
.hero-subtitle {
|
||||
font-size: 1.3rem;
|
||||
color: #6c757d;
|
||||
margin-bottom: 32px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.features-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: 20px;
|
||||
margin: 40px 0;
|
||||
}
|
||||
|
||||
.feature-item {
|
||||
background: rgba(102, 126, 234, 0.1);
|
||||
border-radius: 12px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
font-size: 2rem;
|
||||
margin-bottom: 12px;
|
||||
color: #667eea;
|
||||
}
|
||||
|
||||
.loading-text {
|
||||
margin-top: 20px;
|
||||
color: #6c757d;
|
||||
font-size: 0.9rem;
|
||||
animation: fadeInOut 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes fadeInOut {
|
||||
0%, 100% { opacity: 0.5; }
|
||||
50% { opacity: 1; }
|
||||
}
|
||||
</style>
|
||||
</h:head>
|
||||
<title>UnionFlow - Plateforme de Gestion Intégrée pour Mutuelles, Associations et Clubs</title>
|
||||
|
||||
<!-- Freya Layout Resources (placés dans le head pour éviter tout conflit et suivre le template) -->
|
||||
<h:outputStylesheet name="css/primeicons.css" library="freya-layout" />
|
||||
<h:outputStylesheet name="css/primeflex.min.css" library="freya-layout" />
|
||||
<h:outputStylesheet name="css/layout-#{guestPreferences.layout}.css" library="freya-layout" />
|
||||
<h:outputStylesheet name="primefaces-freya-#{guestPreferences.componentTheme}/theme.css" />
|
||||
<meta name="description" content="UnionFlow : La solution complète de gestion pour les mutuelles, associations, clubs (informatiques, juridiques, etc.) et organisations similaires. Gestion des membres, cotisations, événements, solidarité et analytics." />
|
||||
</h:head>
|
||||
|
||||
<h:body>
|
||||
<div class="hero-container">
|
||||
<!-- Logo animé -->
|
||||
<div class="logo-animation">
|
||||
<i class="pi pi-users"></i>
|
||||
</div>
|
||||
|
||||
<!-- Titre principal -->
|
||||
<h1 class="hero-title">UnionFlow</h1>
|
||||
<p class="hero-subtitle">
|
||||
Plateforme intégrée de gestion associative<br/>
|
||||
<strong>Moderne • Sécurisée • Intuitive</strong>
|
||||
</p>
|
||||
|
||||
<!-- Grille des fonctionnalités -->
|
||||
<div class="features-grid">
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">
|
||||
<i class="pi pi-users"></i>
|
||||
</div>
|
||||
<div class="text-900 font-semibold">Gestion Membres</div>
|
||||
</div>
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">
|
||||
<i class="pi pi-dollar"></i>
|
||||
</div>
|
||||
<div class="text-900 font-semibold">Cotisations</div>
|
||||
</div>
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">
|
||||
<i class="pi pi-calendar"></i>
|
||||
</div>
|
||||
<div class="text-900 font-semibold">Événements</div>
|
||||
</div>
|
||||
<div class="feature-item">
|
||||
<div class="feature-icon">
|
||||
<i class="pi pi-chart-bar"></i>
|
||||
</div>
|
||||
<div class="text-900 font-semibold">Analytics</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Boutons d'action -->
|
||||
<div class="flex justify-content-center gap-3 mb-4">
|
||||
<p:button value="Connexion Sécurisée"
|
||||
icon="pi pi-sign-in"
|
||||
outcome="/pages/public/login"
|
||||
styleClass="p-button-lg p-button-rounded"/>
|
||||
<h:body styleClass="landing-body">
|
||||
<div class="landing-wrapper">
|
||||
<!-- Landing Topbar -->
|
||||
<div class="landing-topbar">
|
||||
<div class="landing-topbar-left">
|
||||
<h:link id="logolink" outcome="/pages/secure/dashboard" styleClass="logo">
|
||||
<p:graphicImage name="images/logo-freya.svg" library="freya-layout" />
|
||||
</h:link>
|
||||
|
||||
<p:button value="Accès Direct"
|
||||
icon="pi pi-home"
|
||||
outcome="/pages/secure/dashboard"
|
||||
styleClass="p-button-lg p-button-rounded p-button-outlined"/>
|
||||
<ul class="landing-menu">
|
||||
<li>
|
||||
<a href="#" id="landing-menu-close">
|
||||
<i class="pi pi-times"> </i>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#home">Accueil</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#features">Fonctionnalités</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#benefits">Avantages</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Texte de chargement -->
|
||||
<div class="loading-text">
|
||||
<i class="pi pi-spin pi-spinner mr-2"></i>
|
||||
Vérification de l'authentification...
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="mt-5 pt-4 border-top-1 surface-border">
|
||||
<small class="text-500">
|
||||
© 2024 UnionFlow v1.0 - Développé par <strong>Lions Dev</strong><br/>
|
||||
<span class="text-600">Côte d'Ivoire • Sénégal • Mali</span>
|
||||
</small>
|
||||
<div class="landing-topbar-right">
|
||||
<ui:include src="/templates/components/button-primary.xhtml">
|
||||
<ui:param name="value" value="Accéder" />
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="outcome" value="/pages/secure/dashboard" />
|
||||
<ui:param name="styleClass" value="landing-button" />
|
||||
</ui:include>
|
||||
<a href="#" id="landing-menu-button">
|
||||
<i class="pi pi-bars"> </i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Landing Banner (Hero Section) -->
|
||||
<div id="home" class="landing-banner">
|
||||
<div class="landing-banner-content">
|
||||
<span class="title">UnionFlow</span>
|
||||
<h3>Plateforme de Gestion Intégrée pour Mutuelles, Associations et Clubs<br/>
|
||||
Simplifiez la gestion de votre organisation avec une solution complète et moderne</h3>
|
||||
<ui:include src="/templates/components/button-primary.xhtml">
|
||||
<ui:param name="value" value="Accéder à la plateforme" />
|
||||
<ui:param name="icon" value="pi pi-sign-in" />
|
||||
<ui:param name="outcome" value="/pages/secure/dashboard" />
|
||||
<ui:param name="styleClass" value="landing-button" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</h:body>
|
||||
</f:view>
|
||||
|
||||
</html>
|
||||
<!-- Landing Features Section -->
|
||||
<div id="features" class="landing-features">
|
||||
<div class="grid parallax-box">
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="feature yellow">
|
||||
<span>1</span>
|
||||
<div class="feature-card">
|
||||
<span>1</span>
|
||||
<div class="card-content">
|
||||
<h3>Gestion des Membres</h3>
|
||||
<h5>Inscription, profils détaillés, gestion des statuts, historique des adhésions et suivi complet de chaque membre.</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="grid">
|
||||
<div class="col-12">
|
||||
<div class="feature blue">
|
||||
<span>2</span>
|
||||
<div class="feature-card">
|
||||
<span>2</span>
|
||||
<div class="card-content">
|
||||
<h3>Gestion des Cotisations</h3>
|
||||
<h5>Types variés (mensuelle, annuelle, adhésion, événement, formation, projet, solidarité), suivi des paiements et rappels automatiques. <strong>Paiements sécurisés via Wave</strong> (bientôt disponible).</h5>
|
||||
<div style="margin-top: 10px;">
|
||||
<!-- Image locale du client (servie depuis META-INF/resources/images) -->
|
||||
<h:graphicImage value="#{request.contextPath}/images/logo-wave.png" style="max-height: 30px; width: auto;" alt="Wave - Paiements mobiles" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="feature gray">
|
||||
<span>3</span>
|
||||
<div class="feature-card">
|
||||
<span>3</span>
|
||||
<div class="card-content">
|
||||
<h3>Organisation<br/>d'Événements</h3>
|
||||
<h5>Assemblées générales, réunions, formations, conférences, ateliers, séminaires, événements sociaux avec gestion des inscriptions.</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-3 feature-4">
|
||||
<div class="col-12">
|
||||
<div class="feature darker-gray">
|
||||
<span>4</span>
|
||||
<div class="feature-card">
|
||||
<span>4</span>
|
||||
<div class="card-content">
|
||||
<h3>Système de Solidarité</h3>
|
||||
<h5>Gestion complète des demandes d'aide, propositions, évaluations, suivi des statuts et coordination des actions solidaires.</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="feature darker-blue">
|
||||
<span>5</span>
|
||||
<div class="feature-card">
|
||||
<span>5</span>
|
||||
<div class="card-content">
|
||||
<h3>Gestion des Organisations</h3>
|
||||
<h5>Gestion des clubs et unions avec hiérarchie organisationnelle, statistiques détaillées, rapports et vue d'ensemble complète.</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 lg:col-3">
|
||||
<div class="feature gray">
|
||||
<span>6</span>
|
||||
<div class="feature-card">
|
||||
<span>6</span>
|
||||
<div class="card-content">
|
||||
<h3>Analytics & Rapports</h3>
|
||||
<h5>Tableaux de bord interactifs, KPIs en temps réel, analyses approfondies et rapports personnalisables pour une prise de décision éclairée.</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Benefits Section -->
|
||||
<div id="benefits" class="landing-pricing">
|
||||
<div class="section-header">
|
||||
<span class="title">Pourquoi choisir UnionFlow ?</span>
|
||||
<h3>Une solution pensée pour les mutuelles, associations, clubs et organisations similaires avec sécurité avancée, multi-plateforme et synchronisation temps réel.</h3>
|
||||
</div>
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="pricing-card">
|
||||
<h2>Sécurité</h2>
|
||||
<span class="price">100%</span>
|
||||
<span class="time">Sécurisé</span>
|
||||
<ul>
|
||||
<li>Connexion sécurisée et centralisée</li>
|
||||
<li>Contrôle d'accès basé sur les rôles</li>
|
||||
<li>Protection des données sensibles</li>
|
||||
<li>Chiffrement des communications</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-4 preferred">
|
||||
<div class="pricing-card pro">
|
||||
<span class="preferred-tag">RECOMMANDÉ</span>
|
||||
<h2>Multi-Plateforme</h2>
|
||||
<span class="price">24/7</span>
|
||||
<span class="time">Disponible</span>
|
||||
<ul>
|
||||
<li>Application web responsive</li>
|
||||
<li>Application mobile Flutter</li>
|
||||
<li>iOS et Android</li>
|
||||
<li>Accès depuis n'importe où</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="pricing-card enterprise">
|
||||
<h2>Cloud</h2>
|
||||
<span class="price">Cloud</span>
|
||||
<span class="time">Moderne</span>
|
||||
<ul>
|
||||
<li>Architecture cloud-native</li>
|
||||
<li>Synchronisation temps réel</li>
|
||||
<li>Sauvegarde automatique</li>
|
||||
<li>Scalabilité illimitée</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center mt-5">
|
||||
<ui:include src="/templates/components/button-primary.xhtml">
|
||||
<ui:param name="value" value="Découvrir toutes les fonctionnalités" />
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="outcome" value="/pages/secure/dashboard" />
|
||||
<ui:param name="styleClass" value="landing-button" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div class="layout-footer">
|
||||
<div class="grid">
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="grid">
|
||||
<div class="col-6">
|
||||
<span class="footer-menutitle">NAVIGATION</span>
|
||||
<ul>
|
||||
<li><a href="#home">Accueil</a></li>
|
||||
<li><a href="#features">Fonctionnalités</a></li>
|
||||
<li><a href="#benefits">Avantages</a></li>
|
||||
<li><a href="/pages/secure/dashboard">Tableau de Bord</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<span class="footer-menutitle">FONCTIONNALITÉS</span>
|
||||
<ul>
|
||||
<li><a href="/pages/secure/membre/liste">Membres</a></li>
|
||||
<li><a href="/pages/secure/cotisation/historique">Cotisations</a></li>
|
||||
<li><a href="/pages/secure/evenement/calendrier">Événements</a></li>
|
||||
<li><a href="/pages/secure/aide/documentation">Aide</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 md:col-6 lg:col-3">
|
||||
<span class="footer-menutitle">CONTACT</span>
|
||||
<ul>
|
||||
<li>support@unionflow.dev</li>
|
||||
<li>Abidjan, Côte d'Ivoire</li>
|
||||
<li>Plateforme de Gestion Intégrée</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-12 md:col-6 lg:col-5">
|
||||
<span class="footer-menutitle">NEWSLETTER</span>
|
||||
<span class="footer-subtitle">Rejoignez notre newsletter pour être informé des nouvelles fonctionnalités.</span>
|
||||
<h:form>
|
||||
<div class="newsletter-input">
|
||||
<p:inputText placeholder="adresse email" />
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="S'abonner" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="footer-bottom">
|
||||
<h4>UnionFlow</h4>
|
||||
<h6>Copyright © 2025 UnionFlow Dev Team</h6>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="landing-mask"> </div>
|
||||
</div>
|
||||
<!-- Landing Page JavaScript - selon Freya -->
|
||||
<h:outputScript name="js/layout.js" library="freya-layout" />
|
||||
<h:outputScript>
|
||||
<![CDATA[
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
const initParallax = function() {
|
||||
if (typeof $ === 'undefined') return;
|
||||
|
||||
$(document).ready(function() {
|
||||
const parallax = function() {
|
||||
const scrolled = $(window).scrollTop();
|
||||
$('.landing-banner').css('top', -(scrolled * 0.01) + '%');
|
||||
$('.landing-banner-content').css('top', (scrolled * -0.065) + '%');
|
||||
$('.parallax-box .lg\\:col-3:odd').css('transform', 'translateY(' + (scrolled * 0.01) + '%)');
|
||||
$('.parallax-box .lg\\:col-3:even').css('margin-top', -(scrolled * 0.01) + '%');
|
||||
};
|
||||
$(window).scroll(parallax);
|
||||
});
|
||||
};
|
||||
|
||||
const initMenu = function() {
|
||||
if (typeof $ === 'undefined') return;
|
||||
|
||||
const hideMenu = function() {
|
||||
$('.landing-menu').removeClass('fadeInDown').addClass('fadeOutUp');
|
||||
setTimeout(function() {
|
||||
$('.landing-wrapper').removeClass('landing-menu-active');
|
||||
$('.landing-menu').removeClass('fadeOutUp');
|
||||
$(document.body).removeClass('block-scroll');
|
||||
}, 150);
|
||||
};
|
||||
|
||||
const showMenu = function() {
|
||||
$('.landing-wrapper').addClass('landing-menu-active');
|
||||
$('.landing-menu').addClass('fadeInDown');
|
||||
$(document.body).addClass('block-scroll');
|
||||
};
|
||||
|
||||
$(function() {
|
||||
$('#landing-menu-button').on('click', function(e) {
|
||||
const wrapper = $('.landing-wrapper');
|
||||
if (wrapper.hasClass('landing-menu-active')) {
|
||||
hideMenu();
|
||||
} else {
|
||||
showMenu();
|
||||
}
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
$('.landing-menu').find('a').on('click', function() {
|
||||
hideMenu();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const initScroll = function() {
|
||||
if (typeof $ === 'undefined') return;
|
||||
|
||||
$(document).ready(function() {
|
||||
$('html, body').animate({ scrollTop: 0 }, 1);
|
||||
});
|
||||
|
||||
const isMobile = function() {
|
||||
return $(window).width() <= 896;
|
||||
};
|
||||
|
||||
$('a[href*="#"]:not([href="#"])').click(function() {
|
||||
const target = $(this.hash);
|
||||
if (target.length) {
|
||||
const offset = isMobile() ? target.offset().top : target.offset().top - 100;
|
||||
$('html, body').animate({ scrollTop: offset }, 500);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Initialize when DOM is ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
initParallax();
|
||||
initMenu();
|
||||
initScroll();
|
||||
});
|
||||
} else {
|
||||
initParallax();
|
||||
initMenu();
|
||||
initScroll();
|
||||
}
|
||||
})();
|
||||
]]>
|
||||
</h:outputScript>
|
||||
|
||||
</h:body>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -1,214 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui"
|
||||
template="/templates/public-template.xhtml">
|
||||
|
||||
<ui:define name="title">Connexion - UnionFlow</ui:define>
|
||||
|
||||
<ui:define name="content">
|
||||
<div class="min-h-screen flex relative lg:static surface-ground">
|
||||
<!-- Panneau gauche - Branding -->
|
||||
<div class="flex flex-column align-items-center justify-content-center bg-blue-500 flex-shrink-0 w-full lg:w-6">
|
||||
<div class="text-center">
|
||||
<!-- Logo et icône principale -->
|
||||
<div class="mb-6">
|
||||
<div class="text-white text-7xl font-bold mb-4">
|
||||
<i class="pi pi-users"></i>
|
||||
</div>
|
||||
<h1 class="text-white text-5xl font-bold mb-2 line-height-3">UnionFlow</h1>
|
||||
<p class="text-blue-100 text-xl font-medium line-height-3 mb-0">
|
||||
Plateforme de Gestion Associative
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Fonctionnalités clés -->
|
||||
<div class="hidden lg:block">
|
||||
<div class="surface-0 shadow-2 border-round p-4 mx-6">
|
||||
<div class="text-900 text-lg font-bold mb-3">Fonctionnalités Principales</div>
|
||||
<ul class="list-none p-0 m-0 text-left">
|
||||
<li class="flex align-items-center py-2">
|
||||
<div class="w-2rem h-2rem bg-green-100 text-green-600 border-round flex align-items-center justify-content-center mr-3">
|
||||
<i class="pi pi-users"></i>
|
||||
</div>
|
||||
<span class="text-900 font-medium">Gestion des membres</span>
|
||||
</li>
|
||||
<li class="flex align-items-center py-2">
|
||||
<div class="w-2rem h-2rem bg-purple-100 text-purple-600 border-round flex align-items-center justify-content-center mr-3">
|
||||
<i class="pi pi-dollar"></i>
|
||||
</div>
|
||||
<span class="text-900 font-medium">Cotisations & Paiements</span>
|
||||
</li>
|
||||
<li class="flex align-items-center py-2">
|
||||
<div class="w-2rem h-2rem bg-orange-100 text-orange-600 border-round flex align-items-center justify-content-center mr-3">
|
||||
<i class="pi pi-calendar"></i>
|
||||
</div>
|
||||
<span class="text-900 font-medium">Événements & Activités</span>
|
||||
</li>
|
||||
<li class="flex align-items-center py-2">
|
||||
<div class="w-2rem h-2rem bg-cyan-100 text-cyan-600 border-round flex align-items-center justify-content-center mr-3">
|
||||
<i class="pi pi-chart-bar"></i>
|
||||
</div>
|
||||
<span class="text-900 font-medium">Rapports & Analytics</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Panneau droit - Formulaire de connexion -->
|
||||
<div class="flex flex-column align-items-center justify-content-center w-full lg:w-6 px-4 py-8 surface-card">
|
||||
<div class="w-full" style="max-width: 400px;">
|
||||
<!-- En-tête du formulaire -->
|
||||
<div class="text-center mb-6">
|
||||
<div class="text-900 text-3xl font-bold mb-2">Bienvenue !</div>
|
||||
<div class="text-600 mb-4">Connectez-vous à votre espace UnionFlow</div>
|
||||
|
||||
<!-- Messages système -->
|
||||
<p:messages id="messages" showDetail="true" closable="true"
|
||||
styleClass="mb-4" globalOnly="true" />
|
||||
|
||||
<!-- Message de session expirée -->
|
||||
<p:outputPanel rendered="#{param.expired == 'true'}" styleClass="mb-4">
|
||||
<div class="surface-100 border-round-lg p-3 border-left-3 border-orange-500">
|
||||
<div class="flex align-items-center">
|
||||
<i class="pi pi-clock text-orange-500 mr-3 text-2xl"></i>
|
||||
<div>
|
||||
<div class="text-900 font-semibold">Session expirée</div>
|
||||
<div class="text-600 text-sm mt-1">
|
||||
Votre session a expiré pour des raisons de sécurité. Veuillez vous reconnecter.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</p:outputPanel>
|
||||
</div>
|
||||
|
||||
<!-- Formulaire principal -->
|
||||
<h:form id="loginForm" styleClass="ui-fluid">
|
||||
|
||||
<!-- Sélecteur de type de compte avec design moderne -->
|
||||
<div class="field mb-4">
|
||||
<label for="typeCompte" class="block text-900 font-semibold mb-2">
|
||||
<i class="pi pi-user-plus mr-2"></i>Type de compte
|
||||
</label>
|
||||
<p:selectOneMenu id="typeCompte" value="#{loginBean.typeCompte}"
|
||||
required="true" styleClass="w-full">
|
||||
<f:selectItem itemLabel="Choisir votre profil..." itemValue="" noSelectionOption="true" />
|
||||
<f:selectItem itemLabel="🔱 Super-Administrateur Plateforme" itemValue="SUPER_ADMIN" />
|
||||
<f:selectItem itemLabel="🏛️ Administrateur d'Organisation" itemValue="ADMIN_ENTITE" />
|
||||
<f:selectItem itemLabel="👤 Membre Actif" itemValue="MEMBRE" />
|
||||
</p:selectOneMenu>
|
||||
</div>
|
||||
|
||||
<!-- Champ email/username -->
|
||||
<div class="field mb-4">
|
||||
<label for="username" class="block text-900 font-semibold mb-2">
|
||||
<i class="pi pi-at mr-2"></i>Email ou nom d'utilisateur
|
||||
</label>
|
||||
<p:inputText id="username" value="#{loginBean.username}"
|
||||
placeholder="votre@email.com"
|
||||
required="true" styleClass="w-full p-3">
|
||||
<f:validateLength minimum="3" />
|
||||
</p:inputText>
|
||||
</div>
|
||||
|
||||
<!-- Champ mot de passe -->
|
||||
<div class="field mb-4">
|
||||
<label for="password" class="block text-900 font-semibold mb-2">
|
||||
<i class="pi pi-key mr-2"></i>Mot de passe
|
||||
</label>
|
||||
<p:password id="password" value="#{loginBean.password}"
|
||||
placeholder="••••••••••"
|
||||
required="true" toggleMask="true"
|
||||
styleClass="w-full p-3" />
|
||||
</div>
|
||||
|
||||
<!-- Options avancées -->
|
||||
<div class="flex align-items-center justify-content-between mb-5">
|
||||
<div class="flex align-items-center">
|
||||
<p:selectBooleanCheckbox id="rememberme" value="#{loginBean.rememberMe}"
|
||||
styleClass="mr-2" />
|
||||
<label for="rememberme" class="text-900 font-medium cursor-pointer">
|
||||
Se souvenir de moi
|
||||
</label>
|
||||
</div>
|
||||
<a href="#" class="font-semibold no-underline text-primary text-right cursor-pointer">
|
||||
Mot de passe oublié ?
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Bouton de connexion principal -->
|
||||
<p:commandButton id="loginButton" value="Se connecter"
|
||||
action="#{loginBean.login}"
|
||||
styleClass="w-full p-3 text-xl border-round font-bold mb-4"
|
||||
icon="pi pi-sign-in"
|
||||
iconPos="right"
|
||||
update="@form" />
|
||||
|
||||
<!-- Séparateur élégant -->
|
||||
<div class="flex align-items-center mb-4">
|
||||
<hr class="flex-1 border-top-1 border-300 m-0"/>
|
||||
<div class="px-3 text-500 font-medium">ou essayez en mode démo</div>
|
||||
<hr class="flex-1 border-top-1 border-300 m-0"/>
|
||||
</div>
|
||||
|
||||
<!-- Boutons démo redesignés -->
|
||||
<div class="grid gap-2">
|
||||
<div class="col-12">
|
||||
<p:commandButton value="🔱 Mode Démo Super-Admin"
|
||||
action="#{loginBean.loginDemo('SUPER_ADMIN')}"
|
||||
styleClass="ui-button-outlined ui-button-danger w-full p-2 font-bold"
|
||||
update="@form" />
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<p:commandButton value="🏛️ Démo Admin"
|
||||
action="#{loginBean.loginDemo('ADMIN')}"
|
||||
styleClass="ui-button-outlined ui-button-warning w-full p-2"
|
||||
update="@form" />
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<p:commandButton value="👤 Démo Membre"
|
||||
action="#{loginBean.loginDemo('MEMBRE')}"
|
||||
styleClass="ui-button-outlined ui-button-info w-full p-2"
|
||||
update="@form" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Call to action pour inscription -->
|
||||
<div class="surface-50 border-round p-4 mt-6 text-center">
|
||||
<div class="text-900 font-semibold mb-2">
|
||||
<i class="pi pi-star-fill text-yellow-500 mr-2"></i>
|
||||
Votre organisation n'est pas encore inscrite ?
|
||||
</div>
|
||||
<p class="text-600 mb-3 line-height-3">
|
||||
Découvrez UnionFlow avec une démonstration personnalisée
|
||||
</p>
|
||||
<a href="#" class="text-primary font-bold no-underline">
|
||||
<i class="pi pi-arrow-right mr-2"></i>Demander une démonstration
|
||||
</a>
|
||||
</div>
|
||||
</h:form>
|
||||
|
||||
<!-- Footer discret -->
|
||||
<div class="text-center mt-6 pt-4">
|
||||
<div class="text-500 text-sm mb-2">
|
||||
© 2024 UnionFlow - Développé par Lions Dev
|
||||
</div>
|
||||
<div class="flex justify-content-center gap-3 text-xs">
|
||||
<a href="#" class="text-500 no-underline hover:text-primary">Aide</a>
|
||||
<span class="text-300">•</span>
|
||||
<a href="#" class="text-500 no-underline hover:text-primary">Confidentialité</a>
|
||||
<span class="text-300">•</span>
|
||||
<a href="#" class="text-500 no-underline hover:text-primary">Conditions</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:define>
|
||||
|
||||
</ui:composition>
|
||||
@@ -32,8 +32,16 @@
|
||||
<p:inputTextarea id="motifAdhesion" rows="4" />
|
||||
</div>
|
||||
<div class="field col-12">
|
||||
<p:commandButton value="Soumettre la demande" icon="pi pi-send" styleClass="ui-button-success" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times" styleClass="ui-button-secondary" style="margin-left: 0.5rem" />
|
||||
<ui:include src="/templates/components/button-success.xhtml">
|
||||
<ui:param name="value" value="Soumettre la demande" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
<ui:param name="styleClass" value="ml-2" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
|
||||
@@ -23,8 +23,14 @@
|
||||
<h:outputText value="#{adhesion.statut}" />
|
||||
</p:column>
|
||||
<p:column headerText="Actions">
|
||||
<p:commandButton icon="pi pi-eye" styleClass="ui-button-rounded ui-button-info ui-button-text" />
|
||||
<p:commandButton icon="pi pi-pencil" styleClass="ui-button-rounded ui-button-success ui-button-text" />
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-eye" />
|
||||
<ui:param name="severity" value="info" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-pencil" />
|
||||
<ui:param name="severity" value="success" />
|
||||
</ui:include>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
|
||||
@@ -24,7 +24,11 @@
|
||||
<h:outputText value="#{adhesion.dateExpiration}" />
|
||||
</p:column>
|
||||
<p:column headerText="Action">
|
||||
<p:commandButton value="Renouveler" icon="pi pi-refresh" styleClass="ui-button-success ui-button-sm" />
|
||||
<ui:include src="/templates/components/button-success.xhtml">
|
||||
<ui:param name="value" value="Renouveler" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
|
||||
@@ -23,8 +23,16 @@
|
||||
<h:outputText value="#{adhesion.type}" />
|
||||
</p:column>
|
||||
<p:column headerText="Actions">
|
||||
<p:commandButton value="Approuver" icon="pi pi-check" styleClass="ui-button-success ui-button-sm" />
|
||||
<p:commandButton value="Rejeter" icon="pi pi-times" styleClass="ui-button-danger ui-button-sm" style="margin-left: 0.5rem" />
|
||||
<ui:include src="/templates/components/button-success.xhtml">
|
||||
<ui:param name="value" value="Approuver" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Rejeter" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="styleClass" value="ui-button-danger ui-button-sm" />
|
||||
</ui:include>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
|
||||
@@ -26,13 +26,17 @@
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Version PDF"
|
||||
styleClass="p-button-outlined"
|
||||
icon="pi pi-file-pdf" />
|
||||
<p:commandButton value="Rechercher"
|
||||
styleClass="p-button-primary p-button-outlined"
|
||||
icon="pi pi-search"
|
||||
onclick="PF('rechercheDialog').show()" />
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Version PDF" />
|
||||
<ui:param name="icon" value="pi pi-file-pdf" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-primary.xhtml">
|
||||
<ui:param name="value" value="Rechercher" />
|
||||
<ui:param name="icon" value="pi pi-search" />
|
||||
<ui:param name="onclick" value="PF('rechercheDialog').show()" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -145,12 +149,18 @@
|
||||
<!-- Actions rapides -->
|
||||
<div class="surface-card border-round p-3 mt-3">
|
||||
<div class="text-center">
|
||||
<p:commandButton value="Tout marquer comme lu"
|
||||
styleClass="p-button-text p-button-sm w-full"
|
||||
icon="pi pi-check-square" />
|
||||
<p:commandButton value="Réinitialiser progression"
|
||||
styleClass="p-button-text p-button-sm w-full mt-2"
|
||||
icon="pi pi-refresh" />
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Tout marquer comme lu" />
|
||||
<ui:param name="icon" value="pi pi-check-square" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-text ui-button-sm w-full" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Réinitialiser progression" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-text ui-button-sm w-full mt-2" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
@@ -171,15 +181,27 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton icon="pi pi-bookmark"
|
||||
styleClass="p-button-rounded p-button-outlined p-button-sm"
|
||||
title="Marquer comme favori" />
|
||||
<p:commandButton icon="pi pi-share-alt"
|
||||
styleClass="p-button-rounded p-button-outlined p-button-sm"
|
||||
title="Partager" />
|
||||
<p:commandButton icon="pi pi-print"
|
||||
styleClass="p-button-rounded p-button-outlined p-button-sm"
|
||||
title="Imprimer" />
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-bookmark" />
|
||||
<ui:param name="title" value="Marquer comme favori" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-share-alt" />
|
||||
<ui:param name="title" value="Partager" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-sm" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-print" />
|
||||
<ui:param name="title" value="Imprimer" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-sm" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -325,31 +347,37 @@
|
||||
|
||||
<!-- Navigation entre sections -->
|
||||
<div class="flex justify-content-between align-items-center mt-6 pt-4 border-top-1 border-200">
|
||||
<p:commandButton value="Section précédente"
|
||||
icon="pi pi-angle-left"
|
||||
styleClass="p-button-outlined"
|
||||
rendered="#{guideBean.APrecedent}"
|
||||
action="#{guideBean.sectionPrecedente}" />
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Section précédente" />
|
||||
<ui:param name="icon" value="pi pi-angle-left" />
|
||||
<ui:param name="action" value="#{guideBean.sectionPrecedente}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="rendered" value="#{guideBean.APrecedent}" />
|
||||
</ui:include>
|
||||
|
||||
<div class="flex gap-2" rendered="#{guideBean.sectionCourante.id != 'default'}">
|
||||
<p:commandButton value="Marquer comme lu"
|
||||
icon="pi pi-check"
|
||||
styleClass="p-button-success"
|
||||
rendered="#{not guideBean.sectionCourante.lu}"
|
||||
action="#{guideBean.marquerCommeLu}" />
|
||||
<p:commandButton value="Lu"
|
||||
icon="pi pi-check"
|
||||
styleClass="p-button-outlined"
|
||||
rendered="#{guideBean.sectionCourante.lu}"
|
||||
disabled="true" />
|
||||
<ui:include src="/templates/components/button-success.xhtml">
|
||||
<ui:param name="value" value="Marquer comme lu" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{guideBean.marquerCommeLu}" />
|
||||
<ui:param name="rendered" value="#{not guideBean.sectionCourante.lu}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Lu" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="true" />
|
||||
<ui:param name="rendered" value="#{guideBean.sectionCourante.lu}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<p:commandButton value="Section suivante"
|
||||
icon="pi pi-angle-right"
|
||||
iconPos="right"
|
||||
styleClass="p-button-outlined"
|
||||
rendered="#{guideBean.ASuivant}"
|
||||
action="#{guideBean.sectionSuivante}" />
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Section suivante" />
|
||||
<ui:param name="icon" value="pi pi-angle-right" />
|
||||
<ui:param name="action" value="#{guideBean.sectionSuivante}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="rendered" value="#{guideBean.ASuivant}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -376,7 +404,7 @@
|
||||
</p:inputText>
|
||||
</div>
|
||||
|
||||
<div id="resultatsRecherche">
|
||||
<h:panelGroup id="resultatsRecherche" layout="block">
|
||||
<ui:repeat value="#{guideBean.resultatsRecherche}" var="resultat" rendered="#{not empty guideBean.termeRecherche}">
|
||||
<div class="surface-100 border-round p-3 mb-3 cursor-pointer hover:surface-200 transition-duration-200"
|
||||
onclick="#{guideBean.naviguerVers(resultat.id)}; PF('rechercheDialog').hide();">
|
||||
@@ -395,7 +423,7 @@
|
||||
<i class="pi pi-search text-3xl text-300 mb-2"></i>
|
||||
<p class="text-600">Aucun résultat trouvé pour "#{guideBean.termeRecherche}"</p>
|
||||
</div>
|
||||
</div>
|
||||
</h:panelGroup>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
@@ -26,18 +26,27 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-3 lg:mt-0">
|
||||
<p:commandButton value="Rapport mensuel" icon="pi pi-download"
|
||||
styleClass="ui-button-outlined ui-button-success mr-2"
|
||||
action="#{dashboardBean.generateRapport}"/>
|
||||
<p:commandButton value="Aide" icon="pi pi-question-circle"
|
||||
styleClass="ui-button-outlined ui-button-help"/>
|
||||
<ui:include src="/templates/components/button-success.xhtml">
|
||||
<ui:param name="value" value="Rapport mensuel" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{dashboardBean.generateRapport}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="mr-2" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Aide" />
|
||||
<ui:param name="icon" value="pi pi-question-circle" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-help" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Alertes URGENTES - En premier pour l'attention immédiate -->
|
||||
<div class="col-12" rendered="#{dashboardBean.hasAlerts}">
|
||||
<ui:fragment rendered="#{dashboardBean.hasAlerts}">
|
||||
<div class="col-12">
|
||||
<div class="card surface-50 border-round">
|
||||
<h5 class="text-900 font-bold mb-3">
|
||||
<i class="pi pi-exclamation-circle text-orange-500 mr-2"></i>
|
||||
@@ -110,6 +119,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ui:fragment>
|
||||
|
||||
<!-- KPIs principaux - Ordre psychologique optimal -->
|
||||
<div class="col-12">
|
||||
@@ -359,11 +369,11 @@
|
||||
|
||||
<!-- Journal d'activités et Tâches prioritaires -->
|
||||
<div class="col-12 lg:col-8">
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<h5>Journal d'activités</h5>
|
||||
<div>
|
||||
<h:form>
|
||||
<h:form>
|
||||
<div class="card">
|
||||
<div class="flex align-items-center justify-content-between mb-4">
|
||||
<h5>Journal d'activités</h5>
|
||||
<div>
|
||||
<p:selectOneMenu value="#{dashboardBean.filtreActivite}">
|
||||
<f:selectItem itemLabel="Toutes" itemValue="ALL" />
|
||||
<f:selectItem itemLabel="Cotisations" itemValue="COTISATION" />
|
||||
@@ -372,83 +382,105 @@
|
||||
<f:selectItem itemLabel="Événements" itemValue="EVENEMENT" />
|
||||
<p:ajax update="activitiesTable" />
|
||||
</p:selectOneMenu>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p:dataTable id="activitiesTable" value="#{dashboardBean.recentActivities}" var="activity"
|
||||
rows="8" paginator="true" paginatorPosition="bottom">
|
||||
<p:column headerText="Date" style="width:120px">
|
||||
<div class="flex flex-column">
|
||||
<span class="text-900 font-medium">
|
||||
<h:outputText value="#{activity.date}">
|
||||
<f:convertDateTime pattern="dd/MM HH:mm" type="localDateTime"/>
|
||||
</h:outputText>
|
||||
</span>
|
||||
<small class="text-500">
|
||||
<h:outputText value="#{activity.date}">
|
||||
<f:convertDateTime pattern="yyyy" type="localDateTime"/>
|
||||
</h:outputText>
|
||||
</small>
|
||||
</div>
|
||||
</p:column>
|
||||
<p:column headerText="Activité" style="width:100px">
|
||||
<p:tag value="#{activity.type}" severity="#{activity.severity}"
|
||||
icon="#{activity.icon}" styleClass="mr-2"/>
|
||||
</p:column>
|
||||
<p:column headerText="Description">
|
||||
<div>
|
||||
<div class="text-900 font-medium">#{activity.titre}</div>
|
||||
<div class="text-600 mt-1">#{activity.description}</div>
|
||||
<div class="mt-2" rendered="#{activity.montant != null}">
|
||||
<span class="text-green-600 font-medium">#{activity.montant} FCFA</span>
|
||||
<p:dataTable id="activitiesTable" value="#{dashboardBean.recentActivities}" var="activity"
|
||||
rows="8" paginator="true" paginatorPosition="bottom">
|
||||
<p:column headerText="Date" style="width:120px">
|
||||
<div class="flex flex-column">
|
||||
<span class="text-900 font-medium">
|
||||
<h:outputText value="#{activity.date}">
|
||||
<f:convertDateTime pattern="dd/MM HH:mm" type="localDateTime"/>
|
||||
</h:outputText>
|
||||
</span>
|
||||
<small class="text-500">
|
||||
<h:outputText value="#{activity.date}">
|
||||
<f:convertDateTime pattern="yyyy" type="localDateTime"/>
|
||||
</h:outputText>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
<p:column headerText="Acteur" style="width:150px">
|
||||
<div class="flex align-items-center">
|
||||
<p:graphicImage name="images/avatar/profile.jpg" library="demo"
|
||||
styleClass="w-2rem h-2rem border-circle mr-2"/>
|
||||
</p:column>
|
||||
<p:column headerText="Activité" style="width:100px">
|
||||
<p:tag value="#{activity.type}" severity="#{activity.severity}"
|
||||
icon="#{activity.icon}" styleClass="mr-2"/>
|
||||
</p:column>
|
||||
<p:column headerText="Description">
|
||||
<div>
|
||||
<div class="text-900 font-medium">#{activity.userNom}</div>
|
||||
<small class="text-500">#{activity.userRole}</small>
|
||||
<div class="text-900 font-medium">#{activity.titre}</div>
|
||||
<div class="text-600 mt-1">#{activity.description}</div>
|
||||
<ui:fragment rendered="#{activity.montant != null}">
|
||||
<div class="mt-2">
|
||||
<span class="text-green-600 font-medium">#{activity.montant} FCFA</span>
|
||||
</div>
|
||||
</ui:fragment>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
<p:column headerText="Action" style="width:80px">
|
||||
<p:commandButton icon="pi pi-eye" styleClass="ui-button-rounded ui-button-text"
|
||||
title="Voir détails"/>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</p:column>
|
||||
<p:column headerText="Acteur" style="width:150px">
|
||||
<div class="flex align-items-center">
|
||||
<p:graphicImage name="images/avatar/profile.jpg" library="demo"
|
||||
styleClass="w-2rem h-2rem border-circle mr-2"/>
|
||||
<div>
|
||||
<div class="text-900 font-medium">#{activity.userNom}</div>
|
||||
<small class="text-500">#{activity.userRole}</small>
|
||||
</div>
|
||||
</div>
|
||||
</p:column>
|
||||
<p:column headerText="Action" style="width:80px">
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-eye" />
|
||||
<ui:param name="title" value="Voir détails" />
|
||||
</ui:include>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
<!-- Actions rapides et Tâches -->
|
||||
<div class="col-12 lg:col-4">
|
||||
<div class="card mb-4">
|
||||
<h5>Actions rapides</h5>
|
||||
<div class="grid">
|
||||
<div class="col-6">
|
||||
<p:commandButton value="Nouveau membre" icon="pi pi-user-plus"
|
||||
styleClass="ui-button-outlined w-full mb-2"
|
||||
action="#{dashboardBean.redirectToNewMember}"/>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<p:commandButton value="Collecter" icon="pi pi-wallet"
|
||||
styleClass="ui-button-success ui-button-outlined w-full mb-2"
|
||||
action="#{dashboardBean.redirectToCotisation}"/>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<p:commandButton value="Événement" icon="pi pi-calendar-plus"
|
||||
styleClass="ui-button-info ui-button-outlined w-full mb-2"
|
||||
action="#{dashboardBean.redirectToEvenement}"/>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<p:commandButton value="Rapport" icon="pi pi-chart-bar"
|
||||
styleClass="ui-button-warning ui-button-outlined w-full mb-2"
|
||||
action="#{dashboardBean.generateRapport}"/>
|
||||
<h:form>
|
||||
<div class="card mb-4">
|
||||
<h5>Actions rapides</h5>
|
||||
<div class="grid">
|
||||
<div class="col-6">
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Nouveau membre" />
|
||||
<ui:param name="icon" value="pi pi-user-plus" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToNewMember}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full mb-2" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<ui:include src="/templates/components/button-success.xhtml">
|
||||
<ui:param name="value" value="Collecter" />
|
||||
<ui:param name="icon" value="pi pi-wallet" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToCotisation}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full mb-2" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<ui:include src="/templates/components/button-info.xhtml">
|
||||
<ui:param name="value" value="Événement" />
|
||||
<ui:param name="icon" value="pi pi-calendar-plus" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToEvenement}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full mb-2" />
|
||||
</ui:include>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<ui:include src="/templates/components/button-warning.xhtml">
|
||||
<ui:param name="value" value="Rapport" />
|
||||
<ui:param name="icon" value="pi pi-chart-bar" />
|
||||
<ui:param name="action" value="#{dashboardBean.generateRapport}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="w-full mb-2" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
|
||||
<div class="card">
|
||||
<h5>Tâches prioritaires</h5>
|
||||
@@ -459,9 +491,11 @@
|
||||
<div class="text-900 font-medium">Valider #{dashboardBean.adhesionsPendantes} adhésions</div>
|
||||
<small class="text-600">Demandes en attente de validation</small>
|
||||
</div>
|
||||
<p:commandButton icon="pi pi-arrow-right"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{dashboardBean.redirectToAdhesionValidation}"/>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToAdhesionValidation}" />
|
||||
<ui:param name="severity" value="info" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex align-items-center p-3 border-round bg-orange-50 border-orange-200">
|
||||
@@ -470,9 +504,11 @@
|
||||
<div class="text-900 font-medium">Relancer #{dashboardBean.cotisationsRetard} cotisations</div>
|
||||
<small class="text-600">Paiements en retard</small>
|
||||
</div>
|
||||
<p:commandButton icon="pi pi-arrow-right"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning"
|
||||
action="#{dashboardBean.redirectToRelances}"/>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToRelances}" />
|
||||
<ui:param name="severity" value="warning" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex align-items-center p-3 border-round bg-green-50 border-green-200">
|
||||
@@ -481,9 +517,11 @@
|
||||
<div class="text-900 font-medium">Traiter #{dashboardBean.aidesEnAttente} aides</div>
|
||||
<small class="text-600">Demandes d'aide à examiner</small>
|
||||
</div>
|
||||
<p:commandButton icon="pi pi-arrow-right"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{dashboardBean.redirectToAidesTraitement}"/>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToAidesTraitement}" />
|
||||
<ui:param name="severity" value="success" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="flex align-items-center p-3 border-round bg-purple-50 border-purple-200">
|
||||
@@ -492,9 +530,11 @@
|
||||
<div class="text-900 font-medium">Organiser prochains événements</div>
|
||||
<small class="text-600">#{dashboardBean.evenementsAPlanifier} événements à planifier</small>
|
||||
</div>
|
||||
<p:commandButton icon="pi pi-arrow-right"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-help"
|
||||
action="#{dashboardBean.redirectToEvenementPlanning}"/>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-arrow-right" />
|
||||
<ui:param name="action" value="#{dashboardBean.redirectToEvenementPlanning}" />
|
||||
<ui:param name="styleClass" value="ui-button-help" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -511,9 +551,13 @@
|
||||
yearNavigator="true" yearRange="2020:2030">
|
||||
<p:ajax update="financialSummary" listener="#{dashboardBean.onMoisChange}"/>
|
||||
</p:calendar>
|
||||
<p:commandButton value="Exporter" icon="pi pi-download"
|
||||
styleClass="ui-button-outlined ui-button-sm"
|
||||
action="#{dashboardBean.exportFinancialReport}"/>
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Exporter" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{dashboardBean.exportFinancialReport}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</h:form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -177,11 +177,14 @@
|
||||
<i class="pi pi-file text-blue-500 mr-2"></i>
|
||||
<span class="text-900">#{document}</span>
|
||||
</div>
|
||||
<p:commandButton icon="pi pi-times"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger ui-button-sm"
|
||||
action="#{membreInscriptionBean.supprimerDocument(document)}"
|
||||
update="documentsListPanel"
|
||||
title="Supprimer le fichier" />
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="action" value="#{membreInscriptionBean.supprimerDocument(document)}" />
|
||||
<ui:param name="update" value="documentsListPanel" />
|
||||
<ui:param name="title" value="Supprimer le fichier" />
|
||||
<ui:param name="severity" value="danger" />
|
||||
<ui:param name="styleClass" value="ui-button-sm" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</ui:repeat>
|
||||
</h:panelGroup>
|
||||
@@ -242,8 +245,13 @@
|
||||
<p:outputLabel for="numeroParrain" value="N° Membre parrain" />
|
||||
<div class="ui-inputgroup">
|
||||
<p:inputText id="numeroParrain" value="#{membreInscriptionBean.numeroParrain}" />
|
||||
<p:commandButton icon="pi pi-search" styleClass="ui-button-info"
|
||||
action="#{membreInscriptionBean.rechercherParrain}" />
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-search" />
|
||||
<ui:param name="action" value="#{membreInscriptionBean.rechercherParrain}" />
|
||||
<ui:param name="severity" value="info" />
|
||||
<ui:param name="rounded" value="false" />
|
||||
<ui:param name="text" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
@@ -358,28 +366,37 @@
|
||||
</div>
|
||||
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<p:commandButton value="🎯 Inscrire le membre" icon="pi pi-user-plus"
|
||||
styleClass="ui-button ui-button-success"
|
||||
onclick="return preparePhotoForSubmission(this);"
|
||||
action="#{membreInscriptionBean.inscrire}"
|
||||
update="messages"
|
||||
disabled="#{!membreInscriptionBean.formulaireValide}" />
|
||||
|
||||
<p:commandButton value="💾 Enregistrer brouillon" icon="pi pi-save"
|
||||
styleClass="ui-button ui-button-outlined ui-button-info"
|
||||
action="#{membreInscriptionBean.enregistrerBrouillon}"
|
||||
update="messages" />
|
||||
|
||||
<p:commandButton value="🔄 Réinitialiser" icon="pi pi-refresh"
|
||||
styleClass="ui-button ui-button-outlined ui-button-warning"
|
||||
type="reset"
|
||||
onclick="removePhoto(); return confirm('Êtes-vous sûr de vouloir réinitialiser le formulaire ?');" />
|
||||
|
||||
<p:commandButton value="❌ Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button ui-button-outlined ui-button-secondary"
|
||||
action="#{membreInscriptionBean.annuler}"
|
||||
immediate="true"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir annuler l\'inscription ?');" />
|
||||
<ui:include src="/templates/components/button-success.xhtml">
|
||||
<ui:param name="value" value="🎯 Inscrire le membre" />
|
||||
<ui:param name="icon" value="pi pi-user-plus" />
|
||||
<ui:param name="onclick" value="return preparePhotoForSubmission(this);" />
|
||||
<ui:param name="action" value="#{membreInscriptionBean.inscrire}" />
|
||||
<ui:param name="update" value="messages" />
|
||||
<ui:param name="disabled" value="#{!membreInscriptionBean.formulaireValide}" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/button-info.xhtml">
|
||||
<ui:param name="value" value="💾 Enregistrer brouillon" />
|
||||
<ui:param name="icon" value="pi pi-save" />
|
||||
<ui:param name="action" value="#{membreInscriptionBean.enregistrerBrouillon}" />
|
||||
<ui:param name="update" value="messages" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/button-warning.xhtml">
|
||||
<ui:param name="value" value="🔄 Réinitialiser" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="onclick" value="removePhoto(); return confirm('Êtes-vous sûr de vouloir réinitialiser le formulaire ?');" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="❌ Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="action" value="#{membreInscriptionBean.annuler}" />
|
||||
<ui:param name="onclick" value="return confirm('Êtes-vous sûr de vouloir annuler l\'inscription ?');" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
|
||||
<div class="mt-4 text-600">
|
||||
|
||||
@@ -23,14 +23,17 @@
|
||||
</div>
|
||||
<h:form id="formActionsMembres">
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Nouveau membre"
|
||||
icon="pi pi-user-plus"
|
||||
styleClass="ui-button-success"
|
||||
action="/pages/secure/membre/inscription?faces-redirect=true" />
|
||||
<p:commandButton value="Import/Export"
|
||||
icon="pi pi-upload"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
onclick="PF('dlgImportExport').show();" />
|
||||
<ui:include src="/templates/components/button-success.xhtml">
|
||||
<ui:param name="value" value="Nouveau membre" />
|
||||
<ui:param name="icon" value="pi pi-user-plus" />
|
||||
<ui:param name="action" value="/pages/secure/membre/inscription?faces-redirect=true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Import/Export" />
|
||||
<ui:param name="icon" value="pi pi-upload" />
|
||||
<ui:param name="onclick" value="PF('dlgImportExport').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
@@ -94,15 +97,22 @@
|
||||
</p:toolbarGroup>
|
||||
|
||||
<p:toolbarGroup align="right">
|
||||
<p:commandButton value="Filtres avancés"
|
||||
icon="pi pi-filter"
|
||||
styleClass="ui-button-outlined ui-button-secondary mr-2"
|
||||
onclick="PF('dlgFiltresAvances').show();" />
|
||||
<p:commandButton icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{membreListeBean.actualiser}"
|
||||
update="@form"
|
||||
title="Actualiser" />
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Filtres avancés" />
|
||||
<ui:param name="icon" value="pi pi-filter" />
|
||||
<ui:param name="onclick" value="PF('dlgFiltresAvances').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="mr-2" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{membreListeBean.actualiser}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="title" value="Actualiser" />
|
||||
<ui:param name="rounded" value="false" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-outlined ui-button-secondary" />
|
||||
</ui:include>
|
||||
</p:toolbarGroup>
|
||||
</p:toolbar>
|
||||
|
||||
@@ -188,33 +198,45 @@
|
||||
|
||||
<p:column headerText="Actions" style="width:200px">
|
||||
<div class="flex gap-1">
|
||||
<p:commandButton icon="pi pi-eye"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-info"
|
||||
action="#{membreListeBean.voirProfil(membre)}"
|
||||
title="Voir profil" />
|
||||
<p:commandButton icon="pi pi-pencil"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-warning"
|
||||
action="#{membreListeBean.modifierMembre(membre)}"
|
||||
title="Modifier" />
|
||||
<p:commandButton icon="pi pi-dollar"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{membreListeBean.gererCotisations(membre)}"
|
||||
title="Cotisations" />
|
||||
<p:commandButton icon="pi pi-envelope"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-secondary"
|
||||
action="#{membreListeBean.contacterMembre(membre)}"
|
||||
title="Contacter" />
|
||||
<p:commandButton icon="pi pi-ban"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-danger"
|
||||
action="#{membreListeBean.suspendreMembre(membre)}"
|
||||
onclick="return confirm('Êtes-vous sûr de vouloir suspendre ce membre ?');"
|
||||
title="Suspendre"
|
||||
rendered="#{membre.statut == 'ACTIF'}" />
|
||||
<p:commandButton icon="pi pi-check"
|
||||
styleClass="ui-button-rounded ui-button-text ui-button-success"
|
||||
action="#{membreListeBean.reactiverMembre(membre)}"
|
||||
title="Réactiver"
|
||||
rendered="#{membre.statut == 'SUSPENDU'}" />
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-eye" />
|
||||
<ui:param name="action" value="#{membreListeBean.voirProfil(membre)}" />
|
||||
<ui:param name="title" value="Voir profil" />
|
||||
<ui:param name="severity" value="info" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-pencil" />
|
||||
<ui:param name="action" value="#{membreListeBean.modifierMembre(membre)}" />
|
||||
<ui:param name="title" value="Modifier" />
|
||||
<ui:param name="severity" value="warning" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-dollar" />
|
||||
<ui:param name="action" value="#{membreListeBean.gererCotisations(membre)}" />
|
||||
<ui:param name="title" value="Cotisations" />
|
||||
<ui:param name="severity" value="success" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-envelope" />
|
||||
<ui:param name="action" value="#{membreListeBean.contacterMembre(membre)}" />
|
||||
<ui:param name="title" value="Contacter" />
|
||||
<ui:param name="severity" value="" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-ban" />
|
||||
<ui:param name="action" value="#{membreListeBean.suspendreMembre(membre)}" />
|
||||
<ui:param name="onclick" value="return confirm('Êtes-vous sûr de vouloir suspendre ce membre ?');" />
|
||||
<ui:param name="title" value="Suspendre" />
|
||||
<ui:param name="severity" value="danger" />
|
||||
<ui:param name="rendered" value="#{membre.statut == 'ACTIF'}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{membreListeBean.reactiverMembre(membre)}" />
|
||||
<ui:param name="title" value="Réactiver" />
|
||||
<ui:param name="severity" value="success" />
|
||||
<ui:param name="rendered" value="#{membre.statut == 'SUSPENDU'}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:column>
|
||||
</p:dataTable>
|
||||
@@ -228,29 +250,35 @@
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<p:commandButton value="Envoyer message"
|
||||
icon="pi pi-envelope"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
onclick="PF('dlgMessageGroupe').show();"
|
||||
disabled="#{empty membreListeBean.selectedMembres}" />
|
||||
<p:commandButton value="Rappel cotisations"
|
||||
icon="pi pi-bell"
|
||||
styleClass="ui-button-outlined ui-button-warning"
|
||||
action="#{membreListeBean.rappelCotisationsGroupe}"
|
||||
update="@form"
|
||||
process="@form"
|
||||
disabled="#{empty membreListeBean.selectedMembres}" />
|
||||
<p:commandButton value="Exporter sélection"
|
||||
icon="pi pi-file-excel"
|
||||
styleClass="ui-button-outlined ui-button-success"
|
||||
action="#{membreListeBean.exporterSelection}"
|
||||
process="@form"
|
||||
disabled="#{empty membreListeBean.selectedMembres}" />
|
||||
<p:commandButton value="Modifier en lot"
|
||||
icon="pi pi-pencil"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
onclick="PF('dlgModificationLot').show();"
|
||||
disabled="#{empty membreListeBean.selectedMembres}" />
|
||||
<ui:include src="/templates/components/button-info.xhtml">
|
||||
<ui:param name="value" value="Envoyer message" />
|
||||
<ui:param name="icon" value="pi pi-envelope" />
|
||||
<ui:param name="onclick" value="PF('dlgMessageGroupe').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreListeBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-warning.xhtml">
|
||||
<ui:param name="value" value="Rappel cotisations" />
|
||||
<ui:param name="icon" value="pi pi-bell" />
|
||||
<ui:param name="action" value="#{membreListeBean.rappelCotisationsGroupe}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreListeBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-success.xhtml">
|
||||
<ui:param name="value" value="Exporter sélection" />
|
||||
<ui:param name="icon" value="pi pi-file-excel" />
|
||||
<ui:param name="action" value="#{membreListeBean.exporterSelection}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreListeBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Modifier en lot" />
|
||||
<ui:param name="icon" value="pi pi-pencil" />
|
||||
<ui:param name="onclick" value="PF('dlgModificationLot').show();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="disabled" value="#{empty membreListeBean.selectedMembres}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</div>
|
||||
</h:form>
|
||||
@@ -320,18 +348,27 @@
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Appliquer" icon="pi pi-check"
|
||||
styleClass="ui-button-info"
|
||||
action="#{membreListeBean.appliquerFiltresAvances}"
|
||||
update=":formMembres:dtMembres"
|
||||
oncomplete="PF('dlgFiltresAvances').hide();" />
|
||||
<p:commandButton value="Réinitialiser" icon="pi pi-refresh"
|
||||
styleClass="ui-button-outlined ui-button-secondary"
|
||||
action="#{membreListeBean.reinitialiserFiltres}"
|
||||
update="@form :formMembres:dtMembres" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-outlined ui-button-danger"
|
||||
onclick="PF('dlgFiltresAvances').hide();" type="button" />
|
||||
<ui:include src="/templates/components/button-info.xhtml">
|
||||
<ui:param name="value" value="Appliquer" />
|
||||
<ui:param name="icon" value="pi pi-check" />
|
||||
<ui:param name="action" value="#{membreListeBean.appliquerFiltresAvances}" />
|
||||
<ui:param name="update" value=":formMembres:dtMembres" />
|
||||
<ui:param name="onclick" value="PF('dlgFiltresAvances').hide();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Réinitialiser" />
|
||||
<ui:param name="icon" value="pi pi-refresh" />
|
||||
<ui:param name="action" value="#{membreListeBean.reinitialiserFiltres}" />
|
||||
<ui:param name="update" value="@form :formMembres:dtMembres" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgFiltresAvances').hide();" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="ui-button-danger" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
@@ -370,14 +407,19 @@
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Envoyer" icon="pi pi-send"
|
||||
styleClass="ui-button-info"
|
||||
action="#{membreListeBean.envoyerMessageGroupe}"
|
||||
update="@form"
|
||||
oncomplete="if(!args.validationFailed) PF('dlgMessageGroupe').hide();" />
|
||||
<p:commandButton value="Annuler" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgMessageGroupe').hide();" type="button" />
|
||||
<ui:include src="/templates/components/button-info.xhtml">
|
||||
<ui:param name="value" value="Envoyer" />
|
||||
<ui:param name="icon" value="pi pi-send" />
|
||||
<ui:param name="action" value="#{membreListeBean.envoyerMessageGroupe}" />
|
||||
<ui:param name="update" value="@form" />
|
||||
<ui:param name="onclick" value="if(!args.validationFailed) PF('dlgMessageGroupe').hide();" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Annuler" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgMessageGroupe').hide();" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
@@ -408,13 +450,18 @@
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Importer" icon="pi pi-upload"
|
||||
styleClass="ui-button-success"
|
||||
action="#{membreListeBean.importerMembres}"
|
||||
update="@form :formMembres" />
|
||||
<p:commandButton value="Télécharger modèle" icon="pi pi-download"
|
||||
styleClass="ui-button-outlined ui-button-info"
|
||||
action="#{membreListeBean.telechargerModele}" />
|
||||
<ui:include src="/templates/components/button-success.xhtml">
|
||||
<ui:param name="value" value="Importer" />
|
||||
<ui:param name="icon" value="pi pi-upload" />
|
||||
<ui:param name="action" value="#{membreListeBean.importerMembres}" />
|
||||
<ui:param name="update" value="@form :formMembres" />
|
||||
</ui:include>
|
||||
<ui:include src="/templates/components/button-info.xhtml">
|
||||
<ui:param name="value" value="Télécharger modèle" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{membreListeBean.telechargerModele}" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:tab>
|
||||
|
||||
@@ -448,17 +495,22 @@
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 mt-3">
|
||||
<p:commandButton value="Exporter" icon="pi pi-download"
|
||||
styleClass="ui-button-success"
|
||||
action="#{membreListeBean.exporterMembres}" />
|
||||
<ui:include src="/templates/components/button-success.xhtml">
|
||||
<ui:param name="value" value="Exporter" />
|
||||
<ui:param name="icon" value="pi pi-download" />
|
||||
<ui:param name="action" value="#{membreListeBean.exporterMembres}" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</p:tab>
|
||||
</p:tabView>
|
||||
|
||||
<div class="flex justify-content-end mt-3">
|
||||
<p:commandButton value="Fermer" icon="pi pi-times"
|
||||
styleClass="ui-button-secondary"
|
||||
onclick="PF('dlgImportExport').hide();" type="button" />
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Fermer" />
|
||||
<ui:param name="icon" value="pi pi-times" />
|
||||
<ui:param name="onclick" value="PF('dlgImportExport').hide();" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</p:dialog>
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<!--
|
||||
Composant bouton icône seule réutilisable (WOU/DRY)
|
||||
Usage: <ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-icon-name" />
|
||||
<ui:param name="action" value="#{bean.method}" />
|
||||
<ui:param name="update" value="componentId" />
|
||||
<ui:param name="onclick" value="javascript" />
|
||||
<ui:param name="severity" value="info|success|warning|danger" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="true" />
|
||||
</ui:include>
|
||||
-->
|
||||
|
||||
<ui:fragment rendered="#{empty rendered or rendered}">
|
||||
<p:commandButton
|
||||
icon="#{icon}"
|
||||
action="#{action}"
|
||||
actionListener="#{actionListener}"
|
||||
update="#{update}"
|
||||
onclick="#{onclick}"
|
||||
disabled="#{not empty disabled and disabled}"
|
||||
styleClass="#{not empty rounded and rounded ? 'ui-button-rounded' : ''} #{not empty text and text ? 'ui-button-text' : ''} #{not empty severity ? 'ui-button-' += severity : ''} #{styleClass}"
|
||||
title="#{title}" />
|
||||
</ui:fragment>
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<!--
|
||||
Composant bouton info réutilisable (WOU/DRY)
|
||||
-->
|
||||
|
||||
<ui:fragment rendered="#{empty rendered or rendered}">
|
||||
<ui:fragment rendered="#{empty outcome}">
|
||||
<p:commandButton
|
||||
value="#{value}"
|
||||
icon="#{icon}"
|
||||
action="#{action}"
|
||||
actionListener="#{actionListener}"
|
||||
update="#{update}"
|
||||
onclick="#{onclick}"
|
||||
disabled="#{not empty disabled and disabled}"
|
||||
styleClass="ui-button-info #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{styleClass}"
|
||||
title="#{title}" />
|
||||
</ui:fragment>
|
||||
<ui:fragment rendered="#{not empty outcome}">
|
||||
<p:button
|
||||
value="#{value}"
|
||||
icon="#{icon}"
|
||||
outcome="#{outcome}"
|
||||
styleClass="ui-button-info #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{styleClass}"
|
||||
title="#{title}" />
|
||||
</ui:fragment>
|
||||
</ui:fragment>
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<!--
|
||||
Composant bouton primaire réutilisable (WOU/DRY)
|
||||
Usage: <ui:include src="/templates/components/button-primary.xhtml">
|
||||
<ui:param name="value" value="Texte du bouton" />
|
||||
<ui:param name="icon" value="pi pi-icon-name" />
|
||||
<ui:param name="action" value="#{bean.method}" />
|
||||
<ui:param name="outcome" value="/page" />
|
||||
<ui:param name="update" value="componentId" />
|
||||
<ui:param name="onclick" value="javascript" />
|
||||
<ui:param name="disabled" value="false" />
|
||||
<ui:param name="styleClass" value="" />
|
||||
</ui:include>
|
||||
-->
|
||||
|
||||
<ui:fragment rendered="#{empty rendered or rendered}">
|
||||
<ui:fragment rendered="#{empty outcome}">
|
||||
<p:commandButton
|
||||
value="#{value}"
|
||||
icon="#{icon}"
|
||||
action="#{action}"
|
||||
actionListener="#{actionListener}"
|
||||
update="#{update}"
|
||||
onclick="#{onclick}"
|
||||
disabled="#{not empty disabled and disabled}"
|
||||
styleClass="ui-button-primary #{styleClass}"
|
||||
title="#{title}" />
|
||||
</ui:fragment>
|
||||
<ui:fragment rendered="#{not empty outcome}">
|
||||
<p:button
|
||||
value="#{value}"
|
||||
icon="#{icon}"
|
||||
outcome="#{outcome}"
|
||||
styleClass="ui-button-primary #{styleClass}"
|
||||
title="#{title}" />
|
||||
</ui:fragment>
|
||||
</ui:fragment>
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<!--
|
||||
Composant bouton secondaire réutilisable (WOU/DRY)
|
||||
Usage: <ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="Texte du bouton" />
|
||||
<ui:param name="icon" value="pi pi-icon-name" />
|
||||
<ui:param name="action" value="#{bean.method}" />
|
||||
<ui:param name="outcome" value="/page" />
|
||||
<ui:param name="update" value="componentId" />
|
||||
<ui:param name="onclick" value="javascript" />
|
||||
<ui:param name="disabled" value="false" />
|
||||
<ui:param name="outlined" value="true" />
|
||||
<ui:param name="styleClass" value="" />
|
||||
</ui:include>
|
||||
-->
|
||||
|
||||
<ui:fragment rendered="#{empty rendered or rendered}">
|
||||
<ui:fragment rendered="#{empty outcome}">
|
||||
<p:commandButton
|
||||
value="#{value}"
|
||||
icon="#{icon}"
|
||||
action="#{action}"
|
||||
actionListener="#{actionListener}"
|
||||
update="#{update}"
|
||||
onclick="#{onclick}"
|
||||
disabled="#{not empty disabled and disabled}"
|
||||
styleClass="ui-button-secondary #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{styleClass}"
|
||||
title="#{title}" />
|
||||
</ui:fragment>
|
||||
<ui:fragment rendered="#{not empty outcome}">
|
||||
<p:button
|
||||
value="#{value}"
|
||||
icon="#{icon}"
|
||||
outcome="#{outcome}"
|
||||
styleClass="ui-button-secondary #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{styleClass}"
|
||||
title="#{title}" />
|
||||
</ui:fragment>
|
||||
</ui:fragment>
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<!--
|
||||
Composant bouton succès réutilisable (WOU/DRY)
|
||||
-->
|
||||
|
||||
<ui:fragment rendered="#{empty rendered or rendered}">
|
||||
<ui:fragment rendered="#{empty outcome}">
|
||||
<p:commandButton
|
||||
value="#{value}"
|
||||
icon="#{icon}"
|
||||
action="#{action}"
|
||||
actionListener="#{actionListener}"
|
||||
update="#{update}"
|
||||
onclick="#{onclick}"
|
||||
disabled="#{not empty disabled and disabled}"
|
||||
styleClass="ui-button-success #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{styleClass}"
|
||||
title="#{title}" />
|
||||
</ui:fragment>
|
||||
<ui:fragment rendered="#{not empty outcome}">
|
||||
<p:button
|
||||
value="#{value}"
|
||||
icon="#{icon}"
|
||||
outcome="#{outcome}"
|
||||
styleClass="ui-button-success #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{styleClass}"
|
||||
title="#{title}" />
|
||||
</ui:fragment>
|
||||
</ui:fragment>
|
||||
</ui:composition>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||
xmlns:p="http://primefaces.org/ui">
|
||||
|
||||
<!--
|
||||
Composant bouton warning réutilisable (WOU/DRY)
|
||||
-->
|
||||
|
||||
<ui:fragment rendered="#{empty rendered or rendered}">
|
||||
<ui:fragment rendered="#{empty outcome}">
|
||||
<p:commandButton
|
||||
value="#{value}"
|
||||
icon="#{icon}"
|
||||
action="#{action}"
|
||||
actionListener="#{actionListener}"
|
||||
update="#{update}"
|
||||
onclick="#{onclick}"
|
||||
disabled="#{not empty disabled and disabled}"
|
||||
styleClass="ui-button-warning #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{styleClass}"
|
||||
title="#{title}" />
|
||||
</ui:fragment>
|
||||
<ui:fragment rendered="#{not empty outcome}">
|
||||
<p:button
|
||||
value="#{value}"
|
||||
icon="#{icon}"
|
||||
outcome="#{outcome}"
|
||||
styleClass="ui-button-warning #{not empty outlined and outlined ? 'ui-button-outlined' : ''} #{styleClass}"
|
||||
title="#{title}" />
|
||||
</ui:fragment>
|
||||
</ui:fragment>
|
||||
</ui:composition>
|
||||
|
||||
@@ -41,7 +41,10 @@
|
||||
<h:form>
|
||||
<div class="newsletter-input">
|
||||
<p:inputText placeholder="adresse email" />
|
||||
<p:commandButton value="S'abonner" styleClass="ui-button-secondary "/>
|
||||
<ui:include src="/templates/components/button-secondary.xhtml">
|
||||
<ui:param name="value" value="S'abonner" />
|
||||
<ui:param name="outlined" value="false" />
|
||||
</ui:include>
|
||||
</div>
|
||||
</h:form>
|
||||
</div>
|
||||
|
||||
@@ -22,7 +22,12 @@
|
||||
<div class="section-header">
|
||||
<h6>Mes tâches</h6>
|
||||
<h:form>
|
||||
<p:commandButton type="button" icon="pi pi-plus" styleClass="ui-button-secondary ui-button-flat rounded-button" />
|
||||
<ui:include src="/templates/components/button-icon.xhtml">
|
||||
<ui:param name="icon" value="pi pi-plus" />
|
||||
<ui:param name="rounded" value="true" />
|
||||
<ui:param name="text" value="false" />
|
||||
<ui:param name="styleClass" value="ui-button-secondary ui-button-flat" />
|
||||
</ui:include>
|
||||
</h:form>
|
||||
</div>
|
||||
<ul>
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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<74>me par d<>faut et chargeons le th<74>me Freya via index.xhtml/main-template.xhtml
|
||||
# pour <20>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<71>e c<>t<EFBFBD> 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<63>s ci?dessous couvrent les variantes selon version de Quarkus; l'une sera ignor<6F>e si non support<72>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<6F>g<EFBFBD>s par OIDC) - Doit <20>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 <20>tre publiques pour permettre le chargement des CSS/JS (th<74>me Freya, primeicons, primeflex, etc.)
|
||||
# On inclut <20>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
|
||||
Reference in New Issue
Block a user