Files
pretix_cgo/src/tests/base/test_invoices.py
2017-07-17 23:03:20 +02:00

278 lines
9.3 KiB
Python

from datetime import timedelta
from decimal import Decimal
import pytest
from django.db import DatabaseError
from django.utils.timezone import now
from pretix.base.models import (
Event, Invoice, InvoiceAddress, Item, ItemVariation, Order, OrderPosition,
Organizer,
)
from pretix.base.services.invoices import (
build_preview_invoice_pdf, generate_cancellation, generate_invoice,
invoice_pdf_task, regenerate_invoice,
)
@pytest.fixture
def env():
o = Organizer.objects.create(name='Dummy', slug='dummy')
event = Event.objects.create(
organizer=o, name='Dummy', slug='dummy',
date_from=now(), plugins='pretix.plugins.banktransfer'
)
o = Order.objects.create(
code='FOO', event=event, email='dummy@dummy.test',
status=Order.STATUS_PENDING,
datetime=now(), expires=now() + timedelta(days=10),
total=0, payment_provider='banktransfer',
payment_fee=Decimal('0.25'), payment_fee_tax_rate=0,
payment_fee_tax_value=0, locale='en'
)
ticket = Item.objects.create(event=event, name='Early-bird ticket',
category=None, default_price=23,
admission=True)
t_shirt = Item.objects.create(event=event, name='T-Shirt',
category=None, default_price=42,
admission=True)
variation = ItemVariation.objects.create(value='M', item=t_shirt)
OrderPosition.objects.create(
order=o,
item=ticket,
variation=None,
price=Decimal("23.00"),
positionid=1,
)
OrderPosition.objects.create(
order=o,
item=t_shirt,
variation=variation,
price=Decimal("42.00"),
positionid=2,
)
return event, o
@pytest.mark.django_db
def test_locale_setting(env):
event, order = env
event.settings.set('invoice_language', 'de')
inv = generate_invoice(order)
assert inv.locale == 'de'
@pytest.mark.django_db
def test_locale_user(env):
event, order = env
order.locale = 'en'
event.settings.set('invoice_language', '__user__')
inv = generate_invoice(order)
assert inv.locale == order.locale
@pytest.mark.django_db
def test_address(env):
event, order = env
event.settings.set('invoice_language', 'en')
InvoiceAddress.objects.create(company='Acme Company', street='221B Baker Street',
zipcode='12345', city='London', country='UK',
order=order)
inv = generate_invoice(order)
assert inv.invoice_to == "Acme Company\n\n221B Baker Street\n12345 London\nUK"
@pytest.mark.django_db
def test_address_vat_id(env):
event, order = env
event.settings.set('invoice_language', 'en')
InvoiceAddress.objects.create(company='Acme Company', street='221B Baker Street',
name='Sherlock Holmes', zipcode='12345', city='London', country='UK',
vat_id='UK1234567', order=order)
inv = generate_invoice(order)
assert inv.invoice_to == "Acme Company\nSherlock Holmes\n221B Baker Street\n12345 London\nUK\nVAT-ID: UK1234567"
@pytest.mark.django_db
def test_positions_skip_free(env):
event, order = env
event.settings.invoice_include_free = False
op1 = order.positions.first()
op1.price = Decimal('0.00')
op1.save()
inv = generate_invoice(order)
assert inv.lines.count() == 2
@pytest.mark.django_db
def test_positions(env):
event, order = env
inv = generate_invoice(order)
assert inv.lines.count() == 3
first = inv.lines.first()
assert 'Early-bird' in first.description
assert first.gross_value == Decimal('23.00')
second = inv.lines.all()[1]
assert 'T-Shirt' in second.description
assert 'M' in second.description
assert second.gross_value == Decimal('42.00')
last = inv.lines.last()
assert 'Payment' in last.description
assert last.gross_value == order.payment_fee
assert last.tax_rate == order.payment_fee_tax_rate
assert last.tax_value == order.payment_fee_tax_value
assert inv.invoice_to == ""
@pytest.mark.django_db
def test_rebuilding(env):
event, order = env
inv = generate_invoice(order)
inv2 = regenerate_invoice(inv)
assert inv.order == inv2.order
inv3 = generate_cancellation(inv)
inv4 = regenerate_invoice(inv3)
assert inv3.order == inv4.order
@pytest.mark.django_db
def test_cannot_delete_invoice(env):
event, order = env
inv = generate_invoice(order)
with pytest.raises(Exception):
inv.delete()
@pytest.mark.django_db
def test_cannot_write_invoice_without_order(env):
event, _ = env
with pytest.raises(Exception):
i = Invoice(order=None, event=event)
i.save()
@pytest.mark.django_db
def test_pdf_generation(env):
event, order = env
inv = generate_invoice(order)
cancellation = generate_cancellation(inv)
assert invoice_pdf_task(inv.pk)
assert invoice_pdf_task(cancellation.pk)
@pytest.mark.django_db
def test_pdf_generation_custom_text(env):
event, order = env
event.settings.set('invoice_introductory_text', 'introductory invoice text')
# set a really long additional text, to make the invoice span two pages
event.settings.set('invoice_additional_text', 'additional invoice text\n' * 100)
event.settings.set('show_date_to', False)
inv = generate_invoice(order)
assert invoice_pdf_task(inv.pk)
@pytest.mark.django_db
def test_pdf_preview_generation(env):
event, order = env
assert build_preview_invoice_pdf(event)
@pytest.mark.django_db
def test_invoice_numbers(env):
event, order = env
order2 = Order.objects.create(
code='BAR', event=event, email='dummy2@dummy.test',
status=Order.STATUS_PENDING,
datetime=now(), expires=now() + timedelta(days=10),
total=0, payment_provider='banktransfer',
payment_fee=Decimal('0.25'), payment_fee_tax_rate=0,
payment_fee_tax_value=0, locale='en'
)
inv1 = generate_invoice(order)
inv2 = generate_invoice(order)
event.settings.set('invoice_numbers_consecutive', False)
inv3 = generate_invoice(order)
inv4 = generate_invoice(order)
inv21 = generate_invoice(order2)
inv22 = generate_invoice(order2)
event.settings.set('invoice_numbers_consecutive', True)
inv5 = generate_invoice(order)
inv23 = generate_invoice(order2)
# expected behaviour for switching between numbering formats
assert inv1.invoice_no == '00001'
assert inv2.invoice_no == '00002'
assert inv3.invoice_no == '{}-3'.format(order.code)
assert inv4.invoice_no == '{}-4'.format(order.code)
assert inv5.invoice_no == '00003'
# test that separate orders are counted separately in this mode
assert inv21.invoice_no == '{}-1'.format(order2.code)
assert inv22.invoice_no == '{}-2'.format(order2.code)
# but consecutively in this mode
assert inv23.invoice_no == '00004'
# test Invoice.number, too
assert inv1.number == '{}-00001'.format(event.slug.upper())
assert inv3.number == '{}-{}-3'.format(event.slug.upper(), order.code)
@pytest.mark.django_db
def test_invoice_number_prefixes(env):
event, order = env
event2 = Event.objects.create(
organizer=event.organizer, name='Dummy', slug='dummy2',
date_from=now(), plugins='pretix.plugins.banktransfer'
)
order2 = Order.objects.create(
event=event2, email='dummy2@dummy.test',
status=Order.STATUS_PENDING,
datetime=now(), expires=now() + timedelta(days=10),
total=0, payment_provider='banktransfer',
payment_fee=Decimal('0.25'), payment_fee_tax_rate=0,
payment_fee_tax_value=0, locale='en'
)
event.settings.set('invoice_numbers_consecutive', False)
event2.settings.set('invoice_numbers_consecutive', False)
assert generate_invoice(order).number == 'DUMMY-{}-1'.format(order.code)
assert generate_invoice(order2).number == 'DUMMY2-{}-1'.format(order2.code)
event.settings.set('invoice_numbers_consecutive', True)
event2.settings.set('invoice_numbers_consecutive', True)
event.settings.set('invoice_numbers_prefix', '')
event2.settings.set('invoice_numbers_prefix', '')
assert generate_invoice(order).number == 'DUMMY-00001'
assert generate_invoice(order).number == 'DUMMY-00002'
assert generate_invoice(order2).number == 'DUMMY2-00001'
assert generate_invoice(order2).number == 'DUMMY2-00002'
event.settings.set('invoice_numbers_prefix', 'shared_')
event2.settings.set('invoice_numbers_prefix', 'shared_')
assert generate_invoice(order).number == 'shared_00001'
assert generate_invoice(order2).number == 'shared_00002'
assert generate_invoice(order).number == 'shared_00003'
assert generate_invoice(order2).number == 'shared_00004'
event.settings.set('invoice_numbers_consecutive', False)
event2.settings.set('invoice_numbers_consecutive', False)
assert generate_invoice(order).number == 'shared_{}-6'.format(order.code)
assert generate_invoice(order2).number == 'shared_{}-6'.format(order2.code)
# Test database uniqueness check
with pytest.raises(DatabaseError):
Invoice.objects.create(
order=order,
event=order.event,
organizer=order.event.organizer,
date=now().date(),
locale='en',
invoice_no='00001',
)