From 8d6d0c589330d52ff5a85e666163436cc5c7d8d5 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Wed, 17 May 2023 11:53:28 +0200 Subject: [PATCH] Show name including saluation in some places (Z#23121817) (#3320) Co-authored-by: Richard Schreiber --- src/pretix/base/models/customers.py | 29 ++++++-------- src/pretix/base/models/memberships.py | 12 +----- src/pretix/base/models/orders.py | 30 ++++++--------- src/pretix/base/models/waitinglist.py | 16 +++----- src/pretix/base/settings.py | 15 ++++++++ .../templates/pretixcontrol/order/index.html | 2 +- .../pretixcontrol/waitinglist/index.html | 2 +- src/pretix/helpers/names.py | 38 +++++++++++++++++++ 8 files changed, 86 insertions(+), 58 deletions(-) create mode 100644 src/pretix/helpers/names.py diff --git a/src/pretix/base/models/customers.py b/src/pretix/base/models/customers.py index 373dac8f3c..7ffebbdfbc 100644 --- a/src/pretix/base/models/customers.py +++ b/src/pretix/base/models/customers.py @@ -39,6 +39,7 @@ from pretix.base.models.fields import MultiStringField from pretix.base.models.organizer import Organizer from pretix.base.settings import PERSON_NAME_SCHEMES from pretix.helpers.countries import FastCountryField +from pretix.helpers.names import build_name class CustomerSSOProvider(LoggedModel): @@ -171,15 +172,11 @@ class Customer(LoggedModel): @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() + return build_name(self.name_parts, fallback_scheme=lambda: self.organizer.settings.name_scheme) or "" + + @property + def name_all_components(self): + return build_name(self.name_parts, "concatenation_all_components", fallback_scheme=lambda: self.organizer.settings.name_scheme) or "" def __str__(self): s = f'#{self.identifier}' @@ -302,15 +299,11 @@ class AttendeeProfile(models.Model): @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.customer.organizer.settings.name_scheme] - return scheme['concatenation'](self.attendee_name_parts).strip() + return build_name(self.attendee_name_parts, fallback_scheme=lambda: self.customer.organizer.settings.name_scheme) + + @property + def attendee_name_all_components(self): + return build_name(self.attendee_name_parts, "concatenation_all_components", fallback_scheme=lambda: self.customer.organizer.settings.name_scheme) @property def state_name(self): diff --git a/src/pretix/base/models/memberships.py b/src/pretix/base/models/memberships.py index 873a96dcee..864011f748 100644 --- a/src/pretix/base/models/memberships.py +++ b/src/pretix/base/models/memberships.py @@ -31,7 +31,7 @@ from i18nfield.fields import I18nCharField from pretix.base.models import Customer from pretix.base.models.base import LoggedModel from pretix.base.models.organizer import Organizer -from pretix.base.settings import PERSON_NAME_SCHEMES +from pretix.helpers.names import build_name class MembershipType(LoggedModel): @@ -160,15 +160,7 @@ class Membership(models.Model): @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.customer.organizer.settings.name_scheme] - return scheme['concatenation'](self.attendee_name_parts).strip() + return build_name(self.attendee_name_parts, fallback_scheme=lambda: self.customer.organizer.settings.name_scheme) def is_valid(self, ev=None): if ev: diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index 5f901f9686..036688abd4 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -82,6 +82,7 @@ from pretix.base.signals import order_gracefully_delete from ...helpers import OF_SELF from ...helpers.countries import CachedCountries, FastCountryField from ...helpers.format import format_map +from ...helpers.names import build_name from ._transactions import ( _fail, _transactions_mark_order_clean, _transactions_mark_order_dirty, ) @@ -1448,18 +1449,15 @@ class AbstractPosition(models.Model): if self.attendee_name_parts is None: self.attendee_name_parts = {} super().save(*args, **kwargs) + print(self.pk, self.attendee_name_cached) @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() + return build_name(self.attendee_name_parts, fallback_scheme=lambda: self.event.settings.name_scheme) + + @property + def attendee_name_all_components(self): + return build_name(self.attendee_name_parts, "concatenation_all_components", fallback_scheme=lambda: self.event.settings.name_scheme) @property def state_name(self): @@ -2980,15 +2978,11 @@ class InvoiceAddress(models.Model): @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() + return build_name(self.name_parts, fallback_scheme=lambda: self.order.event.settings.name_scheme) or "" + + @property + def name_all_components(self): + return build_name(self.name_parts, "concatenation_all_components", fallback_scheme=lambda: self.order.event.settings.name_scheme) or "" def for_js(self): d = {} diff --git a/src/pretix/base/models/waitinglist.py b/src/pretix/base/models/waitinglist.py index 8d577938aa..1d42182153 100644 --- a/src/pretix/base/models/waitinglist.py +++ b/src/pretix/base/models/waitinglist.py @@ -35,9 +35,9 @@ from pretix.base.email import get_email_context from pretix.base.i18n import language from pretix.base.models import User, Voucher from pretix.base.services.mail import SendMailException, mail, render_mail -from pretix.base.settings import PERSON_NAME_SCHEMES from ...helpers.format import format_map +from ...helpers.names import build_name from .base import LoggedModel from .event import Event, SubEvent from .items import Item, ItemVariation @@ -136,15 +136,11 @@ class WaitingListEntry(LoggedModel): @property def name(self): - if not self.name_parts: - return None - 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: - scheme = PERSON_NAME_SCHEMES[self.event.settings.name_scheme] - return scheme['concatenation'](self.name_parts).strip() + return build_name(self.name_parts, fallback_scheme=lambda: self.event.settings.name_scheme) + + @property + def name_all_components(self): + return build_name(self.name_parts, "concatenation_all_components", fallback_scheme=lambda: self.event.settings.name_scheme) def send_voucher(self, quota_cache=None, user=None, auth=None): availability = ( diff --git a/src/pretix/base/settings.py b/src/pretix/base/settings.py index 76e1324890..312b816c61 100644 --- a/src/pretix/base/settings.py +++ b/src/pretix/base/settings.py @@ -3354,6 +3354,7 @@ PERSON_NAME_SCHEMES = OrderedDict([ ('full_name', _('Full name'), 2), ), 'concatenation': lambda d: str(d.get('full_name', '')), + 'concatenation_all_components': lambda d: str(d.get('full_name', '')) + " (\"" + d.get('calling_name', '') + "\")", 'sample': { 'full_name': pgettext_lazy('person_name_sample', 'John Doe'), 'calling_name': pgettext_lazy('person_name_sample', 'John'), @@ -3366,6 +3367,7 @@ PERSON_NAME_SCHEMES = OrderedDict([ ('latin_transcription', _('Latin transcription'), 2), ), 'concatenation': lambda d: str(d.get('full_name', '')), + 'concatenation_all_components': lambda d: str(d.get('full_name', '')) + " (" + d.get('latin_transcription', '') + ")", 'sample': { 'full_name': '庄司', 'latin_transcription': 'Shōji', @@ -3382,6 +3384,9 @@ PERSON_NAME_SCHEMES = OrderedDict([ str(p) for p in (d.get(key, '') for key in ["given_name", "family_name"]) if p ), 'concatenation_for_salutation': concatenation_for_salutation, + 'concatenation_all_components': lambda d: ' '.join( + str(p) for p in (d.get(key, '') for key in ["salutation", "given_name", "family_name"]) if p + ), 'sample': { 'salutation': pgettext_lazy('person_name_sample', 'Mr'), 'given_name': pgettext_lazy('person_name_sample', 'John'), @@ -3400,6 +3405,9 @@ PERSON_NAME_SCHEMES = OrderedDict([ str(p) for p in (d.get(key, '') for key in ["title", "given_name", "family_name"]) if p ), 'concatenation_for_salutation': concatenation_for_salutation, + 'concatenation_all_components': lambda d: ' '.join( + str(p) for p in (d.get(key, '') for key in ["salutation", "title", "given_name", "family_name"]) if p + ), 'sample': { 'salutation': pgettext_lazy('person_name_sample', 'Mr'), 'title': pgettext_lazy('person_name_sample', 'Dr'), @@ -3424,6 +3432,13 @@ PERSON_NAME_SCHEMES = OrderedDict([ str(d.get('degree', '')) ), 'concatenation_for_salutation': concatenation_for_salutation, + 'concatenation_all_components': lambda d: ( + ' '.join( + str(p) for p in (d.get(key, '') for key in ["salutation", "title", "given_name", "family_name"]) if p + ) + + str((', ' if d.get('degree') else '')) + + str(d.get('degree', '')) + ), 'sample': { 'salutation': pgettext_lazy('person_name_sample', 'Mr'), 'title': pgettext_lazy('person_name_sample', 'Dr'), diff --git a/src/pretix/control/templates/pretixcontrol/order/index.html b/src/pretix/control/templates/pretixcontrol/order/index.html index aab797e9ee..7050cd23b7 100644 --- a/src/pretix/control/templates/pretixcontrol/order/index.html +++ b/src/pretix/control/templates/pretixcontrol/order/index.html @@ -511,7 +511,7 @@
{% if line.item.ask_attendee_data and event.settings.attendee_names_asked %}
{% trans "Attendee name" %}
-
{% if line.attendee_name %}{{ line.attendee_name }}{% else %} +
{% if line.attendee_name %}{{ line.attendee_name_all_components }}{% else %} {% trans "not answered" %}{% endif %}
{% endif %} {% if line.item.ask_attendee_data and event.settings.attendee_emails_asked %} diff --git a/src/pretix/control/templates/pretixcontrol/waitinglist/index.html b/src/pretix/control/templates/pretixcontrol/waitinglist/index.html index b34416d854..e3bab5dbd9 100644 --- a/src/pretix/control/templates/pretixcontrol/waitinglist/index.html +++ b/src/pretix/control/templates/pretixcontrol/waitinglist/index.html @@ -178,7 +178,7 @@ {% endif %} {% if request.event.settings.waiting_list_names_asked %} - {{ e.name|default:"" }} + {{ e.name_all_components|default:"" }} {% endif %} {{ e.email }} {% if request.event.settings.waiting_list_phones_asked %} diff --git a/src/pretix/helpers/names.py b/src/pretix/helpers/names.py new file mode 100644 index 0000000000..7ff30db354 --- /dev/null +++ b/src/pretix/helpers/names.py @@ -0,0 +1,38 @@ +# +# This file is part of pretix (Community Edition). +# +# Copyright (C) 2014-2020 Raphael Michel and contributors +# Copyright (C) 2020-2021 rami.io GmbH and contributors +# +# This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General +# Public License as published by the Free Software Foundation in version 3 of the License. +# +# ADDITIONAL TERMS APPLY: Pursuant to Section 7 of the GNU Affero General Public License, additional terms are +# applicable granting you additional permissions and placing additional restrictions on your usage of this software. +# Please refer to the pretix LICENSE file to obtain the full terms applicable to this work. If you did not receive +# this file, see . +# +# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied +# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more +# details. +# +# You should have received a copy of the GNU Affero General Public License along with this program. If not, see +# . +# +from pretix.base.settings import PERSON_NAME_SCHEMES + + +def build_name(parts, concatenation=None, fallback_scheme=None): + if not parts: + return None + if "_legacy" in parts: + return parts["_legacy"] + if "_scheme" in parts: + scheme = PERSON_NAME_SCHEMES[parts["_scheme"]] + elif fallback_scheme: + scheme = PERSON_NAME_SCHEMES[fallback_scheme() if callable(fallback_scheme) else fallback_scheme] + else: + raise TypeError("Invalid name given.") + if not concatenation or concatenation not in scheme: + concatenation = "concatenation" + return scheme[concatenation](parts).strip()