From 56421fb9dd32ba75b662388e9ac045f45cfe7b65 Mon Sep 17 00:00:00 2001
From: Serghei Mihai <smihai@entrouvert.com>
Date: Tue, 10 Nov 2020 17:55:03 +0100
Subject: [PATCH] maelis add child month planning listing (#47172)

---
 passerelle/apps/maelis/models.py              | 33 +++++++++++++++++++
 passerelle/apps/maelis/utils.py               | 13 ++++++++
 .../maelis/readChildMonthPlanningResponse.xml |  1 +
 tests/test_maelis.py                          | 32 ++++++++++++++++++
 4 files changed, 79 insertions(+)
 create mode 100644 tests/data/maelis/readChildMonthPlanningResponse.xml

diff --git a/passerelle/apps/maelis/models.py b/passerelle/apps/maelis/models.py
index 617f69ed..b1533f07 100644
--- a/passerelle/apps/maelis/models.py
+++ b/passerelle/apps/maelis/models.py
@@ -370,7 +370,9 @@ class Maelis(BaseResource):
         pass
 
     @endpoint(
+        display_category=_('Activities'),
         perm='can_access',
+        display_order=1,
         description=_('Get activity list'),
         name='activity-list',
         parameters={
@@ -397,6 +399,37 @@ class Maelis(BaseResource):
         activities = serialize_object(r)
         return {'data': [utils.normalize_activity(a) for a in activities]}
 
+    @endpoint(
+        display_category=_('Activities'),
+        perm='can_access',
+        display_order=2,
+        description=_('Read child month planning'),
+        name='child-month-planning',
+        parameters={
+            'NameID': {'description': _('Publik ID')},
+            'personID': {'description': _('Person ID')},
+            'year': {'description': _('Year')},
+            'month': {'description': _('Month')},
+        })
+    def child_month_planning(self, request, NameID, personID, activityID,
+                             year=None, month=None):
+        link = self.get_link(NameID)
+        family_data = self.get_family_data(link.family_id)
+        if personID not in [c['id'] for c in family_data['childInfoList']]:
+            raise APIError('Child not found', err_code='not-found')
+        if not year:
+            year = timezone.now().year
+        if not month:
+            month = timezone.now().month
+
+        r = self.call('ActivityService?wsdl', 'readChildMonthPlanning',
+                      year=timezone.now().year,
+                      numMonth=month,
+                      idActivity=activityID,
+                      numPerson=personID)
+        planning = serialize_object(r['calendList'])
+        return {'data': [utils.normalize_schedule(s) for s in planning]}
+
 
 class Link(models.Model):
     resource = models.ForeignKey(Maelis, on_delete=models.CASCADE)
diff --git a/passerelle/apps/maelis/utils.py b/passerelle/apps/maelis/utils.py
index 60444cb4..5e71ab7f 100644
--- a/passerelle/apps/maelis/utils.py
+++ b/passerelle/apps/maelis/utils.py
@@ -63,3 +63,16 @@ def get_default_school_year():
         return now.year
     else:
         return now.year - 1
+
+
+def normalize_schedule(schedule):
+    schedule['id'] = schedule['unit']['idActivity']
+    schedule['text'] = schedule['unit']['libelle']
+    schedule['days'] = []
+    for day in schedule.pop('listDays'):
+        schedule['days'].append(
+            {'type': day['dayType']['code'],
+             'id': day['datePlanning'],
+             'text': day['datePlanning'].strftime(datetime_format)
+             })
+    return schedule
diff --git a/tests/data/maelis/readChildMonthPlanningResponse.xml b/tests/data/maelis/readChildMonthPlanningResponse.xml
new file mode 100644
index 00000000..d49abee1
--- /dev/null
+++ b/tests/data/maelis/readChildMonthPlanningResponse.xml
@@ -0,0 +1 @@
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:readChildMonthPlanningResponse xmlns:ns1="activity.ws.maelis.sigec.com"><ResultCalendarList><person><num>0</num></person><calendList><unit><id>A10003123492</id><idActivity>A10003123490</idActivity><libelle>2 2020-2021  RESTAURATION SCOLAIRE</libelle><motif>X</motif></unit><listDays><datePlanning>2020-11-02T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-03T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-05T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-06T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-09T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-10T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-12T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-13T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-16T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-17T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-19T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-20T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-23T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-24T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-26T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-27T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays><listDays><datePlanning>2020-11-30T18:12:36.038+01:00</datePlanning><dayType><code>DAY</code></dayType></listDays></calendList></ResultCalendarList></ns1:readChildMonthPlanningResponse></soap:Body></soap:Envelope>
diff --git a/tests/test_maelis.py b/tests/test_maelis.py
index 5790046b..5df2f412 100644
--- a/tests/test_maelis.py
+++ b/tests/test_maelis.py
@@ -198,3 +198,35 @@ def test_get_invoice_details(mocked_post, mocked_get, invoice_service_wsdl,
     assert resp.json['data']
     assert resp.json['data']['label'] == 'FACTURATION SEPTEMBRE 2014'
     assert resp.json['data']['display_id'] == '53186'
+
+
+@mock.patch('passerelle.utils.Request.get')
+@mock.patch('passerelle.utils.Request.post')
+def test_get_child_month_planning(mocked_post, mocked_get, family_service_wsdl,
+                                  activity_service_wsdl, app, connector):
+    mocked_get.side_effect = (
+        utils.FakedResponse(content=family_service_wsdl,
+                            status_code=200,
+                            headers={'Content-Type': 'text/xml'}),
+        utils.FakedResponse(content=activity_service_wsdl,
+                            status_code=200,
+                            headers={'Content-Type': 'text/xml'})
+    )
+    mocked_post.side_effect = (
+        utils.FakedResponse(content=get_xml_file('readFamily.xml'),
+                            status_code=200,
+                            headers={'Content-Type': 'text/xml'}),
+        utils.FakedResponse(content=get_xml_file('readChildMonthPlanningResponse.xml'),
+                            status_code=200,
+                            headers={'Content-Type': 'text/xml'})
+    )
+    Link.objects.create(resource=connector, family_id='3264', name_id='local')
+    resp = app.get('/maelis/test/child-month-planning?NameID=local&personID=21293&activityID=A10003132293')
+    assert resp.json['data']
+    for planning in resp.json['data']:
+        assert planning['id']
+        assert planning['text']
+        assert planning['days']
+        for day in planning['days']:
+            assert day['id']
+            assert day['text']
-- 
2.29.2

