diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index 0b4b26763c..3f7b9321aa 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -1172,7 +1172,8 @@ class OrderPayment(models.Model): self.order.log_action('pretix.event.order.overpaid', {}, user=user, auth=auth) order_paid.send(self.order.event, order=self.order) - def confirm(self, count_waitinglist=True, send_mail=True, force=False, user=None, auth=None, mail_text='', ignore_date=False, lock=True): + def confirm(self, count_waitinglist=True, send_mail=True, force=False, user=None, auth=None, mail_text='', + ignore_date=False, lock=True, payment_date=None): """ Marks the payment as complete. If possible, this also marks the order as paid if no further payment is required @@ -1203,7 +1204,7 @@ class OrderPayment(models.Model): return locked_instance.state = self.PAYMENT_STATE_CONFIRMED - locked_instance.payment_date = now() + locked_instance.payment_date = payment_date or now() locked_instance.info = self.info # required for backwards compatibility locked_instance.save(update_fields=['state', 'payment_date', 'info']) diff --git a/src/pretix/control/forms/orders.py b/src/pretix/control/forms/orders.py index 320f811005..3ac05f6742 100644 --- a/src/pretix/control/forms/orders.py +++ b/src/pretix/control/forms/orders.py @@ -9,6 +9,7 @@ from django.utils.timezone import now from django.utils.translation import pgettext_lazy, ugettext_lazy as _ from pretix.base.forms import I18nModelForm, PlaceholderValidator +from pretix.base.forms.widgets import DatePickerWidget from pretix.base.models import InvoiceAddress, ItemAddOn, Order, OrderPosition from pretix.base.models.event import SubEvent from pretix.base.services.pricing import get_price @@ -116,6 +117,12 @@ class MarkPaidForm(ConfirmPaymentForm): localize=True, label=_('Payment amount'), ) + payment_date = forms.DateField( + required=True, + label=_('Payment date'), + widget=DatePickerWidget(), + initial=now + ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) diff --git a/src/pretix/control/templates/pretixcontrol/order/pay.html b/src/pretix/control/templates/pretixcontrol/order/pay.html index 5c1eed4ab8..cc359d46d5 100644 --- a/src/pretix/control/templates/pretixcontrol/order/pay.html +++ b/src/pretix/control/templates/pretixcontrol/order/pay.html @@ -23,6 +23,7 @@ {% bootstrap_form_errors form %} {% bootstrap_field form.amount layout='horizontal' %} + {% bootstrap_field form.payment_date layout='horizontal' %} {% if form.force %} {% bootstrap_field form.force layout='horizontal' horizontal_label_class='sr-only' horizontal_field_class='col-md-12' %} {% endif %} diff --git a/src/pretix/control/views/orders.py b/src/pretix/control/views/orders.py index b89c602488..0d20681ced 100644 --- a/src/pretix/control/views/orders.py +++ b/src/pretix/control/views/orders.py @@ -3,7 +3,7 @@ import logging import mimetypes import os import re -from datetime import timedelta +from datetime import datetime, time, timedelta from decimal import Decimal, DecimalException import pytz @@ -24,7 +24,7 @@ from django.utils import formats from django.utils.formats import date_format from django.utils.functional import cached_property from django.utils.http import is_safe_url -from django.utils.timezone import now +from django.utils.timezone import make_aware, now from django.utils.translation import ugettext_lazy as _ from django.views.generic import ( DetailView, FormView, ListView, TemplateView, View, @@ -862,8 +862,15 @@ class OrderTransition(OrderView): fee=None ) + 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) + try: - p.confirm(user=self.request.user, count_waitinglist=False, + p.confirm(user=self.request.user, count_waitinglist=False, payment_date=payment_date, force=self.mark_paid_form.cleaned_data.get('force', False)) except Quota.QuotaExceededException as e: p.state = OrderPayment.PAYMENT_STATE_FAILED