Skip to content

Commit

Permalink
Merge pull request #1453 from open-zaak/feature/1452-status-zio-new-p…
Browse files Browse the repository at this point in the history
…roperties

add new properties to Status and ZIO resources
  • Loading branch information
annashamray committed Sep 18, 2023
2 parents ae10fce + 470376e commit e552254
Show file tree
Hide file tree
Showing 15 changed files with 423 additions and 12 deletions.
16 changes: 13 additions & 3 deletions src/openzaak/components/zaken/admin/zaken.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class StatusAdmin(AuditTrailAdminMixin, UUIDAdminMixin, admin.ModelAdmin):
form = StatusForm
ordering = ("datum_status_gezet",)
date_hierarchy = "datum_status_gezet"
raw_id_fields = ("zaak", "_statustype", "_statustype_base_url")
raw_id_fields = ("zaak", "_statustype", "_statustype_base_url", "gezetdoor")
viewset = "openzaak.components.zaken.api.viewsets.StatusViewSet"


Expand Down Expand Up @@ -243,7 +243,12 @@ class ZaakInformatieObjectAdmin(AuditTrailAdminMixin, UUIDAdminMixin, admin.Mode
"titel",
"beschrijving",
)
list_select_related = ("zaak", "_informatieobject", "_informatieobject_base_url")
list_select_related = (
"zaak",
"_informatieobject",
"_informatieobject_base_url",
"status",
)
list_filter = ("aard_relatie",)
search_fields = (
"uuid",
Expand All @@ -261,7 +266,12 @@ class ZaakInformatieObjectAdmin(AuditTrailAdminMixin, UUIDAdminMixin, admin.Mode
"_informatieobject_base_url",
"_informatieobject_relative_url",
)
raw_id_fields = ("zaak", "_informatieobject", "_informatieobject_base_url")
raw_id_fields = (
"zaak",
"_informatieobject",
"_informatieobject_base_url",
"status",
)
viewset = "openzaak.components.zaken.api.viewsets.ZaakInformatieObjectViewSet"

def get_queryset(self, request):
Expand Down
24 changes: 23 additions & 1 deletion src/openzaak/components/zaken/api/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from urllib.parse import urlparse

from django.conf import settings
from django.db import models
from django.utils.translation import gettext_lazy as _

from django_filters import filters
Expand Down Expand Up @@ -166,9 +167,30 @@ class Meta:


class StatusFilter(FilterSet):
indicatie_laatst_gezette_status = filters.BooleanFilter(
method="filter_is_last_status",
help_text=_(
"Het gegeven is afleidbaar uit de historie van de attribuutsoort Datum "
"status gezet van van alle statussen bij de desbetreffende zaak."
),
)

class Meta:
model = Status
fields = ("zaak", "statustype")
fields = ("zaak", "statustype", "indicatie_laatst_gezette_status")

def filter_is_last_status(self, queryset, name, value):
if value is True:
return queryset.filter(
datum_status_gezet=models.F("max_datum_status_gezet")
)

if value is False:
return queryset.exclude(
datum_status_gezet=models.F("max_datum_status_gezet")
)

return queryset.none()


class ResultaatFilter(FilterSet):
Expand Down
22 changes: 22 additions & 0 deletions src/openzaak/components/zaken/api/serializers/zaken.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
HoofdzaakValidator,
NotSelfValidator,
RolOccurenceValidator,
StatusRolValidator,
UniekeIdentificatieValidator,
ZaakArchiveIOsArchivedValidator,
)
Expand Down Expand Up @@ -511,6 +512,9 @@ class Meta:
"statustype",
"datum_status_gezet",
"statustoelichting",
"indicatie_laatst_gezette_status",
"gezetdoor",
"zaakinformatieobjecten",
)
validators = [
UniqueTogetherValidator(
Expand All @@ -519,6 +523,7 @@ class Meta:
CorrectZaaktypeValidator("statustype"),
EndStatusIOsUnlockedValidator(),
EndStatusIOsIndicatieGebruiksrechtValidator(),
StatusRolValidator(),
]
extra_kwargs = {
"url": {"lookup_field": "uuid"},
Expand All @@ -533,6 +538,20 @@ class Meta:
LooseFkResourceValidator("StatusType", settings.ZTC_API_STANDARD),
],
},
"indicatie_laatst_gezette_status": {
"read_only": True,
"help_text": _(
"Het gegeven is afleidbaar uit de historie van de attribuutsoort Datum "
"status gezet van van alle statussen bij de desbetreffende zaak."
),
},
"gezetdoor": {"lookup_field": "uuid"},
"zaakinformatieobjecten": {
"lookup_field": "uuid",
"read_only": True,
"many": True,
"help_text": _("URL-referenties naar ZAAKINFORMATIEOBJECTen."),
},
}

def to_internal_value(self, data: dict) -> dict:
Expand Down Expand Up @@ -674,6 +693,8 @@ class Meta:
"titel",
"beschrijving",
"registratiedatum",
"vernietigingsdatum",
"status",
)
validators = [
UniqueTogetherValidator(
Expand All @@ -686,6 +707,7 @@ class Meta:
"url": {"lookup_field": "uuid"},
"uuid": {"read_only": True},
"zaak": {"lookup_field": "uuid", "validators": [IsImmutableValidator()]},
"status": {"lookup_field": "uuid"},
}

def create(self, validated_data):
Expand Down
14 changes: 14 additions & 0 deletions src/openzaak/components/zaken/api/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,3 +493,17 @@ def __call__(self, attrs: dict):
{"object": _("The object data does not match the specified schema.")},
code="invalid-schema",
)


class StatusRolValidator:
code = "zaak-mismatch"
message = _("De 'gezetdoor' rol hoort niet bij het zaak.")

def __call__(self, attrs):
gezetdoor = attrs.get("gezetdoor")
zaak = attrs.get("zaak")
if not gezetdoor:
return

if gezetdoor.zaak != zaak:
raise serializers.ValidationError(self.message, code=self.code)
6 changes: 4 additions & 2 deletions src/openzaak/components/zaken/api/viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,8 +422,10 @@ class StatusViewSet(
"""

queryset = Status.objects.select_related("_statustype", "zaak").order_by(
"-datum_status_gezet", "-pk"
queryset = (
Status.objects.select_related("_statustype", "zaak", "gezetdoor")
.annotate_with_max_datum_status_gezet()
.order_by("-datum_status_gezet", "-pk")
)
serializer_class = StatusSerializer
filterset_class = StatusFilter
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# SPDX-License-Identifier: EUPL-1.2
# Copyright (C) 2023 Dimpact
# Generated by Django 3.2.18 on 2023-08-30 10:55

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

dependencies = [
("zaken", "0025_auto_20230823_1221"),
]

operations = [
migrations.AddField(
model_name="status",
name="gezetdoor",
field=models.ForeignKey(
blank=True,
help_text="De BETROKKENE die in zijn/haar ROL in een ZAAK heeft geregistreerd dat STATUSsen in die ZAAK bereikt zijn.",
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="statussen",
to="zaken.rol",
verbose_name="gezet door",
),
),
migrations.AddField(
model_name="zaakinformatieobject",
name="status",
field=models.ForeignKey(
blank=True,
help_text="De bij de desbetreffende ZAAK behorende STATUS waarvoor het ZAAK-INFORMATIEOBJECT relevant is (geweest) met het oog op het bereiken van die STATUS en/of de communicatie daarover.",
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="zaakinformatieobjecten",
to="zaken.status",
verbose_name="status",
),
),
migrations.AddField(
model_name="zaakinformatieobject",
name="vernietigingsdatum",
field=models.DateTimeField(
blank=True,
help_text="De datum waarop het informatieobject uit het zaakdossier verwijderd moet worden.",
null=True,
verbose_name="vernietigingsdatum",
),
),
migrations.AlterField(
model_name="zaakinformatieobject",
name="_objectinformatieobject_url",
field=models.URLField(
blank=True,
help_text="URL of related ObjectInformatieObject object in the other API",
max_length=1000,
),
),
]
47 changes: 45 additions & 2 deletions src/openzaak/components/zaken/models/zaken.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@

from ..constants import AardZaakRelatie, BetalingsIndicatie, IndicatieMachtiging
from ..query import (
StatusQuerySet,
ZaakBesluitQuerySet,
ZaakInformatieObjectQuerySet,
ZaakQuerySet,
Expand Down Expand Up @@ -590,8 +591,20 @@ class Status(ETagMixin, models.Model):
help_text="Een, voor de initiator van de zaak relevante, toelichting "
"op de status van een zaak.",
)
gezetdoor = models.ForeignKey(
"zaken.Rol",
on_delete=models.CASCADE,
verbose_name=_("gezet door"),
related_name="statussen",
blank=True,
null=True,
help_text=_(
"De BETROKKENE die in zijn/haar ROL in een ZAAK heeft geregistreerd "
"dat STATUSsen in die ZAAK bereikt zijn."
),
)

objects = ZaakRelatedQuerySet.as_manager()
objects = StatusQuerySet.as_manager()

class Meta:
verbose_name = "status"
Expand All @@ -605,6 +618,14 @@ def __str__(self):
def unique_representation(self):
return f"({self.zaak.unique_representation()}) - {self.datum_status_gezet}"

@property
def indicatie_laatst_gezette_status(self) -> bool:
"""⚡️ use annotated field when possible """
if hasattr(self, "max_datum_status_gezet"):
return self.max_datum_status_gezet == self.datum_status_gezet

return self.zaak.current_status_uuid == self.uuid


class Resultaat(ETagMixin, models.Model):
"""
Expand Down Expand Up @@ -1038,7 +1059,29 @@ class ZaakInformatieObject(ETagMixin, models.Model):
_objectinformatieobject_url = models.URLField(
blank=True,
max_length=1000,
help_text="URL of related IbjectInformatieObject object in the other API",
help_text="URL of related ObjectInformatieObject object in the other API",
)
vernietigingsdatum = models.DateTimeField(
_("vernietigingsdatum"),
help_text=_(
"De datum waarop het informatieobject uit het zaakdossier verwijderd "
"moet worden."
),
null=True,
blank=True,
)
status = models.ForeignKey(
Status,
on_delete=models.CASCADE,
verbose_name=_("status"),
related_name="zaakinformatieobjecten",
help_text=_(
"De bij de desbetreffende ZAAK behorende STATUS waarvoor het "
"ZAAK-INFORMATIEOBJECT relevant is (geweest) met het oog op het bereiken "
"van die STATUS en/of de communicatie daarover."
),
blank=True,
null=True,
)

objects = ZaakInformatieObjectQuerySet.as_manager()
Expand Down
44 changes: 44 additions & 0 deletions src/openzaak/components/zaken/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1159,6 +1159,13 @@ paths:
schema:
type: string
format: uri
- name: indicatieLaatstGezetteStatus
in: query
description: Het gegeven is afleidbaar uit de historie van de attribuutsoort
Datum status gezet van van alle statussen bij de desbetreffende zaak.
required: false
schema:
type: string
- name: page
in: query
description: Een pagina binnen de gepagineerde set resultaten.
Expand Down Expand Up @@ -5435,6 +5442,28 @@ components:
de status van een zaak.
type: string
maxLength: 1000
indicatieLaatstGezetteStatus:
title: Indicatie laatst gezette status
description: Het gegeven is afleidbaar uit de historie van de attribuutsoort
Datum status gezet van van alle statussen bij de desbetreffende zaak.
type: boolean
readOnly: true
gezetdoor:
title: Gezet door
description: De BETROKKENE die in zijn/haar ROL in een ZAAK heeft geregistreerd
dat STATUSsen in die ZAAK bereikt zijn.
type: string
format: uri
nullable: true
zaakinformatieobjecten:
description: URL-referenties naar ZAAKINFORMATIEOBJECTen.
type: array
items:
description: URL-referenties naar ZAAKINFORMATIEOBJECTen.
type: string
format: uri
readOnly: true
uniqueItems: true
ZaakContactMoment:
required:
- zaak
Expand Down Expand Up @@ -5528,6 +5557,21 @@ components:
type: string
format: date-time
readOnly: true
vernietigingsdatum:
title: Vernietigingsdatum
description: De datum waarop het informatieobject uit het zaakdossier verwijderd
moet worden.
type: string
format: date-time
nullable: true
status:
title: Status
description: De bij de desbetreffende ZAAK behorende STATUS waarvoor het
ZAAK-INFORMATIEOBJECT relevant is (geweest) met het oog op het bereiken
van die STATUS en/of de communicatie daarover.
type: string
format: uri
nullable: true
ObjectTypeOverigeDefinitie:
description: 'Verwijzing naar het schema van het type OBJECT als `objectType`
de waarde "overige" heeft.
Expand Down
15 changes: 15 additions & 0 deletions src/openzaak/components/zaken/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ class ZaakRelatedQuerySet(ZaakAuthorizationsFilterMixin, models.QuerySet):
authorizations_lookup = "zaak"


class StatusQuerySet(ZaakRelatedQuerySet):
def annotate_with_max_datum_status_gezet(self):
"""
add `max_datum_status_gezet` of all statuses grouped by zaak
"""
grouped_statussen = (
self.filter(zaak=models.OuterRef("zaak"))
.order_by()
.values("zaak")
.annotate(max_datum_status_gezet=models.Max("datum_status_gezet"))
.values("max_datum_status_gezet")
)
return self.annotate(max_datum_status_gezet=models.Subquery(grouped_statussen))


class ZaakInformatieObjectQuerySet(BlockChangeMixin, ZaakRelatedQuerySet):
def filter(self, *args, **kwargs):
if settings.CMIS_ENABLED and "informatieobject" in kwargs:
Expand Down

0 comments on commit e552254

Please sign in to comment.