Skip to content

Commit

Permalink
[#2862] Integrate OpenKlant2 service with zaak detail view
Browse files Browse the repository at this point in the history
  • Loading branch information
pi-sigma committed Nov 22, 2024
1 parent 00f2d62 commit 44d235b
Show file tree
Hide file tree
Showing 17 changed files with 606 additions and 411 deletions.
63 changes: 34 additions & 29 deletions src/open_inwoner/accounts/views/contactmoments.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,18 @@ class KlantContactMomentBaseView(
CommonPageMixin, BaseBreadcrumbMixin, KlantContactMomentAccessMixin, TemplateView
):
def get_service(self, service_type: KlantenServiceType) -> VragenService | None:
if service_type == KlantenServiceType.OPENKLANT2:
try:
return OpenKlant2Service()
except ImproperlyConfigured:
logger.error("OpenKlant2 configuration missing")
if service_type == KlantenServiceType.ESUITE:
try:
return eSuiteVragenService()
except ImproperlyConfigured:
logger.error("eSuiteVragenService configuration missing")
elif service_type == KlantenServiceType.OPENKLANT2:
try:
return OpenKlant2Service()
except ImproperlyConfigured:
logger.error("OpenKlant2 configuration missing")
except RuntimeError:
logger.error("Failed to build OpenKlant2Service")
logger.error("Failed to build eSuiteVragenService")

def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
Expand Down Expand Up @@ -146,24 +146,24 @@ def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)

questions = []
if esuite_service := self.get_service(service_type=KlantenServiceType.ESUITE):
if ok2_service := self.get_service(service_type=KlantenServiceType.OPENKLANT2):
questions.extend(
esuite_service.list_questions(
fetch_params=self.get_fetch_params(esuite_service),
ok2_service.list_questions(
self.get_fetch_params(ok2_service),
user=self.request.user,
)
)
if ok2_service := self.get_service(service_type=KlantenServiceType.OPENKLANT2):
if esuite_service := self.get_service(service_type=KlantenServiceType.ESUITE):
questions.extend(
ok2_service.list_questions(
self.get_fetch_params(ok2_service),
esuite_service.list_questions(
fetch_params=self.get_fetch_params(esuite_service),
user=self.request.user,
)
)
questions.sort(key=lambda q: q["registered_date"], reverse=True)
ctx["contactmomenten"] = questions
ctx["questions"] = questions

paginator_dict = self.paginate_with_context(ctx["contactmomenten"])
paginator_dict = self.paginate_with_context(ctx["questions"])
ctx.update(paginator_dict)

return ctx
Expand All @@ -188,28 +188,27 @@ def get_anchors(self) -> list:
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)

if KlantenServiceType.esuite in self.request.path:
service = self.get_service(service_type=KlantenServiceType.esuite)
elif KlantenServiceType.openklant2 in self.request.path:
service = self.get_service(service_type=KlantenServiceType.openklant2)
if KlantenServiceType.ESUITE.value in self.request.path:
service = self.get_service(service_type=KlantenServiceType.ESUITE)
elif KlantenServiceType.OPENKLANT2.value in self.request.path:
service = self.get_service(service_type=KlantenServiceType.OPENKLANT2)

kcm, zaak = service.retrieve_question(
question, zaak = service.retrieve_question(
self.get_fetch_params(service), kwargs["kcm_uuid"], user=self.request.user
)
if not kcm:
if not question:
raise Http404()

QuestionValidator.validate_python(kcm)
QuestionValidator.validate_python(question)

local_kcm, created = KlantContactMomentAnswer.objects.get_or_create( # noqa
user=self.request.user, contactmoment_url=kcm["url"]
user=self.request.user, contactmoment_url=question["api_source_url"]
)
if not local_kcm.is_seen:
local_kcm.is_seen = True
local_kcm.save()

contactmoment = kcm
ctx["contactmoment"] = contactmoment
ctx["question"] = question
ctx["zaak"] = zaak.zaak if zaak else None
case_url = (
reverse(
Expand All @@ -225,19 +224,19 @@ def get_context_data(self, **kwargs):
ctx["metrics"] = [
{
"label": _("Status: "),
"value": contactmoment["status"],
"value": question["status"].capitalize(),
},
{
"label": _("Ingediend op: "),
"value": contactmoment["registered_date"],
"value": question["registered_date"],
},
{
"label": _("Vraag nummer: "),
"value": contactmoment["identification"],
"value": question["identification"],
},
{
"label": _("Contact gehad via: "),
"value": contactmoment["channel"],
"value": question["channel"].capitalize(),
},
]
origin = self.request.headers.get("Referer")
Expand Down Expand Up @@ -288,5 +287,11 @@ def get(self, request, *args, **kwargs):
raise Http404

return HttpResponseRedirect(
reverse("cases:contactmoment_detail", kwargs={"kcm_uuid": kcm.uuid})
reverse(
"cases:contactmoment_detail",
kwargs={
"api_service": KlantenServiceType.ESUITE.value,
"kcm_uuid": kcm.uuid,
},
)
)
91 changes: 53 additions & 38 deletions src/open_inwoner/cms/cases/views/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@
import logging
from collections import defaultdict
from datetime import datetime
from typing import Iterable, Protocol

from django.conf import settings
from django.contrib import messages
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
from django.core.exceptions import (
ImproperlyConfigured,
ObjectDoesNotExist,
PermissionDenied,
)
from django.http import (
Http404,
HttpRequest,
Expand All @@ -20,19 +25,21 @@
from django.views.generic import FormView, TemplateView

from django_htmx.http import HttpResponseClientRedirect
from glom import glom
from mail_editor.helpers import find_template
from view_breadcrumbs import BaseBreadcrumbMixin
from zgw_consumers.api_models.constants import RolOmschrijving

from open_inwoner.accounts.models import User
from open_inwoner.mail.service import send_contact_confirmation_mail
from open_inwoner.openklant.constants import KlantenServiceType
from open_inwoner.openklant.models import OpenKlantConfig
from open_inwoner.openklant.services import eSuiteKlantenService, eSuiteVragenService
from open_inwoner.openklant.wrap import (
contactmoment_has_new_answer,
get_fetch_parameters,
get_kcm_answer_mapping,
from open_inwoner.openklant.services import (
OpenKlant2Service,
Question,
eSuiteKlantenService,
eSuiteVragenService,
)
from open_inwoner.openklant.wrap import get_fetch_parameters
from open_inwoner.openzaak.api_models import Status, StatusType, Zaak
from open_inwoner.openzaak.clients import CatalogiClient, ZakenClient
from open_inwoner.openzaak.documents import (
Expand Down Expand Up @@ -67,6 +74,15 @@ class SimpleFile:
created: datetime | None = None


class VragenService(Protocol):
def list_questions_for_zaak(
self,
zaak: Zaak,
user: User | None = None,
) -> Iterable[Question]: # noqa: E704
...


class OuterCaseDetailView(
OuterCaseAccessMixin, CommonPageMixin, BaseBreadcrumbMixin, TemplateView
):
Expand Down Expand Up @@ -110,6 +126,20 @@ class InnerCaseDetailView(
contact_form_class = CaseContactForm
case: Zaak | None = None

def get_service(self, service_type: KlantenServiceType) -> VragenService | None:
if service_type == KlantenServiceType.OPENKLANT2:
try:
return OpenKlant2Service()
except ImproperlyConfigured:
logger.error("OpenKlant2 configuration missing")
if service_type == KlantenServiceType.ESUITE:
try:
return eSuiteVragenService()
except ImproperlyConfigured:
logger.error("eSuiteVragenService configuration missing")
except RuntimeError:
logger.error("Failed to build eSuiteVragenService")

def store_statustype_mapping(self, zaaktype_identificatie):
# Filter on ZaakType identificatie to avoid eSuite situation where one statustype
# is linked to multiple zaaktypes
Expand Down Expand Up @@ -151,7 +181,6 @@ def get_context_data(self, **kwargs):
self.log_access_case_detail(self.case)

openzaak_config = OpenZaakConfig.get_solo()
openklant_config = OpenKlantConfig.get_solo()

api_group = ZGWApiGroupConfig.objects.get(pk=self.kwargs["api_group_id"])
zaken_client = api_group.zaken_client
Expand All @@ -162,38 +191,24 @@ def get_context_data(self, **kwargs):
self.store_statustype_mapping(self.case.zaaktype.identificatie)
self.store_resulttype_mapping(self.case.zaaktype.identificatie)

# questions/E-suite contactmomenten
try:
service = eSuiteVragenService(config=openklant_config)
except RuntimeError:
logger.error("Failed to build eSuiteVragenService")
objectcontactmomenten = []
else:
objectcontactmomenten = service.retrieve_objectcontactmomenten_for_zaak(
self.case
)

questions = []
for ocm in objectcontactmomenten:
question = getattr(ocm, "contactmoment", None)
if question:
questions.append(question)
questions.sort(key=lambda q: q.registratiedatum, reverse=True)

kcm_answer_mapping = get_kcm_answer_mapping(questions, self.request.user)
for question in questions:
question.new_answer_available = contactmoment_has_new_answer(
question, kcm_answer_mapping
if ok2_service := self.get_service(
service_type=KlantenServiceType.OPENKLANT2
):
questions.extend(
ok2_service.list_questions_for_zaak(
self.case, user=self.request.user
)
)

# filter questions
openklant_config = OpenKlantConfig.get_solo()
if exclude_range := openklant_config.exclude_contactmoment_kanalen:
questions = [
item
for item in questions
if glom(item, "kanaal") not in exclude_range
]
if esuite_service := self.get_service(
service_type=KlantenServiceType.ESUITE
):
questions.extend(
esuite_service.list_questions_for_zaak(
self.case, user=self.request.user
)
)
questions.sort(key=lambda q: q["registered_date"], reverse=True)

statustypen = []
catalogi_client = api_group.catalogi_client
Expand Down
Loading

0 comments on commit 44d235b

Please sign in to comment.