Coverage for segments/serializers.py: 93%

73 statements  

« 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 

4 

5 

6class CycleSerializer(serializers.ModelSerializer): 

7 """ 

8 Serializer for Segment Cycle 

9 """ 

10 

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"] 

15 

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) 

20 

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"}) 

24 

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 ) 

34 

35 # check that date does not overlap another cycle range from the same segment 

36 segment_cycles = Cycle.objects.filter(segment=segment) 

37 

38 overlapping = segment_cycles.filter(start_date__lte=end_date, end_date__gte=start_date) 

39 

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) 

42 

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}") 

49 

50 return data 

51 

52 

53class SegmentTreeSerializer(serializers.ModelSerializer): 

54 """ 

55 Serializer for Organizations Segment formatted as a tree 

56 """ 

57 

58 children = serializers.SerializerMethodField() 

59 

60 active_cycle = serializers.SerializerMethodField() 

61 

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"] 

66 

67 def get_children(self, instance): 

68 qs = Segment.objects.filter(parent=instance) 

69 serializer = SegmentTreeSerializer(qs, many=True) 

70 return serializer.data 

71 

72 def get_active_cycle(self, instance): 

73 active_cycle = instance.active_cycle 

74 

75 if active_cycle is None: 

76 return None 

77 else: 

78 serializer = CycleSerializer(active_cycle) 

79 return serializer.data 

80 

81 

82class SegmentSerializer(serializers.ModelSerializer): 

83 """ 

84 Serializer for Organizations Segment 

85 """ 

86 

87 class Meta: 

88 model = Segment 

89 read_only_fields = ["random_slug", "name", "level"] 

90 fields = read_only_fields + [] 

91 

92 

93class DisplaySegmentSerializer(SegmentTreeSerializer): 

94 """ 

95 Segment Serializer to display as nested serializer in memberships 

96 """ 

97 

98 random_slug = serializers.CharField() 

99 name = serializers.CharField(required=False, read_only=True) 

100 is_active = serializers.CharField(required=False, read_only=True) 

101 

102 class Meta(SegmentTreeSerializer.Meta): 

103 fields = ["random_slug", "name", "is_active"] 

104 

105 

106class AssignationSerializer(serializers.ModelSerializer): 

107 email = serializers.EmailField(write_only=True) 

108 

109 class Meta: 

110 model = Assignation 

111 read_only_fields = ["random_slug", "is_active", "functionary"] 

112 fields = read_only_fields + ["email", "cycle", "role"] 

113 

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 

124 

125 

126class AssignationRoleSerializer(serializers.ModelSerializer): 

127 class Meta: 

128 model = AssignationRole 

129 read_only_fields = ["random_slug"] 

130 fields = read_only_fields + ["name"]