mirror of
https://github.com/pretix/pretix.git
synced 2025-12-29 18:02:26 +00:00
Compare commits
1 Commits
widget-sea
...
dnspython2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cdb992134 |
@@ -87,18 +87,6 @@ website. If you confident to have a good reason for not using SSL, you can overr
|
||||
|
||||
<pretix-widget event="https://pretix.eu/demo/democon/" skip-ssl-check></pretix-widget>
|
||||
|
||||
Seating plans
|
||||
-------------
|
||||
|
||||
By default, events with seating plans just show a button that opens the seating plan. You can also have the seating
|
||||
plan embedded into the widget directly by using::
|
||||
|
||||
<pretix-widget event="https://pretix.eu/demo/democon/" seating-embedded></pretix-widget>
|
||||
|
||||
Note that the seating plan will only be embedded if the widget has enough space (currently min. 992 pixels width, may change
|
||||
in the future) and that the seating plan part of the widget can unfortunately *not* be styled with CSS like the rest of
|
||||
the widget.
|
||||
|
||||
Always open a new tab
|
||||
---------------------
|
||||
|
||||
|
||||
@@ -59,10 +59,10 @@ class RelativeDateWrapper:
|
||||
def date(self, event) -> datetime.date:
|
||||
from .models import SubEvent
|
||||
|
||||
if isinstance(self.data, datetime.datetime):
|
||||
return self.data.date()
|
||||
elif isinstance(self.data, datetime.date):
|
||||
if isinstance(self.data, datetime.date):
|
||||
return self.data
|
||||
elif isinstance(self.data, datetime.datetime):
|
||||
return self.data.date()
|
||||
else:
|
||||
if self.data.minutes_before is not None:
|
||||
raise ValueError('A minute-based relative datetime can not be used as a date')
|
||||
|
||||
@@ -140,7 +140,7 @@ error_messages = {
|
||||
'addon_min_count': _('You need to select at least %(min)s add-ons from the category %(cat)s for the '
|
||||
'product %(base)s.'),
|
||||
'addon_no_multi': _('You can select every add-ons from the category %(cat)s for the product %(base)s at most once.'),
|
||||
'addon_only': _('One of the products you selected can only be bought as an add-on to another product.'),
|
||||
'addon_only': _('One of the products you selected can only be bought as an add-on to another project.'),
|
||||
'bundled_only': _('One of the products you selected can only be bought part of a bundle.'),
|
||||
'seat_required': _('You need to select a specific seat.'),
|
||||
'seat_invalid': _('Please select a valid seat.'),
|
||||
|
||||
@@ -353,12 +353,6 @@ class Recover(TemplateView):
|
||||
user.save()
|
||||
messages.success(request, _('You can now login using your new password.'))
|
||||
user.log_action('pretix.control.auth.user.forgot_password.recovered')
|
||||
|
||||
has_redis = settings.HAS_REDIS
|
||||
if has_redis:
|
||||
from django_redis import get_redis_connection
|
||||
rc = get_redis_connection("redis")
|
||||
rc.delete('pretix_pwreset_%s' % user.id)
|
||||
return redirect('control:auth.login')
|
||||
else:
|
||||
return self.get(request, *args, **kwargs)
|
||||
|
||||
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-12-14 13:09+0000\n"
|
||||
"PO-Revision-Date: 2022-12-21 20:00+0000\n"
|
||||
"Last-Translator: Fazenda Dengo <fazendadengo@gmail.com>\n"
|
||||
"PO-Revision-Date: 2021-09-27 06:00+0000\n"
|
||||
"Last-Translator: Diego Rodrigo <diegorodrigo90@gmail.com>\n"
|
||||
"Language-Team: Portuguese (Brazil) <https://translate.pretix.eu/projects/"
|
||||
"pretix/pretix/pt_BR/>\n"
|
||||
"Language: pt_BR\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 4.15\n"
|
||||
"X-Generator: Weblate 4.8\n"
|
||||
|
||||
#: pretix/api/auth/devicesecurity.py:28
|
||||
msgid ""
|
||||
@@ -9268,8 +9268,10 @@ msgstr "Nome do evento"
|
||||
#: pretix/base/settings.py:3031 pretix/base/settings.py:3045
|
||||
#: pretix/base/settings.py:3096 pretix/base/settings.py:3114
|
||||
#: pretix/base/settings.py:3133
|
||||
#, fuzzy
|
||||
#| msgid "Full name"
|
||||
msgid "Family name"
|
||||
msgstr "Sobrenome"
|
||||
msgstr "Nome completo"
|
||||
|
||||
#: pretix/base/settings.py:2943 pretix/base/settings.py:2959
|
||||
#: pretix/base/settings.py:2975 pretix/base/settings.py:2990
|
||||
|
||||
@@ -8,8 +8,8 @@ msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-12-14 13:09+0000\n"
|
||||
"PO-Revision-Date: 2022-12-21 20:00+0000\n"
|
||||
"Last-Translator: Fazenda Dengo <fazendadengo@gmail.com>\n"
|
||||
"PO-Revision-Date: 2022-11-28 19:03+0000\n"
|
||||
"Last-Translator: Vasco Baleia <vb2003.12@gmail.com>\n"
|
||||
"Language-Team: Portuguese (Portugal) <https://translate.pretix.eu/projects/"
|
||||
"pretix/pretix/pt_PT/>\n"
|
||||
"Language: pt_PT\n"
|
||||
@@ -17,7 +17,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: Weblate 4.15\n"
|
||||
"X-Generator: Weblate 4.14.1\n"
|
||||
|
||||
#: pretix/api/auth/devicesecurity.py:28
|
||||
msgid ""
|
||||
@@ -9560,7 +9560,7 @@ msgstr "Nome próprio"
|
||||
#: pretix/base/settings.py:3096 pretix/base/settings.py:3114
|
||||
#: pretix/base/settings.py:3133
|
||||
msgid "Family name"
|
||||
msgstr "Sobrenome"
|
||||
msgstr "Apelido"
|
||||
|
||||
#: pretix/base/settings.py:2943 pretix/base/settings.py:2959
|
||||
#: pretix/base/settings.py:2975 pretix/base/settings.py:2990
|
||||
|
||||
@@ -698,7 +698,7 @@ class PaypalMethod(BasePaymentProvider):
|
||||
except ReferencedPayPalObject.MultipleObjectsReturned:
|
||||
pass
|
||||
|
||||
if capture.status != 'COMPLETED':
|
||||
if capture.status == 'PENDING':
|
||||
messages.warning(request, _('PayPal has not yet approved the payment. We will inform you as '
|
||||
'soon as the payment completed.'))
|
||||
payment.info = json.dumps(pp_captured_order.dict())
|
||||
|
||||
@@ -73,21 +73,12 @@ var pretixpaypal = {
|
||||
pretixpaypal.locale = this.guessLocale();
|
||||
}
|
||||
|
||||
$("input[name=payment][value^='paypal']").change(function () {
|
||||
if (pretixpaypal.paypal !== null) {
|
||||
pretixpaypal.renderButton($(this).val());
|
||||
} else {
|
||||
// If no payment option is selected, and we're not on the paypage (which doesn't have a continue button),
|
||||
// disable the continue button
|
||||
if (!pretixpaypal.paypage) {
|
||||
if (!pretixpaypal.continue_button[0].form.elements['payment'].value) {
|
||||
pretixpaypal.continue_button.prop("disabled", true);
|
||||
}
|
||||
});
|
||||
|
||||
$("input[name=payment]").not("[value^='paypal']").change(function () {
|
||||
pretixpaypal.restore();
|
||||
});
|
||||
|
||||
// If paypal is pre-selected, we must disable the continue button and handle it after SDK is loaded
|
||||
if ($("input[name=payment][value^='paypal']").is(':checked')) {
|
||||
pretixpaypal.continue_button.prop("disabled", true);
|
||||
}
|
||||
|
||||
// We are setting the cogwheel already here, as the renderAPM() method might take some time to get loaded.
|
||||
@@ -148,6 +139,14 @@ var pretixpaypal = {
|
||||
pretixpaypal.renderAPMs();
|
||||
}
|
||||
|
||||
$("input[name=payment][value^='paypal']").change(function () {
|
||||
pretixpaypal.renderButton($(this).val());
|
||||
});
|
||||
|
||||
$("input[name=payment]").not("[value^='paypal']").change(function () {
|
||||
pretixpaypal.restore();
|
||||
});
|
||||
|
||||
if ($("input[name=payment][value^='paypal']").is(':checked')) {
|
||||
pretixpaypal.renderButton($("input[name=payment][value^='paypal']:checked").val());
|
||||
} else if ($(".payment-redo-form").length) {
|
||||
@@ -163,8 +162,8 @@ var pretixpaypal = {
|
||||
$('#paypal-button-container').empty()
|
||||
pretixpaypal.continue_button.text(gettext('Continue'));
|
||||
pretixpaypal.continue_button.show();
|
||||
pretixpaypal.continue_button.prop("disabled", false);
|
||||
}
|
||||
pretixpaypal.continue_button.prop("disabled", false);
|
||||
},
|
||||
|
||||
renderButton: function (method) {
|
||||
@@ -322,15 +321,6 @@ var pretixpaypal = {
|
||||
};
|
||||
|
||||
$(function () {
|
||||
// This script is always loaded if paypal is enabled as a payment method, regardless of
|
||||
// whether it is available (it could e.g. be hidden or limited to certain countries).
|
||||
// We do not want to unnecessarily load the sdk.
|
||||
// If no paypal/paypal_apm payment option is present and we are not on
|
||||
// the (APM) PayView, then we do not need the SDK.
|
||||
if (!$("input[name=payment][value^='paypal']").length && !$('#paypal-button-container').data('paypage')) {
|
||||
return
|
||||
}
|
||||
|
||||
pretixpaypal.load();
|
||||
|
||||
(async() => {
|
||||
|
||||
@@ -426,10 +426,7 @@ def webhook(request, *args, **kwargs):
|
||||
if not payment:
|
||||
return HttpResponse('Payment not found', status=200)
|
||||
|
||||
payment.order.log_action('pretix.plugins.paypal.event', data={
|
||||
**event_json,
|
||||
'_order_state': sale.dict(),
|
||||
})
|
||||
payment.order.log_action('pretix.plugins.paypal.event', data=event_json)
|
||||
|
||||
if payment.state == OrderPayment.PAYMENT_STATE_CONFIRMED and sale['status'] in ('PARTIALLY_REFUNDED', 'REFUNDED', 'COMPLETED'):
|
||||
if event_json['resource_type'] == 'refund':
|
||||
@@ -473,27 +470,10 @@ def webhook(request, *args, **kwargs):
|
||||
elif payment.state in (OrderPayment.PAYMENT_STATE_PENDING, OrderPayment.PAYMENT_STATE_CREATED,
|
||||
OrderPayment.PAYMENT_STATE_CANCELED, OrderPayment.PAYMENT_STATE_FAILED) \
|
||||
and sale['status'] == 'COMPLETED':
|
||||
any_captures = False
|
||||
all_captures_completed = True
|
||||
for purchaseunit in sale['purchase_units']:
|
||||
for capture in purchaseunit['payments']['captures']:
|
||||
try:
|
||||
ReferencedPayPalObject.objects.get_or_create(order=payment.order, payment=payment,
|
||||
reference=capture['id'])
|
||||
except ReferencedPayPalObject.MultipleObjectsReturned:
|
||||
pass
|
||||
|
||||
if capture['status'] not in ('COMPLETED', 'REFUNDED', 'PARTIALLY_REFUNDED'):
|
||||
all_captures_completed = False
|
||||
else:
|
||||
any_captures = True
|
||||
if any_captures and all_captures_completed:
|
||||
try:
|
||||
payment.info = json.dumps(sale.dict())
|
||||
payment.save(update_fields=['info'])
|
||||
payment.confirm()
|
||||
except Quota.QuotaExceededException:
|
||||
pass
|
||||
try:
|
||||
payment.confirm()
|
||||
except Quota.QuotaExceededException:
|
||||
pass
|
||||
|
||||
return HttpResponse(status=200)
|
||||
|
||||
|
||||
@@ -663,15 +663,11 @@ class EventIndex(EventViewMixin, EventListMixin, CartMixin, TemplateView):
|
||||
return context
|
||||
|
||||
|
||||
@method_decorator(allow_frame_if_namespaced, 'dispatch')
|
||||
@method_decorator(iframe_entry_view_wrapper, 'dispatch')
|
||||
class SeatingPlanView(EventViewMixin, TemplateView):
|
||||
template_name = "pretixpresale/event/seatingplan.html"
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
r = super().dispatch(request, *args, **kwargs)
|
||||
r.xframe_options_exempt = True
|
||||
return r
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
from pretix.presale.views.cart import get_or_create_cart_id
|
||||
|
||||
|
||||
@@ -243,7 +243,6 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
voucher=self.voucher,
|
||||
channel=self.request.sales_channel.identifier,
|
||||
base_qs=qs,
|
||||
require_seat=None,
|
||||
memberships=(
|
||||
self.request.customer.usable_memberships(
|
||||
for_event=self.subevent or self.request.event,
|
||||
@@ -253,7 +252,7 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
)
|
||||
|
||||
grps = []
|
||||
for cat, g in item_group_by_category([i for i in items if not i.requires_seat]):
|
||||
for cat, g in item_group_by_category(items):
|
||||
grps.append({
|
||||
'id': cat.pk if cat else None,
|
||||
'name': str(cat.name) if cat else None,
|
||||
@@ -313,7 +312,7 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
} for item in g
|
||||
]
|
||||
})
|
||||
return grps, display_add_to_cart, len(items), items
|
||||
return grps, display_add_to_cart, len(items)
|
||||
|
||||
def post_process(self, data):
|
||||
data['poweredby'] = get_powered_by(self.request, safelink=False)
|
||||
@@ -712,30 +711,14 @@ class WidgetAPIProductList(EventListMixin, View):
|
||||
fail = True
|
||||
|
||||
if not fail and (ev.presale_is_running or request.event.settings.show_items_outside_presale_period):
|
||||
data['items_by_category'], data['display_add_to_cart'], data['itemnum'], items = self._get_items()
|
||||
data['items_by_category'], data['display_add_to_cart'], data['itemnum'] = self._get_items()
|
||||
data['display_add_to_cart'] = data['display_add_to_cart'] and ev.presale_is_running
|
||||
else:
|
||||
items = []
|
||||
data['items_by_category'] = []
|
||||
data['display_add_to_cart'] = False
|
||||
data['itemnum'] = 0
|
||||
|
||||
data['has_seating_plan'] = ev.seating_plan is not None
|
||||
data['has_seating_plan_waitinglist'] = False
|
||||
if request.event.settings.waiting_list_enabled and ev.presale_is_running:
|
||||
for i in items:
|
||||
if not i.allow_waitinglist or not i.requires_seat:
|
||||
continue
|
||||
|
||||
if i.has_variations:
|
||||
for v in i.available_variations:
|
||||
if v.cached_availability[0] != Quota.AVAILABILITY_OK:
|
||||
data['has_seating_plan_waitinglist'] = True
|
||||
break
|
||||
else:
|
||||
if i.cached_availability[0] != Quota.AVAILABILITY_OK:
|
||||
data['has_seating_plan_waitinglist'] = True
|
||||
break
|
||||
|
||||
vouchers_exist = self.request.event.get_cache().get('vouchers_exist')
|
||||
if vouchers_exist is None:
|
||||
|
||||
@@ -130,7 +130,6 @@ DATABASES = {
|
||||
'HOST': config.get('database', 'host', fallback=''),
|
||||
'PORT': config.get('database', 'port', fallback=''),
|
||||
'CONN_MAX_AGE': 0 if db_backend == 'sqlite3' else 120,
|
||||
'CONN_HEALTH_CHECKS': db_backend != 'sqlite3', # Will only be used from Django 4.1 onwards
|
||||
'OPTIONS': db_options,
|
||||
'TEST': {
|
||||
'CHARSET': 'utf8mb4',
|
||||
|
||||
@@ -53,7 +53,6 @@ var strings = {
|
||||
'next_week': django.pgettext('widget', 'Next week'),
|
||||
'previous_week': django.pgettext('widget', 'Previous week'),
|
||||
'show_seating': django.pgettext('widget', 'Open seat selection'),
|
||||
'seating_plan_waiting_list': django.pgettext('widget', 'Some or all ticket categories are currently sold out. If you want, you can add yourself to the waiting list. We will then notify if seats are available again.'),
|
||||
'load_more': django.pgettext('widget', 'Load more'),
|
||||
'days': {
|
||||
'MO': django.gettext('Mo'),
|
||||
@@ -141,21 +140,18 @@ var api = {
|
||||
},
|
||||
|
||||
'_postFormJSON': function (endpoint, form, callback, err_callback) {
|
||||
var params;
|
||||
if (Array.isArray(form)) {
|
||||
params = form
|
||||
} else {
|
||||
params = [].filter.call(form.elements, function (el) {
|
||||
return (el.type !== 'checkbox' && el.type !== 'radio') || el.checked;
|
||||
}).filter(function (el) {
|
||||
return !!el.name && !!el.value;
|
||||
}).filter(function (el) {
|
||||
var params = [].filter.call(form.elements, function (el) {
|
||||
return (el.type !== 'checkbox' && el.type !== 'radio') || el.checked;
|
||||
})
|
||||
.filter(function (el) {
|
||||
return !!el.name && !!el.value;
|
||||
})
|
||||
.filter(function (el) {
|
||||
return !el.disabled;
|
||||
})
|
||||
}
|
||||
params = params.map(function (el) {
|
||||
return encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value);
|
||||
}).join('&');
|
||||
.map(function (el) {
|
||||
return encodeURIComponent(el.name) + '=' + encodeURIComponent(el.value);
|
||||
}).join('&');
|
||||
|
||||
var xhr = api._getXHR();
|
||||
xhr.open("POST", endpoint, true);
|
||||
@@ -364,7 +360,6 @@ Vue.component('variation', {
|
||||
template: ('<div class="pretix-widget-variation">'
|
||||
+ '<div class="pretix-widget-item-row">'
|
||||
|
||||
// Variation description
|
||||
+ '<div class="pretix-widget-item-info-col">'
|
||||
+ '<div class="pretix-widget-item-title-and-description">'
|
||||
+ '<strong class="pretix-widget-item-title">{{ variation.value }}</strong>'
|
||||
@@ -376,15 +371,12 @@ Vue.component('variation', {
|
||||
+ '</div>'
|
||||
+ '</div>'
|
||||
|
||||
// Price
|
||||
+ '<div class="pretix-widget-item-price-col">'
|
||||
+ '<pricebox :price="variation.price" :free_price="item.free_price" :original_price="orig_price"'
|
||||
+ ' :field_name="\'price_\' + item.id + \'_\' + variation.id" v-if="$root.showPrices">'
|
||||
+ '</pricebox>'
|
||||
+ '<span v-if="!$root.showPrices"> </span>'
|
||||
+ '</div>'
|
||||
|
||||
// Availability
|
||||
+ '<div class="pretix-widget-item-availability-col">'
|
||||
+ '<availbox :item="item" :variation="variation"></availbox>'
|
||||
+ '</div>'
|
||||
@@ -412,7 +404,6 @@ Vue.component('item', {
|
||||
template: ('<div v-bind:class="classObject">'
|
||||
+ '<div class="pretix-widget-item-row pretix-widget-main-item-row">'
|
||||
|
||||
// Product description
|
||||
+ '<div class="pretix-widget-item-info-col">'
|
||||
+ '<img :src="item.picture" v-if="item.picture" class="pretix-widget-item-picture">'
|
||||
+ '<div class="pretix-widget-item-title-and-description">'
|
||||
@@ -432,7 +423,6 @@ Vue.component('item', {
|
||||
+ '</div>'
|
||||
+ '</div>'
|
||||
|
||||
// Price
|
||||
+ '<div class="pretix-widget-item-price-col">'
|
||||
+ '<pricebox :price="item.price" :free_price="item.free_price" v-if="!item.has_variations && $root.showPrices"'
|
||||
+ ' :field_name="\'price_\' + item.id" :original_price="item.original_price">'
|
||||
@@ -440,8 +430,6 @@ Vue.component('item', {
|
||||
+ '<div class="pretix-widget-pricebox" v-if="item.has_variations && $root.showPrices">{{ pricerange }}</div>'
|
||||
+ '<span v-if="!$root.showPrices"> </span>'
|
||||
+ '</div>'
|
||||
|
||||
// Availability
|
||||
+ '<div class="pretix-widget-item-availability-col">'
|
||||
+ '<a v-if="show_toggle" href="#" @click.prevent.stop="expand">'+ strings.variations + '</a>'
|
||||
+ '<availbox v-if="!item.has_variations" :item="item"></availbox>'
|
||||
@@ -450,7 +438,6 @@ Vue.component('item', {
|
||||
+ '<div class="pretix-widget-clear"></div>'
|
||||
+ '</div>'
|
||||
|
||||
// Variations
|
||||
+ '<div :class="varClasses" v-if="item.has_variations">'
|
||||
+ '<variation v-for="variation in item.variations" :variation="variation" :item="item" :key="variation.id">'
|
||||
+ '</variation>'
|
||||
@@ -525,7 +512,7 @@ Vue.component('category', {
|
||||
});
|
||||
|
||||
var shared_methods = {
|
||||
buy: function (event, data) {
|
||||
buy: function (event) {
|
||||
if (this.$root.useIframe) {
|
||||
if (event) {
|
||||
event.preventDefault();
|
||||
@@ -544,7 +531,7 @@ var shared_methods = {
|
||||
this.$root.overlay.frame_loading = true;
|
||||
|
||||
this.async_task_interval = 100;
|
||||
var form = data === undefined ? this.$refs.form : data;
|
||||
var form = this.$refs.form;
|
||||
if (form === undefined) {
|
||||
form = this.$refs.formcomp.$refs.form;
|
||||
}
|
||||
@@ -666,7 +653,7 @@ var shared_methods = {
|
||||
}
|
||||
},
|
||||
handleResize: function () {
|
||||
this.clientWidth = this.$refs.wrapper.clientWidth;
|
||||
this.mobile = this.$refs.wrapper.clientWidth <= 800;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -677,7 +664,7 @@ var shared_widget_data = function () {
|
||||
async_task_timeout: null,
|
||||
async_task_interval: 100,
|
||||
voucher: null,
|
||||
clientWidth: 1000,
|
||||
mobile: false,
|
||||
}
|
||||
};
|
||||
|
||||
@@ -773,7 +760,6 @@ Vue.component('pretix-overlay', {
|
||||
|
||||
Vue.component('pretix-widget-event-form', {
|
||||
template: ('<div class="pretix-widget-event-form">'
|
||||
// Back navigation
|
||||
+ '<div class="pretix-widget-event-list-back" v-if="$root.events || $root.weeks || $root.days">'
|
||||
+ '<a href="#" @click.prevent.stop="back_to_list" v-if="!$root.subevent">‹ '
|
||||
+ strings['back_to_list']
|
||||
@@ -782,28 +768,18 @@ Vue.component('pretix-widget-event-form', {
|
||||
+ strings['back_to_dates']
|
||||
+ '</a>'
|
||||
+ '</div>'
|
||||
|
||||
// Event name
|
||||
+ '<div class="pretix-widget-event-header" v-if="$root.events || $root.weeks || $root.days">'
|
||||
+ '<strong>{{ $root.name }}</strong>'
|
||||
+ '</div>'
|
||||
|
||||
// Date range
|
||||
+ '<div class="pretix-widget-event-details" v-if="($root.events || $root.weeks || $root.days) && $root.date_range">'
|
||||
+ '{{ $root.date_range }}'
|
||||
+ '</div>'
|
||||
|
||||
// Form start
|
||||
+ '<div class="pretix-widget-event-description" v-if="($root.events || $root.weeks || $root.days) && $root.frontpage_text" v-html="$root.frontpage_text"></div>'
|
||||
+ '<form method="post" :action="$root.formAction" ref="form" :target="$root.formTarget">'
|
||||
+ '<input type="hidden" name="_voucher_code" :value="$root.voucher_code" v-if="$root.voucher_code">'
|
||||
+ '<input type="hidden" name="subevent" :value="$root.subevent" />'
|
||||
+ '<input type="hidden" name="widget_data" :value="$root.widget_data_json" />'
|
||||
|
||||
// Error message
|
||||
+ '<div class="pretix-widget-error-message" v-if="$root.error">{{ $root.error }}</div>'
|
||||
|
||||
// Resume cart
|
||||
+ '<div class="pretix-widget-info-message pretix-widget-clickable"'
|
||||
+ ' v-if="$root.cart_exists">'
|
||||
+ '<button @click.prevent.stop="$parent.resume" class="pretix-widget-resume-button" type="button">'
|
||||
@@ -812,43 +788,16 @@ Vue.component('pretix-widget-event-form', {
|
||||
+ strings['cart_exists']
|
||||
+ '<div class="pretix-widget-clear"></div>'
|
||||
+ '</div>'
|
||||
|
||||
// Seating plan
|
||||
+ '<div class="pretix-widget-seating-link-wrapper" v-if="$root.has_seating_plan && !show_seating_plan_inline">'
|
||||
+ '<div class="pretix-widget-seating-link-wrapper" v-if="this.$root.has_seating_plan">'
|
||||
+ '<button class="pretix-widget-seating-link" @click.prevent.stop="$root.startseating">'
|
||||
+ strings['show_seating']
|
||||
+ '</button>'
|
||||
+ '</div>'
|
||||
+ '<div class="pretix-widget-seating-embed" v-else-if="$root.has_seating_plan && show_seating_plan_inline">'
|
||||
+ '<iframe :key="\'seatingframe\' + $root.loadid" class="pretix-widget-seating-embed-iframe" ref="seatingframe"'
|
||||
+ ' :src="seatingframe" frameborder="0" referrerpolicy="origin" allowtransparency="true">'
|
||||
+ '</iframe>'
|
||||
+ '</div>'
|
||||
|
||||
// Waiting list for seating plan
|
||||
+ '<div class="pretix-widget-seating-waitinglist" v-if="this.$root.has_seating_plan && this.$root.has_seating_plan_waitinglist">'
|
||||
+ '<div class="pretix-widget-seating-waitinglist-text">'
|
||||
+ strings['seating_plan_waiting_list']
|
||||
+ '</div>'
|
||||
+ '<div class="pretix-widget-seating-waitinglist-button-wrap">'
|
||||
+ '<button class="pretix-widget-seating-waitinglist-button" @click.prevent.stop="$root.startseating">'
|
||||
+ strings['waiting_list']
|
||||
+ '</button>'
|
||||
+ '</div>'
|
||||
+ '<div class="pretix-widget-clear"></div>'
|
||||
+ '</div>'
|
||||
|
||||
// Actual product list
|
||||
+ '<category v-for="category in this.$root.categories" :category="category" :key="category.id"></category>'
|
||||
|
||||
// Buy button
|
||||
+ '<div class="pretix-widget-action" v-if="$root.display_add_to_cart">'
|
||||
+ '<button @click="$parent.buy" type="submit" :disabled="buy_disabled">{{ this.buy_label }}</button>'
|
||||
+ '</div>'
|
||||
|
||||
+ '</form>'
|
||||
|
||||
// Voucher form
|
||||
+ '<form method="get" :action="$root.voucherFormTarget" target="_blank" '
|
||||
+ ' v-if="$root.vouchers_exist && !$root.disable_vouchers && !$root.voucher_code">'
|
||||
+ '<div class="pretix-widget-voucher">'
|
||||
@@ -863,10 +812,8 @@ Vue.component('pretix-widget-event-form', {
|
||||
+ '<div class="pretix-widget-voucher-button-wrap">'
|
||||
+ '<button @click="$parent.redeem">' + strings.redeem + '</button>'
|
||||
+ '</div>'
|
||||
+ '<div class="pretix-widget-clear"></div>'
|
||||
+ '</div>'
|
||||
+ '</form>'
|
||||
|
||||
+ '</div>'
|
||||
),
|
||||
data: function () {
|
||||
@@ -878,14 +825,10 @@ Vue.component('pretix-widget-event-form', {
|
||||
this.$root.$on('amounts_changed', this.calculate_buy_disabled)
|
||||
this.$root.$on('focus_voucher_field', this.focus_voucher_field)
|
||||
this.calculate_buy_disabled()
|
||||
|
||||
window.addEventListener('message', this.on_seat_select);
|
||||
},
|
||||
beforeDestroy: function() {
|
||||
this.$root.$off('amounts_changed', this.calculate_buy_disabled)
|
||||
this.$root.$off('focus_voucher_field', this.focus_voucher_field)
|
||||
|
||||
window.addEventListener('message', this.on_seat_select);
|
||||
},
|
||||
computed: {
|
||||
buy_label: function () {
|
||||
@@ -915,26 +858,9 @@ Vue.component('pretix-widget-event-form', {
|
||||
} else {
|
||||
return strings.buy;
|
||||
}
|
||||
},
|
||||
show_seating_plan_inline: function () {
|
||||
return this.$root.seating_embedded && this.$parent.clientWidth > 992;
|
||||
},
|
||||
seatingframe: function () {
|
||||
var seatingframe_url = this.$root.target_url;
|
||||
if (this.$root.subevent){
|
||||
seatingframe_url += '/' + this.$root.subevent;
|
||||
}
|
||||
seatingframe_url += '/seatingframe/?inline=1&locale=' + lang + '&widget_id=' + this.$root.widgetindex;
|
||||
return seatingframe_url;
|
||||
},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
on_seat_select: function (ev) {
|
||||
if (ev.data.source !== "pretix_widget_seating") return;
|
||||
if (parseInt(ev.data.widget_id) !== this.$root.widgetindex) return; // In case multiple widgets are on this page
|
||||
if (ev.data.action !== "buy") return;
|
||||
this.$parent.buy(null, ev.data.data);
|
||||
},
|
||||
focus_voucher_field: function() {
|
||||
this.$refs.voucherinput.scrollIntoView(false)
|
||||
this.$refs.voucherinput.focus()
|
||||
@@ -1218,21 +1144,15 @@ Vue.component('pretix-widget-event-calendar-row', {
|
||||
|
||||
Vue.component('pretix-widget-event-calendar', {
|
||||
template: ('<div class="pretix-widget-event-calendar" ref="calendar">'
|
||||
|
||||
// Back navigation
|
||||
+ '<div class="pretix-widget-back" v-if="$root.events !== undefined">'
|
||||
+ '<a href="#" @click.prevent.stop="back_to_list">‹ '
|
||||
+ strings['back']
|
||||
+ '</a>'
|
||||
+ '</div>'
|
||||
|
||||
// Headline
|
||||
+ '<div class="pretix-widget-event-header" v-if="$root.parent_stack.length > 0">'
|
||||
+ '<strong>{{ $root.name }}</strong>'
|
||||
+ '</div>'
|
||||
+ '<div class="pretix-widget-event-description" v-if="$root.parent_stack.length > 0 && $root.frontpage_text" v-html="$root.frontpage_text"></div>'
|
||||
|
||||
// Calendar navigation
|
||||
+ '<div class="pretix-widget-event-calendar-head">'
|
||||
+ '<a class="pretix-widget-event-calendar-previous-month" href="#" @click.prevent.stop="prevmonth">« '
|
||||
+ strings['previous_month']
|
||||
@@ -1242,8 +1162,6 @@ Vue.component('pretix-widget-event-calendar', {
|
||||
+ strings['next_month']
|
||||
+ ' »</a>'
|
||||
+ '</div>'
|
||||
|
||||
// Calendar
|
||||
+ '<table class="pretix-widget-event-calendar-table">'
|
||||
+ '<thead>'
|
||||
+ '<tr>'
|
||||
@@ -1302,19 +1220,14 @@ Vue.component('pretix-widget-event-calendar', {
|
||||
|
||||
Vue.component('pretix-widget-event-week-calendar', {
|
||||
template: ('<div class="pretix-widget-event-calendar pretix-widget-event-week-calendar" ref="weekcalendar">'
|
||||
// Back navigation
|
||||
+ '<div class="pretix-widget-back" v-if="$root.events !== undefined">'
|
||||
+ '<a href="#" @click.prevent.stop="back_to_list">‹ '
|
||||
+ strings['back']
|
||||
+ '</a>'
|
||||
+ '</div>'
|
||||
|
||||
// Event header
|
||||
+ '<div class="pretix-widget-event-header" v-if="$root.parent_stack.length > 0">'
|
||||
+ '<strong>{{ $root.name }}</strong>'
|
||||
+ '</div>'
|
||||
|
||||
// Calendar navigation
|
||||
+ '<div class="pretix-widget-event-description" v-if="$root.parent_stack.length > 0 && $root.frontpage_text" v-html="$root.frontpage_text"></div>'
|
||||
+ '<div class="pretix-widget-event-calendar-head">'
|
||||
+ '<a class="pretix-widget-event-calendar-previous-month" href="#" @click.prevent.stop="prevweek">« '
|
||||
@@ -1325,15 +1238,12 @@ Vue.component('pretix-widget-event-week-calendar', {
|
||||
+ strings['next_week']
|
||||
+ ' »</a>'
|
||||
+ '</div>'
|
||||
|
||||
// Actual calendar
|
||||
+ '<div class="pretix-widget-event-week-table">'
|
||||
+ '<div class="pretix-widget-event-week-col" v-for="d in $root.days">'
|
||||
+ '<pretix-widget-event-week-cell :day="d">'
|
||||
+ '</pretix-widget-event-week-cell>'
|
||||
+ '</div>'
|
||||
+ '</div>'
|
||||
|
||||
+ '</div>'
|
||||
+ '</div>'),
|
||||
computed: {
|
||||
@@ -1400,12 +1310,9 @@ Vue.component('pretix-widget', {
|
||||
data: shared_widget_data,
|
||||
methods: shared_methods,
|
||||
mounted: function () {
|
||||
this.clientWidth = this.$refs.wrapper.clientWidth;
|
||||
this.mobile = this.$refs.wrapper.clientWidth <= 600;
|
||||
},
|
||||
computed: {
|
||||
mobile: function () {
|
||||
return this.clientWidth <= 600;
|
||||
},
|
||||
classObject: function () {
|
||||
o = {'pretix-widget': true};
|
||||
if (this.mobile) {
|
||||
@@ -1565,16 +1472,14 @@ var shared_root_methods = {
|
||||
root.cart_exists = data.cart_exists;
|
||||
root.vouchers_exist = data.vouchers_exist;
|
||||
root.has_seating_plan = data.has_seating_plan;
|
||||
root.has_seating_plan_waitinglist = data.has_seating_plan_waitinglist;
|
||||
root.itemnum = data.itemnum;
|
||||
}
|
||||
root.loadid++; // force-reload iframes
|
||||
root.poweredby = data.poweredby;
|
||||
if (root.loading > 0) {
|
||||
root.loading--;
|
||||
root.trigger_load_callback();
|
||||
}
|
||||
if (root.parent_stack.length > 0 && root.has_seating_plan && root.categories.length === 0 && !root.frame_dismissed && root.useIframe && !root.error && !root.has_seating_plan_waitinglist) {
|
||||
if (root.parent_stack.length > 0 && root.has_seating_plan && root.categories.length === 0 && !root.frame_dismissed && root.useIframe && !root.error) {
|
||||
// If we're on desktop and someone selects a seating-only event in a calendar, let's open it right away,
|
||||
// but only if the person didn't close it before.
|
||||
root.startseating()
|
||||
@@ -1707,7 +1612,7 @@ var shared_root_computed = {
|
||||
},
|
||||
widget_data_json: function () {
|
||||
return JSON.stringify(this.widget_data);
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
var create_overlay = function (app) {
|
||||
@@ -1749,7 +1654,7 @@ function get_ga_client_id(tracking_id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var create_widget = function (element, widgetindex) {
|
||||
var create_widget = function (element) {
|
||||
var target_url = element.attributes.event.value;
|
||||
if (!target_url.match(/\/$/)) {
|
||||
target_url += "/";
|
||||
@@ -1758,7 +1663,6 @@ var create_widget = function (element, widgetindex) {
|
||||
var subevent = element.attributes.subevent ? element.attributes.subevent.value : null;
|
||||
var style = element.attributes.style ? element.attributes.style.value : null;
|
||||
var skip_ssl = element.attributes["skip-ssl-check"] ? true : false;
|
||||
var seating_embedded = element.attributes["seating-embedded"] ? true : false;
|
||||
var disable_iframe = element.attributes["disable-iframe"] ? true : false;
|
||||
var disable_vouchers = element.attributes["disable-vouchers"] ? true : false;
|
||||
var widget_data = JSON.parse(JSON.stringify(window.PretixWidget.widget_data));
|
||||
@@ -1781,7 +1685,6 @@ var create_widget = function (element, widgetindex) {
|
||||
el: element,
|
||||
data: function () {
|
||||
return {
|
||||
widgetindex: widgetindex,
|
||||
target_url: target_url,
|
||||
parent_stack: [],
|
||||
subevent: subevent,
|
||||
@@ -1803,7 +1706,6 @@ var create_widget = function (element, widgetindex) {
|
||||
voucher_explanation_text: null,
|
||||
show_variations_expanded: !!variations,
|
||||
skip_ssl: skip_ssl,
|
||||
seating_embedded: seating_embedded,
|
||||
disable_iframe: disable_iframe,
|
||||
style: style,
|
||||
connection_error: false,
|
||||
@@ -1818,7 +1720,6 @@ var create_widget = function (element, widgetindex) {
|
||||
display_add_to_cart: false,
|
||||
widget_data: widget_data,
|
||||
loading: 1,
|
||||
loadid: 1,
|
||||
widget_id: 'pretix-widget-' + widget_id,
|
||||
vouchers_exist: false,
|
||||
disable_vouchers: disable_vouchers,
|
||||
@@ -1826,8 +1727,7 @@ var create_widget = function (element, widgetindex) {
|
||||
itemcount: 0,
|
||||
overlay: null,
|
||||
poweredby: "",
|
||||
has_seating_plan: false,
|
||||
has_seating_plan_waitinglist: false,
|
||||
has_seating_plan: false
|
||||
}
|
||||
},
|
||||
created: function () {
|
||||
@@ -1919,7 +1819,7 @@ window.PretixWidget.buildWidgets = function () {
|
||||
var wlength = widgets.length;
|
||||
for (var i = 0; i < wlength; i++) {
|
||||
var widget = widgets[i];
|
||||
widgetlist.push(create_widget(widget, i + 1));
|
||||
widgetlist.push(create_widget(widget));
|
||||
}
|
||||
|
||||
var buttons = document.querySelectorAll("pretix-button, div.pretix-button-compat");
|
||||
|
||||
@@ -331,37 +331,6 @@
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pretix-widget-seating-embed {
|
||||
margin: 0 -10px;
|
||||
}
|
||||
.pretix-widget-seating-embed-iframe {
|
||||
width: 100%;
|
||||
aspect-ratio: 2/1;
|
||||
max-height: 60vh;
|
||||
}
|
||||
|
||||
.pretix-widget-seating-waitinglist {
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
.pretix-widget-seating-waitinglist-text {
|
||||
padding: 0 15px;
|
||||
width: 75%;
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.pretix-widget-seating-waitinglist-button-wrap {
|
||||
padding: 0 15px;
|
||||
width: 25%;
|
||||
box-sizing: border-box;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.pretix-widget-seating-waitinglist-button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pretix-widget-item-with-picture .pretix-widget-main-item-row .pretix-widget-item-title-and-description {
|
||||
margin-left: 70px;
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ from decimal import Decimal
|
||||
import pytest
|
||||
from django.utils.timezone import now
|
||||
from django_scopes import scopes_disabled
|
||||
from paypalhttp.http_response import Result
|
||||
|
||||
from pretix.base.models import (
|
||||
Event, Order, OrderPayment, OrderRefund, Organizer, Team, User,
|
||||
@@ -263,7 +262,7 @@ def init_api(self):
|
||||
@pytest.mark.django_db
|
||||
def test_webhook_all_good(env, client, monkeypatch):
|
||||
order = env[1]
|
||||
pp_order = Result(get_test_order())
|
||||
pp_order = get_test_order()
|
||||
monkeypatch.setattr("paypalcheckoutsdk.orders.OrdersGetRequest", lambda *args: pp_order)
|
||||
monkeypatch.setattr("pretix.plugins.paypal2.payment.PaypalMethod.init_api", init_api)
|
||||
|
||||
@@ -407,7 +406,7 @@ def test_webhook_mark_paid(env, client, monkeypatch):
|
||||
with scopes_disabled():
|
||||
order.payments.update(state=OrderPayment.PAYMENT_STATE_PENDING)
|
||||
|
||||
pp_order = Result(get_test_order())
|
||||
pp_order = get_test_order()
|
||||
monkeypatch.setattr("paypalcheckoutsdk.orders.OrdersGetRequest", lambda *args: pp_order)
|
||||
monkeypatch.setattr("pretix.plugins.paypal2.payment.PaypalMethod.init_api", init_api)
|
||||
with scopes_disabled():
|
||||
@@ -504,8 +503,8 @@ def test_webhook_mark_paid(env, client, monkeypatch):
|
||||
@pytest.mark.django_db
|
||||
def test_webhook_refund1(env, client, monkeypatch):
|
||||
order = env[1]
|
||||
pp_order = Result(get_test_order())
|
||||
pp_refund = Result(get_test_refund())
|
||||
pp_order = get_test_order()
|
||||
pp_refund = get_test_refund()
|
||||
|
||||
monkeypatch.setattr("paypalcheckoutsdk.orders.OrdersGetRequest", lambda *args: pp_order)
|
||||
monkeypatch.setattr("paypalcheckoutsdk.payments.RefundsGetRequest", lambda *args: pp_refund)
|
||||
@@ -598,8 +597,8 @@ def test_webhook_refund1(env, client, monkeypatch):
|
||||
@pytest.mark.django_db
|
||||
def test_webhook_refund2(env, client, monkeypatch):
|
||||
order = env[1]
|
||||
pp_order = Result(get_test_order())
|
||||
pp_refund = Result(get_test_refund())
|
||||
pp_order = get_test_order()
|
||||
pp_refund = get_test_refund()
|
||||
|
||||
monkeypatch.setattr("paypalcheckoutsdk.orders.OrdersGetRequest", lambda *args: pp_order)
|
||||
monkeypatch.setattr("paypalcheckoutsdk.payments.RefundsGetRequest", lambda *args: pp_refund)
|
||||
|
||||
@@ -172,7 +172,6 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
||||
"waiting_list_enabled": False,
|
||||
"error": None,
|
||||
"has_seating_plan": False,
|
||||
"has_seating_plan_waitinglist": False,
|
||||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||||
"items_by_category": [
|
||||
{
|
||||
@@ -349,7 +348,6 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
||||
"show_variations_expanded": False,
|
||||
"display_net_prices": False,
|
||||
"has_seating_plan": False,
|
||||
"has_seating_plan_waitinglist": False,
|
||||
"vouchers_exist": True,
|
||||
"waiting_list_enabled": False,
|
||||
"error": None,
|
||||
@@ -403,7 +401,6 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
||||
"display_net_prices": False,
|
||||
"vouchers_exist": True,
|
||||
"has_seating_plan": False,
|
||||
"has_seating_plan_waitinglist": False,
|
||||
"waiting_list_enabled": False,
|
||||
"error": None,
|
||||
'poweredby': '<a href="https://pretix.eu" target="_blank" rel="noopener">ticketing powered by pretix</a>',
|
||||
@@ -472,7 +469,6 @@ class WidgetCartTest(CartTestMixin, TestCase):
|
||||
"show_variations_expanded": False,
|
||||
"display_net_prices": False,
|
||||
"has_seating_plan": False,
|
||||
"has_seating_plan_waitinglist": False,
|
||||
"vouchers_exist": True,
|
||||
"waiting_list_enabled": False,
|
||||
"error": "This voucher is expired.",
|
||||
|
||||
Reference in New Issue
Block a user