wbcompliance 2.2.1__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.
- wbcompliance/__init__.py +1 -0
- wbcompliance/admin/__init__.py +16 -0
- wbcompliance/admin/compliance_form.py +56 -0
- wbcompliance/admin/compliance_task.py +135 -0
- wbcompliance/admin/compliance_type.py +8 -0
- wbcompliance/admin/risk_management/__init__.py +3 -0
- wbcompliance/admin/risk_management/checks.py +7 -0
- wbcompliance/admin/risk_management/incidents.py +50 -0
- wbcompliance/admin/risk_management/rules.py +63 -0
- wbcompliance/admin/utils.py +46 -0
- wbcompliance/apps.py +14 -0
- wbcompliance/factories/__init__.py +21 -0
- wbcompliance/factories/compliance.py +246 -0
- wbcompliance/factories/risk_management/__init__.py +12 -0
- wbcompliance/factories/risk_management/backends.py +42 -0
- wbcompliance/factories/risk_management/checks.py +12 -0
- wbcompliance/factories/risk_management/incidents.py +84 -0
- wbcompliance/factories/risk_management/rules.py +100 -0
- wbcompliance/filters/__init__.py +2 -0
- wbcompliance/filters/compliances.py +189 -0
- wbcompliance/filters/risk_management/__init__.py +3 -0
- wbcompliance/filters/risk_management/checks.py +22 -0
- wbcompliance/filters/risk_management/incidents.py +113 -0
- wbcompliance/filters/risk_management/rules.py +110 -0
- wbcompliance/filters/risk_management/tables.py +112 -0
- wbcompliance/filters/risk_management/utils.py +3 -0
- wbcompliance/management/__init__.py +10 -0
- wbcompliance/migrations/0001_initial_squashed_squashed_0010_alter_checkedobjectincidentrelationship_resolved_by_and_more.py +1744 -0
- wbcompliance/migrations/0011_alter_riskrule_parameters.py +21 -0
- wbcompliance/migrations/0012_alter_compliancetype_options.py +20 -0
- wbcompliance/migrations/0013_alter_riskrule_unique_together.py +16 -0
- wbcompliance/migrations/0014_alter_reviewcompliancetask_year.py +27 -0
- wbcompliance/migrations/0015_auto_20240103_0957.py +43 -0
- wbcompliance/migrations/0016_checkedobjectincidentrelationship_report_details_and_more.py +37 -0
- wbcompliance/migrations/0017_alter_rulebackend_incident_report_template.py +20 -0
- wbcompliance/migrations/0018_alter_rulecheckedobjectrelationship_unique_together.py +39 -0
- wbcompliance/migrations/0019_rulegroup_riskrule_activation_date_and_more.py +60 -0
- wbcompliance/migrations/__init__.py +0 -0
- wbcompliance/models/__init__.py +20 -0
- wbcompliance/models/compliance_form.py +626 -0
- wbcompliance/models/compliance_task.py +800 -0
- wbcompliance/models/compliance_type.py +133 -0
- wbcompliance/models/enums.py +13 -0
- wbcompliance/models/risk_management/__init__.py +4 -0
- wbcompliance/models/risk_management/backend.py +139 -0
- wbcompliance/models/risk_management/checks.py +194 -0
- wbcompliance/models/risk_management/dispatch.py +41 -0
- wbcompliance/models/risk_management/incidents.py +619 -0
- wbcompliance/models/risk_management/mixins.py +115 -0
- wbcompliance/models/risk_management/rules.py +654 -0
- wbcompliance/permissions.py +32 -0
- wbcompliance/serializers/__init__.py +30 -0
- wbcompliance/serializers/compliance_form.py +320 -0
- wbcompliance/serializers/compliance_task.py +463 -0
- wbcompliance/serializers/compliance_type.py +26 -0
- wbcompliance/serializers/risk_management/__init__.py +19 -0
- wbcompliance/serializers/risk_management/checks.py +53 -0
- wbcompliance/serializers/risk_management/incidents.py +227 -0
- wbcompliance/serializers/risk_management/rules.py +158 -0
- wbcompliance/tasks.py +112 -0
- wbcompliance/tests/__init__.py +0 -0
- wbcompliance/tests/conftest.py +63 -0
- wbcompliance/tests/disable_signals.py +82 -0
- wbcompliance/tests/mixins.py +17 -0
- wbcompliance/tests/risk_management/__init__.py +0 -0
- wbcompliance/tests/risk_management/models/__init__.py +0 -0
- wbcompliance/tests/risk_management/models/test_backends.py +0 -0
- wbcompliance/tests/risk_management/models/test_checks.py +55 -0
- wbcompliance/tests/risk_management/models/test_incidents.py +327 -0
- wbcompliance/tests/risk_management/models/test_rules.py +255 -0
- wbcompliance/tests/signals.py +89 -0
- wbcompliance/tests/test_filters.py +23 -0
- wbcompliance/tests/test_models.py +57 -0
- wbcompliance/tests/test_serializers.py +48 -0
- wbcompliance/tests/test_views.py +377 -0
- wbcompliance/tests/tests.py +21 -0
- wbcompliance/urls.py +238 -0
- wbcompliance/viewsets/__init__.py +40 -0
- wbcompliance/viewsets/buttons/__init__.py +9 -0
- wbcompliance/viewsets/buttons/compliance_form.py +78 -0
- wbcompliance/viewsets/buttons/compliance_task.py +149 -0
- wbcompliance/viewsets/buttons/risk_managment/__init__.py +3 -0
- wbcompliance/viewsets/buttons/risk_managment/checks.py +11 -0
- wbcompliance/viewsets/buttons/risk_managment/incidents.py +51 -0
- wbcompliance/viewsets/buttons/risk_managment/rules.py +35 -0
- wbcompliance/viewsets/compliance_form.py +425 -0
- wbcompliance/viewsets/compliance_task.py +513 -0
- wbcompliance/viewsets/compliance_type.py +38 -0
- wbcompliance/viewsets/display/__init__.py +22 -0
- wbcompliance/viewsets/display/compliance_form.py +317 -0
- wbcompliance/viewsets/display/compliance_task.py +453 -0
- wbcompliance/viewsets/display/compliance_type.py +22 -0
- wbcompliance/viewsets/display/risk_managment/__init__.py +11 -0
- wbcompliance/viewsets/display/risk_managment/checks.py +46 -0
- wbcompliance/viewsets/display/risk_managment/incidents.py +155 -0
- wbcompliance/viewsets/display/risk_managment/rules.py +146 -0
- wbcompliance/viewsets/display/risk_managment/tables.py +51 -0
- wbcompliance/viewsets/endpoints/__init__.py +27 -0
- wbcompliance/viewsets/endpoints/compliance_form.py +207 -0
- wbcompliance/viewsets/endpoints/compliance_task.py +193 -0
- wbcompliance/viewsets/endpoints/compliance_type.py +9 -0
- wbcompliance/viewsets/endpoints/risk_managment/__init__.py +12 -0
- wbcompliance/viewsets/endpoints/risk_managment/checks.py +16 -0
- wbcompliance/viewsets/endpoints/risk_managment/incidents.py +36 -0
- wbcompliance/viewsets/endpoints/risk_managment/rules.py +32 -0
- wbcompliance/viewsets/endpoints/risk_managment/tables.py +14 -0
- wbcompliance/viewsets/menu/__init__.py +17 -0
- wbcompliance/viewsets/menu/compliance_form.py +49 -0
- wbcompliance/viewsets/menu/compliance_task.py +130 -0
- wbcompliance/viewsets/menu/compliance_type.py +17 -0
- wbcompliance/viewsets/menu/risk_management.py +56 -0
- wbcompliance/viewsets/risk_management/__init__.py +21 -0
- wbcompliance/viewsets/risk_management/checks.py +49 -0
- wbcompliance/viewsets/risk_management/incidents.py +204 -0
- wbcompliance/viewsets/risk_management/mixins.py +52 -0
- wbcompliance/viewsets/risk_management/rules.py +179 -0
- wbcompliance/viewsets/risk_management/tables.py +96 -0
- wbcompliance/viewsets/titles/__init__.py +17 -0
- wbcompliance/viewsets/titles/compliance_form.py +101 -0
- wbcompliance/viewsets/titles/compliance_task.py +60 -0
- wbcompliance/viewsets/titles/compliance_type.py +13 -0
- wbcompliance/viewsets/titles/risk_managment/__init__.py +1 -0
- wbcompliance/viewsets/titles/risk_managment/checks.py +0 -0
- wbcompliance/viewsets/titles/risk_managment/incidents.py +0 -0
- wbcompliance/viewsets/titles/risk_managment/rules.py +0 -0
- wbcompliance/viewsets/titles/risk_managment/tables.py +7 -0
- wbcompliance-2.2.1.dist-info/METADATA +7 -0
- wbcompliance-2.2.1.dist-info/RECORD +129 -0
- wbcompliance-2.2.1.dist-info/WHEEL +5 -0
|
@@ -0,0 +1,513 @@
|
|
|
1
|
+
from datetime import datetime, timedelta
|
|
2
|
+
|
|
3
|
+
import pandas as pd
|
|
4
|
+
from django.contrib.contenttypes.models import ContentType
|
|
5
|
+
from django.db.models import F, Q
|
|
6
|
+
from django.shortcuts import get_object_or_404
|
|
7
|
+
from django.utils.translation import gettext as _
|
|
8
|
+
from rest_framework import status
|
|
9
|
+
from rest_framework.decorators import action
|
|
10
|
+
from rest_framework.response import Response
|
|
11
|
+
from reversion.views import RevisionMixin
|
|
12
|
+
from wbcompliance.filters import (
|
|
13
|
+
ComplianceActionFilter,
|
|
14
|
+
ComplianceEventFilter,
|
|
15
|
+
ComplianceTaskFilter,
|
|
16
|
+
ComplianceTaskGroupFilter,
|
|
17
|
+
ComplianceTaskInstanceFilter,
|
|
18
|
+
ComplianceTaskMatrixFilter,
|
|
19
|
+
ComplianceTaskReviewFilter,
|
|
20
|
+
ReviewComplianceTaskFilter,
|
|
21
|
+
)
|
|
22
|
+
from wbcompliance.models import (
|
|
23
|
+
ComplianceAction,
|
|
24
|
+
ComplianceEvent,
|
|
25
|
+
ComplianceTask,
|
|
26
|
+
ComplianceTaskGroup,
|
|
27
|
+
ComplianceTaskInstance,
|
|
28
|
+
ReviewComplianceTask,
|
|
29
|
+
update_or_create_compliance_document,
|
|
30
|
+
)
|
|
31
|
+
from wbcompliance.serializers import (
|
|
32
|
+
ComplianceActionModelSerializer,
|
|
33
|
+
ComplianceEventModelSerializer,
|
|
34
|
+
ComplianceTaskGroupModelSerializer,
|
|
35
|
+
ComplianceTaskGroupRepresentationSerializer,
|
|
36
|
+
ComplianceTaskInstanceListModelSerializer,
|
|
37
|
+
ComplianceTaskInstanceModelSerializer,
|
|
38
|
+
ComplianceTaskModelSerializer,
|
|
39
|
+
ComplianceTaskRepresentationSerializer,
|
|
40
|
+
ComplianceTaskReviewModelSerializer,
|
|
41
|
+
ReviewComplianceTaskModelSerializer,
|
|
42
|
+
ReviewComplianceTaskRepresentationSerializer,
|
|
43
|
+
)
|
|
44
|
+
from wbcore import viewsets
|
|
45
|
+
from wbcore.contrib.authentication.authentication import JWTCookieAuthentication
|
|
46
|
+
from wbcore.pandas import fields as pf
|
|
47
|
+
from wbcore.pandas.views import PandasAPIViewSet
|
|
48
|
+
|
|
49
|
+
from .buttons import ComplianceTaskButtonConfig, ReviewComplianceTaskButtonConfig
|
|
50
|
+
from .display import (
|
|
51
|
+
ComplianceActionDisplayConfig,
|
|
52
|
+
ComplianceEventDisplayConfig,
|
|
53
|
+
ComplianceTaskDisplayConfig,
|
|
54
|
+
ComplianceTaskGroupDisplayConfig,
|
|
55
|
+
ComplianceTaskInstanceComplianceTaskDisplayConfig,
|
|
56
|
+
ComplianceTaskInstanceDisplayConfig,
|
|
57
|
+
ComplianceTaskInstanceReviewDisplayConfig,
|
|
58
|
+
ComplianceTaskMatrixPandasDisplayConfig,
|
|
59
|
+
ComplianceTaskReviewDisplayConfig,
|
|
60
|
+
ReviewComplianceTaskDisplayConfig,
|
|
61
|
+
)
|
|
62
|
+
from .endpoints import (
|
|
63
|
+
ComplianceActionEndpointConfig,
|
|
64
|
+
ComplianceEventEndpointConfig,
|
|
65
|
+
ComplianceTaskComplianceTaskGroupEndpointConfig,
|
|
66
|
+
ComplianceTaskEndpointConfig,
|
|
67
|
+
ComplianceTaskGroupEndpointConfig,
|
|
68
|
+
ComplianceTaskInstanceComplianceTaskEndpointConfig,
|
|
69
|
+
ComplianceTaskInstanceEndpointConfig,
|
|
70
|
+
ComplianceTaskInstanceReviewGroupEndpointConfig,
|
|
71
|
+
ComplianceTaskInstanceReviewNoGroupEndpointConfig,
|
|
72
|
+
ComplianceTaskMatrixEndpointConfig,
|
|
73
|
+
ComplianceTaskReviewGroupEndpointConfig,
|
|
74
|
+
ComplianceTaskReviewNoGroupEndpointConfig,
|
|
75
|
+
ReviewComplianceTaskEndpointConfig,
|
|
76
|
+
)
|
|
77
|
+
from .titles import (
|
|
78
|
+
ComplianceTaskComplianceTaskGroupTitleConfig,
|
|
79
|
+
ComplianceTaskGroupTitleConfig,
|
|
80
|
+
ComplianceTaskInstanceTitleConfig,
|
|
81
|
+
ComplianceTaskMatrixPandasTitleConfig,
|
|
82
|
+
ComplianceTaskTitleConfig,
|
|
83
|
+
ReviewComplianceTaskTitleConfig,
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
class ComplianceTaskGroupRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
88
|
+
IDENTIFIER = "wbcompliance:compliancetaskgrouprepresentation"
|
|
89
|
+
search_fields = ["name"]
|
|
90
|
+
ordering_fields = ["name"]
|
|
91
|
+
|
|
92
|
+
queryset = ComplianceTaskGroup.objects.all()
|
|
93
|
+
serializer_class = ComplianceTaskGroupRepresentationSerializer
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class ComplianceTaskRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
97
|
+
IDENTIFIER = "wbcompliance:compliancetaskrepresentation"
|
|
98
|
+
search_fields = ["title"]
|
|
99
|
+
ordering_fields = ["title", "occurrence", "active", "type"]
|
|
100
|
+
|
|
101
|
+
queryset = ComplianceTask.objects.all()
|
|
102
|
+
serializer_class = ComplianceTaskRepresentationSerializer
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class ReviewComplianceTaskRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
106
|
+
IDENTIFIER = "wbcompliance:reviewcompliancetaskrepresentation"
|
|
107
|
+
search_fields = ordering_fields = ["title"]
|
|
108
|
+
ordering = ["-year", "-occured", "title"]
|
|
109
|
+
filterset_class = ReviewComplianceTaskFilter
|
|
110
|
+
|
|
111
|
+
queryset = ReviewComplianceTask.objects.all()
|
|
112
|
+
serializer_class = ReviewComplianceTaskRepresentationSerializer
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class ComplianceTaskGroupModelViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
116
|
+
IDENTIFIER = "wbcompliance:compliancetaskgroup"
|
|
117
|
+
display_config_class = ComplianceTaskGroupDisplayConfig
|
|
118
|
+
endpoint_config_class = ComplianceTaskGroupEndpointConfig
|
|
119
|
+
title_config_class = ComplianceTaskGroupTitleConfig
|
|
120
|
+
|
|
121
|
+
search_fields = ["name"]
|
|
122
|
+
ordering_fields = ["order", "name"]
|
|
123
|
+
ordering = ["order", "name"]
|
|
124
|
+
|
|
125
|
+
filterset_class = ComplianceTaskGroupFilter
|
|
126
|
+
|
|
127
|
+
serializer_class = ComplianceTaskGroupModelSerializer
|
|
128
|
+
|
|
129
|
+
queryset = ComplianceTaskGroup.objects.all()
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
class ComplianceTaskModelViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
133
|
+
IDENTIFIER = "wbcompliance:compliancetask"
|
|
134
|
+
display_config_class = ComplianceTaskDisplayConfig
|
|
135
|
+
title_config_class = ComplianceTaskTitleConfig
|
|
136
|
+
endpoint_config_class = ComplianceTaskEndpointConfig
|
|
137
|
+
button_config_class = ComplianceTaskButtonConfig
|
|
138
|
+
|
|
139
|
+
search_fields = ["title"]
|
|
140
|
+
ordering_fields = ["title", "occurrence", "risk_level", "group", "active", "type", "review"]
|
|
141
|
+
|
|
142
|
+
filterset_class = ComplianceTaskFilter
|
|
143
|
+
|
|
144
|
+
serializer_class = ComplianceTaskModelSerializer
|
|
145
|
+
|
|
146
|
+
queryset = ComplianceTask.objects.select_related(
|
|
147
|
+
"group",
|
|
148
|
+
"type",
|
|
149
|
+
).prefetch_related("review")
|
|
150
|
+
|
|
151
|
+
@action(detail=True, methods=["PATCH"], authentication_classes=[JWTCookieAuthentication])
|
|
152
|
+
def generate_instance(self, request, pk):
|
|
153
|
+
if not request.user.is_superuser:
|
|
154
|
+
return Response(status=status.HTTP_403_FORBIDDEN)
|
|
155
|
+
|
|
156
|
+
if occured := request.POST.get("occured", None):
|
|
157
|
+
task = get_object_or_404(ComplianceTask, pk=pk)
|
|
158
|
+
task.generate_compliance_task_instance(occured=datetime.strptime(occured, "%Y-%m-%d"))
|
|
159
|
+
else:
|
|
160
|
+
return Response(status=status.HTTP_400_BAD_REQUEST)
|
|
161
|
+
|
|
162
|
+
return Response(
|
|
163
|
+
{"__notification": {"title": "Indicator Instance has been generated."}},
|
|
164
|
+
status=status.HTTP_200_OK,
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
class ComplianceTaskComplianceTaskGroupModelViewSet(ComplianceTaskModelViewSet):
|
|
169
|
+
title_config_class = ComplianceTaskComplianceTaskGroupTitleConfig
|
|
170
|
+
endpoint_config_class = ComplianceTaskComplianceTaskGroupEndpointConfig
|
|
171
|
+
|
|
172
|
+
def get_queryset(self):
|
|
173
|
+
return super().get_queryset().filter(group__id=self.kwargs["group_id"])
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
class ComplianceTaskInstanceModelViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
177
|
+
IDENTIFIER = "wbcompliance:compliancetaskinstance"
|
|
178
|
+
display_config_class = ComplianceTaskInstanceDisplayConfig
|
|
179
|
+
endpoint_config_class = ComplianceTaskInstanceEndpointConfig
|
|
180
|
+
title_config_class = ComplianceTaskInstanceTitleConfig
|
|
181
|
+
|
|
182
|
+
search_fields = ["task__title"]
|
|
183
|
+
ordering_fields = ["task__title", "occured", "status", "review"]
|
|
184
|
+
ordering = ["-occured", "-type_name", "group_name", "task__title"]
|
|
185
|
+
|
|
186
|
+
filterset_class = ComplianceTaskInstanceFilter
|
|
187
|
+
|
|
188
|
+
serializer_class = ComplianceTaskInstanceModelSerializer
|
|
189
|
+
|
|
190
|
+
queryset = ComplianceTaskInstance.objects.select_related("task").prefetch_related("review")
|
|
191
|
+
|
|
192
|
+
def get_serializer_class(self):
|
|
193
|
+
if self.get_action() in ["list", "list-metadata"]:
|
|
194
|
+
return ComplianceTaskInstanceListModelSerializer
|
|
195
|
+
return ComplianceTaskInstanceModelSerializer
|
|
196
|
+
|
|
197
|
+
def get_queryset(self):
|
|
198
|
+
return (
|
|
199
|
+
super()
|
|
200
|
+
.get_queryset()
|
|
201
|
+
.annotate(
|
|
202
|
+
task_title=F("task__title"),
|
|
203
|
+
active=F("task__active"),
|
|
204
|
+
type_name=F("task__type__name"),
|
|
205
|
+
group_name=F("task__group__name"),
|
|
206
|
+
)
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class ComplianceTaskInstanceComplianceTaskModelViewSet(ComplianceTaskInstanceModelViewSet):
|
|
211
|
+
IDENTIFIER = "wbcompliance:compliancetask-compliancetaskinstance"
|
|
212
|
+
display_config_class = ComplianceTaskInstanceComplianceTaskDisplayConfig
|
|
213
|
+
endpoint_config_class = ComplianceTaskInstanceComplianceTaskEndpointConfig
|
|
214
|
+
|
|
215
|
+
def get_queryset(self):
|
|
216
|
+
if task_id := self.kwargs.get("task_id", None):
|
|
217
|
+
return (
|
|
218
|
+
super()
|
|
219
|
+
.get_queryset()
|
|
220
|
+
.filter(task__id=task_id)
|
|
221
|
+
.annotate(
|
|
222
|
+
task_title=F("task__title"),
|
|
223
|
+
active=F("task__active"),
|
|
224
|
+
type_name=F("task__type__name"),
|
|
225
|
+
group_name=F("task__group__name"),
|
|
226
|
+
)
|
|
227
|
+
)
|
|
228
|
+
return ComplianceTask.objects.none()
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
class ComplianceTaskMatrixPandasViewSet(PandasAPIViewSet):
|
|
232
|
+
IDENTIFIER = "wbcommission:compliancetaskmatrix"
|
|
233
|
+
queryset = ComplianceTaskInstance.objects.all()
|
|
234
|
+
|
|
235
|
+
display_config_class = ComplianceTaskMatrixPandasDisplayConfig
|
|
236
|
+
title_config_class = ComplianceTaskMatrixPandasTitleConfig
|
|
237
|
+
endpoint_config_class = ComplianceTaskMatrixEndpointConfig
|
|
238
|
+
|
|
239
|
+
filterset_class = ComplianceTaskMatrixFilter
|
|
240
|
+
|
|
241
|
+
def get_pandas_fields(self, request):
|
|
242
|
+
_fields = [
|
|
243
|
+
pf.PKField("id", label=_("ID")),
|
|
244
|
+
pf.CharField(key="type_name", label=_("Administrator")),
|
|
245
|
+
pf.CharField(key="group_name", label=_("Group")),
|
|
246
|
+
pf.CharField(key="task_title", label=_("Tasks")),
|
|
247
|
+
]
|
|
248
|
+
if _dict := ComplianceTaskInstance.get_dict_max_count_task():
|
|
249
|
+
qs_occured = (
|
|
250
|
+
ComplianceTaskInstance.objects.filter(task=_dict.get("task"))
|
|
251
|
+
.order_by("-occured")
|
|
252
|
+
.values_list("occured", flat=True)
|
|
253
|
+
.distinct()[:12]
|
|
254
|
+
)
|
|
255
|
+
for date in qs_occured:
|
|
256
|
+
date_str = date.strftime("%Y-%m-%d")
|
|
257
|
+
covered_month = (date - timedelta(days=1)).strftime("%Y-%h")
|
|
258
|
+
_fields.append(pf.CharField(key=date_str, label=covered_month))
|
|
259
|
+
return pf.PandasFields(fields=tuple(_fields))
|
|
260
|
+
|
|
261
|
+
def get_queryset(self):
|
|
262
|
+
return (
|
|
263
|
+
super()
|
|
264
|
+
.get_queryset()
|
|
265
|
+
.filter(task__active=True)
|
|
266
|
+
.annotate(task_title=F("task__title"), type_name=F("task__type__name"), group_name=F("task__group__name"))
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
def get_dataframe(self, request, queryset, **kwargs):
|
|
270
|
+
def _rename_columns(df):
|
|
271
|
+
pass
|
|
272
|
+
|
|
273
|
+
rename_map = {}
|
|
274
|
+
for col in df.columns:
|
|
275
|
+
if not isinstance(col, str):
|
|
276
|
+
rename_map[col] = str(col)
|
|
277
|
+
rename_map["index"] = "task"
|
|
278
|
+
return df.rename(columns=rename_map)
|
|
279
|
+
|
|
280
|
+
df = pd.DataFrame()
|
|
281
|
+
if queryset.exists():
|
|
282
|
+
df = pd.DataFrame(
|
|
283
|
+
queryset.values("task", "type_name", "group_name", "task_title", "occured", "status"),
|
|
284
|
+
columns=["task", "type_name", "group_name", "task_title", "occured", "status"],
|
|
285
|
+
)
|
|
286
|
+
df["status"] = df["status"].apply(lambda x: ComplianceTaskInstance.Status[x].label)
|
|
287
|
+
df = df.where(pd.notnull(df), "")
|
|
288
|
+
df = df.pivot_table(
|
|
289
|
+
index=["task", "type_name", "group_name", "task_title"],
|
|
290
|
+
columns="occured",
|
|
291
|
+
values="status",
|
|
292
|
+
aggfunc="last",
|
|
293
|
+
)
|
|
294
|
+
df = _rename_columns(df)
|
|
295
|
+
df = df.reset_index()
|
|
296
|
+
df["id"] = df.index
|
|
297
|
+
|
|
298
|
+
return df
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
class ComplianceActionModelViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
302
|
+
IDENTIFIER = "wbcompliance:complianceaction"
|
|
303
|
+
display_config_class = ComplianceActionDisplayConfig
|
|
304
|
+
endpoint_config_class = ComplianceActionEndpointConfig
|
|
305
|
+
|
|
306
|
+
search_fields = ["title"]
|
|
307
|
+
ordering_fields = [
|
|
308
|
+
"title",
|
|
309
|
+
"deadline",
|
|
310
|
+
"progress",
|
|
311
|
+
"status",
|
|
312
|
+
"active",
|
|
313
|
+
"type",
|
|
314
|
+
"creator",
|
|
315
|
+
"changer",
|
|
316
|
+
"last_modified",
|
|
317
|
+
]
|
|
318
|
+
ordering = ["-last_modified", "active"]
|
|
319
|
+
|
|
320
|
+
filterset_class = ComplianceActionFilter
|
|
321
|
+
|
|
322
|
+
serializer_class = ComplianceActionModelSerializer
|
|
323
|
+
|
|
324
|
+
queryset = ComplianceAction.objects.select_related("type", "creator", "changer")
|
|
325
|
+
|
|
326
|
+
def get_queryset(self):
|
|
327
|
+
if self.request.user.has_perm("wbcompliance.administrate_compliance"):
|
|
328
|
+
return super().get_queryset()
|
|
329
|
+
return ComplianceAction.objects.none()
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
class TypeComplianceActionModelViewSet(ComplianceActionModelViewSet):
|
|
333
|
+
IDENTIFIER = "wbcompliance:type-complianceaction"
|
|
334
|
+
|
|
335
|
+
def get_queryset(self):
|
|
336
|
+
return super().get_queryset().filter(type=self.kwargs["type_id"])
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
class ComplianceEventModelViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
340
|
+
IDENTIFIER = "wbcompliance:complianceevent"
|
|
341
|
+
display_config_class = ComplianceEventDisplayConfig
|
|
342
|
+
endpoint_config_class = ComplianceEventEndpointConfig
|
|
343
|
+
|
|
344
|
+
search_fields = ["title"]
|
|
345
|
+
ordering_fields = ["title", "type", "level", "active", "type", "creator", "last_modified", "confidential"]
|
|
346
|
+
ordering = ["-last_modified", "active"]
|
|
347
|
+
|
|
348
|
+
filterset_class = ComplianceEventFilter
|
|
349
|
+
|
|
350
|
+
serializer_class = ComplianceEventModelSerializer
|
|
351
|
+
|
|
352
|
+
queryset = ComplianceEvent.objects.select_related(
|
|
353
|
+
"type",
|
|
354
|
+
"creator",
|
|
355
|
+
"changer",
|
|
356
|
+
)
|
|
357
|
+
|
|
358
|
+
def get_queryset(self):
|
|
359
|
+
qs = super().get_queryset()
|
|
360
|
+
if self.request.user.has_perm("wbcompliance.administrate_compliance"):
|
|
361
|
+
return qs
|
|
362
|
+
return qs.filter(Q(creator=self.request.user.profile) | Q(confidential=False))
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
class TypeComplianceEventModelViewSet(ComplianceEventModelViewSet):
|
|
366
|
+
IDENTIFIER = "wbcompliance:type-complianceevent"
|
|
367
|
+
|
|
368
|
+
def get_queryset(self):
|
|
369
|
+
return super().get_queryset().filter(type=self.kwargs["type_id"])
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
class ReviewComplianceTaskModelViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
373
|
+
IDENTIFIER = "wbcompliance:reviewcompliancetask"
|
|
374
|
+
display_config_class = ReviewComplianceTaskDisplayConfig
|
|
375
|
+
endpoint_config_class = ReviewComplianceTaskEndpointConfig
|
|
376
|
+
button_config_class = ReviewComplianceTaskButtonConfig
|
|
377
|
+
title_config_class = ReviewComplianceTaskTitleConfig
|
|
378
|
+
|
|
379
|
+
search_fields = ["title"]
|
|
380
|
+
ordering = ["-year", "-is_instance", "-occured", "-changed", "title"]
|
|
381
|
+
ordering_fields = [
|
|
382
|
+
"title",
|
|
383
|
+
"from_date",
|
|
384
|
+
"to_date",
|
|
385
|
+
"year",
|
|
386
|
+
"status",
|
|
387
|
+
"changer",
|
|
388
|
+
"changed",
|
|
389
|
+
"is_instance",
|
|
390
|
+
"occured",
|
|
391
|
+
"review_task",
|
|
392
|
+
"ocurrance",
|
|
393
|
+
]
|
|
394
|
+
|
|
395
|
+
filterset_class = ReviewComplianceTaskFilter
|
|
396
|
+
|
|
397
|
+
serializer_class = ReviewComplianceTaskModelSerializer
|
|
398
|
+
|
|
399
|
+
queryset = ReviewComplianceTask.objects.select_related(
|
|
400
|
+
"creator",
|
|
401
|
+
"changer",
|
|
402
|
+
"review_task",
|
|
403
|
+
"type",
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
@action(detail=True, methods=["PATCH"], authentication_classes=[JWTCookieAuthentication])
|
|
407
|
+
def regenerate_document(self, request, pk):
|
|
408
|
+
if not request.user.has_perm("wbcompliance.administrate_compliance"):
|
|
409
|
+
return Response({}, status=status.HTTP_403_FORBIDDEN)
|
|
410
|
+
content_type = ContentType.objects.get_for_model(ReviewComplianceTask)
|
|
411
|
+
send_email = request.POST.get("send_email", "false") == "true"
|
|
412
|
+
update_or_create_compliance_document.delay(request.user.id, content_type.id, pk, send_email=send_email)
|
|
413
|
+
|
|
414
|
+
return Response(
|
|
415
|
+
{"__notification": {"title": "PDF is going to be created and sent to you."}},
|
|
416
|
+
status=status.HTTP_200_OK,
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
@action(detail=True, methods=["PATCH"], authentication_classes=[JWTCookieAuthentication])
|
|
420
|
+
def generate_instance(self, request, pk):
|
|
421
|
+
if not request.user.has_perm("wbcompliance.administrate_compliance"):
|
|
422
|
+
return Response({}, status=status.HTTP_403_FORBIDDEN)
|
|
423
|
+
review = ReviewComplianceTask.objects.get(id=pk)
|
|
424
|
+
review.generate_review_compliance_task_instance(link_instance=True)
|
|
425
|
+
return Response(
|
|
426
|
+
{"__notification": {"title": "Instance is going to be generate."}},
|
|
427
|
+
status=status.HTTP_200_OK,
|
|
428
|
+
)
|
|
429
|
+
|
|
430
|
+
@action(detail=True, methods=["PATCH"], authentication_classes=[JWTCookieAuthentication])
|
|
431
|
+
def link_tasks(self, request, pk):
|
|
432
|
+
if not request.user.has_perm("wbcompliance.administrate_compliance"):
|
|
433
|
+
return Response({}, status=status.HTTP_403_FORBIDDEN)
|
|
434
|
+
|
|
435
|
+
if (_type := request.POST.get("type", None)) and (operation := request.POST.get("operation", None)):
|
|
436
|
+
review = ReviewComplianceTask.objects.get(id=pk)
|
|
437
|
+
for task in ComplianceTask.objects.filter(type__name=_type):
|
|
438
|
+
if operation == "ADD":
|
|
439
|
+
task.review.add(review)
|
|
440
|
+
elif operation == "REMOVE":
|
|
441
|
+
task.review.remove(review)
|
|
442
|
+
task.save()
|
|
443
|
+
else:
|
|
444
|
+
return Response({}, status=status.HTTP_400_BAD_REQUEST)
|
|
445
|
+
|
|
446
|
+
return Response(
|
|
447
|
+
{"__notification": {"title": "Tasks of a type is going to be linked."}},
|
|
448
|
+
status=status.HTTP_200_OK,
|
|
449
|
+
)
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
class ComplianceTaskReviewNoGroupModelViewSet(ComplianceTaskModelViewSet):
|
|
453
|
+
display_config_class = ComplianceTaskReviewDisplayConfig
|
|
454
|
+
endpoint_config_class = ComplianceTaskReviewNoGroupEndpointConfig
|
|
455
|
+
filterset_class = ComplianceTaskReviewFilter
|
|
456
|
+
serializer_class = ComplianceTaskReviewModelSerializer
|
|
457
|
+
|
|
458
|
+
def get_queryset(self):
|
|
459
|
+
return super().get_queryset().filter(Q(review__id=self.kwargs["review_id"]) & Q(group=None))
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
class ComplianceTaskReviewGroupModelViewSet(ComplianceTaskModelViewSet):
|
|
463
|
+
display_config_class = ComplianceTaskReviewDisplayConfig
|
|
464
|
+
endpoint_config_class = ComplianceTaskReviewGroupEndpointConfig
|
|
465
|
+
filterset_class = ComplianceTaskReviewFilter
|
|
466
|
+
serializer_class = ComplianceTaskReviewModelSerializer
|
|
467
|
+
|
|
468
|
+
def get_queryset(self):
|
|
469
|
+
return super().get_queryset().filter(Q(review__id=self.kwargs["review_id"]) & Q(group=self.kwargs["group_id"]))
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
class ComplianceTaskInstanceReviewNoGroupModelViewSet(ComplianceTaskInstanceModelViewSet):
|
|
473
|
+
IDENTIFIER = "wbcompliance:review-compliancetaskinstancenogroup"
|
|
474
|
+
display_config_class = ComplianceTaskInstanceReviewDisplayConfig
|
|
475
|
+
endpoint_config_class = ComplianceTaskInstanceReviewNoGroupEndpointConfig
|
|
476
|
+
|
|
477
|
+
def get_serializer_class(self):
|
|
478
|
+
return ComplianceTaskInstanceModelSerializer
|
|
479
|
+
|
|
480
|
+
def get_queryset(self):
|
|
481
|
+
return (
|
|
482
|
+
super()
|
|
483
|
+
.get_queryset()
|
|
484
|
+
.filter(Q(review__id=self.kwargs["review_id"]) & Q(task__group=None))
|
|
485
|
+
.annotate(
|
|
486
|
+
task_title=F("task__title"),
|
|
487
|
+
active=F("task__active"),
|
|
488
|
+
type_name=F("task__type__name"),
|
|
489
|
+
group_name=F("task__group__name"),
|
|
490
|
+
)
|
|
491
|
+
)
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
class ComplianceTaskInstanceReviewGroupModelViewSet(ComplianceTaskInstanceModelViewSet):
|
|
495
|
+
IDENTIFIER = "wbcompliance:review-compliancetaskinstancegroup"
|
|
496
|
+
display_config_class = ComplianceTaskInstanceReviewDisplayConfig
|
|
497
|
+
endpoint_config_class = ComplianceTaskInstanceReviewGroupEndpointConfig
|
|
498
|
+
|
|
499
|
+
def get_serializer_class(self):
|
|
500
|
+
return ComplianceTaskInstanceModelSerializer
|
|
501
|
+
|
|
502
|
+
def get_queryset(self):
|
|
503
|
+
return (
|
|
504
|
+
super()
|
|
505
|
+
.get_queryset()
|
|
506
|
+
.filter(Q(review__id=self.kwargs["review_id"]) & Q(task__group=self.kwargs["group_id"]))
|
|
507
|
+
.annotate(
|
|
508
|
+
task_title=F("task__title"),
|
|
509
|
+
active=F("task__active"),
|
|
510
|
+
type_name=F("task__type__name"),
|
|
511
|
+
group_name=F("task__group__name"),
|
|
512
|
+
)
|
|
513
|
+
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from reversion.views import RevisionMixin
|
|
2
|
+
from wbcompliance.filters import ComplianceTypeFilter
|
|
3
|
+
from wbcompliance.models import ComplianceType
|
|
4
|
+
from wbcompliance.serializers import (
|
|
5
|
+
ComplianceTypeModelSerializer,
|
|
6
|
+
ComplianceTypeRepresentationSerializer,
|
|
7
|
+
)
|
|
8
|
+
from wbcore import viewsets
|
|
9
|
+
|
|
10
|
+
from .display import ComplianceTypeDisplayConfig
|
|
11
|
+
from .endpoints import ComplianceTypeEndpointConfig
|
|
12
|
+
from .titles import ComplianceTypeTitleConfig
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ComplianceTypeRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
16
|
+
IDENTIFIER = "wbcompliance:compliancetyperepresentation"
|
|
17
|
+
search_fields = ["name"]
|
|
18
|
+
ordering_fields = ["name"]
|
|
19
|
+
|
|
20
|
+
queryset = ComplianceType.objects.all()
|
|
21
|
+
serializer_class = ComplianceTypeRepresentationSerializer
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class ComplianceTypeModelViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
25
|
+
IDENTIFIER = "wbcompliance:compliancetype"
|
|
26
|
+
display_config_class = ComplianceTypeDisplayConfig
|
|
27
|
+
endpoint_config_class = ComplianceTypeEndpointConfig
|
|
28
|
+
title_config_class = ComplianceTypeTitleConfig
|
|
29
|
+
|
|
30
|
+
search_fields = ["name"]
|
|
31
|
+
ordering_fields = ["name", "in_charge"]
|
|
32
|
+
ordering = ["name"]
|
|
33
|
+
|
|
34
|
+
filterset_class = ComplianceTypeFilter
|
|
35
|
+
|
|
36
|
+
serializer_class = ComplianceTypeModelSerializer
|
|
37
|
+
|
|
38
|
+
queryset = ComplianceType.objects.prefetch_related("in_charge")
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from .compliance_form import (
|
|
2
|
+
ComplianceFormDisplayConfig,
|
|
3
|
+
ComplianceFormRuleDisplayConfig,
|
|
4
|
+
ComplianceFormSectionDisplayConfig,
|
|
5
|
+
ComplianceFormSignatureDisplayConfig,
|
|
6
|
+
ComplianceFormSignatureSectionRuleDisplayConfig,
|
|
7
|
+
ComplianceFormTypeDisplayConfig,
|
|
8
|
+
)
|
|
9
|
+
from .compliance_task import (
|
|
10
|
+
ComplianceActionDisplayConfig,
|
|
11
|
+
ComplianceEventDisplayConfig,
|
|
12
|
+
ComplianceTaskDisplayConfig,
|
|
13
|
+
ComplianceTaskGroupDisplayConfig,
|
|
14
|
+
ComplianceTaskInstanceComplianceTaskDisplayConfig,
|
|
15
|
+
ComplianceTaskInstanceDisplayConfig,
|
|
16
|
+
ComplianceTaskInstanceReviewDisplayConfig,
|
|
17
|
+
ComplianceTaskMatrixPandasDisplayConfig,
|
|
18
|
+
ComplianceTaskReviewDisplayConfig,
|
|
19
|
+
ReviewComplianceTaskDisplayConfig,
|
|
20
|
+
)
|
|
21
|
+
from .compliance_type import ComplianceTypeDisplayConfig
|
|
22
|
+
from .risk_managment import *
|