feat: formulaire types organisation avec categorie et modules requis

- TypeOrganisationsAdminBean: gestion List<String> modulesSelectionnes
  (sync CSV↔List), constantes CATEGORIES/MODULES_DISPONIBLES, getters JSF,
  CreateTypeReferenceRequest et UpdateTypeReferenceRequest mis à jour (11 args)
- organisations.xhtml: dropdown catégorie + selectManyCheckbox modules (16),
  colonnes Catégorie et Modules requis dans le DataTable, dialogue 750px
- pom.xml: unionflow-server-api 1.0.0 → 1.0.3
This commit is contained in:
dahoud
2026-04-09 15:08:48 +00:00
parent 1a52e7c6bc
commit 0d936eb80a
3 changed files with 99 additions and 8 deletions

View File

@@ -7,7 +7,7 @@
<parent> <parent>
<groupId>dev.lions.unionflow</groupId> <groupId>dev.lions.unionflow</groupId>
<artifactId>unionflow-parent</artifactId> <artifactId>unionflow-parent</artifactId>
<version>1.0.0</version> <version>1.0.3</version>
<relativePath>../unionflow-server-api/parent-pom.xml</relativePath> <relativePath>../unionflow-server-api/parent-pom.xml</relativePath>
</parent> </parent>
@@ -129,7 +129,7 @@
<dependency> <dependency>
<groupId>dev.lions.unionflow</groupId> <groupId>dev.lions.unionflow</groupId>
<artifactId>unionflow-server-api</artifactId> <artifactId>unionflow-server-api</artifactId>
<version>1.0.0</version> <version>1.0.3</version>
</dependency> </dependency>
<!-- Lions User Manager Client - Module réutilisable de gestion d'utilisateurs Keycloak --> <!-- Lions User Manager Client - Module réutilisable de gestion d'utilisateurs Keycloak -->

View File

@@ -13,6 +13,7 @@ import jakarta.inject.Inject;
import jakarta.inject.Named; import jakarta.inject.Named;
import java.io.Serializable; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import org.eclipse.microprofile.rest.client.inject.RestClient; import org.eclipse.microprofile.rest.client.inject.RestClient;
@@ -52,12 +53,25 @@ public class TypeOrganisationsAdminBean implements Serializable {
@Inject @Inject
TypeCatalogueService typeCatalogueService; TypeCatalogueService typeCatalogueService;
private static final List<String> CATEGORIES_DISPONIBLES = Arrays.asList(
"ASSOCIATIF", "FINANCIER_SOLIDAIRE", "RELIGIEUX", "PROFESSIONNEL", "RESEAU_FEDERATION"
);
private static final List<String> MODULES_DISPONIBLES = Arrays.asList(
"COTISATIONS", "EVENEMENTS", "SOLIDARITE", "COMPTABILITE", "DOCUMENTS",
"NOTIFICATIONS", "CREDIT_EPARGNE", "AYANTS_DROIT", "TONTINE", "ONG_PROJETS",
"COOP_AGRICOLE", "VOTE_INTERNE", "COLLECTE_FONDS", "REGISTRE_PROFESSIONNEL",
"CULTES_RELIGIEUX", "GOUVERNANCE_MULTI"
);
private List<TypeReferenceResponse> types = new ArrayList<>(); private List<TypeReferenceResponse> types = new ArrayList<>();
/** Type actuellement édité dans le dialogue (nouveau ou existant). */ /** Type actuellement édité dans le dialogue (nouveau ou existant). */
private TypeReferenceResponse typeCourant; private TypeReferenceResponse typeCourant;
private TypeReferenceResponse typeSelectionne; private TypeReferenceResponse typeSelectionne;
/** ID du type à supprimer (pour dialogue de confirmation explicite). */ /** ID du type à supprimer (pour dialogue de confirmation explicite). */
private UUID typeASupprimerId; private UUID typeASupprimerId;
/** Modules sélectionnés dans le dialogue (synchronisé avec typeCourant.modulesRequis CSV). */
private List<String> modulesSelectionnes = new ArrayList<>();
@PostConstruct @PostConstruct
public void init() { public void init() {
@@ -82,6 +96,7 @@ public class TypeOrganisationsAdminBean implements Serializable {
typeCourant = new TypeReferenceResponse(); typeCourant = new TypeReferenceResponse();
typeCourant.setActif(true); typeCourant.setActif(true);
typeSelectionne = null; typeSelectionne = null;
modulesSelectionnes = new ArrayList<>();
} }
private void creerType() { private void creerType() {
@@ -93,6 +108,9 @@ public class TypeOrganisationsAdminBean implements Serializable {
try { try {
LOG.infof("Tentative de création d'un type d'organisation: %s", typeCourant); LOG.infof("Tentative de création d'un type d'organisation: %s", typeCourant);
String modulesRequisCsv = modulesSelectionnes.isEmpty()
? null : String.join(",", modulesSelectionnes);
CreateTypeReferenceRequest request = CreateTypeReferenceRequest.builder() CreateTypeReferenceRequest request = CreateTypeReferenceRequest.builder()
.domaine("TYPE_ORGANISATION") .domaine("TYPE_ORGANISATION")
.code(typeCourant.getCode()) .code(typeCourant.getCode())
@@ -102,6 +120,8 @@ public class TypeOrganisationsAdminBean implements Serializable {
.estDefaut(false) .estDefaut(false)
.estSysteme(false) .estSysteme(false)
.organisationId(null) .organisationId(null)
.categorie(typeCourant.getCategorie())
.modulesRequis(modulesRequisCsv)
.build(); .build();
TypeReferenceResponse cree = retryService.executeWithRetrySupplier( TypeReferenceResponse cree = retryService.executeWithRetrySupplier(
@@ -156,6 +176,9 @@ public class TypeOrganisationsAdminBean implements Serializable {
} }
try { try {
String modulesRequisCsv = modulesSelectionnes.isEmpty()
? null : String.join(",", modulesSelectionnes);
UpdateTypeReferenceRequest request = new UpdateTypeReferenceRequest( UpdateTypeReferenceRequest request = new UpdateTypeReferenceRequest(
typeCourant.getCode(), typeCourant.getCode(),
typeCourant.getLibelle(), typeCourant.getLibelle(),
@@ -165,7 +188,9 @@ public class TypeOrganisationsAdminBean implements Serializable {
null, // severity null, // severity
typeCourant.getOrdreAffichage(), typeCourant.getOrdreAffichage(),
null, // estDefaut null, // estDefaut
typeCourant.getActif() typeCourant.getActif(),
typeCourant.getCategorie(),
modulesRequisCsv
); );
TypeReferenceResponse maj = retryService.executeWithRetrySupplier( TypeReferenceResponse maj = retryService.executeWithRetrySupplier(
@@ -248,6 +273,11 @@ public class TypeOrganisationsAdminBean implements Serializable {
public void setTypeSelectionne(TypeReferenceResponse typeSelectionne) { public void setTypeSelectionne(TypeReferenceResponse typeSelectionne) {
this.typeSelectionne = typeSelectionne; this.typeSelectionne = typeSelectionne;
this.typeCourant = typeSelectionne; this.typeCourant = typeSelectionne;
// Reconvertir le CSV en liste pour les checkboxes
String csv = (typeSelectionne != null) ? typeSelectionne.getModulesRequis() : null;
modulesSelectionnes = (csv != null && !csv.isBlank())
? new ArrayList<>(Arrays.asList(csv.split(",")))
: new ArrayList<>();
} }
/** /**
@@ -266,4 +296,20 @@ public class TypeOrganisationsAdminBean implements Serializable {
public void setTypeCourant(TypeReferenceResponse typeCourant) { public void setTypeCourant(TypeReferenceResponse typeCourant) {
this.typeCourant = typeCourant; this.typeCourant = typeCourant;
} }
public List<String> getModulesSelectionnes() {
return modulesSelectionnes;
}
public void setModulesSelectionnes(List<String> modulesSelectionnes) {
this.modulesSelectionnes = modulesSelectionnes;
}
public List<String> getCategoriesDisponibles() {
return CATEGORIES_DISPONIBLES;
}
public List<String> getModulesDisponibles() {
return MODULES_DISPONIBLES;
}
} }

View File

@@ -62,6 +62,14 @@
<h:outputText value="#{type.ordreAffichage}" /> <h:outputText value="#{type.ordreAffichage}" />
</p:column> </p:column>
<p:column headerText="Catégorie" style="width: 150px;">
<h:outputText value="#{type.categorie}" />
</p:column>
<p:column headerText="Modules requis">
<h:outputText value="#{type.modulesRequis}" style="font-size: 0.85em; color: #6c757d;" />
</p:column>
<p:column headerText="Actif" style="width: 90px; text-align: center;"> <p:column headerText="Actif" style="width: 90px; text-align: center;">
<p:tag value="#{type.actif ? 'Actif' : 'Inactif'}" <p:tag value="#{type.actif ? 'Actif' : 'Inactif'}"
severity="#{type.actif ? 'success' : 'danger'}" /> severity="#{type.actif ? 'success' : 'danger'}" />
@@ -117,7 +125,7 @@
modal="true" modal="true"
resizable="false" resizable="false"
responsive="true" responsive="true"
width="600"> width="750">
<div class="ui-fluid"> <div class="ui-fluid">
<div class="formgrid grid"> <div class="formgrid grid">
@@ -146,18 +154,55 @@
rows="3" rows="3"
maxlength="500" /> maxlength="500" />
</div> </div>
<div class="field col-12 md:col-4"> <div class="field col-12 md:col-6">
<p:outputLabel for="categorie" value="Catégorie fonctionnelle" />
<p:selectOneMenu id="categorie"
value="#{typeOrganisationsAdminBean.typeCourant.categorie}"
style="width:100%">
<f:selectItem itemLabel="-- Choisir --" itemValue="#{null}" noSelectionOption="true" />
<f:selectItem itemLabel="Associatif" itemValue="ASSOCIATIF" />
<f:selectItem itemLabel="Financier solidaire" itemValue="FINANCIER_SOLIDAIRE" />
<f:selectItem itemLabel="Religieux" itemValue="RELIGIEUX" />
<f:selectItem itemLabel="Professionnel" itemValue="PROFESSIONNEL" />
<f:selectItem itemLabel="Réseau / Fédération" itemValue="RESEAU_FEDERATION" />
</p:selectOneMenu>
</div>
<div class="field col-12 md:col-3">
<p:outputLabel for="ordre" value="Ordre d'affichage" /> <p:outputLabel for="ordre" value="Ordre d'affichage" />
<p:inputNumber id="ordre" <p:inputNumber id="ordre"
value="#{typeOrganisationsAdminBean.typeCourant.ordreAffichage}" value="#{typeOrganisationsAdminBean.typeCourant.ordreAffichage}"
decimalPlaces="0" decimalPlaces="0"
minValue="0" /> minValue="0" />
</div> </div>
<div class="field col-12 md:col-4"> <div class="field col-12 md:col-3">
<p:selectBooleanCheckbox id="actif" <p:selectBooleanCheckbox id="actif"
value="#{typeOrganisationsAdminBean.typeCourant.actif}" /> value="#{typeOrganisationsAdminBean.typeCourant.actif}" />
<p:outputLabel for="actif" value="Actif" styleClass="ml-2" /> <p:outputLabel for="actif" value="Actif" styleClass="ml-2" />
</div> </div>
<div class="field col-12">
<p:outputLabel value="Modules métier activés" />
<p:selectManyCheckbox id="modulesRequis"
value="#{typeOrganisationsAdminBean.modulesSelectionnes}"
layout="grid"
columns="3">
<f:selectItem itemLabel="Cotisations" itemValue="COTISATIONS" />
<f:selectItem itemLabel="Événements" itemValue="EVENEMENTS" />
<f:selectItem itemLabel="Solidarité" itemValue="SOLIDARITE" />
<f:selectItem itemLabel="Comptabilité" itemValue="COMPTABILITE" />
<f:selectItem itemLabel="Documents" itemValue="DOCUMENTS" />
<f:selectItem itemLabel="Notifications" itemValue="NOTIFICATIONS" />
<f:selectItem itemLabel="Épargne &amp; Crédit" itemValue="CREDIT_EPARGNE" />
<f:selectItem itemLabel="Ayants-droit" itemValue="AYANTS_DROIT" />
<f:selectItem itemLabel="Tontine" itemValue="TONTINE" />
<f:selectItem itemLabel="Projets ONG" itemValue="ONG_PROJETS" />
<f:selectItem itemLabel="Coopérative agricole" itemValue="COOP_AGRICOLE" />
<f:selectItem itemLabel="Vote interne" itemValue="VOTE_INTERNE" />
<f:selectItem itemLabel="Collecte de fonds" itemValue="COLLECTE_FONDS" />
<f:selectItem itemLabel="Registre professionnel" itemValue="REGISTRE_PROFESSIONNEL" />
<f:selectItem itemLabel="Cultes / Dîmes" itemValue="CULTES_RELIGIEUX" />
<f:selectItem itemLabel="Gouvernance multi-niveaux" itemValue="GOUVERNANCE_MULTI" />
</p:selectManyCheckbox>
</div>
</div> </div>
</div> </div>