diff --git a/RESUME_TRAVAIL_EN_COURS.md b/RESUME_TRAVAIL_EN_COURS.md new file mode 100644 index 0000000..9cdc1af --- /dev/null +++ b/RESUME_TRAVAIL_EN_COURS.md @@ -0,0 +1,74 @@ +# 🚀 RÉSUMÉ EXÉCUTIF - TRAVAIL EN COURS + +**Date** : 2025-12-01 +**Statut global** : ✅ Projet compile sans erreurs + +--- + +## ✅ DERNIÈRES CORRECTIONS TERMINÉES + +1. **Erreur PropertyNotFoundException pour `type` sur EvenementDTO** ✅ + - Toutes les occurrences `.type` remplacĂ©es par `.typeEvenement` + - Fichiers : `pages/admin/evenements/*.xhtml`, `pages/secure/membre/profil.xhtml` + +2. **Dialogue de contact membre** ✅ + - TODO implĂ©mentĂ© dans `MembreListeBean.java` + - Dialog créé dans `liste.xhtml` + - Utilise `NotificationService` pour envoyer les messages + +--- + +## 📋 PROCHAINES TÂCHES PRIORITAIRES + +### 1. TODOs restants (7 TODOs identifiĂ©s) + +**Fichiers concernĂ©s** : +- `DemandesAideBean.java` (3 TODOs) - lignes 317, 357, 362 +- `RapportDetailsBean.java` (2 TODOs) - lignes 101, 111 +- `ConfigurationBean.java` (1 TODO) - ligne 719 + +**Action** : ImplĂ©menter en suivant le pattern du dialogue de contact + +### 2. Audit des pages XHTML + +**À vĂ©rifier** : +- 72 pages XHTML (60% complĂštes selon roadmap) +- S'assurer que tous les beans sont injectĂ©s +- VĂ©rifier l'utilisation des composants rĂ©utilisables (DRY/WOU) +- VĂ©rifier la navigation outcomes + +### 3. Beans manquants + +**Beans Ă  crĂ©er** : +- `AideNouveautesBean`, `AideDocumentationBean`, `AideAproposBean` +- `CotisationRemindersBean`, `CotisationReportBean` +- `EvenementCreateBean`, `EvenementCalendarBean` + +--- + +## 🔧 ÉTAT ACTUEL + +- **Compilation** : ✅ SUCCESS (client et serveur) +- **Tests** : ❌ Erreurs Ă  corriger (3596 selon audit) +- **Pages XHTML** : 60% complĂštes +- **Beans JSF** : 70% complĂštes + +--- + +## 📝 PRINCIPES À RESPECTER + +1. **DRY/WOU strict** : Toujours rĂ©utiliser les composants existants +2. **Navigation outcomes** : Utiliser les constantes dĂ©finies dans `faces-config.xml` +3. **DTOs serveur** : Utiliser les DTOs de `unionflow-server-api` +4. **Services REST** : Injecter via `@RestClient` + +--- + +## 📚 DOCUMENTATION COMPLÈTE + +Voir `STATUT_TRAVAIL_EN_COURS.md` pour les dĂ©tails complets. + +--- + +**Prochaine Ă©tape recommandĂ©e** : ImplĂ©menter les TODOs dans `DemandesAideBean.java` + diff --git a/ROADMAP_FINALISATION_UNIONFLOW.md b/ROADMAP_FINALISATION_UNIONFLOW.md new file mode 100644 index 0000000..50bb30f --- /dev/null +++ b/ROADMAP_FINALISATION_UNIONFLOW.md @@ -0,0 +1,394 @@ +# 🎯 ROADMAP DE FINALISATION - UNIONFLOW + +**Date** : 2025-01-30 +**Version** : 1.0 +**Objectif** : Terminer intĂ©gralement le dĂ©veloppement d'UnionFlow + +--- + +## 📊 ÉTAT ACTUEL DU PROJET + +### ✅ Modules ComplĂ©tĂ©s + +| Module | Fichiers | Statut | % | +|--------|----------|--------|---| +| **Server API** | DTOs, Enums | ✅ Complet | 100% | +| **Server Impl - Services** | 25 services | ✅ Complet | 100% | +| **Server Impl - Resources** | 18 resources | ✅ Complet | 100% | +| **Server Impl - Entities** | Toutes entitĂ©s | ✅ Complet | 100% | +| **Server Impl - Repositories** | Tous repositories | ✅ Complet | 100% | +| **Client - Beans** | 36 beans | 🔄 Partiel | 70% | +| **Client - Pages XHTML** | 72 pages | 🔄 Partiel | 60% | +| **Client - Composants** | Composants rĂ©utilisables | ✅ Complet | 100% | +| **Configuration** | faces-config.xml, web.xml | ✅ Complet | 100% | +| **Tests** | Tests unitaires/intĂ©gration | ❌ Manquant | 5% | +| **Documentation** | Documentation technique | 🔄 Partiel | 40% | + +--- + +## 🚹 PRIORITÉ 1 - CRITIQUE (À FAIRE IMMÉDIATEMENT) + +### 1.1 RĂ©solution des TODOs (215 occurrences) + +#### TODOs dans Beans Client (8 fichiers) +- [ ] **MembreListeBean.java** (8 TODOs) + - [ ] ImplĂ©menter rĂ©cupĂ©ration des organisations + - [ ] ImplĂ©menter complĂ©tion des villes depuis serveur + - [ ] ImplĂ©menter complĂ©tion des professions depuis serveur + - [ ] ImplĂ©menter ouverture dialogue de contact + - [ ] ImplĂ©menter envoi de rappels groupĂ©s + - [ ] ImplĂ©menter export de la sĂ©lection + - [ ] ImplĂ©menter envoi de messages groupĂ©s + - [ ] Mettre Ă  jour liste.xhtml pour utiliser organisationsDisponibles + +- [ ] **MembreDTO.java** (4 TODOs) + - [ ] IntĂ©grer avec module Cotisations (statut cotisation) + - [ ] IntĂ©grer avec module Cotisations (montant dĂ») + - [ ] IntĂ©grer avec module ÉvĂ©nements (Ă©vĂ©nements participĂ©s) + - [ ] IntĂ©grer avec module ÉvĂ©nements (Ă©vĂ©nements organisĂ©s) + +#### TODOs dans Mobile Apps (Flutter) +- [ ] **super_admin_dashboard.dart** (8 TODOs) +- [ ] **dashboard_offline_service.dart** (5 TODOs) +- [ ] **advanced_dashboard_page.dart** (3 TODOs) +- [ ] **Tests** (20+ TODOs) + +**Action** : CrĂ©er un plan de rĂ©solution pour chaque TODO avec prioritĂ© + +--- + +### 1.2 Pages XHTML Manquantes ou IncomplĂštes + +#### Pages RĂ©fĂ©rencĂ©es dans faces-config.xml mais Manquantes +- [ ] `/pages/secure/membre/modifier.xhtml` (supprimĂ©e, doit ĂȘtre recréée ou rĂ©utiliser inscription.xhtml) +- [ ] `/pages/secure/cotisations.xhtml` (rĂ©fĂ©rencĂ©e dans MembreListeBean) +- [ ] `/pages/secure/membre/cotisations.xhtml` (rĂ©fĂ©rencĂ©e dans MembreProfilBean) +- [ ] `/pages/secure/rapport/details.xhtml` (rĂ©fĂ©rencĂ©e dans RapportsBean) + +#### Pages Existantes mais Potentiellement IncomplĂštes +- [ ] VĂ©rifier toutes les pages `aide/*.xhtml` (15 pages) +- [ ] VĂ©rifier toutes les pages `admin/*.xhtml` (5 pages) +- [ ] VĂ©rifier toutes les pages `adhesion/*.xhtml` (8 pages) +- [ ] VĂ©rifier toutes les pages `cotisation/*.xhtml` (7 pages) +- [ ] VĂ©rifier toutes les pages `evenement/*.xhtml` (10 pages) +- [ ] VĂ©rifier toutes les pages `personnel/*.xhtml` (8 pages) +- [ ] VĂ©rifier toutes les pages `rapport/*.xhtml` (4 pages) + +**Action** : Audit de chaque page pour vĂ©rifier : +- Bean associĂ© existe et est injectĂ© +- Composants rĂ©utilisables utilisĂ©s (DRY/WOU) +- Navigation outcomes utilisĂ©s au lieu de chemins directs +- Validation des formulaires +- Gestion des erreurs + +--- + +### 1.3 Beans Manquants ou Incomplets + +#### Beans Manquants pour Pages Existantes +- [ ] **MembreModifierBean** (si page modifier.xhtml recréée) +- [ ] **CotisationsBean** (pour page cotisations.xhtml) +- [ ] **RapportDetailsBean** (pour page rapport/details.xhtml) +- [ ] **AideTraitementBean** (pour aide/traitement.xhtml) +- [ ] **AideStatistiquesBean** (pour aide/statistiques.xhtml) +- [ ] **AideTicketsBean** (pour aide/tickets.xhtml) +- [ ] **AideSupportBean** (pour aide/support.xhtml) +- [ ] **AideRequestsBean** (pour aide/requests.xhtml) +- [ ] **AideNouveautesBean** (pour aide/nouveautes.xhtml) +- [ ] **AideApprovedBean** (pour aide/approved.xhtml) +- [ ] **AideAproposBean** (pour aide/apropos.xhtml) +- [ ] **AideSuggestionsBean** (pour aide/suggestions.xhtml) +- [ ] **AideHistoryBean** (pour aide/history.xhtml) +- [ ] **AideHistoriqueBean** (pour aide/historique.xhtml) +- [ ] **AdminSauvegardeBean** (pour admin/sauvegarde.xhtml) +- [ ] **AdhesionHistoryBean** (pour adhesion/history.xhtml) +- [ ] **CotisationRemindersBean** (pour cotisation/reminders.xhtml) +- [ ] **CotisationReportBean** (pour cotisation/report.xhtml) +- [ ] **EvenementCreateBean** (pour evenement/create.xhtml - diffĂ©rente de creation.xhtml?) +- [ ] **EvenementCalendarBean** (pour evenement/calendar.xhtml - diffĂ©rente de calendrier.xhtml?) +- [ ] **EvenementParticipationBean** (pour evenement/participation.xhtml) +- [ ] **EvenementParticipantsBean** (pour evenement/participants.xhtml) + +#### Beans Existants Ă  ComplĂ©ter +- [ ] **MembreListeBean** : ComplĂ©ter mĂ©thodes TODO +- [ ] **MembreInscriptionBean** : VĂ©rifier validation complĂšte +- [ ] **OrganisationsBean** : VĂ©rifier toutes fonctionnalitĂ©s +- [ ] **EvenementsBean** : VĂ©rifier gestion complĂšte Ă©vĂ©nements +- [ ] **CotisationsGestionBean** : VĂ©rifier toutes fonctionnalitĂ©s +- [ ] **DashboardBean** : VĂ©rifier toutes statistiques +- [ ] **RapportsBean** : ComplĂ©ter gĂ©nĂ©ration rapports + +**Action** : CrĂ©er les beans manquants et complĂ©ter les existants + +--- + +### 1.4 Navigation Outcomes dans Beans + +#### Migration des Chemins Directs vers Navigation Outcomes + +**ProblĂšme** : Les beans retournent des chemins directs au lieu d'utiliser les navigation outcomes dĂ©finis dans `faces-config.xml` + +**Exemples Ă  Corriger** : +- [ ] `MembreListeBean.modifierMembre()` : `return "/pages/secure/membre/modifier?id=..."` → `return "membreModifierPage?id=..."` +- [ ] `MembreListeBean.voirProfil()` : `return "/pages/secure/membre/profil?id=..."` → `return "membreProfilPage?id=..."` +- [ ] `MembreInscriptionBean.enregistrer()` : `return "/pages/secure/membre/liste?faces-redirect=true"` → `return "membreListPage?faces-redirect=true"` +- [ ] `DashboardBean.*()` : Tous les retours de navigation +- [ ] `MembreProfilBean.*()` : Tous les retours de navigation +- [ ] Tous les autres beans (36 beans Ă  vĂ©rifier) + +**Action** : +1. Ajouter constantes `OUTCOME` dans chaque bean (comme CEADP) +2. Modifier toutes les mĂ©thodes pour retourner ces constantes +3. Mettre Ă  jour `faces-config.xml` si nĂ©cessaire + +--- + +## ⚠ PRIORITÉ 2 - IMPORTANT (À FAIRE AVANT PRODUCTION) + +### 2.1 Tests + +#### Tests Unitaires Manquants +- [ ] **Services** (25 services × ~5 tests = 125 tests) + - [ ] MembreServiceTest + - [ ] OrganisationServiceTest + - [ ] EvenementServiceTest + - [ ] CotisationServiceTest + - [ ] AdhesionServiceTest + - [ ] DemandeAideServiceTest + - [ ] PaiementServiceTest + - [ ] DocumentServiceTest + - [ ] NotificationServiceTest + - [ ] WaveServiceTest + - [ ] ComptabiliteServiceTest + - [ ] RoleServiceTest + - [ ] PermissionServiceTest + - [ ] AuditServiceTest + - [ ] ExportServiceTest + - [ ] AnalyticsServiceTest + - [ ] KPICalculatorServiceTest + - [ ] TrendAnalysisServiceTest + - [ ] MatchingServiceTest + - [ ] PreferencesNotificationServiceTest + - [ ] NotificationHistoryServiceTest + - [ ] KeycloakServiceTest + - [ ] AdresseServiceTest + - [ ] TypeOrganisationServiceTest + - [ ] PropositionAideServiceTest + +- [ ] **Repositories** (Tous repositories) + - [ ] Tests de base CRUD + - [ ] Tests de recherche + - [ ] Tests de filtres + +- [ ] **Mappers** (DTO ↔ Entity) + - [ ] Tests de conversion + - [ ] Tests de validation + +#### Tests d'IntĂ©gration Manquants +- [ ] **Resources REST** (18 resources) + - [ ] Tests avec Testcontainers + - [ ] Tests de sĂ©curitĂ© (@RolesAllowed) + - [ ] Tests de validation + - [ ] Tests de pagination + - [ ] Tests de recherche + +- [ ] **Beans JSF** (36 beans) + - [ ] Tests de mĂ©thodes principales + - [ ] Tests de validation + - [ ] Tests de navigation + +#### Tests End-to-End +- [ ] ScĂ©narios complets utilisateur +- [ ] Tests de performance +- [ ] Tests de charge + +**Objectif** : Couverture de code minimum 80% + +--- + +### 2.2 Validation et Gestion d'Erreurs + +#### Validation CĂŽtĂ© Client +- [ ] Ajouter validation JSF sur tous les formulaires +- [ ] Messages d'erreur personnalisĂ©s +- [ ] Validation en temps rĂ©el (AJAX) +- [ ] Validation cĂŽtĂ© serveur (Bean Validation) + +#### Gestion d'Erreurs +- [ ] Exception handlers globaux +- [ ] Messages d'erreur utilisateur-friendly +- [ ] Logging des erreurs +- [ ] Gestion des erreurs REST (RestClientExceptionMapper) + +--- + +### 2.3 SĂ©curitĂ© + +#### Authentification et Autorisation +- [ ] VĂ©rifier tous les `@RolesAllowed` sur Resources +- [ ] VĂ©rifier sĂ©curitĂ© des Beans JSF +- [ ] Tests de sĂ©curitĂ© +- [ ] Gestion des sessions +- [ ] Timeout de session + +#### Protection des DonnĂ©es +- [ ] Chiffrement des donnĂ©es sensibles +- [ ] Validation des entrĂ©es (XSS, SQL Injection) +- [ ] CSRF protection +- [ ] Audit de sĂ©curitĂ© + +--- + +## 📋 PRIORITÉ 3 - AMÉLIORATION (OPTIMISATION) + +### 3.1 Performance + +#### Optimisations Base de DonnĂ©es +- [ ] Index sur colonnes frĂ©quemment recherchĂ©es +- [ ] RequĂȘtes optimisĂ©es (N+1 queries) +- [ ] Cache (Caffeine, Redis) +- [ ] Pagination efficace + +#### Optimisations Frontend +- [ ] Lazy loading des composants +- [ ] Optimisation des requĂȘtes AJAX +- [ ] Cache cĂŽtĂ© client +- [ ] Compression des ressources + +--- + +### 3.2 ExpĂ©rience Utilisateur + +#### AmĂ©liorations UI/UX +- [ ] Feedback utilisateur (loading, success, error) +- [ ] Confirmations pour actions critiques +- [ ] Tooltips et help text +- [ ] Responsive design complet +- [ ] AccessibilitĂ© (WCAG) + +#### FonctionnalitĂ©s AvancĂ©es +- [ ] Recherche avancĂ©e avec filtres +- [ ] Export Excel/PDF amĂ©liorĂ© +- [ ] Import de donnĂ©es (Excel, CSV) +- [ ] Notifications en temps rĂ©el +- [ ] Dashboard personnalisable + +--- + +### 3.3 Documentation + +#### Documentation Technique +- [ ] Documentation API (OpenAPI/Swagger complĂšte) +- [ ] Documentation des services +- [ ] Guide de dĂ©veloppement +- [ ] Architecture documentation +- [ ] Guide de dĂ©ploiement + +#### Documentation Utilisateur +- [ ] Guide utilisateur +- [ ] Tutoriels vidĂ©o +- [ ] FAQ +- [ ] Changelog + +--- + +## 🔧 PRIORITÉ 4 - MAINTENANCE (POST-PRODUCTION) + +### 4.1 Monitoring et ObservabilitĂ© + +- [ ] MĂ©triques Prometheus +- [ ] Logs centralisĂ©s (ELK Stack) +- [ ] Alertes +- [ ] Health checks +- [ ] Performance monitoring + +### 4.2 CI/CD + +- [ ] Pipeline CI complet +- [ ] Tests automatiques +- [ ] DĂ©ploiement automatique +- [ ] Rollback automatique +- [ ] Environnements (dev, staging, prod) + +### 4.3 Backup et RĂ©cupĂ©ration + +- [ ] StratĂ©gie de backup +- [ ] Tests de restauration +- [ ] Plan de reprise d'activitĂ© +- [ ] Documentation de rĂ©cupĂ©ration + +--- + +## 📊 ESTIMATION TEMPORELLE + +| PrioritĂ© | TĂąches | Estimation | Statut | +|----------|--------|------------|--------| +| **P1 - Critique** | TODOs, Pages, Beans, Navigation | 2-3 semaines | 🔮 Urgent | +| **P2 - Important** | Tests, Validation, SĂ©curitĂ© | 3-4 semaines | ⚠ Important | +| **P3 - AmĂ©lioration** | Performance, UX, Documentation | 2-3 semaines | 🟡 Optionnel | +| **P4 - Maintenance** | Monitoring, CI/CD, Backup | 1-2 semaines | 🟱 Post-prod | +| **TOTAL** | | **8-12 semaines** | | + +--- + +## 🎯 PLAN D'ACTION RECOMMANDÉ + +### Semaine 1-2 : P1 - Critique +1. RĂ©soudre tous les TODOs critiques +2. CrĂ©er les beans manquants +3. VĂ©rifier/complĂ©ter toutes les pages XHTML +4. Migrer navigation vers outcomes + +### Semaine 3-4 : P1 - Critique (suite) +1. Tests de base pour services critiques +2. Validation des formulaires +3. Gestion d'erreurs + +### Semaine 5-7 : P2 - Important +1. Tests unitaires complets +2. Tests d'intĂ©gration +3. SĂ©curitĂ© + +### Semaine 8-9 : P2 - Important (suite) +1. Tests E2E +2. Performance +3. Documentation technique + +### Semaine 10-12 : P3 - AmĂ©lioration +1. Optimisations +2. UX improvements +3. Documentation utilisateur + +--- + +## ✅ CHECKLIST DE FINALISATION + +### Avant Production +- [ ] Tous les TODOs rĂ©solus +- [ ] Toutes les pages fonctionnelles +- [ ] Tous les beans créés et testĂ©s +- [ ] Navigation outcomes utilisĂ©s partout +- [ ] Tests unitaires > 80% couverture +- [ ] Tests d'intĂ©gration complets +- [ ] SĂ©curitĂ© validĂ©e +- [ ] Performance acceptable +- [ ] Documentation complĂšte +- [ ] CI/CD configurĂ© +- [ ] Monitoring en place +- [ ] Backup configurĂ© + +--- + +## 📝 NOTES + +- **DRY/WOU** : Continuer Ă  respecter strictement ces principes +- **Composants rĂ©utilisables** : VĂ©rifier que tous les composants sont bien rĂ©utilisĂ©s +- **Navigation** : Aligner sur le pattern CEADP (outcomes dans faces-config.xml) +- **Tests** : Prioriser les tests critiques (services mĂ©tier, sĂ©curitĂ©) +- **Documentation** : Maintenir Ă  jour au fur et Ă  mesure + +--- + +**DerniĂšre mise Ă  jour** : 2025-01-30 +**Prochaine rĂ©vision** : AprĂšs chaque sprint + diff --git a/STATUT_TRAVAIL_EN_COURS.md b/STATUT_TRAVAIL_EN_COURS.md new file mode 100644 index 0000000..da801f1 --- /dev/null +++ b/STATUT_TRAVAIL_EN_COURS.md @@ -0,0 +1,341 @@ +# 📋 STATUT DU TRAVAIL EN COURS - UNIONFLOW + +**Date de derniĂšre mise Ă  jour** : 2025-12-01 +**DerniĂšre session de travail** : Correction erreurs PropertyNotFoundException et implĂ©mentation dialogue de contact + +--- + +## ✅ TRAVAIL RÉCEMMENT TERMINÉ + +### 1. Correction de l'erreur `PropertyNotFoundException` pour `type` sur `EvenementDTO` + +**ProblĂšme** : L'erreur `jakarta.el.PropertyNotFoundException: Property [type] not found on type [dev.lions.unionflow.client.dto.EvenementDTO]` se produisait dans plusieurs pages XHTML. + +**Solution appliquĂ©e** : +- Remplacement de toutes les occurrences de `.type` par `.typeEvenement` dans les pages XHTML +- Correction dans `pages/admin/evenements/gestion.xhtml` (lignes 468, 354, 345, 355-357) +- Correction dans `pages/admin/evenements/liste.xhtml` (lignes 224, 357) +- Correction dans `pages/admin/evenements/creation.xhtml` (lignes 107, 479) +- Correction dans `pages/secure/membre/profil.xhtml` (lignes 343-344) + +**Fichiers modifiĂ©s** : +- `unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/gestion.xhtml` +- `unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/liste.xhtml` +- `unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/creation.xhtml` +- `unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/profil.xhtml` + +**Statut** : ✅ **TERMINÉ** - Compilation rĂ©ussie, erreur rĂ©solue + +--- + +### 2. ImplĂ©mentation du dialogue de contact membre + +**ProblĂšme** : TODO dans `MembreListeBean.java` ligne 316 : `// TODO: ImplĂ©menter l'ouverture du dialogue de contact` + +**Solution appliquĂ©e** : +- Ajout des propriĂ©tĂ©s dans `MembreListeBean.java` : + - `membreAContacter` (MembreDTO) + - `messageContact` (String) + - `sujetContact` (String) + - `dialogContactVisible` (boolean) +- ImplĂ©mentation de `contacterMembre(MembreDTO membre)` : initialise le dialog +- ImplĂ©mentation de `envoyerMessageContact()` : envoie la notification via `NotificationService` +- ImplĂ©mentation de `annulerContact()` : ferme le dialog et rĂ©initialise les champs +- CrĂ©ation du dialog dans `liste.xhtml` avec formulaire complet utilisant les composants rĂ©utilisables + +**Fichiers modifiĂ©s** : +- `unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreListeBean.java` +- `unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml` + +**Statut** : ✅ **TERMINÉ** - Compilation rĂ©ussie, fonctionnalitĂ© opĂ©rationnelle + +--- + +## 🔄 TRAVAIL EN COURS + +### Aucun travail en cours actuellement + +Le dernier travail a Ă©tĂ© complĂ©tĂ© avec succĂšs. Le projet compile sans erreurs. + +--- + +## 📋 PROCHAINES PRIORITÉS + +### PrioritĂ© 1 - CRITIQUE (À faire immĂ©diatement) + +#### 1. RĂ©solution des TODOs restants + +**TODOs identifiĂ©s dans les Beans Client** : + +1. **MembreListeBean.java** (1 TODO restant) + - ✅ `contacterMembre()` - **TERMINÉ** + - Autres TODOs dĂ©jĂ  rĂ©solus prĂ©cĂ©demment + +2. **DemandesAideBean.java** (3 TODOs) + - Ligne 317 : `// TODO: Ouvrir un dialogue avec les dĂ©tails complets` + - Ligne 357 : `// TODO: ImplĂ©menter avec PrimeNG Charts ou une autre bibliothĂšque` + - Ligne 362 : `// TODO: ImplĂ©menter avec PrimeNG Charts ou une autre bibliothĂšque` + +3. **RapportDetailsBean.java** (2 TODOs) + - Ligne 101 : `// TODO: ImplĂ©menter le tĂ©lĂ©chargement rĂ©el du rapport` + - Ligne 111 : `// TODO: ImplĂ©menter la rĂ©gĂ©nĂ©ration du rapport` + +4. **ConfigurationBean.java** (1 TODO) + - Ligne 719 : `// TODO: Charger depuis le backend` + +**Action recommandĂ©e** : ImplĂ©menter ces TODOs un par un en suivant le mĂȘme pattern que pour le dialogue de contact. + +--- + +#### 2. VĂ©rification des pages XHTML manquantes ou incomplĂštes + +**Pages Ă  vĂ©rifier** (selon `ROADMAP_FINALISATION_UNIONFLOW.md`) : + +- [ ] `/pages/secure/membre/modifier.xhtml` (supprimĂ©e, doit ĂȘtre recréée ou rĂ©utiliser inscription.xhtml) +- [ ] VĂ©rifier toutes les pages `aide/*.xhtml` (15 pages) - certaines utilisent `#{demandesAideBean}` mais pourraient nĂ©cessiter des beans dĂ©diĂ©s +- [ ] VĂ©rifier toutes les pages `admin/*.xhtml` (5 pages) +- [ ] VĂ©rifier toutes les pages `adhesion/*.xhtml` (8 pages) +- [ ] VĂ©rifier toutes les pages `cotisation/*.xhtml` (7 pages) +- [ ] VĂ©rifier toutes les pages `evenement/*.xhtml` (10 pages) +- [ ] VĂ©rifier toutes les pages `personnel/*.xhtml` (8 pages) +- [ ] VĂ©rifier toutes les pages `rapport/*.xhtml` (4 pages) + +**Action recommandĂ©e** : Audit de chaque page pour vĂ©rifier : +- Bean associĂ© existe et est injectĂ© +- Composants rĂ©utilisables utilisĂ©s (DRY/WOU) +- Navigation outcomes utilisĂ©s au lieu de chemins directs +- Validation des formulaires +- Gestion des erreurs + +--- + +#### 3. Beans manquants ou incomplets + +**Beans manquants identifiĂ©s** (selon roadmap) : + +- [ ] **AideNouveautesBean** (pour `aide/nouveautes.xhtml` - actuellement utilise `#{demandesAideBean}`) +- [ ] **AideDocumentationBean** (pour `aide/documentation.xhtml` - actuellement utilise `#{demandesAideBean}`) +- [ ] **AideAproposBean** (pour `aide/apropos.xhtml` - actuellement utilise `#{demandesAideBean}`) +- [ ] **CotisationRemindersBean** (pour `cotisation/reminders.xhtml`) +- [ ] **CotisationReportBean** (pour `cotisation/report.xhtml`) +- [ ] **EvenementCreateBean** (pour `evenement/create.xhtml` - diffĂ©rente de `creation.xhtml`?) +- [ ] **EvenementCalendarBean** (pour `evenement/calendar.xhtml` - diffĂ©rente de `calendrier.xhtml`?) + +**Action recommandĂ©e** : CrĂ©er les beans manquants en suivant le pattern des beans existants (DRY/WOU). + +--- + +### PrioritĂ© 2 - IMPORTANT (À faire avant production) + +#### 1. Tests + +- [ ] Corriger tous les tests cassĂ©s (3596 erreurs de compilation selon audit) +- [ ] Ajouter tests unitaires pour les services (25 services) +- [ ] Ajouter tests d'intĂ©gration pour les resources REST (18 resources) +- [ ] Ajouter tests pour les beans JSF (36 beans) + +#### 2. Validation et Gestion d'Erreurs + +- [ ] Ajouter validation JSF sur tous les formulaires +- [ ] Messages d'erreur personnalisĂ©s +- [ ] Validation en temps rĂ©el (AJAX) +- [ ] Exception handlers globaux +- [ ] Gestion des erreurs REST (RestClientExceptionMapper) + +#### 3. SĂ©curitĂ© + +- [ ] VĂ©rifier tous les `@RolesAllowed` sur Resources +- [ ] VĂ©rifier sĂ©curitĂ© des Beans JSF +- [ ] Tests de sĂ©curitĂ© +- [ ] Supprimer secrets hardcodĂ©s (selon audit) + +--- + +## đŸ—ïž ARCHITECTURE ET STRUCTURE + +### Modules du projet + +``` +unionflow/ +├── unionflow-server-api/ # ✅ Complet (DTOs, Enums) +├── unionflow-server-impl-quarkus/ # ✅ Complet (Services, Resources, Entities, Repositories) +└── unionflow-client-quarkus-primefaces-freya/ # 🔄 Partiel (70% beans, 60% pages) +``` + +### Structure des composants rĂ©utilisables + +**Composants disponibles** (DRY/WOU) : +- `/templates/components/forms/` : `form-field-text.xhtml`, `form-field-select.xhtml`, `form-field-textarea.xhtml`, etc. +- `/templates/components/buttons/` : `button-success.xhtml`, `button-secondary.xhtml`, `button-icon.xhtml`, etc. +- `/templates/components/cards/` : `filter-bar.xhtml`, `stat-card.xhtml`, etc. +- `/templates/components/layout/` : `page-header.xhtml` + +**Principe** : Toujours utiliser ces composants rĂ©utilisables au lieu de crĂ©er des composants inline. + +--- + +## 🔧 CONFIGURATION ET DÉPENDANCES + +### Technologies principales + +- **Framework** : Quarkus 3.15.1 +- **Interface** : PrimeFaces 14.0.5 (Freya Theme) +- **Base de donnĂ©es** : PostgreSQL 15 +- **Build** : Maven +- **Java** : OpenJDK 21 + +### Configuration importante + +- **Navigation** : `faces-config.xml` contient toutes les rĂšgles de navigation +- **REST Client** : Configuration via `application.properties` avec `unionflow-api` configKey +- **Lombok** : UtilisĂ© pour rĂ©duire le boilerplate (getters/setters) + +--- + +## 📝 PRINCIPES DE DÉVELOPPEMENT + +### DRY (Don't Repeat Yourself) et WOU (Write Once Use) + +**RĂšgles strictes Ă  suivre** : +1. **Toujours rĂ©utiliser les composants existants** avant de crĂ©er de nouveaux +2. **Utiliser les DTOs du serveur API** (`unionflow-server-api`) au lieu de crĂ©er des DTOs client +3. **Utiliser les navigation outcomes** dĂ©finis dans `faces-config.xml` au lieu de chemins directs +4. **Injeter les services REST** via `@RestClient` au lieu de crĂ©er des clients manuels +5. **Utiliser Lombok** pour les getters/setters standards + +### Exemples de bonnes pratiques + +**✅ BON** : +```java +@Inject @RestClient MembreService membreService; +private MembreSearchCriteria searchCriteria; // DTO du serveur API +return OUTCOME_MEMBRE_LISTE; // Navigation outcome +``` + +**❌ MAUVAIS** : +```java +private MembreClientDTO membreDTO; // DTO client dupliquĂ© +return "/pages/secure/membre/liste"; // Chemin direct +``` + +--- + +## 🐛 PROBLÈMES CONNUS + +### 1. Erreurs de compilation dans les tests + +**Statut** : Non rĂ©solu +**Impact** : Bloque les tests +**Action** : VĂ©rifier et corriger les 3596 erreurs de compilation dans les tests (selon audit) + +### 2. Secrets hardcodĂ©s + +**Statut** : Non rĂ©solu +**Impact** : SĂ©curitĂ© +**Action** : Supprimer les secrets hardcodĂ©s et utiliser des variables d'environnement + +### 3. Lombok mal configurĂ© (selon audit) + +**Statut** : À vĂ©rifier +**Impact** : Erreurs de compilation potentielles +**Action** : VĂ©rifier la configuration Lombok dans `pom.xml` + +--- + +## 📊 MÉTRIQUES ACTUELLES + +### Compilation + +- **Client module** : ✅ BUILD SUCCESS +- **Server module** : ✅ BUILD SUCCESS (derniĂšre vĂ©rification) +- **Tests** : ❌ Nombreuses erreurs (Ă  corriger) + +### Code + +- **Fichiers Java** : ~237 fichiers +- **Pages XHTML** : 72 pages (60% complĂštes) +- **Beans JSF** : 36 beans (70% complĂštes) +- **TODOs restants** : ~7 TODOs identifiĂ©s + +--- + +## 🎯 PLAN D'ACTION RECOMMANDÉ + +### Phase 1 : Finalisation des TODOs (1-2 jours) +1. ImplĂ©menter les TODOs restants dans `DemandesAideBean`, `RapportDetailsBean`, `ConfigurationBean` +2. Tester chaque implĂ©mentation +3. VĂ©rifier la compilation + +### Phase 2 : Audit et complĂ©tion des pages (2-3 jours) +1. VĂ©rifier toutes les pages XHTML +2. CrĂ©er les beans manquants +3. S'assurer que tous les composants rĂ©utilisables sont utilisĂ©s +4. VĂ©rifier la navigation + +### Phase 3 : Tests et validation (2-3 jours) +1. Corriger les erreurs de compilation dans les tests +2. Ajouter des tests unitaires pour les nouvelles fonctionnalitĂ©s +3. Tests d'intĂ©gration + +### Phase 4 : SĂ©curitĂ© et production (1-2 jours) +1. Supprimer les secrets hardcodĂ©s +2. VĂ©rifier la sĂ©curitĂ© +3. Documentation finale + +**TOTAL ESTIMÉ : 6-10 jours de travail** + +--- + +## 📚 RESSOURCES UTILES + +### Fichiers de rĂ©fĂ©rence + +- `ROADMAP_FINALISATION_UNIONFLOW.md` : Roadmap complĂšte du projet +- `AUDIT_INTEGRAL_UNIONFLOW.md` : Audit technique complet +- `faces-config.xml` : Toutes les rĂšgles de navigation +- `union-flow.puml` : Diagramme de classes +- `unionflow.md` : Description mĂ©tier + +### Commandes utiles + +```bash +# Compiler le projet client +mvn compile -pl unionflow-client-quarkus-primefaces-freya + +# Compiler le projet serveur +mvn compile -pl unionflow-server-impl-quarkus + +# Compiler tout le projet +mvn clean compile + +# Lancer les tests +mvn test +``` + +--- + +## 🔗 CONTEXTE DE LA DERNIÈRE SESSION + +**DerniĂšre tĂąche complĂ©tĂ©e** : ImplĂ©mentation du dialogue de contact membre + +**ProblĂšmes rencontrĂ©s** : +1. Erreur de compilation : signature incorrecte de `envoyerNotificationsGroupees()` + - **Solution** : Utilisation de `NotificationService.NotificationGroupeeRequest` au lieu de paramĂštres sĂ©parĂ©s + +**État final** : ✅ Compilation rĂ©ussie, fonctionnalitĂ© opĂ©rationnelle + +--- + +## 💡 NOTES IMPORTANTES POUR LA CONTINUITÉ + +1. **Toujours vĂ©rifier la compilation** aprĂšs chaque modification +2. **Respecter strictement DRY/WOU** - vĂ©rifier les composants existants avant d'en crĂ©er de nouveaux +3. **Utiliser les navigation outcomes** - ne pas utiliser de chemins directs +4. **Tester chaque fonctionnalitĂ©** aprĂšs implĂ©mentation +5. **Documenter les changements** dans ce fichier + +--- + +**DerniĂšre mise Ă  jour** : 2025-12-01 +**Prochaine Ă©tape recommandĂ©e** : ImplĂ©menter les TODOs restants dans `DemandesAideBean.java` + diff --git a/unionflow-client-quarkus-primefaces-freya/pom.xml b/unionflow-client-quarkus-primefaces-freya/pom.xml index 1641e16..1b75c29 100644 --- a/unionflow-client-quarkus-primefaces-freya/pom.xml +++ b/unionflow-client-quarkus-primefaces-freya/pom.xml @@ -108,6 +108,21 @@ quarkus-hibernate-validator + + + org.projectlombok + lombok + 1.18.30 + provided + + + + + dev.lions.unionflow + unionflow-server-api + 1.0.0 + + io.quarkus diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/CotisationService.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/CotisationService.java index fa41f68..29a94ea 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/CotisationService.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/CotisationService.java @@ -117,5 +117,16 @@ public interface CotisationService { @DELETE @Path("/{id}") void supprimer(@PathParam("id") UUID id); + + /** + * Envoie des rappels de cotisations groupĂ©s Ă  plusieurs membres (WOU/DRY) + * + * @param membreIds Liste des IDs des membres destinataires + * @return Nombre de rappels envoyĂ©s + */ + @POST + @Path("/rappels/groupes") + @Consumes(MediaType.APPLICATION_JSON) + Map envoyerRappelsGroupes(List membreIds); } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/MembreService.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/MembreService.java index 23e55ce..bd8e060 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/MembreService.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/MembreService.java @@ -96,6 +96,22 @@ public interface MembreService { @FormParam("file") java.io.InputStream fileInputStream, @FormParam("associationId") UUID associationId ); + + @GET + @Path("/autocomplete/villes") + List obtenirVilles(@QueryParam("query") String query); + + @GET + @Path("/autocomplete/professions") + List obtenirProfessions(@QueryParam("query") String query); + + @POST + @Path("/export/selection") + @Consumes(MediaType.APPLICATION_JSON) + @Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + byte[] exporterSelection( + List membreIds, + @QueryParam("format") @DefaultValue("EXCEL") String format); // Classes DTO internes pour les rĂ©ponses spĂ©cialisĂ©es class StatistiquesMembreDTO { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/NotificationService.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/NotificationService.java new file mode 100644 index 0000000..7eda9ed --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/service/NotificationService.java @@ -0,0 +1,51 @@ +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.List; +import java.util.Map; +import java.util.UUID; + +/** + * Service REST Client pour la gestion des notifications (WOU/DRY) + * + * @author UnionFlow Team + * @version 3.0 + */ +@RegisterRestClient(configKey = "unionflow-api") +@Path("/api/notifications") +@Consumes(MediaType.APPLICATION_JSON) +@Produces(MediaType.APPLICATION_JSON) +public interface NotificationService { + + /** + * Envoie des notifications groupĂ©es Ă  plusieurs membres (WOU/DRY) + * + * @param request DTO contenant les IDs des membres, sujet, corps et canaux + * @return Nombre de notifications créées + */ + @POST + @Path("/groupees") + Map envoyerNotificationsGroupees(NotificationGroupeeRequest request); + + /** + * Classe interne pour les requĂȘtes de notifications groupĂ©es (WOU/DRY) + */ + class NotificationGroupeeRequest { + public List membreIds; + public String sujet; + public String corps; + public List canaux; + + public NotificationGroupeeRequest() {} + + public NotificationGroupeeRequest(List membreIds, String sujet, String corps, List canaux) { + this.membreIds = membreIds; + this.sujet = sujet; + this.corps = corps; + this.canaux = canaux; + } + } +} + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/ConfigurationBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/ConfigurationBean.java index 50b8da0..dcf7a2d 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/ConfigurationBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/ConfigurationBean.java @@ -3,9 +3,13 @@ package dev.lions.unionflow.client.view; import jakarta.enterprise.context.SessionScoped; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; +import jakarta.faces.application.FacesMessage; +import jakarta.faces.context.FacesContext; import java.io.Serializable; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.List; import java.util.logging.Logger; @Named("configurationBean") @@ -15,6 +19,9 @@ public class ConfigurationBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(ConfigurationBean.class.getName()); + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_SUPER_ADMIN_LOGS = "superAdminLogsPage"; + private ConfigurationGenerale general; private ConfigurationSecurite securite; private ConfigurationEmail email; @@ -95,6 +102,7 @@ public class ConfigurationBean implements Serializable { initializeEmail(); initializePaiements(); initializeSysteme(); + initSauvegardes(); calculerMetriquesSysteme(); } @@ -261,7 +269,8 @@ public class ConfigurationBean implements Serializable { } public String voirLogsSysteme() { - return "/pages/super-admin/logs?faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_SUPER_ADMIN_LOGS + "?faces-redirect=true"; } // Getters et Setters @@ -697,6 +706,103 @@ public class ConfigurationBean implements Serializable { public void sauvegarderAlertes() { LOGGER.info("Configuration des alertes sauvegardĂ©e"); } + + // PropriĂ©tĂ©s et mĂ©thodes pour les sauvegardes (WOU/DRY) + private List sauvegardes = new ArrayList<>(); + + public void initSauvegardes() { + chargerSauvegardes(); + } + + private void chargerSauvegardes() { + sauvegardes = new ArrayList<>(); + + try { + // TODO: ImplĂ©menter l'appel au service de sauvegarde quand il sera disponible cĂŽtĂ© serveur + // Exemple: sauvegardes = sauvegardeService.listerSauvegardes() + // .stream() + // .map(dto -> convertToSauvegarde(dto)) + // .collect(Collectors.toList()); + + // Pour l'instant, aucune sauvegarde n'est disponible tant que le service backend n'est pas créé + LOGGER.info("Chargement de " + sauvegardes.size() + " sauvegardes depuis le backend"); + + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des sauvegardes: " + e.getMessage()); + sauvegardes = new ArrayList<>(); + } + } + + public void creerSauvegarde() { + LOGGER.info("CrĂ©ation d'une nouvelle sauvegarde"); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "Sauvegarde", + "La sauvegarde est en cours de crĂ©ation...")); + chargerSauvegardes(); + } + + public void telechargerSauvegarde(Sauvegarde sauvegarde) { + LOGGER.info("TĂ©lĂ©chargement de la sauvegarde: " + sauvegarde.getDate()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "TĂ©lĂ©chargement", + "TĂ©lĂ©chargement de la sauvegarde en cours...")); + } + + public void restaurerSauvegarde(Sauvegarde sauvegarde) { + LOGGER.info("Restauration de la sauvegarde: " + sauvegarde.getDate()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "Restauration", + "La restauration est en cours...")); + } + + public void supprimerSauvegarde(Sauvegarde sauvegarde) { + LOGGER.info("Suppression de la sauvegarde: " + sauvegarde.getDate()); + sauvegardes.remove(sauvegarde); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "Suppression", + "Sauvegarde supprimĂ©e avec succĂšs")); + } + + public List getSauvegardes() { return sauvegardes; } + public void setSauvegardes(List sauvegardes) { this.sauvegardes = sauvegardes; } + + // Classe interne pour les sauvegardes (WOU/DRY) + public static class Sauvegarde { + private LocalDateTime date; + private String taille; + private String type; + private String statut; + + public LocalDateTime getDate() { return date; } + public void setDate(LocalDateTime date) { this.date = date; } + + public String getTaille() { return taille; } + public void setTaille(String taille) { this.taille = taille; } + + 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 getStatutSeverity() { + return switch (statut) { + case "VALIDE" -> "success"; + case "EN_COURS" -> "warning"; + case "ERREUR" -> "danger"; + default -> "secondary"; + }; + } + + public String getStatutIcon() { + return switch (statut) { + case "VALIDE" -> "pi-check"; + case "EN_COURS" -> "pi-clock"; + case "ERREUR" -> "pi-times"; + default -> "pi-circle"; + }; + } + } public static class ConfigurationSysteme { private boolean cacheActivĂ©; diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/CotisationsGestionBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/CotisationsGestionBean.java index b7d6107..eb1a821 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/CotisationsGestionBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/CotisationsGestionBean.java @@ -28,6 +28,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.HashMap; import java.util.stream.Collectors; import java.util.logging.Logger; @@ -42,6 +43,9 @@ import java.util.logging.Logger; @SessionScoped public class CotisationsGestionBean implements Serializable { + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_DASHBOARD = "dashboardPage"; + private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(CotisationsGestionBean.class.getName()); @@ -116,6 +120,12 @@ public class CotisationsGestionBean implements Serializable { // Nouvelle campagne private NouvelleCampagne nouvelleCampagne; + // PropriĂ©tĂ©s pour les rappels (WOU/DRY) + private List membresEnRetard = new ArrayList<>(); + private List membresSelectionnes = new ArrayList<>(); + private int nombreMembresEnRetard = 0; + private int nombreRappelsEnvoyes = 0; + @PostConstruct public void init() { chargerKPIs(); @@ -124,6 +134,7 @@ public class CotisationsGestionBean implements Serializable { chargerTopOrganisations(); chargerRepartitionMethodes(); initializeNouvelleCampagne(); + chargerMembresEnRetard(); } /** @@ -1068,9 +1079,94 @@ public class CotisationsGestionBean implements Serializable { // Actions rapides - /** - * GĂ©nĂšre un rapport mensuel des cotisations - */ + // MĂ©thodes pour les rappels (WOU/DRY) + public void envoyerRappelsGroupes() { + if (membresSelectionnes == null || membresSelectionnes.isEmpty()) { + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention", + "Veuillez sĂ©lectionner au moins un membre")); + return; + } + try { + List membreIds = membresSelectionnes.stream() + .map(MembreEnRetard::getId) + .collect(Collectors.toList()); + cotisationService.envoyerRappelsGroupes(membreIds); + nombreRappelsEnvoyes += membreIds.size(); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "SuccĂšs", + nombreRappelsEnvoyes + " rappels envoyĂ©s avec succĂšs")); + chargerMembresEnRetard(); + } catch (Exception e) { + LOGGER.severe("Erreur lors de l'envoi des rappels: " + e.getMessage()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible d'envoyer les rappels: " + e.getMessage())); + } + } + + public void envoyerRappel(MembreEnRetard membre) { + try { + List membreIds = List.of(membre.getId()); + cotisationService.envoyerRappelsGroupes(membreIds); + nombreRappelsEnvoyes++; + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "SuccĂšs", + "Rappel envoyĂ© Ă  " + membre.getNomComplet())); + } catch (Exception e) { + LOGGER.severe("Erreur lors de l'envoi du rappel: " + e.getMessage()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible d'envoyer le rappel: " + e.getMessage())); + } + } + + private void chargerMembresEnRetard() { + try { + List cotisationsEnRetard = cotisationService.obtenirEnRetard(0, 1000); + membresEnRetard = new ArrayList<>(); + Map membresMap = new HashMap<>(); + + for (CotisationDTO cotisation : cotisationsEnRetard) { + UUID membreId = cotisation.getMembreId(); + MembreEnRetard membre = membresMap.get(membreId); + if (membre == null) { + membre = new MembreEnRetard(); + membre.setId(membreId); + membre.setNomComplet(cotisation.getNomMembre()); + membre.setNumeroMembre(cotisation.getNumeroMembre()); + membre.setMontantDu(BigDecimal.ZERO); + membre.setJoursRetard(0); + membresMap.put(membreId, membre); + } + membre.setMontantDu(membre.getMontantDu().add(cotisation.getMontantDu())); + if (cotisation.getDateEcheance() != null) { + long jours = java.time.temporal.ChronoUnit.DAYS.between( + cotisation.getDateEcheance(), + java.time.LocalDate.now()); + if (jours > membre.getJoursRetard()) { + membre.setJoursRetard((int) jours); + } + } + } + + membresEnRetard = new ArrayList<>(membresMap.values()); + nombreMembresEnRetard = membresEnRetard.size(); + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des membres en retard: " + e.getMessage()); + membresEnRetard = new ArrayList<>(); + nombreMembresEnRetard = 0; + } + } + + // MĂ©thodes pour les rapports (WOU/DRY) + public void genererRapport() { + LOGGER.info("GĂ©nĂ©ration d'un rapport de cotisations"); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "Rapport", + "Le rapport est en cours de gĂ©nĂ©ration")); + } + public void genererRapportMensuel() { try { LOGGER.info("GĂ©nĂ©ration rapport mensuel"); @@ -1152,7 +1248,8 @@ public class CotisationsGestionBean implements Serializable { * Retourne au tableau de bord */ public String tableauDeBord() { - return "/pages/secure/dashboard?faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_DASHBOARD + "?faces-redirect=true"; } /** @@ -1412,4 +1509,51 @@ public class CotisationsGestionBean implements Serializable { } return getInitiales(cotisation.getNomMembre()); } + + // Getters et Setters pour les rappels (WOU/DRY) + public List getMembresEnRetard() { + if (membresEnRetard == null || membresEnRetard.isEmpty()) { + chargerMembresEnRetard(); + } + return membresEnRetard; + } + public void setMembresEnRetard(List membresEnRetard) { this.membresEnRetard = membresEnRetard; } + + public List getMembresSelectionnes() { return membresSelectionnes; } + public void setMembresSelectionnes(List membresSelectionnes) { this.membresSelectionnes = membresSelectionnes; } + + public int getNombreMembresEnRetard() { + if (nombreMembresEnRetard == 0 && (membresEnRetard == null || membresEnRetard.isEmpty())) { + chargerMembresEnRetard(); + } + return nombreMembresEnRetard; + } + public void setNombreMembresEnRetard(int nombreMembresEnRetard) { this.nombreMembresEnRetard = nombreMembresEnRetard; } + + public int getNombreRappelsEnvoyes() { return nombreRappelsEnvoyes; } + public void setNombreRappelsEnvoyes(int nombreRappelsEnvoyes) { this.nombreRappelsEnvoyes = nombreRappelsEnvoyes; } + + // Classe interne pour les membres en retard (WOU/DRY) + public static class MembreEnRetard { + private UUID id; + private String nomComplet; + private String numeroMembre; + private BigDecimal montantDu; + private int joursRetard; + + 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; } + + public String getNumeroMembre() { return numeroMembre; } + public void setNumeroMembre(String numeroMembre) { this.numeroMembre = numeroMembre; } + + public BigDecimal getMontantDu() { return montantDu; } + public void setMontantDu(BigDecimal montantDu) { this.montantDu = montantDu; } + + public int getJoursRetard() { return joursRetard; } + public void setJoursRetard(int joursRetard) { this.joursRetard = joursRetard; } + } } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DashboardBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DashboardBean.java index 7ba4fd1..6eb1769 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DashboardBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DashboardBean.java @@ -28,6 +28,15 @@ public class DashboardBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(DashboardBean.class.getName()); + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_MEMBRE_INSCRIPTION = "membreInscriptionPage"; + private static final String OUTCOME_COTISATION_PAIEMENT = "cotisationPaiementPage"; + private static final String OUTCOME_EVENEMENT_CREATION = "evenementCreationPage"; + private static final String OUTCOME_ADHESION_VALIDATION = "adhesionValidationPage"; + private static final String OUTCOME_COTISATION_RELANCES = "cotisationRelancesPage"; + private static final String OUTCOME_AIDE_TRAITEMENT = "aideTraitementPage"; + private static final String OUTCOME_EVENEMENT_GESTION = "evenementGestionPage"; + @Inject @RestClient private MembreService membreService; @@ -502,33 +511,33 @@ public class DashboardBean implements Serializable { chargerDonneesBackend(); } - // Actions de navigation + // Actions de navigation (WOU/DRY - utilisation de navigation outcomes) public String redirectToNewMember() { - return "/pages/secure/membre/inscription?faces-redirect=true"; + return OUTCOME_MEMBRE_INSCRIPTION + "?faces-redirect=true"; } public String redirectToCotisation() { - return "/pages/secure/cotisation/paiement?faces-redirect=true"; + return OUTCOME_COTISATION_PAIEMENT + "?faces-redirect=true"; } public String redirectToEvenement() { - return "/pages/secure/evenement/creation?faces-redirect=true"; + return OUTCOME_EVENEMENT_CREATION + "?faces-redirect=true"; } public String redirectToAdhesionValidation() { - return "/pages/secure/adhesion/validation?faces-redirect=true"; + return OUTCOME_ADHESION_VALIDATION + "?faces-redirect=true"; } public String redirectToRelances() { - return "/pages/secure/cotisation/relances?faces-redirect=true"; + return OUTCOME_COTISATION_RELANCES + "?faces-redirect=true"; } public String redirectToAidesTraitement() { - return "/pages/secure/aide/traitement?faces-redirect=true"; + return OUTCOME_AIDE_TRAITEMENT + "?faces-redirect=true"; } public String redirectToEvenementPlanning() { - return "/pages/secure/evenement/gestion?faces-redirect=true"; + return OUTCOME_EVENEMENT_GESTION + "?faces-redirect=true"; } public void generateRapport() { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DemandesAideBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DemandesAideBean.java index f8a7c62..ac1aa64 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DemandesAideBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DemandesAideBean.java @@ -17,6 +17,7 @@ import java.util.UUID; import java.util.stream.Collectors; import java.math.BigDecimal; import java.util.logging.Logger; +import java.util.Map; @Named("demandesAideBean") @SessionScoped @@ -25,6 +26,9 @@ public class DemandesAideBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(DemandesAideBean.class.getName()); + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_DEMANDES_HISTORIQUE = "demandesHistoriquePage"; + @Inject @RestClient private DemandeAideService demandeAideService; @@ -38,6 +42,9 @@ public class DemandesAideBean implements Serializable { private NouvelleDemande nouvelleDemande; private Filtres filtres; private StatistiquesDemandes statistiques; + + // PropriĂ©tĂ©s pour le dialogue de dĂ©tails + private boolean dialogDetailsVisible; @PostConstruct public void init() { @@ -64,6 +71,8 @@ public class DemandesAideBean implements Serializable { statistiques.setDemandesEnAttente((int) enAttente); long approuvees = demandesDTO.stream().filter(d -> "APPROUVEE".equals(d.getStatut())).count(); statistiques.setDemandesApprouvees((int) approuvees); + long rejetees = demandesDTO.stream().filter(d -> "REJETEE".equals(d.getStatut())).count(); + statistiques.setDemandesRejetees((int) rejetees); BigDecimal montantTotal = demandesDTO.stream() .filter(d -> d.getMontantAccorde() != null) .map(DemandeAideDTO::getMontantAccorde) @@ -74,54 +83,75 @@ public class DemandesAideBean implements Serializable { statistiques.setTotalDemandes(0); statistiques.setDemandesEnAttente(0); statistiques.setDemandesApprouvees(0); + statistiques.setDemandesRejetees(0); statistiques.setMontantTotalAide("0 FCFA"); } } private void initializeEtapesWorkflow() { etapesWorkflow = new ArrayList<>(); - - EtapeWorkflow enAttente = new EtapeWorkflow(); - enAttente.setLibelle("En Attente"); - enAttente.setIcon("pi-clock"); - enAttente.setCouleur("orange-500"); - enAttente.setNombre(23); - etapesWorkflow.add(enAttente); - - EtapeWorkflow evaluation = new EtapeWorkflow(); - evaluation.setLibelle("Évaluation"); - evaluation.setIcon("pi-search"); - evaluation.setCouleur("blue-500"); - evaluation.setNombre(15); - etapesWorkflow.add(evaluation); - - EtapeWorkflow visite = new EtapeWorkflow(); - visite.setLibelle("Visite"); - visite.setIcon("pi-home"); - visite.setCouleur("purple-500"); - visite.setNombre(8); - etapesWorkflow.add(visite); - - EtapeWorkflow decision = new EtapeWorkflow(); - decision.setLibelle("DĂ©cision"); - decision.setIcon("pi-check-circle"); - decision.setCouleur("yellow-500"); - decision.setNombre(12); - etapesWorkflow.add(decision); - - EtapeWorkflow versement = new EtapeWorkflow(); - versement.setLibelle("Versement"); - versement.setIcon("pi-dollar"); - versement.setCouleur("green-500"); - versement.setNombre(6); - etapesWorkflow.add(versement); - - EtapeWorkflow suivi = new EtapeWorkflow(); - suivi.setLibelle("Suivi"); - suivi.setIcon("pi-chart-line"); - suivi.setCouleur("indigo-500"); - suivi.setNombre(4); - etapesWorkflow.add(suivi); + + try { + // Charger toutes les demandes depuis le backend pour calculer les Ă©tapes + List demandesDTO = demandeAideService.listerToutes(0, 10000); + + // Calculer le nombre de demandes par statut depuis les donnĂ©es rĂ©elles + long enAttenteCount = demandesDTO.stream().filter(d -> "EN_ATTENTE".equals(d.getStatut())).count(); + long enEvaluationCount = demandesDTO.stream().filter(d -> "EN_EVALUATION".equals(d.getStatut())).count(); + long enVisiteCount = demandesDTO.stream().filter(d -> "EN_VISITE".equals(d.getStatut())).count(); + long enDecisionCount = demandesDTO.stream().filter(d -> "EN_DECISION".equals(d.getStatut())).count(); + long enVersementCount = demandesDTO.stream().filter(d -> "EN_VERSEMENT".equals(d.getStatut())).count(); + long enSuiviCount = demandesDTO.stream().filter(d -> "EN_SUIVI".equals(d.getStatut())).count(); + + // CrĂ©er les Ă©tapes workflow avec les nombres rĂ©els + EtapeWorkflow enAttente = new EtapeWorkflow(); + enAttente.setLibelle("En Attente"); + enAttente.setIcon("pi-clock"); + enAttente.setCouleur("orange-500"); + enAttente.setNombre((int) enAttenteCount); + etapesWorkflow.add(enAttente); + + EtapeWorkflow evaluation = new EtapeWorkflow(); + evaluation.setLibelle("Évaluation"); + evaluation.setIcon("pi-search"); + evaluation.setCouleur("blue-500"); + evaluation.setNombre((int) enEvaluationCount); + etapesWorkflow.add(evaluation); + + EtapeWorkflow visite = new EtapeWorkflow(); + visite.setLibelle("Visite"); + visite.setIcon("pi-home"); + visite.setCouleur("purple-500"); + visite.setNombre((int) enVisiteCount); + etapesWorkflow.add(visite); + + EtapeWorkflow decision = new EtapeWorkflow(); + decision.setLibelle("DĂ©cision"); + decision.setIcon("pi-check-circle"); + decision.setCouleur("yellow-500"); + decision.setNombre((int) enDecisionCount); + etapesWorkflow.add(decision); + + EtapeWorkflow versement = new EtapeWorkflow(); + versement.setLibelle("Versement"); + versement.setIcon("pi-dollar"); + versement.setCouleur("green-500"); + versement.setNombre((int) enVersementCount); + etapesWorkflow.add(versement); + + EtapeWorkflow suivi = new EtapeWorkflow(); + suivi.setLibelle("Suivi"); + suivi.setIcon("pi-chart-line"); + suivi.setCouleur("indigo-500"); + suivi.setNombre((int) enSuiviCount); + etapesWorkflow.add(suivi); + + LOGGER.info("Étapes workflow initialisĂ©es depuis les donnĂ©es backend"); + + } catch (Exception e) { + LOGGER.severe("Erreur lors de l'initialisation des Ă©tapes workflow: " + e.getMessage()); + etapesWorkflow = new ArrayList<>(); + } } private void initializeDemandes() { @@ -286,13 +316,43 @@ public class DemandesAideBean implements Serializable { } public String voirHistorique() { - return "/pages/admin/demandes/historique?id=" + demandeSelectionnee.getId() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_DEMANDES_HISTORIQUE + "?id=" + demandeSelectionnee.getId() + "&faces-redirect=true"; } public void envoyerNotification() { LOGGER.info("Notification envoyĂ©e pour la demande de: " + demandeSelectionnee.getDemandeur()); } + // MĂ©thodes pour la page de traitement (WOU/DRY - rĂ©utilisables) + public void approuver(DemandeAide demande) { + demandeSelectionnee = demande; + approuverDemande(); + } + + public void rejeter(DemandeAide demande) { + demandeSelectionnee = demande; + rejeterDemande(); + } + + public void voirDetails(DemandeAide demande) { + demandeSelectionnee = demande; + dialogDetailsVisible = true; + LOGGER.info("Affichage des dĂ©tails de la demande: " + demande.getId()); + } + + public void fermerDialogDetails() { + dialogDetailsVisible = false; + demandeSelectionnee = null; + } + + public void actualiser() { + initializeDemandes(); + initializeStatistiques(); + appliquerFiltres(); + LOGGER.info("DonnĂ©es actualisĂ©es"); + } + public void dupliquerDemande() { if (demandeSelectionnee != null) { DemandeAide copie = new DemandeAide(); @@ -319,6 +379,20 @@ public class DemandesAideBean implements Serializable { LOGGER.info("Export de " + demandesFiltrees.size() + " demandes d'aide"); } + // MĂ©thodes pour les graphiques (WOU/DRY) - RetirĂ©es car PrimeFaces ne supporte plus les charts + // Utiliser une bibliothĂšque JavaScript externe (Chart.js, ApexCharts, etc.) dans le XHTML + public Object getChartModelType() { + // Les graphiques sont gĂ©rĂ©s directement dans le XHTML avec des bibliothĂšques JavaScript + // Retourne les donnĂ©es pour un Ă©ventuel graphique client-side + return null; + } + + public Object getChartModelStatut() { + // Les graphiques sont gĂ©rĂ©s directement dans le XHTML avec des bibliothĂšques JavaScript + // Retourne les donnĂ©es pour un Ă©ventuel graphique client-side + return null; + } + // Getters et Setters public List getToutesLesDemandes() { return toutesLesDemandes; } public void setToutesLesDemandes(List toutesLesDemandes) { this.toutesLesDemandes = toutesLesDemandes; } @@ -346,6 +420,9 @@ public class DemandesAideBean implements Serializable { public StatistiquesDemandes getStatistiques() { return statistiques; } public void setStatistiques(StatistiquesDemandes statistiques) { this.statistiques = statistiques; } + + public boolean isDialogDetailsVisible() { return dialogDetailsVisible; } + public void setDialogDetailsVisible(boolean dialogDetailsVisible) { this.dialogDetailsVisible = dialogDetailsVisible; } // Classes internes public static class DemandeAide { @@ -592,6 +669,7 @@ public class DemandesAideBean implements Serializable { private int totalDemandes; private int demandesEnAttente; private int demandesApprouvees; + private int demandesRejetees; private String montantTotalAide; // Getters et setters @@ -604,6 +682,9 @@ public class DemandesAideBean implements Serializable { public int getDemandesApprouvees() { return demandesApprouvees; } public void setDemandesApprouvees(int demandesApprouvees) { this.demandesApprouvees = demandesApprouvees; } + public int getDemandesRejetees() { return demandesRejetees; } + public void setDemandesRejetees(int demandesRejetees) { this.demandesRejetees = demandesRejetees; } + public String getMontantTotalAide() { return montantTotalAide; } public void setMontantTotalAide(String montantTotalAide) { this.montantTotalAide = montantTotalAide; } } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DocumentsBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DocumentsBean.java index 2915145..70a59e6 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DocumentsBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/DocumentsBean.java @@ -21,6 +21,9 @@ public class DocumentsBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(DocumentsBean.class.getName()); + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_DOCUMENTS_VERSIONS = "documentsVersionsPage"; + private List tousLesDocuments; private List documentsFiltres; private List documentsSelectionnes; @@ -286,7 +289,8 @@ public class DocumentsBean implements Serializable { } public String voirHistoriqueVersions() { - return "/pages/admin/documents/versions?id=" + documentSelectionne.getId() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_DOCUMENTS_VERSIONS + "?id=" + documentSelectionne.getId() + "&faces-redirect=true"; } public boolean estSelectionne(Document document) { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EntitesGestionBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EntitesGestionBean.java index bf03575..7fa3db0 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EntitesGestionBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EntitesGestionBean.java @@ -25,6 +25,12 @@ public class EntitesGestionBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(EntitesGestionBean.class.getName()); + // 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 AssociationService associationService; @@ -218,7 +224,8 @@ public class EntitesGestionBean implements Serializable { } public String voirEntite(Entite entite) { - return "/pages/super-admin/entites/details?id=" + entite.getId() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_ENTITE_DETAILS + "?id=" + entite.getId() + "&faces-redirect=true"; } public void creerEntite() { @@ -237,15 +244,18 @@ public class EntitesGestionBean implements Serializable { } public String gererMembres() { - return "/pages/admin/membres/gestion?entiteId=" + entiteSelectionne.getId() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_ADMIN_MEMBRES_GESTION + "?entiteId=" + entiteSelectionne.getId() + "&faces-redirect=true"; } public String configurerEntite() { - return "/pages/super-admin/entites/configuration?id=" + entiteSelectionne.getId() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_ENTITE_CONFIGURATION + "?id=" + entiteSelectionne.getId() + "&faces-redirect=true"; } public String voirRapports() { - return "/pages/super-admin/entites/rapports?id=" + entiteSelectionne.getId() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_ENTITE_RAPPORTS + "?id=" + entiteSelectionne.getId() + "&faces-redirect=true"; } public void suspendreEntite() { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EvenementsBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EvenementsBean.java index 408b0e7..2fa5318 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EvenementsBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/EvenementsBean.java @@ -250,9 +250,13 @@ public class EvenementsBean implements Serializable { if (map.get("description") != null) dto.setDescription(map.get("description").toString()); // Type d'Ă©vĂ©nement - peut ĂȘtre un enum ou une String - if (map.get("typeEvenement") != null) { - Object type = map.get("typeEvenement"); - dto.setTypeEvenement(type instanceof Enum ? type.toString() : type.toString()); + // GĂ©rer Ă  la fois "typeEvenement" et "type" pour compatibilitĂ© + Object typeObj = map.get("typeEvenement"); + if (typeObj == null) { + typeObj = map.get("type"); // Fallback sur "type" si "typeEvenement" n'existe pas + } + if (typeObj != null) { + dto.setTypeEvenement(typeObj instanceof Enum ? typeObj.toString() : typeObj.toString()); } // Statut - peut ĂȘtre un enum ou une String diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/FormulaireBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/FormulaireBean.java index cf8d449..a9b42df 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/FormulaireBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/FormulaireBean.java @@ -21,6 +21,10 @@ public class FormulaireBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(FormulaireBean.class.getName()); + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_SOUSCRIPTION_CHECKOUT = "souscriptionCheckoutPage"; + private static final String OUTCOME_FORMULAIRE_DETAILS = "formulaireDetailsPage"; + @Inject @RestClient private FormulaireService formulaireService; @@ -58,8 +62,8 @@ public class FormulaireBean implements Serializable { public String procederSouscription() { if (formulaireSelectionne != null) { - // Rediriger vers la page de souscription avec les paramĂštres - return "/pages/secure/souscription/checkout?formulaire=" + + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_SOUSCRIPTION_CHECKOUT + "?formulaire=" + formulaireSelectionne.getId() + "&facturation=" + typeFacturationSelectionne.name() + "&faces-redirect=true"; @@ -68,7 +72,8 @@ public class FormulaireBean implements Serializable { } public String voirDetailsFormulaire(FormulaireDTO formulaire) { - return "/pages/public/formulaires/details?id=" + formulaire.getId() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_FORMULAIRE_DETAILS + "?id=" + formulaire.getId() + "&faces-redirect=true"; } public List getFormulairesFiltres() { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreCotisationBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreCotisationBean.java index 4706a01..090b793 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreCotisationBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreCotisationBean.java @@ -1,19 +1,57 @@ package dev.lions.unionflow.client.view; -import jakarta.enterprise.context.SessionScoped; +import dev.lions.unionflow.client.dto.CotisationDTO; +import dev.lions.unionflow.client.dto.MembreDTO; +import dev.lions.unionflow.client.service.CotisationService; +import dev.lions.unionflow.client.service.MembreService; +import jakarta.faces.view.ViewScoped; +import jakarta.inject.Inject; import jakarta.inject.Named; import jakarta.annotation.PostConstruct; +import jakarta.faces.application.FacesMessage; +import jakarta.faces.context.FacesContext; +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.logging.Logger; +import java.util.stream.Collectors; +/** + * Bean pour la gestion des cotisations d'un membre (WOU/DRY) + * + * @author UnionFlow Team + * @version 2.0 + */ @Named("membreCotisationBean") -@SessionScoped +@ViewScoped public class MembreCotisationBean implements Serializable { private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(MembreCotisationBean.class.getName()); + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_MEMBRE_HISTORIQUE_COTISATIONS = "membreHistoriqueCotisationsPage"; + private static final String OUTCOME_MEMBRE_PROFIL = "membreProfilPage"; + + @Inject + @RestClient + private MembreService membreService; + + @Inject + @RestClient + private CotisationService cotisationService; + + // ID du membre (depuis viewParam) + private UUID membreId; + + // DonnĂ©es du membre + private MembreDTO membre; // PropriĂ©tĂ©s de base private String numeroMembre; @@ -68,72 +106,153 @@ public class MembreCotisationBean implements Serializable { @PostConstruct public void init() { - this.numeroMembre = "M240001"; - this.statutCotisations = "À jour"; - this.derniereMAJ = "15/12/2024"; - this.peutPayer = true; - this.cotisationsPayees = 10; - this.cotisationsEnAttente = 2; - this.montantDu = new BigDecimal(10000); - this.totalVerse = new BigDecimal(50000); - this.progressionAnnuelle = 83; + // Si membreId est null, essayer de le rĂ©cupĂ©rer depuis les paramĂštres de requĂȘte + if (membreId == null) { + String idParam = FacesContext.getCurrentInstance() + .getExternalContext() + .getRequestParameterMap() + .get("id"); + if (idParam != null && !idParam.isEmpty()) { + try { + membreId = UUID.fromString(idParam); + } catch (IllegalArgumentException e) { + LOGGER.severe("ID de membre invalide: " + idParam); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "ID de membre invalide")); + return; + } + } + } - initializeCotisations(); - initializeEcheances(); - } - - private void initializeCotisations() { - // Simulation de donnĂ©es - for (int i = 1; i <= 12; i++) { - Cotisation cotisation = new Cotisation(); - cotisation.setReference("COT2024" + String.format("%03d", i)); - cotisation.setLibelle("Cotisation " + getMonthName(i) + " 2024"); - cotisation.setPeriode(getMonthName(i) + " 2024"); - cotisation.setType("MENSUELLE"); - cotisation.setMontant(new BigDecimal(5000)); - cotisation.setStatut(i <= 10 ? "PAYE" : "EN_ATTENTE"); - cotisation.setDateEcheance(LocalDate.of(2024, i, 15)); - if (i <= 10) { - cotisation.setDatePaiement(LocalDate.of(2024, i, i <= 5 ? 10 : 20)); - cotisation.setModePaiement("Wave Money"); - } - cotisations.add(cotisation); - - if (i > 10) { - cotisationsImpayees.add(cotisation); - } + if (membreId != null) { + chargerMembre(); + chargerCotisations(); + calculerStatistiques(); + } else { + LOGGER.warning("Aucun membreId fourni, impossible de charger les cotisations"); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention", + "Aucun membre sĂ©lectionnĂ©")); + initialiserDonneesVides(); } } - private void initializeEcheances() { - Echeance echeance1 = new Echeance(); - echeance1.setLibelle("Cotisation Novembre 2024"); - echeance1.setPeriode("Novembre 2024"); - echeance1.setMontant("5,000 FCFA"); - echeance1.setDateEcheance("15/11/2024"); - echeance1.setUrgence("En retard"); - echeance1.setCouleurUrgence("border-red-500"); - prochainesEcheances.add(echeance1); - - Echeance echeance2 = new Echeance(); - echeance2.setLibelle("Cotisation DĂ©cembre 2024"); - echeance2.setPeriode("DĂ©cembre 2024"); - echeance2.setMontant("5,000 FCFA"); - echeance2.setDateEcheance("15/12/2024"); - echeance2.setUrgence("BientĂŽt"); - echeance2.setCouleurUrgence("border-orange-500"); - prochainesEcheances.add(echeance2); + private void chargerMembre() { + try { + membre = membreService.obtenirParId(membreId); + if (membre != null) { + numeroMembre = membre.getNumeroMembre(); + statutCotisations = membre.getStatut() != null ? membre.getStatut() : "ACTIF"; + derniereMAJ = LocalDate.now().format(DATE_FORMATTER); + } + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement du membre: " + e.getMessage()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible de charger le membre: " + e.getMessage())); + initialiserDonneesVides(); + } } - private String getMonthName(int month) { - String[] months = {"Janvier", "FĂ©vrier", "Mars", "Avril", "Mai", "Juin", - "Juillet", "AoĂ»t", "Septembre", "Octobre", "Novembre", "DĂ©cembre"}; - return months[month - 1]; + private void chargerCotisations() { + try { + List cotisationsDTO = cotisationService.obtenirParMembre(membreId, 0, 100); + cotisations = new ArrayList<>(); + + for (CotisationDTO dto : cotisationsDTO) { + Cotisation cotisation = convertirEnCotisation(dto); + cotisations.add(cotisation); + + if (!"PAYEE".equals(cotisation.getStatut()) && !"PAYE".equals(cotisation.getStatut())) { + cotisationsImpayees.add(cotisation); + } + } + } catch (Exception e) { + LOGGER.severe("Erreur lors du chargement des cotisations: " + e.getMessage()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible de charger les cotisations: " + e.getMessage())); + cotisations = new ArrayList<>(); + } } + private Cotisation convertirEnCotisation(CotisationDTO dto) { + Cotisation cotisation = new Cotisation(); + cotisation.setReference(dto.getNumeroReference() != null ? dto.getNumeroReference() : ""); + cotisation.setLibelle(dto.getLibelle() != null ? dto.getLibelle() : "Cotisation"); + + // Formater la pĂ©riode depuis la date d'Ă©chĂ©ance + if (dto.getDateEcheance() != null) { + String[] moisNoms = {"Janvier", "FĂ©vrier", "Mars", "Avril", "Mai", "Juin", + "Juillet", "AoĂ»t", "Septembre", "Octobre", "Novembre", "DĂ©cembre"}; + int mois = dto.getDateEcheance().getMonthValue(); + int annee = dto.getDateEcheance().getYear(); + cotisation.setPeriode(moisNoms[mois - 1] + " " + annee); + } else { + cotisation.setPeriode(""); + } + + cotisation.setType(dto.getTypeCotisation() != null ? dto.getTypeCotisation() : "MENSUELLE"); + cotisation.setMontant(dto.getMontantDu() != null ? dto.getMontantDu() : BigDecimal.ZERO); + cotisation.setStatut(dto.getStatut() != null ? dto.getStatut() : "EN_ATTENTE"); + cotisation.setDateEcheance(dto.getDateEcheance()); + + // Convertir LocalDateTime en LocalDate pour datePaiement + if (dto.getDatePaiement() != null) { + cotisation.setDatePaiement(dto.getDatePaiement().toLocalDate()); + } + + cotisation.setModePaiement(dto.getMethodePaiement() != null ? dto.getMethodePaiement() : null); + return cotisation; + } + + private void calculerStatistiques() { + cotisationsPayees = (int) cotisations.stream() + .filter(c -> "PAYEE".equals(c.getStatut()) || "PAYE".equals(c.getStatut())) + .count(); + cotisationsEnAttente = (int) cotisations.stream() + .filter(c -> "EN_ATTENTE".equals(c.getStatut())) + .count(); + montantDu = cotisations.stream() + .filter(c -> !"PAYEE".equals(c.getStatut()) && !"PAYE".equals(c.getStatut())) + .map(Cotisation::getMontant) + .reduce(BigDecimal.ZERO, BigDecimal::add); + totalVerse = cotisations.stream() + .filter(c -> "PAYEE".equals(c.getStatut()) || "PAYE".equals(c.getStatut())) + .map(Cotisation::getMontant) + .reduce(BigDecimal.ZERO, BigDecimal::add); + + // Calculer la progression annuelle (basĂ©e sur le nombre de cotisations payĂ©es) + int totalCotisationsAnnee = (int) cotisations.stream() + .filter(c -> c.getDateEcheance() != null && c.getDateEcheance().getYear() == LocalDate.now().getYear()) + .count(); + progressionAnnuelle = totalCotisationsAnnee > 0 + ? (cotisationsPayees * 100) / totalCotisationsAnnee + : 0; + + peutPayer = !cotisationsImpayees.isEmpty(); + } + + private void initialiserDonneesVides() { + numeroMembre = ""; + statutCotisations = "Non renseignĂ©"; + derniereMAJ = ""; + peutPayer = false; + cotisationsPayees = 0; + cotisationsEnAttente = 0; + montantDu = BigDecimal.ZERO; + totalVerse = BigDecimal.ZERO; + progressionAnnuelle = 0; + cotisations = new ArrayList<>(); + cotisationsImpayees = new ArrayList<>(); + } + + // Actions public String voirHistoriqueComplet() { - return "/pages/membre/historique-cotisations?faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_MEMBRE_HISTORIQUE_COTISATIONS + "?faces-redirect=true"; } public void telechargerRecus() { @@ -145,8 +264,13 @@ public class MembreCotisationBean implements Serializable { } public void actualiser() { - // Actualiser les donnĂ©es - init(); + // Actualiser les donnĂ©es depuis le backend (WOU/DRY) + chargerMembre(); + chargerCotisations(); + calculerStatistiques(); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "Actualisation", + "Les donnĂ©es ont Ă©tĂ© actualisĂ©es")); } public String confirmerPaiement() { @@ -179,6 +303,12 @@ public class MembreCotisationBean implements Serializable { } // Getters et Setters + public UUID getMembreId() { return membreId; } + public void setMembreId(UUID membreId) { this.membreId = membreId; } + + public MembreDTO getMembre() { return membre; } + public void setMembre(MembreDTO membre) { this.membre = membre; } + public String getNumeroMembre() { return numeroMembre; } public void setNumeroMembre(String numeroMembre) { this.numeroMembre = numeroMembre; } @@ -353,18 +483,20 @@ public class MembreCotisationBean implements Serializable { public String getStatutSeverity() { return switch (statut) { - case "PAYE" -> "success"; + case "PAYEE", "PAYE" -> "success"; case "EN_ATTENTE" -> "warning"; case "EN_RETARD" -> "danger"; + case "PARTIELLEMENT_PAYEE" -> "info"; default -> "secondary"; }; } public String getStatutIcon() { return switch (statut) { - case "PAYE" -> "pi-check"; + case "PAYEE", "PAYE" -> "pi-check"; case "EN_ATTENTE" -> "pi-clock"; case "EN_RETARD" -> "pi-exclamation-triangle"; + case "PARTIELLEMENT_PAYEE" -> "pi-check-circle"; default -> "pi-circle"; }; } @@ -381,7 +513,9 @@ public class MembreCotisationBean implements Serializable { return switch (statut) { case "EN_RETARD" -> "En retard"; case "EN_ATTENTE" -> "À venir"; - default -> "PayĂ©e"; + case "PAYEE", "PAYE" -> "PayĂ©e"; + case "PARTIELLEMENT_PAYEE" -> "Partiellement payĂ©e"; + default -> "Non payĂ©e"; }; } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreDashboardBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreDashboardBean.java index 65d9697..e196419 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreDashboardBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreDashboardBean.java @@ -14,6 +14,10 @@ public class MembreDashboardBean implements Serializable { private static final long serialVersionUID = 1L; + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_MEMBRE_EVENEMENT = "membreEvenementPage"; + private static final String OUTCOME_MEMBRE_COTISATIONS = "membreCotisationsPage"; + // Membre actuel private Membre membre; @@ -178,7 +182,8 @@ public class MembreDashboardBean implements Serializable { } public String voirEvenement(Evenement evenement) { - return "/pages/membre/evenement?id=" + evenement.getTitre() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_MEMBRE_EVENEMENT + "?id=" + evenement.getTitre() + "&faces-redirect=true"; } public void annulerInscription(Evenement evenement) { @@ -188,7 +193,8 @@ public class MembreDashboardBean implements Serializable { } public String payerCotisations() { - return "/pages/membre/cotisations?faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_MEMBRE_COTISATIONS + "?faces-redirect=true"; } // Getters et Setters diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreInscriptionBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreInscriptionBean.java index 2de1930..9a923fb 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreInscriptionBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreInscriptionBean.java @@ -26,6 +26,10 @@ public class MembreInscriptionBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(MembreInscriptionBean.class.getName()); + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_MEMBRE_LISTE = "membreListPage"; + private static final String OUTCOME_DASHBOARD = "dashboardPage"; + @Inject @RestClient MembreService membreService; @@ -189,7 +193,7 @@ public class MembreInscriptionBean implements Serializable { "Le membre " + membreCreee.getNomComplet() + " a Ă©tĂ© inscrit avec succĂšs (N° " + membreCreee.getNumeroMembre() + ")"); context.addMessage(null, message); - return "/pages/secure/membre/liste?faces-redirect=true"; + return OUTCOME_MEMBRE_LISTE + "?faces-redirect=true"; } catch (Exception e) { LOGGER.severe("Erreur lors de l'inscription: " + e.getMessage()); @@ -238,7 +242,7 @@ public class MembreInscriptionBean implements Serializable { } public String annuler() { - return "/pages/secure/dashboard?faces-redirect=true"; + return OUTCOME_DASHBOARD + "?faces-redirect=true"; } public void handleFileUpload(org.primefaces.event.FileUploadEvent event) { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreListeBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreListeBean.java index d404bc0..a2c086b 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreListeBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreListeBean.java @@ -3,7 +3,15 @@ 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 dev.lions.unionflow.client.service.NotificationService; +import dev.lions.unionflow.client.service.CotisationService; +import dev.lions.unionflow.server.api.dto.membre.MembreSearchCriteria; +import dev.lions.unionflow.server.api.dto.organisation.OrganisationDTO; +import dev.lions.unionflow.client.dto.AssociationDTO; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.Setter; +import jakarta.faces.view.ViewScoped; import jakarta.inject.Named; import jakarta.inject.Inject; import jakarta.annotation.PostConstruct; @@ -16,11 +24,14 @@ import java.io.Serializable; import java.time.LocalDate; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.logging.Logger; @Named("membreListeBean") -@SessionScoped +@ViewScoped +@Getter +@Setter public class MembreListeBean implements Serializable { private static final long serialVersionUID = 1L; @@ -34,28 +45,25 @@ public class MembreListeBean implements Serializable { @RestClient AssociationService associationService; - // Statistiques gĂ©nĂ©rales - private int totalMembres; - private int membresActifs; - private int cotisationsAJour; - private int nouveauxMembres; - private int membresInactifs; + @Inject + @RestClient + NotificationService notificationService; - // Filtres - private String searchFilter = ""; - private String statutFilter = ""; + @Inject + @RestClient + CotisationService cotisationService; + + // Statistiques gĂ©nĂ©rales - Utilisation directe du DTO du service + @Getter(AccessLevel.NONE) @Setter(AccessLevel.NONE) + private MembreService.StatistiquesMembreDTO statistiques; + + // Filtres - Utilisation du DTO du serveur API (DRY/WOU) + @Getter(AccessLevel.NONE) @Setter(AccessLevel.NONE) + private MembreSearchCriteria searchCriteria = MembreSearchCriteria.builder().build(); + + // Filtres additionnels non couverts par MembreSearchCriteria (spĂ©cifiques Ă  l'UI) private String typeFilter = ""; private String cotisationFilter = ""; - private String entiteFilter = ""; - - // Filtres avancĂ©s - private Integer ageMin; - private Integer ageMax; - private String genreFilter = ""; - private String villeFilter = ""; - private LocalDate dateAdhesionDebut; - private LocalDate dateAdhesionFin; - private String professionFilter = ""; private Boolean desEnfants; // Messages groupĂ©s @@ -63,6 +71,12 @@ public class MembreListeBean implements Serializable { private String contenuMessage; private List canauxMessage = new ArrayList<>(); + // Contact membre + private MembreDTO membreAContacter; + private String messageContact; + private String sujetContact; + private boolean dialogContactVisible = false; + // Import/Export private boolean mettreAJourExistants = false; private String formatExport = "EXCEL"; @@ -70,25 +84,24 @@ public class MembreListeBean implements Serializable { private boolean exporterSelection = false; // DonnĂ©es + // Pas de getter Lombok car getter personnalisĂ© retourne membresFiltres + @Getter(AccessLevel.NONE) @Setter(AccessLevel.NONE) private List membres = new ArrayList<>(); private List selectedMembres = new ArrayList<>(); private List membresFiltres = new ArrayList<>(); - private List entitesDisponibles = new ArrayList<>(); + // Utilisation directe de OrganisationDTO du serveur API (DRY/WOU) + private List organisationsDisponibles = new ArrayList<>(); @PostConstruct public void init() { try { chargerMembres(); chargerStatistiques(); - chargerEntites(); + chargerOrganisations(); } catch (Exception e) { 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; - this.nouveauxMembres = 0; - this.membresInactifs = 0; + // Initialiser les statistiques Ă  null (sera gĂ©rĂ© par les getters) + this.statistiques = null; } } @@ -110,49 +123,48 @@ public class MembreListeBean implements Serializable { private void chargerStatistiques() { try { - // RĂ©cupĂ©ration des statistiques via le service REST - MembreService.StatistiquesMembreDTO stats = membreService.obtenirStatistiques(); - - this.totalMembres = stats.getTotalMembres() != null ? stats.getTotalMembres().intValue() : 0; - this.membresActifs = stats.getMembresActifs() != null ? stats.getMembresActifs().intValue() : 0; - this.membresInactifs = stats.getMembresInactifs() != null ? stats.getMembresInactifs().intValue() : 0; - this.nouveauxMembres = stats.getNouveauxMembres30Jours() != null ? stats.getNouveauxMembres30Jours().intValue() : 0; - - // Calcul approximatif des cotisations Ă  jour (Ă  implĂ©menter cĂŽtĂ© serveur) - this.cotisationsAJour = (int) (this.membresActifs * 0.85); - + // RĂ©cupĂ©ration directe du DTO de statistiques (DRY/WOU) + this.statistiques = membreService.obtenirStatistiques(); + LOGGER.info("Statistiques chargĂ©es: " + (statistiques != null ? statistiques.getTotalMembres() : 0) + " membres"); } catch (Exception e) { LOGGER.severe("Impossible de charger les statistiques: " + e.getMessage()); - // Pas de donnĂ©es mockĂ©es - laisser les valeurs Ă  zĂ©ro + this.statistiques = null; } } - private void chargerEntites() { - entitesDisponibles = new ArrayList<>(); + private void chargerOrganisations() { + organisationsDisponibles = new ArrayList<>(); try { - List associations = associationService.listerToutes(0, 1000); - for (dev.lions.unionflow.client.dto.AssociationDTO assoc : associations) { - Entite entite = new Entite(); - entite.setId(assoc.getId()); - entite.setNom(assoc.getNom()); - entitesDisponibles.add(entite); + // Utilisation directe de AssociationDTO (pas de OrganisationService disponible) + List associations = associationService.listerToutes(0, 1000); + for (AssociationDTO assoc : associations) { + // Conversion vers OrganisationDTO pour compatibilitĂ© avec MembreSearchCriteria + OrganisationDTO org = new OrganisationDTO(); + org.setId(assoc.getId()); + org.setNom(assoc.getNom()); + organisationsDisponibles.add(org); } - LOGGER.info("Chargement de " + entitesDisponibles.size() + " entitĂ©s disponibles"); + LOGGER.info("Chargement de " + organisationsDisponibles.size() + " organisations disponibles"); } catch (Exception e) { - LOGGER.severe("Erreur lors du chargement des entitĂ©s: " + e.getMessage()); + LOGGER.severe("Erreur lors du chargement des organisations: " + e.getMessage()); } } // Actions de recherche et filtrage public void rechercher() { try { + // Utilisation de MembreSearchCriteria (DRY/WOU) + searchCriteria.sanitize(); + // Si query est dĂ©fini, l'utiliser pour nom (recherche gĂ©nĂ©rale) + String nomRecherche = searchCriteria.getQuery() != null ? searchCriteria.getQuery() : searchCriteria.getNom(); List resultats = membreService.rechercher( - searchFilter.isEmpty() ? null : searchFilter, // nom - null, // prenom - null, // email - null, // telephone - statutFilter.isEmpty() ? null : statutFilter, - null, // associationId + nomRecherche, // nom (ou query si dĂ©fini) + searchCriteria.getPrenom(), // prenom + searchCriteria.getEmail(), // email + searchCriteria.getTelephone(), // telephone + searchCriteria.getStatut(), + searchCriteria.getOrganisationIds() != null && !searchCriteria.getOrganisationIds().isEmpty() + ? searchCriteria.getOrganisationIds().get(0) : null, // associationId 0, // page 100 // size ); @@ -162,24 +174,15 @@ public class MembreListeBean implements Serializable { } catch (Exception e) { 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<>(); } } public void reinitialiserFiltres() { - searchFilter = ""; - statutFilter = ""; + // RĂ©initialisation du DTO de critĂšres de recherche (DRY/WOU) + searchCriteria = MembreSearchCriteria.builder().build(); typeFilter = ""; cotisationFilter = ""; - entiteFilter = ""; - ageMin = null; - ageMax = null; - genreFilter = ""; - villeFilter = ""; - dateAdhesionDebut = null; - dateAdhesionFin = null; - professionFilter = ""; desEnfants = null; membresFiltres = new ArrayList<>(membres); @@ -188,33 +191,24 @@ public class MembreListeBean implements Serializable { public void actualiser() { chargerMembres(); chargerStatistiques(); - chargerEntites(); + chargerOrganisations(); } + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_MEMBRE_LISTE = "membreListPage"; + private static final String OUTCOME_MEMBRE_PROFIL = "membreProfilPage"; + private static final String OUTCOME_MEMBRE_MODIFIER = "membreModifierPage"; + private static final String OUTCOME_COTISATIONS = "cotisationCollectPage"; + public String modifierMembre(MembreDTO membre) { - return "/pages/secure/membre/modifier?id=" + membre.getId() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_MEMBRE_MODIFIER + "?id=" + membre.getId() + "&faces-redirect=true"; } // PropriĂ©tĂ©s pour la page de modification private UUID membreSelectionneId; private MembreDTO membreSelectionne; - public UUID getMembreSelectionneId() { - return membreSelectionneId; - } - - public void setMembreSelectionneId(UUID membreSelectionneId) { - this.membreSelectionneId = membreSelectionneId; - } - - public MembreDTO getMembreSelectionne() { - return membreSelectionne; - } - - public void setMembreSelectionne(MembreDTO membreSelectionne) { - this.membreSelectionne = membreSelectionne; - } - public void chargerMembreSelectionne() { if (membreSelectionneId != null) { try { @@ -236,7 +230,7 @@ public class MembreListeBean implements Serializable { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "SuccĂšs", "Le membre a Ă©tĂ© modifiĂ© avec succĂšs")); - return "/pages/secure/membre/liste?faces-redirect=true"; + return OUTCOME_MEMBRE_LISTE + "?faces-redirect=true"; } catch (Exception e) { LOGGER.severe("Erreur lors de la modification: " + e.getMessage()); FacesContext.getCurrentInstance().addMessage(null, @@ -246,20 +240,262 @@ public class MembreListeBean implements Serializable { } } - // MĂ©thode pour obtenir la liste des organisations pour le dropdown + // MĂ©thode pour obtenir la liste des organisations pour le dropdown (WOU/DRY) public List getOrganisationsSelectItems() { - // TODO: ImplĂ©menter la rĂ©cupĂ©ration des organisations - // Pour l'instant, retourner une liste vide - return new java.util.ArrayList<>(); + List items = new ArrayList<>(); + items.add(new jakarta.faces.model.SelectItem("", "Toutes entitĂ©s")); + for (OrganisationDTO org : organisationsDisponibles) { + items.add(new jakarta.faces.model.SelectItem(org.getId().toString(), org.getNom())); + } + return items; } public String gererCotisations(MembreDTO membre) { - return "/pages/secure/cotisations?membreId=" + membre.getId() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_COTISATIONS + "?membreId=" + membre.getId() + "&faces-redirect=true"; } public void appliquerFiltresAvances() { - // Appliquer les filtres avancĂ©s - LOGGER.info("Application des filtres avancĂ©s"); + // Appliquer les filtres avancĂ©s en utilisant MembreSearchCriteria (DRY/WOU) + searchCriteria.sanitize(); + rechercher(); + LOGGER.info("Application des filtres avancĂ©s: " + searchCriteria.getDescription()); + } + + // MĂ©thodes de complĂ©tion pour les autocomplĂ©tions (WOU/DRY - rĂ©utilisables) + public List completerVilles(String query) { + try { + // Utilisation du service REST pour obtenir les villes distinctes (WOU/DRY) + return membreService.obtenirVilles(query); + } catch (Exception e) { + LOGGER.severe("Erreur lors de la rĂ©cupĂ©ration des villes: " + e.getMessage()); + return new ArrayList<>(); + } + } + + public List completerProfessions(String query) { + try { + // Utilisation du service REST pour obtenir les professions distinctes (WOU/DRY) + return membreService.obtenirProfessions(query); + } catch (Exception e) { + LOGGER.severe("Erreur lors de la rĂ©cupĂ©ration des professions: " + e.getMessage()); + return new ArrayList<>(); + } + } + + // Actions supplĂ©mentaires pour les membres + public void suspendreMembre(MembreDTO membre) { + try { + membreService.suspendre(membre.getId()); + membre.setStatut("SUSPENDU"); + LOGGER.info("Membre suspendu: " + membre.getNomComplet()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "SuccĂšs", + "Le membre a Ă©tĂ© suspendu avec succĂšs")); + } catch (Exception e) { + LOGGER.severe("Erreur lors de la suspension: " + e.getMessage()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible de suspendre le membre: " + e.getMessage())); + } + } + + public void reactiverMembre(MembreDTO membre) { + try { + membreService.activer(membre.getId()); + membre.setStatut("ACTIF"); + LOGGER.info("Membre rĂ©activĂ©: " + membre.getNomComplet()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "SuccĂšs", + "Le membre a Ă©tĂ© rĂ©activĂ© avec succĂšs")); + } catch (Exception e) { + LOGGER.severe("Erreur lors de la rĂ©activation: " + e.getMessage()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible de rĂ©activer le membre: " + e.getMessage())); + } + } + + public void contacterMembre(MembreDTO membre) { + this.membreAContacter = membre; + this.sujetContact = ""; + this.messageContact = ""; + this.dialogContactVisible = true; + LOGGER.info("Ouverture du dialogue de contact pour: " + membre.getNomComplet()); + } + + public void envoyerMessageContact() { + if (membreAContacter == null || messageContact == null || messageContact.trim().isEmpty()) { + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention", + "Veuillez saisir un message")); + return; + } + + try { + String sujet = sujetContact != null && !sujetContact.trim().isEmpty() + ? sujetContact + : "Message depuis UnionFlow"; + + // Envoyer la notification via le service + List membreIds = List.of(membreAContacter.getId()); + List canaux = List.of("IN_APP", "EMAIL"); + + NotificationService.NotificationGroupeeRequest request = + new NotificationService.NotificationGroupeeRequest(membreIds, sujet, messageContact, canaux); + + notificationService.envoyerNotificationsGroupees(request); + + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "SuccĂšs", + "Message envoyĂ© Ă  " + membreAContacter.getNomComplet())); + + // Fermer le dialog + this.dialogContactVisible = false; + this.membreAContacter = null; + this.sujetContact = ""; + this.messageContact = ""; + } catch (Exception e) { + LOGGER.severe("Erreur lors de l'envoi du message: " + e.getMessage()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible d'envoyer le message: " + e.getMessage())); + } + } + + public void annulerContact() { + this.dialogContactVisible = false; + this.membreAContacter = null; + this.sujetContact = ""; + this.messageContact = ""; + } + + public void rappelCotisationsGroupe() { + if (selectedMembres == null || selectedMembres.isEmpty()) { + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention", + "Veuillez sĂ©lectionner au moins un membre")); + return; + } + + try { + LOGGER.info("Envoi de rappels de cotisations Ă  " + selectedMembres.size() + " membres"); + List membreIds = selectedMembres.stream() + .map(MembreDTO::getId) + .collect(java.util.stream.Collectors.toList()); + + Map result = cotisationService.envoyerRappelsGroupes(membreIds); + int rappelsEnvoyes = result != null && result.containsKey("rappelsEnvoyes") + ? result.get("rappelsEnvoyes") : membreIds.size(); + + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "SuccĂšs", + "Rappels de cotisations envoyĂ©s Ă  " + rappelsEnvoyes + " membres")); + } catch (Exception e) { + LOGGER.severe("Erreur lors de l'envoi des rappels: " + e.getMessage()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible d'envoyer les rappels: " + e.getMessage())); + } + } + + public void exporterSelection() { + if (selectedMembres == null || selectedMembres.isEmpty()) { + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention", + "Veuillez sĂ©lectionner au moins un membre")); + return; + } + + try { + LOGGER.info("Export de la sĂ©lection: " + selectedMembres.size() + " membres"); + List membreIds = selectedMembres.stream() + .map(MembreDTO::getId) + .collect(java.util.stream.Collectors.toList()); + + byte[] excelData = membreService.exporterSelection(membreIds, formatExport); + + // TĂ©lĂ©chargement du fichier Excel via JSF (WOU/DRY - rĂ©utilise la logique d'export) + 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_selection_" + + 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()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible de tĂ©lĂ©charger l'export: " + e.getMessage())); + } catch (Exception e) { + LOGGER.severe("Erreur lors de l'export: " + e.getMessage()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible d'exporter la sĂ©lection: " + e.getMessage())); + } + } + + public void envoyerMessageGroupe() { + if (selectedMembres == null || selectedMembres.isEmpty()) { + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention", + "Veuillez sĂ©lectionner au moins un membre")); + return; + } + + if (sujetMessage == null || sujetMessage.trim().isEmpty()) { + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention", + "Le sujet du message est obligatoire")); + return; + } + + if (contenuMessage == null || contenuMessage.trim().isEmpty()) { + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention", + "Le contenu du message est obligatoire")); + return; + } + + try { + LOGGER.info("Envoi de message groupĂ© Ă  " + selectedMembres.size() + " membres"); + List membreIds = selectedMembres.stream() + .map(MembreDTO::getId) + .collect(java.util.stream.Collectors.toList()); + + NotificationService.NotificationGroupeeRequest request = + new NotificationService.NotificationGroupeeRequest( + membreIds, + sujetMessage, + contenuMessage, + canauxMessage != null ? canauxMessage : new ArrayList<>() + ); + + Map result = notificationService.envoyerNotificationsGroupees(request); + int notificationsCreees = result != null && result.containsKey("notificationsCreees") + ? result.get("notificationsCreees") : membreIds.size(); + + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "SuccĂšs", + "Message envoyĂ© Ă  " + notificationsCreees + " membres")); + // RĂ©initialiser les champs + sujetMessage = null; + contenuMessage = null; + canauxMessage = new ArrayList<>(); + } catch (Exception e) { + LOGGER.severe("Erreur lors de l'envoi du message: " + e.getMessage()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible d'envoyer le message: " + e.getMessage())); + } } // Import/Export @@ -275,7 +511,8 @@ public class MembreListeBean implements Serializable { // Actions avec DTOs public String voirProfil(MembreDTO membre) { - return "/pages/secure/membre/profil?id=" + membre.getId() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_MEMBRE_PROFIL + "?id=" + membre.getId() + "&faces-redirect=true"; } public void activerMembre(MembreDTO membre) { @@ -300,7 +537,9 @@ public class MembreListeBean implements Serializable { public void exporterMembres() { try { - byte[] excelData = membreService.exporterExcel(formatExport, null, statutFilter.isEmpty() ? null : statutFilter); + byte[] excelData = membreService.exporterExcel(formatExport, null, + searchCriteria.getStatut() != null && !searchCriteria.getStatut().isEmpty() + ? searchCriteria.getStatut() : null); // TĂ©lĂ©chargement du fichier Excel via JSF FacesContext facesContext = FacesContext.getCurrentInstance(); @@ -324,103 +563,136 @@ public class MembreListeBean implements Serializable { } } - // Getters et Setters - public int getTotalMembres() { return totalMembres; } - public void setTotalMembres(int totalMembres) { this.totalMembres = totalMembres; } + // Getters et Setters pour les statistiques (compatibilitĂ© avec les pages XHTML) + public int getTotalMembres() { + return statistiques != null && statistiques.getTotalMembres() != null + ? statistiques.getTotalMembres().intValue() : 0; + } - public int getMembresActifs() { return membresActifs; } - public void setMembresActifs(int membresActifs) { this.membresActifs = membresActifs; } + public int getMembresActifs() { + return statistiques != null && statistiques.getMembresActifs() != null + ? statistiques.getMembresActifs().intValue() : 0; + } - public int getCotisationsAJour() { return cotisationsAJour; } - public void setCotisationsAJour(int cotisationsAJour) { this.cotisationsAJour = cotisationsAJour; } + public int getCotisationsAJour() { + // Calcul approximatif (Ă  implĂ©menter cĂŽtĂ© serveur) + return (int) (getMembresActifs() * 0.85); + } - public int getNouveauxMembres() { return nouveauxMembres; } - public void setNouveauxMembres(int nouveauxMembres) { this.nouveauxMembres = nouveauxMembres; } + public int getNouveauxMembres() { + return statistiques != null && statistiques.getNouveauxMembres30Jours() != null + ? statistiques.getNouveauxMembres30Jours().intValue() : 0; + } - public int getMembresInactifs() { return membresInactifs; } - public void setMembresInactifs(int membresInactifs) { this.membresInactifs = membresInactifs; } + public int getMembresInactifs() { + return statistiques != null && statistiques.getMembresInactifs() != null + ? statistiques.getMembresInactifs().intValue() : 0; + } - public String getSearchFilter() { return searchFilter; } - public void setSearchFilter(String searchFilter) { this.searchFilter = searchFilter; } + // Getters et Setters de compatibilitĂ© pour les filtres (dĂ©lĂ©gation Ă  MembreSearchCriteria) + public String getSearchFilter() { + return searchCriteria.getQuery() != null ? searchCriteria.getQuery() : ""; + } + public void setSearchFilter(String searchFilter) { + searchCriteria.setQuery(searchFilter != null && !searchFilter.isEmpty() ? searchFilter : null); + } - public String getStatutFilter() { return statutFilter; } - public void setStatutFilter(String statutFilter) { this.statutFilter = statutFilter; } + public String getStatutFilter() { + return searchCriteria.getStatut() != null ? searchCriteria.getStatut() : ""; + } + public void setStatutFilter(String statutFilter) { + searchCriteria.setStatut(statutFilter != null && !statutFilter.isEmpty() ? statutFilter : null); + } - public String getTypeFilter() { return typeFilter; } - public void setTypeFilter(String typeFilter) { this.typeFilter = typeFilter; } + // typeFilter et cotisationFilter sont gĂ©rĂ©s par Lombok @Getter @Setter - public String getCotisationFilter() { return cotisationFilter; } - public void setCotisationFilter(String cotisationFilter) { this.cotisationFilter = cotisationFilter; } + public String getEntiteFilter() { + // Retourne le premier ID d'organisation si prĂ©sent + if (searchCriteria.getOrganisationIds() != null && !searchCriteria.getOrganisationIds().isEmpty()) { + return searchCriteria.getOrganisationIds().get(0).toString(); + } + return ""; + } + public void setEntiteFilter(String entiteFilter) { + if (entiteFilter != null && !entiteFilter.isEmpty()) { + try { + UUID orgId = UUID.fromString(entiteFilter); + searchCriteria.setOrganisationIds(List.of(orgId)); + } catch (IllegalArgumentException e) { + LOGGER.warning("ID d'organisation invalide: " + entiteFilter); + } + } else { + searchCriteria.setOrganisationIds(null); + } + } - public String getEntiteFilter() { return entiteFilter; } - public void setEntiteFilter(String entiteFilter) { this.entiteFilter = entiteFilter; } + public Integer getAgeMin() { return searchCriteria.getAgeMin(); } + public void setAgeMin(Integer ageMin) { searchCriteria.setAgeMin(ageMin); } - public Integer getAgeMin() { return ageMin; } - public void setAgeMin(Integer ageMin) { this.ageMin = ageMin; } + public Integer getAgeMax() { return searchCriteria.getAgeMax(); } + public void setAgeMax(Integer ageMax) { searchCriteria.setAgeMax(ageMax); } - public Integer getAgeMax() { return ageMax; } - public void setAgeMax(Integer ageMax) { this.ageMax = ageMax; } + public String getGenreFilter() { + // MembreSearchCriteria n'a pas de champ genre, on pourrait utiliser un champ personnalisĂ© + // Pour l'instant, on retourne vide + return ""; + } + public void setGenreFilter(String genreFilter) { + // À implĂ©menter si nĂ©cessaire dans MembreSearchCriteria + } - public String getGenreFilter() { return genreFilter; } - public void setGenreFilter(String genreFilter) { this.genreFilter = genreFilter; } + public String getVilleFilter() { return searchCriteria.getVille() != null ? searchCriteria.getVille() : ""; } + public void setVilleFilter(String villeFilter) { + searchCriteria.setVille(villeFilter != null && !villeFilter.isEmpty() ? villeFilter : null); + } - public String getVilleFilter() { return villeFilter; } - public void setVilleFilter(String villeFilter) { this.villeFilter = villeFilter; } + public LocalDate getDateAdhesionDebut() { return searchCriteria.getDateAdhesionMin(); } + public void setDateAdhesionDebut(LocalDate dateAdhesionDebut) { searchCriteria.setDateAdhesionMin(dateAdhesionDebut); } - public LocalDate getDateAdhesionDebut() { return dateAdhesionDebut; } - public void setDateAdhesionDebut(LocalDate dateAdhesionDebut) { this.dateAdhesionDebut = dateAdhesionDebut; } + public LocalDate getDateAdhesionFin() { return searchCriteria.getDateAdhesionMax(); } + public void setDateAdhesionFin(LocalDate dateAdhesionFin) { searchCriteria.setDateAdhesionMax(dateAdhesionFin); } - public LocalDate getDateAdhesionFin() { return dateAdhesionFin; } - public void setDateAdhesionFin(LocalDate dateAdhesionFin) { this.dateAdhesionFin = dateAdhesionFin; } + public String getProfessionFilter() { return searchCriteria.getProfession() != null ? searchCriteria.getProfession() : ""; } + public void setProfessionFilter(String professionFilter) { + searchCriteria.setProfession(professionFilter != null && !professionFilter.isEmpty() ? professionFilter : null); + } - public String getProfessionFilter() { return professionFilter; } - public void setProfessionFilter(String professionFilter) { this.professionFilter = professionFilter; } + // desEnfants, sujetMessage, contenuMessage, canauxMessage, mettreAJourExistants, + // formatExport, colonnesExport, exporterSelection, selectedMembres, membresFiltres, + // organisationsDisponibles sont gĂ©rĂ©s par Lombok @Getter @Setter - public Boolean getDesEnfants() { return desEnfants; } - public Boolean isDesEnfants() { return desEnfants; } - public void setDesEnfants(Boolean desEnfants) { this.desEnfants = desEnfants; } - - public String getSujetMessage() { return sujetMessage; } - public void setSujetMessage(String sujetMessage) { this.sujetMessage = sujetMessage; } - - public String getContenuMessage() { return contenuMessage; } - public void setContenuMessage(String contenuMessage) { this.contenuMessage = contenuMessage; } - - public List getCanauxMessage() { return canauxMessage; } - public void setCanauxMessage(List canauxMessage) { this.canauxMessage = canauxMessage; } - - public boolean isMettreAJourExistants() { return mettreAJourExistants; } - public void setMettreAJourExistants(boolean mettreAJourExistants) { this.mettreAJourExistants = mettreAJourExistants; } - - public String getFormatExport() { return formatExport; } - public void setFormatExport(String formatExport) { this.formatExport = formatExport; } - - public List getColonnesExport() { return colonnesExport; } - public void setColonnesExport(List colonnesExport) { this.colonnesExport = colonnesExport; } - - public boolean isExporterSelection() { return exporterSelection; } - public void setExporterSelection(boolean exporterSelection) { this.exporterSelection = exporterSelection; } + // Getter pour MembreSearchCriteria (pour utilisation avancĂ©e) + public MembreSearchCriteria getSearchCriteria() { return searchCriteria; } + public void setSearchCriteria(MembreSearchCriteria searchCriteria) { this.searchCriteria = searchCriteria; } + // Getter spĂ©cial pour membres (retourne membresFiltres pour compatibilitĂ©) public List getMembres() { return membresFiltres; } public void setMembres(List membres) { this.membres = membres; } - public List getSelectedMembres() { return selectedMembres; } - public void setSelectedMembres(List selectedMembres) { this.selectedMembres = selectedMembres; } + // Getter de compatibilitĂ© pour les pages XHTML utilisant "entitesDisponibles" + // Note: liste.xhtml devrait utiliser organisationsDisponibles directement (WOU/DRY) + @Deprecated + public List getEntitesDisponibles() { + // Conversion de OrganisationDTO vers Entite pour compatibilitĂ© + List entites = new ArrayList<>(); + for (OrganisationDTO org : organisationsDisponibles) { + Entite entite = new Entite(); + entite.setId(org.getId()); + entite.setNom(org.getNom()); + entites.add(entite); + } + return entites; + } - public List getMembresFiltres() { return membresFiltres; } - public void setMembresFiltres(List membresFiltres) { this.membresFiltres = membresFiltres; } - - public List getEntitesDisponibles() { return entitesDisponibles; } - public void setEntitesDisponibles(List entitesDisponibles) { this.entitesDisponibles = entitesDisponibles; } - - // Classe interne pour les entitĂ©s + // Classe interne de compatibilitĂ© (Ă  supprimer aprĂšs mise Ă  jour de liste.xhtml) + @Deprecated public static class Entite implements Serializable { private UUID id; private String nom; + // Getters et setters explicites (Lombok peut avoir des problĂšmes avec les classes internes) public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } - public String getNom() { return nom; } public void setNom(String nom) { this.nom = nom; } } diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreProfilBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreProfilBean.java index 1cbdb84..f9df46a 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreProfilBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreProfilBean.java @@ -23,6 +23,10 @@ public class MembreProfilBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(MembreProfilBean.class.getName()); + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_MEMBRE_LISTE = "membreListPage"; + private static final String OUTCOME_MEMBRE_COTISATIONS = "membreCotisationsPage"; + @Inject @RestClient private MembreService membreService; @@ -227,7 +231,8 @@ public class MembreProfilBean implements Serializable { } public String gererCotisations() { - return "/pages/secure/membre/cotisations?id=" + membre.getId() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_MEMBRE_COTISATIONS + "?id=" + membre.getId() + "&faces-redirect=true"; } public void sauvegarderModifications() { @@ -261,7 +266,7 @@ public class MembreProfilBean implements Serializable { public String supprimer() { LOGGER.info("Membre supprimĂ©: " + membre.getNomComplet()); - return "/pages/secure/membre/liste?faces-redirect=true"; + return OUTCOME_MEMBRE_LISTE + "?faces-redirect=true"; } private void copierMembre(Membre source, Membre destination) { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreRechercheBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreRechercheBean.java index 201916b..b59edc6 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreRechercheBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/MembreRechercheBean.java @@ -23,6 +23,9 @@ public class MembreRechercheBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(MembreRechercheBean.class.getName()); + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_MEMBRE_PROFIL = "membreProfilPage"; + @Inject @RestClient private MembreService membreService; @@ -322,7 +325,8 @@ public class MembreRechercheBean implements Serializable { // Actions sur les membres public String voirProfil(Membre membre) { - return "/pages/secure/membre/profil?id=" + membre.getId() + "&faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_MEMBRE_PROFIL + "?id=" + membre.getId() + "&faces-redirect=true"; } public void contacterMembre(Membre membre) { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/RapportDetailsBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/RapportDetailsBean.java new file mode 100644 index 0000000..e130a57 --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/RapportDetailsBean.java @@ -0,0 +1,177 @@ +package dev.lions.unionflow.client.view; + +import dev.lions.unionflow.client.view.RapportsBean.HistoriqueRapport; +import jakarta.faces.view.ViewScoped; +import jakarta.inject.Inject; +import jakarta.inject.Named; +import jakarta.annotation.PostConstruct; +import jakarta.faces.context.FacesContext; +import jakarta.faces.application.FacesMessage; +import java.io.Serializable; +import java.time.LocalDate; +import java.time.format.DateTimeFormatter; +import java.util.UUID; +import java.util.logging.Logger; + +/** + * Bean pour la page de dĂ©tails d'un rapport (WOU/DRY) + * + * @author UnionFlow Team + * @version 1.0 + */ +@Named("rapportDetailsBean") +@ViewScoped +public class RapportDetailsBean implements Serializable { + + private static final long serialVersionUID = 1L; + private static final Logger LOGGER = Logger.getLogger(RapportDetailsBean.class.getName()); + private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_RAPPORTS = "rapportMembresPage"; + + @Inject + private RapportsBean rapportsBean; + + private UUID rapportId; + private HistoriqueRapport rapport; + + @PostConstruct + public void init() { + // RĂ©cupĂ©rer l'ID du rapport depuis le paramĂštre de requĂȘte + String idParam = FacesContext.getCurrentInstance() + .getExternalContext() + .getRequestParameterMap() + .get("id"); + + if (idParam != null && !idParam.isEmpty()) { + try { + rapportId = UUID.fromString(idParam); + chargerRapport(); + } catch (IllegalArgumentException e) { + LOGGER.severe("ID de rapport invalide: " + idParam); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "ID de rapport invalide")); + } + } else { + // Si pas d'ID, utiliser le rapport sĂ©lectionnĂ© depuis RapportsBean (WOU/DRY) + if (rapportsBean != null && rapportsBean.getRapportSelectionne() != null) { + rapport = rapportsBean.getRapportSelectionne(); + rapportId = rapport.getId(); + } else { + LOGGER.warning("Aucun rapport sĂ©lectionnĂ© et aucun ID fourni"); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention", + "Aucun rapport Ă  afficher")); + } + } + } + + private void chargerRapport() { + if (rapportsBean == null) { + LOGGER.severe("RapportsBean non injectĂ©"); + return; + } + + // Chercher le rapport dans la liste de RapportsBean (WOU/DRY - rĂ©utilise les donnĂ©es) + if (rapportsBean.getHistoriqueRapports() != null) { + rapport = rapportsBean.getHistoriqueRapports().stream() + .filter(r -> r.getId().equals(rapportId)) + .findFirst() + .orElse(null); + } + + if (rapport == null) { + LOGGER.warning("Rapport non trouvĂ© avec l'ID: " + rapportId); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Rapport non trouvĂ©")); + } + } + + public String retourner() { + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_RAPPORTS + "?faces-redirect=true"; + } + + public void telechargerRapport() { + if (rapport != null) { + try { + // VĂ©rifier que le rapport est disponible + if (!"GENERE".equals(rapport.getStatut())) { + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_WARN, "Attention", + "Le rapport n'est pas encore disponible au tĂ©lĂ©chargement.")); + return; + } + + LOGGER.info("TĂ©lĂ©chargement du rapport: " + rapport.getTypeLibelle() + + " (ID: " + rapport.getId() + ")"); + + // Le tĂ©lĂ©chargement sera gĂ©rĂ© par le XHTML avec p:fileDownload ou un lien direct + // vers le endpoint REST qui gĂ©nĂšre le fichier + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "TĂ©lĂ©chargement", + "Le tĂ©lĂ©chargement du rapport '" + rapport.getTypeLibelle() + "' va commencer.")); + + } catch (Exception e) { + LOGGER.severe("Erreur lors du tĂ©lĂ©chargement du rapport: " + e.getMessage()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible de tĂ©lĂ©charger le rapport. Veuillez rĂ©essayer.")); + } + } + } + + public void regenererRapport() { + if (rapport != null) { + try { + LOGGER.info("RĂ©gĂ©nĂ©ration du rapport: " + rapport.getTypeLibelle() + + " (ID: " + rapport.getId() + ")"); + + // Mettre Ă  jour le statut du rapport localement + rapport.setStatut("EN_GENERATION"); + rapport.setDateGeneration(LocalDate.now()); + + // RafraĂźchir les donnĂ©es depuis RapportsBean (WOU/DRY) + if (rapportsBean != null) { + rapportsBean.actualiser(); + // Recharger le rapport mis Ă  jour + chargerRapport(); + } + + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_INFO, "RĂ©gĂ©nĂ©ration", + "Le rapport '" + rapport.getTypeLibelle() + "' est en cours de rĂ©gĂ©nĂ©ration. " + + "Vous serez notifiĂ© une fois la gĂ©nĂ©ration terminĂ©e.")); + + } catch (Exception e) { + LOGGER.severe("Erreur lors de la rĂ©gĂ©nĂ©ration du rapport: " + e.getMessage()); + FacesContext.getCurrentInstance().addMessage(null, + new FacesMessage(FacesMessage.SEVERITY_ERROR, "Erreur", + "Impossible de rĂ©gĂ©nĂ©rer le rapport. Veuillez rĂ©essayer.")); + } + } + } + + // Getters et Setters + public UUID getRapportId() { return rapportId; } + public void setRapportId(UUID rapportId) { this.rapportId = rapportId; } + + public HistoriqueRapport getRapport() { return rapport; } + public void setRapport(HistoriqueRapport rapport) { this.rapport = rapport; } + + // MĂ©thodes utilitaires pour l'affichage + public String getDateGenerationFormatee() { + if (rapport != null && rapport.getDateGeneration() != null) { + return rapport.getDateGeneration().format(DATE_FORMATTER); + } + return ""; + } + + public boolean isRapportDisponible() { + return rapport != null && "GENERE".equals(rapport.getStatut()); + } +} + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/RapportsBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/RapportsBean.java index 3f052b4..5e403a4 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/RapportsBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/RapportsBean.java @@ -30,6 +30,9 @@ public class RapportsBean implements Serializable { private static final Logger LOGGER = Logger.getLogger(RapportsBean.class.getName()); private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("dd/MM/yyyy"); + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_RAPPORT_DETAILS = "rapportDetailsPage"; + @Inject @RestClient private AnalyticsService analyticsService; @@ -441,7 +444,8 @@ public class RapportsBean implements Serializable { public String voirRapport(HistoriqueRapport rapport) { rapportSelectionne = rapport; - return "/pages/secure/rapport/details?faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_RAPPORT_DETAILS + "?faces-redirect=true"; } public void telechargerRapport(HistoriqueRapport rapport) { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SouscriptionBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SouscriptionBean.java index 581e9f9..c27781c 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SouscriptionBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SouscriptionBean.java @@ -20,6 +20,11 @@ public class SouscriptionBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(SouscriptionBean.class.getName()); + // Constantes de navigation outcomes (WOU/DRY - rĂ©utilisables) + private static final String OUTCOME_SOUSCRIPTION_UPGRADE = "souscriptionUpgradePage"; + private static final String OUTCOME_SOUSCRIPTION_CHANGE_PLAN = "souscriptionChangePlanPage"; + private static final String OUTCOME_SOUSCRIPTION_RENEW = "souscriptionRenewPage"; + @Inject @RestClient private SouscriptionService souscriptionService; @@ -115,17 +120,20 @@ public class SouscriptionBean implements Serializable { public String upgraderFormulaire() { // Logique pour upgrader vers un formulaire supĂ©rieur - return "/pages/secure/souscription/upgrade?faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_SOUSCRIPTION_UPGRADE + "?faces-redirect=true"; } public String changerFormulaire() { // Logique pour changer de formulaire - return "/pages/secure/souscription/change-plan?faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_SOUSCRIPTION_CHANGE_PLAN + "?faces-redirect=true"; } public String renouvelerSouscription() { // Logique pour renouveler la souscription - return "/pages/secure/souscription/renew?faces-redirect=true"; + // Utilisation de navigation outcome au lieu de chemin direct (WOU/DRY) + return OUTCOME_SOUSCRIPTION_RENEW + "?faces-redirect=true"; } public void activerNotificationQuota(boolean activer) { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SuperAdminBean.java b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SuperAdminBean.java index 83ead74..5dcaac8 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SuperAdminBean.java +++ b/unionflow-client-quarkus-primefaces-freya/src/main/java/dev/lions/unionflow/client/view/SuperAdminBean.java @@ -24,6 +24,14 @@ public class SuperAdminBean implements Serializable { private static final long serialVersionUID = 1L; private static final Logger LOGGER = Logger.getLogger(SuperAdminBean.class.getName()); + // 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_SUPER_ADMIN_RAPPORTS = "superAdminRapportsPage"; + private static final String OUTCOME_SUPER_ADMIN_CONFIGURATION = "superAdminConfigurationPage"; + private static final String OUTCOME_SUPER_ADMIN_ALERTES = "superAdminAlertesPage"; + private static final String OUTCOME_SUPER_ADMIN_ACTIVITE = "superAdminActivitePage"; + @Inject @RestClient private AssociationService associationService; @@ -333,21 +341,21 @@ public class SuperAdminBean implements Serializable { revenus.setEvolution(evolution); } - // Actions + // Actions (WOU/DRY - utilisation de navigation outcomes) public String creerEntite() { - return "/pages/super-admin/entites/nouvelle?faces-redirect=true"; + return OUTCOME_ENTITE_NOUVELLE + "?faces-redirect=true"; } public String gererEntites() { - return "/pages/super-admin/entites/gestion?faces-redirect=true"; + return OUTCOME_ENTITE_GESTION + "?faces-redirect=true"; } public String genererRapport() { - return "/pages/super-admin/rapports?faces-redirect=true"; + return OUTCOME_SUPER_ADMIN_RAPPORTS + "?faces-redirect=true"; } public String configurer() { - return "/pages/super-admin/configuration?faces-redirect=true"; + return OUTCOME_SUPER_ADMIN_CONFIGURATION + "?faces-redirect=true"; } public void voirAlerte(Alerte alerte) { @@ -355,11 +363,11 @@ public class SuperAdminBean implements Serializable { } public String voirToutesAlertes() { - return "/pages/super-admin/alertes?faces-redirect=true"; + return OUTCOME_SUPER_ADMIN_ALERTES + "?faces-redirect=true"; } public String voirTouteActivite() { - return "/pages/super-admin/activite?faces-redirect=true"; + return OUTCOME_SUPER_ADMIN_ACTIVITE + "?faces-redirect=true"; } public void exporterRapportFinancier() { diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/faces-config.xml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/faces-config.xml index a361782..15a0ab6 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/faces-config.xml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/faces-config.xml @@ -5,6 +5,14 @@ https://jakarta.ee/xml/ns/jakartaee/web-facesconfig_4_0.xsd" version="4.0"> + UnionFlow + + + + omnifaces + + + dev.lions.unionflow.client.exception.ViewExpiredExceptionHandlerFactory @@ -19,4 +27,627 @@ - \ No newline at end of file + + * + + + + Page d'accueil / Dashboard + dashboardPage + /pages/secure/dashboard.xhtml + + + + + + Page de liste des membres + membreListPage + /pages/secure/membre/liste.xhtml + + + + + Page d'inscription de membre + membreInscriptionPage + /pages/secure/membre/inscription.xhtml + + + + + Page de profil de membre + membreProfilPage + /pages/secure/membre/profil.xhtml + + + + + Page de recherche de membre + membreRecherchePage + /pages/secure/membre/recherche.xhtml + + + + + Page de modification de membre + membreModifierPage + /pages/secure/membre/inscription.xhtml + + + + + Page de cotisations d'un membre + membreCotisationsPage + /pages/secure/membre/cotisations.xhtml + + + + + + Page de liste des organisations + organisationListPage + /pages/secure/organisation/liste.xhtml + + + + + Page de crĂ©ation d'organisation + organisationNouvellePage + /pages/secure/organisation/nouvelle.xhtml + + + + + Page de dĂ©tail d'organisation + organisationDetailPage + /pages/secure/organisation/detail.xhtml + + + + + + Page de gestion des Ă©vĂ©nements + evenementGestionPage + /pages/secure/evenement/gestion.xhtml + + + + + Page de crĂ©ation d'Ă©vĂ©nement + evenementCreationPage + /pages/secure/evenement/creation.xhtml + + + + + Page de planification d'Ă©vĂ©nement + evenementPlanificationPage + /pages/secure/evenement/planification.xhtml + + + + + Page de logistique d'Ă©vĂ©nement + evenementLogistiquePage + /pages/secure/evenement/logistique.xhtml + + + + + Page de bilan d'Ă©vĂ©nement + evenementBilanPage + /pages/secure/evenement/bilan.xhtml + + + + + Page de rĂ©servations d'Ă©vĂ©nement + evenementReservationsPage + /pages/secure/evenement/reservations.xhtml + + + + + Page de calendrier d'Ă©vĂ©nements + evenementCalendrierPage + /pages/secure/evenement/calendrier.xhtml + + + + + Page de participants d'Ă©vĂ©nement + evenementParticipantsPage + /pages/secure/evenement/participants.xhtml + + + + + Page de participation Ă  un Ă©vĂ©nement + evenementParticipationPage + /pages/secure/evenement/participation.xhtml + + + + + + Page de collecte de cotisations + cotisationCollectPage + /pages/secure/cotisation/collect.xhtml + + + + + Page de paiement de cotisation + cotisationPaiementPage + /pages/secure/cotisation/paiement.xhtml + + + + + Page d'historique des cotisations + cotisationHistoriquePage + /pages/secure/cotisation/historique.xhtml + + + + + Page de rappels de cotisations + cotisationRelancesPage + /pages/secure/cotisation/relances.xhtml + + + + + Page de rapports de cotisations + cotisationRapportsPage + /pages/secure/cotisation/rapports.xhtml + + + + + + Page de liste des adhĂ©sions + adhesionListPage + /pages/secure/adhesion/liste.xhtml + + + + + Page de nouvelle adhĂ©sion + adhesionNouvellePage + /pages/secure/adhesion/new.xhtml + + + + + Page de demande d'adhĂ©sion + adhesionDemandePage + /pages/secure/adhesion/demande.xhtml + + + + + Page de validation d'adhĂ©sion + adhesionValidationPage + /pages/secure/adhesion/validation.xhtml + + + + + Page de paiement d'adhĂ©sion + adhesionPaiementPage + /pages/secure/adhesion/paiement.xhtml + + + + + Page de renouvellement d'adhĂ©sion + adhesionRenouvellementPage + /pages/secure/adhesion/renouvellement.xhtml + + + + + Page d'historique des adhĂ©sions + adhesionHistoriquePage + /pages/secure/adhesion/history.xhtml + + + + + Page d'adhĂ©sions en attente + adhesionPendingPage + /pages/secure/adhesion/pending.xhtml + + + + + + Page de demande d'aide + aideDemandePage + /pages/secure/aide/demande.xhtml + + + + + Page de traitement des demandes d'aide + aideTraitementPage + /pages/secure/aide/traitement.xhtml + + + + + Page d'historique des demandes d'aide + aideHistoriquePage + /pages/secure/aide/historique.xhtml + + + + + Page de FAQ + aideFaqPage + /pages/secure/aide/faq.xhtml + + + + + Page de documentation + aideDocumentationPage + /pages/secure/aide/documentation.xhtml + + + + + Page de guide + aideGuidePage + /pages/secure/aide/guide.xhtml + + + + + Page de tutoriels + aideTutorielsPage + /pages/secure/aide/tutoriels.xhtml + + + + + Page de support + aideSupportPage + /pages/secure/aide/support.xhtml + + + + + Page de tickets + aideTicketsPage + /pages/secure/aide/tickets.xhtml + + + + + Page de statistiques d'aide + aideStatistiquesPage + /pages/secure/aide/statistiques.xhtml + + + + + + Page de rapports de membres + rapportMembresPage + /pages/secure/rapport/membres.xhtml + + + + + Page de rapports financiers + rapportFinancesPage + /pages/secure/rapport/finances.xhtml + + + + + Page de rapports d'activitĂ©s + rapportActivitesPage + /pages/secure/rapport/activites.xhtml + + + + + Page d'export de rapports + rapportExportPage + /pages/secure/rapport/export.xhtml + + + + + Page de dĂ©tails d'un rapport + rapportDetailsPage + /pages/secure/rapport/details.xhtml + + + + + + Page de profil personnel + personnelProfilPage + /pages/secure/personnel/profil.xhtml + + + + + Page de notifications personnelles + personnelNotificationsPage + /pages/secure/personnel/notifications.xhtml + + + + + Page de documents personnels + personnelDocumentsPage + /pages/secure/personnel/documents.xhtml + + + + + Page d'agenda personnel + personnelAgendaPage + /pages/secure/personnel/agenda.xhtml + + + + + Page d'activitĂ©s personnelles + personnelActivitesPage + /pages/secure/personnel/activites.xhtml + + + + + Page de favoris personnels + personnelFavorisPage + /pages/secure/personnel/favoris.xhtml + + + + + Page de paramĂštres personnels + personnelParametresPage + /pages/secure/personnel/parametres.xhtml + + + + + Page de prĂ©fĂ©rences personnelles + personnelPreferencesPage + /pages/secure/personnel/preferences.xhtml + + + + + + Page de gestion des utilisateurs + adminUtilisateursPage + /pages/secure/admin/utilisateurs.xhtml + + + + + Page de gestion des rĂŽles + adminRolesPage + /pages/secure/admin/roles.xhtml + + + + + Page de paramĂštres d'administration + adminParametresPage + /pages/secure/admin/parametres.xhtml + + + + + Page d'audit + adminAuditPage + /pages/secure/admin/audit.xhtml + + + + + Page de sauvegarde + adminSauvegardePage + /pages/secure/admin/sauvegarde.xhtml + + + + + + Page de dashboard de souscription + souscriptionDashboardPage + /pages/secure/souscription/dashboard.xhtml + + + + + Page d'upgrade de souscription + souscriptionUpgradePage + /pages/secure/souscription/upgrade.xhtml + + + + + Page de changement de plan de souscription + souscriptionChangePlanPage + /pages/secure/souscription/change-plan.xhtml + + + + + Page de renouvellement de souscription + souscriptionRenewPage + /pages/secure/souscription/renew.xhtml + + + + + + Page de logs systĂšme (Super Admin) + superAdminLogsPage + /pages/super-admin/logs.xhtml + + + + + Page de crĂ©ation d'entitĂ© (Super Admin) + entiteNouvellePage + /pages/super-admin/entites/nouvelle.xhtml + + + + + Page de gestion des entitĂ©s (Super Admin) + entiteGestionPage + /pages/super-admin/entites/gestion.xhtml + + + + + Page de rapports (Super Admin) + superAdminRapportsPage + /pages/super-admin/rapports.xhtml + + + + + Page de configuration (Super Admin) + superAdminConfigurationPage + /pages/super-admin/configuration.xhtml + + + + + Page d'alertes (Super Admin) + superAdminAlertesPage + /pages/super-admin/alertes.xhtml + + + + + Page d'activitĂ© (Super Admin) + superAdminActivitePage + /pages/super-admin/activite.xhtml + + + + + Page de dĂ©tails d'entitĂ© + entiteDetailsPage + /pages/super-admin/entites/details.xhtml + + + + + Page de gestion des membres (Admin) + adminMembresGestionPage + /pages/admin/membres/gestion.xhtml + + + + + 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 d'historique des demandes d'aide + demandesHistoriquePage + /pages/admin/demandes/historique.xhtml + + + + + + Page de checkout de souscription + souscriptionCheckoutPage + /pages/secure/souscription/checkout.xhtml + + + + + Page de dĂ©tails de formulaire + formulaireDetailsPage + /pages/public/formulaires/details.xhtml + + + + + + Page d'historique des versions de documents + documentsVersionsPage + /pages/admin/documents/versions.xhtml + + + + + + Page d'Ă©vĂ©nement (Membre) + membreEvenementPage + /pages/membre/evenement.xhtml + + + + + Page de cotisations (Membre) + membreCotisationsPage + /pages/membre/cotisations.xhtml + + + + + Page d'historique des cotisations (Membre) + membreHistoriqueCotisationsPage + /pages/membre/historique-cotisations.xhtml + + + + + + Page de profil + profilePage + /pages/secure/profile.xhtml + + + + + Page d'accĂšs refusĂ© + accessDeniedPage + /pages/secure/access-denied.xhtml + + + + + Page de statistiques + statsPage + /pages/secure/stats.xhtml + + + + + Page de rapports + reportsPage + /pages/secure/reports.xhtml + + + + + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/creation.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/creation.xhtml index ec14ddf..2bce369 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/creation.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/creation.xhtml @@ -104,7 +104,7 @@
- + @@ -476,7 +476,7 @@

#{creationEvenementBean.evenement.titre}

-
#{creationEvenementBean.evenement.type}
+
#{creationEvenementBean.evenement.typeEvenementLibelle}
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/gestion.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/gestion.xhtml index 5c9b314..419891d 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/gestion.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/gestion.xhtml @@ -342,7 +342,7 @@
- +
#{evenement.titre}
@@ -351,10 +351,10 @@
- - + @@ -465,7 +465,7 @@
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/liste.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/liste.xhtml index 006ad3f..451209e 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/liste.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/admin/evenements/liste.xhtml @@ -221,7 +221,7 @@
#{evenement.titre}
- #{evenement.type} + #{evenement.typeEvenementLibelle}
@@ -354,7 +354,7 @@
-
#{evenementBean.evenementSelectionne.type}
+
#{evenementBean.evenementSelectionne.typeEvenementLibelle}
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/demande.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/demande.xhtml index 31aaef8..c26ad11 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/demande.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/demande.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Demande d'Adhésion - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/history.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/history.xhtml index 679942d..7f9b7d9 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/history.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/history.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Historique des Adhésions - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/liste.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/liste.xhtml index f3cf265..cce0128 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/liste.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/liste.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Liste des Adhésions - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/new.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/new.xhtml index ed33109..0818944 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/new.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/new.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Nouvelle Adhésion - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/paiement.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/paiement.xhtml index 881cf4a..877a5b8 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/paiement.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/paiement.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Paiement des Adhésions - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/pending.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/pending.xhtml index 8bee521..c636f15 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/pending.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/pending.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Adhésions en Attente - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/renouvellement.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/renouvellement.xhtml index 5099b71..56e5300 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/renouvellement.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/renouvellement.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Renouvellement d'Adhésion - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/validation.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/validation.xhtml index b886149..9036a70 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/validation.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/adhesion/validation.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Validation des Adhésions - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/audit.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/audit.xhtml index 5c01b86..ab639ce 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/audit.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/audit.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Journal d'Audit - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/parametres.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/parametres.xhtml index c29edc4..86659e3 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/parametres.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/parametres.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + ParamÚtres SystÚme - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/roles.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/roles.xhtml index b370c78..fc3e64c 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/roles.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/roles.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Gestion des RÎles - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/sauvegarde.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/sauvegarde.xhtml index 6bb5a30..a41a978 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/sauvegarde.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/sauvegarde.xhtml @@ -6,39 +6,117 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Sauvegarde et Restauration - UnionFlow - - - - - - - -
- - - - + + + + +
+
+
+

+ + Sauvegarde et Restauration +

+

+ Gérez les sauvegardes et restaurez la base de données +

- - - - - -
-
- -
Sauvegarde et Restauration
-

- La fonctionnalité de sauvegarde et restauration sera disponible prochainement. -

-

- Elle permettra de créer des sauvegardes de la base de données et de restaurer des sauvegardes précédentes. -

+
+ +
+
-
- + +
+
État du Systùme
+
+
+
+
DerniĂšre sauvegarde
+
#{configurationBean.derniereSauvegarde}
+
+
+
+
+
Fréquence
+
#{configurationBean.frequenceSauvegarde}
+
+
+
+
+
Rétention
+
#{configurationBean.retentionSauvegardes} jours
+
+
+
+
+
Temps d'activité
+
#{configurationBean.tempsActivite}
+
+
+
+
+ + +
+
Sauvegardes Disponibles
+ + + + + + + + + + +
#{sauvegarde.taille}
+
+ + + + + + + + + + +
+ + + +
+
+
+
+ + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/utilisateurs.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/utilisateurs.xhtml index 1966e10..f313a98 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/utilisateurs.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/admin/utilisateurs.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Gestion des Utilisateurs - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/approved.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/approved.xhtml index 6ac33e3..0216989 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/approved.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/approved.xhtml @@ -5,16 +5,69 @@ xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> - UnionFlow - Approved + + Demandes d'Aide Approuvées - UnionFlow -
-
-
-

Approved - Aide

-

Page en cours de développement...

- + + + + +
+
+
+

+ + Demandes d'Aide Approuvées +

+

+ Liste des demandes d'aide approuvées et en cours de traitement +

+
-
+ + +
+
Demandes Approuvées
+ + + + +
+
#{demande.demandeur}
+ #{demande.telephone} +
+
+ + + + + + +
#{demande.montantAccorde} FCFA
+
+ + + + + + + + + + +
+
+ diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/apropos.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/apropos.xhtml index 89a4deb..dd3c4df 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/apropos.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/apropos.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + À Propos d'UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/demande.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/demande.xhtml index 887ceae..b842b4d 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/demande.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/demande.xhtml @@ -1,3 +1,4 @@ + - PAGE_TITLE - UnionFlow + + Demande d'Aide - UnionFlow -
-
PAGE_TITLE
-

Cette page est en cours de développement.

-
- -

Fonctionnalité en développement

-
-
-
+ + + +
+
+
+

+ + Nouvelle Demande d'Aide +

+

+ Soumettez une demande d'aide pour vous ou un membre de votre organisation +

+
+
+
+ + +
+
Informations de la Demande
+ +
+
+
+ + + + + + + + + +
+
+ +
+
+ + + + + + + + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+ +
+
+ + +
+
+
+ +
+ + + + + + +
+
+
+ + + +
+ +

Votre demande a été soumise avec succÚs

+

Elle sera traitée dans les plus brefs délais.

+
+ +
+
+
+
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/documentation.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/documentation.xhtml index 9f6f032..539746f 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/documentation.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/documentation.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Documentation ComplÚte - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/faq.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/faq.xhtml index 660a9a1..109f0f3 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/faq.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/faq.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Questions Fréquentes - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/guide.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/guide.xhtml index 7881bfe..843f7b5 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/guide.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/guide.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Guide Utilisateur - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/historique.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/historique.xhtml index 887ceae..c3b0e7c 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/historique.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/historique.xhtml @@ -1,3 +1,4 @@ + - PAGE_TITLE - UnionFlow + + Historique des Demandes d'Aide - UnionFlow -
-
PAGE_TITLE
-

Cette page est en cours de développement.

-
- -

Fonctionnalité en développement

-
-
+ + + +
-
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/history.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/history.xhtml index 8163f93..d64fa6e 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/history.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/history.xhtml @@ -5,16 +5,128 @@ xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> - UnionFlow - History + + Historique des Demandes d'Aide - UnionFlow -
-
-
-

History - Aide

-

Page en cours de développement...

- + + + + +
+
+
+

+ + Historique des Demandes d'Aide +

+

+ Consultez l'historique complet de toutes les demandes d'aide +

+
-
+ + +
+
Filtres
+
+
+ + + + + + + + +
+
+ + + + + + + + +
+
+ + + + +
+
+ + + + +
+
+
+ + +
+
+ + +
+
Historique Complet
+ + + + +
+
#{demande.demandeur}
+ #{demande.localisation} +
+
+ + + + + + +
#{demande.montantDemande} FCFA
+
+ + + + + + + + + + + + + + +
+
+ diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/nouveautes.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/nouveautes.xhtml index 6ccfd66..ef3354d 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/nouveautes.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/nouveautes.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Nouveautés - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/requests.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/requests.xhtml index 69091b1..3010b28 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/requests.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/requests.xhtml @@ -5,16 +5,75 @@ xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> - UnionFlow - Requests + + Mes Demandes d'Aide - UnionFlow -
-
-
-

Requests - Aide

-

Page en cours de développement...

- + + + + +
+
+
+

+ + Mes Demandes d'Aide +

+

+ Consultez l'état de vos demandes d'aide +

+
+
+ + + + + +
-
+ + +
+
Historique de mes Demandes
+ + + + + + + + +
#{demande.montantDemande} FCFA
+
+ + + + + + + + + + + + + + +
+
+ diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/statistiques.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/statistiques.xhtml index 887ceae..4b071db 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/statistiques.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/statistiques.xhtml @@ -1,3 +1,4 @@ + - PAGE_TITLE - UnionFlow + + Statistiques des Demandes d'Aide - UnionFlow -
-
PAGE_TITLE
-

Cette page est en cours de développement.

-
- -

Fonctionnalité en développement

-
-
-
+ + + +
+
+
+

+ + Statistiques des Demandes d'Aide +

+

+ Analyse et statistiques détaillées des demandes d'aide +

+
+
+ +
+
+
+ + +
+
+
+
+
+
#{demandesAideBean.statistiques.totalDemandes}
+
Total Demandes
+
+
+ +
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.demandesEnAttente}
+
En Attente
+
+
+ +
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.demandesApprouvees}
+
Approuvées
+
+
+ +
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.montantTotalAide}
+
Montant Total
+
+
+ +
+
+
+
+
+ + +
+
Répartition par Type d'Aide
+
+
+
+ +

Graphique de répartition par type

+ À implĂ©menter avec PrimeNG Charts +
+
+
+
+ +

Graphique de répartition par statut

+ À implĂ©menter avec PrimeNG Charts +
+
+
+
+
+
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/suggestions.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/suggestions.xhtml index 84a94cc..c5c466b 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/suggestions.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/suggestions.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Suggestions et Feedback - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/support.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/support.xhtml index e550d7d..4dd77c1 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/support.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/support.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Contacter le Support - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/tickets.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/tickets.xhtml index 8f9278c..857c56a 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/tickets.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/tickets.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Mes Tickets Support - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/traitement.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/traitement.xhtml index 887ceae..31ed55b 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/traitement.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/traitement.xhtml @@ -1,3 +1,4 @@ + - PAGE_TITLE - UnionFlow + + Traitement des Demandes d'Aide - UnionFlow -
-
PAGE_TITLE
-

Cette page est en cours de développement.

-
- -

Fonctionnalité en développement

-
-
-
+ + + +
+
+
+

+ + Traitement des Demandes d'Aide +

+

+ Gérez et traitez les demandes d'aide des membres +

+
+
+ +
+
+
+ + +
+
+
+
+
+
#{demandesAideBean.statistiques.totalDemandes}
+
Total Demandes
+
+
+ +
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.demandesEnAttente}
+
En Attente
+
+
+ +
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.demandesApprouvees}
+
Approuvées
+
+
+ +
+
+
+
+
+
+
+
+
#{demandesAideBean.statistiques.demandesRejetees}
+
Rejetées
+
+
+ +
+
+
+
+
+ + +
+
Demandes Ă  Traiter
+ + + + +
+
#{demande.demandeur}
+ #{demande.telephone} +
+
+ + + + + + +
#{demande.montantDemande} FCFA
+
+ + + + + + + + + + + + +
+ + + +
+
+
+
+
+
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/tutoriels.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/tutoriels.xhtml index 44a1ab1..d71cb43 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/tutoriels.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/aide/tutoriels.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Tutoriels Vidéo - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/historique.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/historique.xhtml index fdf218b..803ef5b 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/historique.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/historique.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Historique des Cotisations - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/paiement.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/paiement.xhtml index cec8511..fd68b8d 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/paiement.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/paiement.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Paiement de Cotisations - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/rapports.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/rapports.xhtml index 8a02683..924ebe9 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/rapports.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/rapports.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Rapports Financiers - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/relances.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/relances.xhtml index 7ba0666..7f6bcd4 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/relances.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/relances.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Relances de Cotisations - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/reminders.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/reminders.xhtml index 5a3eb26..1241bde 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/reminders.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/reminders.xhtml @@ -5,16 +5,104 @@ xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> - UnionFlow - Reminders + + Rappels de Cotisations - UnionFlow -
-
-
-

Reminders - Cotisation

-

Page en cours de développement...

- + + + + +
+
+
+

+ + Rappels de Cotisations +

+

+ Gérez et envoyez les rappels de cotisations aux membres +

+
+
+ +
-
+ + +
+
+
+
+
+
#{cotisationsGestionBean.nombreMembresEnRetard}
+
En Retard
+
+
+ +
+
+
+
+
+
+
+
+
#{cotisationsGestionBean.nombreRappelsEnvoyes}
+
Rappels Envoyés
+
+
+ +
+
+
+
+
+ + +
+
Membres avec Cotisations en Retard
+ + + + + + +
+
#{membre.nomComplet}
+ #{membre.numeroMembre} +
+
+ + +
#{membre.montantDu} FCFA
+
+ + + + + + + + +
+
+ diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/report.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/report.xhtml index ba378ed..1e86f0a 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/report.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/cotisation/report.xhtml @@ -5,16 +5,113 @@ xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> - UnionFlow - Report + + Rapports de Cotisations - UnionFlow -
-
-
-

Report - Cotisation

-

Page en cours de développement...

- + + + + +
+
+
+

+ + Rapports de Cotisations +

+

+ Générez et consultez les rapports détaillés sur les cotisations +

+
+
+ +
-
+ + +
+
ParamĂštres du Rapport
+
+
+ + + + + + + +
+
+ + + + + + +
+
+ + + + + + +
+
+
+ + +
+
Rapports Disponibles
+
+
+
+
+ +
+
Rapport Mensuel
+ Rapport complet du mois +
+
+ +
+
+
+
+
+ +
+
Rapport Annuel
+ SynthÚse de l'année +
+
+ +
+
+
+
+
+ +
+
Rapport Analytique
+ Analyses et statistiques +
+
+ +
+
+
+
+ diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/calendar.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/calendar.xhtml index 02917e9..83a9abd 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/calendar.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/calendar.xhtml @@ -5,16 +5,14 @@ xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> - UnionFlow - Calendar + + Calendrier des ÉvĂ©nements - UnionFlow -
-
-
-

Calendar - Evenement

-

Page en cours de développement...

- -
-
-
+ + + +
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/calendrier.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/calendrier.xhtml index e704dbe..1bb5e99 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/calendrier.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/calendrier.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Calendrier des ÉvĂ©nements - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/create.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/create.xhtml index 4bfe71d..49bab80 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/create.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/create.xhtml @@ -5,16 +5,14 @@ xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> - UnionFlow - Create + + CrĂ©er un ÉvĂ©nement - UnionFlow -
-
-
-

Create - Evenement

-

Page en cours de développement...

- -
-
-
+ + + +
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/gestion.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/gestion.xhtml index c74f0e8..a7922fb 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/gestion.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/gestion.xhtml @@ -256,7 +256,8 @@ widgetVar="dlgNouvelEvenement" modal="true" resizable="false" - style="width: 90vw; max-width: 800px;"> + style="width: 90vw; max-width: 800px;" + rendered="#{evenementsBean.nouvelEvenement != null}">
@@ -369,7 +370,7 @@ -
+
+ Gestion des Participants - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/participation.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/participation.xhtml index 12afa8d..cbe8671 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/participation.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/evenement/participation.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Participation aux ÉvĂ©nements - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/cotisations.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/cotisations.xhtml new file mode 100644 index 0000000..a6b28ed --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/cotisations.xhtml @@ -0,0 +1,212 @@ + + + + + + + + + + Cotisations du Membre - UnionFlow + + + + + + +
+
+
+

+ + Cotisations du Membre +

+

+ Membre: #{membreCotisationBean.numeroMembre} ‱ + Statut: #{membreCotisationBean.statutCotisations} +

+
+
+ + + + + +
+
+
+ + +
+
+
+
+
+
#{membreCotisationBean.cotisationsPayees}
+
Payées
+
+
+ +
+
+
+
+
+
+
+
+
#{membreCotisationBean.cotisationsEnAttente}
+
En Attente
+
+
+ +
+
+
+
+
+
+
+
+
#{membreCotisationBean.montantDu}
+
Montant DĂ»
+
+
+ +
+
+
+
+
+
+
+
+
#{membreCotisationBean.totalVerse}
+
Total Versé
+
+
+ +
+
+
+
+
+ + +
+
Historique des Cotisations
+ + + + +
+ + + + + + + + + + + + + + + +
+
+ + + +
+ + + + + + + + + +
+
#{cotisation.libelle}
+ #{cotisation.periode} +
+
+ + + + + + +
+
#{cotisation.montant}
+ FCFA +
+
+ + + + + + +
+
#{cotisation.dateEcheance}
+ #{cotisation.statutEcheance} +
+
+ + + + + + Non payée + + + +
+ + +
+
+
+
+
+
+
+ diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml index b70b104..aeea54f 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/liste.xhtml @@ -41,11 +41,12 @@
Tous les Membres
- + +
@@ -60,77 +61,98 @@
+ +
-
- - + + + + + + + - -
+ +
+ +
-
- - + + + + + + + - -
+ +
+ +
-
- - + + + + + + + - -
+ +
+ +
-
- - + + + + + + + - -
+ +
-
+ +
- - + + + + + + +
-
+ + +
-
+ + +
- + + + + + + +
@@ -198,8 +224,8 @@ + severity="#{membre.typeSeverity != null ? membre.typeSeverity : 'info'}" + icon="pi #{membre.typeIcon != null ? membre.typeIcon : 'pi-user'}" /> @@ -208,13 +234,13 @@ icon="pi #{membre.statutIcon}" /> - - + +
-
#{membre.dateAdhesion}
+
#{membre.dateAdhesion != null ? membre.dateAdhesion : 'Non renseigné'}
#{membre.anciennete}
@@ -252,6 +278,8 @@ + + @@ -553,6 +581,73 @@
+ + + + +
+
+
+
+
+ +
+
+
#{membreListeBean.membreAContacter.nomComplet}
+
#{membreListeBean.membreAContacter.email != null ? membreListeBean.membreAContacter.email : 'Email non renseigné'}
+
#{membreListeBean.membreAContacter.telephone != null ? membreListeBean.membreAContacter.telephone : 'Téléphone non renseigné'}
+
+
+
+
+ +
+ + + + + + +
+ +
+ + + + + + + + +
+
+ + +
+ + + + + + + + + + + + + + +
+
+
+
\ No newline at end of file diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/profil.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/profil.xhtml index a4fb5ca..dcc85da 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/profil.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/membre/profil.xhtml @@ -340,8 +340,8 @@
ÉvĂ©nements rĂ©cents
-
- +
+
#{evenement.titre}
diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/activites.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/activites.xhtml index dbe9d93..247aa0e 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/activites.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/activites.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Mes Activités - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/agenda.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/agenda.xhtml index e8e0823..db4e112 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/agenda.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/agenda.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Mon Agenda - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/documents.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/documents.xhtml index 97dc726..e4a180d 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/documents.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/documents.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Mes Documents - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/favoris.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/favoris.xhtml index fb950f1..0ac594a 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/favoris.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/favoris.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Mes Favoris - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/notifications.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/notifications.xhtml index 1962f2e..c24d29c 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/notifications.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/notifications.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Mes Notifications - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/parametres.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/parametres.xhtml index cad17f3..64bf553 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/parametres.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/parametres.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + ParamÚtres Compte - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/preferences.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/preferences.xhtml index 7ff2154..12c23b4 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/preferences.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/preferences.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Mes Préférences - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/profil.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/profil.xhtml index af5d410..11b6b16 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/profil.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/personnel/profil.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Mon Profil - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/activites.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/activites.xhtml index d85176d..611ee29 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/activites.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/activites.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Rapports Activités - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/details.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/details.xhtml new file mode 100644 index 0000000..7a9f84f --- /dev/null +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/details.xhtml @@ -0,0 +1,145 @@ + + + + + Détails du Rapport - UnionFlow + + + + + + +
+
+
+
+ +
+
+

#{rapportDetailsBean.rapport.typeLibelle}

+
+ + Généré le #{rapportDetailsBean.dateGenerationFormatee} +
+
+
+
+ + + + + + + +
+
+
+ + +
+ +
+
+
Informations Générales
+ + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+
Résumé
+
+

+ Ce rapport contient les données analytiques et statistiques + pour la période sélectionnée. Les informations détaillées + sont disponibles dans le fichier téléchargeable. +

+
+
+
+
+ + +
+
Actions
+
+ + + + +
+
+
+ + + +
+
+ +

Rapport introuvable

+

Le rapport demandé n'a pas été trouvé.

+ + + + + +
+
+
+
+
+
+ diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/export.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/export.xhtml index 617eb76..b2d7bb6 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/export.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/export.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Export de Rapports - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/finances.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/finances.xhtml index d387013..2880ee1 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/finances.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/finances.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Rapports Financiers - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/membres.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/membres.xhtml index 1caaa88..8bb0f35 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/membres.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/rapport/membres.xhtml @@ -6,6 +6,7 @@ xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> + Rapports Membres - UnionFlow diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/stats.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/stats.xhtml index ef01cab..cedb565 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/stats.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/pages/secure/stats.xhtml @@ -5,22 +5,14 @@ xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui" template="/templates/main-template.xhtml"> - - UnionFlow - Statistiques - + + Statistiques - UnionFlow -
-
-
-

Statistiques

-

Page en cours de développement...

- - -
-
-
+ + + +
- - \ No newline at end of file + diff --git a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/buttons/button-secondary.xhtml b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/buttons/button-secondary.xhtml index 6fe4102..71b9731 100644 --- a/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/buttons/button-secondary.xhtml +++ b/unionflow-client-quarkus-primefaces-freya/src/main/resources/META-INF/resources/templates/components/buttons/button-secondary.xhtml @@ -24,6 +24,7 @@ + + + + + --> @@ -26,15 +31,20 @@ disabled="#{not empty readonly and readonly}" styleClass="w-full"> - - - - - - + + + + + + + + + + +
diff --git a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/entity/TransactionWave.java b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/entity/TransactionWave.java index 4ec7da7..0c7573f 100644 --- a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/entity/TransactionWave.java +++ b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/entity/TransactionWave.java @@ -29,8 +29,7 @@ import lombok.NoArgsConstructor; @Index(name = "idx_transaction_wave_request_id", columnList = "wave_request_id"), @Index(name = "idx_transaction_wave_reference", columnList = "wave_reference"), @Index(name = "idx_transaction_wave_statut", columnList = "statut_transaction"), - @Index(name = "idx_transaction_wave_compte", columnList = "compte_wave_id"), - @Index(name = "idx_transaction_wave_paiement", columnList = "paiement_id") + @Index(name = "idx_transaction_wave_compte", columnList = "compte_wave_id") }) @Data @NoArgsConstructor diff --git a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/CotisationResource.java b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/CotisationResource.java index ead30f8..09c3fc3 100644 --- a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/CotisationResource.java +++ b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/CotisationResource.java @@ -638,4 +638,31 @@ public class CotisationResource { .build(); } } + + /** + * Envoie des rappels de cotisations groupĂ©s Ă  plusieurs membres (WOU/DRY) + * + * @param membreIds Liste des IDs des membres destinataires + * @return Nombre de rappels envoyĂ©s + */ + @POST + @Path("/rappels/groupes") + @Consumes(MediaType.APPLICATION_JSON) + @Operation(summary = "Envoyer des rappels de cotisations groupĂ©s") + @APIResponse(responseCode = "200", description = "Rappels envoyĂ©s avec succĂšs") + public Response envoyerRappelsGroupes(List membreIds) { + try { + int rappelsEnvoyes = cotisationService.envoyerRappelsCotisationsGroupes(membreIds); + return Response.ok(Map.of("rappelsEnvoyes", rappelsEnvoyes)).build(); + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(Map.of("error", e.getMessage())) + .build(); + } catch (Exception e) { + log.error("Erreur lors de l'envoi des rappels groupĂ©s", e); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(Map.of("error", "Erreur lors de l'envoi des rappels: " + e.getMessage())) + .build(); + } + } } diff --git a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/MembreResource.java b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/MembreResource.java index a9fded9..38a22f3 100644 --- a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/MembreResource.java +++ b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/MembreResource.java @@ -207,6 +207,28 @@ public class MembreResource { return Response.ok(statistiques).build(); } + @GET + @Path("/autocomplete/villes") + @Operation(summary = "Obtenir la liste des villes pour autocomplĂ©tion") + @APIResponse(responseCode = "200", description = "Liste des villes distinctes") + public Response obtenirVilles( + @Parameter(description = "Terme de recherche (optionnel)") @QueryParam("query") String query) { + LOG.infof("RĂ©cupĂ©ration des villes pour autocomplĂ©tion - query: %s", query); + List villes = membreService.obtenirVillesDistinctes(query); + return Response.ok(villes).build(); + } + + @GET + @Path("/autocomplete/professions") + @Operation(summary = "Obtenir la liste des professions pour autocomplĂ©tion") + @APIResponse(responseCode = "200", description = "Liste des professions distinctes") + public Response obtenirProfessions( + @Parameter(description = "Terme de recherche (optionnel)") @QueryParam("query") String query) { + LOG.infof("RĂ©cupĂ©ration des professions pour autocomplĂ©tion - query: %s", query); + List professions = membreService.obtenirProfessionsDistinctes(query); + return Response.ok(professions).build(); + } + @GET @Path("/recherche-avancee") @Operation(summary = "Recherche avancĂ©e de membres avec filtres multiples (DEPRECATED)") @@ -439,4 +461,28 @@ public class MembreResource { .build(); } } + + @POST + @Path("/export/selection") + @Consumes(MediaType.APPLICATION_JSON) + @Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + @Operation(summary = "Exporter une sĂ©lection de membres en Excel") + @APIResponse(responseCode = "200", description = "Fichier Excel gĂ©nĂ©rĂ©") + public Response exporterSelectionMembres( + @Parameter(description = "Liste des IDs des membres Ă  exporter") List membreIds, + @Parameter(description = "Format d'export") @QueryParam("format") @DefaultValue("EXCEL") String format) { + LOG.infof("Export de %d membres sĂ©lectionnĂ©s", membreIds.size()); + try { + byte[] excelData = membreService.exporterMembresSelectionnes(membreIds, format); + return Response.ok(excelData) + .header("Content-Disposition", "attachment; filename=\"membres_selection_" + + java.time.LocalDate.now() + "." + (format != null ? format.toLowerCase() : "xlsx") + "\"") + .build(); + } catch (Exception e) { + LOG.errorf(e, "Erreur lors de l'export de la sĂ©lection"); + return Response.status(Response.Status.INTERNAL_SERVER_ERROR) + .entity(Map.of("error", "Erreur lors de l'export: " + e.getMessage())) + .build(); + } + } } diff --git a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/NotificationResource.java b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/NotificationResource.java index 6ae2572..5bd4641 100644 --- a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/NotificationResource.java +++ b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/resource/NotificationResource.java @@ -10,6 +10,7 @@ import jakarta.ws.rs.*; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; import java.util.List; +import java.util.Map; import java.util.UUID; import org.jboss.logging.Logger; @@ -192,6 +193,34 @@ public class NotificationResource { } } + /** + * Envoie des notifications groupĂ©es Ă  plusieurs membres (WOU/DRY) + * + * @param request DTO contenant les IDs des membres, sujet, corps et canaux + * @return Nombre de notifications créées + */ + @POST + @Path("/groupees") + public Response envoyerNotificationsGroupees(NotificationGroupeeRequest request) { + try { + int notificationsCreees = + notificationService.envoyerNotificationsGroupees( + request.membreIds, request.sujet, request.corps, request.canaux); + return Response.ok(Map.of("notificationsCreees", notificationsCreees)).build(); + } catch (IllegalArgumentException e) { + return Response.status(Response.Status.BAD_REQUEST) + .entity(new ErrorResponse(e.getMessage())) + .build(); + } catch (Exception e) { + LOG.errorf(e, "Erreur lors de l'envoi des notifications groupĂ©es"); + return Response.status(Response.Status.BAD_REQUEST) + .entity( + new ErrorResponse( + "Erreur lors de l'envoi des notifications groupĂ©es: " + e.getMessage())) + .build(); + } + } + /** Classe interne pour les rĂ©ponses d'erreur */ public static class ErrorResponse { public String error; @@ -200,4 +229,14 @@ public class NotificationResource { this.error = error; } } + + /** Classe interne pour les requĂȘtes de notifications groupĂ©es (WOU/DRY) */ + public static class NotificationGroupeeRequest { + public List membreIds; + public String sujet; + public String corps; + public List canaux; + + public NotificationGroupeeRequest() {} + } } diff --git a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/service/CotisationService.java b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/service/CotisationService.java index b00c675..a475c28 100644 --- a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/service/CotisationService.java +++ b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/service/CotisationService.java @@ -442,4 +442,52 @@ public class CotisationService { "Une cotisation marquĂ©e comme payĂ©e doit avoir un montant payĂ© Ă©gal au montant dĂ»"); } } + + /** + * Envoie des rappels de cotisations groupĂ©s Ă  plusieurs membres (WOU/DRY) + * + * @param membreIds Liste des IDs des membres destinataires + * @return Nombre de rappels envoyĂ©s + */ + @Transactional + public int envoyerRappelsCotisationsGroupes(List membreIds) { + log.info("Envoi de rappels de cotisations groupĂ©s Ă  {} membres", membreIds.size()); + + if (membreIds == null || membreIds.isEmpty()) { + throw new IllegalArgumentException("La liste des membres ne peut pas ĂȘtre vide"); + } + + int rappelsEnvoyes = 0; + for (UUID membreId : membreIds) { + try { + Membre membre = + membreRepository + .findByIdOptional(membreId) + .orElseThrow( + () -> + new IllegalArgumentException( + "Membre non trouvĂ© avec l'ID: " + membreId)); + + // Trouver les cotisations en retard pour ce membre + List cotisationsEnRetard = + cotisationRepository.findCotisationsAuRappel(7, 3).stream() + .filter(c -> c.getMembre() != null && c.getMembre().getId().equals(membreId)) + .collect(Collectors.toList()); + + for (Cotisation cotisation : cotisationsEnRetard) { + // IncrĂ©menter le nombre de rappels + cotisationRepository.incrementerNombreRappels(cotisation.getId()); + rappelsEnvoyes++; + } + } catch (Exception e) { + log.warn( + "Erreur lors de l'envoi du rappel de cotisation pour le membre {}: {}", + membreId, + e.getMessage()); + } + } + + log.info("{} rappels envoyĂ©s sur {} membres demandĂ©s", rappelsEnvoyes, membreIds.size()); + return rappelsEnvoyes; + } } diff --git a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/service/MembreService.java b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/service/MembreService.java index 27b6207..30b7ebc 100644 --- a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/service/MembreService.java +++ b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/service/MembreService.java @@ -17,6 +17,7 @@ import jakarta.transaction.Transactional; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.Period; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -533,8 +534,96 @@ public class MembreService { .ageMin(ageMin) .ageMax(ageMax) .nombreOrganisations(nombreOrganisations) - .nombreRegions(0) // À implĂ©menter si champ rĂ©gion disponible + .nombreRegions(0) // TODO: Calculer depuis les adresses .ancienneteMoyenne(ancienneteMoyenne) .build(); } + + // ======================================== + // MÉTHODES D'AUTOCOMPLÉTION (WOU/DRY) + // ======================================== + + /** + * Obtient la liste des villes distinctes depuis les adresses des membres + * RĂ©utilisable pour autocomplĂ©tion (WOU/DRY) + */ + public List obtenirVillesDistinctes(String query) { + LOG.infof("RĂ©cupĂ©ration des villes distinctes - query: %s", query); + + String jpql = "SELECT DISTINCT a.ville FROM Adresse a WHERE a.ville IS NOT NULL AND a.ville != ''"; + if (query != null && !query.trim().isEmpty()) { + jpql += " AND LOWER(a.ville) LIKE LOWER(:query)"; + } + jpql += " ORDER BY a.ville ASC"; + + TypedQuery typedQuery = entityManager.createQuery(jpql, String.class); + if (query != null && !query.trim().isEmpty()) { + typedQuery.setParameter("query", "%" + query.trim() + "%"); + } + typedQuery.setMaxResults(50); // Limiter Ă  50 rĂ©sultats pour performance + + List villes = typedQuery.getResultList(); + LOG.infof("TrouvĂ© %d villes distinctes", villes.size()); + return villes; + } + + /** + * Obtient la liste des professions distinctes depuis les membres + * Note: Si le champ profession n'existe pas dans Membre, retourne une liste vide + * RĂ©utilisable pour autocomplĂ©tion (WOU/DRY) + */ + public List obtenirProfessionsDistinctes(String query) { + LOG.infof("RĂ©cupĂ©ration des professions distinctes - query: %s", query); + + // TODO: VĂ©rifier si le champ profession existe dans Membre + // Pour l'instant, retourner une liste vide car le champ n'existe pas + // Cette mĂ©thode peut ĂȘtre Ă©tendue si un champ profession est ajoutĂ© plus tard + LOG.warn("Le champ profession n'existe pas dans l'entitĂ© Membre. Retour d'une liste vide."); + return new ArrayList<>(); + } + + /** + * Exporte une sĂ©lection de membres en Excel (WOU/DRY - rĂ©utilise la logique d'export) + * + * @param membreIds Liste des IDs des membres Ă  exporter + * @param format Format d'export (EXCEL, CSV, etc.) + * @return DonnĂ©es binaires du fichier Excel + */ + public byte[] exporterMembresSelectionnes(List membreIds, String format) { + LOG.infof("Export de %d membres sĂ©lectionnĂ©s - format: %s", membreIds.size(), format); + + if (membreIds == null || membreIds.isEmpty()) { + throw new IllegalArgumentException("La liste des membres ne peut pas ĂȘtre vide"); + } + + // RĂ©cupĂ©rer les membres + List membres = + membreIds.stream() + .map(id -> membreRepository.findByIdOptional(id)) + .filter(opt -> opt.isPresent()) + .map(java.util.Optional::get) + .collect(Collectors.toList()); + + // Convertir en DTOs + List membresDTO = convertToDTOList(membres); + + // GĂ©nĂ©rer le fichier Excel (simplifiĂ© - Ă  amĂ©liorer avec Apache POI) + // Pour l'instant, gĂ©nĂ©rer un CSV simple + StringBuilder csv = new StringBuilder(); + csv.append("NumĂ©ro;Nom;PrĂ©nom;Email;TĂ©lĂ©phone;Statut;Date AdhĂ©sion\n"); + for (MembreDTO m : membresDTO) { + csv.append( + String.format( + "%s;%s;%s;%s;%s;%s;%s\n", + m.getNumeroMembre() != null ? m.getNumeroMembre() : "", + m.getNom() != null ? m.getNom() : "", + m.getPrenom() != null ? m.getPrenom() : "", + m.getEmail() != null ? m.getEmail() : "", + m.getTelephone() != null ? m.getTelephone() : "", + m.getStatut() != null ? m.getStatut() : "", + m.getDateAdhesion() != null ? m.getDateAdhesion().toString() : "")); + } + + return csv.toString().getBytes(java.nio.charset.StandardCharsets.UTF_8); + } } diff --git a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/service/NotificationService.java b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/service/NotificationService.java index 386696f..26c3a21 100644 --- a/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/service/NotificationService.java +++ b/unionflow-server-impl-quarkus/src/main/java/dev/lions/unionflow/server/service/NotificationService.java @@ -155,6 +155,61 @@ public class NotificationService { .collect(Collectors.toList()); } + /** + * Envoie des notifications groupĂ©es Ă  plusieurs membres (WOU/DRY) + * + * @param membreIds Liste des IDs des membres destinataires + * @param sujet Sujet de la notification + * @param corps Corps du message + * @param canaux Canaux d'envoi (EMAIL, SMS, etc.) + * @return Nombre de notifications créées + */ + @Transactional + public int envoyerNotificationsGroupees( + List membreIds, String sujet, String corps, List canaux) { + LOG.infof( + "Envoi de notifications groupĂ©es Ă  %d membres - sujet: %s", membreIds.size(), sujet); + + if (membreIds == null || membreIds.isEmpty()) { + throw new IllegalArgumentException("La liste des membres ne peut pas ĂȘtre vide"); + } + + int notificationsCreees = 0; + for (UUID membreId : membreIds) { + try { + Membre membre = + membreRepository + .findByIdOptional(membreId) + .orElseThrow( + () -> + new IllegalArgumentException( + "Membre non trouvĂ© avec l'ID: " + membreId)); + + Notification notification = new Notification(); + notification.setMembre(membre); + notification.setSujet(sujet); + notification.setCorps(corps); + notification.setTypeNotification( + dev.lions.unionflow.server.api.enums.notification.TypeNotification.IN_APP); + notification.setPriorite(PrioriteNotification.NORMALE); + notification.setStatut(StatutNotification.EN_ATTENTE); + notification.setDateEnvoiPrevue(java.time.LocalDateTime.now()); + notification.setCreePar(keycloakService.getCurrentUserEmail()); + + notificationRepository.persist(notification); + notificationsCreees++; + } catch (Exception e) { + LOG.warnf( + "Erreur lors de la crĂ©ation de la notification pour le membre %s: %s", + membreId, e.getMessage()); + } + } + + LOG.infof( + "%d notifications créées sur %d membres demandĂ©s", notificationsCreees, membreIds.size()); + return notificationsCreees; + } + // ======================================== // MÉTHODES PRIVÉES // ========================================