mirror of
https://github.com/pretix/pretix.git
synced 2026-08-24 13:02:00 +00:00
Allow the automatic creation of customer accounts for guest users
This commit is contained in:
@@ -64,9 +64,9 @@ from pretix.base.i18n import (
|
||||
LazyLocaleException, get_language_without_region, language,
|
||||
)
|
||||
from pretix.base.models import (
|
||||
CartPosition, Device, Event, GiftCard, Item, ItemVariation, Membership,
|
||||
Order, OrderPayment, OrderPosition, Quota, Seat, SeatCategoryMapping, User,
|
||||
Voucher,
|
||||
CartPosition, Customer, Device, Event, GiftCard, Item, ItemVariation,
|
||||
Membership, Order, OrderPayment, OrderPosition, Quota, Seat,
|
||||
SeatCategoryMapping, User, Voucher,
|
||||
)
|
||||
from pretix.base.models.event import SubEvent
|
||||
from pretix.base.models.orders import (
|
||||
@@ -849,7 +849,7 @@ def _get_fees(positions: List[CartPosition], payment_requests: List[dict], addre
|
||||
def _create_order(event: Event, email: str, positions: List[CartPosition], now_dt: datetime,
|
||||
payment_requests: List[dict], locale: str=None, address: InvoiceAddress=None,
|
||||
meta_info: dict=None, sales_channel: str='web', shown_total=None,
|
||||
customer=None):
|
||||
customer=None, customer_attached=False):
|
||||
payments = []
|
||||
sales_channel = get_all_sales_channels()[sales_channel]
|
||||
|
||||
@@ -931,6 +931,8 @@ def _create_order(event: Event, email: str, positions: List[CartPosition], now_d
|
||||
if meta_info:
|
||||
for msg in meta_info.get('confirm_messages', []):
|
||||
order.log_action('pretix.event.order.consent', data={'msg': msg})
|
||||
if customer and customer_attached:
|
||||
customer.log_action('pretix.customer.order.attached', data={'order': order.code})
|
||||
|
||||
order_placed.send(event, order=order)
|
||||
return order, payments
|
||||
@@ -981,9 +983,6 @@ def _perform_order(event: Event, payment_requests: List[dict], position_ids: Lis
|
||||
if not p['pprov']:
|
||||
raise OrderError(error_messages['internal'])
|
||||
|
||||
if customer:
|
||||
customer = event.organizer.customers.get(pk=customer)
|
||||
|
||||
if email == settings.PRETIX_EMAIL_NONE_VALUE:
|
||||
email = None
|
||||
|
||||
@@ -995,6 +994,30 @@ def _perform_order(event: Event, payment_requests: List[dict], position_ids: Lis
|
||||
except InvoiceAddress.DoesNotExist:
|
||||
pass
|
||||
|
||||
customer_attached = False
|
||||
if customer:
|
||||
customer = event.organizer.customers.get(pk=customer)
|
||||
elif event.settings.customer_accounts_link_by_email in ('attach', 'create') and email:
|
||||
try:
|
||||
customer = event.organizer.customers.get(email__iexact=email)
|
||||
customer_attached = True
|
||||
except Customer.MultipleObjectsReturned:
|
||||
logger.warning(f'Multiple customer accounts found for {email}, not attaching.')
|
||||
except Customer.DoesNotExist:
|
||||
if event.settings.customer_accounts_link_by_email == 'create':
|
||||
customer = event.organizer.customers.create(
|
||||
email=email,
|
||||
name_parts=addr.name_parts if addr else None,
|
||||
phone=(meta_info or {}).get('contact_form_data', {}).get('phone'),
|
||||
is_active=True,
|
||||
is_verified=False,
|
||||
locale=locale,
|
||||
)
|
||||
customer.set_unusable_password()
|
||||
customer.save()
|
||||
customer.log_action('pretix.customer.created.auto', {})
|
||||
customer_attached = True
|
||||
|
||||
requires_seat = Exists(
|
||||
SeatCategoryMapping.objects.filter(
|
||||
Q(product=OuterRef('item'))
|
||||
@@ -1018,7 +1041,7 @@ def _perform_order(event: Event, payment_requests: List[dict], position_ids: Lis
|
||||
locale=locale,
|
||||
invoice_address=addr,
|
||||
meta_info=meta_info,
|
||||
customer=customer,
|
||||
customer=customer if not customer_attached else None,
|
||||
)
|
||||
|
||||
lockfn = NoLockManager
|
||||
@@ -1041,10 +1064,11 @@ def _perform_order(event: Event, payment_requests: List[dict], position_ids: Lis
|
||||
raise OrderError(error_messages['empty'])
|
||||
if len(position_ids) != len(positions):
|
||||
raise OrderError(error_messages['internal'])
|
||||
_check_positions(event, now_dt, positions, address=addr, sales_channel=sales_channel, customer=customer)
|
||||
_check_positions(event, now_dt, positions, address=addr, sales_channel=sales_channel,
|
||||
customer=customer if not customer_attached else None)
|
||||
order, payment_objs = _create_order(event, email, positions, now_dt, payment_requests,
|
||||
locale=locale, address=addr, meta_info=meta_info, sales_channel=sales_channel,
|
||||
shown_total=shown_total, customer=customer)
|
||||
shown_total=shown_total, customer=customer, customer_attached=customer_attached)
|
||||
try:
|
||||
for p in payment_objs:
|
||||
if p.provider == 'free':
|
||||
|
||||
@@ -159,13 +159,37 @@ DEFAULTS = {
|
||||
},
|
||||
'customer_accounts_link_by_email': {
|
||||
'default': 'False',
|
||||
'type': bool,
|
||||
'form_class': forms.BooleanField,
|
||||
'serializer_class': serializers.BooleanField,
|
||||
'type': str,
|
||||
'form_class': forms.ChoiceField,
|
||||
'serializer_class': serializers.ChoiceField,
|
||||
'serializer_kwargs': dict(
|
||||
choices=(
|
||||
('False', _('Keep guest orders separate and do not link them to customer accounts.')),
|
||||
('True', _('Do not attach guest orders to customer accounts, but show them in customer '
|
||||
'accounts with a verified matching email address.')),
|
||||
('attach', _('Attach guest orders to existing customer accounts with a matching email address if such '
|
||||
'an account exists.')),
|
||||
('create', _('Attach guest orders to existing customer accounts with a matching email and '
|
||||
'automatically create a customer account for all others.')),
|
||||
('forbidden', _('Do not allow guest orders.')),
|
||||
),
|
||||
),
|
||||
'form_kwargs': dict(
|
||||
label=_("Match orders based on email address"),
|
||||
help_text=_("This will allow registered customers to access orders made with the same email address, even if the customer "
|
||||
"was not logged in during the purchase.")
|
||||
label=_("Guest order handling"),
|
||||
widget=forms.RadioSelect,
|
||||
choices=(
|
||||
('False', _('Keep guest orders separate and do not link them to customer accounts.')),
|
||||
('True', _('Do not attach guest orders to customer accounts, but show them in customer '
|
||||
'accounts with a verified matching email address.')),
|
||||
('attach', _('Attach guest orders to existing customer accounts with a matching email address if '
|
||||
'such an account exists.')),
|
||||
('create', _('Attach guest orders to existing customer accounts with a matching email address and '
|
||||
'automatically create a customer account for all others.')),
|
||||
('forbidden', _('Do not allow guest orders.')),
|
||||
),
|
||||
help_text=_('Please be aware that creating customer accounts without a users consent might not be a '
|
||||
'good idea for privacy reasons in some jurisdictions or situations. We always recommend to '
|
||||
'let the user choose if they want an account.'),
|
||||
)
|
||||
},
|
||||
'max_items_per_order': {
|
||||
|
||||
Reference in New Issue
Block a user