Esempio n. 1
0
def _perform_order(event: str, payment_provider: str, position_ids: List[str],
                   email: str, locale: str, address: int, meta_info: dict=None):

    event = Event.objects.get(id=event)
    responses = register_payment_providers.send(event)
    pprov = None
    for rec, response in responses:
        provider = response(event)
        if provider.identifier == payment_provider:
            pprov = provider
    if not pprov:
        raise OrderError(error_messages['internal'])

    with event.lock() as now_dt:
        positions = list(CartPosition.objects.filter(
            id__in=position_ids).select_related('item', 'variation'))
        if len(positions) == 0:
            raise OrderError(error_messages['empty'])
        if len(position_ids) != len(positions):
            raise OrderError(error_messages['internal'])
        _check_positions(event, now_dt, positions)
        order = _create_order(event, email, positions, now_dt, pprov,
                              locale=locale, address=address, meta_info=meta_info)

    if event.settings.get('invoice_generate') == 'True' and invoice_qualified(order):
        if not order.invoices.exists():
            generate_invoice(order)

    if order.total == Decimal('0.00'):
        mailtext = event.settings.mail_text_order_free
    else:
        mailtext = event.settings.mail_text_order_placed

    try:
        invoice_name = order.invoice_address.name
        invoice_company = order.invoice_address.company
    except InvoiceAddress.DoesNotExist:
        invoice_name = ""
        invoice_company = ""

    mail(
        order.email, _('Your order: %(code)s') % {'code': order.code},
        mailtext,
        {
            'total': LazyNumber(order.total),
            'currency': event.currency,
            'date': LazyDate(order.expires),
            'event': event.name,
            'url': build_absolute_uri(event, 'presale:event.order', kwargs={
                'order': order.code,
                'secret': order.secret
            }),
            'paymentinfo': str(pprov.order_pending_mail_render(order)),
            'invoice_name': invoice_name,
            'invoice_company': invoice_company,
        },
        event, locale=order.locale
    )

    return order.id
Esempio n. 2
0
def _perform_order(event: str, payment_provider: str, position_ids: List[str],
                   email: str, locale: str, address: int, meta_info: dict=None):

    event = Event.objects.get(id=event)
    pprov = event.get_payment_providers().get(payment_provider)
    if not pprov:
        raise OrderError(error_messages['internal'])

    with event.lock() as now_dt:
        positions = list(CartPosition.objects.filter(
            id__in=position_ids).select_related('item', 'variation', 'subevent'))
        if len(positions) == 0:
            raise OrderError(error_messages['empty'])
        if len(position_ids) != len(positions):
            raise OrderError(error_messages['internal'])
        _check_positions(event, now_dt, positions)
        order = _create_order(event, email, positions, now_dt, pprov,
                              locale=locale, address=address, meta_info=meta_info)

    if event.settings.get('invoice_generate') == 'True' and invoice_qualified(order):
        if not order.invoices.exists():
            generate_invoice(order)

    if order.total == Decimal('0.00'):
        email_template = event.settings.mail_text_order_free
        log_entry = 'pretix.event.order.email.order_free'
    else:
        email_template = event.settings.mail_text_order_placed
        log_entry = 'pretix.event.order.email.order_placed'

    try:
        invoice_name = order.invoice_address.name
        invoice_company = order.invoice_address.company
    except InvoiceAddress.DoesNotExist:
        invoice_name = ""
        invoice_company = ""
    email_context = {
        'total': LazyNumber(order.total),
        'currency': event.currency,
        'date': LazyDate(order.expires),
        'event': event.name,
        'url': build_absolute_uri(event, 'presale:event.order', kwargs={
            'order': order.code,
            'secret': order.secret
        }),
        'payment_info': str(pprov.order_pending_mail_render(order)),
        'invoice_name': invoice_name,
        'invoice_company': invoice_company,
    }
    email_subject = _('Your order: %(code)s') % {'code': order.code}
    try:
        order.send_mail(
            email_subject, email_template, email_context,
            log_entry
        )
    except SendMailException:
        logger.exception('Order received email could not be sent')

    return order.id
Esempio n. 3
0
def _perform_order(event: str, payment_provider: str, position_ids: List[str],
                   email: str, locale: str):
    event = Event.objects.get(id=event)
    responses = register_payment_providers.send(event)
    pprov = None
    for receiver, response in responses:
        provider = response(event)
        if provider.identifier == payment_provider:
            pprov = provider
    if not pprov:
        raise OrderError(error_messages['internal'])

    dt = now()
    with event.lock():
        positions = list(
            CartPosition.objects.filter(id__in=position_ids).select_related(
                'item', 'variation'))
        if len(position_ids) != len(positions):
            raise OrderError(error_messages['internal'])
        _check_positions(event, dt, positions)
        order = _create_order(event,
                              email,
                              positions,
                              dt,
                              pprov,
                              locale=locale)

    mail(order.email,
         _('Your order: %(code)s') % {'code': order.code},
         event.settings.mail_text_order_placed, {
             'total':
             LazyNumber(order.total),
             'currency':
             event.currency,
             'date':
             LazyDate(order.expires),
             'event':
             event.name,
             'url':
             build_absolute_uri(event,
                                'presale:event.order',
                                kwargs={
                                    'order': order.code,
                                    'secret': order.secret
                                }),
             'paymentinfo':
             str(pprov.order_pending_mail_render(order))
         },
         event,
         locale=order.locale)
    return order.id
Esempio n. 4
0
def base_placeholders(sender, **kwargs):
    from pretix.base.models import InvoiceAddress
    from pretix.multidomain.urlreverse import build_absolute_uri

    ph = [
        SimpleFunctionalMailTextPlaceholder('event', ['event'],
                                            lambda event: event.name,
                                            lambda event: event.name),
        SimpleFunctionalMailTextPlaceholder(
            'event', ['event_or_subevent'],
            lambda event_or_subevent: event_or_subevent.name,
            lambda event_or_subevent: event_or_subevent.name),
        SimpleFunctionalMailTextPlaceholder('event_slug', ['event'],
                                            lambda event: event.slug,
                                            lambda event: event.slug),
        SimpleFunctionalMailTextPlaceholder('code', ['order'],
                                            lambda order: order.code, 'F8VVL'),
        SimpleFunctionalMailTextPlaceholder(
            'total', ['order'], lambda order: LazyNumber(order.total),
            lambda event: LazyNumber(Decimal('42.23'))),
        SimpleFunctionalMailTextPlaceholder('currency', ['event'],
                                            lambda event: event.currency,
                                            lambda event: event.currency),
        SimpleFunctionalMailTextPlaceholder(
            'refund_amount', ['event_or_subevent', 'refund_amount'],
            lambda event_or_subevent, refund_amount: LazyCurrencyNumber(
                refund_amount, event_or_subevent.currency),
            lambda event_or_subevent: LazyCurrencyNumber(
                Decimal('42.23'), event_or_subevent.currency)),
        SimpleFunctionalMailTextPlaceholder(
            'total_with_currency',
            ['event', 'order'], lambda event, order: LazyCurrencyNumber(
                order.total, event.currency), lambda event: LazyCurrencyNumber(
                    Decimal('42.23'), event.currency)),
        SimpleFunctionalMailTextPlaceholder(
            'expire_date', ['event', 'order'], lambda event, order: LazyDate(
                order.expires.astimezone(event.timezone)),
            lambda event: LazyDate(now() + timedelta(days=15))
            # TODO: This used to be "date" in some placeholders, add a migration!
        ),
        SimpleFunctionalMailTextPlaceholder(
            'url',
            ['order', 'event'],
            lambda order, event: build_absolute_uri(
                event,
                'presale:event.order.open',
                kwargs={
                    'order': order.code,
                    'secret': order.secret,
                    'hash': order.email_confirm_hash()
                }),
            lambda event: build_absolute_uri(event,
                                             'presale:event.order.open',
                                             kwargs={
                                                 'order': 'F8VVL',
                                                 'secret': '6zzjnumtsx136ddy',
                                                 'hash': '98kusd8ofsj8dnkd'
                                             }),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'url_info_change',
            ['order', 'event'],
            lambda order, event: build_absolute_uri(
                event,
                'presale:event.order.modify',
                kwargs={
                    'order': order.code,
                    'secret': order.secret,
                }),
            lambda event: build_absolute_uri(event,
                                             'presale:event.order.modify',
                                             kwargs={
                                                 'order': 'F8VVL',
                                                 'secret': '6zzjnumtsx136ddy',
                                             }),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'url_products_change',
            ['order', 'event'],
            lambda order, event: build_absolute_uri(
                event,
                'presale:event.order.change',
                kwargs={
                    'order': order.code,
                    'secret': order.secret,
                }),
            lambda event: build_absolute_uri(event,
                                             'presale:event.order.change',
                                             kwargs={
                                                 'order': 'F8VVL',
                                                 'secret': '6zzjnumtsx136ddy',
                                             }),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'url_cancel',
            ['order', 'event'],
            lambda order, event: build_absolute_uri(
                event,
                'presale:event.order.cancel',
                kwargs={
                    'order': order.code,
                    'secret': order.secret,
                }),
            lambda event: build_absolute_uri(event,
                                             'presale:event.order.cancel',
                                             kwargs={
                                                 'order': 'F8VVL',
                                                 'secret': '6zzjnumtsx136ddy',
                                             }),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'url',
            ['event', 'position'],
            lambda event, position: build_absolute_uri(
                event,
                'presale:event.order.position',
                kwargs={
                    'order': position.order.code,
                    'secret': position.web_secret,
                    'position': position.positionid
                }),
            lambda event: build_absolute_uri(event,
                                             'presale:event.order.position',
                                             kwargs={
                                                 'order': 'F8VVL',
                                                 'secret': '6zzjnumtsx136ddy',
                                                 'position': '123'
                                             }),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'url',
            ['waiting_list_entry', 'event'],
            lambda waiting_list_entry, event: build_absolute_uri(
                event, 'presale:event.redeem') + '?voucher=' +
            waiting_list_entry.voucher.code,
            lambda event: build_absolute_uri(
                event,
                'presale:event.redeem',
            ) + '?voucher=68CYU2H6ZTP3WLK5',
        ),
        SimpleFunctionalMailTextPlaceholder(
            'invoice_name', ['invoice_address'],
            lambda invoice_address: invoice_address.name or '', _('John Doe')),
        SimpleFunctionalMailTextPlaceholder(
            'invoice_company', ['invoice_address'],
            lambda invoice_address: invoice_address.company or '',
            _('Sample Corporation')),
        SimpleFunctionalMailTextPlaceholder(
            'orders',
            ['event', 'orders'],
            lambda event, orders: '\n' + '\n\n'.join('* {} - {}'.format(
                order.full_code,
                build_absolute_uri(event,
                                   'presale:event.order',
                                   kwargs={
                                       'event': event.slug,
                                       'organizer': event.organizer.slug,
                                       'order': order.code,
                                       'secret': order.secret
                                   }),
            ) for order in orders),
            lambda event: '\n' + '\n\n'.join('* {} - {}'.format(
                '{}-{}'.format(event.slug.upper(), order['code']),
                build_absolute_uri(event,
                                   'presale:event.order',
                                   kwargs={
                                       'event': event.slug,
                                       'organizer': event.organizer.slug,
                                       'order': order['code'],
                                       'secret': order['secret']
                                   }),
            ) for order in [{
                'code': 'F8VVL',
                'secret': '6zzjnumtsx136ddy'
            }, {
                'code': 'HIDHK',
                'secret': '98kusd8ofsj8dnkd'
            }, {
                'code': 'OPKSB',
                'secret': '09pjdksflosk3njd'
            }]),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'hours', ['event', 'waiting_list_entry'], lambda event,
            waiting_list_entry: event.settings.waiting_list_hours,
            lambda event: event.settings.waiting_list_hours),
        SimpleFunctionalMailTextPlaceholder(
            'product', ['waiting_list_entry'],
            lambda waiting_list_entry: waiting_list_entry.item.name,
            _('Sample Admission Ticket')),
        SimpleFunctionalMailTextPlaceholder(
            'code', ['waiting_list_entry'],
            lambda waiting_list_entry: waiting_list_entry.voucher.code,
            '68CYU2H6ZTP3WLK5'),
        SimpleFunctionalMailTextPlaceholder(
            'voucher_list', ['voucher_list'],
            lambda voucher_list: '\n'.join(voucher_list),
            '    68CYU2H6ZTP3WLK5\n    7MB94KKPVEPSMVF2'),
        SimpleFunctionalMailTextPlaceholder(
            'url', ['event', 'voucher_list'], lambda event, voucher_list:
            build_absolute_uri(event,
                               'presale:event.index',
                               kwargs={
                                   'event': event.slug,
                                   'organizer': event.organizer.slug,
                               }), lambda event: build_absolute_uri(
                                   event,
                                   'presale:event.index',
                                   kwargs={
                                       'event': event.slug,
                                       'organizer': event.organizer.slug,
                                   })),
        SimpleFunctionalMailTextPlaceholder('name', ['name'],
                                            lambda name: name, _('John Doe')),
        SimpleFunctionalMailTextPlaceholder(
            'comment',
            ['comment'],
            lambda comment: comment,
            _('An individual text with a reason can be inserted here.'),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'payment_info',
            ['order', 'payment'],
            _placeholder_payment,
            _('The amount has been charged to your card.'),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'payment_info',
            ['payment_info'],
            lambda payment_info: payment_info,
            _('Please transfer money to this bank account: 9999-9999-9999-9999'
              ),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'attendee_name',
            ['position'],
            lambda position: position.attendee_name,
            _('John Doe'),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'name',
            ['position_or_address'],
            lambda position_or_address:
            (position_or_address.name
             if isinstance(position_or_address, InvoiceAddress) else
             position_or_address.attendee_name),
            _('John Doe'),
        ),
    ]

    name_scheme = PERSON_NAME_SCHEMES[sender.settings.name_scheme]
    for f, l, w in name_scheme['fields']:
        if f == 'full_name':
            continue
        ph.append(
            SimpleFunctionalMailTextPlaceholder(
                'attendee_name_%s' % f, ['position'],
                lambda position, f=f: position.attendee_name_parts.get(f, ''),
                name_scheme['sample'][f]))
        ph.append(
            SimpleFunctionalMailTextPlaceholder(
                'name_%s' % f, ['position_or_address'],
                lambda position_or_address, f=f:
                (position_or_address.name_parts.get(f, '')
                 if isinstance(position_or_address, InvoiceAddress) else
                 position_or_address.attendee_name_parts.get(f, '')),
                name_scheme['sample'][f]))

    for k, v in sender.meta_data.items():
        ph.append(
            SimpleFunctionalMailTextPlaceholder(
                'meta_%s' % k, ['event'],
                lambda event, k=k: event.meta_data[k],
                v))

    return ph
Esempio n. 5
0
def base_placeholders(sender, **kwargs):
    from pretix.multidomain.urlreverse import build_absolute_uri

    ph = [
        SimpleFunctionalMailTextPlaceholder('event', ['event'],
                                            lambda event: event.name,
                                            lambda event: event.name),
        SimpleFunctionalMailTextPlaceholder(
            'event', ['event_or_subevent'],
            lambda event_or_subevent: event_or_subevent.name,
            lambda event_or_subevent: event_or_subevent.name),
        SimpleFunctionalMailTextPlaceholder('event_slug', ['event'],
                                            lambda event: event.slug,
                                            lambda event: event.slug),
        SimpleFunctionalMailTextPlaceholder('code', ['order'],
                                            lambda order: order.code, 'F8VVL'),
        SimpleFunctionalMailTextPlaceholder(
            'total', ['order'], lambda order: LazyNumber(order.total),
            lambda event: LazyNumber(Decimal('42.23'))),
        SimpleFunctionalMailTextPlaceholder('currency', ['event'],
                                            lambda event: event.currency,
                                            lambda event: event.currency),
        SimpleFunctionalMailTextPlaceholder(
            'refund_amount', ['event_or_subevent', 'refund_amount'],
            lambda event_or_subevent, refund_amount: LazyCurrencyNumber(
                refund_amount, event_or_subevent.currency),
            lambda event_or_subevent: LazyCurrencyNumber(
                Decimal('42.23'), event_or_subevent.currency)),
        SimpleFunctionalMailTextPlaceholder(
            'total_with_currency',
            ['event', 'order'], lambda event, order: LazyCurrencyNumber(
                order.total, event.currency), lambda event: LazyCurrencyNumber(
                    Decimal('42.23'), event.currency)),
        SimpleFunctionalMailTextPlaceholder(
            'expire_date', ['event', 'order'],
            lambda event, order: LazyExpiresDate(
                order.expires.astimezone(event.timezone)),
            lambda event: LazyDate(now() + timedelta(days=15))),
        SimpleFunctionalMailTextPlaceholder(
            'url',
            ['order', 'event'],
            lambda order, event: build_absolute_uri(
                event,
                'presale:event.order.open',
                kwargs={
                    'order': order.code,
                    'secret': order.secret,
                    'hash': order.email_confirm_hash()
                }),
            lambda event: build_absolute_uri(event,
                                             'presale:event.order.open',
                                             kwargs={
                                                 'order': 'F8VVL',
                                                 'secret': '6zzjnumtsx136ddy',
                                                 'hash': '98kusd8ofsj8dnkd'
                                             }),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'url_info_change',
            ['order', 'event'],
            lambda order, event: build_absolute_uri(
                event,
                'presale:event.order.modify',
                kwargs={
                    'order': order.code,
                    'secret': order.secret,
                }),
            lambda event: build_absolute_uri(event,
                                             'presale:event.order.modify',
                                             kwargs={
                                                 'order': 'F8VVL',
                                                 'secret': '6zzjnumtsx136ddy',
                                             }),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'url_products_change',
            ['order', 'event'],
            lambda order, event: build_absolute_uri(
                event,
                'presale:event.order.change',
                kwargs={
                    'order': order.code,
                    'secret': order.secret,
                }),
            lambda event: build_absolute_uri(event,
                                             'presale:event.order.change',
                                             kwargs={
                                                 'order': 'F8VVL',
                                                 'secret': '6zzjnumtsx136ddy',
                                             }),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'url_cancel',
            ['order', 'event'],
            lambda order, event: build_absolute_uri(
                event,
                'presale:event.order.cancel',
                kwargs={
                    'order': order.code,
                    'secret': order.secret,
                }),
            lambda event: build_absolute_uri(event,
                                             'presale:event.order.cancel',
                                             kwargs={
                                                 'order': 'F8VVL',
                                                 'secret': '6zzjnumtsx136ddy',
                                             }),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'url',
            ['event', 'position'],
            lambda event, position: build_absolute_uri(
                event,
                'presale:event.order.position',
                kwargs={
                    'order': position.order.code,
                    'secret': position.web_secret,
                    'position': position.positionid
                }),
            lambda event: build_absolute_uri(event,
                                             'presale:event.order.position',
                                             kwargs={
                                                 'order': 'F8VVL',
                                                 'secret': '6zzjnumtsx136ddy',
                                                 'position': '123'
                                             }),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'event_location',
            ['event_or_subevent'],
            lambda event_or_subevent: str(event_or_subevent.location or ''),
            lambda event: str(event.location or ''),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'event_admission_time',
            ['event_or_subevent'],
            lambda event_or_subevent: date_format(
                event_or_subevent.date_admission, 'TIME_FORMAT')
            if event_or_subevent.date_admission else '',
            lambda event: date_format(event.date_admission, 'TIME_FORMAT')
            if event.date_admission else '',
        ),
        SimpleFunctionalMailTextPlaceholder(
            'subevent', ['waiting_list_entry', 'event'],
            lambda waiting_list_entry, event: str(waiting_list_entry.subevent
                                                  or event),
            lambda event: str(event
                              if not event.has_subevents or not event.subevents
                              .exists() else event.subevents.first())),
        SimpleFunctionalMailTextPlaceholder(
            'subevent_date_from', ['waiting_list_entry', 'event'],
            lambda waiting_list_entry, event:
            (waiting_list_entry.subevent or event).get_date_from_display(),
            lambda event:
            (event if not event.has_subevents or not event.subevents.exists()
             else event.subevents.first()).get_date_from_display()),
        SimpleFunctionalMailTextPlaceholder(
            'url_remove',
            ['waiting_list_entry', 'event'],
            lambda waiting_list_entry, event: build_absolute_uri(
                event, 'presale:event.waitinglist.remove') + '?voucher=' +
            waiting_list_entry.voucher.code,
            lambda event: build_absolute_uri(
                event,
                'presale:event.waitinglist.remove',
            ) + '?voucher=68CYU2H6ZTP3WLK5',
        ),
        SimpleFunctionalMailTextPlaceholder(
            'url',
            ['waiting_list_entry', 'event'],
            lambda waiting_list_entry, event: build_absolute_uri(
                event, 'presale:event.redeem') + '?voucher=' +
            waiting_list_entry.voucher.code,
            lambda event: build_absolute_uri(
                event,
                'presale:event.redeem',
            ) + '?voucher=68CYU2H6ZTP3WLK5',
        ),
        SimpleFunctionalMailTextPlaceholder(
            'invoice_name', ['invoice_address'],
            lambda invoice_address: invoice_address.name or '', _('John Doe')),
        SimpleFunctionalMailTextPlaceholder(
            'invoice_company', ['invoice_address'],
            lambda invoice_address: invoice_address.company or '',
            _('Sample Corporation')),
        SimpleFunctionalMailTextPlaceholder(
            'orders',
            ['event', 'orders'],
            lambda event, orders: '\n' + '\n\n'.join('* {} - {}'.format(
                order.full_code,
                build_absolute_uri(event,
                                   'presale:event.order.open',
                                   kwargs={
                                       'event': event.slug,
                                       'organizer': event.organizer.slug,
                                       'order': order.code,
                                       'secret': order.secret,
                                       'hash': order.email_confirm_hash(),
                                   }),
            ) for order in orders),
            lambda event: '\n' + '\n\n'.join('* {} - {}'.format(
                '{}-{}'.format(event.slug.upper(), order['code']),
                build_absolute_uri(event,
                                   'presale:event.order.open',
                                   kwargs={
                                       'event': event.slug,
                                       'organizer': event.organizer.slug,
                                       'order': order['code'],
                                       'secret': order['secret'],
                                       'hash': order['hash'],
                                   }),
            ) for order in [{
                'code': 'F8VVL',
                'secret': '6zzjnumtsx136ddy',
                'hash': 'abcdefghi'
            }, {
                'code': 'HIDHK',
                'secret': '98kusd8ofsj8dnkd',
                'hash': 'jklmnopqr'
            }, {
                'code': 'OPKSB',
                'secret': '09pjdksflosk3njd',
                'hash': 'stuvwxy2z'
            }]),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'hours', ['event', 'waiting_list_entry'], lambda event,
            waiting_list_entry: event.settings.waiting_list_hours,
            lambda event: event.settings.waiting_list_hours),
        SimpleFunctionalMailTextPlaceholder(
            'product', ['waiting_list_entry'],
            lambda waiting_list_entry: waiting_list_entry.item.name,
            _('Sample Admission Ticket')),
        SimpleFunctionalMailTextPlaceholder(
            'code', ['waiting_list_entry'],
            lambda waiting_list_entry: waiting_list_entry.voucher.code,
            '68CYU2H6ZTP3WLK5'),
        SimpleFunctionalMailTextPlaceholder(
            # join vouchers with two spaces at end of line so markdown-parser inserts a <br>
            'voucher_list',
            ['voucher_list'],
            lambda voucher_list: '  \n'.join(voucher_list),
            '    68CYU2H6ZTP3WLK5\n    7MB94KKPVEPSMVF2'),
        SimpleFunctionalMailTextPlaceholder(
            # join vouchers with two spaces at end of line so markdown-parser inserts a <br>
            'voucher_url_list',
            ['event', 'voucher_list'],
            lambda event, voucher_list: '  \n'.join([
                build_absolute_uri(event, 'presale:event.redeem') + '?voucher='
                + c for c in voucher_list
            ]),
            lambda event: '  \n'.join([
                build_absolute_uri(event, 'presale:event.redeem') + '?voucher='
                + c for c in ['68CYU2H6ZTP3WLK5', '7MB94KKPVEPSMVF2']
            ]),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'url', ['event', 'voucher_list'], lambda event, voucher_list:
            build_absolute_uri(event,
                               'presale:event.index',
                               kwargs={
                                   'event': event.slug,
                                   'organizer': event.organizer.slug,
                               }), lambda event: build_absolute_uri(
                                   event,
                                   'presale:event.index',
                                   kwargs={
                                       'event': event.slug,
                                       'organizer': event.organizer.slug,
                                   })),
        SimpleFunctionalMailTextPlaceholder('name', ['name'],
                                            lambda name: name, _('John Doe')),
        SimpleFunctionalMailTextPlaceholder(
            'comment',
            ['comment'],
            lambda comment: comment,
            _('An individual text with a reason can be inserted here.'),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'payment_info',
            ['order', 'payment'],
            _placeholder_payment,
            _('The amount has been charged to your card.'),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'payment_info',
            ['payment_info'],
            lambda payment_info: payment_info,
            _('Please transfer money to this bank account: 9999-9999-9999-9999'
              ),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'attendee_name',
            ['position'],
            lambda position: position.attendee_name,
            _('John Doe'),
        ),
        SimpleFunctionalMailTextPlaceholder(
            'name',
            ['position_or_address'],
            get_best_name,
            _('John Doe'),
        ),
    ]

    name_scheme = PERSON_NAME_SCHEMES[sender.settings.name_scheme]
    if "concatenation_for_salutation" in name_scheme:
        concatenation_for_salutation = name_scheme[
            "concatenation_for_salutation"]
    else:
        concatenation_for_salutation = name_scheme["concatenation"]

    ph.append(
        SimpleFunctionalMailTextPlaceholder(
            "name_for_salutation",
            ["position_or_address"],
            lambda position_or_address: concatenation_for_salutation(
                get_best_name(position_or_address, parts=True)),
            _("Mr Doe"),
        ))

    for f, l, w in name_scheme['fields']:
        if f == 'full_name':
            continue
        ph.append(
            SimpleFunctionalMailTextPlaceholder(
                'attendee_name_%s' % f, ['position'],
                lambda position, f=f: get_name_parts_localized(
                    position.attendee_name_parts, f),
                name_scheme['sample'][f]))
        ph.append(
            SimpleFunctionalMailTextPlaceholder(
                'name_%s' % f, ['position_or_address'],
                lambda position_or_address, f=f: get_name_parts_localized(
                    get_best_name(position_or_address, parts=True), f),
                name_scheme['sample'][f]))

    for k, v in sender.meta_data.items():
        ph.append(
            SimpleFunctionalMailTextPlaceholder(
                'meta_%s' % k, ['event'],
                lambda event, k=k: event.meta_data[k],
                v))
        ph.append(
            SimpleFunctionalMailTextPlaceholder(
                'meta_%s' % k, ['event_or_subevent'],
                lambda event_or_subevent, k=k: event_or_subevent.meta_data[k],
                v))

    return ph