diff --git a/combo/apps/lingo/manager_views.py b/combo/apps/lingo/manager_views.py
index 2897b2bc..af373085 100644
--- a/combo/apps/lingo/manager_views.py
+++ b/combo/apps/lingo/manager_views.py
@@ -18,13 +18,16 @@ import csv
import datetime
from dateutil import parser as date_parser
+from django.core.urlresolvers import reverse
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, now
-from django.views.generic import CreateView, UpdateView, ListView, DeleteView
+from django.views.generic import CreateView, UpdateView, ListView, DeleteView, View
from django.http import HttpResponse
+from django.http import HttpResponseRedirect
+from django.shortcuts import get_object_or_404
from django.template.response import TemplateResponse
import eopayment
@@ -142,6 +145,20 @@ class BasketItemErrorListView(ListView):
return queryset1.union(queryset2).order_by('-creation_date')
+class BasketItemMarkAsNotifiedView(View):
+ def get(self, request, *args, **kwargs):
+ item = get_object_or_404(
+ BasketItem.objects.exclude(source_url=''),
+ pk=kwargs['item_id'],
+ regie__webservice_url='',
+ notification_date__isnull=True,
+ cancellation_date__isnull=True,
+ payment_date__lt=now() - datetime.timedelta(minutes=300))
+ item.notify_payment(notify_origin=False)
+
+ return HttpResponseRedirect(reverse('lingo-manager-payment-error-list'))
+
+
def download_transactions_csv(request):
if request.method == 'POST':
form = TransactionExportForm(data=request.POST)
diff --git a/combo/apps/lingo/models.py b/combo/apps/lingo/models.py
index 7bbb1efb..83b4ded5 100644
--- a/combo/apps/lingo/models.py
+++ b/combo/apps/lingo/models.py
@@ -373,8 +373,9 @@ class BasketItem(models.Model):
data=json.dumps(message), headers=headers, timeout=15)
r.raise_for_status()
- def notify_payment(self):
- self.notify('paid')
+ def notify_payment(self, notify_origin=True):
+ if notify_origin:
+ self.notify('paid')
self.notification_date = timezone.now()
self.save()
self.regie.compute_extra_fees(user=self.user)
diff --git a/combo/apps/lingo/templates/lingo/basketitem_error_list.html b/combo/apps/lingo/templates/lingo/basketitem_error_list.html
index b4102975..2f4f5e4b 100644
--- a/combo/apps/lingo/templates/lingo/basketitem_error_list.html
+++ b/combo/apps/lingo/templates/lingo/basketitem_error_list.html
@@ -34,6 +34,10 @@
{% if object.transaction_status != 99 %}
{% trans "See transaction" %}
+ {% if object.source_url %}
+
+ {% trans "Mark as notified" %}
+ {% endif %}
{% endif %}
|
diff --git a/combo/apps/lingo/urls.py b/combo/apps/lingo/urls.py
index a0d0a61e..902d8954 100644
--- a/combo/apps/lingo/urls.py
+++ b/combo/apps/lingo/urls.py
@@ -26,11 +26,13 @@ from .manager_views import (RegieListView, RegieCreateView, RegieUpdateView,
RegieDeleteView, TransactionListView, BasketItemErrorListView,
download_transactions_csv, PaymentBackendListView,
PaymentBackendCreateView, PaymentBackendUpdateView,
- PaymentBackendDeleteView)
+ PaymentBackendDeleteView, BasketItemMarkAsNotifiedView)
lingo_manager_urls = [
url('^$', TransactionListView.as_view(), name='lingo-manager-homepage'),
url('^payments/error/$', BasketItemErrorListView.as_view(), name='lingo-manager-payment-error-list'),
+ url(r'^item/(?P\d+)/mark-as-notified/$',
+ BasketItemMarkAsNotifiedView.as_view(), name='lingo-manager-basket-item-mark-as-notified'),
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'),
diff --git a/tests/test_lingo_manager.py b/tests/test_lingo_manager.py
index 05ab92c5..2c7769c7 100644
--- a/tests/test_lingo_manager.py
+++ b/tests/test_lingo_manager.py
@@ -3,9 +3,9 @@
import datetime
from django.contrib.auth.models import User
-from django.core.wsgi import get_wsgi_application
from django.utils.timezone import now
-from webtest import TestApp
+
+import mock
import pytest
import eopayment
@@ -364,33 +364,54 @@ def test_basketitem_error_list(app, admin_user, payment_backend):
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
+ # item with payment_date but no notification_date, in the past
+ # => displayed
item6 = BasketItem.objects.create(
user=user,
regie=regie,
subject='item 6',
- source_url='http://example.net/6',
+ source_url='', # without source_url
amount=6,
payment_date=date_in_past,
- notification_date=None,
- cancellation_date=date_now)
+ notification_date=None)
transaction6 = Transaction.objects.create(
order_id='order id 6',
bank_transaction_id='bank_id_6',
amount=6)
transaction6.items.add(item6)
+ # item with payment_date, no notification_date, but a cancellation_date, in the past
+ # => not displayed
+ item7 = BasketItem.objects.create(
+ user=user,
+ regie=regie,
+ subject='item 7',
+ source_url='http://example.net/7',
+ amount=7,
+ payment_date=date_in_past,
+ notification_date=None,
+ cancellation_date=date_now)
+ transaction7 = Transaction.objects.create(
+ order_id='order id 7',
+ bank_transaction_id='bank_id_7',
+ amount=7)
+ transaction7.items.add(item7)
+
app = login(app)
resp = app.get('/manage/lingo/payments/error/', status=200)
- assert list(resp.context['object_list']) == [item5, item3, item2]
+ assert list(resp.context['object_list']) == [item6, item5, item3, item2]
+ assert '' % item6.source_url not in resp.text
assert '' % item5.source_url in resp.text
assert '' % item3.source_url in resp.text
assert '' % item2.source_url not in resp.text
+ assert '/manage/lingo/?q=%s' % transaction6.bank_transaction_id 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
+ assert '/manage/lingo/item/%s/mark-as-notified/' % item6.pk not in resp.text
+ assert '/manage/lingo/item/%s/mark-as-notified/' % item5.pk in resp.text
+ assert '/manage/lingo/item/%s/mark-as-notified/' % item3.pk not in resp.text
+ assert '/manage/lingo/item/%s/mark-as-notified/' % item2.pk not in resp.text
def test_basketitem_error_list_search(app, admin_user, payment_backend):
@@ -428,6 +449,63 @@ def test_basketitem_error_list_search(app, admin_user, payment_backend):
assert list(resp.context['object_list']) == [item]
+def test_basketitem_mark_as_notified(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')
+
+ date_now = now()
+ date_in_past = date_now - datetime.timedelta(minutes=300)
+
+ item = BasketItem.objects.create(
+ user=user,
+ regie=regie,
+ subject='item',
+ source_url='http://example.net/',
+ amount=42,
+ payment_date=date_in_past,
+ notification_date=date_in_past)
+
+ app = login(app)
+
+ # notification_date is not None
+ resp = app.get('/manage/lingo/item/%s/mark-as-notified/' % item.pk, status=404)
+ # payment_date is not old enough
+ item.notification_date = None
+ item.payment_date = date_now
+ item.save()
+ resp = app.get('/manage/lingo/item/%s/mark-as-notified/' % item.pk, status=404)
+ # cancellation_date is not None
+ item.payment_date = date_in_past
+ item.cancellation_date = date_now
+ item.save()
+ resp = app.get('/manage/lingo/item/%s/mark-as-notified/' % item.pk, status=404)
+ # notification_date and cancellation_date are None, payment_date is old enough
+ # but webservice_url is not None
+ item.cancellation_date = None
+ item.save()
+ regie.webservice_url = 'http://example.net'
+ regie.save()
+ resp = app.get('/manage/lingo/item/%s/mark-as-notified/' % item.pk, status=404)
+ # notification_date and cancellation_date are None, payment_date is old enough
+ # but source_url is not set
+ regie.webservice_url = ''
+ regie.save()
+ item.source_url = ''
+ item.save()
+ resp = app.get('/manage/lingo/item/%s/mark-as-notified/' % item.pk, status=404)
+
+ # source_url is set
+ item.source_url = 'http://example.com'
+ item.save()
+ with mock.patch('combo.apps.lingo.models.BasketItem.notify') as mock_notify:
+ resp = app.get('/manage/lingo/item/%s/mark-as-notified/' % item.pk, status=302)
+ assert mock_notify.call_args_list == []
+ assert resp.location.endswith('/manage/lingo/payments/error/')
+ item.refresh_from_db()
+ assert item.notification_date is not None
+
+
def test_configure_tipi_cell(app, admin_user):
page = Page(title='tipi', slug='tipi', template_name='standard')
page.save()