163 lines
4.2 KiB
Python
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()
|