Add sub-events and relative date settings (#503)

* Data model

* little crud

* SubEventItemForm etc

* Drop SubEventItem.active, quota editor

* Fix failing tests

* First frontend stuff

* Addons form stuff

* Quota calculation

* net price display on EventIndex

* Add tests, solve some bugs

* Correct quota selection in more places, consolidate pricing logic

* Fix failing quota tests

* Fix TypeError

* Add tests for checkout

* Fixed a bug in QuotaForm

* Prevent immutable cart if a quota was removed from an item

* Add tests for pricing

* Handle waiting list

* Filter in check-in list

* Fixed import lost in rebase

* Fix waiting list widget

* Voucher management

* Voucher redemption

* Fix broken tests

* Add subevents to OrderChangeManager

* Create a subevent during event creation

* Fix bulk voucher creation

* Introduce subevent.active

* Copy from for subevents

* Show active in list

* ICal download for subevents

* Check start and end of presale

* Failing tests / show cart logic

* Test

* Rebase migrations

* REST API integration of sub-events

* Integrate quota calculation into the traditional quota form

* Make subevent argument to add_position optional

* Log-display foo

* pretixdroid and subevents

* Filter by subevent

* Add more tests

* Some mor tests

* Rebase fixes

* More tests

* Relative dates

* Restrict selection in relative datetime widgets

* Filter subevent list

* Re-label has_subevents

* Rebase fixes, subevents in calendar view

* Performance and caching issues

* Refactor calendar templates

* Permission tests

* Calendar fixes and month selection

* subevent selection

* Rename subevents to dates

* Add tests for calendar views
This commit is contained in:
Raphael Michel
2017-07-11 13:56:00 +02:00
committed by GitHub
parent 554800c06f
commit 8123effa65
141 changed files with 5920 additions and 1012 deletions

View File

@@ -7,8 +7,12 @@ from django.test import TestCase
from django.utils.timezone import make_aware, now
from pretix.base.decimal import round_decimal
from pretix.base.models import Event, Item, Order, OrderPosition, Organizer
from pretix.base.models import (
CartPosition, Event, Item, Order, OrderPosition, Organizer,
)
from pretix.base.models.items import SubEventItem
from pretix.base.payment import FreeOrderProvider
from pretix.base.reldate import RelativeDate, RelativeDateWrapper
from pretix.base.services.orders import (
OrderChangeManager, OrderError, _create_order, expire_orders,
)
@@ -71,6 +75,52 @@ def test_expiry_last(event):
assert (order.expires - today).days == 5
@pytest.mark.django_db
def test_expiry_last_relative(event):
today = now()
event.settings.set('payment_term_days', 5)
event.settings.set('payment_term_weekdays', False)
event.date_from = now() + timedelta(days=5)
event.save()
event.settings.set('payment_term_last', RelativeDateWrapper(
RelativeDate(days_before=2, time=None, base_date_name='date_from')
))
order = _create_order(event, email='dummy@example.org', positions=[],
now_dt=today, payment_provider=FreeOrderProvider(event),
locale='de')
assert (order.expires - today).days == 3
@pytest.mark.django_db
def test_expiry_last_relative_subevents(event):
today = now()
event.settings.set('payment_term_days', 100)
event.settings.set('payment_term_weekdays', False)
event.date_from = now() + timedelta(days=5)
event.has_subevents = True
event.save()
ticket = Item.objects.create(event=event, name='Early-bird ticket', tax_rate=Decimal('7.00'),
default_price=Decimal('23.00'), admission=True)
se1 = event.subevents.create(name="SE1", date_from=now() + timedelta(days=10))
se2 = event.subevents.create(name="SE2", date_from=now() + timedelta(days=8))
cp1 = CartPosition.objects.create(
item=ticket, price=23, expires=now() + timedelta(days=1), subevent=se1, event=event, cart_id="123"
)
cp2 = CartPosition.objects.create(
item=ticket, price=23, expires=now() + timedelta(days=1), subevent=se2, event=event, cart_id="123"
)
event.settings.set('payment_term_last', RelativeDateWrapper(
RelativeDate(days_before=2, time=None, base_date_name='date_from')
))
order = _create_order(event, email='dummy@example.org', positions=[cp1, cp2],
now_dt=today, payment_provider=FreeOrderProvider(event),
locale='de')
assert (order.expires - today).days == 6
@pytest.mark.django_db
def test_expiry_dst(event):
event.settings.set('timezone', 'Europe/Berlin')
@@ -153,6 +203,63 @@ class OrderChangeManagerTests(TestCase):
price=Decimal("23.00"), attendee_name="Dieter", positionid=2
)
self.ocm = OrderChangeManager(self.order, None)
self.quota = self.event.quotas.create(name='Test', size=None)
self.quota.items.add(self.ticket)
self.quota.items.add(self.ticket2)
self.quota.items.add(self.shirt)
def test_change_subevent_quota_required(self):
self.event.has_subevents = True
self.event.save()
se1 = self.event.subevents.create(name="Foo", date_from=now())
se2 = self.event.subevents.create(name="Bar", date_from=now())
self.op1.subevent = se1
self.op1.save()
self.quota.subevent = se1
self.quota.save()
with self.assertRaises(OrderError):
self.ocm.change_subevent(self.op1, se2)
def test_change_subevent_success(self):
self.event.has_subevents = True
self.event.save()
se1 = self.event.subevents.create(name="Foo", date_from=now())
se2 = self.event.subevents.create(name="Bar", date_from=now())
SubEventItem.objects.create(subevent=se2, item=self.ticket, price=12)
self.op1.subevent = se1
self.op1.save()
self.quota.subevent = se2
self.quota.save()
self.ocm.change_subevent(self.op1, se2)
self.ocm.commit()
self.op1.refresh_from_db()
self.order.refresh_from_db()
assert self.op1.subevent == se2
assert self.op1.price == 12
assert self.order.total == self.op1.price + self.op2.price
def test_change_subevent_sold_out(self):
self.event.has_subevents = True
self.event.save()
se1 = self.event.subevents.create(name="Foo", date_from=now())
se2 = self.event.subevents.create(name="Bar", date_from=now())
self.op1.subevent = se1
self.op1.save()
self.quota.subevent = se2
self.quota.size = 0
self.quota.save()
self.ocm.change_subevent(self.op1, se2)
with self.assertRaises(OrderError):
self.ocm.commit()
self.op1.refresh_from_db()
assert self.op1.subevent == se1
def test_change_item_quota_required(self):
self.quota.delete()
with self.assertRaises(OrderError):
self.ocm.change_item(self.op1, self.shirt, None)
def test_change_item_success(self):
self.ocm.change_item(self.op1, self.shirt, None)
@@ -325,6 +432,11 @@ class OrderChangeManagerTests(TestCase):
assert self.order.total == 46
assert self.order.status == Order.STATUS_PAID
def test_add_item_quota_required(self):
self.quota.delete()
with self.assertRaises(OrderError):
self.ocm.add_position(self.shirt, None, None, None)
def test_add_item_success(self):
self.ocm.add_position(self.shirt, None, None, None)
self.ocm.commit()
@@ -375,3 +487,26 @@ class OrderChangeManagerTests(TestCase):
self.shirt.category = self.event.categories.create(name='Add-ons', is_addon=True)
with self.assertRaises(OrderError):
self.ocm.add_position(self.shirt, None, Decimal('13.00'), None)
def test_add_item_subevent_required(self):
self.event.has_subevents = True
self.event.save()
with self.assertRaises(OrderError):
self.ocm.add_position(self.ticket, None, None, None)
def test_add_item_subevent_price(self):
self.event.has_subevents = True
self.event.save()
se1 = self.event.subevents.create(name="Foo", date_from=now())
SubEventItem.objects.create(subevent=se1, item=self.ticket, price=12)
self.quota.subevent = se1
self.quota.save()
self.ocm.add_position(self.ticket, None, None, subevent=se1)
self.ocm.commit()
self.order.refresh_from_db()
assert self.order.positions.count() == 3
nop = self.order.positions.last()
assert nop.item == self.ticket
assert nop.price == Decimal('12.00')
assert nop.subevent == se1