fix(api): 1.0.4 — OrganisationSummaryResponse record→@Data (compat JSF/EL), version bump

This commit is contained in:
dahoud
2026-04-11 02:00:07 +00:00
parent 5fa4711a8f
commit 43678c8ae9
21 changed files with 897 additions and 238 deletions

View File

@@ -6,7 +6,7 @@
<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.4</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>UnionFlow - Parent</name> <name>UnionFlow - Parent</name>
@@ -60,6 +60,7 @@
<artifactId>unionflow-server-api</artifactId> <artifactId>unionflow-server-api</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>

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.4</version>
<relativePath>parent-pom.xml</relativePath> <relativePath>parent-pom.xml</relativePath>
</parent> </parent>

View File

@@ -1,13 +1,22 @@
package dev.lions.unionflow.server.api.dto.common; package dev.lions.unionflow.server.api.dto.common;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/** /**
* DTO d'erreur unifié retourné par tous les endpoints REST. * DTO d'erreur unifié retourné par tous les endpoints REST.
* Remplace les ErrorResponse locales dupliquées dans chaque Resource. * Remplace les ErrorResponse locales dupliquées dans chaque Resource.
*/ */
@JsonInclude(JsonInclude.Include.NON_NULL) @JsonInclude(JsonInclude.Include.NON_NULL)
public record ErrorResponse(String message, String error) { @Data
@NoArgsConstructor
@AllArgsConstructor
public class ErrorResponse {
private String message;
private String error;
/** Constructeur pratique avec message uniquement (cas le plus courant). */ /** Constructeur pratique avec message uniquement (cas le plus courant). */
public static ErrorResponse of(String message) { public static ErrorResponse of(String message) {

View File

@@ -1,7 +1,10 @@
package dev.lions.unionflow.server.api.dto.communication.response; package dev.lions.unionflow.server.api.dto.communication.response;
import dev.lions.unionflow.server.api.enums.communication.ConversationType; import dev.lions.unionflow.server.api.enums.communication.ConversationType;
import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@@ -14,20 +17,23 @@ import java.util.UUID;
* @version 1.0 * @version 1.0
* @since 2026-03-16 * @since 2026-03-16
*/ */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder @Builder
public record ConversationResponse( public class ConversationResponse {
UUID id, private UUID id;
String name, private String name;
String description, private String description;
ConversationType type, private ConversationType type;
List<UUID> participantIds, private List<UUID> participantIds;
UUID organisationId, private UUID organisationId;
MessageResponse lastMessage, private MessageResponse lastMessage;
int unreadCount, private int unreadCount;
boolean isMuted, private boolean muted;
boolean isPinned, private boolean pinned;
boolean isArchived, private boolean archived;
LocalDateTime createdAt, private LocalDateTime createdAt;
LocalDateTime updatedAt, private LocalDateTime updatedAt;
String avatarUrl private String avatarUrl;
) {} }

View File

@@ -3,7 +3,10 @@ package dev.lions.unionflow.server.api.dto.communication.response;
import dev.lions.unionflow.server.api.enums.communication.MessagePriority; import dev.lions.unionflow.server.api.enums.communication.MessagePriority;
import dev.lions.unionflow.server.api.enums.communication.MessageStatus; import dev.lions.unionflow.server.api.enums.communication.MessageStatus;
import dev.lions.unionflow.server.api.enums.communication.MessageType; import dev.lions.unionflow.server.api.enums.communication.MessageType;
import lombok.AllArgsConstructor;
import lombok.Builder; import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@@ -16,24 +19,27 @@ import java.util.UUID;
* @version 1.0 * @version 1.0
* @since 2026-03-16 * @since 2026-03-16
*/ */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder @Builder
public record MessageResponse( public class MessageResponse {
UUID id, private UUID id;
UUID conversationId, private UUID conversationId;
UUID senderId, private UUID senderId;
String senderName, private String senderName;
String senderAvatar, private String senderAvatar;
String content, private String content;
MessageType type, private MessageType type;
MessageStatus status, private MessageStatus status;
MessagePriority priority, private MessagePriority priority;
List<UUID> recipientIds, private List<UUID> recipientIds;
List<String> recipientRoles, private List<String> recipientRoles;
UUID organisationId, private UUID organisationId;
LocalDateTime createdAt, private LocalDateTime createdAt;
LocalDateTime readAt, private LocalDateTime readAt;
List<String> attachments, private List<String> attachments;
boolean isEdited, private boolean edited;
LocalDateTime editedAt, private LocalDateTime editedAt;
boolean isDeleted private boolean deleted;
) {} }

View File

@@ -1,5 +1,9 @@
package dev.lions.unionflow.server.api.dto.cotisation.response; package dev.lions.unionflow.server.api.dto.cotisation.response;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.UUID; import java.util.UUID;
@@ -7,29 +11,32 @@ import java.util.UUID;
/** /**
* Réponse simplifiée pour les listes de cotisations. * Réponse simplifiée pour les listes de cotisations.
* *
* @param id Identifiant unique.
* @param numeroReference Référence unique.
* @param nomMembre Nom du membre.
* @param montantDu Montant total dû.
* @param montantPaye Montant déjà réglé.
* @param statut Statut actuel (code).
* @param statutLibelle Libellé du statut pour l'UI.
* @param dateEcheance Date limite.
* @param annee Année concernée.
* @param actif Indique si l'entité est active.
* @author UnionFlow Team * @author UnionFlow Team
* @version 1.0 * @version 1.0
* @since 2026-02-22 * @since 2026-02-22
*/ */
public record CotisationSummaryResponse( @Data
UUID id, @NoArgsConstructor
String numeroReference, @AllArgsConstructor
String nomMembre, public class CotisationSummaryResponse {
BigDecimal montantDu, /** Identifiant unique. */
BigDecimal montantPaye, private UUID id;
String statut, /** Référence unique. */
String statutLibelle, private String numeroReference;
LocalDate dateEcheance, /** Nom du membre. */
Integer annee, private String nomMembre;
Boolean actif) { /** Montant total dû. */
private BigDecimal montantDu;
/** Montant déjà réglé. */
private BigDecimal montantPaye;
/** Statut actuel (code). */
private String statut;
/** Libellé du statut pour l'UI. */
private String statutLibelle;
/** Date limite. */
private LocalDate dateEcheance;
/** Année concernée. */
private Integer annee;
/** Indique si l'entité est active. */
private Boolean actif;
} }

View File

@@ -1,5 +1,9 @@
package dev.lions.unionflow.server.api.dto.dashboard; package dev.lions.unionflow.server.api.dto.dashboard;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
@@ -10,39 +14,42 @@ import java.time.LocalDate;
* @author UnionFlow Team * @author UnionFlow Team
* @version 1.0 * @version 1.0
*/ */
public record MembreDashboardSyntheseResponse( @Data
String prenom, @NoArgsConstructor
String nom, @AllArgsConstructor
LocalDate dateInscription, public class MembreDashboardSyntheseResponse implements Serializable {
private String prenom;
private String nom;
private LocalDate dateInscription;
// Cotisations // Cotisations
BigDecimal mesCotisationsPaiement, private BigDecimal mesCotisationsPaiement;
/** Total des cotisations payées sur l'année en cours (pour affichage dashboard). */ /** Total des cotisations payées sur l'année en cours (pour affichage dashboard). */
BigDecimal totalCotisationsPayeesAnnee, private BigDecimal totalCotisationsPayeesAnnee;
/** Total des cotisations payées tout temps (pour la carte « Contribution Totale »). */ /** Total des cotisations payées tout temps (pour la carte « Contribution Totale »). */
BigDecimal totalCotisationsPayeesToutTemps, private BigDecimal totalCotisationsPayeesToutTemps;
/** Nombre de cotisations PAYÉES (pour la carte « Cotisations »). */ /** Nombre de cotisations PAYÉES (pour la carte « Cotisations »). */
Integer nombreCotisationsPayees, private Integer nombreCotisationsPayees;
String statutCotisations, private String statutCotisations;
/** Taux de cotisation en % (0-100). Calculé sur l'année courante ou toutes années si pas de cotisation 2026. */ /** Taux de cotisation en % (0-100). Calculé sur l'année courante ou toutes années si pas de cotisation 2026. */
Integer tauxCotisationsPerso, private Integer tauxCotisationsPerso;
/** Nombre TOTAL de cotisations (toutes années, tous statuts) — pour calcul du taux d'engagement. */ /** Nombre TOTAL de cotisations (toutes années, tous statuts) — pour calcul du taux d'engagement. */
Integer nombreCotisationsTotal, private Integer nombreCotisationsTotal;
// Epargne // Epargne
BigDecimal monSoldeEpargne, private BigDecimal monSoldeEpargne;
BigDecimal evolutionEpargneNombre, private BigDecimal evolutionEpargneNombre;
String evolutionEpargne, private String evolutionEpargne;
Integer objectifEpargne, private Integer objectifEpargne;
// Evenements // Evenements
Integer mesEvenementsInscrits, private Integer mesEvenementsInscrits;
Integer evenementsAVenir, private Integer evenementsAVenir;
Integer tauxParticipationPerso, private Integer tauxParticipationPerso;
// Aides // Aides
Integer mesDemandesAide, private Integer mesDemandesAide;
Integer aidesEnCours, private Integer aidesEnCours;
Integer tauxAidesApprouvees) implements Serializable { private Integer tauxAidesApprouvees;
} }

View File

@@ -1,5 +1,9 @@
package dev.lions.unionflow.server.api.dto.membre; package dev.lions.unionflow.server.api.dto.membre;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate; import java.time.LocalDate;
@@ -18,57 +22,55 @@ import java.time.LocalDate;
* <li>Capacité d'emprunt estimée (3× l'épargne — règle mutuelle classique)</li> * <li>Capacité d'emprunt estimée (3× l'épargne — règle mutuelle classique)</li>
* </ul> * </ul>
* *
* @param numeroMembre Numéro unique du membre sur la plateforme (ex: MUF-2026-001)
* @param nomComplet Nom et prénom du membre
* @param organisationNom Nom de l'organisation principale (ou null si aucune)
* @param dateAdhesion Date d'inscription sur la plateforme
* @param statutCompte Statut actuel du compte (ACTIF, SUSPENDU, etc.)
*
* @param soldeCotisations Total des cotisations payées (toutes années confondues)
* @param soldeEpargne Solde disponible sur l'ensemble des comptes épargne actifs
* @param soldeBloque Montant bloqué (garantie de prêt)
* @param soldeTotalDisponible soldeCotisations + soldeEpargne - soldeBloque
* @param encoursCreditTotal Montant total des prêts en cours (0 si fonctionnalité non encore activée)
* @param capaciteEmprunt Capacité d'emprunt estimée (3 × soldeEpargne selon règle mutuelle standard)
*
* @param nombreCotisationsPayees Nombre de cotisations payées (historique complet)
* @param nombreCotisationsTotal Nombre total de cotisations (payées + en attente + retard)
* @param nombreCotisationsEnRetard Nombre de cotisations en retard
* @param tauxEngagement Taux de paiement global en % (0-100)
*
* @param nombreComptesEpargne Nombre de comptes épargne actifs
* @param dateCalcul Date/heure du calcul (pour information client)
*
* @author UnionFlow Team * @author UnionFlow Team
* @version 1.0 * @version 1.0
*/ */
public record CompteAdherentResponse( @Data
@NoArgsConstructor
@AllArgsConstructor
public class CompteAdherentResponse implements Serializable {
// ── Identité ────────────────────────────────────────────────────────── // ── Identité ──────────────────────────────────────────────────────────
String numeroMembre, /** Numéro unique du membre sur la plateforme (ex: MUF-2026-001) */
String nomComplet, private String numeroMembre;
String organisationNom, /** Nom et prénom du membre */
LocalDate dateAdhesion, private String nomComplet;
String statutCompte, /** Nom de l'organisation principale (ou null si aucune) */
private String organisationNom;
/** Date d'inscription sur la plateforme */
private LocalDate dateAdhesion;
/** Statut actuel du compte (ACTIF, SUSPENDU, etc.) */
private String statutCompte;
// ── Soldes ──────────────────────────────────────────────────────────── // ── Soldes ────────────────────────────────────────────────────────────
BigDecimal soldeCotisations, /** Total des cotisations payées (toutes années confondues) */
BigDecimal soldeEpargne, private BigDecimal soldeCotisations;
BigDecimal soldeBloque, /** Solde disponible sur l'ensemble des comptes épargne actifs */
BigDecimal soldeTotalDisponible, private BigDecimal soldeEpargne;
BigDecimal encoursCreditTotal, /** Montant bloqué (garantie de prêt) */
BigDecimal capaciteEmprunt, private BigDecimal soldeBloque;
/** soldeCotisations + soldeEpargne - soldeBloque */
private BigDecimal soldeTotalDisponible;
/** Montant total des prêts en cours (0 si fonctionnalité non encore activée) */
private BigDecimal encoursCreditTotal;
/** Capacité d'emprunt estimée (3 × soldeEpargne selon règle mutuelle standard) */
private BigDecimal capaciteEmprunt;
// ── Cotisations ─────────────────────────────────────────────────────── // ── Cotisations ───────────────────────────────────────────────────────
Integer nombreCotisationsPayees, /** Nombre de cotisations payées (historique complet) */
Integer nombreCotisationsTotal, private Integer nombreCotisationsPayees;
Integer nombreCotisationsEnRetard, /** Nombre total de cotisations (payées + en attente + retard) */
Integer tauxEngagement, private Integer nombreCotisationsTotal;
/** Nombre de cotisations en retard */
private Integer nombreCotisationsEnRetard;
/** Taux de paiement global en % (0-100) */
private Integer tauxEngagement;
// ── Épargne ─────────────────────────────────────────────────────────── // ── Épargne ───────────────────────────────────────────────────────────
Integer nombreComptesEpargne, /** Nombre de comptes épargne actifs */
private Integer nombreComptesEpargne;
// ── Méta ────────────────────────────────────────────────────────────── // ── Méta ──────────────────────────────────────────────────────────────
LocalDate dateCalcul /** Date/heure du calcul (pour information client) */
private LocalDate dateCalcul;
) implements Serializable {} }

View File

@@ -1,5 +1,9 @@
package dev.lions.unionflow.server.api.dto.membre.response; package dev.lions.unionflow.server.api.dto.membre.response;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
@@ -7,81 +11,56 @@ import java.util.UUID;
/** /**
* DTO de réponse résumé pour Membre (listes et optimisations). * DTO de réponse résumé pour Membre (listes et optimisations).
* *
* <p>Ce record expose des méthodes calculées pour la compatibilité JSF EL : * <p>Classe JavaBean pour compatibilité JSF EL (EL cherche getXxx()).
* {@link #nomComplet()}, {@link #statut()}, {@link #typeMembre()}, etc. * Expose également des propriétés calculées (nomComplet, statut, typeMembre, etc.)
*/ */
public record MembreSummaryResponse( @Data
UUID id, @NoArgsConstructor
String numeroMembre, @AllArgsConstructor
String prenom, public class MembreSummaryResponse {
String nom,
String email,
String telephone,
String profession,
String statutCompte,
String statutCompteLibelle,
String statutCompteSeverity,
Boolean actif,
List<String> roles,
UUID organisationId,
String organisationNom,
LocalDate dateAdhesion) {
// ── Getters JavaBean pour compatibilité JSF EL (EL cherche getXxx()) ────── private UUID id;
private String numeroMembre;
public UUID getId() { return id; } private String prenom;
public String getNumeroMembre() { return numeroMembre; } private String nom;
public String getPrenom() { return prenom; } private String email;
public String getNom() { return nom; } private String telephone;
public String getEmail() { return email; } private String profession;
public String getTelephone() { return telephone; } private String statutCompte;
public String getProfession() { return profession; } private String statutCompteLibelle;
public String getStatutCompte() { return statutCompte; } private String statutCompteSeverity;
public String getStatutCompteLibelle() { return statutCompteLibelle; } private Boolean actif;
public String getStatutCompteSeverity() { return statutCompteSeverity; } private List<String> roles;
public Boolean getActif() { return actif; } private UUID organisationId;
public boolean isActif() { return Boolean.TRUE.equals(actif); } private String organisationNom;
public List<String> getRoles() { return roles; } private LocalDate dateAdhesion;
public UUID getOrganisationId() { return organisationId; }
public String getOrganisationNom() { return organisationNom; }
public LocalDate getDateAdhesion() { return dateAdhesion; }
// Getters JavaBean pour les propriétés calculées
public String getNomComplet() { return nomComplet(); }
public String getStatut() { return statut(); }
public String getStatutLibelle() { return statutLibelle(); }
public String getStatutSeverity() { return statutSeverity(); }
public String getStatutIcon() { return statutIcon(); }
public String getTypeMembre() { return typeMembre(); }
public String getTypeSeverity() { return typeSeverity(); }
public String getTypeIcon() { return typeIcon(); }
// ── Propriétés calculées pour la compatibilité JSF EL ────────────────── // ── Propriétés calculées pour la compatibilité JSF EL ──────────────────
/** Prénom + Nom concaténés. */ /** Prénom + Nom concaténés. */
public String nomComplet() { public String getNomComplet() {
String p = prenom != null ? prenom.trim() : ""; String p = prenom != null ? prenom.trim() : "";
String n = nom != null ? nom.trim() : ""; String n = nom != null ? nom.trim() : "";
return (p + " " + n).trim(); return (p + " " + n).trim();
} }
/** Alias de {@link #statutCompte()} pour #{membre.statut}. */ /** Alias de {@link #getStatutCompte()} pour #{membre.statut}. */
public String statut() { public String getStatut() {
return statutCompte; return statutCompte;
} }
/** Alias de {@link #statutCompteLibelle()} pour #{membre.statutLibelle}. */ /** Alias de {@link #getStatutCompteLibelle()} pour #{membre.statutLibelle}. */
public String statutLibelle() { public String getStatutLibelle() {
return statutCompteLibelle; return statutCompteLibelle;
} }
/** Alias de {@link #statutCompteSeverity()} pour #{membre.statutSeverity}. */ /** Alias de {@link #getStatutCompteSeverity()} pour #{membre.statutSeverity}. */
public String statutSeverity() { public String getStatutSeverity() {
return statutCompteSeverity; return statutCompteSeverity;
} }
/** Icône PrimeIcons calculée depuis {@link #statutCompte()}. */ /** Icône PrimeIcons calculée depuis {@link #getStatutCompte()}. */
public String statutIcon() { public String getStatutIcon() {
if (statutCompte == null) return "pi pi-question-circle"; if (statutCompte == null) return "pi pi-question-circle";
return switch (statutCompte) { return switch (statutCompte) {
case "ACTIF" -> "pi pi-check-circle"; case "ACTIF" -> "pi pi-check-circle";
@@ -92,8 +71,8 @@ public record MembreSummaryResponse(
}; };
} }
/** Libellé du rôle principal calculé depuis {@link #roles()}. */ /** Libellé du rôle principal calculé depuis {@link #getRoles()}. */
public String typeMembre() { public String getTypeMembre() {
if (roles == null || roles.isEmpty()) return "Membre"; if (roles == null || roles.isEmpty()) return "Membre";
if (roles.contains("PRESIDENT")) return "Président"; if (roles.contains("PRESIDENT")) return "Président";
if (roles.contains("VICE_PRESIDENT")) return "Vice-Président"; if (roles.contains("VICE_PRESIDENT")) return "Vice-Président";
@@ -104,8 +83,8 @@ public record MembreSummaryResponse(
return "Membre"; return "Membre";
} }
/** Severity PrimeUI calculée depuis {@link #roles()}. */ /** Severity PrimeUI calculée depuis {@link #getRoles()}. */
public String typeSeverity() { public String getTypeSeverity() {
if (roles == null || roles.isEmpty()) return "secondary"; if (roles == null || roles.isEmpty()) return "secondary";
if (roles.contains("PRESIDENT")) return "primary"; if (roles.contains("PRESIDENT")) return "primary";
if (roles.contains("VICE_PRESIDENT")) return "primary"; if (roles.contains("VICE_PRESIDENT")) return "primary";
@@ -116,8 +95,8 @@ public record MembreSummaryResponse(
return "secondary"; return "secondary";
} }
/** Icône PrimeIcons calculée depuis {@link #roles()}. */ /** Icône PrimeIcons calculée depuis {@link #getRoles()}. */
public String typeIcon() { public String getTypeIcon() {
if (roles == null || roles.isEmpty()) return "pi pi-user"; if (roles == null || roles.isEmpty()) return "pi pi-user";
if (roles.contains("PRESIDENT")) return "pi pi-star"; if (roles.contains("PRESIDENT")) return "pi pi-star";
if (roles.contains("VICE_PRESIDENT")) return "pi pi-star"; if (roles.contains("VICE_PRESIDENT")) return "pi pi-star";

View File

@@ -1,23 +1,31 @@
package dev.lions.unionflow.server.api.dto.organisation.response; package dev.lions.unionflow.server.api.dto.organisation.response;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.UUID; import java.util.UUID;
/** /**
* Résumé d'une organisation pour les listes. * Résumé d'une organisation pour les listes.
* Classe JavaBean (pas un record) pour compatibilité JSF/EL (getNom() requis).
* *
* @author UnionFlow Team * @author UnionFlow Team
* @version 3.0 * @version 3.1
* @since 2026-02-22 * @since 2026-02-22
*/ */
public record OrganisationSummaryResponse( @Data
UUID id, @NoArgsConstructor
String nom, @AllArgsConstructor
String nomCourt, public class OrganisationSummaryResponse {
String typeOrganisation, private UUID id;
String typeOrganisationLibelle, private String nom;
String statut, private String nomCourt;
String statutLibelle, private String typeOrganisation;
String statutSeverity, private String typeOrganisationLibelle;
Integer nombreMembres, private String statut;
Boolean actif) { private String statutLibelle;
private String statutSeverity;
private Integer nombreMembres;
private Boolean actif;
} }

View File

@@ -1,24 +1,31 @@
package dev.lions.unionflow.server.api.dto.paiement.response; package dev.lions.unionflow.server.api.dto.paiement.response;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.UUID; import java.util.UUID;
import lombok.Builder;
/** /**
* Réponse du polling de statut d'une IntentionPaiement Wave. * Réponse du polling de statut d'une IntentionPaiement Wave.
* Utilisée par le web pour savoir si le paiement est confirmé. * Utilisée par le web pour savoir si le paiement est confirmé.
*/ */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder @Builder
public record IntentionStatutResponse( public class IntentionStatutResponse {
UUID intentionId, private UUID intentionId;
/** INITIEE | EN_COURS | COMPLETEE | EXPIREE | ECHOUEE */ /** INITIEE | EN_COURS | COMPLETEE | EXPIREE | ECHOUEE */
String statut, private String statut;
/** URL à encoder en QR code (wave_launch_url Wave Checkout) */ /** URL à encoder en QR code (wave_launch_url Wave Checkout) */
String waveLaunchUrl, private String waveLaunchUrl;
String waveCheckoutSessionId, private String waveCheckoutSessionId;
/** ID de transaction Wave (TCN...) — disponible quand COMPLETEE */ /** ID de transaction Wave (TCN...) — disponible quand COMPLETEE */
String waveTransactionId, private String waveTransactionId;
BigDecimal montant, private BigDecimal montant;
String referenceCotisation, private String referenceCotisation;
String message private String message;
) {} }

View File

@@ -1,5 +1,9 @@
package dev.lions.unionflow.server.api.dto.paiement.response; package dev.lions.unionflow.server.api.dto.paiement.response;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.UUID; import java.util.UUID;
@@ -11,14 +15,17 @@ import java.util.UUID;
* @author UnionFlow Team * @author UnionFlow Team
* @version 3.0 * @version 3.0
*/ */
public record PaiementSummaryResponse( @Data
UUID id, @NoArgsConstructor
String numeroReference, @AllArgsConstructor
BigDecimal montant, public class PaiementSummaryResponse {
String codeDevise, private UUID id;
String methodePaiementLibelle, private String numeroReference;
String statutPaiement, private BigDecimal montant;
String statutPaiementLibelle, private String codeDevise;
String statutPaiementSeverity, private String methodePaiementLibelle;
LocalDateTime datePaiement) { private String statutPaiement;
private String statutPaiementLibelle;
private String statutPaiementSeverity;
private LocalDateTime datePaiement;
} }

View File

@@ -52,5 +52,17 @@ public record CreateTypeReferenceRequest(
Boolean estSysteme, Boolean estSysteme,
/** UUID de l'organisation (null = global). */ /** UUID de l'organisation (null = global). */
UUID organisationId) { UUID organisationId,
/**
* Catégorie fonctionnelle (ex: FINANCIER_SOLIDAIRE).
* Obligatoire pour domaine=TYPE_ORGANISATION.
*/
@Size(max = 50) String categorie,
/**
* Modules métier CSV (ex: "MEMBRES,COTISATIONS,TONTINE,FINANCE").
* Obligatoire pour domaine=TYPE_ORGANISATION.
*/
String modulesRequis) {
} }

View File

@@ -41,5 +41,11 @@ public record UpdateTypeReferenceRequest(
Boolean estDefaut, Boolean estDefaut,
/** Nouvel état actif/inactif (optionnel). */ /** Nouvel état actif/inactif (optionnel). */
Boolean actif) { Boolean actif,
/** Nouvelle catégorie fonctionnelle (optionnel). */
@Size(max = 50) String categorie,
/** Nouveaux modules requis CSV (optionnel). */
String modulesRequis) {
} }

View File

@@ -60,4 +60,19 @@ public class TypeReferenceResponse extends BaseResponse {
/** UUID de l'organisation (null = global). */ /** UUID de l'organisation (null = global). */
private UUID organisationId; private UUID organisationId;
/**
* Catégorie fonctionnelle du type d'organisation.
* Valeurs: ASSOCIATIF, FINANCIER_SOLIDAIRE, RELIGIEUX, PROFESSIONNEL, RESEAU_FEDERATION.
* Uniquement pertinent pour domaine=TYPE_ORGANISATION.
*/
private String categorie;
/**
* Modules métier activés pour ce type d'organisation (CSV).
* Exemple: "MEMBRES,COTISATIONS,TONTINE,FINANCE"
* Utilisé pour initialiser Organisation.modulesActifs à la création.
* Uniquement pertinent pour domaine=TYPE_ORGANISATION.
*/
private String modulesRequis;
} }

View File

@@ -0,0 +1,32 @@
package dev.lions.unionflow.server.api.dto.common;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
class ErrorResponseTest {
@Test
void testOf_messageUniquement() {
ErrorResponse response = ErrorResponse.of("Une erreur est survenue");
assertThat(response.message()).isEqualTo("Une erreur est survenue");
assertThat(response.error()).isNull();
}
@Test
void testOfError_errorUniquement() {
ErrorResponse response = ErrorResponse.ofError("NOT_FOUND");
assertThat(response.message()).isNull();
assertThat(response.error()).isEqualTo("NOT_FOUND");
}
@Test
void testConstructeurComplet() {
ErrorResponse response = new ErrorResponse("Message d'erreur", "VALIDATION_ERROR");
assertThat(response.message()).isEqualTo("Message d'erreur");
assertThat(response.error()).isEqualTo("VALIDATION_ERROR");
}
}

View File

@@ -228,6 +228,28 @@ class CotisationResponseTest {
} }
} }
@Nested
@DisplayName("Alias getMethodePaiementLibelle")
class AliasMethodePaiement {
@Test
@DisplayName("getMethodePaiementLibelle retourne modePaiementLibelle")
void getMethodePaiementLibelle_retourneModePaiementLibelle() {
CotisationResponse r = CotisationResponse.builder()
.modePaiementLibelle("Wave Money")
.build();
assertThat(r.getMethodePaiementLibelle()).isEqualTo("Wave Money");
}
@Test
@DisplayName("getMethodePaiementLibelle retourne null si non renseigné")
void getMethodePaiementLibelle_null() {
CotisationResponse r = CotisationResponse.builder().build();
assertThat(r.getMethodePaiementLibelle()).isNull();
}
}
@Nested @Nested
@DisplayName("Builder complet") @DisplayName("Builder complet")
class BuilderComplet { class BuilderComplet {

View File

@@ -0,0 +1,344 @@
package dev.lions.unionflow.server.api.dto.membre.response;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@DisplayName("Tests MembreResponse")
class MembreResponseTest {
@Nested
@DisplayName("Builder et getters de base")
class BuilderGetters {
@Test
@DisplayName("builder remplit tous les champs")
void builder_tousLesChamps() {
UUID id = UUID.randomUUID();
UUID keycloakId = UUID.randomUUID();
UUID orgId = UUID.randomUUID();
LocalDate dateNaissance = LocalDate.of(1990, 5, 15);
LocalDate dateAdhesion = LocalDate.of(2024, 1, 10);
MembreResponse m = MembreResponse.builder()
.numeroMembre("M-001")
.keycloakId(keycloakId)
.prenom("Jean")
.nom("Dupont")
.nomComplet("Jean Dupont")
.email("jean.dupont@example.com")
.telephone("+225001122334")
.telephoneWave("+225001122334")
.dateNaissance(dateNaissance)
.age(35)
.profession("Ingénieur")
.photoUrl("https://example.com/photo.jpg")
.statutMatrimonial("MARIE")
.statutMatrimonialLibelle("Marié")
.nationalite("Ivoirienne")
.typeIdentite("CNI")
.typeIdentiteLibelle("Carte Nationale d'Identité")
.numeroIdentite("CI12345")
.niveauVigilanceKyc("STANDARD")
.statutKyc("VERIFIE")
.dateVerificationIdentite(LocalDate.of(2024, 2, 1))
.statutCompte("ACTIF")
.statutCompteLibelle("Actif")
.statutCompteSeverity("success")
.roles(Arrays.asList("MEMBRE"))
.organisationId(orgId)
.organisationNom("Club Lions Abidjan")
.dateAdhesion(dateAdhesion)
.adresse("123 Rue de la Paix")
.ville("Abidjan")
.codePostal("00225")
.notes("Membre actif")
.nombreEvenementsParticipes(5)
.motDePasseTemporaire("TempPass123!")
.build();
m.setId(id);
assertThat(m.getId()).isEqualTo(id);
assertThat(m.getNumeroMembre()).isEqualTo("M-001");
assertThat(m.getKeycloakId()).isEqualTo(keycloakId);
assertThat(m.getPrenom()).isEqualTo("Jean");
assertThat(m.getNom()).isEqualTo("Dupont");
assertThat(m.getNomComplet()).isEqualTo("Jean Dupont");
assertThat(m.getEmail()).isEqualTo("jean.dupont@example.com");
assertThat(m.getTelephone()).isEqualTo("+225001122334");
assertThat(m.getTelephoneWave()).isEqualTo("+225001122334");
assertThat(m.getDateNaissance()).isEqualTo(dateNaissance);
assertThat(m.getAge()).isEqualTo(35);
assertThat(m.getProfession()).isEqualTo("Ingénieur");
assertThat(m.getPhotoUrl()).isEqualTo("https://example.com/photo.jpg");
assertThat(m.getStatutMatrimonial()).isEqualTo("MARIE");
assertThat(m.getStatutMatrimonialLibelle()).isEqualTo("Marié");
assertThat(m.getNationalite()).isEqualTo("Ivoirienne");
assertThat(m.getTypeIdentite()).isEqualTo("CNI");
assertThat(m.getTypeIdentiteLibelle()).isEqualTo("Carte Nationale d'Identité");
assertThat(m.getNumeroIdentite()).isEqualTo("CI12345");
assertThat(m.getNiveauVigilanceKyc()).isEqualTo("STANDARD");
assertThat(m.getStatutKyc()).isEqualTo("VERIFIE");
assertThat(m.getDateVerificationIdentite()).isEqualTo(LocalDate.of(2024, 2, 1));
assertThat(m.getStatutCompte()).isEqualTo("ACTIF");
assertThat(m.getStatutCompteLibelle()).isEqualTo("Actif");
assertThat(m.getStatutCompteSeverity()).isEqualTo("success");
assertThat(m.getRoles()).containsExactly("MEMBRE");
assertThat(m.getOrganisationId()).isEqualTo(orgId);
assertThat(m.getOrganisationNom()).isEqualTo("Club Lions Abidjan");
assertThat(m.getDateAdhesion()).isEqualTo(dateAdhesion);
assertThat(m.getAdresse()).isEqualTo("123 Rue de la Paix");
assertThat(m.getVille()).isEqualTo("Abidjan");
assertThat(m.getCodePostal()).isEqualTo("00225");
assertThat(m.getNotes()).isEqualTo("Membre actif");
assertThat(m.getNombreEvenementsParticipes()).isEqualTo(5);
assertThat(m.getMotDePasseTemporaire()).isEqualTo("TempPass123!");
}
@Test
@DisplayName("constructeur vide produit un objet non null")
void constructeurVide() {
MembreResponse m = new MembreResponse();
assertThat(m).isNotNull();
assertThat(m.getPrenom()).isNull();
assertThat(m.getNom()).isNull();
}
@Test
@DisplayName("setters mettent à jour les champs")
void setters_mettentAJour() {
MembreResponse m = new MembreResponse();
m.setPrenom("Marie");
m.setNom("Martin");
m.setEmail("marie.martin@example.com");
m.setStatutCompte("INACTIF");
m.setStatutCompteSeverity("secondary");
m.setDateAdhesion(LocalDate.of(2023, 6, 1));
assertThat(m.getPrenom()).isEqualTo("Marie");
assertThat(m.getNom()).isEqualTo("Martin");
assertThat(m.getEmail()).isEqualTo("marie.martin@example.com");
}
}
@Nested
@DisplayName("getInitiales")
class GetInitiales {
@Test
@DisplayName("retourne initiales quand prénom et nom sont renseignés")
void initiales_prenomNomPresents() {
MembreResponse m = MembreResponse.builder().prenom("Jean").nom("Dupont").build();
assertThat(m.getInitiales()).isEqualTo("JD");
}
@Test
@DisplayName("retourne initiale du prénom uniquement si nom null")
void initiales_nomNull() {
MembreResponse m = MembreResponse.builder().prenom("Jean").nom(null).build();
assertThat(m.getInitiales()).isEqualTo("J");
}
@Test
@DisplayName("retourne initiale du nom uniquement si prénom null")
void initiales_prenomNull() {
MembreResponse m = MembreResponse.builder().prenom(null).nom("Dupont").build();
assertThat(m.getInitiales()).isEqualTo("D");
}
@Test
@DisplayName("retourne chaîne vide si prénom et nom vides")
void initiales_prenomNomVides() {
MembreResponse m = MembreResponse.builder().prenom("").nom("").build();
assertThat(m.getInitiales()).isEmpty();
}
@Test
@DisplayName("retourne chaîne vide si prénom et nom null")
void initiales_prenomNomNull() {
MembreResponse m = new MembreResponse();
assertThat(m.getInitiales()).isEmpty();
}
}
@Nested
@DisplayName("getDateAdhesionFormatee")
class GetDateAdhesionFormatee {
@Test
@DisplayName("retourne null quand dateAdhesion est null")
void dateAdhesion_null() {
MembreResponse m = new MembreResponse();
assertThat(m.getDateAdhesionFormatee()).isNull();
}
@Test
@DisplayName("retourne date formatée dd/MM/yyyy")
void dateAdhesion_formatee() {
MembreResponse m = MembreResponse.builder().dateAdhesion(LocalDate.of(2024, 3, 15)).build();
assertThat(m.getDateAdhesionFormatee()).isEqualTo("15/03/2024");
}
}
@Nested
@DisplayName("getStatut et getStatutSeverity")
class AliasStatut {
@Test
@DisplayName("getStatut retourne statutCompte")
void getStatut() {
MembreResponse m = MembreResponse.builder().statutCompte("ACTIF").build();
assertThat(m.getStatut()).isEqualTo("ACTIF");
}
@Test
@DisplayName("getStatutSeverity retourne statutCompteSeverity")
void getStatutSeverity() {
MembreResponse m = MembreResponse.builder().statutCompteSeverity("warning").build();
assertThat(m.getStatutSeverity()).isEqualTo("warning");
}
}
@Nested
@DisplayName("getTypeMembre")
class GetTypeMembre {
@Test
@DisplayName("retourne Membre quand roles null")
void typeMembre_rolesNull() {
MembreResponse m = new MembreResponse();
assertThat(m.getTypeMembre()).isEqualTo("Membre");
}
@Test
@DisplayName("retourne Membre quand roles vide")
void typeMembre_rolesVide() {
MembreResponse m = MembreResponse.builder().roles(Collections.emptyList()).build();
assertThat(m.getTypeMembre()).isEqualTo("Membre");
}
@Test
@DisplayName("retourne Président quand rôle PRESIDENT")
void typeMembre_president() {
MembreResponse m = MembreResponse.builder().roles(List.of("PRESIDENT")).build();
assertThat(m.getTypeMembre()).isEqualTo("Président");
}
@Test
@DisplayName("retourne Vice-Président quand rôle VICE_PRESIDENT")
void typeMembre_vicePresident() {
MembreResponse m = MembreResponse.builder().roles(List.of("VICE_PRESIDENT")).build();
assertThat(m.getTypeMembre()).isEqualTo("Vice-Président");
}
@Test
@DisplayName("retourne Secrétaire quand rôle SECRETAIRE")
void typeMembre_secretaire() {
MembreResponse m = MembreResponse.builder().roles(List.of("SECRETAIRE")).build();
assertThat(m.getTypeMembre()).isEqualTo("Secrétaire");
}
@Test
@DisplayName("retourne Trésorier quand rôle TRESORIER")
void typeMembre_tresorier() {
MembreResponse m = MembreResponse.builder().roles(List.of("TRESORIER")).build();
assertThat(m.getTypeMembre()).isEqualTo("Trésorier");
}
@Test
@DisplayName("retourne Administrateur quand rôle ADMIN_ORGANISATION")
void typeMembre_adminOrganisation() {
MembreResponse m = MembreResponse.builder().roles(List.of("ADMIN_ORGANISATION")).build();
assertThat(m.getTypeMembre()).isEqualTo("Administrateur");
}
@Test
@DisplayName("retourne Modérateur quand rôle MODERATEUR")
void typeMembre_moderateur() {
MembreResponse m = MembreResponse.builder().roles(List.of("MODERATEUR")).build();
assertThat(m.getTypeMembre()).isEqualTo("Modérateur");
}
@Test
@DisplayName("retourne Membre pour rôle inconnu")
void typeMembre_roleInconnu() {
MembreResponse m = MembreResponse.builder().roles(List.of("AUTRE_ROLE")).build();
assertThat(m.getTypeMembre()).isEqualTo("Membre");
}
}
@Nested
@DisplayName("getTypeSeverity")
class GetTypeSeverity {
@Test
@DisplayName("retourne secondary quand roles null")
void typeSeverity_rolesNull() {
MembreResponse m = new MembreResponse();
assertThat(m.getTypeSeverity()).isEqualTo("secondary");
}
@Test
@DisplayName("retourne secondary quand roles vide")
void typeSeverity_rolesVide() {
MembreResponse m = MembreResponse.builder().roles(Collections.emptyList()).build();
assertThat(m.getTypeSeverity()).isEqualTo("secondary");
}
@Test
@DisplayName("retourne primary pour PRESIDENT")
void typeSeverity_president() {
MembreResponse m = MembreResponse.builder().roles(List.of("PRESIDENT")).build();
assertThat(m.getTypeSeverity()).isEqualTo("primary");
}
@Test
@DisplayName("retourne primary pour VICE_PRESIDENT")
void typeSeverity_vicePresident() {
MembreResponse m = MembreResponse.builder().roles(List.of("VICE_PRESIDENT")).build();
assertThat(m.getTypeSeverity()).isEqualTo("primary");
}
@Test
@DisplayName("retourne info pour SECRETAIRE")
void typeSeverity_secretaire() {
MembreResponse m = MembreResponse.builder().roles(List.of("SECRETAIRE")).build();
assertThat(m.getTypeSeverity()).isEqualTo("info");
}
@Test
@DisplayName("retourne warning pour TRESORIER")
void typeSeverity_tresorier() {
MembreResponse m = MembreResponse.builder().roles(List.of("TRESORIER")).build();
assertThat(m.getTypeSeverity()).isEqualTo("warning");
}
@Test
@DisplayName("retourne danger pour ADMIN_ORGANISATION")
void typeSeverity_adminOrganisation() {
MembreResponse m = MembreResponse.builder().roles(List.of("ADMIN_ORGANISATION")).build();
assertThat(m.getTypeSeverity()).isEqualTo("danger");
}
@Test
@DisplayName("retourne warning pour MODERATEUR")
void typeSeverity_moderateur() {
MembreResponse m = MembreResponse.builder().roles(List.of("MODERATEUR")).build();
assertThat(m.getTypeSeverity()).isEqualTo("warning");
}
@Test
@DisplayName("retourne secondary pour rôle inconnu")
void typeSeverity_roleInconnu() {
MembreResponse m = MembreResponse.builder().roles(List.of("INCONNU")).build();
assertThat(m.getTypeSeverity()).isEqualTo("secondary");
}
}
}

View File

@@ -37,6 +37,8 @@ class CreateTypeReferenceRequestTest {
.estDefaut(true) .estDefaut(true)
.estSysteme(true) .estSysteme(true)
.organisationId(organisationId) .organisationId(organisationId)
.categorie("FINANCIER_SOLIDAIRE")
.modulesRequis("MEMBRES,COTISATIONS,TONTINE,FINANCE")
.build(); .build();
assertThat(request).isNotNull(); assertThat(request).isNotNull();
@@ -51,6 +53,8 @@ class CreateTypeReferenceRequestTest {
assertThat(request.estDefaut()).isTrue(); assertThat(request.estDefaut()).isTrue();
assertThat(request.estSysteme()).isTrue(); assertThat(request.estSysteme()).isTrue();
assertThat(request.organisationId()).isEqualTo(organisationId); assertThat(request.organisationId()).isEqualTo(organisationId);
assertThat(request.categorie()).isEqualTo("FINANCIER_SOLIDAIRE");
assertThat(request.modulesRequis()).isEqualTo("MEMBRES,COTISATIONS,TONTINE,FINANCE");
} }
@Test @Test

View File

@@ -31,7 +31,9 @@ class UpdateTypeReferenceRequestTest {
"warning", "warning",
5, 5,
true, true,
false false,
"FINANCIER_SOLIDAIRE",
"MEMBRES,COTISATIONS,TONTINE"
); );
assertThat(request).isNotNull(); assertThat(request).isNotNull();
@@ -44,6 +46,8 @@ class UpdateTypeReferenceRequestTest {
assertThat(request.ordreAffichage()).isEqualTo(5); assertThat(request.ordreAffichage()).isEqualTo(5);
assertThat(request.estDefaut()).isTrue(); assertThat(request.estDefaut()).isTrue();
assertThat(request.actif()).isFalse(); assertThat(request.actif()).isFalse();
assertThat(request.categorie()).isEqualTo("FINANCIER_SOLIDAIRE");
assertThat(request.modulesRequis()).isEqualTo("MEMBRES,COTISATIONS,TONTINE");
} }
@Test @Test
@@ -57,11 +61,15 @@ class UpdateTypeReferenceRequestTest {
null, null,
null, null,
null, null,
null,
null,
null null
); );
assertThat(request).isNotNull(); assertThat(request).isNotNull();
assertThat(request.libelle()).isEqualTo("Libellé mis à jour"); assertThat(request.libelle()).isEqualTo("Libellé mis à jour");
assertThat(request.categorie()).isNull();
assertThat(request.modulesRequis()).isNull();
} }
@Test @Test
@@ -76,6 +84,8 @@ class UpdateTypeReferenceRequestTest {
null, null,
null, null,
null, null,
null,
null,
null null
); );
@@ -97,6 +107,8 @@ class UpdateTypeReferenceRequestTest {
null, null,
null, null,
null, null,
null,
null,
null null
); );
@@ -106,6 +118,29 @@ class UpdateTypeReferenceRequestTest {
assertThat(violations).anyMatch(v -> v.getPropertyPath().toString().equals("libelle")); assertThat(violations).anyMatch(v -> v.getPropertyPath().toString().equals("libelle"));
} }
@Test
void testValidation_CategorieTooLong() {
String longCategorie = "A".repeat(51);
UpdateTypeReferenceRequest request = new UpdateTypeReferenceRequest(
null,
null,
null,
null,
null,
null,
null,
null,
null,
longCategorie,
null
);
Set<ConstraintViolation<UpdateTypeReferenceRequest>> violations = validator.validate(request);
assertThat(violations).isNotEmpty();
assertThat(violations).anyMatch(v -> v.getPropertyPath().toString().equals("categorie"));
}
@Test @Test
void testValidation_ValidFields() { void testValidation_ValidFields() {
UpdateTypeReferenceRequest request = new UpdateTypeReferenceRequest( UpdateTypeReferenceRequest request = new UpdateTypeReferenceRequest(
@@ -117,7 +152,9 @@ class UpdateTypeReferenceRequestTest {
"success", "success",
1, 1,
false, false,
true true,
"ASSOCIATIF",
"MEMBRES,COTISATIONS"
); );
Set<ConstraintViolation<UpdateTypeReferenceRequest>> violations = validator.validate(request); Set<ConstraintViolation<UpdateTypeReferenceRequest>> violations = validator.validate(request);
@@ -136,7 +173,9 @@ class UpdateTypeReferenceRequestTest {
null, null,
null, null,
null, null,
true true,
"ASSOCIATIF",
"MEMBRES"
); );
UpdateTypeReferenceRequest request2 = new UpdateTypeReferenceRequest( UpdateTypeReferenceRequest request2 = new UpdateTypeReferenceRequest(
@@ -148,7 +187,9 @@ class UpdateTypeReferenceRequestTest {
null, null,
null, null,
null, null,
true true,
"ASSOCIATIF",
"MEMBRES"
); );
assertThat(request1).isEqualTo(request2); assertThat(request1).isEqualTo(request2);
@@ -166,7 +207,9 @@ class UpdateTypeReferenceRequestTest {
null, null,
null, null,
null, null,
true true,
"FINANCIER_SOLIDAIRE",
"MEMBRES,TONTINE"
); );
String toString = request.toString(); String toString = request.toString();
@@ -174,5 +217,6 @@ class UpdateTypeReferenceRequestTest {
assertThat(toString).isNotNull(); assertThat(toString).isNotNull();
assertThat(toString).contains("UpdateTypeReferenceRequest"); assertThat(toString).contains("UpdateTypeReferenceRequest");
assertThat(toString).contains("CODE_UPDATE"); assertThat(toString).contains("CODE_UPDATE");
assertThat(toString).contains("FINANCIER_SOLIDAIRE");
} }
} }

View File

@@ -0,0 +1,141 @@
package dev.lions.unionflow.server.api.dto.reference.response;
import static org.assertj.core.api.Assertions.assertThat;
import java.time.LocalDateTime;
import java.util.UUID;
import org.junit.jupiter.api.Test;
class TypeReferenceResponseTest {
@Test
void testBuilder_AllFields() {
UUID id = UUID.randomUUID();
UUID orgId = UUID.randomUUID();
LocalDateTime now = LocalDateTime.now();
TypeReferenceResponse response = TypeReferenceResponse.builder()
.domaine("TYPE_ORGANISATION")
.code("TONTINE")
.libelle("Tontine")
.description("Organisation de type tontine")
.icone("pi-money-bill")
.couleur("#F59E0B")
.severity("warning")
.ordreAffichage(1)
.estDefaut(false)
.estSysteme(true)
.organisationId(orgId)
.categorie("FINANCIER_SOLIDAIRE")
.modulesRequis("MEMBRES,COTISATIONS,TONTINE,FINANCE")
.build();
response.setId(id);
response.setDateCreation(now);
response.setDateModification(now);
response.setCreePar("admin@test.com");
response.setModifiePar("admin@test.com");
response.setVersion(1L);
response.setActif(true);
assertThat(response.getDomaine()).isEqualTo("TYPE_ORGANISATION");
assertThat(response.getCode()).isEqualTo("TONTINE");
assertThat(response.getLibelle()).isEqualTo("Tontine");
assertThat(response.getDescription()).isEqualTo("Organisation de type tontine");
assertThat(response.getIcone()).isEqualTo("pi-money-bill");
assertThat(response.getCouleur()).isEqualTo("#F59E0B");
assertThat(response.getSeverity()).isEqualTo("warning");
assertThat(response.getOrdreAffichage()).isEqualTo(1);
assertThat(response.getEstDefaut()).isFalse();
assertThat(response.getEstSysteme()).isTrue();
assertThat(response.getOrganisationId()).isEqualTo(orgId);
assertThat(response.getCategorie()).isEqualTo("FINANCIER_SOLIDAIRE");
assertThat(response.getModulesRequis()).isEqualTo("MEMBRES,COTISATIONS,TONTINE,FINANCE");
assertThat(response.getId()).isEqualTo(id);
assertThat(response.getDateCreation()).isEqualTo(now);
assertThat(response.getDateModification()).isEqualTo(now);
assertThat(response.getCreePar()).isEqualTo("admin@test.com");
assertThat(response.getModifiePar()).isEqualTo("admin@test.com");
assertThat(response.getVersion()).isEqualTo(1L);
assertThat(response.getActif()).isTrue();
}
@Test
void testNoArgsConstructor() {
TypeReferenceResponse response = new TypeReferenceResponse();
assertThat(response).isNotNull();
assertThat(response.getDomaine()).isNull();
assertThat(response.getCode()).isNull();
assertThat(response.getCategorie()).isNull();
assertThat(response.getModulesRequis()).isNull();
}
@Test
void testAllArgsConstructor() {
UUID orgId = UUID.randomUUID();
TypeReferenceResponse response = new TypeReferenceResponse(
"TYPE_ORGANISATION",
"MUTUELLE",
"Mutuelle d'épargne",
"Description mutuelle",
"pi-wallet",
"#6366F1",
"info",
2,
true,
false,
orgId,
"FINANCIER_SOLIDAIRE",
"MEMBRES,EPARGNE,CREDIT"
);
assertThat(response.getDomaine()).isEqualTo("TYPE_ORGANISATION");
assertThat(response.getCode()).isEqualTo("MUTUELLE");
assertThat(response.getLibelle()).isEqualTo("Mutuelle d'épargne");
assertThat(response.getCategorie()).isEqualTo("FINANCIER_SOLIDAIRE");
assertThat(response.getModulesRequis()).isEqualTo("MEMBRES,EPARGNE,CREDIT");
assertThat(response.getEstDefaut()).isTrue();
assertThat(response.getEstSysteme()).isFalse();
assertThat(response.getOrganisationId()).isEqualTo(orgId);
}
@Test
void testSetters() {
TypeReferenceResponse response = new TypeReferenceResponse();
response.setDomaine("STATUT_MEMBRE");
response.setCode("ACTIF");
response.setLibelle("Membre Actif");
response.setDescription("Description");
response.setIcone("pi-user");
response.setCouleur("#22C55E");
response.setSeverity("success");
response.setOrdreAffichage(1);
response.setEstDefaut(true);
response.setEstSysteme(false);
response.setOrganisationId(null);
response.setCategorie("ASSOCIATIF");
response.setModulesRequis("MEMBRES,COTISATIONS");
assertThat(response.getDomaine()).isEqualTo("STATUT_MEMBRE");
assertThat(response.getCode()).isEqualTo("ACTIF");
assertThat(response.getCategorie()).isEqualTo("ASSOCIATIF");
assertThat(response.getModulesRequis()).isEqualTo("MEMBRES,COTISATIONS");
}
@Test
void testEqualsAndHashCode() {
UUID id = UUID.randomUUID();
TypeReferenceResponse r1 = TypeReferenceResponse.builder().build();
r1.setId(id);
TypeReferenceResponse r2 = TypeReferenceResponse.builder().build();
r2.setId(id);
assertThat(r1).isEqualTo(r2);
assertThat(r1.hashCode()).isEqualTo(r2.hashCode());
}
}