forked from CGM_Public/pretix_original
Fix #999 -- Clarify definition of overpaid
This commit is contained in:
@@ -240,15 +240,17 @@ class Order(LoggedModel):
|
||||
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 * F('payment_sum') + 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__in=(Order.STATUS_REFUNDED, Order.STATUS_CANCELED)) & Q(pending_sum_t__lt=0),
|
||||
then=Value('1')),
|
||||
When(Q(status__in=(Order.STATUS_REFUNDED, Order.STATUS_CANCELED)) & Q(pending_sum_rc__lt=0),
|
||||
then=Value('1')),
|
||||
When(Q(status__in=(Order.STATUS_EXPIRED, Order.STATUS_PENDING)) & Q(pending_sum_t__lt=0),
|
||||
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=0)
|
||||
& Q(require_approval=False),
|
||||
then=Value('1')),
|
||||
|
||||
@@ -209,6 +209,7 @@ class EventOrderFilterForm(OrderFilterForm):
|
||||
('pa', _('Approval pending')),
|
||||
('overpaid', _('Overpaid')),
|
||||
('underpaid', _('Underpaid')),
|
||||
('pendingpaid', _('Pending (but fully paid)'))
|
||||
),
|
||||
required=False,
|
||||
)
|
||||
@@ -276,9 +277,11 @@ class EventOrderFilterForm(OrderFilterForm):
|
||||
qs = qs.filter(
|
||||
Q(~Q(status__in=(Order.STATUS_REFUNDED, Order.STATUS_CANCELED)) & Q(pending_sum_t__lt=0))
|
||||
| Q(Q(status__in=(Order.STATUS_REFUNDED, Order.STATUS_CANCELED)) & Q(pending_sum_rc__lt=0))
|
||||
| Q(Q(status__in=(Order.STATUS_EXPIRED, Order.STATUS_PENDING)) & Q(pending_sum_t__lt=0))
|
||||
| Q(Q(status__in=(Order.STATUS_EXPIRED, Order.STATUS_PENDING)) & Q(pending_sum_t__lte=0)
|
||||
& Q(require_approval=False))
|
||||
)
|
||||
elif fdata.get('status') == 'pendingpaid':
|
||||
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 = qs.filter(
|
||||
|
||||
@@ -43,6 +43,17 @@
|
||||
class="btn btn-primary">{% trans "Show orders pending approval" %}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if has_pending_orders_with_full_payment %}
|
||||
<div class="alert alert-warning">
|
||||
{% blocktrans trimmed %}
|
||||
This event contains <strong>fully paid orders</strong> that are not marked as paid, probably
|
||||
because no quota was left at the time their payment arrived. You should review the cases and consider
|
||||
either refunding the customer or creating more space.
|
||||
{% endblocktrans %}
|
||||
<a href="{% url "control:event.orders" event=request.event.slug organizer=request.event.organizer.slug %}?status=pendingpaid"
|
||||
class="btn btn-primary">{% trans "Show affected orders" %}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if actions|length > 0 %}
|
||||
<div class="panel panel-danger">
|
||||
<div class="panel-heading">
|
||||
|
||||
@@ -137,6 +137,8 @@
|
||||
<span class="label label-warning">{% trans "OVERPAID" %}</span>
|
||||
{% elif o.is_underpaid %}
|
||||
<span class="label label-danger">{% trans "UNDERPAID" %}</span>
|
||||
{% elif o.is_pending_with_full_payment %}
|
||||
<span class="label label-danger">{% trans "FULLY PAID" %}</span>
|
||||
{% endif %}
|
||||
{{ o.total|money:request.event.currency }}
|
||||
</td>
|
||||
|
||||
@@ -270,9 +270,9 @@ def event_index(request, organizer, event):
|
||||
ctx['has_overpaid_orders'] = Order.annotate_overpayments(request.event.orders).filter(
|
||||
Q(~Q(status__in=(Order.STATUS_REFUNDED, Order.STATUS_CANCELED)) & Q(pending_sum_t__lt=0))
|
||||
| Q(Q(status__in=(Order.STATUS_REFUNDED, Order.STATUS_CANCELED)) & Q(pending_sum_rc__lt=0))
|
||||
| Q(Q(status__in=(Order.STATUS_EXPIRED, Order.STATUS_PENDING)) & Q(pending_sum_t__lt=0))
|
||||
| Q(Q(status__in=(Order.STATUS_EXPIRED, Order.STATUS_PENDING)) & Q(pending_sum_t__lte=0)
|
||||
& Q(require_approval=False))
|
||||
).exists()
|
||||
ctx['has_pending_orders_with_full_payment'] = Order.annotate_overpayments(request.event.orders).filter(
|
||||
Q(status__in=(Order.STATUS_EXPIRED, Order.STATUS_PENDING)) & Q(pending_sum_t__lte=0) & Q(require_approval=False)
|
||||
).exists()
|
||||
ctx['has_pending_refunds'] = OrderRefund.objects.filter(
|
||||
order__event=request.event,
|
||||
|
||||
@@ -1018,7 +1018,8 @@ class OrderTestCase(BaseQuotaTestCase):
|
||||
assert self.order.pending_sum == Decimal('0.00')
|
||||
o = Order.annotate_overpayments(Order.objects.all()).first()
|
||||
assert not o.is_underpaid
|
||||
assert o.is_overpaid
|
||||
assert not o.is_overpaid
|
||||
assert not o.is_pending_with_full_payment
|
||||
assert not o.has_pending_refund
|
||||
assert not o.has_external_refund
|
||||
|
||||
|
||||
Reference in New Issue
Block a user