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,115 @@
|
|
|
1
|
+
from datetime import date
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from django.contrib.contenttypes.models import ContentType
|
|
5
|
+
from django.db import models, transaction
|
|
6
|
+
from django.utils.functional import cached_property
|
|
7
|
+
|
|
8
|
+
from .checks import RiskCheck, evaluate_as_task
|
|
9
|
+
from .rules import RiskRule, RuleCheckedObjectRelationship
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class RiskCheckMixin(models.Model):
|
|
13
|
+
"""
|
|
14
|
+
A utility mixin to inherit from when a model proposes a risk check workflow on one of its field
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
id: int
|
|
18
|
+
|
|
19
|
+
def _get_checked_object_field_name(self) -> str:
|
|
20
|
+
"""
|
|
21
|
+
Return the object representing the checked object
|
|
22
|
+
Returns NotImplementedError by default
|
|
23
|
+
"""
|
|
24
|
+
raise NotImplementedError()
|
|
25
|
+
|
|
26
|
+
@cached_property
|
|
27
|
+
def content_type(self) -> ContentType:
|
|
28
|
+
return ContentType.objects.get_for_model(self)
|
|
29
|
+
|
|
30
|
+
@cached_property
|
|
31
|
+
def checked_object(self) -> Any:
|
|
32
|
+
return getattr(self, self._get_checked_object_field_name())
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def checks(self) -> models.QuerySet[RiskCheck]:
|
|
36
|
+
"""
|
|
37
|
+
Returned the check triggered by this object (self)
|
|
38
|
+
Returns: A queryset of RiskCheck
|
|
39
|
+
"""
|
|
40
|
+
return RiskCheck.objects.filter(trigger_content_type=self.content_type, trigger_id=self.id)
|
|
41
|
+
|
|
42
|
+
@cached_property
|
|
43
|
+
def has_assigned_active_rules(self) -> bool:
|
|
44
|
+
"""
|
|
45
|
+
Return True if an enabled and active rule is available for the assigned checked object
|
|
46
|
+
"""
|
|
47
|
+
relationships = RuleCheckedObjectRelationship.objects.get_for_object(
|
|
48
|
+
self.checked_object, rule__is_enable=True, rule__only_passive_check_allowed=False
|
|
49
|
+
)
|
|
50
|
+
return RiskRule.objects.filter(id__in=relationships.distinct("rule").values("rule")).exists()
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def has_all_check_completed_and_succeed(self) -> bool:
|
|
54
|
+
"""
|
|
55
|
+
Return True if checks are available and they all succeed
|
|
56
|
+
"""
|
|
57
|
+
return (
|
|
58
|
+
self.checks.exists()
|
|
59
|
+
and not self.checks.exclude(
|
|
60
|
+
status__in=[RiskCheck.CheckStatus.SUCCESS, RiskCheck.CheckStatus.WARNING]
|
|
61
|
+
).exists()
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def has_all_check_completed(self) -> bool:
|
|
66
|
+
"""
|
|
67
|
+
Return True if checks are available and they all succeed
|
|
68
|
+
"""
|
|
69
|
+
return (
|
|
70
|
+
self.checks.exists()
|
|
71
|
+
and not self.checks.filter(
|
|
72
|
+
status__in=[RiskCheck.CheckStatus.RUNNING, RiskCheck.CheckStatus.PENDING]
|
|
73
|
+
).exists()
|
|
74
|
+
) or not self.checks.exists()
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def has_no_rule_or_all_checked_succeed(self) -> bool:
|
|
78
|
+
return (
|
|
79
|
+
self.has_assigned_active_rules and self.has_all_check_completed_and_succeed
|
|
80
|
+
) or not self.has_assigned_active_rules
|
|
81
|
+
|
|
82
|
+
def get_worst_check_status(self) -> RiskCheck.CheckStatus:
|
|
83
|
+
status_ordered = [
|
|
84
|
+
RiskCheck.CheckStatus.FAILED,
|
|
85
|
+
RiskCheck.CheckStatus.WARNING,
|
|
86
|
+
RiskCheck.CheckStatus.RUNNING,
|
|
87
|
+
RiskCheck.CheckStatus.PENDING,
|
|
88
|
+
]
|
|
89
|
+
for status in status_ordered:
|
|
90
|
+
if self.checks.filter(status=status).exists():
|
|
91
|
+
return status
|
|
92
|
+
return RiskCheck.CheckStatus.SUCCESS
|
|
93
|
+
|
|
94
|
+
def evaluate_active_rules(self, evaluation_date: date, *dto, asynchronously: bool = True):
|
|
95
|
+
for rel in RuleCheckedObjectRelationship.objects.get_for_object(
|
|
96
|
+
self.checked_object, rule__is_enable=True, rule__only_passive_check_allowed=False
|
|
97
|
+
):
|
|
98
|
+
check = RiskCheck.objects.update_or_create(
|
|
99
|
+
rule_checked_object_relationship=rel,
|
|
100
|
+
evaluation_date=evaluation_date,
|
|
101
|
+
trigger_content_type=self.content_type,
|
|
102
|
+
trigger_id=self.id,
|
|
103
|
+
defaults={"status": RiskCheck.CheckStatus.PENDING},
|
|
104
|
+
)[0]
|
|
105
|
+
if asynchronously:
|
|
106
|
+
transaction.on_commit(
|
|
107
|
+
lambda: evaluate_as_task.delay(
|
|
108
|
+
check.id, *dto, override_incident=True, ignore_informational_threshold=True
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
else:
|
|
112
|
+
check.evaluate(*dto, override_incident=True, ignore_informational_threshold=True)
|
|
113
|
+
|
|
114
|
+
class Meta:
|
|
115
|
+
abstract = True
|