From f4cf44bba71510b2d3d29532b6caf5413355be45 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Tue, 13 Oct 2020 17:09:01 +0200
Subject: [PATCH] maelis: add Activity calendar endpoints (#47172)

---
 passerelle/apps/maelis/models.py              | 108 +++++++++++++++++-
 .../maelis/updateRealCalendarsResponse.xml    |   1 +
 .../updateScheduleCalendarsResponse.xml       |   1 +
 .../maelis/updateWeekCalendarResponse.xml     |   1 +
 tests/test_maelis.py                          |  81 +++++++++++++
 5 files changed, 191 insertions(+), 1 deletion(-)
 create mode 100644 tests/data/maelis/updateRealCalendarsResponse.xml
 create mode 100644 tests/data/maelis/updateScheduleCalendarsResponse.xml
 create mode 100644 tests/data/maelis/updateWeekCalendarResponse.xml

diff --git a/passerelle/apps/maelis/models.py b/passerelle/apps/maelis/models.py
index b1533f07..f57e65ff 100644
--- a/passerelle/apps/maelis/models.py
+++ b/passerelle/apps/maelis/models.py
@@ -90,17 +90,16 @@ COORDINATES_SCHEMA = {
         },
         "mail": {
             "description": "mail",
             "type": "string",
         }
     }
 }
 
-
 class Maelis(BaseResource):
     base_url = models.URLField(_('Base API URL'),
                                default='http://www3.sigec.fr/entrouvertws/services/')
     login = models.CharField(_('API Login'), max_length=256)
     password = models.CharField(_('API Password'), max_length=256)
 
     category = _('Business Process Connectors')
 
@@ -425,16 +424,123 @@ class Maelis(BaseResource):
         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]}
 
+    @endpoint(
+        display_category=_('Activity'),
+        perm='can_access',
+        display_order=3,
+        description=_('Update week calendar'),
+        name='update-week-calendar',
+        parameters={
+            'NameID': {'description': _('Publik ID')},
+            'personID': {'description': _('Person ID')},
+            'activityID': {'description': _('Activity ID')},
+            'dateStart': {'description': _('Booking start date ?')},
+            'dateEnd': {'description': _('Booking end date ?')},
+            'weeklyPlanningAM': {'description': _('?')},
+            'weeklyPlanningPM': {'description': _('?')},
+        })
+    def update_week_calendar(self, request, NameID, personID, activityID,
+                              dateStart, dateEnd, weeklyPlanningAM, weeklyPlanningPM):
+        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')
+
+        r = self.call('ActivityService?wsdl', 'updateWeekCalendar',
+                      numPerson=personID,
+                      idActivity=activityID,
+                      dateStart=dateStart,
+                      dateEnd=dateEnd,
+                      weeklyPlanningAM=weeklyPlanningAM,
+                      weeklyPlanningPM=weeklyPlanningPM)
+        return {'data': serialize_object(r)}
+
+    @endpoint(
+        display_category=_('Activity'),
+        perm='can_access',
+        display_order=4,
+        description=_('Update schedule calendars'),
+        name='update-schedule-calendars',
+        parameters={
+            'NameID': {'description': _('Publik ID')},
+            'personID': {'description': _('Person ID')},
+            'activityID': {'description': _('Activity ID')},
+            'unitID': {'description': _('Unit ID')},
+            'placeID': {'description': _('Place ID')},
+            'day': {'description': _('Date')},
+            'action': {'description': _('Booking action: ADD_PRES_PREVI or DEL_PRES_PREVI')},
+        })
+    def update_schedule_calendars(self, request, NameID, personID, activityID, unitID, placeID,
+                                  day, action):
+        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')
+
+        client = self.get_client('ActivityService?wsdl')
+        type_event1 = client.get_type('ns1:updateScheduleCalendarsRequestBean')
+        type_event2 = client.get_type('ns1:unitPersonDayInfoBean')
+        event = type_event1(type_event2(
+            numPerson=personID,
+            idAct=activityID,
+            idUni=unitID,
+            idPlace=placeID,
+            date=day,
+            action=action,
+        ))
+
+        r = self.call('ActivityService?wsdl', 'updateScheduleCalendars',
+                      updateScheduleCalendarsRequestBean=event)
+        return {'data': serialize_object(r)}
+
+    @endpoint(
+        display_category=_('Activity'),
+        perm='can_access',
+        display_order=5,
+        description=_('Update real calendars'),
+        name='update-real-calendars',
+        parameters={
+            'NameID': {'description': _('Publik ID')},
+            'personID': {'description': _('Person ID')},
+            'activityID': {'description': _('Activity ID')},
+            'unitID': {'description': _('Unit ID')},
+            'placeID': {'description': _('Place ID')},
+            'day': {'description': _('Date')},
+            'action': {'description': _('Booking action: ADD_PRES_REAL or DEL_PRES_REAL')},
+        })
+    def update_real_calendars(self, request, NameID, personID, activityID, unitID, placeID,
+                              day, action):
+        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')
+
+        client = self.get_client('ActivityService?wsdl')
+        type_event1 = client.get_type('ns1:updateRealCalendarsRequestBean')
+        type_event2 = client.get_type('ns1:unitPersonDayInfoBean')
+        event = type_event1(type_event2(
+            numPerson=personID,
+            idAct=activityID,
+            idUni=unitID,
+            idPlace=placeID,
+            date=day,
+            action=action,
+        ))
+
+        r = self.call('ActivityService?wsdl', 'updateRealCalendars',
+                      updateRealCalendarsRequestBean=event)
+        return {'data': serialize_object(r)}
+
 
 class Link(models.Model):
     resource = models.ForeignKey(Maelis, on_delete=models.CASCADE)
     name_id = models.CharField(blank=False, max_length=256)
     family_id = models.CharField(blank=False, max_length=128)
     created = models.DateTimeField(auto_now_add=True)
     updated = models.DateTimeField(auto_now=True)
 
diff --git a/tests/data/maelis/updateRealCalendarsResponse.xml b/tests/data/maelis/updateRealCalendarsResponse.xml
new file mode 100644
index 00000000..7d7ff85e
--- /dev/null
+++ b/tests/data/maelis/updateRealCalendarsResponse.xml
@@ -0,0 +1 @@
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:updateScheduleCalendarsResponse xmlns:ns1="activity.ws.maelis.sigec.com"><return><result>true</result></return></ns1:updateScheduleCalendarsResponse></soap:Body></soap:Envelope>
diff --git a/tests/data/maelis/updateScheduleCalendarsResponse.xml b/tests/data/maelis/updateScheduleCalendarsResponse.xml
new file mode 100644
index 00000000..7d7ff85e
--- /dev/null
+++ b/tests/data/maelis/updateScheduleCalendarsResponse.xml
@@ -0,0 +1 @@
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:updateScheduleCalendarsResponse xmlns:ns1="activity.ws.maelis.sigec.com"><return><result>true</result></return></ns1:updateScheduleCalendarsResponse></soap:Body></soap:Envelope>
diff --git a/tests/data/maelis/updateWeekCalendarResponse.xml b/tests/data/maelis/updateWeekCalendarResponse.xml
new file mode 100644
index 00000000..7c039472
--- /dev/null
+++ b/tests/data/maelis/updateWeekCalendarResponse.xml
@@ -0,0 +1 @@
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns1:updateWeekCalendarResponse xmlns:ns1="activity.ws.maelis.sigec.com"></ns1:updateWeekCalendarResponse></soap:Body></soap:Envelope>
diff --git a/tests/test_maelis.py b/tests/test_maelis.py
index 5df2f412..73c0d0d3 100644
--- a/tests/test_maelis.py
+++ b/tests/test_maelis.py
@@ -225,8 +225,89 @@ def test_get_child_month_planning(mocked_post, mocked_get, family_service_wsdl,
     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']
+
+
+@mock.patch('passerelle.utils.Request.get')
+@mock.patch('passerelle.utils.Request.post')
+def test_update_week_calendar(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('updateWeekCalendarResponse.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/update-week-calendar?NameID=local&personID=21293'
+                   + '&activityID=A10003132293&dateStart=2020-11-24&dateEnd=2020-11-25'
+                   + '&weeklyPlanningAM=bof&weeklyPlanningPM=bof')
+    assert resp.json == {'data': None, 'err': 0}
+
+
+@mock.patch('passerelle.utils.Request.get')
+@mock.patch('passerelle.utils.Request.post')
+def test_update_schedule_calendars(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('updateScheduleCalendarsResponse.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/update-schedule-calendars?NameID=local&personID=21293'
+                   + '&activityID=A10003132030&unitID=A10003132038&placeID=A10000000212'
+                   + '&day=2020-11-25&action=ADD_PRES_PREVI')
+    assert resp.json['data'] == {'result' : True, 'unitPersonDayInfoList' : []}
+
+
+@mock.patch('passerelle.utils.Request.get')
+@mock.patch('passerelle.utils.Request.post')
+def test_update_real_calendars(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('updateRealCalendarsResponse.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/update-real-calendars?NameID=local&personID=21293'
+                   + '&activityID=A10003132030&unitID=A10003132038&placeID=A10000000212'
+                   + '&day=2020-11-25&action=ADD_PRES_PREVI')
+    assert resp.json['data'] == {'result' : True, 'unitPersonDayInfoList' : []}
-- 
2.29.2

