forked from CGM_Public/pretix_original
Separate personalization from admission (#2990)
Co-authored-by: Richard Schreiber <schreiber@rami.io>
This commit is contained in:
@@ -295,6 +295,7 @@ class ItemCreateForm(I18nModelForm):
|
||||
self.user = kwargs.pop('user')
|
||||
kwargs.setdefault('initial', {})
|
||||
kwargs['initial'].setdefault('admission', True)
|
||||
kwargs['initial'].setdefault('personalized', True)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.fields['category'].queryset = self.instance.event.categories.all()
|
||||
@@ -403,6 +404,8 @@ class ItemCreateForm(I18nModelForm):
|
||||
self.instance.sales_channels = list(get_all_sales_channels().keys())
|
||||
|
||||
self.instance.position = (self.event.items.aggregate(p=Max('position'))['p'] or 0) + 1
|
||||
if not self.instance.admission:
|
||||
self.instance.personalized = False
|
||||
instance = super().save(*args, **kwargs)
|
||||
|
||||
if not self.event.has_subevents and not self.cleaned_data.get('has_variations'):
|
||||
@@ -494,6 +497,7 @@ class ItemCreateForm(I18nModelForm):
|
||||
'internal_name',
|
||||
'category',
|
||||
'admission',
|
||||
'personalized',
|
||||
'default_price',
|
||||
'tax_rule',
|
||||
]
|
||||
@@ -588,13 +592,14 @@ class ItemUpdateForm(I18nModelForm):
|
||||
'tax_rule',
|
||||
_("Gift card products should use a tax rule with a rate of 0 percent since sales tax will be applied when the gift card is redeemed.")
|
||||
)
|
||||
if d['admission']:
|
||||
if d.get('admission'):
|
||||
self.add_error(
|
||||
'admission',
|
||||
_(
|
||||
"Gift card products should not be admission products at the same time."
|
||||
)
|
||||
)
|
||||
|
||||
if d.get('require_membership') and not d.get('require_membership_types'):
|
||||
self.add_error(
|
||||
'require_membership_types',
|
||||
@@ -602,6 +607,18 @@ class ItemUpdateForm(I18nModelForm):
|
||||
"If a valid membership is required, at least one valid membership type needs to be selected."
|
||||
)
|
||||
)
|
||||
|
||||
if not d.get('admission'):
|
||||
d['personalized'] = False
|
||||
|
||||
if d.get('grant_membership_type'):
|
||||
if not d['grant_membership_type'].transferable and not d['personalized']:
|
||||
self.add_error(
|
||||
'personalized' if d['admission'] else 'admission',
|
||||
_("Your product grants a non-transferable membership and should therefore be a personalized "
|
||||
"admission ticket. Otherwise customers might not be able to use the membership later. If you "
|
||||
"want the membership to be non-personalized, set the membership type to be transferable.")
|
||||
)
|
||||
return d
|
||||
|
||||
def clean_picture(self):
|
||||
@@ -622,6 +639,7 @@ class ItemUpdateForm(I18nModelForm):
|
||||
'active',
|
||||
'sales_channels',
|
||||
'admission',
|
||||
'personalized',
|
||||
'description',
|
||||
'picture',
|
||||
'default_price',
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4>{% trans "Attendee data (once per admission ticket)" %}</h4>
|
||||
<h4>{% trans "Attendee data (once per personalized ticket)" %}</h4>
|
||||
|
||||
{% bootstrap_field sform.attendee_names_asked_required layout="control" %}
|
||||
{% bootstrap_field sform.attendee_emails_asked_required layout="control" %}
|
||||
|
||||
@@ -20,13 +20,19 @@
|
||||
<div class="col-md-9">
|
||||
<div class="big-radio radio">
|
||||
<label>
|
||||
<input type="radio" value="on" name="{{ form.admission.html_name }}" {% if form.admission.value %}checked{% endif %}>
|
||||
<span class="fa fa-user"></span>
|
||||
<input type="radio" value="on" name="{{ form.admission.html_name }}" {% if form.admission.value %}checked{% endif %} id="admission_on">
|
||||
<span class="fa fa-fw fa-user"></span>
|
||||
<strong>{% trans "Admission product" %}</strong><br>
|
||||
<div class="help-block">
|
||||
{% blocktrans trimmed %}
|
||||
Every purchase of this product represents one person who is allowed to enter your event.
|
||||
By default, pretix will only ask for attendee information and offer ticket downloads for these products.
|
||||
By default, we will only offer ticket downloads for these products.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
<div class="help-block">
|
||||
{% blocktrans trimmed %}
|
||||
Only purchases of such products will be considered "attendees" for most statistical
|
||||
purposes or within some plugins.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
<div class="help-block">
|
||||
@@ -40,12 +46,12 @@
|
||||
<div class="big-radio radio">
|
||||
<label>
|
||||
<input type="radio" value="" name="{{ form.admission.html_name }}" {% if not form.admission.value %}checked{% endif %}>
|
||||
<span class="fa fa-cube"></span>
|
||||
<span class="fa fa-fw fa-cube"></span>
|
||||
<strong>{% trans "Non-admission product" %}</strong>
|
||||
<div class="help-block">
|
||||
{% blocktrans trimmed %}
|
||||
A product that does not represent a person. By default, pretix will not ask for attendee information or offer
|
||||
ticket downloads.
|
||||
A product that does not represent a person. By default, we will not offer ticket downloads
|
||||
(but you can still enable ticket downloads in event settings or product settings).
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
<div class="help-block">
|
||||
@@ -58,6 +64,47 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" data-display-dependency="#admission_on">
|
||||
<label class="col-md-3 control-label">{% trans "Personalization" %}</label>
|
||||
<div class="col-md-9">
|
||||
<div class="big-radio radio">
|
||||
<label>
|
||||
<input type="radio" value="on" name="{{ form.personalized.html_name }}" {% if form.personalized.value %}checked{% endif %}>
|
||||
<span class="fa fa-fw fa-id-card-o"></span>
|
||||
<strong>{% trans "Personalized ticket" %}</strong><br>
|
||||
<div class="help-block">
|
||||
{% blocktrans trimmed %}
|
||||
When this ticket is purchased, the system will ask for a name or other details according
|
||||
to your event settings.
|
||||
{% endblocktrans %}
|
||||
{% if not request.event.settings.attendee_names_asked and not request.event.settings.attendee_emails_asked and not request.event.settings.attendee_company_asked and not request.event.settings.attendee_addresses_asked %}
|
||||
<br>
|
||||
<span class="text-warning">
|
||||
<span class="fa fa-warning" aria-hidden="true"></span>
|
||||
{% trans "This will currently have no effect since all data fields are turned off in event settings." %}
|
||||
</span>
|
||||
<a href="{% url "control:event.settings" organizer=request.event.organizer.slug event=request.event.slug %}#tab-0-2-open"
|
||||
class="btn btn-default btn-xs" target="_blank">{% trans "Change settings" %}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="big-radio radio">
|
||||
<label>
|
||||
<input type="radio" value="" name="{{ form.personalized.html_name }}" {% if not form.personalized.value %}checked{% endif %}>
|
||||
<span class="fa fa-fw fa-circle-o"></span>
|
||||
<strong>{% trans "Non-personalized ticket" %}</strong>
|
||||
<div class="help-block">
|
||||
{% blocktrans trimmed %}
|
||||
The system will not ask for a name or other attendee details. This only affects
|
||||
system-provided fields, you can still add your own questions.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% bootstrap_field form.category layout="control" %}
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
@@ -27,13 +27,19 @@
|
||||
{% endfor %}
|
||||
<div class="big-radio radio">
|
||||
<label>
|
||||
<input type="radio" value="on" name="{{ form.admission.html_name }}" {% if form.admission.value %}checked{% endif %}>
|
||||
<input type="radio" value="on" name="{{ form.admission.html_name }}" {% if form.admission.value %}checked{% endif %} id="admission_on">
|
||||
<span class="fa fa-fw fa-user"></span>
|
||||
<strong>{% trans "Admission product" %}</strong><br>
|
||||
<div class="help-block">
|
||||
{% blocktrans trimmed %}
|
||||
Every purchase of this product represents one person who is allowed to enter your event.
|
||||
By default, pretix will only ask for attendee information and offer ticket downloads for these products.
|
||||
By default, we will only offer ticket downloads for these products.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
<div class="help-block">
|
||||
{% blocktrans trimmed %}
|
||||
Only purchases of such products will be considered "attendees" for most statistical
|
||||
purposes or within some plugins.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
<div class="help-block">
|
||||
@@ -51,8 +57,8 @@
|
||||
<strong>{% trans "Non-admission product" %}</strong>
|
||||
<div class="help-block">
|
||||
{% blocktrans trimmed %}
|
||||
A product that does not represent a person. By default, pretix will not ask for attendee information or offer
|
||||
ticket downloads.
|
||||
A product that does not represent a person. By default, we will not offer ticket downloads
|
||||
(but you can still enable ticket downloads in event settings or product settings).
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
<div class="help-block">
|
||||
@@ -65,6 +71,52 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group" data-display-dependency="#admission_on">
|
||||
<label class="col-md-3 control-label">{% trans "Personalization" %}</label>
|
||||
<div class="col-md-9">
|
||||
{% for e in form.errors.personalized %}
|
||||
<div class="alert alert-danger has-error">
|
||||
{{ e }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class="big-radio radio">
|
||||
<label>
|
||||
<input type="radio" value="on" name="{{ form.personalized.html_name }}" {% if form.personalized.value %}checked{% endif %}>
|
||||
<span class="fa fa-fw fa-id-card-o"></span>
|
||||
<strong>{% trans "Personalized ticket" %}</strong><br>
|
||||
<div class="help-block">
|
||||
{% blocktrans trimmed %}
|
||||
When this ticket is purchased, the system will ask for a name or other details according
|
||||
to your event settings.
|
||||
{% endblocktrans %}
|
||||
{% if not request.event.settings.attendee_names_asked and not request.event.settings.attendee_emails_asked and not request.event.settings.attendee_company_asked and not request.event.settings.attendee_addresses_asked %}
|
||||
<br>
|
||||
<span class="text-warning">
|
||||
<span class="fa fa-warning" aria-hidden="true"></span>
|
||||
{% trans "This will currently have no effect since all data fields are turned off in event settings." %}
|
||||
</span>
|
||||
<a href="{% url "control:event.settings" organizer=request.event.organizer.slug event=request.event.slug %}#tab-0-2-open"
|
||||
class="btn btn-default btn-xs" target="_blank">{% trans "Change settings" %}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="big-radio radio">
|
||||
<label>
|
||||
<input type="radio" value="" name="{{ form.personalized.html_name }}" {% if not form.personalized.value %}checked{% endif %}>
|
||||
<span class="fa fa-fw fa-circle-o"></span>
|
||||
<strong>{% trans "Non-personalized ticket" %}</strong>
|
||||
<div class="help-block">
|
||||
{% blocktrans trimmed %}
|
||||
The system will not ask for a name or other attendee details. This only affects
|
||||
system-provided fields, you can still add your own questions.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% bootstrap_field form.description layout="control" %}
|
||||
{% bootstrap_field form.picture layout="control" %}
|
||||
{% bootstrap_field form.require_approval layout="control" %}
|
||||
|
||||
@@ -81,7 +81,11 @@
|
||||
</td>
|
||||
<td>
|
||||
{% if i.admission %}
|
||||
<span class="fa fa-user fa-fw text-muted" data-toggle="tooltip" title="{% trans "Admission ticket" %}"></span>
|
||||
{% if i.personalized %}
|
||||
<span class="fa fa-id-card-o fa-fw text-muted" data-toggle="tooltip" title="{% trans "Personalized admission ticket" %}"></span>
|
||||
{% else %}
|
||||
<span class="fa fa-user fa-fw text-muted" data-toggle="tooltip" title="{% trans "Admission ticket without personalization" %}"></span>
|
||||
{% endif %}
|
||||
{% elif i.issue_giftcard %}
|
||||
<span class="fa fa-gift fa-fw text-muted" data-toggle="tooltip" title="{% trans "Gift card" %}"></span>
|
||||
{% endif %}
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% else %}
|
||||
<small>{% trans "All admission products" %}</small>
|
||||
<small>{% trans "All personalized products" %}</small>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td class="dnd-container">
|
||||
|
||||
@@ -468,12 +468,12 @@
|
||||
{% endif %}
|
||||
{% if line.has_questions %}
|
||||
<dl>
|
||||
{% if line.item.admission and event.settings.attendee_names_asked %}
|
||||
{% if line.item.ask_attendee_data and event.settings.attendee_names_asked %}
|
||||
<dt>{% trans "Attendee name" %}</dt>
|
||||
<dd>{% if line.attendee_name %}{{ line.attendee_name }}{% else %}
|
||||
<em>{% trans "not answered" %}</em>{% endif %}</dd>
|
||||
{% endif %}
|
||||
{% if line.item.admission and event.settings.attendee_emails_asked %}
|
||||
{% if line.item.ask_attendee_data and event.settings.attendee_emails_asked %}
|
||||
<dt>{% trans "Attendee email" %}</dt>
|
||||
<dd>
|
||||
{% if line.attendee_email %}
|
||||
@@ -496,7 +496,7 @@
|
||||
{% endif %}
|
||||
</dd>
|
||||
{% endif %}
|
||||
{% if line.item.admission and event.settings.attendee_company_asked %}
|
||||
{% if line.item.ask_attendee_data and event.settings.attendee_company_asked %}
|
||||
<dt>
|
||||
{% trans "Attendee company" %}
|
||||
</dt>
|
||||
@@ -504,7 +504,7 @@
|
||||
{% if line.company %}{{ line.company }}{% else %}<em>{% trans "not answered" %}</em>{% endif %}
|
||||
</dd>
|
||||
{% endif %}
|
||||
{% if line.item.admission and event.settings.attendee_addresses_asked %}
|
||||
{% if line.item.ask_attendee_data and event.settings.attendee_addresses_asked %}
|
||||
<dt>
|
||||
{% trans "Attendee address" %}
|
||||
</dt>
|
||||
|
||||
@@ -1204,7 +1204,7 @@ class ItemCreate(EventPermissionRequiredMixin, CreateView):
|
||||
initial['tax_rule'] = trs[0]
|
||||
|
||||
if self.copy_from:
|
||||
fields = ('name', 'internal_name', 'category', 'admission', 'default_price', 'tax_rule')
|
||||
fields = ('name', 'internal_name', 'category', 'admission', 'personalized', 'default_price', 'tax_rule')
|
||||
for f in fields:
|
||||
initial[f] = getattr(self.copy_from, f)
|
||||
initial['copy_from'] = self.copy_from
|
||||
|
||||
@@ -383,8 +383,8 @@ class OrderDetail(OrderView):
|
||||
|
||||
p.has_questions = (
|
||||
p.additional_fields or
|
||||
(p.item.admission and self.request.event.settings.attendee_names_asked) or
|
||||
(p.item.admission and self.request.event.settings.attendee_emails_asked) or
|
||||
(p.item.ask_attendee_data and self.request.event.settings.attendee_names_asked) or
|
||||
(p.item.ask_attendee_data and self.request.event.settings.attendee_emails_asked) or
|
||||
p.item.questions.all()
|
||||
)
|
||||
p.cache_answers()
|
||||
|
||||
Reference in New Issue
Block a user