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,267 @@
1
+ from django.utils.translation import gettext_lazy as _
2
+ from rest_framework.reverse import reverse
3
+ from wbcore import serializers as wb_serializers
4
+ from wbcore.contrib.authentication.serializers import GroupRepresentationSerializer
5
+ from wbcore.contrib.directory.models import Person
6
+ from wbcore.contrib.directory.serializers import PersonRepresentationSerializer
7
+
8
+ from wbhuman_resources.models import (
9
+ EmployeeHumanResource,
10
+ EmployeeWeeklyOffPeriods,
11
+ EmployeeYearBalance,
12
+ Position,
13
+ )
14
+
15
+ from .calendars import (
16
+ DayOffCalendarRepresentationSerializer,
17
+ DefaultDailyPeriodRepresentationSerializer,
18
+ )
19
+
20
+
21
+ class PositionRepresentationSerializer(wb_serializers.RepresentationSerializer):
22
+ _detail = wb_serializers.HyperlinkField(reverse_name="wbhuman_resources:position-detail")
23
+
24
+ class Meta:
25
+ model = Position
26
+ fields = ("id", "computed_str", "height", "level", "_detail")
27
+
28
+
29
+ class EmployeeYearBalanceRepresentationSerializer(wb_serializers.RepresentationSerializer):
30
+ class Meta:
31
+ model = EmployeeYearBalance
32
+ fields = ("id", "computed_str")
33
+
34
+
35
+ class EmployeeHumanResourceRepresentationSerializer(wb_serializers.RepresentationSerializer):
36
+ _detail = wb_serializers.HyperlinkField(reverse_name="wbhuman_resources:employee-detail")
37
+
38
+ class Meta:
39
+ model = EmployeeHumanResource
40
+ fields = ("id", "computed_str", "is_active", "_detail")
41
+
42
+
43
+ class EmployeeWeeklyOffPeriodsModelSerializer(wb_serializers.ModelSerializer):
44
+ _employee = EmployeeHumanResourceRepresentationSerializer(source="calendar")
45
+ _period = DefaultDailyPeriodRepresentationSerializer(source="period")
46
+
47
+ class Meta:
48
+ model = EmployeeWeeklyOffPeriods
49
+ fields = ("id", "employee", "period", "weekday", "_employee", "_period", "computed_str")
50
+
51
+
52
+ class PositionModelSerializer(wb_serializers.ModelSerializer):
53
+ _parent = PositionRepresentationSerializer(source="parent")
54
+ _manager = PersonRepresentationSerializer(source="manager", filter_params={"is_internal_profile": True})
55
+ _groups = GroupRepresentationSerializer(source="groups", many=True)
56
+
57
+ class Meta:
58
+ model = Position
59
+ read_only_fields = ["groups", "_groups"]
60
+ fields = [
61
+ "id",
62
+ "name",
63
+ "color",
64
+ "computed_str",
65
+ "level",
66
+ "height",
67
+ "parent",
68
+ "_parent",
69
+ "manager",
70
+ "_manager",
71
+ "_groups",
72
+ "groups",
73
+ ]
74
+
75
+
76
+ class EmployeeBalanceModelSerializer(wb_serializers.ModelSerializer):
77
+ _profile = PersonRepresentationSerializer(source="profile")
78
+ _position = PositionRepresentationSerializer(source="position")
79
+ _calendar = DayOffCalendarRepresentationSerializer(source="calendar")
80
+
81
+ available_vacation_balance_previous_year = wb_serializers.FloatField(
82
+ label=_("Available Vacation Balance from previous year"),
83
+ read_only=True,
84
+ help_text=_(
85
+ "Available Vacation Balance from previous year. Can only be used until a certain point the next year."
86
+ ),
87
+ )
88
+ available_vacation_balance_current_year = wb_serializers.FloatField(
89
+ label=_("Available Vacation Balance from current year"),
90
+ read_only=True,
91
+ help_text=_("Available Vacation Balance from the current year balance."),
92
+ )
93
+
94
+ available_vacation_balance_next_year = wb_serializers.FloatField(
95
+ label=_("Available Vacation Balance from next year"),
96
+ read_only=True,
97
+ help_text=_("Available Vacation Balance from the next year balance."),
98
+ )
99
+
100
+ took_long_vacations = wb_serializers.BooleanField(
101
+ label=_("Long Vacation"),
102
+ help_text=_("True if the user took at least one long vacation in a row"),
103
+ read_only=True,
104
+ default=False,
105
+ )
106
+
107
+ extra_days_per_period = wb_serializers.FloatField(read_only=True, label=_("Extra days per period"))
108
+
109
+ @wb_serializers.register_resource()
110
+ def additional_resources(self, instance, request, user):
111
+ additional_resources = dict()
112
+
113
+ additional_resources["periods_count_per_type"] = reverse(
114
+ "wbhuman_resources:employee-absencecount-list",
115
+ args=[instance.id],
116
+ request=request,
117
+ )
118
+ additional_resources["absencerequest"] = reverse(
119
+ "wbhuman_resources:employee-absencerequest-list",
120
+ args=[instance.id],
121
+ request=request,
122
+ )
123
+
124
+ if (view := request.parser_context["view"]) and view.is_administrator:
125
+ additional_resources["employeeyearbalance"] = reverse(
126
+ "wbhuman_resources:employee-employeeyearbalance-list",
127
+ args=[instance.id],
128
+ request=request,
129
+ )
130
+ return additional_resources
131
+
132
+ class Meta:
133
+ model = EmployeeHumanResource
134
+ percent_fields = ["occupancy_rate"]
135
+ fields = [
136
+ "id",
137
+ "profile",
138
+ "computed_str",
139
+ "position",
140
+ "_position",
141
+ "is_active",
142
+ "enrollment_at",
143
+ "_profile",
144
+ "extra_days_frequency",
145
+ "extra_days_per_period",
146
+ "occupancy_rate",
147
+ "contract_type",
148
+ "available_vacation_balance_previous_year",
149
+ "available_vacation_balance_current_year",
150
+ "available_vacation_balance_next_year",
151
+ "took_long_vacations",
152
+ "calendar",
153
+ "_calendar",
154
+ "_additional_resources",
155
+ ]
156
+
157
+
158
+ class EmployeeModelSerializer(wb_serializers.ModelSerializer):
159
+ _direct_manager = PersonRepresentationSerializer(
160
+ source="direct_manager", filter_params={"is_internal_profile": True}
161
+ )
162
+ _position = PositionRepresentationSerializer(source="position")
163
+ _calendar = DayOffCalendarRepresentationSerializer(source="calendar")
164
+ _profile = PersonRepresentationSerializer(source="profile")
165
+
166
+ position_manager = wb_serializers.PrimaryKeyRelatedField(read_only=True)
167
+ _position_manager = PersonRepresentationSerializer(
168
+ source="position_manager", filter_params={"is_internal_profile": True}
169
+ )
170
+ top_position_repr = wb_serializers.CharField(read_only=True)
171
+ primary_email = wb_serializers.CharField(label=_("Primary Email"), allow_null=True, read_only=True)
172
+ primary_address = wb_serializers.CharField(label=_("Primary Address"), allow_null=True, read_only=True)
173
+ primary_telephone = wb_serializers.TelephoneField(label=_("Primary Telephone"), allow_null=True, read_only=True)
174
+
175
+ @wb_serializers.register_resource()
176
+ def extra_additional_resources(self, instance, request, user):
177
+ res = dict()
178
+
179
+ if instance.is_active and (view := request.parser_context["view"]):
180
+ if view.is_administrator:
181
+ res["deactivate"] = reverse(
182
+ "wbhuman_resources:employee-deactivate",
183
+ args=[instance.id],
184
+ request=request,
185
+ )
186
+
187
+ if (
188
+ view.is_administrator or instance in view.employee.get_managed_employees()
189
+ ) and instance.balances.exists():
190
+ res["balance_and_usage"] = reverse(
191
+ "wbhuman_resources:employeebalance-detail",
192
+ args=[instance.id],
193
+ request=request,
194
+ )
195
+ return res
196
+
197
+ class Meta:
198
+ fields = [
199
+ "id",
200
+ "_profile",
201
+ "profile",
202
+ "position",
203
+ "_position",
204
+ "_position_manager",
205
+ "position_manager",
206
+ "top_position_repr",
207
+ "primary_telephone",
208
+ "primary_email",
209
+ "primary_address",
210
+ "direct_manager",
211
+ "_direct_manager",
212
+ "calendar",
213
+ "_calendar",
214
+ "enrollment_at",
215
+ "occupancy_rate",
216
+ "contract_type",
217
+ "is_active",
218
+ "extra_days_frequency",
219
+ "_additional_resources",
220
+ ]
221
+ model = EmployeeHumanResource
222
+
223
+
224
+ class DeactivateEmployeeSerializer(wb_serializers.Serializer):
225
+ substitute = wb_serializers.PrimaryKeyRelatedField(
226
+ queryset=Person.objects.all(), label=_("Substitution Person"), many=False
227
+ )
228
+ _substitute = PersonRepresentationSerializer(source="substitute")
229
+
230
+
231
+ class EmployeeYearBalanceModelSerializer(EmployeeYearBalanceRepresentationSerializer):
232
+ _employee = EmployeeHumanResourceRepresentationSerializer(source="employee")
233
+ _balance = wb_serializers.FloatField(read_only=True, label="Given yearly balance (in hours)")
234
+ _number_mandatory_days_off = wb_serializers.FloatField(read_only=True, label="Mandatory days off (in hours)")
235
+ _total_vacation_hourly_usage = wb_serializers.FloatField(read_only=True, label="Hourly usage (in hours)")
236
+ actual_total_vacation_hourly_balance = wb_serializers.FloatField(
237
+ read_only=True, label="Hourly available balance (in hours)"
238
+ )
239
+
240
+ _balance_in_days = wb_serializers.FloatField(read_only=True, label="Given yearly balance (in days)")
241
+ _number_mandatory_days_off_in_days = wb_serializers.FloatField(
242
+ read_only=True, label="Mandatory days off (in days)"
243
+ )
244
+ _total_vacation_hourly_usage_in_days = wb_serializers.FloatField(read_only=True, label="Hourly usage (in days)")
245
+ actual_total_vacation_hourly_balance_in_days = wb_serializers.FloatField(
246
+ read_only=True, label="Hourly available balance (in days)"
247
+ )
248
+
249
+ class Meta:
250
+ model = EmployeeYearBalance
251
+ fields = [
252
+ "id",
253
+ "employee",
254
+ "_employee",
255
+ "extra_balance",
256
+ "year",
257
+ "_balance",
258
+ "_number_mandatory_days_off",
259
+ "_total_vacation_hourly_usage",
260
+ "actual_total_vacation_hourly_balance",
261
+ "_balance_in_days",
262
+ "_number_mandatory_days_off_in_days",
263
+ "_total_vacation_hourly_usage_in_days",
264
+ "actual_total_vacation_hourly_balance_in_days",
265
+ "_additional_resources",
266
+ ]
267
+ read_only_fields = fields
@@ -0,0 +1,80 @@
1
+ from django.utils.translation import gettext_lazy as _
2
+ from rest_framework.reverse import reverse
3
+ from wbcore import serializers
4
+ from wbcore.contrib.directory.serializers import PersonRepresentationSerializer
5
+
6
+ from wbhuman_resources.models import KPI, Evaluation
7
+
8
+
9
+ class KPIRepresentationSerializer(serializers.RepresentationSerializer):
10
+ _detail = serializers.HyperlinkField(reverse_name="wbhuman_resources:kpi-detail")
11
+
12
+ class Meta:
13
+ model = KPI
14
+ fields = ("id", "name", "_detail")
15
+
16
+
17
+ class EvaluationRepresentationSerializer(serializers.RepresentationSerializer):
18
+ _person = PersonRepresentationSerializer(source="person")
19
+
20
+ class Meta:
21
+ model = Evaluation
22
+ fields = ("id", "evaluated_score", "person", "_person", "evaluation_date")
23
+
24
+
25
+ class KPIModelSerializer(serializers.ModelSerializer):
26
+ handler = serializers.ChoiceField(choices=list(KPI.get_all_handler_choices()), label=_("Handler"))
27
+ parameters = serializers.ListField(read_only=True)
28
+ _evaluated_persons = PersonRepresentationSerializer(source="evaluated_persons", many=True)
29
+
30
+ @serializers.register_resource()
31
+ def register_history_resource(self, instance, request, user):
32
+ resources = {
33
+ "evaluations": reverse("wbhuman_resources:kpi-evaluation-list", args=[instance.id], request=request),
34
+ "evaluationgraph": reverse(
35
+ "wbhuman_resources:kpi-evaluationgraph-list", args=[instance.id], request=request
36
+ ),
37
+ "kpievaluationpandas": reverse("wbhuman_resources:kpievaluationpandas-list", args=[], request=request)
38
+ + f"?kpi={instance.id}",
39
+ }
40
+
41
+ return resources
42
+
43
+ class Meta:
44
+ model = KPI
45
+ fields = (
46
+ "id",
47
+ "name",
48
+ "handler",
49
+ "goal",
50
+ "period",
51
+ "evaluated_intervals",
52
+ "evaluated_persons",
53
+ "_evaluated_persons",
54
+ "parameters",
55
+ "last_update",
56
+ "individual_evaluation",
57
+ "is_active",
58
+ "_additional_resources",
59
+ )
60
+
61
+
62
+ class EvaluationModelSerializer(serializers.ModelSerializer):
63
+ _kpi = KPIRepresentationSerializer(source="kpi")
64
+ _person = PersonRepresentationSerializer(source="person")
65
+ goal = serializers.IntegerField(read_only=True)
66
+
67
+ class Meta:
68
+ model = Evaluation
69
+ fields = (
70
+ "id",
71
+ "kpi",
72
+ "_kpi",
73
+ "person",
74
+ "_person",
75
+ "evaluated_score",
76
+ "evaluated_period",
77
+ "evaluation_date",
78
+ "last_update",
79
+ "goal",
80
+ )