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.
- wbhuman_resources/__init__.py +1 -0
- wbhuman_resources/admin/__init__.py +5 -0
- wbhuman_resources/admin/absence.py +113 -0
- wbhuman_resources/admin/calendars.py +37 -0
- wbhuman_resources/admin/employee.py +109 -0
- wbhuman_resources/admin/kpi.py +21 -0
- wbhuman_resources/admin/review.py +157 -0
- wbhuman_resources/apps.py +23 -0
- wbhuman_resources/dynamic_preferences_registry.py +119 -0
- wbhuman_resources/factories/__init__.py +38 -0
- wbhuman_resources/factories/absence.py +109 -0
- wbhuman_resources/factories/calendars.py +60 -0
- wbhuman_resources/factories/employee.py +80 -0
- wbhuman_resources/factories/kpi.py +155 -0
- wbhuman_resources/filters/__init__.py +20 -0
- wbhuman_resources/filters/absence.py +109 -0
- wbhuman_resources/filters/absence_graphs.py +85 -0
- wbhuman_resources/filters/calendars.py +28 -0
- wbhuman_resources/filters/employee.py +81 -0
- wbhuman_resources/filters/kpi.py +35 -0
- wbhuman_resources/filters/review.py +134 -0
- wbhuman_resources/filters/signals.py +27 -0
- wbhuman_resources/locale/de/LC_MESSAGES/django.mo +0 -0
- wbhuman_resources/locale/de/LC_MESSAGES/django.po +2207 -0
- wbhuman_resources/locale/de/LC_MESSAGES/django.po.translated +2456 -0
- wbhuman_resources/locale/en/LC_MESSAGES/django.mo +0 -0
- wbhuman_resources/locale/en/LC_MESSAGES/django.po +2091 -0
- wbhuman_resources/locale/fr/LC_MESSAGES/django.mo +0 -0
- wbhuman_resources/locale/fr/LC_MESSAGES/django.po +2093 -0
- wbhuman_resources/management/__init__.py +23 -0
- wbhuman_resources/migrations/0001_initial_squashed_squashed_0015_alter_absencerequest_calendaritem_ptr_and_more.py +949 -0
- wbhuman_resources/migrations/0016_alter_employeehumanresource_options.py +20 -0
- wbhuman_resources/migrations/0017_absencerequest_crossborder_country_and_more.py +55 -0
- wbhuman_resources/migrations/0018_remove_position_group_position_groups.py +32 -0
- wbhuman_resources/migrations/0019_alter_absencerequest_options_alter_kpi_options_and_more.py +44 -0
- wbhuman_resources/migrations/0020_alter_employeeyearbalance_year_alter_review_year.py +27 -0
- wbhuman_resources/migrations/0021_alter_position_color.py +18 -0
- wbhuman_resources/migrations/0022_remove_review_editable_mode.py +64 -0
- wbhuman_resources/migrations/__init__.py +0 -0
- wbhuman_resources/models/__init__.py +23 -0
- wbhuman_resources/models/absence.py +903 -0
- wbhuman_resources/models/calendars.py +370 -0
- wbhuman_resources/models/employee.py +1241 -0
- wbhuman_resources/models/kpi.py +199 -0
- wbhuman_resources/models/preferences.py +40 -0
- wbhuman_resources/models/review.py +982 -0
- wbhuman_resources/permissions/__init__.py +0 -0
- wbhuman_resources/permissions/backend.py +26 -0
- wbhuman_resources/serializers/__init__.py +49 -0
- wbhuman_resources/serializers/absence.py +308 -0
- wbhuman_resources/serializers/calendars.py +73 -0
- wbhuman_resources/serializers/employee.py +267 -0
- wbhuman_resources/serializers/kpi.py +80 -0
- wbhuman_resources/serializers/review.py +415 -0
- wbhuman_resources/signals.py +4 -0
- wbhuman_resources/tasks.py +195 -0
- wbhuman_resources/templates/review/review_report.html +322 -0
- wbhuman_resources/tests/__init__.py +1 -0
- wbhuman_resources/tests/conftest.py +96 -0
- wbhuman_resources/tests/models/__init__.py +0 -0
- wbhuman_resources/tests/models/test_absences.py +478 -0
- wbhuman_resources/tests/models/test_calendars.py +209 -0
- wbhuman_resources/tests/models/test_employees.py +502 -0
- wbhuman_resources/tests/models/test_review.py +103 -0
- wbhuman_resources/tests/models/test_utils.py +110 -0
- wbhuman_resources/tests/signals.py +108 -0
- wbhuman_resources/tests/test_permission.py +64 -0
- wbhuman_resources/tests/test_tasks.py +74 -0
- wbhuman_resources/urls.py +221 -0
- wbhuman_resources/utils.py +43 -0
- wbhuman_resources/viewsets/__init__.py +61 -0
- wbhuman_resources/viewsets/absence.py +312 -0
- wbhuman_resources/viewsets/absence_charts.py +328 -0
- wbhuman_resources/viewsets/buttons/__init__.py +7 -0
- wbhuman_resources/viewsets/buttons/absence.py +32 -0
- wbhuman_resources/viewsets/buttons/employee.py +44 -0
- wbhuman_resources/viewsets/buttons/kpis.py +16 -0
- wbhuman_resources/viewsets/buttons/review.py +195 -0
- wbhuman_resources/viewsets/calendars.py +103 -0
- wbhuman_resources/viewsets/display/__init__.py +39 -0
- wbhuman_resources/viewsets/display/absence.py +334 -0
- wbhuman_resources/viewsets/display/calendars.py +83 -0
- wbhuman_resources/viewsets/display/employee.py +254 -0
- wbhuman_resources/viewsets/display/kpis.py +92 -0
- wbhuman_resources/viewsets/display/review.py +429 -0
- wbhuman_resources/viewsets/employee.py +210 -0
- wbhuman_resources/viewsets/endpoints/__init__.py +42 -0
- wbhuman_resources/viewsets/endpoints/absence.py +57 -0
- wbhuman_resources/viewsets/endpoints/calendars.py +18 -0
- wbhuman_resources/viewsets/endpoints/employee.py +51 -0
- wbhuman_resources/viewsets/endpoints/kpis.py +53 -0
- wbhuman_resources/viewsets/endpoints/review.py +191 -0
- wbhuman_resources/viewsets/kpi.py +280 -0
- wbhuman_resources/viewsets/menu/__init__.py +22 -0
- wbhuman_resources/viewsets/menu/absence.py +50 -0
- wbhuman_resources/viewsets/menu/administration.py +15 -0
- wbhuman_resources/viewsets/menu/calendars.py +33 -0
- wbhuman_resources/viewsets/menu/employee.py +44 -0
- wbhuman_resources/viewsets/menu/kpis.py +18 -0
- wbhuman_resources/viewsets/menu/review.py +97 -0
- wbhuman_resources/viewsets/mixins.py +14 -0
- wbhuman_resources/viewsets/review.py +837 -0
- wbhuman_resources/viewsets/titles/__init__.py +18 -0
- wbhuman_resources/viewsets/titles/absence.py +30 -0
- wbhuman_resources/viewsets/titles/employee.py +18 -0
- wbhuman_resources/viewsets/titles/kpis.py +15 -0
- wbhuman_resources/viewsets/titles/review.py +62 -0
- wbhuman_resources/viewsets/utils.py +28 -0
- wbhuman_resources-1.58.4.dist-info/METADATA +8 -0
- wbhuman_resources-1.58.4.dist-info/RECORD +111 -0
- wbhuman_resources-1.58.4.dist-info/WHEEL +5 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
from django.db.models import Q
|
|
2
|
+
from django.utils.translation import gettext_lazy as _
|
|
3
|
+
from wbcore import filters as wb_filters
|
|
4
|
+
|
|
5
|
+
from wbhuman_resources.models import EmployeeHumanResource, Position
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class PositionFilterSet(wb_filters.FilterSet):
|
|
9
|
+
class Meta:
|
|
10
|
+
model = Position
|
|
11
|
+
fields = {"name": ["exact", "icontains"], "parent": ["exact"], "level": ["exact"], "manager": ["exact"]}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class BaseEmployeeFilterSet(wb_filters.FilterSet):
|
|
15
|
+
contract_type = wb_filters.ChoiceFilter(
|
|
16
|
+
label=_("Contract"),
|
|
17
|
+
choices=EmployeeHumanResource.ContractType.choices,
|
|
18
|
+
initial=EmployeeHumanResource.ContractType.INTERNAL,
|
|
19
|
+
)
|
|
20
|
+
is_active = wb_filters.BooleanFilter(label=_("Is Active"), initial=True)
|
|
21
|
+
position = wb_filters.ModelChoiceFilter(
|
|
22
|
+
label=_("Position"),
|
|
23
|
+
queryset=Position.objects.all(),
|
|
24
|
+
endpoint=Position.get_representation_endpoint(),
|
|
25
|
+
value_key=Position.get_representation_value_key(),
|
|
26
|
+
label_key=Position.get_representation_label_key(),
|
|
27
|
+
method="filter_position",
|
|
28
|
+
filter_params={"height": 0},
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
def filter_position(self, queryset, name, value):
|
|
32
|
+
if value:
|
|
33
|
+
return queryset.filter(position__in=value.get_descendants(include_self=True)).distinct()
|
|
34
|
+
return queryset
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class EmployeeBalanceFilterSet(BaseEmployeeFilterSet):
|
|
38
|
+
took_long_vacations = wb_filters.BooleanFilter(field_name="took_long_vacations", lookup_expr="exact")
|
|
39
|
+
|
|
40
|
+
extra_days_per_period__gte = wb_filters.NumberFilter(
|
|
41
|
+
field_name="extra_days_per_period", method="filter_str_number_gte", lookup_expr="gte"
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
def filter_str_number_lte(self, queryset, name, value):
|
|
45
|
+
if value:
|
|
46
|
+
numerical_field_name = name.replace("_repr", "")
|
|
47
|
+
return queryset.filter(**{f"{numerical_field_name}__lte": value})
|
|
48
|
+
return queryset
|
|
49
|
+
|
|
50
|
+
def filter_str_number_gte(self, queryset, name, value):
|
|
51
|
+
if value:
|
|
52
|
+
numerical_field_name = name.replace("_repr", "")
|
|
53
|
+
return queryset.filter(**{f"{numerical_field_name}__gte": value})
|
|
54
|
+
return queryset
|
|
55
|
+
|
|
56
|
+
class Meta:
|
|
57
|
+
model = EmployeeHumanResource
|
|
58
|
+
fields = {"profile": ["exact"], "position": ["exact"], "extra_days_frequency": ["exact"]}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class EmployeeFilterSet(BaseEmployeeFilterSet):
|
|
62
|
+
top_position_repr = wb_filters.ModelChoiceFilter(
|
|
63
|
+
label=_("Position"),
|
|
64
|
+
queryset=Position.objects.all(),
|
|
65
|
+
endpoint=Position.get_representation_endpoint(),
|
|
66
|
+
value_key=Position.get_representation_value_key(),
|
|
67
|
+
label_key=Position.get_representation_label_key(),
|
|
68
|
+
filter_params={"height": 1},
|
|
69
|
+
method="filter_top_position",
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
def filter_top_position(self, queryset, name, value):
|
|
73
|
+
if value:
|
|
74
|
+
return queryset.filter(
|
|
75
|
+
Q(position__parent__isnull=False) & Q(position__parent__in=value.get_descendants(include_self=True))
|
|
76
|
+
).distinct()
|
|
77
|
+
return queryset
|
|
78
|
+
|
|
79
|
+
class Meta:
|
|
80
|
+
model = EmployeeHumanResource
|
|
81
|
+
fields = {"calendar": ["exact"], "contract_type": ["exact"], "enrollment_at": ["gte", "lte"]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from django.utils.translation import gettext_lazy as _
|
|
2
|
+
from wbcore import filters as wb_filters
|
|
3
|
+
|
|
4
|
+
from wbhuman_resources.models import KPI, Evaluation
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class KPIFilterSet(wb_filters.FilterSet):
|
|
8
|
+
class Meta:
|
|
9
|
+
model = KPI
|
|
10
|
+
fields = {
|
|
11
|
+
"name": ["exact", "icontains"],
|
|
12
|
+
"evaluated_persons": ["exact"],
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class KPIEvaluationFilterSet(wb_filters.FilterSet):
|
|
17
|
+
class Meta:
|
|
18
|
+
model = Evaluation
|
|
19
|
+
fields = {
|
|
20
|
+
"person": ["exact"],
|
|
21
|
+
"evaluation_date": ["lte", "gte"],
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class KPIEvaluationPandasFilter(wb_filters.FilterSet):
|
|
26
|
+
kpi_name = wb_filters.CharFilter(label=_("KPI"), lookup_expr="icontains")
|
|
27
|
+
goal = wb_filters.CharFilter(label=_("Goal"), lookup_expr="icontains")
|
|
28
|
+
|
|
29
|
+
class Meta:
|
|
30
|
+
model = Evaluation
|
|
31
|
+
fields = {
|
|
32
|
+
"person": ["exact"],
|
|
33
|
+
"kpi": ["exact"],
|
|
34
|
+
"evaluation_date": ["lte", "gte"],
|
|
35
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
from django.db.models import Q
|
|
2
|
+
from django.utils.translation import gettext_lazy as _
|
|
3
|
+
from wbcore import filters as wb_filters
|
|
4
|
+
from wbcore.contrib.directory.models import Person
|
|
5
|
+
|
|
6
|
+
from wbhuman_resources.models import (
|
|
7
|
+
Review,
|
|
8
|
+
ReviewAnswer,
|
|
9
|
+
ReviewGroup,
|
|
10
|
+
ReviewQuestion,
|
|
11
|
+
ReviewQuestionCategory,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ReviewGroupFilter(wb_filters.FilterSet):
|
|
16
|
+
class Meta:
|
|
17
|
+
model = ReviewGroup
|
|
18
|
+
fields = {
|
|
19
|
+
"name": ["exact", "icontains"],
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_filter_params(request, view):
|
|
24
|
+
return {"related_to": request.user.profile}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def filter_default_related_to(field, request, view):
|
|
28
|
+
return request.user.profile.id if request.user.profile else None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class ReviewTemplateFilter(wb_filters.FilterSet):
|
|
32
|
+
related_to = wb_filters.ModelChoiceFilter(
|
|
33
|
+
label=_("Related to"),
|
|
34
|
+
queryset=Person.objects.all(),
|
|
35
|
+
endpoint=Person.get_representation_endpoint(),
|
|
36
|
+
value_key=Person.get_representation_value_key(),
|
|
37
|
+
label_key=Person.get_representation_label_key(),
|
|
38
|
+
method="filter_related_to",
|
|
39
|
+
initial=filter_default_related_to,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
def filter_related_to(self, queryset, name, value):
|
|
43
|
+
if value:
|
|
44
|
+
queryset = queryset.filter(Q(reviewee=value) | Q(reviewer=value) | Q(moderator=value))
|
|
45
|
+
return queryset
|
|
46
|
+
|
|
47
|
+
class Meta:
|
|
48
|
+
model = Review
|
|
49
|
+
fields = {
|
|
50
|
+
"review": ["lte", "gte"],
|
|
51
|
+
"status": ["exact"],
|
|
52
|
+
"moderator": ["exact"],
|
|
53
|
+
"review_group": ["exact"],
|
|
54
|
+
"changed": ["lte", "gte"],
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class ReviewFilter(ReviewTemplateFilter):
|
|
59
|
+
is_template = wb_filters.BooleanFilter(initial=False, label=_("Is Template"))
|
|
60
|
+
|
|
61
|
+
class Meta:
|
|
62
|
+
model = Review
|
|
63
|
+
fields = {
|
|
64
|
+
"from_date": ["lte", "gte"],
|
|
65
|
+
"to_date": ["lte", "gte"],
|
|
66
|
+
"review_deadline": ["lte", "gte"],
|
|
67
|
+
"review": ["lte", "gte"],
|
|
68
|
+
"status": ["exact"],
|
|
69
|
+
"reviewee": ["exact"],
|
|
70
|
+
"reviewer": ["exact"],
|
|
71
|
+
"moderator": ["exact"],
|
|
72
|
+
"review_group": ["exact"],
|
|
73
|
+
"is_template": ["exact"],
|
|
74
|
+
"year": ["exact"],
|
|
75
|
+
"type": ["exact"],
|
|
76
|
+
"changed": ["lte", "gte"],
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class ReviewQuestionCategoryFilter(wb_filters.FilterSet):
|
|
81
|
+
class Meta:
|
|
82
|
+
model = ReviewQuestionCategory
|
|
83
|
+
fields = {
|
|
84
|
+
"name": ["exact", "icontains"],
|
|
85
|
+
"order": ["exact"],
|
|
86
|
+
"weight": ["exact"],
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class ReviewQuestionFilter(wb_filters.FilterSet):
|
|
91
|
+
class Meta:
|
|
92
|
+
model = ReviewQuestion
|
|
93
|
+
fields = {
|
|
94
|
+
"review": ["exact"],
|
|
95
|
+
"category": ["exact"],
|
|
96
|
+
"mandatory": ["exact"],
|
|
97
|
+
"answer_type": ["exact"],
|
|
98
|
+
"order": ["exact"],
|
|
99
|
+
"weight": ["exact"],
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
class ReviewAnswerFilter(wb_filters.FilterSet):
|
|
104
|
+
question_name = wb_filters.CharFilter(label=_("Question"), lookup_expr="icontains")
|
|
105
|
+
|
|
106
|
+
class Meta:
|
|
107
|
+
model = ReviewAnswer
|
|
108
|
+
fields = {"answer_text": ["exact", "icontains"], "answered_by": ["exact"], "question": ["exact"]}
|
|
109
|
+
hidden_fields = ["question"]
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
class ReviewProgressReviewFilter(wb_filters.FilterSet):
|
|
113
|
+
class Meta:
|
|
114
|
+
model = ReviewAnswer
|
|
115
|
+
fields = {}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
class RatingReviewAnswerReviewFilter(wb_filters.FilterSet):
|
|
119
|
+
deviation = wb_filters.ChoiceFilter(
|
|
120
|
+
label=_("Deviation"),
|
|
121
|
+
choices=[("EQUAL", _("Equal")), ("LESS", _("Less")), ("GREAT", _("Greater"))],
|
|
122
|
+
method="fake_filter",
|
|
123
|
+
clearable=False,
|
|
124
|
+
required=False,
|
|
125
|
+
)
|
|
126
|
+
category_question_name = wb_filters.CharFilter(label=_("Category"), lookup_expr="icontains")
|
|
127
|
+
question_name = wb_filters.CharFilter(label=_("Question"), lookup_expr="icontains")
|
|
128
|
+
answer_type = wb_filters.ChoiceFilter(
|
|
129
|
+
label="Answer Type", choices=ReviewQuestion.ANSWERTYPE.choices, required=False, hidden=True
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
class Meta:
|
|
133
|
+
model = ReviewAnswer
|
|
134
|
+
fields = {}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from django.utils.translation import gettext_lazy as _
|
|
2
|
+
from wbcore import filters as wb_filters
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def add_position_filter(sender, request=None, *args, **kwargs):
|
|
6
|
+
from wbcore.contrib.directory.models import Entry
|
|
7
|
+
|
|
8
|
+
from wbhuman_resources.models import Position
|
|
9
|
+
|
|
10
|
+
def filter_position(queryset, name, value):
|
|
11
|
+
if value:
|
|
12
|
+
ids = value.get_employees().values_list("profile")
|
|
13
|
+
entries = Entry.objects.filter(id__in=ids)
|
|
14
|
+
return queryset.filter(participants__in=entries)
|
|
15
|
+
return queryset
|
|
16
|
+
|
|
17
|
+
return {
|
|
18
|
+
"position": wb_filters.ModelChoiceFilter(
|
|
19
|
+
label=_("Participant's position"),
|
|
20
|
+
field_name="position",
|
|
21
|
+
queryset=Position.objects.all(),
|
|
22
|
+
endpoint=Position.get_representation_endpoint(),
|
|
23
|
+
value_key=Position.get_representation_value_key(),
|
|
24
|
+
label_key=Position.get_representation_label_key(),
|
|
25
|
+
method=filter_position,
|
|
26
|
+
)
|
|
27
|
+
}
|
|
Binary file
|