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() ]
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
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
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
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()]
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
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
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
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
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