From dd3e72928bbcdfd7b5716b8999dbaf9d3510c486 Mon Sep 17 00:00:00 2001
From: Nicolas ROCHE <nroche@entrouvert.com>
Date: Fri, 25 Nov 2022 15:58:36 +0100
Subject: [PATCH 1/2] toulouse-maelis: add endpoint to create or update
 quotients (#71698)

---
 functests/toulouse_maelis/conftest.py         |   8 +-
 .../data/test_update_quotient.json            |  29 +++++
 functests/toulouse_maelis/test_family.py      |  46 ++++++++
 passerelle/contrib/toulouse_maelis/models.py  |  25 ++++
 passerelle/contrib/toulouse_maelis/schemas.py |  36 ++++++
 .../Q_create_update_quotient.xml              |  23 ++++
 .../R_create_update_quotient.xml              |   5 +
 .../R_create_update_quotient_soap_error.xml   |  13 +++
 tests/data/toulouse_maelis/R_read_family.xml  |  14 +++
 .../toulouse_maelis/R_read_family_relax.xml   |  14 +++
 .../R_read_family_reordered.xml               |  14 +++
 tests/test_toulouse_maelis.py                 | 108 +++++++++++++++++-
 12 files changed, 332 insertions(+), 3 deletions(-)
 create mode 100644 functests/toulouse_maelis/data/test_update_quotient.json
 create mode 100644 tests/data/toulouse_maelis/Q_create_update_quotient.xml
 create mode 100644 tests/data/toulouse_maelis/R_create_update_quotient.xml
 create mode 100644 tests/data/toulouse_maelis/R_create_update_quotient_soap_error.xml

diff --git a/functests/toulouse_maelis/conftest.py b/functests/toulouse_maelis/conftest.py
index d3625bee..61ed673b 100644
--- a/functests/toulouse_maelis/conftest.py
+++ b/functests/toulouse_maelis/conftest.py
@@ -283,21 +283,24 @@ def diff_child(conn, name_id, index, expected_file, key=None):
     remove_id_on_child(child)
     if not key:
         assert diff(child, expected_file)
     else:
         assert diff(child[key], expected_file)
     return data
 
 
-def diff_rlg(conn, name_id, index, expected_file):
+def diff_rlg(conn, name_id, index, expected_file, key=None):
     data = read_family(conn, name_id)
     rlg = copy.deepcopy(data['RL%s' % index])
     remove_id_on_rlg(rlg)
-    assert diff(rlg, expected_file)
+    if not key:
+        assert diff(rlg, expected_file)
+    else:
+        assert diff(rlg[key], expected_file)
     return data
 
 
 def diff_family(conn, name_id, expected_file, key=None):
     data = read_family(conn, name_id)
     family = copy.deepcopy(data)
     remove_id_on_family(family)
     if not key:
@@ -333,16 +336,17 @@ def create_data(request, conn):
     assert create_result['err'] == 0
     print('\ncreate DUI: %s' % str(create_result['data']['number']))
     data = diff_family(conn, name_id, 'test_create_family.json')
 
     return {
         'name_id': name_id,  # linked
         'family_id': str(create_result['data']['number']),
         'lastname': lastname,
+        'rl1_num': data['RL1']['num'],
         'family_payload': create_family_payload,
         'data': data,
     }
 
 
 @pytest.fixture(scope='session')
 def update_data(request, conn):
     name_id = request.config.getoption('--nameid')
diff --git a/functests/toulouse_maelis/data/test_update_quotient.json b/functests/toulouse_maelis/data/test_update_quotient.json
new file mode 100644
index 00000000..a257f05a
--- /dev/null
+++ b/functests/toulouse_maelis/data/test_update_quotient.json
@@ -0,0 +1,29 @@
+[
+  {
+    "yearRev": 2021,
+    "dateStart": "2022-01-02T00:00:00+01:00",
+    "dateEnd": "2022-12-31T00:00:00+01:00",
+    "mtt": 1500.33,
+    "cdquo": "QS",
+    "codeUti": null,
+    "cdquo_text": "QUOTIENT SCOLAIRE"
+  },
+  {
+    "yearRev": 2020,
+    "dateStart": "2022-01-02T00:00:00+01:00",
+    "dateEnd": "2022-12-31T00:00:00+01:00",
+    "mtt": 1500.33,
+    "cdquo": "QS",
+    "codeUti": null,
+    "cdquo_text": "QUOTIENT SCOLAIRE"
+  },
+  {
+    "yearRev": 2021,
+    "dateStart": "2022-01-01T00:00:00+01:00",
+    "dateEnd": "2022-01-01T00:00:00+01:00",
+    "mtt": 1500.33,
+    "cdquo": "QS",
+    "codeUti": null,
+    "cdquo_text": "QUOTIENT SCOLAIRE"
+  }
+]
diff --git a/functests/toulouse_maelis/test_family.py b/functests/toulouse_maelis/test_family.py
index 9713cc4f..d87c54f9 100644
--- a/functests/toulouse_maelis/test_family.py
+++ b/functests/toulouse_maelis/test_family.py
@@ -686,8 +686,54 @@ def test_child_person(conn, update_data):
         update_data['bart_num'],
         abi_num,
     )
     payload = update_data['family_payload']['childList'][0]['authorizedPersonList'][0]
     resp = requests.post(url, json=payload)
     resp.raise_for_status()
     assert resp.json()['err'] == 0
     assert diff_family(conn, update_data['name_id'], 'test_update_family.json')
+
+
+def test_update_quotient(conn, create_data):
+    unlink(conn, create_data['name_id'])
+    link(conn, create_data)
+
+    # add quotient
+    url = conn + '/update-quotient?NameID=%s&rl_id=%s' % (create_data['name_id'], create_data['rl1_num'])
+    payload = {
+        'yearRev': '2021',
+        'dateStart': '2022-01-01',
+        'dateEnd': '2022-12-31',
+        'mtt': '1500.33',
+        'cdquo': 'QS',
+    }
+    resp = requests.post(url, json=payload)
+    resp.raise_for_status()
+    assert resp.json()['err'] == 0
+    data = read_family(conn, create_data['name_id'])
+    assert data['RL1']['quotientList'] == [
+        {
+            'yearRev': 2021,
+            'dateStart': '2022-01-01T00:00:00+01:00',
+            'dateEnd': '2022-12-31T00:00:00+01:00',
+            'mtt': 1500.33,
+            'cdquo': 'QS',
+            'codeUti': None,
+            'cdquo_text': 'QUOTIENT SCOLAIRE',
+        }
+    ]
+
+    # add quotient
+    payload['dateStart'] = '2022-01-02'
+    resp = requests.post(url, json=payload)
+    resp.raise_for_status()
+    assert resp.json()['err'] == 0
+    data = read_family(conn, create_data['name_id'])
+    assert len(data['RL1']['quotientList']) == 2
+
+    # add quotient on another income year
+    payload['yearRev'] = '2020'
+    resp = requests.post(url, json=payload)
+    resp.raise_for_status()
+    assert resp.json()['err'] == 0
+    data = diff_rlg(conn, create_data['name_id'], 1, 'test_update_quotient.json', 'quotientList')
+    assert len(data['RL1']['quotientList']) == 3
diff --git a/passerelle/contrib/toulouse_maelis/models.py b/passerelle/contrib/toulouse_maelis/models.py
index 31eb3ed1..f66d9006 100644
--- a/passerelle/contrib/toulouse_maelis/models.py
+++ b/passerelle/contrib/toulouse_maelis/models.py
@@ -188,16 +188,18 @@ class ToulouseMaelis(BaseResource, HTTPResource):
         self.add_text_value('Sex', data, ['sexe'])
 
     def add_text_value_to_rl(self, data):
         self.add_text_value('Civility', data, ['civility'])
         self.add_text_value('Quality', data, ['quality'])
         self.add_text_value('Complement', data, ['adresse', 'numComp'])
         self.add_text_value('CSP', data, ['profession', 'codeCSP'])
         self.add_text_value('Organ', data, ['CAFInfo', 'organ'])
+        for quotient in data['quotientList']:
+            self.add_text_value('Quotient', quotient, ['cdquo'])
 
     def add_text_value_to_family(self, data):
         self.add_text_value('Category', data, ['category'])
         self.add_text_value('Situation', data, ['situation'])
         for rlg in 'RL1', 'RL2':
             if data.get(rlg):
                 self.add_text_value_to_rl(data[rlg])
         for child in data['childList']:
@@ -837,16 +839,39 @@ class ToulouseMaelis(BaseResource, HTTPResource):
     def update_coordinate(self, request, NameID, rl_id, post_data):
         family_id = self.get_link(NameID).family_id
         self.assert_update_coordinate_payload_in_referential(post_data)
         self.replace_null_values(post_data)
 
         self.call('Family', 'updateCoordinate', numDossier=family_id, numPerson=rl_id, **post_data)
         return {'data': 'ok'}
 
+    @endpoint(
+        display_category='Famille',
+        description="Créer ou mettre à jour un quotient d'un responsable légal",
+        name='update-quotient',
+        perm='can_access',
+        parameters={
+            'NameID': {'description': 'Publik NameID'},
+            'rl_id': {'description': "Numéro du responsable légal"},
+        },
+        post={'request_body': {'schema': {'application/json': schemas.UPDATE_QUOTIENT_SCHEMA}}},
+    )
+    def update_quotient(self, request, NameID, rl_id, post_data):
+        family_id = self.get_link(NameID).family_id
+        self.assert_post_data_in_referential('Quotient', post_data, ['cdquo'])
+
+        payload = {
+            'dossierNumber': family_id,
+            'personNumber': rl_id,
+            'quotient': post_data,
+        }
+        self.call('Family', 'createUpdateQuotient', **payload)
+        return {'data': 'ok'}
+
     @endpoint(
         display_category='Famille',
         description="Création d'une personne à prévenir en cas d'urgence",
         name='create-person',
         perm='can_access',
         parameters={
             'NameID': {'description': 'Publik NameID'},
         },
diff --git a/passerelle/contrib/toulouse_maelis/schemas.py b/passerelle/contrib/toulouse_maelis/schemas.py
index a15411c6..b72b55e2 100644
--- a/passerelle/contrib/toulouse_maelis/schemas.py
+++ b/passerelle/contrib/toulouse_maelis/schemas.py
@@ -650,8 +650,44 @@ UPDATE_COORDINATE_SCHEMA = {
         'adresse': ADDRESS_SCHEMA,
         'contact': {'oneOf': [CONTACT_SCHEMA, {'type': 'null'}]},
         'profession': {'oneOf': [PROFESSION_SCHEMA, {'type': 'null'}]},
         'CAFInfo': {'oneOf': [CAFINFO_SCHEMA, {'type': 'null'}]},
     },
     'unflatten': True,
     'additionalProperties': False,
 }
+
+UPDATE_QUOTIENT_SCHEMA = {
+    '$schema': 'http://json-schema.org/draft-04/schema#',
+    'title': 'Family persons',
+    'description': "Informations sur les personnes autorisées à venir chercher l'enfant avec leur qualité",
+    'type': 'object',
+    'required': ['yearRev', 'dateStart', 'dateEnd', 'mtt', 'cdquo'],
+    'properties': {
+        'yearRev': {
+            'description': 'Année de revenu',
+            'type': 'string',
+            'pattern': '^[0-9]{4}$',
+        },
+        'dateStart': {
+            'description': 'Date de début',
+            'type': 'string',
+            'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
+        },
+        'dateEnd': {
+            'description': 'Date de fin',
+            'type': 'string',
+            'pattern': '^[0-9]{4}-[0-9]{2}-[0-9]{2}$',
+        },
+        'mtt': {
+            'description': 'Montant',
+            'type': 'string',
+            'pattern': r'^[0-9]+\.?[0-9]*$',
+        },
+        'cdquo': {
+            'description': 'Code du quotient (depuis référentiel)',
+            'type': 'string',
+            'pattern': '.+',
+        },
+    },
+    'additionalProperties': False,
+}
diff --git a/tests/data/toulouse_maelis/Q_create_update_quotient.xml b/tests/data/toulouse_maelis/Q_create_update_quotient.xml
new file mode 100644
index 00000000..0d519a11
--- /dev/null
+++ b/tests/data/toulouse_maelis/Q_create_update_quotient.xml
@@ -0,0 +1,23 @@
+<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
+  <soap-env:Header>
+    <wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
+      <wsse:UsernameToken>
+        <wsse:Username>maelis-webservice</wsse:Username>
+        <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">maelis-password</wsse:Password>
+      </wsse:UsernameToken>
+    </wsse:Security>
+  </soap-env:Header>
+  <soap-env:Body>
+    <ns0:createUpdateQuotient xmlns:ns0="family.ws.maelis.sigec.com">
+      <dossierNumber>1312</dossierNumber>
+      <personNumber>613878</personNumber>
+      <quotient>
+        <yearRev>2021</yearRev>
+        <dateStart>2022-10-01</dateStart>
+        <dateEnd>2023-01-31</dateEnd>
+        <mtt>1500.33</mtt>
+        <cdquo>QS</cdquo>
+      </quotient>
+    </ns0:createUpdateQuotient>
+  </soap-env:Body>
+</soap-env:Envelope>
diff --git a/tests/data/toulouse_maelis/R_create_update_quotient.xml b/tests/data/toulouse_maelis/R_create_update_quotient.xml
new file mode 100644
index 00000000..76428f17
--- /dev/null
+++ b/tests/data/toulouse_maelis/R_create_update_quotient.xml
@@ -0,0 +1,5 @@
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+  <soap:Body>
+    <ns2:createUpdateQuotientResponse xmlns:ns2="family.ws.maelis.sigec.com"/>
+  </soap:Body>
+</soap:Envelope>
diff --git a/tests/data/toulouse_maelis/R_create_update_quotient_soap_error.xml b/tests/data/toulouse_maelis/R_create_update_quotient_soap_error.xml
new file mode 100644
index 00000000..1e86f858
--- /dev/null
+++ b/tests/data/toulouse_maelis/R_create_update_quotient_soap_error.xml
@@ -0,0 +1,13 @@
+<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
+  <soap:Body>
+    <soap:Fault>
+      <faultcode>soap:Server</faultcode>
+      <faultstring>E07 : Il existe d&#233;j&#224; un quotient post&#233;rieur pour cette p&#233;riode</faultstring>
+      <detail>
+        <ns1:MaelisFamilyException xmlns:ns1="family.ws.maelis.sigec.com">
+          <message xmlns:ns2="family.ws.maelis.sigec.com">E07 : Il existe d&#233;j&#224; un quotient post&#233;rieur pour cette p&#233;riode</message>
+        </ns1:MaelisFamilyException>
+      </detail>
+    </soap:Fault>
+  </soap:Body>
+</soap:Envelope>
diff --git a/tests/data/toulouse_maelis/R_read_family.xml b/tests/data/toulouse_maelis/R_read_family.xml
index a2ac0818..c12c5c6c 100644
--- a/tests/data/toulouse_maelis/R_read_family.xml
+++ b/tests/data/toulouse_maelis/R_read_family.xml
@@ -31,16 +31,30 @@
             <mail>djhon@example.org</mail>
             <isContactMail>true</isContactMail>
             <isContactSms>true</isContactSms>
             <isInvoicePdf>true</isInvoicePdf>
           </contact>
           <profession>
             <addressPro/>
           </profession>
+          <quotientList>
+            <yearRev>2020</yearRev>
+            <dateStart>2021-01-01T00:00:00+01:00</dateStart>
+            <dateEnd>2021-12-31T00:00:00+01:00</dateEnd>
+            <mtt>1500.33</mtt>
+            <cdquo>QS</cdquo>
+          </quotientList>
+          <quotientList>
+            <yearRev>2021</yearRev>
+            <dateStart>2022-01-01T00:00:00+01:00</dateStart>
+            <dateEnd>2022-12-31T00:00:00+01:00</dateEnd>
+            <mtt>1500.44</mtt>
+            <cdquo>MOY ECO</cdquo>
+          </quotientList>
         </RL1>
         <RL2>
           <num>613879</num>
           <lastname>DOE</lastname>
           <firstname>JANE</firstname>
           <maidenName>SMITH</maidenName>
           <quality>MERE</quality>
           <civility>MME</civility>
diff --git a/tests/data/toulouse_maelis/R_read_family_relax.xml b/tests/data/toulouse_maelis/R_read_family_relax.xml
index 0f9f1618..414b19bc 100644
--- a/tests/data/toulouse_maelis/R_read_family_relax.xml
+++ b/tests/data/toulouse_maelis/R_read_family_relax.xml
@@ -31,16 +31,30 @@
             <mail>djhon@example.org</mail>
             <isContactMail>true</isContactMail>
             <isContactSms>true</isContactSms>
             <isInvoicePdf>true</isInvoicePdf>
           </contact>
           <profession>
             <addressPro/>
           </profession>
+          <quotientList>
+            <yearRev>2020</yearRev>
+            <dateStart>2021-01-01T00:00:00+01:00</dateStart>
+            <dateEnd>2021-12-31T00:00:00+01:00</dateEnd>
+            <mtt>1500.33</mtt>
+            <cdquo>QS</cdquo>
+          </quotientList>
+          <quotientList>
+            <yearRev>2021</yearRev>
+            <dateStart>2022-01-01T00:00:00+01:00</dateStart>
+            <dateEnd>2022-12-31T00:00:00+01:00</dateEnd>
+            <mtt>1500.44</mtt>
+            <cdquo>MOY ECO</cdquo>
+          </quotientList>
         </RL1>
         <RL2>
           <num>613879</num>
           <lastname>DOE</lastname>
           <firstname>JANE</firstname>
           <civility>MME</civility>
           <birth>
             <dateBirth>1940-06-22T00:00:00+02:00</dateBirth>
diff --git a/tests/data/toulouse_maelis/R_read_family_reordered.xml b/tests/data/toulouse_maelis/R_read_family_reordered.xml
index aadfee96..5707f57f 100644
--- a/tests/data/toulouse_maelis/R_read_family_reordered.xml
+++ b/tests/data/toulouse_maelis/R_read_family_reordered.xml
@@ -31,16 +31,30 @@
             <mail>djhon@example.org</mail>
             <isContactMail>true</isContactMail>
             <isContactSms>true</isContactSms>
             <isInvoicePdf>true</isInvoicePdf>
           </contact>
           <profession>
             <addressPro/>
           </profession>
+          <quotientList>
+            <yearRev>2020</yearRev>
+            <dateStart>2021-01-01T00:00:00+01:00</dateStart>
+            <dateEnd>2021-12-31T00:00:00+01:00</dateEnd>
+            <mtt>1500.33</mtt>
+            <cdquo>QS</cdquo>
+          </quotientList>
+          <quotientList>
+            <yearRev>2021</yearRev>
+            <dateStart>2022-01-01T00:00:00+01:00</dateStart>
+            <dateEnd>2022-12-31T00:00:00+01:00</dateEnd>
+            <mtt>1500.44</mtt>
+            <cdquo>MOY ECO</cdquo>
+          </quotientList>
         </RL1>
         <RL2>
           <num>613879</num>
           <lastname>DOE</lastname>
           <firstname>JANE</firstname>
           <quality>MERE</quality>
           <civility>MME</civility>
           <birth>
diff --git a/tests/test_toulouse_maelis.py b/tests/test_toulouse_maelis.py
index 256e755a..32f5c577 100644
--- a/tests/test_toulouse_maelis.py
+++ b/tests/test_toulouse_maelis.py
@@ -63,16 +63,20 @@ IS_CHILD_EXISTS_FALSE = FakedResponse(
 )
 CREATE_FAMILY = FakedResponse(content=get_xml_file('R_create_family.xml'), status_code=200)
 CREATE_FAMILY_ERR = FakedResponse(content=get_xml_file('R_create_family_error.xml'), status_code=200)
 CREATE_CHILD = FakedResponse(content=get_xml_file('R_create_child.xml'), status_code=200)
 CREATE_CHILD_ERR = FakedResponse(content=get_xml_file('R_create_child_error.xml'), status_code=200)
 UPDATE_FAMILY = FakedResponse(content=get_xml_file('R_update_family.xml'), status_code=200)
 UPDATE_FAMILY_ERR = FakedResponse(content=get_xml_file('R_update_family_error.xml'), status_code=200)
 UPDATE_FAMILY_500 = FakedResponse(content=get_xml_file('R_update_family_soap_error.xml'), status_code=500)
+UPDATE_QUOTIENT = FakedResponse(content=get_xml_file('R_create_update_quotient.xml'), status_code=200)
+UPDATE_QUOTIENT_500 = FakedResponse(
+    content=get_xml_file('R_create_update_quotient_soap_error.xml'), status_code=500
+)
 UPDATE_DIETCODE = FakedResponse(content=get_xml_file('R_update_child_dietcode.xml'), status_code=200)
 UPDATE_PAI = FakedResponse(content=get_xml_file('R_update_child_pai.xml'), status_code=200)
 UPDATE_PAI_500 = FakedResponse(content=get_xml_file('R_update_child_pai_soap_error.xml'), status_code=500)
 UPDATE_MEDICAL = FakedResponse(content=get_xml_file('R_update_child_medical_record.xml'), status_code=200)
 UPDATE_MEDICAL_500 = FakedResponse(
     content=get_xml_file('R_update_child_medical_record_soap_error.xml'), status_code=500
 )
 UPDATE_CHILD_AUTO = FakedResponse(content=get_xml_file('R_update_child_authorization.xml'), status_code=200)
@@ -544,16 +548,17 @@ def test_read_vaccin_list(mocked_post, mocked_get, con, app):
 def test_read_family(mocked_post, mocked_get, read_family, con, app):
     mocked_get.return_value = FAMILY_SERVICE_WSDL
     mocked_post.side_effect = [
         read_family,
         READ_CATEGORIES,
         READ_SITUATIONS,
         READ_CIVILITIES,
         READ_QUALITIES,
+        READ_QUOTIENT,
         READ_CSP,
         READ_ORGAN,
         READ_DIETCODE,
         READ_PAI,
     ]
     url = get_endpoint('read-family')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
@@ -608,17 +613,36 @@ def test_read_family(mocked_post, mocked_get, read_family, con, app):
             'mail': 'djhon@example.org',
             'isContactMail': True,
             'isContactSms': True,
             'isInvoicePdf': True,
         },
         'CAFInfo': None,
         'civility_text': 'Monsieur',
         'quality_text': 'PERE',
-        'quotientList': [],
+        'quotientList': [
+            {
+                'cdquo': 'QS',
+                'cdquo_text': 'QUOTIENT SCOLAIRE',
+                'codeUti': None,
+                'dateEnd': '2021-12-31T00:00:00+01:00',
+                'dateStart': '2021-01-01T00:00:00+01:00',
+                'mtt': 1500.33,
+                'yearRev': 2020,
+            },
+            {
+                'cdquo': 'MOY ECO',
+                'cdquo_text': 'REVENU MOYEN ( MENSUEL OU ANNUEL)',
+                'codeUti': None,
+                'dateEnd': '2022-12-31T00:00:00+01:00',
+                'dateStart': '2022-01-01T00:00:00+01:00',
+                'mtt': 1500.44,
+                'yearRev': 2021,
+            },
+        ],
         'indicatorList': [],
         'subscribeActivityList': [],
     }
     data = resp.json['data']['childList'][0]
     del data['medicalRecord']
     del data['authorizedPersonList']
     del data['paiInfoBean']
     assert data == {
@@ -736,16 +760,17 @@ def test_read_family_not_linked_error(con, app):
 @mock.patch('passerelle.utils.Request.post')
 def test_read_rl1(mocked_post, mocked_get, con, app):
     mocked_get.return_value = FAMILY_SERVICE_WSDL
     mocked_post.side_effect = [
         READ_FAMILY,
         READ_CIVILITIES,
         READ_QUALITIES,
         READ_CSP,
+        READ_QUOTIENT,
     ]
     url = get_endpoint('read-rl')
     Link.objects.create(resource=con, family_id='1312', name_id='local')
 
     resp = app.get(url + '?NameID=local&rl_id=613878')
     assert resp.json['err'] == 0
     assert resp.json['data']['firstname'] == 'JHON'
 
@@ -2116,16 +2141,97 @@ def test_update_coordinate_wrong_referential_key_error(mocked_post, mocked_get,
     Link.objects.create(resource=con, family_id='1312', name_id='local')
     resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params)
     assert resp.json['err'] == 'wrong-key'
     assert (
         resp.json['err_desc'] == "adresse/numComp key value 'plop' do not belong to 'Complement' referential"
     )
 
 
+@mock.patch('passerelle.utils.Request.get')
+@mock.patch('passerelle.utils.Request.post')
+def test_update_quotient(mocked_post, mocked_get, con, app):
+    mocked_get.return_value = FAMILY_SERVICE_WSDL
+    mocked_post.side_effect = [READ_QUOTIENT, UPDATE_QUOTIENT]
+    url = get_endpoint('update-quotient')
+    params = {
+        'yearRev': '2021',
+        'dateStart': '2022-10-01',
+        'dateEnd': '2023-01-31',
+        'mtt': '1500.33',
+        'cdquo': 'QS',
+    }
+
+    Link.objects.create(resource=con, family_id='1312', name_id='local')
+    resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params)
+    assert_sent_payload(mocked_post, 'Q_create_update_quotient.xml')
+    assert resp.json['err'] == 0
+    assert resp.json['data'] == 'ok'
+
+
+@mock.patch('passerelle.utils.Request.get')
+@mock.patch('passerelle.utils.Request.post')
+def test_update_quotient_schema_error(mocked_post, mocked_get, con, app):
+    mocked_get.return_value = FAMILY_SERVICE_WSDL
+    mocked_post.side_effect = [READ_QUOTIENT, UPDATE_QUOTIENT]
+    url = get_endpoint('update-quotient')
+    params = {
+        'yearRev': '2021',
+        'dateStart': '2022-10-01',
+        'dateEnd': '2023-01-31',
+        'mtt': '1500,33',
+        'cdquo': 'QS',
+    }
+
+    Link.objects.create(resource=con, family_id='1312', name_id='local')
+    resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params, status=400)
+    assert resp.json['err'] == 1
+    assert resp.json['err_desc'] == "mtt: '1500,33' does not match '^[0-9]+\\\\.?[0-9]*$'"
+
+
+@mock.patch('passerelle.utils.Request.get')
+@mock.patch('passerelle.utils.Request.post')
+def test_update_quotient_soap_error(mocked_post, mocked_get, con, app):
+    mocked_get.return_value = FAMILY_SERVICE_WSDL
+    mocked_post.side_effect = [READ_QUOTIENT, UPDATE_QUOTIENT_500]
+    url = get_endpoint('update-quotient')
+    params = {
+        'yearRev': '2021',
+        'dateStart': '2022-10-01',
+        'dateEnd': '2023-01-31',
+        'mtt': '1500.33',
+        'cdquo': 'QS',
+    }
+
+    Link.objects.create(resource=con, family_id='1312', name_id='local')
+    resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params)
+    assert resp.json['err'] == 'Family-createUpdateQuotient-soap:Server'
+    assert 'E07 : Il existe déjà un quotient postérieur' in resp.json['err_desc']
+
+
+@mock.patch('passerelle.utils.Request.get')
+@mock.patch('passerelle.utils.Request.post')
+def test_update_quotient_wrong_referential_key_error(mocked_post, mocked_get, con, app):
+    mocked_get.return_value = FAMILY_SERVICE_WSDL
+    mocked_post.return_value = READ_QUOTIENT
+    url = get_endpoint('update-quotient')
+    params = {
+        'yearRev': '2021',
+        'dateStart': '2023-10-01',
+        'dateEnd': '2023-01-31',
+        'mtt': '1500.33',
+        'cdquo': 'plop',
+    }
+
+    Link.objects.create(resource=con, family_id='1312', name_id='local')
+    resp = app.post_json(url + '?NameID=local&rl_id=613878', params=params)
+    assert resp.json['err'] == 'wrong-key'
+    assert resp.json['err_desc'] == "cdquo key value 'plop' do not belong to 'Quotient' required referential"
+
+
 @mock.patch('passerelle.utils.Request.get')
 @mock.patch('passerelle.utils.Request.post')
 def test_create_person(mocked_post, mocked_get, con, app):
     mocked_get.return_value = FAMILY_SERVICE_WSDL
     mocked_post.side_effect = [READ_FAMILY, READ_QUALITIES, UPDATE_FAMILY]
     url = get_endpoint('create-person')
     params = {
         'civility': None,
-- 
2.30.2

