Compare commits

...

13 Commits

Author SHA1 Message Date
Raphael Michel
40440c1ce2 Bump version 2018-08-05 16:56:15 +02:00
Raphael Michel
6544c20cbb Backport a migration 2018-08-05 16:36:02 +02:00
Raphael Michel
6c0be6aef8 Delete old and unused settings entries 2018-08-05 16:27:53 +02:00
Raphael Michel
2bd34f23d0 Fix TypeError in price_too_high detection 2018-08-05 16:12:46 +02:00
Raphael Michel
e4f941598a Fix error condition in event cloning 2018-08-05 16:12:42 +02:00
Raphael Michel
f4df82bdfb Fix event meta deletion 2018-08-05 16:12:40 +02:00
Raphael Michel
ba355ae78a Throw cart error for price_too_high 2018-08-05 16:12:36 +02:00
Raphael Michel
64b3361ae3 Fix KeyError when accessing settings for disabled payment provider 2018-08-05 16:12:32 +02:00
Raphael Michel
86f50c8e61 OrderCreateSerializer: Do not crash on optional fields missing 2018-08-05 16:12:29 +02:00
Raphael Michel
6411d17e0d Prevent a KeyError during form validation 2018-08-05 16:12:26 +02:00
Raphael Michel
dcbc0ba7f3 Prevent a KeyError with invalid add-on configuration 2018-08-05 16:12:22 +02:00
Raphael Michel
51554a4757 Prevent ValueError with invalid state of relative date 2018-08-05 16:12:19 +02:00
Raphael Michel
504e65844f Fix race condition in formset validation 2018-08-05 16:11:48 +02:00
9 changed files with 57 additions and 22 deletions

View File

@@ -1 +1 @@
__version__ = "1.17.0"
__version__ = "1.17.1"

View File

@@ -464,7 +464,7 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
raise ValidationError({'positions': errs})
order = Order(event=self.context['event'], **validated_data)
order.set_expires(subevents=[p['subevent'] for p in positions_data])
order.set_expires(subevents=[p.get('subevent') for p in positions_data])
order.total = sum([p['price'] for p in positions_data]) + sum([f['value'] for f in fees_data], Decimal('0.00'))
order.meta_info = "{}"
if order.total == Decimal('0.00') and validated_data.get('status') != Order.STATUS_PAID:
@@ -480,8 +480,8 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
ia.save()
pos_map = {}
for pos_data in positions_data:
answers_data = pos_data.pop('answers')
addon_to = pos_data.pop('addon_to')
answers_data = pos_data.pop('answers', [])
addon_to = pos_data.pop('addon_to', None)
pos = OrderPosition(**pos_data)
pos.order = order
pos._calculate_tax()
@@ -490,7 +490,7 @@ class OrderCreateSerializer(I18nAwareModelSerializer):
pos.save()
pos_map[pos.positionid] = pos
for answ_data in answers_data:
options = answ_data.pop('options')
options = answ_data.pop('options', [])
answ = pos.answers.create(**answ_data)
answ.options.add(*options)

View File

@@ -450,10 +450,8 @@ class Event(EventMixin, LoggedModel):
if int(s.value) in tax_map:
s.value = tax_map.get(int(s.value)).pk
s.save()
else:
s.delete()
except ValueError:
s.delete()
pass
else:
s.save()

View File

@@ -104,7 +104,7 @@ class RelativeDateWrapper:
timeparts = parts[2].split(':')
time = datetime.time(hour=int(timeparts[0]), minute=int(timeparts[1]), second=int(timeparts[2]))
data = RelativeDate(
days_before=int(parts[1]),
days_before=int(parts[1] or 0),
base_date_name=parts[3],
time=time
)

View File

@@ -232,11 +232,17 @@ class CartManager:
def _get_price(self, item: Item, variation: Optional[ItemVariation],
voucher: Optional[Voucher], custom_price: Optional[Decimal],
subevent: Optional[SubEvent], cp_is_net: bool=None):
return get_price(
item, variation, voucher, custom_price, subevent,
custom_price_is_net=cp_is_net if cp_is_net is not None else self.event.settings.display_net_prices,
invoice_address=self.invoice_address
)
try:
return get_price(
item, variation, voucher, custom_price, subevent,
custom_price_is_net=cp_is_net if cp_is_net is not None else self.event.settings.display_net_prices,
invoice_address=self.invoice_address
)
except ValueError as e:
if str(e) == 'price_too_high':
raise CartError(error_messages['price_too_high'])
else:
raise e
def extend_expired_positions(self):
expired = self.positions.filter(expires__lte=self.now_dt).select_related(

View File

@@ -404,19 +404,24 @@ class ItemAddOnsFormSet(I18nFormSet):
def clean(self):
super().clean()
categories = set()
categories = set(self.queryset.values_list('addon_category_id', flat=True))
for i in range(0, self.total_form_count()):
form = self.forms[i]
if self.can_delete:
if self._should_delete_form(form):
# This form is going to be deleted so any of its errors
# should not cause the entire formset to be invalid.
try:
categories.remove(form.cleaned_data['addon_category'].pk)
except KeyError:
pass
continue
if form.cleaned_data['addon_category'] in categories:
raise ValidationError(_('You added the same add-on category twice'))
if 'addon_category' in form.cleaned_data:
if form.cleaned_data['addon_category'].pk in categories:
raise ValidationError(_('You added the same add-on category twice'))
categories.add(form.cleaned_data['addon_category'])
categories.add(form.cleaned_data['addon_category'].pk)
@property
def empty_form(self):

View File

@@ -100,7 +100,7 @@ class MetaDataEditorMixin:
if f.cleaned_data.get('value'):
f.save()
elif f.instance and f.instance.pk:
f.delete()
f.instance.delete()
class EventUpdate(EventSettingsViewMixin, EventPermissionRequiredMixin, MetaDataEditorMixin, UpdateView):
@@ -255,9 +255,7 @@ class PaymentProviderSettings(EventSettingsViewMixin, EventPermissionRequiredMix
@cached_property
def provider(self):
provider = self.request.event.get_payment_providers()[self.kwargs['provider']]
if not provider:
raise Http404()
provider = self.request.event.get_payment_providers().get(self.kwargs['provider'])
return provider
@cached_property
@@ -276,6 +274,13 @@ class PaymentProviderSettings(EventSettingsViewMixin, EventPermissionRequiredMix
form.prepare_fields()
return form
def dispatch(self, request, *args, **kwargs):
if not self.provider:
messages.error(self.request, _('This payment provider does not exist or the respective plugin is '
'disabled.'))
return redirect(self.get_success_url())
return super().dispatch(request, *args, **kwargs)
@cached_property
def settings_content(self):
return self.provider.settings_content_render(self.request)

View File

@@ -42,6 +42,7 @@ def convert_old_settings(app, schema_editor):
l.background.name = es.value[7:]
setattr(l, 'background', l.background.name)
l.save()
es.delete()
class Migration(migrations.Migration):

View File

@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-08-05 14:32
from __future__ import unicode_literals
from django.db import migrations
def cleanup(app, schema_editor):
EventSettingsStore = app.get_model('pretixbase', 'Event_SettingsStore')
EventSettingsStore.objects.filter(key='ticketoutput_pdf_layout').delete()
class Migration(migrations.Migration):
dependencies = [
('ticketoutputpdf', '0002_auto_20180605_2022'),
]
operations = [
migrations.RunPython(cleanup, migrations.RunPython.noop)
]