diff --git a/CHANGELOG.md b/CHANGELOG.md
index 43d69f6..5ec864b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -84,7 +84,7 @@ et ce projet adhère au [Semantic Versioning](https://semver.org/lang/fr/).
- ✅ **FavorisBean** - Favoris utilisateur
- ✅ **WaveBean** - Intégration Wave Money
- ✅ **LoginBean** - Authentification
-- ✅ **EntitesGestionBean** - Gestion des entités
+- ✅ **OrganisationsBean** - Gestion des organisations
- ✅ Et 9 autres beans...
##### Changements par Bean
diff --git a/README.md b/README.md
index d7172a8..3806b5a 100644
--- a/README.md
+++ b/README.md
@@ -253,7 +253,7 @@ export LOCKOUT_DURATION="300"
- Web Origins: `https://votre-domaine.com`
3. Configurer les rôles:
- `SUPER_ADMIN`: Administrateur système
- - `ADMIN_ENTITE`: Administrateur d'organisation
+ - `ADMIN_ORGANISATION`: Administrateur d'organisation
- `MEMBRE`: Membre standard
4. Configurer les mappers pour inclure les rôles dans les tokens JWT
@@ -302,7 +302,7 @@ docker run -p 8080:8080 \
- **Méthode**: OpenID Connect (OIDC) via Keycloak
- **Tokens**: JWT (JSON Web Tokens)
-- **Rôles supportés**: SUPER_ADMIN, ADMIN_ENTITE, MEMBRE
+- **Rôles supportés**: SUPER_ADMIN, ADMIN_ORGANISATION, MEMBRE
- **Permissions granulaires**: Basées sur les rôles et fonctionnalités
### Headers de Sécurité (Production)
diff --git a/SECURITY.md b/SECURITY.md
index 673bd4a..145d778 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -98,7 +98,7 @@ quarkus.oidc.tls.verification=required # JAMAIS 'none' en production
#### Hiérarchie des Rôles
1. **SUPER_ADMIN** - Accès complet système
-2. **ADMIN_ENTITE** - Administration organisation
+2. **ADMIN_ORGANISATION** - Administration organisation
3. **ADMIN** - Administration locale
4. **GESTIONNAIRE_*** - Gestion fonctionnelle
5. **TRESORIER** - Gestion financière
diff --git a/setup-keycloak.bat b/setup-keycloak.bat
index c23b4f2..41f2858 100644
--- a/setup-keycloak.bat
+++ b/setup-keycloak.bat
@@ -82,8 +82,8 @@ echo ✅ Rôle SUPER_ADMIN créé
curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
-H "Authorization: Bearer %ADMIN_TOKEN%" ^
-H "Content-Type: application/json" ^
- -d "{\"name\":\"ADMIN_ENTITE\",\"description\":\"Administrateur d'entité\"}" > nul 2>&1
-echo ✅ Rôle ADMIN_ENTITE créé
+ -d "{\"name\":\"ADMIN_ORGANISATION\",\"description\":\"Administrateur d'entité\"}" > nul 2>&1
+echo ✅ Rôle ADMIN_ORGANISATION créé
curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
-H "Authorization: Bearer %ADMIN_TOKEN%" ^
@@ -205,9 +205,9 @@ if not "%USER_ID%"=="" (
curl -s -X GET "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/roles" ^
-H "Authorization: Bearer %ADMIN_TOKEN%" > roles.json
- REM Assigner les rôles MEMBRE et ADMIN_ENTITE
+ REM Assigner les rôles MEMBRE et ADMIN_ORGANISATION
for /f "delims=" %%i in ('powershell -Command "(Get-Content roles.json | ConvertFrom-Json) | Where-Object {$_.name -eq 'MEMBRE'} | Select-Object -ExpandProperty id"') do set ROLE_MEMBRE_ID=%%i
- for /f "delims=" %%i in ('powershell -Command "(Get-Content roles.json | ConvertFrom-Json) | Where-Object {$_.name -eq 'ADMIN_ENTITE'} | Select-Object -ExpandProperty id"') do set ROLE_ADMIN_ID=%%i
+ for /f "delims=" %%i in ('powershell -Command "(Get-Content roles.json | ConvertFrom-Json) | Where-Object {$_.name -eq 'ADMIN_ORGANISATION'} | Select-Object -ExpandProperty id"') do set ROLE_ADMIN_ID=%%i
if not "%ROLE_MEMBRE_ID%"=="" (
curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/users/%USER_ID%/role-mappings/realm" ^
@@ -221,8 +221,8 @@ if not "%USER_ID%"=="" (
curl -s -X POST "%KEYCLOAK_URL%/admin/realms/%REALM_NAME%/users/%USER_ID%/role-mappings/realm" ^
-H "Authorization: Bearer %ADMIN_TOKEN%" ^
-H "Content-Type: application/json" ^
- -d "[{\"id\":\"%ROLE_ADMIN_ID%\",\"name\":\"ADMIN_ENTITE\"}]" > nul 2>&1
- echo ✅ Rôle ADMIN_ENTITE assigné
+ -d "[{\"id\":\"%ROLE_ADMIN_ID%\",\"name\":\"ADMIN_ORGANISATION\"}]" > nul 2>&1
+ echo ✅ Rôle ADMIN_ORGANISATION assigné
)
) else (
echo ⚠️ Impossible de configurer l'utilisateur
@@ -262,7 +262,7 @@ echo - Client ID: %CLIENT_ID%
echo - Client Secret: %CLIENT_SECRET%
echo - Utilisateur test: test@unionflow.dev
echo - Mot de passe: test123
-echo - Rôles assignés: MEMBRE, ADMIN_ENTITE
+echo - Rôles assignés: MEMBRE, ADMIN_ORGANISATION
echo.
echo 📄 Le client secret a été sauvegardé dans le fichier .env
echo.
diff --git a/setup-keycloak.sh b/setup-keycloak.sh
index 2ad6897..604ff78 100644
--- a/setup-keycloak.sh
+++ b/setup-keycloak.sh
@@ -78,8 +78,8 @@ echo " ✅ Rôle SUPER_ADMIN créé"
curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
- -d '{"name":"ADMIN_ENTITE","description":"Administrateur d'\''entité"}' > /dev/null 2>&1
-echo " ✅ Rôle ADMIN_ENTITE créé"
+ -d '{"name":"ADMIN_ORGANISATION","description":"Administrateur d'\''entité"}' > /dev/null 2>&1
+echo " ✅ Rôle ADMIN_ORGANISATION créé"
curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/roles" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
@@ -240,11 +240,11 @@ if [ -n "$USER_ID" ]; then
-H "Authorization: Bearer $ADMIN_TOKEN")
ROLE_MEMBRE_ID=$(echo "$ROLES" | grep -B2 '"name":"MEMBRE"' | grep '"id"' | cut -d'"' -f4)
- ROLE_ADMIN_ID=$(echo "$ROLES" | grep -B2 '"name":"ADMIN_ENTITE"' | grep '"id"' | cut -d'"' -f4)
+ ROLE_ADMIN_ID=$(echo "$ROLES" | grep -B2 '"name":"ADMIN_ORGANISATION"' | grep '"id"' | cut -d'"' -f4)
if command -v jq &> /dev/null; then
ROLE_MEMBRE_ID=$(echo "$ROLES" | jq -r '.[] | select(.name=="MEMBRE") | .id')
- ROLE_ADMIN_ID=$(echo "$ROLES" | jq -r '.[] | select(.name=="ADMIN_ENTITE") | .id')
+ ROLE_ADMIN_ID=$(echo "$ROLES" | jq -r '.[] | select(.name=="ADMIN_ORGANISATION") | .id')
fi
if [ -n "$ROLE_MEMBRE_ID" ]; then
@@ -259,8 +259,8 @@ if [ -n "$USER_ID" ]; then
curl -s -X POST "$KEYCLOAK_URL/admin/realms/$REALM_NAME/users/$USER_ID/role-mappings/realm" \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
- -d "[{\"id\":\"$ROLE_ADMIN_ID\",\"name\":\"ADMIN_ENTITE\"}]" > /dev/null 2>&1
- echo " ✅ Rôle ADMIN_ENTITE assigné"
+ -d "[{\"id\":\"$ROLE_ADMIN_ID\",\"name\":\"ADMIN_ORGANISATION\"}]" > /dev/null 2>&1
+ echo " ✅ Rôle ADMIN_ORGANISATION assigné"
fi
else
echo "⚠️ Impossible de configurer l'utilisateur"
@@ -297,7 +297,7 @@ echo " - Client ID: $CLIENT_ID"
echo " - Client Secret: $CLIENT_SECRET"
echo " - Utilisateur test: test@unionflow.dev"
echo " - Mot de passe: test123"
-echo " - Rôles assignés: MEMBRE, ADMIN_ENTITE"
+echo " - Rôles assignés: MEMBRE, ADMIN_ORGANISATION"
echo ""
echo "📄 Le client secret a été sauvegardé dans le fichier .env"
echo ""
diff --git a/src/main/java/dev/lions/unionflow/client/UnionFlowClientApplication.java b/src/main/java/dev/lions/unionflow/client/UnionFlowClientApplication.java
index b594346..fdffe88 100644
--- a/src/main/java/dev/lions/unionflow/client/UnionFlowClientApplication.java
+++ b/src/main/java/dev/lions/unionflow/client/UnionFlowClientApplication.java
@@ -85,7 +85,7 @@ import org.jboss.logging.Logger;
*
OIDC avec Keycloak (realm: unionflow)
* JWT dans HTTP-only cookies (protection XSS)
* CSRF protection avec PrimeFaces ViewState
- * RBAC avec rôles: SUPER_ADMIN, ADMIN_ENTITE, MEMBRE
+ * RBAC avec rôles: SUPER_ADMIN, ADMIN_ORGANISATION, MEMBRE
* ViewExpiredException handling pour timeout session
* HTTPS obligatoire en production
* Content Security Policy headers
diff --git a/src/main/java/dev/lions/unionflow/client/bean/MenuBean.java b/src/main/java/dev/lions/unionflow/client/bean/MenuBean.java
index fb54b23..cdf294e 100644
--- a/src/main/java/dev/lions/unionflow/client/bean/MenuBean.java
+++ b/src/main/java/dev/lions/unionflow/client/bean/MenuBean.java
@@ -152,15 +152,6 @@ public class MenuBean implements Serializable {
// MEMBRE_ACTIF retiré intentionnellement pour raisons UX et RGPD
}
- /**
- * DEPRECATED: Utilisez isGestionMembresMenuVisible() ou isAnnuaireMembresVisible()
- * @deprecated Remplacé par isGestionMembresMenuVisible() et isAnnuaireMembresVisible()
- */
- @Deprecated
- public boolean isMembresMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "MEMBRE_BUREAU", "MEMBRE_ACTIF");
- }
-
/**
* Gestion Financière - Administration finances (trésorerie, budgets, comptabilité)
* Visible pour TRESORIER et ADMIN uniquement
@@ -199,33 +190,6 @@ public class MenuBean implements Serializable {
return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "SECRETAIRE", "MEMBRE_BUREAU");
}
- /**
- * DEPRECATED: Utilisez isGestionFinancesMenuVisible() ou isMesFinancesMenuVisible()
- * @deprecated Remplacé par isGestionFinancesMenuVisible() (admin) et isMesFinancesMenuVisible() (membre)
- */
- @Deprecated
- public boolean isFinancesMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "TRESORIER", "RESPONSABLE_CREDIT", "MEMBRE_BUREAU");
- }
-
- /**
- * DEPRECATED: Utilisez isGestionAidesSocialesMenuVisible() ou isMesAidesSocialesMenuVisible()
- * @deprecated Remplacé par isGestionAidesSocialesMenuVisible() (admin) et isMesAidesSocialesMenuVisible() (membre)
- */
- @Deprecated
- public boolean isAidesMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "RESPONSABLE_SOCIAL", "SECRETAIRE", "MEMBRE_BUREAU");
- }
-
- /**
- * DEPRECATED: Utilisez isGestionEvenementsMenuVisible() ou isMesEvenementsMenuVisible()
- * @deprecated Remplacé par isGestionEvenementsMenuVisible() (admin) et isMesEvenementsMenuVisible() (membre)
- */
- @Deprecated
- public boolean isEvenementsMenuVisible() {
- return hasAnyRole("SUPER_ADMIN", "ADMIN_ORGANISATION", "RESPONSABLE_EVENEMENTS", "SECRETAIRE", "MEMBRE_BUREAU", "MEMBRE_ACTIF");
- }
-
/**
* Communication - Visible pour admins, secrétaires, bureau
*/
diff --git a/src/main/java/dev/lions/unionflow/client/view/EntitesGestionBean.java b/src/main/java/dev/lions/unionflow/client/view/EntitesGestionBean.java
deleted file mode 100644
index f67d3f0..0000000
--- a/src/main/java/dev/lions/unionflow/client/view/EntitesGestionBean.java
+++ /dev/null
@@ -1,1217 +0,0 @@
-package dev.lions.unionflow.client.view;
-
-import dev.lions.unionflow.server.api.dto.organisation.response.OrganisationResponse;
-import dev.lions.unionflow.server.api.dto.organisation.response.OrganisationSummaryResponse;
-import dev.lions.unionflow.server.api.dto.common.PagedResponse;
-import dev.lions.unionflow.server.api.dto.souscription.SouscriptionStatutResponse;
-import dev.lions.unionflow.server.api.dto.common.PagedResponse;
-import dev.lions.unionflow.client.service.OrganisationService;
-import dev.lions.unionflow.client.service.CotisationService;
-import dev.lions.unionflow.client.service.ErrorHandlerService;
-import dev.lions.unionflow.client.service.SouscriptionService;
-import dev.lions.unionflow.client.service.TypeCatalogueService;
-import jakarta.faces.model.SelectItem;
-import java.util.Map;
-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.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 org.jboss.logging.Logger;
-
-@Named("entitesGestionBean")
-@SessionScoped
-public class EntitesGestionBean implements Serializable {
-
- private static final long serialVersionUID = 1L;
- private static final Logger LOG = Logger.getLogger(EntitesGestionBean.class);
-
- // Constantes de navigation outcomes (WOU/DRY - réutilisables)
- private static final String OUTCOME_ENTITE_DETAILS = "entiteDetailsPage";
- private static final String OUTCOME_ADMIN_MEMBRES_GESTION = "adminMembresGestionPage";
- private static final String OUTCOME_ENTITE_CONFIGURATION = "entiteConfigurationPage";
- private static final String OUTCOME_ENTITE_RAPPORTS = "entiteRapportsPage";
-
- @Inject
- @RestClient
- private OrganisationService organisationService;
-
- @Inject
- @RestClient
- private CotisationService cotisationService;
-
- @Inject
- @RestClient
- private SouscriptionService souscriptionService;
-
- @Inject
- TypeCatalogueService typeCatalogueService;
-
- @Inject
- ErrorHandlerService errorHandler;
-
- private List toutesLesEntites;
- private List entitesFiltrees;
- private List entitesSelectionnees;
- private Entite entiteSelectionne;
- private OrganisationResponse entiteEnEdition;
- private Entite nouvelleEntite;
- private Filtres filtres;
- private Statistiques statistiques;
-
- @PostConstruct
- public void init() {
- initializeFiltres();
- initializeEntites();
- initializeStatistiques();
- initializeNouvelleEntite();
- appliquerFiltres();
- }
-
- public List getTypesSelectItems() {
- return typeCatalogueService.getSelectItems("Tous les types");
- }
-
- public List getTypesSelectItemsForForm() {
- return typeCatalogueService.getSelectItems("Sélectionner un type *");
- }
-
- public List getRegionsDisponibles() {
- List items = new ArrayList<>();
- items.add(new SelectItem("", "Toutes les régions"));
- if (toutesLesEntites != null) {
- toutesLesEntites.stream()
- .map(Entite::getRegion)
- .filter(r -> r != null && !r.trim().isEmpty())
- .distinct()
- .sorted()
- .forEach(r -> items.add(new SelectItem(r, r)));
- }
- return items;
- }
-
- private void initializeFiltres() {
- filtres = new Filtres();
- entitesSelectionnees = new ArrayList<>();
- }
-
- private void initializeStatistiques() {
- statistiques = new Statistiques();
- try {
- PagedResponse response = organisationService.listerToutes(0, 1000);
- List associations = new ArrayList<>();
- if (response != null && response.getData() != null) {
- associations = response.getData();
- }
- 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);
- initializeRevenusStats();
- statistiques.setSouscriptionsExpirantes(0);
- statistiques.setEntitesQuotaAtteint(0);
- initializeSouscriptionStats(associations);
- statistiques.setFormulairePopulaire("N/A");
- statistiques.setTauxRenouvellement(0.0f);
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors du calcul des statistiques");
- statistiques.setTotalEntites(0);
- statistiques.setEntitesActives(0);
- statistiques.setTotalMembres(0);
- statistiques.setMoyenneMembresParEntite(0);
- }
- calculerStatistiquesSouscriptions();
- }
-
- private void initializeEntites() {
- toutesLesEntites = new ArrayList<>();
- try {
- PagedResponse response = organisationService.listerToutes(0, 1000);
- if (response != null && response.getData() != null) {
- for (OrganisationSummaryResponse dto : response.getData()) {
- Entite entite = convertToEntite(dto);
- toutesLesEntites.add(entite);
- }
- }
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors du chargement des entités");
- }
- }
-
- private Entite convertToEntite(OrganisationSummaryResponse dto) {
- Entite entite = new Entite();
- entite.setId(dto.getId());
- entite.setNom(dto.getNom());
- entite.setCodeEntite(dto.getNomCourt()); // Using nomCourt as code
- entite.setType(dto.getTypeOrganisation());
- entite.setTypeLibelle(typeCatalogueService.resolveLibelle(dto.getTypeOrganisation()));
- entite.setRegion(null); // Not available in Summary
- entite.setStatut(dto.getStatut());
- entite.setNombreMembres(dto.getNombreMembres() != null ? dto.getNombreMembres() : 0);
- entite.setMembresUtilises(dto.getNombreMembres() != null ? dto.getNombreMembres() : 0);
- entite.setAdresse(null); // Not available in Summary
- entite.setTelephone(null); // Not available in Summary
- entite.setEmail(null); // Not available in Summary
- entite.setDescription(null); // Not available in Summary
- entite.setDerniereActivite(null); // Not available in Summary
-
- try {
- SouscriptionStatutResponse souscription = souscriptionService.obtenirActive(dto.getId());
- if (souscription != null) {
- entite.setForfaitSouscrit(
- souscription.getPlanCommercial() != null ? souscription.getPlanCommercial() : "Non défini");
- entite.setMembresQuota(
- souscription.getQuotaMax() != null ? souscription.getQuotaMax() : 0);
- entite.setMontantMensuel(souscription.getMontantTotal() != null
- ? String.format("%,.0f FCFA", souscription.getMontantTotal().doubleValue())
- : "0 FCFA");
- entite.setDateExpirationSouscription(souscription.getDateFin());
- entite.setStatutSouscription(
- souscription.getStatut() != null ? souscription.getStatut() : "NON_DEFINI");
- } else {
- entite.setForfaitSouscrit("Non défini");
- entite.setMembresQuota(0);
- entite.setMontantMensuel("0 FCFA");
- entite.setDateExpirationSouscription(null);
- entite.setStatutSouscription("NON_DEFINI");
- }
- } catch (Exception e) {
- entite.setForfaitSouscrit("Non défini");
- entite.setMembresQuota(0);
- entite.setMontantMensuel("0 FCFA");
- entite.setDateExpirationSouscription(null);
- entite.setStatutSouscription("NON_DEFINI");
- }
-
- return entite;
- }
-
- // Overload for full OrganisationResponse (CRUD operations)
- private Entite convertToEntite(OrganisationResponse dto) {
- Entite entite = new Entite();
- entite.setId(dto.getId());
- entite.setNom(dto.getNom());
- entite.setCodeEntite(dto.getNomCourt());
- entite.setType(dto.getTypeOrganisation());
- entite.setTypeLibelle(typeCatalogueService.resolveLibelle(dto.getTypeOrganisation()));
- entite.setRegion(dto.getRegion());
- entite.setVille(dto.getVille());
- 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(null);
-
- try {
- SouscriptionStatutResponse souscription = souscriptionService.obtenirActive(dto.getId());
- if (souscription != null) {
- entite.setForfaitSouscrit(
- souscription.getPlanCommercial() != null ? souscription.getPlanCommercial() : "Non défini");
- entite.setMembresQuota(
- souscription.getQuotaMax() != null ? souscription.getQuotaMax() : 0);
- entite.setMontantMensuel(souscription.getMontantTotal() != null
- ? String.format("%,.0f FCFA", souscription.getMontantTotal().doubleValue())
- : "0 FCFA");
- entite.setDateExpirationSouscription(souscription.getDateFin());
- entite.setStatutSouscription(
- souscription.getStatut() != null ? souscription.getStatut() : "NON_DEFINI");
- } else {
- entite.setForfaitSouscrit("Non défini");
- entite.setMembresQuota(0);
- entite.setMontantMensuel("0 FCFA");
- entite.setDateExpirationSouscription(null);
- entite.setStatutSouscription("NON_DEFINI");
- }
- } catch (Exception e) {
- entite.setForfaitSouscrit("Non défini");
- entite.setMembresQuota(0);
- entite.setMontantMensuel("0 FCFA");
- entite.setDateExpirationSouscription(null);
- entite.setStatutSouscription("NON_DEFINI");
- }
-
- return entite;
- }
-
- private void initializeNouvelleEntite() {
- nouvelleEntite = new Entite();
- }
-
- private void appliquerFiltres() {
- entitesFiltrees = toutesLesEntites.stream()
- .filter(this::appliquerFiltre)
- .collect(Collectors.toList());
- }
-
- private boolean appliquerFiltre(Entite entite) {
- // Filtre par nom
- if (filtres.getNom() != null && !filtres.getNom().trim().isEmpty()) {
- if (!entite.getNom().toLowerCase().contains(filtres.getNom().toLowerCase())) {
- return false;
- }
- }
-
- // Filtre par type
- if (filtres.getType() != null && !filtres.getType().trim().isEmpty()) {
- if (!entite.getType().equals(filtres.getType())) {
- return false;
- }
- }
-
- // Filtre par statut
- if (filtres.getStatut() != null && !filtres.getStatut().trim().isEmpty()) {
- if (!entite.getStatut().equals(filtres.getStatut())) {
- return false;
- }
- }
-
- // Filtre par région
- if (filtres.getRegion() != null && !filtres.getRegion().trim().isEmpty()) {
- if (!entite.getRegion().equals(filtres.getRegion())) {
- return false;
- }
- }
-
- // Filtre par forfait
- if (filtres.getForfait() != null && !filtres.getForfait().trim().isEmpty()) {
- if (!entite.getForfaitSouscrit().equals(filtres.getForfait())) {
- return false;
- }
- }
-
- // Filtre par alerte quota
- if (filtres.getAlerteQuota() != null && !filtres.getAlerteQuota().trim().isEmpty()) {
- if ("OUI".equals(filtres.getAlerteQuota()) && !entite.isQuotaProche()) {
- return false;
- }
- if ("NON".equals(filtres.getAlerteQuota()) && entite.isQuotaProche()) {
- return false;
- }
- }
-
- // Filtre par alerte expiration
- if (filtres.getAlerteExpiration() != null && !filtres.getAlerteExpiration().trim().isEmpty()) {
- if ("OUI".equals(filtres.getAlerteExpiration()) && !entite.isExpirationProche()) {
- return false;
- }
- if ("NON".equals(filtres.getAlerteExpiration()) && entite.isExpirationProche()) {
- return false;
- }
- }
-
- // Filtre par statut souscription
- if (filtres.getStatutSouscription() != null && !filtres.getStatutSouscription().trim().isEmpty()) {
- if (!entite.getStatutSouscription().equals(filtres.getStatutSouscription())) {
- return false;
- }
- }
-
- return true;
- }
-
- // Actions
- public void rechercher() {
- appliquerFiltres();
- }
-
- public void reinitialiserFiltres() {
- filtres = new Filtres();
- appliquerFiltres();
- }
-
- public String voirEntite(Entite entite) {
- return "/pages/secure/organisation/detail.xhtml?id=" + entite.getId() + "&faces-redirect=true";
- }
-
- public void creerEntite() {
- if (nouvelleEntite == null || nouvelleEntite.getNom() == null || nouvelleEntite.getNom().isBlank()) {
- LOG.warn("Tentative de création d'une entité sans nom");
- return;
- }
-
- try {
- OrganisationResponse dto = new OrganisationResponse();
- dto.setNom(nouvelleEntite.getNom());
- dto.setTypeOrganisation(nouvelleEntite.getType());
- dto.setRegion(nouvelleEntite.getRegion());
- dto.setAdresse(nouvelleEntite.getAdresse());
- dto.setVille(nouvelleEntite.getVille());
- dto.setTelephone(nouvelleEntite.getTelephone());
- dto.setEmail(nouvelleEntite.getEmail());
- dto.setDescription(nouvelleEntite.getDescription());
- dto.setStatut("ACTIVE");
-
- OrganisationResponse creee = organisationService.creer(dto);
- LOG.infof("Entité créée avec succès : id=%s, nom=%s", creee.getId(), creee.getNom());
-
- toutesLesEntites.add(convertToEntite(creee));
- appliquerFiltres();
- initializeNouvelleEntite();
-
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors de la création de l'entité");
- }
- }
-
- // ── Préparation du dialog Modifier ──────────────────────────────────────
-
- public void preparerModification(Entite entite) {
- this.entiteSelectionne = entite;
- try {
- entiteEnEdition = organisationService.obtenirParId(entite.getId());
- } catch (Exception e) {
- LOG.errorf(e, "Impossible de charger les détails de l'entité %s pour modification", entite.getId());
- entiteEnEdition = new OrganisationResponse();
- entiteEnEdition.setId(entite.getId());
- entiteEnEdition.setNom(entite.getNom());
- entiteEnEdition.setTypeOrganisation(entite.getType());
- entiteEnEdition.setRegion(entite.getRegion());
- entiteEnEdition.setAdresse(entite.getAdresse());
- entiteEnEdition.setVille(entite.getVille());
- entiteEnEdition.setTelephone(entite.getTelephone());
- entiteEnEdition.setEmail(entite.getEmail());
- entiteEnEdition.setStatut(entite.getStatut());
- }
- }
-
- public void modifierEntite() {
- if (entiteEnEdition == null || entiteEnEdition.getId() == null) return;
- try {
- OrganisationResponse maj = organisationService.modifier(entiteEnEdition.getId(), entiteEnEdition);
- Entite entiteMaj = convertToEntite(maj);
- int idx = -1;
- for (int i = 0; i < toutesLesEntites.size(); i++) {
- if (toutesLesEntites.get(i).getId().equals(maj.getId())) {
- idx = i;
- break;
- }
- }
- if (idx >= 0) toutesLesEntites.set(idx, entiteMaj);
- appliquerFiltres();
- errorHandler.showSuccess("Succès", "Entité '" + maj.getNom() + "' modifiée.");
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors de la modification de l'entité");
- errorHandler.handleException(e, "lors de la modification de l'entité", null);
- }
- }
-
- // ── Navigation depuis le dialog Actions ─────────────────────────────────
-
- public String gererMembres() {
- if (entiteSelectionne == null) return null;
- return "/pages/secure/membre/liste.xhtml?organisationId=" + entiteSelectionne.getId() + "&faces-redirect=true";
- }
-
- public String configurerEntite() {
- if (entiteSelectionne == null) return null;
- return "/pages/secure/organisation/detail.xhtml?id=" + entiteSelectionne.getId() + "&faces-redirect=true";
- }
-
- public String voirRapports() {
- if (entiteSelectionne == null) return null;
- return "/pages/admin/rapports/statistiques.xhtml?faces-redirect=true";
- }
-
- // ── Actions de statut (persistées en base) ────────────────────────────────
-
- public void suspendreEntite() {
- if (entiteSelectionne == null) return;
- try {
- OrganisationResponse maj = organisationService.suspendre(entiteSelectionne.getId());
- mettreAJourStatutEntite(maj);
- errorHandler.showSuccess("Suspendues", "Entité '" + entiteSelectionne.getNom() + "' suspendue.");
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors de la suspension de l'entité");
- errorHandler.handleException(e, "lors de la suspension de l'entité", null);
- }
- }
-
- public void reactiverEntite() {
- if (entiteSelectionne == null) return;
- try {
- OrganisationResponse maj = organisationService.activer(entiteSelectionne.getId());
- mettreAJourStatutEntite(maj);
- errorHandler.showSuccess("Réactivée", "Entité '" + entiteSelectionne.getNom() + "' réactivée.");
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors de la réactivation de l'entité");
- errorHandler.handleException(e, "lors de la réactivation de l'entité", null);
- }
- }
-
- private void mettreAJourStatutEntite(OrganisationResponse maj) {
- for (Entite e : toutesLesEntites) {
- if (e.getId().equals(maj.getId())) {
- e.setStatut(maj.getStatut());
- break;
- }
- }
- appliquerFiltres();
- }
-
- public void supprimerEntite() {
- if (entiteSelectionne == null) return;
- try {
- organisationService.supprimer(entiteSelectionne.getId());
- toutesLesEntites.removeIf(e -> e.getId().equals(entiteSelectionne.getId()));
- appliquerFiltres();
- errorHandler.showSuccess("Supprimée", "Entité supprimée avec succès.");
- entiteSelectionne = null;
- } catch (Exception e) {
- LOG.errorf(e, "Erreur lors de la suppression de l'entité");
- errorHandler.handleException(e, "lors de la suppression de l'entité", null);
- }
- }
-
- public void exporterEntites() {
- LOG.infof("Export de %d entités", entitesFiltrees.size());
- }
-
- // Getters et Setters
- public List getToutesLesEntites() {
- return toutesLesEntites;
- }
-
- public void setToutesLesEntites(List toutesLesEntites) {
- this.toutesLesEntites = toutesLesEntites;
- }
-
- public List getEntitesFiltrees() {
- return entitesFiltrees;
- }
-
- public void setEntitesFiltrees(List entitesFiltrees) {
- this.entitesFiltrees = entitesFiltrees;
- }
-
- public List getEntitesSelectionnees() {
- return entitesSelectionnees;
- }
-
- public void setEntitesSelectionnees(List entitesSelectionnees) {
- this.entitesSelectionnees = entitesSelectionnees;
- }
-
- public Entite getEntiteSelectionne() {
- return entiteSelectionne;
- }
-
- public void setEntiteSelectionne(Entite entiteSelectionne) {
- this.entiteSelectionne = entiteSelectionne;
- }
-
- public OrganisationResponse getEntiteEnEdition() { return entiteEnEdition; }
- public void setEntiteEnEdition(OrganisationResponse entiteEnEdition) { this.entiteEnEdition = entiteEnEdition; }
-
- public Entite getNouvelleEntite() {
- return nouvelleEntite;
- }
-
- public void setNouvelleEntite(Entite nouvelleEntite) {
- this.nouvelleEntite = nouvelleEntite;
- }
-
- public Filtres getFiltres() {
- return filtres;
- }
-
- public void setFiltres(Filtres filtres) {
- this.filtres = filtres;
- }
-
- public Statistiques getStatistiques() {
- return statistiques;
- }
-
- public void setStatistiques(Statistiques statistiques) {
- this.statistiques = statistiques;
- }
-
- private void initializeRevenusStats() {
- try {
- Map stats = cotisationService.obtenirStatistiques();
- if (stats != null) {
- Object montantTotal = stats.get("montantTotal");
- if (montantTotal instanceof Number) {
- statistiques.setRevenus(String.format("%,.0f FCFA", ((Number) montantTotal).doubleValue()));
- } else {
- statistiques.setRevenus("0 FCFA");
- }
- } else {
- statistiques.setRevenus("0 FCFA");
- }
- } catch (Exception e) {
- LOG.debugf("Impossible de charger les stats cotisations: %s", e.getMessage());
- statistiques.setRevenus("0 FCFA");
- }
- }
-
- private void initializeSouscriptionStats(List associations) {
- try {
- int expirantes = 0;
- int totalSouscriptions = 0;
- int souscriptionsActives = 0;
- String forfaitLePlusPopulaire = "N/A";
- Map forfaitCount = new java.util.HashMap<>();
-
- for (OrganisationSummaryResponse assoc : associations) {
- try {
- SouscriptionStatutResponse souscription = souscriptionService.obtenirActive(assoc.getId());
- if (souscription != null) {
- totalSouscriptions++;
- if ("ACTIVE".equals(souscription.getStatut())) {
- souscriptionsActives++;
- }
- if (souscription.getDateFin() != null
- && souscription.getDateFin().isAfter(LocalDate.now())
- && souscription.getDateFin().isBefore(LocalDate.now().plusDays(30))) {
- expirantes++;
- }
- String forfait = souscription.getPlanCommercial() != null ? souscription.getPlanCommercial()
- : "Inconnu";
- forfaitCount.merge(forfait, 1, Integer::sum);
- }
- } catch (Exception ignored) {
- // Organisation sans souscription active
- }
- }
-
- statistiques.setSouscriptionsExpirantes(expirantes);
- if (!forfaitCount.isEmpty()) {
- forfaitLePlusPopulaire = forfaitCount.entrySet().stream()
- .max(Map.Entry.comparingByValue())
- .map(Map.Entry::getKey)
- .orElse("N/A");
- }
- statistiques.setFormulairePopulaire(forfaitLePlusPopulaire);
- statistiques.setTauxRenouvellement(totalSouscriptions > 0
- ? (float) souscriptionsActives / totalSouscriptions * 100
- : 0.0f);
- } catch (Exception e) {
- LOG.debugf("Impossible de charger les stats souscriptions: %s", e.getMessage());
- }
- }
-
- // Méthodes utilitaires pour les souscriptions
- private void calculerStatistiquesSouscriptions() {
- if (toutesLesEntites == null || statistiques == null) {
- return; // Sécurité si appelé avant initialisation complète
- }
-
- int expirantes = 0;
- int quotaAtteint = 0;
-
- for (Entite entite : toutesLesEntites) {
- if (entite.isExpirationProche()) {
- expirantes++;
- }
- if (entite.isQuotaAtteint()) {
- quotaAtteint++;
- }
- }
-
- statistiques.setSouscriptionsExpirantes(expirantes);
- statistiques.setEntitesQuotaAtteint(quotaAtteint);
- }
-
- public void renouvelerSouscription() {
- if (entiteSelectionne != null) {
- entiteSelectionne.setDateExpirationSouscription(LocalDate.now().plusMonths(12));
- entiteSelectionne.setStatutSouscription("ACTIVE");
- LOG.infof("Souscription renouvelée pour: %s", entiteSelectionne.getNom());
- appliquerFiltres();
- }
- }
-
- public void upgraderForfait() {
- if (entiteSelectionne != null) {
- String forfaitActuel = entiteSelectionne.getForfaitSouscrit();
- switch (forfaitActuel) {
- case "Starter":
- entiteSelectionne.setForfaitSouscrit("Standard");
- entiteSelectionne.setMembresQuota(200);
- entiteSelectionne.setMontantMensuel("3 000 FCFA");
- break;
- case "Standard":
- entiteSelectionne.setForfaitSouscrit("Premium");
- entiteSelectionne.setMembresQuota(500);
- entiteSelectionne.setMontantMensuel("4 000 FCFA");
- break;
- case "Premium":
- entiteSelectionne.setForfaitSouscrit("Cristal");
- entiteSelectionne.setMembresQuota(2000);
- entiteSelectionne.setMontantMensuel("5 000 FCFA");
- break;
- }
- LOG.infof("Forfait upgradé pour: %s", entiteSelectionne.getNom());
- appliquerFiltres();
- }
- }
-
- public void gererQuotas() {
- LOG.info("Gestion des quotas pour toutes les entités");
- }
-
- public void envoyerRelancesSouscriptions() {
- int compteur = 0;
- for (Entite entite : toutesLesEntites) {
- if (entite.isExpirationProche()) {
- LOG.infof("Relance envoyée à: %s", entite.getNom());
- compteur++;
- }
- }
- LOG.infof("%d relances de souscription envoyées", compteur);
- }
-
- // Actions groupées
- public void renouvelerSouscriptionsGroupees() {
- int compteur = 0;
- for (Entite entite : entitesSelectionnees) {
- entite.setDateExpirationSouscription(LocalDate.now().plusMonths(12));
- entite.setStatutSouscription("ACTIVE");
- compteur++;
- }
- LOG.infof("%d souscriptions renouvelées en masse", compteur);
- entitesSelectionnees.clear();
- appliquerFiltres();
- }
-
- public void suspendreEntitesGroupees() {
- int compteur = 0;
- for (Entite entite : entitesSelectionnees) {
- entite.setStatut("SUSPENDUE");
- compteur++;
- }
- LOG.infof("%d entités suspendues en masse", compteur);
- entitesSelectionnees.clear();
- appliquerFiltres();
- }
-
- public void reactiverEntitesGroupees() {
- int compteur = 0;
- for (Entite entite : entitesSelectionnees) {
- entite.setStatut("ACTIVE");
- compteur++;
- }
- LOG.infof("%d entités réactivées en masse", compteur);
- entitesSelectionnees.clear();
- appliquerFiltres();
- }
-
- public void proposerUpgradeGroupees() {
- int compteur = 0;
- for (Entite entite : entitesSelectionnees) {
- if (entite.isQuotaProche()) {
- // Simulation d'envoi de proposition d'upgrade
- LOG.infof("Proposition d'upgrade envoyée à: %s", entite.getNom());
- compteur++;
- }
- }
- LOG.infof("%d propositions d'upgrade envoyées", compteur);
- }
-
- // Classes internes
- public static class Entite {
- private UUID id;
- private String nom;
- private String codeEntite;
- private String type;
- private String typeLibelle;
- private String region;
- private String statut;
- private int nombreMembres;
- private String adresse;
- private String ville; // Ajouté: champ manquant
- private String telephone;
- private String email;
- private String description;
- private LocalDateTime derniereActivite;
- private Administrateur administrateur;
-
- // Informations de souscription
- private String forfaitSouscrit = "Standard";
- private int membresQuota = 200;
- private int membresUtilises;
- private LocalDate dateExpirationSouscription;
- private String statutSouscription = "ACTIVE";
- private String montantMensuel = "3 000 FCFA";
-
- // Getters et setters
- 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 String getCodeEntite() {
- return codeEntite;
- }
-
- public void setCodeEntite(String codeEntite) {
- this.codeEntite = codeEntite;
- }
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public String getRegion() {
- return region;
- }
-
- public void setRegion(String region) {
- this.region = region;
- }
-
- public String getStatut() {
- return statut;
- }
-
- public void setStatut(String statut) {
- this.statut = statut;
- }
-
- public int getNombreMembres() {
- return nombreMembres;
- }
-
- public void setNombreMembres(int nombreMembres) {
- this.nombreMembres = nombreMembres;
- }
-
- public String getAdresse() {
- return adresse;
- }
-
- public void setAdresse(String adresse) {
- this.adresse = adresse;
- }
-
- public String getVille() {
- return ville;
- }
-
- public void setVille(String ville) {
- this.ville = ville;
- }
-
- 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 String getDescription() {
- return description;
- }
-
- public void setDescription(String description) {
- this.description = description;
- }
-
- public LocalDateTime getDerniereActivite() {
- return derniereActivite;
- }
-
- public void setDerniereActivite(LocalDateTime derniereActivite) {
- this.derniereActivite = derniereActivite;
- }
-
- public Administrateur getAdministrateur() {
- return administrateur;
- }
-
- public void setAdministrateur(Administrateur administrateur) {
- this.administrateur = administrateur;
- }
-
- public String getTypeLibelle() { return typeLibelle != null ? typeLibelle : type; }
- public void setTypeLibelle(String typeLibelle) { this.typeLibelle = typeLibelle; }
-
- // Propriétés dérivées
-
- public String getTypeSeverity() {
- return switch (type) {
- case "ASSOCIATION" -> "info";
- case "CLUB" -> "success";
- case "GROUPE" -> "warning";
- case "GROUPE_JEUNES" -> "primary";
- case "BRANCHE" -> "secondary";
- default -> "secondary";
- };
- }
-
- public String getTypeIcon() {
- return switch (type) {
- case "ASSOCIATION" -> "pi-users";
- case "CLUB" -> "pi-home";
- case "GROUPE" -> "pi-sitemap";
- case "GROUPE_JEUNES" -> "pi-star";
- case "BRANCHE" -> "pi-share-alt";
- default -> "pi-building";
- };
- }
-
- public String getStatutSeverity() {
- return switch (statut) {
- case "ACTIVE" -> "success";
- case "INACTIVE" -> "warning";
- case "SUSPENDUE" -> "danger";
- default -> "secondary";
- };
- }
-
- public String getStatutIcon() {
- return switch (statut) {
- case "ACTIVE" -> "pi-check";
- case "INACTIVE" -> "pi-pause";
- case "SUSPENDUE" -> "pi-ban";
- default -> "pi-circle";
- };
- }
-
- public String getDerniereActiviteFormatee() {
- if (derniereActivite == null)
- return "N/A";
- return derniereActivite.format(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
- }
-
- public String getDerniereActiviteRelative() {
- if (derniereActivite == null)
- return "";
- long jours = ChronoUnit.DAYS.between(derniereActivite.toLocalDate(), LocalDate.now());
- if (jours == 0)
- return "Aujourd'hui";
- if (jours == 1)
- return "Hier";
- if (jours < 7)
- return "Il y a " + jours + " jours";
- if (jours < 30)
- return "Il y a " + (jours / 7) + " semaine" + (jours / 7 > 1 ? "s" : "");
- return "Il y a " + (jours / 30) + " mois";
- }
-
- // Getters et setters pour les informations de souscription
- public String getForfaitSouscrit() {
- return forfaitSouscrit;
- }
-
- public void setForfaitSouscrit(String forfaitSouscrit) {
- this.forfaitSouscrit = forfaitSouscrit;
- }
-
- public int getMembresQuota() {
- return membresQuota;
- }
-
- public void setMembresQuota(int membresQuota) {
- this.membresQuota = membresQuota;
- }
-
- public int getMembresUtilises() {
- return membresUtilises;
- }
-
- public void setMembresUtilises(int membresUtilises) {
- this.membresUtilises = membresUtilises;
- }
-
- public LocalDate getDateExpirationSouscription() {
- return dateExpirationSouscription;
- }
-
- public void setDateExpirationSouscription(LocalDate dateExpirationSouscription) {
- this.dateExpirationSouscription = dateExpirationSouscription;
- }
-
- public String getStatutSouscription() {
- return statutSouscription;
- }
-
- public void setStatutSouscription(String statutSouscription) {
- this.statutSouscription = statutSouscription;
- }
-
- public String getMontantMensuel() {
- return montantMensuel;
- }
-
- public void setMontantMensuel(String montantMensuel) {
- this.montantMensuel = montantMensuel;
- }
-
- // Méthodes utilitaires pour les souscriptions
- public boolean isQuotaProche() {
- return getMembresUtilises() >= (getMembresQuota() * 0.85);
- }
-
- public boolean isQuotaAtteint() {
- return getMembresUtilises() >= getMembresQuota();
- }
-
- public boolean isExpirationProche() {
- if (dateExpirationSouscription == null)
- return false;
- return ChronoUnit.DAYS.between(LocalDate.now(), dateExpirationSouscription) <= 30;
- }
-
- public int getPourcentageUtilisationQuota() {
- if (membresQuota == 0)
- return 0;
- return (membresUtilises * 100) / membresQuota;
- }
-
- public String getForfaitCouleur() {
- return switch (forfaitSouscrit) {
- case "Starter" -> "primary";
- case "Standard" -> "success";
- case "Premium" -> "warning";
- case "Cristal" -> "info";
- default -> "secondary";
- };
- }
-
- public String getForfaitIcone() {
- return switch (forfaitSouscrit) {
- case "Starter" -> "pi-star";
- case "Standard" -> "pi-users";
- case "Premium" -> "pi-crown";
- case "Cristal" -> "pi-diamond";
- default -> "pi-circle";
- };
- }
-
- public long getJoursAvantExpiration() {
- if (dateExpirationSouscription == null)
- return 0;
- return ChronoUnit.DAYS.between(LocalDate.now(), dateExpirationSouscription);
- }
- }
-
- public static class Administrateur {
- private String nomComplet;
- private String email;
-
- // Getters et setters
- public String getNomComplet() {
- return nomComplet;
- }
-
- public void setNomComplet(String nomComplet) {
- this.nomComplet = nomComplet;
- }
-
- public String getEmail() {
- return email;
- }
-
- public void setEmail(String email) {
- this.email = email;
- }
- }
-
- public static class Filtres {
- private String nom;
- private String type;
- private String statut;
- private String region;
- private String forfait;
- private String alerteQuota;
- private String alerteExpiration;
- private String statutSouscription;
-
- // Getters et setters
- public String getNom() {
- return nom;
- }
-
- public void setNom(String nom) {
- this.nom = nom;
- }
-
- 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 getRegion() {
- return region;
- }
-
- public void setRegion(String region) {
- this.region = region;
- }
-
- public String getForfait() {
- return forfait;
- }
-
- public void setForfait(String forfait) {
- this.forfait = forfait;
- }
-
- public String getAlerteQuota() {
- return alerteQuota;
- }
-
- public void setAlerteQuota(String alerteQuota) {
- this.alerteQuota = alerteQuota;
- }
-
- public String getAlerteExpiration() {
- return alerteExpiration;
- }
-
- public void setAlerteExpiration(String alerteExpiration) {
- this.alerteExpiration = alerteExpiration;
- }
-
- public String getStatutSouscription() {
- return statutSouscription;
- }
-
- public void setStatutSouscription(String statutSouscription) {
- this.statutSouscription = statutSouscription;
- }
- }
-
- public static class Statistiques {
- private int totalEntites;
- private int entitesActives;
- private int totalMembres;
- private String revenus;
- private int souscriptionsExpirantes;
- private int entitesQuotaAtteint;
- private String formulairePopulaire;
- private float tauxRenouvellement;
- private int moyenneMembresParEntite;
-
- // Getters et setters
- public int getTotalEntites() {
- return totalEntites;
- }
-
- public void setTotalEntites(int totalEntites) {
- this.totalEntites = totalEntites;
- }
-
- public int getEntitesActives() {
- return entitesActives;
- }
-
- public void setEntitesActives(int entitesActives) {
- this.entitesActives = entitesActives;
- }
-
- public int getTotalMembres() {
- return totalMembres;
- }
-
- public void setTotalMembres(int totalMembres) {
- this.totalMembres = totalMembres;
- }
-
- public String getRevenus() {
- return revenus;
- }
-
- public void setRevenus(String revenus) {
- this.revenus = revenus;
- }
-
- public int getSouscriptionsExpirantes() {
- return souscriptionsExpirantes;
- }
-
- public void setSouscriptionsExpirantes(int souscriptionsExpirantes) {
- this.souscriptionsExpirantes = souscriptionsExpirantes;
- }
-
- public int getEntitesQuotaAtteint() {
- return entitesQuotaAtteint;
- }
-
- public void setEntitesQuotaAtteint(int entitesQuotaAtteint) {
- this.entitesQuotaAtteint = entitesQuotaAtteint;
- }
-
- public String getFormulairePopulaire() {
- return formulairePopulaire;
- }
-
- public void setFormulairePopulaire(String formulairePopulaire) {
- this.formulairePopulaire = formulairePopulaire;
- }
-
- public float getTauxRenouvellement() {
- return tauxRenouvellement;
- }
-
- public void setTauxRenouvellement(float tauxRenouvellement) {
- this.tauxRenouvellement = tauxRenouvellement;
- }
-
- public int getMoyenneMembresParEntite() {
- return moyenneMembresParEntite;
- }
-
- public void setMoyenneMembresParEntite(int moyenneMembresParEntite) {
- this.moyenneMembresParEntite = moyenneMembresParEntite;
- }
-
- public String getTauxRenouvellementFormat() {
- return String.format("%.1f%%", tauxRenouvellement);
- }
- }
-}
diff --git a/src/main/java/dev/lions/unionflow/client/view/NavigationBean.java b/src/main/java/dev/lions/unionflow/client/view/NavigationBean.java
index 93ea91d..d89487d 100644
--- a/src/main/java/dev/lions/unionflow/client/view/NavigationBean.java
+++ b/src/main/java/dev/lions/unionflow/client/view/NavigationBean.java
@@ -127,8 +127,8 @@ public class NavigationBean implements Serializable {
return "Tableau de Bord";
} else if (viewId.contains("membres")) {
return "Gestion des Membres";
- } else if (viewId.contains("entites")) {
- return "Gestion des Entités";
+ } else if (viewId.contains("organisation")) {
+ return "Gestion des Organisations";
} else if (viewId.contains("configuration")) {
return "Configuration";
} else if (viewId.contains("rapports")) {
diff --git a/src/main/java/dev/lions/unionflow/client/view/SuperAdminBean.java b/src/main/java/dev/lions/unionflow/client/view/SuperAdminBean.java
index 685c780..1730e1f 100644
--- a/src/main/java/dev/lions/unionflow/client/view/SuperAdminBean.java
+++ b/src/main/java/dev/lions/unionflow/client/view/SuperAdminBean.java
@@ -37,8 +37,8 @@ public class SuperAdminBean implements Serializable {
private static final Logger LOG = Logger.getLogger(SuperAdminBean.class);
// Constantes de navigation outcomes (WOU/DRY - réutilisables)
- private static final String OUTCOME_ENTITE_NOUVELLE = "entiteNouvellePage";
- private static final String OUTCOME_ENTITE_GESTION = "entiteGestionPage";
+ private static final String OUTCOME_ORGANISATION_NOUVELLE = "organisationNouvellePage";
+ private static final String OUTCOME_ORGANISATION_GESTION = "organisationGestionPage";
private static final String OUTCOME_SUPER_ADMIN_RAPPORTS = "superAdminRapportsPage";
private static final String OUTCOME_SUPER_ADMIN_CONFIGURATION = "superAdminConfigurationPage";
private static final String OUTCOME_SUPER_ADMIN_ALERTES = "superAdminAlertesPage";
@@ -431,12 +431,12 @@ public class SuperAdminBean implements Serializable {
}
// Actions (WOU/DRY - utilisation de navigation outcomes)
- public String creerEntite() {
- return OUTCOME_ENTITE_NOUVELLE + "?faces-redirect=true";
+ public String creerOrganisation() {
+ return OUTCOME_ORGANISATION_NOUVELLE + "?faces-redirect=true";
}
- public String gererEntites() {
- return OUTCOME_ENTITE_GESTION + "?faces-redirect=true";
+ public String gererOrganisations() {
+ return OUTCOME_ORGANISATION_GESTION + "?faces-redirect=true";
}
public String genererRapport() {
diff --git a/src/main/resources/META-INF/faces-config.xml b/src/main/resources/META-INF/faces-config.xml
index b33ce1f..9d36116 100644
--- a/src/main/resources/META-INF/faces-config.xml
+++ b/src/main/resources/META-INF/faces-config.xml
@@ -546,16 +546,16 @@
- Page de création d'entité (Super Admin)
- entiteNouvellePage
- /pages/super-admin/entites/nouvelle.xhtml
+ Page de création d'organisation (Super Admin)
+ organisationNouvellePage
+ /pages/secure/organisation/nouvelle.xhtml
- Page de gestion des entités (Super Admin)
- entiteGestionPage
- /pages/super-admin/entites/gestion.xhtml
+ Page de gestion des organisations (Super Admin)
+ organisationGestionPage
+ /pages/secure/organisation/liste.xhtml
@@ -588,9 +588,9 @@
- Page de détails d'entité
- entiteDetailsPage
- /pages/super-admin/entites/details.xhtml
+ Page de détails d'organisation
+ organisationDetailsPage
+ /pages/secure/organisation/detail.xhtml
@@ -602,16 +602,9 @@
- Page de configuration d'entité
- entiteConfigurationPage
- /pages/super-admin/entites/configuration.xhtml
-
-
-
-
- Page de rapports d'entité
- entiteRapportsPage
- /pages/super-admin/entites/rapports.xhtml
+ Page de statistiques d'organisation
+ organisationStatistiquesPage
+ /pages/secure/organisation/statistiques.xhtml
diff --git a/src/main/resources/META-INF/resources/pages/super-admin/dashboard.xhtml b/src/main/resources/META-INF/resources/pages/super-admin/dashboard.xhtml
index 740a934..bca4387 100644
--- a/src/main/resources/META-INF/resources/pages/super-admin/dashboard.xhtml
+++ b/src/main/resources/META-INF/resources/pages/super-admin/dashboard.xhtml
@@ -32,7 +32,7 @@
-
+
@@ -67,7 +67,7 @@
-
+
@@ -103,18 +103,18 @@
-
+
-
+
-
+
-
+
@@ -205,12 +205,12 @@
-
+
- Top 5 Entités
+ Top 5 Organisations
-
Aucune entité enregistrée
+
Aucune organisation enregistrée
@@ -346,7 +346,7 @@
#{superAdminBean.revenus.moyenne}
-
Revenu moyen / entité
+
Revenu moyen / organisation
diff --git a/src/main/resources/META-INF/resources/pages/super-admin/entites/gestion-enhanced.xhtml b/src/main/resources/META-INF/resources/pages/super-admin/entites/gestion-enhanced.xhtml
deleted file mode 100644
index 34f2f88..0000000
--- a/src/main/resources/META-INF/resources/pages/super-admin/entites/gestion-enhanced.xhtml
+++ /dev/null
@@ -1,641 +0,0 @@
-
-
-
- Gestion des Entités Enhanced - UnionFlow
-
-
-
-
-
-
- >
-
-
-
-
-
-
-
- Gestion des Entités - Stratégie Volume
-
-
Administration complète avec suivi des souscriptions et quotas
-
-
-
-
-
-
-
-
-
- >
-
-
-
-
-
-
#{entitesGestionBean.statistiques.totalEntites}
-
Total Entités
-
-
- #{entitesGestionBean.statistiques.entitesActives} actives
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{entitesGestionBean.statistiques.totalMembres}
-
Total Membres
-
-
- Moyenne: 146/entité
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{entitesGestionBean.statistiques.souscriptionsExpirantes}
-
Expirations Proches
-
-
- Sous 30 jours
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{entitesGestionBean.statistiques.entitesQuotaAtteint}
-
Quotas Atteints
-
-
- Nécessitent upgrade
-
-
-
-
-
-
-
-
-
-
- >
-
-
-
-
Répartition par Forfait - Nouvelle Grille Tarifaire
-
-
-
-
44
-
Starter
-
2K FCFA/mois
-
100 membres max
-
-
-
-
-
60
-
Standard
-
3K FCFA/mois
-
200 membres max
-
-
-
-
-
20
-
Premium
-
4K FCFA/mois
-
500 membres max
-
-
-
-
-
3
-
Cristal
-
5K FCFA/mois
-
2000 membres max
-
-
-
-
-
-
-
-
-
Performance Commerciale
-
-
-
-
#{entitesGestionBean.statistiques.revenus}
-
Revenus Mensuels
-
-
-
-
-
#{entitesGestionBean.statistiques.tauxRenouvellementFormat}
-
Taux Renouvellement
-
-
-
-
-
Forfait le plus populaire
-
-
-
-
-
-
- >
-
-
Filtres et Recherche Avancée
-
-
-
-
-
-
- >
-
-
-
Entités avec Souscriptions (#{entitesGestionBean.entitesFiltrees.size()})
-
-
-
-
-
- #{entitesGestionBean.entitesFiltrees.size()} sur #{entitesGestionBean.toutesLesEntites.size()} entités
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{entite.nom}
-
#{entite.codeEntite}
-
-
-
-
-
-
-
-
#{entite.montantMensuel}
-
-
-
-
-
-
#{entite.membresUtilises}/#{entite.membresQuota}
-
-
#{entite.pourcentageUtilisationQuota}%
-
-
-
-
-
-
- #{entite.dateExpirationSouscription != null ? entite.dateExpirationSouscription.format(java.time.format.DateTimeFormatter.ofPattern('dd/MM/yyyy')) : 'N/A'}
-
-
-
- #{entite.joursAvantExpiration} jours
-
-
-
-
-
- #{entite.region}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
-
-
-
-
-
-
Confirmer le renouvellement
-
- Entité: #{entitesGestionBean.entiteSelectionne.nom}
- Forfait: #{entitesGestionBean.entiteSelectionne.forfaitSouscrit}
- Montant: #{entitesGestionBean.entiteSelectionne.montantMensuel}
-
-
-
-
-
-
-
-
- >
-
-
-
-
-
-
Upgrader le forfait
-
- Entité: #{entitesGestionBean.entiteSelectionne.nom}
- Forfait actuel: #{entitesGestionBean.entiteSelectionne.forfaitSouscrit}
- Quota utilisé: #{entitesGestionBean.entiteSelectionne.pourcentageUtilisationQuota}%
-
-
-
-
-
-
-
-
- >
-
-
-
-
-
-
Actions sur #{entitesGestionBean.entitesSelectionnees.size()} entités sélectionnées
-
-
-
-
-
Actions de Souscription
-
-
-
-
-
-
-
-
-
Actions Administratives
-
-
-
-
-
-
-
-
-
-
-
-
-
- >
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/super-admin/entites/gestion.xhtml b/src/main/resources/META-INF/resources/pages/super-admin/entites/gestion.xhtml
deleted file mode 100644
index 68c5a6d..0000000
--- a/src/main/resources/META-INF/resources/pages/super-admin/entites/gestion.xhtml
+++ /dev/null
@@ -1,426 +0,0 @@
-
-
-
- Gestion des Entités - UnionFlow
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Filtres et Recherche
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Liste des Entités
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
#{entite.nom}
-
#{entite.codeEntite}
-
-
-
-
-
-
-
-
-
- #{entite.region}
-
-
-
-
-
#{entite.nombreMembres}
-
membres
-
-
-
-
-
-
-
-
#{entite.administrateur.nomComplet}
-
#{entite.administrateur.email}
-
-
-
- Aucun administrateur
-
-
-
-
- #{entite.derniereActiviteFormatee}
- #{entite.derniereActiviteRelative}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Entité sélectionnée
-
#{entitesGestionBean.entiteSelectionne.nom}
-
#{entitesGestionBean.entiteSelectionne.codeEntite}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/main/resources/META-INF/resources/pages/super-admin/organisations.xhtml b/src/main/resources/META-INF/resources/pages/super-admin/organisations.xhtml
deleted file mode 100644
index 9d9e958..0000000
--- a/src/main/resources/META-INF/resources/pages/super-admin/organisations.xhtml
+++ /dev/null
@@ -1,223 +0,0 @@
-
-
-
- Gestion des Organisations
-
-
-
-
-
-
-
-
-
Organisations
-
- CRUD complet des organisations. Respect DRY/WOU: composants réutilisés et simplicité.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Confirmez l'action sur le statut de l'organisation ?
-
-
-
-
-
-
- Supprimer cette organisation ? Cette action est irréversible.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/main/resources/META-INF/resources/templates/components/layout/menu.xhtml b/src/main/resources/META-INF/resources/templates/components/layout/menu.xhtml
index eed332e..1bc1ed9 100644
--- a/src/main/resources/META-INF/resources/templates/components/layout/menu.xhtml
+++ b/src/main/resources/META-INF/resources/templates/components/layout/menu.xhtml
@@ -1,7 +1,7 @@
-
@@ -24,271 +24,202 @@