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

[#2771] Add support for fetching open submissions with KVK #1411

Merged
merged 3 commits into from
Sep 30, 2024
Merged
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
58 changes: 51 additions & 7 deletions src/open_inwoner/cms/cases/views/cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@
from zgw_consumers.concurrent import parallel

from open_inwoner.htmx.mixins import RequiresHtmxMixin
from open_inwoner.openzaak.api_models import Zaak
from open_inwoner.openzaak.api_models import OpenSubmission, Zaak
from open_inwoner.openzaak.cases import preprocess_data
from open_inwoner.openzaak.formapi import fetch_open_submissions
from open_inwoner.openzaak.models import OpenZaakConfig, ZGWApiGroupConfig
from open_inwoner.openzaak.types import UniformCase
from open_inwoner.openzaak.utils import get_user_fetch_parameters
Expand Down Expand Up @@ -47,17 +46,37 @@ def process_data(self) -> dict:
return {**self.zaak.process_data(), "api_group": self.api_group}


@dataclass(frozen=True)
class SubmissionWithApiGroup:
submission: OpenSubmission
api_group: ZGWApiGroupConfig

@property
def identifier(self):
return self.submission.url

def process_data(self) -> dict:
return {**self.submission.process_data(), "api_group": self.api_group}


class CaseListService:
def __init__(self, request: HttpRequest):
self.request = request

def get_cases_for_api_group(self, group: ZGWApiGroupConfig):
def get_cases_for_api_group(self, group: ZGWApiGroupConfig) -> list[UniformCase]:
raw_cases = group.zaken_client.fetch_cases(
**get_user_fetch_parameters(self.request)
**get_user_fetch_parameters(self.request, check_rsin=True)
)
preprocessed_cases = preprocess_data(raw_cases, group)
return preprocessed_cases

def get_submissions_for_api_group(
self, group: ZGWApiGroupConfig
) -> list[UniformCase]:
return group.forms_client.fetch_open_submissions(
**get_user_fetch_parameters(self.request, check_rsin=False)
)

def get_cases(self) -> list[ZaakWithApiGroup]:
all_api_groups = list(ZGWApiGroupConfig.objects.all())

Expand All @@ -84,10 +103,35 @@ def get_cases(self) -> list[ZaakWithApiGroup]:
return cases_with_api_group

def get_submissions(self):
subs = fetch_open_submissions(self.request.user.bsn)
subs.sort(key=lambda sub: sub.datum_laatste_wijziging, reverse=True)
all_api_groups = list(
ZGWApiGroupConfig.objects.exclude(form_service__isnull=True)
)

with parallel() as executor:
futures = [
executor.submit(self.get_submissions_for_api_group, group)
for group in all_api_groups
]

subs_with_api_group = []
for task in concurrent.futures.as_completed(futures):
try:
group_for_task = all_api_groups[futures.index(task)]
for row in task.result():
subs_with_api_group.append(
SubmissionWithApiGroup(
submission=row, api_group=group_for_task
)
)
except BaseException:
logger.exception("Error fetching and pre-processing cases")

# Sort submissions by date modified
subs_with_api_group.sort(
key=lambda sub: sub.submission.datum_laatste_wijziging, reverse=True
)

return subs
return subs_with_api_group

@staticmethod
def get_case_filter_status(zaak: Zaak) -> CaseFilterFormOption:
Expand Down
74 changes: 66 additions & 8 deletions src/open_inwoner/openzaak/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,25 @@ class ZakenClient(ZgwAPIClient):
def fetch_cases(
self,
user_bsn: str | None = None,
user_kvk_or_rsin: str | None = None,
user_kvk: str | None = None,
user_rsin: str | None = None,
max_requests: int = 4,
identificatie: str | None = None,
vestigingsnummer: str | None = None,
):
if user_bsn and (user_kvk_or_rsin or vestigingsnummer):
if user_bsn and (user_kvk or user_rsin or vestigingsnummer):
raise ValueError(
"either `user_bsn` or `user_kvk_or_rsin`/`vestigingsnummer` should be supplied, not both"
"either `user_bsn` or `user_kvk`/`user_risin` (+ optionally `vestigingsnummer`) "
"should be supplied, not both"
)

if user_bsn:
return self.fetch_cases_by_bsn(
user_bsn, max_requests=max_requests, identificatie=identificatie
)
elif user_kvk_or_rsin:

if user_kvk or user_rsin:
user_kvk_or_rsin = user_rsin if user_rsin else user_kvk
return self.fetch_cases_by_kvk_or_rsin(
user_kvk_or_rsin,
max_requests=max_requests,
Expand Down Expand Up @@ -666,17 +670,71 @@ def upload_document(


class FormClient(ZgwAPIClient):
def fetch_open_submissions(self, bsn: str) -> list[OpenSubmission]:
if not bsn:
def fetch_open_submissions(
self,
user_bsn: str | None = None,
user_kvk: str | None = None,
vestigingsnummer: str | None = None,
max_requests: int = 4,
**kwargs,
):
if user_bsn and (user_kvk or vestigingsnummer):
raise ValueError(
"either `user_bsn` or `user_kvk` (optionally with `vestigingsnummer`) "
"should be supplied, not both"
)

if user_bsn:
return self.fetch_open_submissions_by_bsn(
user_bsn, max_requests=max_requests
)

if user_kvk:
return self.fetch_open_submissions_by_kvk(
user_kvk,
max_requests=max_requests,
vestigingsnummer=vestigingsnummer,
)

return []

def fetch_open_submissions_by_bsn(
self,
user_bsn: str,
max_requests: int,
) -> list[OpenSubmission]:
try:
response = self.get(
"openstaande-inzendingen",
params={"bsn": user_bsn},
)
data = get_json_response(response)
all_data = list(pagination_helper(self, data, max_requests=max_requests))
except (RequestException, ClientError) as e:
logger.exception("exception while making request", exc_info=e)
return []

results = factory(OpenSubmission, all_data)

return results

def fetch_open_submissions_by_kvk(
self,
user_kvk: str,
vestigingsnummer: str | None,
max_requests: int,
) -> list[OpenSubmission]:
request_params = {"kvk": user_kvk}
if vestigingsnummer:
request_params["vestigingsnummer"] = vestigingsnummer

try:
response = self.get(
"openstaande-inzendingen",
params={"bsn": bsn},
params=request_params,
)
data = get_json_response(response)
all_data = list(pagination_helper(self, data))
all_data = list(pagination_helper(self, data, max_requests=max_requests))
except (RequestException, ClientError) as e:
logger.exception("exception while making request", exc_info=e)
return []
Expand Down
16 changes: 0 additions & 16 deletions src/open_inwoner/openzaak/formapi.py

This file was deleted.

75 changes: 65 additions & 10 deletions src/open_inwoner/openzaak/tests/mocks.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
from furl import furl
from zgw_consumers.api_models.constants import VertrouwelijkheidsAanduidingen

from open_inwoner.accounts.models import User
from open_inwoner.openzaak.tests.shared import FORMS_ROOT
from open_inwoner.utils.test import paginated_response


class ESuiteSubmissionData:
def __init__(self):
def __init__(self, *, zaken_root: str, forms_root: str, user: User):
self.zaken_root = zaken_root
self.forms_root = forms_root
self.user = user

self.submission_1 = {
"url": "https://dmidoffice2.esuite-development.net/formulieren-provider/api/v1/8e3ae29c-7bc5-4f7d-a27c-b0c83c13328e",
"uuid": "8e3ae29c-7bc5-4f7d-a27c-b0c83c13328e",
Expand All @@ -19,18 +28,64 @@ def __init__(self):
"datumLaatsteWijziging": "2023-02-13T14:10:26.197000+0100",
"eindDatumGeldigheid": "2023-05-14T14:10:26.197+02:00",
}
# note this is a weird esuite response without pagination links
self.response = {
"count": 2,
"results": [
self.submission_1,
self.submission_2,
],
self.submission_3 = {
"url": "https://dmidoffice2.esuite-development.net/formulieren-provider/api/v1/e25769c1-dcb4-4d3c-a61c-fd7d0c78f296",
"uuid": "e25769c1-dcb4-4d3c-a61c-fd7d0c78f296",
"naam": "Indienen bezwaarschrift",
"vervolgLink": "https://dloket2.esuite-development.net/formulieren-nieuw/formulier/start/e25769c1-dcb4-4d3c-a61c-fd7d0c78f296",
"datumLaatsteWijziging": "2023-04-05T14:10:26.197000+0100",
"eindDatumGeldigheid": "2023-06-14T14:10:26.197+02:00",
}

def install_mocks(self, m):
# esuite response without pagination links
if self.forms_root == FORMS_ROOT:
self.response = {
"count": 2,
"results": [
self.submission_1,
self.submission_2,
],
}
else:
self.response = {
"count": 1,
"results": [
self.submission_3,
],
}

def install_digid_mocks(self, m):
m.get(
furl(f"{self.zaken_root}zaken")
.add(
{
"rol__betrokkeneIdentificatie__natuurlijkPersoon__inpBsn": self.user.bsn,
"maximaleVertrouwelijkheidaanduiding": VertrouwelijkheidsAanduidingen.openbaar,
}
)
.url,
json=paginated_response([]),
)
m.get(
f"{self.forms_root}openstaande-inzendingen",
json=self.response,
)
return self

def install_eherkenning_mocks(self, m):
m.get(
furl(f"{self.zaken_root}zaken")
.add(
{
"rol__betrokkeneIdentificatie__nietNatuurlijkPersoon__innNnpId": self.user.kvk,
"maximaleVertrouwelijkheidaanduiding": VertrouwelijkheidsAanduidingen.openbaar,
}
)
.url,
json=paginated_response([]),
)
m.get(
f"{FORMS_ROOT}openstaande-inzendingen",
f"{self.forms_root}openstaande-inzendingen",
json=self.response,
)
return self
Expand Down
Loading
Loading