mirror of
https://github.com/pretix/pretix.git
synced 2026-05-04 15:04:03 +00:00
Cancelling events: Allow to select fee types to keep
This commit is contained in:
@@ -2,9 +2,7 @@ import logging
|
||||
from decimal import Decimal
|
||||
|
||||
from django.db import transaction
|
||||
from django.db.models import (
|
||||
Count, Exists, IntegerField, OuterRef, Subquery, Sum,
|
||||
)
|
||||
from django.db.models import Count, Exists, IntegerField, OuterRef, Subquery
|
||||
from i18nfield.strings import LazyI18nString
|
||||
|
||||
from pretix.base.decimal import round_decimal
|
||||
@@ -85,8 +83,8 @@ def _send_mail(order: Order, subject: LazyI18nString, message: LazyI18nString, s
|
||||
|
||||
@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,))
|
||||
def cancel_event(self, event: Event, subevent: int, auto_refund: bool, keep_fee_fixed: str,
|
||||
keep_fee_percentage: str, keep_fees: bool,
|
||||
send: bool, send_subject: dict, send_message: dict,
|
||||
keep_fee_percentage: str, keep_fees: list=None,
|
||||
send: bool=False, send_subject: dict=None, send_message: dict=None,
|
||||
send_waitinglist: bool=False, send_waitinglist_subject: dict={}, send_waitinglist_message: dict={},
|
||||
user: int=None):
|
||||
send_subject = LazyI18nString(send_subject)
|
||||
@@ -151,20 +149,21 @@ def cancel_event(self, event: Event, subevent: int, auto_refund: bool, keep_fee_
|
||||
for o in orders_to_cancel.only('id', 'total'):
|
||||
try:
|
||||
fee = Decimal('0.00')
|
||||
fee_sum = Decimal('0.00')
|
||||
keep_fee_objects = []
|
||||
if keep_fees:
|
||||
fee += o.fees.filter(
|
||||
fee_type__in=(OrderFee.FEE_TYPE_PAYMENT, OrderFee.FEE_TYPE_SHIPPING, OrderFee.FEE_TYPE_SERVICE,
|
||||
OrderFee.FEE_TYPE_CANCELLATION)
|
||||
).aggregate(
|
||||
s=Sum('value')
|
||||
)['s'] or 0
|
||||
for f in o.fees.all():
|
||||
if f.fee_type in keep_fees:
|
||||
fee += f.value
|
||||
keep_fee_objects.append(f)
|
||||
fee_sum += f.value
|
||||
if keep_fee_percentage:
|
||||
fee += Decimal(keep_fee_percentage) / Decimal('100.00') * (o.total - fee)
|
||||
fee += Decimal(keep_fee_percentage) / Decimal('100.00') * (o.total - fee_sum)
|
||||
if keep_fee_fixed:
|
||||
fee += Decimal(keep_fee_fixed)
|
||||
fee = round_decimal(min(fee, o.payment_refund_sum), event.currency)
|
||||
|
||||
_cancel_order(o.pk, user, send_mail=False, cancellation_fee=fee)
|
||||
_cancel_order(o.pk, user, send_mail=False, cancellation_fee=fee, keep_fees=keep_fee_objects)
|
||||
refund_amount = o.payment_refund_sum
|
||||
|
||||
if auto_refund:
|
||||
|
||||
@@ -319,7 +319,7 @@ def deny_order(order, comment='', user=None, send_mail: bool=True, auth=None):
|
||||
|
||||
|
||||
def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device=None, oauth_application=None,
|
||||
cancellation_fee=None):
|
||||
cancellation_fee=None, keep_fees=None):
|
||||
"""
|
||||
Mark this order as canceled
|
||||
:param order: The order to change
|
||||
@@ -367,23 +367,28 @@ def _cancel_order(order, user=None, send_mail: bool=True, api_token=None, device
|
||||
Voucher.objects.filter(pk=position.voucher.pk).update(redeemed=Greatest(0, F('redeemed') - 1))
|
||||
position.canceled = True
|
||||
position.save(update_fields=['canceled'])
|
||||
new_fee = cancellation_fee
|
||||
for fee in order.fees.all():
|
||||
fee.canceled = True
|
||||
fee.save(update_fields=['canceled'])
|
||||
if keep_fees and fee in keep_fees:
|
||||
new_fee -= fee.value
|
||||
else:
|
||||
fee.canceled = True
|
||||
fee.save(update_fields=['canceled'])
|
||||
|
||||
f = OrderFee(
|
||||
fee_type=OrderFee.FEE_TYPE_CANCELLATION,
|
||||
value=cancellation_fee,
|
||||
tax_rule=order.event.settings.tax_rate_default,
|
||||
order=order,
|
||||
)
|
||||
f._calculate_tax()
|
||||
f.save()
|
||||
if new_fee:
|
||||
f = OrderFee(
|
||||
fee_type=OrderFee.FEE_TYPE_CANCELLATION,
|
||||
value=new_fee,
|
||||
tax_rule=order.event.settings.tax_rate_default,
|
||||
order=order,
|
||||
)
|
||||
f._calculate_tax()
|
||||
f.save()
|
||||
|
||||
if order.payment_refund_sum < cancellation_fee:
|
||||
raise OrderError(_('The cancellation fee cannot be higher than the payment credit of this order.'))
|
||||
order.status = Order.STATUS_PAID
|
||||
order.total = f.value
|
||||
order.total = cancellation_fee
|
||||
order.save(update_fields=['status', 'total'])
|
||||
|
||||
if i:
|
||||
|
||||
Reference in New Issue
Block a user