Add BasePaymentProvider.payment_control_render_short and use it on refund page

This commit is contained in:
Raphael Michel
2021-01-27 10:34:59 +01:00
parent f93c780e6a
commit 33b34f31d1
7 changed files with 100 additions and 44 deletions

View File

@@ -712,6 +712,18 @@ class BasePaymentProvider:
"""
return ''
def payment_control_render_short(self, payment: OrderPayment) -> str:
"""
Will be called if the *event administrator* performs an action on the payment. Should
return a very short version of the payment method. Usually, this should return e.g.
a transaction ID or account identifier, but no information on status, dates, etc.
The default implementation falls back to payment_presa_elrender.
:param order: The order object
"""
return self.payment_presale_render(payment)
def refund_control_render(self, request: HttpRequest, refund: OrderRefund) -> str:
"""
Will be called if the *event administrator* views the details of a refund.

View File

@@ -17,16 +17,23 @@
</h1>
<form method="post" href="">
{% csrf_token %}
<fieldset class="form-inline form-order-change">
<fieldset class="form-inline form-refund-choose">
<legend>{% trans "How should the refund be sent?" %}</legend>
<p>
{% blocktrans trimmed %}
Any payments that you selected for automatical refunds will be immediately communicate the refund
request to the respective payment provider. Manual refunds will be created as pending refunds, you
can then later mark them as done once you actually transferred the money back to the customer.
{% endblocktrans %}
</p>
<h4>{% trans "Refund to original payment method" %}</h4>
<div class="table-responsive">
<table class="table table-condensed">
<thead>
<tr>
<th>#</th>
<th>{% trans "Payment confirmation date" %}</th>
<th>{% trans "Payment method" %}</th>
<th>{% trans "Payment" %}</th>
<th>{% trans "Payment details" %}</th>
<th>{% trans "Amount not refunded" %}</th>
<th>{% trans "Refund" %}</th>
</tr>
@@ -34,11 +41,8 @@
<tbody>
{% for p in payments %}
<tr>
<td>{{ p.full_id }}</td>
<td>{{ p.payment_date|date:"SHORT_DATETIME_FORMAT" }}</td>
<td>
{{ p.payment_provider.verbose_name }}
</td>
<td>{{ p.full_id }}<br/>{{ p.payment_date|date:"SHORT_DATETIME_FORMAT" }}<br/>{{ p.payment_provider.verbose_name }}</td>
<td class="payment-details">{{ p.html_info|safe }}</td>
<td>{{ p.available_amount|money:request.event.currency }}</td>
<td>
{% if p.partial_refund_possible %}
@@ -46,9 +50,9 @@
<div class="input-group">
<input type="text" name="refund-{{ p.pk }}"
{% if p.propose_refund %}
value="{{ p.propose_refund|floatformat:2 }}"
value="{{ p.propose_refund|floatformat:2 }}"
{% else %}
placeholder="{{ p.propose_refund|floatformat:2 }}"
placeholder="{{ p.propose_refund|floatformat:2 }}"
{% endif %}
title="" class="form-control">
<span class="input-group-addon">
@@ -68,59 +72,67 @@
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<h4>{% trans "Refund to a different payment method" %}</h4>
<div class="table-responsive">
<table class="table table-condensed">
<thead>
<tr>
<th>{% trans "Payment method" %}</th>
<th>{% trans "Refund" %}</th>
</tr>
</thead>
<tbody>
{% for prov, form in new_refunds %}
<tr>
<td></td>
<td></td>
<td>
{{ prov.verbose_name }}
<strong>
{{ prov.verbose_name }}
</strong>
</td>
<td></td>
<td>
{% trans "Automatically refund" context "amount_label" %}
<div class="input-group">
<input type="text" name="newrefund-{{ prov }}"
placeholder="{{ 0|floatformat:2 }}"
title="" class="form-control">
placeholder="{{ 0|floatformat:2 }}"
title="" class="form-control">
<span class="input-group-addon">
{{ request.event.currency }}
</span>
</div><br>
</div>
<br>
{{ form|safe }}
</td>
</tr>
{% endfor %}
<tr>
<td></td>
<td></td>
<td><strong>{% trans "Transfer to other order" %}</strong></td>
<td></td>
<td>
{% trans "Transfer" context "amount_label" %}
<div class="input-group">
<input type="text" name="refund-offsetting"
title="" class="form-control" placeholder="{{ 0|floatformat:2 }}">
title="" class="form-control" placeholder="{{ 0|floatformat:2 }}">
<span class="input-group-addon">
{{ request.event.currency }}
</span>
</div>
{% trans "to" context "order_label" %}
<input type="text" name="order-offsetting"
value="" title="" class="form-control">
value="" title="" class="form-control">
</td>
</tr>
<tr>
<td></td>
<td></td>
<td>
<strong>{% trans "Create a new gift card" %}</strong>
</td>
<td></td>
<td>
<div class="input-group">
<input type="text" name="refund-new-giftcard"
title="" class="form-control"
title="" class="form-control"
{% if giftcard_proposal %}
value="{{ giftcard_proposal|floatformat:2 }}"
{% else %}
@@ -138,29 +150,26 @@
</tr>
<tr>
<td></td>
<td></td>
<td><strong>{% trans "Manual refund" %}</strong></td>
<td></td>
<td>
{% trans "Manually refund" context "amount_label" %}
<div class="input-group">
<input type="text" name="refund-manual"
{% if remainder %}
value="{{ remainder|floatformat:2 }}"
value="{{ remainder|floatformat:2 }}"
{% else %}
placeholder="{{ remainder|floatformat:2 }}"
placeholder="{{ remainder|floatformat:2 }}"
{% endif %}
title="" class="form-control">
<span class="input-group-addon">
{{ request.event.currency }}
</span>
</div>
<label class="radio">
</div><br>
<label class="radio no-bold">
<input type="radio" name="manual_state" value="created" checked>
{% trans "Keep transfer as to do" %}
</label>
<label class="radio">
<label class="radio no-bold">
<input type="radio" name="manual_state" value="done">
{% trans "Mark refund as done" %}
</label>
@@ -171,13 +180,6 @@
</table>
</div>
</fieldset>
<p>
{% blocktrans trimmed %}
Any payments that you selected for automatical refunds will be immediately communicate the refund
request to the respective payment provider. Manual refunds will be created as pending refunds, you
can then later mark them as done once you actually transferred the money back to the customer.
{% endblocktrans %}
</p>
<p>&nbsp;</p>
<input type="hidden" name="start-action" value="{{ start_form.cleaned_data.action }}">
@@ -187,7 +189,7 @@
<div class="form-group">
<label class="control-label" for="id_comment">{% trans "Refund reason" %}</label>
<input type="text" name="comment" class="form-control" title="{% trans "May be shown to the end user or used e.g. as part of a payment reference." %}" id="id_comment"
value="{{ comment|default:"" }}">
value="{{ comment|default:"" }}">
<div class="help-block">{% trans "May be shown to the end user or used e.g. as part of a payment reference." %}</div>
</div>

View File

@@ -1001,6 +1001,10 @@ class OrderRefundView(OrderView):
(prov, form)
)
for p in payments:
if p.payment_provider:
p.html_info = (p.payment_provider.payment_control_render_short(p) or "").strip()
return render(self.request, 'pretixcontrol/order/refund_choose.html', {
'payments': payments,
'new_refunds': new_refunds,

View File

@@ -282,6 +282,19 @@ class BankTransfer(BasePaymentProvider):
def payment_partial_refund_supported(self, payment: OrderPayment) -> bool:
return self.payment_refund_supported(payment)
def payment_control_render_short(self, payment: OrderPayment) -> str:
pi = payment.info_data or {}
r = pi.get('payer', '')
if pi.get('iban'):
if r:
r += ' / '
r += pi.get('iban')
if pi.get('bic'):
if r:
r += ' / '
r += pi.get('bic')
return r
def payment_presale_render(self, payment: OrderPayment) -> str:
pi = payment.info_data or {}
if self.payment_refund_supported(payment):

View File

@@ -477,6 +477,9 @@ class Paypal(BasePaymentProvider):
'payment_info': payment.info_data, 'order': payment.order, 'sale_id': sale_id}
return template.render(ctx)
def payment_control_render_short(self, payment: OrderPayment) -> str:
return payment.info_data.get('payer', {}).get('payer_info', {}).get('email', '')
def payment_partial_refund_supported(self, payment: OrderPayment):
# Paypal refunds are possible for 180 days after purchase:
# https://www.paypal.com/lc/smarthelp/article/how-do-i-issue-a-refund-faq780#:~:text=Refund%20after%20180%20days%20of,PayPal%20balance%20of%20the%20recipient.

View File

@@ -327,6 +327,9 @@ input[type=number].short {
label.label-empty {
pointer-events: none;
}
label.no-bold {
font-weight: normal;
}
label .optional {
color: $text-muted;
font-weight: normal;
@@ -501,11 +504,28 @@ table td > .checkbox input[type="checkbox"] {
}
}
.form-order-change {
.form-order-change, .form-refund-choose {
.row {
padding: 5px 0;
}
}
.form-refund-choose {
.payment-details {
max-width: 200px;
overflow: hidden;
dt {
float: none;
text-align: left;
font-weight: normal;
width: auto;
color: $text-muted;
}
dd {
margin-left: 0px;
word-break: break-word;
}
}
}
@media(max-width: $screen-xs-max) {
.nameparts-form-group {