mirror of
https://github.com/pretix/pretix.git
synced 2026-05-08 15:44:02 +00:00
* Fix #467 -- Pluggable email placeholders * Previews * Polishing * Fix tests * Add missing doc file
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
import json
|
||||
import re
|
||||
from collections import OrderedDict
|
||||
from datetime import timedelta
|
||||
from decimal import Decimal
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
@@ -18,7 +17,6 @@ from django.http import (
|
||||
from django.shortcuts import get_object_or_404, redirect
|
||||
from django.urls import reverse
|
||||
from django.utils import translation
|
||||
from django.utils.formats import date_format
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
@@ -29,7 +27,7 @@ from i18nfield.strings import LazyI18nString
|
||||
from pytz import timezone
|
||||
|
||||
from pretix.base.channels import get_all_sales_channels
|
||||
from pretix.base.i18n import LazyCurrencyNumber
|
||||
from pretix.base.email import get_available_placeholders
|
||||
from pretix.base.models import (
|
||||
Event, LogEntry, Order, RequiredAction, TaxRule, Voucher,
|
||||
)
|
||||
@@ -37,7 +35,6 @@ from pretix.base.models.event import EventMetaValue
|
||||
from pretix.base.services import tickets
|
||||
from pretix.base.services.invoices import build_preview_invoice_pdf
|
||||
from pretix.base.signals import register_ticket_outputs
|
||||
from pretix.base.templatetags.money import money_filter
|
||||
from pretix.base.templatetags.rich_text import markdown_compile_email
|
||||
from pretix.control.forms.event import (
|
||||
CancelSettingsForm, CommentForm, EventDeleteForm, EventMetaValueForm,
|
||||
@@ -48,7 +45,6 @@ from pretix.control.forms.event import (
|
||||
)
|
||||
from pretix.control.permissions import EventPermissionRequiredMixin
|
||||
from pretix.helpers.database import rolledback_transaction
|
||||
from pretix.helpers.urls import build_absolute_uri
|
||||
from pretix.multidomain.urlreverse import get_domain
|
||||
from pretix.plugins.stripe.payment import StripeSettingsHolder
|
||||
from pretix.presale.style import regenerate_css
|
||||
@@ -538,20 +534,6 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
|
||||
def __missing__(self, key):
|
||||
return '{' + key + '}'
|
||||
|
||||
@staticmethod
|
||||
def generate_order_fullname(slug, code):
|
||||
return '{event}-{code}'.format(event=slug.upper(), code=code)
|
||||
|
||||
# create data which depend on locale
|
||||
def localized_data(self):
|
||||
return {
|
||||
'date': date_format(now() + timedelta(days=7), 'SHORT_DATE_FORMAT'),
|
||||
'expire_date': date_format(now() + timedelta(days=15), 'SHORT_DATE_FORMAT'),
|
||||
'payment_info': _('{} has been transferred to account <9999-9999-9999-9999> at {}').format(
|
||||
money_filter(Decimal('42.23'), self.request.event.currency),
|
||||
date_format(now(), 'SHORT_DATETIME_FORMAT'))
|
||||
}
|
||||
|
||||
# create index-language mapping
|
||||
@cached_property
|
||||
def supported_locale(self):
|
||||
@@ -561,91 +543,23 @@ class MailSettingsPreview(EventPermissionRequiredMixin, View):
|
||||
locales[str(idx)] = val[0]
|
||||
return locales
|
||||
|
||||
@cached_property
|
||||
def meta_properties(self):
|
||||
return [p.name for p in self.request.organizer.meta_properties.all()]
|
||||
|
||||
@cached_property
|
||||
def items(self):
|
||||
kv = {
|
||||
'mail_text_order_placed': ['total', 'currency', 'date', 'invoice_company', 'total_with_currency',
|
||||
'event', 'payment_info', 'url', 'invoice_name'],
|
||||
'mail_text_order_placed_attendee': ['event', 'url', 'attendee_name'],
|
||||
'mail_text_order_paid': ['event', 'url', 'invoice_name', 'invoice_company', 'payment_info'],
|
||||
'mail_text_order_paid_attendee': ['event', 'url', 'attendee_name'],
|
||||
'mail_text_order_free': ['event', 'url', 'invoice_name', 'invoice_company'],
|
||||
'mail_text_order_free_attendee': ['event', 'url', 'attendee_name'],
|
||||
'mail_text_resend_link': ['event', 'url', 'invoice_name', 'invoice_company'],
|
||||
'mail_text_resend_all_links': ['event', 'orders'],
|
||||
'mail_text_order_changed': ['event', 'url', 'invoice_name', 'invoice_company'],
|
||||
'mail_text_order_expire_warning': ['event', 'url', 'expire_date', 'invoice_name', 'invoice_company'],
|
||||
'mail_text_waiting_list': ['event', 'url', 'product', 'hours', 'code'],
|
||||
'mail_text_order_canceled': ['code', 'event', 'url'],
|
||||
'mail_text_order_custom_mail': ['expire_date', 'event', 'code', 'date', 'url',
|
||||
'invoice_name', 'invoice_company'],
|
||||
'mail_text_download_reminder': ['event', 'url'],
|
||||
'mail_text_download_reminder_attendee': ['attendee_name', 'event', 'url'],
|
||||
'mail_text_order_placed_require_approval': ['total', 'currency', 'date', 'invoice_company',
|
||||
'total_with_currency', 'event', 'url', 'invoice_name'],
|
||||
'mail_text_order_approved': ['total', 'currency', 'date', 'invoice_company',
|
||||
'total_with_currency', 'event', 'url', 'invoice_name'],
|
||||
'mail_text_order_denied': ['total', 'currency', 'date', 'invoice_company',
|
||||
'total_with_currency', 'event', 'url', 'invoice_name'],
|
||||
}
|
||||
for v in kv.values():
|
||||
for p in self.meta_properties:
|
||||
v.append('meta_' + p)
|
||||
return kv
|
||||
|
||||
@cached_property
|
||||
def base_data(self):
|
||||
user_orders = [
|
||||
{'code': 'F8VVL', 'secret': '6zzjnumtsx136ddy'},
|
||||
{'code': 'HIDHK', 'secret': '98kusd8ofsj8dnkd'},
|
||||
{'code': 'OPKSB', 'secret': '09pjdksflosk3njd'}
|
||||
]
|
||||
orders = [' - {} - {}'.format(self.generate_order_fullname(self.request.event.slug, order['code']),
|
||||
self.generate_order_url(order['code'], order['secret']))
|
||||
for order in user_orders]
|
||||
d = {
|
||||
'event': self.request.event.name,
|
||||
'total': 42.23,
|
||||
'total_with_currency': LazyCurrencyNumber(42.23, self.request.event.currency),
|
||||
'currency': self.request.event.currency,
|
||||
'url': self.generate_order_url(user_orders[0]['code'], user_orders[0]['secret']),
|
||||
'orders': '\n'.join(orders),
|
||||
'hours': self.request.event.settings.waiting_list_hours,
|
||||
'product': _('Sample Admission Ticket'),
|
||||
'code': '68CYU2H6ZTP3WLK5',
|
||||
'invoice_name': _('John Doe'),
|
||||
'invoice_company': _('Sample Corporation'),
|
||||
'common': _('An individual text with a reason can be inserted here.'),
|
||||
'payment_info': _('Please transfer money to this bank account: 9999-9999-9999-9999'),
|
||||
'attendee_name': _('John Doe'),
|
||||
}
|
||||
for k, v in self.request.event.meta_data.items():
|
||||
d['meta_' + k] = v
|
||||
return d
|
||||
|
||||
def generate_order_url(self, code, secret):
|
||||
return build_absolute_uri('presale:event.order', kwargs={
|
||||
'event': self.request.event.slug,
|
||||
'organizer': self.request.event.organizer.slug,
|
||||
'order': code,
|
||||
'secret': secret
|
||||
})
|
||||
|
||||
# get all supported placeholders with dummy values
|
||||
def placeholders(self, item):
|
||||
supported = {}
|
||||
local_data = self.localized_data()
|
||||
for key in self.items.get(item):
|
||||
supported[key] = self.base_data.get(key) if key in self.base_data else local_data.get(key)
|
||||
return self.SafeDict(supported)
|
||||
ctx = {}
|
||||
for p in get_available_placeholders(self.request.event, MailSettingsForm.base_context[item]).values():
|
||||
s = str(p.render_sample(self.request.event))
|
||||
if s.strip().startswith('*'):
|
||||
ctx[p.identifier] = s
|
||||
else:
|
||||
ctx[p.identifier] = '<span class="placeholder" title="{}">{}</span>'.format(
|
||||
_('This value will be replaced based on dynamic parameters.'),
|
||||
s
|
||||
)
|
||||
return self.SafeDict(ctx)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
preview_item = request.POST.get('item', '')
|
||||
if preview_item not in self.items:
|
||||
if preview_item not in MailSettingsForm.base_context:
|
||||
return HttpResponseBadRequest(_('invalid item'))
|
||||
|
||||
regex = r"^" + re.escape(preview_item) + r"_(?P<idx>[\d+])$"
|
||||
|
||||
@@ -6,7 +6,6 @@ import re
|
||||
from datetime import datetime, time, timedelta
|
||||
from decimal import Decimal, DecimalException
|
||||
|
||||
import pytz
|
||||
import vat_moss.id
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
@@ -21,7 +20,6 @@ from django.http import (
|
||||
from django.shortcuts import get_object_or_404, redirect, render
|
||||
from django.urls import reverse
|
||||
from django.utils import formats
|
||||
from django.utils.formats import date_format
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.http import is_safe_url
|
||||
from django.utils.timezone import make_aware, now
|
||||
@@ -32,6 +30,7 @@ from django.views.generic import (
|
||||
from i18nfield.strings import LazyI18nString
|
||||
|
||||
from pretix.base.channels import get_all_sales_channels
|
||||
from pretix.base.email import get_email_context
|
||||
from pretix.base.i18n import language
|
||||
from pretix.base.models import (
|
||||
CachedCombinedTicket, CachedFile, CachedTicket, Invoice, InvoiceAddress,
|
||||
@@ -77,7 +76,6 @@ from pretix.control.forms.orders import (
|
||||
from pretix.control.permissions import EventPermissionRequiredMixin
|
||||
from pretix.control.views import PaginationMixin
|
||||
from pretix.helpers.safedownload import check_token
|
||||
from pretix.multidomain.urlreverse import build_absolute_uri
|
||||
from pretix.presale.signals import question_form_fields
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -1490,32 +1488,13 @@ class OrderSendMail(EventPermissionRequiredMixin, OrderViewMixin, FormView):
|
||||
return super().form_invalid(form)
|
||||
|
||||
def form_valid(self, form):
|
||||
tz = pytz.timezone(self.request.event.settings.timezone)
|
||||
order = Order.objects.get(
|
||||
event=self.request.event,
|
||||
code=self.kwargs['code'].upper()
|
||||
)
|
||||
self.preview_output = {}
|
||||
try:
|
||||
invoice_name = order.invoice_address.name
|
||||
invoice_company = order.invoice_address.company
|
||||
except InvoiceAddress.DoesNotExist:
|
||||
invoice_name = ""
|
||||
invoice_company = ""
|
||||
with language(order.locale):
|
||||
email_context = {
|
||||
'event': order.event,
|
||||
'code': order.code,
|
||||
'date': date_format(order.datetime.astimezone(tz), 'SHORT_DATETIME_FORMAT'),
|
||||
'expire_date': date_format(order.expires, 'SHORT_DATE_FORMAT'),
|
||||
'url': build_absolute_uri(order.event, 'presale:event.order.open', kwargs={
|
||||
'order': order.code,
|
||||
'secret': order.secret,
|
||||
'hash': order.email_confirm_hash()
|
||||
}),
|
||||
'invoice_name': invoice_name,
|
||||
'invoice_company': invoice_company,
|
||||
}
|
||||
email_context = get_email_context(event=order.event, order=order)
|
||||
email_template = LazyI18nString(form.cleaned_data['message'])
|
||||
email_content = render_mail(email_template, email_context)
|
||||
if self.request.POST.get('action') == 'preview':
|
||||
|
||||
Reference in New Issue
Block a user