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,12 @@
1
+ from .checks import RiskCheckFactory
2
+ from .incidents import (
3
+ CheckedObjectIncidentRelationshipFactory,
4
+ RiskIncidentFactory,
5
+ RiskIncidentTypeFactory,
6
+ )
7
+ from .rules import (
8
+ RiskRuleFactory,
9
+ RuleBackendFactory,
10
+ RuleCheckedObjectRelationshipFactory,
11
+ RuleThresholdFactory,
12
+ )
@@ -0,0 +1,42 @@
1
+ from typing import Generator
2
+
3
+ from django.contrib.auth import get_user_model
4
+ from django.contrib.contenttypes.models import ContentType
5
+ from faker import Faker
6
+ from wbcompliance.models.risk_management import backend
7
+ from wbcore import serializers as wb_serializers
8
+
9
+ User = get_user_model()
10
+ fake = Faker()
11
+
12
+
13
+ class RuleBackend(backend.AbstractRuleBackend):
14
+ @classmethod
15
+ def get_serializer_class(cls):
16
+ class RuleBackendSerializer(wb_serializers.Serializer):
17
+ date = wb_serializers.DateField(required=False)
18
+ name = wb_serializers.CharField(required=False)
19
+ int = wb_serializers.IntegerField(required=False)
20
+ anonymous_user = wb_serializers.PrimaryKeyRelatedField(
21
+ queryset=User.objects.all(), default=User.objects.none(), required=False
22
+ )
23
+
24
+ @classmethod
25
+ def get_parameter_fields(cls):
26
+ return ["date", "name", "int", "anonymous_user"]
27
+
28
+ return RuleBackendSerializer
29
+
30
+ def check_rule(self, *dto_args, **kwargs) -> Generator[backend.IncidentResult, None, None]:
31
+ severity = self.thresholds.first().severity if self.thresholds.exists() else None
32
+ yield backend.IncidentResult(
33
+ breached_object=None,
34
+ breached_value=str(fake.word()),
35
+ breached_object_repr=fake.text(max_nb_chars=125),
36
+ report_details={"label": fake.paragraph()},
37
+ severity=severity,
38
+ )
39
+
40
+ @classmethod
41
+ def get_allowed_content_type(cls) -> "ContentType":
42
+ return None
@@ -0,0 +1,12 @@
1
+ import factory
2
+ from wbcompliance.models.risk_management.checks import RiskCheck
3
+
4
+
5
+ class RiskCheckFactory(factory.django.DjangoModelFactory):
6
+ rule_checked_object_relationship = factory.SubFactory(
7
+ "wbcompliance.factories.risk_management.rules.RuleCheckedObjectRelationshipFactory"
8
+ )
9
+ evaluation_date = factory.Faker("date_object")
10
+
11
+ class Meta:
12
+ model = RiskCheck
@@ -0,0 +1,84 @@
1
+ from datetime import timedelta
2
+
3
+ import factory
4
+ from faker import Faker
5
+ from psycopg.types.range import DateRange
6
+ from wbcompliance.models.risk_management import (
7
+ CheckedObjectIncidentRelationship,
8
+ RiskIncident,
9
+ RiskIncidentType,
10
+ )
11
+
12
+ from .checks import RiskCheckFactory
13
+ from .rules import RuleCheckedObjectRelationshipFactory
14
+
15
+ fake = Faker()
16
+
17
+
18
+ def _generate_date_range():
19
+ d1 = fake.date_object()
20
+ return DateRange(lower=d1, upper=d1 + timedelta(days=fake.pyint(min_value=1, max_value=100)))
21
+
22
+
23
+ def _extract_date_range_from_incident(incident):
24
+ return fake.date_between_dates(incident.date_range.lower, incident.date_range.upper)
25
+
26
+
27
+ class RiskIncidentMixinFactory:
28
+ status = RiskIncident.Status.OPEN.value
29
+ comment = factory.Faker("paragraph")
30
+ resolved_by = factory.SubFactory("wbcore.contrib.authentication.factories.AuthenticatedPersonFactory")
31
+
32
+
33
+ def get_severity_order(o):
34
+ types = RiskIncidentType.objects.all()
35
+ if types.exists():
36
+ return types.last().severity_order + 1
37
+ return 0
38
+
39
+
40
+ def _get_severity(o):
41
+ if o.rule.thresholds.exists():
42
+ return o.rule.thresholds.first().severity
43
+ return RiskIncidentTypeFactory.create()
44
+
45
+
46
+ class RiskIncidentTypeFactory(factory.django.DjangoModelFactory):
47
+ name = "LOW"
48
+ severity_order = factory.LazyAttribute(lambda o: get_severity_order(o))
49
+ is_ignorable = True
50
+ is_automatically_closed = False
51
+ is_informational = False
52
+
53
+ class Meta:
54
+ model = RiskIncidentType
55
+
56
+
57
+ class RiskIncidentFactory(RiskIncidentMixinFactory, factory.django.DjangoModelFactory):
58
+ rule = factory.SubFactory("wbcompliance.factories.risk_management.rules.RiskRuleFactory")
59
+ severity = factory.LazyAttribute(lambda x: x.rule.thresholds.first().severity)
60
+ date_range = factory.LazyAttribute(lambda o: _generate_date_range())
61
+
62
+ breached_content_type = None
63
+ breached_object_id = None
64
+ breached_object_repr = factory.Faker("text", max_nb_chars=32)
65
+
66
+ class Meta:
67
+ model = RiskIncident
68
+
69
+
70
+ def _create_risk_check(incident):
71
+ rel = RuleCheckedObjectRelationshipFactory.create(rule=incident.rule)
72
+ return RiskCheckFactory.create(rule_checked_object_relationship=rel)
73
+
74
+
75
+ class CheckedObjectIncidentRelationshipFactory(RiskIncidentMixinFactory, factory.django.DjangoModelFactory):
76
+ severity = factory.LazyAttribute(lambda x: x.incident.rule.thresholds.first().severity)
77
+ rule_check = factory.LazyAttribute(lambda x: _create_risk_check(x.incident))
78
+ incident = factory.SubFactory("wbcompliance.factories.risk_management.incidents.RiskIncidentFactory")
79
+ # rule_check = factory.SubFactory("wbcompliance.factories.risk_management.checks.RiskCheckFactory")
80
+ report = factory.Faker("paragraph")
81
+ report_details = factory.LazyAttribute(lambda x: dict(a="b"))
82
+
83
+ class Meta:
84
+ model = CheckedObjectIncidentRelationship
@@ -0,0 +1,100 @@
1
+ import json
2
+ import random
3
+ from datetime import date
4
+
5
+ import factory
6
+ from django.contrib.auth import get_user_model
7
+ from django.contrib.contenttypes.models import ContentType
8
+ from django.core.serializers.json import DjangoJSONEncoder
9
+ from faker import Faker
10
+ from guardian.utils import get_anonymous_user
11
+ from psycopg.types.range import NumericRange
12
+ from wbcompliance.models.risk_management.rules import (
13
+ RiskRule,
14
+ RuleBackend,
15
+ RuleCheckedObjectRelationship,
16
+ RuleThreshold,
17
+ )
18
+ from wbcore.contrib.authentication.factories import UserFactory
19
+
20
+ fake = Faker()
21
+
22
+
23
+ class RuleBackendFactory(factory.django.DjangoModelFactory):
24
+ name = factory.Faker("name")
25
+ backend_class_path = "wbcompliance.factories.risk_management.backends"
26
+ backend_class_name = "RuleBackend"
27
+ allowed_checked_object_content_type = None
28
+
29
+ class Meta:
30
+ model = RuleBackend
31
+
32
+
33
+ def _get_default_parameter():
34
+ return json.loads(
35
+ json.dumps(
36
+ {
37
+ "date": fake.date_object(),
38
+ "name": fake.name(),
39
+ "int": fake.pyint(),
40
+ "anonymous_user": get_anonymous_user().id,
41
+ },
42
+ cls=DjangoJSONEncoder,
43
+ )
44
+ )
45
+
46
+
47
+ class RiskRuleFactory(factory.django.DjangoModelFactory):
48
+ name = factory.Faker("name")
49
+ description = factory.Faker("paragraph")
50
+ rule_backend = factory.SubFactory("wbcompliance.factories.risk_management.RuleBackendFactory")
51
+ is_enable = True
52
+ only_passive_check_allowed = True
53
+ is_silent = False
54
+ is_mandatory = True
55
+ automatically_close_incident = False
56
+ parameters = factory.LazyAttribute(lambda x: _get_default_parameter())
57
+ activation_date = date.min
58
+
59
+ @factory.post_generation
60
+ def threshold(self, create, extracted, **kwargs):
61
+ if not RuleThreshold.objects.filter(rule=self).exists():
62
+ RuleThresholdFactory.create(rule=self, notifiable_users=[UserFactory.create().profile])
63
+
64
+ class Meta:
65
+ model = RiskRule
66
+
67
+
68
+ class RuleThresholdFactory(factory.django.DjangoModelFactory):
69
+ rule = factory.SubFactory("wbcompliance.factories.risk_management.RiskRuleFactory")
70
+ range = factory.LazyAttribute(lambda o: NumericRange(lower=random.uniform(0, 0.5), upper=random.uniform(0.5, 1)))
71
+ severity = factory.SubFactory("wbcompliance.factories.risk_management.incidents.RiskIncidentTypeFactory")
72
+
73
+ @factory.post_generation
74
+ def notifiable_users(self, create, extracted, **kwargs):
75
+ if not create:
76
+ return
77
+ if extracted:
78
+ for person in extracted:
79
+ self.notifiable_users.add(person)
80
+
81
+ @factory.post_generation
82
+ def notifiable_groups(self, create, extracted, **kwargs):
83
+ if not create:
84
+ return
85
+ if extracted:
86
+ for group in extracted:
87
+ self.notifiable_groups.add(group)
88
+
89
+ class Meta:
90
+ model = RuleThreshold
91
+
92
+
93
+ class RuleCheckedObjectRelationshipFactory(factory.django.DjangoModelFactory):
94
+ rule = factory.SubFactory("wbcompliance.factories.risk_management.RiskRuleFactory")
95
+ checked_object_content_type = factory.LazyAttribute(lambda o: ContentType.objects.get_for_model(get_user_model()))
96
+ checked_object_id = 1
97
+
98
+ class Meta:
99
+ model = RuleCheckedObjectRelationship
100
+ django_get_or_create = ["rule", "checked_object_content_type", "checked_object_id"]
@@ -0,0 +1,2 @@
1
+ from .compliances import *
2
+ from .risk_management import *
@@ -0,0 +1,189 @@
1
+ from django.db.models import Max, Q
2
+ from django.utils.translation import gettext_lazy as _
3
+ from wbcompliance.models import (
4
+ ComplianceAction,
5
+ ComplianceEvent,
6
+ ComplianceForm,
7
+ ComplianceFormSignature,
8
+ ComplianceTask,
9
+ ComplianceTaskGroup,
10
+ ComplianceTaskInstance,
11
+ ComplianceType,
12
+ ReviewComplianceTask,
13
+ )
14
+ from wbcore import filters as wb_filters
15
+
16
+
17
+ class ComplianceFormFilter(wb_filters.FilterSet):
18
+ is_signed = wb_filters.BooleanFilter(label=_("Is Signed"), required=False)
19
+
20
+ class Meta:
21
+ model = ComplianceForm
22
+ fields = {
23
+ "form_type": ["exact"],
24
+ "compliance_type": ["exact"],
25
+ "title": ["exact", "icontains"],
26
+ "creator": ["exact"],
27
+ "changer": ["exact"],
28
+ "version": ["exact"],
29
+ "status": ["exact"],
30
+ "start": ["gte", "lte"],
31
+ "end": ["gte", "lte"],
32
+ }
33
+
34
+
35
+ class ComplianceFormSignatureFilter(wb_filters.FilterSet):
36
+ is_signed = wb_filters.BooleanFilter(label=_("Is Signed"), required=False)
37
+ last_version = wb_filters.BooleanFilter(
38
+ label=_("Last version"), default=True, required=False, method="filter_version"
39
+ )
40
+ # compliance_form = wb_filters.ModelChoiceFilter(
41
+ # label=_("Compliance Form"),
42
+ # queryset=ComplianceForm.objects.filter(status=ComplianceForm.Status.ACTIVE),
43
+ # endpoint=ComplianceForm.get_representation_endpoint(),
44
+ # value_key=ComplianceForm.get_representation_value_key(),
45
+ # label_key = ComplianceForm.get_representation_label_key(),
46
+ # method="filter_compliance_form"
47
+ # )
48
+ # def filter_compliance_form(self, queryset, name, value):
49
+ # return queryset.filter(status=ComplianceForm.Status.ACTIVE)
50
+
51
+ class Meta:
52
+ model = ComplianceFormSignature
53
+ fields = {
54
+ "person": ["exact"],
55
+ "signed": ["gte", "lte"],
56
+ "version": ["exact"],
57
+ "compliance_form": ["exact"],
58
+ }
59
+
60
+ def filter_version(self, queryset, name, value):
61
+ if value:
62
+ max_compliance_forms = queryset.values("compliance_form").annotate(max_version=Max("version")).order_by()
63
+ q_statement = Q()
64
+ for max_compliance_form in max_compliance_forms:
65
+ q_statement |= Q(compliance_form__exact=max_compliance_form["compliance_form"]) & Q(
66
+ version=max_compliance_form["max_version"]
67
+ )
68
+ return queryset.filter(q_statement)
69
+
70
+ return queryset
71
+
72
+
73
+ class ComplianceTypeFilter(wb_filters.FilterSet):
74
+ class Meta:
75
+ model = ComplianceType
76
+ fields = {
77
+ "name": ["exact", "icontains"],
78
+ }
79
+
80
+
81
+ class ComplianceTaskGroupFilter(wb_filters.FilterSet):
82
+ class Meta:
83
+ model = ComplianceTaskGroup
84
+ fields = {
85
+ "name": ["exact", "icontains"],
86
+ }
87
+
88
+
89
+ class ComplianceTaskReviewFilter(wb_filters.FilterSet):
90
+ class Meta:
91
+ model = ComplianceTask
92
+ fields = {
93
+ "title": ["exact", "icontains"],
94
+ "occurrence": ["exact"],
95
+ "active": ["exact"],
96
+ "type": ["exact"],
97
+ "group": ["exact"],
98
+ "risk_level": ["exact"],
99
+ }
100
+
101
+
102
+ class ComplianceTaskFilter(ComplianceTaskReviewFilter):
103
+ is_recurring = wb_filters.BooleanFilter(
104
+ label=_("Is Recurring"), required=False, default=True, method="filter_occurrence"
105
+ )
106
+ active = wb_filters.BooleanFilter(label=_("Active"), required=False, default=True)
107
+
108
+ def filter_occurrence(self, queryset, name, value):
109
+ if value is not None:
110
+ if value:
111
+ return queryset.filter(~Q(occurrence=ComplianceTask.Occurrence.NEVER))
112
+ else:
113
+ return queryset.filter(occurrence=ComplianceTask.Occurrence.NEVER)
114
+ return queryset
115
+
116
+
117
+ class ComplianceTaskInstanceFilter(wb_filters.FilterSet):
118
+ type_name = wb_filters.CharFilter(label=_("Administrator"), lookup_expr="icontains")
119
+ group_name = wb_filters.CharFilter(label=_("Group"), lookup_expr="icontains")
120
+
121
+ class Meta:
122
+ model = ComplianceTaskInstance
123
+ fields = {"task": ["exact"], "occured": ["lte", "gte"], "status": ["exact"], "review": ["exact"]}
124
+
125
+
126
+ class ComplianceTaskMatrixFilter(wb_filters.FilterSet):
127
+ type_name = wb_filters.CharFilter(label=_("Administrator"), lookup_expr="icontains")
128
+ group_name = wb_filters.CharFilter(label=_("Group"), lookup_expr="icontains")
129
+ task_title = wb_filters.CharFilter(label=_("Tasks"), lookup_expr="icontains")
130
+
131
+ class Meta:
132
+ model = ComplianceTaskInstance
133
+ fields = {}
134
+
135
+
136
+ class ComplianceActionFilter(wb_filters.FilterSet):
137
+ active = wb_filters.BooleanFilter(label=_("Active"), required=False, default=True)
138
+
139
+ class Meta:
140
+ model = ComplianceAction
141
+ fields = {
142
+ "title": ["exact", "icontains"],
143
+ "deadline": ["exact"],
144
+ "progress": ["exact"],
145
+ "status": ["exact"],
146
+ "active": ["exact"],
147
+ "type": ["exact"],
148
+ "creator": ["exact"],
149
+ "changer": ["exact"],
150
+ "last_modified": ["lte", "gte"],
151
+ }
152
+
153
+
154
+ class ComplianceEventFilter(wb_filters.FilterSet):
155
+ active = wb_filters.BooleanFilter(label=_("Active"), required=False, default=True)
156
+
157
+ class Meta:
158
+ model = ComplianceEvent
159
+ fields = {
160
+ "title": ["exact", "icontains"],
161
+ "type": ["exact"],
162
+ "level": ["exact"],
163
+ "active": ["exact"],
164
+ "type_event": ["exact"],
165
+ "creator": ["exact"],
166
+ "last_modified": ["lte", "gte"],
167
+ "confidential": ["exact"],
168
+ }
169
+
170
+
171
+ class ReviewComplianceTaskFilter(wb_filters.FilterSet):
172
+ is_instance = wb_filters.BooleanFilter(label=_("Is occurrence"), default=True, required=False)
173
+
174
+ class Meta:
175
+ model = ReviewComplianceTask
176
+ fields = {
177
+ "year": ["exact"],
178
+ "from_date": ["lte", "gte"],
179
+ "to_date": ["lte", "gte"],
180
+ "title": ["exact", "icontains"],
181
+ "is_instance": ["exact"],
182
+ "status": ["exact"],
183
+ "changer": ["exact"],
184
+ "changed": ["lte", "gte"],
185
+ "occured": ["lte", "gte"],
186
+ "review_task": ["exact"],
187
+ "occurrence": ["exact"],
188
+ "type": ["exact"],
189
+ }
@@ -0,0 +1,3 @@
1
+ from .incidents import CheckedObjectIncidentRelationshipFilterSet, RiskIncidentFilterSet
2
+ from .rules import RiskRuleFilterSet
3
+ from .tables import RiskManagementIncidentFilter
@@ -0,0 +1,22 @@
1
+ from wbcompliance.models.risk_management import RiskCheck
2
+ from wbcore import filters as wb_filters
3
+
4
+
5
+ class RiskCheckFilterSet(wb_filters.FilterSet):
6
+ triggers = wb_filters.MultipleChoiceContentTypeFilter(
7
+ label="Triggerers",
8
+ field_name="triggers",
9
+ object_id_label="trigger_id",
10
+ content_type_label="trigger_content_type",
11
+ distinct=True,
12
+ )
13
+
14
+ class Meta:
15
+ model = RiskCheck
16
+
17
+ fields = {
18
+ "rule_checked_object_relationship": ["exact"],
19
+ "creation_datetime": ["gte", "exact", "lte"],
20
+ "evaluation_date": ["exact"],
21
+ "status": ["exact"],
22
+ }
@@ -0,0 +1,113 @@
1
+ from django.db.models import Q
2
+ from django.utils.translation import gettext_lazy as _
3
+ from wbcompliance.models.risk_management import (
4
+ CheckedObjectIncidentRelationship,
5
+ RiskIncident,
6
+ RiskIncidentType,
7
+ RiskRule,
8
+ RuleCheckedObjectRelationship,
9
+ )
10
+ from wbcompliance.models.risk_management.rules import RuleGroup
11
+ from wbcore import filters as wb_filters
12
+
13
+
14
+ def get_default_severity(*args, **kwargs):
15
+ non_informational_qs = RiskIncidentType.objects.exclude(is_informational=True)
16
+ if non_informational_qs.exists():
17
+ return list(non_informational_qs.values_list("id", flat=True))
18
+ return []
19
+
20
+
21
+ class RiskIncidentFilterSet(wb_filters.FilterSet):
22
+ date_range = wb_filters.DateRangeFilter(label="Date Range")
23
+ status = wb_filters.ChoiceFilter(
24
+ default=RiskIncident.Status.OPEN, choices=RiskIncident.Status.choices, label=_("Label")
25
+ )
26
+ rule = wb_filters.ModelMultipleChoiceFilter(
27
+ label=_("Rule"),
28
+ queryset=RiskRule.objects.all(),
29
+ endpoint=RiskRule.get_representation_endpoint(),
30
+ value_key=RiskRule.get_representation_value_key(),
31
+ label_key=RiskRule.get_representation_label_key(),
32
+ )
33
+
34
+ severity = wb_filters.ModelMultipleChoiceFilter(
35
+ label=_("Severity"),
36
+ queryset=RiskIncidentType.objects.all(),
37
+ endpoint=RiskIncidentType.get_representation_endpoint(),
38
+ value_key=RiskIncidentType.get_representation_value_key(),
39
+ label_key=RiskIncidentType.get_representation_label_key(),
40
+ default=get_default_severity,
41
+ )
42
+ checked_object_relationships = wb_filters.MultipleChoiceContentTypeFilter(
43
+ label="Checked Objects",
44
+ field_name="checked_object_relationships",
45
+ object_id_label="checked_object_relationships__rule_check__rule_checked_object_relationship__checked_object_id",
46
+ content_type_label="checked_object_relationships__rule_check__rule_checked_object_relationship__checked_object_content_type",
47
+ distinct=True,
48
+ hidden=True,
49
+ )
50
+
51
+ rule_checked_object_relationship = wb_filters.ModelChoiceFilter(
52
+ label=_("Rule Relationship"),
53
+ queryset=RuleCheckedObjectRelationship.objects.all(),
54
+ endpoint=RuleCheckedObjectRelationship.get_representation_endpoint(),
55
+ value_key=RuleCheckedObjectRelationship.get_representation_value_key(),
56
+ label_key=RuleCheckedObjectRelationship.get_representation_label_key(),
57
+ hidden=True,
58
+ method="filter_rule_checked_object_relationship",
59
+ )
60
+ object_repr = wb_filters.CharFilter(label="Object Representation", lookup_expr="icontains")
61
+
62
+ def filter_rule_checked_object_relationship(self, queryset, label, value):
63
+ if value:
64
+ return queryset.filter(checked_object_relationships__rule_check__rule_checked_object_relationship=value)
65
+ return queryset
66
+
67
+ rule_group = wb_filters.ModelChoiceFilter(
68
+ label=_("Group"),
69
+ queryset=RuleGroup.objects.all(),
70
+ endpoint=RuleGroup.get_representation_endpoint(),
71
+ value_key=RuleGroup.get_representation_value_key(),
72
+ label_key=RuleGroup.get_representation_label_key(),
73
+ method="filter_rule_group",
74
+ )
75
+
76
+ def filter_rule_group(self, queryset, label, value):
77
+ if value:
78
+ return queryset.filter(
79
+ Q(rule__rule_backend__rule_group=value) | Q(rule__rule_backend__rule_group__isnull=True)
80
+ )
81
+ return queryset
82
+
83
+ class Meta:
84
+ model = RiskIncident
85
+ fields = {
86
+ "status": ["exact"],
87
+ "resolved_by": ["exact"],
88
+ "comment": ["icontains"],
89
+ "severity": ["exact"],
90
+ }
91
+
92
+
93
+ class CheckedObjectIncidentRelationshipFilterSet(wb_filters.FilterSet):
94
+ checked_object = wb_filters.CharFilter(
95
+ method="filter_checked_object", field_name="checked_object", lookup_expr="icontains"
96
+ )
97
+
98
+ def filter_checked_object(self, queryset, label, value):
99
+ if value:
100
+ return queryset.filter(rule_check__rule_checked_object_relationship__checked_object_repr__icontains=value)
101
+ return queryset
102
+
103
+ class Meta:
104
+ model = CheckedObjectIncidentRelationship
105
+ fields = {
106
+ "severity": ["exact"],
107
+ "report": ["icontains"],
108
+ "comment": ["icontains"],
109
+ "resolved_by": ["exact"],
110
+ "incident": ["exact"],
111
+ "rule_check": ["exact"],
112
+ "status": ["exact"],
113
+ }