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={ |
... | ... | |
86 | 93 |
}), |
87 | 94 |
params={ |
88 | 95 |
'num_facture': num, |
96 |
'num_factures': [num2], |
|
89 | 97 |
'urlretour_asynchrone': 'http://async.example.com/coin', |
90 | 98 |
'urlretour_synchrone': 'http://async.example.com/coin', |
91 | 99 |
'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_facture = serializers.CharField(required=False, default='') |
|
1422 |
num_factures = serializers.ListField(child=serializers.CharField(), required=False, default=[]) |
|
1422 | 1423 |
urlretour_asynchrone = serializers.URLField() |
1423 | 1424 |
urlretour_synchrone = serializers.URLField() |
1424 | 1425 |
email = serializers.EmailField(required=False) |
1425 | 1426 | |
1427 |
def validate(self, data): |
|
1428 |
if not data['num_facture'] and not data['num_factures']: |
|
1429 |
raise serializers.ValidationError('vous devez fournir num_facture ou num_factures') |
|
1430 |
return data |
|
1431 | ||
1426 | 1432 | |
1427 | 1433 |
class SagaTransaction(SagaFactures): |
1428 | 1434 |
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 | 1435 |
serializer = TransactionSagaSerializer(data=request.data) |
1435 | 1436 |
if not serializer.is_valid(): |
1436 | 1437 |
return Response({ |
... | ... | |
1438 | 1439 |
'errors': flatten_errors(serializer.errors), |
1439 | 1440 |
}, status=400) |
1440 | 1441 | |
1442 |
data = serializer.validated_data |
|
1443 | ||
1444 |
factures, error_response = self.get_factures(identifier) |
|
1445 | ||
1446 |
if error_response: |
|
1447 |
return error_response |
|
1448 | ||
1449 |
factures_a_payer = [] |
|
1450 | ||
1441 | 1451 |
for facture in factures: |
1442 |
if facture.num == serializer.validated_data['num_facture']:
|
|
1443 |
break
|
|
1444 |
else:
|
|
1452 |
if facture.num == data['num_facture'] or facture.num in data['num_factures']:
|
|
1453 |
factures_a_payer.append(facture)
|
|
1454 |
if not factures_a_payer:
|
|
1445 | 1455 |
return Response({ |
1446 | 1456 |
'err': 1, |
1447 | 1457 |
'errors': [ |
1448 |
'numéro de facture inconnu',
|
|
1458 |
u'numéro(s) de facture inconnu',
|
|
1449 | 1459 |
] |
1450 | 1460 |
}) |
1451 | 1461 | |
1452 | 1462 |
data = serializer.validated_data |
1453 | 1463 |
email = data.get('email') or self.individu.content['email'] or '' |
1454 | 1464 |
url, error = self.ws.transaction( |
1455 |
facture=facture,
|
|
1465 |
facture_or_factures=factures_a_payer,
|
|
1456 | 1466 |
urlretour_asynchrone=data['urlretour_asynchrone'], |
1457 | 1467 |
urlretour_synchrone=data['urlretour_synchrone'], |
1458 | 1468 |
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, facture_or_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 |
if isinstance(facture_or_factures, Facture): |
|
163 |
id_facture = unicode(facture_or_factures.num) |
|
164 |
montant = facture_or_factures.reste_a_payer |
|
165 |
else: |
|
166 |
id_facture = u'--'.join(unicode(facture.num) for facture in facture_or_factures) |
|
167 |
montant = sum(facture.reste_a_payer for facture in facture_or_factures) |
|
162 | 168 |
tree, error = self.soap_call( |
163 | 169 |
self.paiement_url, body, 'TransactionReturn', |
164 | 170 |
num_service=self.num_service, |
165 |
id_facture=facture.num,
|
|
166 |
montant=facture.reste_a_payer,
|
|
171 |
id_facture=id_facture,
|
|
172 |
montant=montant,
|
|
167 | 173 |
urlretour_asynchrone=urlretour_asynchrone, |
168 | 174 |
urlretour_synchrone=urlretour_synchrone, |
169 | 175 |
email=email) |
170 |
- |