Exemplo n.º 1
0
class RegisterForm(forms.ModelForm):
    dob = forms.DateField(
        required=True,
        label='Date of Birth',
        widget=DatePickerWidget(),
    )
    dob_again = forms.DateField(
        required=True,
        label='Date of Birth again',
        widget=DatePickerWidget(),
    )
    email = forms.CharField(
        widget=forms.TextInput(attrs={'class': 'form-control'}),
        label="E-mail address")
    email_again = forms.CharField(
        widget=forms.TextInput(attrs={'class': 'form-control'}),
        label="E-mail address again")
    first_name = forms.CharField(
        widget=forms.TextInput(attrs={'class': 'form-control'}),
        label="Legal First Name")
    last_name = forms.CharField(
        widget=forms.TextInput(attrs={'class': 'form-control'}),
        label="Legal Last Name")

    class Meta:
        model = LotteryEntry
        fields = ["email", "email_again", "first_name", "last_name", "dob"]
Exemplo n.º 2
0
class BankTransactionFilterForm(forms.Form):
    search_text = forms.CharField(required=False, widget=forms.TextInput(attrs={'class': "form-control", "placeholder": _("Search text")}))
    amount_min = forms.DecimalField(required=False, localize=True, widget=forms.TextInput(attrs={'class': "form-control", "placeholder": _("min"), "size": 8}))
    amount_max = forms.DecimalField(required=False, localize=True, widget=forms.TextInput(attrs={'class': "form-control", "placeholder": _("max"), "size": 8}))
    date_min = forms.DateField(required=False, widget=DatePickerWidget(attrs={"size": 8}))
    date_max = forms.DateField(required=False, widget=DatePickerWidget(attrs={"size": 8}))

    def is_valid(self):
        return super().is_valid() and any(value for value in self.cleaned_data.values())

    def filter(self, qs):
        if not self.is_valid():
            raise ValueError(_("Filter form is not valid."))
        if self.cleaned_data.get('search_text'):
            q = self.cleaned_data['search_text']
            qs = qs.filter(Q(payer__icontains=q) | Q(reference__icontains=q) | Q(comment__icontains=q) | Q(iban__icontains=q) | Q(bic__icontains=q))
        if self.cleaned_data.get('amount_min') is not None:
            qs = qs.filter(amount__gte=self.cleaned_data['amount_min'])
        if self.cleaned_data.get("amount_max") is not None:
            qs = qs.filter(amount__lte=self.cleaned_data['amount_max'])
        if self.cleaned_data.get('date_min') is not None:
            qs = qs.filter(date_parsed__gte=self.cleaned_data['date_min'])
        if self.cleaned_data.get('date_max') is not None:
            qs = qs.filter(date_parsed__lte=self.cleaned_data['date_max'])
        return qs
Exemplo n.º 3
0
 class Meta:
     model = Question
     localized_fields = '__all__'
     fields = [
         'question',
         'help_text',
         'type',
         'required',
         'ask_during_checkin',
         'hidden',
         'identifier',
         'items',
         'dependency_question',
         'dependency_values',
         'print_on_invoice',
         'valid_number_min',
         'valid_number_max',
         'valid_datetime_min',
         'valid_datetime_max',
         'valid_date_min',
         'valid_date_max',
         'valid_file_portrait',
     ]
     widgets = {
         'valid_datetime_min':
         SplitDateTimePickerWidget(),
         'valid_datetime_max':
         SplitDateTimePickerWidget(),
         'valid_date_min':
         DatePickerWidget(),
         'valid_date_max':
         DatePickerWidget(),
         'items':
         forms.CheckboxSelectMultiple(
             attrs={'class': 'scrolling-multiple-choice'}),
         'dependency_values':
         forms.SelectMultiple,
     }
     field_classes = {
         'valid_datetime_min': SplitDateTimeField,
         'valid_datetime_max': SplitDateTimeField,
         'items': ItemMultipleChoiceField,
         'dependency_question': SafeModelChoiceField,
     }
Exemplo n.º 4
0
 class Meta:
     model = Order
     fields = ['comment', 'checkin_attention', 'custom_followup_at']
     widgets = {
         'comment': forms.Textarea(attrs={
             'rows': 3,
             'class': 'helper-width-100',
         }),
         'custom_followup_at': DatePickerWidget(),
     }
Exemplo n.º 5
0
class MarkPaidForm(ConfirmPaymentForm):
    amount = forms.DecimalField(
        required=True,
        max_digits=10, decimal_places=2,
        localize=True,
        label=_('Payment amount'),
    )
    payment_date = forms.DateField(
        required=True,
        label=_('Payment date'),
        widget=DatePickerWidget(),
        initial=now
    )

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        change_decimal_field(self.fields['amount'], self.instance.event.currency)
        self.fields['amount'].initial = max(Decimal('0.00'), self.instance.pending_sum)
Exemplo n.º 6
0
    def __init__(self, *args, **kwargs):
        self.mixed_values = kwargs.pop('mixed_values')
        self.queryset = kwargs.pop('queryset')
        super().__init__(*args, **kwargs)
        self.fields['location'].widget.attrs['rows'] = '3'

        for k in ('name', 'location', 'frontpage_text'):
            # i18n fields
            if k in self.mixed_values:
                self.fields[k].widget.attrs['placeholder'] = '[{}]'.format(
                    _('Selection contains various values'))
            else:
                self.fields[k].widget.attrs['placeholder'] = ''
            self.fields[k].one_required = False

        for k in ('geo_lat', 'geo_lon'):
            # scalar fields
            if k in self.mixed_values:
                self.fields[k].widget.attrs['placeholder'] = '[{}]'.format(
                    _('Selection contains various values'))
            else:
                self.fields[k].widget.attrs['placeholder'] = ''
            self.fields[k].widget.is_required = False
            self.fields[k].required = False

        for k in ('date_from', 'date_to', 'date_admission', 'presale_start',
                  'presale_end'):
            self.fields[k + '_day'] = forms.DateField(
                label=self._meta.model._meta.get_field(k).verbose_name,
                help_text=self._meta.model._meta.get_field(k).help_text,
                widget=DatePickerWidget(),
                required=False,
            )
            self.fields[k + '_time'] = forms.TimeField(
                label=self._meta.model._meta.get_field(k).verbose_name,
                help_text=self._meta.model._meta.get_field(k).help_text,
                widget=TimePickerWidget(),
                required=False,
            )
Exemplo n.º 7
0
    def __init__(self, *args, **kwargs):
        """
        Takes two additional keyword arguments:

        :param cartpos: The cart position the form should be for
        :param event: The event this belongs to
        """
        cartpos = self.cartpos = kwargs.pop('cartpos', None)
        orderpos = self.orderpos = kwargs.pop('orderpos', None)
        pos = cartpos or orderpos
        item = pos.item
        questions = pos.item.questions_to_ask
        event = kwargs.pop('event')
        self.all_optional = kwargs.pop('all_optional', False)

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

        add_fields = {}

        if item.admission and event.settings.attendee_names_asked:
            add_fields['attendee_name_parts'] = NamePartsFormField(
                max_length=255,
                required=event.settings.attendee_names_required
                and not self.all_optional,
                scheme=event.settings.name_scheme,
                titles=event.settings.name_scheme_titles,
                label=_('Attendee name'),
                initial=(cartpos.attendee_name_parts
                         if cartpos else orderpos.attendee_name_parts),
            )
        if item.admission and event.settings.attendee_emails_asked:
            add_fields['attendee_email'] = forms.EmailField(
                required=event.settings.attendee_emails_required
                and not self.all_optional,
                label=_('Attendee email'),
                initial=(cartpos.attendee_email
                         if cartpos else orderpos.attendee_email),
                widget=forms.EmailInput(attrs={'autocomplete': 'email'}))
        if item.admission and event.settings.attendee_company_asked:
            add_fields['company'] = forms.CharField(
                required=event.settings.attendee_company_required
                and not self.all_optional,
                label=_('Company'),
                max_length=255,
                initial=(cartpos.company if cartpos else orderpos.company),
            )

        if item.admission and event.settings.attendee_addresses_asked:
            add_fields['street'] = forms.CharField(
                required=event.settings.attendee_addresses_required
                and not self.all_optional,
                label=_('Address'),
                widget=forms.Textarea(
                    attrs={
                        'rows': 2,
                        'placeholder': _('Street and Number'),
                        'autocomplete': 'street-address'
                    }),
                initial=(cartpos.street if cartpos else orderpos.street),
            )
            add_fields['zipcode'] = forms.CharField(
                required=event.settings.attendee_addresses_required
                and not self.all_optional,
                max_length=30,
                label=_('ZIP code'),
                initial=(cartpos.zipcode if cartpos else orderpos.zipcode),
                widget=forms.TextInput(attrs={
                    'autocomplete': 'postal-code',
                }),
            )
            add_fields['city'] = forms.CharField(
                required=event.settings.attendee_addresses_required
                and not self.all_optional,
                label=_('City'),
                max_length=255,
                initial=(cartpos.city if cartpos else orderpos.city),
                widget=forms.TextInput(attrs={
                    'autocomplete': 'address-level2',
                }),
            )
            country = (cartpos.country if cartpos else
                       orderpos.country) or guess_country(event)
            add_fields['country'] = CountryField(
                countries=CachedCountries).formfield(
                    required=event.settings.attendee_addresses_required
                    and not self.all_optional,
                    label=_('Country'),
                    initial=country,
                    widget=forms.Select(attrs={
                        'autocomplete': 'country',
                    }),
                )
            c = [('', pgettext_lazy('address', 'Select state'))]
            fprefix = str(
                self.prefix
            ) + '-' if self.prefix is not None and self.prefix != '-' else ''
            cc = None
            if fprefix + 'country' in self.data:
                cc = str(self.data[fprefix + 'country'])
            elif country:
                cc = str(country)
            if cc and cc in COUNTRIES_WITH_STATE_IN_ADDRESS:
                types, form = COUNTRIES_WITH_STATE_IN_ADDRESS[cc]
                statelist = [
                    s for s in pycountry.subdivisions.get(country_code=cc)
                    if s.type in types
                ]
                c += sorted([(s.code[3:], s.name) for s in statelist],
                            key=lambda s: s[1])
            elif fprefix + 'state' in self.data:
                self.data = self.data.copy()
                del self.data[fprefix + 'state']

            add_fields['state'] = forms.ChoiceField(
                label=pgettext_lazy('address', 'State'),
                required=False,
                choices=c,
                widget=forms.Select(attrs={
                    'autocomplete': 'address-level1',
                }),
            )
            add_fields['state'].widget.is_required = True

        field_positions = list([(n,
                                 event.settings.system_question_order.get(
                                     n if n != 'state' else 'country', 0))
                                for n in add_fields.keys()])

        for q in questions:
            # Do we already have an answer? Provide it as the initial value
            answers = [a for a in pos.answerlist if a.question_id == q.id]
            if answers:
                initial = answers[0]
            else:
                initial = None
            tz = pytz.timezone(event.settings.timezone)
            help_text = rich_text(q.help_text)
            label = escape(q.question)  # django-bootstrap3 calls mark_safe
            required = q.required and not self.all_optional
            if q.type == Question.TYPE_BOOLEAN:
                if q.required:
                    # For some reason, django-bootstrap3 does not set the required attribute
                    # itself.
                    widget = forms.CheckboxInput(
                        attrs={'required': 'required'})
                else:
                    widget = forms.CheckboxInput()

                if initial:
                    initialbool = (initial.answer == "True")
                else:
                    initialbool = False

                field = forms.BooleanField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=initialbool,
                    widget=widget,
                )
            elif q.type == Question.TYPE_NUMBER:
                field = forms.DecimalField(
                    label=label,
                    required=required,
                    min_value=q.valid_number_min or Decimal('0.00'),
                    max_value=q.valid_number_max,
                    help_text=q.help_text,
                    initial=initial.answer if initial else None,
                )
            elif q.type == Question.TYPE_STRING:
                field = forms.CharField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=initial.answer if initial else None,
                )
            elif q.type == Question.TYPE_TEXT:
                field = forms.CharField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    widget=forms.Textarea,
                    initial=initial.answer if initial else None,
                )
            elif q.type == Question.TYPE_COUNTRYCODE:
                field = 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.answer if initial else
                    (guess_country(event) if required else None),
                )
            elif q.type == Question.TYPE_CHOICE:
                field = forms.ModelChoiceField(
                    queryset=q.options,
                    label=label,
                    required=required,
                    help_text=help_text,
                    widget=forms.Select,
                    to_field_name='identifier',
                    empty_label='',
                    initial=initial.options.first() if initial else None,
                )
            elif q.type == Question.TYPE_CHOICE_MULTIPLE:
                field = forms.ModelMultipleChoiceField(
                    queryset=q.options,
                    label=label,
                    required=required,
                    help_text=help_text,
                    to_field_name='identifier',
                    widget=QuestionCheckboxSelectMultiple,
                    initial=initial.options.all() if initial else None,
                )
            elif q.type == Question.TYPE_FILE:
                field = ExtFileField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=initial.file if initial else None,
                    widget=UploadedFileWidget(position=pos,
                                              event=event,
                                              answer=initial),
                    ext_whitelist=(".png", ".jpg", ".gif", ".jpeg", ".pdf",
                                   ".txt", ".docx", ".gif", ".svg", ".pptx",
                                   ".ppt", ".doc", ".xlsx", ".xls", ".jfif",
                                   ".heic", ".heif", ".pages", ".bmp", ".tif",
                                   ".tiff"),
                    max_size=10 * 1024 * 1024,
                )
            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.answer).date()
                    if initial and initial.answer 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))
            elif q.type == Question.TYPE_TIME:
                field = forms.TimeField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=dateutil.parser.parse(initial.answer).time()
                    if initial and initial.answer 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.answer).astimezone(tz)
                    if initial and initial.answer 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))
            elif q.type == Question.TYPE_PHONENUMBER:
                babel_locale = 'en'
                # Babel, and therefore django-phonenumberfield, do not support our custom locales such das de_Informal
                if localedata.exists(get_language()):
                    babel_locale = get_language()
                elif localedata.exists(get_language()[:2]):
                    babel_locale = get_language()[:2]
                with language(babel_locale):
                    default_country = guess_country(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 = PhoneNumber().from_string(
                            initial.answer) if initial else "+{}.".format(
                                default_prefix)
                    except NumberParseException:
                        initial = None
                    field = PhoneNumberField(
                        label=label,
                        required=required,
                        help_text=help_text,
                        # 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())
            field.question = q
            if answers:
                # Cache the answer object for later use
                field.answer = answers[0]

            if q.dependency_question_id:
                field.widget.attrs[
                    'data-question-dependency'] = q.dependency_question_id
                field.widget.attrs[
                    'data-question-dependency-values'] = escapejson_attr(
                        json.dumps(q.dependency_values))
                if q.type != 'M':
                    field.widget.attrs[
                        'required'] = q.required and not self.all_optional
                    field._required = q.required and not self.all_optional
                field.required = False

            add_fields['question_%s' % q.id] = field
            field_positions.append(('question_%s' % q.id, q.position))

        field_positions.sort(key=lambda e: e[1])
        for fname, p in field_positions:
            self.fields[fname] = add_fields[fname]

        responses = question_form_fields.send(sender=event, position=pos)
        data = pos.meta_info_data
        for r, response in sorted(responses, key=lambda r: str(r[0])):
            for key, value in response.items():
                # We need to be this explicit, since OrderedDict.update does not retain ordering
                self.fields[key] = value
                value.initial = data.get('question_form_data', {}).get(key)

        for k, v in self.fields.items():
            if v.widget.attrs.get(
                    'autocomplete') or k == 'attendee_name_parts':
                v.widget.attrs['autocomplete'] = 'section-{} '.format(
                    self.prefix) + v.widget.attrs.get('autocomplete', '')
Exemplo n.º 8
0
    def __init__(self, *args, **kwargs):
        """
        Takes two additional keyword arguments:

        :param cartpos: The cart position the form should be for
        :param event: The event this belongs to
        """
        cartpos = self.cartpos = kwargs.pop('cartpos', None)
        orderpos = self.orderpos = kwargs.pop('orderpos', None)
        pos = cartpos or orderpos
        item = pos.item
        questions = pos.item.questions_to_ask
        event = kwargs.pop('event')
        self.all_optional = kwargs.pop('all_optional', False)

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

        if item.admission and event.settings.attendee_names_asked:
            self.fields['attendee_name_parts'] = NamePartsFormField(
                max_length=255,
                required=event.settings.attendee_names_required,
                scheme=event.settings.name_scheme,
                titles=event.settings.name_scheme_titles,
                label=_('Attendee name'),
                initial=(cartpos.attendee_name_parts
                         if cartpos else orderpos.attendee_name_parts),
            )
        if item.admission and event.settings.attendee_emails_asked:
            self.fields['attendee_email'] = forms.EmailField(
                required=event.settings.attendee_emails_required,
                label=_('Attendee email'),
                initial=(cartpos.attendee_email
                         if cartpos else orderpos.attendee_email),
                widget=forms.EmailInput(attrs={'autocomplete': 'email'}))

        for q in questions:
            # Do we already have an answer? Provide it as the initial value
            answers = [a for a in pos.answerlist if a.question_id == q.id]
            if answers:
                initial = answers[0]
            else:
                initial = None
            tz = pytz.timezone(event.settings.timezone)
            help_text = rich_text(q.help_text)
            label = escape(q.question)  # django-bootstrap3 calls mark_safe
            required = q.required and not self.all_optional
            if q.type == Question.TYPE_BOOLEAN:
                if q.required:
                    # For some reason, django-bootstrap3 does not set the required attribute
                    # itself.
                    widget = forms.CheckboxInput(
                        attrs={'required': 'required'})
                else:
                    widget = forms.CheckboxInput()

                if initial:
                    initialbool = (initial.answer == "True")
                else:
                    initialbool = False

                field = forms.BooleanField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=initialbool,
                    widget=widget,
                )
            elif q.type == Question.TYPE_NUMBER:
                field = forms.DecimalField(
                    label=label,
                    required=required,
                    help_text=q.help_text,
                    initial=initial.answer if initial else None,
                    min_value=Decimal('0.00'),
                )
            elif q.type == Question.TYPE_STRING:
                field = forms.CharField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=initial.answer if initial else None,
                )
            elif q.type == Question.TYPE_TEXT:
                field = forms.CharField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    widget=forms.Textarea,
                    initial=initial.answer if initial else None,
                )
            elif q.type == Question.TYPE_COUNTRYCODE:
                field = CountryField().formfield(
                    label=label,
                    required=required,
                    help_text=help_text,
                    widget=forms.Select,
                    empty_label='',
                    initial=initial.answer if initial else None,
                )
            elif q.type == Question.TYPE_CHOICE:
                field = forms.ModelChoiceField(
                    queryset=q.options,
                    label=label,
                    required=required,
                    help_text=help_text,
                    widget=forms.Select,
                    to_field_name='identifier',
                    empty_label='',
                    initial=initial.options.first() if initial else None,
                )
            elif q.type == Question.TYPE_CHOICE_MULTIPLE:
                field = forms.ModelMultipleChoiceField(
                    queryset=q.options,
                    label=label,
                    required=required,
                    help_text=help_text,
                    to_field_name='identifier',
                    widget=forms.CheckboxSelectMultiple,
                    initial=initial.options.all() if initial else None,
                )
            elif q.type == Question.TYPE_FILE:
                field = forms.FileField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=initial.file if initial else None,
                    widget=UploadedFileWidget(position=pos,
                                              event=event,
                                              answer=initial),
                )
            elif q.type == Question.TYPE_DATE:
                field = forms.DateField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=dateutil.parser.parse(initial.answer).date()
                    if initial and initial.answer else None,
                    widget=DatePickerWidget(),
                )
            elif q.type == Question.TYPE_TIME:
                field = forms.TimeField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=dateutil.parser.parse(initial.answer).time()
                    if initial and initial.answer 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.answer).astimezone(tz)
                    if initial and initial.answer else None,
                    widget=SplitDateTimePickerWidget(
                        time_format=get_format_without_seconds(
                            'TIME_INPUT_FORMATS')),
                )
            elif q.type == Question.TYPE_PHONENUMBER:
                babel_locale = 'en'
                # Babel, and therefore django-phonenumberfield, do not support our custom locales such das de_Informal
                if localedata.exists(get_language()):
                    babel_locale = get_language()
                elif localedata.exists(get_language()[:2]):
                    babel_locale = get_language()[:2]
                with language(babel_locale):
                    default_country = guess_country(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 = PhoneNumber().from_string(
                            initial.answer) if initial else "+{}.".format(
                                default_prefix)
                    except NumberParseException:
                        initial = None
                    field = PhoneNumberField(
                        label=label,
                        required=required,
                        help_text=help_text,
                        # 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())
            field.question = q
            if answers:
                # Cache the answer object for later use
                field.answer = answers[0]

            if q.dependency_question_id:
                field.widget.attrs[
                    'data-question-dependency'] = q.dependency_question_id
                field.widget.attrs[
                    'data-question-dependency-values'] = escapejson_attr(
                        json.dumps(q.dependency_values))
                if q.type != 'M':
                    field.widget.attrs[
                        'required'] = q.required and not self.all_optional
                    field._required = q.required and not self.all_optional
                field.required = False

            self.fields['question_%s' % q.id] = field

        responses = question_form_fields.send(sender=event, position=pos)
        data = pos.meta_info_data
        for r, response in sorted(responses, key=lambda r: str(r[0])):
            for key, value in response.items():
                # We need to be this explicit, since OrderedDict.update does not retain ordering
                self.fields[key] = value
                value.initial = data.get('question_form_data', {}).get(key)

        for k, v in self.fields.items():
            if v.widget.attrs.get(
                    'autocomplete') or k == 'attendee_name_parts':
                v.widget.attrs['autocomplete'] = 'section-{} '.format(
                    self.prefix) + v.widget.attrs.get('autocomplete', '')
Exemplo n.º 9
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.fields['date'].widget = DatePickerWidget()
Exemplo n.º 10
0
    def __init__(self, *args, **kwargs):
        """
        Takes two additional keyword arguments:

        :param cartpos: The cart position the form should be for
        :param event: The event this belongs to
        """
        cartpos = self.cartpos = kwargs.pop('cartpos', None)
        orderpos = self.orderpos = kwargs.pop('orderpos', None)
        pos = cartpos or orderpos
        item = pos.item
        questions = pos.item.questions_to_ask
        event = kwargs.pop('event')
        self.all_optional = kwargs.pop('all_optional', False)

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

        if item.admission and event.settings.attendee_names_asked:
            self.fields['attendee_name_parts'] = NamePartsFormField(
                max_length=255,
                required=event.settings.attendee_names_required,
                scheme=event.settings.name_scheme,
                label=_('Attendee name'),
                initial=(cartpos.attendee_name_parts
                         if cartpos else orderpos.attendee_name_parts),
            )
        if item.admission and event.settings.attendee_emails_asked:
            self.fields['attendee_email'] = forms.EmailField(
                required=event.settings.attendee_emails_required,
                label=_('Attendee email'),
                initial=(cartpos.attendee_email
                         if cartpos else orderpos.attendee_email))

        for q in questions:
            # Do we already have an answer? Provide it as the initial value
            answers = [a for a in pos.answerlist if a.question_id == q.id]
            if answers:
                initial = answers[0]
            else:
                initial = None
            tz = pytz.timezone(event.settings.timezone)
            help_text = rich_text(q.help_text)
            label = escape(q.question)  # django-bootstrap3 calls mark_safe
            required = q.required and not self.all_optional
            if q.type == Question.TYPE_BOOLEAN:
                if q.required:
                    # For some reason, django-bootstrap3 does not set the required attribute
                    # itself.
                    widget = forms.CheckboxInput(
                        attrs={'required': 'required'})
                else:
                    widget = forms.CheckboxInput()

                if initial:
                    initialbool = (initial.answer == "True")
                else:
                    initialbool = False

                field = forms.BooleanField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=initialbool,
                    widget=widget,
                )
            elif q.type == Question.TYPE_NUMBER:
                field = forms.DecimalField(
                    label=label,
                    required=required,
                    help_text=q.help_text,
                    initial=initial.answer if initial else None,
                    min_value=Decimal('0.00'),
                )
            elif q.type == Question.TYPE_STRING:
                field = forms.CharField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=initial.answer if initial else None,
                )
            elif q.type == Question.TYPE_TEXT:
                field = forms.CharField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    widget=forms.Textarea,
                    initial=initial.answer if initial else None,
                )
            elif q.type == Question.TYPE_CHOICE:
                field = forms.ModelChoiceField(
                    queryset=q.options,
                    label=label,
                    required=required,
                    help_text=help_text,
                    widget=forms.Select,
                    to_field_name='identifier',
                    empty_label='',
                    initial=initial.options.first() if initial else None,
                )
            elif q.type == Question.TYPE_CHOICE_MULTIPLE:
                field = forms.ModelMultipleChoiceField(
                    queryset=q.options,
                    label=label,
                    required=required,
                    help_text=help_text,
                    to_field_name='identifier',
                    widget=forms.CheckboxSelectMultiple,
                    initial=initial.options.all() if initial else None,
                )
            elif q.type == Question.TYPE_FILE:
                field = forms.FileField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=initial.file if initial else None,
                    widget=UploadedFileWidget(position=pos,
                                              event=event,
                                              answer=initial),
                )
            elif q.type == Question.TYPE_DATE:
                field = forms.DateField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=dateutil.parser.parse(initial.answer).date()
                    if initial and initial.answer else None,
                    widget=DatePickerWidget(),
                )
            elif q.type == Question.TYPE_TIME:
                field = forms.TimeField(
                    label=label,
                    required=required,
                    help_text=help_text,
                    initial=dateutil.parser.parse(initial.answer).time()
                    if initial and initial.answer 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.answer).astimezone(tz)
                    if initial and initial.answer else None,
                    widget=SplitDateTimePickerWidget(
                        time_format=get_format_without_seconds(
                            'TIME_INPUT_FORMATS')),
                )
            field.question = q
            if answers:
                # Cache the answer object for later use
                field.answer = answers[0]

            if q.dependency_question_id:
                field.widget.attrs[
                    'data-question-dependency'] = q.dependency_question_id
                field.widget.attrs[
                    'data-question-dependency-value'] = q.dependency_value
                if q.type != 'M':
                    field.widget.attrs[
                        'required'] = q.required and not self.all_optional
                    field._required = q.required and not self.all_optional
                field.required = False

            self.fields['question_%s' % q.id] = field

        responses = question_form_fields.send(sender=event, position=pos)
        data = pos.meta_info_data
        for r, response in sorted(responses, key=lambda r: str(r[0])):
            for key, value in response.items():
                # We need to be this explicit, since OrderedDict.update does not retain ordering
                self.fields[key] = value
                value.initial = data.get('question_form_data', {}).get(key)
Exemplo n.º 11
0
class StretchgoalsSettingsForm(I18nForm, SettingsForm):
    # General settings
    stretchgoals_start_date = forms.DateField(
        required=False,
        label=_('Start date'),
        widget=DatePickerWidget(),
        help_text=_('Will start at first sale by default.'),
    )
    stretchgoals_end_date = forms.DateField(
        required=False,
        label=_('End date'),
        widget=DatePickerWidget(),
        help_text=_('Will end at last sale by default.'),
    )
    stretchgoals_items = SafeModelMultipleChoiceField(
        queryset=Item.objects.none(),
        required=False,
        label=_('Item types'),
        help_text=_('Items to be included in the calculation.'),
        widget=forms.CheckboxSelectMultiple,
    )
    stretchgoals_include_pending = forms.BooleanField(
        required=False,
        label=_('Include pending orders'),
        help_text=_(
            'By default, only paid orders are included in the calculation.'),
    )

    # Goal settings
    stretchgoals_new_name = I18nFormField(required=False,
                                          label=_('New goal\'s name'),
                                          widget=I18nTextInput)
    stretchgoals_new_total = forms.IntegerField(
        required=False, min_value=0, label=_('New total revenue goal'))
    stretchgoals_new_amount = forms.IntegerField(
        required=False,
        min_value=0,
        label=_('New goal\'s amount of items to be sold'))
    stretchgoals_new_description = I18nFormField(
        required=False,
        label=_('New goal\'s description'),
        widget=I18nTextarea)

    # Display settings
    stretchgoals_is_public = forms.BooleanField(
        required=False,
        label=_('Show publicly'),
        help_text=_('By default, the chart is only shown in the backend.'),
    )
    stretchgoals_calculation_text = forms.BooleanField(
        required=False,
        label=_('Show public text'),
        help_text=
        _('This text will include the current state and extrapolations for all goals.'
          ),
    )
    stretchgoals_chart_averages = forms.BooleanField(
        required=False,
        label=_('Generate average price graph'),
        help_text=_(
            'This graph shows the development of the average price paid.'),
    )
    stretchgoals_chart_totals = forms.BooleanField(
        required=False,
        label=_('Generate total revenue graph'),
        help_text=_('This graph shows the total revenue over time.'),
    )
    stretchgoals_chart_itemsales = forms.BooleanField(
        required=False,
        label=_('Generate sold items graph'),
        help_text=_(
            'This graph shows the total amount of sold items over time.'),
    )
    stretchgoals_show_itemsales_items = forms.BooleanField(
        required=False,
        label=_('Show individual products in sold items graph'),
        help_text=_(
            'If this option is disabled, an aggregated number will only be shown in the sold items graph.'
            'Else, a per-item breakdown will be displayed'),
        widget=forms.CheckboxInput(
            attrs={
                'data-checkbox-dependency': '#id_stretchgoals_chart_itemsales'
            }),
    )
    stretchgoals_min_orders = forms.IntegerField(
        required=False,
        label=_('Minimal number of orders'),
        help_text=
        _('Only show the graph if more than this many orders are taken into consideration.'
          ),
    )
    stretchgoals_public_text = I18nFormField(
        required=False,
        label=_('Text shown on the public page'),
        help_text=_(
            'Text shown on the public page. You can use the placeholder '
            '{avg_now} (the current average).'),
        widget=I18nTextarea,
    )

    def __init__(self, *args, **kwargs):
        """ Reduce possible friends_ticket_items to items of this event. """
        self.event = kwargs.pop('event')
        super().__init__(*args, **kwargs)

        initial_items = (self.event.settings.get('stretchgoals_items',
                                                 as_type=QuerySet) or [])
        if isinstance(initial_items, str) and initial_items:
            initial_items = self.event.items.filter(
                id__in=initial_items.split(','))
        elif isinstance(initial_items, list):
            initial_items = self.event.items.filter(
                id__in=[i.pk for i in initial_items])

        self.fields['stretchgoals_items'].queryset = Item.objects.filter(
            event=self.event)
        self.initial['stretchgoals_items'] = initial_items
        self.goals = get_goals(self.event)

    def _save_new_goal(self):
        goals = json.loads(
            self.event.settings.get('stretchgoals_goals') or "[]")
        new_goal = dict()
        for item in ['name', 'total', 'amount', 'description']:
            new_goal[item] = self.cleaned_data.pop(
                'stretchgoals_new_{}'.format(item))
            self.fields.pop('stretchgoals_new_{}'.format(item))

        if new_goal['total']:
            goals.append(new_goal)
            set_goals(self.event, goals)

    def save(self, *args, **kwargs):
        self._save_new_goal()
        self.event.settings._h.add_type(
            QuerySet, lambda queryset: ','.join(
                [str(element.pk) for element in queryset]),
            lambda pk_list: Item.objects.filter(pk__in=list(
                filter(None, pk_list.split(',')))))
        super().save(*args, **kwargs)
Exemplo n.º 12
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(),
         )