wbcompliance 2.2.1__tar.gz

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 (136) hide show
  1. wbcompliance-2.2.1/.gitignore +181 -0
  2. wbcompliance-2.2.1/PKG-INFO +7 -0
  3. wbcompliance-2.2.1/pyproject.toml +30 -0
  4. wbcompliance-2.2.1/wbcompliance/__init__.py +1 -0
  5. wbcompliance-2.2.1/wbcompliance/admin/__init__.py +16 -0
  6. wbcompliance-2.2.1/wbcompliance/admin/compliance_form.py +56 -0
  7. wbcompliance-2.2.1/wbcompliance/admin/compliance_task.py +135 -0
  8. wbcompliance-2.2.1/wbcompliance/admin/compliance_type.py +8 -0
  9. wbcompliance-2.2.1/wbcompliance/admin/risk_management/__init__.py +3 -0
  10. wbcompliance-2.2.1/wbcompliance/admin/risk_management/checks.py +7 -0
  11. wbcompliance-2.2.1/wbcompliance/admin/risk_management/incidents.py +50 -0
  12. wbcompliance-2.2.1/wbcompliance/admin/risk_management/rules.py +63 -0
  13. wbcompliance-2.2.1/wbcompliance/admin/utils.py +46 -0
  14. wbcompliance-2.2.1/wbcompliance/apps.py +14 -0
  15. wbcompliance-2.2.1/wbcompliance/factories/__init__.py +21 -0
  16. wbcompliance-2.2.1/wbcompliance/factories/compliance.py +246 -0
  17. wbcompliance-2.2.1/wbcompliance/factories/risk_management/__init__.py +12 -0
  18. wbcompliance-2.2.1/wbcompliance/factories/risk_management/backends.py +42 -0
  19. wbcompliance-2.2.1/wbcompliance/factories/risk_management/checks.py +12 -0
  20. wbcompliance-2.2.1/wbcompliance/factories/risk_management/incidents.py +84 -0
  21. wbcompliance-2.2.1/wbcompliance/factories/risk_management/rules.py +100 -0
  22. wbcompliance-2.2.1/wbcompliance/filters/__init__.py +2 -0
  23. wbcompliance-2.2.1/wbcompliance/filters/compliances.py +189 -0
  24. wbcompliance-2.2.1/wbcompliance/filters/risk_management/__init__.py +3 -0
  25. wbcompliance-2.2.1/wbcompliance/filters/risk_management/checks.py +22 -0
  26. wbcompliance-2.2.1/wbcompliance/filters/risk_management/incidents.py +113 -0
  27. wbcompliance-2.2.1/wbcompliance/filters/risk_management/rules.py +110 -0
  28. wbcompliance-2.2.1/wbcompliance/filters/risk_management/tables.py +112 -0
  29. wbcompliance-2.2.1/wbcompliance/filters/risk_management/utils.py +3 -0
  30. wbcompliance-2.2.1/wbcompliance/fixtures/compliance.yaml +16 -0
  31. wbcompliance-2.2.1/wbcompliance/locale/de/LC_MESSAGES/django.po +1446 -0
  32. wbcompliance-2.2.1/wbcompliance/locale/fr/LC_MESSAGES/django.po +1446 -0
  33. wbcompliance-2.2.1/wbcompliance/management/__init__.py +10 -0
  34. wbcompliance-2.2.1/wbcompliance/migrations/0001_initial_squashed_squashed_0010_alter_checkedobjectincidentrelationship_resolved_by_and_more.py +1744 -0
  35. wbcompliance-2.2.1/wbcompliance/migrations/0011_alter_riskrule_parameters.py +21 -0
  36. wbcompliance-2.2.1/wbcompliance/migrations/0012_alter_compliancetype_options.py +20 -0
  37. wbcompliance-2.2.1/wbcompliance/migrations/0013_alter_riskrule_unique_together.py +16 -0
  38. wbcompliance-2.2.1/wbcompliance/migrations/0014_alter_reviewcompliancetask_year.py +27 -0
  39. wbcompliance-2.2.1/wbcompliance/migrations/0015_auto_20240103_0957.py +43 -0
  40. wbcompliance-2.2.1/wbcompliance/migrations/0016_checkedobjectincidentrelationship_report_details_and_more.py +37 -0
  41. wbcompliance-2.2.1/wbcompliance/migrations/0017_alter_rulebackend_incident_report_template.py +20 -0
  42. wbcompliance-2.2.1/wbcompliance/migrations/0018_alter_rulecheckedobjectrelationship_unique_together.py +39 -0
  43. wbcompliance-2.2.1/wbcompliance/migrations/0019_rulegroup_riskrule_activation_date_and_more.py +60 -0
  44. wbcompliance-2.2.1/wbcompliance/migrations/__init__.py +0 -0
  45. wbcompliance-2.2.1/wbcompliance/models/__init__.py +20 -0
  46. wbcompliance-2.2.1/wbcompliance/models/compliance_form.py +626 -0
  47. wbcompliance-2.2.1/wbcompliance/models/compliance_task.py +800 -0
  48. wbcompliance-2.2.1/wbcompliance/models/compliance_type.py +133 -0
  49. wbcompliance-2.2.1/wbcompliance/models/enums.py +13 -0
  50. wbcompliance-2.2.1/wbcompliance/models/risk_management/__init__.py +4 -0
  51. wbcompliance-2.2.1/wbcompliance/models/risk_management/backend.py +139 -0
  52. wbcompliance-2.2.1/wbcompliance/models/risk_management/checks.py +194 -0
  53. wbcompliance-2.2.1/wbcompliance/models/risk_management/dispatch.py +41 -0
  54. wbcompliance-2.2.1/wbcompliance/models/risk_management/incidents.py +619 -0
  55. wbcompliance-2.2.1/wbcompliance/models/risk_management/mixins.py +115 -0
  56. wbcompliance-2.2.1/wbcompliance/models/risk_management/rules.py +654 -0
  57. wbcompliance-2.2.1/wbcompliance/permissions.py +32 -0
  58. wbcompliance-2.2.1/wbcompliance/serializers/__init__.py +30 -0
  59. wbcompliance-2.2.1/wbcompliance/serializers/compliance_form.py +320 -0
  60. wbcompliance-2.2.1/wbcompliance/serializers/compliance_task.py +463 -0
  61. wbcompliance-2.2.1/wbcompliance/serializers/compliance_type.py +26 -0
  62. wbcompliance-2.2.1/wbcompliance/serializers/risk_management/__init__.py +19 -0
  63. wbcompliance-2.2.1/wbcompliance/serializers/risk_management/checks.py +53 -0
  64. wbcompliance-2.2.1/wbcompliance/serializers/risk_management/incidents.py +227 -0
  65. wbcompliance-2.2.1/wbcompliance/serializers/risk_management/rules.py +158 -0
  66. wbcompliance-2.2.1/wbcompliance/tasks.py +112 -0
  67. wbcompliance-2.2.1/wbcompliance/templates/compliance/compliance_form.html +320 -0
  68. wbcompliance-2.2.1/wbcompliance/templates/compliance/review_compliance_task_report.html +232 -0
  69. wbcompliance-2.2.1/wbcompliance/templates/risk_management/incident_notification.html +42 -0
  70. wbcompliance-2.2.1/wbcompliance/templates/risk_management/incident_report.html +5 -0
  71. wbcompliance-2.2.1/wbcompliance/tests/__init__.py +0 -0
  72. wbcompliance-2.2.1/wbcompliance/tests/conftest.py +63 -0
  73. wbcompliance-2.2.1/wbcompliance/tests/disable_signals.py +82 -0
  74. wbcompliance-2.2.1/wbcompliance/tests/mixins.py +17 -0
  75. wbcompliance-2.2.1/wbcompliance/tests/risk_management/__init__.py +0 -0
  76. wbcompliance-2.2.1/wbcompliance/tests/risk_management/models/__init__.py +0 -0
  77. wbcompliance-2.2.1/wbcompliance/tests/risk_management/models/test_backends.py +0 -0
  78. wbcompliance-2.2.1/wbcompliance/tests/risk_management/models/test_checks.py +55 -0
  79. wbcompliance-2.2.1/wbcompliance/tests/risk_management/models/test_incidents.py +327 -0
  80. wbcompliance-2.2.1/wbcompliance/tests/risk_management/models/test_rules.py +255 -0
  81. wbcompliance-2.2.1/wbcompliance/tests/signals.py +89 -0
  82. wbcompliance-2.2.1/wbcompliance/tests/test_filters.py +23 -0
  83. wbcompliance-2.2.1/wbcompliance/tests/test_models.py +57 -0
  84. wbcompliance-2.2.1/wbcompliance/tests/test_serializers.py +48 -0
  85. wbcompliance-2.2.1/wbcompliance/tests/test_views.py +377 -0
  86. wbcompliance-2.2.1/wbcompliance/tests/tests.py +21 -0
  87. wbcompliance-2.2.1/wbcompliance/urls.py +238 -0
  88. wbcompliance-2.2.1/wbcompliance/viewsets/__init__.py +40 -0
  89. wbcompliance-2.2.1/wbcompliance/viewsets/buttons/__init__.py +9 -0
  90. wbcompliance-2.2.1/wbcompliance/viewsets/buttons/compliance_form.py +78 -0
  91. wbcompliance-2.2.1/wbcompliance/viewsets/buttons/compliance_task.py +149 -0
  92. wbcompliance-2.2.1/wbcompliance/viewsets/buttons/risk_managment/__init__.py +3 -0
  93. wbcompliance-2.2.1/wbcompliance/viewsets/buttons/risk_managment/checks.py +11 -0
  94. wbcompliance-2.2.1/wbcompliance/viewsets/buttons/risk_managment/incidents.py +51 -0
  95. wbcompliance-2.2.1/wbcompliance/viewsets/buttons/risk_managment/rules.py +35 -0
  96. wbcompliance-2.2.1/wbcompliance/viewsets/compliance_form.py +425 -0
  97. wbcompliance-2.2.1/wbcompliance/viewsets/compliance_task.py +513 -0
  98. wbcompliance-2.2.1/wbcompliance/viewsets/compliance_type.py +38 -0
  99. wbcompliance-2.2.1/wbcompliance/viewsets/display/__init__.py +22 -0
  100. wbcompliance-2.2.1/wbcompliance/viewsets/display/compliance_form.py +317 -0
  101. wbcompliance-2.2.1/wbcompliance/viewsets/display/compliance_task.py +453 -0
  102. wbcompliance-2.2.1/wbcompliance/viewsets/display/compliance_type.py +22 -0
  103. wbcompliance-2.2.1/wbcompliance/viewsets/display/risk_managment/__init__.py +11 -0
  104. wbcompliance-2.2.1/wbcompliance/viewsets/display/risk_managment/checks.py +46 -0
  105. wbcompliance-2.2.1/wbcompliance/viewsets/display/risk_managment/incidents.py +155 -0
  106. wbcompliance-2.2.1/wbcompliance/viewsets/display/risk_managment/rules.py +146 -0
  107. wbcompliance-2.2.1/wbcompliance/viewsets/display/risk_managment/tables.py +51 -0
  108. wbcompliance-2.2.1/wbcompliance/viewsets/endpoints/__init__.py +27 -0
  109. wbcompliance-2.2.1/wbcompliance/viewsets/endpoints/compliance_form.py +207 -0
  110. wbcompliance-2.2.1/wbcompliance/viewsets/endpoints/compliance_task.py +193 -0
  111. wbcompliance-2.2.1/wbcompliance/viewsets/endpoints/compliance_type.py +9 -0
  112. wbcompliance-2.2.1/wbcompliance/viewsets/endpoints/risk_managment/__init__.py +12 -0
  113. wbcompliance-2.2.1/wbcompliance/viewsets/endpoints/risk_managment/checks.py +16 -0
  114. wbcompliance-2.2.1/wbcompliance/viewsets/endpoints/risk_managment/incidents.py +36 -0
  115. wbcompliance-2.2.1/wbcompliance/viewsets/endpoints/risk_managment/rules.py +32 -0
  116. wbcompliance-2.2.1/wbcompliance/viewsets/endpoints/risk_managment/tables.py +14 -0
  117. wbcompliance-2.2.1/wbcompliance/viewsets/menu/__init__.py +17 -0
  118. wbcompliance-2.2.1/wbcompliance/viewsets/menu/compliance_form.py +49 -0
  119. wbcompliance-2.2.1/wbcompliance/viewsets/menu/compliance_task.py +130 -0
  120. wbcompliance-2.2.1/wbcompliance/viewsets/menu/compliance_type.py +17 -0
  121. wbcompliance-2.2.1/wbcompliance/viewsets/menu/risk_management.py +56 -0
  122. wbcompliance-2.2.1/wbcompliance/viewsets/risk_management/__init__.py +21 -0
  123. wbcompliance-2.2.1/wbcompliance/viewsets/risk_management/checks.py +49 -0
  124. wbcompliance-2.2.1/wbcompliance/viewsets/risk_management/incidents.py +204 -0
  125. wbcompliance-2.2.1/wbcompliance/viewsets/risk_management/mixins.py +52 -0
  126. wbcompliance-2.2.1/wbcompliance/viewsets/risk_management/rules.py +179 -0
  127. wbcompliance-2.2.1/wbcompliance/viewsets/risk_management/tables.py +96 -0
  128. wbcompliance-2.2.1/wbcompliance/viewsets/titles/__init__.py +17 -0
  129. wbcompliance-2.2.1/wbcompliance/viewsets/titles/compliance_form.py +101 -0
  130. wbcompliance-2.2.1/wbcompliance/viewsets/titles/compliance_task.py +60 -0
  131. wbcompliance-2.2.1/wbcompliance/viewsets/titles/compliance_type.py +13 -0
  132. wbcompliance-2.2.1/wbcompliance/viewsets/titles/risk_managment/__init__.py +1 -0
  133. wbcompliance-2.2.1/wbcompliance/viewsets/titles/risk_managment/checks.py +0 -0
  134. wbcompliance-2.2.1/wbcompliance/viewsets/titles/risk_managment/incidents.py +0 -0
  135. wbcompliance-2.2.1/wbcompliance/viewsets/titles/risk_managment/rules.py +0 -0
  136. wbcompliance-2.2.1/wbcompliance/viewsets/titles/risk_managment/tables.py +7 -0
@@ -0,0 +1,181 @@
1
+ ~
2
+
3
+ # Docker volumes
4
+ volumes/
5
+ # Poetry auth file
6
+ auth.toml
7
+
8
+ media/*
9
+ media/
10
+ mediafiles/
11
+ mediafiles/*
12
+ test/*
13
+ staticfiles/*
14
+ staticfiles/
15
+ #
16
+ # Byte-compiled / optimized / DLL files
17
+ __pycache__/
18
+ *.py[cod]
19
+ *$py.class
20
+
21
+ # C extensions
22
+ *.so
23
+
24
+ # Distribution / packaging
25
+ .Python
26
+ build/
27
+ develop-eggs/
28
+ dist/
29
+ info/
30
+ downloads/
31
+ eggs/
32
+ .eggs/
33
+ lib/
34
+ lib64/
35
+ parts/
36
+ sdist/
37
+ var/
38
+ wheels/
39
+ share/python-wheels/
40
+ *.egg-info/
41
+ .installed.cfg
42
+ *.egg
43
+ MANIFEST
44
+
45
+ # PyInstaller
46
+ # Usually these files are written by a python script from a template
47
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
48
+ *.manifest
49
+ *.spec
50
+
51
+ # Installer logs
52
+ pip-log.txt
53
+ pip-delete-this-directory.txt
54
+
55
+ # Unit test / coverage reports
56
+ htmlcov/
57
+ .tox/
58
+ .nox/
59
+ .coverage
60
+ .coverage.*
61
+ .cache
62
+ .dccache
63
+ nosetests.xml
64
+ coverage.xml
65
+ *.cover
66
+ *.py,cover
67
+ .hypothesis/
68
+ .pytest_cache/
69
+ cover/
70
+ report.xml
71
+ */report.xml
72
+
73
+ # Translations
74
+ *.mo
75
+ *.pot
76
+
77
+ # Django stuff:
78
+ *.log
79
+ local_settings.py
80
+ *.sqlite3
81
+ db.sqlite3-journal
82
+
83
+ # Flask stuff:
84
+ instance/
85
+ .webassets-cache
86
+
87
+ # Scrapy stuff:
88
+ .scrapy
89
+
90
+ # Sphinx documentation
91
+ docs/_build/
92
+
93
+ # PyBuilder
94
+ .pybuilder/
95
+ target/
96
+
97
+ # Jupyter Notebook
98
+ .ipynb_checkpoints
99
+ *.ipynb
100
+ # IPython
101
+ profile_default/
102
+ ipython_config.py
103
+
104
+ # pyenv
105
+ # For a library or package, you might want to ignore these files since the code is
106
+ # intended to run in multiple environments; otherwise, check them in:
107
+ # .python-version
108
+
109
+ # pipenv
110
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
111
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
112
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
113
+ # install all needed dependencies.
114
+ #Pipfile.lock
115
+
116
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow
117
+ __pypackages__/
118
+
119
+ # Celery stuff
120
+ celerybeat-schedule
121
+ celerybeat.pid
122
+
123
+ # SageMath parsed files
124
+ *.sage.py
125
+
126
+ # Environments
127
+ .env
128
+ .envrc
129
+ .venv
130
+ env/
131
+ venv/
132
+ ENV/
133
+ env.bak/
134
+ venv.bak/
135
+ .vscode/
136
+ .idea/
137
+ .idea.bkp/
138
+
139
+ # Spyder project settings
140
+ .spyderproject
141
+ .spyproject
142
+
143
+ # Rope project settings
144
+ .ropeproject
145
+
146
+ # mkdocs documentation
147
+ /site
148
+
149
+ # mypy
150
+ .mypy_cache/
151
+ .dmypy.json
152
+ dmypy.json
153
+
154
+ # Pyre type checker
155
+ .pyre/
156
+
157
+ # pytype static type analyzer
158
+ .pytype/
159
+ crm/
160
+ # Cython debug symbols
161
+ cython_debug/
162
+
163
+ # Gitlab Runner
164
+ builds
165
+ builds/
166
+
167
+ # Integrator Office 365 : reverse proxy tunnel for outlook365
168
+ ngrok
169
+ */ngrok
170
+ /modules/**/system/
171
+
172
+ /modules/wbmailing/files/*
173
+ /modules/wbmailing/mailing/*
174
+
175
+ /projects/*/requirements.txt
176
+ public
177
+
178
+ # Ignore archive localization generated folder
179
+ backend/modules/**/archive/*
180
+ **/**/requirements.txt
181
+ CHANGELOG-*
@@ -0,0 +1,7 @@
1
+ Metadata-Version: 2.3
2
+ Name: wbcompliance
3
+ Version: 2.2.1
4
+ Summary: A workbench module for managing compliance.
5
+ Author-email: Christopher Wittlinger <c.wittlinger@stainly.com>
6
+ Requires-Dist: wbcore
7
+ Requires-Dist: weasyprint==57.*
@@ -0,0 +1,30 @@
1
+ [project]
2
+ name = "wbcompliance"
3
+ description = "A workbench module for managing compliance."
4
+ authors = [{ name = "Christopher Wittlinger", email = "c.wittlinger@stainly.com"}]
5
+ dynamic = ["version"]
6
+
7
+ dependencies = [
8
+ "wbcore",
9
+ "weasyprint == 57.*",
10
+ ]
11
+
12
+ [tool.uv.sources]
13
+ wbcore = { workspace = true }
14
+
15
+ [tool.uv]
16
+ package = true
17
+
18
+ [tool.hatch.version]
19
+ path = "../../pyproject.toml"
20
+
21
+ [tool.hatch.build.targets.sdist]
22
+ include = ["wbcompliance/*"]
23
+
24
+ [tool.hatch.build.targets.wheel]
25
+ packages = ["wbcompliance"]
26
+ only-packages = true
27
+
28
+ [build-system]
29
+ requires = ["hatchling"]
30
+ build-backend = "hatchling.build"
@@ -0,0 +1 @@
1
+ __version__ = "1.0.0"
@@ -0,0 +1,16 @@
1
+ from .compliance_form import (
2
+ ComplianceFormAdmin,
3
+ ComplianceFormRuleAdmin,
4
+ ComplianceFormSectionAdmin,
5
+ ComplianceFormSignatureAdmin,
6
+ ComplianceFormSignatureRuleAdmin,
7
+ ComplianceFormSignatureSectionAdmin,
8
+ ComplianceFormTypeAdmin,
9
+ )
10
+ from .compliance_task import (
11
+ ComplianceActionAdmin,
12
+ ComplianceEventAdmin,
13
+ ReviewComplianceTaskAdmin,
14
+ )
15
+ from .compliance_type import ComplianceTypeAdmin
16
+ from .risk_management import *
@@ -0,0 +1,56 @@
1
+ from django.contrib import admin
2
+ from reversion_compare.admin import CompareVersionAdmin
3
+ from wbcompliance.models import (
4
+ ComplianceForm,
5
+ ComplianceFormRule,
6
+ ComplianceFormSection,
7
+ ComplianceFormSignature,
8
+ ComplianceFormSignatureRule,
9
+ ComplianceFormSignatureSection,
10
+ ComplianceFormType,
11
+ )
12
+
13
+
14
+ @admin.register(ComplianceFormType)
15
+ class ComplianceFormTypeAdmin(CompareVersionAdmin):
16
+ list_display = ["name", "type"]
17
+
18
+
19
+ @admin.register(ComplianceForm)
20
+ class ComplianceFormAdmin(CompareVersionAdmin):
21
+ list_display = ["status", "creator", "created", "title"]
22
+
23
+ autocomplete_fields = ["creator"]
24
+
25
+ def reversion_register(self, model, **options):
26
+ options = {
27
+ "ignore_duplicates": True,
28
+ }
29
+ super().reversion_register(model, **options)
30
+
31
+
32
+ @admin.register(ComplianceFormSignature)
33
+ class ComplianceFormSignatureAdmin(CompareVersionAdmin):
34
+ list_display = ["compliance_form", "version", "signed", "person"]
35
+
36
+ autocomplete_fields = ["person"]
37
+
38
+
39
+ @admin.register(ComplianceFormSection)
40
+ class ComplianceFormSectionAdmin(CompareVersionAdmin):
41
+ list_display = ["compliance_form", "name"]
42
+
43
+
44
+ @admin.register(ComplianceFormRule)
45
+ class ComplianceFormRuleAdmin(CompareVersionAdmin):
46
+ list_display = ["section", "text", "ticked"]
47
+
48
+
49
+ @admin.register(ComplianceFormSignatureSection)
50
+ class ComplianceFormSignatureSectionAdmin(CompareVersionAdmin):
51
+ list_display = ["compliance_form_signature", "name"]
52
+
53
+
54
+ @admin.register(ComplianceFormSignatureRule)
55
+ class ComplianceFormSignatureRuleAdmin(CompareVersionAdmin):
56
+ list_display = ["section", "text", "ticked", "comments"]
@@ -0,0 +1,135 @@
1
+ import pandas as pd
2
+ from django.contrib import admin
3
+ from reversion_compare.admin import CompareVersionAdmin
4
+ from wbcompliance.models import (
5
+ ComplianceAction,
6
+ ComplianceEvent,
7
+ ComplianceTask,
8
+ ComplianceTaskGroup,
9
+ ComplianceTaskInstance,
10
+ ComplianceType,
11
+ ReviewComplianceTask,
12
+ )
13
+ from wbcore.admin import ExportCsvMixin
14
+
15
+ from .utils import CustomImportCsvMixin
16
+
17
+
18
+ @admin.register(ComplianceTaskGroup)
19
+ class ComplianceTaskGroupAdmin(ExportCsvMixin, CustomImportCsvMixin, CompareVersionAdmin):
20
+ list_display = ["name", "order"]
21
+
22
+ def manipulate_df(self, df):
23
+ df["name"] = df["name"].fillna("")
24
+ return df
25
+
26
+ def get_import_fields(self):
27
+ return [
28
+ "name",
29
+ ]
30
+
31
+ def process_model(self, model):
32
+ if model.get("name"):
33
+ _, created = self.model.objects.get_or_create(name=model.get("name"))
34
+ return 1 if created else 0
35
+ return 0
36
+
37
+
38
+ @admin.register(ComplianceTask)
39
+ class ComplianceTaskAdmin(ExportCsvMixin, CustomImportCsvMixin, CompareVersionAdmin):
40
+ list_display = ["title", "occurrence", "active", "risk_level", "group", "type"]
41
+
42
+ def manipulate_df(self, df):
43
+ df["type"] = df["type_name"].apply(lambda x: ComplianceType.objects.filter(name__exact=x).first())
44
+ df["group"] = df.apply(
45
+ lambda x: ComplianceTaskGroup.objects.filter(name__exact=x["group_name"]).first(), axis=1
46
+ )
47
+ return df
48
+
49
+ def get_import_fields(self):
50
+ return ["type_name", "group_name", "occurrence", "title", "description"]
51
+
52
+ def process_model(self, model):
53
+ if model.get("title"):
54
+ _, created = self.model.objects.update_or_create(
55
+ title=model.get("title"),
56
+ defaults={
57
+ "type": model.get("type"),
58
+ "group": model.get("group"),
59
+ "occurrence": model.get("occurrence"),
60
+ # 'description': model.get('description')
61
+ },
62
+ )
63
+ return 1 if created else 0
64
+ return 0
65
+
66
+
67
+ @admin.register(ComplianceTaskInstance)
68
+ class ComplianceTaskInstanceAdmin(ExportCsvMixin, CustomImportCsvMixin, CompareVersionAdmin):
69
+ list_display = ["task", "occured", "status"]
70
+
71
+ def manipulate_df(self, df):
72
+ df["task"] = df.apply(lambda x: ComplianceTask.objects.filter(title__exact=x["task_name"]).first(), axis=1)
73
+ df["occured"] = pd.to_datetime(df["occured"])
74
+ return df
75
+
76
+ def get_import_fields(self):
77
+ return ["task_name", "occured", "status", "text"]
78
+
79
+ def process_model(self, model):
80
+ if (task := model.get("task")) and (occured := model.get("occured")):
81
+ obj, created = self.model.objects.update_or_create(
82
+ task=task,
83
+ occured=occured,
84
+ defaults={
85
+ "status": model.get("status"),
86
+ "text": model.get("text"),
87
+ },
88
+ )
89
+ if created:
90
+ obj.occured = occured
91
+ obj.save()
92
+
93
+ return 1 if created else 0
94
+ return 0
95
+
96
+
97
+ @admin.register(ComplianceAction)
98
+ class ComplianceActionAdmin(CompareVersionAdmin):
99
+ search_fields = ["title"]
100
+ list_display = [
101
+ "title",
102
+ "deadline",
103
+ "progress",
104
+ "status",
105
+ "type",
106
+ "creator",
107
+ "created",
108
+ "changer",
109
+ "last_modified",
110
+ ]
111
+
112
+
113
+ @admin.register(ComplianceEvent)
114
+ class ComplianceEventAdmin(CompareVersionAdmin):
115
+ search_fields = ["title"]
116
+ list_display = ["title", "type", "level", "type", "confidential", "creator", "created", "changer", "last_modified"]
117
+
118
+
119
+ @admin.register(ReviewComplianceTask)
120
+ class ReviewComplianceTaskAdmin(CompareVersionAdmin):
121
+ list_display = [
122
+ "id",
123
+ "year",
124
+ "title",
125
+ "from_date",
126
+ "to_date",
127
+ "status",
128
+ "occurrence",
129
+ "is_instance",
130
+ "changer",
131
+ "changed",
132
+ "review_task",
133
+ "occured",
134
+ ]
135
+ search_fields = ["title"]
@@ -0,0 +1,8 @@
1
+ from django.contrib import admin
2
+ from reversion_compare.admin import CompareVersionAdmin
3
+ from wbcompliance.models import ComplianceType
4
+
5
+
6
+ @admin.register(ComplianceType)
7
+ class ComplianceTypeAdmin(CompareVersionAdmin):
8
+ list_display = ["name"]
@@ -0,0 +1,3 @@
1
+ from .checks import RiskCheckModelAdmin
2
+ from .incidents import RiskIncidentModelAdmin
3
+ from .rules import RiskRuleModelAdmin, RuleBackendModelAdmin
@@ -0,0 +1,7 @@
1
+ from django.contrib import admin
2
+ from wbcompliance.models.risk_management.checks import RiskCheck
3
+
4
+
5
+ @admin.register(RiskCheck)
6
+ class RiskCheckModelAdmin(admin.ModelAdmin):
7
+ list_display = ["rule_checked_object_relationship", "creation_datetime", "evaluation_date"]
@@ -0,0 +1,50 @@
1
+ from django.contrib import admin
2
+ from wbcompliance.models.risk_management.incidents import (
3
+ CheckedObjectIncidentRelationship,
4
+ RiskIncident,
5
+ RiskIncidentType,
6
+ )
7
+
8
+
9
+ class CheckedObjectIncidentRelationshipInLine(admin.TabularInline):
10
+ model = CheckedObjectIncidentRelationship
11
+ fields = ["status", "severity", "incident", "rule_check", "breached_value", "report_details", "report"]
12
+ extra = 0
13
+ raw_id_fields = ["incident", "rule_check"]
14
+ readonly_fields = ["status", "severity", "incident", "rule_check"]
15
+
16
+
17
+ class IncidentInLine(admin.TabularInline):
18
+ show_change_link = True
19
+ model = RiskIncident
20
+ fields = ["status", "severity", "date_range", "breached_content_type", "breached_object_id"]
21
+ extra = 0
22
+
23
+
24
+ @admin.register(RiskIncidentType)
25
+ class RiskIncidentTypeModelAdmin(admin.ModelAdmin):
26
+ list_display = [
27
+ "name",
28
+ "severity_order",
29
+ "color",
30
+ "is_ignorable",
31
+ "is_automatically_closed",
32
+ "is_informational",
33
+ ]
34
+
35
+
36
+ @admin.register(RiskIncident)
37
+ class RiskIncidentModelAdmin(admin.ModelAdmin):
38
+ list_display = [
39
+ "status",
40
+ "severity",
41
+ "date_range",
42
+ "rule",
43
+ "breached_content_type",
44
+ "breached_object_id",
45
+ "resolved_by",
46
+ ]
47
+
48
+ inlines = [
49
+ CheckedObjectIncidentRelationshipInLine,
50
+ ]
@@ -0,0 +1,63 @@
1
+ from django.contrib import admin
2
+ from guardian.admin import GuardedModelAdmin
3
+ from wbcompliance.models.risk_management.rules import (
4
+ RiskRule,
5
+ RuleBackend,
6
+ RuleCheckedObjectRelationship,
7
+ RuleGroup,
8
+ RuleThreshold,
9
+ )
10
+
11
+ from .incidents import IncidentInLine
12
+
13
+
14
+ class RuleThresholdInLine(admin.TabularInline):
15
+ model = RuleThreshold
16
+ fields = ["range", "severity", "notifiable_users", "notifiable_groups"]
17
+ extra = 0
18
+ autocomplete_fields = ["notifiable_users"]
19
+ raw_id_fields = ["notifiable_users", "notifiable_groups", "rule"]
20
+
21
+
22
+ class RuleCheckedObjectRelationshipInLine(admin.TabularInline):
23
+ model = RuleCheckedObjectRelationship
24
+ fields = [
25
+ "checked_object_content_type",
26
+ "checked_object_id",
27
+ ]
28
+ extra = 0
29
+ raw_id_fields = ["checked_object_content_type", "rule"]
30
+
31
+
32
+ @admin.register(RuleGroup)
33
+ class RuleGroupModelAdmin(admin.ModelAdmin):
34
+ list_display = [
35
+ "key",
36
+ "name",
37
+ ]
38
+
39
+
40
+ @admin.register(RuleBackend)
41
+ class RuleBackendModelAdmin(admin.ModelAdmin):
42
+ list_display = [
43
+ "name",
44
+ "rule_group",
45
+ "backend_class_path",
46
+ "backend_class_name",
47
+ "allowed_checked_object_content_type",
48
+ ]
49
+ raw_id_fields = ["allowed_checked_object_content_type"]
50
+
51
+
52
+ @admin.register(RiskRule)
53
+ class RiskRuleModelAdmin(GuardedModelAdmin):
54
+ list_display = [
55
+ "name",
56
+ "rule_backend",
57
+ "is_enable",
58
+ "only_passive_check_allowed",
59
+ "is_silent",
60
+ "is_mandatory",
61
+ "parameters",
62
+ ]
63
+ inlines = [RuleThresholdInLine, IncidentInLine, RuleCheckedObjectRelationshipInLine]
@@ -0,0 +1,46 @@
1
+ from io import StringIO
2
+
3
+ import pandas as pd
4
+ from django.shortcuts import redirect, render
5
+ from reversion.errors import RevertError
6
+ from wbcore.admin import CsvImportForm, ImportCsvMixin
7
+
8
+
9
+ class CustomImportCsvMixin(ImportCsvMixin):
10
+ def _import_csv(self, request, _sep=";"):
11
+ if request.method == "POST":
12
+ csv_file = request.FILES["csv_file"]
13
+
14
+ str_text = ""
15
+ for line in csv_file:
16
+ str_text = str_text + line.decode()
17
+ # Import csv as df
18
+ df = pd.read_csv(StringIO(str_text), sep=_sep)
19
+ # Sanitize dataframe
20
+ df = df.where(pd.notnull(df), None)
21
+ df = df.drop(df.columns.difference(self.get_import_fields()), axis=1)
22
+
23
+ # Overide this function if there is foreign key ids in the dataframe
24
+ df = self.manipulate_df(df)
25
+ errors = 0
26
+ revert_errors = 0
27
+ nb_added = 0
28
+ for model in df.to_dict("records"):
29
+ # by default, process the modela as a create request. Can be override to change the behavior
30
+ try:
31
+ nb_added += self.process_model(model)
32
+ # https://django-reversion.readthedocs.io/en/stable/common-problems.html
33
+ except RevertError:
34
+ revert_errors += 1
35
+ except Exception as e:
36
+ print(e) # noqa: T201
37
+ errors += 1
38
+ msg = f"""Your csv file has been imported : {df.shape[0] - errors - revert_errors} imported
39
+ ({nb_added} added, {df.shape[0] - errors - revert_errors - nb_added} updated), {errors} errors,
40
+ {revert_errors} revert errors found due to failure to restore old versions
41
+ """
42
+ self.message_user(request, msg)
43
+ return redirect("..")
44
+ form = CsvImportForm()
45
+ payload = {"form": form}
46
+ return render(request, "wbcore/admin/csv_form.html", payload)
@@ -0,0 +1,14 @@
1
+ from django.apps import AppConfig
2
+ from django.db.models.signals import post_migrate
3
+ from wbcompliance.management import autodiscover_riskmanagement_backends
4
+
5
+
6
+ class WbcomplianceConfig(AppConfig):
7
+ name = "wbcompliance"
8
+
9
+ #
10
+ def ready(self) -> None:
11
+ post_migrate.connect(
12
+ autodiscover_riskmanagement_backends,
13
+ dispatch_uid="wbcrm.synchronization.initialize_task",
14
+ )
@@ -0,0 +1,21 @@
1
+ from .compliance import (
2
+ ComplianceActionFactory,
3
+ ComplianceEventFactory,
4
+ ComplianceFormFactory,
5
+ ComplianceFormRuleFactory,
6
+ ComplianceFormSectionFactory,
7
+ ComplianceFormSignatureFactory,
8
+ ComplianceFormSignatureRuleFactory,
9
+ ComplianceFormSignatureSectionFactory,
10
+ ComplianceFormTypeFactory,
11
+ ComplianceTaskFactory,
12
+ ComplianceTaskGroupFactory,
13
+ ComplianceTaskInstanceFactory,
14
+ ComplianceTaskInstanceReviewFactory,
15
+ ComplianceTaskInstanceReviewNoGroupFactory,
16
+ ComplianceTaskReviewFactory,
17
+ ComplianceTaskReviewNoGroupFactory,
18
+ ComplianceTypeFactory,
19
+ UnsignedComplianceFormSignatureFactory,
20
+ )
21
+ from .risk_management import *