Louis Mazin 4db822aebe big maj
2026-10-05 17:52:28 +02:00

163 lines
4.2 KiB
Python

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()