forked from CGM_Public/pretix_original
New concept for fee handling (#610)
* New concept for fee handling * More usages * Remove all usages, make all tests pass * API changes * Small fixes * Fix order of invoice lines * Rebase migration
This commit is contained in:
@@ -156,28 +156,28 @@
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% if cart.payment_fee %}
|
||||
{% for fee in cart.fees %}
|
||||
<div class="row cart-row">
|
||||
<div class="col-md-4 col-xs-6">
|
||||
<strong>{% trans "Payment method fee" %}</strong>
|
||||
</div>
|
||||
<div class="col-md-3 col-xs-6 col-md-offset-5 price">
|
||||
{% if event.settings.display_net_prices %}
|
||||
<strong>{{ event.currency }} {{ cart.payment_fee_net|floatformat:2 }}</strong>
|
||||
{% if cart.payment_fee_tax_rate %}
|
||||
<strong>{{ event.currency }} {{ fee.net_value|floatformat:2 }}</strong>
|
||||
{% if fee.tax_rate %}
|
||||
<br />
|
||||
<small>
|
||||
{% blocktrans trimmed with rate=cart.payment_fee_tax_rate taxname=cart.payment_fee_tax_rule.name|default:s_taxes %}
|
||||
{% blocktrans trimmed with rate=fee.tax_rate taxname=fee.tax_rule.name|default:s_taxes %}
|
||||
<strong>plus</strong> {{ rate }}% {{ taxname }}
|
||||
{% endblocktrans %}
|
||||
</small>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<strong>{{ event.currency }} {{ cart.payment_fee|floatformat:2 }}</strong>
|
||||
{% if cart.payment_fee_tax_rate %}
|
||||
<strong>{{ event.currency }} {{ fee.value|floatformat:2 }}</strong>
|
||||
{% if fee.tax_rate %}
|
||||
<br />
|
||||
<small>
|
||||
{% blocktrans trimmed with rate=cart.payment_fee_tax_rate taxname=cart.payment_fee_tax_rule.name|default:s_taxes %}
|
||||
{% blocktrans trimmed with rate=fee.tax_rate taxname=fee.tax_rule.name|default:s_taxes %}
|
||||
incl. {{ rate }}% {{ taxname }}
|
||||
{% endblocktrans %}
|
||||
</small>
|
||||
@@ -186,7 +186,7 @@
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if event.settings.display_net_prices and cart.tax_total %}
|
||||
<div class="row cart-row total">
|
||||
<div class="col-md-4 col-xs-6">
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from collections import defaultdict
|
||||
from datetime import timedelta
|
||||
from decimal import Decimal
|
||||
from itertools import groupby
|
||||
|
||||
from django.db.models import Sum
|
||||
@@ -8,7 +7,7 @@ from django.utils.functional import cached_property
|
||||
from django.utils.timezone import now
|
||||
|
||||
from pretix.base.models import CartPosition, InvoiceAddress, OrderPosition
|
||||
from pretix.base.models.tax import TaxRule
|
||||
from pretix.base.services.cart import get_fees
|
||||
from pretix.presale.signals import question_form_fields
|
||||
|
||||
|
||||
@@ -101,34 +100,21 @@ class CartMixin:
|
||||
tax_total = sum(p.total - p.net_total for p in positions)
|
||||
|
||||
if order:
|
||||
payment_fee = order.payment_fee
|
||||
tax_total += order.payment_fee_tax_value
|
||||
payment_fee_net = order.payment_fee - order.payment_fee_tax_value
|
||||
net_total += payment_fee_net
|
||||
payment_fee_tax_rule = order.payment_fee_tax_rule
|
||||
payment_fee_tax_rate = order.payment_fee_tax_rate
|
||||
fees = order.fees.all()
|
||||
else:
|
||||
payment_fee = self.get_payment_fee(total)
|
||||
payment_fee_tax_rule = self.request.event.settings.tax_rate_default or TaxRule.zero()
|
||||
|
||||
iapk = self.request.session.get('invoice_address_{}'.format(self.request.event.pk))
|
||||
ia = None
|
||||
if payment_fee_tax_rule.eu_reverse_charge and iapk:
|
||||
if iapk:
|
||||
try:
|
||||
ia = InvoiceAddress.objects.get(pk=iapk, order__isnull=True)
|
||||
except InvoiceAddress.DoesNotExist:
|
||||
pass
|
||||
|
||||
if payment_fee_tax_rule.tax_applicable(ia):
|
||||
payment_fee_tax = payment_fee_tax_rule.tax(payment_fee, base_price_is='gross')
|
||||
tax_total += payment_fee_tax.tax
|
||||
net_total += payment_fee_tax.net
|
||||
payment_fee_net = payment_fee_tax.net
|
||||
payment_fee_tax_rate = payment_fee_tax.rate
|
||||
else:
|
||||
net_total += payment_fee
|
||||
payment_fee_net = payment_fee
|
||||
payment_fee_tax_rate = Decimal('0.00')
|
||||
fees = get_fees(self.request.event, total, ia, self.request.session.get('payment'))
|
||||
|
||||
total += sum([f.value for f in fees])
|
||||
net_total += sum([f.net_value for f in fees])
|
||||
tax_total += sum([f.tax_value for f in fees])
|
||||
|
||||
try:
|
||||
first_expiry = min(p.expires for p in positions) if positions else now()
|
||||
@@ -140,28 +126,15 @@ class CartMixin:
|
||||
return {
|
||||
'positions': positions,
|
||||
'raw': cartpos,
|
||||
'total': total + payment_fee,
|
||||
'total': total,
|
||||
'net_total': net_total,
|
||||
'tax_total': tax_total,
|
||||
'payment_fee': payment_fee,
|
||||
'payment_fee_net': payment_fee_net,
|
||||
'payment_fee_tax_rate': payment_fee_tax_rate,
|
||||
'payment_fee_tax_rule': payment_fee_tax_rule,
|
||||
'fees': fees,
|
||||
'answers': answers,
|
||||
'minutes_left': minutes_left,
|
||||
'first_expiry': first_expiry,
|
||||
}
|
||||
|
||||
def get_payment_fee(self, total):
|
||||
if total == 0:
|
||||
return Decimal('0.00')
|
||||
payment_fee = 0
|
||||
if 'payment' in self.request.session:
|
||||
provider = self.request.event.get_payment_providers().get(self.request.session['payment'])
|
||||
if provider:
|
||||
payment_fee = provider.calculate_fee(total)
|
||||
return payment_fee
|
||||
|
||||
|
||||
def get_cart(request):
|
||||
if not hasattr(request, '_cart_cache'):
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import mimetypes
|
||||
import os
|
||||
from decimal import Decimal
|
||||
|
||||
from django.contrib import messages
|
||||
from django.db import transaction
|
||||
@@ -12,7 +13,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||
from django.views.generic import TemplateView, View
|
||||
|
||||
from pretix.base.models import CachedTicket, Invoice, Order, OrderPosition
|
||||
from pretix.base.models.orders import InvoiceAddress, QuestionAnswer
|
||||
from pretix.base.models.orders import InvoiceAddress, OrderFee, QuestionAnswer
|
||||
from pretix.base.payment import PaymentException
|
||||
from pretix.base.services.invoices import (
|
||||
generate_cancellation, generate_invoice, invoice_pdf, invoice_qualified,
|
||||
@@ -305,11 +306,12 @@ class OrderPayChangeMethod(EventViewMixin, OrderDetailMixin, TemplateView):
|
||||
if not provider.is_enabled or not provider.order_change_allowed(self.order):
|
||||
continue
|
||||
fee = provider.calculate_fee(self._total_order_value)
|
||||
current_fee = self.order.fees.filter(fee_type=OrderFee.FEE_TYPE_PAYMENT).aggregate(s=Sum('value'))['s'] or Decimal('0.00')
|
||||
providers.append({
|
||||
'provider': provider,
|
||||
'fee': fee,
|
||||
'fee_diff': fee - self.order.payment_fee,
|
||||
'fee_diff_abs': abs(fee - self.order.payment_fee),
|
||||
'fee_diff': fee - current_fee,
|
||||
'fee_diff_abs': abs(fee - current_fee),
|
||||
'total': abs(self._total_order_value + fee),
|
||||
'form': provider.payment_form_render(self.request)
|
||||
})
|
||||
@@ -323,16 +325,29 @@ class OrderPayChangeMethod(EventViewMixin, OrderDetailMixin, TemplateView):
|
||||
request.session['payment_change_{}'.format(self.order.pk)] = '1'
|
||||
|
||||
new_fee = p['provider'].calculate_fee(self._total_order_value)
|
||||
if new_fee:
|
||||
fee = self.order.fees.get_or_create(fee_type=OrderFee.FEE_TYPE_PAYMENT, defaults={'value': 0})[0]
|
||||
old_fee = fee.value
|
||||
fee.value = new_fee
|
||||
fee.internal_type = p['provider'].identifier
|
||||
fee._calculate_tax()
|
||||
fee.save()
|
||||
else:
|
||||
try:
|
||||
fee = self.order.fees.get(fee_type=OrderFee.FEE_TYPE_PAYMENT)
|
||||
old_fee = fee.value
|
||||
fee.delete()
|
||||
except OrderFee.DoesNotExist:
|
||||
old_fee = Decimal('0.00')
|
||||
|
||||
self.order.payment_provider = p['provider'].identifier
|
||||
self.order.payment_fee = new_fee
|
||||
self.order.total = self._total_order_value + new_fee
|
||||
self.order._calculate_tax()
|
||||
self.order.total = self._total_order_value + (self.order.fees.aggregate(sum=Sum('value'))['sum'] or 0)
|
||||
|
||||
resp = p['provider'].order_prepare(request, self.order)
|
||||
if resp:
|
||||
with transaction.atomic():
|
||||
self.order.log_action('pretix.event.order.payment.changed', {
|
||||
'old_fee': self.order.payment_fee,
|
||||
'old_fee': old_fee,
|
||||
'new_fee': new_fee,
|
||||
'old_provider': self.order.payment_provider,
|
||||
'new_provider': p['provider'].identifier
|
||||
|
||||
Reference in New Issue
Block a user