mirror of
https://github.com/pretix/pretix.git
synced 2026-05-17 17:14:04 +00:00
Rounding on payment method change
This commit is contained in:
@@ -3146,6 +3146,7 @@ def change_payment_provider(order: Order, payment_provider, amount=None, new_pay
|
|||||||
raise Exception('change_payment_provider should only be called in atomic transaction!')
|
raise Exception('change_payment_provider should only be called in atomic transaction!')
|
||||||
|
|
||||||
oldtotal = order.total
|
oldtotal = order.total
|
||||||
|
already_paid = order.payment_refund_sum
|
||||||
e = OrderPayment.objects.filter(fee=OuterRef('pk'), state__in=(OrderPayment.PAYMENT_STATE_CONFIRMED,
|
e = OrderPayment.objects.filter(fee=OuterRef('pk'), state__in=(OrderPayment.PAYMENT_STATE_CONFIRMED,
|
||||||
OrderPayment.PAYMENT_STATE_REFUNDED))
|
OrderPayment.PAYMENT_STATE_REFUNDED))
|
||||||
open_fees = list(
|
open_fees = list(
|
||||||
@@ -3162,19 +3163,44 @@ def change_payment_provider(order: Order, payment_provider, amount=None, new_pay
|
|||||||
fee = OrderFee(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=Decimal('0.00'), order=order)
|
fee = OrderFee(fee_type=OrderFee.FEE_TYPE_PAYMENT, value=Decimal('0.00'), order=order)
|
||||||
old_fee = fee.value
|
old_fee = fee.value
|
||||||
|
|
||||||
|
positions = list(order.positions.all())
|
||||||
|
fees = list(order.fees.all())
|
||||||
|
rounding_changed = set(apply_rounding(
|
||||||
|
order.tax_rounding_mode, order.event.currency, [*positions, *[f for f in fees if f.pk != fee.pk]]
|
||||||
|
))
|
||||||
|
total_without_fee = sum(c.price for c in positions) + sum(f.value for f in fees if f.pk != fee.pk)
|
||||||
|
pending_sum_without_fee = max(Decimal("0.00"), total_without_fee - already_paid)
|
||||||
|
|
||||||
new_fee = payment_provider.calculate_fee(
|
new_fee = payment_provider.calculate_fee(
|
||||||
order.pending_sum - old_fee if amount is None else amount
|
pending_sum_without_fee if amount is None else amount
|
||||||
)
|
)
|
||||||
if new_fee:
|
if new_fee:
|
||||||
fee.value = new_fee
|
fee.value = new_fee
|
||||||
fee.internal_type = payment_provider.identifier
|
fee.internal_type = payment_provider.identifier
|
||||||
fee._calculate_tax()
|
fee._calculate_tax()
|
||||||
|
if not fee.pk:
|
||||||
|
fees.append(fee)
|
||||||
fee.save()
|
fee.save()
|
||||||
else:
|
else:
|
||||||
if fee.pk:
|
if fee.pk:
|
||||||
fee.delete()
|
fee.delete()
|
||||||
|
if fee in fees:
|
||||||
|
fees.remove(fee)
|
||||||
fee = None
|
fee = None
|
||||||
|
|
||||||
|
rounding_changed |= set(apply_rounding(
|
||||||
|
order.tax_rounding_mode, order.event.currency, [*positions, *fees]
|
||||||
|
))
|
||||||
|
for l in rounding_changed:
|
||||||
|
if isinstance(l, OrderPosition):
|
||||||
|
l.save(update_fields=[
|
||||||
|
"price", "price_includes_rounding_correction", "tax_value", "tax_value_includes_rounding_correction"
|
||||||
|
])
|
||||||
|
elif isinstance(l, OrderFee):
|
||||||
|
l.save(update_fields=[
|
||||||
|
"value", "value_includes_rounding_correction", "tax_value", "tax_value_includes_rounding_correction"
|
||||||
|
])
|
||||||
|
|
||||||
open_payment = None
|
open_payment = None
|
||||||
if new_payment:
|
if new_payment:
|
||||||
lp = order.payments.select_for_update(of=OF_SELF).exclude(pk=new_payment.pk).last()
|
lp = order.payments.select_for_update(of=OF_SELF).exclude(pk=new_payment.pk).last()
|
||||||
@@ -3201,7 +3227,7 @@ def change_payment_provider(order: Order, payment_provider, amount=None, new_pay
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
order.total = (order.positions.aggregate(sum=Sum('price'))['sum'] or 0) + (order.fees.aggregate(sum=Sum('value'))['sum'] or 0)
|
order.total = sum(c.price for c in positions) + sum(f.value for f in fees)
|
||||||
order.save(update_fields=['total'])
|
order.save(update_fields=['total'])
|
||||||
|
|
||||||
if not new_payment:
|
if not new_payment:
|
||||||
|
|||||||
@@ -1388,7 +1388,7 @@ class PaymentStep(CartMixin, TemplateFlowStep):
|
|||||||
ctx['cart'] = self.get_cart()
|
ctx['cart'] = self.get_cart()
|
||||||
ctx['current_payments'] = [
|
ctx['current_payments'] = [
|
||||||
p for p in self.current_selected_payments(
|
p for p in self.current_selected_payments(
|
||||||
ctx['cart']['positions'], ctx['cart']['fees'], ctx['cart']['invoice_address'],
|
ctx['cart']['raw'], ctx['cart']['fees'], ctx['cart']['invoice_address'],
|
||||||
)
|
)
|
||||||
if p.get('multi_use_supported')
|
if p.get('multi_use_supported')
|
||||||
]
|
]
|
||||||
@@ -1430,7 +1430,6 @@ class PaymentStep(CartMixin, TemplateFlowStep):
|
|||||||
total = sum([c.price for c in cart]) + sum([f.value for f in fees])
|
total = sum([c.price for c in cart]) + sum([f.value for f in fees])
|
||||||
|
|
||||||
selected = self.current_selected_payments(cart, fees, self.invoice_address, warn=warn)
|
selected = self.current_selected_payments(cart, fees, self.invoice_address, warn=warn)
|
||||||
print(sum(p['payment_amount'] for p in selected), total)
|
|
||||||
if sum(p['payment_amount'] for p in selected) != total:
|
if sum(p['payment_amount'] for p in selected) != total:
|
||||||
if warn:
|
if warn:
|
||||||
messages.error(request, _('Please select a payment method to proceed.'))
|
messages.error(request, _('Please select a payment method to proceed.'))
|
||||||
@@ -1515,7 +1514,7 @@ class ConfirmStep(CartMixin, AsyncAction, TemplateFlowStep):
|
|||||||
ctx['cart'] = self.get_cart(answers=True)
|
ctx['cart'] = self.get_cart(answers=True)
|
||||||
|
|
||||||
selected_payments = self.current_selected_payments(
|
selected_payments = self.current_selected_payments(
|
||||||
ctx['cart']['positions'],
|
ctx['cart']['raw'],
|
||||||
ctx['cart']['fees'],
|
ctx['cart']['fees'],
|
||||||
ctx['cart']['invoice_address'],
|
ctx['cart']['invoice_address'],
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user