mirror of
https://github.com/pretix/pretix.git
synced 2026-04-25 23:42:32 +00:00
Compare commits
1 Commits
db-ro-user
...
error-page
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6642b0e88 |
@@ -1415,7 +1415,6 @@ class BaseInvoiceAddressForm(forms.ModelForm):
|
|||||||
if not data.get(r):
|
if not data.get(r):
|
||||||
raise ValidationError({r: _("This field is required for the selected type of invoice transmission.")})
|
raise ValidationError({r: _("This field is required for the selected type of invoice transmission.")})
|
||||||
|
|
||||||
transmission_type.validate_invoice_address_data(data)
|
|
||||||
self.instance.transmission_type = transmission_type.identifier
|
self.instance.transmission_type = transmission_type.identifier
|
||||||
self.instance.transmission_info = transmission_type.form_data_to_transmission_info(data)
|
self.instance.transmission_info = transmission_type.form_data_to_transmission_info(data)
|
||||||
elif transmission_type.is_exclusive(self.event, data.get("country"), data.get("is_business")):
|
elif transmission_type.is_exclusive(self.event, data.get("country"), data.get("is_business")):
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ from pretix.base.invoicing.transmission import (
|
|||||||
transmission_types,
|
transmission_types,
|
||||||
)
|
)
|
||||||
from pretix.base.models import Invoice, InvoiceAddress
|
from pretix.base.models import Invoice, InvoiceAddress
|
||||||
from pretix.base.services.mail import mail
|
from pretix.base.services.mail import mail, render_mail
|
||||||
|
from pretix.helpers.format import format_map
|
||||||
|
|
||||||
|
|
||||||
@transmission_types.new()
|
@transmission_types.new()
|
||||||
@@ -133,7 +134,9 @@ class EmailTransmissionProvider(TransmissionProvider):
|
|||||||
subject = invoice.order.event.settings.get('mail_subject_order_invoice', as_type=LazyI18nString)
|
subject = invoice.order.event.settings.get('mail_subject_order_invoice', as_type=LazyI18nString)
|
||||||
|
|
||||||
# Do not set to completed because that is done by the email sending task
|
# Do not set to completed because that is done by the email sending task
|
||||||
outgoing_mail = mail(
|
subject = format_map(subject, context)
|
||||||
|
email_content = render_mail(template, context)
|
||||||
|
mail(
|
||||||
[recipient],
|
[recipient],
|
||||||
subject,
|
subject,
|
||||||
template,
|
template,
|
||||||
@@ -148,10 +151,19 @@ class EmailTransmissionProvider(TransmissionProvider):
|
|||||||
plain_text_only=True,
|
plain_text_only=True,
|
||||||
no_order_links=True,
|
no_order_links=True,
|
||||||
)
|
)
|
||||||
if outgoing_mail:
|
invoice.order.log_action(
|
||||||
invoice.order.log_action(
|
'pretix.event.order.email.invoice',
|
||||||
'pretix.event.order.email.invoice',
|
user=None,
|
||||||
user=None,
|
auth=None,
|
||||||
auth=None,
|
data={
|
||||||
data=outgoing_mail.log_data()
|
'subject': subject,
|
||||||
)
|
'message': email_content,
|
||||||
|
'position': None,
|
||||||
|
'recipient': recipient,
|
||||||
|
'invoices': [invoice.pk],
|
||||||
|
'attach_tickets': False,
|
||||||
|
'attach_ical': False,
|
||||||
|
'attach_other_files': [],
|
||||||
|
'attach_cached_files': [],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -204,12 +204,6 @@ class PeppolTransmissionType(TransmissionType):
|
|||||||
}
|
}
|
||||||
return base | {"transmission_peppol_participant_id"}
|
return base | {"transmission_peppol_participant_id"}
|
||||||
|
|
||||||
def validate_invoice_address_data(self, address_data: dict):
|
|
||||||
# Special case Belgium: If a Belgian business ID is used as Peppol ID, it should match the VAT ID
|
|
||||||
if address_data.get("transmission_peppol_participant_id").startswith("0208:") and address_data.get("vat_id"):
|
|
||||||
if address_data["vat_id"].removeprefix("BE") != address_data["transmission_peppol_participant_id"].removeprefix("0208:"):
|
|
||||||
raise ValidationError({"transmission_peppol_participant_id": _("The Peppol participant ID does not match your VAT ID.")})
|
|
||||||
|
|
||||||
def pdf_watermark(self) -> str:
|
def pdf_watermark(self) -> str:
|
||||||
return pgettext("peppol_invoice", "Visual copy")
|
return pgettext("peppol_invoice", "Visual copy")
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ from typing import Optional
|
|||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
from django_countries.fields import Country
|
from django_countries.fields import Country
|
||||||
|
|
||||||
from pretix.base.models import Invoice
|
from pretix.base.models import Invoice, InvoiceAddress
|
||||||
from pretix.base.signals import EventPluginRegistry, Registry
|
from pretix.base.signals import EventPluginRegistry, Registry
|
||||||
|
|
||||||
|
|
||||||
@@ -89,7 +89,7 @@ class TransmissionType:
|
|||||||
def invoice_address_form_fields_visible(self, country: Country, is_business: bool) -> set:
|
def invoice_address_form_fields_visible(self, country: Country, is_business: bool) -> set:
|
||||||
return set(self.invoice_address_form_fields.keys())
|
return set(self.invoice_address_form_fields.keys())
|
||||||
|
|
||||||
def validate_invoice_address_data(self, address_data: dict):
|
def validate_address(self, ia: InvoiceAddress):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -220,20 +220,3 @@ class OutgoingMail(models.Model):
|
|||||||
error_log_action_type = 'pretix.email.error'
|
error_log_action_type = 'pretix.email.error'
|
||||||
log_target = None
|
log_target = None
|
||||||
return log_target, error_log_action_type
|
return log_target, error_log_action_type
|
||||||
|
|
||||||
def log_data(self):
|
|
||||||
return {
|
|
||||||
"subject": self.subject,
|
|
||||||
"message": self.body_plain,
|
|
||||||
"to": self.to,
|
|
||||||
"cc": self.cc,
|
|
||||||
"bcc": self.bcc,
|
|
||||||
|
|
||||||
"invoices": [i.pk for i in self.should_attach_invoices.all()],
|
|
||||||
"attach_tickets": self.should_attach_tickets,
|
|
||||||
"attach_ical": self.should_attach_ical,
|
|
||||||
"attach_other_files": self.should_attach_other_files,
|
|
||||||
"attach_cached_files": [cf.filename for cf in self.should_attach_cached_files.all()],
|
|
||||||
|
|
||||||
"position": self.orderposition.positionid if self.orderposition else None,
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ from pretix.base.timemachine import time_machine_now
|
|||||||
|
|
||||||
from ...helpers import OF_SELF
|
from ...helpers import OF_SELF
|
||||||
from ...helpers.countries import CachedCountries, FastCountryField
|
from ...helpers.countries import CachedCountries, FastCountryField
|
||||||
|
from ...helpers.format import FormattedString, format_map
|
||||||
from ...helpers.names import build_name
|
from ...helpers.names import build_name
|
||||||
from ...testutils.middleware import debugflags_var
|
from ...testutils.middleware import debugflags_var
|
||||||
from ._transactions import (
|
from ._transactions import (
|
||||||
@@ -1166,7 +1167,7 @@ class Order(LockModel, LoggedModel):
|
|||||||
only be attached for this position and child positions, the link will only point to the
|
only be attached for this position and child positions, the link will only point to the
|
||||||
position and the attendee email will be used if available.
|
position and the attendee email will be used if available.
|
||||||
"""
|
"""
|
||||||
from pretix.base.services.mail import mail
|
from pretix.base.services.mail import mail, render_mail
|
||||||
|
|
||||||
if not self.email and not (position and position.attendee_email):
|
if not self.email and not (position and position.attendee_email):
|
||||||
return
|
return
|
||||||
@@ -1176,20 +1177,32 @@ class Order(LockModel, LoggedModel):
|
|||||||
if position and position.attendee_email:
|
if position and position.attendee_email:
|
||||||
recipient = position.attendee_email
|
recipient = position.attendee_email
|
||||||
|
|
||||||
outgoing_mail = mail(
|
email_content = render_mail(template, context)
|
||||||
|
if not isinstance(subject, FormattedString):
|
||||||
|
subject = format_map(subject, context)
|
||||||
|
mail(
|
||||||
recipient, subject, template, context,
|
recipient, subject, template, context,
|
||||||
self.event, self.locale, self, headers=headers, sender=sender,
|
self.event, self.locale, self, headers=headers, sender=sender,
|
||||||
invoices=invoices, attach_tickets=attach_tickets,
|
invoices=invoices, attach_tickets=attach_tickets,
|
||||||
position=position, auto_email=auto_email, attach_ical=attach_ical,
|
position=position, auto_email=auto_email, attach_ical=attach_ical,
|
||||||
attach_other_files=attach_other_files, attach_cached_files=attach_cached_files,
|
attach_other_files=attach_other_files, attach_cached_files=attach_cached_files,
|
||||||
)
|
)
|
||||||
if outgoing_mail:
|
self.log_action(
|
||||||
self.log_action(
|
log_entry_type,
|
||||||
log_entry_type,
|
user=user,
|
||||||
user=user,
|
auth=auth,
|
||||||
auth=auth,
|
data={
|
||||||
data=outgoing_mail.log_data(),
|
'subject': subject,
|
||||||
)
|
'message': email_content,
|
||||||
|
'position': position.positionid if position else None,
|
||||||
|
'recipient': recipient,
|
||||||
|
'invoices': [i.pk for i in invoices] if invoices else [],
|
||||||
|
'attach_tickets': attach_tickets,
|
||||||
|
'attach_ical': attach_ical,
|
||||||
|
'attach_other_files': attach_other_files,
|
||||||
|
'attach_cached_files': [cf.filename for cf in attach_cached_files] if attach_cached_files else [],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def resend_link(self, user=None, auth=None):
|
def resend_link(self, user=None, auth=None):
|
||||||
with language(self.locale, self.event.settings.region):
|
with language(self.locale, self.event.settings.region):
|
||||||
@@ -2887,14 +2900,17 @@ class OrderPosition(AbstractPosition):
|
|||||||
:param attach_tickets: Attach tickets of this order, if they are existing and ready to download
|
:param attach_tickets: Attach tickets of this order, if they are existing and ready to download
|
||||||
:param attach_ical: Attach relevant ICS files
|
:param attach_ical: Attach relevant ICS files
|
||||||
"""
|
"""
|
||||||
from pretix.base.services.mail import mail
|
from pretix.base.services.mail import mail, render_mail
|
||||||
|
|
||||||
if not self.attendee_email:
|
if not self.attendee_email:
|
||||||
return
|
return
|
||||||
|
|
||||||
with language(self.order.locale, self.order.event.settings.region):
|
with language(self.order.locale, self.order.event.settings.region):
|
||||||
recipient = self.attendee_email
|
recipient = self.attendee_email
|
||||||
outgoing_mail = mail(
|
email_content = render_mail(template, context)
|
||||||
|
if not isinstance(subject, FormattedString):
|
||||||
|
subject = format_map(subject, context)
|
||||||
|
mail(
|
||||||
recipient, subject, template, context,
|
recipient, subject, template, context,
|
||||||
self.event, self.order.locale, order=self.order, headers=headers, sender=sender,
|
self.event, self.order.locale, order=self.order, headers=headers, sender=sender,
|
||||||
position=self,
|
position=self,
|
||||||
@@ -2903,13 +2919,21 @@ class OrderPosition(AbstractPosition):
|
|||||||
attach_ical=attach_ical,
|
attach_ical=attach_ical,
|
||||||
attach_other_files=attach_other_files,
|
attach_other_files=attach_other_files,
|
||||||
)
|
)
|
||||||
if outgoing_mail:
|
self.order.log_action(
|
||||||
self.order.log_action(
|
log_entry_type,
|
||||||
log_entry_type,
|
user=user,
|
||||||
user=user,
|
auth=auth,
|
||||||
auth=auth,
|
data={
|
||||||
data=outgoing_mail.log_data(),
|
'subject': subject,
|
||||||
)
|
'message': email_content,
|
||||||
|
'recipient': recipient,
|
||||||
|
'invoices': [i.pk for i in invoices] if invoices else [],
|
||||||
|
'attach_tickets': attach_tickets,
|
||||||
|
'attach_ical': attach_ical,
|
||||||
|
'attach_other_files': attach_other_files,
|
||||||
|
'attach_cached_files': [],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def resend_link(self, user=None, auth=None):
|
def resend_link(self, user=None, auth=None):
|
||||||
|
|
||||||
|
|||||||
@@ -34,9 +34,10 @@ from phonenumber_field.modelfields import PhoneNumberField
|
|||||||
from pretix.base.email import get_email_context
|
from pretix.base.email import get_email_context
|
||||||
from pretix.base.i18n import language
|
from pretix.base.i18n import language
|
||||||
from pretix.base.models import User, Voucher
|
from pretix.base.models import User, Voucher
|
||||||
from pretix.base.services.mail import mail
|
from pretix.base.services.mail import mail, render_mail
|
||||||
from pretix.helpers import OF_SELF
|
from pretix.helpers import OF_SELF
|
||||||
|
|
||||||
|
from ...helpers.format import format_map
|
||||||
from ...helpers.names import build_name
|
from ...helpers.names import build_name
|
||||||
from .base import LoggedModel
|
from .base import LoggedModel
|
||||||
from .event import Event, SubEvent
|
from .event import Event, SubEvent
|
||||||
@@ -272,7 +273,9 @@ class WaitingListEntry(LoggedModel):
|
|||||||
with language(self.locale, self.event.settings.region):
|
with language(self.locale, self.event.settings.region):
|
||||||
recipient = self.email
|
recipient = self.email
|
||||||
|
|
||||||
outgoing_mail = mail(
|
email_content = render_mail(template, context)
|
||||||
|
subject = format_map(subject, context)
|
||||||
|
mail(
|
||||||
recipient, subject, template, context,
|
recipient, subject, template, context,
|
||||||
self.event,
|
self.event,
|
||||||
self.locale,
|
self.locale,
|
||||||
@@ -282,13 +285,18 @@ class WaitingListEntry(LoggedModel):
|
|||||||
attach_other_files=attach_other_files,
|
attach_other_files=attach_other_files,
|
||||||
attach_cached_files=attach_cached_files,
|
attach_cached_files=attach_cached_files,
|
||||||
)
|
)
|
||||||
if outgoing_mail:
|
self.log_action(
|
||||||
self.log_action(
|
log_entry_type,
|
||||||
log_entry_type,
|
user=user,
|
||||||
user=user,
|
auth=auth,
|
||||||
auth=auth,
|
data={
|
||||||
data=outgoing_mail.log_data(),
|
'subject': subject,
|
||||||
)
|
'message': email_content,
|
||||||
|
'recipient': recipient,
|
||||||
|
'attach_other_files': attach_other_files,
|
||||||
|
'attach_cached_files': [cf.filename for cf in attach_cached_files] if attach_cached_files else [],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def clean_itemvar(event, item, variation):
|
def clean_itemvar(event, item, variation):
|
||||||
|
|||||||
@@ -1295,7 +1295,6 @@ class ManualPayment(BasePaymentProvider):
|
|||||||
|
|
||||||
def format_map(self, order, payment):
|
def format_map(self, order, payment):
|
||||||
return {
|
return {
|
||||||
# Possible placeholder injection, we should make sure to never include user-controlled variables here
|
|
||||||
'order': order.code,
|
'order': order.code,
|
||||||
'amount': payment.amount,
|
'amount': payment.amount,
|
||||||
'currency': self.event.currency,
|
'currency': self.event.currency,
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ from pretix.base.services.tax import split_fee_for_taxes
|
|||||||
from pretix.base.templatetags.money import money_filter
|
from pretix.base.templatetags.money import money_filter
|
||||||
from pretix.celery_app import app
|
from pretix.celery_app import app
|
||||||
from pretix.helpers import OF_SELF
|
from pretix.helpers import OF_SELF
|
||||||
|
from pretix.helpers.format import format_map
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -54,7 +55,7 @@ def _send_wle_mail(wle: WaitingListEntry, subject: LazyI18nString, message: Lazy
|
|||||||
email_context = get_email_context(event_or_subevent=subevent or wle.event, event=wle.event)
|
email_context = get_email_context(event_or_subevent=subevent or wle.event, event=wle.event)
|
||||||
mail(
|
mail(
|
||||||
wle.email,
|
wle.email,
|
||||||
str(subject),
|
format_map(subject, email_context),
|
||||||
message,
|
message,
|
||||||
email_context,
|
email_context,
|
||||||
wle.event,
|
wle.event,
|
||||||
@@ -72,8 +73,9 @@ def _send_mail(order: Order, subject: LazyI18nString, message: LazyI18nString, s
|
|||||||
|
|
||||||
email_context = get_email_context(event_or_subevent=subevent or order.event, refund_amount=refund_amount,
|
email_context = get_email_context(event_or_subevent=subevent or order.event, refund_amount=refund_amount,
|
||||||
order=order, position_or_address=ia, event=order.event)
|
order=order, position_or_address=ia, event=order.event)
|
||||||
|
real_subject = format_map(subject, email_context)
|
||||||
order.send_mail(
|
order.send_mail(
|
||||||
subject, message, email_context,
|
real_subject, message, email_context,
|
||||||
'pretix.event.order.email.event_canceled',
|
'pretix.event.order.email.event_canceled',
|
||||||
user,
|
user,
|
||||||
)
|
)
|
||||||
@@ -83,13 +85,14 @@ def _send_mail(order: Order, subject: LazyI18nString, message: LazyI18nString, s
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email:
|
if p.addon_to_id is None and p.attendee_email and p.attendee_email != order.email:
|
||||||
|
real_subject = format_map(subject, email_context)
|
||||||
email_context = get_email_context(event_or_subevent=p.subevent or order.event,
|
email_context = get_email_context(event_or_subevent=p.subevent or order.event,
|
||||||
event=order.event,
|
event=order.event,
|
||||||
refund_amount=refund_amount,
|
refund_amount=refund_amount,
|
||||||
position_or_address=p,
|
position_or_address=p,
|
||||||
order=order, position=p)
|
order=order, position=p)
|
||||||
order.send_mail(
|
order.send_mail(
|
||||||
subject, message, email_context,
|
real_subject, message, email_context,
|
||||||
'pretix.event.order.email.event_canceled',
|
'pretix.event.order.email.event_canceled',
|
||||||
position=p,
|
position=p,
|
||||||
user=user
|
user=user
|
||||||
|
|||||||
@@ -149,13 +149,13 @@ def prefix_subject(settings_holder, subject, highlight=False):
|
|||||||
return subject
|
return subject
|
||||||
|
|
||||||
|
|
||||||
def mail(email: Union[str, Sequence[str]], subject: Union[str, FormattedString], template: Union[str, LazyI18nString],
|
def mail(email: Union[str, Sequence[str]], subject: str, template: Union[str, LazyI18nString],
|
||||||
context: Dict[str, Any] = None, event: Event = None, locale: str = None, order: Order = None,
|
context: Dict[str, Any] = None, event: Event = None, locale: str = None, order: Order = None,
|
||||||
position: OrderPosition = None, *, headers: dict = None, sender: str = None, organizer: Organizer = None,
|
position: OrderPosition = None, *, headers: dict = None, sender: str = None, organizer: Organizer = None,
|
||||||
customer: Customer = None, invoices: Sequence = None, attach_tickets=False, auto_email=True, user=None,
|
customer: Customer = None, invoices: Sequence = None, attach_tickets=False, auto_email=True, user=None,
|
||||||
attach_ical=False, attach_cached_files: Sequence = None, attach_other_files: list=None,
|
attach_ical=False, attach_cached_files: Sequence = None, attach_other_files: list=None,
|
||||||
plain_text_only=False, no_order_links=False, cc: Sequence[str]=None, bcc: Sequence[str]=None,
|
plain_text_only=False, no_order_links=False, cc: Sequence[str]=None, bcc: Sequence[str]=None,
|
||||||
sensitive: bool=False) -> Optional[OutgoingMail]:
|
sensitive: bool=False):
|
||||||
"""
|
"""
|
||||||
Sends out an email to a user. The mail will be sent synchronously or asynchronously depending on the installation.
|
Sends out an email to a user. The mail will be sent synchronously or asynchronously depending on the installation.
|
||||||
|
|
||||||
@@ -335,26 +335,14 @@ def mail(email: Union[str, Sequence[str]], subject: Union[str, FormattedString],
|
|||||||
should_attach_other_files=attach_other_files or [],
|
should_attach_other_files=attach_other_files or [],
|
||||||
sensitive=sensitive,
|
sensitive=sensitive,
|
||||||
)
|
)
|
||||||
m._prefetched_objects_cache = {}
|
|
||||||
if invoices and not position:
|
if invoices and not position:
|
||||||
m.should_attach_invoices.add(*invoices)
|
m.should_attach_invoices.add(*invoices)
|
||||||
# Hack: For logging, we'll later make a `should_attach_invoices.all()` call. We can prevent a useless
|
|
||||||
# DB query by filling the cache
|
|
||||||
m._prefetched_objects_cache[m.should_attach_invoices.prefetch_cache_name] = invoices
|
|
||||||
else:
|
|
||||||
m._prefetched_objects_cache[m.should_attach_invoices.prefetch_cache_name] = Invoice.objects.none()
|
|
||||||
if attach_cached_files:
|
if attach_cached_files:
|
||||||
cf_list = []
|
|
||||||
for cf in attach_cached_files:
|
for cf in attach_cached_files:
|
||||||
if not isinstance(cf, CachedFile):
|
if not isinstance(cf, CachedFile):
|
||||||
cf = CachedFile.objects.get(pk=cf)
|
m.should_attach_cached_files.add(CachedFile.objects.get(pk=cf))
|
||||||
m.should_attach_cached_files.add(cf)
|
else:
|
||||||
cf_list.append(cf)
|
m.should_attach_cached_files.add(cf)
|
||||||
# Hack: For logging, we'll later make a `should_attach_cached_files.all()` call. We can prevent a useless
|
|
||||||
# DB query by filling the cache
|
|
||||||
m._prefetched_objects_cache[m.should_attach_cached_files.prefetch_cache_name] = cf_list
|
|
||||||
else:
|
|
||||||
m._prefetched_objects_cache[m.should_attach_cached_files.prefetch_cache_name] = CachedFile.objects.none()
|
|
||||||
|
|
||||||
send_task = mail_send_task.si(
|
send_task = mail_send_task.si(
|
||||||
outgoing_mail=m.id
|
outgoing_mail=m.id
|
||||||
@@ -376,8 +364,6 @@ def mail(email: Union[str, Sequence[str]], subject: Union[str, FormattedString],
|
|||||||
lambda: chain(*task_chain).apply_async()
|
lambda: chain(*task_chain).apply_async()
|
||||||
)
|
)
|
||||||
|
|
||||||
return m
|
|
||||||
|
|
||||||
|
|
||||||
class CustomEmail(EmailMultiAlternatives):
|
class CustomEmail(EmailMultiAlternatives):
|
||||||
def _create_mime_attachment(self, content, mimetype):
|
def _create_mime_attachment(self, content, mimetype):
|
||||||
|
|||||||
@@ -1799,6 +1799,8 @@ class OrderChangeManager:
|
|||||||
tax_rule = tax_rules.get(pos.pk, pos.tax_rule)
|
tax_rule = tax_rules.get(pos.pk, pos.tax_rule)
|
||||||
if not tax_rule:
|
if not tax_rule:
|
||||||
continue
|
continue
|
||||||
|
if not pos.price:
|
||||||
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
new_rate = tax_rule.tax_rate_for(ia)
|
new_rate = tax_rule.tax_rate_for(ia)
|
||||||
@@ -1815,9 +1817,7 @@ class OrderChangeManager:
|
|||||||
override_tax_rate=new_rate, override_tax_code=new_code)
|
override_tax_rate=new_rate, override_tax_code=new_code)
|
||||||
self._totaldiff_guesstimate += new_tax.gross - pos.price
|
self._totaldiff_guesstimate += new_tax.gross - pos.price
|
||||||
self._operations.append(self.PriceOperation(pos, new_tax, new_tax.gross - pos.price))
|
self._operations.append(self.PriceOperation(pos, new_tax, new_tax.gross - pos.price))
|
||||||
if pos.price:
|
self._invoice_dirty = True
|
||||||
# We do not consider the invoice dirty if only 0€-valued taxes are changed
|
|
||||||
self._invoice_dirty = True
|
|
||||||
|
|
||||||
def cancel_fee(self, fee: OrderFee):
|
def cancel_fee(self, fee: OrderFee):
|
||||||
self._totaldiff_guesstimate -= fee.value
|
self._totaldiff_guesstimate -= fee.value
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ def vouchers_send(event: Event, vouchers: list, subject: str, message: str, reci
|
|||||||
with language(event.settings.locale):
|
with language(event.settings.locale):
|
||||||
email_context = get_email_context(event=event, name=r.get('name') or '',
|
email_context = get_email_context(event=event, name=r.get('name') or '',
|
||||||
voucher_list=[v.code for v in voucher_list])
|
voucher_list=[v.code for v in voucher_list])
|
||||||
outgoing_mail = mail(
|
mail(
|
||||||
r['email'],
|
r['email'],
|
||||||
subject,
|
subject,
|
||||||
LazyI18nString(message),
|
LazyI18nString(message),
|
||||||
@@ -60,8 +60,8 @@ def vouchers_send(event: Event, vouchers: list, subject: str, message: str, reci
|
|||||||
data={
|
data={
|
||||||
'recipient': r['email'],
|
'recipient': r['email'],
|
||||||
'name': r.get('name'),
|
'name': r.get('name'),
|
||||||
'subject': outgoing_mail.subject,
|
'subject': subject,
|
||||||
'message': outgoing_mail.body_plain,
|
'message': message,
|
||||||
},
|
},
|
||||||
save=False
|
save=False
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -363,7 +363,7 @@ class EmailAddressShredder(BaseDataShredder):
|
|||||||
le.save(update_fields=['data', 'shredded'])
|
le.save(update_fields=['data', 'shredded'])
|
||||||
else:
|
else:
|
||||||
shred_log_fields(le, banlist=[
|
shred_log_fields(le, banlist=[
|
||||||
'recipient', 'message', 'subject', 'full_mail', 'old_email', 'new_email', 'bcc', 'cc',
|
'recipient', 'message', 'subject', 'full_mail', 'old_email', 'new_email'
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load urlreplace %}
|
{% load urlreplace %}
|
||||||
{% load bootstrap3 %}
|
{% load bootstrap3 %}
|
||||||
{% load static %}
|
|
||||||
{% block title %}{% trans "Events" %}{% endblock %}
|
{% block title %}{% trans "Events" %}{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>{% trans "Events" %}</h1>
|
<h1>{% trans "Events" %}</h1>
|
||||||
@@ -75,7 +74,6 @@
|
|||||||
<a href="?{% url_replace request 'ordering' 'organizer' %}"><i class="fa fa-caret-up"></i></a>
|
<a href="?{% url_replace request 'ordering' 'organizer' %}"><i class="fa fa-caret-up"></i></a>
|
||||||
</th>
|
</th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<th>{% trans "Sales channels" %}</th>
|
|
||||||
<th>
|
<th>
|
||||||
{% trans "Start date" %}
|
{% trans "Start date" %}
|
||||||
<a href="?{% url_replace request 'ordering' '-date_from' %}"><i class="fa fa-caret-down"></i></a>
|
<a href="?{% url_replace request 'ordering' '-date_from' %}"><i class="fa fa-caret-down"></i></a>
|
||||||
@@ -110,21 +108,6 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
{% if not hide_orga %}<td>{{ e.organizer }}</td>{% endif %}
|
{% if not hide_orga %}<td>{{ e.organizer }}</td>{% endif %}
|
||||||
<td>
|
|
||||||
{% for c in e.organizer.sales_channels.all %}
|
|
||||||
{% if e.all_sales_channels or c in e.limit_sales_channels.all %}
|
|
||||||
{% if "." in c.icon %}
|
|
||||||
<img src="{% static c.icon %}" class="fa-like-image"
|
|
||||||
data-toggle="tooltip" title="{{ c.label }}">
|
|
||||||
{% else %}
|
|
||||||
<span class="fa fa-fw fa-{{ c.icon }} text-muted"
|
|
||||||
data-toggle="tooltip" title="{{ c.label }}"></span>
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
<span class="fa fa-fw"></span>
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</td>
|
|
||||||
<td class="event-date-col">
|
<td class="event-date-col">
|
||||||
{% if e.has_subevents %}
|
{% if e.has_subevents %}
|
||||||
<span class="fa fa-fw- fa-calendar"></span>
|
<span class="fa fa-fw- fa-calendar"></span>
|
||||||
|
|||||||
@@ -24,9 +24,7 @@
|
|||||||
{% if log.display %}
|
{% if log.display %}
|
||||||
<br/><span class="fa fa-fw fa-comment-o"></span> {{ log.display }}
|
<br/><span class="fa fa-fw fa-comment-o"></span> {{ log.display }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if log.parsed_data.to %}
|
{% if log.parsed_data.recipient %}
|
||||||
<br/><span class="fa fa-fw fa-envelope-o"></span> {{ log.parsed_data.to|join:", " }}
|
|
||||||
{% elif log.parsed_data.recipient %} {# legacy #}
|
|
||||||
<br/><span class="fa fa-fw fa-envelope-o"></span> {{ log.parsed_data.recipient }}
|
<br/><span class="fa fa-fw fa-envelope-o"></span> {{ log.parsed_data.recipient }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
{% extends "pretixcontrol/organizers/base.html" %}
|
{% extends "pretixcontrol/organizers/base.html" %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load bootstrap3 %}
|
{% load bootstrap3 %}
|
||||||
{% load static %}
|
|
||||||
{% block inner %}
|
{% block inner %}
|
||||||
<h1>
|
<h1>
|
||||||
{% blocktrans with name=request.organizer.name %}Organizer: {{ name }}{% endblocktrans %}
|
{% blocktrans with name=request.organizer.name %}Organizer: {{ name }}{% endblocktrans %}
|
||||||
@@ -63,7 +62,6 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>{% trans "Event name" %}</th>
|
<th>{% trans "Event name" %}</th>
|
||||||
<th>{% trans "Sales channels" %}</th>
|
|
||||||
<th>
|
<th>
|
||||||
{% trans "Start date" %}
|
{% trans "Start date" %}
|
||||||
/
|
/
|
||||||
@@ -79,30 +77,10 @@
|
|||||||
<td>
|
<td>
|
||||||
<strong><a
|
<strong><a
|
||||||
href="{% url "control:event.index" organizer=e.organizer.slug event=e.slug %}">{{ e.name }}</a></strong>
|
href="{% url "control:event.index" organizer=e.organizer.slug event=e.slug %}">{{ e.name }}</a></strong>
|
||||||
<br>
|
<br><small>{{ e.slug }}</small>
|
||||||
<small>
|
{% for k, v in e.meta_data.items %}
|
||||||
{{ e.slug }}
|
{% if v %}
|
||||||
</small>
|
<small class="text-muted">· {{ k }}: {{ v }}</small>
|
||||||
<small class="text-muted">
|
|
||||||
{% for k, v in e.meta_data.items %}
|
|
||||||
{% if v %}
|
|
||||||
· {{ k }}: {{ v }}
|
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
|
||||||
</small>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
{% for c in sales_channels %}
|
|
||||||
{% if e.all_sales_channels or c in e.limit_sales_channels.all %}
|
|
||||||
{% if "." in c.icon %}
|
|
||||||
<img src="{% static c.icon %}" class="fa-like-image"
|
|
||||||
data-toggle="tooltip" title="{{ c.label }}">
|
|
||||||
{% else %}
|
|
||||||
<span class="fa fa-fw fa-{{ c.icon }} text-muted"
|
|
||||||
data-toggle="tooltip" title="{{ c.label }}"></span>
|
|
||||||
{% endif %}
|
|
||||||
{% else %}
|
|
||||||
<span class="fa fa-fw"></span>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</td>
|
</td>
|
||||||
|
|||||||
@@ -264,17 +264,12 @@
|
|||||||
The paper size will match the PDF.
|
The paper size will match the PDF.
|
||||||
{% endblocktrans %}
|
{% endblocktrans %}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-center">
|
<p>
|
||||||
<span class="btn btn-default fileinput-button background-button btn-block">
|
<span class="btn btn-default fileinput-button background-button btn-block">
|
||||||
<i class="fa fa-upload"></i>
|
<i class="fa fa-upload"></i>
|
||||||
<span>{% trans "Upload PDF as background" %}</span>
|
<span>{% trans "Upload PDF as background" %}</span>
|
||||||
<input id="fileupload" type="file" name="background" accept="application/pdf">
|
<input id="fileupload" type="file" name="background" accept="application/pdf">
|
||||||
</span>
|
</span>
|
||||||
<small class="text-muted">
|
|
||||||
{% blocktrans trimmed with size=maxfilesize|filesizeformat %}
|
|
||||||
max. {{ size }}, smaller is better
|
|
||||||
{% endblocktrans %}
|
|
||||||
</small>
|
|
||||||
</p>
|
</p>
|
||||||
<p class="text-center">
|
<p class="text-center">
|
||||||
<a class="btn btn-link background-download-button" href="{{ pdf }}" target="_blank">
|
<a class="btn btn-link background-download-button" href="{{ pdf }}" target="_blank">
|
||||||
|
|||||||
@@ -67,12 +67,7 @@ class EventList(PaginationMixin, ListView):
|
|||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = self.request.user.get_events_with_any_permission(self.request).prefetch_related(
|
qs = self.request.user.get_events_with_any_permission(self.request).prefetch_related(
|
||||||
'organizer',
|
'organizer', '_settings_objects', 'organizer___settings_objects', 'organizer__meta_properties',
|
||||||
'organizer__sales_channels',
|
|
||||||
'_settings_objects',
|
|
||||||
'organizer___settings_objects',
|
|
||||||
'organizer__meta_properties',
|
|
||||||
'limit_sales_channels',
|
|
||||||
Prefetch(
|
Prefetch(
|
||||||
'meta_values',
|
'meta_values',
|
||||||
EventMetaValue.objects.select_related('property'),
|
EventMetaValue.objects.select_related('property'),
|
||||||
|
|||||||
@@ -2421,9 +2421,9 @@ class OrderSendMail(EventPermissionRequiredMixin, OrderViewMixin, FormView):
|
|||||||
with language(order.locale, self.request.event.settings.region):
|
with language(order.locale, self.request.event.settings.region):
|
||||||
email_context = get_email_context(event=order.event, order=order)
|
email_context = get_email_context(event=order.event, order=order)
|
||||||
email_template = LazyI18nString(form.cleaned_data['message'])
|
email_template = LazyI18nString(form.cleaned_data['message'])
|
||||||
|
email_subject = format_map(str(form.cleaned_data['subject']), email_context)
|
||||||
|
email_content = render_mail(email_template, email_context)
|
||||||
if self.request.POST.get('action') == 'preview':
|
if self.request.POST.get('action') == 'preview':
|
||||||
email_subject = format_map(form.cleaned_data['subject'], email_context)
|
|
||||||
email_content = render_mail(email_template, email_context)
|
|
||||||
self.preview_output = {
|
self.preview_output = {
|
||||||
'subject': mark_safe(_('Subject: {subject}').format(
|
'subject': mark_safe(_('Subject: {subject}').format(
|
||||||
subject=prefix_subject(order.event, escape(email_subject), highlight=True)
|
subject=prefix_subject(order.event, escape(email_subject), highlight=True)
|
||||||
@@ -2485,9 +2485,9 @@ class OrderPositionSendMail(OrderSendMail):
|
|||||||
with language(position.order.locale, self.request.event.settings.region):
|
with language(position.order.locale, self.request.event.settings.region):
|
||||||
email_context = get_email_context(event=position.order.event, order=position.order, position=position)
|
email_context = get_email_context(event=position.order.event, order=position.order, position=position)
|
||||||
email_template = LazyI18nString(form.cleaned_data['message'])
|
email_template = LazyI18nString(form.cleaned_data['message'])
|
||||||
|
email_subject = format_map(str(form.cleaned_data['subject']), email_context)
|
||||||
|
email_content = render_mail(email_template, email_context)
|
||||||
if self.request.POST.get('action') == 'preview':
|
if self.request.POST.get('action') == 'preview':
|
||||||
email_subject = format_map(str(form.cleaned_data['subject']), email_context)
|
|
||||||
email_content = render_mail(email_template, email_context)
|
|
||||||
self.preview_output = {
|
self.preview_output = {
|
||||||
'subject': mark_safe(_('Subject: {subject}').format(
|
'subject': mark_safe(_('Subject: {subject}').format(
|
||||||
subject=prefix_subject(position.order.event, escape(email_subject), highlight=True))
|
subject=prefix_subject(position.order.event, escape(email_subject), highlight=True))
|
||||||
|
|||||||
@@ -207,7 +207,6 @@ class OrganizerDetail(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin
|
|||||||
'organizer').prefetch_related(
|
'organizer').prefetch_related(
|
||||||
'organizer', '_settings_objects', 'organizer___settings_objects',
|
'organizer', '_settings_objects', 'organizer___settings_objects',
|
||||||
'organizer__meta_properties',
|
'organizer__meta_properties',
|
||||||
'limit_sales_channels',
|
|
||||||
Prefetch(
|
Prefetch(
|
||||||
'meta_values',
|
'meta_values',
|
||||||
EventMetaValue.objects.select_related('property'),
|
EventMetaValue.objects.select_related('property'),
|
||||||
@@ -238,7 +237,6 @@ class OrganizerDetail(OrganizerDetailViewMixin, OrganizerPermissionRequiredMixin
|
|||||||
self.filter_form['meta_{}'.format(p.name)] for p in
|
self.filter_form['meta_{}'.format(p.name)] for p in
|
||||||
self.organizer.meta_properties.filter(filter_allowed=True)
|
self.organizer.meta_properties.filter(filter_allowed=True)
|
||||||
]
|
]
|
||||||
ctx['sales_channels'] = self.request.organizer.sales_channels.all()
|
|
||||||
return ctx
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -292,7 +292,6 @@ class BaseEditorView(EventPermissionRequiredMixin, TemplateView):
|
|||||||
ctx['layout'] = json.dumps(self.get_current_layout())
|
ctx['layout'] = json.dumps(self.get_current_layout())
|
||||||
ctx['title'] = self.title
|
ctx['title'] = self.title
|
||||||
ctx['locales'] = [p for p in settings.LANGUAGES if p[0] in self.request.event.settings.locales]
|
ctx['locales'] = [p for p in settings.LANGUAGES if p[0] in self.request.event.settings.locales]
|
||||||
ctx['maxfilesize'] = self.maxfilesize
|
|
||||||
return ctx
|
return ctx
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ class VoucherList(PaginationMixin, EventPermissionRequiredMixin, ListView):
|
|||||||
elif v.quota:
|
elif v.quota:
|
||||||
prod = _('Any product in quota "{quota}"').format(quota=str(v.quota.name))
|
prod = _('Any product in quota "{quota}"').format(quota=str(v.quota.name))
|
||||||
else:
|
else:
|
||||||
prod = ""
|
prod = _('Any product')
|
||||||
row = [
|
row = [
|
||||||
v.code,
|
v.code,
|
||||||
v.valid_until.isoformat() if v.valid_until else "",
|
v.valid_until.isoformat() if v.valid_until else "",
|
||||||
|
|||||||
@@ -38,10 +38,13 @@ from i18nfield.strings import LazyI18nString
|
|||||||
|
|
||||||
from pretix.base.email import get_email_context
|
from pretix.base.email import get_email_context
|
||||||
from pretix.base.i18n import language
|
from pretix.base.i18n import language
|
||||||
from pretix.base.models import Checkin, Event, InvoiceAddress, Order, User
|
from pretix.base.models import (
|
||||||
|
CachedFile, Checkin, Event, InvoiceAddress, Order, User,
|
||||||
|
)
|
||||||
from pretix.base.services.mail import mail
|
from pretix.base.services.mail import mail
|
||||||
from pretix.base.services.tasks import ProfiledEventTask
|
from pretix.base.services.tasks import ProfiledEventTask
|
||||||
from pretix.celery_app import app
|
from pretix.celery_app import app
|
||||||
|
from pretix.helpers.format import format_map
|
||||||
|
|
||||||
|
|
||||||
def _chunks(lst, n):
|
def _chunks(lst, n):
|
||||||
@@ -61,6 +64,7 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
|
|||||||
user = User.objects.get(pk=user) if user else None
|
user = User.objects.get(pk=user) if user else None
|
||||||
subject = LazyI18nString(subject)
|
subject = LazyI18nString(subject)
|
||||||
message = LazyI18nString(message)
|
message = LazyI18nString(message)
|
||||||
|
attachments_for_log = [cf.filename for cf in CachedFile.objects.filter(pk__in=attachments)] if attachments else []
|
||||||
|
|
||||||
def _send_to_order(o):
|
def _send_to_order(o):
|
||||||
send_to_order = recipients in ('both', 'orders')
|
send_to_order = recipients in ('both', 'orders')
|
||||||
@@ -118,7 +122,7 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
|
|||||||
|
|
||||||
with language(o.locale, event.settings.region):
|
with language(o.locale, event.settings.region):
|
||||||
email_context = get_email_context(event=event, order=o, invoice_address=ia, position=p)
|
email_context = get_email_context(event=event, order=o, invoice_address=ia, position=p)
|
||||||
outgoing_mail = mail(
|
mail(
|
||||||
p.attendee_email,
|
p.attendee_email,
|
||||||
subject,
|
subject,
|
||||||
message,
|
message,
|
||||||
@@ -131,17 +135,25 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
|
|||||||
attach_ical=attach_ical,
|
attach_ical=attach_ical,
|
||||||
attach_cached_files=attachments
|
attach_cached_files=attachments
|
||||||
)
|
)
|
||||||
if outgoing_mail:
|
o.log_action(
|
||||||
o.log_action(
|
'pretix.plugins.sendmail.order.email.sent.attendee',
|
||||||
'pretix.plugins.sendmail.order.email.sent.attendee',
|
user=user,
|
||||||
user=user,
|
data={
|
||||||
data=outgoing_mail.log_data(),
|
'position': p.positionid,
|
||||||
)
|
'subject': format_map(subject.localize(o.locale), email_context),
|
||||||
|
'message': format_map(message.localize(o.locale), email_context),
|
||||||
|
'recipient': p.attendee_email,
|
||||||
|
'attach_tickets': attach_tickets,
|
||||||
|
'attach_ical': attach_ical,
|
||||||
|
'attach_other_files': [],
|
||||||
|
'attach_cached_files': attachments_for_log,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
if send_to_order and o.email:
|
if send_to_order and o.email:
|
||||||
with language(o.locale, event.settings.region):
|
with language(o.locale, event.settings.region):
|
||||||
email_context = get_email_context(event=event, order=o, invoice_address=ia)
|
email_context = get_email_context(event=event, order=o, invoice_address=ia)
|
||||||
outgoing_mail = mail(
|
mail(
|
||||||
o.email,
|
o.email,
|
||||||
subject,
|
subject,
|
||||||
message,
|
message,
|
||||||
@@ -153,12 +165,19 @@ def send_mails_to_orders(event: Event, user: int, subject: dict, message: dict,
|
|||||||
attach_ical=attach_ical,
|
attach_ical=attach_ical,
|
||||||
attach_cached_files=attachments,
|
attach_cached_files=attachments,
|
||||||
)
|
)
|
||||||
if outgoing_mail:
|
o.log_action(
|
||||||
o.log_action(
|
'pretix.plugins.sendmail.order.email.sent',
|
||||||
'pretix.plugins.sendmail.order.email.sent',
|
user=user,
|
||||||
user=user,
|
data={
|
||||||
data=outgoing_mail.log_data(),
|
'subject': format_map(subject.localize(o.locale), email_context),
|
||||||
)
|
'message': format_map(message.localize(o.locale), email_context),
|
||||||
|
'recipient': o.email,
|
||||||
|
'attach_tickets': attach_tickets,
|
||||||
|
'attach_ical': attach_ical,
|
||||||
|
'attach_other_files': [],
|
||||||
|
'attach_cached_files': attachments_for_log,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
for chunk in _chunks(objects, 1000):
|
for chunk in _chunks(objects, 1000):
|
||||||
orders = Order.objects.filter(pk__in=chunk, event=event)
|
orders = Order.objects.filter(pk__in=chunk, event=event)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="panel-group" id="questions_accordion">
|
<div class="panel-group" id="questions_accordion">
|
||||||
{% if invoice_address_asked or event.settings.invoice_name_required %}
|
{% if invoice_address_asked or event.settings.invoice_name_required %}
|
||||||
{% if invoice_address_asked and not request.GET.generate_invoice == "true" and not invoice_generation_selfservice %}
|
{% if invoice_address_asked and not request.GET.generate_invoice == "true" and not event.settings.invoice_reissue_after_modify %}
|
||||||
<div class="alert alert-info">
|
<div class="alert alert-info">
|
||||||
{% blocktrans trimmed %}
|
{% blocktrans trimmed %}
|
||||||
Modifying your invoice address will not automatically generate a new invoice.
|
Modifying your invoice address will not automatically generate a new invoice.
|
||||||
|
|||||||
@@ -909,21 +909,6 @@ class OrderModify(EventViewMixin, OrderDetailMixin, OrderQuestionsViewMixin, Tem
|
|||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
return super().get(request, *args, **kwargs)
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
|
||||||
ctx = super().get_context_data(
|
|
||||||
**kwargs,
|
|
||||||
)
|
|
||||||
|
|
||||||
ctx['invoice_generation_selfservice'] = (
|
|
||||||
self.request.event.settings.invoice_reissue_after_modify or
|
|
||||||
(
|
|
||||||
can_generate_invoice(self.request.event, self.order, ignore_payments=True) and
|
|
||||||
not self.order.invoices.exists()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return ctx
|
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
self.request = request
|
self.request = request
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ DATABASES = {
|
|||||||
'HOST': config.get('database', 'host', fallback=''),
|
'HOST': config.get('database', 'host', fallback=''),
|
||||||
'PORT': config.get('database', 'port', fallback=''),
|
'PORT': config.get('database', 'port', fallback=''),
|
||||||
'CONN_MAX_AGE': 0 if db_backend == 'sqlite3' else 120,
|
'CONN_MAX_AGE': 0 if db_backend == 'sqlite3' else 120,
|
||||||
'CONN_HEALTH_CHECKS': db_backend != 'sqlite3',
|
'CONN_HEALTH_CHECKS': db_backend != 'sqlite3', # Will only be used from Django 4.1 onwards
|
||||||
'DISABLE_SERVER_SIDE_CURSORS': db_disable_server_side_cursors,
|
'DISABLE_SERVER_SIDE_CURSORS': db_disable_server_side_cursors,
|
||||||
'OPTIONS': db_options,
|
'OPTIONS': db_options,
|
||||||
'TEST': {}
|
'TEST': {}
|
||||||
@@ -179,21 +179,6 @@ if config.has_section('replica'):
|
|||||||
}
|
}
|
||||||
DATABASE_ROUTERS = ['pretix.helpers.database.ReplicaRouter']
|
DATABASE_ROUTERS = ['pretix.helpers.database.ReplicaRouter']
|
||||||
|
|
||||||
if config.has_section('dbreadonly'):
|
|
||||||
DATABASES['readonly'] = {
|
|
||||||
'ENGINE': 'django.db.backends.' + db_backend,
|
|
||||||
'NAME': config.get('dbreadonly', 'name', fallback=DATABASES['default']['NAME']),
|
|
||||||
'USER': config.get('dbreadonly', 'user', fallback=DATABASES['default']['USER']),
|
|
||||||
'PASSWORD': config.get('dbreadonly', 'password', fallback=DATABASES['default']['PASSWORD']),
|
|
||||||
'HOST': config.get('dbreadonly', 'host', fallback=DATABASES['default']['HOST']),
|
|
||||||
'PORT': config.get('dbreadonly', 'port', fallback=DATABASES['default']['PORT']),
|
|
||||||
'CONN_MAX_AGE': 0, # do not spam primary with open connections as long as readonly is only used occasionally
|
|
||||||
'CONN_HEALTH_CHECKS': db_backend != 'sqlite3',
|
|
||||||
'DISABLE_SERVER_SIDE_CURSORS': db_disable_server_side_cursors,
|
|
||||||
'OPTIONS': db_options,
|
|
||||||
'TEST': {}
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC_URL = config.get('urls', 'static', fallback='/static/')
|
STATIC_URL = config.get('urls', 'static', fallback='/static/')
|
||||||
|
|
||||||
MEDIA_URL = config.get('urls', 'media', fallback='/media/')
|
MEDIA_URL = config.get('urls', 'media', fallback='/media/')
|
||||||
|
|||||||
@@ -173,8 +173,8 @@ $(function () {
|
|||||||
if (!dependents.transmission_peppol_participant_id.val()) {
|
if (!dependents.transmission_peppol_participant_id.val()) {
|
||||||
const fill_peppol_id = function () {
|
const fill_peppol_id = function () {
|
||||||
const vatId = dependents.vat_id.val();
|
const vatId = dependents.vat_id.val();
|
||||||
if (vatId && vatId.startsWith("BE") && dependents.transmission_type.val() === "peppol") {
|
if (vatId && vatId.startsWith("BE") && dependents.transmission_type.val() === "peppol" && autofill_peppol_id) {
|
||||||
dependents.transmission_peppol_participant_id.val("0208:" + vatId.substring(2))
|
dependents.transmission_peppol_participant_id.val("0201:" + vatId.substring(2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependents.vat_id.add(dependents.transmission_type).on("change", fill_peppol_id);
|
dependents.vat_id.add(dependents.transmission_type).on("change", fill_peppol_id);
|
||||||
|
|||||||
Reference in New Issue
Block a user