toulouse-maelis : gérer l'expiration lors du paiement (#76395) #224
|
@ -0,0 +1,30 @@
|
||||||
|
# Generated by Django 3.2.18 on 2023-04-17 16:36
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('toulouse_maelis', '0008_auto_20230413_1757'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='invoice',
|
||||||
|
name='basket_generation_date',
|
||||||
|
field=models.DateTimeField(null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='invoice',
|
||||||
|
name='maelis_cancel_notification_date',
|
||||||
|
field=models.DateTimeField(null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='toulousemaelis',
|
||||||
|
name='cancel_invoice_delay',
|
||||||
|
field=models.PositiveIntegerField(
|
||||||
|
default='30',
|
||||||
|
verbose_name="Délais de conservation des factures issues d'un panier (en minutes)",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -81,6 +81,10 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
||||||
default='P,L,S,' + ','.join(str(x) for x in range(1, 10)),
|
default='P,L,S,' + ','.join(str(x) for x in range(1, 10)),
|
||||||
verbose_name='Codes des natures des activités loisirs, séparés par des virgules',
|
verbose_name='Codes des natures des activités loisirs, séparés par des virgules',
|
||||||
)
|
)
|
||||||
|
cancel_invoice_delay = models.PositiveIntegerField(
|
||||||
|
default='30',
|
||||||
|
verbose_name="Délais de conservation des factures issues d'un panier (en minutes)",
|
||||||
|
)
|
||||||
|
|
||||||
category = 'Connecteurs métiers'
|
category = 'Connecteurs métiers'
|
||||||
_category_ordering = ['Famille', 'Activités']
|
_category_ordering = ['Famille', 'Activités']
|
||||||
|
@ -287,8 +291,19 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
||||||
for invoice in invoices:
|
for invoice in invoices:
|
||||||
invoice.notify()
|
invoice.notify()
|
||||||
|
|
||||||
|
def cancel_basket_invoices(self):
|
||||||
|
|||||||
|
invoices = self.invoice_set.filter(
|
||||||
|
lingo_notification_date__isnull=True,
|
||||||
|
basket_generation_date__isnull=False,
|
||||||
|
maelis_cancel_notification_date__isnull=True,
|
||||||
|
created__lte=now() - datetime.timedelta(minutes=self.cancel_invoice_delay + 20),
|
||||||
|
)
|
||||||
|
for invoice in invoices:
|
||||||
|
invoice.cancel()
|
||||||
|
|
||||||
def hourly(self):
|
def hourly(self):
|
||||||
self.notify_invoices_paid()
|
self.notify_invoices_paid()
|
||||||
|
self.cancel_basket_invoices()
|
||||||
bdauvergne
commented
Un léger doute sur le fait d'avoir un délai par défaut de 30 minutes et un cron toutes les heures :) Un léger doute sur le fait d'avoir un délai par défaut de 30 minutes et un cron toutes les heures :)
|
|||||||
|
|
||||||
def get_referential(self, referential_name, id=None, q=None, limit=None, distinct=True):
|
def get_referential(self, referential_name, id=None, q=None, limit=None, distinct=True):
|
||||||
if id is not None:
|
if id is not None:
|
||||||
|
@ -3628,6 +3643,10 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
||||||
baskets = self.get_baskets_raw(family_id)
|
baskets = self.get_baskets_raw(family_id)
|
||||||
for item in baskets:
|
for item in baskets:
|
||||||
item['text'] = self.get_referential_value('Regie', item['codeRegie'])
|
item['text'] = self.get_referential_value('Regie', item['codeRegie'])
|
||||||
|
|
||||||
|
# send invoice cancellation order more often than hourly
|
||||||
|
self.cancel_basket_invoices()
|
||||||
|
|
||||||
return {'data': baskets}
|
return {'data': baskets}
|
||||||
|
|
||||||
@endpoint(
|
@endpoint(
|
||||||
|
@ -3724,6 +3743,19 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
||||||
'idBasket': post_data['basket_id'],
|
'idBasket': post_data['basket_id'],
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# only one invoice should be returned, create it now to manage cancellation
|
||||||
|
if response:
|
||||||
|
for item in response.get('factureLst') or []:
|
||||||
|
invoice = self.invoice_set.create(
|
||||||
|
regie_id=item['regie']['code'],
|
||||||
|
invoice_id=item['numInvoice'],
|
||||||
|
family_id=family_id,
|
||||||
|
basket_generation_date=now(),
|
||||||
|
maelis_data=item,
|
||||||
|
maelis_data_update_date=now(),
|
||||||
|
)
|
||||||
|
self.logger.info("Ajout de %s sur la famille '%s'", repr(invoice), family_id)
|
||||||
return {'data': response}
|
return {'data': response}
|
||||||
|
|
||||||
@endpoint(
|
@endpoint(
|
||||||
|
@ -4003,7 +4035,10 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
def invoice(self, request, regie_id, invoice_id, **kwargs):
|
def invoice(self, request, regie_id, invoice_id, **kwargs):
|
||||||
return {'data': self.get_invoice(regie_id, invoice_id).format_content()}
|
invoice = self.get_invoice(regie_id, invoice_id)
|
||||||
|
if invoice.status() == 'cancelled':
|
||||||
|
raise APIError('Invoice cancelled')
|
||||||
|
return {'data': invoice.format_content()}
|
||||||
|
|
||||||
@endpoint(
|
@endpoint(
|
||||||
display_category='Facture',
|
display_category='Facture',
|
||||||
|
@ -4026,8 +4061,10 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
||||||
)
|
)
|
||||||
def pay_invoice(self, request, regie_id, invoice_id, post_data, **kwargs):
|
def pay_invoice(self, request, regie_id, invoice_id, post_data, **kwargs):
|
||||||
invoice = self.get_invoice(regie_id, invoice_id)
|
invoice = self.get_invoice(regie_id, invoice_id)
|
||||||
if invoice.status() != 'created':
|
if invoice.status() in ['paid', 'notified']:
|
||||||
raise APIError('Invoice already paid')
|
raise APIError('Invoice already paid')
|
||||||
|
if invoice.maelis_cancel_notification_date is not None:
|
||||||
|
raise APIError('Invoice cancelled')
|
||||||
|
|
||||||
invoice.lingo_data = post_data
|
invoice.lingo_data = post_data
|
||||||
invoice.lingo_notification_date = now()
|
invoice.lingo_notification_date = now()
|
||||||
|
@ -4139,6 +4176,8 @@ class Invoice(models.Model):
|
||||||
maelis_data_update_date = models.DateTimeField(null=True)
|
maelis_data_update_date = models.DateTimeField(null=True)
|
||||||
lingo_notification_date = models.DateTimeField(null=True)
|
lingo_notification_date = models.DateTimeField(null=True)
|
||||||
maelis_notification_date = models.DateTimeField(null=True)
|
maelis_notification_date = models.DateTimeField(null=True)
|
||||||
|
basket_generation_date = models.DateTimeField(null=True)
|
||||||
|
maelis_cancel_notification_date = models.DateTimeField(null=True)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<Invoice "%s/%s">' % (self.regie_id, self.invoice_id)
|
return '<Invoice "%s/%s">' % (self.regie_id, self.invoice_id)
|
||||||
|
@ -4151,6 +4190,12 @@ class Invoice(models.Model):
|
||||||
return 'notified'
|
return 'notified'
|
||||||
if self.lingo_notification_date is not None:
|
if self.lingo_notification_date is not None:
|
||||||
return 'paid'
|
return 'paid'
|
||||||
|
if (
|
||||||
|
self.lingo_notification_date is None
|
||||||
|
and self.basket_generation_date is not None
|
||||||
|
and self.created <= now() - datetime.timedelta(minutes=self.resource.cancel_invoice_delay)
|
||||||
|
):
|
||||||
|
return 'cancelled'
|
||||||
return 'created'
|
return 'created'
|
||||||
|
|
||||||
def format_content(self):
|
def format_content(self):
|
||||||
|
@ -4204,6 +4249,24 @@ class Invoice(models.Model):
|
||||||
obj.save()
|
obj.save()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@transaction.atomic
|
||||||
|
def cancel(self):
|
||||||
|
obj = Invoice.objects.select_for_update().get(pk=self.pk)
|
||||||
|
if obj.lingo_notification_date is not None or obj.basket_generation_date is None:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
obj.resource.call(
|
||||||
|
'Activity',
|
||||||
|
'cancelInvoiceAndDeleteSubscribeList',
|
||||||
|
idInvoice=obj.maelis_data['idInvoice'],
|
||||||
|
)
|
||||||
|
except SOAPServiceUnreachable:
|
||||||
|
return False
|
||||||
|
obj.maelis_cancel_notification_date = now()
|
||||||
|
obj.save()
|
||||||
|
obj.resource.logger.info("Annulation de %s sur la famille '%s'", repr(obj), obj.family_id)
|
||||||
|
return True
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('resource', 'regie_id', 'invoice_id')
|
ordering = ('resource', 'regie_id', 'invoice_id')
|
||||||
unique_together = [['resource', 'regie_id', 'invoice_id']]
|
unique_together = [['resource', 'regie_id', 'invoice_id']]
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
|
<soap:Body>
|
||||||
|
<ns2:cancelInvoiceAndDeleteSubscribeListResponse xmlns:ns2="activity.ws.maelis.sigec.com" xmlns:ns3="bean.persistence.activity.ws.maelis.sigec.com" xmlns:ns4="bean.persistence.school.ws.maelis.sigec.com"/>
|
||||||
|
</soap:Body>
|
||||||
|
</soap:Envelope>
|
|
@ -0,0 +1,19 @@
|
||||||
|
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
|
<soap:Body>
|
||||||
|
<soap:Fault>
|
||||||
|
<faultcode>soap:Server</faultcode>
|
||||||
|
<faultstring>Une erreur est survenue : java.sql.SQLException: ORA-01403: aucune donnée trouvée
|
||||||
|
ORA-06512: à "MAELIS_T2.FACTURE_SUPPRIMER", ligne 144
|
||||||
|
ORA-06512: à ligne 1
|
||||||
|
</faultstring>
|
||||||
|
<detail>
|
||||||
|
<ns1:MaelisActivityException xmlns:ns1="activity.ws.maelis.sigec.com">
|
||||||
|
<message xmlns:ns4="bean.persistence.school.ws.maelis.sigec.com" xmlns:ns3="bean.persistence.activity.ws.maelis.sigec.com" xmlns:ns2="activity.ws.maelis.sigec.com">Une erreur est survenue : java.sql.SQLException: ORA-01403: aucune donnée trouvée
|
||||||
|
ORA-06512: à "MAELIS_T2.FACTURE_SUPPRIMER", ligne 144
|
||||||
|
ORA-06512: à ligne 1
|
||||||
|
</message>
|
||||||
|
</ns1:MaelisActivityException>
|
||||||
|
</detail>
|
||||||
|
</soap:Fault>
|
||||||
|
</soap:Body>
|
||||||
|
</soap:Envelope>
|
|
@ -0,0 +1,56 @@
|
||||||
|
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||||
|
<soap:Body>
|
||||||
|
<ns2:readInvoicesResponse xmlns:ns2="ws.maelis.sigec.com">
|
||||||
|
<invoiceList>
|
||||||
|
<numInvoice>18</numInvoice>
|
||||||
|
<idInvoice>F10055641671</idInvoice>
|
||||||
|
<libelleTTF>DSBL TEST</libelleTTF>
|
||||||
|
<regie>
|
||||||
|
<code>109</code>
|
||||||
|
<libelle>DSBL</libelle>
|
||||||
|
</regie>
|
||||||
|
<numFamily>1312</numFamily>
|
||||||
|
<name>EO_NICOLAS MARGE</name>
|
||||||
|
<amountInvoice>300</amountInvoice>
|
||||||
|
<amountPaid>0</amountPaid>
|
||||||
|
<amountPaidTG>0</amountPaidTG>
|
||||||
|
<dateInvoice>2023-04-20T00:00:00+02:00</dateInvoice>
|
||||||
|
<dateDeadline>2023-12-31T00:00:00+01:00</dateDeadline>
|
||||||
|
<payer>
|
||||||
|
<num>266143</num>
|
||||||
|
<lastname>EO_NICOLAS</lastname>
|
||||||
|
<firstname>MARGE</firstname>
|
||||||
|
<civility>MME</civility>
|
||||||
|
</payer>
|
||||||
|
<lineInvoiceList>
|
||||||
|
<numLine>1</numLine>
|
||||||
|
<numPers>266148</numPers>
|
||||||
|
<idActivity>A10053179798</idActivity>
|
||||||
|
<idUnit>A10053179809</idUnit>
|
||||||
|
<idIns>S10055641665</idIns>
|
||||||
|
<libelleLine>PORTAIL MERCREDI - 15h30/17h - 8/15Ans</libelleLine>
|
||||||
|
<name>EO_NICOLAS LISA</name>
|
||||||
|
<dateStart>2023-02-01T00:00:00+01:00</dateStart>
|
||||||
|
<dateEnd>2023-06-30T00:00:00+02:00</dateEnd>
|
||||||
|
<quantity>1.0</quantity>
|
||||||
|
<unitPrice>150.0</unitPrice>
|
||||||
|
<amountLine>150</amountLine>
|
||||||
|
</lineInvoiceList>
|
||||||
|
<lineInvoiceList>
|
||||||
|
<numLine>2</numLine>
|
||||||
|
<numPers>266145</numPers>
|
||||||
|
<idActivity>A10053179798</idActivity>
|
||||||
|
<idUnit>A10053179809</idUnit>
|
||||||
|
<idIns>S10055641658</idIns>
|
||||||
|
<libelleLine>PORTAIL MERCREDI - 15h30/17h - 8/15Ans</libelleLine>
|
||||||
|
<name>EO_NICOLAS BART</name>
|
||||||
|
<dateStart>2023-02-01T00:00:00+01:00</dateStart>
|
||||||
|
<dateEnd>2023-06-30T00:00:00+02:00</dateEnd>
|
||||||
|
<quantity>1.0</quantity>
|
||||||
|
<unitPrice>150.0</unitPrice>
|
||||||
|
<amountLine>150</amountLine>
|
||||||
|
</lineInvoiceList>
|
||||||
|
</invoiceList>
|
||||||
|
</ns2:readInvoicesResponse>
|
||||||
|
</soap:Body>
|
||||||
|
</soap:Envelope>
|
|
@ -11,7 +11,7 @@
|
||||||
<code>109</code>
|
<code>109</code>
|
||||||
<libelle>DSBL</libelle>
|
<libelle>DSBL</libelle>
|
||||||
</regie>
|
</regie>
|
||||||
<numFamily>322802</numFamily>
|
<numFamily>1312</numFamily>
|
||||||
<name>EO_NICOLAS MARGE</name>
|
<name>EO_NICOLAS MARGE</name>
|
||||||
<amountInvoice>300</amountInvoice>
|
<amountInvoice>300</amountInvoice>
|
||||||
<amountPaid>0</amountPaid>
|
<amountPaid>0</amountPaid>
|
||||||
|
|
|
@ -8522,7 +8522,7 @@ def test_get_baskets_not_linked_error(con, app):
|
||||||
def test_get_baskets_no_basket(activity_service, con, app):
|
def test_get_baskets_no_basket(activity_service, con, app):
|
||||||
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml'))
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml'))
|
||||||
url = get_endpoint('get-baskets')
|
url = get_endpoint('get-baskets')
|
||||||
resp = app.get(url + '?family_id=311352')
|
resp = app.get(url + '?family_id=1312')
|
||||||
assert resp.json['err'] == 0
|
assert resp.json['err'] == 0
|
||||||
assert resp.json['data'] == []
|
assert resp.json['data'] == []
|
||||||
|
|
||||||
|
@ -8534,9 +8534,9 @@ def test_update_basket_time(activity_service, con, app):
|
||||||
url = get_endpoint('update-basket-time')
|
url = get_endpoint('update-basket-time')
|
||||||
params = {'basket_id': 'S10055641661'}
|
params = {'basket_id': 'S10055641661'}
|
||||||
|
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
resp = app.post_json(url + '?family_id=1312', params=params)
|
||||||
assert resp.json['err'] == 0
|
assert resp.json['err'] == 0
|
||||||
Link.objects.create(resource=con, family_id='311352', name_id='local')
|
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||||
|
|
||||||
resp = app.post_json(url + '?NameID=local', params=params)
|
resp = app.post_json(url + '?NameID=local', params=params)
|
||||||
assert resp.json['err'] == 0
|
assert resp.json['err'] == 0
|
||||||
|
@ -8555,7 +8555,7 @@ def test_update_basket_time_no_basket(activity_service, con, app):
|
||||||
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml'))
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml'))
|
||||||
url = get_endpoint('update-basket-time')
|
url = get_endpoint('update-basket-time')
|
||||||
params = {'basket_id': 'S10055641661'}
|
params = {'basket_id': 'S10055641661'}
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
resp = app.post_json(url + '?family_id=1312', params=params)
|
||||||
assert resp.json['err'] == 1
|
assert resp.json['err'] == 1
|
||||||
assert resp.json['err_desc'] == "no 'S10055641661' basket on family"
|
assert resp.json['err_desc'] == "no 'S10055641661' basket on family"
|
||||||
|
|
||||||
|
@ -8564,7 +8564,7 @@ def test_update_basket_time_basket_not_found(activity_service, con, app):
|
||||||
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
url = get_endpoint('update-basket-time')
|
url = get_endpoint('update-basket-time')
|
||||||
params = {'basket_id': 'plop'}
|
params = {'basket_id': 'plop'}
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
resp = app.post_json(url + '?family_id=1312', params=params)
|
||||||
assert resp.json['err'] == 1
|
assert resp.json['err'] == 1
|
||||||
assert resp.json['err_desc'] == "no 'plop' basket on family"
|
assert resp.json['err_desc'] == "no 'plop' basket on family"
|
||||||
|
|
||||||
|
@ -8577,9 +8577,9 @@ def test_delete_basket_line(activity_service, con, app):
|
||||||
url = get_endpoint('delete-basket-line')
|
url = get_endpoint('delete-basket-line')
|
||||||
params = {'basket_id': 'S10055641661', 'line_id': 'S10055641668'}
|
params = {'basket_id': 'S10055641661', 'line_id': 'S10055641668'}
|
||||||
|
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
resp = app.post_json(url + '?family_id=1312', params=params)
|
||||||
assert resp.json['err'] == 0
|
assert resp.json['err'] == 0
|
||||||
Link.objects.create(resource=con, family_id='311352', name_id='local')
|
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||||
|
|
||||||
resp = app.post_json(url + '?NameID=local', params=params)
|
resp = app.post_json(url + '?NameID=local', params=params)
|
||||||
assert resp.json['err'] == 0
|
assert resp.json['err'] == 0
|
||||||
|
@ -8599,7 +8599,7 @@ def test_delete_basket_line_no_basket(activity_service, con, app):
|
||||||
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml'))
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml'))
|
||||||
url = get_endpoint('delete-basket-line')
|
url = get_endpoint('delete-basket-line')
|
||||||
params = {'basket_id': 'S10055641661', 'line_id': 'S10055641668'}
|
params = {'basket_id': 'S10055641661', 'line_id': 'S10055641668'}
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
resp = app.post_json(url + '?family_id=1312', params=params)
|
||||||
assert resp.json['err'] == 1
|
assert resp.json['err'] == 1
|
||||||
assert resp.json['err_desc'] == "no 'S10055641661' basket on family"
|
assert resp.json['err_desc'] == "no 'S10055641661' basket on family"
|
||||||
|
|
||||||
|
@ -8608,7 +8608,7 @@ def test_delete_basket_line_basket_not_found(activity_service, con, app):
|
||||||
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
url = get_endpoint('delete-basket-line')
|
url = get_endpoint('delete-basket-line')
|
||||||
params = {'basket_id': 'plop', 'line_id': 'S10055641668'}
|
params = {'basket_id': 'plop', 'line_id': 'S10055641668'}
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
resp = app.post_json(url + '?family_id=1312', params=params)
|
||||||
assert resp.json['err'] == 1
|
assert resp.json['err'] == 1
|
||||||
assert resp.json['err_desc'] == "no 'plop' basket on family"
|
assert resp.json['err_desc'] == "no 'plop' basket on family"
|
||||||
|
|
||||||
|
@ -8617,7 +8617,7 @@ def test_delete_basket_line_line_not_found(activity_service, con, app):
|
||||||
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
url = get_endpoint('delete-basket-line')
|
url = get_endpoint('delete-basket-line')
|
||||||
params = {'basket_id': 'S10055641661', 'line_id': 'plop'}
|
params = {'basket_id': 'S10055641661', 'line_id': 'plop'}
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
resp = app.post_json(url + '?family_id=1312', params=params)
|
||||||
assert resp.json['err'] == 1
|
assert resp.json['err'] == 1
|
||||||
assert resp.json['err_desc'] == "no 'plop' basket line on basket"
|
assert resp.json['err_desc'] == "no 'plop' basket line on basket"
|
||||||
|
|
||||||
|
@ -8635,9 +8635,9 @@ def test_delete_basket(activity_service, con, app):
|
||||||
url = get_endpoint('delete-basket')
|
url = get_endpoint('delete-basket')
|
||||||
params = {'basket_id': 'S10055641661'}
|
params = {'basket_id': 'S10055641661'}
|
||||||
|
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
resp = app.post_json(url + '?family_id=1312', params=params)
|
||||||
assert resp.json['err'] == 0
|
assert resp.json['err'] == 0
|
||||||
Link.objects.create(resource=con, family_id='311352', name_id='local')
|
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||||
|
|
||||||
resp = app.post_json(url + '?NameID=local', params=params)
|
resp = app.post_json(url + '?NameID=local', params=params)
|
||||||
assert resp.json['err'] == 0
|
assert resp.json['err'] == 0
|
||||||
|
@ -8656,7 +8656,7 @@ def test_delete_basket_no_basket(activity_service, con, app):
|
||||||
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml'))
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml'))
|
||||||
url = get_endpoint('delete-basket')
|
url = get_endpoint('delete-basket')
|
||||||
params = {'basket_id': 'S10055641661'}
|
params = {'basket_id': 'S10055641661'}
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
resp = app.post_json(url + '?family_id=1312', params=params)
|
||||||
assert resp.json['err'] == 1
|
assert resp.json['err'] == 1
|
||||||
assert resp.json['err_desc'] == "no 'S10055641661' basket on family"
|
assert resp.json['err_desc'] == "no 'S10055641661' basket on family"
|
||||||
|
|
||||||
|
@ -8665,20 +8665,17 @@ def test_delete_basket_not_found(activity_service, con, app):
|
||||||
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
url = get_endpoint('delete-basket')
|
url = get_endpoint('delete-basket')
|
||||||
params = {'basket_id': 'plop'}
|
params = {'basket_id': 'plop'}
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
resp = app.post_json(url + '?family_id=1312', params=params)
|
||||||
assert resp.json['err'] == 1
|
assert resp.json['err'] == 1
|
||||||
assert resp.json['err_desc'] == "no 'plop' basket on family"
|
assert resp.json['err_desc'] == "no 'plop' basket on family"
|
||||||
|
|
||||||
|
|
||||||
def test_validate_basket(activity_service, con, app):
|
def test_validate_basket(activity_service, con, app, caplog):
|
||||||
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
activity_service.add_soap_response('validateBasket', get_xml_file('R_validate_basket.xml'))
|
activity_service.add_soap_response('validateBasket', get_xml_file('R_validate_basket.xml'))
|
||||||
url = get_endpoint('validate-basket')
|
url = get_endpoint('validate-basket')
|
||||||
params = {'basket_id': 'S10055641661'}
|
params = {'basket_id': 'S10055641661'}
|
||||||
|
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
|
||||||
assert resp.json['err'] == 0
|
|
||||||
Link.objects.create(resource=con, family_id='311352', name_id='local')
|
|
||||||
|
|
||||||
resp = app.post_json(url + '?NameID=local', params=params)
|
resp = app.post_json(url + '?NameID=local', params=params)
|
||||||
assert resp.json['err'] == 0
|
assert resp.json['err'] == 0
|
||||||
|
@ -8690,7 +8687,7 @@ def test_validate_basket(activity_service, con, app):
|
||||||
'idInvoice': 'F10055641671',
|
'idInvoice': 'F10055641671',
|
||||||
'libelleTTF': 'DSBL TEST',
|
'libelleTTF': 'DSBL TEST',
|
||||||
'regie': {'code': 109, 'libelle': 'DSBL'},
|
'regie': {'code': 109, 'libelle': 'DSBL'},
|
||||||
'numFamily': 322802,
|
'numFamily': 1312,
|
||||||
'name': 'EO_NICOLAS MARGE',
|
'name': 'EO_NICOLAS MARGE',
|
||||||
'refTIPI': None,
|
'refTIPI': None,
|
||||||
'amountInvoice': '300',
|
'amountInvoice': '300',
|
||||||
|
@ -8747,6 +8744,10 @@ def test_validate_basket(activity_service, con, app):
|
||||||
'idInsLst': ['S10055641665', 'S10055641658'],
|
'idInsLst': ['S10055641665', 'S10055641658'],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.status() == 'created'
|
||||||
|
assert invoice.basket_generation_date is not None
|
||||||
|
|
||||||
|
|
||||||
def test_validate_basket_not_linked_error(con, app):
|
def test_validate_basket_not_linked_error(con, app):
|
||||||
url = get_endpoint('validate-basket')
|
url = get_endpoint('validate-basket')
|
||||||
|
@ -8760,7 +8761,7 @@ def test_validate_basket_no_basket(activity_service, con, app):
|
||||||
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml'))
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket_empty.xml'))
|
||||||
url = get_endpoint('validate-basket')
|
url = get_endpoint('validate-basket')
|
||||||
params = {'basket_id': 'S10055641661'}
|
params = {'basket_id': 'S10055641661'}
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
resp = app.post_json(url + '?family_id=1312', params=params)
|
||||||
assert resp.json['err'] == 1
|
assert resp.json['err'] == 1
|
||||||
assert resp.json['err_desc'] == "no 'S10055641661' basket on family"
|
assert resp.json['err_desc'] == "no 'S10055641661' basket on family"
|
||||||
|
|
||||||
|
@ -8769,11 +8770,233 @@ def test_validate_basket_not_found(activity_service, con, app):
|
||||||
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
url = get_endpoint('validate-basket')
|
url = get_endpoint('validate-basket')
|
||||||
params = {'basket_id': 'plop'}
|
params = {'basket_id': 'plop'}
|
||||||
resp = app.post_json(url + '?family_id=311352', params=params)
|
resp = app.post_json(url + '?family_id=1312', params=params)
|
||||||
assert resp.json['err'] == 1
|
assert resp.json['err'] == 1
|
||||||
assert resp.json['err_desc'] == "no 'plop' basket on family"
|
assert resp.json['err_desc'] == "no 'plop' basket on family"
|
||||||
|
|
||||||
|
|
||||||
|
def test_cancel_basket_invoice_cron(activity_service, invoice_service, con, app, freezer, caplog):
|
||||||
|
def request_check(request):
|
||||||
|
assert request == 'F10055641671'
|
||||||
|
|
||||||
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
|
activity_service.add_soap_response('validateBasket', get_xml_file('R_validate_basket.xml'))
|
||||||
|
invoice_service.add_soap_response('readInvoices', get_xml_file('R_read_invoices_regie_109.xml'))
|
||||||
|
activity_service.add_soap_response(
|
||||||
|
'cancelInvoiceAndDeleteSubscribeList',
|
||||||
|
get_xml_file('R_cancel_invoice_and_delete_subscribe_list.xml'),
|
||||||
|
request_check=request_check,
|
||||||
|
)
|
||||||
|
url = get_endpoint('validate-basket')
|
||||||
|
params = {'basket_id': 'S10055641661'}
|
||||||
|
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||||
|
assert con.cancel_invoice_delay == 30
|
||||||
|
|
||||||
|
# invoice created on validate basket
|
||||||
|
freezer.move_to('2023-03-03 18:30:00')
|
||||||
|
resp = app.post_json(url + '?NameID=local', params=params)
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
data = resp.json['data']['factureLst'][0]
|
||||||
|
assert data['regie']['code'] == 109
|
||||||
|
assert data['numInvoice'] == '18'
|
||||||
|
assert data['idInvoice'] == 'F10055641671'
|
||||||
|
assert caplog.records[-1].levelno == logging.INFO
|
||||||
|
assert caplog.records[-1].message == 'Ajout de <Invoice "109/18"> sur la famille \'1312\''
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.status() == 'created'
|
||||||
|
assert invoice.basket_generation_date.strftime('%Y-%m-%d %H:%M:%S') == '2023-03-03 18:30:00'
|
||||||
|
assert invoice.maelis_cancel_notification_date is None
|
||||||
|
|
||||||
|
# invoice is not yet cancelled
|
||||||
|
con.cancel_basket_invoices()
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.status() == 'created'
|
||||||
|
|
||||||
|
resp = app.get(get_endpoint('regie/109/invoices') + '?family_id=1312')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert '1312-18' in [x['id'] for x in resp.json['data']]
|
||||||
|
|
||||||
|
# invoice is no more display but cancellation order is not sent to maelis yet
|
||||||
|
freezer.move_to('2023-03-03 19:00:00')
|
||||||
|
con.cancel_basket_invoices()
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.status() == 'cancelled'
|
||||||
|
assert invoice.maelis_cancel_notification_date is None
|
||||||
|
|
||||||
|
resp = app.get(get_endpoint('regie/109/invoices') + '?family_id=1312')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert '1312-18' not in [x['id'] for x in resp.json['data']]
|
||||||
|
|
||||||
|
# cancellation order is now sent to maelis
|
||||||
|
freezer.move_to('2023-03-03 19:20:00')
|
||||||
|
con.cancel_basket_invoices()
|
||||||
|
assert caplog.records[-1].levelno == logging.INFO
|
||||||
|
assert caplog.records[-1].message == 'Annulation de <Invoice "109/18"> sur la famille \'1312\''
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.maelis_cancel_notification_date.strftime('%Y-%m-%d %H:%M:%S') == '2023-03-03 19:20:00'
|
||||||
|
|
||||||
|
|
||||||
|
def test_cancel_basket_invoice_cron_keep_paid_invoices(
|
||||||
|
activity_service, invoice_service, con, app, freezer, caplog
|
||||||
|
):
|
||||||
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
|
activity_service.add_soap_response('validateBasket', get_xml_file('R_validate_basket.xml'))
|
||||||
|
invoice_service.add_soap_response('readInvoices', get_xml_file('R_read_invoices_regie_109.xml'))
|
||||||
|
assert con.cancel_invoice_delay == 30
|
||||||
|
|
||||||
|
# get a basket invoice
|
||||||
|
freezer.move_to('2023-03-03 18:30:00')
|
||||||
|
url = get_endpoint('validate-basket')
|
||||||
|
params = {'basket_id': 'S10055641661'}
|
||||||
|
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||||
|
resp = app.post_json(url + '?NameID=local', params=params)
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert caplog.records[-1].levelno == logging.INFO
|
||||||
|
assert caplog.records[-1].message == 'Ajout de <Invoice "109/18"> sur la famille \'1312\''
|
||||||
|
assert [(str(repr(x)), x.status()) for x in con.invoice_set.filter(regie_id=109)] == [
|
||||||
|
('<Invoice "109/18">', 'created')
|
||||||
|
]
|
||||||
|
|
||||||
|
# get family invoices
|
||||||
|
freezer.move_to('2023-03-03 18:35:00')
|
||||||
|
resp = app.get(get_endpoint('regie/109/invoices') + '?family_id=1312')
|
||||||
|
assert '1312-18' in [x['id'] for x in resp.json['data']]
|
||||||
|
assert 'Mise à jour de <Invoice "109/18">' not in caplog.records[-1].message
|
||||||
|
assert [(str(repr(x)), x.status()) for x in con.invoice_set.filter(regie_id=109)] == [
|
||||||
|
('<Invoice "109/18">', 'created'),
|
||||||
|
]
|
||||||
|
|
||||||
|
resp = app.get(get_endpoint('regie/109/invoices/history') + '?family_id=1312')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert '1312-18' not in [x['id'] for x in resp.json['data']]
|
||||||
|
|
||||||
|
# pay invoice
|
||||||
|
freezer.move_to('2023-03-03 18:38:00')
|
||||||
|
url = get_endpoint('regie/109/invoice/1312-18/pay/')
|
||||||
|
data = {
|
||||||
|
'transaction_date': '2023-03-03T18:38:00',
|
||||||
|
'transaction_id': 'xxx',
|
||||||
|
}
|
||||||
|
resp = app.post_json(url + '?NameID=ignored', params=data)
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert [(str(repr(x)), x.status()) for x in con.invoice_set.filter(regie_id=109)] == [
|
||||||
|
('<Invoice "109/18">', 'paid'),
|
||||||
|
]
|
||||||
|
|
||||||
|
resp = app.get(get_endpoint('regie/109/invoices') + '?family_id=1312')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert '1312-18' not in [x['id'] for x in resp.json['data']]
|
||||||
|
resp = app.get(get_endpoint('regie/109/invoices/history') + '?family_id=1312')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert '1312-18' in [x['id'] for x in resp.json['data']]
|
||||||
|
|
||||||
|
# invoice is not cancelled and no cancellation order is sent to maelis
|
||||||
|
freezer.move_to('2023-03-03 19:20:00')
|
||||||
|
con.cancel_basket_invoices()
|
||||||
|
assert [(str(repr(x)), x.status()) for x in con.invoice_set.filter(regie_id=109)] == [
|
||||||
|
('<Invoice "109/18">', 'paid'),
|
||||||
|
]
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.maelis_cancel_notification_date is None
|
||||||
|
|
||||||
|
resp = app.get(get_endpoint('regie/109/invoices/history') + '?family_id=1312')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert '1312-18' in [x['id'] for x in resp.json['data']]
|
||||||
|
|
||||||
|
|
||||||
|
def test_cancel_basket_invoice_cron_maelis_error(activity_service, invoice_service, con, app, freezer):
|
||||||
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
|
activity_service.add_soap_response('validateBasket', get_xml_file('R_validate_basket.xml'))
|
||||||
|
invoice_service.add_soap_response('readInvoices', get_xml_file('R_read_invoices_regie_109.xml'))
|
||||||
|
activity_service.add_soap_response(
|
||||||
|
'cancelInvoiceAndDeleteSubscribeList',
|
||||||
|
get_xml_file('R_cancel_invoice_and_delete_subscribe_list_error.xml'),
|
||||||
|
)
|
||||||
|
url = get_endpoint('validate-basket')
|
||||||
|
params = {'basket_id': 'S10055641661'}
|
||||||
|
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||||
|
assert con.cancel_invoice_delay == 30
|
||||||
|
|
||||||
|
# invoice created on validate basket
|
||||||
|
freezer.move_to('2023-03-03 18:30:00')
|
||||||
|
resp = app.post_json(url + '?NameID=local', params=params)
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
data = resp.json['data']['factureLst'][0]
|
||||||
|
assert data['regie']['code'] == 109
|
||||||
|
assert data['numInvoice'] == '18'
|
||||||
|
assert data['idInvoice'] == 'F10055641671'
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.status() == 'created'
|
||||||
|
assert invoice.basket_generation_date.strftime('%Y-%m-%d %H:%M:%S') == '2023-03-03 18:30:00'
|
||||||
|
assert invoice.maelis_cancel_notification_date is None
|
||||||
|
|
||||||
|
resp = app.get(get_endpoint('regie/109/invoices') + '?family_id=1312')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert '1312-18' in [x['id'] for x in resp.json['data']]
|
||||||
|
|
||||||
|
# error on cancellation order
|
||||||
|
freezer.move_to('2023-03-03 19:20:00')
|
||||||
|
try:
|
||||||
|
con.cancel_basket_invoices()
|
||||||
|
except SOAPError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
assert False, 'cron should raise an exception'
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.status() == 'cancelled'
|
||||||
|
assert invoice.maelis_cancel_notification_date is None
|
||||||
|
|
||||||
|
resp = app.get(get_endpoint('regie/109/invoices') + '?family_id=1312')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert '1312-18' not in [x['id'] for x in resp.json['data']]
|
||||||
|
|
||||||
|
|
||||||
|
def test_cancel_basket_invoice_on_get_baskets(activity_service, con, app, freezer, caplog):
|
||||||
|
def request_check(request):
|
||||||
|
assert request == 'F10055641671'
|
||||||
|
|
||||||
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
|
activity_service.add_soap_response('validateBasket', get_xml_file('R_validate_basket.xml'))
|
||||||
|
activity_service.add_soap_response(
|
||||||
|
'cancelInvoiceAndDeleteSubscribeList',
|
||||||
|
get_xml_file('R_cancel_invoice_and_delete_subscribe_list.xml'),
|
||||||
|
request_check=request_check,
|
||||||
|
)
|
||||||
|
Link.objects.create(resource=con, family_id='1312', name_id='local')
|
||||||
|
url = get_endpoint('get-baskets')
|
||||||
|
assert con.cancel_invoice_delay == 30
|
||||||
|
|
||||||
|
# invoice created on validate basket
|
||||||
|
freezer.move_to('2023-03-03 18:30:00')
|
||||||
|
resp = app.post_json(
|
||||||
|
get_endpoint('validate-basket') + '?NameID=local', params={'basket_id': 'S10055641661'}
|
||||||
|
)
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.status() == 'created'
|
||||||
|
|
||||||
|
# invoice is not yet cancelled
|
||||||
|
resp = app.get(url + '?family_id=1312')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.status() == 'created'
|
||||||
|
|
||||||
|
# invoice is no more display but cancellation order is not sent to maelis yet
|
||||||
|
freezer.move_to('2023-03-03 19:00:00')
|
||||||
|
resp = app.get(url + '?family_id=1312')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.status() == 'cancelled'
|
||||||
|
assert invoice.maelis_cancel_notification_date is None
|
||||||
|
|
||||||
|
# cancellation order is now sent to maelis
|
||||||
|
freezer.move_to('2023-03-03 19:20:00')
|
||||||
|
resp = app.get(url + '?family_id=1312')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.maelis_cancel_notification_date.strftime('%Y-%m-%d %H:%M:%S') == '2023-03-03 19:20:00'
|
||||||
|
|
||||||
|
|
||||||
def test_read_nursery_list(con, app):
|
def test_read_nursery_list(con, app):
|
||||||
url = get_endpoint('read-nursery-list')
|
url = get_endpoint('read-nursery-list')
|
||||||
resp = app.get(url)
|
resp = app.get(url)
|
||||||
|
@ -9050,6 +9273,15 @@ def test_invoices(invoice_service, con, app, caplog, freezer):
|
||||||
assert invoice.maelis_data_update_date.strftime('%Y-%m-%d %H:%M:%S') == '2023-03-03 18:20:00'
|
assert invoice.maelis_data_update_date.strftime('%Y-%m-%d %H:%M:%S') == '2023-03-03 18:20:00'
|
||||||
assert invoice.status() == 'created'
|
assert invoice.status() == 'created'
|
||||||
|
|
||||||
|
# Cancelled basket invoices are not displayed
|
||||||
|
freezer.move_to('2023-03-03 18:30:00')
|
||||||
|
invoice.basket_generation_date = invoice.created
|
||||||
|
invoice.save()
|
||||||
|
assert invoice.status() == 'cancelled'
|
||||||
|
resp = app.get(url + '?NameID=local')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert resp.json['data'] == []
|
||||||
|
|
||||||
|
|
||||||
@mock.patch('passerelle.utils.Request.get')
|
@mock.patch('passerelle.utils.Request.get')
|
||||||
def test_invoices_cache(mocked_get, con, app):
|
def test_invoices_cache(mocked_get, con, app):
|
||||||
|
@ -9201,6 +9433,33 @@ def test_invoice(invoice_service, con, app):
|
||||||
assert resp.json['data']['label'] == 'CLAE JANVIER 2023'
|
assert resp.json['data']['label'] == 'CLAE JANVIER 2023'
|
||||||
|
|
||||||
|
|
||||||
|
def test_invoice_if_cancelled(activity_service, invoice_service, con, app, freezer):
|
||||||
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
|
activity_service.add_soap_response('validateBasket', get_xml_file('R_validate_basket.xml'))
|
||||||
|
invoice_service.add_soap_response('readInvoices', get_xml_file('R_read_invoices_regie_109.xml'))
|
||||||
|
url = get_endpoint('regie/109/invoice/1312-18')
|
||||||
|
|
||||||
|
# invoice created on validate basket
|
||||||
|
freezer.move_to('2023-03-03 18:30:00')
|
||||||
|
resp = app.post_json(
|
||||||
|
get_endpoint('validate-basket') + '?family_id=1312', params={'basket_id': 'S10055641661'}
|
||||||
|
)
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
|
||||||
|
resp = app.get(url + '?NameID=ignored')
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert resp.json['data']['display_id'] == '18'
|
||||||
|
assert resp.json['data']['label'] == 'DSBL TEST'
|
||||||
|
|
||||||
|
# cancelled basket invoice is no more returned
|
||||||
|
freezer.move_to('2023-03-03 19:00:00')
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.status() == 'cancelled'
|
||||||
|
resp = app.get(url + '?NameID=local')
|
||||||
|
assert resp.json['err'] == 1
|
||||||
|
assert resp.json['err_desc'] == 'Invoice cancelled'
|
||||||
|
|
||||||
|
|
||||||
def test_invoice_wrong_referential_key_error(con, app):
|
def test_invoice_wrong_referential_key_error(con, app):
|
||||||
url = get_endpoint('regie/plop/invoice/1312-8')
|
url = get_endpoint('regie/plop/invoice/1312-8')
|
||||||
resp = app.get(url)
|
resp = app.get(url)
|
||||||
|
@ -9388,6 +9647,65 @@ def test_pay_historical_invoice(invoice_service, con, app):
|
||||||
assert resp.json['err_desc'] == 'Invoice already paid'
|
assert resp.json['err_desc'] == 'Invoice already paid'
|
||||||
|
|
||||||
|
|
||||||
|
def test_pay_not_yet_cancelled_basket_invoice(activity_service, invoice_service, con, app, freezer):
|
||||||
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
|
activity_service.add_soap_response('validateBasket', get_xml_file('R_validate_basket.xml'))
|
||||||
|
invoice_service.add_soap_response('readInvoices', get_xml_file('R_read_invoices_regie_109.xml'))
|
||||||
|
url = get_endpoint('regie/109/invoice/1312-18/pay/')
|
||||||
|
data = {
|
||||||
|
'transaction_date': '2023-03-03T19:20:00',
|
||||||
|
'transaction_id': 'xxx',
|
||||||
|
}
|
||||||
|
|
||||||
|
# invoice created on validate basket
|
||||||
|
freezer.move_to('2023-03-03 18:30:00')
|
||||||
|
resp = app.post_json(
|
||||||
|
get_endpoint('validate-basket') + '?family_id=1312', params={'basket_id': 'S10055641661'}
|
||||||
|
)
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
|
||||||
|
# cancellation order was not sent to maelis
|
||||||
|
freezer.move_to('2023-03-03 19:20:00')
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.status() == 'cancelled'
|
||||||
|
assert invoice.maelis_cancel_notification_date is None
|
||||||
|
resp = app.post_json(url + '?NameID=ignored', params=data)
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
assert resp.json['data'] == 'ok'
|
||||||
|
|
||||||
|
|
||||||
|
def test_pay_cancelled_basket_invoice(activity_service, invoice_service, con, app, freezer):
|
||||||
|
activity_service.add_soap_response('getFamilyBasket', get_xml_file('R_get_family_basket.xml'))
|
||||||
|
activity_service.add_soap_response('validateBasket', get_xml_file('R_validate_basket.xml'))
|
||||||
|
activity_service.add_soap_response(
|
||||||
|
'cancelInvoiceAndDeleteSubscribeList',
|
||||||
|
get_xml_file('R_cancel_invoice_and_delete_subscribe_list.xml'),
|
||||||
|
)
|
||||||
|
invoice_service.add_soap_response('readInvoices', get_xml_file('R_read_invoices_regie_109.xml'))
|
||||||
|
url = get_endpoint('regie/109/invoice/1312-18/pay/')
|
||||||
|
data = {
|
||||||
|
'transaction_date': '2023-03-03T19:20:00',
|
||||||
|
'transaction_id': 'xxx',
|
||||||
|
}
|
||||||
|
|
||||||
|
# invoice created on validate basket
|
||||||
|
freezer.move_to('2023-03-03 18:30:00')
|
||||||
|
resp = app.post_json(
|
||||||
|
get_endpoint('validate-basket') + '?family_id=1312', params={'basket_id': 'S10055641661'}
|
||||||
|
)
|
||||||
|
assert resp.json['err'] == 0
|
||||||
|
|
||||||
|
# cancellation order sent to maelis
|
||||||
|
freezer.move_to('2023-03-03 19:20:00')
|
||||||
|
con.cancel_basket_invoices()
|
||||||
|
invoice = con.invoice_set.get(regie_id=109, invoice_id=18)
|
||||||
|
assert invoice.status() == 'cancelled'
|
||||||
|
assert invoice.maelis_cancel_notification_date.strftime('%Y-%m-%d %H:%M:%S') == '2023-03-03 19:20:00'
|
||||||
|
resp = app.post_json(url + '?NameID=ignored', params=data)
|
||||||
|
assert resp.json['err'] == 1
|
||||||
|
assert resp.json['err_desc'] == 'Invoice cancelled'
|
||||||
|
|
||||||
|
|
||||||
def test_invoice_pdf(invoice_service, con, app):
|
def test_invoice_pdf(invoice_service, con, app):
|
||||||
def request_check(request):
|
def request_check(request):
|
||||||
assert request.codeRegie == 102
|
assert request.codeRegie == 102
|
||||||
|
|
Loading…
Reference in New Issue
Je mettrai un @atomic et un select_for_update(), pendant qu'on fait ça on a pas trop envie qu'il se passe autre chose.