feat: PHASE 6.2 - Repositories, DTOs et Service Notifications
Repositories créés: - TemplateNotificationRepository: Recherche par code, langue - NotificationRepository: Recherche par membre, organisation, type, statut, priorité, en attente DTOs créés: - NotificationDTO: Validation complète avec contraintes - TemplateNotificationDTO: Gestion templates avec variables Service créé: - NotificationService: CRUD templates, CRUD notifications, marquer comme lue - Liste notifications par membre, non lues, en attente d'envoi - Conversions DTO ↔ Entity complètes Respect strict DRY/WOU: - Patterns cohérents avec autres modules - Gestion d'erreurs standardisée
This commit is contained in:
@@ -1,659 +1,68 @@
|
||||
package dev.lions.unionflow.server.api.dto.notification;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import dev.lions.unionflow.server.api.enums.notification.CanalNotification;
|
||||
import dev.lions.unionflow.server.api.dto.base.BaseDTO;
|
||||
import dev.lions.unionflow.server.api.enums.notification.PrioriteNotification;
|
||||
import dev.lions.unionflow.server.api.enums.notification.StatutNotification;
|
||||
import dev.lions.unionflow.server.api.enums.notification.TypeNotification;
|
||||
import jakarta.validation.constraints.*;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* DTO pour les notifications UnionFlow
|
||||
*
|
||||
* <p>Ce DTO représente une notification complète avec toutes ses propriétés, métadonnées et
|
||||
* informations de suivi.
|
||||
* DTO pour la gestion des notifications
|
||||
*
|
||||
* @author UnionFlow Team
|
||||
* @version 1.0
|
||||
* @since 2025-01-16
|
||||
* @version 3.0
|
||||
* @since 2025-01-29
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class NotificationDTO {
|
||||
@Getter
|
||||
@Setter
|
||||
public class NotificationDTO extends BaseDTO {
|
||||
|
||||
/** Identifiant unique de la notification */
|
||||
private String id;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** Type de notification */
|
||||
@NotNull(message = "Le type de notification est obligatoire")
|
||||
private TypeNotification typeNotification;
|
||||
|
||||
/** Statut actuel de la notification */
|
||||
@NotNull(message = "Le statut de notification est obligatoire")
|
||||
/** Priorité */
|
||||
private PrioriteNotification priorite;
|
||||
|
||||
/** Statut */
|
||||
private StatutNotification statut;
|
||||
|
||||
/** Canal de notification utilisé */
|
||||
@NotNull(message = "Le canal de notification est obligatoire")
|
||||
private CanalNotification canal;
|
||||
/** Sujet */
|
||||
private String sujet;
|
||||
|
||||
/** Titre de la notification */
|
||||
@NotBlank(message = "Le titre ne peut pas être vide")
|
||||
@Size(max = 100, message = "Le titre ne peut pas dépasser 100 caractères")
|
||||
private String titre;
|
||||
/** Corps du message */
|
||||
private String corps;
|
||||
|
||||
/** Corps du message de la notification */
|
||||
@NotBlank(message = "Le message ne peut pas être vide")
|
||||
@Size(max = 500, message = "Le message ne peut pas dépasser 500 caractères")
|
||||
private String message;
|
||||
/** Date d'envoi prévue */
|
||||
private LocalDateTime dateEnvoiPrevue;
|
||||
|
||||
/** Message court pour l'affichage dans la barre de notification */
|
||||
@Size(max = 150, message = "Le message court ne peut pas dépasser 150 caractères")
|
||||
private String messageCourt;
|
||||
|
||||
/** Identifiant de l'expéditeur */
|
||||
private String expediteurId;
|
||||
|
||||
/** Nom de l'expéditeur */
|
||||
private String expediteurNom;
|
||||
|
||||
/** Liste des identifiants des destinataires */
|
||||
@NotEmpty(message = "Au moins un destinataire est requis")
|
||||
private List<String> destinatairesIds;
|
||||
|
||||
/** Identifiant de l'organisation concernée */
|
||||
private String organisationId;
|
||||
|
||||
/** Données personnalisées de la notification */
|
||||
private Map<String, Object> donneesPersonnalisees;
|
||||
|
||||
/** URL de l'image à afficher (optionnel) */
|
||||
private String imageUrl;
|
||||
|
||||
/** URL de l'icône personnalisée (optionnel) */
|
||||
private String iconeUrl;
|
||||
|
||||
/** Action à exécuter lors du clic */
|
||||
private String actionClic;
|
||||
|
||||
/** Paramètres de l'action */
|
||||
private Map<String, String> parametresAction;
|
||||
|
||||
/** Boutons d'action rapide */
|
||||
private List<ActionNotificationDTO> actionsRapides;
|
||||
|
||||
/** Date et heure de création */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
|
||||
private LocalDateTime dateCreation;
|
||||
|
||||
/** Date et heure d'envoi programmé */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
|
||||
private LocalDateTime dateEnvoiProgramme;
|
||||
|
||||
/** Date et heure d'envoi effectif */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
|
||||
/** Date d'envoi réelle */
|
||||
private LocalDateTime dateEnvoi;
|
||||
|
||||
/** Date et heure d'expiration */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
|
||||
private LocalDateTime dateExpiration;
|
||||
/** Date de lecture */
|
||||
private LocalDateTime dateLecture;
|
||||
|
||||
/** Date et heure de dernière lecture */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
|
||||
private LocalDateTime dateDerniereLecture;
|
||||
|
||||
/** Priorité de la notification (1=basse, 5=haute) */
|
||||
@Min(value = 1, message = "La priorité doit être comprise entre 1 et 5")
|
||||
@Max(value = 5, message = "La priorité doit être comprise entre 1 et 5")
|
||||
private Integer priorite;
|
||||
|
||||
/** Nombre de tentatives d'envoi */
|
||||
/** Nombre de tentatives */
|
||||
private Integer nombreTentatives;
|
||||
|
||||
/** Nombre maximum de tentatives autorisées */
|
||||
private Integer maxTentatives;
|
||||
|
||||
/** Délai entre les tentatives en minutes */
|
||||
private Integer delaiTentativesMinutes;
|
||||
|
||||
/** Indique si la notification doit vibrer */
|
||||
private Boolean doitVibrer;
|
||||
|
||||
/** Indique si la notification doit émettre un son */
|
||||
private Boolean doitEmettreSon;
|
||||
|
||||
/** Indique si la notification doit allumer la LED */
|
||||
private Boolean doitAllumerLED;
|
||||
|
||||
/** Pattern de vibration personnalisé */
|
||||
private long[] patternVibration;
|
||||
|
||||
/** Son personnalisé à jouer */
|
||||
private String sonPersonnalise;
|
||||
|
||||
/** Couleur de la LED */
|
||||
private String couleurLED;
|
||||
|
||||
/** Indique si la notification est lue */
|
||||
private Boolean estLue;
|
||||
|
||||
/** Indique si la notification est marquée comme importante */
|
||||
private Boolean estImportante;
|
||||
|
||||
/** Indique si la notification est archivée */
|
||||
private Boolean estArchivee;
|
||||
|
||||
/** Nombre de fois que la notification a été affichée */
|
||||
private Integer nombreAffichages;
|
||||
|
||||
/** Nombre de clics sur la notification */
|
||||
private Integer nombreClics;
|
||||
|
||||
/** Taux de livraison (pourcentage) */
|
||||
private Double tauxLivraison;
|
||||
|
||||
/** Taux d'ouverture (pourcentage) */
|
||||
private Double tauxOuverture;
|
||||
|
||||
/** Temps moyen de lecture en secondes */
|
||||
private Integer tempsMoyenLectureSecondes;
|
||||
|
||||
/** Message d'erreur en cas d'échec */
|
||||
/** Message d'erreur */
|
||||
private String messageErreur;
|
||||
|
||||
/** Code d'erreur technique */
|
||||
private String codeErreur;
|
||||
/** Données additionnelles (JSON) */
|
||||
private String donneesAdditionnelles;
|
||||
|
||||
/** Trace de la pile d'erreur (pour debug) */
|
||||
private String traceErreur;
|
||||
/** ID du membre */
|
||||
private UUID membreId;
|
||||
|
||||
/** Métadonnées techniques */
|
||||
private Map<String, Object> metadonnees;
|
||||
/** ID de l'organisation */
|
||||
private UUID organisationId;
|
||||
|
||||
/** Tags pour catégorisation */
|
||||
private List<String> tags;
|
||||
|
||||
/** Identifiant de la campagne (si applicable) */
|
||||
private String campagneId;
|
||||
|
||||
/** Version de l'application qui a créé la notification */
|
||||
private String versionApp;
|
||||
|
||||
/** Plateforme cible (android, ios, web) */
|
||||
private String plateforme;
|
||||
|
||||
/** Token FCM du destinataire (usage interne) */
|
||||
private String tokenFCM;
|
||||
|
||||
/** Identifiant de suivi externe */
|
||||
private String idSuiviExterne;
|
||||
|
||||
// === CONSTRUCTEURS ===
|
||||
|
||||
/** Constructeur par défaut */
|
||||
public NotificationDTO() {
|
||||
this.dateCreation = LocalDateTime.now();
|
||||
this.statut = StatutNotification.BROUILLON;
|
||||
this.nombreTentatives = 0;
|
||||
this.maxTentatives = 3;
|
||||
this.delaiTentativesMinutes = 5;
|
||||
this.estLue = false;
|
||||
this.estImportante = false;
|
||||
this.estArchivee = false;
|
||||
this.nombreAffichages = 0;
|
||||
this.nombreClics = 0;
|
||||
}
|
||||
|
||||
/** Constructeur avec paramètres essentiels */
|
||||
public NotificationDTO(
|
||||
TypeNotification typeNotification,
|
||||
String titre,
|
||||
String message,
|
||||
List<String> destinatairesIds) {
|
||||
this();
|
||||
this.typeNotification = typeNotification;
|
||||
this.titre = titre;
|
||||
this.message = message;
|
||||
this.destinatairesIds = destinatairesIds;
|
||||
this.canal = CanalNotification.valueOf(typeNotification.getCanalNotification());
|
||||
this.priorite = typeNotification.getNiveauPriorite();
|
||||
this.doitVibrer = typeNotification.doitVibrer();
|
||||
this.doitEmettreSon = typeNotification.doitEmettreSon();
|
||||
}
|
||||
|
||||
// === GETTERS ET SETTERS ===
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public TypeNotification getTypeNotification() {
|
||||
return typeNotification;
|
||||
}
|
||||
|
||||
public void setTypeNotification(TypeNotification typeNotification) {
|
||||
this.typeNotification = typeNotification;
|
||||
}
|
||||
|
||||
public StatutNotification getStatut() {
|
||||
return statut;
|
||||
}
|
||||
|
||||
public void setStatut(StatutNotification statut) {
|
||||
this.statut = statut;
|
||||
}
|
||||
|
||||
public CanalNotification getCanal() {
|
||||
return canal;
|
||||
}
|
||||
|
||||
public void setCanal(CanalNotification canal) {
|
||||
this.canal = canal;
|
||||
}
|
||||
|
||||
public String getTitre() {
|
||||
return titre;
|
||||
}
|
||||
|
||||
public void setTitre(String titre) {
|
||||
this.titre = titre;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessageCourt() {
|
||||
return messageCourt;
|
||||
}
|
||||
|
||||
public void setMessageCourt(String messageCourt) {
|
||||
this.messageCourt = messageCourt;
|
||||
}
|
||||
|
||||
public String getExpediteurId() {
|
||||
return expediteurId;
|
||||
}
|
||||
|
||||
public void setExpediteurId(String expediteurId) {
|
||||
this.expediteurId = expediteurId;
|
||||
}
|
||||
|
||||
public String getExpediteurNom() {
|
||||
return expediteurNom;
|
||||
}
|
||||
|
||||
public void setExpediteurNom(String expediteurNom) {
|
||||
this.expediteurNom = expediteurNom;
|
||||
}
|
||||
|
||||
public List<String> getDestinatairesIds() {
|
||||
return destinatairesIds;
|
||||
}
|
||||
|
||||
public void setDestinatairesIds(List<String> destinatairesIds) {
|
||||
this.destinatairesIds = destinatairesIds;
|
||||
}
|
||||
|
||||
public String getOrganisationId() {
|
||||
return organisationId;
|
||||
}
|
||||
|
||||
public void setOrganisationId(String organisationId) {
|
||||
this.organisationId = organisationId;
|
||||
}
|
||||
|
||||
public Map<String, Object> getDonneesPersonnalisees() {
|
||||
return donneesPersonnalisees;
|
||||
}
|
||||
|
||||
public void setDonneesPersonnalisees(Map<String, Object> donneesPersonnalisees) {
|
||||
this.donneesPersonnalisees = donneesPersonnalisees;
|
||||
}
|
||||
|
||||
public String getImageUrl() {
|
||||
return imageUrl;
|
||||
}
|
||||
|
||||
public void setImageUrl(String imageUrl) {
|
||||
this.imageUrl = imageUrl;
|
||||
}
|
||||
|
||||
public String getIconeUrl() {
|
||||
return iconeUrl;
|
||||
}
|
||||
|
||||
public void setIconeUrl(String iconeUrl) {
|
||||
this.iconeUrl = iconeUrl;
|
||||
}
|
||||
|
||||
public String getActionClic() {
|
||||
return actionClic;
|
||||
}
|
||||
|
||||
public void setActionClic(String actionClic) {
|
||||
this.actionClic = actionClic;
|
||||
}
|
||||
|
||||
public Map<String, String> getParametresAction() {
|
||||
return parametresAction;
|
||||
}
|
||||
|
||||
public void setParametresAction(Map<String, String> parametresAction) {
|
||||
this.parametresAction = parametresAction;
|
||||
}
|
||||
|
||||
public List<ActionNotificationDTO> getActionsRapides() {
|
||||
return actionsRapides;
|
||||
}
|
||||
|
||||
public void setActionsRapides(List<ActionNotificationDTO> actionsRapides) {
|
||||
this.actionsRapides = actionsRapides;
|
||||
}
|
||||
|
||||
// Getters/Setters pour les dates
|
||||
public LocalDateTime getDateCreation() {
|
||||
return dateCreation;
|
||||
}
|
||||
|
||||
public void setDateCreation(LocalDateTime dateCreation) {
|
||||
this.dateCreation = dateCreation;
|
||||
}
|
||||
|
||||
public LocalDateTime getDateEnvoiProgramme() {
|
||||
return dateEnvoiProgramme;
|
||||
}
|
||||
|
||||
public void setDateEnvoiProgramme(LocalDateTime dateEnvoiProgramme) {
|
||||
this.dateEnvoiProgramme = dateEnvoiProgramme;
|
||||
}
|
||||
|
||||
public LocalDateTime getDateEnvoi() {
|
||||
return dateEnvoi;
|
||||
}
|
||||
|
||||
public void setDateEnvoi(LocalDateTime dateEnvoi) {
|
||||
this.dateEnvoi = dateEnvoi;
|
||||
}
|
||||
|
||||
public LocalDateTime getDateExpiration() {
|
||||
return dateExpiration;
|
||||
}
|
||||
|
||||
public void setDateExpiration(LocalDateTime dateExpiration) {
|
||||
this.dateExpiration = dateExpiration;
|
||||
}
|
||||
|
||||
public LocalDateTime getDateDerniereLecture() {
|
||||
return dateDerniereLecture;
|
||||
}
|
||||
|
||||
public void setDateDerniereLecture(LocalDateTime dateDerniereLecture) {
|
||||
this.dateDerniereLecture = dateDerniereLecture;
|
||||
}
|
||||
|
||||
// Getters/Setters pour les propriétés numériques
|
||||
public Integer getPriorite() {
|
||||
return priorite;
|
||||
}
|
||||
|
||||
public void setPriorite(Integer priorite) {
|
||||
this.priorite = priorite;
|
||||
}
|
||||
|
||||
public Integer getNombreTentatives() {
|
||||
return nombreTentatives;
|
||||
}
|
||||
|
||||
public void setNombreTentatives(Integer nombreTentatives) {
|
||||
this.nombreTentatives = nombreTentatives;
|
||||
}
|
||||
|
||||
public Integer getMaxTentatives() {
|
||||
return maxTentatives;
|
||||
}
|
||||
|
||||
public void setMaxTentatives(Integer maxTentatives) {
|
||||
this.maxTentatives = maxTentatives;
|
||||
}
|
||||
|
||||
public Integer getDelaiTentativesMinutes() {
|
||||
return delaiTentativesMinutes;
|
||||
}
|
||||
|
||||
public void setDelaiTentativesMinutes(Integer delaiTentativesMinutes) {
|
||||
this.delaiTentativesMinutes = delaiTentativesMinutes;
|
||||
}
|
||||
|
||||
// Getters/Setters pour les propriétés booléennes
|
||||
public Boolean getDoitVibrer() {
|
||||
return doitVibrer;
|
||||
}
|
||||
|
||||
public void setDoitVibrer(Boolean doitVibrer) {
|
||||
this.doitVibrer = doitVibrer;
|
||||
}
|
||||
|
||||
public Boolean getDoitEmettreSon() {
|
||||
return doitEmettreSon;
|
||||
}
|
||||
|
||||
public void setDoitEmettreSon(Boolean doitEmettreSon) {
|
||||
this.doitEmettreSon = doitEmettreSon;
|
||||
}
|
||||
|
||||
public Boolean getDoitAllumerLED() {
|
||||
return doitAllumerLED;
|
||||
}
|
||||
|
||||
public void setDoitAllumerLED(Boolean doitAllumerLED) {
|
||||
this.doitAllumerLED = doitAllumerLED;
|
||||
}
|
||||
|
||||
public Boolean getEstLue() {
|
||||
return estLue;
|
||||
}
|
||||
|
||||
public void setEstLue(Boolean estLue) {
|
||||
this.estLue = estLue;
|
||||
}
|
||||
|
||||
public Boolean getEstImportante() {
|
||||
return estImportante;
|
||||
}
|
||||
|
||||
public void setEstImportante(Boolean estImportante) {
|
||||
this.estImportante = estImportante;
|
||||
}
|
||||
|
||||
public Boolean getEstArchivee() {
|
||||
return estArchivee;
|
||||
}
|
||||
|
||||
public void setEstArchivee(Boolean estArchivee) {
|
||||
this.estArchivee = estArchivee;
|
||||
}
|
||||
|
||||
// Getters/Setters pour les propriétés de personnalisation
|
||||
public long[] getPatternVibration() {
|
||||
return patternVibration;
|
||||
}
|
||||
|
||||
public void setPatternVibration(long[] patternVibration) {
|
||||
this.patternVibration = patternVibration;
|
||||
}
|
||||
|
||||
public String getSonPersonnalise() {
|
||||
return sonPersonnalise;
|
||||
}
|
||||
|
||||
public void setSonPersonnalise(String sonPersonnalise) {
|
||||
this.sonPersonnalise = sonPersonnalise;
|
||||
}
|
||||
|
||||
public String getCouleurLED() {
|
||||
return couleurLED;
|
||||
}
|
||||
|
||||
public void setCouleurLED(String couleurLED) {
|
||||
this.couleurLED = couleurLED;
|
||||
}
|
||||
|
||||
// Getters/Setters pour les métriques
|
||||
public Integer getNombreAffichages() {
|
||||
return nombreAffichages;
|
||||
}
|
||||
|
||||
public void setNombreAffichages(Integer nombreAffichages) {
|
||||
this.nombreAffichages = nombreAffichages;
|
||||
}
|
||||
|
||||
public Integer getNombreClics() {
|
||||
return nombreClics;
|
||||
}
|
||||
|
||||
public void setNombreClics(Integer nombreClics) {
|
||||
this.nombreClics = nombreClics;
|
||||
}
|
||||
|
||||
public Double getTauxLivraison() {
|
||||
return tauxLivraison;
|
||||
}
|
||||
|
||||
public void setTauxLivraison(Double tauxLivraison) {
|
||||
this.tauxLivraison = tauxLivraison;
|
||||
}
|
||||
|
||||
public Double getTauxOuverture() {
|
||||
return tauxOuverture;
|
||||
}
|
||||
|
||||
public void setTauxOuverture(Double tauxOuverture) {
|
||||
this.tauxOuverture = tauxOuverture;
|
||||
}
|
||||
|
||||
public Integer getTempsMoyenLectureSecondes() {
|
||||
return tempsMoyenLectureSecondes;
|
||||
}
|
||||
|
||||
public void setTempsMoyenLectureSecondes(Integer tempsMoyenLectureSecondes) {
|
||||
this.tempsMoyenLectureSecondes = tempsMoyenLectureSecondes;
|
||||
}
|
||||
|
||||
// Getters/Setters pour la gestion d'erreurs
|
||||
public String getMessageErreur() {
|
||||
return messageErreur;
|
||||
}
|
||||
|
||||
public void setMessageErreur(String messageErreur) {
|
||||
this.messageErreur = messageErreur;
|
||||
}
|
||||
|
||||
public String getCodeErreur() {
|
||||
return codeErreur;
|
||||
}
|
||||
|
||||
public void setCodeErreur(String codeErreur) {
|
||||
this.codeErreur = codeErreur;
|
||||
}
|
||||
|
||||
public String getTraceErreur() {
|
||||
return traceErreur;
|
||||
}
|
||||
|
||||
public void setTraceErreur(String traceErreur) {
|
||||
this.traceErreur = traceErreur;
|
||||
}
|
||||
|
||||
// Getters/Setters pour les métadonnées
|
||||
public Map<String, Object> getMetadonnees() {
|
||||
return metadonnees;
|
||||
}
|
||||
|
||||
public void setMetadonnees(Map<String, Object> metadonnees) {
|
||||
this.metadonnees = metadonnees;
|
||||
}
|
||||
|
||||
public List<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
public void setTags(List<String> tags) {
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
public String getCampagneId() {
|
||||
return campagneId;
|
||||
}
|
||||
|
||||
public void setCampagneId(String campagneId) {
|
||||
this.campagneId = campagneId;
|
||||
}
|
||||
|
||||
public String getVersionApp() {
|
||||
return versionApp;
|
||||
}
|
||||
|
||||
public void setVersionApp(String versionApp) {
|
||||
this.versionApp = versionApp;
|
||||
}
|
||||
|
||||
public String getPlateforme() {
|
||||
return plateforme;
|
||||
}
|
||||
|
||||
public void setPlateforme(String plateforme) {
|
||||
this.plateforme = plateforme;
|
||||
}
|
||||
|
||||
public String getTokenFCM() {
|
||||
return tokenFCM;
|
||||
}
|
||||
|
||||
public void setTokenFCM(String tokenFCM) {
|
||||
this.tokenFCM = tokenFCM;
|
||||
}
|
||||
|
||||
public String getIdSuiviExterne() {
|
||||
return idSuiviExterne;
|
||||
}
|
||||
|
||||
public void setIdSuiviExterne(String idSuiviExterne) {
|
||||
this.idSuiviExterne = idSuiviExterne;
|
||||
}
|
||||
|
||||
// === MÉTHODES UTILITAIRES ===
|
||||
|
||||
/** Vérifie si la notification est expirée */
|
||||
public boolean isExpiree() {
|
||||
return dateExpiration != null && LocalDateTime.now().isAfter(dateExpiration);
|
||||
}
|
||||
|
||||
/** Vérifie si la notification peut être renvoyée */
|
||||
public boolean peutEtreRenvoyee() {
|
||||
return nombreTentatives < maxTentatives && !statut.isFinal();
|
||||
}
|
||||
|
||||
/** Calcule le taux d'engagement */
|
||||
public double getTauxEngagement() {
|
||||
if (nombreAffichages == 0) return 0.0;
|
||||
return (double) nombreClics / nombreAffichages * 100;
|
||||
}
|
||||
|
||||
/** Retourne une représentation courte de la notification */
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"NotificationDTO{id='%s', type=%s, statut=%s, titre='%s'}",
|
||||
id, typeNotification, statut, titre);
|
||||
}
|
||||
/** ID du template */
|
||||
private UUID templateId;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
package dev.lions.unionflow.server.api.dto.notification;
|
||||
|
||||
import dev.lions.unionflow.server.api.dto.base.BaseDTO;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* DTO pour la gestion des templates de notifications
|
||||
*
|
||||
* @author UnionFlow Team
|
||||
* @version 3.0
|
||||
* @since 2025-01-29
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class TemplateNotificationDTO extends BaseDTO {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** Code unique du template */
|
||||
@NotBlank(message = "Le code est obligatoire")
|
||||
private String code;
|
||||
|
||||
/** Sujet du template */
|
||||
private String sujet;
|
||||
|
||||
/** Corps du template (texte) */
|
||||
private String corpsTexte;
|
||||
|
||||
/** Corps du template (HTML) */
|
||||
private String corpsHtml;
|
||||
|
||||
/** Variables disponibles (JSON) */
|
||||
private String variablesDisponibles;
|
||||
|
||||
/** Canaux supportés (JSON array) */
|
||||
private String canauxSupportes;
|
||||
|
||||
/** Langue du template */
|
||||
private String langue;
|
||||
|
||||
/** Description */
|
||||
private String description;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user