Skip to content

Commit

Permalink
✨ [#397] Add zaak creation logic
Browse files Browse the repository at this point in the history
  • Loading branch information
SilviaAmAm authored and svenvandescheur committed Oct 17, 2024
1 parent 4408c51 commit fb69999
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Generated by Django 4.2.16 on 2024-10-14 12:51

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("destruction", "0023_destructionlist_destruction_report"),
]

operations = [
migrations.AddField(
model_name="destructionlist",
name="internal_results",
field=models.JSONField(
default=dict,
help_text="After this list is processed, the URL of the resources created in Open Zaak to store the destruction report are stored here.",
verbose_name="internal result",
),
),
migrations.AlterField(
model_name="destructionlist",
name="zaak_destruction_report_url",
field=models.URLField(
blank=True,
help_text="The URL of the case containing the destruction report for this destruction list.",
max_length=1000,
verbose_name="zaak destruction report URL",
),
),
]
27 changes: 27 additions & 0 deletions backend/src/openarchiefbeheer/destruction/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class DestructionList(models.Model):
"The URL of the case containing the destruction report for this destruction list."
),
blank=True,
max_length=1000,
)
processing_status = models.CharField(
_("processing status"),
Expand All @@ -119,6 +120,14 @@ class DestructionList(models.Model):
blank=True,
null=True,
)
internal_results = models.JSONField(
verbose_name=_("internal result"),
help_text=_(
"After this list is processed, the URL of the resources created in Open Zaak "
"to store the destruction report are stored here."
),
default=dict,
)

logs = GenericRelation(TimelineLog, related_query_name="destruction_list")

Expand Down Expand Up @@ -244,6 +253,24 @@ def generate_destruction_report(self) -> None:

self.save()

def create_report_zaak(self) -> None:
from .utils import (
attach_report_to_zaak,
create_eio_destruction_report,
create_zaak_for_report,
)

if self.processing_status == InternalStatus.succeeded:
return

destruction_list = self
store = ResultStore(store=destruction_list)

create_zaak_for_report(destruction_list, store)
create_eio_destruction_report(destruction_list, store)

attach_report_to_zaak(destruction_list, store)


class DestructionListItem(models.Model):
destruction_list = models.ForeignKey(
Expand Down
8 changes: 5 additions & 3 deletions backend/src/openarchiefbeheer/destruction/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,12 @@ def complete_and_notify(pk: int) -> None:
if destruction_list.has_failures():
raise DeletionProcessingError()

destruction_list.processing_status = InternalStatus.succeeded
destruction_list.save()

destruction_list.set_status(ListStatus.deleted)

destruction_list.generate_destruction_report()
destruction_list.create_report_zaak()

destruction_list.processing_status = InternalStatus.succeeded
destruction_list.save()

notify_assignees_successful_deletion(destruction_list)
123 changes: 123 additions & 0 deletions backend/src/openarchiefbeheer/destruction/utils.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
from base64 import b64encode
from typing import Protocol

from django.conf import settings
from django.core.mail import send_mail
from django.db import transaction
from django.db.models import OuterRef, Q, Subquery
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from zgw_consumers.client import build_client
from zgw_consumers.constants import APITypes
from zgw_consumers.models import Service

from openarchiefbeheer.accounts.models import User
from openarchiefbeheer.config.models import ArchiveConfig
from openarchiefbeheer.emails.models import EmailConfig
from openarchiefbeheer.emails.render_backend import get_sandboxed_backend
from openarchiefbeheer.utils.results_store import ResultStore
from openarchiefbeheer.zaken.models import Zaak

from .constants import InternalStatus, ListRole
Expand Down Expand Up @@ -121,3 +130,117 @@ def resync_items_and_zaken() -> None:
Zaak.objects.filter(url=OuterRef("_zaak_url")).values("pk")[:1]
)
)


def create_zaak_for_report(
destruction_list: DestructionList, store: ResultStore
) -> None:
config = ArchiveConfig.get_solo()

zrc_service = Service.objects.get(api_type=APITypes.zrc)
zrc_client = build_client(zrc_service)

with zrc_client:
if not destruction_list.zaak_destruction_report_url:
response = zrc_client.post(
"zaken",
headers={
"Accept-Crs": "EPSG:4326",
"Content-Crs": "EPSG:4326",
},
json={
"bronorganisatie": config.bronorganisatie,
"omschrijving": _("Destruction report of list: %(list_name)s")
% {"list_name": destruction_list.name},
"zaaktype": config.zaaktype,
"vertrouwelijkheidaanduiding": "openbaar",
"startdatum": timezone.now().date().isoformat(),
"verantwoordelijkeOrganisatie": config.bronorganisatie,
"archiefnominatie": "blijvend_bewaren",
},
timeout=settings.REQUESTS_DEFAULT_TIMEOUT,
)
response.raise_for_status()
new_zaak = response.json()

destruction_list.zaak_destruction_report_url = new_zaak["url"]
destruction_list.save()

if not store.has_created_resource("resultaten"):
response = zrc_client.post(
"resultaten",
json={
"zaak": destruction_list.zaak_destruction_report_url,
"resultaattype": config.resultaattype,
},
)
response.raise_for_status()
store.add_created_resource("resultaten", response.json()["url"])

if not store.has_created_resource("statussen"):
response = zrc_client.post(
"statussen",
json={
"zaak": destruction_list.zaak_destruction_report_url,
"statustype": config.statustype,
"datum_status_gezet": timezone.now().date().isoformat(),
},
)
response.raise_for_status()
store.add_created_resource("statussen", response.json()["url"])


def create_eio_destruction_report(
destruction_list: DestructionList, store: ResultStore
) -> None:
if store.has_created_resource("enkelvoudiginformatieobjecten"):
return

config = ArchiveConfig.get_solo()

drc_service = Service.objects.get(api_type=APITypes.drc)
drc_client = build_client(drc_service)

with drc_client, destruction_list.destruction_report.open("rb") as f_report:
response = drc_client.post(
"enkelvoudiginformatieobjecten",
json={
"bronorganisatie": config.bronorganisatie,
"creatiedatum": timezone.now().date().isoformat(),
"titel": _("Destruction report of list: %(list_name)s")
% {"list_name": destruction_list.name},
"auteur": "Open Archiefbeheer",
"taal": "nld",
"formaat": "text/csv",
"inhoud": b64encode(f_report.read()).decode("utf-8"),
"informatieobjecttype": config.informatieobjecttype,
"indicatie_gebruiksrecht": False,
},
)
response.raise_for_status()
new_document = response.json()

store.add_created_resource("enkelvoudiginformatieobjecten", new_document["url"])


def attach_report_to_zaak(
destruction_list: DestructionList, store: ResultStore
) -> None:
if store.has_created_resource("zaakinformatieobjecten"):
return

zrc_service = Service.objects.get(api_type=APITypes.zrc)
zrc_client = build_client(zrc_service)

with zrc_client:
response = zrc_client.post(
"zaakinformatieobjecten",
json={
"zaak": destruction_list.zaak_destruction_report_url,
"informatieobject": store.get_created_resources(
"enkelvoudiginformatieobjecten"
)[0],
},
)
response.raise_for_status()
store.add_created_resource("zaakinformatieobjecten", response.json()["url"])
23 changes: 23 additions & 0 deletions backend/src/openarchiefbeheer/utils/results_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

class InternalResults(TypedDict):
deleted_resources: dict[str, list]
created_resources: dict[str, list]
resources_to_delete: dict[str, list]
traceback: str = ""

Expand All @@ -27,6 +28,10 @@ def get_internal_results(self) -> InternalResults:

if not results.get("resources_to_delete"):
results["resources_to_delete"] = defaultdict(list)

if not results.get("created_resources"):
results["created_resources"] = defaultdict(list)

return results

def refresh_from_db(self) -> None:
Expand All @@ -48,16 +53,34 @@ def has_resource_to_delete(self, resource_type: str) -> bool:
and len(results["resources_to_delete"][resource_type]) > 0
)

def has_created_resource(self, resource_type: str) -> bool:
results = self.get_internal_results()

return (
resource_type in results["created_resources"]
and len(results["created_resources"][resource_type]) > 0
)

def add_resource_to_delete(self, resource_type: str, value: str) -> None:
results = self.get_internal_results()

results["resources_to_delete"][resource_type].append(value)
self.save()

def add_created_resource(self, resource_type: str, value) -> None:
results = self.get_internal_results()

results["created_resources"][resource_type].append(value)
self.save()

def get_resources_to_delete(self, resource_type: str) -> list[str]:
results = self.get_internal_results()
return results["resources_to_delete"][resource_type]

def get_created_resources(self, resource_type: str) -> list[str]:
results = self.get_internal_results()
return results["created_resources"][resource_type]

def clear_resources_to_delete(self, resource_type: str) -> None:
results = self.get_internal_results()
del results["resources_to_delete"][resource_type]
Expand Down

0 comments on commit fb69999

Please sign in to comment.