diff --git a/src/pretix/base/migrations/0107_auto_20190129_1337.py b/src/pretix/base/migrations/0107_auto_20190129_1337.py new file mode 100644 index 0000000000..7ae952a3b5 --- /dev/null +++ b/src/pretix/base/migrations/0107_auto_20190129_1337.py @@ -0,0 +1,21 @@ +# Generated by Django 2.1.5 on 2019-01-29 13:37 + +from django.db import migrations, models +import django.db.models.deletion +import jsonfallback.fields +import pretix.base.models.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('pretixbase', '0106_auto_20190118_1527'), + ] + + operations = [ + migrations.AlterField( + model_name='order', + name='datetime', + field=models.DateTimeField(db_index=True, verbose_name='Date'), + ), + ] diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index cb6b5247aa..babbf5af13 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -137,7 +137,7 @@ class Order(LockModel, LoggedModel): ) secret = models.CharField(max_length=32, default=generate_secret) datetime = models.DateTimeField( - verbose_name=_("Date") + verbose_name=_("Date"), db_index=True ) expires = models.DateTimeField( verbose_name=_("Expiration date") @@ -240,7 +240,7 @@ class Order(LockModel, LoggedModel): return total - payment_sum + refund_sum @classmethod - def annotate_overpayments(cls, qs): + def annotate_overpayments(cls, qs, results=True, refunds=True, sums=False): payment_sum = OrderPayment.objects.filter( state__in=(OrderPayment.PAYMENT_STATE_CONFIRMED, OrderPayment.PAYMENT_STATE_REFUNDED), order=OuterRef('pk') @@ -258,38 +258,47 @@ class Order(LockModel, LoggedModel): state__in=(OrderRefund.REFUND_STATE_CREATED, OrderRefund.REFUND_STATE_TRANSIT), order=OuterRef('pk') ) + payment_sum_sq = Subquery(payment_sum, output_field=models.DecimalField(decimal_places=2, max_digits=10)) + refund_sum_sq = Subquery(refund_sum, output_field=models.DecimalField(decimal_places=2, max_digits=10)) + if sums: + qs = qs.annotate( + payment_sum=payment_sum_sq, + refund_sum=refund_sum_sq, + ) qs = qs.annotate( - payment_sum=Subquery(payment_sum, output_field=models.DecimalField(decimal_places=2, max_digits=10)), - refund_sum=Subquery(refund_sum, output_field=models.DecimalField(decimal_places=2, max_digits=10)), - has_external_refund=Exists(external_refund), - has_pending_refund=Exists(pending_refund), - ).annotate( - pending_sum_t=F('total') - Coalesce(F('payment_sum'), 0) + Coalesce(F('refund_sum'), 0), - pending_sum_rc=-1 * Coalesce(F('payment_sum'), 0) + Coalesce(F('refund_sum'), 0), - ).annotate( - is_overpaid=Case( - When(~Q(status=Order.STATUS_CANCELED) & Q(pending_sum_t__lt=-1e-8), - then=Value('1')), - When(Q(status=Order.STATUS_CANCELED) & Q(pending_sum_rc__lt=-1e-8), - then=Value('1')), - default=Value('0'), - output_field=models.IntegerField() - ), - is_pending_with_full_payment=Case( - When(Q(status__in=(Order.STATUS_EXPIRED, Order.STATUS_PENDING)) & Q(pending_sum_t__lte=1e-8) - & Q(require_approval=False), - then=Value('1')), - default=Value('0'), - output_field=models.IntegerField() - ), - is_underpaid=Case( - When(Q(status=Order.STATUS_PAID) & Q(pending_sum_t__gt=1e-8), - then=Value('1')), - default=Value('0'), - output_field=models.IntegerField() - ) + pending_sum_t=F('total') - Coalesce(payment_sum_sq, 0) + Coalesce(refund_sum_sq, 0), + pending_sum_rc=-1 * Coalesce(payment_sum_sq, 0) + Coalesce(refund_sum_sq, 0), ) + if refunds: + qs = qs.annotate( + has_external_refund=Exists(external_refund), + has_pending_refund=Exists(pending_refund), + ) + if results: + qs = qs.annotate( + is_overpaid=Case( + When(~Q(status=Order.STATUS_CANCELED) & Q(pending_sum_t__lt=-1e-8), + then=Value('1')), + When(Q(status=Order.STATUS_CANCELED) & Q(pending_sum_rc__lt=-1e-8), + then=Value('1')), + default=Value('0'), + output_field=models.IntegerField() + ), + is_pending_with_full_payment=Case( + When(Q(status__in=(Order.STATUS_EXPIRED, Order.STATUS_PENDING)) & Q(pending_sum_t__lte=1e-8) + & Q(require_approval=False), + then=Value('1')), + default=Value('0'), + output_field=models.IntegerField() + ), + is_underpaid=Case( + When(Q(status=Order.STATUS_PAID) & Q(pending_sum_t__gt=1e-8), + then=Value('1')), + default=Value('0'), + output_field=models.IntegerField() + ) + ) return qs @property diff --git a/src/pretix/control/forms/filter.py b/src/pretix/control/forms/filter.py index b63fc7f6d6..0d9cf0ada8 100644 --- a/src/pretix/control/forms/filter.py +++ b/src/pretix/control/forms/filter.py @@ -175,7 +175,7 @@ class OrderFilterForm(FilterForm): class EventOrderFilterForm(OrderFilterForm): orders = {'code': 'code', 'email': 'email', 'total': 'total', - 'datetime': 'datetime', 'status': 'status', 'pcnt': 'pcnt'} + 'datetime': 'datetime', 'status': 'status'} item = forms.ModelChoiceField( label=_('Products'), @@ -275,16 +275,19 @@ class EventOrderFilterForm(OrderFilterForm): qs = qs.annotate(has_answer=Exists(answers)).filter(has_answer=True) if fdata.get('status') == 'overpaid': + qs = Order.annotate_overpayments(qs, refunds=False, results=False, sums=True) qs = qs.filter( Q(~Q(status=Order.STATUS_CANCELED) & Q(pending_sum_t__lt=0)) | Q(Q(status=Order.STATUS_CANCELED) & Q(pending_sum_rc__lt=0)) ) elif fdata.get('status') == 'pendingpaid': + qs = Order.annotate_overpayments(qs, refunds=False, results=False, sums=True) qs = qs.filter( Q(status__in=(Order.STATUS_EXPIRED, Order.STATUS_PENDING)) & Q(pending_sum_t__lte=0) & Q(require_approval=False) ) elif fdata.get('status') == 'underpaid': + qs = Order.annotate_overpayments(qs, refunds=False, results=False, sums=True) qs = qs.filter( status=Order.STATUS_PAID, pending_sum_t__gt=0 @@ -300,7 +303,7 @@ class EventOrderFilterForm(OrderFilterForm): class OrderSearchFilterForm(OrderFilterForm): orders = {'code': 'code', 'email': 'email', 'total': 'total', - 'datetime': 'datetime', 'status': 'status', 'pcnt': 'pcnt', + 'datetime': 'datetime', 'status': 'status', 'event': 'event'} organizer = forms.ModelChoiceField( diff --git a/src/pretix/control/templates/pretixcontrol/orders/index.html b/src/pretix/control/templates/pretixcontrol/orders/index.html index edcf7ea6d8..abc23b2519 100644 --- a/src/pretix/control/templates/pretixcontrol/orders/index.html +++ b/src/pretix/control/templates/pretixcontrol/orders/index.html @@ -101,9 +101,7 @@