From 3f07177ea88ba4650ac262c06f6208af22cb36bb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laur=C3=A9line=20Gu=C3=A9rin?= <zebuline@entrouvert.com>
Date: Thu, 16 Jan 2020 10:33:39 +0100
Subject: [PATCH] toulouse_axel: get update management dates (#39001)

---
 functests/toulouse_axel/test_toulouse_axel.py |  9 ++++
 passerelle/contrib/toulouse_axel/models.py    | 48 +++++++++++++------
 .../xsd/Dui/R_RefDateGestionDui.xsd           | 38 +++++++++++++++
 tests/test_toulouse_axel.py                   | 34 +++++++++++++
 4 files changed, 115 insertions(+), 14 deletions(-)
 create mode 100644 passerelle/contrib/toulouse_axel/xsd/Dui/R_RefDateGestionDui.xsd

diff --git a/functests/toulouse_axel/test_toulouse_axel.py b/functests/toulouse_axel/test_toulouse_axel.py
index e7c43f04..7c6e0971 100644
--- a/functests/toulouse_axel/test_toulouse_axel.py
+++ b/functests/toulouse_axel/test_toulouse_axel.py
@@ -3,6 +3,15 @@ import requests
 
 
 def test_link(conn, user):
+    print("Get update management dates")
+    url = conn + '/update_management_dates'
+    resp = requests.get(url)
+    resp.raise_for_status()
+    res = resp.json()
+    assert res['err'] == 0
+    pprint.pprint(res)
+    print('\n')
+
     name_id = user['name_id']
     url = conn + '/link?NameID=%s' % name_id
     payload = {
diff --git a/passerelle/contrib/toulouse_axel/models.py b/passerelle/contrib/toulouse_axel/models.py
index a3c002fb..cab85f29 100644
--- a/passerelle/contrib/toulouse_axel/models.py
+++ b/passerelle/contrib/toulouse_axel/models.py
@@ -172,7 +172,10 @@ class AxelError(Exception):
 
 
 def xml_schema_converter(name, root_element):
-    return AxelSchema(os.path.join(BASE_XSD_PATH, name), root_element)
+    xsd_path = os.path.join(BASE_XSD_PATH, name)
+    if not os.path.exists(xsd_path):
+        return None
+    return AxelSchema(xsd_path, root_element)
 
 
 OperationResult = namedtuple('OperationResult', ['json_response', 'xml_request', 'xml_response'])
@@ -196,21 +199,23 @@ class Operation(object):
         schema['merge_extra'] = True
         return schema
 
-    def __call__(self, resource, request_data):
+    def __call__(self, resource, request_data=None):
         client = resource.soap_client()
 
-        try:
-            serialized_request = self.request_converter.encode(request_data)
-        except xmlschema.XMLSchemaValidationError as e:
-            raise AxelError('invalid request %s' % str(e))
-        indent(serialized_request)
-        serialized_request = ET.tostring(serialized_request)
-        try:
-            self.request_converter.xml_schema.validate(serialized_request)
-        except xmlschema.XMLSchemaValidationError as e:
-            raise AxelError(
-                'invalid request %s' % str(e),
-                xml_request=serialized_request)
+        serialized_request = ''
+        if self.request_converter:
+            try:
+                serialized_request = self.request_converter.encode(request_data)
+            except xmlschema.XMLSchemaValidationError as e:
+                raise AxelError('invalid request %s' % str(e))
+            indent(serialized_request)
+            serialized_request = ET.tostring(serialized_request)
+            try:
+                self.request_converter.xml_schema.validate(serialized_request)
+            except xmlschema.XMLSchemaValidationError as e:
+                raise AxelError(
+                    'invalid request %s' % str(e),
+                    xml_request=serialized_request)
 
         result = client.service.getData(
             self.operation,
@@ -240,6 +245,7 @@ class Operation(object):
                 xml_response=pretty_result)
 
 
+ref_date_gestion_dui = Operation('RefDateGestionDui')
 ref_verif_dui = Operation('RefVerifDui')
 ref_famille_dui = Operation('RefFamilleDui')
 form_maj_famille_dui = Operation('FormMajFamilleDui')
@@ -402,6 +408,20 @@ class ToulouseAxel(BaseResource):
         except Lock.DoesNotExist:
             return {'key': key, 'locked': False}
 
+    @endpoint(
+        description=_("Get dates of the update management"),
+        perm='can_access')
+    def update_management_dates(self, request):
+        try:
+            result = ref_date_gestion_dui(self)
+        except AxelError as e:
+            raise APIError(
+                'Axel error: %s' % e,
+                err_code='error',
+                data={'xml_request': e.xml_request,
+                      'xml_response': e.xml_response})
+        return {'data': result.json_response['DATA']['PORTAIL']['DUIDATEGESTION']}
+
     @endpoint(
         description=_('Create link between user and Toulouse Axel'),
         perm='can_access',
diff --git a/passerelle/contrib/toulouse_axel/xsd/Dui/R_RefDateGestionDui.xsd b/passerelle/contrib/toulouse_axel/xsd/Dui/R_RefDateGestionDui.xsd
new file mode 100644
index 00000000..c591c2a8
--- /dev/null
+++ b/passerelle/contrib/toulouse_axel/xsd/Dui/R_RefDateGestionDui.xsd
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:all="urn:AllAxelTypes">
+	
+	<xsd:import schemaLocation="../AllAxelTypes.xsd" namespace="urn:AllAxelTypes"  />
+
+	<xsd:redefine schemaLocation="../R_ShemaResultat.xsd">
+	    <xsd:simpleType name="TYPEType">
+			<xsd:restriction base="TYPEType">
+				<xsd:enumeration value="RefDateGestionDui" />
+			</xsd:restriction>
+	    </xsd:simpleType>
+		
+		<xsd:complexType name="PORTAILType">
+			<xsd:complexContent>
+				<xsd:extension base="PORTAILType">
+					<xsd:sequence>
+							<xsd:element ref="DUIDATEGESTION" minOccurs="0"/>
+					</xsd:sequence>	
+				</xsd:extension>
+			 </xsd:complexContent>
+		</xsd:complexType>
+	</xsd:redefine>
+	
+	<xsd:complexType name="DUIDATEGESTIONType">
+		<xsd:sequence>
+			<xsd:element ref="REPORT-REVENUS" />
+			<xsd:element ref="EXTRACTION-FAMILLES" />
+			<xsd:element ref="EXTRACTION-CAFPRO" />
+		</xsd:sequence> 
+	</xsd:complexType>
+		
+	<xsd:element name="REPORT-REVENUS" type="all:DATEType"/>
+	<xsd:element name="EXTRACTION-FAMILLES" type="all:DATEType"/>
+	<xsd:element name="EXTRACTION-CAFPRO" type="all:DATEType"/>
+	
+	<xsd:element name="DUIDATEGESTION" type="DUIDATEGESTIONType" />
+		
+</xsd:schema>
diff --git a/tests/test_toulouse_axel.py b/tests/test_toulouse_axel.py
index 0cbf94ba..d370a6dc 100644
--- a/tests/test_toulouse_axel.py
+++ b/tests/test_toulouse_axel.py
@@ -32,6 +32,7 @@ from passerelle.contrib.toulouse_axel.models import (
     OperationResult,
     ToulouseAxel,
     form_maj_famille_dui,
+    ref_date_gestion_dui,
     ref_famille_dui,
     ref_facture_a_payer,
     ref_facture_pdf,
@@ -238,6 +239,15 @@ def mock_getdata(content, operation):
         yield
 
 
+@pytest.mark.parametrize('content', [
+    '<PORTAIL><DUIDATEGESTION/></PORTAIL>',
+])
+def test_operation_ref_date_gestion_dui(resource, content):
+    with mock_getdata(content, 'RefDateGestionDui'):
+        with pytest.raises(AxelError):
+            ref_date_gestion_dui(resource)
+
+
 @pytest.mark.parametrize('content', [
     '<PORTAIL><DUI/></PORTAIL>',
     '<PORTAIL><DUI><CODE>foo</CODE></DUI></PORTAIL>',
@@ -317,6 +327,30 @@ def test_operation_ref_facture_pdf(resource, content):
             })
 
 
+def test_update_management_dates_endpoint_axel_error(app, resource):
+    with mock.patch('passerelle.contrib.toulouse_axel.models.ref_date_gestion_dui') as operation:
+        operation.side_effect = AxelError('FooBar')
+        resp = app.get('/toulouse-axel/test/update_management_dates')
+    assert resp.json['err_desc'] == "Axel error: FooBar"
+    assert resp.json['err'] == 'error'
+    assert resp.json['data'] == {'xml_request': None, 'xml_response': None}
+
+
+def test_update_management_dates_endpoint(app, resource):
+    content = '''<PORTAIL>
+    <DUIDATEGESTION>
+        <REPORT-REVENUS>08/08/2019</REPORT-REVENUS>
+        <EXTRACTION-FAMILLES>18/10/2019</EXTRACTION-FAMILLES>
+        <EXTRACTION-CAFPRO>18/01/2020</EXTRACTION-CAFPRO>
+    </DUIDATEGESTION>
+</PORTAIL>'''
+    with mock_getdata(content, 'RefDateGestionDui'):
+        resp = app.get('/toulouse-axel/test/update_management_dates')
+    assert set(resp.json.keys()) == set(['err', 'data'])
+    assert resp.json['err'] == 0
+    assert set(resp.json['data'].keys()) == set(['REPORT-REVENUS', 'EXTRACTION-FAMILLES', 'EXTRACTION-CAFPRO'])
+
+
 def test_link_endpoint_nameid_empty(app, resource, link_params):
     resp = app.post_json('/toulouse-axel/test/link?NameID=', params=link_params, status=400)
     assert resp.json['err_desc'] == "NameID is empty"
-- 
2.20.1

