New signals: fee_calculation_for_cart, order_fee_calculation

This commit is contained in:
Raphael Michel
2017-09-07 18:59:21 +02:00
parent de992cecf3
commit 7c4fc7bd0d
7 changed files with 46 additions and 12 deletions

View File

@@ -19,13 +19,13 @@ Order events
There are multiple signals that will be sent out in the ordering cycle: There are multiple signals that will be sent out in the ordering cycle:
.. automodule:: pretix.base.signals .. automodule:: pretix.base.signals
:members: validate_cart, order_paid, order_placed :members: validate_cart, fee_calculation_for_cart, order_fee_calculation, order_paid, order_placed
Frontend Frontend
-------- --------
.. automodule:: pretix.presale.signals .. automodule:: pretix.presale.signals
:members: html_head, html_footer, footer_links, front_page_top, front_page_bottom, contact_form_fields, question_form_fields, checkout_confirm_messages :members: html_head, html_footer, footer_links, front_page_top, front_page_bottom, contact_form_fields, question_form_fields, checkout_confirm_messages, checkout_confirm_page_content
.. automodule:: pretix.presale.signals .. automodule:: pretix.presale.signals

View File

@@ -20,6 +20,7 @@ from pretix.base.services.async import ProfiledTask
from pretix.base.services.locking import LockTimeoutException from pretix.base.services.locking import LockTimeoutException
from pretix.base.services.pricing import get_price from pretix.base.services.pricing import get_price
from pretix.celery_app import app from pretix.celery_app import app
from pretix.presale.signals import fee_calculation_for_cart
class CartError(LazyLocaleException): class CartError(LazyLocaleException):
@@ -627,7 +628,7 @@ def update_tax_rates(event: Event, cart_id: str, invoice_address: InvoiceAddress
return totaldiff return totaldiff
def get_fees(event, total, invoice_address, provider): def get_fees(event, request, total, invoice_address, provider):
fees = [] fees = []
if total == 0: if total == 0:
@@ -643,7 +644,7 @@ def get_fees(event, total, invoice_address, provider):
if payment_fee_tax_rule.tax_applicable(invoice_address): if payment_fee_tax_rule.tax_applicable(invoice_address):
payment_fee_tax = payment_fee_tax_rule.tax(payment_fee, base_price_is='gross') payment_fee_tax = payment_fee_tax_rule.tax(payment_fee, base_price_is='gross')
fees.append(OrderFee( fees.append(OrderFee(
fee_type="PAYMENT", fee_type=OrderFee.FEE_TYPE_PAYMENT,
value=payment_fee, value=payment_fee,
tax_rate=payment_fee_tax.rate, tax_rate=payment_fee_tax.rate,
tax_value=payment_fee_tax.tax, tax_value=payment_fee_tax.tax,
@@ -651,13 +652,16 @@ def get_fees(event, total, invoice_address, provider):
)) ))
else: else:
fees.append(OrderFee( fees.append(OrderFee(
fee_type="PAYMENT", fee_type=OrderFee.FEE_TYPE_PAYMENT,
value=payment_fee, value=payment_fee,
tax_rate=Decimal('0.00'), tax_rate=Decimal('0.00'),
tax_value=Decimal('0.00'), tax_value=Decimal('0.00'),
tax_rule=payment_fee_tax_rule tax_rule=payment_fee_tax_rule
)) ))
for recv, resp in fee_calculation_for_cart.send(sender=event, request=request, invoice_address=invoice_address):
fees += resp
return fees return fees

View File

@@ -34,7 +34,9 @@ from pretix.base.services.invoices import (
from pretix.base.services.locking import LockTimeoutException from pretix.base.services.locking import LockTimeoutException
from pretix.base.services.mail import SendMailException from pretix.base.services.mail import SendMailException
from pretix.base.services.pricing import get_price from pretix.base.services.pricing import get_price
from pretix.base.signals import order_paid, order_placed, periodic_task from pretix.base.signals import (
order_fee_calculation, order_paid, order_placed, periodic_task,
)
from pretix.celery_app import app from pretix.celery_app import app
from pretix.multidomain.urlreverse import build_absolute_uri from pretix.multidomain.urlreverse import build_absolute_uri
@@ -342,7 +344,8 @@ def _check_positions(event: Event, now_dt: datetime, positions: List[CartPositio
raise OrderError(err, errargs) raise OrderError(err, errargs)
def _get_fees(positions: List[CartPosition], payment_provider: BasePaymentProvider): def _get_fees(positions: List[CartPosition], payment_provider: BasePaymentProvider, address: InvoiceAddress,
meta_info: dict, event: Event):
fees = [] fees = []
total = sum([c.price for c in positions]) total = sum([c.price for c in positions])
payment_fee = payment_provider.calculate_fee(total) payment_fee = payment_provider.calculate_fee(total)
@@ -350,15 +353,18 @@ def _get_fees(positions: List[CartPosition], payment_provider: BasePaymentProvid
fees.append(OrderFee(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=payment_fee, fees.append(OrderFee(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=payment_fee,
internal_type=payment_provider.identifier)) internal_type=payment_provider.identifier))
for recv, resp in order_fee_calculation.send(sender=event, invoice_address=address,
meta_info=meta_info, posiitons=positions):
fees += resp
return fees return fees
def _create_order(event: Event, email: str, positions: List[CartPosition], now_dt: datetime, def _create_order(event: Event, email: str, positions: List[CartPosition], now_dt: datetime,
payment_provider: BasePaymentProvider, locale: str=None, address: int=None, payment_provider: BasePaymentProvider, locale: str=None, address: InvoiceAddress=None,
meta_info: dict=None): meta_info: dict=None):
from datetime import time from datetime import time
fees = _get_fees(positions, payment_provider) fees = _get_fees(positions, payment_provider, address, meta_info, event)
total = sum([c.price for c in positions]) + sum([c.value for c in fees]) total = sum([c.price for c in positions]) + sum([c.value for c in fees])
tz = pytz.timezone(event.settings.timezone) tz = pytz.timezone(event.settings.timezone)

View File

@@ -209,3 +209,16 @@ register_global_settings = django.dispatch.Signal()
All plugins that are installed may send fields for the global settings form, as All plugins that are installed may send fields for the global settings form, as
an OrderedDict of (setting name, form field). an OrderedDict of (setting name, form field).
""" """
order_fee_calculation = EventPluginSignal(
providing_args=['request']
)
"""
This signals allows you to add fees to an order while it is being created. You are expected to
return a list of ``OrderFee`` objects that are not yet saved to the database
(because there is no order yet).
As with all plugin signals, the ``sender`` keyword argument will contain the event. A ``positions``
argument will contain the cart positions and ``invoice_address`` the invoice address (useful for
tax calculation). The argument ``meta_info`` contains the order's meta dictionary.
"""

View File

@@ -68,7 +68,6 @@ You will recieve the request triggering the order creation as the ``request`` ke
As with all event-plugin signals, the ``sender`` keyword argument will contain the event. As with all event-plugin signals, the ``sender`` keyword argument will contain the event.
""" """
checkout_confirm_page_content = EventPluginSignal( checkout_confirm_page_content = EventPluginSignal(
providing_args=['request'] providing_args=['request']
) )
@@ -80,6 +79,18 @@ As with all plugin signals, the ``sender`` keyword argument will contain the eve
argument will contain the request object. argument will contain the request object.
""" """
fee_calculation_for_cart = EventPluginSignal(
providing_args=['request']
)
"""
This signals allows you to add fees to a cart. You are expected to return a list of ``OrderFee``
objects that are not yet saved to the database (because there is no order yet).
As with all plugin signals, the ``sender`` keyword argument will contain the event. A ``request``
argument will contain the request object and ``invoice_address`` the invoice address (useful for
tax calculation).
"""
contact_form_fields = EventPluginSignal( contact_form_fields = EventPluginSignal(
providing_args=[] providing_args=[]
) )

View File

@@ -159,7 +159,7 @@
{% for fee in cart.fees %} {% for fee in cart.fees %}
<div class="row cart-row"> <div class="row cart-row">
<div class="col-md-4 col-xs-6"> <div class="col-md-4 col-xs-6">
<strong>{% trans "Payment method fee" %}</strong> <strong>{{ fee.get_fee_type_display }}</strong>
</div> </div>
<div class="col-md-3 col-xs-6 col-md-offset-5 price"> <div class="col-md-3 col-xs-6 col-md-offset-5 price">
{% if event.settings.display_net_prices %} {% if event.settings.display_net_prices %}

View File

@@ -110,7 +110,7 @@ class CartMixin:
except InvoiceAddress.DoesNotExist: except InvoiceAddress.DoesNotExist:
pass pass
fees = get_fees(self.request.event, total, ia, self.request.session.get('payment')) fees = get_fees(self.request.event, self.request, total, ia, self.request.session.get('payment'))
total += sum([f.value for f in fees]) total += sum([f.value for f in fees])
net_total += sum([f.net_value for f in fees]) net_total += sum([f.net_value for f in fees])