Compare commits

..

1 Commits

Author SHA1 Message Date
Raphael Michel
3cdb992134 Bump dnspython to 2.2.* 2022-12-20 11:55:52 +01:00
16 changed files with 65 additions and 269 deletions

View File

@@ -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
---------------------

View File

@@ -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')

View File

@@ -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.'),

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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())

View File

@@ -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() => {

View File

@@ -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)

View File

@@ -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

View File

@@ -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:

View File

@@ -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',

View File

@@ -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">&nbsp;</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">&nbsp;</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">&lsaquo; '
+ 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">&lsaquo; '
+ 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">&laquo; '
+ strings['previous_month']
@@ -1242,8 +1162,6 @@ Vue.component('pretix-widget-event-calendar', {
+ strings['next_month']
+ ' &raquo;</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">&lsaquo; '
+ 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">&laquo; '
@@ -1325,15 +1238,12 @@ Vue.component('pretix-widget-event-week-calendar', {
+ strings['next_week']
+ ' &raquo;</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");

View File

@@ -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;
}

View File

@@ -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)

View File

@@ -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.",