From cfb1e98aaab6f3608bd85aa0d9102573f0c1ef88 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Tue, 7 Apr 2020 11:50:54 +0200
Subject: [PATCH] toulouse-axel: endpoint to return the list of remaining weeks
 (#41388)

---
 passerelle/contrib/toulouse_axel/models.py | 34 ++++++++-
 tests/test_toulouse_axel.py                | 81 ++++++++++++++++++++++
 2 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/passerelle/contrib/toulouse_axel/models.py b/passerelle/contrib/toulouse_axel/models.py
index 6b5b23e6..a7f0ba3d 100644
--- a/passerelle/contrib/toulouse_axel/models.py
+++ b/passerelle/contrib/toulouse_axel/models.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 # passerelle - uniform access to multiple data sources and services
 # Copyright (C) 2020  Entr'ouvert
 #
@@ -14,6 +15,8 @@
 # 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/>.
 
+from __future__ import unicode_literals
+
 import base64
 import copy
 import datetime
@@ -26,6 +29,7 @@ from collections import namedtuple
 from django.core.cache import cache
 from django.db import models
 from django.http import HttpResponse
+from django.utils import dateformat
 from django.utils.dates import WEEKDAYS
 from django.utils.encoding import force_text
 from django.utils.translation import ugettext_lazy as _
@@ -1128,7 +1132,7 @@ class ToulouseAxel(BaseResource):
             activity['id'] = activity['IDACTIVITE']
             start_date = datetime.datetime.strptime(activity['DATEENTREE'], utils.json_date_format)
             end_date = datetime.datetime.strptime(activity['DATESORTIE'], utils.json_date_format)
-            activity['text'] = u'{} (inscription du {} au {})'.format(
+            activity['text'] = '{} (inscription du {} au {})'.format(
                 activity['LIBELLEACTIVITE'],
                 start_date.strftime(utils.xml_date_format),
                 end_date.strftime(utils.xml_date_format))
@@ -1231,6 +1235,34 @@ class ToulouseAxel(BaseResource):
         possible_days = self.clae_booking_activity_possible_days(request, NameID, idpersonne, activity_type, booking_date)
         return {'data': [d['id'] for d in possible_days['data'] if d['prefill'] is True]}
 
+    @endpoint(
+        description=_("Get list of next weeks for the current reference year"),
+        perm='can_access')
+    def clae_next_weeks(self, request):
+        today = datetime.date.today()
+        current_reference_year = utils.get_reference_year_from_date(today)
+        # starts in 8 days
+        start_date = today + datetime.timedelta(days=8)
+        # but if start_date is a saturday or a sunday, jump to the next monday
+        if start_date.weekday() > 4:
+            start_date = start_date + datetime.timedelta(days=7 - start_date.weekday())
+        end_date = datetime.date(current_reference_year + 1, 7, 31)
+        weeks = []
+        while start_date <= end_date:
+            week_end_date = min(end_date, start_date + datetime.timedelta(days=4 - start_date.weekday()))
+            weeks.append({
+                'id': 'week%s-week%s' % (start_date.strftime('%Y%m%d'), week_end_date.strftime('%Y%m%d')),
+                'text': '%s → %s' % (
+                    dateformat.format(start_date, 'l j F' if start_date.year == week_end_date.year else 'l j F Y'),
+                    dateformat.format(week_end_date, 'l j F Y')),
+                'date_debut': start_date.strftime(utils.json_date_format),
+                'date_fin': week_end_date.strftime(utils.json_date_format),
+                'annee_reference': str(current_reference_year),
+            })
+            # find next monday
+            start_date = start_date + datetime.timedelta(days=7 - start_date.weekday())
+        return {'data': weeks}
+
     @endpoint(
         description=_("CLAE/Cantine booking"),
         perm='can_access',
diff --git a/tests/test_toulouse_axel.py b/tests/test_toulouse_axel.py
index fd421243..02b2e918 100644
--- a/tests/test_toulouse_axel.py
+++ b/tests/test_toulouse_axel.py
@@ -2811,6 +2811,87 @@ def test_are_children_registered(resource, activities, expected):
         assert resource.are_children_registered(dui='XXX', reference_year=get_reference_year_from_date(today)) == expected
 
 
+@pytest.mark.parametrize('today, first_day, last_day', [
+    # first day of the period
+    ('2019-08-01', '2019-08-09', '2019-08-09'),
+    # last day of the period
+    ('2020-07-31', None, None),
+    # today+8 is a friday => starts friday, ends friday
+    ('2020-03-26', '2020-04-03', '2020-04-03'),
+    # today+8 is a saturday => starts on next monday, ends next friday
+    ('2020-03-27', '2020-04-06', '2020-04-10'),
+    # today+8 is a sunday => starts on next monday, ends next friday
+    ('2020-03-28', '2020-04-06', '2020-04-10'),
+    # today+8 is a monday => starts monday, ends friday
+    ('2020-03-29', '2020-04-06', '2020-04-10'),
+    # today+8 is a tuesday => starts tuesday, ends friday
+    ('2020-03-30', '2020-04-07', '2020-04-10'),
+])
+def test_clae_next_week(app, resource, today, first_day, last_day):
+    with freezegun.freeze_time(today):
+        resp = app.get('/toulouse-axel/test/clae_next_weeks')
+    # check first week
+    if first_day is None:
+        assert resp.json['data'] == []
+    else:
+        assert resp.json['data'][0]['date_debut'] == first_day
+    if last_day is None:
+        assert resp.json['data'] == []
+    else:
+        assert resp.json['data'][0]['date_fin'] == last_day
+
+
+def test_clae_next_week_result(app, resource):
+    with freezegun.freeze_time('2020-04-07'):
+        resp = app.get('/toulouse-axel/test/clae_next_weeks')
+    assert len(resp.json['data']) == 15
+    assert resp.json['data'][0] == {
+        'id': 'week20200420-week20200424',
+        'text': 'Monday 20 April → Friday 24 April 2020',
+        'date_debut': '2020-04-20',
+        'date_fin': '2020-04-24',
+        'annee_reference': '2019',
+    }
+    assert resp.json['data'][14] == {
+        'id': 'week20200727-week20200731',
+        'text': 'Monday 27 July → Friday 31 July 2020',
+        'date_debut': '2020-07-27',
+        'date_fin': '2020-07-31',
+        'annee_reference': '2019',
+    }
+
+    # a week with a new year
+    with freezegun.freeze_time('2019-12-22'):
+        resp = app.get('/toulouse-axel/test/clae_next_weeks')
+    assert resp.json['data'][0] == {
+        'id': 'week20191230-week20200103',
+        'text': 'Monday 30 December 2019 → Friday 3 January 2020',
+        'date_debut': '2019-12-30',
+        'date_fin': '2020-01-03',
+        'annee_reference': '2019',
+    }
+
+    # last week is not complete
+    with freezegun.freeze_time('2019-07-01'):
+        resp = app.get('/toulouse-axel/test/clae_next_weeks')
+    assert resp.json['data'][-1] == {
+        'id': 'week20190729-week20190731',
+        'text': 'Monday 29 July → Wednesday 31 July 2019',
+        'date_debut': '2019-07-29',
+        'date_fin': '2019-07-31',
+        'annee_reference': '2018',
+    }
+    with freezegun.freeze_time('2017-07-01'):
+        resp = app.get('/toulouse-axel/test/clae_next_weeks')
+    assert resp.json['data'][-1] == {
+        'id': 'week20170731-week20170731',
+        'text': 'Monday 31 July → Monday 31 July 2017',
+        'date_debut': '2017-07-31',
+        'date_fin': '2017-07-31',
+        'annee_reference': '2016',
+    }
+
+
 def test_clae_booking_endpoint_axel_error(app, resource, booking_params):
     Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
     with freezegun.freeze_time('2019-09-01'):
-- 
2.20.1

