예제 #1
0
class ZaakEigenschap(models.Model):
    """
    Een relevant inhoudelijk gegeven waarvan waarden bij
    ZAAKen van eenzelfde ZAAKTYPE geregistreerd moeten
    kunnen worden en dat geen standaard kenmerk is van een
    ZAAK.

    Het RGBZ biedt generieke kenmerken van zaken. Bij zaken van een bepaald zaaktype kan de
    behoefte bestaan om waarden uit te wisselen van gegevens die specifiek zijn voor die zaken. Met
    dit groepattribuutsoort simuleren we de aanwezigheid van dergelijke eigenschappen. Aangezien
    deze eigenschappen specifiek zijn per zaaktype, modelleren we deze eigenschappen hier niet
    specifiek. De eigenschappen worden per zaaktype in een desbetreffende zaaktypecatalogus
    gespecificeerd.

    TODO: on save/submit, validate the value format against the defined eigenschap format
    """

    uuid = models.UUIDField(unique=True,
                            default=uuid.uuid4,
                            help_text="Unieke resource identifier (UUID4)")
    zaak = models.ForeignKey(Zaak, on_delete=models.CASCADE)
    _eigenschap_url = models.URLField(
        _("externe eigenschap"),
        blank=True,
        max_length=1000,
        help_text=
        _("URL-referentie naar externe EIGENSCHAP (in een andere Catalogi API)."
          ),
    )
    _eigenschap = models.ForeignKey(
        "catalogi.Eigenschap",
        on_delete=models.CASCADE,
        help_text="URL-referentie naar de EIGENSCHAP (in de Catalogi API).",
        null=True,
        blank=True,
    )
    eigenschap = FkOrURLField(
        fk_field="_eigenschap",
        url_field="_eigenschap_url",
        help_text=_("URL-referentie naar de EIGENSCHAP (in de Catalogi API)."),
    )

    _naam = models.CharField(
        max_length=20,
        help_text=_(
            "De naam van de EIGENSCHAP (overgenomen uit de Catalogi API)."),
    )
    waarde = models.TextField()

    objects = ZaakRelatedQuerySet.as_manager()

    class Meta:
        verbose_name = "zaakeigenschap"
        verbose_name_plural = "zaakeigenschappen"

    def __str__(self):
        return f"{self._naam}: {self.waarde}"

    def unique_representation(self):
        return f"({self.zaak.unique_representation()}) - {self._naam}"
예제 #2
0
class Status(models.Model):
    """
    Modelleer een status van een ZAAK.

    Een aanduiding van de stand van zaken van een ZAAK op basis van
    betekenisvol behaald resultaat voor de initiator van de ZAAK.
    """

    uuid = models.UUIDField(unique=True,
                            default=uuid.uuid4,
                            help_text="Unieke resource identifier (UUID4)")
    # relaties
    zaak = models.ForeignKey(Zaak,
                             on_delete=models.CASCADE,
                             help_text=("URL-referentie naar de ZAAK."))

    _statustype_url = models.URLField(
        _("extern statustype"),
        blank=True,
        max_length=1000,
        help_text=
        _("URL-referentie naar extern STATUSTYPE (in een andere Catalogi API)."
          ),
    )
    _statustype = models.ForeignKey(
        "catalogi.StatusType",
        on_delete=models.CASCADE,
        help_text="URL-referentie naar het STATUSTYPE (in de Catalogi API).",
        null=True,
        blank=True,
    )
    statustype = FkOrURLField(
        fk_field="_statustype",
        url_field="_statustype_url",
        help_text=_(
            "URL-referentie naar het STATUSTYPE (in de Catalogi API)."),
    )

    # extra informatie
    datum_status_gezet = models.DateTimeField(
        help_text="De datum waarop de ZAAK de status heeft verkregen.")
    statustoelichting = models.TextField(
        max_length=1000,
        blank=True,
        help_text="Een, voor de initiator van de zaak relevante, toelichting "
        "op de status van een zaak.",
    )

    objects = ZaakRelatedQuerySet.as_manager()

    class Meta:
        verbose_name = "status"
        verbose_name_plural = "statussen"
        unique_together = ("zaak", "datum_status_gezet")

    def __str__(self):
        return "Status op {}".format(self.datum_status_gezet)

    def unique_representation(self):
        return f"({self.zaak.unique_representation()}) - {self.datum_status_gezet}"
예제 #3
0
class ZaakBesluit(models.Model):
    uuid = models.UUIDField(
        unique=True, default=uuid.uuid4, help_text="Unieke resource identifier (UUID4)"
    )
    zaak = models.ForeignKey(
        Zaak, on_delete=models.CASCADE, help_text=_("URL-referentie naar de ZAAK.")
    )

    _besluit_url = models.URLField(
        _("extern besluit"),
        blank=True,
        max_length=1000,
        help_text=_(
            "URL-referentie naar extern BESLUIT (in een andere Besluiten API)."
        ),
    )
    _besluit = models.ForeignKey(
        "besluiten.Besluit",
        on_delete=models.CASCADE,
        help_text="URL-referentie naar het BESLUIT (in de Besluiten API).",
        null=True,
        blank=True,
    )
    besluit = FkOrURLField(
        fk_field="_besluit",
        url_field="_besluit_url",
        help_text="URL-referentie naar het BESLUIT (in de Besluiten API).",
    )

    objects = ZaakBesluitQuerySet.as_manager()

    class Meta:
        verbose_name = _("zaakbesluit")
        verbose_name_plural = _("zaakbesluiten")
        unique_together = ("zaak", "_besluit")
        constraints = [
            models.UniqueConstraint(
                fields=["zaak", "_besluit_url"],
                condition=~models.Q(_besluit_url=""),
                name="unique_zaak_and_besluit",
            )
        ]

    def __str__(self):
        try:
            return _("Relation between {zaak} and {besluit}").format(
                zaak=self.zaak, besluit=self.besluit
            )
        except FetchError:
            return _("Relation between {zaak} and {besluit}").format(
                zaak=self.zaak, besluit=self._besluit_url
            )

    def unique_representation(self):
        zaak_repr = self.zaak.unique_representation()

        return f"({zaak_repr}) - {self.besluit.identificatie}"
예제 #4
0
class Resultaat(models.Model):
    """
    Het behaalde RESULTAAT is een koppeling tussen een RESULTAATTYPE en een
    ZAAK.
    """

    uuid = models.UUIDField(unique=True,
                            default=uuid.uuid4,
                            help_text="Unieke resource identifier (UUID4)")
    # relaties
    zaak = models.OneToOneField(Zaak,
                                on_delete=models.CASCADE,
                                help_text=("URL-referentie naar de ZAAK."))

    _resultaattype_url = models.URLField(
        _("extern resultaattype"),
        blank=True,
        max_length=1000,
        help_text=
        _("URL-referentie naar extern RESULTAATTYPE (in een andere Catalogi API)."
          ),
    )
    _resultaattype = models.ForeignKey(
        "catalogi.ResultaatType",
        on_delete=models.CASCADE,
        help_text="URL-referentie naar het RESULTAATTYPE (in de Catalogi API).",
        null=True,
        blank=True,
    )
    resultaattype = FkOrURLField(
        fk_field="_resultaattype",
        url_field="_resultaattype_url",
        help_text=_(
            "URL-referentie naar het RESULTAATTYPE (in de Catalogi API)."),
    )

    toelichting = models.TextField(
        max_length=1000,
        blank=True,
        help_text="Een toelichting op wat het resultaat van de zaak inhoudt.",
    )

    objects = ZaakRelatedQuerySet.as_manager()

    class Meta:
        verbose_name = "resultaat"
        verbose_name_plural = "resultaten"

    def __str__(self):
        return "Resultaat ({})".format(self.uuid)

    def unique_representation(self):
        return (
            f"({self.zaak.unique_representation()}) - {self.resultaattype.omschrijving}"
        )
예제 #5
0
class RelevanteZaakRelatie(models.Model):
    """
    Registreer een ZAAK als relevant voor een andere ZAAK
    """

    zaak = models.ForeignKey(Zaak,
                             on_delete=models.CASCADE,
                             related_name="relevante_andere_zaken")

    _relevant_zaak_url = models.URLField(
        _("externe relevante zaak"),
        blank=True,
        max_length=1000,
        help_text=_(
            "URL-referentie naar extern ZAAK (in een andere zaken API)"),
    )
    _relevant_zaak = models.ForeignKey(
        Zaak,
        on_delete=models.CASCADE,
        verbose_name=_("relevante zaak"),
        help_text=_("URL-referentie naar de ZAAK."),
        null=True,
        blank=True,
    )
    url = FkOrURLField(
        fk_field="_relevant_zaak",
        url_field="_relevant_zaak_url",
        help_text=_("URL-referentie naar de ZAAK."),
    )

    aard_relatie = models.CharField(
        max_length=20,
        choices=AardZaakRelatie.choices,
        help_text=
        _("Benamingen van de aard van de relaties van andere zaken tot (onderhanden) zaken."
          ),
    )
예제 #6
0
class ZaakInformatieObject(models.Model):
    """
    Modelleer INFORMATIEOBJECTen die bij een ZAAK horen.
    """

    uuid = models.UUIDField(unique=True,
                            default=uuid.uuid4,
                            help_text="Unieke resource identifier (UUID4)")
    zaak = models.ForeignKey(Zaak,
                             on_delete=models.CASCADE,
                             help_text=("URL-referentie naar de ZAAK."))
    _informatieobject_url = models.URLField(
        _("External informatieobject"),
        blank=True,
        max_length=1000,
        help_text=_("URL to the informatieobject in an external API"),
    )
    _informatieobject = models.ForeignKey(
        "documenten.EnkelvoudigInformatieObjectCanonical",
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        help_text=
        "URL-referentie naar het INFORMATIEOBJECT (in de Documenten API), waar "
        "ook de relatieinformatie opgevraagd kan worden.",
    )
    informatieobject = FkOrURLField(
        fk_field="_informatieobject",
        url_field="_informatieobject_url",
        loader=EIOLoader(),
        help_text=_(
            "URL-referentie naar het INFORMATIEOBJECT (in de Documenten "
            "API), waar ook de relatieinformatie opgevraagd kan worden."),
    )
    aard_relatie = models.CharField("aard relatie",
                                    max_length=20,
                                    choices=RelatieAarden.choices)

    # relatiegegevens
    titel = models.CharField(
        "titel",
        max_length=200,
        blank=True,
        help_text=
        "De naam waaronder het INFORMATIEOBJECT binnen het OBJECT bekend is.",
    )
    beschrijving = models.TextField(
        "beschrijving",
        blank=True,
        help_text="Een op het object gerichte beschrijving van de inhoud van"
        "het INFORMATIEOBJECT.",
    )
    registratiedatum = models.DateTimeField(
        "registratiedatum",
        auto_now_add=True,
        help_text="De datum waarop de behandelende organisatie het "
        "INFORMATIEOBJECT heeft geregistreerd bij het OBJECT. "
        "Geldige waardes zijn datumtijden gelegen op of voor de "
        "huidige datum en tijd.",
    )
    _objectinformatieobject_url = models.URLField(
        blank=True,
        max_length=1000,
        help_text=
        "URL of related IbjectInformatieObject object in the other API",
    )

    objects = ZaakInformatieObjectQuerySet.as_manager()

    class Meta:
        verbose_name = "zaakinformatieobject"
        verbose_name_plural = "zaakinformatieobjecten"
        unique_together = ("zaak", "_informatieobject")
        constraints = [
            models.UniqueConstraint(
                fields=["zaak", "_informatieobject_url"],
                condition=~models.Q(_informatieobject_url=""),
                name="unique_zaak_and_external_document",
            )
        ]

    def __str__(self) -> str:
        # In case of an external informatieobject, use the URL as fallback
        try:
            return f"{self.zaak} - {self.informatieobject}"
        except FetchError:
            return f"{self.zaak} - {self._informatieobject_url}"

    def unique_representation(self):
        zaak_repr = self.zaak.unique_representation()

        if hasattr(self.informatieobject, "identificatie"):
            doc_identificatie = self.informatieobject.identificatie
        else:
            doc_identificatie = self.informatieobject.latest_version.identificatie

        return f"({zaak_repr}) - {doc_identificatie}"

    def save(self, *args, **kwargs):
        # override to set aard_relatie
        self.aard_relatie = RelatieAarden.from_object_type("zaak")
        super().save(*args, **kwargs)
예제 #7
0
class Zaak(AuditTrailMixin, APIMixin, models.Model):
    """
    Modelleer de structuur van een ZAAK.

    Een samenhangende hoeveelheid werk met een welgedefinieerde aanleiding
    en een welgedefinieerd eindresultaat, waarvan kwaliteit en doorlooptijd
    bewaakt moeten worden.
    """

    uuid = models.UUIDField(unique=True,
                            default=uuid.uuid4,
                            help_text="Unieke resource identifier (UUID4)")

    # Relate 'is_deelzaak_van'
    # De relatie vanuit een zaak mag niet verwijzen naar
    # dezelfde zaak d.w.z. moet verwijzen naar een andere
    # zaak. Die andere zaak mag geen relatie ?is deelzaak
    # van? hebben (d.w.z. deelzaken van deelzaken worden
    # niet ondersteund).
    hoofdzaak = models.ForeignKey(
        "self",
        limit_choices_to={"hoofdzaak__isnull": True},
        null=True,
        blank=True,
        on_delete=models.CASCADE,
        related_name="deelzaken",
        verbose_name="is deelzaak van",
        help_text=_("URL-referentie naar de ZAAK, waarom verzocht is door de "
                    "initiator daarvan, die behandeld wordt in twee of meer "
                    "separate ZAAKen waarvan de onderhavige ZAAK er één is."),
    )

    identificatie = models.CharField(
        max_length=40,
        blank=True,
        help_text="De unieke identificatie van de ZAAK binnen de organisatie "
        "die verantwoordelijk is voor de behandeling van de ZAAK.",
        validators=[alphanumeric_excluding_diacritic],
        db_index=True,
    )
    bronorganisatie = RSINField(
        help_text="Het RSIN van de Niet-natuurlijk persoon zijnde de "
        "organisatie die de zaak heeft gecreeerd. Dit moet een geldig "
        "RSIN zijn van 9 nummers en voldoen aan "
        "https://nl.wikipedia.org/wiki/Burgerservicenummer#11-proef")
    omschrijving = models.CharField(
        max_length=80,
        blank=True,
        help_text="Een korte omschrijving van de zaak.")
    toelichting = models.TextField(max_length=1000,
                                   blank=True,
                                   help_text="Een toelichting op de zaak.")

    _zaaktype_url = models.URLField(
        _("extern zaaktype"),
        blank=True,
        max_length=1000,
        help_text=_(
            "URL-referentie naar extern ZAAKTYPE (in een andere Catalogi API)."
        ),
    )
    _zaaktype = models.ForeignKey(
        "catalogi.ZaakType",
        on_delete=models.CASCADE,
        help_text="URL-referentie naar het ZAAKTYPE (in de Catalogi API).",
        null=True,
        blank=True,
    )
    zaaktype = FkOrURLField(
        fk_field="_zaaktype",
        url_field="_zaaktype_url",
        help_text="URL-referentie naar het ZAAKTYPE (in de Catalogi API).",
    )

    registratiedatum = models.DateField(
        help_text="De datum waarop de zaakbehandelende organisatie de ZAAK "
        "heeft geregistreerd. Indien deze niet opgegeven wordt, "
        "wordt de datum van vandaag gebruikt.",
        default=date.today,
    )
    verantwoordelijke_organisatie = RSINField(
        help_text=
        "Het RSIN van de Niet-natuurlijk persoon zijnde de organisatie "
        "die eindverantwoordelijk is voor de behandeling van de "
        "zaak. Dit moet een geldig RSIN zijn van 9 nummers en voldoen aan "
        "https://nl.wikipedia.org/wiki/Burgerservicenummer#11-proef")

    startdatum = models.DateField(
        help_text="De datum waarop met de uitvoering van de zaak is gestart",
        db_index=True,
    )
    einddatum = models.DateField(
        blank=True,
        null=True,
        help_text="De datum waarop de uitvoering van de zaak afgerond is.",
    )
    einddatum_gepland = models.DateField(
        blank=True,
        null=True,
        help_text="De datum waarop volgens de planning verwacht wordt dat de "
        "zaak afgerond wordt.",
    )
    uiterlijke_einddatum_afdoening = models.DateField(
        blank=True,
        null=True,
        help_text="De laatste datum waarop volgens wet- en regelgeving de zaak "
        "afgerond dient te zijn.",
    )
    publicatiedatum = models.DateField(
        _("publicatiedatum"),
        null=True,
        blank=True,
        help_text=_(
            "Datum waarop (het starten van) de zaak gepubliceerd is of wordt."
        ),
    )

    producten_of_diensten = ArrayField(
        models.URLField(_("URL naar product/dienst"), max_length=1000),
        default=list,
        help_text=_(
            "De producten en/of diensten die door de zaak worden voortgebracht. "
            "Dit zijn URLs naar de resources zoals die door de producten- "
            "en dienstencatalogus-API wordt ontsloten. "
            "De producten/diensten moeten bij het zaaktype vermeld zijn."),
        blank=True,
    )

    communicatiekanaal = models.URLField(
        _("communicatiekanaal"),
        blank=True,
        max_length=1000,
        help_text=
        _("Het medium waarlangs de aanleiding om een zaak te starten is ontvangen. "
          "URL naar een communicatiekanaal in de VNG-Referentielijst van communicatiekanalen."
          ),
    )

    vertrouwelijkheidaanduiding = VertrouwelijkheidsAanduidingField(
        _("vertrouwlijkheidaanduiding"),
        help_text=
        _("Aanduiding van de mate waarin het zaakdossier van de ZAAK voor de openbaarheid bestemd is."
          ),
    )

    betalingsindicatie = models.CharField(
        _("betalingsindicatie"),
        max_length=20,
        blank=True,
        choices=BetalingsIndicatie.choices,
        help_text=_("Indicatie of de, met behandeling van de zaak gemoeide, "
                    "kosten betaald zijn door de desbetreffende betrokkene."),
    )
    laatste_betaaldatum = models.DateTimeField(
        _("laatste betaaldatum"),
        blank=True,
        null=True,
        help_text=_(
            "De datum waarop de meest recente betaling is verwerkt "
            "van kosten die gemoeid zijn met behandeling van de zaak."),
    )

    zaakgeometrie = GeometryField(
        blank=True,
        null=True,
        help_text="Punt, lijn of (multi-)vlak geometrie-informatie.",
    )

    verlenging_reden = models.CharField(
        _("reden verlenging"),
        max_length=200,
        blank=True,
        help_text=
        _("Omschrijving van de reden voor het verlengen van de behandeling van de zaak."
          ),
    )
    verlenging_duur = DurationField(
        _("duur verlenging"),
        blank=True,
        null=True,
        help_text=_(
            "Het aantal werkbare dagen waarmee de doorlooptijd van de "
            "behandeling van de ZAAK is verlengd (of verkort) ten opzichte "
            "van de eerder gecommuniceerde doorlooptijd."),
    )
    verlenging = GegevensGroepType({
        "reden": verlenging_reden,
        "duur": verlenging_duur
    })

    opschorting_indicatie = models.BooleanField(
        _("indicatie opschorting"),
        default=False,
        blank=True,
        help_text=_(
            "Aanduiding of de behandeling van de ZAAK tijdelijk is opgeschort."
        ),
    )
    opschorting_reden = models.CharField(
        _("reden opschorting"),
        max_length=200,
        blank=True,
        help_text=
        _("Omschrijving van de reden voor het opschorten van de behandeling van de zaak."
          ),
    )
    opschorting = GegevensGroepType({
        "indicatie": opschorting_indicatie,
        "reden": opschorting_reden
    })

    selectielijstklasse = models.URLField(
        _("selectielijstklasse"),
        blank=True,
        max_length=1000,
        help_text=
        _("URL-referentie naar de categorie in de gehanteerde 'Selectielijst Archiefbescheiden' die, gezien "
          "het zaaktype en het resultaattype van de zaak, bepalend is voor het archiefregime van de zaak."
          ),
    )

    # Archiving
    archiefnominatie = models.CharField(
        _("archiefnominatie"),
        max_length=40,
        null=True,
        blank=True,
        choices=Archiefnominatie.choices,
        help_text=
        _("Aanduiding of het zaakdossier blijvend bewaard of na een bepaalde termijn vernietigd moet worden."
          ),
        db_index=True,
    )
    archiefstatus = models.CharField(
        _("archiefstatus"),
        max_length=40,
        choices=Archiefstatus.choices,
        default=Archiefstatus.nog_te_archiveren,
        help_text=
        _("Aanduiding of het zaakdossier blijvend bewaard of na een bepaalde termijn vernietigd moet worden."
          ),
        db_index=True,
    )
    archiefactiedatum = models.DateField(
        _("archiefactiedatum"),
        null=True,
        blank=True,
        help_text=
        _("De datum waarop het gearchiveerde zaakdossier vernietigd moet worden dan wel overgebracht moet "
          "worden naar een archiefbewaarplaats. Wordt automatisch berekend bij het aanmaken of wijzigen van "
          "een RESULTAAT aan deze ZAAK indien nog leeg."),
        db_index=True,
    )

    objects = ZaakQuerySet.as_manager()

    class Meta:
        verbose_name = "zaak"
        verbose_name_plural = "zaken"
        unique_together = ("bronorganisatie", "identificatie")

    def __str__(self):
        return self.identificatie

    def save(self, *args, **kwargs):
        if not self.identificatie:
            self.identificatie = generate_unique_identification(
                self, "registratiedatum")

        if (self.betalingsindicatie == BetalingsIndicatie.nvt
                and self.laatste_betaaldatum):
            self.laatste_betaaldatum = None

        super().save(*args, **kwargs)

    @property
    def current_status_uuid(self):
        status = self.status_set.first()
        return status.uuid if status else None

    @property
    def is_closed(self) -> bool:
        return self.einddatum is not None

    def unique_representation(self):
        return f"{self.bronorganisatie} - {self.identificatie}"
예제 #8
0
class Rol(models.Model):
    """
    Modelleer de rol van een BETROKKENE bij een ZAAK.

    Een of meerdere BETROKKENEn hebben een of meerdere ROL(len) in een ZAAK.
    """

    uuid = models.UUIDField(unique=True,
                            default=uuid.uuid4,
                            help_text="Unieke resource identifier (UUID4)")
    zaak = models.ForeignKey(Zaak,
                             on_delete=models.CASCADE,
                             help_text=("URL-referentie naar de ZAAK."))
    betrokkene = models.URLField(
        help_text="URL-referentie naar een betrokkene gerelateerd aan de ZAAK.",
        max_length=1000,
        blank=True,
        db_index=True,
    )
    betrokkene_type = models.CharField(
        max_length=100,
        choices=RolTypes.choices,
        help_text="Type van de `betrokkene`.",
        db_index=True,
    )

    _roltype_url = models.URLField(
        _("extern roltype"),
        blank=True,
        max_length=1000,
        help_text=_(
            "URL-referentie naar extern ROLTYPE (in een andere Catalogi API)."
        ),
    )
    _roltype = models.ForeignKey(
        "catalogi.RolType",
        on_delete=models.CASCADE,
        help_text="URL-referentie naar het ROLTYPE (in de Catalogi API).",
        null=True,
        blank=True,
    )
    roltype = FkOrURLField(
        fk_field="_roltype",
        url_field="_roltype_url",
        help_text=_(
            "URL-referentie naar een roltype binnen het ZAAKTYPE van de ZAAK."
        ),
    )

    omschrijving = models.CharField(
        _("omschrijving"),
        max_length=20,
        editable=False,
        db_index=True,
        help_text=_("Omschrijving van de aard van de ROL, afgeleid uit "
                    "het ROLTYPE."),
    )
    omschrijving_generiek = models.CharField(
        max_length=80,
        choices=RolOmschrijving.choices,
        help_text=
        _("Algemeen gehanteerde benaming van de aard van de ROL, afgeleid uit het ROLTYPE."
          ),
        editable=False,
        db_index=True,
    )
    roltoelichting = models.TextField(max_length=1000)

    registratiedatum = models.DateTimeField(
        "registratiedatum",
        auto_now_add=True,
        help_text="De datum waarop dit object is geregistreerd.",
    )
    indicatie_machtiging = models.CharField(
        max_length=40,
        choices=IndicatieMachtiging.choices,
        blank=True,
        help_text="Indicatie machtiging",
    )

    objects = ZaakRelatedQuerySet.as_manager()

    class Meta:
        verbose_name = "Rol"
        verbose_name_plural = "Rollen"

    def save(self, *args, **kwargs):
        self._derive_roltype_attributes()

        super().save(*args, **kwargs)

    def _derive_roltype_attributes(self):
        if self.omschrijving and self.omschrijving_generiek:
            return

        self.omschrijving = self.roltype.omschrijving
        self.omschrijving_generiek = self.roltype.omschrijving_generiek

    def unique_representation(self):
        if self.betrokkene == "":
            return f"({self.zaak.unique_representation()}) - {self.roltoelichting}"

        betrokkene = (self.betrokkene.rstrip("/")
                      if self.betrokkene.endswith("/") else self.betrokkene)
        return f"({self.zaak.unique_representation()}) - {betrokkene.rsplit('/')[-1]}"
예제 #9
0
class ObjectInformatieObject(models.Model, CMISClientMixin):
    uuid = models.UUIDField(unique=True,
                            default=_uuid.uuid4,
                            help_text="Unieke resource identifier (UUID4)")
    informatieobject = models.ForeignKey(
        "EnkelvoudigInformatieObjectCanonical",
        on_delete=models.CASCADE,
        help_text="URL-referentie naar het INFORMATIEOBJECT.",
    )

    # meta-info about relation
    object_type = models.CharField(
        "objecttype",
        max_length=100,
        choices=ObjectTypes.choices,
        help_text="Het type van het gerelateerde OBJECT.",
    )

    # relations to the possible other objects
    _zaak_url = models.URLField(_("extern zaak"), blank=True, max_length=1000)
    _zaak = models.ForeignKey("zaken.Zaak",
                              on_delete=models.CASCADE,
                              null=True,
                              blank=True)
    zaak = FkOrURLField(
        fk_field="_zaak",
        url_field="_zaak_url",
        blank=True,
        null=True,
    )

    _besluit_url = models.URLField(_("extern besluit"),
                                   blank=True,
                                   max_length=1000)
    _besluit = models.ForeignKey("besluiten.Besluit",
                                 on_delete=models.CASCADE,
                                 null=True,
                                 blank=True)
    besluit = FkOrURLField(
        fk_field="_besluit",
        url_field="_besluit_url",
        blank=True,
        null=True,
    )

    objects = ObjectInformatieObjectAdapterManager()

    class Meta:
        verbose_name = _("objectinformatieobject")
        verbose_name_plural = _("objectinformatieobjecten")
        # check that only one loose-fk field (fk or url) is filled
        constraints = [
            models.CheckConstraint(
                check=Q(
                    Q(_zaak_url="", _zaak__isnull=False)
                    | Q(~Q(_zaak_url=""), _zaak__isnull=True),
                    object_type=ObjectTypes.zaak,
                    _besluit__isnull=True,
                    _besluit_url="",
                )
                | Q(
                    Q(_besluit_url="", _besluit__isnull=False)
                    | Q(~Q(_besluit_url=""), _besluit__isnull=True),
                    object_type=ObjectTypes.besluit,
                    _zaak__isnull=True,
                    _zaak_url="",
                ),
                name="check_type",
            ),
            models.UniqueConstraint(fields=("informatieobject", "_zaak"),
                                    name="unique_io_zaak_local"),
            models.UniqueConstraint(
                fields=("informatieobject", "_zaak_url"),
                name="unique_io_zaak_external",
                condition=~Q(_zaak_url=""),
            ),
            models.UniqueConstraint(fields=("informatieobject", "_besluit"),
                                    name="unique_io_besluit_local"),
            models.UniqueConstraint(
                fields=("informatieobject", "_besluit_url"),
                name="unique_io_besluit_external",
                condition=~Q(_besluit_url=""),
            ),
        ]

    def __str__(self):
        return _("Relation between {document} and {object}").format(
            document=self.informatieobject, object=self.object)

    @property
    def object(self) -> models.Model:
        return getattr(self, self.object_type)

    def unique_representation(self):
        if settings.CMIS_ENABLED:
            informatieobject = self.get_informatieobject()
        else:
            informatieobject = self.informatieobject.latest_version
        io_id = self.object.identificatie
        return f"({informatieobject.unique_representation()}) - {io_id}"

    def save(self, *args, **kwargs):
        if not settings.CMIS_ENABLED:
            super().save(*args, **kwargs)

    def get_url(self):
        oio_path = reverse(
            "objectinformatieobject-detail",
            kwargs={
                "version": "1",
                "uuid": self.uuid
            },
        )
        return make_absolute_uri(oio_path)

    def delete(self, *args, **kwargs):
        if not settings.CMIS_ENABLED:
            super().delete(*args, **kwargs)
        else:
            self.cmis_client.delete_content_object(self.uuid,
                                                   object_type="oio")

    def get_informatieobject(self, permission_main_object=None):
        """
        For the CMIS case it retrieves the EnkelvoudigInformatieObject from Alfresco and returns it as a django type
        """
        if settings.CMIS_ENABLED:
            eio_url = self.get_informatieobject_url()
            # From the URL of the informatie object, retrieve the EnkelvoudigInformatieObject
            eio_uuid = eio_url.split("/")[-1]
            return EnkelvoudigInformatieObject.objects.get(uuid=eio_uuid)
        elif permission_main_object:
            return getattr(self, permission_main_object).latest_version
        else:
            return self.informatieobject.latest_version

    def get_informatieobject_url(self):
        """
        Retrieves the EnkelvoudigInformatieObject url from Alfresco
        """
        cmis_oio = self.cmis_client.get_content_object(self.uuid,
                                                       object_type="oio")
        return cmis_oio.informatieobject

    def does_besluitinformatieobject_exist(self):
        """
        Checks if the corresponding BesluitInformatieObject still exists
        """
        if settings.CMIS_ENABLED:
            eio_url = self.get_informatieobject_url()
            return BesluitInformatieObject.objects.filter(
                informatieobject=eio_url, besluit=self.besluit).exists()
        else:
            return BesluitInformatieObject.objects.filter(
                informatieobject=self.informatieobject,
                besluit=self.besluit).exists()

    def does_zaakinformatieobject_exist(self):
        """
        Checks if the corresponding ZaakInformatieObject still exists
        """
        if settings.CMIS_ENABLED:
            eio_url = self.get_informatieobject_url()
            return ZaakInformatieObject.objects.filter(
                informatieobject=eio_url, zaak=self.zaak).exists()
        else:
            return ZaakInformatieObject.objects.filter(
                informatieobject=self.informatieobject,
                zaak=self.zaak).exists()
예제 #10
0
class InformatieObject(models.Model):
    identificatie = models.CharField(
        max_length=40,
        validators=[alphanumeric_excluding_diacritic],
        blank=True,
        default="",
        help_text="Een binnen een gegeven context ondubbelzinnige referentie "
        "naar het INFORMATIEOBJECT.",
        db_index=True,
    )
    bronorganisatie = RSINField(
        max_length=9,
        help_text="Het RSIN van de Niet-natuurlijk persoon zijnde de "
        "organisatie die het informatieobject heeft gecreëerd of "
        "heeft ontvangen en als eerste in een samenwerkingsketen "
        "heeft vastgelegd.",
        db_index=True,
    )
    # TODO: change to read-only?
    creatiedatum = models.DateField(
        help_text="Een datum of een gebeurtenis in de levenscyclus van het "
        "INFORMATIEOBJECT.")
    titel = models.CharField(
        max_length=200,
        help_text="De naam waaronder het INFORMATIEOBJECT formeel bekend is.",
    )
    vertrouwelijkheidaanduiding = VertrouwelijkheidsAanduidingField(
        blank=True,
        help_text="Aanduiding van de mate waarin het INFORMATIEOBJECT voor de "
        "openbaarheid bestemd is.",
    )
    auteur = models.CharField(
        max_length=200,
        help_text="De persoon of organisatie die in de eerste plaats "
        "verantwoordelijk is voor het creëren van de inhoud van het "
        "INFORMATIEOBJECT.",
    )
    status = models.CharField(
        _("status"),
        max_length=20,
        blank=True,
        choices=Statussen.choices,
        help_text=
        _("Aanduiding van de stand van zaken van een INFORMATIEOBJECT. "
          "De waarden 'in bewerking' en 'ter vaststelling' komen niet "
          "voor als het attribuut `ontvangstdatum` van een waarde is voorzien. "
          "Wijziging van de Status in 'gearchiveerd' impliceert dat "
          "het informatieobject een duurzaam, niet-wijzigbaar Formaat dient te hebben."
          ),
    )
    beschrijving = models.TextField(
        max_length=1000,
        blank=True,
        help_text="Een generieke beschrijving van de inhoud van het "
        "INFORMATIEOBJECT.",
    )
    ontvangstdatum = models.DateField(
        _("ontvangstdatum"),
        null=True,
        blank=True,
        help_text=_(
            "De datum waarop het INFORMATIEOBJECT ontvangen is. Verplicht "
            "te registreren voor INFORMATIEOBJECTen die van buiten de "
            "zaakbehandelende organisatie(s) ontvangen zijn. "
            "Ontvangst en verzending is voorbehouden aan documenten die "
            "van of naar andere personen ontvangen of verzonden zijn "
            "waarbij die personen niet deel uit maken van de behandeling "
            "van de zaak waarin het document een rol speelt."),
    )
    verzenddatum = models.DateField(
        _("verzenddatum"),
        null=True,
        blank=True,
        help_text=_(
            "De datum waarop het INFORMATIEOBJECT verzonden is, zoals "
            "deze op het INFORMATIEOBJECT vermeld is. Dit geldt voor zowel "
            "inkomende als uitgaande INFORMATIEOBJECTen. Eenzelfde "
            "informatieobject kan niet tegelijk inkomend en uitgaand zijn. "
            "Ontvangst en verzending is voorbehouden aan documenten die "
            "van of naar andere personen ontvangen of verzonden zijn "
            "waarbij die personen niet deel uit maken van de behandeling "
            "van de zaak waarin het document een rol speelt."),
    )
    indicatie_gebruiksrecht = models.NullBooleanField(
        _("indicatie gebruiksrecht"),
        blank=True,
        default=None,
        help_text=_(
            "Indicatie of er beperkingen gelden aangaande het gebruik van "
            "het informatieobject anders dan raadpleging. Dit veld mag "
            "`null` zijn om aan te geven dat de indicatie nog niet bekend is. "
            "Als de indicatie gezet is, dan kan je de gebruiksrechten die "
            "van toepassing zijn raadplegen via de GEBRUIKSRECHTen resource."),
    )

    # signing in some sort of way
    # TODO: De attribuutsoort mag niet van een waarde zijn voorzien
    # als de attribuutsoort ?Status? de waarde ?in bewerking?
    # of ?ter vaststelling? heeft.
    ondertekening_soort = models.CharField(
        _("ondertekeningsoort"),
        max_length=10,
        blank=True,
        choices=OndertekeningSoorten.choices,
        help_text=_(
            "Aanduiding van de wijze van ondertekening van het INFORMATIEOBJECT"
        ),
    )
    ondertekening_datum = models.DateField(
        _("ondertekeningdatum"),
        blank=True,
        null=True,
        help_text=
        _("De datum waarop de ondertekening van het INFORMATIEOBJECT heeft plaatsgevonden."
          ),
    )

    _informatieobjecttype_url = models.URLField(
        _("extern informatieobjecttype"),
        blank=True,
        max_length=1000,
        help_text=
        _("URL-referentie naar extern INFORMATIEOBJECTTYPE (in een andere Catalogi API)."
          ),
    )
    _informatieobjecttype = models.ForeignKey(
        "catalogi.InformatieObjectType",
        on_delete=models.CASCADE,
        help_text=_(
            "URL-referentie naar het INFORMATIEOBJECTTYPE (in de Catalogi API)."
        ),
        null=True,
        blank=True,
    )
    informatieobjecttype = FkOrURLField(
        fk_field="_informatieobjecttype",
        url_field="_informatieobjecttype_url",
        help_text=
        "URL-referentie naar het INFORMATIEOBJECTTYPE (in de Catalogi API).",
    )

    objects = InformatieobjectQuerySet.as_manager()

    IDENTIFICATIE_PREFIX = "DOCUMENT"

    class Meta:
        verbose_name = "informatieobject"
        verbose_name_plural = "informatieobject"
        unique_together = ("bronorganisatie", "identificatie")
        abstract = True

    def __str__(self) -> str:
        return self.identificatie

    def save(self, *args, **kwargs):
        if not self.identificatie:
            self.identificatie = generate_unique_identification(
                self, "creatiedatum")
        super().save(*args, **kwargs)

    def clean(self):
        super().clean()
        validate_status(status=self.status,
                        ontvangstdatum=self.ontvangstdatum,
                        instance=self)

    ondertekening = GegevensGroepType({
        "soort": ondertekening_soort,
        "datum": ondertekening_datum
    })

    def unique_representation(self):
        return f"{self.bronorganisatie} - {self.identificatie}"
예제 #11
0
class Besluit(AuditTrailMixin, APIMixin, models.Model):
    uuid = models.UUIDField(unique=True,
                            default=_uuid.uuid4,
                            help_text="Unieke resource identifier (UUID4)")
    identificatie = models.CharField(
        "identificatie",
        max_length=50,
        blank=True,
        validators=[alphanumeric_excluding_diacritic],
        help_text="Identificatie van het besluit binnen de organisatie die "
        "het besluit heeft vastgesteld. Indien deze niet opgegeven is, "
        "dan wordt die gegenereerd.",
    )
    verantwoordelijke_organisatie = RSINField(
        "verantwoordelijke organisatie",
        help_text="Het RSIN van de niet-natuurlijk persoon zijnde de "
        "organisatie die het besluit heeft vastgesteld.",
        db_index=True,
    )

    _besluittype_url = models.URLField(
        _("extern besluittype"),
        blank=True,
        max_length=1000,
        help_text=
        _("URL-referentie naar extern BESLUITTYPE (in een andere Catalogi API)."
          ),
    )
    _besluittype = models.ForeignKey(
        "catalogi.BesluitType",
        on_delete=models.CASCADE,
        help_text="URL-referentie naar het BESLUITTYPE (in de Catalogi API).",
        null=True,
        blank=True,
    )
    besluittype = FkOrURLField(
        fk_field="_besluittype",
        url_field="_besluittype_url",
        help_text="URL-referentie naar het BESLUITTYPE (in de Catalogi API).",
    )

    _zaak_url = models.URLField(
        _("externe zaak"),
        blank=True,
        max_length=1000,
        help_text=
        "URL-referentie naar de ZAAK (in de Zaken API) waarvan dit besluit uitkomst is.",
    )
    _zaak = models.ForeignKey(
        "zaken.Zaak",
        on_delete=models.PROTECT,
        null=True,
        blank=True,  # een besluit kan niet bij een zaak horen
        help_text=
        "URL-referentie naar de ZAAK (in de Zaken API) waarvan dit besluit uitkomst is.",
    )
    zaak = FkOrURLField(
        fk_field="_zaak",
        url_field="_zaak_url",
        blank=True,
        null=True,
        help_text=
        "URL-referentie naar de ZAAK (in de Zaken API) waarvan dit besluit uitkomst is.",
    )

    datum = models.DateField(
        "datum",
        validators=[UntilTodayValidator()],
        help_text="De beslisdatum (AWB) van het besluit.",
    )
    toelichting = models.TextField("toelichting",
                                   blank=True,
                                   help_text="Toelichting bij het besluit.")

    # TODO: hoe dit valideren? Beter ook objectregistratie en URL referentie?
    # Alleen de namen van bestuursorganen mogen gebruikt
    # worden die voor de desbetrreffende (sic) organisatie van
    # toepassing zijn. Voor een gemeente zijn dit
    # 'Burgemeester', 'Gemeenteraad' en 'College van B&W'.
    # Indien het, bij mandatering, een bestuursorgaan van
    # een andere organisatie betreft dan de organisatie die
    # verantwoordelijk is voor de behandeling van de zaak,
    # dan moet tevens de naam van die andere organisatie
    # vermeld worden (bijvoorbeeld "Burgemeester gemeente
    # Lent").
    bestuursorgaan = models.CharField(
        "bestuursorgaan",
        max_length=50,
        blank=True,
        help_text="Een orgaan van een rechtspersoon krachtens publiekrecht "
        "ingesteld of een persoon of college, met enig openbaar gezag "
        "bekleed onder wiens verantwoordelijkheid het besluit "
        "vastgesteld is.",
    )

    ingangsdatum = models.DateField(
        "ingangsdatum",
        help_text="Ingangsdatum van de werkingsperiode van het besluit.")
    vervaldatum = models.DateField(
        "vervaldatum",
        null=True,
        blank=True,
        help_text="Datum waarop de werkingsperiode van het besluit eindigt.",
    )
    vervalreden = models.CharField(
        "vervalreden",
        max_length=30,
        blank=True,
        choices=VervalRedenen.choices,
        help_text=
        _("De omschrijving die aangeeft op grond waarvan het besluit is of komt te vervallen."
          ),
    )
    publicatiedatum = models.DateField(
        "publicatiedatum",
        null=True,
        blank=True,
        help_text="Datum waarop het besluit gepubliceerd wordt.",
    )
    verzenddatum = models.DateField(
        "verzenddatum",
        null=True,
        blank=True,
        help_text="Datum waarop het besluit verzonden is.",
    )
    # TODO: validator
    # Afleidbaar gegeven (uit BESLUITTYPE.Reactietermijn en
    # BESLUIT.Besluitdatum)
    # .. note: (rekening houdend met weekend- en feestdagen
    uiterlijke_reactiedatum = models.DateField(
        "uiterlijke reactiedatum",
        null=True,
        blank=True,
        help_text="De datum tot wanneer verweer tegen het besluit mogelijk is.",
    )

    _zaakbesluit_url = models.URLField(
        blank=True,
        max_length=1000,
        help_text="URL of related ZaakBesluit object in the other API",
    )

    objects = BesluitQuerySet.as_manager()

    class Meta:
        verbose_name = "besluit"
        verbose_name_plural = "besluiten"
        unique_together = (("identificatie",
                            "verantwoordelijke_organisatie"), )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        # save previous zaak for triggers
        # self._previous_zaak = self.zaak

        self._previous_zaak = self._zaak
        self._previous_zaak_url = self._zaak_url

    def __str__(self):
        return f"{self.verantwoordelijke_organisatie} - {self.identificatie}"

    def save(self, *args, **kwargs):
        if not self.identificatie:
            self.identificatie = generate_unique_identification(self, "datum")

        super().save(*args, **kwargs)

    def unique_representation(self):
        return f"{self.identificatie}"

    @property
    def previous_zaak(self):
        if self._previous_zaak:
            return self._previous_zaak

        if self._previous_zaak_url:
            remote_model = apps.get_model("zaken", "Zaak")
            return AuthorizedRequestsLoader().load(url=self._previous_zaak_url,
                                                   model=remote_model)

        return None
예제 #12
0
class BesluitInformatieObject(models.Model):
    """
    Aanduiding van het (de) INFORMATIEOBJECT(en) waarin
    het BESLUIT beschreven is.

    Besluiten worden veelal schriftelijk vastgelegd maar kunnen ook mondeling
    genomen zijn. Deze relatie verwijst naar het informatieobject waarin het
    besluit is vastgelegd, indien van toepassing. Mogelijkerwijs is het besluit in
    meerdere afzonderlijke informatieobjecten vastgelegd of zijn in één
    informatieobject meerdere besluiten vastgelegd.
    """

    uuid = models.UUIDField(unique=True,
                            default=_uuid.uuid4,
                            help_text="Unieke resource identifier (UUID4)")

    besluit = models.ForeignKey(Besluit,
                                on_delete=models.CASCADE,
                                help_text="URL-referentie naar het BESLUIT.")

    _informatieobject_url = models.URLField(
        _("External informatieobject"),
        blank=True,
        max_length=1000,
        help_text=_("URL to the informatieobject in an external API"),
    )
    _informatieobject = models.ForeignKey(
        "documenten.EnkelvoudigInformatieObjectCanonical",
        on_delete=models.CASCADE,
        blank=True,
        null=True,
        help_text="URL-referentie naar het INFORMATIEOBJECT (in de Documenten "
        "API) waarin (een deel van) het besluit beschreven is.",
    )
    informatieobject = FkOrURLField(
        fk_field="_informatieobject",
        url_field="_informatieobject_url",
        loader=EIOLoader(),
        help_text=_(
            "URL-referentie naar het INFORMATIEOBJECT (in de Documenten "
            "API) waarin (een deel van) het besluit beschreven is.", ),
    )
    _objectinformatieobject_url = models.URLField(
        blank=True,
        max_length=1000,
        help_text=_(
            "URL of related ObjectInformatieObject object in the other API"),
    )

    objects = BesluitInformatieObjectQuerySet.as_manager()

    class Meta:
        verbose_name = "besluitinformatieobject"
        verbose_name_plural = "besluitinformatieobjecten"
        unique_together = ("besluit", "_informatieobject")
        constraints = [
            models.UniqueConstraint(
                fields=["besluit", "_informatieobject_url"],
                condition=~models.Q(_informatieobject_url=""),
                name="unique_besluit_and_external_document",
            )
        ]

    def __str__(self):
        return str(self.uuid)

    def unique_representation(self):
        besluit_repr = self.besluit.unique_representation()

        if hasattr(self.informatieobject, "identificatie"):
            doc_identificatie = self.informatieobject.identificatie
        else:
            doc_identificatie = self.informatieobject.latest_version.identificatie

        return f"({besluit_repr}) - {doc_identificatie}"
예제 #13
0
class ObjectInformatieObject(models.Model):
    uuid = models.UUIDField(unique=True,
                            default=_uuid.uuid4,
                            help_text="Unieke resource identifier (UUID4)")
    informatieobject = models.ForeignKey(
        "EnkelvoudigInformatieObjectCanonical",
        on_delete=models.CASCADE,
        help_text="URL-referentie naar het INFORMATIEOBJECT.",
    )

    # meta-info about relation
    object_type = models.CharField(
        "objecttype",
        max_length=100,
        choices=ObjectTypes.choices,
        help_text="Het type van het gerelateerde OBJECT.",
    )

    # relations to the possible other objects
    _zaak_url = models.URLField(_("extern zaak"), blank=True, max_length=1000)
    _zaak = models.ForeignKey("zaken.Zaak",
                              on_delete=models.CASCADE,
                              null=True,
                              blank=True)
    zaak = FkOrURLField(
        fk_field="_zaak",
        url_field="_zaak_url",
        blank=True,
        null=True,
    )

    _besluit_url = models.URLField(_("extern besluit"),
                                   blank=True,
                                   max_length=1000)
    _besluit = models.ForeignKey("besluiten.Besluit",
                                 on_delete=models.CASCADE,
                                 null=True,
                                 blank=True)
    besluit = FkOrURLField(
        fk_field="_besluit",
        url_field="_besluit_url",
        blank=True,
        null=True,
    )

    objects = ObjectInformatieObjectQuerySet.as_manager()

    class Meta:
        verbose_name = _("objectinformatieobject")
        verbose_name_plural = _("objectinformatieobjecten")
        # check that only one loose-fk field (fk or url) is filled
        constraints = [
            models.CheckConstraint(
                check=Q(
                    Q(_zaak_url="", _zaak__isnull=False)
                    | Q(~Q(_zaak_url=""), _zaak__isnull=True),
                    object_type=ObjectTypes.zaak,
                    _besluit__isnull=True,
                    _besluit_url="",
                )
                | Q(
                    Q(_besluit_url="", _besluit__isnull=False)
                    | Q(~Q(_besluit_url=""), _besluit__isnull=True),
                    object_type=ObjectTypes.besluit,
                    _zaak__isnull=True,
                    _zaak_url="",
                ),
                name="check_type",
            ),
            models.UniqueConstraint(fields=("informatieobject", "_zaak"),
                                    name="unique_io_zaak_local"),
            models.UniqueConstraint(
                fields=("informatieobject", "_zaak_url"),
                name="unique_io_zaak_external",
                condition=~Q(_zaak_url=""),
            ),
            models.UniqueConstraint(fields=("informatieobject", "_besluit"),
                                    name="unique_io_besluit_local"),
            models.UniqueConstraint(
                fields=("informatieobject", "_besluit_url"),
                name="unique_io_besluit_external",
                condition=~Q(_besluit_url=""),
            ),
        ]

    def __str__(self):
        return _("Relation between {document} and {object}").format(
            document=self.informatieobject, object=self.object)

    @property
    def object(self) -> models.Model:
        return getattr(self, self.object_type)

    def unique_representation(self):
        io_id = self.object.identificatie
        return f"({self.informatieobject.latest_version.unique_representation()}) - {io_id}"