loko/loko/notifications/migrations/0001_initial.py

193 lines
14 KiB
Python

# Generated by Django 6.0.7 on 2026-07-22 13:42
import django.db.models.deletion
import notifications.models
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('contenttypes', '0002_remove_content_type_name'),
('contracts', '0001_initial'),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Discussion',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(blank=True, max_length=255, verbose_name='Titre')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Créé le')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Mis à jour le')),
('is_closed', models.BooleanField(default=False, verbose_name='Clôturée')),
('object_id', models.PositiveIntegerField(blank=True, null=True, verbose_name='ID objet lié')),
('object_url', models.CharField(blank=True, max_length=500, verbose_name='URL objet lié')),
('object_label', models.CharField(blank=True, max_length=255, verbose_name='Libellé objet lié')),
('content_type', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='contenttypes.contenttype', verbose_name="Type d'objet lié")),
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='discussions_created', to=settings.AUTH_USER_MODEL, verbose_name='Créé par')),
('participants', models.ManyToManyField(blank=True, related_name='discussions', to=settings.AUTH_USER_MODEL, verbose_name='Participants')),
],
options={
'verbose_name': 'Discussion',
'verbose_name_plural': 'Discussions',
'ordering': ['-updated_at'],
},
),
migrations.CreateModel(
name='Message',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('content', models.TextField(verbose_name='Contenu')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Envoyé le')),
('is_deleted', models.BooleanField(default=False, verbose_name='Supprimé')),
('author', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='discussion_messages', to=settings.AUTH_USER_MODEL, verbose_name='Auteur')),
('discussion', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='messages', to='notifications.discussion', verbose_name='Discussion')),
],
options={
'verbose_name': 'Message',
'verbose_name_plural': 'Messages',
'ordering': ['created_at'],
},
),
migrations.CreateModel(
name='MessageAttachment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.FileField(upload_to=notifications.models._message_attachment_upload, verbose_name='Fichier')),
('name', models.CharField(blank=True, max_length=255, verbose_name='Nom du fichier')),
('uploaded_at', models.DateTimeField(auto_now_add=True, verbose_name='Ajouté le')),
('message', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='notifications.message', verbose_name='Message')),
],
options={
'verbose_name': 'Pièce jointe de message',
'verbose_name_plural': 'Pièces jointes de messages',
'ordering': ['uploaded_at'],
},
),
migrations.CreateModel(
name='Notification',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('notification_type', models.CharField(choices=[('message', 'Message'), ('reminder', 'Rappel'), ('task', 'Tâche'), ('alert', 'Alerte'), ('info', 'Information')], default='info', max_length=20, verbose_name='Type')),
('title', models.CharField(max_length=255, verbose_name='Titre')),
('content', models.TextField(blank=True, verbose_name='Contenu')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Créé le')),
('expires_at', models.DateTimeField(blank=True, help_text='Laisser vide pour ne pas faire expirer la notification.', null=True, verbose_name='Expire le')),
('action_url', models.CharField(blank=True, help_text="URL relative ou absolue vers laquelle l'utilisateur est redirigé.", max_length=500, verbose_name="Lien d'action")),
('action_label', models.CharField(blank=True, max_length=100, verbose_name='Libellé du lien')),
('source_app', models.CharField(blank=True, help_text="Nom de l'application qui a généré la notification.", max_length=50, verbose_name='Application source')),
('is_system', models.BooleanField(default=False, help_text='Générée automatiquement par le système.', verbose_name='Notification système')),
('is_single_claim', models.BooleanField(default=False, help_text="Si activé, dès qu'un destinataire marque cette notification comme lue, elle est automatiquement archivée pour tous les autres destinataires.", verbose_name='Prise en charge unique')),
('sender', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='sent_notifications', to=settings.AUTH_USER_MODEL, verbose_name='Expéditeur')),
('source_discussion', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='notifications', to='notifications.discussion', verbose_name='Discussion liée')),
],
options={
'verbose_name': 'Notification',
'verbose_name_plural': 'Notifications',
'ordering': ['-created_at'],
},
),
migrations.CreateModel(
name='NotificationAttachment',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('file', models.FileField(upload_to=notifications.models.NotificationAttachment._upload_to, verbose_name='Fichier')),
('name', models.CharField(blank=True, max_length=255, verbose_name='Nom du fichier')),
('uploaded_at', models.DateTimeField(auto_now_add=True, verbose_name='Ajouté le')),
('notification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='notifications.notification', verbose_name='Notification')),
('uploaded_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='notification_attachments', to=settings.AUTH_USER_MODEL, verbose_name='Ajouté par')),
],
options={
'verbose_name': 'Pièce jointe',
'verbose_name_plural': 'Pièces jointes',
'ordering': ['uploaded_at'],
},
),
migrations.CreateModel(
name='NotificationRule',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=200, verbose_name='Nom de la règle')),
('is_active', models.BooleanField(default=True, verbose_name='Active')),
('trigger_event', models.CharField(choices=[('intervention_canceled', 'Intervention annulée')], max_length=50, verbose_name='Événement déclencheur')),
('trigger_cancellation_type', models.CharField(blank=True, choices=[('', 'Tous (pas de filtre)'), ('duplicate', 'Doublon'), ('to_redirect', 'A rediriger'), ('not_our_assets', 'Pas sous notre gestion'), ('non_relevant', 'Non-relevant'), ('other', 'Autre')], help_text="Laisser vide pour déclencher sur tout type d'annulation. Sélectionner une valeur pour n'agir que sur ce type précis.", max_length=50, verbose_name="Filtre : type d'annulation")),
('notification_type', models.CharField(choices=[('message', 'Message'), ('reminder', 'Rappel'), ('task', 'Tâche'), ('alert', 'Alerte'), ('info', 'Information')], default='alert', max_length=20, verbose_name='Type de notification')),
('title_template', models.CharField(help_text='Variables disponibles : {intervention_code}, {intervention_title}, {cancellation_type_label}', max_length=255, verbose_name='Modèle de titre')),
('content_template', models.TextField(blank=True, help_text='Variables disponibles : {intervention_code}, {intervention_title}, {cancellation_type_label}, {cancellation_reason}', verbose_name='Modèle de contenu')),
('single_claim', models.BooleanField(default=False, help_text="Si activé, dès qu'un destinataire marque la notification comme lue (prise en charge), elle est automatiquement archivée pour tous les autres destinataires.", verbose_name='Prise en charge unique')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Créée le')),
('updated_at', models.DateTimeField(auto_now=True, verbose_name='Mise à jour le')),
('recipient_teams', models.ManyToManyField(blank=True, help_text='Les notifications seront envoyées à tous les membres (CompanyMember) de ces équipes.', related_name='notification_rules', to='contracts.companyteam', verbose_name='Équipes destinataires')),
('recipient_users', models.ManyToManyField(blank=True, related_name='notification_rules', to=settings.AUTH_USER_MODEL, verbose_name='Utilisateurs destinataires supplémentaires')),
],
options={
'verbose_name': 'Règle de notification',
'verbose_name_plural': 'Règles de notification',
'ordering': ['name'],
},
),
migrations.CreateModel(
name='Team',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=100, verbose_name='Nom')),
('description', models.TextField(blank=True, verbose_name='Description')),
('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Créé le')),
('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='notification_teams_created', to=settings.AUTH_USER_MODEL, verbose_name='Créé par')),
('members', models.ManyToManyField(blank=True, related_name='notification_teams', to=settings.AUTH_USER_MODEL, verbose_name='Membres')),
],
options={
'verbose_name': 'Équipe',
'verbose_name_plural': 'Équipes',
'ordering': ['name'],
},
),
migrations.CreateModel(
name='TeamNotificationTarget',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('notification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='team_targets', to='notifications.notification', verbose_name='Notification')),
('team', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='received_notifications', to='notifications.team', verbose_name='Équipe')),
],
options={
'verbose_name': "Notification d'équipe",
'verbose_name_plural': "Notifications d'équipe",
'unique_together': {('notification', 'team')},
},
),
migrations.CreateModel(
name='NotificationRecipient',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('read_at', models.DateTimeField(blank=True, null=True, verbose_name='Lu le')),
('archived_at', models.DateTimeField(blank=True, null=True, verbose_name='Archivé le')),
('notification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='recipients', to='notifications.notification', verbose_name='Notification')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='notification_recipients', to=settings.AUTH_USER_MODEL, verbose_name='Destinataire')),
],
options={
'verbose_name': 'Destinataire de notification',
'verbose_name_plural': 'Destinataires de notification',
'ordering': ['-notification__created_at'],
'unique_together': {('notification', 'user')},
},
),
migrations.CreateModel(
name='TeamNotificationRead',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('read_at', models.DateTimeField(auto_now_add=True, verbose_name='Lu le')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='team_notification_reads', to=settings.AUTH_USER_MODEL, verbose_name='Utilisateur')),
('team_notification', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='reads', to='notifications.teamnotificationtarget', verbose_name="Notification d'équipe")),
],
options={
'verbose_name': "Lecture de notification d'équipe",
'verbose_name_plural': "Lectures de notifications d'équipe",
'unique_together': {('team_notification', 'user')},
},
),
]