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,425 @@
|
|
|
1
|
+
from django.contrib.auth import get_user_model
|
|
2
|
+
from django.contrib.contenttypes.models import ContentType
|
|
3
|
+
from django.db.models import (
|
|
4
|
+
BooleanField,
|
|
5
|
+
Case,
|
|
6
|
+
CharField,
|
|
7
|
+
ExpressionWrapper,
|
|
8
|
+
F,
|
|
9
|
+
Q,
|
|
10
|
+
Value,
|
|
11
|
+
When,
|
|
12
|
+
)
|
|
13
|
+
from django.db.models.functions import Concat
|
|
14
|
+
from django.shortcuts import get_object_or_404
|
|
15
|
+
from django.utils import timezone
|
|
16
|
+
from django.utils.functional import cached_property
|
|
17
|
+
from django.utils.translation import gettext as _
|
|
18
|
+
from rest_framework import filters, permissions, status
|
|
19
|
+
from rest_framework.decorators import action
|
|
20
|
+
from rest_framework.response import Response
|
|
21
|
+
from reversion.views import RevisionMixin
|
|
22
|
+
from wbcompliance.filters import ComplianceFormFilter, ComplianceFormSignatureFilter
|
|
23
|
+
from wbcompliance.models import (
|
|
24
|
+
ComplianceForm,
|
|
25
|
+
ComplianceFormRule,
|
|
26
|
+
ComplianceFormSection,
|
|
27
|
+
ComplianceFormSignature,
|
|
28
|
+
ComplianceFormSignatureRule,
|
|
29
|
+
ComplianceFormSignatureSection,
|
|
30
|
+
ComplianceFormType,
|
|
31
|
+
update_or_create_compliance_document,
|
|
32
|
+
)
|
|
33
|
+
from wbcompliance.serializers import (
|
|
34
|
+
ComplianceFormModelSerializer,
|
|
35
|
+
ComplianceFormRepresentationSerializer,
|
|
36
|
+
ComplianceFormRuleModelSerializer,
|
|
37
|
+
ComplianceFormSectionModelSerializer,
|
|
38
|
+
ComplianceFormSectionRepresentationSerializer,
|
|
39
|
+
ComplianceFormSignatureModelSerializer,
|
|
40
|
+
ComplianceFormSignatureRuleModelSerializer,
|
|
41
|
+
ComplianceFormSignatureSectionRepresentationSerializer,
|
|
42
|
+
ComplianceFormTypeModelSerializer,
|
|
43
|
+
ComplianceFormTypeRepresentationSerializer,
|
|
44
|
+
)
|
|
45
|
+
from wbcore import viewsets
|
|
46
|
+
from wbcore.contrib.authentication.authentication import JWTCookieAuthentication
|
|
47
|
+
from wbcore.contrib.notifications.dispatch import send_notification
|
|
48
|
+
from wbcore.filters import DjangoFilterBackend
|
|
49
|
+
|
|
50
|
+
from .buttons import ComplianceFormButtonConfig, ComplianceFormSignatureButtonConfig
|
|
51
|
+
from .compliance_type import ComplianceType
|
|
52
|
+
from .display import (
|
|
53
|
+
ComplianceFormDisplayConfig,
|
|
54
|
+
ComplianceFormRuleDisplayConfig,
|
|
55
|
+
ComplianceFormSectionDisplayConfig,
|
|
56
|
+
ComplianceFormSignatureDisplayConfig,
|
|
57
|
+
ComplianceFormSignatureSectionRuleDisplayConfig,
|
|
58
|
+
ComplianceFormTypeDisplayConfig,
|
|
59
|
+
)
|
|
60
|
+
from .endpoints import (
|
|
61
|
+
CFComplianceFormSectionEndpointConfig,
|
|
62
|
+
CFComplianceFormSignatureEndpointConfig,
|
|
63
|
+
ComplianceFormEndpointConfig,
|
|
64
|
+
ComplianceFormRuleEndpointConfig,
|
|
65
|
+
ComplianceFormSectionRuleEndpointConfig,
|
|
66
|
+
ComplianceFormSignatureEndpointConfig,
|
|
67
|
+
ComplianceFormSignatureSectionRuleEndpointConfig,
|
|
68
|
+
ComplianceFormTypeEndpointConfig,
|
|
69
|
+
)
|
|
70
|
+
from .titles import (
|
|
71
|
+
ComplianceFormSectionRuleTitleConfig,
|
|
72
|
+
ComplianceFormSectionTitleConfig,
|
|
73
|
+
ComplianceFormSignatureSectionRuleTitleConfig,
|
|
74
|
+
ComplianceFormSignatureTitleConfig,
|
|
75
|
+
ComplianceFormTitleConfig,
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
User = get_user_model()
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class ComplianceFormRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
82
|
+
IDENTIFIER = "wbcompliance:complianceformrepresentation"
|
|
83
|
+
|
|
84
|
+
queryset = ComplianceForm.objects.all()
|
|
85
|
+
serializer_class = ComplianceFormRepresentationSerializer
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class ComplianceFormSectionRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
89
|
+
IDENTIFIER = "wbcompliance:complianceformsectionrepresentation"
|
|
90
|
+
|
|
91
|
+
queryset = ComplianceFormSection.objects.all()
|
|
92
|
+
serializer_class = ComplianceFormSectionRepresentationSerializer
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class ComplianceFormSignatureSectionRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
96
|
+
IDENTIFIER = "wbcompliance:complianceformsignaturesectionrepresentation"
|
|
97
|
+
|
|
98
|
+
queryset = ComplianceFormSignatureSection.objects.all()
|
|
99
|
+
serializer_class = ComplianceFormSignatureSectionRepresentationSerializer
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
# TYPE OF THE COMPLIANCE FORM
|
|
103
|
+
class ComplianceFormTypeRepresentationViewSet(viewsets.RepresentationViewSet):
|
|
104
|
+
IDENTIFIER = "wbcompliance:complianceformtyperepresentation"
|
|
105
|
+
queryset = ComplianceFormType.objects.all()
|
|
106
|
+
serializer_class = ComplianceFormTypeRepresentationSerializer
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class ComplianceFormTypeViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
110
|
+
endpoint_config_class = ComplianceFormTypeEndpointConfig
|
|
111
|
+
display_config_class = ComplianceFormTypeDisplayConfig
|
|
112
|
+
|
|
113
|
+
ordering_fields = ["name"]
|
|
114
|
+
|
|
115
|
+
serializer_class = ComplianceFormTypeModelSerializer
|
|
116
|
+
queryset = ComplianceFormType.objects.all()
|
|
117
|
+
|
|
118
|
+
def get_queryset(self):
|
|
119
|
+
if ComplianceType.is_administrator(self.request.user):
|
|
120
|
+
return super().get_queryset()
|
|
121
|
+
return ComplianceFormType.objects.none()
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
# SECTION OF THE COMPLIANCE FORM
|
|
125
|
+
class ComplianceFormSectionViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
126
|
+
title_config_class = ComplianceFormSectionTitleConfig
|
|
127
|
+
display_config_class = ComplianceFormSectionDisplayConfig
|
|
128
|
+
|
|
129
|
+
search_fields = ["name"]
|
|
130
|
+
ordering_fields = ["name"]
|
|
131
|
+
queryset = ComplianceFormSection.objects.all()
|
|
132
|
+
serializer_class = ComplianceFormSectionModelSerializer
|
|
133
|
+
|
|
134
|
+
def get_queryset(self):
|
|
135
|
+
if ComplianceType.is_administrator(self.request.user):
|
|
136
|
+
return ComplianceFormSection.objects.select_related("compliance_form")
|
|
137
|
+
return ComplianceFormSection.objects.none()
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
class ComplianceFormSectionComplianceFormViewSet(ComplianceFormSectionViewSet):
|
|
141
|
+
endpoint_config_class = CFComplianceFormSectionEndpointConfig
|
|
142
|
+
|
|
143
|
+
def get_queryset(self):
|
|
144
|
+
return super().get_queryset().filter(compliance_form__id=self.kwargs["compliance_form_id"])
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
# RULES
|
|
148
|
+
class ComplianceFormRuleViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
149
|
+
IDENTIFIER = "wbcompliance:complianceformrule"
|
|
150
|
+
display_config_class = ComplianceFormRuleDisplayConfig
|
|
151
|
+
endpoint_config_class = ComplianceFormRuleEndpointConfig
|
|
152
|
+
|
|
153
|
+
filter_backends = (
|
|
154
|
+
DjangoFilterBackend,
|
|
155
|
+
filters.OrderingFilter,
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
serializer_class = ComplianceFormRuleModelSerializer
|
|
159
|
+
|
|
160
|
+
queryset = ComplianceFormRule.objects.select_related("section")
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
# RULES OF THE SECTION OF THE COMPLIANCE FORM
|
|
164
|
+
class ComplianceFormSectionRuleViewSet(ComplianceFormRuleViewSet):
|
|
165
|
+
IDENTIFIER = "wbcompliance:complianceformsection-rules"
|
|
166
|
+
title_config_class = ComplianceFormSectionRuleTitleConfig
|
|
167
|
+
endpoint_config_class = ComplianceFormSectionRuleEndpointConfig
|
|
168
|
+
|
|
169
|
+
def get_queryset(self):
|
|
170
|
+
if ComplianceType.is_administrator(self.request.user):
|
|
171
|
+
return super().get_queryset().filter(section__id=self.kwargs["section_id"])
|
|
172
|
+
return ComplianceFormRule.objects.none()
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
# RULES OF THE SECTION OF THE COMPLIANCE FORM SIGNATURE
|
|
176
|
+
class ComplianceFormSignatureSectionRuleViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
177
|
+
IDENTIFIER = "wbcompliance:complianceformsignaturesection-signaturerules"
|
|
178
|
+
title_config_class = ComplianceFormSignatureSectionRuleTitleConfig
|
|
179
|
+
display_config_class = ComplianceFormSignatureSectionRuleDisplayConfig
|
|
180
|
+
endpoint_config_class = ComplianceFormSignatureSectionRuleEndpointConfig
|
|
181
|
+
|
|
182
|
+
serializer_class = ComplianceFormSignatureRuleModelSerializer
|
|
183
|
+
|
|
184
|
+
queryset = ComplianceFormSignatureRule.objects.all()
|
|
185
|
+
|
|
186
|
+
def get_queryset(self):
|
|
187
|
+
return (
|
|
188
|
+
super()
|
|
189
|
+
.get_queryset()
|
|
190
|
+
.filter(section__id=self.kwargs["section_id"])
|
|
191
|
+
.annotate(
|
|
192
|
+
expected_result=ComplianceFormSignatureRule.get_subquery_expected_ticked(),
|
|
193
|
+
same_answer=ExpressionWrapper(
|
|
194
|
+
Q(ticked__exact=F("expected_result")),
|
|
195
|
+
output_field=BooleanField(),
|
|
196
|
+
),
|
|
197
|
+
)
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
# COMPLIANCE FORM
|
|
202
|
+
class ComplianceFormModelViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
203
|
+
IDENTIFIER = "wbcompliance:complianceform"
|
|
204
|
+
|
|
205
|
+
ordering_fields = [
|
|
206
|
+
"title",
|
|
207
|
+
"status",
|
|
208
|
+
"creator",
|
|
209
|
+
"changer",
|
|
210
|
+
"changed",
|
|
211
|
+
"start",
|
|
212
|
+
"end",
|
|
213
|
+
"version",
|
|
214
|
+
"form_type",
|
|
215
|
+
"compliance_type",
|
|
216
|
+
]
|
|
217
|
+
ordering = ["-changed", "-created"]
|
|
218
|
+
search_fields = ["title"]
|
|
219
|
+
|
|
220
|
+
filterset_class = ComplianceFormFilter
|
|
221
|
+
|
|
222
|
+
display_config_class = ComplianceFormDisplayConfig
|
|
223
|
+
title_config_class = ComplianceFormTitleConfig
|
|
224
|
+
button_config_class = ComplianceFormButtonConfig
|
|
225
|
+
endpoint_config_class = ComplianceFormEndpointConfig
|
|
226
|
+
|
|
227
|
+
serializer_class = ComplianceFormModelSerializer
|
|
228
|
+
queryset = ComplianceForm.objects.select_related(
|
|
229
|
+
"creator",
|
|
230
|
+
"changer",
|
|
231
|
+
"form_type",
|
|
232
|
+
"compliance_type",
|
|
233
|
+
).prefetch_related("assigned_to")
|
|
234
|
+
|
|
235
|
+
@cached_property
|
|
236
|
+
def user_has_compliance_admin_permission(self):
|
|
237
|
+
return self.request.user.has_perm("wbcompliance.administrate_compliance")
|
|
238
|
+
|
|
239
|
+
def get_queryset(self):
|
|
240
|
+
if ComplianceType.is_administrator(self.request.user):
|
|
241
|
+
qs = super().get_queryset()
|
|
242
|
+
qs = qs.annotate(
|
|
243
|
+
# is_signed = ComplianceForm.get_subquery_compliance_form_signature(self.request.user.profile),
|
|
244
|
+
total_compliance_form_signature=ComplianceForm.get_subquery_total_compliance_form_signature(),
|
|
245
|
+
total_signed=F("total_compliance_form_signature")
|
|
246
|
+
- ComplianceForm.get_subquery_total_compliance_form_signature(remaining_signed=True),
|
|
247
|
+
current_signed=ExpressionWrapper(
|
|
248
|
+
Concat(
|
|
249
|
+
Value(" ("), F("total_signed"), Value("/"), F("total_compliance_form_signature"), Value(")")
|
|
250
|
+
),
|
|
251
|
+
output_field=CharField(),
|
|
252
|
+
),
|
|
253
|
+
is_signed=Case(
|
|
254
|
+
When(total_compliance_form_signature=F("total_signed"), then=Value(True)),
|
|
255
|
+
default=Value(False),
|
|
256
|
+
output_field=BooleanField(),
|
|
257
|
+
),
|
|
258
|
+
)
|
|
259
|
+
else:
|
|
260
|
+
qs = super().get_queryset().filter(status=ComplianceForm.Status.ACTIVE)
|
|
261
|
+
qs = qs.annotate(
|
|
262
|
+
is_signed=ComplianceForm.get_subquery_compliance_form_signature(self.request.user.profile),
|
|
263
|
+
).filter(is_signed__isnull=False)
|
|
264
|
+
return qs
|
|
265
|
+
|
|
266
|
+
@action(detail=True, methods=["PATCH"], permission_classes=[permissions.IsAuthenticated])
|
|
267
|
+
def sendcomplianceformnotification(self, request, pk=None):
|
|
268
|
+
compliance_form = ComplianceForm.objects.get(pk=pk)
|
|
269
|
+
person_ids = ComplianceFormSignature.objects.filter(
|
|
270
|
+
compliance_form=compliance_form, version=compliance_form.version, signed=None
|
|
271
|
+
).values_list("person", flat=True)
|
|
272
|
+
|
|
273
|
+
if person_ids:
|
|
274
|
+
msg = _("<p>{} has activated a {} {} version {} </p>").format(
|
|
275
|
+
str(compliance_form.creator), compliance_form.title, compliance_form.form_type, compliance_form.version
|
|
276
|
+
)
|
|
277
|
+
if compliance_form.policy and compliance_form.policy != "<p></p>" and compliance_form.policy != "null":
|
|
278
|
+
msg += _("</br><p><b>User's ComplianceForm:</b></p><i>{}</i>").format(compliance_form.policy)
|
|
279
|
+
title = _("Unsigned Compliance Form - {} Reminder : {} ").format(
|
|
280
|
+
compliance_form.form_type, compliance_form.title
|
|
281
|
+
)
|
|
282
|
+
compliance_form.notify(title, msg, recipients=User.objects.filter(profile__id__in=person_ids))
|
|
283
|
+
|
|
284
|
+
return Response(
|
|
285
|
+
{
|
|
286
|
+
"__notification": {
|
|
287
|
+
"compliance_form": compliance_form.id,
|
|
288
|
+
"status": "Compliance Form notification sent",
|
|
289
|
+
"person_signed": person_ids,
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
status=status.HTTP_200_OK,
|
|
293
|
+
)
|
|
294
|
+
return Response(
|
|
295
|
+
{
|
|
296
|
+
"__notification": {
|
|
297
|
+
"compliance_form": compliance_form.id,
|
|
298
|
+
"status": "Compliance Form notification not sent",
|
|
299
|
+
"person_signed": None,
|
|
300
|
+
}
|
|
301
|
+
},
|
|
302
|
+
status=status.HTTP_400_BAD_REQUEST,
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
@action(detail=True, methods=["PATCH"], authentication_classes=[JWTCookieAuthentication])
|
|
306
|
+
def regenerate_document(self, request, pk):
|
|
307
|
+
if not request.user.has_perm("wbcompliance.administrate_compliance"):
|
|
308
|
+
return Response(status=status.HTTP_403_FORBIDDEN)
|
|
309
|
+
content_type = ContentType.objects.get_for_model(ComplianceForm)
|
|
310
|
+
send_email = request.POST.get("send_email", "false") == "true"
|
|
311
|
+
update_or_create_compliance_document.delay(request.user.id, content_type.id, pk, send_email=send_email)
|
|
312
|
+
|
|
313
|
+
return Response(
|
|
314
|
+
{"__notification": {"title": "PDF is going to be created and sent to you."}},
|
|
315
|
+
status=status.HTTP_200_OK,
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
# COMPLIANCE FORM SIGNATURE
|
|
320
|
+
class ComplianceFormSignatureModelViewSet(RevisionMixin, viewsets.ModelViewSet):
|
|
321
|
+
IDENTIFIER = "wbcompliance:complianceformsignature"
|
|
322
|
+
display_config_class = ComplianceFormSignatureDisplayConfig
|
|
323
|
+
title_config_class = ComplianceFormSignatureTitleConfig
|
|
324
|
+
button_config_class = ComplianceFormSignatureButtonConfig
|
|
325
|
+
endpoint_config_class = ComplianceFormSignatureEndpointConfig
|
|
326
|
+
|
|
327
|
+
search_fields = ["compliance_form__title"]
|
|
328
|
+
|
|
329
|
+
ordering_fields = ["version", "signed", "start", "end", "person"]
|
|
330
|
+
ordering = ["-version", "-signed"]
|
|
331
|
+
|
|
332
|
+
filterset_class = ComplianceFormSignatureFilter
|
|
333
|
+
|
|
334
|
+
serializer_class = ComplianceFormSignatureModelSerializer
|
|
335
|
+
queryset = ComplianceFormSignature.objects.select_related("compliance_form", "person")
|
|
336
|
+
|
|
337
|
+
def get_queryset(self):
|
|
338
|
+
if ComplianceType.is_administrator(self.request.user):
|
|
339
|
+
qs = super().get_queryset()
|
|
340
|
+
else:
|
|
341
|
+
qs = super().get_queryset().filter(person=self.request.user.profile)
|
|
342
|
+
return qs.annotate(
|
|
343
|
+
is_signed=Case(
|
|
344
|
+
When(signed=None, then=Value(False)),
|
|
345
|
+
default=Value(True),
|
|
346
|
+
output_field=BooleanField(),
|
|
347
|
+
)
|
|
348
|
+
)
|
|
349
|
+
|
|
350
|
+
@action(detail=True, methods=["PATCH"], permission_classes=[permissions.IsAuthenticated])
|
|
351
|
+
def signature(self, request, pk=None):
|
|
352
|
+
compliance_form_signature = get_object_or_404(ComplianceFormSignature, pk=pk)
|
|
353
|
+
if request.user.profile != compliance_form_signature.person:
|
|
354
|
+
return Response(status=status.HTTP_403_FORBIDDEN)
|
|
355
|
+
compliance_form_signature.signed = timezone.now()
|
|
356
|
+
compliance_form_signature.remark = request.POST.get("remark")
|
|
357
|
+
compliance_form_signature.save()
|
|
358
|
+
|
|
359
|
+
ComplianceFormSignature.objects.filter(
|
|
360
|
+
Q(compliance_form=compliance_form_signature.compliance_form)
|
|
361
|
+
& Q(version__lt=compliance_form_signature.version)
|
|
362
|
+
& Q(signed__isnull=True)
|
|
363
|
+
& Q(person=request.user.profile)
|
|
364
|
+
).update(signed=timezone.now())
|
|
365
|
+
|
|
366
|
+
if hasattr(compliance_form_signature.person, "user_account"):
|
|
367
|
+
msg = _("<p><b>{}</b> {} version <b>{} </b> has been signed</p>").format(
|
|
368
|
+
compliance_form_signature.compliance_form.title,
|
|
369
|
+
compliance_form_signature.compliance_form.form_type,
|
|
370
|
+
compliance_form_signature.version,
|
|
371
|
+
)
|
|
372
|
+
if (
|
|
373
|
+
compliance_form_signature.policy
|
|
374
|
+
and compliance_form_signature.policy != "<p></p>"
|
|
375
|
+
and compliance_form_signature.policy != "null"
|
|
376
|
+
):
|
|
377
|
+
msg += _("</br><p><b>{}:</b></p> <i>{}</i>").format(
|
|
378
|
+
compliance_form_signature.compliance_form.form_type, compliance_form_signature.policy
|
|
379
|
+
)
|
|
380
|
+
send_notification(
|
|
381
|
+
code="wbcompliance.complianceformsignature.signed",
|
|
382
|
+
title=_("Confirmation : {} {} version {} has been signed").format(
|
|
383
|
+
compliance_form_signature.compliance_form.title,
|
|
384
|
+
compliance_form_signature.compliance_form.form_type,
|
|
385
|
+
compliance_form_signature.version,
|
|
386
|
+
),
|
|
387
|
+
body=msg,
|
|
388
|
+
user=compliance_form_signature.person.user_account,
|
|
389
|
+
reverse_name="wbcompliance:complianceformsignature-detail",
|
|
390
|
+
reverse_args=[compliance_form_signature.id],
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
return Response(
|
|
394
|
+
{
|
|
395
|
+
"__notification": {
|
|
396
|
+
str(compliance_form_signature.signed): "Compliance Form signed",
|
|
397
|
+
"person_signed": compliance_form_signature.person.id,
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
status=status.HTTP_200_OK,
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
@action(detail=True, methods=["PATCH"], authentication_classes=[JWTCookieAuthentication])
|
|
404
|
+
def regenerate_document(self, request, pk):
|
|
405
|
+
compliance_form_signature = get_object_or_404(ComplianceFormSignature, pk=pk)
|
|
406
|
+
if (
|
|
407
|
+
not request.user.has_perm("wbcompliance.administrate_compliance")
|
|
408
|
+
and request.user.profile != compliance_form_signature.person
|
|
409
|
+
):
|
|
410
|
+
return Response(status=status.HTTP_403_FORBIDDEN)
|
|
411
|
+
content_type = ContentType.objects.get_for_model(ComplianceFormSignature)
|
|
412
|
+
send_email = request.POST.get("send_email", "false") == "true"
|
|
413
|
+
update_or_create_compliance_document.delay(request.user.id, content_type.id, pk, send_email=send_email)
|
|
414
|
+
|
|
415
|
+
return Response(
|
|
416
|
+
{"__notification": {"title": "PDF is going to be created and sent to you."}},
|
|
417
|
+
status=status.HTTP_200_OK,
|
|
418
|
+
)
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
class CFComplianceFormSignatureModelViewSet(ComplianceFormSignatureModelViewSet):
|
|
422
|
+
endpoint_config_class = CFComplianceFormSignatureEndpointConfig
|
|
423
|
+
|
|
424
|
+
def get_queryset(self):
|
|
425
|
+
return super().get_queryset().filter(compliance_form__id=self.kwargs["compliance_form_id"])
|