You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
5.1 KiB
156 lines
5.1 KiB
from rest_framework import serializers
|
|
from apps.meetings.models import MeetingRequest, MeetingStatus
|
|
from apps.profiles.models import Institution, InstitutionMember
|
|
from apps.account.models import User
|
|
|
|
|
|
class InstitutionMeetingMinimalSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Institution
|
|
fields = ['id', 'name', 'slug', 'type', 'avatar', 'city', 'country']
|
|
|
|
|
|
class MeetingUserSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = User
|
|
fields = ['id', 'email', 'fullname', 'avatar']
|
|
|
|
|
|
class MeetingListSerializer(serializers.ModelSerializer):
|
|
requester_institution = InstitutionMeetingMinimalSerializer(read_only=True)
|
|
recipient_institution = InstitutionMeetingMinimalSerializer(read_only=True)
|
|
created_by = MeetingUserSerializer(read_only=True)
|
|
|
|
class Meta:
|
|
model = MeetingRequest
|
|
fields = [
|
|
'id',
|
|
'title',
|
|
'requester_institution',
|
|
'recipient_institution',
|
|
'created_by',
|
|
'status',
|
|
'meeting_date',
|
|
'meeting_time',
|
|
'duration_minutes',
|
|
'meeting_url',
|
|
'rejection_reason',
|
|
'created_at',
|
|
]
|
|
|
|
|
|
class MeetingDetailSerializer(serializers.ModelSerializer):
|
|
requester_institution = InstitutionMeetingMinimalSerializer(read_only=True)
|
|
recipient_institution = InstitutionMeetingMinimalSerializer(read_only=True)
|
|
created_by = MeetingUserSerializer(read_only=True)
|
|
|
|
class Meta:
|
|
model = MeetingRequest
|
|
fields = [
|
|
'id',
|
|
'title',
|
|
'requester_institution',
|
|
'recipient_institution',
|
|
'created_by',
|
|
'status',
|
|
'meeting_date',
|
|
'meeting_time',
|
|
'duration_minutes',
|
|
'meeting_url',
|
|
'agenda',
|
|
'admin_notes',
|
|
'rejection_reason',
|
|
'created_at',
|
|
'updated_at',
|
|
]
|
|
|
|
|
|
class MeetingCreateSerializer(serializers.ModelSerializer):
|
|
requester_institution_id = serializers.PrimaryKeyRelatedField(
|
|
queryset=Institution.objects.all(),
|
|
source='requester_institution',
|
|
write_only=True
|
|
)
|
|
recipient_institution_id = serializers.PrimaryKeyRelatedField(
|
|
queryset=Institution.objects.all(),
|
|
source='recipient_institution',
|
|
write_only=True
|
|
)
|
|
|
|
class Meta:
|
|
model = MeetingRequest
|
|
fields = [
|
|
'id',
|
|
'title',
|
|
'requester_institution_id',
|
|
'recipient_institution_id',
|
|
'meeting_date',
|
|
'meeting_time',
|
|
'duration_minutes',
|
|
'meeting_url',
|
|
'agenda',
|
|
]
|
|
|
|
def validate(self, attrs):
|
|
requester = attrs.get('requester_institution')
|
|
recipient = attrs.get('recipient_institution')
|
|
if requester == recipient:
|
|
raise serializers.ValidationError({"recipient_institution_id": "Requester and recipient institutions cannot be the same."})
|
|
|
|
request = self.context.get('request')
|
|
user = request.user if request else None
|
|
|
|
if user and not (user.is_superuser or getattr(user, 'user_type', None) in ['super_admin', 'regional_admin']):
|
|
is_member = InstitutionMember.objects.filter(
|
|
institution=requester,
|
|
user=user,
|
|
role__in=['admin', 'editor']
|
|
).exists()
|
|
if not is_member:
|
|
raise serializers.ValidationError({"requester_institution_id": "You are not authorized to schedule meetings for this institution."})
|
|
|
|
return attrs
|
|
|
|
def create(self, validated_data):
|
|
request = self.context.get('request')
|
|
if request and request.user.is_authenticated:
|
|
validated_data['created_by'] = request.user
|
|
return super().create(validated_data)
|
|
|
|
|
|
class MeetingUpdateSerializer(serializers.ModelSerializer):
|
|
rejection_reason = serializers.CharField(
|
|
required=False,
|
|
allow_blank=True,
|
|
help_text="Required explanation when rejecting/declining a meeting request."
|
|
)
|
|
|
|
class Meta:
|
|
model = MeetingRequest
|
|
fields = [
|
|
'status',
|
|
'meeting_date',
|
|
'meeting_time',
|
|
'duration_minutes',
|
|
'meeting_url',
|
|
'agenda',
|
|
'admin_notes',
|
|
'rejection_reason',
|
|
]
|
|
|
|
def validate(self, attrs):
|
|
status_val = attrs.get('status')
|
|
if status_val == MeetingStatus.DECLINED:
|
|
reason = (attrs.get('rejection_reason') or attrs.get('admin_notes') or '').strip()
|
|
if not reason:
|
|
if self.instance and self.instance.rejection_reason:
|
|
reason = self.instance.rejection_reason
|
|
else:
|
|
raise serializers.ValidationError({
|
|
"rejection_reason": "An explanation or reason is required when declining a meeting request."
|
|
})
|
|
attrs['rejection_reason'] = reason
|
|
if not attrs.get('admin_notes'):
|
|
attrs['admin_notes'] = reason
|
|
|
|
return attrs
|