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

[#2899] Integrate OpenKlantConfig and OpenKlant2Config #1520

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
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
87 changes: 85 additions & 2 deletions src/open_inwoner/openklant/admin.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
from django import forms
from django.contrib import admin
from django.contrib import admin, messages
from django.db.utils import IntegrityError
from django.utils.translation import gettext_lazy as _

from ordered_model.admin import OrderedInlineModelAdminMixin, OrderedTabularInline
from solo.admin import SingletonModelAdmin
from zgw_consumers.constants import APITypes
from zgw_consumers.models import Service

from .models import ContactFormSubject, KlantContactMomentAnswer, OpenKlantConfig
from .models import (
ContactFormSubject,
KlantContactMomentAnswer,
KlantenInteractiesConfig,
OpenKlant2Config,
OpenKlantConfig,
)


class ContactFormSubjectForm(forms.ModelForm):
Expand Down Expand Up @@ -108,3 +117,77 @@ class KlantContactMomentAnswerAdmin(admin.ModelAdmin):
]
list_filter = ["is_seen"]
list_display = ["user", "contactmoment_url", "is_seen"]


#
# OpenKlant2
#


class OpenKlant2ConfigAdminForm(forms.ModelForm):
class Meta:
model = OpenKlantConfig
fields = "__all__"


@admin.register(OpenKlant2Config)
class OpenKlant2Config2Admin(SingletonModelAdmin):
model = OpenKlant2Config
form = OpenKlant2ConfigAdminForm
fieldsets = [
(
_("API configuration"),
{
"fields": [
"service",
]
},
),
(
_("Vragen"),
{
"fields": [
"mijn_vragen_kanaal",
"mijn_vragen_organisatie_naam",
"mijn_vragen_actor",
"interne_taak_gevraagde_handeling",
"interne_taak_toelichting",
]
},
),
]

def change_view(self, request, object_id, form_url="", extra_context=None):
if object_id == str(self.singleton_instance_id):
try:
self.model.objects.get_or_create(pk=self.singleton_instance_id)
except IntegrityError:
service = Service.objects.create(
label="OpenKlant2 API service",
slug="openklant2-api-service",
api_type=APITypes.kc,
api_root="",
)
OpenKlant2Config.objects.create(service=service)

messages.warning(
request,
"OpenKlant2Config was created. An API service for OpenKlant2Config "
"was automatically created. Please update the Klanten API service "
"configuration as necessary.",
)

return super(SingletonModelAdmin, self).change_view(
request,
object_id,
form_url=form_url,
extra_context=extra_context,
)
pi-sigma marked this conversation as resolved.
Show resolved Hide resolved


@admin.register(KlantenInteractiesConfig)
class KlantenInteractiesConfigAdmin(SingletonModelAdmin):
change_form_template = "admin/openklant/klanteninteractiesconfig/change_form.html"

class Meta:
model = KlantenInteractiesConfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Generated by Django 4.2.16 on 2025-01-07 11:28

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("openklant", "0015_openklant2config"),
]

operations = [
migrations.CreateModel(
name="KlantenInteractiesConfig",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"primary_backend",
models.CharField(
choices=[("esuite", "ESUITE"), ("openklant2", "OPENKLANT2")],
max_length=10,
help_text="Choose the primary backend for retrieving klanten data. Changes to klanten data will be saved to both backends (if configured).",
),
),
],
options={
"verbose_name": "Configuratie Klanten Interacties",
},
),
]
108 changes: 60 additions & 48 deletions src/open_inwoner/openklant/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

from open_inwoner.utils.validators import validate_array_contents_non_empty

from .constants import KlantenServiceType


class OpenKlantConfigManager(models.Manager):
def get_queryset(self):
Expand All @@ -17,7 +19,7 @@ def get_queryset(self):

class OpenKlantConfig(SingletonModel):
"""
Global configuration and defaults for Klant & Contactmomenten APIs
Configuration and defaults for eSuite Klant & Contactmomenten APIs
"""

klanten_service = models.OneToOneField(
Expand Down Expand Up @@ -132,51 +134,6 @@ def has_api_configuration(self):
return all(getattr(self, f, "") for f in self.register_api_required_fields)


class OpenKlant2ConfigManager(models.Manager):
def get_queryset(self):
qs = super().get_queryset()
return qs.select_related("service")


class OpenKlant2Config(models.Model):
service = models.OneToOneField(
"zgw_consumers.Service",
verbose_name=_("Klanten API"),
on_delete=models.PROTECT,
related_name="+",
)

# Vragen
mijn_vragen_kanaal = models.CharField(
verbose_name=_("Mijn vragen kanaal"),
default="",
blank=True,
)
mijn_vragen_organisatie_naam = models.CharField(
verbose_name=_("Mijn vragen organisatie naam"),
default="",
blank=True,
)
mijn_vragen_actor = models.CharField(
verbose_name=_("Mijn vragen actor"),
default="",
blank=True,
)
interne_taak_gevraagde_handeling = models.CharField(
verbose_name=_("Interne taak gevraagde handeling"),
default="",
blank=True,
)
interne_taak_toelichting = models.CharField(
verbose_name=_("Interne taak toelichting"),
default="",
blank=True,
)

class Meta:
verbose_name = _("OpenKlant2 configuration")


class ContactFormSubject(OrderedModel):
subject = models.CharField(
verbose_name=_("Onderwerp"),
Expand All @@ -187,9 +144,8 @@ class ContactFormSubject(OrderedModel):
max_length=255,
blank=True,
)
# FK for easy inline admins
config = models.ForeignKey(
OpenKlantConfig,
"OpenKlantConfig",
on_delete=models.CASCADE,
)

Expand Down Expand Up @@ -229,3 +185,59 @@ class Meta:
verbose_name = _("KlantContactMoment")
verbose_name_plural = _("KlantContactMomenten")
unique_together = [["user", "contactmoment_url"]]


class OpenKlant2Config(SingletonModel):
service = models.OneToOneField(
"zgw_consumers.Service",
verbose_name=_("Klanten API"),
on_delete=models.PROTECT,
related_name="+",
)

# Vragen
mijn_vragen_kanaal = models.CharField(
verbose_name=_("Mijn vragen kanaal"),
default="",
blank=True,
)
mijn_vragen_organisatie_naam = models.CharField(
verbose_name=_("Mijn vragen organisatie naam"),
default="",
blank=True,
)
mijn_vragen_actor = models.CharField(
verbose_name=_("Mijn vragen actor"),
default="",
blank=True,
)
interne_taak_gevraagde_handeling = models.CharField(
verbose_name=_("Interne taak gevraagde handeling"),
default="",
blank=True,
)
interne_taak_toelichting = models.CharField(
verbose_name=_("Interne taak toelichting"),
default="",
blank=True,
)

class Meta:
verbose_name = _("OpenKlant2 configuration")


class KlantenInteractiesConfig(SingletonModel):
pi-sigma marked this conversation as resolved.
Show resolved Hide resolved
pi-sigma marked this conversation as resolved.
Show resolved Hide resolved
primary_backend = models.CharField(
max_length=10,
choices=[(service.value, service.name) for service in KlantenServiceType],
help_text=_(
"Choose the primary backend for retrieving klanten data. "
"Changes to klanten data will be saved to both backends (if configured)."
),
)

class Meta:
verbose_name = _("Configuratie Klanten Interacties")

def __str__(self):
return "Klanten Interacties Configuratie"
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% extends "admin/solo/change_form.html" %}

{% block content %}
<p>Configure the backends for retrieving Klanten data:</p>
<ul>
<li><a href="{% url 'admin:openklant_openklantconfig_change' %}">Configure eSuite backend</a></li>
<li><a href="{% url 'admin:openklant_openklant2config_change' %}">Configure OpenKlant2 backend</a></li>
</ul>
Comment on lines +5 to +8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect we could solve this by using a combination of the @admin.display/readonly_fields attribute (docs): there will be no list page (because singleton), but the read only fields should still be display in the singleton detail page. Arguably less complex than tweaking the template.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I played with @admin.display but couldn't get it to do what's needed without modifying the templates anyway. Also, compare:

  • want to customize detail page -> customize template for detail page
  • want to customize detail page -> use @admin.display to customize list page; although there is no list page, the strategy can still be used to change detail page indirectly

The first is less complex. Unless I'm missing something about the use of the decorator?

{{ block.super }}
{% endblock content %}
Loading