Skip to content

Commit

Permalink
🏷️ [#3457] Extend type checking to most of the payments app
Browse files Browse the repository at this point in the history
Rather than just type-checking some files, we are close enough to
type check most of the package and instead skip some files/subpackages
with known (but not critical) type checking issues.

Here and there we need to suppress some errors because the Django ORM
magic is too much for Pyright.
  • Loading branch information
sergei-maertens committed Dec 16, 2024
1 parent a6d2ad7 commit e9aa4d7
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 71 deletions.
11 changes: 5 additions & 6 deletions pyright.pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ include = [
"src/openforms/dmn/registry.py",
"src/openforms/formio/registry.py",
"src/openforms/formio/rendering/registry.py",
"src/openforms/payments/base.py",
"src/openforms/payments/registry.py",
"src/openforms/pre_requests/base.py",
"src/openforms/pre_requests/registry.py",
"src/openforms/prefill/base.py",
Expand All @@ -29,10 +27,7 @@ include = [
# Core forms app
"src/openforms/forms/api/serializers/logic/action_serializers.py",
# Payments
"src/openforms/payments/models.py",
"src/openforms/payments/contrib/ogone/client.py",
"src/openforms/payments/contrib/ogone/plugin.py",
"src/openforms/payments/views.py",
"src/openforms/payments/",
# Interaction with the outside world
"src/openforms/contrib/zgw/service.py",
"src/openforms/contrib/objects_api/",
Expand Down Expand Up @@ -64,6 +59,10 @@ exclude = [
"src/openforms/contrib/objects_api/tests/",
"src/openforms/contrib/objects_api/json_schema.py",
"src/openforms/formio/formatters/tests/",
"src/openforms/payments/management/commands/checkpaymentemaildupes.py",
"src/openforms/payments/tests/",
"src/openforms/payments/contrib/demo/tests/",
"src/openforms/payments/contrib/ogone/tests/",
"src/openforms/registrations/contrib/zgw_apis/tests/test_backend_partial_failure.py",
"src/openforms/registrations/contrib/zgw_apis/tests/test_utils.py",
]
Expand Down
2 changes: 0 additions & 2 deletions src/openforms/forms/admin/form.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

from openforms.api.utils import underscore_to_camel
from openforms.emails.models import ConfirmationEmailTemplate
from openforms.payments.admin import PaymentBackendChoiceFieldMixin
from openforms.registrations.admin import RegistrationBackendFieldMixin
from openforms.typing import StrOrPromise
from openforms.utils.expressions import FirstNotBlank
Expand Down Expand Up @@ -127,7 +126,6 @@ def expected_parameters(self):
class FormAdmin(
FormioConfigMixin,
RegistrationBackendFieldMixin,
PaymentBackendChoiceFieldMixin,
OrderedInlineModelAdminMixin,
admin.ModelAdmin,
):
Expand Down
14 changes: 0 additions & 14 deletions src/openforms/payments/admin.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,8 @@
from django.contrib import admin

from .fields import PaymentBackendChoiceField
from .models import SubmissionPayment


class PaymentBackendChoiceFieldMixin:
def formfield_for_dbfield(self, db_field, request, **kwargs):
if isinstance(db_field, PaymentBackendChoiceField):
assert not db_field.choices
_old = db_field.choices
db_field.choices = db_field._get_plugin_choices()
field = super().formfield_for_dbfield(db_field, request, **kwargs)
db_field.choices = _old
return field

return super().formfield_for_dbfield(db_field, request, **kwargs)


@admin.register(SubmissionPayment)
class SubmissionPaymentAdmin(admin.ModelAdmin):
fields = (
Expand Down
7 changes: 5 additions & 2 deletions src/openforms/payments/api/fields.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from rest_framework import serializers

from openforms.forms.models import Form

from ..registry import register as payment_register
from .serializers import PaymentOptionSerializer

Expand All @@ -20,7 +22,8 @@ def __init__(self, *args, **kwargs):
def to_internal_value(self, data):
raise NotImplementedError("read only")

def to_representation(self, form):
def to_representation(self, value):
assert isinstance(value, Form)
request = self.context["request"]
temp = payment_register.get_options(request, form)
temp = payment_register.get_options(request, value)
return super().to_representation(temp)
4 changes: 2 additions & 2 deletions src/openforms/payments/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class PaymentPluginSerializer(PluginBaseSerializer):
class PaymentOptionSerializer(serializers.Serializer):
# serializer for form
identifier = serializers.CharField(label=_("Identifier"), read_only=True)
label = serializers.CharField(
label = serializers.CharField( # pyright: ignore[reportAssignmentType]
label=_("Button label"), help_text=_("Button label"), read_only=True
)

Expand All @@ -34,7 +34,7 @@ class PaymentInfoSerializer(serializers.Serializer):
label=_("Request type"), choices=PaymentRequestType.choices, read_only=True
)
url = serializers.URLField(label=_("URL"), read_only=True)
data = serializers.DictField(
data = serializers.DictField( # pyright: ignore[reportAssignmentType,reportIncompatibleMethodOverride]
label=_("Data"),
child=serializers.CharField(label=_("Value"), read_only=True),
read_only=True,
Expand Down
2 changes: 1 addition & 1 deletion src/openforms/payments/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def get_return_url(self, request: HttpRequest, payment: SubmissionPayment) -> st
request=request,
)

def get_webhook_url(self, request: HttpRequest) -> str:
def get_webhook_url(self, request: HttpRequest | None) -> str:
return reverse_plus(
"payments:webhook",
kwargs={"plugin_id": self.identifier},
Expand Down
77 changes: 36 additions & 41 deletions src/openforms/payments/contrib/ogone/constants.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from typing import cast

from django.db import models
from django.utils.translation import gettext_lazy as _

Expand Down Expand Up @@ -60,45 +58,42 @@ def as_payment_status(cls, ogone_status: str) -> str:
return OGONE_TO_PAYMENT_STATUS[ogone_status]


OGONE_TO_PAYMENT_STATUS = cast(
dict[str, str],
{
OgoneStatus.invalid_or_incomplete: PaymentStatus.failed.value,
OgoneStatus.cancelled_by_customer: PaymentStatus.failed.value,
OgoneStatus.authorisation_declined: PaymentStatus.failed.value,
OgoneStatus.waiting_for_client_payment: PaymentStatus.processing.value,
OgoneStatus.waiting_authentication: PaymentStatus.processing.value,
OgoneStatus.authorised: PaymentStatus.processing.value,
OgoneStatus.authorised_waiting_external_result: PaymentStatus.processing.value,
OgoneStatus.authorisation_waiting: PaymentStatus.processing.value,
OgoneStatus.authorisation_not_known: PaymentStatus.processing.value,
OgoneStatus.standby: PaymentStatus.processing.value,
OgoneStatus.ok_with_scheduled_payments: PaymentStatus.processing.value,
OgoneStatus.not_ok_with_scheduled_payments: PaymentStatus.failed.value,
OgoneStatus.authorised_and_cancelled: PaymentStatus.failed.value,
OgoneStatus.author_deletion_waiting: PaymentStatus.failed.value,
OgoneStatus.author_deletion_uncertain: PaymentStatus.failed.value,
OgoneStatus.author_deletion_refused: PaymentStatus.failed.value,
OgoneStatus.payment_deleted: PaymentStatus.failed.value,
OgoneStatus.payment_deletion_pending: PaymentStatus.failed.value,
OgoneStatus.payment_deletion_uncertain: PaymentStatus.failed.value,
OgoneStatus.payment_deletion_refused: PaymentStatus.failed.value,
OgoneStatus.payment_deleted2: PaymentStatus.failed, # doubl.valuee
OgoneStatus.refund: PaymentStatus.failed.value,
OgoneStatus.refund_pending: PaymentStatus.failed.value,
OgoneStatus.refund_uncertain: PaymentStatus.failed.value,
OgoneStatus.refund_refused: PaymentStatus.failed.value,
OgoneStatus.payment_declined_by_the_acquirer: PaymentStatus.failed.value,
OgoneStatus.refund_processed_by_merchant: PaymentStatus.failed.value,
OgoneStatus.payment_requested: PaymentStatus.completed.value,
OgoneStatus.payment_processing: PaymentStatus.processing.value,
OgoneStatus.payment_uncertain: PaymentStatus.processing.value,
OgoneStatus.payment_refused: PaymentStatus.failed.value,
OgoneStatus.refund_declined_by_the_acquirer: PaymentStatus.failed.value,
OgoneStatus.payment_processed_by_merchant: PaymentStatus.failed.value,
OgoneStatus.being_processed: PaymentStatus.processing.value,
},
)
OGONE_TO_PAYMENT_STATUS: dict[str, str] = {
OgoneStatus.invalid_or_incomplete.value: PaymentStatus.failed.value,
OgoneStatus.cancelled_by_customer.value: PaymentStatus.failed.value,
OgoneStatus.authorisation_declined.value: PaymentStatus.failed.value,
OgoneStatus.waiting_for_client_payment.value: PaymentStatus.processing.value,
OgoneStatus.waiting_authentication.value: PaymentStatus.processing.value,
OgoneStatus.authorised.value: PaymentStatus.processing.value,
OgoneStatus.authorised_waiting_external_result.value: PaymentStatus.processing.value,
OgoneStatus.authorisation_waiting.value: PaymentStatus.processing.value,
OgoneStatus.authorisation_not_known.value: PaymentStatus.processing.value,
OgoneStatus.standby.value: PaymentStatus.processing.value,
OgoneStatus.ok_with_scheduled_payments.value: PaymentStatus.processing.value,
OgoneStatus.not_ok_with_scheduled_payments.value: PaymentStatus.failed.value,
OgoneStatus.authorised_and_cancelled.value: PaymentStatus.failed.value,
OgoneStatus.author_deletion_waiting.value: PaymentStatus.failed.value,
OgoneStatus.author_deletion_uncertain.value: PaymentStatus.failed.value,
OgoneStatus.author_deletion_refused.value: PaymentStatus.failed.value,
OgoneStatus.payment_deleted.value: PaymentStatus.failed.value,
OgoneStatus.payment_deletion_pending.value: PaymentStatus.failed.value,
OgoneStatus.payment_deletion_uncertain.value: PaymentStatus.failed.value,
OgoneStatus.payment_deletion_refused.value: PaymentStatus.failed.value,
OgoneStatus.payment_deleted2.value: PaymentStatus.failed, # doubl.valuee
OgoneStatus.refund.value: PaymentStatus.failed.value,
OgoneStatus.refund_pending.value: PaymentStatus.failed.value,
OgoneStatus.refund_uncertain.value: PaymentStatus.failed.value,
OgoneStatus.refund_refused.value: PaymentStatus.failed.value,
OgoneStatus.payment_declined_by_the_acquirer.value: PaymentStatus.failed.value,
OgoneStatus.refund_processed_by_merchant.value: PaymentStatus.failed.value,
OgoneStatus.payment_requested.value: PaymentStatus.completed.value,
OgoneStatus.payment_processing.value: PaymentStatus.processing.value,
OgoneStatus.payment_uncertain.value: PaymentStatus.processing.value,
OgoneStatus.payment_refused.value: PaymentStatus.failed.value,
OgoneStatus.refund_declined_by_the_acquirer.value: PaymentStatus.failed.value,
OgoneStatus.payment_processed_by_merchant.value: PaymentStatus.failed.value,
OgoneStatus.being_processed.value: PaymentStatus.processing.value,
}

assert set(OgoneStatus.values) == set(
OGONE_TO_PAYMENT_STATUS.keys()
Expand Down
12 changes: 9 additions & 3 deletions src/openforms/payments/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@


def update_submission_payment_registration(submission: Submission):
if (registration_backend := submission.registration_backend) is None:
error = AttributeError("Submission has no registration backend")
logevent.registration_payment_update_failure(submission, error=error)
return

Check warning on line 16 in src/openforms/payments/services.py

View check run for this annotation

Codecov / codecov/patch

src/openforms/payments/services.py#L14-L16

Added lines #L14 - L16 were not covered by tests

try:
plugin = register[submission.registration_backend.backend]
except (AttributeError, KeyError) as e:
plugin = register[registration_backend.backend]
except KeyError as e:
logevent.registration_payment_update_failure(submission, error=e)
return

Expand All @@ -37,7 +42,8 @@ def update_submission_payment_registration(submission: Submission):

try:
plugin.update_payment_status(submission, options_serializer.validated_data)
payments.mark_registered()
# FIXME: pyright + custom querysets...
payments.mark_registered() # pyright: ignore[reportAttributeAccessIssue]
except Exception as e:
logevent.registration_payment_update_failure(
submission, error=e, plugin=plugin
Expand Down

0 comments on commit e9aa4d7

Please sign in to comment.