lingo: new page to display payments in error (#21626)
This commit is contained in:
parent
850bab5600
commit
964d0a87aa
|
@ -20,8 +20,9 @@ from dateutil import parser as date_parser
|
|||
|
||||
from django.core.urlresolvers import reverse_lazy
|
||||
from django.db.models import Q
|
||||
from django.db.models.expressions import RawSQL
|
||||
from django.utils import six
|
||||
from django.utils.timezone import make_aware
|
||||
from django.utils.timezone import make_aware, now
|
||||
from django.views.generic import CreateView, UpdateView, ListView, DeleteView
|
||||
from django.http import HttpResponse
|
||||
from django.template.response import TemplateResponse
|
||||
|
@ -30,7 +31,7 @@ import eopayment
|
|||
|
||||
from .forms import RegieForm
|
||||
from .forms import TransactionExportForm
|
||||
from .models import PaymentBackend, Regie, Transaction
|
||||
from .models import BasketItem, PaymentBackend, Regie, Transaction
|
||||
|
||||
|
||||
class RegieListView(ListView):
|
||||
|
@ -103,6 +104,34 @@ class TransactionListView(ListView):
|
|||
return qs
|
||||
|
||||
|
||||
class BasketItemErrorListView(ListView):
|
||||
model = BasketItem
|
||||
template_name = 'lingo/basketitem_error_list.html'
|
||||
paginate_by = 10
|
||||
|
||||
def get_queryset(self):
|
||||
raw = (
|
||||
'SELECT %s FROM lingo_transaction '
|
||||
'INNER JOIN lingo_transaction_items '
|
||||
'ON "lingo_transaction"."id" = "lingo_transaction_items"."transaction_id" '
|
||||
'AND "lingo_transaction_items"."basketitem_id"="lingo_basketitem"."id" '
|
||||
'ORDER BY start_date DESC LIMIT 1')
|
||||
queryset = (
|
||||
BasketItem.objects
|
||||
.annotate(bank_transaction_id=RawSQL(raw % 'bank_transaction_id', []))
|
||||
.annotate(transaction_status=RawSQL(raw % 'status', []))
|
||||
.filter(regie__webservice_url='')
|
||||
.order_by())
|
||||
queryset1 = (
|
||||
queryset
|
||||
.filter(
|
||||
notification_date__isnull=True,
|
||||
cancellation_date__isnull=True,
|
||||
payment_date__lt=now() - datetime.timedelta(minutes=300)))
|
||||
queryset2 = queryset.filter(transaction_status=eopayment.ERROR)
|
||||
return queryset1.union(queryset2).order_by('-creation_date')
|
||||
|
||||
|
||||
def download_transactions_csv(request):
|
||||
if request.method == 'POST':
|
||||
form = TransactionExportForm(data=request.POST)
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
{% extends "lingo/manager_base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block appbar %}
|
||||
<h2>{% trans 'Payments in error' %}</h2>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumb %}
|
||||
{{ block.super }}
|
||||
<a href="{% url 'lingo-manager-payment-error-list' %}">{% trans 'Payments in error' %}</a>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% if object_list %}
|
||||
<table class="main">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans 'Item' %}</th>
|
||||
<th>{% trans 'Amount' %}</th>
|
||||
<th colspan="2">{% trans 'Date' %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for object in object_list %}
|
||||
<tr>
|
||||
<td>{% if object.source_url %}<a href="{{ object.source_url }}">{{ object.subject }}</a>{% else %}{{ object.subject }}{% endif %}</td>
|
||||
<td class="price">{{ object.amount }} €</td>
|
||||
<td>{{ object.payment_date }}</td>
|
||||
<td>
|
||||
{% if object.transaction_status != 99 %}
|
||||
<a href="{% url 'lingo-manager-homepage' %}?q={{ object.bank_transaction_id }}">{% trans "See transaction" %}</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
{% include "gadjo/pagination.html" %}
|
||||
|
||||
{% else %}
|
||||
<div class="big-msg-info">
|
||||
{% blocktrans %}
|
||||
This site doesn't have any payment in error.
|
||||
{% endblocktrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
|
@ -4,6 +4,7 @@
|
|||
{% block appbar %}
|
||||
<h2>{% trans 'Transactions' %}</h2>
|
||||
<span class="actions">
|
||||
<a href="{% url 'lingo-manager-payment-error-list' %}">{% trans 'Payments in error' %}</a>
|
||||
<a href="{% url 'lingo-manager-paymentbackend-list' %}">{% trans 'Payment backends' %}</a>
|
||||
<a href="{% url 'lingo-manager-regie-list' %}">{% trans 'Regies' %}</a>
|
||||
<a rel="popup" href="{% url 'lingo-manager-transactions-download' %}" data-autoclose-dialog="true">{% trans 'download CSV' %}</a>
|
||||
|
|
|
@ -23,12 +23,14 @@ from .views import (RegiesApiView, AddBasketItemApiView, PayView, CallbackView,
|
|||
RemoveBasketItemApiView, ValidateTransactionApiView,
|
||||
CancelTransactionApiView, SelfInvoiceView, BasketItemPayView)
|
||||
from .manager_views import (RegieListView, RegieCreateView, RegieUpdateView,
|
||||
RegieDeleteView, TransactionListView, download_transactions_csv,
|
||||
PaymentBackendListView, PaymentBackendCreateView,
|
||||
PaymentBackendUpdateView, PaymentBackendDeleteView)
|
||||
RegieDeleteView, TransactionListView, BasketItemErrorListView,
|
||||
download_transactions_csv, PaymentBackendListView,
|
||||
PaymentBackendCreateView, PaymentBackendUpdateView,
|
||||
PaymentBackendDeleteView)
|
||||
|
||||
lingo_manager_urls = [
|
||||
url('^$', TransactionListView.as_view(), name='lingo-manager-homepage'),
|
||||
url('^payments/error/$', BasketItemErrorListView.as_view(), name='lingo-manager-payment-error-list'),
|
||||
url('^transactions/download-csv/$', download_transactions_csv, name='lingo-manager-transactions-download'),
|
||||
url('^regies/$', RegieListView.as_view(), name='lingo-manager-regie-list'),
|
||||
url('^regies/add/$', RegieCreateView.as_view(), name='lingo-manager-regie-add'),
|
||||
|
|
|
@ -227,6 +227,172 @@ def test_transactions_search(app, admin_user):
|
|||
assert resp.text.count('<tr') == 0
|
||||
assert 'No transactions found matching' in resp.text
|
||||
|
||||
|
||||
def test_basketitem_error_list(app, admin_user, payment_backend):
|
||||
regie = Regie.objects.create(
|
||||
label='test-regie',
|
||||
slug='test-regie',
|
||||
payment_backend=payment_backend)
|
||||
user = User.objects.create_user('dimebag', 'dime@bag.pan', 'pwd')
|
||||
regie_with_webservice_url = Regie.objects.create(
|
||||
label='test-regie2',
|
||||
slug='test-regie2',
|
||||
payment_backend=payment_backend,
|
||||
webservice_url='http://example.net')
|
||||
|
||||
date_now = now()
|
||||
date_in_past = date_now - datetime.timedelta(minutes=300)
|
||||
|
||||
# item with payment_date and notification_date, status PAID
|
||||
# => not displayed
|
||||
item1 = BasketItem.objects.create(
|
||||
user=user,
|
||||
regie=regie,
|
||||
subject='item 1',
|
||||
source_url='http://example.net/1',
|
||||
amount=1,
|
||||
payment_date=date_in_past,
|
||||
notification_date=date_in_past)
|
||||
transaction11 = Transaction.objects.create(
|
||||
status=eopayment.ERROR,
|
||||
order_id='order id 1.1',
|
||||
bank_transaction_id='bank_id_11',
|
||||
amount=1)
|
||||
transaction11.items.add(item1)
|
||||
transaction12 = Transaction.objects.create(
|
||||
status=eopayment.PAID,
|
||||
order_id='order id 1.2',
|
||||
bank_transaction_id='bank_id_12',
|
||||
amount=1)
|
||||
transaction12.items.add(item1)
|
||||
|
||||
# item with payment_date and notification_date, status ERROR
|
||||
# => displayed
|
||||
item2 = BasketItem.objects.create(
|
||||
user=user,
|
||||
regie=regie,
|
||||
subject='item 2',
|
||||
source_url='',
|
||||
amount=2,
|
||||
payment_date=date_in_past,
|
||||
notification_date=date_in_past)
|
||||
transaction21 = Transaction.objects.create(
|
||||
status=eopayment.ERROR,
|
||||
order_id='order id 2.1',
|
||||
bank_transaction_id='bank_id_21',
|
||||
amount=2)
|
||||
transaction21.items.add(item2)
|
||||
transaction22 = Transaction.objects.create(
|
||||
status=eopayment.ERROR,
|
||||
order_id='order id 2.2',
|
||||
bank_transaction_id='bank_id_22',
|
||||
amount=2)
|
||||
transaction22.items.add(item2)
|
||||
# the same but for the other regie
|
||||
item2_bis = BasketItem.objects.create(
|
||||
user=user,
|
||||
regie=regie_with_webservice_url,
|
||||
subject='item 2 bis',
|
||||
source_url='',
|
||||
amount=22222,
|
||||
payment_date=date_in_past,
|
||||
notification_date=date_in_past)
|
||||
transaction2_bis = Transaction.objects.create(
|
||||
status=eopayment.ERROR,
|
||||
order_id='order id 2 bis',
|
||||
bank_transaction_id='bank_id_2_bis',
|
||||
amount=22222)
|
||||
transaction2_bis.items.add(item2_bis)
|
||||
|
||||
# item without dates, status ERROR
|
||||
# => displayed
|
||||
item3 = BasketItem.objects.create(
|
||||
user=user,
|
||||
regie=regie,
|
||||
subject='item 3',
|
||||
source_url='http://example.net/3',
|
||||
amount=3)
|
||||
transaction3 = Transaction.objects.create(
|
||||
status=eopayment.ERROR,
|
||||
order_id='order id 3',
|
||||
bank_transaction_id='bank_id_3',
|
||||
amount=3)
|
||||
transaction3.items.add(item3)
|
||||
|
||||
# item with payment_date but no notification_date, too young
|
||||
# => not displayed
|
||||
item4 = BasketItem.objects.create(
|
||||
user=user,
|
||||
regie=regie,
|
||||
subject='item 4',
|
||||
source_url='http://example.net/4',
|
||||
amount=4,
|
||||
payment_date=date_now,
|
||||
notification_date=None)
|
||||
transaction4 = Transaction.objects.create(
|
||||
order_id='order id 4',
|
||||
bank_transaction_id='bank_id_4',
|
||||
amount=4)
|
||||
transaction4.items.add(item4)
|
||||
|
||||
# item with payment_date but no notification_date, in the past
|
||||
# => displayed
|
||||
item5 = BasketItem.objects.create(
|
||||
user=user,
|
||||
regie=regie,
|
||||
subject='item 5',
|
||||
source_url='http://example.net/5',
|
||||
amount=5,
|
||||
payment_date=date_in_past,
|
||||
notification_date=None)
|
||||
transaction5 = Transaction.objects.create(
|
||||
order_id='order id 5',
|
||||
bank_transaction_id='bank_id_5',
|
||||
amount=5)
|
||||
transaction5.items.add(item5)
|
||||
# the same but for the other regie
|
||||
item5_bis = BasketItem.objects.create(
|
||||
user=user,
|
||||
regie=regie_with_webservice_url,
|
||||
subject='item 5 bis',
|
||||
source_url='http://example.net/5_bis',
|
||||
amount=55555,
|
||||
payment_date=date_in_past,
|
||||
notification_date=None)
|
||||
transaction5_bis = Transaction.objects.create(
|
||||
order_id='order id 5 bis',
|
||||
bank_transaction_id='bank_id_5_bis',
|
||||
amount=55555)
|
||||
transaction5_bis.items.add(item5_bis)
|
||||
|
||||
# item with payment_date, no notification_date, but a cancellation_date, in the past
|
||||
# => not displayed
|
||||
item6 = BasketItem.objects.create(
|
||||
user=user,
|
||||
regie=regie,
|
||||
subject='item 6',
|
||||
source_url='http://example.net/6',
|
||||
amount=6,
|
||||
payment_date=date_in_past,
|
||||
notification_date=None,
|
||||
cancellation_date=date_now)
|
||||
transaction6 = Transaction.objects.create(
|
||||
order_id='order id 6',
|
||||
bank_transaction_id='bank_id_6',
|
||||
amount=6)
|
||||
transaction6.items.add(item6)
|
||||
|
||||
app = login(app)
|
||||
resp = app.get('/manage/lingo/payments/error/', status=200)
|
||||
assert list(resp.context['object_list']) == [item5, item3, item2]
|
||||
assert '<a href="%s">' % item5.source_url in resp.text
|
||||
assert '<a href="%s">' % item3.source_url in resp.text
|
||||
assert '<a href="%s">' % item2.source_url not in resp.text
|
||||
assert '/manage/lingo/?q=%s' % transaction5.bank_transaction_id in resp.text
|
||||
assert '/manage/lingo/?q=%s' % transaction3.bank_transaction_id not in resp.text
|
||||
assert '/manage/lingo/?q=%s' % transaction22.bank_transaction_id not in resp.text
|
||||
|
||||
|
||||
def test_configure_tipi_cell(app, admin_user):
|
||||
page = Page(title='tipi', slug='tipi', template_name='standard')
|
||||
page.save()
|
||||
|
|
Loading…
Reference in New Issue