wbhuman_resources 1.58.4__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. wbhuman_resources/__init__.py +1 -0
  2. wbhuman_resources/admin/__init__.py +5 -0
  3. wbhuman_resources/admin/absence.py +113 -0
  4. wbhuman_resources/admin/calendars.py +37 -0
  5. wbhuman_resources/admin/employee.py +109 -0
  6. wbhuman_resources/admin/kpi.py +21 -0
  7. wbhuman_resources/admin/review.py +157 -0
  8. wbhuman_resources/apps.py +23 -0
  9. wbhuman_resources/dynamic_preferences_registry.py +119 -0
  10. wbhuman_resources/factories/__init__.py +38 -0
  11. wbhuman_resources/factories/absence.py +109 -0
  12. wbhuman_resources/factories/calendars.py +60 -0
  13. wbhuman_resources/factories/employee.py +80 -0
  14. wbhuman_resources/factories/kpi.py +155 -0
  15. wbhuman_resources/filters/__init__.py +20 -0
  16. wbhuman_resources/filters/absence.py +109 -0
  17. wbhuman_resources/filters/absence_graphs.py +85 -0
  18. wbhuman_resources/filters/calendars.py +28 -0
  19. wbhuman_resources/filters/employee.py +81 -0
  20. wbhuman_resources/filters/kpi.py +35 -0
  21. wbhuman_resources/filters/review.py +134 -0
  22. wbhuman_resources/filters/signals.py +27 -0
  23. wbhuman_resources/locale/de/LC_MESSAGES/django.mo +0 -0
  24. wbhuman_resources/locale/de/LC_MESSAGES/django.po +2207 -0
  25. wbhuman_resources/locale/de/LC_MESSAGES/django.po.translated +2456 -0
  26. wbhuman_resources/locale/en/LC_MESSAGES/django.mo +0 -0
  27. wbhuman_resources/locale/en/LC_MESSAGES/django.po +2091 -0
  28. wbhuman_resources/locale/fr/LC_MESSAGES/django.mo +0 -0
  29. wbhuman_resources/locale/fr/LC_MESSAGES/django.po +2093 -0
  30. wbhuman_resources/management/__init__.py +23 -0
  31. wbhuman_resources/migrations/0001_initial_squashed_squashed_0015_alter_absencerequest_calendaritem_ptr_and_more.py +949 -0
  32. wbhuman_resources/migrations/0016_alter_employeehumanresource_options.py +20 -0
  33. wbhuman_resources/migrations/0017_absencerequest_crossborder_country_and_more.py +55 -0
  34. wbhuman_resources/migrations/0018_remove_position_group_position_groups.py +32 -0
  35. wbhuman_resources/migrations/0019_alter_absencerequest_options_alter_kpi_options_and_more.py +44 -0
  36. wbhuman_resources/migrations/0020_alter_employeeyearbalance_year_alter_review_year.py +27 -0
  37. wbhuman_resources/migrations/0021_alter_position_color.py +18 -0
  38. wbhuman_resources/migrations/0022_remove_review_editable_mode.py +64 -0
  39. wbhuman_resources/migrations/__init__.py +0 -0
  40. wbhuman_resources/models/__init__.py +23 -0
  41. wbhuman_resources/models/absence.py +903 -0
  42. wbhuman_resources/models/calendars.py +370 -0
  43. wbhuman_resources/models/employee.py +1241 -0
  44. wbhuman_resources/models/kpi.py +199 -0
  45. wbhuman_resources/models/preferences.py +40 -0
  46. wbhuman_resources/models/review.py +982 -0
  47. wbhuman_resources/permissions/__init__.py +0 -0
  48. wbhuman_resources/permissions/backend.py +26 -0
  49. wbhuman_resources/serializers/__init__.py +49 -0
  50. wbhuman_resources/serializers/absence.py +308 -0
  51. wbhuman_resources/serializers/calendars.py +73 -0
  52. wbhuman_resources/serializers/employee.py +267 -0
  53. wbhuman_resources/serializers/kpi.py +80 -0
  54. wbhuman_resources/serializers/review.py +415 -0
  55. wbhuman_resources/signals.py +4 -0
  56. wbhuman_resources/tasks.py +195 -0
  57. wbhuman_resources/templates/review/review_report.html +322 -0
  58. wbhuman_resources/tests/__init__.py +1 -0
  59. wbhuman_resources/tests/conftest.py +96 -0
  60. wbhuman_resources/tests/models/__init__.py +0 -0
  61. wbhuman_resources/tests/models/test_absences.py +478 -0
  62. wbhuman_resources/tests/models/test_calendars.py +209 -0
  63. wbhuman_resources/tests/models/test_employees.py +502 -0
  64. wbhuman_resources/tests/models/test_review.py +103 -0
  65. wbhuman_resources/tests/models/test_utils.py +110 -0
  66. wbhuman_resources/tests/signals.py +108 -0
  67. wbhuman_resources/tests/test_permission.py +64 -0
  68. wbhuman_resources/tests/test_tasks.py +74 -0
  69. wbhuman_resources/urls.py +221 -0
  70. wbhuman_resources/utils.py +43 -0
  71. wbhuman_resources/viewsets/__init__.py +61 -0
  72. wbhuman_resources/viewsets/absence.py +312 -0
  73. wbhuman_resources/viewsets/absence_charts.py +328 -0
  74. wbhuman_resources/viewsets/buttons/__init__.py +7 -0
  75. wbhuman_resources/viewsets/buttons/absence.py +32 -0
  76. wbhuman_resources/viewsets/buttons/employee.py +44 -0
  77. wbhuman_resources/viewsets/buttons/kpis.py +16 -0
  78. wbhuman_resources/viewsets/buttons/review.py +195 -0
  79. wbhuman_resources/viewsets/calendars.py +103 -0
  80. wbhuman_resources/viewsets/display/__init__.py +39 -0
  81. wbhuman_resources/viewsets/display/absence.py +334 -0
  82. wbhuman_resources/viewsets/display/calendars.py +83 -0
  83. wbhuman_resources/viewsets/display/employee.py +254 -0
  84. wbhuman_resources/viewsets/display/kpis.py +92 -0
  85. wbhuman_resources/viewsets/display/review.py +429 -0
  86. wbhuman_resources/viewsets/employee.py +210 -0
  87. wbhuman_resources/viewsets/endpoints/__init__.py +42 -0
  88. wbhuman_resources/viewsets/endpoints/absence.py +57 -0
  89. wbhuman_resources/viewsets/endpoints/calendars.py +18 -0
  90. wbhuman_resources/viewsets/endpoints/employee.py +51 -0
  91. wbhuman_resources/viewsets/endpoints/kpis.py +53 -0
  92. wbhuman_resources/viewsets/endpoints/review.py +191 -0
  93. wbhuman_resources/viewsets/kpi.py +280 -0
  94. wbhuman_resources/viewsets/menu/__init__.py +22 -0
  95. wbhuman_resources/viewsets/menu/absence.py +50 -0
  96. wbhuman_resources/viewsets/menu/administration.py +15 -0
  97. wbhuman_resources/viewsets/menu/calendars.py +33 -0
  98. wbhuman_resources/viewsets/menu/employee.py +44 -0
  99. wbhuman_resources/viewsets/menu/kpis.py +18 -0
  100. wbhuman_resources/viewsets/menu/review.py +97 -0
  101. wbhuman_resources/viewsets/mixins.py +14 -0
  102. wbhuman_resources/viewsets/review.py +837 -0
  103. wbhuman_resources/viewsets/titles/__init__.py +18 -0
  104. wbhuman_resources/viewsets/titles/absence.py +30 -0
  105. wbhuman_resources/viewsets/titles/employee.py +18 -0
  106. wbhuman_resources/viewsets/titles/kpis.py +15 -0
  107. wbhuman_resources/viewsets/titles/review.py +62 -0
  108. wbhuman_resources/viewsets/utils.py +28 -0
  109. wbhuman_resources-1.58.4.dist-info/METADATA +8 -0
  110. wbhuman_resources-1.58.4.dist-info/RECORD +111 -0
  111. wbhuman_resources-1.58.4.dist-info/WHEEL +5 -0
@@ -0,0 +1,210 @@
1
+ from django.db.models import F, OuterRef, Subquery
2
+ from rest_framework.decorators import action
3
+ from rest_framework.response import Response
4
+ from wbcore import viewsets
5
+ from wbcore.contrib.directory.models import Person
6
+ from wbcore.utils.date import current_month_date_end
7
+
8
+ from wbhuman_resources.filters import (
9
+ EmployeeBalanceFilterSet,
10
+ EmployeeFilterSet,
11
+ PositionFilterSet,
12
+ )
13
+ from wbhuman_resources.models import (
14
+ EmployeeHumanResource,
15
+ EmployeeWeeklyOffPeriods,
16
+ EmployeeYearBalance,
17
+ Position,
18
+ deactivate_profile_as_task,
19
+ )
20
+ from wbhuman_resources.serializers import (
21
+ EmployeeBalanceModelSerializer,
22
+ EmployeeHumanResourceRepresentationSerializer,
23
+ EmployeeModelSerializer,
24
+ EmployeeWeeklyOffPeriodsModelSerializer,
25
+ EmployeeYearBalanceModelSerializer,
26
+ EmployeeYearBalanceRepresentationSerializer,
27
+ PositionModelSerializer,
28
+ PositionRepresentationSerializer,
29
+ )
30
+ from wbhuman_resources.viewsets.buttons import (
31
+ EmployeeButtonConfig,
32
+ YearBalanceEmployeeHumanResourceButtonConfig,
33
+ )
34
+ from wbhuman_resources.viewsets.display import (
35
+ EmployeeBalanceDisplayConfig,
36
+ EmployeeDisplayConfig,
37
+ PositionDisplayConfig,
38
+ WeeklyOffPeriodEmployeeHumanResourceDisplayConfig,
39
+ YearBalanceEmployeeHumanResourceDisplayConfig,
40
+ )
41
+ from wbhuman_resources.viewsets.endpoints import (
42
+ EmployeeBalanceEndpointConfig,
43
+ WeeklyOffPeriodEmployeeHumanResourceEndpointConfig,
44
+ YearBalanceEmployeeHumanResourceEndpointConfig,
45
+ )
46
+ from wbhuman_resources.viewsets.titles import (
47
+ EmployeeBalanceTitleConfig,
48
+ EmployeeTitleConfig,
49
+ )
50
+
51
+ from .mixins import EmployeeViewMixin
52
+
53
+
54
+ class PositionRepresentationViewSet(viewsets.RepresentationViewSet):
55
+ ordering_fields = ordering = ("name",)
56
+ search_fields = ("name",)
57
+ filterset_fields = {"height": ["exact"], "level": ["exact"]}
58
+ queryset = Position.objects.all()
59
+ serializer_class = PositionRepresentationSerializer
60
+
61
+
62
+ class EmployeeHumanResourceRepresentationViewSet(viewsets.RepresentationViewSet):
63
+ ordering_fields = ordering = ("profile__computed_str",)
64
+ search_fields = ("profile__computed_str",)
65
+
66
+ queryset = EmployeeHumanResource.active_employees.select_related("profile")
67
+ serializer_class = EmployeeHumanResourceRepresentationSerializer
68
+
69
+
70
+ class EmployeeYearBalanceRepresentationViewSet(viewsets.RepresentationViewSet):
71
+ ordering_fields = ordering = "-year"
72
+
73
+ queryset = EmployeeYearBalance.objects.all()
74
+ serializer_class = EmployeeYearBalanceRepresentationSerializer
75
+
76
+
77
+ class PositionModelViewSet(viewsets.ModelViewSet):
78
+ queryset = Position.objects.select_related(
79
+ "parent",
80
+ "manager",
81
+ )
82
+ serializer_class = PositionModelSerializer
83
+
84
+ filterset_class = PositionFilterSet
85
+ ordering_fields = ordering = ["name"]
86
+ search_fields = ["name"]
87
+
88
+ display_config_class = PositionDisplayConfig
89
+
90
+
91
+ class EmployeeBalanceModelViewSet(EmployeeViewMixin, viewsets.ModelViewSet):
92
+ queryset = EmployeeHumanResource.objects.all()
93
+ serializer_class = EmployeeBalanceModelSerializer
94
+
95
+ filterset_class = EmployeeBalanceFilterSet
96
+ ordering_fields = [
97
+ "profile__computed_str",
98
+ "contract_type",
99
+ "is_active",
100
+ "position__name",
101
+ "extra_days_frequency",
102
+ "extra_days_per_period",
103
+ "took_long_vacations",
104
+ "available_vacation_balance_previous_year",
105
+ "available_vacation_balance_current_year",
106
+ "available_vacation_balance_next_year",
107
+ ]
108
+ ordering = ["profile__computed_str"]
109
+ search_fields = ["profile__computed_str"]
110
+
111
+ title_config_class = EmployeeBalanceTitleConfig
112
+ display_config_class = EmployeeBalanceDisplayConfig
113
+ endpoint_config_class = EmployeeBalanceEndpointConfig
114
+
115
+ def get_queryset(self):
116
+ qs = EmployeeHumanResource.objects.none()
117
+ if self.is_administrator:
118
+ qs = super().get_queryset()
119
+ if employee := getattr(self.request.user.profile, "human_resources", None):
120
+ qs = employee.get_managed_employees()
121
+ return (
122
+ EmployeeHumanResource.annotated_queryset(qs, current_month_date_end())
123
+ .filter(balances__isnull=False)
124
+ .distinct()
125
+ ).select_related(
126
+ "profile",
127
+ "position",
128
+ "calendar",
129
+ )
130
+
131
+
132
+ class EmployeeModelViewSet(EmployeeViewMixin, viewsets.ModelViewSet):
133
+ queryset = EmployeeHumanResource.objects.all()
134
+ serializer_class = EmployeeModelSerializer
135
+
136
+ ordering_fields = [
137
+ "profile__computed_str",
138
+ "position__name",
139
+ "top_position_repr",
140
+ "primary_telephone",
141
+ "primary_email",
142
+ "primary_address",
143
+ ]
144
+ ordering = ["profile__computed_str"]
145
+ search_fields = ["profile__computed_str", "primary_telephone", "primary_email", "primary_address"]
146
+
147
+ filterset_class = EmployeeFilterSet
148
+
149
+ title_config_class = EmployeeTitleConfig
150
+ display_config_class = EmployeeDisplayConfig
151
+ button_config_class = EmployeeButtonConfig
152
+
153
+ def get_queryset(self):
154
+ return (
155
+ super()
156
+ .get_queryset()
157
+ .annotate(
158
+ top_position_repr=F("position__parent__name"),
159
+ position_manager=F("position__manager"),
160
+ primary_email=Subquery(
161
+ Person.objects.filter(id=OuterRef("profile")).annotate_all().values("primary_email")[:1]
162
+ ),
163
+ primary_address=Subquery(
164
+ Person.objects.filter(id=OuterRef("profile")).annotate_all().values("primary_address")[:1]
165
+ ),
166
+ primary_telephone=Subquery(
167
+ Person.objects.filter(id=OuterRef("profile")).annotate_all().values("primary_telephone")[:1]
168
+ ),
169
+ )
170
+ .select_related(
171
+ "direct_manager",
172
+ "position",
173
+ "calendar",
174
+ "profile",
175
+ )
176
+ .prefetch_related("balances", "position__manager")
177
+ )
178
+
179
+ @action(detail=True, methods=["PATCH"])
180
+ def deactivate(self, request, pk=None):
181
+ if pk and EmployeeHumanResource.is_administrator(self.request.user):
182
+ deactivate_profile_as_task.delay(request.user.id, pk, request.POST.get("substitute", None))
183
+ return Response({"send": True})
184
+
185
+
186
+ # Employee Subs Viewsets
187
+
188
+
189
+ class WeeklyOffPeriodEmployeeHumanResourceModelViewSet(viewsets.ModelViewSet):
190
+ display_config_class = WeeklyOffPeriodEmployeeHumanResourceDisplayConfig
191
+ endpoint_config_class = WeeklyOffPeriodEmployeeHumanResourceEndpointConfig
192
+
193
+ serializer_class = EmployeeWeeklyOffPeriodsModelSerializer
194
+ queryset = EmployeeWeeklyOffPeriods.objects.all()
195
+
196
+ def get_queryset(self):
197
+ return super().get_queryset().filter(employee=self.kwargs["employee_id"])
198
+
199
+
200
+ class YearBalanceEmployeeHumanResourceModelViewset(viewsets.ModelViewSet):
201
+ display_config_class = YearBalanceEmployeeHumanResourceDisplayConfig
202
+ endpoint_config_class = YearBalanceEmployeeHumanResourceEndpointConfig
203
+ button_config_class = YearBalanceEmployeeHumanResourceButtonConfig
204
+
205
+ ordering = ["-year"]
206
+ serializer_class = EmployeeYearBalanceModelSerializer
207
+ queryset = EmployeeYearBalance.objects.all()
208
+
209
+ def get_queryset(self):
210
+ return super().get_queryset().filter(employee=self.kwargs["employee_id"])
@@ -0,0 +1,42 @@
1
+ from .absence import (
2
+ AbsenceRequestCrossBorderCountryEndpointConfig,
3
+ AbsenceRequestEndpointConfig,
4
+ AbsenceRequestPeriodsAbsenceRequestEndpointConfig,
5
+ AbsenceRequestPlannerEndpointConfig,
6
+ AbsenceTablePandasEndpointConfig,
7
+ AbsenceTypeCountEmployeeEndpointConfig,
8
+ )
9
+ from .calendars import (
10
+ DayOffDayOffCalendarEndpointConfig,
11
+ DefaultDailyPeriodDayOffCalendar,
12
+ )
13
+ from .employee import (
14
+ AbsenceRequestEmployeeHumanResourceEndpointConfig,
15
+ EmployeeBalanceEndpointConfig,
16
+ EmployeeEndpointConfig,
17
+ WeeklyOffPeriodEmployeeHumanResourceEndpointConfig,
18
+ YearBalanceEmployeeHumanResourceEndpointConfig,
19
+ )
20
+ from .kpis import (
21
+ EvaluationGraphEndpointConfig,
22
+ KPIEndpointConfig,
23
+ KPIEvaluationEndpointConfig,
24
+ KPIEvaluationPandasEndpointConfig,
25
+ )
26
+ from .review import (
27
+ ReviewAnswerReviewPandasEndpointConfig,
28
+ ReviewAnswerEndpointConfig,
29
+ ReviewAnswerReviewNoCategoryEndpointConfig,
30
+ ReviewAnswerReviewQuestionCategoryEndpointConfig,
31
+ ReviewEndpointConfig,
32
+ ReviewGroupEndpointConfig,
33
+ ReviewProgressPandasEndpointConfig,
34
+ ReviewProgressReviewPandasEndpointConfig,
35
+ ReviewQuestionCategoryEndpointConfig,
36
+ ReviewQuestionEndpointConfig,
37
+ ReviewQuestionReviewCategoryEndpointConfig,
38
+ ReviewQuestionReviewEndpointConfig,
39
+ ReviewQuestionReviewNoCategoryEndpointConfig,
40
+ ReviewQuestionReviewQuestionCategoryEndpointConfig,
41
+ ReviewReviewGroupEndpointConfig,
42
+ )
@@ -0,0 +1,57 @@
1
+ from rest_framework.reverse import reverse
2
+ from wbcore.metadata.configs.endpoints import EndpointViewConfig
3
+
4
+ from wbhuman_resources.models import AbsenceRequest, EmployeeHumanResource
5
+
6
+
7
+ class AbsenceRequestEndpointConfig(EndpointViewConfig):
8
+ def get_endpoint(self, **kwargs):
9
+ return reverse(f"{self.view.get_model().get_endpoint_basename()}-list", request=self.request)
10
+
11
+ def get_instance_endpoint(self, **kwargs):
12
+ if self.instance:
13
+ obj = self.view.get_object()
14
+ if obj.status != AbsenceRequest.Status.DRAFT.name and not EmployeeHumanResource.is_administrator(
15
+ self.request.user
16
+ ):
17
+ return None
18
+ return self.get_endpoint()
19
+
20
+ def get_create_endpoint(self, **kwargs):
21
+ return self.get_endpoint()
22
+
23
+ def get_delete_endpoint(self, **kwargs):
24
+ if self.instance:
25
+ obj = self.view.get_object()
26
+ if obj.is_deletable_for_user(self.request.user):
27
+ return self.get_endpoint()
28
+ return None
29
+
30
+
31
+ class AbsenceRequestCrossBorderCountryEndpointConfig(EndpointViewConfig):
32
+ def get_endpoint(self, **kwargs):
33
+ return reverse(
34
+ "wbhuman_resources:absencerequesttype-crossbordercountry-list",
35
+ args=[self.view.kwargs["absencerequesttype_id"]],
36
+ request=self.request,
37
+ )
38
+
39
+
40
+ class AbsenceTypeCountEmployeeEndpointConfig(EndpointViewConfig):
41
+ def get_endpoint(self, **kwargs):
42
+ return None
43
+
44
+
45
+ class AbsenceRequestPeriodsAbsenceRequestEndpointConfig(EndpointViewConfig):
46
+ def get_endpoint(self, **kwargs):
47
+ return None
48
+
49
+
50
+ class AbsenceRequestPlannerEndpointConfig(EndpointViewConfig):
51
+ def get_endpoint(self, **kwargs):
52
+ return None
53
+
54
+
55
+ class AbsenceTablePandasEndpointConfig(EndpointViewConfig):
56
+ def get_endpoint(self, **kwargs):
57
+ return None
@@ -0,0 +1,18 @@
1
+ from rest_framework.reverse import reverse
2
+ from wbcore.metadata.configs.endpoints import EndpointViewConfig
3
+
4
+
5
+ class DayOffDayOffCalendarEndpointConfig(EndpointViewConfig):
6
+ def get_endpoint(self, **kwargs):
7
+ return reverse(
8
+ "wbhuman_resources:calendar-dayoff-list", args=[self.view.kwargs["calendar_id"]], request=self.request
9
+ )
10
+
11
+
12
+ class DefaultDailyPeriodDayOffCalendar(EndpointViewConfig):
13
+ def get_endpoint(self, **kwargs):
14
+ return reverse(
15
+ "wbhuman_resources:calendar-defaultperiod-list",
16
+ args=[self.view.kwargs["calendar_id"]],
17
+ request=self.request,
18
+ )
@@ -0,0 +1,51 @@
1
+ from rest_framework.reverse import reverse
2
+ from wbcore.metadata.configs.endpoints import EndpointViewConfig
3
+
4
+
5
+ class AbsenceRequestEmployeeHumanResourceEndpointConfig(EndpointViewConfig):
6
+ def get_create_endpoint(self, **kwargs):
7
+ return reverse("wbhuman_resources:absencerequest-list", args=[], request=self.request)
8
+
9
+ def get_endpoint(self, **kwargs):
10
+ return reverse(
11
+ "wbhuman_resources:employee-absencerequest-list",
12
+ args=[self.view.kwargs["employee_id"]],
13
+ request=self.request,
14
+ )
15
+
16
+
17
+ class YearBalanceEmployeeHumanResourceEndpointConfig(EndpointViewConfig):
18
+ def get_endpoint(self, **kwargs):
19
+ return reverse(
20
+ "wbhuman_resources:employee-employeeyearbalance-list",
21
+ args=[self.view.kwargs["employee_id"]],
22
+ request=self.request,
23
+ )
24
+
25
+ def get_create_endpoint(self, **kwargs):
26
+ return None
27
+
28
+ def get_delete_endpoint(self, **kwargs):
29
+ return None
30
+
31
+
32
+ class EmployeeBalanceEndpointConfig(EndpointViewConfig):
33
+ def get_instance_endpoint(self, **kwargs):
34
+ return reverse("wbhuman_resources:employeebalance-list", args=[], request=self.request)
35
+
36
+ def get_endpoint(self, **kwargs):
37
+ return None
38
+
39
+
40
+ class EmployeeEndpointConfig(EndpointViewConfig):
41
+ def get_endpoint(self, **kwargs):
42
+ return None
43
+
44
+
45
+ class WeeklyOffPeriodEmployeeHumanResourceEndpointConfig(EndpointViewConfig):
46
+ def get_endpoint(self, **kwargs):
47
+ return reverse(
48
+ "wbhuman_resources:employee-weeklyoffperiod-list",
49
+ args=[self.view.kwargs["employee_id"]],
50
+ request=self.request,
51
+ )
@@ -0,0 +1,53 @@
1
+ from rest_framework.reverse import reverse
2
+ from wbcore.metadata.configs.endpoints import EndpointViewConfig
3
+
4
+ from wbhuman_resources.models import KPI
5
+
6
+
7
+ class KPIEndpointConfig(EndpointViewConfig):
8
+ def get_endpoint(self, **kwargs):
9
+ return super().get_endpoint()
10
+
11
+ def get_instance_endpoint(self, **kwargs):
12
+ if self.instance:
13
+ if not KPI.is_administrator(self.request.user):
14
+ return None
15
+ return super().get_instance_endpoint()
16
+
17
+ def get_create_endpoint(self, **kwargs):
18
+ if KPI.is_administrator(self.request.user):
19
+ return super().get_instance_endpoint()
20
+ return None
21
+
22
+ def get_delete_endpoint(self, **kwargs):
23
+ if KPI.is_administrator(self.request.user):
24
+ return super().get_delete_endpoint()
25
+ return None
26
+
27
+
28
+ class KPIEvaluationEndpointConfig(EndpointViewConfig):
29
+ def get_endpoint(self, **kwargs):
30
+ return reverse(
31
+ "wbhuman_resources:kpi-evaluation-list",
32
+ args=[self.view.kwargs["kpi_id"]],
33
+ request=self.request,
34
+ )
35
+
36
+ def get_instance_endpoint(self, **kwargs):
37
+ if self.instance:
38
+ return None
39
+ return super().get_instance_endpoint()
40
+
41
+ def get_create_endpoint(self, **kwargs):
42
+ return None
43
+
44
+ def get_delete_endpoint(self, **kwargs):
45
+ return None
46
+
47
+
48
+ class EvaluationGraphEndpointConfig(EndpointViewConfig):
49
+ pass
50
+
51
+
52
+ class KPIEvaluationPandasEndpointConfig(EndpointViewConfig):
53
+ pass
@@ -0,0 +1,191 @@
1
+ from django.db.models import Q
2
+ from rest_framework.reverse import reverse
3
+ from wbcore.metadata.configs.endpoints import EndpointViewConfig
4
+
5
+ from wbhuman_resources.models import Review
6
+
7
+
8
+ class ReviewGroupEndpointConfig(EndpointViewConfig):
9
+ def get_endpoint(self, **kwargs):
10
+ return super().get_endpoint()
11
+
12
+
13
+ class ReviewEndpointConfig(EndpointViewConfig):
14
+ def get_endpoint(self, **kwargs):
15
+ if "pk" in self.view.kwargs:
16
+ obj = Review.objects.get(id=self.view.kwargs.get("pk"))
17
+ if (moderator := obj.moderator) and (moderator != self.request.user.profile):
18
+ return None
19
+ if obj.status in [Review.Status.REVIEW, Review.Status.EVALUATION, Review.Status.VALIDATION]:
20
+ return None
21
+ # Block click on the row to access to the view if it's not an administrator and no review is linked to this person and only has read access
22
+ elif (
23
+ self.request.user in Review.get_administrators()
24
+ and not self.request.user.has_perm("wbcompliance.add_review")
25
+ and self.request.user not in Review.get_administrators()
26
+ and self.view.get_queryset()
27
+ .filter(
28
+ Q(moderator=self.request.user.profile)
29
+ | Q(reviewer=self.request.user.profile)
30
+ | Q(reviewee=self.request.user.profile)
31
+ )
32
+ .count()
33
+ == 0
34
+ ):
35
+ return None
36
+ return super().get_endpoint()
37
+
38
+ def get_delete_endpoint(self, **kwargs):
39
+ if "pk" in self.view.kwargs:
40
+ obj = Review.objects.get(id=self.view.kwargs.get("pk"))
41
+ if obj.status in [Review.Status.REVIEW, Review.Status.EVALUATION, Review.Status.VALIDATION]:
42
+ return None
43
+ elif obj.moderator == self.request.user.profile:
44
+ return super().get_delete_endpoint()
45
+ return None
46
+
47
+
48
+ class ReviewReviewGroupEndpointConfig(ReviewEndpointConfig):
49
+ def get_endpoint(self, **kwargs):
50
+ if review_group_id := self.view.kwargs.get("review_group_id", None):
51
+ if "pk" in self.view.kwargs:
52
+ obj = Review.objects.get(id=self.view.kwargs.get("pk"))
53
+ if (moderator := obj.moderator) and (moderator != self.request.user.profile):
54
+ return None
55
+ if obj.status in [Review.Status.REVIEW, Review.Status.EVALUATION, Review.Status.VALIDATION]:
56
+ return None
57
+ return reverse("wbhuman_resources:reviewgroup-review-list", args=[review_group_id], request=self.request)
58
+ return None
59
+
60
+
61
+ class ReviewQuestionCategoryEndpointConfig(EndpointViewConfig):
62
+ def get_endpoint(self, **kwargs):
63
+ return super().get_endpoint()
64
+
65
+
66
+ class ReviewQuestionEndpointConfig(EndpointViewConfig):
67
+ def get_endpoint(self, **kwargs):
68
+ return super().get_endpoint()
69
+
70
+
71
+ class ReviewQuestionReviewEndpointConfig(ReviewQuestionEndpointConfig):
72
+ def get_endpoint(self, **kwargs):
73
+ if review_id := self.view.kwargs.get("review_id", None):
74
+ return reverse("wbhuman_resources:review-reviewquestion-list", args=[review_id], request=self.request)
75
+ return None
76
+
77
+ def get_create_endpoint(self, **kwargs):
78
+ if review_id := self.view.kwargs.get("review_id", None):
79
+ obj = Review.objects.get(id=review_id)
80
+ if obj.moderator == self.request.user.profile:
81
+ return self.get_endpoint()
82
+ return None
83
+
84
+ def get_delete_endpoint(self, **kwargs):
85
+ if review_id := self.view.kwargs.get("review_id", None):
86
+ obj = Review.objects.get(id=review_id)
87
+ if obj.moderator == self.request.user.profile:
88
+ if "pk" in self.view.kwargs:
89
+ return f'{self.get_endpoint()}{self.view.kwargs["pk"]}/'
90
+ return super().get_delete_endpoint()
91
+ return None
92
+
93
+
94
+ class ReviewQuestionReviewNoCategoryEndpointConfig(ReviewQuestionReviewEndpointConfig):
95
+ def get_endpoint(self, **kwargs):
96
+ if review_id := self.view.kwargs.get("review_id", None):
97
+ return reverse(
98
+ "wbhuman_resources:review-reviewquestionnocategory-list", args=[review_id], request=self.request
99
+ )
100
+ return None
101
+
102
+
103
+ class ReviewQuestionReviewCategoryEndpointConfig(ReviewQuestionReviewEndpointConfig):
104
+ def get_endpoint(self, **kwargs):
105
+ if (review_id := self.view.kwargs.get("review_id", None)) and (
106
+ category_id := self.view.kwargs.get("category_id", None)
107
+ ):
108
+ return reverse(
109
+ "wbhuman_resources:review-reviewquestioncategory-list",
110
+ args=[review_id, category_id],
111
+ request=self.request,
112
+ )
113
+ return None
114
+
115
+
116
+ class ReviewQuestionReviewQuestionCategoryEndpointConfig(ReviewQuestionEndpointConfig):
117
+ def get_endpoint(self, **kwargs):
118
+ if category_id := self.view.kwargs.get("category_id", None):
119
+ return reverse(
120
+ "wbhuman_resources:reviewquestioncategory-reviewquestion-list",
121
+ args=[category_id],
122
+ request=self.request,
123
+ )
124
+ return None
125
+
126
+
127
+ class ReviewAnswerEndpointConfig(EndpointViewConfig):
128
+ def get_endpoint(self, **kwargs):
129
+ return super().get_endpoint()
130
+
131
+ def get_instance_endpoint(self, **kwargs):
132
+ if self.instance:
133
+ obj = self.view.get_object()
134
+ if obj.question.review.status in [
135
+ Review.Status.PREPARATION_OF_REVIEW,
136
+ Review.Status.REVIEW,
137
+ Review.Status.EVALUATION,
138
+ Review.Status.VALIDATION,
139
+ ]:
140
+ return None
141
+ return super().get_endpoint()
142
+
143
+ def get_create_endpoint(self, **kwargs):
144
+ return None
145
+
146
+ def get_delete_endpoint(self, **kwargs):
147
+ return None
148
+
149
+
150
+ class ReviewAnswerReviewNoCategoryEndpointConfig(ReviewAnswerEndpointConfig):
151
+ def get_endpoint(self, **kwargs):
152
+ if review_id := self.view.kwargs.get("review_id", None):
153
+ return reverse(
154
+ "wbhuman_resources:review-reviewanswerquestionnocategory-list", args=[review_id], request=self.request
155
+ )
156
+ return None
157
+
158
+
159
+ class ReviewAnswerReviewQuestionCategoryEndpointConfig(ReviewAnswerEndpointConfig):
160
+ def get_endpoint(self, **kwargs):
161
+ if (review_id := self.view.kwargs.get("review_id", None)) and (
162
+ category_id := self.view.kwargs.get("category_id", None)
163
+ ):
164
+ return reverse(
165
+ "wbhuman_resources:review-reviewanswerquestioncategory-list",
166
+ args=[review_id, category_id],
167
+ request=self.request,
168
+ )
169
+ return None
170
+
171
+
172
+ class ReviewProgressReviewPandasEndpointConfig(EndpointViewConfig):
173
+ def get_endpoint(self, **kwargs):
174
+ return None
175
+
176
+
177
+ class ReviewAnswerReviewPandasEndpointConfig(EndpointViewConfig):
178
+ def get_endpoint(self, **kwargs):
179
+ return reverse(
180
+ "wbhuman_resources:review-reviewquestion-list",
181
+ [self.view.kwargs["review_id"]],
182
+ request=self.request,
183
+ )
184
+
185
+
186
+ class ReviewProgressPandasEndpointConfig(EndpointViewConfig):
187
+ def get_endpoint(self, **kwargs):
188
+ return None
189
+
190
+ def get_instance_endpoint(self, **kwargs):
191
+ return reverse("wbhuman_resources:review-list", args=[], request=self.request)