From 12b48948e3b24868acf6a9a5b1806bbc6dfafeb0 Mon Sep 17 00:00:00 2001 From: Raphael Michel Date: Fri, 8 Mar 2019 11:40:22 +0100 Subject: [PATCH] Add a new notification category for overpayments --- src/pretix/base/models/orders.py | 9 ++++++--- src/pretix/base/notifications.py | 6 ++++++ src/pretix/control/logdisplay.py | 1 + src/tests/base/test_models.py | 11 +++++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index 6a8d22a0a..c07fa507d 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -1086,7 +1086,7 @@ class OrderPayment(models.Model): """ return self.order.event.get_payment_providers().get(self.provider) - def _mark_paid(self, force, count_waitinglist, user, auth): + def _mark_paid(self, force, count_waitinglist, user, auth, overpaid=False): from pretix.base.signals import order_paid can_be_paid = self.order._can_be_paid(count_waitinglist=count_waitinglist) if not force and can_be_paid is not True: @@ -1103,6 +1103,9 @@ class OrderPayment(models.Model): 'date': self.payment_date, 'force': force }, user=user, auth=auth) + + if overpaid: + 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=''): @@ -1168,10 +1171,10 @@ class OrderPayment(models.Model): # Performance optimization. In this case, there's really no reason to lock everything and an atomic # database transaction is more than enough. with transaction.atomic(): - self._mark_paid(force, count_waitinglist, user, auth) + self._mark_paid(force, count_waitinglist, user, auth, overpaid=payment_sum - refund_sum > self.order.total) else: with self.order.event.lock(): - self._mark_paid(force, count_waitinglist, user, auth) + self._mark_paid(force, count_waitinglist, user, auth, overpaid=payment_sum - refund_sum > self.order.total) invoice = None if invoice_qualified(self.order): diff --git a/src/pretix/base/notifications.py b/src/pretix/base/notifications.py index 75e95bec1..1a78242ed 100644 --- a/src/pretix/base/notifications.py +++ b/src/pretix/base/notifications.py @@ -236,6 +236,12 @@ def register_default_notification_types(sender, **kwargs): _('Order changed'), _('Order {order.code} has been changed.') ), + ParametrizedOrderNotificationType( + sender, + 'pretix.event.order.overpaid', + _('Order has been overpaid'), + _('Order {order.code} has been overpaid.') + ), ParametrizedOrderNotificationType( sender, 'pretix.event.order.refund.created.externally', diff --git a/src/pretix/control/logdisplay.py b/src/pretix/control/logdisplay.py index 4bfa1e70a..43d564cc9 100644 --- a/src/pretix/control/logdisplay.py +++ b/src/pretix/control/logdisplay.py @@ -211,6 +211,7 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs): 'pretix.event.order.payment.started': _('Payment {local_id} has been started.'), 'pretix.event.order.payment.failed': _('Payment {local_id} has failed.'), 'pretix.event.order.quotaexceeded': _('The order could not be marked as paid: {message}'), + 'pretix.event.order.overpaid': _('The order has been overpaid.'), 'pretix.event.order.refund.created': _('Refund {local_id} has been created.'), 'pretix.event.order.refund.created.externally': _('Refund {local_id} has been created by an external entity.'), 'pretix.event.order.refund.requested': _('The customer requested you to issue a refund.'), diff --git a/src/tests/base/test_models.py b/src/tests/base/test_models.py index bce761e12..f1a893956 100644 --- a/src/tests/base/test_models.py +++ b/src/tests/base/test_models.py @@ -616,6 +616,7 @@ class OrderTestCase(BaseQuotaTestCase): ).confirm() self.order = Order.objects.get(id=self.order.id) self.assertEqual(self.order.status, Order.STATUS_PAID) + assert not self.order.all_logentries().filter(action_type='pretix.event.order.overpaid').exists() def test_paid_expired_available(self): self.event.settings.payment_term_last = (now() + timedelta(days=2)).strftime('%Y-%m-%d') @@ -742,6 +743,16 @@ class OrderTestCase(BaseQuotaTestCase): self.order = Order.objects.get(id=self.order.id) self.assertEqual(self.order.status, Order.STATUS_PAID) + def test_paid_overpaid(self): + self.quota.size = 2 + self.quota.save() + self.order.payments.create( + provider='manual', amount=self.order.total + 2 + ).confirm(count_waitinglist=False) + self.order = Order.objects.get(id=self.order.id) + self.assertEqual(self.order.status, Order.STATUS_PAID) + assert self.order.all_logentries().filter(action_type='pretix.event.order.overpaid').exists() + def test_can_modify_answers(self): self.event.settings.set('invoice_address_asked', False) self.event.settings.set('attendee_names_asked', True)