Refactroring
This commit is contained in:
@@ -2,6 +2,7 @@ package dev.lions.unionflow.client.dto;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
@@ -9,6 +10,14 @@ import java.time.LocalDateTime;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DTO client pour les organisations (alias historique Association).
|
||||||
|
*
|
||||||
|
* Harmonisé avec le contrat serveur `OrganisationDTO`:
|
||||||
|
* - `dateCreation`/`dateModification` d'audit (LocalDateTime) alignés sur BaseDTO avec pattern JSON
|
||||||
|
* - `dateFondation` (LocalDate) pour la date de création fonctionnelle de l'organisation
|
||||||
|
*/
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public class AssociationDTO implements Serializable {
|
public class AssociationDTO implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -28,9 +37,13 @@ public class AssociationDTO implements Serializable {
|
|||||||
@JsonProperty("typeOrganisation")
|
@JsonProperty("typeOrganisation")
|
||||||
private String typeAssociation;
|
private String typeAssociation;
|
||||||
|
|
||||||
|
// Date de fondation (fonctionnelle), côté serveur: OrganisationDTO.dateFondation
|
||||||
|
@JsonProperty("dateFondation")
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
private LocalDate dateCreation;
|
private LocalDate dateFondation;
|
||||||
|
|
||||||
|
// Côté serveur: OrganisationDTO.numeroEnregistrement
|
||||||
|
@JsonProperty("numeroEnregistrement")
|
||||||
private String numeroRegistre;
|
private String numeroRegistre;
|
||||||
private String statut;
|
private String statut;
|
||||||
private Integer nombreMembres;
|
private Integer nombreMembres;
|
||||||
@@ -41,10 +54,22 @@ public class AssociationDTO implements Serializable {
|
|||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
private LocalDateTime dateDerniereActivite;
|
private LocalDateTime dateDerniereActivite;
|
||||||
|
|
||||||
|
// Champs d'audit issus de BaseDTO (côté serveur)
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime dateCreation;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||||
|
private LocalDateTime dateModification;
|
||||||
|
|
||||||
|
private Long version;
|
||||||
|
private Boolean actif;
|
||||||
|
|
||||||
private String region;
|
private String region;
|
||||||
private String ville;
|
private String ville;
|
||||||
private String quartier;
|
private String quartier;
|
||||||
private String pays;
|
private String pays;
|
||||||
|
// Aligné sur OrganisationDTO.codePostal
|
||||||
|
private String codePostal;
|
||||||
|
|
||||||
// Constructeurs
|
// Constructeurs
|
||||||
public AssociationDTO() {}
|
public AssociationDTO() {}
|
||||||
@@ -53,7 +78,7 @@ public class AssociationDTO implements Serializable {
|
|||||||
this.nom = nom;
|
this.nom = nom;
|
||||||
this.typeAssociation = typeAssociation;
|
this.typeAssociation = typeAssociation;
|
||||||
this.statut = "ACTIVE";
|
this.statut = "ACTIVE";
|
||||||
this.dateCreation = LocalDate.now();
|
this.dateFondation = LocalDate.now();
|
||||||
this.nombreMembres = 0;
|
this.nombreMembres = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,8 +107,8 @@ public class AssociationDTO implements Serializable {
|
|||||||
public String getTypeAssociation() { return typeAssociation; }
|
public String getTypeAssociation() { return typeAssociation; }
|
||||||
public void setTypeAssociation(String typeAssociation) { this.typeAssociation = typeAssociation; }
|
public void setTypeAssociation(String typeAssociation) { this.typeAssociation = typeAssociation; }
|
||||||
|
|
||||||
public LocalDate getDateCreation() { return dateCreation; }
|
public LocalDate getDateFondation() { return dateFondation; }
|
||||||
public void setDateCreation(LocalDate dateCreation) { this.dateCreation = dateCreation; }
|
public void setDateFondation(LocalDate dateFondation) { this.dateFondation = dateFondation; }
|
||||||
|
|
||||||
public String getNumeroRegistre() { return numeroRegistre; }
|
public String getNumeroRegistre() { return numeroRegistre; }
|
||||||
public void setNumeroRegistre(String numeroRegistre) { this.numeroRegistre = numeroRegistre; }
|
public void setNumeroRegistre(String numeroRegistre) { this.numeroRegistre = numeroRegistre; }
|
||||||
@@ -118,6 +143,21 @@ public class AssociationDTO implements Serializable {
|
|||||||
public String getPays() { return pays; }
|
public String getPays() { return pays; }
|
||||||
public void setPays(String pays) { this.pays = pays; }
|
public void setPays(String pays) { this.pays = pays; }
|
||||||
|
|
||||||
|
public String getCodePostal() { return codePostal; }
|
||||||
|
public void setCodePostal(String codePostal) { this.codePostal = codePostal; }
|
||||||
|
|
||||||
|
public LocalDateTime getDateCreation() { return dateCreation; }
|
||||||
|
public void setDateCreation(LocalDateTime dateCreation) { this.dateCreation = dateCreation; }
|
||||||
|
|
||||||
|
public LocalDateTime getDateModification() { return dateModification; }
|
||||||
|
public void setDateModification(LocalDateTime dateModification) { this.dateModification = dateModification; }
|
||||||
|
|
||||||
|
public Long getVersion() { return version; }
|
||||||
|
public void setVersion(Long version) { this.version = version; }
|
||||||
|
|
||||||
|
public Boolean getActif() { return actif; }
|
||||||
|
public void setActif(Boolean actif) { this.actif = actif; }
|
||||||
|
|
||||||
// Propriétés dérivées
|
// Propriétés dérivées
|
||||||
public String getTypeLibelle() {
|
public String getTypeLibelle() {
|
||||||
return switch (typeAssociation != null ? typeAssociation : "") {
|
return switch (typeAssociation != null ? typeAssociation : "") {
|
||||||
|
|||||||
@@ -54,15 +54,13 @@ public interface AssociationService {
|
|||||||
@Path("/{id}")
|
@Path("/{id}")
|
||||||
void supprimer(@PathParam("id") UUID id);
|
void supprimer(@PathParam("id") UUID id);
|
||||||
|
|
||||||
@PUT
|
// Côté serveur: POST /{id}/activer
|
||||||
|
@POST
|
||||||
@Path("/{id}/activer")
|
@Path("/{id}/activer")
|
||||||
AssociationDTO activer(@PathParam("id") UUID id);
|
AssociationDTO activer(@PathParam("id") UUID id);
|
||||||
|
|
||||||
@PUT
|
// Suspension: POST /{id}/suspendre (alias historique "désactiver")
|
||||||
@Path("/{id}/desactiver")
|
@POST
|
||||||
AssociationDTO desactiver(@PathParam("id") UUID id);
|
|
||||||
|
|
||||||
@PUT
|
|
||||||
@Path("/{id}/suspendre")
|
@Path("/{id}/suspendre")
|
||||||
AssociationDTO suspendre(@PathParam("id") UUID id);
|
AssociationDTO suspendre(@PathParam("id") UUID id);
|
||||||
|
|
||||||
|
|||||||
@@ -104,6 +104,18 @@ public class OrganisationsBean implements Serializable {
|
|||||||
.count();
|
.count();
|
||||||
organisationsInactives = totalOrganisations - organisationsActives;
|
organisationsInactives = totalOrganisations - organisationsActives;
|
||||||
}
|
}
|
||||||
|
} catch (dev.lions.unionflow.client.service.RestClientExceptionMapper.UnauthorizedException e) {
|
||||||
|
// Non bloquant: afficher une info et calculer depuis la liste
|
||||||
|
LOGGER.warning("Statistiques non autorisées (401): " + e.getMessage());
|
||||||
|
FacesContext.getCurrentInstance().addMessage(null,
|
||||||
|
new FacesMessage(FacesMessage.SEVERITY_INFO,
|
||||||
|
"Information",
|
||||||
|
"Statistiques indisponibles (non autorisé) — affichage des données sans stats."));
|
||||||
|
totalOrganisations = organisations.size();
|
||||||
|
organisationsActives = organisations.stream()
|
||||||
|
.filter(o -> o.getStatut() != null && StatutOrganisationConstants.ACTIVE.equals(o.getStatut()))
|
||||||
|
.count();
|
||||||
|
organisationsInactives = totalOrganisations - organisationsActives;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LOGGER.warning("Impossible de charger les statistiques: " + e.getMessage());
|
LOGGER.warning("Impossible de charger les statistiques: " + e.getMessage());
|
||||||
// Fallback: calculer depuis la liste
|
// Fallback: calculer depuis la liste
|
||||||
@@ -118,8 +130,23 @@ public class OrganisationsBean implements Serializable {
|
|||||||
public void preparerNouvelleOrganisation() {
|
public void preparerNouvelleOrganisation() {
|
||||||
nouvelleOrganisation = new AssociationDTO();
|
nouvelleOrganisation = new AssociationDTO();
|
||||||
nouvelleOrganisation.setStatut(StatutOrganisationConstants.ACTIVE);
|
nouvelleOrganisation.setStatut(StatutOrganisationConstants.ACTIVE);
|
||||||
nouvelleOrganisation.setTypeAssociation("ASSOCIATION");
|
|
||||||
nouvelleOrganisation.setDateCreation(java.time.LocalDate.now());
|
// S'assurer que le catalogue des types est chargé avant d'initialiser le formulaire
|
||||||
|
if (typesCatalogue == null || typesCatalogue.isEmpty()) {
|
||||||
|
chargerTypesOrganisation();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Déterminer un type par défaut dynamique (premier type actif du catalogue)
|
||||||
|
String typeDefaut = null;
|
||||||
|
if (typesCatalogue != null) {
|
||||||
|
typeDefaut = typesCatalogue.stream()
|
||||||
|
.filter(t -> t.getActif() == null || Boolean.TRUE.equals(t.getActif()))
|
||||||
|
.map(TypeOrganisationClientDTO::getCode)
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
nouvelleOrganisation.setTypeAssociation(typeDefaut);
|
||||||
|
nouvelleOrganisation.setDateFondation(java.time.LocalDate.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void creerOrganisation() {
|
public void creerOrganisation() {
|
||||||
@@ -207,7 +234,7 @@ public class OrganisationsBean implements Serializable {
|
|||||||
|
|
||||||
public void desactiverOrganisation(AssociationDTO organisation) {
|
public void desactiverOrganisation(AssociationDTO organisation) {
|
||||||
try {
|
try {
|
||||||
associationService.desactiver(organisation.getId());
|
associationService.suspendre(organisation.getId());
|
||||||
organisation.setStatut(StatutOrganisationConstants.INACTIVE);
|
organisation.setStatut(StatutOrganisationConstants.INACTIVE);
|
||||||
|
|
||||||
FacesContext.getCurrentInstance().addMessage(null,
|
FacesContext.getCurrentInstance().addMessage(null,
|
||||||
@@ -277,6 +304,14 @@ public class OrganisationsBean implements Serializable {
|
|||||||
organisationsFiltrees = organisations;
|
organisationsFiltrees = organisations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recharge la liste et les statistiques (DRY)
|
||||||
|
*/
|
||||||
|
public void recharger() {
|
||||||
|
chargerOrganisations();
|
||||||
|
chargerStatistiques();
|
||||||
|
}
|
||||||
|
|
||||||
// Getters & Setters
|
// Getters & Setters
|
||||||
public List<AssociationDTO> getOrganisations() { return organisations; }
|
public List<AssociationDTO> getOrganisations() { return organisations; }
|
||||||
public void setOrganisations(List<AssociationDTO> organisations) { this.organisations = organisations; }
|
public void setOrganisations(List<AssociationDTO> organisations) { this.organisations = organisations; }
|
||||||
|
|||||||
@@ -144,7 +144,7 @@
|
|||||||
<p:commandButton icon="#{org.statut == organisationsBean.statutActive ? 'pi pi-ban' : 'pi pi-check'}"
|
<p:commandButton icon="#{org.statut == organisationsBean.statutActive ? 'pi pi-ban' : 'pi pi-check'}"
|
||||||
title="#{org.statut == organisationsBean.statutActive ? 'Désactiver' : 'Activer'}"
|
title="#{org.statut == organisationsBean.statutActive ? 'Désactiver' : 'Activer'}"
|
||||||
action="#{organisationsBean.basculerStatutOrganisation(org)}"
|
action="#{organisationsBean.basculerStatutOrganisation(org)}"
|
||||||
update="dtOrganisations messages"
|
update=":formOrganisations:dtOrganisations :formOrganisations:messages"
|
||||||
styleClass="ui-button-rounded #{org.statut == organisationsBean.statutActive ? 'ui-button-secondary' : 'ui-button-success'} mr-2">
|
styleClass="ui-button-rounded #{org.statut == organisationsBean.statutActive ? 'ui-button-secondary' : 'ui-button-success'} mr-2">
|
||||||
<p:confirm header="Confirmation"
|
<p:confirm header="Confirmation"
|
||||||
message="Êtes-vous sûr de vouloir #{org.statut == organisationsBean.statutActive ? 'désactiver' : 'activer'} cette organisation ?"
|
message="Êtes-vous sûr de vouloir #{org.statut == organisationsBean.statutActive ? 'désactiver' : 'activer'} cette organisation ?"
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
<p:commandButton icon="pi pi-trash"
|
<p:commandButton icon="pi pi-trash"
|
||||||
title="Supprimer"
|
title="Supprimer"
|
||||||
action="#{organisationsBean.supprimerOrganisation(org)}"
|
action="#{organisationsBean.supprimerOrganisation(org)}"
|
||||||
update="dtOrganisations messages"
|
update=":formOrganisations:dtOrganisations :formOrganisations:messages"
|
||||||
styleClass="ui-button-rounded ui-button-danger">
|
styleClass="ui-button-rounded ui-button-danger">
|
||||||
<p:confirm header="Confirmation"
|
<p:confirm header="Confirmation"
|
||||||
message="Êtes-vous sûr de vouloir supprimer cette organisation ? Cette action est irréversible."
|
message="Êtes-vous sûr de vouloir supprimer cette organisation ? Cette action est irréversible."
|
||||||
@@ -179,68 +179,10 @@
|
|||||||
<ui:param name="formId" value="formNouvelle" />
|
<ui:param name="formId" value="formNouvelle" />
|
||||||
<ui:param name="width" value="800" />
|
<ui:param name="width" value="800" />
|
||||||
<ui:define name="content">
|
<ui:define name="content">
|
||||||
<div class="col-12 md:col-8">
|
<ui:include src="/ui/includes/organisation-form.xhtml">
|
||||||
<ui:include src="/templates/components/form-field-text.xhtml">
|
<ui:param name="model" value="#{organisationsBean.nouvelleOrganisation}" />
|
||||||
<ui:param name="id" value="nom" />
|
<ui:param name="typesItems" value="#{organisationsBean.typesSelectItemsForForm}" />
|
||||||
<ui:param name="label" value="Nom complet *" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.nouvelleOrganisation.nom}" />
|
|
||||||
<ui:param name="required" value="true" />
|
|
||||||
</ui:include>
|
</ui:include>
|
||||||
</div>
|
|
||||||
<div class="col-12 md:col-6">
|
|
||||||
<ui:include src="/templates/components/form-field-select.xhtml">
|
|
||||||
<ui:param name="id" value="type" />
|
|
||||||
<ui:param name="label" value="Type *" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.nouvelleOrganisation.typeAssociation}" />
|
|
||||||
<ui:param name="items" value="#{organisationsBean.typesSelectItemsForForm}" />
|
|
||||||
<ui:param name="required" value="true" />
|
|
||||||
</ui:include>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 md:col-6">
|
|
||||||
<ui:include src="/templates/components/form-field-text.xhtml">
|
|
||||||
<ui:param name="id" value="email" />
|
|
||||||
<ui:param name="label" value="Email *" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.nouvelleOrganisation.email}" />
|
|
||||||
<ui:param name="required" value="true" />
|
|
||||||
</ui:include>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 md:col-6">
|
|
||||||
<ui:include src="/templates/components/form-field-text.xhtml">
|
|
||||||
<ui:param name="id" value="telephone" />
|
|
||||||
<ui:param name="label" value="Téléphone" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.nouvelleOrganisation.telephone}" />
|
|
||||||
</ui:include>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 md:col-6">
|
|
||||||
<ui:include src="/templates/components/form-field-text.xhtml">
|
|
||||||
<ui:param name="id" value="ville" />
|
|
||||||
<ui:param name="label" value="Ville *" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.nouvelleOrganisation.ville}" />
|
|
||||||
<ui:param name="required" value="true" />
|
|
||||||
</ui:include>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 md:col-6">
|
|
||||||
<ui:include src="/templates/components/form-field-text.xhtml">
|
|
||||||
<ui:param name="id" value="region" />
|
|
||||||
<ui:param name="label" value="Région" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.nouvelleOrganisation.region}" />
|
|
||||||
</ui:include>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 md:col-6">
|
|
||||||
<ui:include src="/templates/components/form-field-text.xhtml">
|
|
||||||
<ui:param name="id" value="pays" />
|
|
||||||
<ui:param name="label" value="Pays" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.nouvelleOrganisation.pays}" />
|
|
||||||
</ui:include>
|
|
||||||
</div>
|
|
||||||
<div class="col-12">
|
|
||||||
<ui:include src="/templates/components/form-field-textarea.xhtml">
|
|
||||||
<ui:param name="id" value="description" />
|
|
||||||
<ui:param name="label" value="Description" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.nouvelleOrganisation.description}" />
|
|
||||||
<ui:param name="rows" value="3" />
|
|
||||||
</ui:include>
|
|
||||||
</div>
|
|
||||||
</ui:define>
|
</ui:define>
|
||||||
<ui:define name="footer">
|
<ui:define name="footer">
|
||||||
<p:commandButton value="Annuler"
|
<p:commandButton value="Annuler"
|
||||||
@@ -265,52 +207,10 @@
|
|||||||
<ui:param name="width" value="800" />
|
<ui:param name="width" value="800" />
|
||||||
<ui:define name="content">
|
<ui:define name="content">
|
||||||
<ui:fragment rendered="#{organisationsBean.organisationSelectionnee != null}">
|
<ui:fragment rendered="#{organisationsBean.organisationSelectionnee != null}">
|
||||||
<div class="col-12 md:col-8">
|
<ui:include src="/ui/includes/organisation-form.xhtml">
|
||||||
<ui:include src="/templates/components/form-field-text.xhtml">
|
<ui:param name="model" value="#{organisationsBean.organisationSelectionnee}" />
|
||||||
<ui:param name="id" value="nomMod" />
|
<ui:param name="typesItems" value="#{organisationsBean.typesSelectItemsForForm}" />
|
||||||
<ui:param name="label" value="Nom complet *" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.organisationSelectionnee.nom}" />
|
|
||||||
<ui:param name="required" value="true" />
|
|
||||||
</ui:include>
|
</ui:include>
|
||||||
</div>
|
|
||||||
<div class="col-12 md:col-6">
|
|
||||||
<ui:include src="/templates/components/form-field-text.xhtml">
|
|
||||||
<ui:param name="id" value="emailMod" />
|
|
||||||
<ui:param name="label" value="Email *" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.organisationSelectionnee.email}" />
|
|
||||||
<ui:param name="required" value="true" />
|
|
||||||
</ui:include>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 md:col-6">
|
|
||||||
<ui:include src="/templates/components/form-field-text.xhtml">
|
|
||||||
<ui:param name="id" value="telephoneMod" />
|
|
||||||
<ui:param name="label" value="Téléphone" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.organisationSelectionnee.telephone}" />
|
|
||||||
</ui:include>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 md:col-6">
|
|
||||||
<ui:include src="/templates/components/form-field-text.xhtml">
|
|
||||||
<ui:param name="id" value="villeMod" />
|
|
||||||
<ui:param name="label" value="Ville *" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.organisationSelectionnee.ville}" />
|
|
||||||
<ui:param name="required" value="true" />
|
|
||||||
</ui:include>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 md:col-6">
|
|
||||||
<ui:include src="/templates/components/form-field-text.xhtml">
|
|
||||||
<ui:param name="id" value="regionMod" />
|
|
||||||
<ui:param name="label" value="Région" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.organisationSelectionnee.region}" />
|
|
||||||
</ui:include>
|
|
||||||
</div>
|
|
||||||
<div class="col-12">
|
|
||||||
<ui:include src="/templates/components/form-field-textarea.xhtml">
|
|
||||||
<ui:param name="id" value="descriptionMod" />
|
|
||||||
<ui:param name="label" value="Description" />
|
|
||||||
<ui:param name="value" value="#{organisationsBean.organisationSelectionnee.description}" />
|
|
||||||
<ui:param name="rows" value="3" />
|
|
||||||
</ui:include>
|
|
||||||
</div>
|
|
||||||
</ui:fragment>
|
</ui:fragment>
|
||||||
</ui:define>
|
</ui:define>
|
||||||
<ui:define name="footer">
|
<ui:define name="footer">
|
||||||
|
|||||||
@@ -0,0 +1,212 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||||
|
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||||
|
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||||
|
xmlns:p="http://primefaces.org/ui"
|
||||||
|
template="/templates/main-template.xhtml">
|
||||||
|
|
||||||
|
<ui:define name="title">Gestion des Organisations</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="content">
|
||||||
|
<h:form id="formOrgs">
|
||||||
|
<p:messages id="messages" showDetail="true" closable="true" />
|
||||||
|
|
||||||
|
<div class="card mb-3">
|
||||||
|
<div class="flex justify-content-between align-items-center">
|
||||||
|
<div>
|
||||||
|
<h5 class="mb-1">Organisations</h5>
|
||||||
|
<span class="text-600">
|
||||||
|
CRUD complet des organisations. Respect DRY/WOU: composants réutilisés et simplicité.
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p:commandButton value="Nouvelle organisation"
|
||||||
|
icon="pi pi-plus"
|
||||||
|
styleClass="ui-button-success"
|
||||||
|
actionListener="#{organisationsBean.preparerNouvelleOrganisation}"
|
||||||
|
update=":formOrgs:dlgCreate"
|
||||||
|
oncomplete="PF('dlgCreate').show();" />
|
||||||
|
<p:commandButton value="Rafraîchir"
|
||||||
|
icon="pi pi-refresh"
|
||||||
|
styleClass="ui-button-secondary ml-2"
|
||||||
|
actionListener="#{organisationsBean.recharger}"
|
||||||
|
update=":formOrgs:dtOrgs :formOrgs:stats :formOrgs:messages" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p:outputPanel id="stats" styleClass="grid mb-3">
|
||||||
|
<div class="col-12 md:col-4">
|
||||||
|
<p:card>
|
||||||
|
<f:facet name="title">Total</f:facet>
|
||||||
|
<h:outputText value="#{organisationsBean.totalOrganisations}" />
|
||||||
|
</p:card>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 md:col-4">
|
||||||
|
<p:card>
|
||||||
|
<f:facet name="title">Actives</f:facet>
|
||||||
|
<h:outputText value="#{organisationsBean.organisationsActives}" />
|
||||||
|
</p:card>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 md:col-4">
|
||||||
|
<p:card>
|
||||||
|
<f:facet name="title">Inactives</f:facet>
|
||||||
|
<h:outputText value="#{organisationsBean.organisationsInactives}" />
|
||||||
|
</p:card>
|
||||||
|
</div>
|
||||||
|
</p:outputPanel>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="grid mb-3 p-3">
|
||||||
|
<div class="col-12 md:col-4">
|
||||||
|
<p:inputText placeholder="Recherche (nom, ville, description)"
|
||||||
|
value="#{organisationsBean.rechercheGlobale}">
|
||||||
|
<p:ajax event="keyup" update=":formOrgs:dtOrgs" listener="#{organisationsBean.appliquerFiltres}" />
|
||||||
|
</p:inputText>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 md:col-3">
|
||||||
|
<p:selectOneMenu value="#{organisationsBean.filtreStatut}">
|
||||||
|
<f:selectItems value="#{organisationsBean.statutsSelectItems}" />
|
||||||
|
<p:ajax update=":formOrgs:dtOrgs" listener="#{organisationsBean.appliquerFiltres}" />
|
||||||
|
</p:selectOneMenu>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 md:col-3">
|
||||||
|
<p:selectOneMenu value="#{organisationsBean.filtreType}">
|
||||||
|
<f:selectItems value="#{organisationsBean.typesSelectItems}" />
|
||||||
|
<p:ajax update=":formOrgs:dtOrgs" listener="#{organisationsBean.appliquerFiltres}" />
|
||||||
|
</p:selectOneMenu>
|
||||||
|
</div>
|
||||||
|
<div class="col-12 md:col-2 text-right">
|
||||||
|
<p:commandButton value="Réinitialiser"
|
||||||
|
icon="pi pi-filter-slash"
|
||||||
|
styleClass="ui-button-secondary"
|
||||||
|
actionListener="#{organisationsBean.reinitialiserFiltres}"
|
||||||
|
update=":formOrgs:dtOrgs :formOrgs:filters" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p:dataTable id="dtOrgs"
|
||||||
|
value="#{organisationsBean.organisationsFiltrees}"
|
||||||
|
var="org"
|
||||||
|
paginator="true"
|
||||||
|
rows="20"
|
||||||
|
rowsPerPageTemplate="10,20,50"
|
||||||
|
paginatorPosition="bottom"
|
||||||
|
emptyMessage="Aucune organisation trouvée">
|
||||||
|
|
||||||
|
<p:column headerText="Nom" sortBy="#{org.nom}">
|
||||||
|
<h:outputText value="#{org.nom}" />
|
||||||
|
</p:column>
|
||||||
|
|
||||||
|
<p:column headerText="Type" sortBy="#{org.typeAssociation}" style="width: 200px;">
|
||||||
|
<p:tag value="#{org.typeLibelle}" severity="info" />
|
||||||
|
</p:column>
|
||||||
|
|
||||||
|
<p:column headerText="Statut" style="width: 140px; text-align: center;">
|
||||||
|
<p:tag value="#{org.statutLibelle}" severity="#{org.statutSeverity}" />
|
||||||
|
</p:column>
|
||||||
|
|
||||||
|
<p:column headerText="Localisation" sortBy="#{org.ville}">
|
||||||
|
<h:outputText value="#{org.ville}" />
|
||||||
|
<h:outputText value=", " rendered="#{not empty org.ville and not empty org.region}" />
|
||||||
|
<h:outputText value="#{org.region}" />
|
||||||
|
</p:column>
|
||||||
|
|
||||||
|
<p:column headerText="Actions" style="width: 220px; text-align: center;">
|
||||||
|
<p:commandButton icon="pi pi-pencil"
|
||||||
|
title="Modifier"
|
||||||
|
styleClass="ui-button-rounded ui-button-warning mr-2"
|
||||||
|
actionListener="#{organisationsBean.setOrganisationSelectionnee(org)}"
|
||||||
|
update=":formOrgs:dlgEdit"
|
||||||
|
oncomplete="PF('dlgEdit').show();" />
|
||||||
|
|
||||||
|
<p:commandButton icon="#{organisationsBean.estActive(org) ? 'pi pi-ban' : 'pi pi-check'}"
|
||||||
|
title="#{organisationsBean.estActive(org) ? 'Désactiver' : 'Activer'}"
|
||||||
|
styleClass="ui-button-rounded #{organisationsBean.estActive(org) ? 'ui-button-secondary' : 'ui-button-success'} mr-2"
|
||||||
|
update=":formOrgs:dtOrgs :formOrgs:messages :formOrgs:stats"
|
||||||
|
actionListener="#{organisationsBean.basculerStatutOrganisation(org)}">
|
||||||
|
<p:confirm header="Confirmation"
|
||||||
|
message="Confirmez l'action sur le statut de l'organisation ?"
|
||||||
|
icon="pi pi-exclamation-triangle" />
|
||||||
|
</p:commandButton>
|
||||||
|
|
||||||
|
<p:commandButton icon="pi pi-trash"
|
||||||
|
title="Supprimer"
|
||||||
|
styleClass="ui-button-rounded ui-button-danger"
|
||||||
|
update=":formOrgs:dtOrgs :formOrgs:messages :formOrgs:stats"
|
||||||
|
actionListener="#{organisationsBean.supprimerOrganisation(org)}">
|
||||||
|
<p:confirm header="Confirmation"
|
||||||
|
message="Supprimer cette organisation ?"
|
||||||
|
icon="pi pi-exclamation-triangle" />
|
||||||
|
</p:commandButton>
|
||||||
|
</p:column>
|
||||||
|
</p:dataTable>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade" responsive="true" width="350">
|
||||||
|
<p:commandButton value="Non" type="button" styleClass="ui-button-secondary" icon="pi pi-times"
|
||||||
|
onclick="PF('confirmDialog').hide()" />
|
||||||
|
<p:commandButton value="Oui" type="button" styleClass="ui-button-danger" icon="pi pi-check" />
|
||||||
|
</p:confirmDialog>
|
||||||
|
|
||||||
|
<!-- Dialogue création -->
|
||||||
|
<p:dialog id="dlgCreate"
|
||||||
|
widgetVar="dlgCreate"
|
||||||
|
header="Nouvelle organisation"
|
||||||
|
modal="true"
|
||||||
|
resizable="false"
|
||||||
|
responsive="true"
|
||||||
|
width="700">
|
||||||
|
|
||||||
|
<ui:include src="/ui/includes/organisation-form.xhtml">
|
||||||
|
<ui:param name="model" value="#{organisationsBean.nouvelleOrganisation}" />
|
||||||
|
<ui:param name="typesItems" value="#{organisationsBean.typesSelectItemsForForm}" />
|
||||||
|
</ui:include>
|
||||||
|
|
||||||
|
<f:facet name="footer">
|
||||||
|
<p:commandButton value="Annuler"
|
||||||
|
icon="pi pi-times"
|
||||||
|
onclick="PF('dlgCreate').hide();"
|
||||||
|
styleClass="ui-button-secondary" />
|
||||||
|
|
||||||
|
<p:commandButton value="Créer"
|
||||||
|
icon="pi pi-check"
|
||||||
|
process="@form"
|
||||||
|
update=":formOrgs:dtOrgs :formOrgs:messages :formOrgs:stats"
|
||||||
|
actionListener="#{organisationsBean.creerOrganisation}"
|
||||||
|
oncomplete="if(!args.validationFailed) PF('dlgCreate').hide();" />
|
||||||
|
</f:facet>
|
||||||
|
</p:dialog>
|
||||||
|
|
||||||
|
<!-- Dialogue édition -->
|
||||||
|
<p:dialog id="dlgEdit"
|
||||||
|
widgetVar="dlgEdit"
|
||||||
|
header="Modifier l'organisation"
|
||||||
|
modal="true"
|
||||||
|
resizable="false"
|
||||||
|
responsive="true"
|
||||||
|
width="700">
|
||||||
|
|
||||||
|
<ui:include src="/ui/includes/organisation-form.xhtml">
|
||||||
|
<ui:param name="model" value="#{organisationsBean.organisationSelectionnee}" />
|
||||||
|
<ui:param name="typesItems" value="#{organisationsBean.typesSelectItemsForForm}" />
|
||||||
|
</ui:include>
|
||||||
|
|
||||||
|
<f:facet name="footer">
|
||||||
|
<p:commandButton value="Annuler"
|
||||||
|
icon="pi pi-times"
|
||||||
|
onclick="PF('dlgEdit').hide();"
|
||||||
|
styleClass="ui-button-secondary" />
|
||||||
|
|
||||||
|
<p:commandButton value="Enregistrer"
|
||||||
|
icon="pi pi-check"
|
||||||
|
process="@form"
|
||||||
|
update=":formOrgs:dtOrgs :formOrgs:messages"
|
||||||
|
actionListener="#{organisationsBean.modifierOrganisation}"
|
||||||
|
oncomplete="if(!args.validationFailed) PF('dlgEdit').hide();" />
|
||||||
|
</f:facet>
|
||||||
|
</p:dialog>
|
||||||
|
</h:form>
|
||||||
|
</ui:define>
|
||||||
|
</ui:composition>
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
<ui:fragment xmlns="http://www.w3.org/1999/xhtml"
|
||||||
|
xmlns:h="http://xmlns.jcp.org/jsf/html"
|
||||||
|
xmlns:f="http://xmlns.jcp.org/jsf/core"
|
||||||
|
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
|
||||||
|
xmlns:p="http://primefaces.org/ui">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Fragment réutilisable (DRY) pour le formulaire d'Organisation
|
||||||
|
Paramètres attendus via <ui:param>:
|
||||||
|
- model: l'objet cible (ex: #{organisationsBean.nouvelleOrganisation} ou #{organisationsBean.organisationSelectionnee})
|
||||||
|
- typesItems: la liste des SelectItem pour les types (ex: #{organisationsBean.typesSelectItemsForForm})
|
||||||
|
-->
|
||||||
|
|
||||||
|
<div class="ui-fluid">
|
||||||
|
<div class="formgrid grid">
|
||||||
|
<!-- Nom -->
|
||||||
|
<div class="field col-12 md:col-8">
|
||||||
|
<p:outputLabel for="nom" value="Nom *" />
|
||||||
|
<p:inputText id="nom"
|
||||||
|
value="#{model.nom}"
|
||||||
|
required="true"
|
||||||
|
requiredMessage="Nom: une donnée est requise."
|
||||||
|
maxlength="200" />
|
||||||
|
<p:message for="nom" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Type -->
|
||||||
|
<div class="field col-12 md:col-4">
|
||||||
|
<p:outputLabel for="type" value="Type *" />
|
||||||
|
<p:selectOneMenu id="type" value="#{model.typeAssociation}" required="true"
|
||||||
|
requiredMessage="Type d'organisation requis.">
|
||||||
|
<f:selectItems value="#{typesItems}" />
|
||||||
|
</p:selectOneMenu>
|
||||||
|
<p:message for="type" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Date de fondation -->
|
||||||
|
<div class="field col-12 md:col-4">
|
||||||
|
<p:outputLabel for="dateFondation" value="Date de fondation" />
|
||||||
|
<p:datePicker id="dateFondation" value="#{model.dateFondation}" pattern="yyyy-MM-dd" showIcon="true" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Email -->
|
||||||
|
<div class="field col-12 md:col-4">
|
||||||
|
<p:outputLabel for="email" value="Email" />
|
||||||
|
<p:inputText id="email" value="#{model.email}" maxlength="200" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Téléphone -->
|
||||||
|
<div class="field col-12 md:col-4">
|
||||||
|
<p:outputLabel for="telephone" value="Téléphone" />
|
||||||
|
<p:inputText id="telephone" value="#{model.telephone}" maxlength="20" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Description -->
|
||||||
|
<div class="field col-12">
|
||||||
|
<p:outputLabel for="description" value="Description" />
|
||||||
|
<p:inputTextarea id="description" value="#{model.description}" rows="3" maxlength="500" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Adresse -->
|
||||||
|
<div class="field col-12">
|
||||||
|
<p:outputLabel for="adresse" value="Adresse" />
|
||||||
|
<p:inputTextarea id="adresse" value="#{model.adresse}" rows="2" maxlength="500" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Ville / Région / Pays -->
|
||||||
|
<div class="field col-12 md:col-4">
|
||||||
|
<p:outputLabel for="ville" value="Ville" />
|
||||||
|
<p:inputText id="ville" value="#{model.ville}" maxlength="100" />
|
||||||
|
</div>
|
||||||
|
<div class="field col-12 md:col-4">
|
||||||
|
<p:outputLabel for="region" value="Région" />
|
||||||
|
<p:inputText id="region" value="#{model.region}" maxlength="100" />
|
||||||
|
</div>
|
||||||
|
<div class="field col-12 md:col-4">
|
||||||
|
<p:outputLabel for="pays" value="Pays" />
|
||||||
|
<p:inputText id="pays" value="#{model.pays}" maxlength="100" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Numéro d'enregistrement -->
|
||||||
|
<div class="field col-12 md:col-6">
|
||||||
|
<p:outputLabel for="numEnreg" value="Numéro d'enregistrement" />
|
||||||
|
<p:inputText id="numEnreg" value="#{model.numeroRegistre}" maxlength="100" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Code postal -->
|
||||||
|
<div class="field col-12 md:col-6">
|
||||||
|
<p:outputLabel for="codePostal" value="Code postal" />
|
||||||
|
<p:inputText id="codePostal" value="#{model.codePostal}" maxlength="10" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Site web -->
|
||||||
|
<div class="field col-12 md:col-6">
|
||||||
|
<p:outputLabel for="siteWeb" value="Site web" />
|
||||||
|
<p:inputText id="siteWeb" value="#{model.siteWeb}" maxlength="500" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</ui:fragment>
|
||||||
Reference in New Issue
Block a user