Files
unionflow-server-impl-quarkus/unionflow-mobile-apps/lib/features/notifications/data/models/notification_model.dart
2025-09-17 17:54:06 +00:00

419 lines
14 KiB
Dart

import 'package:json_annotation/json_annotation.dart';
import '../../domain/entities/notification.dart';
part 'notification_model.g.dart';
/// Modèle de données pour les actions de notification
@JsonSerializable()
class ActionNotificationModel extends ActionNotification {
const ActionNotificationModel({
required super.id,
required super.libelle,
required super.typeAction,
super.description,
super.icone,
super.couleur,
super.url,
super.route,
super.parametres,
super.fermeNotification = true,
super.necessiteConfirmation = false,
super.estDestructive = false,
super.ordre = 0,
super.estActivee = true,
});
factory ActionNotificationModel.fromJson(Map<String, dynamic> json) =>
_$ActionNotificationModelFromJson(json);
@override
Map<String, dynamic> toJson() => _$ActionNotificationModelToJson(this);
factory ActionNotificationModel.fromEntity(ActionNotification entity) {
return ActionNotificationModel(
id: entity.id,
libelle: entity.libelle,
typeAction: entity.typeAction,
description: entity.description,
icone: entity.icone,
couleur: entity.couleur,
url: entity.url,
route: entity.route,
parametres: entity.parametres,
fermeNotification: entity.fermeNotification,
necessiteConfirmation: entity.necessiteConfirmation,
estDestructive: entity.estDestructive,
ordre: entity.ordre,
estActivee: entity.estActivee,
);
}
ActionNotification toEntity() {
return ActionNotification(
id: id,
libelle: libelle,
typeAction: typeAction,
description: description,
icone: icone,
couleur: couleur,
url: url,
route: route,
parametres: parametres,
fermeNotification: fermeNotification,
necessiteConfirmation: necessiteConfirmation,
estDestructive: estDestructive,
ordre: ordre,
estActivee: estActivee,
);
}
}
/// Modèle de données pour les notifications
@JsonSerializable()
class NotificationModel extends NotificationEntity {
const NotificationModel({
required super.id,
required super.typeNotification,
required super.statut,
required super.titre,
required super.message,
super.messageCourt,
super.expediteurId,
super.expediteurNom,
required super.destinatairesIds,
super.organisationId,
super.donneesPersonnalisees,
super.imageUrl,
super.iconeUrl,
super.actionClic,
super.parametresAction,
super.actionsRapides,
required super.dateCreation,
super.dateEnvoiProgramme,
super.dateEnvoi,
super.dateExpiration,
super.dateDerniereLecture,
super.priorite = 3,
super.estLue = false,
super.estImportante = false,
super.estArchivee = false,
super.nombreAffichages = 0,
super.nombreClics = 0,
super.tags,
super.campagneId,
super.plateforme,
super.tokenFCM,
});
factory NotificationModel.fromJson(Map<String, dynamic> json) =>
_$NotificationModelFromJson(json);
@override
Map<String, dynamic> toJson() => _$NotificationModelToJson(this);
factory NotificationModel.fromEntity(NotificationEntity entity) {
return NotificationModel(
id: entity.id,
typeNotification: entity.typeNotification,
statut: entity.statut,
titre: entity.titre,
message: entity.message,
messageCourt: entity.messageCourt,
expediteurId: entity.expediteurId,
expediteurNom: entity.expediteurNom,
destinatairesIds: entity.destinatairesIds,
organisationId: entity.organisationId,
donneesPersonnalisees: entity.donneesPersonnalisees,
imageUrl: entity.imageUrl,
iconeUrl: entity.iconeUrl,
actionClic: entity.actionClic,
parametresAction: entity.parametresAction,
actionsRapides: entity.actionsRapides?.map((action) =>
ActionNotificationModel.fromEntity(action)).toList(),
dateCreation: entity.dateCreation,
dateEnvoiProgramme: entity.dateEnvoiProgramme,
dateEnvoi: entity.dateEnvoi,
dateExpiration: entity.dateExpiration,
dateDerniereLecture: entity.dateDerniereLecture,
priorite: entity.priorite,
estLue: entity.estLue,
estImportante: entity.estImportante,
estArchivee: entity.estArchivee,
nombreAffichages: entity.nombreAffichages,
nombreClics: entity.nombreClics,
tags: entity.tags,
campagneId: entity.campagneId,
plateforme: entity.plateforme,
tokenFCM: entity.tokenFCM,
);
}
NotificationEntity toEntity() {
return NotificationEntity(
id: id,
typeNotification: typeNotification,
statut: statut,
titre: titre,
message: message,
messageCourt: messageCourt,
expediteurId: expediteurId,
expediteurNom: expediteurNom,
destinatairesIds: destinatairesIds,
organisationId: organisationId,
donneesPersonnalisees: donneesPersonnalisees,
imageUrl: imageUrl,
iconeUrl: iconeUrl,
actionClic: actionClic,
parametresAction: parametresAction,
actionsRapides: actionsRapides?.map((action) =>
(action as ActionNotificationModel).toEntity()).toList(),
dateCreation: dateCreation,
dateEnvoiProgramme: dateEnvoiProgramme,
dateEnvoi: dateEnvoi,
dateExpiration: dateExpiration,
dateDerniereLecture: dateDerniereLecture,
priorite: priorite,
estLue: estLue,
estImportante: estImportante,
estArchivee: estArchivee,
nombreAffichages: nombreAffichages,
nombreClics: nombreClics,
tags: tags,
campagneId: campagneId,
plateforme: plateforme,
tokenFCM: tokenFCM,
);
}
/// Crée un modèle depuis une notification Firebase
factory NotificationModel.fromFirebaseMessage(Map<String, dynamic> data) {
// Extraction des données de base
final id = data['id'] ?? data['notification_id'] ?? '';
final titre = data['title'] ?? data['titre'] ?? '';
final message = data['body'] ?? data['message'] ?? '';
final messageCourt = data['short_message'] ?? data['message_court'];
// Parsing du type de notification
TypeNotification typeNotification = TypeNotification.annonceGenerale;
if (data['type'] != null) {
try {
typeNotification = TypeNotification.values.firstWhere(
(type) => type.name == data['type'] || type.toString().split('.').last == data['type'],
orElse: () => TypeNotification.annonceGenerale,
);
} catch (e) {
// Utilise le type par défaut en cas d'erreur
}
}
// Parsing du statut
StatutNotification statut = StatutNotification.recue;
if (data['status'] != null) {
try {
statut = StatutNotification.values.firstWhere(
(s) => s.name == data['status'] || s.toString().split('.').last == data['status'],
orElse: () => StatutNotification.recue,
);
} catch (e) {
// Utilise le statut par défaut
}
}
// Parsing des actions rapides
List<ActionNotification>? actionsRapides;
if (data['actions'] != null && data['actions'] is List) {
try {
actionsRapides = (data['actions'] as List)
.map((actionData) => ActionNotificationModel.fromJson(
actionData is Map<String, dynamic> ? actionData : {}))
.toList();
} catch (e) {
// Ignore les erreurs de parsing des actions
}
}
// Parsing des destinataires
List<String> destinatairesIds = [];
if (data['recipients'] != null) {
if (data['recipients'] is List) {
destinatairesIds = List<String>.from(data['recipients']);
} else if (data['recipients'] is String) {
destinatairesIds = [data['recipients']];
}
}
// Parsing des tags
List<String>? tags;
if (data['tags'] != null && data['tags'] is List) {
tags = List<String>.from(data['tags']);
}
// Parsing des dates
DateTime dateCreation = DateTime.now();
if (data['created_at'] != null) {
try {
if (data['created_at'] is int) {
dateCreation = DateTime.fromMillisecondsSinceEpoch(data['created_at']);
} else if (data['created_at'] is String) {
dateCreation = DateTime.parse(data['created_at']);
}
} catch (e) {
// Utilise la date actuelle en cas d'erreur
}
}
DateTime? dateExpiration;
if (data['expires_at'] != null) {
try {
if (data['expires_at'] is int) {
dateExpiration = DateTime.fromMillisecondsSinceEpoch(data['expires_at']);
} else if (data['expires_at'] is String) {
dateExpiration = DateTime.parse(data['expires_at']);
}
} catch (e) {
// Ignore les erreurs de parsing de date
}
}
// Parsing des données personnalisées
Map<String, dynamic>? donneesPersonnalisees;
if (data['custom_data'] != null && data['custom_data'] is Map) {
donneesPersonnalisees = Map<String, dynamic>.from(data['custom_data']);
}
return NotificationModel(
id: id,
typeNotification: typeNotification,
statut: statut,
titre: titre,
message: message,
messageCourt: messageCourt,
expediteurId: data['sender_id'],
expediteurNom: data['sender_name'],
destinatairesIds: destinatairesIds,
organisationId: data['organization_id'],
donneesPersonnalisees: donneesPersonnalisees,
imageUrl: data['image_url'],
iconeUrl: data['icon_url'],
actionClic: data['click_action'],
parametresAction: data['action_params'] != null
? Map<String, String>.from(data['action_params'])
: null,
actionsRapides: actionsRapides,
dateCreation: dateCreation,
dateExpiration: dateExpiration,
priorite: data['priority'] ?? 3,
tags: tags,
campagneId: data['campaign_id'],
plateforme: data['platform'],
tokenFCM: data['fcm_token'],
);
}
/// Convertit vers le format Firebase
Map<String, dynamic> toFirebaseData() {
final data = <String, dynamic>{
'id': id,
'type': typeNotification.name,
'status': statut.name,
'title': titre,
'body': message,
'recipients': destinatairesIds,
'created_at': dateCreation.millisecondsSinceEpoch,
'priority': priorite,
};
if (messageCourt != null) data['short_message'] = messageCourt;
if (expediteurId != null) data['sender_id'] = expediteurId;
if (expediteurNom != null) data['sender_name'] = expediteurNom;
if (organisationId != null) data['organization_id'] = organisationId;
if (donneesPersonnalisees != null) data['custom_data'] = donneesPersonnalisees;
if (imageUrl != null) data['image_url'] = imageUrl;
if (iconeUrl != null) data['icon_url'] = iconeUrl;
if (actionClic != null) data['click_action'] = actionClic;
if (parametresAction != null) data['action_params'] = parametresAction;
if (dateExpiration != null) data['expires_at'] = dateExpiration!.millisecondsSinceEpoch;
if (tags != null) data['tags'] = tags;
if (campagneId != null) data['campaign_id'] = campagneId;
if (plateforme != null) data['platform'] = plateforme;
if (tokenFCM != null) data['fcm_token'] = tokenFCM;
if (actionsRapides != null && actionsRapides!.isNotEmpty) {
data['actions'] = actionsRapides!
.map((action) => (action as ActionNotificationModel).toJson())
.toList();
}
return data;
}
/// Crée une copie avec des modifications
NotificationModel copyWithModel({
String? id,
TypeNotification? typeNotification,
StatutNotification? statut,
String? titre,
String? message,
String? messageCourt,
String? expediteurId,
String? expediteurNom,
List<String>? destinatairesIds,
String? organisationId,
Map<String, dynamic>? donneesPersonnalisees,
String? imageUrl,
String? iconeUrl,
String? actionClic,
Map<String, String>? parametresAction,
List<ActionNotification>? actionsRapides,
DateTime? dateCreation,
DateTime? dateEnvoiProgramme,
DateTime? dateEnvoi,
DateTime? dateExpiration,
DateTime? dateDerniereLecture,
int? priorite,
bool? estLue,
bool? estImportante,
bool? estArchivee,
int? nombreAffichages,
int? nombreClics,
List<String>? tags,
String? campagneId,
String? plateforme,
String? tokenFCM,
}) {
return NotificationModel(
id: id ?? this.id,
typeNotification: typeNotification ?? this.typeNotification,
statut: statut ?? this.statut,
titre: titre ?? this.titre,
message: message ?? this.message,
messageCourt: messageCourt ?? this.messageCourt,
expediteurId: expediteurId ?? this.expediteurId,
expediteurNom: expediteurNom ?? this.expediteurNom,
destinatairesIds: destinatairesIds ?? this.destinatairesIds,
organisationId: organisationId ?? this.organisationId,
donneesPersonnalisees: donneesPersonnalisees ?? this.donneesPersonnalisees,
imageUrl: imageUrl ?? this.imageUrl,
iconeUrl: iconeUrl ?? this.iconeUrl,
actionClic: actionClic ?? this.actionClic,
parametresAction: parametresAction ?? this.parametresAction,
actionsRapides: actionsRapides ?? this.actionsRapides,
dateCreation: dateCreation ?? this.dateCreation,
dateEnvoiProgramme: dateEnvoiProgramme ?? this.dateEnvoiProgramme,
dateEnvoi: dateEnvoi ?? this.dateEnvoi,
dateExpiration: dateExpiration ?? this.dateExpiration,
dateDerniereLecture: dateDerniereLecture ?? this.dateDerniereLecture,
priorite: priorite ?? this.priorite,
estLue: estLue ?? this.estLue,
estImportante: estImportante ?? this.estImportante,
estArchivee: estArchivee ?? this.estArchivee,
nombreAffichages: nombreAffichages ?? this.nombreAffichages,
nombreClics: nombreClics ?? this.nombreClics,
tags: tags ?? this.tags,
campagneId: campagneId ?? this.campagneId,
plateforme: plateforme ?? this.plateforme,
tokenFCM: tokenFCM ?? this.tokenFCM,
);
}
}