Coverage for segments/serializers.py: 93%
73 statements
« prev ^ index » next coverage.py v6.4.4, created at 2023-05-25 13:00 -0600
« prev ^ index » next coverage.py v6.4.4, created at 2023-05-25 13:00 -0600
1from rest_framework import serializers
2from .models import Segment, Cycle, Assignation, AssignationRole
3from users.models import User, Functionary
6class CycleSerializer(serializers.ModelSerializer):
7 """
8 Serializer for Segment Cycle
9 """
11 class Meta:
12 model = Cycle
13 read_only_fields = ["random_slug", "is_active"]
14 fields = read_only_fields + ["segment", "start_date", "end_date", "descriptor"]
16 def validate(self, data):
17 start_date = data.get("start_date", self.instance.start_date if self.instance else None)
18 end_date = data.get("end_date", self.instance.end_date if self.instance else None)
19 segment = data.get("segment", self.instance.segment if self.instance else None)
21 if self.instance: 21 ↛ 22line 21 didn't jump to line 22, because the condition on line 21 was never true
22 if data.get("segment"):
23 raise serializers.ValidationError({"segment": "Este campo no es editable"})
25 if start_date and end_date: 25 ↛ 50line 25 didn't jump to line 50, because the condition on line 25 was never false
26 # check that start_date is before end_date
27 if start_date > end_date:
28 raise serializers.ValidationError(
29 {
30 "start_date": "La fecha de inicio debe ser anterior a la fecha de fin",
31 "end_date": "La fecha de fin debe ser posterior a la fecha de inicio",
32 }
33 )
35 # check that date does not overlap another cycle range from the same segment
36 segment_cycles = Cycle.objects.filter(segment=segment)
38 overlapping = segment_cycles.filter(start_date__lte=end_date, end_date__gte=start_date)
40 if self.instance: 40 ↛ 41line 40 didn't jump to line 41, because the condition on line 40 was never true
41 overlapping = overlapping.exclude(random_slug=self.instance.random_slug)
43 if overlapping.count() > 0:
44 overlapping_cycles = [
45 f"{cycle.descriptor}, {cycle.start_date}, {cycle.end_date}" for cycle in overlapping
46 ]
47 overlapping_text = ", ".join(overlapping_cycles)
48 raise serializers.ValidationError(f"Las fechas tienen conflicto con {overlapping_text}")
50 return data
53class SegmentTreeSerializer(serializers.ModelSerializer):
54 """
55 Serializer for Organizations Segment formatted as a tree
56 """
58 children = serializers.SerializerMethodField()
60 active_cycle = serializers.SerializerMethodField()
62 class Meta:
63 model = Segment
64 read_only_fields = ["random_slug", "active_cycle", "is_active"]
65 fields = read_only_fields + ["parent", "name", "children", "comment"]
67 def get_children(self, instance):
68 qs = Segment.objects.filter(parent=instance)
69 serializer = SegmentTreeSerializer(qs, many=True)
70 return serializer.data
72 def get_active_cycle(self, instance):
73 active_cycle = instance.active_cycle
75 if active_cycle is None:
76 return None
77 else:
78 serializer = CycleSerializer(active_cycle)
79 return serializer.data
82class SegmentSerializer(serializers.ModelSerializer):
83 """
84 Serializer for Organizations Segment
85 """
87 class Meta:
88 model = Segment
89 read_only_fields = ["random_slug", "name", "level"]
90 fields = read_only_fields + []
93class DisplaySegmentSerializer(SegmentTreeSerializer):
94 """
95 Segment Serializer to display as nested serializer in memberships
96 """
98 random_slug = serializers.CharField()
99 name = serializers.CharField(required=False, read_only=True)
100 is_active = serializers.CharField(required=False, read_only=True)
102 class Meta(SegmentTreeSerializer.Meta):
103 fields = ["random_slug", "name", "is_active"]
106class AssignationSerializer(serializers.ModelSerializer):
107 email = serializers.EmailField(write_only=True)
109 class Meta:
110 model = Assignation
111 read_only_fields = ["random_slug", "is_active", "functionary"]
112 fields = read_only_fields + ["email", "cycle", "role"]
114 def create(self, validated_data):
115 """
116 Override to get or create for Asssignation
117 """
118 email = validated_data.pop("email")
119 user, _ = User.objects.get_or_create(email=email)
120 functionary, _ = Functionary.objects.get_or_create(user=user)
121 validated_data["functionary"] = functionary
122 assignation = Assignation.objects.create(**validated_data)
123 return assignation
126class AssignationRoleSerializer(serializers.ModelSerializer):
127 class Meta:
128 model = AssignationRole
129 read_only_fields = ["random_slug"]
130 fields = read_only_fields + ["name"]