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,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
+ }