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,280 @@
|
|
|
1
|
+
from typing import Type
|
|
2
|
+
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import plotly.graph_objects as go
|
|
5
|
+
from django.db.models.expressions import F
|
|
6
|
+
from django.db.models.query import QuerySet
|
|
7
|
+
from django.shortcuts import get_object_or_404
|
|
8
|
+
from django.utils.translation import gettext
|
|
9
|
+
from django.utils.translation import gettext_lazy as _
|
|
10
|
+
from rest_framework import filters
|
|
11
|
+
from wbcore import viewsets
|
|
12
|
+
from wbcore.filters import DjangoFilterBackend
|
|
13
|
+
from wbcore.pandas import fields as pf
|
|
14
|
+
from wbcore.pandas.views import PandasAPIViewSet
|
|
15
|
+
from wbcore.serializers.serializers import ModelSerializer
|
|
16
|
+
from wbcore.utils.strings import format_number
|
|
17
|
+
|
|
18
|
+
from wbhuman_resources.filters import (
|
|
19
|
+
KPIEvaluationFilterSet,
|
|
20
|
+
KPIEvaluationPandasFilter,
|
|
21
|
+
KPIFilterSet,
|
|
22
|
+
)
|
|
23
|
+
from wbhuman_resources.models import KPI, Evaluation
|
|
24
|
+
from wbhuman_resources.serializers import (
|
|
25
|
+
EvaluationModelSerializer,
|
|
26
|
+
EvaluationRepresentationSerializer,
|
|
27
|
+
KPIModelSerializer,
|
|
28
|
+
KPIRepresentationSerializer,
|
|
29
|
+
)
|
|
30
|
+
from wbhuman_resources.viewsets.buttons import KPIButtonConfig
|
|
31
|
+
from wbhuman_resources.viewsets.display import (
|
|
32
|
+
KPIDisplayConfig,
|
|
33
|
+
KPIEvaluationDisplayConfig,
|
|
34
|
+
KPIEvaluationPandasDisplayConfig,
|
|
35
|
+
)
|
|
36
|
+
from wbhuman_resources.viewsets.endpoints import (
|
|
37
|
+
EvaluationGraphEndpointConfig,
|
|
38
|
+
KPIEndpointConfig,
|
|
39
|
+
KPIEvaluationEndpointConfig,
|
|
40
|
+
KPIEvaluationPandasEndpointConfig,
|
|
41
|
+
)
|
|
42
|
+
from wbhuman_resources.viewsets.titles import (
|
|
43
|
+
EvaluationGraphTitleConfig,
|
|
44
|
+
KPIEvaluationPandasTitleConfig,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class KPIRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
49
|
+
queryset = KPI.objects.all()
|
|
50
|
+
serializer_class = KPIRepresentationSerializer
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class KPIModelViewSet(viewsets.ModelViewSet):
|
|
54
|
+
queryset = KPI.objects.all()
|
|
55
|
+
serializer_class = KPIModelSerializer
|
|
56
|
+
display_config_class = KPIDisplayConfig
|
|
57
|
+
endpoint_config_class = KPIEndpointConfig
|
|
58
|
+
button_config_class = KPIButtonConfig
|
|
59
|
+
filter_backends = (
|
|
60
|
+
filters.SearchFilter,
|
|
61
|
+
filters.OrderingFilter,
|
|
62
|
+
DjangoFilterBackend,
|
|
63
|
+
)
|
|
64
|
+
filterset_class = KPIFilterSet
|
|
65
|
+
ordering = ["last_update", "period"]
|
|
66
|
+
ordering_fields = ["name", "evaluated_persons", "parameters", "period"]
|
|
67
|
+
search_fields = ["name", "evaluated_persons__computed_str"]
|
|
68
|
+
|
|
69
|
+
def get_serializer_class(self) -> Type[ModelSerializer]:
|
|
70
|
+
if pk := self.kwargs.get("pk", None):
|
|
71
|
+
kpi = get_object_or_404(KPI, pk=pk)
|
|
72
|
+
handler = kpi.get_handler()
|
|
73
|
+
return handler.get_serializer()
|
|
74
|
+
return super().get_serializer_class()
|
|
75
|
+
|
|
76
|
+
def get_queryset(self) -> QuerySet[KPI]:
|
|
77
|
+
queryset = super().get_queryset()
|
|
78
|
+
if pk := self.kwargs.get("pk", None):
|
|
79
|
+
kpi = get_object_or_404(KPI, pk=pk)
|
|
80
|
+
handler = kpi.get_handler()
|
|
81
|
+
queryset = handler.annotate_parameters(queryset)
|
|
82
|
+
queryset = queryset.annotate(
|
|
83
|
+
parameters=F("additional_data__list_data"),
|
|
84
|
+
)
|
|
85
|
+
if KPI.is_administrator(self.request.user):
|
|
86
|
+
return queryset
|
|
87
|
+
return queryset.filter(evaluated_persons=self.request.user.profile)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class EvaluationRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
91
|
+
queryset = Evaluation.objects.all()
|
|
92
|
+
serializer_class = EvaluationRepresentationSerializer
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class KPIEvaluationModelViewSet(viewsets.ModelViewSet):
|
|
96
|
+
serializer_class = EvaluationModelSerializer
|
|
97
|
+
display_config_class = KPIEvaluationDisplayConfig
|
|
98
|
+
endpoint_config_class = KPIEvaluationEndpointConfig
|
|
99
|
+
queryset = Evaluation.objects.all()
|
|
100
|
+
filter_backends = (
|
|
101
|
+
filters.SearchFilter,
|
|
102
|
+
filters.OrderingFilter,
|
|
103
|
+
DjangoFilterBackend,
|
|
104
|
+
)
|
|
105
|
+
filterset_class = KPIEvaluationFilterSet
|
|
106
|
+
ordering = ["-evaluated_period"]
|
|
107
|
+
ordering_fields = ["person", "evaluated_score", "evaluation_date", "evaluated_period"]
|
|
108
|
+
|
|
109
|
+
def get_queryset(self):
|
|
110
|
+
queryset = super().get_queryset().filter(kpi__id=self.kwargs["kpi_id"]).annotate(goal=F("kpi__goal"))
|
|
111
|
+
if KPI.is_administrator(self.request.user):
|
|
112
|
+
return queryset
|
|
113
|
+
return queryset.filter(person=self.request.user.profile)
|
|
114
|
+
|
|
115
|
+
def get_aggregates(self, queryset, paginated_queryset):
|
|
116
|
+
if queryset.exists():
|
|
117
|
+
kpi = get_object_or_404(KPI, pk=self.kwargs["kpi_id"])
|
|
118
|
+
person_ids = kpi.evaluated_persons.all().values_list("id", flat=True)
|
|
119
|
+
evaluation = queryset.filter(person__id__in=person_ids).order_by("evaluation_date").last()
|
|
120
|
+
evaluated_score = kpi.get_handler().evaluate(kpi, evaluation_date=evaluation.evaluation_date)
|
|
121
|
+
return {
|
|
122
|
+
"evaluated_score": {"Σ": format_number(evaluated_score)},
|
|
123
|
+
}
|
|
124
|
+
return {}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class EvaluationGraphChartViewset(viewsets.ChartViewSet):
|
|
128
|
+
filter_backends = (DjangoFilterBackend,)
|
|
129
|
+
queryset = Evaluation.objects.all()
|
|
130
|
+
endpoint_config_class = EvaluationGraphEndpointConfig
|
|
131
|
+
title_config_class = EvaluationGraphTitleConfig
|
|
132
|
+
# filterset_class = EvaluationGraphFilter
|
|
133
|
+
|
|
134
|
+
def get_queryset(self):
|
|
135
|
+
queryset = super().get_queryset().filter(kpi__id=self.kwargs["kpi_id"]).annotate(goal=F("kpi__goal"))
|
|
136
|
+
if KPI.is_administrator(self.request.user):
|
|
137
|
+
return queryset
|
|
138
|
+
return queryset.filter(person=self.request.user.profile)
|
|
139
|
+
|
|
140
|
+
def get_dataframe_period(self, kpi_id):
|
|
141
|
+
kpi = KPI.objects.get(id=kpi_id)
|
|
142
|
+
list_date = list(
|
|
143
|
+
pd.date_range(
|
|
144
|
+
start=kpi.period.lower,
|
|
145
|
+
end=kpi.period.upper,
|
|
146
|
+
freq=KPI.Interval.get_frequence_correspondance(kpi.evaluated_intervals),
|
|
147
|
+
)
|
|
148
|
+
)
|
|
149
|
+
list_date = [_date.date() for _date in list_date]
|
|
150
|
+
|
|
151
|
+
df_date = pd.DataFrame(list_date, columns=["evaluation_date"])
|
|
152
|
+
df_goal = df_date.copy()
|
|
153
|
+
df_goal["goal"] = kpi.goal
|
|
154
|
+
df_date = df_date.set_index("evaluation_date")
|
|
155
|
+
return df_date, df_goal["goal"]
|
|
156
|
+
|
|
157
|
+
def get_plotly(self, queryset):
|
|
158
|
+
fig = go.Figure()
|
|
159
|
+
if queryset.exists():
|
|
160
|
+
kpi = KPI.objects.get(id=self.kwargs["kpi_id"])
|
|
161
|
+
activity_type = kpi.additional_data.get("list_data").pop(0) if kpi.additional_data.get("list_data") else ""
|
|
162
|
+
parameters = kpi.additional_data.get("list_data")
|
|
163
|
+
|
|
164
|
+
df = pd.DataFrame(
|
|
165
|
+
queryset.values(
|
|
166
|
+
"evaluation_date", "person__first_name", "person__last_name", "evaluated_score", "goal"
|
|
167
|
+
)
|
|
168
|
+
)
|
|
169
|
+
df["Name"] = df["person__first_name"] + " " + df["person__last_name"]
|
|
170
|
+
df["Name"] = df["Name"].fillna("Group")
|
|
171
|
+
df = df.set_index(["Name", "evaluation_date"]).evaluated_score.unstack("Name")
|
|
172
|
+
df_date, goal = self.get_dataframe_period(self.kwargs["kpi_id"])
|
|
173
|
+
|
|
174
|
+
df = df.merge(df_date, on=["evaluation_date"], how="outer")
|
|
175
|
+
df = df.sort_values(by=["evaluation_date"]).fillna("")
|
|
176
|
+
pd.options.plotting.backend = "plotly"
|
|
177
|
+
fig = df.plot.line(labels=dict(value="#KPI", variable="Name"), markers=True)
|
|
178
|
+
fig.update_traces(hovertemplate=None)
|
|
179
|
+
fig.update_layout(
|
|
180
|
+
title=gettext("<b>Parameters</b>: {}<br>{} ").format(parameters, activity_type),
|
|
181
|
+
hovermode="x",
|
|
182
|
+
xaxis_rangeslider_visible=True,
|
|
183
|
+
autosize=True,
|
|
184
|
+
)
|
|
185
|
+
fig.update_xaxes(title="")
|
|
186
|
+
fig.add_trace( # goal line
|
|
187
|
+
go.Scatter(
|
|
188
|
+
x=df.index,
|
|
189
|
+
y=goal,
|
|
190
|
+
name=gettext("Goal"),
|
|
191
|
+
mode="lines",
|
|
192
|
+
line=dict(color="Green", width=4, dash="dot"),
|
|
193
|
+
)
|
|
194
|
+
)
|
|
195
|
+
fig.add_trace( # diagonal line
|
|
196
|
+
go.Scatter(
|
|
197
|
+
x=df.index,
|
|
198
|
+
y=(goal / len(df)).cumsum().round(2),
|
|
199
|
+
mode="lines",
|
|
200
|
+
name=gettext("Progress expected to reach goal"),
|
|
201
|
+
line=dict(color="springgreen", width=3, dash="dot"),
|
|
202
|
+
)
|
|
203
|
+
)
|
|
204
|
+
return fig
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
class KPIEvaluationPandasViewSet(PandasAPIViewSet):
|
|
208
|
+
IDENTIFIER = "wbcommission:kpievaluationpandas"
|
|
209
|
+
queryset = Evaluation.objects.all()
|
|
210
|
+
|
|
211
|
+
filter_backends = (
|
|
212
|
+
DjangoFilterBackend,
|
|
213
|
+
filters.SearchFilter,
|
|
214
|
+
filters.OrderingFilter,
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
search_fields = ["kpi__name", "person__computed_str"]
|
|
218
|
+
ordering_fields = [
|
|
219
|
+
"evaluated_period",
|
|
220
|
+
"evaluation_date",
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
display_config_class = KPIEvaluationPandasDisplayConfig
|
|
224
|
+
title_config_class = KPIEvaluationPandasTitleConfig
|
|
225
|
+
endpoint_config_class = KPIEvaluationPandasEndpointConfig
|
|
226
|
+
filterset_class = KPIEvaluationPandasFilter
|
|
227
|
+
|
|
228
|
+
def get_queryset(self):
|
|
229
|
+
queryset = super().get_queryset().annotate(goal=F("kpi__goal"), kpi_name=F("kpi__name"))
|
|
230
|
+
if KPI.is_administrator(self.request.user):
|
|
231
|
+
return queryset
|
|
232
|
+
return queryset.filter(kpi__evaluated_persons=self.request.user.profile)
|
|
233
|
+
|
|
234
|
+
def get_pandas_fields(self, request):
|
|
235
|
+
fields = [
|
|
236
|
+
pf.PKField("id", label=_("ID")),
|
|
237
|
+
pf.CharField(key="person", label=_("Person")),
|
|
238
|
+
pf.CharField(key="kpi", label=_("KPI")),
|
|
239
|
+
pf.CharField(key="kpi_name", label=_("KPI")),
|
|
240
|
+
pf.CharField(key="period", label=_("Period")),
|
|
241
|
+
pf.DateField(key="evaluation_date", label=_("Evaluation Date")),
|
|
242
|
+
pf.IntegerField(key="goal", label=_("Goal")),
|
|
243
|
+
pf.IntegerField(key="evaluated_score", label=_("Evaluated Score")),
|
|
244
|
+
pf.CharField(key="progression", label=_("Progression")),
|
|
245
|
+
]
|
|
246
|
+
return pf.PandasFields(fields=tuple(fields))
|
|
247
|
+
|
|
248
|
+
def get_dataframe(self, request, queryset, **kwargs):
|
|
249
|
+
df = pd.DataFrame()
|
|
250
|
+
if queryset.exists():
|
|
251
|
+
df = pd.DataFrame(
|
|
252
|
+
queryset.order_by("evaluation_date").values(
|
|
253
|
+
"kpi",
|
|
254
|
+
"kpi_name",
|
|
255
|
+
"kpi__period",
|
|
256
|
+
"evaluation_date",
|
|
257
|
+
"goal",
|
|
258
|
+
"person__computed_str",
|
|
259
|
+
"evaluated_score",
|
|
260
|
+
)
|
|
261
|
+
)
|
|
262
|
+
df["kpi__period"] = df["kpi__period"].apply(
|
|
263
|
+
lambda x: f"{x.lower.strftime('%d.%m.%Y')} - {x.upper.strftime('%d.%m.%Y')}"
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
df["person__computed_str"] = df["person__computed_str"].fillna("Group").astype(str)
|
|
267
|
+
df = df.rename(columns={"kpi__period": "period", "person__computed_str": "person"})
|
|
268
|
+
df = df.pivot_table(
|
|
269
|
+
index=["person", "kpi"],
|
|
270
|
+
values=["kpi_name", "evaluation_date", "period", "goal", "evaluated_score"],
|
|
271
|
+
aggfunc="last",
|
|
272
|
+
)
|
|
273
|
+
if "evaluated_score" in df.columns:
|
|
274
|
+
df["progression"] = ((df["evaluated_score"] / df["goal"]) * 100).round(2).astype(str) + "%"
|
|
275
|
+
else:
|
|
276
|
+
df["progression"] = "0%"
|
|
277
|
+
|
|
278
|
+
df = df.reset_index()
|
|
279
|
+
df["id"] = df.index
|
|
280
|
+
return df
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from .absence import (
|
|
2
|
+
ABSENCEPLANNER_MENUITEM,
|
|
3
|
+
ABSENCEREQUEST_MENUITEM,
|
|
4
|
+
ABSENCEREQUESTTYPE_MENUITEM,
|
|
5
|
+
ABSENCETABLE_MENUITEM,
|
|
6
|
+
)
|
|
7
|
+
from .administration import ADMINISTRATION_MENU
|
|
8
|
+
from .calendars import DAYOFF_MENUITEM, DAYOFFCALENDAR_MENUITEM
|
|
9
|
+
from .employee import (
|
|
10
|
+
EMPLOYEE_MENUITEM,
|
|
11
|
+
EMPLOYEEHUMANRESOURCE_MENUITEM,
|
|
12
|
+
POSITION_MENUITEM,
|
|
13
|
+
)
|
|
14
|
+
from .kpis import KPI_MENUITEM, KPIEVALUATIONPANDAS_MENUITEM
|
|
15
|
+
from .review import (
|
|
16
|
+
REVIEW_MENUITEM,
|
|
17
|
+
REVIEWANDWER_MENUITEM,
|
|
18
|
+
REVIEWGROUP_MENUITEM,
|
|
19
|
+
REVIEWQUESTION_MENUITEM,
|
|
20
|
+
REVIEWQUESTIONCATEFORY_MENUITEM,
|
|
21
|
+
REVIEWTEMPLATE_MENUITEM,
|
|
22
|
+
)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
from django.utils.translation import gettext as _
|
|
2
|
+
from wbcore.menus import ItemPermission, MenuItem
|
|
3
|
+
from wbcore.permissions.shortcuts import is_internal_user
|
|
4
|
+
|
|
5
|
+
ABSENCEPLANNER_MENUITEM = MenuItem(
|
|
6
|
+
label=_("Absence Graph"),
|
|
7
|
+
endpoint="wbhuman_resources:absenceplanner-list",
|
|
8
|
+
permission=ItemPermission(
|
|
9
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_absencerequest"]
|
|
10
|
+
),
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
ABSENCETABLE_MENUITEM = MenuItem(
|
|
14
|
+
label=_("Presence Table"),
|
|
15
|
+
endpoint="wbhuman_resources:absencetable-list",
|
|
16
|
+
permission=ItemPermission(
|
|
17
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_absencerequest"]
|
|
18
|
+
),
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
ABSENCEREQUEST_MENUITEM = MenuItem(
|
|
22
|
+
label=_("Requests"),
|
|
23
|
+
endpoint="wbhuman_resources:absencerequest-list",
|
|
24
|
+
permission=ItemPermission(
|
|
25
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_absencerequest"]
|
|
26
|
+
),
|
|
27
|
+
add=MenuItem(
|
|
28
|
+
label=_("Add Requests"),
|
|
29
|
+
endpoint="wbhuman_resources:absencerequest-list",
|
|
30
|
+
permission=ItemPermission(
|
|
31
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.add_absencerequest"]
|
|
32
|
+
),
|
|
33
|
+
),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
ABSENCEREQUESTTYPE_MENUITEM = MenuItem(
|
|
37
|
+
label=_("Request Types"),
|
|
38
|
+
endpoint="wbhuman_resources:absencerequesttype-list",
|
|
39
|
+
permission=ItemPermission(
|
|
40
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_absencerequesttpe"]
|
|
41
|
+
),
|
|
42
|
+
add=MenuItem(
|
|
43
|
+
label=_("Add Request Types"),
|
|
44
|
+
endpoint="wbhuman_resources:absencerequesttype-list",
|
|
45
|
+
permission=ItemPermission(
|
|
46
|
+
method=lambda request: is_internal_user(request.user),
|
|
47
|
+
permissions=["wbhuman_resources.add_absencerequesttype"],
|
|
48
|
+
),
|
|
49
|
+
),
|
|
50
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
from wbcore.menus import Menu
|
|
2
|
+
|
|
3
|
+
from .absence import ABSENCEREQUESTTYPE_MENUITEM
|
|
4
|
+
from .calendars import DAYOFF_MENUITEM, DAYOFFCALENDAR_MENUITEM
|
|
5
|
+
from .employee import POSITION_MENUITEM
|
|
6
|
+
|
|
7
|
+
ADMINISTRATION_MENU = Menu(
|
|
8
|
+
label="Administration",
|
|
9
|
+
items=[
|
|
10
|
+
DAYOFF_MENUITEM,
|
|
11
|
+
ABSENCEREQUESTTYPE_MENUITEM,
|
|
12
|
+
DAYOFFCALENDAR_MENUITEM,
|
|
13
|
+
POSITION_MENUITEM,
|
|
14
|
+
],
|
|
15
|
+
)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from django.utils.translation import gettext as _
|
|
2
|
+
from wbcore.menus import ItemPermission, MenuItem
|
|
3
|
+
from wbcore.permissions.shortcuts import is_internal_user
|
|
4
|
+
|
|
5
|
+
DAYOFF_MENUITEM = MenuItem(
|
|
6
|
+
label=_("Days Off"),
|
|
7
|
+
endpoint="wbhuman_resources:dayoff-list",
|
|
8
|
+
permission=ItemPermission(
|
|
9
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_dayoff"]
|
|
10
|
+
),
|
|
11
|
+
add=MenuItem(
|
|
12
|
+
label=_("Add Day Off"),
|
|
13
|
+
endpoint="wbhuman_resources:dayoff-list",
|
|
14
|
+
permission=ItemPermission(
|
|
15
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.add_dayoff"]
|
|
16
|
+
),
|
|
17
|
+
),
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
DAYOFFCALENDAR_MENUITEM = MenuItem(
|
|
21
|
+
label=_("Calendars"),
|
|
22
|
+
endpoint="wbhuman_resources:dayoffcalendar-list",
|
|
23
|
+
permission=ItemPermission(
|
|
24
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_dayoffcalendar"]
|
|
25
|
+
),
|
|
26
|
+
add=MenuItem(
|
|
27
|
+
label=_("Add Calendar"),
|
|
28
|
+
endpoint="wbhuman_resources:dayoffcalendar-list",
|
|
29
|
+
permission=ItemPermission(
|
|
30
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.add_dayoffcalendar"]
|
|
31
|
+
),
|
|
32
|
+
),
|
|
33
|
+
)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
from django.utils.translation import gettext as _
|
|
2
|
+
from wbcore.menus import ItemPermission, MenuItem
|
|
3
|
+
from wbcore.permissions.shortcuts import is_internal_user
|
|
4
|
+
|
|
5
|
+
EMPLOYEEHUMANRESOURCE_MENUITEM = MenuItem(
|
|
6
|
+
label=_("Balance & Usage"),
|
|
7
|
+
endpoint="wbhuman_resources:employeebalance-list",
|
|
8
|
+
permission=ItemPermission(
|
|
9
|
+
method=lambda request: is_internal_user(request.user),
|
|
10
|
+
permissions=["wbhuman_resources.view_employeehumanresource"],
|
|
11
|
+
),
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
EMPLOYEE_MENUITEM = MenuItem(
|
|
15
|
+
label=_("Employees"),
|
|
16
|
+
endpoint="wbhuman_resources:employee-list",
|
|
17
|
+
permission=ItemPermission(
|
|
18
|
+
method=lambda request: is_internal_user(request.user),
|
|
19
|
+
permissions=["wbhuman_resources.view_employeehumanresource"],
|
|
20
|
+
),
|
|
21
|
+
add=MenuItem(
|
|
22
|
+
label=_("Add Employee"),
|
|
23
|
+
endpoint="wbhuman_resources:employee-list",
|
|
24
|
+
permission=ItemPermission(
|
|
25
|
+
method=lambda request: is_internal_user(request.user),
|
|
26
|
+
permissions=["wbhuman_resources.add_employeehumanresource"],
|
|
27
|
+
),
|
|
28
|
+
),
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
POSITION_MENUITEM = MenuItem(
|
|
32
|
+
label=_("Positions"),
|
|
33
|
+
endpoint="wbhuman_resources:position-list",
|
|
34
|
+
permission=ItemPermission(
|
|
35
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_position"]
|
|
36
|
+
),
|
|
37
|
+
add=MenuItem(
|
|
38
|
+
label=_("Add Position"),
|
|
39
|
+
endpoint="wbhuman_resources:position-list",
|
|
40
|
+
permission=ItemPermission(
|
|
41
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.add_position"]
|
|
42
|
+
),
|
|
43
|
+
),
|
|
44
|
+
)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from django.utils.translation import gettext as _
|
|
2
|
+
from wbcore.menus import ItemPermission, MenuItem
|
|
3
|
+
from wbcore.permissions.shortcuts import is_internal_user
|
|
4
|
+
|
|
5
|
+
KPI_MENUITEM = MenuItem(
|
|
6
|
+
label=_("KPIs"),
|
|
7
|
+
endpoint="wbhuman_resources:kpi-list",
|
|
8
|
+
permission=ItemPermission(
|
|
9
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_kpi"]
|
|
10
|
+
),
|
|
11
|
+
)
|
|
12
|
+
KPIEVALUATIONPANDAS_MENUITEM = MenuItem(
|
|
13
|
+
label=_("KPI Evaluations"),
|
|
14
|
+
endpoint="wbhuman_resources:kpievaluationpandas-list",
|
|
15
|
+
permission=ItemPermission(
|
|
16
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_kpi"]
|
|
17
|
+
),
|
|
18
|
+
)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
from django.utils.translation import gettext as _
|
|
2
|
+
from wbcore.menus import ItemPermission, MenuItem
|
|
3
|
+
from wbcore.permissions.shortcuts import is_internal_user
|
|
4
|
+
|
|
5
|
+
REVIEWGROUP_MENUITEM = MenuItem(
|
|
6
|
+
label=_("Groups"),
|
|
7
|
+
endpoint="wbhuman_resources:reviewgroup-list",
|
|
8
|
+
permission=ItemPermission(
|
|
9
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_reviewgroup"]
|
|
10
|
+
),
|
|
11
|
+
add=MenuItem(
|
|
12
|
+
label=_("Add Group"),
|
|
13
|
+
endpoint="wbhuman_resources:reviewgroup-list",
|
|
14
|
+
permission=ItemPermission(
|
|
15
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.add_reviewgroup"]
|
|
16
|
+
),
|
|
17
|
+
),
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
REVIEW_MENUITEM = MenuItem(
|
|
22
|
+
label=_("Employee Reviews"),
|
|
23
|
+
endpoint="wbhuman_resources:review-list",
|
|
24
|
+
permission=ItemPermission(
|
|
25
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_review"]
|
|
26
|
+
),
|
|
27
|
+
add=MenuItem(
|
|
28
|
+
label=_("Add Review"),
|
|
29
|
+
endpoint="wbhuman_resources:review-list",
|
|
30
|
+
permission=ItemPermission(
|
|
31
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.add_review"]
|
|
32
|
+
),
|
|
33
|
+
),
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
REVIEWTEMPLATE_MENUITEM = MenuItem(
|
|
37
|
+
label=_("Templates"),
|
|
38
|
+
endpoint="wbhuman_resources:reviewtemplate-list",
|
|
39
|
+
permission=ItemPermission(
|
|
40
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.add_review"]
|
|
41
|
+
),
|
|
42
|
+
add=MenuItem(
|
|
43
|
+
label=_("Add Template"),
|
|
44
|
+
endpoint="wbhuman_resources:reviewtemplate-list",
|
|
45
|
+
permission=ItemPermission(
|
|
46
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.add_review"]
|
|
47
|
+
),
|
|
48
|
+
),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
REVIEWQUESTIONCATEFORY_MENUITEM = MenuItem(
|
|
52
|
+
label=_("Categories"),
|
|
53
|
+
endpoint="wbhuman_resources:reviewquestioncategory-list",
|
|
54
|
+
permission=ItemPermission(
|
|
55
|
+
method=lambda request: is_internal_user(request.user),
|
|
56
|
+
permissions=["wbhuman_resources.view_reviewquestioncategory"],
|
|
57
|
+
),
|
|
58
|
+
add=MenuItem(
|
|
59
|
+
label=_("Add Question Category"),
|
|
60
|
+
endpoint="wbhuman_resources:reviewquestioncategory-list",
|
|
61
|
+
permission=ItemPermission(
|
|
62
|
+
method=lambda request: is_internal_user(request.user),
|
|
63
|
+
permissions=["wbhuman_resources.add_reviewquestioncategory"],
|
|
64
|
+
),
|
|
65
|
+
),
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
REVIEWQUESTION_MENUITEM = MenuItem(
|
|
69
|
+
label=_("Questions"),
|
|
70
|
+
endpoint="wbhuman_resources:reviewquestion-list",
|
|
71
|
+
permission=ItemPermission(
|
|
72
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_reviewquestion"]
|
|
73
|
+
),
|
|
74
|
+
add=MenuItem(
|
|
75
|
+
label=_("Add Question"),
|
|
76
|
+
endpoint="wbhuman_resources:reviewquestion-list",
|
|
77
|
+
permission=ItemPermission(
|
|
78
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.add_reviewquestion"]
|
|
79
|
+
),
|
|
80
|
+
),
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
REVIEWANDWER_MENUITEM = MenuItem(
|
|
85
|
+
label=_("Answers"),
|
|
86
|
+
endpoint="wbhuman_resources:reviewanswer-list",
|
|
87
|
+
permission=ItemPermission(
|
|
88
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.view_reviewanswer"]
|
|
89
|
+
),
|
|
90
|
+
add=MenuItem(
|
|
91
|
+
label=_("Add Review"),
|
|
92
|
+
endpoint="wbhuman_resources:reviewanswer-list",
|
|
93
|
+
permission=ItemPermission(
|
|
94
|
+
method=lambda request: is_internal_user(request.user), permissions=["wbhuman_resources.add_reviewanswer"]
|
|
95
|
+
),
|
|
96
|
+
),
|
|
97
|
+
)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from django.shortcuts import get_object_or_404
|
|
2
|
+
from django.utils.functional import cached_property
|
|
3
|
+
|
|
4
|
+
from wbhuman_resources.models.employee import EmployeeHumanResource
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class EmployeeViewMixin:
|
|
8
|
+
@cached_property
|
|
9
|
+
def employee(self):
|
|
10
|
+
return get_object_or_404(EmployeeHumanResource, profile=self.request.user.profile)
|
|
11
|
+
|
|
12
|
+
@cached_property
|
|
13
|
+
def is_administrator(self):
|
|
14
|
+
return EmployeeHumanResource.is_administrator(self.request.user)
|