Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature #58 - Audit trail report #209

Merged
merged 15 commits into from
Apr 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions doc/installation/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -419,3 +419,25 @@ This feature will load the following reasons (in this order):
- Bescheiden die vervangen wat door een calamiteit verloren is gegaan.
- Precedenten: individuele zaken die leiden tot algemene regels.
- Bescheiden waarbij de vernietiging de logische samenhang zou verstoren.

Audit trails
============

In version ``1.0``, the templates used for the audit trail have been renamed. Their extension was changed from
``.txt`` to ``.html``. A management command was added to change the template name in all existing logs.
This can be executed as follows:

.. tabs::

.. group-tab:: Docker

.. code:: shell

$ docker-compose exec web src/manage.py convert_log_templates

.. group-tab:: Python

.. code:: shell

$ source env/bin/activate
$ python src/manage.py convert_log_templates
3 changes: 3 additions & 0 deletions doc/manual/destruction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,9 @@ filtering for lists that have already been reviewed. All lists with an associate
:width: 100%
:alt: Download destruction report

In addition, the PDF of the destruction report contains the audit trail of the destruction process.
It shows in chronological order which actions have been performed and the role of the user who performed
the action.

Audit trails, logs and notifications
====================================
Expand Down
Binary file not shown.
165 changes: 112 additions & 53 deletions src/archiefvernietigingscomponent/conf/locale/nl/LC_MESSAGES/django.po
Original file line number Diff line number Diff line change
Expand Up @@ -339,15 +339,15 @@ msgid "destruction lists"
msgstr "vernietigingslijsten"

#: archiefvernietigingscomponent/destruction/models.py:115
#: archiefvernietigingscomponent/destruction/tests/test_destruction_list_create.py:67
#: archiefvernietigingscomponent/destruction/tests/test_destruction_list_detail.py:99
#: archiefvernietigingscomponent/destruction/tests/test_review_create.py:114
#: archiefvernietigingscomponent/destruction/tests/test_destruction_list_create.py:71
#: archiefvernietigingscomponent/destruction/tests/test_destruction_list_detail.py:113
#: archiefvernietigingscomponent/destruction/tests/test_review_create.py:127
msgid "You are assigned for review."
msgstr "Je bent als reviewer aangewezen."

#: archiefvernietigingscomponent/destruction/models.py:120
#: archiefvernietigingscomponent/destruction/tests/test_review_create.py:174
#: archiefvernietigingscomponent/destruction/tests/test_review_create.py:229
#: archiefvernietigingscomponent/destruction/tests/test_review_create.py:201
#: archiefvernietigingscomponent/destruction/tests/test_review_create.py:270
msgid "There is a review to process."
msgstr "Er is een te verwerken beoordeling."

Expand Down Expand Up @@ -544,59 +544,118 @@ msgstr "De vernietigingslijst is nog niet beoordeeld."
msgid "Download destruction report: "
msgstr "Download verklaring van vernietiging"

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/aborted.txt:7
#: archiefvernietigingscomponent/destruction/templates/destruction/logs/aborted.html:7
#, python-format
msgid ""
"<span class=\"log-item__user\">%(user)s</span> has aborted the list <strong>"
"%(list)s</strong> with %(counter)s zaak."
"User with role <strong>%(role)s</strong> has aborted the list <strong>"
"%(list)s</strong> with %(counter)s case."
msgid_plural ""
"<span class=\"log-item__user\">%(user)s</span> has aborted the list <strong>"
"%(list)s</strong> with %(counter)s zaken."
"User with role <strong>%(role)s</strong> has aborted the list <strong>"
"%(list)s</strong> with %(counter)s cases."
msgstr[0] ""
"<span class=\"log-item__user\">%(user)s</span> heeft de vernietigingslijst "
"<strong>%(list)s</strong> met %(counter)s zaak geannuleerd."
"Gebruiker met rol <strong>%(role)s</strong> heeft de lijst <strong>%(list)s</"
"strong> met %(counter)s zaak geannuleerd."
msgstr[1] ""
"<span class=\"log-item__user\">%(user)s</span> heeft de vernietigingslijst "
"<strong>%(list)s</strong> met %(counter)s zakem geannuleerd."
"Gebruiker met rol <strong>%(role)s</strong> heeft de lijst <strong>%(list)s</"
"strong> met %(counter)s zaken geannuleerd."

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/created.txt:7
#, python-format
#: archiefvernietigingscomponent/destruction/templates/destruction/logs/created.html:7
msgid ""
"<span class=\"log-item__user\">%(user)s</span> heeft de lijst <strong>"
"%(list)s</strong> met %(counter)s zaak aangemaakt."
"User with role <strong>%(role)s</strong> created the list <strong>%(list)s</"
"strong> with %(counter)s case:"
msgid_plural ""
"<span class=\"log-item__user\">%(user)s</span> heeft de lijst <strong>"
"%(list)s</strong> met %(counter)s zaken aangemaakt."
"User with role <strong>%(role)s</strong> created the list <strong>%(list)s</"
"strong> with %(counter)s cases:"
msgstr[0] ""
"Gebruiker met rol <strong>%(role)s</strong> heeft de lijst <strong>%(list)s</"
"strong> met %(counter)s zaak aangemaakt:"
msgstr[1] ""
"Gebruiker met rol <strong>%(role)s</strong> heeft de lijst <strong>%(list)s</"
"strong> met %(counter)s zaken aangemaakt:"

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/item_destruction_failed.html:7
#, python-format
msgid "Case <strong>%(zaak)s</strong> was not deleted."
msgstr "Zaak <strong>%(zaak)s</strong> is niet verwijderd."

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/review_created.txt:7
#: archiefvernietigingscomponent/destruction/templates/destruction/logs/item_destruction_succeeded.html:7
#, python-format
msgid "Case <strong>%(zaak)s</strong> was deleted."
msgstr "Zaak <strong>%(zaak)s</strong> is verwijderd."

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/item_update_failed.html:7
#, python-format
msgid "Case <strong>%(zaak)s</strong> was not updated."
msgstr "Zaak <strong>%(zaak)s</strong> is niet aangepast."

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/item_update_succeeded.html:7
#, python-format
msgid "Case <strong>%(zaak)s</strong> was updated."
msgstr "Zaak <strong>%(zaak)s</strong> is aangepast."

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/review_created.html:8
msgid ""
"User with role <strong>%(role)s</strong> has rejected the list <strong>"
"%(list)s</strong>."
msgstr ""
"Gebruiker met rol <strong>%(role)s</strong> heeft de lijst <strong>%(list)s</"
"strong> afgewezen."

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/review_created.html:12
msgid ""
"<span class=\"log-item__user\">%(user)s</span> has created the review "
"<strong>%(review)s</strong> and requested changes for %(counter)s item."
"User with role <strong>%(role)s</strong> has reviewed the list <strong>"
"%(list)s</strong> and requested changes for %(counter)s item:"
msgid_plural ""
"<span class=\"log-item__user\">%(user)s</span> has created the review "
"<strong>%(review)s</strong> and requested changes for %(counter)s items."
"User with role <strong>%(role)s</strong> has reviewed the list <strong>"
"%(list)s</strong> and requested changes for %(counter)s items:"
msgstr[0] ""
"<span class=\"log-item__user\">%(user)s</span> heeft de review <strong>"
"%(review)s</strong> opgevoerd. Er zijn aanpassingen gevraagd voor "
"%(counter)s record."
"Gebruiker met rol <strong>%(role)s</strong> heeft de lijst <strong>%(list)s</"
"strong> beoordeeld en heeft wijzigingen voor %(counter)s zaak vereist:"
msgstr[1] ""
"<span class=\"log-item__user\">%(user)s</span> heeft de review <strong>"
"%(review)s</strong> opgevoerd. Er zijn aanpassingen gevraagd voor "
"%(counter)s records."
"Gebruiker met rol <strong>%(role)s</strong> heeft de lijst <strong>%(list)s</"
"strong> beoordeeld en heeft wijzigingen voor %(counter)s zaken vereist:"

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/updated.txt:7
#: archiefvernietigingscomponent/destruction/templates/destruction/logs/review_created.html:26
#, python-format
msgid ""
"<span class=\"log-item__user\">%(user)s</span> has updated the list <strong>"
"%(list)s</strong> with %(counter)s zaak removed."
"User with role <strong>%(role)s</strong> has approved the list <strong>"
"%(list)s</strong>."
msgstr ""
"Gebruiker met rol <strong>%(role)s</strong> heeft de lijst <strong>%(list)s</"
"strong> goedgekeurd."

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/review_created.html:33
#, python-format
msgid "<strong>Reviewer's comment</strong>: %(text)s"
msgstr "<strong>Opmerking van de reviewer</strong>: %(text)s"

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/updated.html:8
msgid ""
"User with role <strong>%(role)s</strong> has updated the list <strong>"
"%(list)s</strong> and removed %(counter)s case:"
msgid_plural ""
"<span class=\"log-item__user\">%(user)s</span> has updated the list <strong>"
"%(list)s</strong> with %(counter)s zaken removed."
"User with role <strong>%(role)s</strong> has updated the list <strong>"
"%(list)s</strong> and removed %(counter)s cases:"
msgstr[0] ""
"Gebruiker met rol <strong>%(role)s</strong> heeft de lijst <strong>%(list)s</"
"strong> aangepast en heeft %(counter)s zaak weggehaald:"
msgstr[1] ""
"Gebruiker met rol <strong>%(role)s</strong> heeft de lijst <strong>%(list)s</"
"strong> aangepast en heeft %(counter)s zaken weggehaald:"

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/updated.html:22
#, python-format
msgid ""
"User with role <strong>%(role)s</strong> has resubmitted the list <strong>"
"%(list)s</strong> for review."
msgstr ""
"Gebruiker met rol <strong>%(role)s</strong> heeft de lijst <strong>%(list)s</"
"strong> opnieuw ingediend."

#: archiefvernietigingscomponent/destruction/templates/destruction/logs/updated.html:30
#, python-format
msgid "<strong>Author's comment</strong>: %(text)s"
msgstr "<strong>Opmerking van de auteur</strong>: %(text)s"

#: archiefvernietigingscomponent/destruction/templates/destruction/recordmanager_list.html:13
#: archiefvernietigingscomponent/destruction/templates/destruction/reviewer_list.html:14
Expand Down Expand Up @@ -827,7 +886,7 @@ msgid "Destruction list for which the report was created."
msgstr "Vernietingslijst waarvoor de verklaring van vernietiging is gemaakt."

#: archiefvernietigingscomponent/report/models.py:52
#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:30
#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:29
msgid "Destruction report"
msgstr "Verklaring van vernietiging"

Expand All @@ -842,79 +901,79 @@ msgstr ""
"vernietiging"

#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:32
#: archiefvernietigingscomponent/report/utils.py:169
#: archiefvernietigingscomponent/report/utils.py:170
msgid "Unique ID"
msgstr "Uniek kenmerk"

#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:34
#: archiefvernietigingscomponent/report/utils.py:170
#: archiefvernietigingscomponent/report/utils.py:171
msgid "Description"
msgstr "Beschrijving"

#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:36
#: archiefvernietigingscomponent/report/utils.py:171
#: archiefvernietigingscomponent/report/utils.py:172
msgid "Duration"
msgstr "Looptijd"

#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:37
#: archiefvernietigingscomponent/report/utils.py:172
#: archiefvernietigingscomponent/report/utils.py:173
msgid "Destruction category Selectielijst"
msgstr "Vernietigings-Categorie Selectielijst"

#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:38
#: archiefvernietigingscomponent/report/utils.py:173
#: archiefvernietigingscomponent/report/utils.py:174
msgid "Explanation"
msgstr "Toelichting"

#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:40
#: archiefvernietigingscomponent/report/utils.py:174
#: archiefvernietigingscomponent/report/utils.py:175
msgid "Remarks SAD"
msgstr "Opmerkingen SAD"

#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:42
#: archiefvernietigingscomponent/report/utils.py:175
#: archiefvernietigingscomponent/report/utils.py:176
msgid "Reaction caretaker"
msgstr "Reactie zorgdrager"

#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:43
#: archiefvernietigingscomponent/report/utils.py:176
#: archiefvernietigingscomponent/report/utils.py:177
msgid "Case type"
msgstr "Zaaktype"

#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:44
#: archiefvernietigingscomponent/report/utils.py:177
#: archiefvernietigingscomponent/report/utils.py:178
msgid "Archive action period"
msgstr "Archiefactietermijn"

#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:45
#: archiefvernietigingscomponent/report/utils.py:178
#: archiefvernietigingscomponent/report/utils.py:179
msgid "Result type"
msgstr "Resultaattype"

#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:46
#: archiefvernietigingscomponent/report/utils.py:179
#: archiefvernietigingscomponent/report/utils.py:180
msgid "Organisation responsible"
msgstr "Verantwoordelijke organisatie"

#: archiefvernietigingscomponent/report/templates/report/vernietigings_rapport.html:47
#: archiefvernietigingscomponent/report/utils.py:180
#: archiefvernietigingscomponent/report/utils.py:181
msgid "Relations"
msgstr "Relaties"

#: archiefvernietigingscomponent/report/utils.py:121
#: archiefvernietigingscomponent/report/utils.py:122
#, python-format
msgid "%(looptijd)s days"
msgstr "%(looptijd)s dagen"

#: archiefvernietigingscomponent/report/utils.py:143
#: archiefvernietigingscomponent/report/utils.py:144
msgid "Yes"
msgstr "Ja"

#: archiefvernietigingscomponent/report/utils.py:145
#: archiefvernietigingscomponent/report/utils.py:146
msgid "No"
msgstr "Nee"

#: archiefvernietigingscomponent/report/utils.py:210
#: archiefvernietigingscomponent/report/utils.py:211
#, python-format
msgid "Declaration of destruction - %(name)s (%(date)s)"
msgstr "Verklaring van vernietiging - %(name)s (%(date)s)"
Expand Down
20 changes: 13 additions & 7 deletions src/archiefvernietigingscomponent/destruction/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

from django import forms
from django.contrib.postgres.forms import SimpleArrayField
from django.forms.models import BaseInlineFormSet

from archiefvernietigingscomponent.accounts.models import User

Expand Down Expand Up @@ -54,6 +53,7 @@ class DestructionListForm(forms.ModelForm):
reviewer_2 = forms.ModelChoiceField(
queryset=User.objects.reviewers().all(), required=False
)
zaken_identificaties = SimpleArrayField(forms.CharField(max_length=250))

class Meta:
model = DestructionList
Expand All @@ -62,6 +62,7 @@ class Meta:
"zaken",
"reviewer_1",
"reviewer_2",
"zaken_identificaties",
"contains_sensitive_info",
)

Expand Down Expand Up @@ -115,24 +116,29 @@ class Meta:
fields = ("text",)


class ReviewItemBaseFormset(BaseInlineFormSet):
class ReviewItemBaseForm(forms.ModelForm):
identificatie = forms.CharField()

class Meta:
fields = ["destruction_list_item", "text", "suggestion", "identificatie"]

def save(self, commit=True):
# save only items with suggestions
instances = super().save(commit=False)
instance = super().save(commit=False)

for instance in instances:
if instance.suggestion:
instance.save()
if instance.suggestion:
instance.save()


class ListItemForm(forms.ModelForm):
action = forms.ChoiceField(required=False, choices=Suggestion.choices)
archiefnominatie = forms.CharField(required=False)
# used charfield for easy conversion into json
archiefactiedatum = forms.CharField(required=False)
identificatie = forms.CharField()

class Meta:
fields = ("action", "archiefnominatie", "archiefactiedatum")
fields = ("action", "archiefnominatie", "archiefactiedatum", "identificatie")

def save(self, commit=True):
list_item = super().save(commit)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Generated by Django 2.2.18 on 2021-04-13 08:49

from django.db import migrations
from django.db.models import Value
from django.db.models.functions import Replace


def convert_log_templates(apps, schema_editor):
TimelineLog = apps.get_model("timeline_logger", "TimelineLog")

TimelineLog.objects.filter(template__endswith=".txt").update(
template=Replace("template", Value(".txt"), Value(".html"))
)


class Migration(migrations.Migration):

dependencies = [
("destruction", "0015_auto_20210326_1603"),
("timeline_logger", "0004_alter_fields"),
]

operations = [
migrations.RunPython(convert_log_templates),
]
Loading