from django.contrib.auth import get_user_model from django.db import transaction from rest_framework import serializers from .models import Note from .polls import PollSettingsSerializer, poll_representation, validate_poll_note, configure_poll from .permissions import ( can_complete_note, can_edit_note, ) class NoteUserSerializer(serializers.ModelSerializer): """ Annuaire minimal accessible à l'équipe sans exposer la gestion des comptes. """ class Meta: model = get_user_model() fields = [ 'id', 'username', 'first_name', 'last_name', 'color', ] read_only_fields = fields class NoteSerializer(serializers.ModelSerializer): poll_settings = PollSettingsSerializer(required=False, write_only=True) poll = serializers.SerializerMethodField() def get_poll(self, obj): return poll_representation(obj, self.context['request'].user) author = NoteUserSerializer( read_only=True, ) recipients = NoteUserSerializer( many=True, read_only=True, ) recipient_ids = serializers.PrimaryKeyRelatedField( source='recipients', queryset=get_user_model().objects.filter( is_active=True, ), many=True, required=False, write_only=True, ) is_done = serializers.ReadOnlyField() can_edit = serializers.SerializerMethodField() can_complete = serializers.SerializerMethodField() class Meta: model = Note fields = [ 'id', 'title', 'content', 'kind', 'author', 'recipients', 'recipient_ids', 'is_public', 'is_done', 'completed_at', 'created_at', 'updated_at', 'can_edit', 'can_complete', 'poll', 'poll_settings', ] read_only_fields = [ 'id', 'completed_at', 'created_at', 'updated_at', ] def get_can_edit(self, obj): return can_edit_note( self.context['request'].user, obj, ) def get_can_complete(self, obj): return can_complete_note( self.context['request'].user, obj, ) def validate(self, attrs): kind = attrs.get('kind', self.instance.kind if self.instance else Note.Kind.MEMO) if kind == Note.Kind.POLL: attrs['is_public'] = True attrs['recipients'] = [] validate_poll_note(self.instance, attrs) is_public = attrs.get( 'is_public', self.instance.is_public if self.instance else True, ) if 'recipients' in attrs: recipients = attrs['recipients'] has_recipients = bool(recipients) elif self.instance: has_recipients = ( self.instance.recipients.exists() ) else: has_recipients = False if not is_public and not has_recipients: raise serializers.ValidationError({ 'recipient_ids': 'Une publication privée doit avoir au moins un destinataire.', }) return attrs @transaction.atomic def create(self, validated_data): poll_settings = validated_data.pop('poll_settings', None) note = super().create(validated_data) configure_poll(note, poll_settings) return note @transaction.atomic def update(self, instance, validated_data): poll_settings = validated_data.pop('poll_settings', None) if validated_data.get('kind', instance.kind) != Note.Kind.TASK: validated_data['completed_at'] = None note = super().update(instance, validated_data) configure_poll(note, poll_settings) # Éviter une représentation basée sur les anciennes options préchargées. note._prefetched_objects_cache = {} if 'poll' in note._state.fields_cache: del note._state.fields_cache['poll'] return note class NoteCompletionSerializer( serializers.Serializer, ): is_done = serializers.BooleanField()