Exemple #1
0
 def __init__(self, *args, **kwargs):
     self.event = kwargs['obj']
     super().__init__(*args, **kwargs)
     self.fields['confirm_text'].widget.attrs['rows'] = '3'
     self.fields['confirm_text'].widget.attrs['placeholder'] = _(
         'e.g. I hereby confirm that I have read and agree with the event organizer\'s terms of service '
         'and agree with them.'
     )
     self.fields['name_scheme'].choices = (
         (k, _('Ask for {fields}, display like {example}').format(
             fields=' + '.join(str(vv[1]) for vv in v['fields']),
             example=v['concatenation'](v['sample'])
         ))
         for k, v in PERSON_NAME_SCHEMES.items()
     )
     self.fields['name_scheme_titles'].choices = [('', _('Free text input'))] + [
         (k, '{scheme}: {samples}'.format(
             scheme=v[0],
             samples=', '.join(v[1])
         ))
         for k, v in PERSON_NAME_TITLE_GROUPS.items()
     ]
     if not self.event.has_subevents:
         del self.fields['frontpage_subevent_ordering']
         del self.fields['event_list_type']
     self.fields['primary_font'].choices += [
         (a, {"title": a, "data": v}) for a, v in get_fonts().items()
     ]
Exemple #2
0
 def __init__(self, *args, **kwargs):
     fields = []
     defaults = {
         'widget': self.widget,
         'max_length': kwargs.pop('max_length', None),
     }
     self.scheme_name = kwargs.pop('scheme')
     self.scheme = PERSON_NAME_SCHEMES.get(self.scheme_name)
     self.one_required = kwargs.get('required', True)
     require_all_fields = kwargs.pop('require_all_fields', False)
     kwargs['required'] = False
     kwargs['widget'] = (kwargs.get('widget')
                         or self.widget)(scheme=self.scheme,
                                         field=self,
                                         **kwargs.pop('widget_kwargs', {}))
     defaults.update(**kwargs)
     for fname, label, size in self.scheme['fields']:
         defaults['label'] = label
         field = forms.CharField(**defaults)
         field.part_name = fname
         fields.append(field)
     super().__init__(fields=fields,
                      require_all_fields=False,
                      *args,
                      **kwargs)
     self.require_all_fields = require_all_fields
     self.required = self.one_required
Exemple #3
0
 def __init__(self, *args, **kwargs):
     fields = []
     defaults = {
         'widget': self.widget,
         'max_length': kwargs.pop('max_length', None),
     }
     self.scheme_name = kwargs.pop('scheme')
     self.scheme = PERSON_NAME_SCHEMES.get(self.scheme_name)
     self.one_required = kwargs.get('required', True)
     require_all_fields = kwargs.pop('require_all_fields', False)
     kwargs['required'] = False
     kwargs['widget'] = (kwargs.get('widget') or self.widget)(
         scheme=self.scheme, field=self, **kwargs.pop('widget_kwargs', {})
     )
     defaults.update(**kwargs)
     for fname, label, size in self.scheme['fields']:
         defaults['label'] = label
         field = forms.CharField(**defaults)
         field.part_name = fname
         fields.append(field)
     super().__init__(
         fields=fields, require_all_fields=False, *args, **kwargs
     )
     self.require_all_fields = require_all_fields
     self.required = self.one_required
Exemple #4
0
    def __init__(self, *args, **kwargs):
        fields = []
        defaults = {
            'widget': self.widget,
            'max_length': kwargs.pop('max_length', None),
            'validators': [
                RegexValidator(
                    # The following characters should never appear in a name anywhere of
                    # the world. However, they commonly appear in inputs generated by spam
                    # bots.
                    r'^[^$€/%§{}<>~]*$',
                    message=_('Please do not use special characters in names.')
                )
            ]
        }
        self.scheme_name = kwargs.pop('scheme')
        self.titles = kwargs.pop('titles')
        self.scheme = PERSON_NAME_SCHEMES.get(self.scheme_name)
        if self.titles:
            self.scheme_titles = PERSON_NAME_TITLE_GROUPS.get(self.titles)
        else:
            self.scheme_titles = None
        self.one_required = kwargs.get('required', True)
        require_all_fields = kwargs.pop('require_all_fields', False)
        kwargs['required'] = False
        kwargs['widget'] = (kwargs.get('widget') or self.widget)(
            scheme=self.scheme, titles=self.scheme_titles, field=self, **kwargs.pop('widget_kwargs', {})
        )
        defaults.update(**kwargs)
        for fname, label, size in self.scheme['fields']:
            defaults['label'] = label
            if fname == 'title' and self.scheme_titles:
                d = dict(defaults)
                d.pop('max_length', None)
                d.pop('validators', None)
                field = forms.ChoiceField(
                    **d,
                    choices=[('', '')] + [(d, d) for d in self.scheme_titles[1]]
                )

            elif fname == 'salutation':
                d = dict(defaults)
                d.pop('max_length', None)
                d.pop('validators', None)
                field = forms.ChoiceField(
                    **d,
                    choices=[('', '---')] + PERSON_NAME_SALUTATIONS
                )
            else:
                field = forms.CharField(**defaults)
            field.part_name = fname
            fields.append(field)
        super().__init__(
            fields=fields, require_all_fields=False, *args, **kwargs
        )
        self.require_all_fields = require_all_fields
        self.required = self.one_required
Exemple #5
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.fields['name_scheme'].choices = (
         (k, _('Ask for {fields}, display like {example}').format(
             fields=' + '.join(str(vv[1]) for vv in v['fields']),
             example=v['concatenation'](v['sample'])))
         for k, v in PERSON_NAME_SCHEMES.items())
     self.fields['name_scheme_titles'].choices = [
         ('', _('Free text input'))
     ] + [(k, '{scheme}: {samples}'.format(scheme=v[0],
                                           samples=', '.join(v[1])))
          for k, v in PERSON_NAME_TITLE_GROUPS.items()]
Exemple #6
0
    def __init__(self, *args, **kwargs):
        fields = []
        defaults = {
            'widget': self.widget,
            'max_length': kwargs.pop('max_length', None),
        }
        self.scheme_name = kwargs.pop('scheme')
        self.titles = kwargs.pop('titles')
        self.scheme = PERSON_NAME_SCHEMES.get(self.scheme_name)
        if self.titles:
            self.scheme_titles = PERSON_NAME_TITLE_GROUPS.get(self.titles)
        else:
            self.scheme_titles = None
        self.one_required = kwargs.get('required', True)
        require_all_fields = kwargs.pop('require_all_fields', False)
        kwargs['required'] = False
        kwargs['widget'] = (kwargs.get('widget')
                            or self.widget)(scheme=self.scheme,
                                            titles=self.scheme_titles,
                                            field=self,
                                            **kwargs.pop('widget_kwargs', {}))
        defaults.update(**kwargs)
        for fname, label, size in self.scheme['fields']:
            defaults['label'] = label
            if fname == 'title' and self.scheme_titles:
                d = dict(defaults)
                d.pop('max_length', None)
                field = forms.ChoiceField(**d,
                                          choices=[('', '')] +
                                          [(d, d)
                                           for d in self.scheme_titles[1]])

            elif fname == 'salutation':
                d = dict(defaults)
                d.pop('max_length', None)
                field = forms.ChoiceField(**d,
                                          choices=[('', '---')] +
                                          [(s, s)
                                           for s in PERSON_NAME_SALUTATIONS])
            else:
                field = forms.CharField(**defaults)
            field.part_name = fname
            fields.append(field)
        super().__init__(fields=fields,
                         require_all_fields=False,
                         *args,
                         **kwargs)
        self.require_all_fields = require_all_fields
        self.required = self.one_required
Exemple #7
0
def get_all_columns(event):
    default = []
    if event.has_subevents:
        default.append(SubeventColumn(event))
    default += [
        EmailColumn(event),
        PhoneColumn(event),
        ItemColumn(event),
        Variation(event),
        InvoiceAddressCompany(event),
    ]
    scheme = PERSON_NAME_SCHEMES.get(event.settings.name_scheme)
    for n, l, w in scheme['fields']:
        default.append(InvoiceAddressNamePart(event, n, l))
    default += [
        InvoiceAddressStreet(event),
        InvoiceAddressZip(event),
        InvoiceAddressCity(event),
        InvoiceAddressCountry(event),
        InvoiceAddressState(event),
        InvoiceAddressVATID(event),
        InvoiceAddressReference(event),
    ]
    for n, l, w in scheme['fields']:
        default.append(AttendeeNamePart(event, n, l))
    default += [
        AttendeeEmail(event),
        AttendeeCompany(event),
        AttendeeStreet(event),
        AttendeeZip(event),
        AttendeeCity(event),
        AttendeeCountry(event),
        AttendeeState(event),
        Price(event),
        Secret(event),
        Locale(event),
        Saleschannel(event),
        SeatColumn(event),
        Comment(event)
    ]
    for q in event.questions.prefetch_related('options').exclude(
            type=Question.TYPE_FILE):
        default.append(QuestionColumn(event, q))

    for recv, resp in order_import_columns.send(sender=event):
        default += resp

    return default
Exemple #8
0
    def _perform_operations(self):
        vouchers_ok = self._get_voucher_availability()
        quotas_ok = self._get_quota_availability()
        err = None
        new_cart_positions = []

        err = err or self._check_min_per_product()

        self._operations.sort(key=lambda a: self.order[type(a)])

        for op in self._operations:
            if isinstance(op, self.RemoveOperation):
                if op.position.expires > self.now_dt:
                    for q in op.position.quotas:
                        quotas_ok[q] += 1
                op.position.addons.all().delete()
                op.position.delete()

            elif isinstance(op, self.AddOperation) or isinstance(op, self.ExtendOperation):
                # Create a CartPosition for as much items as we can
                requested_count = quota_available_count = voucher_available_count = op.count

                if op.quotas:
                    quota_available_count = min(requested_count, min(quotas_ok[q] for q in op.quotas))

                if op.voucher:
                    voucher_available_count = min(voucher_available_count, vouchers_ok[op.voucher])

                if quota_available_count < 1:
                    err = err or error_messages['unavailable']
                elif quota_available_count < requested_count:
                    err = err or error_messages['in_part']

                if voucher_available_count < 1:
                    if op.voucher in self._voucher_depend_on_cart:
                        err = err or error_messages['voucher_redeemed_cart'] % self.event.settings.reservation_time
                    else:
                        err = err or error_messages['voucher_redeemed']
                elif voucher_available_count < requested_count:
                    err = err or error_messages['voucher_redeemed_partial'] % voucher_available_count

                available_count = min(quota_available_count, voucher_available_count)

                for q in op.quotas:
                    quotas_ok[q] -= available_count
                if op.voucher:
                    vouchers_ok[op.voucher] -= available_count

                if isinstance(op, self.AddOperation):
                    for k in range(available_count):
                        cp = CartPosition(
                            event=self.event, item=op.item, variation=op.variation,
                            price=op.price.gross, expires=self._expiry, cart_id=self.cart_id,
                            voucher=op.voucher, addon_to=op.addon_to if op.addon_to else None,
                            subevent=op.subevent, includes_tax=op.includes_tax
                        )
                        if self.event.settings.attendee_names_asked:
                            scheme = PERSON_NAME_SCHEMES.get(self.event.settings.name_scheme)
                            if 'attendee-name' in self._widget_data:
                                cp.attendee_name_parts = {'_legacy': self._widget_data['attendee-name']}
                            if any('attendee-name-{}'.format(k.replace('_', '-')) in self._widget_data for k, l, w
                                   in scheme['fields']):
                                cp.attendee_name_parts = {
                                    k: self._widget_data.get('attendee-name-{}'.format(k.replace('_', '-')), '')
                                    for k, l, w in scheme['fields']
                                }
                        if self.event.settings.attendee_emails_asked and 'email' in self._widget_data:
                            cp.attendee_email = self._widget_data.get('email')

                        cp._answers = {}
                        for k, v in self._widget_data.items():
                            if not k.startswith('question-'):
                                continue
                            q = cp.item.questions.filter(ask_during_checkin=False, identifier__iexact=k[9:]).first()
                            if q:
                                try:
                                    cp._answers[q] = q.clean_answer(v)
                                except ValidationError:
                                    pass

                        new_cart_positions.append(cp)
                elif isinstance(op, self.ExtendOperation):
                    if available_count == 1:
                        op.position.expires = self._expiry
                        op.position.price = op.price.gross
                        op.position.save()
                    elif available_count == 0:
                        op.position.delete()
                    else:
                        raise AssertionError("ExtendOperation cannot affect more than one item")

        for p in new_cart_positions:
            if p._answers:
                p.save()
                _save_answers(p, {}, p._answers)
        CartPosition.objects.bulk_create([p for p in new_cart_positions if not p._answers])
        return err
Exemple #9
0
    def _perform_operations(self):
        vouchers_ok = self._get_voucher_availability()
        quotas_ok = self._get_quota_availability()
        err = None
        new_cart_positions = []

        err = err or self._check_min_per_product()

        self._operations.sort(key=lambda a: self.order[type(a)])

        for op in self._operations:
            if isinstance(op, self.RemoveOperation):
                if op.position.expires > self.now_dt:
                    for q in op.position.quotas:
                        quotas_ok[q] += 1
                op.position.addons.all().delete()
                op.position.delete()

            elif isinstance(op, self.AddOperation) or isinstance(
                    op, self.ExtendOperation):
                # Create a CartPosition for as much items as we can
                requested_count = quota_available_count = voucher_available_count = op.count

                if op.quotas:
                    quota_available_count = min(
                        requested_count, min(quotas_ok[q] for q in op.quotas))

                if op.voucher:
                    voucher_available_count = min(voucher_available_count,
                                                  vouchers_ok[op.voucher])

                if quota_available_count < 1:
                    err = err or error_messages['unavailable']
                elif quota_available_count < requested_count:
                    err = err or error_messages['in_part']

                if voucher_available_count < 1:
                    if op.voucher in self._voucher_depend_on_cart:
                        err = err or error_messages[
                            'voucher_redeemed_cart'] % self.event.settings.reservation_time
                    else:
                        err = err or error_messages['voucher_redeemed']
                elif voucher_available_count < requested_count:
                    err = err or error_messages[
                        'voucher_redeemed_partial'] % voucher_available_count

                available_count = min(quota_available_count,
                                      voucher_available_count)

                for q in op.quotas:
                    quotas_ok[q] -= available_count
                if op.voucher:
                    vouchers_ok[op.voucher] -= available_count

                if isinstance(op, self.AddOperation):
                    for k in range(available_count):
                        cp = CartPosition(
                            event=self.event,
                            item=op.item,
                            variation=op.variation,
                            price=op.price.gross,
                            expires=self._expiry,
                            cart_id=self.cart_id,
                            voucher=op.voucher,
                            addon_to=op.addon_to if op.addon_to else None,
                            subevent=op.subevent,
                            includes_tax=op.includes_tax)
                        if self.event.settings.attendee_names_asked:
                            scheme = PERSON_NAME_SCHEMES.get(
                                self.event.settings.name_scheme)
                            if 'attendee-name' in self._widget_data:
                                cp.attendee_name_parts = {
                                    '_legacy':
                                    self._widget_data['attendee-name']
                                }
                            if any('attendee-name-{}'.format(
                                    k.replace('_', '-')) in self._widget_data
                                   for k, l, w in scheme['fields']):
                                cp.attendee_name_parts = {
                                    k: self._widget_data.get(
                                        'attendee-name-{}'.format(
                                            k.replace('_', '-')), '')
                                    for k, l, w in scheme['fields']
                                }
                        if self.event.settings.attendee_emails_asked and 'email' in self._widget_data:
                            cp.attendee_email = self._widget_data.get('email')

                        cp._answers = {}
                        for k, v in self._widget_data.items():
                            if not k.startswith('question-'):
                                continue
                            q = cp.item.questions.filter(
                                ask_during_checkin=False,
                                identifier__iexact=k[9:]).first()
                            if q:
                                try:
                                    cp._answers[q] = q.clean_answer(v)
                                except ValidationError:
                                    pass

                        new_cart_positions.append(cp)
                elif isinstance(op, self.ExtendOperation):
                    if available_count == 1:
                        op.position.expires = self._expiry
                        op.position.price = op.price.gross
                        op.position.save()
                    elif available_count == 0:
                        op.position.addons.all().delete()
                        op.position.delete()
                    else:
                        raise AssertionError(
                            "ExtendOperation cannot affect more than one item")

        for p in new_cart_positions:
            if p._answers:
                p.save()
                _save_answers(p, {}, p._answers)
        CartPosition.objects.bulk_create(
            [p for p in new_cart_positions if not p._answers])
        return err
Exemple #10
0
    def _perform_operations(self):
        vouchers_ok = self._get_voucher_availability()
        quotas_ok = self._get_quota_availability()
        err = None
        new_cart_positions = []

        err = err or self._check_min_per_product()

        self._operations.sort(key=lambda a: self.order[type(a)])

        for op in self._operations:
            if isinstance(op, self.RemoveOperation):
                if op.position.expires > self.now_dt:
                    for q in op.position.quotas:
                        quotas_ok[q] += 1
                op.position.addons.all().delete()
                op.position.delete()

            elif isinstance(op, self.AddOperation) or isinstance(op, self.ExtendOperation):
                # Create a CartPosition for as much items as we can
                requested_count = quota_available_count = voucher_available_count = op.count

                if op.quotas:
                    quota_available_count = min(requested_count, min(quotas_ok[q] for q in op.quotas))

                if op.voucher:
                    voucher_available_count = min(voucher_available_count, vouchers_ok[op.voucher])

                if quota_available_count < 1:
                    err = err or error_messages['unavailable']
                elif quota_available_count < requested_count:
                    err = err or error_messages['in_part']

                if voucher_available_count < 1:
                    if op.voucher in self._voucher_depend_on_cart:
                        err = err or error_messages['voucher_redeemed_cart'] % self.event.settings.reservation_time
                    else:
                        err = err or error_messages['voucher_redeemed']
                elif voucher_available_count < requested_count:
                    err = err or error_messages['voucher_redeemed_partial'] % voucher_available_count

                available_count = min(quota_available_count, voucher_available_count)

                if isinstance(op, self.AddOperation):
                    for b in op.bundled:
                        b_quota_available_count = min(available_count * b.count, min(quotas_ok[q] for q in b.quotas))
                        if b_quota_available_count < b.count:
                            err = err or error_messages['unavailable']
                            available_count = 0
                        elif b_quota_available_count < available_count * b.count:
                            err = err or error_messages['in_part']
                            available_count = b_quota_available_count // b.count
                        for q in b.quotas:
                            quotas_ok[q] -= available_count * b.count
                            # TODO: is this correct?

                for q in op.quotas:
                    quotas_ok[q] -= available_count
                if op.voucher:
                    vouchers_ok[op.voucher] -= available_count

                if any(qa < 0 for qa in quotas_ok.values()):
                    # Safeguard, shouldn't happen
                    err = err or error_messages['unavailable']
                    available_count = 0

                if isinstance(op, self.AddOperation):
                    for k in range(available_count):
                        cp = CartPosition(
                            event=self.event, item=op.item, variation=op.variation,
                            price=op.price.gross, expires=self._expiry, cart_id=self.cart_id,
                            voucher=op.voucher, addon_to=op.addon_to if op.addon_to else None,
                            subevent=op.subevent, includes_tax=op.includes_tax
                        )
                        if self.event.settings.attendee_names_asked:
                            scheme = PERSON_NAME_SCHEMES.get(self.event.settings.name_scheme)
                            if 'attendee-name' in self._widget_data:
                                cp.attendee_name_parts = {'_legacy': self._widget_data['attendee-name']}
                            if any('attendee-name-{}'.format(k.replace('_', '-')) in self._widget_data for k, l, w
                                   in scheme['fields']):
                                cp.attendee_name_parts = {
                                    k: self._widget_data.get('attendee-name-{}'.format(k.replace('_', '-')), '')
                                    for k, l, w in scheme['fields']
                                }
                        if self.event.settings.attendee_emails_asked and 'email' in self._widget_data:
                            cp.attendee_email = self._widget_data.get('email')

                        cp._answers = {}
                        for k, v in self._widget_data.items():
                            if not k.startswith('question-'):
                                continue
                            q = cp.item.questions.filter(ask_during_checkin=False, identifier__iexact=k[9:]).first()
                            if q:
                                try:
                                    cp._answers[q] = q.clean_answer(v)
                                except ValidationError:
                                    pass

                        if op.bundled:
                            cp.save()  # Needs to be in the database already so we have a PK that we can reference
                            for b in op.bundled:
                                for j in range(b.count):
                                    new_cart_positions.append(CartPosition(
                                        event=self.event, item=b.item, variation=b.variation,
                                        price=b.price.gross, expires=self._expiry, cart_id=self.cart_id,
                                        voucher=None, addon_to=cp,
                                        subevent=b.subevent, includes_tax=b.includes_tax, is_bundled=True
                                    ))

                        new_cart_positions.append(cp)
                elif isinstance(op, self.ExtendOperation):
                    if available_count == 1:
                        op.position.expires = self._expiry
                        op.position.price = op.price.gross
                        try:
                            op.position.save(force_update=True)
                        except DatabaseError:
                            # Best effort... The position might have been deleted in the meantime!
                            pass
                    elif available_count == 0:
                        op.position.addons.all().delete()
                        op.position.delete()
                    else:
                        raise AssertionError("ExtendOperation cannot affect more than one item")

        for p in new_cart_positions:
            if getattr(p, '_answers', None):
                if not p.pk:  # We stored some to the database already before
                    p.save()
                _save_answers(p, {}, p._answers)
        CartPosition.objects.bulk_create([p for p in new_cart_positions if not getattr(p, '_answers', None) and not p.pk])
        return err