Пример #1
0
 class Meta:
     model = Order
     fields = ['customer', 'email', 'email_known_to_work', 'phone']
     widgets = {
         'phone': WrappedPhoneNumberPrefixWidget(),
     }
     field_classes = {
         'customer': SafeModelChoiceField,
     }
Пример #2
0
    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
Пример #3
0
    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,
            )
Пример #4
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'),
        )
Пример #5
0
    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'),
        )
Пример #6
0
    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']
Пример #7
0
 class Meta:
     model = Order
     fields = ['email', 'email_known_to_work', 'phone']
     widgets = {'phone': WrappedPhoneNumberPrefixWidget()}
Пример #8
0
    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']
Пример #9
0
    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']
Пример #10
0
 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(),
         )