0001-nanterre-permettre-de-payer-plusieurs-factures-fixes.patch
tests/test_nanterre_saga.py | ||
---|---|---|
23 | 23 |
elt.attrib['xmlns'] = 'ns' |
24 | 24 |
sub = ET.SubElement(elt, node) |
25 | 25 |
sub.text = content |
26 |
print ET.tostring(elt) |
|
27 | 26 |
return ET.tostring(elt) |
28 | 27 | |
29 | 28 |
f['jean'].content['cles_de_federation']['technocarte'] = '1234' |
... | ... | |
54 | 53 |
<factures> |
55 | 54 |
<facture date_facture="10/10/2017" date_limite_recouvrement="20/10/2017" |
56 | 55 |
etat="en cours" incident_paiement="paiement" montant_initial="10.00" |
57 |
reste_a_payer="0.0" num="34">
|
|
56 |
reste_a_payer="1.0" num="34">
|
|
58 | 57 |
<creances> |
59 | 58 |
<creance imputation="1234" montant="1.2" libelle="PISCINE" num_creance="123"/> |
60 | 59 |
</creances> |
61 | 60 |
</facture> |
61 |
<facture date_facture="10/10/2017" date_limite_recouvrement="20/10/2017" |
|
62 |
etat="en cours" incident_paiement="paiement" montant_initial="10.00" |
|
63 |
reste_a_payer="2.0" num="35"> |
|
64 |
<creances> |
|
65 |
<creance imputation="1234" montant="3.2" libelle="PISCINE" num_creance="123"/> |
|
66 |
</creances> |
|
67 |
</facture> |
|
62 | 68 |
</factures>''') |
63 | 69 |
elif 'Transaction' in request.body: |
64 | 70 |
return xml_literal('TransactionReturn', |
... | ... | |
77 | 83 |
'identifier': f['jean'].id, |
78 | 84 |
})) |
79 | 85 |
assert response.json['err'] == 0 |
80 |
assert len(response.json['data']) == 1
|
|
86 |
assert len(response.json['data']) == 2
|
|
81 | 87 |
num = response.json['data'][0]['num'] |
88 |
num2 = response.json['data'][1]['num'] |
|
82 | 89 | |
83 | 90 |
response = app.post_json( |
84 | 91 |
reverse('rsu-api-saga-transaction', kwargs={ |
85 | 92 |
'identifier': f['jean'].id, |
86 | 93 |
}), |
87 | 94 |
params={ |
88 |
'num_facture': num,
|
|
95 |
'num_factures': [num, num2],
|
|
89 | 96 |
'urlretour_asynchrone': 'http://async.example.com/coin', |
90 | 97 |
'urlretour_synchrone': 'http://async.example.com/coin', |
91 | 98 |
'email': 'john.doe@example.com', |
zoo/zoo_nanterre/api_views.py | ||
---|---|---|
1418 | 1418 | |
1419 | 1419 | |
1420 | 1420 |
class TransactionSagaSerializer(serializers.Serializer): |
1421 |
num_facture = serializers.CharField()
|
|
1421 |
num_factures = serializers.ListField(child=serializers.CharField())
|
|
1422 | 1422 |
urlretour_asynchrone = serializers.URLField() |
1423 | 1423 |
urlretour_synchrone = serializers.URLField() |
1424 | 1424 |
email = serializers.EmailField(required=False) |
... | ... | |
1426 | 1426 | |
1427 | 1427 |
class SagaTransaction(SagaFactures): |
1428 | 1428 |
def post(self, request, identifier, format=None): |
1429 |
factures, error_response = self.get_factures(identifier) |
|
1430 | ||
1431 |
if error_response: |
|
1432 |
return error_response |
|
1433 | ||
1434 | 1429 |
serializer = TransactionSagaSerializer(data=request.data) |
1435 | 1430 |
if not serializer.is_valid(): |
1436 | 1431 |
return Response({ |
... | ... | |
1438 | 1433 |
'errors': flatten_errors(serializer.errors), |
1439 | 1434 |
}, status=400) |
1440 | 1435 | |
1436 |
data = serializer.validated_data |
|
1437 | ||
1438 |
factures, error_response = self.get_factures(identifier) |
|
1439 | ||
1440 |
if error_response: |
|
1441 |
return error_response |
|
1442 | ||
1443 |
factures_a_payer = [] |
|
1444 | ||
1441 | 1445 |
for facture in factures: |
1442 |
if facture.num == serializer.validated_data['num_facture']:
|
|
1443 |
break
|
|
1444 |
else:
|
|
1446 |
if facture.num in data['num_factures']:
|
|
1447 |
factures_a_payer.append(facture)
|
|
1448 |
if not factures_a_payer:
|
|
1445 | 1449 |
return Response({ |
1446 | 1450 |
'err': 1, |
1447 | 1451 |
'errors': [ |
1448 |
'numéro de facture inconnu',
|
|
1452 |
u'numéro(s) de facture inconnu',
|
|
1449 | 1453 |
] |
1450 | 1454 |
}) |
1451 | 1455 | |
1452 | 1456 |
data = serializer.validated_data |
1453 | 1457 |
email = data.get('email') or self.individu.content['email'] or '' |
1454 | 1458 |
url, error = self.ws.transaction( |
1455 |
facture=facture,
|
|
1459 |
factures=factures_a_payer,
|
|
1456 | 1460 |
urlretour_asynchrone=data['urlretour_asynchrone'], |
1457 | 1461 |
urlretour_synchrone=data['urlretour_synchrone'], |
1458 | 1462 |
email=email) |
zoo/zoo_nanterre/saga.py | ||
---|---|---|
149 | 149 |
yield facture |
150 | 150 |
return list(helper()), None |
151 | 151 | |
152 |
def transaction(self, facture, urlretour_asynchrone, urlretour_synchrone, email): |
|
152 |
def transaction(self, factures, urlretour_asynchrone, urlretour_synchrone, email):
|
|
153 | 153 |
body = ''' |
154 | 154 |
<Transaction> |
155 | 155 |
<num_service>{num_service}</num_service> |
... | ... | |
159 | 159 |
<email>{email}</email> |
160 | 160 |
<urlretour_synchrone>{urlretour_synchrone}</urlretour_synchrone> |
161 | 161 |
</Transaction>''' |
162 |
assert factures, u'factures ne doit pas être vide' |
|
163 |
id_facture = u'--'.join(unicode(facture.num) for facture in factures) |
|
164 |
montant = sum(facture.reste_a_payer for facture in factures) |
|
162 | 165 |
tree, error = self.soap_call( |
163 | 166 |
self.paiement_url, body, 'TransactionReturn', |
164 | 167 |
num_service=self.num_service, |
165 |
id_facture=facture.num,
|
|
166 |
montant=facture.reste_a_payer,
|
|
168 |
id_facture=id_facture,
|
|
169 |
montant=montant,
|
|
167 | 170 |
urlretour_asynchrone=urlretour_asynchrone, |
168 | 171 |
urlretour_synchrone=urlretour_synchrone, |
169 | 172 |
email=email) |
170 |
- |