diff --git a/doc/api/resources/orders.rst b/doc/api/resources/orders.rst index 0fc3d2ab80..527d437a0c 100644 --- a/doc/api/resources/orders.rst +++ b/doc/api/resources/orders.rst @@ -325,7 +325,8 @@ state string Payment state, source string How this refund has been created, one of ``buyer``, ``admin``, or ``external`` amount money (string) Payment amount created datetime Date and time of creation of this payment -payment_date datetime Date and time of completion of this payment (or ``null``) +comment string Reason for refund (shown to the customer in some cases, can be ``null``). +execution_date datetime Date and time of completion of this refund (or ``null``) provider string Identification string of the payment provider ===================================== ========================== ======================================================= @@ -2119,6 +2120,7 @@ Order refund endpoints "payment": 1, "created": "2017-12-01T10:00:00Z", "execution_date": "2017-12-04T12:13:12Z", + "comment": "Cancellation", "provider": "banktransfer" } ] @@ -2161,6 +2163,7 @@ Order refund endpoints "payment": 1, "created": "2017-12-01T10:00:00Z", "execution_date": "2017-12-04T12:13:12Z", + "comment": "Cancellation", "provider": "banktransfer" } @@ -2195,6 +2198,7 @@ Order refund endpoints "amount": "23.00", "payment": 1, "execution_date": null, + "comment": "Cancellation", "provider": "manual", "mark_canceled": false, "mark_pending": true @@ -2216,6 +2220,7 @@ Order refund endpoints "payment": 1, "created": "2017-12-01T10:00:00Z", "execution_date": null, + "comment": "Cancellation", "provider": "manual" } diff --git a/src/pretix/api/serializers/order.py b/src/pretix/api/serializers/order.py index babadf1bb3..2df995aaad 100644 --- a/src/pretix/api/serializers/order.py +++ b/src/pretix/api/serializers/order.py @@ -502,7 +502,7 @@ class OrderRefundSerializer(I18nAwareModelSerializer): class Meta: model = OrderRefund - fields = ('local_id', 'state', 'source', 'amount', 'payment', 'created', 'execution_date', 'provider') + fields = ('local_id', 'state', 'source', 'amount', 'payment', 'created', 'execution_date', 'comment', 'provider') class OrderURLField(serializers.URLField): @@ -1324,7 +1324,7 @@ class OrderRefundCreateSerializer(I18nAwareModelSerializer): class Meta: model = OrderRefund - fields = ('state', 'source', 'amount', 'payment', 'execution_date', 'provider', 'info') + fields = ('state', 'source', 'amount', 'payment', 'execution_date', 'provider', 'info', 'comment') def create(self, validated_data): pid = validated_data.pop('payment', None) diff --git a/src/pretix/base/exporters/orderlist.py b/src/pretix/base/exporters/orderlist.py index 5b5135a04b..7cb66ce66c 100644 --- a/src/pretix/base/exporters/orderlist.py +++ b/src/pretix/base/exporters/orderlist.py @@ -652,7 +652,7 @@ class PaymentListExporter(ListExporter): headers = [ _('Event slug'), _('Order'), _('Payment ID'), _('Creation date'), _('Completion date'), _('Status'), - _('Status code'), _('Amount'), _('Payment method') + _('Status code'), _('Amount'), _('Payment method'), _('Comment') ] yield headers @@ -674,7 +674,8 @@ class PaymentListExporter(ListExporter): obj.get_state_display(), obj.state, obj.amount * (-1 if isinstance(obj, OrderRefund) else 1), - provider_names.get(obj.provider, obj.provider) + provider_names.get(obj.provider, obj.provider), + obj.comment if isinstance(obj, OrderRefund) else "", ] yield row diff --git a/src/pretix/base/migrations/0175_orderrefund_comment.py b/src/pretix/base/migrations/0175_orderrefund_comment.py new file mode 100644 index 0000000000..2adab5e82e --- /dev/null +++ b/src/pretix/base/migrations/0175_orderrefund_comment.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.11 on 2021-01-15 09:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pretixbase', '0174_merge_20201222_1031'), + ] + + operations = [ + migrations.AddField( + model_name='orderrefund', + name='comment', + field=models.TextField(null=True), + ), + ] diff --git a/src/pretix/base/models/orders.py b/src/pretix/base/models/orders.py index 799bb43f72..9a3cc611ed 100644 --- a/src/pretix/base/models/orders.py +++ b/src/pretix/base/models/orders.py @@ -1716,6 +1716,11 @@ class OrderRefund(models.Model): max_length=255, verbose_name=_("Payment provider") ) + comment = models.TextField( + verbose_name=_("Refund reason"), + help_text=_('May be shown to the end user or used e.g. as part of a payment reference.'), + null=True, blank=True + ) info = models.TextField( verbose_name=_("Payment information"), null=True, blank=True diff --git a/src/pretix/base/services/cancelevent.py b/src/pretix/base/services/cancelevent.py index 300c0a5af1..1e073a85d3 100644 --- a/src/pretix/base/services/cancelevent.py +++ b/src/pretix/base/services/cancelevent.py @@ -3,6 +3,7 @@ from decimal import Decimal from django.db import transaction from django.db.models import Count, Exists, IntegerField, OuterRef, Subquery +from django.utils.translation import gettext from i18nfield.strings import LazyI18nString from pretix.base.decimal import round_decimal @@ -195,7 +196,8 @@ def cancel_event(self, event: Event, subevent: int, auto_refund: bool, if auto_refund: _try_auto_refund(o.pk, manual_refund=manual_refund, allow_partial=True, source=OrderRefund.REFUND_SOURCE_ADMIN, refund_as_giftcard=refund_as_giftcard, - giftcard_expires=giftcard_expires, giftcard_conditions=giftcard_conditions) + giftcard_expires=giftcard_expires, giftcard_conditions=giftcard_conditions, + comment=gettext('Event canceled')) finally: if send: _send_mail(o, send_subject, send_message, subevent, refund_amount, user, o.positions.all()) @@ -252,7 +254,8 @@ def cancel_event(self, event: Event, subevent: int, auto_refund: bool, if auto_refund: _try_auto_refund(o.pk, manual_refund=manual_refund, allow_partial=True, source=OrderRefund.REFUND_SOURCE_ADMIN, refund_as_giftcard=refund_as_giftcard, - giftcard_expires=giftcard_expires, giftcard_conditions=giftcard_conditions) + giftcard_expires=giftcard_expires, giftcard_conditions=giftcard_conditions, + comment=gettext('Event canceled')) if send: _send_mail(o, send_subject, send_message, subevent, refund_amount, user, positions) diff --git a/src/pretix/base/services/orders.py b/src/pretix/base/services/orders.py index c0b8602a6a..922818d29b 100644 --- a/src/pretix/base/services/orders.py +++ b/src/pretix/base/services/orders.py @@ -2034,7 +2034,7 @@ _unset = object() def _try_auto_refund(order, manual_refund=False, allow_partial=False, source=OrderRefund.REFUND_SOURCE_BUYER, - refund_as_giftcard=False, giftcard_expires=_unset, giftcard_conditions=None): + refund_as_giftcard=False, giftcard_expires=_unset, giftcard_conditions=None, comment=None): notify_admin = False error = False if isinstance(order, int): @@ -2059,6 +2059,7 @@ def _try_auto_refund(order, manual_refund=False, allow_partial=False, source=Ord order=order, payment=None, source=source, + comment=comment, state=OrderRefund.REFUND_STATE_CREATED, execution_date=now(), amount=can_auto_refund_sum, @@ -2096,6 +2097,7 @@ def _try_auto_refund(order, manual_refund=False, allow_partial=False, source=Ord source=source, state=OrderRefund.REFUND_STATE_CREATED, amount=value, + comment=comment, provider=p.provider ) order.log_action('pretix.event.order.refund.created', { @@ -2125,6 +2127,7 @@ def _try_auto_refund(order, manual_refund=False, allow_partial=False, source=Ord with transaction.atomic(): r = order.refunds.create( source=source, + comment=comment, state=OrderRefund.REFUND_STATE_CREATED, amount=refund_amount - can_auto_refund_sum, provider='manual' @@ -2149,13 +2152,14 @@ def _try_auto_refund(order, manual_refund=False, allow_partial=False, source=Ord @app.task(base=ProfiledTask, bind=True, max_retries=5, default_retry_delay=1, throws=(OrderError,)) @scopes_disabled() def cancel_order(self, order: int, user: int=None, send_mail: bool=True, api_token=None, oauth_application=None, - device=None, cancellation_fee=None, try_auto_refund=False, refund_as_giftcard=False): + device=None, cancellation_fee=None, try_auto_refund=False, refund_as_giftcard=False, comment=None): try: try: ret = _cancel_order(order, user, send_mail, api_token, device, oauth_application, cancellation_fee) if try_auto_refund: - _try_auto_refund(order, refund_as_giftcard=refund_as_giftcard) + _try_auto_refund(order, refund_as_giftcard=refund_as_giftcard, + comment=comment) return ret except LockTimeoutException: self.retry() diff --git a/src/pretix/control/templates/pretixcontrol/order/index.html b/src/pretix/control/templates/pretixcontrol/order/index.html index a123555cd3..5aef10a8d1 100644 --- a/src/pretix/control/templates/pretixcontrol/order/index.html +++ b/src/pretix/control/templates/pretixcontrol/order/index.html @@ -6,6 +6,7 @@ {% load rich_text %} {% load safelink %} {% load eventsignal %} +{% load l10n %} {% load phone_format %} {% block title %} {% blocktrans trimmed with code=order.code %} @@ -97,7 +98,10 @@ {% csrf_token %} - + {% localize off %} + + {% endlocalize %} +