Skip to content

Commit

Permalink
Allow to set amount and date when manually confirming a payment (#3828)
Browse files Browse the repository at this point in the history
* Allow to set amount and date when manually confirming a payment

* Fix tests
  • Loading branch information
raphaelm committed Jan 26, 2024
1 parent 9eb1c50 commit eaae7e9
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 14 deletions.
10 changes: 4 additions & 6 deletions src/pretix/control/forms/orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,6 @@ def __init__(self, *args, **kwargs):
del self.fields['force']


class ConfirmPaymentForm(ForceQuotaConfirmationForm):
pass


class ReactivateOrderForm(ForceQuotaConfirmationForm):
pass

Expand Down Expand Up @@ -220,10 +216,11 @@ class DenyForm(forms.Form):
)


class MarkPaidForm(ConfirmPaymentForm):
class MarkPaidForm(ForceQuotaConfirmationForm):
send_email = forms.BooleanField(
required=False,
label=_('Notify customer by email'),
help_text=_('A mail will only be sent if the order is fully paid after this.'),
initial=True
)
amount = forms.DecimalField(
Expand All @@ -240,9 +237,10 @@ class MarkPaidForm(ConfirmPaymentForm):
)

def __init__(self, *args, **kwargs):
payment = kwargs.pop('payment', None)
super().__init__(*args, **kwargs)
change_decimal_field(self.fields['amount'], self.instance.event.currency)
self.fields['amount'].initial = max(Decimal('0.00'), self.instance.pending_sum)
self.fields['amount'].initial = max(Decimal('0.00'), payment.amount if payment else self.instance.pending_sum)


class ExporterForm(forms.Form):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,13 @@ <h1>
Do you really want to mark this payment as complete?
{% endblocktrans %}</p>
<input type="hidden" name="status" value="p" />
{% bootstrap_form form layout='horizontal' horizontal_label_class='sr-only' horizontal_field_class='col-md-12' %}
{% bootstrap_form_errors form %}
{% bootstrap_field form.amount layout='horizontal' %}
{% bootstrap_field form.payment_date layout='horizontal' %}
{% bootstrap_field form.send_email layout='horizontal' %}
{% if form.force %}
{% bootstrap_field form.force layout='horizontal' horizontal_label_class='sr-only' horizontal_field_class='col-md-12' %}
{% endif %}
<div class="form-group submit-group">
<a class="btn btn-default btn-lg"
href="{% url "control:event.order" event=request.event.slug organizer=request.event.organizer.slug code=order.code %}">
Expand Down
20 changes: 16 additions & 4 deletions src/pretix/control/views/orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,9 @@
RefundFilterForm,
)
from pretix.control.forms.orders import (
CancelForm, CommentForm, ConfirmPaymentForm, DenyForm, EventCancelForm,
ExporterForm, ExtendForm, MarkPaidForm, OrderContactForm,
OrderFeeChangeForm, OrderLocaleForm, OrderMailForm, OrderPositionAddForm,
CancelForm, CommentForm, DenyForm, EventCancelForm, ExporterForm,
ExtendForm, MarkPaidForm, OrderContactForm, OrderFeeChangeForm,
OrderLocaleForm, OrderMailForm, OrderPositionAddForm,
OrderPositionAddFormset, OrderPositionChangeForm, OrderPositionMailForm,
OrderRefundForm, OtherOperationsForm, ReactivateOrderForm,
)
Expand Down Expand Up @@ -1014,9 +1014,10 @@ def payment(self):

@cached_property
def mark_paid_form(self):
return ConfirmPaymentForm(
return MarkPaidForm(
instance=self.order,
data=self.request.POST if self.request.method == "POST" else None,
payment=self.payment,
)

def post(self, *args, **kwargs):
Expand All @@ -1027,8 +1028,19 @@ def post(self, *args, **kwargs):
'order': self.order,
})
try:
payment_date = None
if self.mark_paid_form.cleaned_data['payment_date'] != now().date():
payment_date = make_aware(datetime.combine(
self.mark_paid_form.cleaned_data['payment_date'],
time(hour=0, minute=0, second=0)
), self.order.event.timezone)

self.payment.amount = self.mark_paid_form.cleaned_data['amount']
self.payment.save(update_fields=['amount'])
self.payment.confirm(user=self.request.user,
send_mail=self.mark_paid_form.cleaned_data['send_email'],
count_waitinglist=False,
payment_date=payment_date,
force=self.mark_paid_form.cleaned_data.get('force', False))
except Quota.QuotaExceededException as e:
messages.error(self.request, str(e))
Expand Down
15 changes: 12 additions & 3 deletions src/tests/control/test_orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -1823,7 +1823,10 @@ def test_confirm_payment(client, env):
with scopes_disabled():
p = env[2].payments.last()
client.login(email='dummy@dummy.dummy', password='dummy')
response = client.post('/control/event/dummy/dummy/orders/FOO/payments/{}/confirm'.format(p.pk), {}, follow=True)
response = client.post('/control/event/dummy/dummy/orders/FOO/payments/{}/confirm'.format(p.pk), {
'amount': str(p.amount),
'payment_date': str(now().date().isoformat()),
}, follow=True)
assert 'alert-success' in response.content.decode()
p.refresh_from_db()
assert p.state == OrderPayment.PAYMENT_STATE_CONFIRMED
Expand All @@ -1838,7 +1841,10 @@ def test_confirm_payment_invalid_state(client, env):
p.state = OrderPayment.PAYMENT_STATE_FAILED
p.save()
client.login(email='dummy@dummy.dummy', password='dummy')
response = client.post('/control/event/dummy/dummy/orders/FOO/payments/{}/confirm'.format(p.pk), {}, follow=True)
response = client.post('/control/event/dummy/dummy/orders/FOO/payments/{}/confirm'.format(p.pk), {
'amount': str(p.amount),
'payment_date': str(now().date().isoformat()),
}, follow=True)
assert 'alert-danger' in response.content.decode()
p.refresh_from_db()
assert p.state == OrderPayment.PAYMENT_STATE_FAILED
Expand All @@ -1853,7 +1859,10 @@ def test_confirm_payment_partal_amount(client, env):
p.amount -= Decimal(5.00)
p.save()
client.login(email='dummy@dummy.dummy', password='dummy')
response = client.post('/control/event/dummy/dummy/orders/FOO/payments/{}/confirm'.format(p.pk), {}, follow=True)
response = client.post('/control/event/dummy/dummy/orders/FOO/payments/{}/confirm'.format(p.pk), {
'amount': str(p.amount),
'payment_date': str(now().date().isoformat()),
}, follow=True)
assert 'alert-success' in response.content.decode()
p.refresh_from_db()
assert p.state == OrderPayment.PAYMENT_STATE_CONFIRMED
Expand Down

0 comments on commit eaae7e9

Please sign in to comment.