From 7643d3da7a8d23a2eb10711ff57f8970ec437fc6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= <fpeters@entrouvert.com>
Date: Tue, 24 Sep 2019 09:46:57 +0200
Subject: [PATCH 2/2] cartads_cs: add endpoint to join existing dossier
 (#36382)

---
 passerelle/apps/cartads_cs/models.py | 47 ++++++++++++++++++++++++++++
 tests/test_cartads_cs.py             | 46 +++++++++++++++++++++++++++
 2 files changed, 93 insertions(+)

diff --git a/passerelle/apps/cartads_cs/models.py b/passerelle/apps/cartads_cs/models.py
index a5363eba..703dfe10 100644
--- a/passerelle/apps/cartads_cs/models.py
+++ b/passerelle/apps/cartads_cs/models.py
@@ -316,6 +316,12 @@ class AbstractCartaDSCS(BaseResource):
         cache = CartaDSDataCache.objects.get(data_type='communes')
         return cache.data_values
 
+    def get_commune_id(self, commune_name):
+        for info in self.communes(request=None)['data']:
+            if info['text'] == commune_name:
+                return info['id']
+        return None
+
     @endpoint(description=_('Get list of file types'),
               parameters={
                   'commune_id': COMMUNE_ID_PARAM,
@@ -974,6 +980,47 @@ class AbstractCartaDSCS(BaseResource):
             } for x in files]
         }
 
+    @endpoint(perm='can_access',
+              description=_('Join dossier'),
+              parameters={
+                  'name_id': {
+                      'description': _('UUID of requester'),
+                      'example_value': '3eb56fc'
+                  },
+                  'dossier_number': {
+                      'description': _('Dossier Number'),
+                      'example_value': 'PC 069 012 23 45678',
+                  },
+                  'dossier_password': {
+                      'description': _('Dossier Password'),
+                      'example_value': '5A3E36FE-80D3-45E5-9323-7415E04D3B14',
+                  },
+              })
+    def join(self, request, name_id, dossier_number, dossier_password):
+        client = self.soap_client(wsdl_url=self.get_wsdl_url('ServiceSuiviNumerique'))
+        try:
+            resp = client.service.ActiverServiceSuiviNumerique(
+                    self.get_token(),
+                    dossier_number,
+                    dossier_password)
+        except zeep.exceptions.Fault as e:
+            self.logger.error('error joining dossier %s (%r)', dossier_number, e.message)
+            raise APIError('error joining dossier (wrong password?)')
+        id_dossier = int(resp)
+        dossier, created = CartaDSDossier.objects.get_or_create(cartads_id_dossier=id_dossier)
+        if created:
+            dossier.cartads_numero_dossier = dossier_number
+            client_dossier = self.soap_client(wsdl_url=self.get_wsdl_url('ServiceRechercheDossier'))
+            infos = client_dossier.service.GetInfosDossier(
+                    self.client_name,
+                    id_dossier)
+            dossier.type_dossier_id = infos['CoTypeDossier']
+            dossier.commune_id = self.get_commune_id(infos['Commune'])
+            dossier.save()
+
+        dossier.subscribers.add(CartaDSSubscriber.objects.get_or_create(name_id=name_id)[0])
+        return {'err': 0, 'dossier_id': dossier.id}
+
 
 class CartaDSCS(AbstractCartaDSCS):
     category = _('Misc')
diff --git a/tests/test_cartads_cs.py b/tests/test_cartads_cs.py
index c79f0a5e..e38cffaf 100644
--- a/tests/test_cartads_cs.py
+++ b/tests/test_cartads_cs.py
@@ -161,6 +161,20 @@ class FakeService():
         assert _soapheaders
         return None
 
+    def ActiverServiceSuiviNumerique(self, toke, dossier_number, dossier_password):
+        return 123
+
+    def GetInfosDossier(self, client_name, id_dossier):
+        assert id_dossier == 123
+        return OrderedDict([
+            (u'AdresseTerrain', u'all\xe9e des Fleurs'),
+            (u'CoTypeDossier', 'PC'),
+            (u'Commune', u'AIGREFEUILLE SUR MAINE'),
+            (u'DateDepot', datetime.datetime(2019, 9, 19, 0, 0)),
+            (u'IdDossier', 478864L),
+            (u'NomDossier', 'PC 069 085 19 00010'),
+            (u'TypeDossier', 'Permis de construire')])
+
 
 def pdf_mock(url, request):
     return {'content': '%PDF...', 'status_code': 200}
@@ -553,3 +567,35 @@ def test_list_of_files(connector, app, cached_data):
         # missing status
         resp = app.get('/cartads-cs/test/files?name_id=1234&status=Attente DOC')
         assert len(resp.json['data']) == 0
+
+
+def test_join(connector, app, cached_data):
+    CartaDSDossier.objects.all().delete()
+
+    # new
+    with mock.patch('passerelle.apps.cartads_cs.models.CartaDSCS.soap_client') as client:
+        client.return_value = mock.Mock(service=FakeService())
+        resp = app.get('/cartads-cs/test/join?name_id=3456&dossier_number=123&dossier_password=XXX')
+        dossier = CartaDSDossier.objects.get(id=resp.json['dossier_id'])
+        assert dossier.commune_id == '2'
+        assert dossier.type_dossier_id == 'PC'
+
+    # existing
+    with mock.patch('passerelle.apps.cartads_cs.models.CartaDSCS.soap_client') as client:
+        client.return_value = mock.Mock(service=FakeService())
+        resp = app.get('/cartads-cs/test/join?name_id=2345&dossier_number=123&dossier_password=XXX')
+        dossier = CartaDSDossier.objects.get(id=resp.json['dossier_id'])
+        assert CartaDSDossier.objects.count() == 1
+        assert dossier.commune_id == '2'
+        assert dossier.type_dossier_id == 'PC'
+        assert [x.name_id for x in dossier.subscribers.all().order_by('name_id')] == ['2345', '3456']
+
+    # check /files API afterwards
+    with mock.patch('passerelle.apps.cartads_cs.models.CartaDSCS.soap_client') as client:
+        client.return_value = mock.Mock(service=FakeService())
+        resp = app.get('/cartads-cs/test/files?name_id=1234')
+        assert len(resp.json['data']) == 0
+        resp = app.get('/cartads-cs/test/files?name_id=2345')
+        assert len(resp.json['data']) == 1
+        resp = app.get('/cartads-cs/test/files?name_id=3456')
+        assert len(resp.json['data']) == 1
-- 
2.23.0

