from django import forms from django.contrib.auth.models import User from django.utils.translation import gettext_lazy as _ from common.models import UserConfig from .models import Notification, Team class MultipleFileInput(forms.FileInput): """Widget FileInput autorisant la sélection de plusieurs fichiers.""" allow_multiple_selected = True def __init__(self, attrs=None): super().__init__(attrs={'multiple': True, 'class': 'form-control', **(attrs or {})}) class MultipleFileField(forms.FileField): """Champ fichier acceptant plusieurs fichiers.""" widget = MultipleFileInput def clean(self, data, initial=None): # data may be a list (multiple files) or a single file if not data: return [] if not isinstance(data, list): data = [data] return [super(MultipleFileField, self).clean(d, initial) for d in data] class NotificationCreateForm(forms.Form): """Formulaire de création manuelle d'une notification.""" title = forms.CharField( max_length=255, label=_("Titre"), widget=forms.TextInput(attrs={'class': 'form-control'}), ) content = forms.CharField( required=False, label=_("Contenu"), widget=forms.Textarea(attrs={'class': 'form-control', 'rows': 4}), ) notification_type = forms.ChoiceField( choices=Notification.TYPES, initial=Notification.TYPE_MESSAGE, label=_("Type"), widget=forms.Select(attrs={'class': 'form-select'}), ) action_url = forms.CharField( required=False, max_length=500, label=_("Lien d'action (URL)"), widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '/example/path/'}), ) action_label = forms.CharField( required=False, max_length=100, label=_("Libellé du lien"), widget=forms.TextInput(attrs={'class': 'form-control'}), ) expires_at = forms.DateTimeField( required=False, label=_("Expire le"), widget=forms.DateTimeInput(attrs={'class': 'form-control', 'type': 'datetime-local'}), ) attachments = MultipleFileField( required=False, label=_("Pièces jointes"), help_text=_("Photos ou documents (plusieurs fichiers possibles)."), ) # Recipients recipient_users = forms.ModelMultipleChoiceField( queryset=User.objects.filter(is_active=True).order_by('first_name', 'last_name', 'username'), required=False, label=_("Destinataires individuels"), widget=forms.SelectMultiple(attrs={'class': 'form-select', 'size': '6'}), ) recipient_teams = forms.ModelMultipleChoiceField( queryset=Team.objects.all(), required=False, label=_("Équipes destinataires"), widget=forms.SelectMultiple(attrs={'class': 'form-select', 'size': '4'}), ) def clean(self): cleaned_data = super().clean() users = cleaned_data.get('recipient_users') teams = cleaned_data.get('recipient_teams') if not users and not teams: raise forms.ValidationError( _("Veuillez sélectionner au moins un destinataire ou une équipe.") ) return cleaned_data class TeamForm(forms.ModelForm): class Meta: model = Team fields = ['name', 'description', 'members'] widgets = { 'name': forms.TextInput(attrs={'class': 'form-control'}), 'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 3}), 'members': forms.SelectMultiple(attrs={'class': 'form-select', 'size': '8'}), } class NotificationReminderSettingsForm(forms.ModelForm): class Meta: model = UserConfig fields = [ 'notification_reminder_enabled', 'notification_reminder_emails', 'notification_reminder_delay_hours', ] widgets = { 'notification_reminder_enabled': forms.CheckboxInput( attrs={'class': 'form-check-input', 'role': 'switch'} ), 'notification_reminder_emails': forms.TextInput( attrs={ 'class': 'form-control rounded-3', 'placeholder': _("Ex: email1@exemple.com, email2@exemple.com"), } ), 'notification_reminder_delay_hours': forms.NumberInput( attrs={'class': 'form-control rounded-3', 'min': 1, 'max': 720} ), } def clean_notification_reminder_emails(self): emails_raw = self.cleaned_data.get('notification_reminder_emails', '') if not emails_raw: return '' import re from django.core.validators import validate_email from django.core.exceptions import ValidationError cleaned_emails = [] for email in re.split(r'[;,]', emails_raw): email = email.strip() if email: try: validate_email(email) cleaned_emails.append(email) except ValidationError: raise forms.ValidationError( _("L'adresse e-mail '%(email)s' n'est pas valide.") % {'email': email} ) return ', '.join(cleaned_emails)