Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enforce membership code on instructor training application #2544

33 changes: 31 additions & 2 deletions amy/extforms/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from django import forms
from django.core.exceptions import ValidationError
from django.db.models.fields import BLANK_CHOICE_DASH
from django.http import HttpRequest

from consents.forms import option_display_value
from consents.models import Term, TrainingRequestConsent
Expand All @@ -19,7 +20,8 @@
Select2Widget,
)
from workshops.forms import BootstrapHelper
from workshops.models import TrainingRequest
from workshops.models import Membership, TrainingRequest
from workshops.utils.feature_flags import feature_flag_enabled


class TrainingRequestForm(forms.ModelForm):
Expand Down Expand Up @@ -88,6 +90,7 @@ class Meta:
}

def __init__(self, *args, **kwargs):
self.request_http = kwargs.pop("request", None)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name is a little bit off. Usually it was named self.request.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this to avoid ambiguity between the http request and the training request that this form describes. I'm not entirely happy with the break from convention but I think it might prevent future confusion

super().__init__(*args, **kwargs)

# Only active and required terms.
Expand Down Expand Up @@ -192,11 +195,32 @@ def create_consent_field(self, term: Term) -> forms.ChoiceField:
)
return field

@feature_flag_enabled("ENFORCE_MEMBER_CODES")
def validate_member_code(self, request: HttpRequest) -> dict:
elichad marked this conversation as resolved.
Show resolved Hide resolved
errors = dict()
member_code = self.cleaned_data.get("member_code", "")

if not member_code:
return
elichad marked this conversation as resolved.
Show resolved Hide resolved

# ensure that code belongs to a membership
# TODO: implement further validation for active membership, etc
# and update text accordingly
try:
Membership.objects.get(registration_code=member_code)
except Membership.DoesNotExist:
errors["member_code"] = ValidationError(
"This code is invalid. "
"Please contact your Member Affiliate to verify your code."
)

return errors

def clean(self):
super().clean()
errors = dict()

# 1: validate registration code / group name
# 1: validate registration code
review_process = self.cleaned_data.get("review_process", "")
member_code = self.cleaned_data.get("member_code", "").split()

Expand All @@ -214,6 +238,11 @@ def clean(self):
"Registration code must be empty for open training review " "process."
)

# confirm that code is valid
membership_errors = self.validate_member_code(request=self.request_http)
if membership_errors:
errors.update(membership_errors)

if errors:
raise ValidationError(errors)

Expand Down
6 changes: 6 additions & 0 deletions amy/extforms/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ def get_context_data(self, **kwargs):
def autoresponder_email_context(self, form):
return dict(object=self.object)

def get_form_kwargs(self):
# request is required for ENFORCE_MEMBER_CODES flag
kwargs = super().get_form_kwargs()
kwargs["request"] = self.request
return kwargs

def get_success_message(self, *args, **kwargs):
"""Don't display a success message."""
return ""
Expand Down