diff --git a/src/openforms/config/data.py b/src/openforms/config/data.py index c377a14b53..6ae4bdd156 100644 --- a/src/openforms/config/data.py +++ b/src/openforms/config/data.py @@ -3,7 +3,9 @@ from django.contrib.admin.templatetags.admin_list import _boolean_icon -Action: TypeAlias = tuple[str, str] +from openforms.typing import StrOrPromise + +Action: TypeAlias = tuple[StrOrPromise, str] # (label, reversed URL path) @dataclass diff --git a/src/openforms/plugins/plugin.py b/src/openforms/plugins/plugin.py index afa63360b7..ed772770d3 100644 --- a/src/openforms/plugins/plugin.py +++ b/src/openforms/plugins/plugin.py @@ -1,5 +1,8 @@ +from collections.abc import Sequence + from django.utils.translation import gettext_lazy as _ +from openforms.config.data import Action from openforms.config.models import GlobalConfiguration from .registry import BaseRegistry @@ -43,7 +46,7 @@ def check_config(self): """ raise NotImplementedError() - def get_config_actions(self) -> list[tuple[str, str]]: + def get_config_actions(self) -> Sequence[Action]: """ Returns a list of tuples containing the label and URL of each action that is related to the configuration of this plugin. This can be to diff --git a/src/openforms/prefill/base.py b/src/openforms/prefill/base.py index bf541b1902..4d7eacda8c 100644 --- a/src/openforms/prefill/base.py +++ b/src/openforms/prefill/base.py @@ -18,7 +18,8 @@ class BasePlugin(AbstractBasePlugin): requires_auth: AuthAttribute | None = None for_components: Container[str] = AllComponentTypes() - def get_available_attributes(self) -> Iterable[tuple[str, str]]: + @staticmethod + def get_available_attributes() -> Iterable[tuple[str, str]]: """ Return a choice list of available attributes this plugin offers. """ @@ -26,8 +27,9 @@ def get_available_attributes(self) -> Iterable[tuple[str, str]]: "You must implement the 'get_available_attributes' method." ) + @classmethod def get_prefill_values( - self, + cls, submission: Submission, attributes: list[str], identifier_role: IdentifierRoles = IdentifierRoles.main, @@ -48,8 +50,9 @@ def get_prefill_values( """ raise NotImplementedError("You must implement the 'get_prefill_values' method.") + @classmethod def get_co_sign_values( - self, submission: Submission, identifier: str + cls, submission: Submission, identifier: str ) -> tuple[dict[str, Any], str]: """ Given an identifier, fetch the co-sign specific values. @@ -64,8 +67,9 @@ def get_co_sign_values( """ raise NotImplementedError("You must implement the 'get_co_sign_values' method.") + @classmethod def get_identifier_value( - self, submission: Submission, identifier_role: IdentifierRoles + cls, submission: Submission, identifier_role: IdentifierRoles ) -> str | None: """ Given a submission and the role of the identifier, return the value of the identifier. @@ -82,6 +86,6 @@ def get_identifier_value( if ( identifier_role == IdentifierRoles.main - and submission.auth_info.attribute == self.requires_auth + and submission.auth_info.attribute == cls.requires_auth ): return submission.auth_info.value diff --git a/src/openforms/prefill/contrib/demo/plugin.py b/src/openforms/prefill/contrib/demo/plugin.py index 43cb3a80c6..0887574bb4 100644 --- a/src/openforms/prefill/contrib/demo/plugin.py +++ b/src/openforms/prefill/contrib/demo/plugin.py @@ -5,15 +5,17 @@ from django.utils.crypto import get_random_string from django.utils.translation import gettext_lazy as _ +from openforms.config.data import Action from openforms.submissions.models import Submission from ...base import BasePlugin +from ...constants import IdentifierRoles from ...registry import register from .constants import Attributes CALLBACKS = { - Attributes.random_number: lambda: random.randint(1000, 10_000), - Attributes.random_string: partial(get_random_string, length=10), + Attributes.random_number.value: lambda: random.randint(1000, 10_000), + Attributes.random_string.value: partial(get_random_string, length=10), } @@ -26,9 +28,12 @@ class DemoPrefill(BasePlugin): def get_available_attributes(): return Attributes.choices - @staticmethod + @classmethod def get_prefill_values( - submission: Submission, attributes: list[str], identifier_role: str + cls, + submission: Submission, + attributes: list[str], + identifier_role: IdentifierRoles = IdentifierRoles.main, ) -> dict[str, Any]: """ Given the requested attributes, look up the appropriate values and return them. @@ -40,8 +45,8 @@ def get_prefill_values( """ return {attr: CALLBACKS[attr]() for attr in attributes} - def check_config(self): + def check_config(self) -> list[Action]: """ Demo config is always valid. """ - pass + return [] diff --git a/src/openforms/prefill/contrib/haalcentraal_brp/plugin.py b/src/openforms/prefill/contrib/haalcentraal_brp/plugin.py index 46326c2c6d..0e8441374a 100644 --- a/src/openforms/prefill/contrib/haalcentraal_brp/plugin.py +++ b/src/openforms/prefill/contrib/haalcentraal_brp/plugin.py @@ -1,6 +1,5 @@ import logging -from collections.abc import Sequence -from typing import Any, TypeAlias +from typing import Any from django.urls import reverse from django.utils.translation import gettext_lazy as _ @@ -32,9 +31,6 @@ } -AttributesSequence: TypeAlias = Sequence[AttributesV1 | AttributesV2] - - def get_attributes_cls(): config = HaalCentraalConfig.get_solo() assert isinstance(config, HaalCentraalConfig) @@ -63,7 +59,7 @@ def _get_values_for_bsn( cls, client: BRPClient, bsn: str, - attributes: AttributesSequence, + attributes: list[str], ) -> dict[str, Any]: if not (data := client.find_person(bsn, attributes=attributes)): return {} @@ -101,7 +97,7 @@ def get_identifier_value( def get_prefill_values( cls, submission: Submission, - attributes: AttributesSequence, + attributes: list[str], identifier_role: IdentifierRoles = IdentifierRoles.main, ) -> dict[str, Any]: try: diff --git a/src/openforms/prefill/contrib/kvk/plugin.py b/src/openforms/prefill/contrib/kvk/plugin.py index 5d944a41d7..a2bdf1b994 100644 --- a/src/openforms/prefill/contrib/kvk/plugin.py +++ b/src/openforms/prefill/contrib/kvk/plugin.py @@ -37,29 +37,32 @@ class KVK_KVKNumberPrefill(BasePlugin): requires_auth = AuthAttribute.kvk - def get_available_attributes(self) -> list[tuple[str, str]]: + @staticmethod + def get_available_attributes() -> list[tuple[str, str]]: return Attributes.choices + @classmethod def get_identifier_value( - self, submission: Submission, identifier_role: str + cls, submission: Submission, identifier_role: str ) -> str | None: if not submission.is_authenticated: return if ( identifier_role == IdentifierRoles.main - and submission.auth_info.attribute == self.requires_auth + and submission.auth_info.attribute == cls.requires_auth ): return submission.auth_info.value + @classmethod def get_prefill_values( - self, + cls, submission: Submission, attributes: list[str], identifier_role: str = IdentifierRoles.main, ) -> dict[str, Any]: # check if submission was logged in with the identifier we're interested - if not (kvk_value := self.get_identifier_value(submission, identifier_role)): + if not (kvk_value := cls.get_identifier_value(submission, identifier_role)): return {} try: @@ -68,7 +71,7 @@ def get_prefill_values( except (RequestException, NoServiceConfigured): return {} - self.modify_result(result) + cls.modify_result(result) values = dict() for attr in attributes: @@ -80,8 +83,8 @@ def get_prefill_values( ) return values - @classmethod - def modify_result(cls, result: BasisProfiel): + @staticmethod + def modify_result(result: BasisProfiel): # first try getting the addresses from the embedded 'hoofdvestiging'. Note that # this may be absent or empty depending on the type of company (see #1299). # If there are no addresses found, we try to get them from 'eigenaar' instead. diff --git a/src/openforms/prefill/contrib/stufbg/plugin.py b/src/openforms/prefill/contrib/stufbg/plugin.py index a9db21a085..4a0f8ba92d 100644 --- a/src/openforms/prefill/contrib/stufbg/plugin.py +++ b/src/openforms/prefill/contrib/stufbg/plugin.py @@ -97,12 +97,12 @@ class StufBgPrefill(BasePlugin): verbose_name = _("StUF-BG") requires_auth = AuthAttribute.bsn - def get_available_attributes(self) -> list[tuple[str, str]]: + @staticmethod + def get_available_attributes() -> list[tuple[str, str]]: return FieldChoices.choices - def _get_values_for_bsn( - self, bsn: str, attributes: list[FieldChoices] - ) -> dict[str, Any]: + @staticmethod + def _get_values_for_bsn(bsn: str, attributes: list[FieldChoices]) -> dict[str, Any]: with get_client() as client: data = client.get_values(bsn, [str(attr) for attr in attributes]) @@ -129,36 +129,39 @@ def _get_values_for_bsn( return response_dict + @classmethod def get_identifier_value( - self, submission: Submission, identifier_role: str + cls, submission: Submission, identifier_role: IdentifierRoles ) -> str | None: if not submission.is_authenticated: return if ( identifier_role == IdentifierRoles.main - and submission.auth_info.attribute == self.requires_auth + and submission.auth_info.attribute == cls.requires_auth ): return submission.auth_info.value if identifier_role == IdentifierRoles.authorised_person: return submission.auth_info.machtigen.get("identifier_value") + @classmethod def get_prefill_values( - self, + cls, submission: Submission, - attributes: list[FieldChoices], - identifier_role: str = IdentifierRoles.main, + attributes: list[str], + identifier_role: IdentifierRoles = IdentifierRoles.main, ) -> dict[str, Any]: - if not (bsn_value := self.get_identifier_value(submission, identifier_role)): + if not (bsn_value := cls.get_identifier_value(submission, identifier_role)): # If there is no bsn we can't prefill any values so just return logger.info("No BSN associated with submission, cannot prefill.") return {} - return self._get_values_for_bsn(bsn_value, attributes) + return cls._get_values_for_bsn(bsn_value, attributes) + @classmethod def get_co_sign_values( - self, submission: Submission, identifier: str + cls, submission: Submission, identifier: str ) -> tuple[dict[str, Any], str]: """ Given an identifier, fetch the co-sign specific values. @@ -171,7 +174,7 @@ def get_co_sign_values( :return: a key-value dictionary, where the key is the requested attribute and the value is the prefill value to use for that attribute. """ - values = self._get_values_for_bsn( + values = cls._get_values_for_bsn( identifier, [ FieldChoices.voornamen, diff --git a/src/openforms/prefill/contrib/suwinet/plugin.py b/src/openforms/prefill/contrib/suwinet/plugin.py index 4e922902cd..c3d1782b05 100644 --- a/src/openforms/prefill/contrib/suwinet/plugin.py +++ b/src/openforms/prefill/contrib/suwinet/plugin.py @@ -6,7 +6,7 @@ from openforms.authentication.service import AuthAttribute from openforms.plugins.exceptions import InvalidPluginConfiguration from openforms.submissions.models import Submission -from openforms.typing import JSONSerializable +from openforms.typing import JSONEncodable, JSONObject from suwinet.client import NoServiceConfigured, SuwinetClient, get_client from suwinet.constants import SERVICES from suwinet.models import SuwinetConfig @@ -43,19 +43,20 @@ def get_available_attributes(): for operation in SERVICES[service_name].operations ] + @classmethod def get_prefill_values( - self, + cls, submission: Submission, attributes: list[str], - identifier_role: str = IdentifierRoles.main, - ) -> dict[str, JSONSerializable]: + identifier_role: IdentifierRoles = IdentifierRoles.main, + ) -> dict[str, JSONEncodable]: if not ( (client := _get_client()) - and (bsn := self.get_identifier_value(submission, identifier_role)) + and (bsn := cls.get_identifier_value(submission, identifier_role)) ): return {} - def get_value(attr) -> dict | None: + def get_value(attr: str) -> JSONObject | None: service_name, operation = attr.split(".") service = getattr(client, service_name) perform_soap_call = getattr(service, operation)