mirror of
https://github.com/pretix/pretix.git
synced 2026-05-05 15:14:04 +00:00
- [x] attendee names - [x] Invoice address names - [x] Data migration - [x] API serializers - [x] orderposition - [x] cartposition - [x] invoiceaddress - [x] checkinlistposition - [x] position API search - [x] invoice API search - [x] business/individual required toggle - [x] Split columns in CSV exports - [x] ticket editor - [x] shredder - [x] ticket/invoice sample data - [x] order search - [x] Handle changed naming scheme - [x] tests - [x] make use in: - [x] Boabee - [x] Certificate download order - [x] Badge download order - [x] Ticket download order - [x] Document new MySQL requirement - [x] Plugins
This commit is contained in:
@@ -75,7 +75,7 @@ class User(AbstractBaseUser, PermissionsMixin, LoggingMixin):
|
||||
REQUIRED_FIELDS = []
|
||||
|
||||
email = models.EmailField(unique=True, db_index=True, null=True, blank=True,
|
||||
verbose_name=_('E-mail'))
|
||||
verbose_name=_('E-mail'), max_length=190)
|
||||
fullname = models.CharField(max_length=255, blank=True, null=True,
|
||||
verbose_name=_('Full name'))
|
||||
is_active = models.BooleanField(default=True,
|
||||
|
||||
@@ -26,10 +26,12 @@ from django.utils.timezone import make_aware, now
|
||||
from django.utils.translation import pgettext_lazy, ugettext_lazy as _
|
||||
from django_countries.fields import CountryField
|
||||
from i18nfield.strings import LazyI18nString
|
||||
from jsonfallback.fields import FallbackJSONField
|
||||
|
||||
from pretix.base.i18n import language
|
||||
from pretix.base.models import User
|
||||
from pretix.base.reldate import RelativeDateWrapper
|
||||
from pretix.base.settings import PERSON_NAME_SCHEMES
|
||||
|
||||
from .base import LockModel, LoggedModel
|
||||
from .event import Event, SubEvent
|
||||
@@ -699,8 +701,10 @@ class AbstractPosition(models.Model):
|
||||
:type expires: datetime
|
||||
:param price: The price of this item
|
||||
:type price: decimal.Decimal
|
||||
:param attendee_name: The attendee's name, if entered.
|
||||
:type attendee_name: str
|
||||
:param attendee_name_parts: The parts of the attendee's name, if entered.
|
||||
:type attendee_name_parts: str
|
||||
:param attendee_name_cached: The concatenated version of the attendee's name, if entered.
|
||||
:type attendee_name_cached: str
|
||||
:param attendee_email: The attendee's email, if entered.
|
||||
:type attendee_email: str
|
||||
:param voucher: A voucher that has been applied to this sale
|
||||
@@ -729,12 +733,15 @@ class AbstractPosition(models.Model):
|
||||
decimal_places=2, max_digits=10,
|
||||
verbose_name=_("Price")
|
||||
)
|
||||
attendee_name = models.CharField(
|
||||
attendee_name_cached = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("Attendee name"),
|
||||
blank=True, null=True,
|
||||
help_text=_("Empty, if this product is not an admission ticket")
|
||||
)
|
||||
attendee_name_parts = FallbackJSONField(
|
||||
blank=True, default=dict
|
||||
)
|
||||
attendee_email = models.EmailField(
|
||||
verbose_name=_("Attendee email"),
|
||||
blank=True, null=True,
|
||||
@@ -797,6 +804,24 @@ class AbstractPosition(models.Model):
|
||||
if self.variation is None
|
||||
else self.variation.quotas.filter(subevent=self.subevent))
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.attendee_name_cached = self.attendee_name
|
||||
if self.attendee_name_parts is None:
|
||||
self.attendee_name_parts = {}
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
@property
|
||||
def attendee_name(self):
|
||||
if not self.attendee_name_parts:
|
||||
return None
|
||||
if '_legacy' in self.attendee_name_parts:
|
||||
return self.attendee_name_parts['_legacy']
|
||||
if '_scheme' in self.attendee_name_parts:
|
||||
scheme = PERSON_NAME_SCHEMES[self.attendee_name_parts['_scheme']]
|
||||
else:
|
||||
scheme = PERSON_NAME_SCHEMES[self.event.settings.name_scheme]
|
||||
return scheme['concatenation'](self.attendee_name_parts).strip()
|
||||
|
||||
|
||||
class OrderPayment(models.Model):
|
||||
"""
|
||||
@@ -1482,6 +1507,10 @@ class OrderPosition(AbstractPosition):
|
||||
self.pseudonymization_id = code
|
||||
return
|
||||
|
||||
@property
|
||||
def event(self):
|
||||
return self.order.event
|
||||
|
||||
|
||||
class CartPosition(AbstractPosition):
|
||||
"""
|
||||
@@ -1547,7 +1576,8 @@ class InvoiceAddress(models.Model):
|
||||
order = models.OneToOneField(Order, null=True, blank=True, related_name='invoice_address', on_delete=models.CASCADE)
|
||||
is_business = models.BooleanField(default=False, verbose_name=_('Business customer'))
|
||||
company = models.CharField(max_length=255, blank=True, verbose_name=_('Company name'))
|
||||
name = models.CharField(max_length=255, verbose_name=_('Full name'), blank=True)
|
||||
name_cached = models.CharField(max_length=255, verbose_name=_('Full name'), blank=True)
|
||||
name_parts = FallbackJSONField(default=dict)
|
||||
street = models.TextField(verbose_name=_('Address'), blank=False)
|
||||
zipcode = models.CharField(max_length=30, verbose_name=_('ZIP code'), blank=False)
|
||||
city = models.CharField(max_length=255, verbose_name=_('City'), blank=False)
|
||||
@@ -1565,8 +1595,25 @@ class InvoiceAddress(models.Model):
|
||||
def save(self, **kwargs):
|
||||
if self.order:
|
||||
self.order.touch()
|
||||
|
||||
if self.name_parts:
|
||||
self.name_cached = self.name
|
||||
else:
|
||||
self.name_cached = ""
|
||||
super().save(**kwargs)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
if not self.name_parts:
|
||||
return ""
|
||||
if '_legacy' in self.name_parts:
|
||||
return self.name_parts['_legacy']
|
||||
if '_scheme' in self.name_parts:
|
||||
scheme = PERSON_NAME_SCHEMES[self.name_parts['_scheme']]
|
||||
else:
|
||||
raise TypeError("Invalid name given.")
|
||||
return scheme['concatenation'](self.name_parts).strip()
|
||||
|
||||
|
||||
def cachedticket_name(instance, filename: str) -> str:
|
||||
secret = get_random_string(length=16, allowed_chars=string.ascii_letters + string.digits)
|
||||
|
||||
Reference in New Issue
Block a user