From 289fc2126ca298e08b16ba1d41d38f3f256c0c6c Mon Sep 17 00:00:00 2001 From: Steven Bal Date: Mon, 5 Feb 2024 14:14:34 +0100 Subject: [PATCH] :recycle: [#2060] Use ZGW API clients directly in views instead of using intermediate functions that each build a new client --- .../accounts/views/contactmoments.py | 11 +- src/open_inwoner/accounts/views/profile.py | 19 +- src/open_inwoner/cms/cases/views/cases.py | 18 +- src/open_inwoner/cms/cases/views/mixins.py | 41 +-- src/open_inwoner/cms/cases/views/status.py | 159 ++++++----- src/open_inwoner/openklant/clients.py | 42 +-- src/open_inwoner/openklant/services.py | 9 +- .../openklant/views/contactform.py | 105 ++++---- src/open_inwoner/openklant/wrap.py | 61 +---- src/open_inwoner/openzaak/cases.py | 250 ++---------------- src/open_inwoner/openzaak/catalog.py | 111 -------- src/open_inwoner/openzaak/clients.py | 118 +++++++-- src/open_inwoner/openzaak/documents.py | 45 +--- .../management/commands/zgw_dev_status.py | 55 ++-- .../0035_populate_zaaktypeconfig_urls.py | 13 +- src/open_inwoner/openzaak/notifications.py | 84 ++++-- .../openzaak/tests/test_case_detail.py | 4 +- .../openzaak/tests/test_case_request.py | 10 +- .../openzaak/tests/test_documents.py | 63 ++--- src/open_inwoner/openzaak/zgw_imports.py | 68 +++-- src/open_inwoner/pdc/managers.py | 12 +- src/open_inwoner/search/views.py | 17 +- 22 files changed, 540 insertions(+), 775 deletions(-) delete mode 100644 src/open_inwoner/openzaak/catalog.py diff --git a/src/open_inwoner/accounts/views/contactmoments.py b/src/open_inwoner/accounts/views/contactmoments.py index 79af911763..03f0ae7c6c 100644 --- a/src/open_inwoner/accounts/views/contactmoments.py +++ b/src/open_inwoner/accounts/views/contactmoments.py @@ -13,14 +13,15 @@ from view_breadcrumbs import BaseBreadcrumbMixin from open_inwoner.openklant.api_models import KlantContactMoment +from open_inwoner.openklant.clients import build_client from open_inwoner.openklant.constants import Status from open_inwoner.openklant.models import ContactFormSubject from open_inwoner.openklant.wrap import ( fetch_klantcontactmoment, fetch_klantcontactmomenten, - fetch_objectcontactmoment, get_fetch_parameters, ) +from open_inwoner.openzaak.clients import build_client as build_client_openzaak from open_inwoner.utils.mixins import PaginationMixin from open_inwoner.utils.views import CommonPageMixin @@ -171,8 +172,12 @@ def get_context_data(self, **kwargs): if not kcm: raise Http404() - ocm = fetch_objectcontactmoment(kcm.contactmoment, "zaak") - ctx["zaak"] = getattr(ocm, "object", None) + if client := build_client("contactmomenten"): + zaken_client = build_client_openzaak("zaak") + ocm = client.retrieve_objectcontactmoment( + kcm.contactmoment, "zaak", zaken_client + ) + ctx["zaak"] = getattr(ocm, "object", None) ctx["contactmoment"] = self.get_kcm_data(kcm) return ctx diff --git a/src/open_inwoner/accounts/views/profile.py b/src/open_inwoner/accounts/views/profile.py index c94bcf9249..1980feee5b 100644 --- a/src/open_inwoner/accounts/views/profile.py +++ b/src/open_inwoner/accounts/views/profile.py @@ -27,13 +27,13 @@ inbox_page_is_published, ) from open_inwoner.haalcentraal.utils import fetch_brp +from open_inwoner.openklant.clients import build_client from open_inwoner.openklant.wrap import get_fetch_parameters from open_inwoner.plans.models import Plan from open_inwoner.questionnaire.models import QuestionnaireStep from open_inwoner.utils.mixins import ExportMixin from open_inwoner.utils.views import CommonPageMixin, LogMixin -from ...openklant.wrap import fetch_klant, patch_klant from ..forms import BrpUserForm, UserForm, UserNotificationsForm from ..models import Action, User @@ -202,18 +202,19 @@ def update_klant_api(self, user_form_data: dict): if user_form_data.get(local_name) } if update_data: - klant = fetch_klant(**get_fetch_parameters(self.request)) + if client := build_client("klanten"): + klant = client.retrieve_klant(**get_fetch_parameters(self.request)) - if klant: - self.log_system_action( - "retrieved klant for user", user=self.request.user - ) - klant = patch_klant(klant, update_data) if klant: self.log_system_action( - f"patched klant from user profile edit with fields: {', '.join(sorted(update_data.keys()))}", - user=self.request.user, + "retrieved klant for user", user=self.request.user ) + client.partial_update_klant(klant, update_data) + if klant: + self.log_system_action( + f"patched klant from user profile edit with fields: {', '.join(sorted(update_data.keys()))}", + user=self.request.user, + ) def get_form_class(self): user = self.request.user diff --git a/src/open_inwoner/cms/cases/views/cases.py b/src/open_inwoner/cms/cases/views/cases.py index 40f4630f20..c1e969149e 100644 --- a/src/open_inwoner/cms/cases/views/cases.py +++ b/src/open_inwoner/cms/cases/views/cases.py @@ -7,11 +7,8 @@ from open_inwoner.htmx.mixins import RequiresHtmxMixin from open_inwoner.kvk.branches import get_kvk_branch_number -from open_inwoner.openzaak.cases import ( - fetch_cases, - fetch_cases_by_kvk_or_rsin, - preprocess_data, -) +from open_inwoner.openzaak.cases import preprocess_data +from open_inwoner.openzaak.clients import build_client from open_inwoner.openzaak.formapi import fetch_open_submissions from open_inwoner.openzaak.models import OpenZaakConfig from open_inwoner.openzaak.types import UniformCase @@ -59,6 +56,11 @@ def page_title(self): return _("Mijn aanvragen") def get_cases(self): + client = build_client("zaak") + + if client is None: + return [] + if self.request.user.kvk: kvk_or_rsin = self.request.user.kvk config = OpenZaakConfig.get_solo() @@ -66,13 +68,13 @@ def get_cases(self): kvk_or_rsin = self.request.user.rsin vestigingsnummer = get_kvk_branch_number(self.request.session) if vestigingsnummer: - raw_cases = fetch_cases_by_kvk_or_rsin( + raw_cases = client.fetch_cases_by_kvk_or_rsin( kvk_or_rsin=kvk_or_rsin, vestigingsnummer=vestigingsnummer ) else: - raw_cases = fetch_cases_by_kvk_or_rsin(kvk_or_rsin=kvk_or_rsin) + raw_cases = client.fetch_cases_by_kvk_or_rsin(kvk_or_rsin=kvk_or_rsin) else: - raw_cases = fetch_cases(self.request.user.bsn) + raw_cases = client.fetch_cases(self.request.user.bsn) preprocessed_cases = preprocess_data(raw_cases) return preprocessed_cases diff --git a/src/open_inwoner/cms/cases/views/mixins.py b/src/open_inwoner/cms/cases/views/mixins.py index 3dded95839..df747a6ca2 100644 --- a/src/open_inwoner/cms/cases/views/mixins.py +++ b/src/open_inwoner/cms/cases/views/mixins.py @@ -7,13 +7,7 @@ from open_inwoner.kvk.branches import get_kvk_branch_number from open_inwoner.openzaak.api_models import Zaak -from open_inwoner.openzaak.cases import ( - fetch_roles_for_case_and_bsn, - fetch_roles_for_case_and_kvk_or_rsin, - fetch_roles_for_case_and_vestigingsnummer, - fetch_single_case, -) -from open_inwoner.openzaak.catalog import fetch_single_case_type +from open_inwoner.openzaak.clients import build_client from open_inwoner.openzaak.models import OpenZaakConfig from open_inwoner.openzaak.types import UniformCase from open_inwoner.openzaak.utils import is_zaak_visible @@ -67,11 +61,17 @@ def dispatch(self, request, *args, **kwargs): ) return self.handle_no_permission() - self.case = self.get_case(kwargs) + client = build_client("zaak") + if client is None: + return super().dispatch(request, *args, **kwargs) + + self.case = self.get_case(client, kwargs) if self.case: # check if we have a role in this case if request.user.bsn: - if not fetch_roles_for_case_and_bsn(self.case.url, request.user.bsn): + if not client.fetch_roles_for_case_and_bsn( + self.case.url, request.user.bsn + ): logger.debug( f"CaseAccessMixin - permission denied: no role for the case {self.case.url}" ) @@ -83,22 +83,33 @@ def dispatch(self, request, *args, **kwargs): identifier = self.request.user.rsin vestigingsnummer = get_kvk_branch_number(self.request.session) - if vestigingsnummer and not fetch_roles_for_case_and_vestigingsnummer( - self.case.url, vestigingsnummer + if ( + vestigingsnummer + and not client.fetch_roles_for_case_and_vestigingsnummer( + self.case.url, vestigingsnummer + ) ): logger.debug( f"CaseAccessMixin - permission denied: no role for the case {self.case.url}" ) return self.handle_no_permission() - if not fetch_roles_for_case_and_kvk_or_rsin(self.case.url, identifier): + if not client.fetch_roles_for_case_and_kvk_or_rsin( + self.case.url, identifier + ): logger.debug( f"CaseAccessMixin - permission denied: no role for the case {self.case.url}" ) return self.handle_no_permission() # resolve case-type - self.case.zaaktype = fetch_single_case_type(self.case.zaaktype) + if catalogi_client := build_client("catalogi"): + self.case.zaaktype = catalogi_client.fetch_single_case_type( + self.case.zaaktype + ) + else: + self.case.zaaktype = None + if not self.case.zaaktype: logger.debug( "CaseAccessMixin - permission denied: no case type for case {self.case.url}" @@ -120,12 +131,12 @@ def handle_no_permission(self): return super().handle_no_permission() - def get_case(self, kwargs) -> Optional[Zaak]: + def get_case(self, client, kwargs) -> Optional[Zaak]: case_uuid = kwargs.get("object_id") if not case_uuid: return None - return fetch_single_case(case_uuid) + return client.fetch_single_case(case_uuid) class OuterCaseAccessMixin(LoginRequiredMixin): diff --git a/src/open_inwoner/cms/cases/views/status.py b/src/open_inwoner/cms/cases/views/status.py index 725c362a4f..99780077c1 100644 --- a/src/open_inwoner/cms/cases/views/status.py +++ b/src/open_inwoner/cms/cases/views/status.py @@ -20,32 +20,17 @@ from view_breadcrumbs import BaseBreadcrumbMixin from zgw_consumers.api_models.constants import RolOmschrijving +from open_inwoner.openklant.clients import build_client as build_client_openklant from open_inwoner.openklant.models import OpenKlantConfig -from open_inwoner.openklant.wrap import ( - create_contactmoment, - create_klant, - fetch_klant, - get_fetch_parameters, -) +from open_inwoner.openklant.wrap import get_fetch_parameters from open_inwoner.openzaak.api_models import Status, StatusType, Zaak -from open_inwoner.openzaak.cases import ( - connect_case_with_document, - fetch_case_information_objects, - fetch_case_information_objects_for_case_and_info, - fetch_case_roles, - fetch_single_result, - fetch_single_status, - fetch_status_history, -) -from open_inwoner.openzaak.catalog import ( - fetch_single_status_type, - fetch_status_types_no_cache, +from open_inwoner.openzaak.clients import ( + build_client, + build_client as build_client_openzaak, ) from open_inwoner.openzaak.documents import ( - download_document, fetch_single_information_object_url, fetch_single_information_object_uuid, - upload_document, ) from open_inwoner.openzaak.models import ( OpenZaakConfig, @@ -148,12 +133,19 @@ def get_context_data(self, **kwargs): config = OpenZaakConfig.get_solo() status_translate = StatusTranslation.objects.get_lookup() + zaken_client = build_client("zaak") + # fetch data associated with `self.case` - documents = self.get_case_document_files(self.case) - statuses = fetch_status_history(self.case.url) + documents = self.get_case_document_files(self.case, zaken_client) + statuses = zaken_client.fetch_status_history(self.case.url) self.store_statustype_mapping(self.case.zaaktype.identificatie) self.store_resulttype_mapping(self.case.zaaktype.identificatie) - statustypen = fetch_status_types_no_cache(self.case.zaaktype.url) + + statustypen = [] + if catalogi_client := build_client("catalogi"): + statustypen = catalogi_client.fetch_status_types_no_cache( + self.case.zaaktype.url + ) # NOTE we cannot sort on the Status.datum_status_gezet (datetime) because eSuite # returns zeros as the time component of the datetime, so we're going with the @@ -168,14 +160,16 @@ def get_context_data(self, **kwargs): second_status_preview = None # handle/transform data associated with `self.case` - status_types_mapping = self.sync_statuses_with_status_types(statuses) + status_types_mapping = self.sync_statuses_with_status_types( + statuses, zaken_client + ) end_statustype_data = self.handle_end_statustype_data( status_types_mapping=status_types_mapping, end_statustype=self.handle_end_statustype(statuses, statustypen), status_translate=status_translate, ) result_data = self.get_result_data( - self.case, self.resulttype_config_mapping + self.case, self.resulttype_config_mapping, zaken_client ) hooks.case_status_seen(self.request.user, self.case) @@ -253,7 +247,7 @@ def get_second_status_preview(self, statustypen: list) -> Optional[StatusType]: ) def sync_statuses_with_status_types( - self, statuses: list[Status] + self, statuses: list[Status], zaken_client ) -> dict[str, StatusType]: """ Update `statuses` (including the status on this view) and sync with `status_types`: @@ -283,13 +277,17 @@ def sync_statuses_with_status_types( logger.info( "Issue #2037 -- Retrieving status individually because of eSuite" ) - self.case.status = fetch_single_status(self.case.status) + self.case.status = zaken_client.fetch_single_status(self.case.status) status_types_mapping[self.case.status.statustype].append(self.case.status) statuses.append(self.case.status) + catalogi_client = build_client("catalogi") + if catalogi_client is None: + return status_types_mapping + # final mapping {status_type url: status_type} for status_type_url, _statuses in list(status_types_mapping.items()): - status_type = fetch_single_status_type(status_type_url) + status_type = catalogi_client.fetch_single_status_type(status_type_url) status_types_mapping[status_type_url] = status_type # resolve statustype url to `StatusType` for status in _statuses: @@ -471,11 +469,11 @@ def get_upload_info_context(self, case: Zaak): } @staticmethod - def get_result_data(case: Zaak, result_type_config_mapping: dict) -> dict: + def get_result_data(case: Zaak, result_type_config_mapping: dict, client) -> dict: if not case.resultaat: return {} - result = fetch_single_result(case.resultaat) + result = client.fetch_single_result(case.resultaat) display = result.toelichting description = getattr( @@ -489,10 +487,10 @@ def get_result_data(case: Zaak, result_type_config_mapping: dict) -> dict: @staticmethod def get_initiator_display(case: Zaak) -> str: - roles = fetch_case_roles(case.url, RolOmschrijving.initiator) - if not roles: - return "" - return ", ".join([get_role_name_display(r) for r in roles]) + if client := build_client("zaak"): + roles = client.fetch_case_roles(case.url, RolOmschrijving.initiator) + return ", ".join([get_role_name_display(r) for r in roles]) + return "" @staticmethod def get_statuses_data( @@ -539,8 +537,11 @@ def get_statuses_data( ] @staticmethod - def get_case_document_files(case: Zaak) -> List[SimpleFile]: - case_info_objects = fetch_case_information_objects(case.url) + def get_case_document_files(case: Zaak, client) -> List[SimpleFile]: + if not client: + return [] + + case_info_objects = client.fetch_case_information_objects(case.url) # get the information objects for the case objects @@ -613,13 +614,17 @@ def get(self, request, *args, **kwargs): if not self.case: raise Http404 + zaken_client = build_client_openzaak("zaak") + if not zaken_client: + raise Http404 + info_object_uuid = kwargs["info_id"] info_object = fetch_single_information_object_uuid(info_object_uuid) if not info_object: raise Http404 # check if this info_object belongs to this case - if not fetch_case_information_objects_for_case_and_info( + if not zaken_client.fetch_case_information_objects_for_case_and_info( self.case.url, info_object.url ): raise PermissionDenied() @@ -630,7 +635,10 @@ def get(self, request, *args, **kwargs): raise PermissionDenied() # retrieve and stream content - content_stream = download_document(info_object.inhoud) + content_stream = None + if client := build_client_openzaak("document"): + content_stream = client.download_document(info_object.inhoud) + if not content_stream: raise Http404 @@ -691,7 +699,11 @@ def handle_document_upload(self, request, form): document_type = cleaned_data["type"] source_organization = self.case.bronorganisatie - created_document = upload_document( + client = build_client_openzaak("document") + if client is None: + return self.handle_document_error(request, file) + + created_document = client.upload_document( request.user, file, title, @@ -701,9 +713,11 @@ def handle_document_upload(self, request, form): if not created_document: return self.handle_document_error(request, file) - created_relationship = connect_case_with_document( - self.case.url, created_document.get("url") - ) + created_relationship = None + if zaken_client := build_client_openzaak("zaak"): + created_relationship = zaken_client.connect_case_with_document( + self.case.url, created_document.get("url") + ) if not created_relationship: return self.handle_document_error(request, file) @@ -836,32 +850,39 @@ def register_by_api(self, form, config: OpenKlantConfig): except ObjectDoesNotExist: ztc = None - klant = fetch_klant(**get_fetch_parameters(self.request)) - if klant: - self.log_system_action("retrieved klant for user", user=self.request.user) - else: - self.log_system_action( - "could not retrieve klant for user", user=self.request.user - ) - data = { - "bronorganisatie": config.register_bronorganisatie_rsin, - "voornaam": self.request.user.first_name, - "voorvoegselAchternaam": self.request.user.infix, - "achternaam": self.request.user.last_name, - "emailadres": self.request.user.email, - "telefoonnummer": self.request.user.phonenumber, - } - # registering klanten won't work in e-Suite as it always pulls from BRP (but try anyway and fallback to appending details to tekst if fails) - klant = create_klant(data) + if klanten_client := build_client_openklant("klanten"): + klant = klanten_client.retrieve_klant(**get_fetch_parameters(self.request)) + if klant: self.log_system_action( - "created klant for basic authenticated user", - user=self.request.user, + "retrieved klant for user", user=self.request.user ) else: self.log_system_action( - "could not create klant for user", user=self.request.user + "could not retrieve klant for user", user=self.request.user ) + data = { + "bronorganisatie": config.register_bronorganisatie_rsin, + "voornaam": self.request.user.first_name, + "voorvoegselAchternaam": self.request.user.infix, + "achternaam": self.request.user.last_name, + "emailadres": self.request.user.email, + "telefoonnummer": self.request.user.phonenumber, + } + # registering klanten won't work in e-Suite as it always pulls from BRP (but try anyway and fallback to appending details to tekst if fails) + klant = klanten_client.create_klant(data) + + if klant: + self.log_system_action( + "created klant for basic authenticated user", + user=self.request.user, + ) + else: + self.log_system_action( + "could not create klant for user", user=self.request.user + ) + else: + self.log_system_action("could not build client for klanten API") # create contact moment question = form.cleaned_data["question"] @@ -877,13 +898,15 @@ def register_by_api(self, form, config: OpenKlantConfig): if ztc and ztc.contact_subject_code: data["onderwerp"] = ztc.contact_subject_code - contactmoment = create_contactmoment(data, klant=klant) - - if contactmoment: - self.log_system_action( - "registered contactmoment by API", user=self.request.user + if contactmomenten_client := build_client_openklant("contactmomenten"): + contactmoment = contactmomenten_client.create_contactmoment( + data, klant=klant ) - return True + if contactmoment: + self.log_system_action( + "registered contactmoment by API", user=self.request.user + ) + return True else: self.log_system_action( "error while registering contactmoment by API", user=self.request.user diff --git a/src/open_inwoner/openklant/clients.py b/src/open_inwoner/openklant/clients.py index bf65c8584e..4dd3020751 100644 --- a/src/open_inwoner/openklant/clients.py +++ b/src/open_inwoner/openklant/clients.py @@ -7,7 +7,6 @@ from zgw_consumers.client import build_client as _build_client from zgw_consumers.utils import pagination_helper -from open_inwoner.openzaak.cases import fetch_case_by_url_no_cache from open_inwoner.utils.api import ClientError, get_json_response from .api_models import ( @@ -129,7 +128,7 @@ def create_contactmoment( if klant: # relate contact to klant though a klantcontactmoment try: - response = self.post( + self.post( "klantcontactmomenten", json={ "klant": klant.url, @@ -156,7 +155,7 @@ def retrieve_contactmoment(self, url) -> Optional[ContactMoment]: return contact_moment def retrieve_objectcontactmomenten_for_contactmoment( - self, contactmoment: ContactMoment + self, contactmoment: ContactMoment, zaken_client ) -> List[ObjectContactMoment]: try: response = self.get( @@ -171,18 +170,19 @@ def retrieve_objectcontactmomenten_for_contactmoment( object_contact_momenten = factory(ObjectContactMoment, all_data) # resolve linked resources - object_mapping = {} - for ocm in object_contact_momenten: - assert ocm.contactmoment == contactmoment.url - ocm.contactmoment = contactmoment - if ocm.object_type == "zaak": - object_url = ocm.object - # Avoid fetching the same object, if multiple relations wit the same object exist - if ocm.object in object_mapping: - ocm.object = object_mapping[object_url] - else: - ocm.object = fetch_case_by_url_no_cache(ocm.object) - object_mapping[object_url] = ocm.object + if zaken_client: + object_mapping = {} + for ocm in object_contact_momenten: + assert ocm.contactmoment == contactmoment.url + ocm.contactmoment = contactmoment + if ocm.object_type == "zaak": + object_url = ocm.object + # Avoid fetching the same object, if multiple relations with the same object exist + if ocm.object in object_mapping: + ocm.object = object_mapping[object_url] + else: + ocm.object = zaken_client.fetch_case_by_url_no_cache(ocm.object) + object_mapping[object_url] = ocm.object return object_contact_momenten @@ -211,10 +211,12 @@ def retrieve_klantcontactmomenten_for_klant( return klanten_contact_moments def retrieve_objectcontactmomenten_for_object_type( - self, contactmoment: ContactMoment, object_type: str + self, contactmoment: ContactMoment, object_type: str, zaken_client ) -> List[ObjectContactMoment]: - moments = self.retrieve_objectcontactmomenten_for_contactmoment(contactmoment) + moments = self.retrieve_objectcontactmomenten_for_contactmoment( + contactmoment, zaken_client + ) # eSuite doesn't implement a `object_type` query parameter ret = [moment for moment in moments if moment.object_type == object_type] @@ -222,10 +224,10 @@ def retrieve_objectcontactmomenten_for_object_type( return ret def retrieve_objectcontactmoment( - self, contactmoment: ContactMoment, object_type: str + self, contactmoment: ContactMoment, object_type: str, zaken_client ) -> Optional[ObjectContactMoment]: ocms = self.retrieve_objectcontactmomenten_for_object_type( - contactmoment, object_type + contactmoment, object_type, zaken_client ) if ocms: return ocms[0] @@ -243,5 +245,5 @@ def build_client(type_) -> Optional[APIClient]: client = _build_client(service, client_factory=client_class) return client - logger.warning(f"no service defined for {type_}") + logger.warning("no service defined for %s", type_) return None diff --git a/src/open_inwoner/openklant/services.py b/src/open_inwoner/openklant/services.py index 44d2266808..53db50179d 100644 --- a/src/open_inwoner/openklant/services.py +++ b/src/open_inwoner/openklant/services.py @@ -1,5 +1,5 @@ from open_inwoner.accounts.models import User -from open_inwoner.openklant.wrap import fetch_klant +from open_inwoner.openklant.clients import build_client from open_inwoner.utils.logentry import system_action from .wrap import get_fetch_parameters @@ -11,7 +11,12 @@ def update_user_from_klant(request): user: User = request.user - klant = fetch_klant(**get_fetch_parameters(request)) + client = build_client("klanten") + if not client: + return + + klant = client.retrieve_klant(**get_fetch_parameters(request)) + if not klant: return diff --git a/src/open_inwoner/openklant/views/contactform.py b/src/open_inwoner/openklant/views/contactform.py index 7cb586ad62..c6ed2de111 100644 --- a/src/open_inwoner/openklant/views/contactform.py +++ b/src/open_inwoner/openklant/views/contactform.py @@ -6,15 +6,10 @@ from mail_editor.helpers import find_template from view_breadcrumbs import BaseBreadcrumbMixin +from open_inwoner.openklant.clients import build_client from open_inwoner.openklant.forms import ContactForm from open_inwoner.openklant.models import OpenKlantConfig -from open_inwoner.openklant.wrap import ( - create_contactmoment, - create_klant, - fetch_klant, - get_fetch_parameters, - patch_klant, -) +from open_inwoner.openklant.wrap import get_fetch_parameters from open_inwoner.utils.views import CommonPageMixin, LogMixin @@ -116,56 +111,61 @@ def register_by_api(self, form, config: OpenKlantConfig): assert config.has_api_configuration() # fetch/update/create klant - if self.request.user.is_authenticated and ( - self.request.user.bsn or self.request.user.kvk - ): - klant = fetch_klant(**get_fetch_parameters(self.request)) - - if klant: - self.log_system_action( - "retrieved klant for BSN or KVK user", user=self.request.user + klant = None + if klanten_client := build_client("klanten"): + if self.request.user.is_authenticated and ( + self.request.user.bsn or self.request.user.kvk + ): + klant = klanten_client.retrieve_klant( + **get_fetch_parameters(self.request) ) - # check if we have some data missing from the Klant - update_data = {} - if not klant.emailadres and form.cleaned_data["email"]: - update_data["emailadres"] = form.cleaned_data["email"] - if not klant.telefoonnummer and form.cleaned_data["phonenumber"]: - update_data["telefoonnummer"] = form.cleaned_data["phonenumber"] - if update_data: - patch_klant(klant, update_data) + if klant: self.log_system_action( - "patched klant from user with missing fields: {patched}".format( - patched=", ".join(sorted(update_data.keys())) - ), - user=self.request.user, + "retrieved klant for BSN or KVK user", user=self.request.user ) - else: - self.log_system_action( - "could not retrieve klant for BSN or KVK user", - user=self.request.user, - ) - else: - data = { - "bronorganisatie": config.register_bronorganisatie_rsin, - "voornaam": form.cleaned_data["first_name"], - "voorvoegselAchternaam": form.cleaned_data["infix"], - "achternaam": form.cleaned_data["last_name"], - "emailadres": form.cleaned_data["email"], - "telefoonnummer": form.cleaned_data["phonenumber"], - } - # registering klanten won't work in e-Suite as it always pulls from BRP - # (but try anyway and fallback to appending details to tekst if fails) - klant = create_klant(data) - if klant: - if self.request.user.is_authenticated: + # check if we have some data missing from the Klant + update_data = {} + if not klant.emailadres and form.cleaned_data["email"]: + update_data["emailadres"] = form.cleaned_data["email"] + if not klant.telefoonnummer and form.cleaned_data["phonenumber"]: + update_data["telefoonnummer"] = form.cleaned_data["phonenumber"] + if update_data: + klanten_client.partial_update_klant(klant, update_data) + self.log_system_action( + "patched klant from user with missing fields: {patched}".format( + patched=", ".join(sorted(update_data.keys())) + ), + user=self.request.user, + ) + else: self.log_system_action( - "created klant for basic authenticated user", + "could not retrieve klant for BSN or KVK user", user=self.request.user, ) - else: - self.log_system_action("created klant for anonymous user") + + else: + data = { + "bronorganisatie": config.register_bronorganisatie_rsin, + "voornaam": form.cleaned_data["first_name"], + "voorvoegselAchternaam": form.cleaned_data["infix"], + "achternaam": form.cleaned_data["last_name"], + "emailadres": form.cleaned_data["email"], + "telefoonnummer": form.cleaned_data["phonenumber"], + } + # registering klanten won't work in e-Suite as it always pulls from BRP + # (but try anyway and fallback to appending details to tekst if fails) + klant = klanten_client.create_klant(data) + + if klant: + if self.request.user.is_authenticated: + self.log_system_action( + "created klant for basic authenticated user", + user=self.request.user, + ) + else: + self.log_system_action("created klant for anonymous user") # create contact moment subject = form.cleaned_data["subject"].subject @@ -208,7 +208,12 @@ def register_by_api(self, form, config: OpenKlantConfig): "identificatie": config.register_employee_id, }, } - contactmoment = create_contactmoment(data, klant=klant) + + contactmoment = None + if contactmomenten_client := build_client("contactmomenten"): + contactmoment = contactmomenten_client.create_contactmoment( + data, klant=klant + ) if contactmoment: self.log_system_action( diff --git a/src/open_inwoner/openklant/wrap.py b/src/open_inwoner/openklant/wrap.py index 37f6ae9832..d133d107e9 100644 --- a/src/open_inwoner/openklant/wrap.py +++ b/src/open_inwoner/openklant/wrap.py @@ -2,15 +2,7 @@ from typing import List, Optional from open_inwoner.kvk.branches import get_kvk_branch_number -from open_inwoner.openklant.api_models import ( - ContactMoment, - ContactMomentCreateData, - Klant, - KlantContactMoment, - KlantContactRol, - KlantCreateData, - ObjectContactMoment, -) +from open_inwoner.openklant.api_models import KlantContactMoment from open_inwoner.openklant.clients import build_client from open_inwoner.openklant.models import OpenKlantConfig @@ -82,57 +74,6 @@ def fetch_klantcontactmoment( return kcm -def fetch_objectcontactmoment( - contactmoment: ContactMoment, object_type: str -) -> Optional[ObjectContactMoment]: - client = build_client("contactmomenten") - if client is None: - return - - return client.retrieve_objectcontactmoment(contactmoment, object_type) - - -def fetch_klant( - user_bsn: Optional[str] = None, - user_kvk_or_rsin: Optional[str] = None, - client=None, -) -> Optional[Klant]: - client = client or build_client("klanten") - if client is None: - return - - return client.retrieve_klant(user_bsn=user_bsn, user_kvk_or_rsin=user_kvk_or_rsin) - - -def create_klant(data: KlantCreateData) -> Optional[Klant]: - client = build_client("klanten") - if client is None: - return - - return client.create_klant(data) - - -def patch_klant(klant: Klant, update_data) -> Optional[Klant]: - client = build_client("klanten") - if client is None: - return - - return client.partial_update_klant(klant, update_data) - - -def create_contactmoment( - data: ContactMomentCreateData, - *, - klant: Optional[Klant] = None, - rol: Optional[str] = KlantContactRol.BELANGHEBBENDE -) -> Optional[ContactMoment]: - client = build_client("contactmomenten") - if client is None: - return - - return client.create_contactmoment(data, klant=klant, rol=rol) - - def get_fetch_parameters(request, use_vestigingsnummer: bool = False) -> dict: """ Determine the parameters used to perform Klanten/Contactmomenten fetches diff --git a/src/open_inwoner/openzaak/cases.py b/src/open_inwoner/openzaak/cases.py index 1978a1c878..7b7ed6316c 100644 --- a/src/open_inwoner/openzaak/cases.py +++ b/src/open_inwoner/openzaak/cases.py @@ -1,233 +1,14 @@ import logging -from typing import List, Optional -from django.conf import settings - -from zgw_consumers.api_models.constants import RolTypes - -from ..utils.decorators import cache as cache_result -from .api_models import Resultaat, Rol, Status, Zaak, ZaakInformatieObject -from .catalog import fetch_single_case_type, fetch_single_status_type +from .api_models import Zaak from .clients import build_client from .models import ZaakTypeConfig, ZaakTypeStatusTypeConfig from .utils import is_zaak_visible logger = logging.getLogger(__name__) -CRS_HEADERS = {"Content-Crs": "EPSG:4326", "Accept-Crs": "EPSG:4326"} - - -def fetch_cases( - user_bsn: str, max_requests: Optional[int] = 1, identificatie: Optional[str] = None -) -> List[Zaak]: - """ - retrieve cases for particular user with allowed confidentiality level - - :param:max_requests - used to limit the number of requests to list_zaken resource. - :param:identificatie - used to filter the cases by a specific identification - """ - client = build_client("zaak") - - if client is None: - return [] - - return client.fetch_cases( - user_bsn=user_bsn, max_requests=max_requests, identificatie=identificatie - ) - - -def fetch_cases_by_kvk_or_rsin( - kvk_or_rsin: Optional[str], - max_requests: Optional[int] = 1, - zaak_identificatie: Optional[str] = None, - vestigingsnummer: Optional[str] = None, -) -> List[Zaak]: - """ - retrieve cases for particular company with allowed confidentiality level - - :param max_requests: - used to limit the number of requests to list_zaken resource. - :param zaak_identificatie: - used to filter the cases by a unique Zaak identification number - :param vestigingsnummer: - used to filter the cases by a vestigingsnummer - """ - client = build_client("zaak") - - if client is None: - return [] - - return client.fetch_cases_by_kvk_or_rsin( - kvk_or_rsin=kvk_or_rsin, - max_requests=max_requests, - zaak_identificatie=zaak_identificatie, - vestigingsnummer=vestigingsnummer, - ) - - -def fetch_single_case(case_uuid: str) -> Optional[Zaak]: - client = build_client("zaak") - - if client is None: - return - - return client.fetch_single_case(case_uuid) - - -def fetch_single_case_information_object(url: str) -> Optional[ZaakInformatieObject]: - client = build_client("zaak") - - if client is None: - return - - return client.fetch_single_case_information_object(url) - - -def fetch_case_by_url_no_cache(case_url: str) -> Optional[Zaak]: - client = build_client("zaak") - return client.fetch_case_by_url_no_cache(case_url) - - -# not cached for quicker uploaded document visibility -def fetch_case_information_objects(case_url: str) -> List[ZaakInformatieObject]: - client = build_client("zaak") - - if client is None: - return [] - - return client.fetch_case_information_objects(case_url) - - -@cache_result("status_history:{case_url}", timeout=settings.CACHE_ZGW_ZAKEN_TIMEOUT) -def fetch_status_history(case_url: str) -> List[Status]: - return fetch_status_history_no_cache(case_url) - - -def fetch_status_history_no_cache(case_url: str) -> List[Status]: - client = build_client("zaak") - - if client is None: - return [] - - return client.fetch_status_history_no_cache(case_url) - - -def fetch_single_status(status_url: str) -> Optional[Status]: - client = build_client("zaak") - - if client is None: - return - return client.fetch_single_status(status_url) - -def fetch_case_roles( - case_url: str, role_desc_generic: Optional[str] = None -) -> List[Rol]: - client = build_client("zaak") - - if client is None: - return [] - - return client.fetch_case_roles(case_url, role_desc_generic=role_desc_generic) - - -# implicitly cached because it uses fetch_case_roles() -def fetch_roles_for_case_and_bsn(case_url: str, bsn: str) -> List[Rol]: - """ - note we do a query on all case_roles and then manually filter our roles from the result, - because e-Suite doesn't support querying on both "zaak" AND "betrokkeneIdentificatie__natuurlijkPersoon__inpBsn" - - see Taiga #948 - """ - case_roles = fetch_case_roles(case_url) - if not case_roles: - return [] - - bsn_roles = [] - for role in case_roles: - if role.betrokkene_type == RolTypes.natuurlijk_persoon: - inp_bsn = role.betrokkene_identificatie.get("inp_bsn") - if inp_bsn and inp_bsn == bsn: - bsn_roles.append(role) - - return bsn_roles - - -# implicitly cached because it uses fetch_case_roles() -def fetch_roles_for_case_and_kvk_or_rsin(case_url: str, kvk_or_rsin: str) -> List[Rol]: - """ - note we do a query on all case_roles and then manually filter our roles from the result, - because e-Suite doesn't support querying on both "zaak" AND "betrokkeneIdentificatie__nietNatuurlijkPersoon__inn_nnp_id" - - see Taiga #948 - """ - case_roles = fetch_case_roles(case_url) - if not case_roles: - return [] - - roles = [] - for role in case_roles: - if role.betrokkene_type == RolTypes.niet_natuurlijk_persoon: - nnp_id = role.betrokkene_identificatie.get("inn_nnp_id") - if nnp_id and nnp_id == kvk_or_rsin: - roles.append(role) - - return roles - - -def fetch_roles_for_case_and_vestigingsnummer( - case_url: str, vestigingsnummer: str -) -> List[Rol]: - """ - note we do a query on all case_roles and then manually filter our roles from the result, - because e-Suite doesn't support querying on both "zaak" AND "rol__betrokkeneIdentificatie__vestiging__vestigingsNummer" - - see Taiga #948 - """ - case_roles = fetch_case_roles(case_url) - if not case_roles: - return [] - - roles = [] - for role in case_roles: - if role.betrokkene_type == RolTypes.vestiging: - identifier = role.betrokkene_identificatie.get("vestigings_nummer") - if identifier and identifier == vestigingsnummer: - roles.append(role) - - return roles - - -# not cached because currently only used in info-object download view -def fetch_case_information_objects_for_case_and_info( - case_url: str, info_object_url: str -) -> List[ZaakInformatieObject]: - client = build_client("zaak") - - if client is None: - return [] - - return client.fetch_case_information_objects_for_case_and_info( - case_url, info_object_url - ) - - -def fetch_single_result(result_url: str) -> Optional[Resultaat]: - client = build_client("zaak") - - if client is None: - return - - return client.fetch_single_result(result_url) - - -def connect_case_with_document(case_url: str, document_url: str) -> Optional[dict]: - client = build_client("zaak") - - if client is None: - return - - return client.connect_case_with_document(case_url, document_url) - - -def resolve_zaak_type(case: Zaak) -> None: +def resolve_zaak_type(case: Zaak, client=None) -> None: """ Resolve `case.zaaktype` (`str`) to a `ZaakType(ZGWModel)` object @@ -235,23 +16,29 @@ def resolve_zaak_type(case: Zaak) -> None: is only made for new case type urls """ case_type_url = case.zaaktype - case_type = fetch_single_case_type(case_type_url) - case.zaaktype = case_type + client = client or build_client("catalogi") + if client: + case_type = client.fetch_single_case_type(case_type_url) + case.zaaktype = case_type -def resolve_status(case: Zaak) -> None: +def resolve_status(case: Zaak, client=None) -> None: """ Resolve `case.status` (`str`) to a `Status(ZGWModel)` object """ - case.status = fetch_single_status(case.status) + client = client or build_client("zaak") + if client: + case.status = client.fetch_single_status(case.status) -def resolve_status_type(case: Zaak) -> None: +def resolve_status_type(case: Zaak, client=None) -> None: """ Resolve `case.statustype` (`str`) to a `StatusType(ZGWModel)` object """ statustype_url = case.status.statustype - case.status.statustype = fetch_single_status_type(statustype_url) + client = client or build_client("zaak") + if client: + case.status.statustype = client.fetch_single_status_type(statustype_url) def add_zaak_type_config(case: Zaak) -> None: @@ -292,14 +79,17 @@ def preprocess_data(cases: list[Zaak]) -> list[Zaak]: Note: we need to iterate twice over `cases` because the `zaak_type` must be resolved to a `ZaakType` object before we can filter by visibility """ + zaken_client = build_client("zaak") + catalogi_client = build_client("catalogi") + for case in cases: - resolve_zaak_type(case) + resolve_zaak_type(case, client=catalogi_client) cases = [case for case in cases if case.status and is_zaak_visible(case)] for case in cases: - resolve_status(case) - resolve_status_type(case) + resolve_status(case, client=zaken_client) + resolve_status_type(case, client=catalogi_client) add_zaak_type_config(case) add_status_type_config(case) diff --git a/src/open_inwoner/openzaak/catalog.py b/src/open_inwoner/openzaak/catalog.py deleted file mode 100644 index e0688e17fc..0000000000 --- a/src/open_inwoner/openzaak/catalog.py +++ /dev/null @@ -1,111 +0,0 @@ -import logging -from typing import List, Optional - -from django.conf import settings - -from zgw_consumers.api_models.catalogi import Catalogus - -from ..utils.decorators import cache as cache_result -from .api_models import InformatieObjectType, ResultaatType, StatusType, ZaakType -from .clients import build_client - -logger = logging.getLogger(__name__) - - -# not cached because only used by tools, -# and because caching (stale) listings can break lookups -def fetch_status_types_no_cache(case_type_url: str) -> List[StatusType]: - client = build_client("catalogi") - - if client is None: - return [] - - return client.fetch_status_types_no_cache(case_type_url) - - -# not cached because only used by tools, -# and because caching (stale) listings can break lookups -def fetch_result_types_no_cache(case_type_url: str) -> List[ResultaatType]: - client = build_client("catalogi") - - if client is None: - return [] - - return client.fetch_result_types_no_cache(case_type_url) - - -def fetch_single_status_type(status_type_url: str) -> Optional[StatusType]: - client = build_client("catalogi") - - if client is None: - return - - return client.fetch_single_status_type(status_type_url) - - -def fetch_single_resultaat_type(resultaat_type_url: str) -> Optional[ResultaatType]: - client = build_client("catalogi") - - if client is None: - return - - return client.fetch_single_resultaat_type(resultaat_type_url) - - -def fetch_zaaktypes_no_cache() -> List[ZaakType]: - """ - list case types - """ - client = build_client("catalogi") - - if client is None: - return [] - - return client.fetch_zaaktypes_no_cache() - - -# not cached because only used by cronjob -# and because caching (stale) listings can break lookups -def fetch_case_types_by_identification_no_cache( - case_type_identification: str, catalog_url: Optional[str] = None -) -> List[ZaakType]: - client = build_client("catalogi") - - if client is None: - return [] - - return client.fetch_case_types_by_identification_no_cache( - case_type_identification, catalog_url=catalog_url - ) - - -def fetch_single_case_type(case_type_url: str) -> Optional[ZaakType]: - client = build_client("catalogi") - - if client is None: - return - - return client.fetch_single_case_type(case_type_url) - - -def fetch_catalogs_no_cache() -> List[Catalogus]: - """ - note the eSuite implementation returns status 500 for this call - """ - client = build_client("catalogi") - - if client is None: - return [] - - return client.fetch_catalogs_no_cache() - - -def fetch_single_information_object_type( - information_object_type_url: str, -) -> Optional[InformatieObjectType]: - client = build_client("catalogi") - - if client is None: - return - - return client.fetch_single_information_object_type(information_object_type_url) diff --git a/src/open_inwoner/openzaak/clients.py b/src/open_inwoner/openzaak/clients.py index ce48e05830..23dee2160c 100644 --- a/src/open_inwoner/openzaak/clients.py +++ b/src/open_inwoner/openzaak/clients.py @@ -11,7 +11,7 @@ from requests import HTTPError, RequestException, Response from zgw_consumers.api_models.base import factory from zgw_consumers.api_models.catalogi import Catalogus -from zgw_consumers.api_models.constants import RolOmschrijving +from zgw_consumers.api_models.constants import RolOmschrijving, RolTypes from zgw_consumers.client import build_client as _build_client from zgw_consumers.service import pagination_helper @@ -47,7 +47,7 @@ class ZakenClient(APIClient): def fetch_cases( self, user_bsn: str, - max_requests: Optional[int] = 1, + max_requests: Optional[int] = 4, identificatie: Optional[str] = None, ) -> List[Zaak]: """ @@ -72,22 +72,19 @@ def fetch_cases( headers=CRS_HEADERS, ) data = get_json_response(response) - # FIXME the previous implementation that used `get_paginated_results` - # never actually retrieved any of the extra pages, because it was limited - # to stop when it reached 100 cases (which is the page size for the Zaken endpoint) - # all_data = list( - # pagination_helper( - # self, - # data, - # max_requests=max_requests, - # headers=CRS_HEADERS, - # ) - # ) + all_data = list( + pagination_helper( + self, + data, + max_requests=max_requests, + headers=CRS_HEADERS, + ) + ) except (RequestException, ClientError) as e: logger.exception("exception while making request", exc_info=e) return [] - cases = factory(Zaak, data["results"]) + cases = factory(Zaak, all_data) return cases @@ -98,7 +95,7 @@ def fetch_cases( def fetch_cases_by_kvk_or_rsin( self, kvk_or_rsin: Optional[str], - max_requests: Optional[int] = 1, + max_requests: Optional[int] = 4, zaak_identificatie: Optional[str] = None, vestigingsnummer: Optional[str] = None, ) -> List[Zaak]: @@ -136,7 +133,14 @@ def fetch_cases_by_kvk_or_rsin( headers=CRS_HEADERS, ) data = get_json_response(response) - all_data = list(pagination_helper(self, data, max_requests=max_requests)) + all_data = list( + pagination_helper( + self, + data, + max_requests=max_requests, + headers=CRS_HEADERS, + ) + ) except (RequestException, ClientError) as e: logger.exception("exception while making request", exc_info=e) return [] @@ -217,6 +221,10 @@ def fetch_status_history_no_cache(self, case_url: str) -> List[Status]: return statuses + @cache_result("status_history:{case_url}", timeout=settings.CACHE_ZGW_ZAKEN_TIMEOUT) + def fetch_status_history(self, case_url: str) -> List[Status]: + return self.fetch_status_history_no_cache(case_url) + @cache_result("status:{status_url}", timeout=60 * 60) def fetch_single_status(self, status_url: str) -> Optional[Status]: try: @@ -263,6 +271,74 @@ def fetch_case_roles( return roles + # implicitly cached because it uses fetch_case_roles() + def fetch_roles_for_case_and_bsn(self, case_url: str, bsn: str) -> List[Rol]: + """ + note we do a query on all case_roles and then manually filter our roles from the result, + because e-Suite doesn't support querying on both "zaak" AND "betrokkeneIdentificatie__natuurlijkPersoon__inpBsn" + + see Taiga #948 + """ + case_roles = self.fetch_case_roles(case_url) + if not case_roles: + return [] + + bsn_roles = [] + for role in case_roles: + if role.betrokkene_type == RolTypes.natuurlijk_persoon: + inp_bsn = role.betrokkene_identificatie.get("inp_bsn") + if inp_bsn and inp_bsn == bsn: + bsn_roles.append(role) + + return bsn_roles + + # implicitly cached because it uses fetch_case_roles() + def fetch_roles_for_case_and_kvk_or_rsin( + self, case_url: str, kvk_or_rsin: str + ) -> List[Rol]: + """ + note we do a query on all case_roles and then manually filter our roles from the result, + because e-Suite doesn't support querying on both "zaak" AND "betrokkeneIdentificatie__nietNatuurlijkPersoon__inn_nnp_id" + + see Taiga #948 + """ + case_roles = self.fetch_case_roles(case_url) + if not case_roles: + return [] + + roles = [] + for role in case_roles: + if role.betrokkene_type == RolTypes.niet_natuurlijk_persoon: + nnp_id = role.betrokkene_identificatie.get("inn_nnp_id") + if nnp_id and nnp_id == kvk_or_rsin: + roles.append(role) + + return roles + + # implicitly cached because it uses fetch_case_roles() + def fetch_roles_for_case_and_vestigingsnummer( + self, case_url: str, vestigingsnummer: str + ) -> List[Rol]: + """ + note we do a query on all case_roles and then manually filter our roles from the result, + because e-Suite doesn't support querying on both "zaak" AND "rol__betrokkeneIdentificatie__vestiging__vestigingsNummer" + + see Taiga #948 + """ + case_roles = self.fetch_case_roles(case_url) + if not case_roles: + return [] + + roles = [] + for role in case_roles: + if role.betrokkene_type == RolTypes.vestiging: + identifier = role.betrokkene_identificatie.get("vestigings_nummer") + if identifier and identifier == vestigingsnummer: + roles.append(role) + + return roles + + # not cached because currently only used in info-object download view def fetch_case_information_objects_for_case_and_info( self, case_url: str, info_object_url: str ) -> List[ZaakInformatieObject]: @@ -315,6 +391,8 @@ def connect_case_with_document( class CatalogiClient(APIClient): + # not cached because only used by tools, + # and because caching (stale) listings can break lookups def fetch_status_types_no_cache(self, case_type_url: str) -> List[StatusType]: try: response = self.get( @@ -331,6 +409,8 @@ def fetch_status_types_no_cache(self, case_type_url: str) -> List[StatusType]: return status_types + # not cached because only used by tools, + # and because caching (stale) listings can break lookups def fetch_result_types_no_cache(self, case_type_url: str) -> List[ResultaatType]: try: response = self.get( @@ -393,6 +473,8 @@ def fetch_zaaktypes_no_cache(self) -> List[ZaakType]: return zaak_types + # not cached because only used by cronjob + # and because caching (stale) listings can break lookups def fetch_case_types_by_identification_no_cache( self, case_type_identification: str, catalog_url: Optional[str] = None ) -> List[ZaakType]: @@ -561,6 +643,6 @@ def build_client(type_) -> Optional[APIClient]: if service: client = _build_client(service, client_factory=client_class) return client - else: - logger.warning(f"no service defined for {type_}") + + logger.warning("no service defined for %s", type_) return None diff --git a/src/open_inwoner/openzaak/documents.py b/src/open_inwoner/openzaak/documents.py index 1727b6f211..74410b9ae7 100644 --- a/src/open_inwoner/openzaak/documents.py +++ b/src/open_inwoner/openzaak/documents.py @@ -2,10 +2,7 @@ from typing import Optional from django.conf import settings -from django.core.files.uploadedfile import InMemoryUploadedFile -from django.utils.functional import SimpleLazyObject -from requests import Response from zgw_consumers.client import build_client from open_inwoner.openzaak.api_models import InformatieObject @@ -18,45 +15,11 @@ @cache_result("information_object_url:{url}", timeout=settings.CACHE_ZGW_ZAKEN_TIMEOUT) def fetch_single_information_object_url(url: str) -> Optional[InformatieObject]: - return _fetch_single_information_object(url=url) + if client := build_client("document"): + return client._fetch_single_information_object(url=url) # not cached because currently only used in info-object download view def fetch_single_information_object_uuid(uuid: str) -> Optional[InformatieObject]: - return _fetch_single_information_object(uuid=uuid) - - -def _fetch_single_information_object( - *, url: Optional[str] = None, uuid: Optional[str] = None -) -> Optional[InformatieObject]: - client = build_client("document") - - if client is None: - return - - return client._fetch_single_information_object(url=url, uuid=uuid) - - -def download_document(url: str) -> Optional[Response]: - client = build_client("document") - if client is None: - return - - return client.download_document(url) - - -def upload_document( - user: SimpleLazyObject, - file: InMemoryUploadedFile, - title: str, - informatieobjecttype_url: str, - source_organization: str, -) -> Optional[dict]: - - client = build_client("document") - if client is None: - return - - return client.upload_document( - user, file, title, informatieobjecttype_url, source_organization - ) + if client := build_client("document"): + return client._fetch_single_information_object(uuid=uuid) diff --git a/src/open_inwoner/openzaak/management/commands/zgw_dev_status.py b/src/open_inwoner/openzaak/management/commands/zgw_dev_status.py index 2f343c31e7..5e3824d56d 100644 --- a/src/open_inwoner/openzaak/management/commands/zgw_dev_status.py +++ b/src/open_inwoner/openzaak/management/commands/zgw_dev_status.py @@ -5,19 +5,6 @@ from django.utils import timezone from open_inwoner.accounts.models import User -from open_inwoner.openzaak.cases import ( - fetch_case_by_url_no_cache, - fetch_cases, - fetch_single_case, - fetch_single_result, - fetch_single_status, -) -from open_inwoner.openzaak.catalog import ( - fetch_result_types_no_cache, - fetch_single_case_type, - fetch_single_status_type, - fetch_status_types_no_cache, -) from open_inwoner.openzaak.clients import build_client from open_inwoner.openzaak.utils import get_zaak_type_config, is_zaak_visible @@ -54,6 +41,14 @@ def silence(self): def handle(self, *args, **options): self.silence() + zaken_client = build_client("zaak") + if zaken_client is None: + self.die(self.style.ERROR("Could not build Zaken API client")) + + catalogi_client = build_client("catalogi") + if catalogi_client is None: + self.die(self.style.ERROR("Could not build Catalogi API client")) + user_ref: str = options.get("user") if not user_ref: self.die("pass 'user'") @@ -74,9 +69,9 @@ def handle(self, *args, **options): if not case_uuid: # if no case_ref is supplied display list of cases and some information about each - cases = fetch_cases(user.bsn) + cases = zaken_client.fetch_cases(user.bsn) for case in cases: - case_type = fetch_single_case_type(case.zaaktype) + case_type = catalogi_client.fetch_single_case_type(case.zaaktype) case.zaaktype = case_type self.stdout.write( @@ -86,8 +81,10 @@ def handle(self, *args, **options): f' {case_type.identificatie} {case_type.uuid} {case_type.indicatie_intern_of_extern} "{case_type.omschrijving}" ' ) - status = fetch_single_status(case.status) - status_type = fetch_single_status_type(status.statustype) + status = zaken_client.fetch_single_status(case.status) + status_type = catalogi_client.fetch_single_status_type( + status.statustype + ) self.stdout.write( f" {status_type.omschrijving} (end {status_type.is_eindstatus}, inform {status_type.informeren}) {status_type.uuid}" ) @@ -95,8 +92,8 @@ def handle(self, *args, **options): else: # dump a bunch of information about the case - case = fetch_single_case(case_uuid) - case_type = fetch_single_case_type(case.zaaktype) + case = zaken_client.fetch_single_case(case_uuid) + case_type = catalogi_client.fetch_single_case_type(case.zaaktype) case.zaaktype = case_type self.stdout.write( @@ -112,17 +109,17 @@ def handle(self, *args, **options): else: self.stdout.write("no ZaakTypeConfig found") - status_types = fetch_status_types_no_cache(case_type.url) + status_types = catalogi_client.fetch_status_types_no_cache(case_type.url) status_type_map = {r.url: r for r in status_types} - result_types = fetch_result_types_no_cache(case_type.url) + result_types = catalogi_client.fetch_result_types_no_cache(case_type.url) result_types_map = {r.url: r for r in result_types} - status = fetch_single_status(case.status) + status = zaken_client.fetch_single_status(case.status) status_type = status_type_map[status.statustype] self.stdout.write(f" status: {status_type.omschrijving}") if case.resultaat: - result = fetch_single_result(case.resultaat) + result = zaken_client.fetch_single_result(case.resultaat) result_type = result_types_map[result.resultaattype] self.stdout.write(f" result: {result_type.omschrijving}") @@ -166,13 +163,11 @@ def handle(self, *args, **options): self.stdout.write("...") - client = build_client("zaak") - # if next status is end-status we need to result, so random select one if next_status_type.is_eindstatus and not case.resultaat: next_result_type = random.choice(result_types) # nosec self.stdout.write(f"setting new result {next_result_type.omschrijving}") - client.create( + zaken_client.create( "resultaat", { "zaak": case.url, @@ -181,7 +176,7 @@ def handle(self, *args, **options): }, ) - client.create( + zaken_client.create( "status", { "zaak": case.url, @@ -192,7 +187,7 @@ def handle(self, *args, **options): ) # check if status was applied - case = fetch_case_by_url_no_cache(case.url) - status = fetch_single_status(case.status) - status_type = fetch_single_status_type(status.statustype) + case = zaken_client.fetch_case_by_url_no_cache(case.url) + status = zaken_client.fetch_single_status(case.status) + status_type = catalogi_client.fetch_single_status_type(status.statustype) self.stdout.write(f" {status_type.omschrijving}") diff --git a/src/open_inwoner/openzaak/migrations/0035_populate_zaaktypeconfig_urls.py b/src/open_inwoner/openzaak/migrations/0035_populate_zaaktypeconfig_urls.py index 306587a2cf..6f4f3f3b40 100644 --- a/src/open_inwoner/openzaak/migrations/0035_populate_zaaktypeconfig_urls.py +++ b/src/open_inwoner/openzaak/migrations/0035_populate_zaaktypeconfig_urls.py @@ -4,6 +4,10 @@ from django.db import migrations, transaction from open_inwoner.openzaak.zgw_imports import get_configurable_zaaktypes +from open_inwoner.openzaak.clients import build_client +import logging + +logger = logging.getLogger(__name__) def populate_zaaktype_config_urls(apps, schema_editor): @@ -14,7 +18,14 @@ def populate_zaaktype_config_urls(apps, schema_editor): CatalogusConfig = apps.get_model("openzaak", "CatalogusConfig") catalog_lookup = {c.url: c for c in CatalogusConfig.objects.all()} - zaaktypes = get_configurable_zaaktypes() + client = build_client("catalogi") + if not client: + logger.warning( + "Not populating zaaktype config urls: could not build Catalogi API client" + ) + return [] + + zaaktypes = get_configurable_zaaktypes(client) if not zaaktypes: return [] diff --git a/src/open_inwoner/openzaak/notifications.py b/src/open_inwoner/openzaak/notifications.py index 880cb3d718..968b98acd2 100644 --- a/src/open_inwoner/openzaak/notifications.py +++ b/src/open_inwoner/openzaak/notifications.py @@ -17,20 +17,9 @@ ZaakInformatieObject, ZaakType, ) -from open_inwoner.openzaak.cases import ( - fetch_case_by_url_no_cache, - fetch_case_roles, - fetch_single_case_information_object, - fetch_single_status, - fetch_status_history_no_cache, - resolve_status, -) -from open_inwoner.openzaak.catalog import ( - fetch_single_case_type, - fetch_single_status_type, -) +from open_inwoner.openzaak.cases import resolve_status +from open_inwoner.openzaak.clients import CatalogiClient, build_client from open_inwoner.openzaak.documents import fetch_single_information_object_url -from open_inwoner.openzaak.managers import UserCaseInfoObjectNotificationManager from open_inwoner.openzaak.models import ( OpenZaakConfig, UserCaseInfoObjectNotification, @@ -79,6 +68,14 @@ def handle_zaken_notification(notification: Notification): resources = ("status", "zaakinformatieobject") r = notification.resource # short alias for logging + client = build_client("zaak") + if not client: + log_system_action( + f"ignored {r} notification: cannot build Zaken API client for case {case_url}", + log_level=logging.ERROR, + ) + return + if notification.resource not in resources: log_system_action( f"ignored {r} notification: resource is not {wrap_join(resources, 'or')} but '{notification.resource}' for case {case_url}", @@ -87,7 +84,7 @@ def handle_zaken_notification(notification: Notification): return # check if we have users that need to be informed about this case - roles = fetch_case_roles(case_url) + roles = client.fetch_case_roles(case_url) if not roles: log_system_action( f"ignored {r} notification: cannot retrieve rollen for case {case_url}", @@ -105,7 +102,7 @@ def handle_zaken_notification(notification: Notification): return # check if this case is visible - case = fetch_case_by_url_no_cache(case_url) + case = client.fetch_case_by_url_no_cache(case_url) if not case: log_system_action( f"ignored {r} notification: cannot retrieve case {case_url}", @@ -113,7 +110,10 @@ def handle_zaken_notification(notification: Notification): ) return - case_type = fetch_single_case_type(case.zaaktype) + case_type = None + if catalogi_client := build_client("catalogi"): + case_type = catalogi_client.fetch_single_case_type(case.zaaktype) + if not case_type: log_system_action( f"ignored {r} notification: cannot retrieve case_type {case.zaaktype} for case {case_url}", @@ -144,6 +144,14 @@ def _handle_zaakinformatieobject_notification( oz_config = OpenZaakConfig.get_solo() r = notification.resource # short alias for logging + client = build_client("zaak") + if not client: + log_system_action( + f"ignored {r} notification: cannot build Zaken API client for case {case.url}", + log_level=logging.ERROR, + ) + return + """ { "kanaal": "zaken", @@ -162,7 +170,7 @@ def _handle_zaakinformatieobject_notification( # check if this is a zaakinformatieobject we want to inform on ziobj_url = notification.resource_url - ziobj = fetch_single_case_information_object(ziobj_url) + ziobj = client.fetch_single_case_information_object(ziobj_url) if not ziobj: log_system_action( @@ -261,12 +269,14 @@ def handle_zaakinformatieobject_update( # # Helper functions for handling status update notifications # -def check_status_history(notification: Notification, case: Zaak) -> List[Status] | None: +def check_status_history( + notification: Notification, case: Zaak, client +) -> List[Status] | None: """ Check if more than one status exists for `case` (else notifications are skipped) """ resource = notification.resource - status_history = fetch_status_history_no_cache(case.url) + status_history = client.fetch_status_history_no_cache(case.url) if not status_history: log_system_action( @@ -289,6 +299,7 @@ def check_status( notification: Notification, case: Zaak, status_history: List[Status], + client, ) -> Status | None: """ Check if this is a status we want to inform on @@ -301,7 +312,9 @@ def check_status( status = s break else: - status = fetch_single_status(status_url) + # TODO currently not covered in tests? + if client: + status = client.fetch_single_status(status_url) if not status: log_system_action( @@ -318,11 +331,12 @@ def check_status_type( case: Zaak, status: Status, oz_config: OpenZaakConfig, + catalogi_client: CatalogiClient, ) -> ZaakType | None: """ Check if a status_type exists for `status` and if notifications are enabled """ - status_type = fetch_single_status_type(status.statustype) + status_type = catalogi_client.fetch_single_status_type(status.statustype) resource = notification.resource if not status_type: @@ -449,19 +463,39 @@ def handle_status_notification( """ oz_config = OpenZaakConfig.get_solo() - if not (status_history := check_status_history(notification, case)): + catalogi_client = build_client("catalogi") + if not catalogi_client: + log_system_action( + f"ignored {notification.resource} notification for {case.url}: cannot create Catalogi API client", + log_level=logging.ERROR, + ) + return None + + zaken_client = build_client("zaak") + if not zaken_client: + log_system_action( + f"ignored {notification.resource} notification for {case.url}: cannot create Zaken API client", + log_level=logging.ERROR, + ) + return + + if not (status_history := check_status_history(notification, case, zaken_client)): return - if not (status := check_status(notification, case, status_history)): + if not (status := check_status(notification, case, status_history, zaken_client)): return - if not (status_type := check_status_type(notification, case, status, oz_config)): + if not ( + status_type := check_status_type( + notification, case, status, oz_config, catalogi_client + ) + ): return if not (ztc := check_zaaktype_config(notification, case, oz_config)): return - resolve_status(case) + resolve_status(case, client=zaken_client) if not (status_type_config := check_statustype_config(notification, case, ztc)): return diff --git a/src/open_inwoner/openzaak/tests/test_case_detail.py b/src/open_inwoner/openzaak/tests/test_case_detail.py index 57f8d998a4..f7886f82e5 100644 --- a/src/open_inwoner/openzaak/tests/test_case_detail.py +++ b/src/open_inwoner/openzaak/tests/test_case_detail.py @@ -1020,7 +1020,7 @@ def test_document_ordering_by_name(self, m): self.assertEqual(documents[1].name, self.informatie_object["titel"]) self.assertEqual(documents[2].name, self.informatie_object_no_date["titel"]) - @patch("open_inwoner.cms.cases.views.status.fetch_status_history") + @patch("open_inwoner.openzaak.clients.ZakenClient.fetch_status_history") def test_e_suite_missing_current_status_fetch_status( self, m, mock_fetch_status_history ): @@ -1065,7 +1065,7 @@ def test_e_suite_missing_current_status_fetch_status( ], ) - @patch("open_inwoner.cms.cases.views.status.fetch_status_history") + @patch("open_inwoner.openzaak.clients.ZakenClient.fetch_status_history") def test_e_suite_missing_current_status_upload_button_displayed( self, m, mock_fetch_status_history ): diff --git a/src/open_inwoner/openzaak/tests/test_case_request.py b/src/open_inwoner/openzaak/tests/test_case_request.py index 14c586e049..8e9097e06e 100644 --- a/src/open_inwoner/openzaak/tests/test_case_request.py +++ b/src/open_inwoner/openzaak/tests/test_case_request.py @@ -3,7 +3,7 @@ import requests_mock from zgw_consumers.constants import APITypes -from open_inwoner.openzaak.cases import fetch_single_case +from open_inwoner.openzaak.clients import build_client from ...utils.test import ClearCachesMixin from ..models import OpenZaakConfig @@ -32,10 +32,12 @@ def setUp(self): einddatum=None, ) + self.client = build_client("zaak") + def test_case_is_retrieved(self, m): m.get(self.zaak["url"], json=self.zaak) - case = fetch_single_case("d8bbdeb7-770f-4ca9-b1ea-77b4730bf67d") + case = self.client.fetch_single_case("d8bbdeb7-770f-4ca9-b1ea-77b4730bf67d") self.assertEquals( case.url, @@ -45,7 +47,7 @@ def test_case_is_retrieved(self, m): def test_no_case_is_retrieved_when_http_404(self, m): m.get(self.zaak["url"], status_code=404) - case = fetch_single_case("d8bbdeb7-770f-4ca9-b1ea-77b4730bf67d") + case = self.client.fetch_single_case("d8bbdeb7-770f-4ca9-b1ea-77b4730bf67d") self.assertIsNone(case) @@ -55,6 +57,6 @@ def test_no_case_is_retrieved_when_http_500(self, m): status_code=500, ) - case = fetch_single_case("d8bbdeb7-770f-4ca9-b1ea-77b4730bf67d") + case = self.client.fetch_single_case("d8bbdeb7-770f-4ca9-b1ea-77b4730bf67d") self.assertIsNone(case) diff --git a/src/open_inwoner/openzaak/tests/test_documents.py b/src/open_inwoner/openzaak/tests/test_documents.py index 121d4fd02e..a2e5a24fc9 100644 --- a/src/open_inwoner/openzaak/tests/test_documents.py +++ b/src/open_inwoner/openzaak/tests/test_documents.py @@ -21,10 +21,9 @@ from open_inwoner.accounts.choices import LoginTypeChoices from open_inwoner.accounts.tests.factories import UserFactory from open_inwoner.cms.cases.views.status import SimpleFile +from open_inwoner.openzaak.clients import build_client from open_inwoner.utils.test import ClearCachesMixin, paginated_response -from ..cases import connect_case_with_document -from ..documents import download_document, upload_document from ..models import OpenZaakConfig from .factories import ( CertificateFactory, @@ -57,6 +56,10 @@ def setUp(self): ) self.config = OpenZaakConfig.get_solo() self.zaak_service = ServiceFactory(api_root=ZAKEN_ROOT, api_type=APITypes.zrc) + self.config.zaak_service = self.zaak_service + self.config.save() + self.zaken_client = build_client("zaak") + self.config.zaak_service = self.zaak_service self.catalogi_service = ServiceFactory( api_root=CATALOGI_ROOT, api_type=APITypes.ztc @@ -384,7 +387,8 @@ def test_document_download_request_uses_service_credentials(self, m): m.get(self.informatie_object["inhoud"], content=self.informatie_object_content) - download_document(self.informatie_object["inhoud"]) + document_client = build_client("document") + document_client.download_document(self.informatie_object["inhoud"]) req = m.request_history[0] self.assertEqual(req.verify, server.public_certificate.path) @@ -407,7 +411,8 @@ def test_document_is_uploaded(self, m): file = get_temporary_text_file() title = "my_document" - created_document = upload_document( + documenten_client = build_client("document") + created_document = documenten_client.upload_document( self.user, file, title, zaak_type_iotc.id, self.zaak["bronorganisatie"] ) @@ -429,7 +434,8 @@ def test_document_response_is_none_when_http_404(self, m): title = "my_document" m.post(f"{DOCUMENTEN_ROOT}enkelvoudiginformatieobjecten", status_code=404) - created_document = upload_document( + documenten_client = build_client("document") + created_document = documenten_client.upload_document( self.user, file, title, zaak_type_iotc.id, self.zaak["bronorganisatie"] ) @@ -451,31 +457,8 @@ def test_document_response_is_none_when_http_500(self, m): title = "my_document" m.post(f"{DOCUMENTEN_ROOT}enkelvoudiginformatieobjecten", status_code=500) - created_document = upload_document( - self.user, file, title, zaak_type_iotc.id, self.zaak["bronorganisatie"] - ) - - self.assertIsNone(created_document) - - def test_document_response_is_none_when_no_client_is_configured(self, m): - self._setUpMocks(m) - - zaak_type_config = ZaakTypeConfigFactory( - identificatie=self.zaaktype["identificatie"] - ) - zaak_type_iotc = ZaakTypeInformatieObjectTypeConfigFactory( - zaaktype_config=zaak_type_config, - informatieobjecttype_url=self.informatie_object["url"], - zaaktype_uuids=[self.zaaktype["uuid"]], - document_upload_enabled=True, - ) - self.config.document_service = None - self.config.save() - - file = get_temporary_text_file() - title = "my_document" - - created_document = upload_document( + documenten_client = build_client("document") + created_document = documenten_client.upload_document( self.user, file, title, zaak_type_iotc.id, self.zaak["bronorganisatie"] ) @@ -484,7 +467,7 @@ def test_document_response_is_none_when_no_client_is_configured(self, m): def test_document_case_relationship_is_created(self, m): self._setUpMocks(m) - created_relationship = connect_case_with_document( + created_relationship = self.zaken_client.connect_case_with_document( self.zaak["url"], self.informatie_object["url"] ) @@ -497,7 +480,7 @@ def test_document_case_relationship_is_not_created_when_http_400(self, m): f"{ZAKEN_ROOT}zaakinformatieobjecten", status_code=400, ) - created_relationship = connect_case_with_document( + created_relationship = self.zaken_client.connect_case_with_document( self.zaak["url"], self.informatie_object["url"] ) @@ -510,21 +493,7 @@ def test_document_case_relationship_is_not_created_when_http_500(self, m): f"{ZAKEN_ROOT}zaakinformatieobjecten", status_code=500, ) - created_relationship = connect_case_with_document( - self.zaak["url"], self.informatie_object["url"] - ) - - self.assertIsNone(created_relationship) - - def test_document_case_relationship_is_not_created_when_no_client_is_configured( - self, m - ): - self._setUpMocks(m) - - self.config.zaak_service = None - self.config.save() - - created_relationship = connect_case_with_document( + created_relationship = self.zaken_client.connect_case_with_document( self.zaak["url"], self.informatie_object["url"] ) diff --git a/src/open_inwoner/openzaak/zgw_imports.py b/src/open_inwoner/openzaak/zgw_imports.py index 4c8c61efee..557f91aaad 100644 --- a/src/open_inwoner/openzaak/zgw_imports.py +++ b/src/open_inwoner/openzaak/zgw_imports.py @@ -1,3 +1,4 @@ +import logging from collections import defaultdict from typing import List, Tuple @@ -10,14 +11,7 @@ ) from open_inwoner.openzaak.api_models import ZaakType -from open_inwoner.openzaak.catalog import ( - fetch_case_types_by_identification_no_cache, - fetch_catalogs_no_cache, - fetch_single_information_object_type, - fetch_single_resultaat_type, - fetch_single_status_type, - fetch_zaaktypes_no_cache, -) +from open_inwoner.openzaak.clients import build_client from open_inwoner.openzaak.models import ( CatalogusConfig, ZaakTypeConfig, @@ -26,21 +20,23 @@ ZaakTypeStatusTypeConfig, ) +logger = logging.getLogger(__name__) + def filter_zaaktypes(case_types: List[ZaakType]) -> List[ZaakType]: return [c for c in case_types if c.indicatie_intern_of_extern == "extern"] -def get_configurable_zaaktypes() -> List[ZaakType]: - case_types = fetch_zaaktypes_no_cache() +def get_configurable_zaaktypes(client) -> List[ZaakType]: + case_types = client.fetch_zaaktypes_no_cache() case_types = filter_zaaktypes(case_types) return case_types def get_configurable_zaaktypes_by_identification( - identificatie, catalogus_url + client, identificatie, catalogus_url ) -> List[ZaakType]: - case_types = fetch_case_types_by_identification_no_cache( + case_types = client.fetch_case_types_by_identification_no_cache( identificatie, catalogus_url ) case_types = filter_zaaktypes(case_types) @@ -53,7 +49,14 @@ def import_catalog_configs() -> List[CatalogusConfig]: note this doesn't generate anything on eSuite """ - catalogs = fetch_catalogs_no_cache() + client = build_client("catalogi") + if not client: + logger.warning( + "Not importing catalogus configs: could not build Catalogi API client" + ) + return [] + + catalogs = client.fetch_catalogs_no_cache() if not catalogs: return [] @@ -84,7 +87,14 @@ def import_zaaktype_configs() -> List[ZaakTypeConfig]: this collapses individual ZaakType versions on their identificatie and catalog """ - zaak_types = get_configurable_zaaktypes() + client = build_client("catalogi") + if not client: + logger.warning( + "Not importing zaaktype configs: could not build Catalogi API client" + ) + return [] + + zaak_types = get_configurable_zaaktypes(client) if not zaak_types: return [] @@ -177,10 +187,16 @@ def import_zaaktype_informatieobjecttype_configs_for_type( this is a bit complicated because one ZaakTypeConfig can represent multiple ZaakTypes """ + client = build_client("catalogi") + if not client: + logger.warning( + "Not importing zaaktype-informatieobjecttype configs: could not build Catalogi API client" + ) + return [] # grab actual ZaakTypes for this identificatie zaak_types: List[ZaakType] = get_configurable_zaaktypes_by_identification( - ztc.identificatie, ztc.catalogus_url + client, ztc.identificatie, ztc.catalogus_url ) if not zaak_types: return [] @@ -204,7 +220,7 @@ def import_zaaktype_informatieobjecttype_configs_for_type( if info_queue: # load urls and update/create records for iot_url, using_zaak_types in info_queue.items(): - info_type = fetch_single_information_object_type(iot_url) + info_type = client.fetch_single_information_object_type(iot_url) ztiotc = info_map.get(info_type.url) if ztiotc: @@ -245,10 +261,16 @@ def import_statustype_configs_for_type( this is a bit complicated because one ZaakTypeConfig can represent multiple ZaakTypes """ + client = build_client("catalogi") + if not client: + logger.warning( + "Not importing statustype configs: could not build Catalogi API client" + ) + return [] # grab actual ZaakTypes for this identificatie zaak_types: List[ZaakType] = get_configurable_zaaktypes_by_identification( - ztc.identificatie, ztc.catalogus_url + client, ztc.identificatie, ztc.catalogus_url ) if not zaak_types: return [] @@ -273,7 +295,7 @@ def import_statustype_configs_for_type( if info_queue: # load urls and update/create records for statustype_url, using_zaak_types in info_queue.items(): - status_type = fetch_single_status_type(statustype_url) + status_type = client.fetch_single_status_type(statustype_url) if not status_type: # Statustype isn't available anymore? continue @@ -315,10 +337,16 @@ def import_resultaattype_configs_for_type( this is a bit complicated because one ZaakTypeConfig can represent multiple ZaakTypes """ + client = build_client("catalogi") + if not client: + logger.warning( + "Not importing resultaattype configs: could not build Catalogi API client" + ) + return [] # grab actual ZaakTypes for this identificatie zaak_types: List[ZaakType] = get_configurable_zaaktypes_by_identification( - ztc.identificatie, ztc.catalogus_url + client, ztc.identificatie, ztc.catalogus_url ) if not zaak_types: return [] @@ -343,7 +371,7 @@ def import_resultaattype_configs_for_type( if info_queue: # load urls and update/create records for resultaattype_url, using_zaak_types in info_queue.items(): - resultaat_type = fetch_single_resultaat_type(resultaattype_url) + resultaat_type = client.fetch_single_resultaat_type(resultaattype_url) zaaktype_resultaattype = info_map.get(resultaat_type.url) if zaaktype_resultaattype: diff --git a/src/open_inwoner/pdc/managers.py b/src/open_inwoner/pdc/managers.py index 231e509424..c0e38b57a9 100644 --- a/src/open_inwoner/pdc/managers.py +++ b/src/open_inwoner/pdc/managers.py @@ -11,7 +11,7 @@ from open_inwoner.configurations.models import SiteConfiguration from open_inwoner.kvk.branches import get_kvk_branch_number from open_inwoner.openzaak.api_models import Zaak -from open_inwoner.openzaak.cases import fetch_cases, fetch_cases_by_kvk_or_rsin +from open_inwoner.openzaak.clients import build_client from open_inwoner.openzaak.models import OpenZaakConfig, ZaakTypeConfig @@ -52,8 +52,12 @@ def filter_by_zaken_for_request(self, request): if not request.user.bsn and not request.user.kvk: return self + client = build_client("zaak") + if client is None: + return self.none() + if request.user.bsn: - cases = fetch_cases(request.user.bsn) + cases = client.fetch_cases(request.user.bsn) elif request.user.kvk: kvk_or_rsin = request.user.kvk config = OpenZaakConfig.get_solo() @@ -61,11 +65,11 @@ def filter_by_zaken_for_request(self, request): kvk_or_rsin = request.user.rsin vestigingsnummer = get_kvk_branch_number(request.session) if vestigingsnummer: - cases = fetch_cases_by_kvk_or_rsin( + cases = client.fetch_cases_by_kvk_or_rsin( kvk_or_rsin=kvk_or_rsin, vestigingsnummer=vestigingsnummer ) else: - cases = fetch_cases_by_kvk_or_rsin(kvk_or_rsin=kvk_or_rsin) + cases = client.fetch_cases_by_kvk_or_rsin(kvk_or_rsin=kvk_or_rsin) return self.filter_by_zaken(cases) diff --git a/src/open_inwoner/search/views.py b/src/open_inwoner/search/views.py index 86d14553e9..9412dd3d9b 100644 --- a/src/open_inwoner/search/views.py +++ b/src/open_inwoner/search/views.py @@ -9,7 +9,7 @@ from furl import furl from open_inwoner.configurations.models import SiteConfiguration -from open_inwoner.openzaak.cases import fetch_cases +from open_inwoner.openzaak.clients import build_client from open_inwoner.utils.mixins import PaginationMixin from open_inwoner.utils.views import CommonPageMixin, LoginMaybeRequiredMixin, LogMixin @@ -62,14 +62,17 @@ def search(self, form): self.log_user_action(user, _("search query: {query}").format(query=query)) # Check if the query exactly matches with a case that belongs to the user + # TODO should be implemented for KVK as well if hasattr(self.request.user, "bsn"): - cases = fetch_cases(self.request.user.bsn, identificatie=query) - if cases and len(cases) == 1: - return HttpResponseRedirect( - reverse( - "cases:case_detail", kwargs={"object_id": str(cases[0].uuid)} + if client := build_client("zaak"): + cases = client.fetch_cases(self.request.user.bsn, identificatie=query) + if cases and len(cases) == 1: + return HttpResponseRedirect( + reverse( + "cases:case_detail", + kwargs={"object_id": str(cases[0].uuid)}, + ) ) - ) # perform search results = search_products(query, filters=data)