class Meta: model = Order fields = ['customer', 'email', 'email_known_to_work', 'phone'] widgets = { 'phone': WrappedPhoneNumberPrefixWidget(), } field_classes = { 'customer': SafeModelChoiceField, }
def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') self.request = kwargs.pop('request') self.all_optional = kwargs.pop('all_optional', False) super().__init__(*args, **kwargs) if self.event.settings.order_email_asked_twice: self.fields['email_repeat'] = forms.EmailField( label=_('E-mail address (repeated)'), help_text= _('Please enter the same email address again to make sure you typed it correctly.' ), ) if self.event.settings.order_phone_asked: with language(get_babel_locale()): default_country = guess_country(self.event) default_prefix = None for prefix, values in _COUNTRY_CODE_TO_REGION_CODE.items(): if str(default_country) in values: default_prefix = prefix try: initial = self.initial.pop('phone', None) initial = PhoneNumber().from_string( initial) if initial else "+{}.".format(default_prefix) except NumberParseException: initial = None self.fields['phone'] = PhoneNumberField( label=_('Phone number'), required=self.event.settings.order_phone_required, help_text=self.event.settings.checkout_phone_helptext, # We now exploit an implementation detail in PhoneNumberPrefixWidget to allow us to pass just # a country code but no number as an initial value. It's a bit hacky, but should be stable for # the future. initial=initial, widget=WrappedPhoneNumberPrefixWidget()) if not self.request.session.get('iframe_session', False): # There is a browser quirk in Chrome that leads to incorrect initial scrolling in iframes if there # is an autofocus field. Who would have thought… See e.g. here: # https://floatboxjs.com/forum/topic.php?post=8440&usebb_sid=2e116486a9ec6b7070e045aea8cded5b#post8440 self.fields['email'].widget.attrs['autofocus'] = 'autofocus' self.fields[ 'email'].help_text = self.event.settings.checkout_email_helptext responses = contact_form_fields.send(self.event, request=self.request) for r, response in responses: for key, value in response.items(): # We need to be this explicit, since OrderedDict.update does not retain ordering self.fields[key] = value if self.all_optional: for k, v in self.fields.items(): v.required = False v.widget.is_required = False
def __init__(self, request=None, *args, **kwargs): self.request = request self.standalone = kwargs.pop('standalone') self.signer = signing.TimestampSigner(salt=f'customer-registration-captcha-{get_client_ip(request)}') super().__init__(*args, **kwargs) event = getattr(request, "event", None) if event and event.settings.order_phone_asked: if event.settings.region or event.organizer.settings.region: country_code = event.settings.region or event.organizer.settings.region phone_prefix = get_phone_prefix(country_code) if phone_prefix: self.initial['phone'] = "+{}.".format(phone_prefix) self.fields['phone'] = PhoneNumberField( label=_('Phone'), required=event.settings.order_phone_required, widget=WrappedPhoneNumberPrefixWidget() ) self.fields['name_parts'] = NamePartsFormField( max_length=255, required=True, scheme=request.organizer.settings.name_scheme, titles=request.organizer.settings.name_scheme_titles, label=_('Name'), ) if self.standalone: # In the setandalone registration form, we add a simple CAPTCHA. We don't expect # this to actually turn away and motivated attacker, it's mainly a protection # against spam bots looking for contact forms. Since the standalone registration # form is one of the simplest public forms we have in the application it is the # most common target for untargeted bots. a = random.randint(1, 9) b = random.randint(1, 9) if 'challenge' in self.data: try: a, b = self.signer.unsign(self.data.get('challenge'), max_age=3600).split('+') a, b = int(a), int(b) except: pass self.fields['challenge'] = forms.CharField( widget=forms.HiddenInput, initial=self.signer.sign(f'{a}+{b}') ) self.fields['response'] = forms.IntegerField( label=_('What is the result of {num1} + {num2}?').format( num1=a, num2=b, ), min_value=0, )
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if not self.instance.phone and (self.instance.organizer.settings.region or self.instance.locale): country_code = self.instance.organizer.settings.region or get_country_by_locale( self.instance.locale) phone_prefix = get_phone_prefix(country_code) if phone_prefix: self.initial['phone'] = "+{}.".format(phone_prefix) self.fields['phone'] = PhoneNumberField( label=_('Phone'), required=False, widget=WrappedPhoneNumberPrefixWidget()) self.fields['name_parts'] = NamePartsFormField( max_length=255, required=False, scheme=self.instance.organizer.settings.name_scheme, titles=self.instance.organizer.settings.name_scheme_titles, label=_('Name'), )
def __init__(self, request=None, *args, **kwargs): self.request = request super().__init__(*args, **kwargs) event = getattr(request, "event", None) if event and event.settings.order_phone_asked: if event.settings.region or event.organizer.settings.region: country_code = event.settings.region or event.organizer.settings.region phone_prefix = get_phone_prefix(country_code) if phone_prefix: self.initial['phone'] = "+{}.".format(phone_prefix) self.fields['phone'] = PhoneNumberField( label=_('Phone'), required=event.settings.order_phone_required, widget=WrappedPhoneNumberPrefixWidget()) self.fields['name_parts'] = NamePartsFormField( max_length=255, required=True, scheme=request.organizer.settings.name_scheme, titles=request.organizer.settings.name_scheme_titles, label=_('Name'), )
def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') super().__init__(*args, **kwargs) event = self.event if event.settings.waiting_list_names_asked: self.fields['name_parts'] = NamePartsFormField( max_length=255, required=event.settings.waiting_list_names_required, scheme=event.settings.name_scheme, titles=event.settings.name_scheme_titles, label=_('Name'), ) else: del self.fields['name_parts'] if event.settings.waiting_list_phones_asked: with language(get_babel_locale()): default_country = guess_country(self.event) for prefix, values in _COUNTRY_CODE_TO_REGION_CODE.items(): if str(default_country ) in values and not self.initial.get('phone'): # We now exploit an implementation detail in PhoneNumberPrefixWidget to allow us to pass just # a country code but no number as an initial value. It's a bit hacky, but should be stable for # the future. self.initial['phone'] = "+{}.".format(prefix) self.fields['phone'] = PhoneNumberField( label=_("Phone number"), required=event.settings.waiting_list_phones_required, help_text=event.settings. waiting_list_phones_explanation_text, widget=WrappedPhoneNumberPrefixWidget()) else: del self.fields['phone']
class Meta: model = Order fields = ['email', 'email_known_to_work', 'phone'] widgets = {'phone': WrappedPhoneNumberPrefixWidget()}
def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') self.channel = kwargs.pop('channel') customer = kwargs.pop('customer') super().__init__(*args, **kwargs) choices = [('', '')] items, display_add_to_cart = get_grouped_items( self.event, self.instance.subevent, require_seat=None, memberships=(customer.usable_memberships( for_event=self.instance.subevent or self.event, testmode=self.event.testmode) if customer else None), ) for i in items: if not i.allow_waitinglist: continue if i.has_variations: for v in i.available_variations: if v.cached_availability[0] == Quota.AVAILABILITY_OK: continue choices.append((f'{i.pk}-{v.pk}', f'{i.name} – {v.value}')) else: if i.cached_availability[0] == Quota.AVAILABILITY_OK: continue choices.append((f'{i.pk}', f'{i.name}')) self.fields['itemvar'] = forms.ChoiceField( label=_('Product'), choices=choices, ) event = self.event if event.settings.waiting_list_names_asked: self.fields['name_parts'] = NamePartsFormField( max_length=255, required=event.settings.waiting_list_names_required, scheme=event.settings.name_scheme, titles=event.settings.name_scheme_titles, label=_('Name'), ) else: del self.fields['name_parts'] if event.settings.waiting_list_phones_asked: if not self.initial.get('phone'): phone_prefix = guess_phone_prefix(event) if phone_prefix: self.initial['phone'] = "+{}.".format(phone_prefix) self.fields['phone'] = PhoneNumberField( label=_("Phone number"), required=event.settings.waiting_list_phones_required, help_text=event.settings.waiting_list_phones_explanation_text, widget=WrappedPhoneNumberPrefixWidget()) else: del self.fields['phone']
def __init__(self, *args, **kwargs): self.event = kwargs.pop('event') self.channel = kwargs.pop('channel') super().__init__(*args, **kwargs) choices = [('', '')] items, display_add_to_cart = get_grouped_items(self.event, self.instance.subevent, require_seat=None) for i in items: if not i.allow_waitinglist: continue if i.has_variations: for v in i.available_variations: if v.cached_availability[0] == Quota.AVAILABILITY_OK: continue choices.append((f'{i.pk}-{v.pk}', f'{i.name} – {v.value}')) else: if i.cached_availability[0] == Quota.AVAILABILITY_OK: continue choices.append((f'{i.pk}', f'{i.name}')) self.fields['itemvar'] = forms.ChoiceField( label=_('Product'), choices=choices, ) event = self.event if event.settings.waiting_list_names_asked: self.fields['name_parts'] = NamePartsFormField( max_length=255, required=event.settings.waiting_list_names_required, scheme=event.settings.name_scheme, titles=event.settings.name_scheme_titles, label=_('Name'), ) else: del self.fields['name_parts'] if event.settings.waiting_list_phones_asked: with language(get_babel_locale()): default_country = guess_country(self.event) for prefix, values in _COUNTRY_CODE_TO_REGION_CODE.items(): if str(default_country ) in values and not self.initial.get('phone'): # We now exploit an implementation detail in PhoneNumberPrefixWidget to allow us to pass just # a country code but no number as an initial value. It's a bit hacky, but should be stable for # the future. self.initial['phone'] = "+{}.".format(prefix) self.fields['phone'] = PhoneNumberField( label=_("Phone number"), required=event.settings.waiting_list_phones_required, help_text=event.settings. waiting_list_phones_explanation_text, widget=WrappedPhoneNumberPrefixWidget()) else: del self.fields['phone']
def get_content_field(self, q, initial): tz = pytz.timezone(self.placeholder.question.event.settings.timezone) label = "" help_text = "" required = False if q.type == Question.TYPE_BOOLEAN: widget = forms.CheckboxInput() initialbool = initial == "True" return forms.BooleanField( label=label, required=False, help_text=help_text, initial=initialbool, widget=widget, ) if q.type == Question.TYPE_NUMBER: return forms.DecimalField( label=label, required=required, help_text=q.help_text, initial=initial, ) if q.type == Question.TYPE_STRING: return forms.CharField( label=label, required=required, help_text=help_text, initial=initial, ) if q.type == Question.TYPE_TEXT: return forms.CharField( label=label, required=required, help_text=help_text, widget=forms.Textarea, initial=initial, ) if q.type == Question.TYPE_COUNTRYCODE: return CountryField( countries=CachedCountries, blank=True, null=True, blank_label=" ", ).formfield( label=label, required=required, help_text=help_text, widget=forms.Select, empty_label=" ", initial=initial, ) if q.type == Question.TYPE_CHOICE: return forms.ModelChoiceField( queryset=q.options, label=label, required=required, help_text=help_text, widget=forms.Select, to_field_name="identifier", empty_label="", initial=q.options.filter( pk=initial).first() if initial else None, ) elif q.type == Question.TYPE_CHOICE_MULTIPLE: return forms.ModelMultipleChoiceField( queryset=q.options, label=label, required=required, help_text=help_text, to_field_name="identifier", widget=QuestionCheckboxSelectMultiple, initial=initial, ) elif q.type == Question.TYPE_DATE: attrs = {} if q.valid_date_min: attrs["data-min"] = q.valid_date_min.isoformat() if q.valid_date_max: attrs["data-max"] = q.valid_date_max.isoformat() field = forms.DateField( label=label, required=required, help_text=help_text, initial=dateutil.parser.parse(initial).date() if initial and initial else None, widget=DatePickerWidget(attrs), ) if q.valid_date_min: field.validators.append(MinDateValidator(q.valid_date_min)) if q.valid_date_max: field.validators.append(MaxDateValidator(q.valid_date_max)) return field elif q.type == Question.TYPE_TIME: return forms.TimeField( label=label, required=required, help_text=help_text, initial=dateutil.parser.parse(initial).time() if initial and initial else None, widget=TimePickerWidget(time_format=get_format_without_seconds( "TIME_INPUT_FORMATS")), ) elif q.type == Question.TYPE_DATETIME: field = SplitDateTimeField( label=label, required=required, help_text=help_text, initial=dateutil.parser.parse(initial).astimezone(tz) if initial else None, widget=SplitDateTimePickerWidget( time_format=get_format_without_seconds( "TIME_INPUT_FORMATS"), min_date=q.valid_datetime_min, max_date=q.valid_datetime_max, ), ) if q.valid_datetime_min: field.validators.append( MinDateTimeValidator(q.valid_datetime_min)) if q.valid_datetime_max: field.validators.append( MaxDateTimeValidator(q.valid_datetime_max)) return field elif q.type == Question.TYPE_PHONENUMBER: return PhoneNumberField( label=label, required=required, help_text=help_text, initial=initial, widget=WrappedPhoneNumberPrefixWidget(), )