Fix #163 -- Form to change orders (#191)

This commit is contained in:
Raphael Michel
2016-08-31 19:10:11 +02:00
committed by GitHub
parent 57374aec1a
commit b21ed4d99f
15 changed files with 751 additions and 16 deletions

View File

@@ -1,11 +1,20 @@
from datetime import timedelta
from decimal import Decimal
import pytest
from django.db import transaction
from django.test import TestCase
from django.utils.timezone import now
from pretix.base.models import Event, Order, Organizer
from pretix.base.decimal import round_decimal
from pretix.base.models import (
Event, Item, Order, OrderPosition, Organizer, Quota,
)
from pretix.base.payment import FreeOrderProvider
from pretix.base.services.orders import _create_order, expire_orders
from pretix.base.services import invoices
from pretix.base.services.orders import (
OrderChangeManager, OrderError, _create_order, expire_orders,
)
@pytest.fixture
@@ -85,3 +94,173 @@ def test_expiring_auto_disabled(event):
assert o1.status == Order.STATUS_PENDING
o2 = Order.objects.get(id=o2.id)
assert o2.status == Order.STATUS_PENDING
class OrderChangeManagerTests(TestCase):
def setUp(self):
super().setUp()
o = Organizer.objects.create(name='Dummy', slug='dummy')
self.event = Event.objects.create(organizer=o, name='Dummy', slug='dummy', date_from=now(), plugins='pretix.plugins.banktransfer')
self.order = Order.objects.create(
code='FOO', event=self.event, email='dummy@dummy.test',
status=Order.STATUS_PENDING,
datetime=now(), expires=now() + timedelta(days=10),
total=Decimal('46.00'), payment_provider='banktransfer'
)
self.ticket = Item.objects.create(event=self.event, name='Early-bird ticket', tax_rate=Decimal('7.00'),
default_price=Decimal('23.00'), admission=True)
self.shirt = Item.objects.create(event=self.event, name='T-Shirt', tax_rate=Decimal('19.00'),
default_price=Decimal('12.00'))
self.op1 = OrderPosition.objects.create(
order=self.order, item=self.ticket, variation=None,
price=Decimal("23.00"), attendee_name="Peter"
)
self.op2 = OrderPosition.objects.create(
order=self.order, item=self.ticket, variation=None,
price=Decimal("23.00"), attendee_name="Dieter"
)
self.ocm = OrderChangeManager(self.order, None)
def test_change_item_success(self):
self.ocm.change_item(self.op1, self.shirt, None)
self.ocm.commit()
self.op1.refresh_from_db()
self.order.refresh_from_db()
assert self.op1.item == self.shirt
assert self.op1.price == self.shirt.default_price
assert self.op1.tax_rate == self.shirt.tax_rate
assert round_decimal(self.op1.price * (1 - 100 / (100 + self.op1.tax_rate))) == self.op1.tax_value
assert self.order.total == self.op1.price + self.op2.price
def test_change_price_success(self):
self.ocm.change_price(self.op1, Decimal('24.00'))
self.ocm.commit()
self.op1.refresh_from_db()
self.order.refresh_from_db()
assert self.op1.item == self.ticket
assert self.op1.price == Decimal('24.00')
assert round_decimal(self.op1.price * (1 - 100 / (100 + self.op1.tax_rate))) == self.op1.tax_value
assert self.order.total == self.op1.price + self.op2.price
def test_cancel_success(self):
self.ocm.cancel(self.op1)
self.ocm.commit()
self.order.refresh_from_db()
assert self.order.positions.count() == 1
assert self.order.total == self.op2.price
def test_free_to_paid(self):
self.op1.price = Decimal('0.00')
self.op1.save()
self.op2.delete()
self.order.total = Decimal('0.00')
self.order.save()
self.ocm.change_price(self.op1, Decimal('24.00'))
with self.assertRaises(OrderError):
self.ocm.commit()
self.op1.refresh_from_db()
assert self.op1.price == Decimal('0.00')
def test_cancel_all_in_order(self):
self.ocm.cancel(self.op1)
self.ocm.cancel(self.op2)
with self.assertRaises(OrderError):
self.ocm.commit()
assert self.order.positions.count() == 2
def test_empty(self):
self.ocm.commit()
def test_quota_full(self):
q = self.event.quotas.create(name='Test', size=0)
q.items.add(self.shirt)
self.ocm.change_item(self.op1, self.shirt, None)
with self.assertRaises(OrderError):
self.ocm.commit()
self.op1.refresh_from_db()
assert self.op1.item == self.ticket
def test_quota_full_but_in_same(self):
q = self.event.quotas.create(name='Test', size=0)
q.items.add(self.shirt)
q.items.add(self.ticket)
self.ocm.change_item(self.op1, self.shirt, None)
self.ocm.commit()
self.op1.refresh_from_db()
assert self.op1.item == self.shirt
def test_multiple_quotas_shared_full(self):
q1 = self.event.quotas.create(name='Test', size=0)
q2 = self.event.quotas.create(name='Test', size=2)
q1.items.add(self.shirt)
q1.items.add(self.ticket)
q2.items.add(self.shirt)
self.ocm.change_item(self.op1, self.shirt, None)
self.ocm.commit()
self.op1.refresh_from_db()
assert self.op1.item == self.shirt
def test_multiple_quotas_unshared_full(self):
q1 = self.event.quotas.create(name='Test', size=2)
q2 = self.event.quotas.create(name='Test', size=0)
q1.items.add(self.shirt)
q1.items.add(self.ticket)
q2.items.add(self.shirt)
self.ocm.change_item(self.op1, self.shirt, None)
with self.assertRaises(OrderError):
self.ocm.commit()
self.op1.refresh_from_db()
assert self.op1.item == self.ticket
def test_multiple_items_success(self):
q1 = self.event.quotas.create(name='Test', size=2)
q1.items.add(self.shirt)
self.ocm.change_item(self.op1, self.shirt, None)
self.ocm.change_item(self.op2, self.shirt, None)
self.ocm.commit()
self.op1.refresh_from_db()
self.op2.refresh_from_db()
assert self.op1.item == self.shirt
assert self.op2.item == self.shirt
def test_multiple_items_quotas_partially_full(self):
q1 = self.event.quotas.create(name='Test', size=1)
q1.items.add(self.shirt)
self.ocm.change_item(self.op1, self.shirt, None)
self.ocm.change_item(self.op2, self.shirt, None)
with self.assertRaises(OrderError):
self.ocm.commit()
self.op1.refresh_from_db()
self.op2.refresh_from_db()
assert self.op1.item == self.ticket
assert self.op2.item == self.ticket
def test_payment_fee_calculation(self):
self.event.settings.set('tax_rate_default', Decimal('19.00'))
prov = self.ocm._get_payment_provider()
prov.settings.set('_fee_abs', Decimal('0.30'))
self.ocm.change_price(self.op1, Decimal('24.00'))
self.ocm.commit()
self.order.refresh_from_db()
assert self.order.total == Decimal('47.30')
assert self.order.payment_fee == prov.calculate_fee(self.order.total)
assert self.order.payment_fee_tax_rate == Decimal('19.00')
assert round_decimal(self.order.payment_fee * (1 - 100 / (100 + self.order.payment_fee_tax_rate))) == self.order.payment_fee_tax_value
def test_require_pending(self):
self.order.status = Order.STATUS_PAID
self.order.save()
self.ocm.change_item(self.op1, self.shirt, None)
with self.assertRaises(OrderError):
self.ocm.commit()
self.op1.refresh_from_db()
assert self.op1.item == self.ticket
def test_change_price_to_free_marked_as_paid(self):
self.ocm.change_price(self.op1, Decimal('0.00'))
self.ocm.change_price(self.op2, Decimal('0.00'))
self.ocm.commit()
self.order.refresh_from_db()
assert self.order.total == 0
assert self.order.status == Order.STATUS_PAID
assert self.order.payment_provider == 'free'