Skip to content

Commit 124a00d

Browse files
committed
[#2483] Make case list page multi-zgw backend aware
1 parent 9afda54 commit 124a00d

File tree

3 files changed

+560
-385
lines changed

3 files changed

+560
-385
lines changed

src/open_inwoner/cms/cases/views/cases.py

+43-11
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,38 @@
1+
import concurrent.futures
2+
import logging
3+
from dataclasses import dataclass
4+
15
from django.urls import reverse
26
from django.utils.functional import cached_property
37
from django.utils.translation import gettext_lazy as _
48
from django.views.generic import TemplateView
59

610
from view_breadcrumbs import BaseBreadcrumbMixin
11+
from zgw_consumers.concurrent import parallel
712

813
from open_inwoner.htmx.mixins import RequiresHtmxMixin
14+
from open_inwoner.openzaak.api_models import Zaak
915
from open_inwoner.openzaak.cases import preprocess_data
10-
from open_inwoner.openzaak.clients import build_zaken_client
1116
from open_inwoner.openzaak.formapi import fetch_open_submissions
12-
from open_inwoner.openzaak.models import OpenZaakConfig
17+
from open_inwoner.openzaak.models import OpenZaakConfig, ZGWApiGroupConfig
1318
from open_inwoner.openzaak.types import UniformCase
1419
from open_inwoner.openzaak.utils import get_user_fetch_parameters
1520
from open_inwoner.utils.mixins import PaginationMixin
1621
from open_inwoner.utils.views import CommonPageMixin
1722

1823
from .mixins import CaseAccessMixin, CaseLogMixin, OuterCaseAccessMixin
1924

25+
logger = logging.getLogger(__name__)
26+
27+
28+
@dataclass
29+
class ZaakWithApiGroup(UniformCase):
30+
zaak: Zaak
31+
api_group: ZGWApiGroupConfig
32+
33+
def process_data(self) -> dict:
34+
return {**self.zaak.process_data(), "api_group": self.api_group}
35+
2036

2137
class OuterCaseListView(
2238
OuterCaseAccessMixin, CommonPageMixin, BaseBreadcrumbMixin, TemplateView
@@ -55,17 +71,33 @@ class InnerCaseListView(
5571
def page_title(self):
5672
return _("Mijn aanvragen")
5773

58-
def get_cases(self):
59-
client = build_zaken_client()
60-
61-
if client is None:
62-
return []
63-
64-
raw_cases = client.fetch_cases(**get_user_fetch_parameters(self.request))
65-
66-
preprocessed_cases = preprocess_data(raw_cases)
74+
def get_cases_for_api_group(self, group: ZGWApiGroupConfig):
75+
zaken_client = group.zaken_client
76+
raw_cases = zaken_client.fetch_cases(**get_user_fetch_parameters(self.request))
77+
preprocessed_cases = preprocess_data(raw_cases, group)
6778
return preprocessed_cases
6879

80+
def get_cases(self) -> list[ZaakWithApiGroup]:
81+
all_api_groups = list(ZGWApiGroupConfig.objects.all())
82+
with parallel() as executor:
83+
futures = [
84+
executor.submit(self.get_cases_for_api_group, group)
85+
for group in all_api_groups
86+
]
87+
88+
cases = []
89+
for task in concurrent.futures.as_completed(futures):
90+
try:
91+
task_group = all_api_groups[futures.index(task)]
92+
for row in task.result():
93+
cases.append(ZaakWithApiGroup(zaak=row, api_group=task_group))
94+
except BaseException:
95+
logger.exception("Error fetching and pre-processing cases")
96+
97+
# Ensure stable sorting for pagination and testing purposes
98+
cases.sort(key=lambda c: all_api_groups.index(c.api_group))
99+
return cases
100+
69101
def get_submissions(self):
70102
subs = fetch_open_submissions(self.request.user.bsn)
71103
subs.sort(key=lambda sub: sub.datum_laatste_wijziging, reverse=True)

src/open_inwoner/openzaak/cases.py

+11-23
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,21 @@
66
from zgw_consumers.concurrent import parallel
77

88
from .api_models import Zaak
9-
from .clients import (
10-
CatalogiClient,
11-
ZakenClient,
12-
build_catalogi_client,
13-
build_zaken_client,
14-
)
15-
from .models import ZaakTypeConfig, ZaakTypeStatusTypeConfig
9+
from .clients import CatalogiClient, ZakenClient
10+
from .models import ZaakTypeConfig, ZaakTypeStatusTypeConfig, ZGWApiGroupConfig
1611
from .utils import is_zaak_visible
1712

1813
logger = logging.getLogger(__name__)
1914

2015

21-
def resolve_zaak_type(case: Zaak, client: CatalogiClient | None = None) -> None:
16+
def resolve_zaak_type(case: Zaak, client: CatalogiClient) -> None:
2217
"""
2318
Resolve `case.zaaktype` (`str`) to a `ZaakType(ZGWModel)` object
2419
2520
Note: the result of `fetch_single_case_type` is cached, hence a request
2621
is only made for new case type urls
2722
"""
2823
case_type_url = case.zaaktype
29-
client = client or build_catalogi_client()
3024
if client:
3125
case_type = client.fetch_single_case_type(case_type_url)
3226
case.zaaktype = case_type
@@ -36,7 +30,6 @@ def resolve_status(case: Zaak, client: ZakenClient | None = None) -> None:
3630
"""
3731
Resolve `case.status` (`str`) to a `Status(ZGWModel)` object
3832
"""
39-
client = client or build_zaken_client()
4033
if client:
4134
case.status = client.fetch_single_status(case.status)
4235

@@ -46,7 +39,6 @@ def resolve_status_type(case: Zaak, client: CatalogiClient | None = None) -> Non
4639
Resolve `case.status.statustype` (`str`) to a `StatusType(ZGWModel)` object
4740
"""
4841
statustype_url = case.status.statustype
49-
client = client or build_catalogi_client()
5042
if client:
5143
case.status.statustype = client.fetch_single_status_type(statustype_url)
5244

@@ -55,16 +47,14 @@ def resolve_resultaat(case: Zaak, client: ZakenClient | None = None) -> None:
5547
"""
5648
Resolve `case.resultaat` (`str`) to a `Resultaat(ZGWModel)` object
5749
"""
58-
client = client or build_zaken_client()
59-
if client and case.resultaat:
50+
if case.resultaat:
6051
case.resultaat = client.fetch_single_result(case.resultaat)
6152

6253

6354
def resolve_resultaat_type(case: Zaak, client: CatalogiClient | None = None) -> None:
6455
"""
6556
Resolve `case.resultaat.resultaattype` (`str`) to a `ResultaatType(ZGWModel)` object
6657
"""
67-
client = client or build_catalogi_client()
6858
if client and case.resultaat:
6959
case.resultaat.resultaattype = client.fetch_single_resultaat_type(
7060
case.resultaat.resultaattype
@@ -102,30 +92,28 @@ def add_status_type_config(case: Zaak) -> None:
10292
pass
10393

10494

105-
def preprocess_data(cases: list[Zaak]) -> list[Zaak]:
95+
def preprocess_data(cases: list[Zaak], group: ZGWApiGroupConfig) -> list[Zaak]:
10696
"""
10797
Resolve zaaktype and statustype, add status type config, filter for visibility
10898
10999
Note: we need to iterate twice over `cases` because the `zaak_type` must be
110100
resolved to a `ZaakType` object before we can filter by visibility
111101
"""
112-
zaken_client = build_zaken_client()
113-
catalogi_client = build_catalogi_client()
114102

115103
def preprocess_case(case: Zaak) -> None:
116-
resolve_status(case, client=zaken_client)
117-
resolve_status_type(case, client=catalogi_client)
118-
resolve_resultaat(case, client=zaken_client)
119-
resolve_resultaat_type(case, client=catalogi_client)
104+
resolve_status(case, client=group.zaken_client)
105+
resolve_status_type(case, client=group.catalogi_client)
106+
resolve_resultaat(case, client=group.zaken_client)
107+
resolve_resultaat_type(case, client=group.catalogi_client)
120108
add_zaak_type_config(case)
121109
add_status_type_config(case)
122110

123111
# TODO error handling if these are none?
124112
# use contextmanager to ensure the `requests.Session` is reused
125-
with zaken_client, catalogi_client:
113+
with group.catalogi_client, group.zaken_client:
126114
with parallel(max_workers=settings.CASE_LIST_NUM_THREADS) as executor:
127115
futures = [
128-
executor.submit(resolve_zaak_type, case, client=catalogi_client)
116+
executor.submit(resolve_zaak_type, case, client=group.catalogi_client)
129117
for case in cases
130118
]
131119
concurrent.futures.wait(futures)

0 commit comments

Comments
 (0)