Projet

Général

Profil

0002-toulouse_axel-invoice-history-39028.patch

Lauréline Guérin, 20 janvier 2020 15:57

Télécharger (22,1 ko)

Voir les différences:

Subject: [PATCH 2/2] toulouse_axel: invoice history (#39028)

 passerelle/contrib/toulouse_axel/models.py    |  77 +++++++--
 .../Dui/Q_ListeDuiFacturesPayeesRecettees.xsd |  18 ++
 .../Dui/R_ListeDuiFacturesPayeesRecettees.xsd |  95 +++++++++++
 tests/data/toulouse_axel/invoices_history.xml |  35 ++++
 tests/test_toulouse_axel.py                   | 159 +++++++++++++++++-
 5 files changed, 370 insertions(+), 14 deletions(-)
 create mode 100644 passerelle/contrib/toulouse_axel/xsd/Dui/Q_ListeDuiFacturesPayeesRecettees.xsd
 create mode 100644 passerelle/contrib/toulouse_axel/xsd/Dui/R_ListeDuiFacturesPayeesRecettees.xsd
 create mode 100644 tests/data/toulouse_axel/invoices_history.xml
passerelle/contrib/toulouse_axel/models.py
210 210

  
211 211

  
212 212
class Operation(object):
213
    def __init__(self, operation, prefix='Dui/'):
213
    def __init__(self, operation, prefix='Dui/', request_root_element='PORTAIL'):
214 214
        self.operation = operation
215
        self.request_converter = xml_schema_converter('%sQ_%s.xsd' % (prefix, operation), 'PORTAIL')
215
        self.request_converter = xml_schema_converter('%sQ_%s.xsd' % (prefix, operation), request_root_element)
216 216
        self.response_converter = xml_schema_converter('%sR_%s.xsd' % (prefix, operation), 'PORTAILSERVICE')
217 217
        self.name = re.sub(
218 218
            '(.?)([A-Z])',
......
280 280
form_paiement_dui = Operation('FormPaiementDui')
281 281
ref_facture_a_payer = Operation('RefFactureAPayer')
282 282
ref_facture_pdf = Operation('RefFacturePDF', prefix='')
283
list_dui_factures = Operation('ListeDuiFacturesPayeesRecettees', request_root_element='LISTFACTURE')
283 284

  
284 285

  
285 286
class ToulouseAxel(BaseResource):
......
753 754
            }
754 755
        }
755 756

  
756
    def normalize_invoice(self, invoice, dui):
757
    def normalize_invoice(self, invoice, dui, historical=False):
757 758
        invoice_id = '%s-%s' % (dui, invoice['IDFACTURE'])
758 759
        data = {
759 760
            'id': invoice_id,
760 761
            'display_id': str(invoice['IDFACTURE']),
761 762
            'label': invoice['LIBELLE'],
762
            'amount': invoice['RESTEAPAYER'],
763
            'total_amount': invoice['MONTANTTOTAL'],
764
            'created': invoice['DATEEMISSION'],
765
            'pay_limit_date': invoice['DATEECHEANCE'],
766
            'has_pdf': True if invoice['EXISTEPDF'] == '1' else False,
767 763
            'paid': False,
768 764
            'vendor': {'toulouse-axel': invoice},
769 765
        }
770
        pay_limit_date = datetime.datetime.strptime(invoice['DATEECHEANCE'], '%Y-%m-%d').date()
771
        data['online_payment'] = data['amount'] > 0 and pay_limit_date >= datetime.date.today()
766
        if historical:
767
            data.update({
768
                'amount': 0,
769
                'total_amount': invoice['MONTANT'],
770
                'created': invoice['EMISSION'],
771
                'pay_limit_date': '',
772
                'online_payment': False,
773
                'has_pdf': True if invoice['IPDF'] == '1' else False,
774
            })
775
        else:
776
            data.update({
777
                'amount': invoice['RESTEAPAYER'],
778
                'total_amount': invoice['MONTANTTOTAL'],
779
                'created': invoice['DATEEMISSION'],
780
                'pay_limit_date': invoice['DATEECHEANCE'],
781
                'has_pdf': True if invoice['EXISTEPDF'] == '1' else False,
782
            })
783
            pay_limit_date = datetime.datetime.strptime(invoice['DATEECHEANCE'], '%Y-%m-%d').date()
784
            data['online_payment'] = data['amount'] > 0 and pay_limit_date >= datetime.date.today()
772 785
        return data
773 786

  
774 787
    def get_invoices(self, regie_id, dui=None, name_id=None):
......
793 806
            result.append(self.normalize_invoice(facture, dui))
794 807
        return result
795 808

  
809
    def get_historical_invoices(self, name_id):
810
        link = self.get_link(name_id)
811
        try:
812
            result = list_dui_factures(
813
                self,
814
                {'LISTFACTURE': {'NUMDUI': link.dui, 'DEBUT': '1970-01-01'}})
815
        except AxelError as e:
816
            raise APIError(
817
                'Axel error: %s' % e,
818
                err_code='error',
819
                data={'xml_request': e.xml_request,
820
                      'xml_response': e.xml_response})
821

  
822
        data = result.json_response['DATA']['PORTAIL']['LISTFACTURE']
823
        result = []
824
        for direction in data.get('DIRECTION', []):
825
            for facture in direction.get('FACTURE', []):
826
                result.append(self.normalize_invoice(facture, link.dui, historical=True))
827
        return result
828

  
796 829
    def get_invoice(self, regie_id, invoice_id, dui=None, name_id=None):
797 830
        invoices_data = self.get_invoices(regie_id=regie_id, dui=dui, name_id=name_id)
798 831
        for invoice in invoices_data:
799 832
            if invoice['display_id'] == invoice_id:
800 833
                return invoice
801 834

  
835
    def get_historical_invoice(self, invoice_id, name_id):
836
        invoices_data = self.get_historical_invoices(name_id=name_id)
837
        for invoice in invoices_data:
838
            if invoice['display_id'] == invoice_id:
839
                return invoice
840

  
802 841
    @endpoint(
803 842
        name='regie',
804 843
        perm='can_access',
......
813 852
        invoices_data = self.get_invoices(regie_id=regie_id, name_id=NameID)
814 853
        return {'data': invoices_data}
815 854

  
855
    @endpoint(
856
        name='regie',
857
        perm='can_access',
858
        pattern=r'^(?P<regie_id>[\w-]+)/invoices/history/?$',
859
        example_pattern='{regie_id}/invoices/history/',
860
        description=_("Get invoices already paid"),
861
        parameters={
862
            'NameID': {'description': _('Publik ID')},
863
            'regie_id': {'description': _('Regie identifier'), 'example_value': '42-PERISCOL'}
864
        })
865
    def invoices_history(self, request, regie_id, NameID):
866
        invoices_data = self.get_historical_invoices(name_id=NameID)
867
        return {'data': invoices_data}
868

  
816 869
    @endpoint(
817 870
        name='regie',
818 871
        perm='can_access',
......
827 880
    def invoice(self, request, regie_id, invoice_id, NameID):
828 881
        invoice_id = invoice_id.split('-')[1]
829 882
        invoice = self.get_invoice(regie_id=regie_id, name_id=NameID, invoice_id=invoice_id)
883
        if invoice is None:
884
            invoice = self.get_historical_invoice(name_id=NameID, invoice_id=invoice_id)
830 885
        if invoice is None:
831 886
            raise APIError('Invoice not found', err_code='not-found')
832 887

  
......
848 903
        invoice_id = invoice_id.split('-')[1]
849 904
        try:
850 905
            invoice = self.get_invoice(regie_id=regie_id, name_id=NameID, invoice_id=invoice_id)
906
            if invoice is None:
907
                invoice = self.get_historical_invoice(name_id=NameID, invoice_id=invoice_id)
851 908
        except APIError as e:
852 909
            e.http_status = 404
853 910
            raise
passerelle/contrib/toulouse_axel/xsd/Dui/Q_ListeDuiFacturesPayeesRecettees.xsd
1
<?xml version="1.0" encoding="utf-8" ?>
2
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:all="urn:AllAxelTypes">
3
	
4
	<xsd:import schemaLocation="../AllAxelTypes.xsd" namespace="urn:AllAxelTypes"  />
5
	
6
	<xsd:complexType name="listefacture">
7
		<xsd:all>
8
			<xsd:element ref="NUMDUI" minOccurs="1" maxOccurs="1"/>
9
			<xsd:element ref="DEBUT" minOccurs="1" maxOccurs="1"/>
10
		</xsd:all> 
11
	</xsd:complexType>
12
	
13
	<xsd:element name="DEBUT" type="all:DATEREQUIREDType"/>
14
	<xsd:element name="NUMDUI" type="all:IDENTREQUIREDType"/>
15
	
16
	<xsd:element name="LISTFACTURE" type="listefacture"/>	
17
		
18
</xsd:schema>
passerelle/contrib/toulouse_axel/xsd/Dui/R_ListeDuiFacturesPayeesRecettees.xsd
1
<?xml version="1.0" encoding="utf-8" ?>
2
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
3
	xmlns:all="urn:AllAxelTypes">
4

  
5
	<xsd:import schemaLocation="../AllAxelTypes.xsd" namespace="urn:AllAxelTypes" />
6

  
7
	<xsd:redefine schemaLocation="../R_ShemaResultat.xsd">
8
		<xsd:simpleType name="TYPEType">
9
			<xsd:restriction base="TYPEType">
10
				<xsd:enumeration value="ListeDuiFacturesPayeesRecettees" />
11
			</xsd:restriction>
12
		</xsd:simpleType>
13

  
14
		<xsd:complexType name="PORTAILType">
15
			<xsd:complexContent>
16
				<xsd:extension base="PORTAILType">
17
					<xsd:sequence>
18
						<xsd:element ref="LISTFACTURE" minOccurs="0"
19
							maxOccurs="1" />
20
					</xsd:sequence>
21
				</xsd:extension>
22
			</xsd:complexContent>
23
		</xsd:complexType>
24
	</xsd:redefine>
25

  
26
	<xsd:complexType name="listfacture">
27
		<xsd:sequence>
28
			<xsd:element ref="NBFACTURERESTANTE" />
29
			<xsd:element ref="DIRECTION" minOccurs="0" maxOccurs="unbounded" />
30
		</xsd:sequence>
31
	</xsd:complexType>
32
	
33
	<xsd:complexType name="direction">
34
		<xsd:sequence>
35
			<xsd:element ref="NUMDIRECTION" />
36
			<xsd:element ref="IDDIRECTION" />
37
			<xsd:element ref="LIBDIRECTION" />
38
			<xsd:element ref="FACTURE" minOccurs="0" maxOccurs="unbounded" />
39
		</xsd:sequence>
40
	</xsd:complexType>
41

  
42
	<xsd:complexType name="facture">
43
		<xsd:sequence>
44
			<xsd:element ref="IDAXEL" />
45
			<xsd:element ref="IDFAMILLE" />
46
			<xsd:element ref="EMISSION" />
47
			<xsd:element ref="MONTANT" />
48
			<xsd:element ref="IDFACTURE" />
49
			<xsd:element ref="NOFACTURE" />
50
			<xsd:element ref="LIBELLE" />
51
			<xsd:element ref="IPDF" />
52
		</xsd:sequence>
53
	</xsd:complexType>
54

  
55
	<xsd:simpleType name="idaxel">
56
		<xsd:restriction base="xsd:string">
57
			<xsd:pattern value="AXEL" />
58
		</xsd:restriction>
59
	</xsd:simpleType>
60

  
61
	<xsd:simpleType name="libelle">
62
		<xsd:restriction base="xsd:string">
63
			<xsd:minLength value="1" />
64
			<xsd:maxLength value="50" />
65
		</xsd:restriction>
66
	</xsd:simpleType>
67

  
68

  
69
	<xsd:simpleType name="positiveInteger" id="positiveInteger">
70
		<xsd:restriction base="xsd:nonNegativeInteger">
71
			<xsd:minInclusive value="0" />
72
		</xsd:restriction>
73
	</xsd:simpleType>
74

  
75
	<xsd:element name="NUMDIRECTION" type="xsd:nonNegativeInteger" />
76
	<xsd:element name="IDDIRECTION" type="all:IDREQUIREDType" />
77
	<xsd:element name="LIBDIRECTION" type="all:NOMREQUIREDType" />
78
	
79
	<xsd:element name="IDAXEL" type="idaxel" />
80
	<xsd:element name="IDFAMILLE" type="all:IDENTREQUIREDType" />
81
	<xsd:element name="EMISSION" type="all:DATEREQUIREDType" />
82
	<xsd:element name="MONTANT" type="xsd:decimal" />
83
	<xsd:element name="IDFACTURE" type="xsd:positiveInteger" />
84
	<xsd:element name="NOFACTURE" type="xsd:positiveInteger" />
85
	<xsd:element name="LIBELLE" type="libelle" />
86
	<xsd:element name="IPDF" type="all:ONType" />
87
	<xsd:element name="NBFACTURERESTANTE" type="positiveInteger" />
88

  
89
	<xsd:element name="DIRECTION" type="direction" />
90
	<xsd:element name="FACTURE" type="facture" />
91
	<xsd:element name="LISTFACTURE" type="listfacture" />
92
	
93
</xsd:schema>
94

  
95

  
tests/data/toulouse_axel/invoices_history.xml
1
<PORTAIL>
2
  <LISTFACTURE>
3
    <NBFACTURERESTANTE>0</NBFACTURERESTANTE>
4
    <DIRECTION>
5
      <NUMDIRECTION>10</NUMDIRECTION>
6
      <IDDIRECTION>DIR-A</IDDIRECTION>
7
      <LIBDIRECTION>DIRECTION A</LIBDIRECTION>
8
      <FACTURE>
9
        <IDAXEL>AXEL</IDAXEL>
10
        <IDFAMILLE>XXX</IDFAMILLE>
11
        <EMISSION>23/03/2017</EMISSION>
12
        <MONTANT>28.98</MONTANT>
13
        <IDFACTURE>42</IDFACTURE>
14
        <NOFACTURE>42</NOFACTURE>
15
        <LIBELLE>PRESTATIONS SEPTEMBRE 2015</LIBELLE>
16
        <IPDF>O</IPDF>
17
      </FACTURE>
18
    </DIRECTION>
19
    <DIRECTION>
20
      <NUMDIRECTION>11</NUMDIRECTION>
21
      <IDDIRECTION>DIR-B</IDDIRECTION>
22
      <LIBDIRECTION>DIRECTION B</LIBDIRECTION>
23
      <FACTURE>
24
        <IDAXEL>AXEL</IDAXEL>
25
        <IDFAMILLE>XXX</IDFAMILLE>
26
        <EMISSION>23/03/2017</EMISSION>
27
        <MONTANT>28.98</MONTANT>
28
        <IDFACTURE>43</IDFACTURE>
29
        <NOFACTURE>43</NOFACTURE>
30
        <LIBELLE>PRESTATIONS OCTOBRE 2015</LIBELLE>
31
        <IPDF>O</IPDF>
32
      </FACTURE>
33
    </DIRECTION>
34
</LISTFACTURE>
35
</PORTAIL>
tests/test_toulouse_axel.py
34 34
    ToulouseAxel,
35 35
    form_maj_famille_dui,
36 36
    form_paiement_dui,
37
    list_dui_factures,
37 38
    ref_date_gestion_dui,
38 39
    ref_famille_dui,
39 40
    ref_facture_a_payer,
......
314 315
            })
315 316

  
316 317

  
318
@pytest.mark.parametrize('content', [
319
    '<PORTAIL><LISTFACTURE/></PORTAIL>',
320
])
321
def test_operation_list_dui_factures(resource, content):
322
    with mock_getdata(content, 'ListeDuiFacturesPayeesRecettees'):
323
        with pytest.raises(AxelError):
324
            list_dui_factures(resource, {
325
                'LISTFACTURE': {
326
                    'NUMDUI': 'XXX',
327
                    'DEBUT': '1970-01-01'
328
                }
329
            })
330

  
331

  
317 332
@pytest.mark.parametrize('content', [
318 333
    "<PORTAIL><PDF FOO='BAR'></PDF></PORTAIL>",
319 334
])
......
1337 1352
    ]
1338 1353

  
1339 1354

  
1355
def test_invoices_history_endpoint_axel_error(app, resource):
1356
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
1357
    with mock.patch('passerelle.contrib.toulouse_axel.models.list_dui_factures') as operation:
1358
        operation.side_effect = AxelError('FooBar')
1359
        resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoices/history?NameID=yyy')
1360
    assert resp.json['err_desc'] == "Axel error: FooBar"
1361
    assert resp.json['err'] == 'error'
1362

  
1363

  
1364
def test_invoices_history_endpoint_no_result(app, resource):
1365
    resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoices/history?NameID=yyy')
1366
    assert resp.json['err_desc'] == "Person not found"
1367
    assert resp.json['err'] == 'not-found'
1368

  
1369

  
1370
def test_invoices_history_endpoint_no_invoices(app, resource):
1371
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
1372
    content = '''<PORTAIL>
1373
    <LISTFACTURE>
1374
        <NBFACTURERESTANTE>0</NBFACTURERESTANTE>
1375
    </LISTFACTURE>
1376
</PORTAIL>'''
1377
    with mock_getdata(content, 'ListeDuiFacturesPayeesRecettees'):
1378
        resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoices/history?NameID=yyy')
1379
    assert resp.json['err'] == 0
1380
    assert resp.json['data'] == []
1381

  
1382

  
1383
def test_invoices_history_endpoint(app, resource):
1384
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
1385
    filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/invoices_history.xml')
1386
    with open(filepath) as xml:
1387
        content = xml.read()
1388
    with mock_getdata(content, 'ListeDuiFacturesPayeesRecettees'):
1389
        resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoices/history?NameID=yyy')
1390
    assert resp.json['err'] == 0
1391
    assert resp.json['data'] == [
1392
        {
1393
            'amount': 0,
1394
            'created': '2017-03-23',
1395
            'display_id': '42',
1396
            'has_pdf': False,
1397
            'id': 'XXX-42',
1398
            'label': 'PRESTATIONS SEPTEMBRE 2015',
1399
            'online_payment': False,
1400
            'paid': False,
1401
            'pay_limit_date': '',
1402
            'total_amount': '28.98',
1403
            'vendor': {
1404
                'toulouse-axel': {
1405
                    'EMISSION': '2017-03-23',
1406
                    'IDAXEL': 'AXEL',
1407
                    'IDFACTURE': 42,
1408
                    'IDFAMILLE': 'XXX',
1409
                    'IPDF': 'O',
1410
                    'LIBELLE': 'PRESTATIONS SEPTEMBRE 2015',
1411
                    'MONTANT': '28.98',
1412
                    'NOFACTURE': 42
1413
                }
1414
            }
1415
        },
1416
        {
1417
            'amount': 0,
1418
            'created': '2017-03-23',
1419
            'display_id': '43',
1420
            'has_pdf': False,
1421
            'id': 'XXX-43',
1422
            'label': 'PRESTATIONS OCTOBRE 2015',
1423
            'online_payment': False,
1424
            'paid': False,
1425
            'pay_limit_date': '',
1426
            'total_amount': '28.98',
1427
            'vendor': {
1428
                'toulouse-axel': {
1429
                    'EMISSION': '2017-03-23',
1430
                    'IDAXEL': 'AXEL',
1431
                    'IDFACTURE': 43,
1432
                    'IDFAMILLE': 'XXX',
1433
                    'IPDF': 'O',
1434
                    'LIBELLE': 'PRESTATIONS OCTOBRE 2015',
1435
                    'MONTANT': '28.98',
1436
                    'NOFACTURE': 43
1437
                }
1438
            }
1439
        }
1440
    ]
1441

  
1442

  
1340 1443
def test_invoice_endpoint_axel_error(app, resource):
1341 1444
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
1342 1445
    with mock.patch('passerelle.contrib.toulouse_axel.models.ref_facture_a_payer') as operation:
......
1356 1459
    with open(filepath) as xml:
1357 1460
        content = xml.read()
1358 1461
    with mock_getdata(content, 'RefFactureAPayer'):
1359
        resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-35?NameID=yyy')
1462
        with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_historical_invoice') as invoice:
1463
            invoice.return_value = None
1464
            resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-35?NameID=yyy')
1360 1465
    assert resp.json['err_desc'] == "Invoice not found"
1361 1466
    assert resp.json['err'] == 'not-found'
1362 1467
    with mock_getdata(content, 'RefFactureAPayer'):
1363
        resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-44?NameID=yyy')
1468
        with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_historical_invoice') as invoice:
1469
            invoice.return_value = None
1470
            resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-44?NameID=yyy')
1364 1471
    assert resp.json['err_desc'] == "Invoice not found"
1365 1472
    assert resp.json['err'] == 'not-found'
1366 1473

  
......
1400 1507
        }
1401 1508
    }
1402 1509

  
1510
    filepath = os.path.join(os.path.dirname(__file__), 'data/toulouse_axel/invoices_history.xml')
1511
    with open(filepath) as xml:
1512
        content = xml.read()
1513
    with mock_getdata(content, 'ListeDuiFacturesPayeesRecettees'):
1514
        with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_invoice') as invoice:
1515
            invoice.return_value = None
1516
            resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-42?NameID=yyy')
1517
    assert resp.json['err'] == 0
1518
    assert resp.json['data'] == {
1519
        'amount': 0,
1520
        'created': '2017-03-23',
1521
        'display_id': '42',
1522
        'has_pdf': False,
1523
        'id': 'XXX-42',
1524
        'label': 'PRESTATIONS SEPTEMBRE 2015',
1525
        'online_payment': False,
1526
        'paid': False,
1527
        'pay_limit_date': '',
1528
        'total_amount': '28.98',
1529
        'vendor': {
1530
            'toulouse-axel': {
1531
                'EMISSION': '2017-03-23',
1532
                'IDAXEL': 'AXEL',
1533
                'IDFACTURE': 42,
1534
                'IDFAMILLE': 'XXX',
1535
                'IPDF': 'O',
1536
                'LIBELLE': 'PRESTATIONS SEPTEMBRE 2015',
1537
                'MONTANT': '28.98',
1538
                'NOFACTURE': 42
1539
            }
1540
        }
1541
    }
1542

  
1403 1543

  
1404 1544
def test_invoice_pdf_endpoint_axel_error(app, resource):
1405 1545
    Link.objects.create(resource=resource, name_id='yyy', dui='XXX', person_id='42')
......
1430 1570
    with open(filepath) as xml:
1431 1571
        content = xml.read()
1432 1572
    with mock_getdata(content, 'RefFactureAPayer'):
1433
        resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-35/pdf?NameID=yyy', status=404)
1573
        with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_historical_invoice') as invoice:
1574
            invoice.return_value = None
1575
            resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-35/pdf?NameID=yyy', status=404)
1434 1576
    assert resp.json['err_desc'] == "Invoice not found"
1435 1577
    assert resp.json['err'] == 'not-found'
1436 1578

  
1437 1579
    with mock_getdata(content, 'RefFactureAPayer'):
1438
        resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-44/pdf?NameID=yyy', status=404)
1580
        with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_historical_invoice') as invoice:
1581
            invoice.return_value = None
1582
            resp = app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-44/pdf?NameID=yyy', status=404)
1439 1583
    assert resp.json['err_desc'] == "Invoice not found"
1440 1584
    assert resp.json['err'] == 'not-found'
1441 1585

  
......
1465 1609
        with mock_getdata(pdf_content, 'RefFacturePDF'):
1466 1610
            app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-42/pdf?NameID=yyy')
1467 1611

  
1612
    with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_invoice') as invoice:
1613
        with mock.patch('passerelle.contrib.toulouse_axel.models.ToulouseAxel.get_historical_invoice') as historical_invoice:
1614
            invoice.return_value = None
1615
            historical_invoice.return_value = {'has_pdf': True, 'display_id': '42'}
1616
            with mock_getdata(pdf_content, 'RefFacturePDF'):
1617
                app.get('/toulouse-axel/test/regie/MAREGIE/invoice/XXX-42/pdf?NameID=yyy')
1618

  
1468 1619

  
1469 1620
def test_pay_invoice_endpoint_axel_error(app, resource):
1470 1621
    payload = {
1471
-