From eb6cbd34c20ca6118de431ea20e5decca4e32d9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Wed, 23 Oct 2019 10:38:53 +0200
Subject: [PATCH] lingo: export transactions between 2 dates (#35988)

---
 combo/apps/lingo/forms.py                     | 20 ++++++++
 combo/apps/lingo/manager_views.py             | 50 ++++++++++++-------
 .../templates/lingo/transaction_export.html   | 17 +++++++
 .../templates/lingo/transaction_list.html     |  2 +-
 tests/test_lingo_manager.py                   | 47 +++++++++++------
 5 files changed, 103 insertions(+), 33 deletions(-)
 create mode 100644 combo/apps/lingo/templates/lingo/transaction_export.html

diff --git a/combo/apps/lingo/forms.py b/combo/apps/lingo/forms.py
index f19573a..224b9e2 100644
--- a/combo/apps/lingo/forms.py
+++ b/combo/apps/lingo/forms.py
@@ -14,8 +14,11 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+import datetime
+
 
 from django import forms
+from django.utils.translation import ugettext_lazy as _
 
 from .models import Regie
 
@@ -67,3 +70,20 @@ class RegieForm(forms.ModelForm):
         )
         instance.save()
         return instance
+
+
+class TransactionExportForm(forms.Form):
+    start_date = forms.DateField(
+        label=_('Start date'),
+        widget=forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d')
+    )
+    end_date = forms.DateField(
+        label=_('End date'),
+        widget=forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d')
+    )
+
+    def __init__(self, *args, **kwargs):
+        super(TransactionExportForm, self).__init__(*args, **kwargs)
+        today = datetime.date.today()
+        self.initial['start_date'] = today - datetime.timedelta(days=30)
+        self.initial['end_date'] = today
diff --git a/combo/apps/lingo/manager_views.py b/combo/apps/lingo/manager_views.py
index d9a8e01..0dc5fd3 100644
--- a/combo/apps/lingo/manager_views.py
+++ b/combo/apps/lingo/manager_views.py
@@ -24,10 +24,12 @@ from django.utils import six
 from django.utils.timezone import make_aware
 from django.views.generic import CreateView, UpdateView, ListView, DeleteView
 from django.http import HttpResponse
+from django.template.response import TemplateResponse
 
 import eopayment
 
 from .forms import RegieForm
+from .forms import TransactionExportForm
 from .models import PaymentBackend, Regie, Transaction
 
 
@@ -102,21 +104,33 @@ class TransactionListView(ListView):
 
 
 def download_transactions_csv(request):
-    response = HttpResponse(content_type='text/csv')
-    response['Content-Disposition'] = 'attachment; filename="transactions.csv"'
-    writer = csv.writer(response)
-    transactions = Transaction.objects.filter(
-            status__in=(eopayment.PAID, eopayment.ACCEPTED)).order_by('-start_date')
-    for transaction in transactions:
-        row = [transaction.order_id,
-               transaction.bank_transaction_id,
-               transaction.start_date.strftime('%Y-%m-%d %H:%M:%S'),
-               transaction.get_user_name(),
-               str(transaction.amount)]
-        for item in transaction.items.all():
-            row.extend([item.subject, str(item.amount)])
-        if six.PY3:
-            writer.writerow([x for x in row])
-        else:
-            writer.writerow([unicode(x).encode('utf-8') for x in row])
-    return response
+    if request.method == 'POST':
+        form = TransactionExportForm(data=request.POST)
+        if form.is_valid():
+            response = HttpResponse(content_type='text/csv')
+            response['Content-Disposition'] = 'attachment; filename="transactions.csv"'
+            writer = csv.writer(response)
+            transactions = (
+                Transaction.objects
+                .filter(
+                    status__in=(eopayment.PAID, eopayment.ACCEPTED),
+                    start_date__gte=form.cleaned_data['start_date'],
+                    start_date__lte=form.cleaned_data['end_date'],
+                ).order_by('-start_date'))
+            for transaction in transactions:
+                row = [transaction.order_id,
+                       transaction.bank_transaction_id,
+                       transaction.start_date.strftime('%Y-%m-%d %H:%M:%S'),
+                       transaction.get_user_name(),
+                       str(transaction.amount)]
+                for item in transaction.items.all():
+                    row.extend([item.subject, str(item.amount)])
+                if six.PY3:
+                    writer.writerow([x for x in row])
+                else:
+                    writer.writerow([unicode(x).encode('utf-8') for x in row])
+            return response
+    else:
+        form = TransactionExportForm()
+
+    return TemplateResponse(request, 'lingo/transaction_export.html', {'form': form})
diff --git a/combo/apps/lingo/templates/lingo/transaction_export.html b/combo/apps/lingo/templates/lingo/transaction_export.html
new file mode 100644
index 0000000..6724e4d
--- /dev/null
+++ b/combo/apps/lingo/templates/lingo/transaction_export.html
@@ -0,0 +1,17 @@
+{% extends "combo/manager_base.html" %}
+{% load i18n %}
+
+{% block appbar %}
+<h2>{% trans "download CSV" %}</h2>
+{% endblock %}
+
+{% block content %}
+<form method="post">
+  {% csrf_token %}
+  {{ form.as_p }}
+  <div class="buttons">
+    <button class="submit-button">{% trans 'Download' %}</button>
+    <a class="cancel" href="{% url 'lingo-manager-homepage' %}">{% trans 'Cancel' %}</a>
+  </div>
+</form>
+{% endblock %}
diff --git a/combo/apps/lingo/templates/lingo/transaction_list.html b/combo/apps/lingo/templates/lingo/transaction_list.html
index 67b6264..2530030 100644
--- a/combo/apps/lingo/templates/lingo/transaction_list.html
+++ b/combo/apps/lingo/templates/lingo/transaction_list.html
@@ -6,7 +6,7 @@
 <span class="actions">
 <a href="{% url 'lingo-manager-paymentbackend-list' %}">{% trans 'Payment backends' %}</a>
 <a href="{% url 'lingo-manager-regie-list' %}">{% trans 'Regies' %}</a>
-<a href="{% url 'lingo-manager-transactions-download' %}">{% trans 'download CSV' %}</a>
+<a rel="popup" href="{% url 'lingo-manager-transactions-download' %}" data-autoclose-dialog="true">{% trans 'download CSV' %}</a>
 </span>
 {% endblock %}
 
diff --git a/tests/test_lingo_manager.py b/tests/test_lingo_manager.py
index 4dccd3a..3421242 100644
--- a/tests/test_lingo_manager.py
+++ b/tests/test_lingo_manager.py
@@ -149,6 +149,7 @@ def test_add_second_regie(app, admin_user, payment_backend):
     assert Regie.objects.get(id=regie.id).is_default is True
     assert Regie.objects.exclude(id=regie.id)[0].is_default is False
 
+
 def test_download_transaction(app, admin_user, payment_backend):
     test_add_regie(app, admin_user, payment_backend)
     regie = Regie.objects.filter(slug='test')[0]
@@ -164,25 +165,43 @@ def test_download_transaction(app, admin_user, payment_backend):
     trans2 = Transaction.objects.create(regie=regie, remote_items='remote items omg', order_id='2', user=user,
                                         bank_transaction_id='136', status=eopayment.PAID)
     trans1.items.set([b_item])
+    trans1.start_date = datetime.date(2019, 7, 29)
     trans1.save()
     trans2.items.set([b_item])
+    trans2.start_date = datetime.date(2019, 10, 1)
     trans2.save()
     app = login(app)
+
     resp = app.get('/manage/lingo/transactions/download-csv/', status=200)
-    content = [i for i in [item.split(',') for item in resp.text.split('\r\n')]]
-    for row in content[:-1]:
-        if row[0] == '2':
-            assert row[1] == trans2.bank_transaction_id
-            assert row[3] == '%s %s' % (user.first_name, user.last_name)
-            assert Decimal(row[4]) == Decimal(trans2.amount)
-            assert row[5] == b_item.subject
-            assert Decimal(row[6]) == b_item.amount
-        else:
-            assert row[1] == trans1.bank_transaction_id
-            assert row[3] == '%s %s' % (user.first_name, user.last_name)
-            assert Decimal(row[4]) == Decimal(trans1.amount)
-            assert row[5] == b_item.subject
-            assert Decimal(row[6]) == b_item.amount
+    resp.forms[0]['start_date'] = datetime.date(2019, 10, 1)
+    resp.forms[0]['end_date'] = datetime.date(2019, 11, 1)
+    resp = resp.forms[0].submit()
+    content = [i for i in [item.split(',') for item in resp.text.split('\r\n')] if len(i) > 1]
+    assert len(content) == 1
+    row = content[0]
+    assert row[0] == '2'
+    assert row[1] == trans2.bank_transaction_id
+    assert row[3] == '%s %s' % (user.first_name, user.last_name)
+    assert Decimal(row[4]) == Decimal(trans2.amount)
+    assert row[5] == b_item.subject
+    assert Decimal(row[6]) == b_item.amount
+
+    resp = app.get('/manage/lingo/transactions/download-csv/', status=200)
+    resp.forms[0]['start_date'] = datetime.date(2019, 7, 1)
+    resp.forms[0]['end_date'] = datetime.date(2019, 11, 1)
+    resp = resp.forms[0].submit()
+    content = [i for i in [item.split(',') for item in resp.text.split('\r\n')] if len(i) > 1]
+    assert len(content) == 2
+    row = content[0]
+    assert row[0] == '2'
+    row = content[1]
+    assert row[0] == '1'
+    assert row[1] == trans1.bank_transaction_id
+    assert row[3] == '%s %s' % (user.first_name, user.last_name)
+    assert Decimal(row[4]) == Decimal(trans1.amount)
+    assert row[5] == b_item.subject
+    assert Decimal(row[6]) == b_item.amount
+
 
 def test_transactions_search(app, admin_user):
     for i in range(50):
-- 
2.20.1

