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.
Files changed (129) hide show
  1. wbcompliance/__init__.py +1 -0
  2. wbcompliance/admin/__init__.py +16 -0
  3. wbcompliance/admin/compliance_form.py +56 -0
  4. wbcompliance/admin/compliance_task.py +135 -0
  5. wbcompliance/admin/compliance_type.py +8 -0
  6. wbcompliance/admin/risk_management/__init__.py +3 -0
  7. wbcompliance/admin/risk_management/checks.py +7 -0
  8. wbcompliance/admin/risk_management/incidents.py +50 -0
  9. wbcompliance/admin/risk_management/rules.py +63 -0
  10. wbcompliance/admin/utils.py +46 -0
  11. wbcompliance/apps.py +14 -0
  12. wbcompliance/factories/__init__.py +21 -0
  13. wbcompliance/factories/compliance.py +246 -0
  14. wbcompliance/factories/risk_management/__init__.py +12 -0
  15. wbcompliance/factories/risk_management/backends.py +42 -0
  16. wbcompliance/factories/risk_management/checks.py +12 -0
  17. wbcompliance/factories/risk_management/incidents.py +84 -0
  18. wbcompliance/factories/risk_management/rules.py +100 -0
  19. wbcompliance/filters/__init__.py +2 -0
  20. wbcompliance/filters/compliances.py +189 -0
  21. wbcompliance/filters/risk_management/__init__.py +3 -0
  22. wbcompliance/filters/risk_management/checks.py +22 -0
  23. wbcompliance/filters/risk_management/incidents.py +113 -0
  24. wbcompliance/filters/risk_management/rules.py +110 -0
  25. wbcompliance/filters/risk_management/tables.py +112 -0
  26. wbcompliance/filters/risk_management/utils.py +3 -0
  27. wbcompliance/management/__init__.py +10 -0
  28. wbcompliance/migrations/0001_initial_squashed_squashed_0010_alter_checkedobjectincidentrelationship_resolved_by_and_more.py +1744 -0
  29. wbcompliance/migrations/0011_alter_riskrule_parameters.py +21 -0
  30. wbcompliance/migrations/0012_alter_compliancetype_options.py +20 -0
  31. wbcompliance/migrations/0013_alter_riskrule_unique_together.py +16 -0
  32. wbcompliance/migrations/0014_alter_reviewcompliancetask_year.py +27 -0
  33. wbcompliance/migrations/0015_auto_20240103_0957.py +43 -0
  34. wbcompliance/migrations/0016_checkedobjectincidentrelationship_report_details_and_more.py +37 -0
  35. wbcompliance/migrations/0017_alter_rulebackend_incident_report_template.py +20 -0
  36. wbcompliance/migrations/0018_alter_rulecheckedobjectrelationship_unique_together.py +39 -0
  37. wbcompliance/migrations/0019_rulegroup_riskrule_activation_date_and_more.py +60 -0
  38. wbcompliance/migrations/__init__.py +0 -0
  39. wbcompliance/models/__init__.py +20 -0
  40. wbcompliance/models/compliance_form.py +626 -0
  41. wbcompliance/models/compliance_task.py +800 -0
  42. wbcompliance/models/compliance_type.py +133 -0
  43. wbcompliance/models/enums.py +13 -0
  44. wbcompliance/models/risk_management/__init__.py +4 -0
  45. wbcompliance/models/risk_management/backend.py +139 -0
  46. wbcompliance/models/risk_management/checks.py +194 -0
  47. wbcompliance/models/risk_management/dispatch.py +41 -0
  48. wbcompliance/models/risk_management/incidents.py +619 -0
  49. wbcompliance/models/risk_management/mixins.py +115 -0
  50. wbcompliance/models/risk_management/rules.py +654 -0
  51. wbcompliance/permissions.py +32 -0
  52. wbcompliance/serializers/__init__.py +30 -0
  53. wbcompliance/serializers/compliance_form.py +320 -0
  54. wbcompliance/serializers/compliance_task.py +463 -0
  55. wbcompliance/serializers/compliance_type.py +26 -0
  56. wbcompliance/serializers/risk_management/__init__.py +19 -0
  57. wbcompliance/serializers/risk_management/checks.py +53 -0
  58. wbcompliance/serializers/risk_management/incidents.py +227 -0
  59. wbcompliance/serializers/risk_management/rules.py +158 -0
  60. wbcompliance/tasks.py +112 -0
  61. wbcompliance/tests/__init__.py +0 -0
  62. wbcompliance/tests/conftest.py +63 -0
  63. wbcompliance/tests/disable_signals.py +82 -0
  64. wbcompliance/tests/mixins.py +17 -0
  65. wbcompliance/tests/risk_management/__init__.py +0 -0
  66. wbcompliance/tests/risk_management/models/__init__.py +0 -0
  67. wbcompliance/tests/risk_management/models/test_backends.py +0 -0
  68. wbcompliance/tests/risk_management/models/test_checks.py +55 -0
  69. wbcompliance/tests/risk_management/models/test_incidents.py +327 -0
  70. wbcompliance/tests/risk_management/models/test_rules.py +255 -0
  71. wbcompliance/tests/signals.py +89 -0
  72. wbcompliance/tests/test_filters.py +23 -0
  73. wbcompliance/tests/test_models.py +57 -0
  74. wbcompliance/tests/test_serializers.py +48 -0
  75. wbcompliance/tests/test_views.py +377 -0
  76. wbcompliance/tests/tests.py +21 -0
  77. wbcompliance/urls.py +238 -0
  78. wbcompliance/viewsets/__init__.py +40 -0
  79. wbcompliance/viewsets/buttons/__init__.py +9 -0
  80. wbcompliance/viewsets/buttons/compliance_form.py +78 -0
  81. wbcompliance/viewsets/buttons/compliance_task.py +149 -0
  82. wbcompliance/viewsets/buttons/risk_managment/__init__.py +3 -0
  83. wbcompliance/viewsets/buttons/risk_managment/checks.py +11 -0
  84. wbcompliance/viewsets/buttons/risk_managment/incidents.py +51 -0
  85. wbcompliance/viewsets/buttons/risk_managment/rules.py +35 -0
  86. wbcompliance/viewsets/compliance_form.py +425 -0
  87. wbcompliance/viewsets/compliance_task.py +513 -0
  88. wbcompliance/viewsets/compliance_type.py +38 -0
  89. wbcompliance/viewsets/display/__init__.py +22 -0
  90. wbcompliance/viewsets/display/compliance_form.py +317 -0
  91. wbcompliance/viewsets/display/compliance_task.py +453 -0
  92. wbcompliance/viewsets/display/compliance_type.py +22 -0
  93. wbcompliance/viewsets/display/risk_managment/__init__.py +11 -0
  94. wbcompliance/viewsets/display/risk_managment/checks.py +46 -0
  95. wbcompliance/viewsets/display/risk_managment/incidents.py +155 -0
  96. wbcompliance/viewsets/display/risk_managment/rules.py +146 -0
  97. wbcompliance/viewsets/display/risk_managment/tables.py +51 -0
  98. wbcompliance/viewsets/endpoints/__init__.py +27 -0
  99. wbcompliance/viewsets/endpoints/compliance_form.py +207 -0
  100. wbcompliance/viewsets/endpoints/compliance_task.py +193 -0
  101. wbcompliance/viewsets/endpoints/compliance_type.py +9 -0
  102. wbcompliance/viewsets/endpoints/risk_managment/__init__.py +12 -0
  103. wbcompliance/viewsets/endpoints/risk_managment/checks.py +16 -0
  104. wbcompliance/viewsets/endpoints/risk_managment/incidents.py +36 -0
  105. wbcompliance/viewsets/endpoints/risk_managment/rules.py +32 -0
  106. wbcompliance/viewsets/endpoints/risk_managment/tables.py +14 -0
  107. wbcompliance/viewsets/menu/__init__.py +17 -0
  108. wbcompliance/viewsets/menu/compliance_form.py +49 -0
  109. wbcompliance/viewsets/menu/compliance_task.py +130 -0
  110. wbcompliance/viewsets/menu/compliance_type.py +17 -0
  111. wbcompliance/viewsets/menu/risk_management.py +56 -0
  112. wbcompliance/viewsets/risk_management/__init__.py +21 -0
  113. wbcompliance/viewsets/risk_management/checks.py +49 -0
  114. wbcompliance/viewsets/risk_management/incidents.py +204 -0
  115. wbcompliance/viewsets/risk_management/mixins.py +52 -0
  116. wbcompliance/viewsets/risk_management/rules.py +179 -0
  117. wbcompliance/viewsets/risk_management/tables.py +96 -0
  118. wbcompliance/viewsets/titles/__init__.py +17 -0
  119. wbcompliance/viewsets/titles/compliance_form.py +101 -0
  120. wbcompliance/viewsets/titles/compliance_task.py +60 -0
  121. wbcompliance/viewsets/titles/compliance_type.py +13 -0
  122. wbcompliance/viewsets/titles/risk_managment/__init__.py +1 -0
  123. wbcompliance/viewsets/titles/risk_managment/checks.py +0 -0
  124. wbcompliance/viewsets/titles/risk_managment/incidents.py +0 -0
  125. wbcompliance/viewsets/titles/risk_managment/rules.py +0 -0
  126. wbcompliance/viewsets/titles/risk_managment/tables.py +7 -0
  127. wbcompliance-2.2.1.dist-info/METADATA +7 -0
  128. wbcompliance-2.2.1.dist-info/RECORD +129 -0
  129. 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 *