diff --git a/INSIGHTSAPI/hierarchy/models.py b/INSIGHTSAPI/hierarchy/models.py index 8f5330c..4af9305 100644 --- a/INSIGHTSAPI/hierarchy/models.py +++ b/INSIGHTSAPI/hierarchy/models.py @@ -14,6 +14,27 @@ class Area(models.Model): "users.User", on_delete=models.SET_NULL, null=True, related_name="managed_areas" ) + def get_children(self): + """Get all the children of the area.""" + return self.children.all() + + def get_children_managers(self): + """Get all the managers of the children of the area.""" + return [child.manager for child in self.get_children() if child.manager] + + def get_parents(self): + """Get all the parents of the area.""" + parents = [] + parent = self.parent + while parent: + parents.append(parent) + parent = parent.parent + return parents + + def get_parents_managers(self): + """Get all the managers of the parents of the area.""" + return [parent.manager for parent in self.get_parents() if parent.manager] + class Meta: permissions = [ ("manage_area", "Can manage the area"), diff --git a/INSIGHTSAPI/hierarchy/tests.py b/INSIGHTSAPI/hierarchy/tests.py index 7ad21ed..aac990b 100644 --- a/INSIGHTSAPI/hierarchy/tests.py +++ b/INSIGHTSAPI/hierarchy/tests.py @@ -33,3 +33,45 @@ def test_area_parent(self): area.save() self.assertIn(area, parent_area.children.all()) self.assertEqual(len(area.children.all()), 0) + + def test_get_children(self): + """Test the get_children method of the area model.""" + area = Area.objects.first() + if not area: + area = Area.objects.create(name="Test Area") + child_area = Area.objects.create(name="Child Area", parent=area) + self.assertIn(child_area, area.get_children()) + self.assertEqual(len(area.get_children()), 1) + + def test_get_children_managers(self): + """Test the get_children_managers method of the area model.""" + area = Area.objects.first() + if not area: + area = Area.objects.create(name="Test Area") + child_area = Area.objects.create( + name="Child Area", parent=area, manager=self.user + ) + self.assertIn(self.user, area.get_children_managers()) + self.assertEqual(len(area.get_children_managers()), 1) + + def test_get_parents(self): + """Test the get_parents method of the area model.""" + area = Area.objects.first() + if not area: + area = Area.objects.create(name="Test Area") + parent_area = Area.objects.create(name="Parent Area") + area.parent = parent_area + area.save() + self.assertIn(parent_area, area.get_parents()) + self.assertEqual(len(area.get_parents()), 1) + + def test_get_parents_managers(self): + """Test the get_parents_managers method of the area model.""" + area = Area.objects.first() + if not area: + area = Area.objects.create(name="Test Area") + parent_area = Area.objects.create(name="Parent Area", manager=self.user) + area.parent = parent_area + area.save() + self.assertIn(self.user, area.get_parents_managers()) + self.assertEqual(len(area.get_parents_managers()), 1) diff --git a/INSIGHTSAPI/vacation/tests.py b/INSIGHTSAPI/vacation/tests.py index 6b00962..9d9ee66 100644 --- a/INSIGHTSAPI/vacation/tests.py +++ b/INSIGHTSAPI/vacation/tests.py @@ -600,3 +600,16 @@ def test_get_vacation_pdf(self): ) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response["Content-Type"], "application/pdf") + + def test_get_manage_multiple_children(self): + """Test managing multiple children.""" + self.vacation_request["user"] = self.test_user + self.vacation_request["uploaded_by"] = self.test_user + self.test_user.area.parent = self.user.area + self.test_user.area.save() + VacationRequest.objects.create(**self.vacation_request) + response = self.client.get( + reverse("vacation-list"), + ) + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertEqual(len(response.data), 1) diff --git a/INSIGHTSAPI/vacation/views.py b/INSIGHTSAPI/vacation/views.py index bef5069..981e040 100644 --- a/INSIGHTSAPI/vacation/views.py +++ b/INSIGHTSAPI/vacation/views.py @@ -19,7 +19,11 @@ class VacationRequestViewSet(viewsets.ModelViewSet): - queryset = VacationRequest.objects.all().select_related("user", "uploaded_by").order_by("-created_at") + queryset = ( + VacationRequest.objects.all() + .select_related("user", "uploaded_by") + .order_by("-created_at") + ) serializer_class = VacationRequestSerializer permission_classes = [IsAuthenticated] @@ -126,14 +130,31 @@ def list(self, request, *args, **kwargs): queryset = self.queryset.all() # Check if the user has employee management permissions elif request.user.job_position.rank >= 2: - queryset = self.queryset.filter( - (Q(uploaded_by=request.user) | Q(user=request.user)) - | (Q(user__area__manager=request.user)) - | ( - Q(user__job_position__rank__lt=request.user.job_position.rank) - & Q(user__area=request.user.area) + children = self.request.user.area.get_children() + # Check if the user is a manager + if children and request.user.area.manager == request.user: + queryset = self.queryset.filter( + # Check if was uploaded by the user or if the user is the owner + (Q(uploaded_by=request.user) | Q(user=request.user)) + # Check if the user is a manager of the area + | (Q(user__area__manager=request.user)) + # Check if the user is a manager of a child area + | (Q(user__area__in=children)) + | ( + Q(user__job_position__rank__lt=request.user.job_position.rank) + & Q(user__area=request.user.area) + ) + ) + else: + queryset = self.queryset.filter( + Q(uploaded_by=request.user) + | Q(user=request.user) + | (Q(user__area__manager=request.user)) + | ( + Q(user__job_position__rank__lt=request.user.job_position.rank) + & Q(user__area=request.user.area) + ) ) - ) # The user is a regular employee else: queryset = self.queryset.filter(