Skip to content

Commit fd0d080

Browse files
committed
✨ [#386] Add validation for bewaartermijn
1 parent dc5a925 commit fd0d080

File tree

3 files changed

+105
-24
lines changed

3 files changed

+105
-24
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
class ServiceNotConfigured(Exception):
2+
pass

backend/src/openarchiefbeheer/destruction/api/serializers.py

+87-24
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from django.utils.translation import gettext_lazy as _
66

77
from drf_spectacular.utils import extend_schema_field
8+
from requests.exceptions import HTTPError
89
from rest_framework import serializers
910
from rest_framework.exceptions import ValidationError
1011
from rest_framework.relations import SlugRelatedField
@@ -16,6 +17,7 @@
1617
from openarchiefbeheer.zaken.api.filtersets import ZaakFilter
1718
from openarchiefbeheer.zaken.api.serializers import ZaakSerializer
1819
from openarchiefbeheer.zaken.models import Zaak
20+
from openarchiefbeheer.zaken.utils import retrieve_selectielijstklasse_resultaat
1921

2022
from ..constants import (
2123
DestructionListItemAction,
@@ -497,6 +499,11 @@ def to_internal_value(self, data: dict) -> dict:
497499

498500

499501
class ReviewItemResponseSerializer(serializers.ModelSerializer):
502+
review_item = serializers.PrimaryKeyRelatedField(
503+
queryset=DestructionListItemReview.objects.all().select_related(
504+
"destruction_list_item__zaak"
505+
),
506+
)
500507
action_zaak = ActionZaakSerializer(required=False)
501508

502509
class Meta:
@@ -511,8 +518,79 @@ class Meta:
511518
"comment",
512519
)
513520

521+
def _get_selectielijst_resultaat(self, resultaat_url: str) -> dict:
522+
try:
523+
resultaat = retrieve_selectielijstklasse_resultaat(resultaat_url)
524+
except HTTPError:
525+
raise ValidationError(
526+
_(
527+
"Could not validate the selectielijstklasse waardering "
528+
"due to an unexpected response from the Selectielijst API."
529+
)
530+
)
531+
532+
return resultaat
533+
534+
def _validate_action_zaak_with_type(
535+
self,
536+
action_zaak: dict,
537+
action_zaak_type: str,
538+
review_item: DestructionListItemReview,
539+
) -> None:
540+
# TODO this could be refactored using a polymorphic serializer
541+
selectielijstklasse = action_zaak.get("selectielijstklasse")
542+
archiefactiedatum = action_zaak.get("archiefactiedatum")
543+
544+
match action_zaak_type:
545+
case ZaakActionType.selectielijstklasse_and_bewaartermijn:
546+
if not selectielijstklasse:
547+
raise ValidationError(
548+
{
549+
"selectielijstklasse": _(
550+
"The selectielijstklasse is required for action type "
551+
"is 'selectielijstklasse_and_bewaartermijn'."
552+
)
553+
}
554+
)
555+
556+
resultaat = self._get_selectielijst_resultaat(selectielijstklasse)
557+
if resultaat["waardering"] == "blijvend_bewaren" and archiefactiedatum:
558+
raise ValidationError(
559+
{
560+
"selectielijstklasse": _(
561+
"The selectielijstklasse has waardering 'blijvend_bewaren', "
562+
"so the archiefactiedatum should be null."
563+
)
564+
}
565+
)
566+
567+
case ZaakActionType.bewaartermijn:
568+
if selectielijstklasse:
569+
raise ValidationError(
570+
{
571+
"action_zaak_type": _(
572+
"The selectielijstklasse cannot be changed if the case action type is 'bewaartermijn'."
573+
)
574+
}
575+
)
576+
577+
resultaat = self._get_selectielijst_resultaat(
578+
review_item.destruction_list_item.zaak.selectielijstklasse
579+
)
580+
if resultaat["waardering"] == "blijvend_bewaren":
581+
raise ValidationError(
582+
{
583+
"archiefactiedatum": _(
584+
"The selectielijstklasse has waardering 'blijvend_bewaren', "
585+
"so an archiefactiedatum cannot be set."
586+
)
587+
}
588+
)
589+
514590
def validate(self, attrs: dict) -> dict:
515591
action_zaak = attrs.get("action_zaak", {})
592+
action_zaak_type = attrs.get("action_zaak_type", {})
593+
516594
if attrs["action_item"] == DestructionListItemAction.keep and action_zaak:
517595
raise ValidationError(
518596
{
@@ -522,32 +600,17 @@ def validate(self, attrs: dict) -> dict:
522600
}
523601
)
524602

525-
zaak_action_type = attrs.get("action_zaak_type")
526-
selectielijstklasse = action_zaak.get("selectielijstklasse")
527-
if (
528-
attrs["action_item"] == DestructionListItemAction.remove
529-
and zaak_action_type == ZaakActionType.bewaartermijn
530-
and selectielijstklasse
531-
):
532-
raise ValidationError(
533-
{
534-
"action_zaak_type": _(
535-
"The selectielijstklasse cannot be changed if the case action type is 'bewaartermijn'."
603+
if attrs["action_item"] == DestructionListItemAction.remove:
604+
if not action_zaak_type or not action_zaak:
605+
raise ValidationError(
606+
_(
607+
"When removing an item from a destruction list, "
608+
"the fields action_zaak_type and action_zaak are required."
536609
)
537-
}
538-
)
610+
)
539611

540-
if (
541-
attrs["action_item"] == DestructionListItemAction.remove
542-
and zaak_action_type == ZaakActionType.selectielijstklasse_and_bewaartermijn
543-
and not selectielijstklasse
544-
):
545-
raise ValidationError(
546-
{
547-
"selectielijstklasse": _(
548-
"The selectielijstklasse is required for action type is 'selectielijstklasse_and_bewaartermijn'."
549-
)
550-
}
612+
self._validate_action_zaak_with_type(
613+
action_zaak, action_zaak_type, attrs["review_item"]
551614
)
552615

553616
return attrs

backend/src/openarchiefbeheer/zaken/utils.py

+16
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from zgw_consumers.models import Service
2121
from zgw_consumers.utils import PaginatedResponseData
2222

23+
from openarchiefbeheer.config.exceptions import ServiceNotConfigured
2324
from openarchiefbeheer.config.models import APIConfig
2425
from openarchiefbeheer.utils.datastructure import HashableDict
2526
from openarchiefbeheer.utils.results_store import ResultStore
@@ -148,6 +149,21 @@ def retrieve_selectielijstklasse_choices(query_params: HashableDict | None) -> l
148149
return results
149150

150151

152+
@lru_cache
153+
def retrieve_selectielijstklasse_resultaat(resultaat_url: str) -> dict:
154+
config = APIConfig.get_solo()
155+
selectielijst_service = config.selectielijst_api_service
156+
if not selectielijst_service:
157+
raise ServiceNotConfigured(msg="No selectielijst API service configured.")
158+
159+
client = build_client(selectielijst_service)
160+
with client:
161+
response = client.get(resultaat_url)
162+
response.raise_for_status()
163+
164+
return response.json()
165+
166+
151167
def delete_object_and_store_result(
152168
store: ResultStore,
153169
resource_type: str,

0 commit comments

Comments
 (0)