From 8b749e4cfbabe3b7ad12715fc93c7ae1bf30feca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Mon, 23 Nov 2020 10:12:49 +0100
Subject: [PATCH 1/2] lingo: stop retrying notify after 4 days (#48393)

---
 combo/apps/lingo/__init__.py | 17 +++++++++++----
 tests/test_lingo_payment.py  | 42 ++++++++++++++++++++++++++++++------
 2 files changed, 48 insertions(+), 11 deletions(-)

diff --git a/combo/apps/lingo/__init__.py b/combo/apps/lingo/__init__.py
index 27921f71..0fbc2f65 100644
--- a/combo/apps/lingo/__init__.py
+++ b/combo/apps/lingo/__init__.py
@@ -22,6 +22,8 @@ from django.urls import reverse
 from django.utils import timezone
 from django.utils.translation import ugettext_lazy as _
 
+import eopayment
+
 
 class AppConfig(django.apps.AppConfig):
     name = 'combo.apps.lingo'
@@ -43,14 +45,21 @@ class AppConfig(django.apps.AppConfig):
         from .models import Transaction, EXPIRED
         logger = logging.getLogger(__name__)
         now = timezone.now()
-        for transaction in Transaction.objects.filter(
-                start_date__lt=now-datetime.timedelta(hours=1),
-                end_date__isnull=True):
+        to_expire = Transaction.objects.filter(
+            start_date__lt=now-datetime.timedelta(hours=1),
+            end_date__isnull=True
+        )
+        for transaction in to_expire:
             logger.info('transaction %r is expired', transaction.order_id)
             transaction.status = EXPIRED
             transaction.save()
 
-        for transaction in Transaction.objects.filter(to_be_paid_remote_items__isnull=False):
+        to_retry = Transaction.objects.filter(
+            status__in=(eopayment.PAID, eopayment.ACCEPTED),
+            to_be_paid_remote_items__isnull=False,
+            start_date__gt=now-datetime.timedelta(days=4)
+        )
+        for transaction in to_retry:
             transaction.retry_notify_remote_items_of_payments()
 
     def notify_payments(self):
diff --git a/tests/test_lingo_payment.py b/tests/test_lingo_payment.py
index 669e3012..5b808c49 100644
--- a/tests/test_lingo_payment.py
+++ b/tests/test_lingo_payment.py
@@ -2,7 +2,6 @@ from contextlib import contextmanager
 import eopayment
 import pytest
 from datetime import datetime, timedelta
-import urllib
 from decimal import Decimal
 import json
 import mock
@@ -14,21 +13,17 @@ from django.apps import apps
 from django.contrib.auth.models import User
 from django.http.request import QueryDict
 from django.urls import reverse
-from django.core.wsgi import get_wsgi_application
 from django.conf import settings
 from django.test import override_settings
 from django.utils import timezone
-from django.utils.http import urlencode
 from django.utils.six.moves.urllib import parse as urlparse
 from django.utils.timezone import utc
-from django.contrib.messages.storage.session import SessionStorage
-from webtest import TestApp
 
 from combo.data.models import Page
 from combo.apps.lingo.models import (
-    Regie, BasketItem, Transaction, TransactionOperation, RemoteItem, EXPIRED, LingoBasketCell,
+    Regie, BasketItem, Transaction, TransactionOperation, EXPIRED, LingoBasketCell,
     PaymentBackend)
-from combo.utils import aes_hex_decrypt, sign_url
+from combo.utils import sign_url
 from combo.apps.lingo.views import signing_loads, signing_dumps
 
 import httmock
@@ -1045,6 +1040,39 @@ def test_transaction_expiration():
     assert Transaction.objects.get(id=t1.id).status == EXPIRED
     assert Transaction.objects.get(id=t2.id).status == 0
 
+
+@mock.patch('combo.utils.requests_wrapper.RequestsSession.request')
+def test_transaction_retry(mock_request, remote_regie):
+    transaction = Transaction.objects.create(
+        status=eopayment.PAID, regie=remote_regie,
+        end_date=timezone.now(),
+        to_be_paid_remote_items='42,35')
+    transaction.start_date = timezone.now() - timedelta(days=3)
+    transaction.save()
+
+    appconfig = apps.get_app_config('lingo')
+
+    mock_json = mock.Mock()
+    mock_json.status_code = 200
+    mock_json.json.return_value = {'err': 0, 'data': {
+        'created': '2020-11-23', 'pay_limit_date': '2021-11-23',
+        'total_amount': '123.45', 'amount': '123.45'}}
+    mock_request.return_value = mock_json
+
+    appconfig.update_transactions()
+    transaction.refresh_from_db()
+    assert transaction.to_be_paid_remote_items is None
+
+    # too old
+    transaction.to_be_paid_remote_items = '42,35'
+    transaction.start_date = timezone.now() - timedelta(days=4)
+    transaction.save()
+
+    appconfig.update_transactions()
+    transaction.refresh_from_db()
+    assert transaction.to_be_paid_remote_items == '42,35'
+
+
 def test_transaction_validate(app, key, regie, user):
     t1 = Transaction(regie=regie, bank_data={'bank': 'data'}, amount=12,
             status=eopayment.PAID)
-- 
2.28.0

