toulouse-maelis: make payInvoices call asynchronous (#76394)
gitea/passerelle/pipeline/head This commit looks good
Details
gitea/passerelle/pipeline/head This commit looks good
Details
This commit is contained in:
parent
324b787f33
commit
29f4774d2b
|
@ -26,7 +26,7 @@ from urllib.parse import urljoin
|
|||
import zeep
|
||||
from dateutil import rrule
|
||||
from django.core.serializers.json import DjangoJSONEncoder
|
||||
from django.db import models
|
||||
from django.db import models, transaction
|
||||
from django.db.models import JSONField
|
||||
from django.http import Http404, HttpResponse
|
||||
from django.utils import dateformat
|
||||
|
@ -278,6 +278,17 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
else:
|
||||
self.logger.info('Réferentiels mis à jour.')
|
||||
|
||||
def notify_invoices_paid(self):
|
||||
invoices = self.invoice_set.filter(
|
||||
maelis_notification_date__isnull=True,
|
||||
lingo_notification_date__lt=now() - datetime.timedelta(minutes=15),
|
||||
)
|
||||
for invoice in invoices:
|
||||
invoice.notify()
|
||||
|
||||
def hourly(self):
|
||||
self.notify_invoices_paid()
|
||||
|
||||
def get_referential(self, referential_name, id=None, q=None, limit=None, distinct=True):
|
||||
if id is not None:
|
||||
queryset = self.referential.filter(referential_name=referential_name, item_id=id)
|
||||
|
@ -3978,21 +3989,26 @@ class ToulouseMaelis(BaseResource, HTTPResource):
|
|||
)
|
||||
def pay_invoice(self, request, regie_id, invoice_id, post_data, **kwargs):
|
||||
invoice = self.get_invoice(regie_id, invoice_id)
|
||||
if invoice.status() != 'created':
|
||||
raise APIError('Invoice already paid')
|
||||
|
||||
result = self.call(
|
||||
'Invoice',
|
||||
'payInvoices',
|
||||
numDossier=invoice.family_id,
|
||||
codeRegie=regie_id,
|
||||
amount=str(
|
||||
Decimal(invoice.maelis_data['amountInvoice']) - Decimal(invoice.maelis_data['amountPaid'])
|
||||
),
|
||||
datePaiement=post_data['transaction_date'],
|
||||
refTransaction=post_data['transaction_id'],
|
||||
numInvoices=[invoice.invoice_id],
|
||||
numPerson=invoice.maelis_data['payer']['num'],
|
||||
invoice.lingo_data = post_data
|
||||
invoice.lingo_notification_date = now()
|
||||
invoice.save(update_fields=['updated', 'lingo_notification_date', 'lingo_data'])
|
||||
self.add_job(
|
||||
'notify_invoice_paid_job',
|
||||
regie_id=regie_id,
|
||||
invoice_id=invoice.invoice_id,
|
||||
natural_id='%s/%s' % (regie_id, invoice.invoice_id),
|
||||
)
|
||||
return {'data': result}
|
||||
return {'data': 'ok'}
|
||||
|
||||
def notify_invoice_paid_job(self, regie_id, invoice_id):
|
||||
try:
|
||||
invoice = self.invoice_set.get(regie_id=regie_id, invoice_id=invoice_id)
|
||||
except Invoice.DoesNotExist:
|
||||
return
|
||||
invoice.notify()
|
||||
|
||||
@endpoint(
|
||||
display_category='Facture',
|
||||
|
@ -4125,6 +4141,32 @@ class Invoice(models.Model):
|
|||
invoice.update({'pay_limit_date': '', 'online_payment': False})
|
||||
return invoice
|
||||
|
||||
@transaction.atomic
|
||||
def notify(self):
|
||||
obj = Invoice.objects.select_for_update().get(pk=self.pk)
|
||||
if obj.maelis_notification_date is not None:
|
||||
return True
|
||||
try:
|
||||
result = obj.resource.call(
|
||||
'Invoice',
|
||||
'payInvoices',
|
||||
numDossier=obj.family_id,
|
||||
codeRegie=obj.regie_id,
|
||||
amount=str(
|
||||
Decimal(obj.maelis_data['amountInvoice']) - Decimal(obj.maelis_data['amountPaid'])
|
||||
),
|
||||
datePaiement=obj.lingo_data['transaction_date'],
|
||||
refTransaction=obj.lingo_data['transaction_id'],
|
||||
numInvoices=[obj.invoice_id],
|
||||
numPerson=obj.maelis_data['payer']['num'],
|
||||
)
|
||||
except SOAPServiceUnreachable:
|
||||
return False
|
||||
obj.maelis_notification_date = now()
|
||||
obj.maelis_notification_data = result
|
||||
obj.save()
|
||||
return True
|
||||
|
||||
class Meta:
|
||||
ordering = ('resource', 'regie_id', 'invoice_id')
|
||||
unique_together = [['resource', 'regie_id', 'invoice_id']]
|
||||
|
|
|
@ -28,6 +28,7 @@ from zeep import Settings
|
|||
from zeep.helpers import serialize_object
|
||||
|
||||
from passerelle.apps.base_adresse.models import BaseAdresse, CityModel
|
||||
from passerelle.base.models import Job
|
||||
from passerelle.contrib.toulouse_maelis.models import Link, Referential, ToulouseMaelis
|
||||
from passerelle.contrib.toulouse_maelis.utils import get_public_criterias
|
||||
from passerelle.utils.jsonresponse import APIError
|
||||
|
@ -9021,6 +9022,9 @@ def test_invoices_history(invoice_service, con, app):
|
|||
'reference_id': '8',
|
||||
}
|
||||
|
||||
invoice = con.invoice_set.get(regie_id=104, invoice_id=8)
|
||||
assert invoice.status() == 'notified'
|
||||
|
||||
|
||||
def test_invoices_history_not_linked_error(con, app):
|
||||
url = get_endpoint('regie/104/invoices/history')
|
||||
|
@ -9074,7 +9078,41 @@ def test_invoice_not_found_invoice(invoice_service, con, app):
|
|||
assert resp.json['err_desc'] == 'Invoice not found'
|
||||
|
||||
|
||||
def test_pay_invoice(invoice_service, con, app):
|
||||
def test_pay_invoice(invoice_service, con, app, freezer):
|
||||
invoice_service.add_soap_response('readInvoices', get_xml_file('R_read_invoices.xml'))
|
||||
|
||||
resp = app.get(get_endpoint('regie/104/invoice/1312-30') + '?family_id=1312')
|
||||
assert resp.json['err'] == 0
|
||||
assert resp.json['data']['amount_paid'] == '0'
|
||||
assert resp.json['data']['paid'] is False
|
||||
assert resp.json['data']['amount'] == '162.3'
|
||||
assert resp.json['data']['online_payment'] is True
|
||||
assert resp.json['data']['pay_limit_date'] == '2023-04-30'
|
||||
|
||||
url = get_endpoint('regie/104/invoice/1312-30/pay/')
|
||||
data = {
|
||||
'transaction_date': '2023-03-03T18:38:00',
|
||||
'transaction_id': 'xxx',
|
||||
}
|
||||
|
||||
freezer.move_to('2023-03-03 18:39:00')
|
||||
resp = app.post_json(url + '?NameID=ignored', params=data)
|
||||
assert resp.json['err'] == 0
|
||||
invoice = con.invoice_set.get(regie_id=104, invoice_id=30)
|
||||
assert invoice.lingo_notification_date.strftime('%Y-%m-%d %H:%M:%S') == '2023-03-03 18:39:00'
|
||||
assert invoice.maelis_notification_date is None
|
||||
assert invoice.status() == 'paid'
|
||||
|
||||
resp = app.get(get_endpoint('regie/104/invoice/1312-30') + '?family_id=1312')
|
||||
assert resp.json['err'] == 0
|
||||
assert resp.json['data']['amount_paid'] == '162.3'
|
||||
assert resp.json['data']['paid'] is True
|
||||
assert resp.json['data']['amount'] == '0.0'
|
||||
assert resp.json['data']['online_payment'] is False
|
||||
assert resp.json['data']['pay_limit_date'] == ''
|
||||
|
||||
|
||||
def test_pay_invoice_job(invoice_service, con, app, freezer):
|
||||
def request_check(request):
|
||||
assert dict(serialize_object(request)) == {
|
||||
'numDossier': 1312,
|
||||
|
@ -9092,15 +9130,82 @@ def test_pay_invoice(invoice_service, con, app):
|
|||
invoice_service.add_soap_response(
|
||||
'payInvoices', get_xml_file('R_pay_invoices.xml'), request_check=request_check
|
||||
)
|
||||
|
||||
url = get_endpoint('regie/104/invoice/1312-30/pay/')
|
||||
data = {
|
||||
'transaction_date': '2023-03-03T18:38:00',
|
||||
'transaction_id': 'xxx',
|
||||
}
|
||||
|
||||
freezer.move_to('2023-03-03 18:39:00')
|
||||
resp = app.post_json(url + '?NameID=ignored', params=data)
|
||||
assert resp.json['err'] == 0
|
||||
assert resp.json['data'] == 4
|
||||
invoice = con.invoice_set.get(regie_id=104, invoice_id=30)
|
||||
assert invoice.lingo_notification_date.strftime('%Y-%m-%d %H:%M:%S') == '2023-03-03 18:39:00'
|
||||
assert invoice.maelis_notification_date is None
|
||||
assert invoice.maelis_notification_data is None
|
||||
assert invoice.status() == 'paid'
|
||||
job = Job.objects.get(method_name='notify_invoice_paid_job', natural_id='104/30')
|
||||
assert job.status == 'registered'
|
||||
|
||||
freezer.move_to('2023-03-03 18:40:00')
|
||||
con.jobs()
|
||||
invoice = con.invoice_set.get(regie_id=104, invoice_id=30)
|
||||
assert invoice.maelis_notification_date.strftime('%Y-%m-%d %H:%M:%S') == '2023-03-03 18:40:00'
|
||||
assert invoice.maelis_notification_data == 4
|
||||
assert invoice.status() == 'notified'
|
||||
job = Job.objects.get(method_name='notify_invoice_paid_job', natural_id='104/30')
|
||||
assert job.status == 'completed'
|
||||
assert job.update_timestamp > job.creation_timestamp
|
||||
|
||||
|
||||
def test_pay_invoice_cron(invoice_service, con, app, freezer):
|
||||
def request_check(request):
|
||||
assert dict(serialize_object(request)) == {
|
||||
'numDossier': 1312,
|
||||
'numPerson': 261483,
|
||||
'lastName': None,
|
||||
'firstName': None,
|
||||
'codeRegie': 104,
|
||||
'amount': 162.3,
|
||||
'datePaiement': datetime.datetime(2023, 3, 3, 18, 38),
|
||||
'refTransaction': 'xxx',
|
||||
'numInvoices': [30],
|
||||
}
|
||||
|
||||
invoice_service.add_soap_response('readInvoices', get_xml_file('R_read_invoices.xml'))
|
||||
invoice_service.add_soap_response(
|
||||
'payInvoices', get_xml_file('R_pay_invoices.xml'), request_check=request_check
|
||||
)
|
||||
|
||||
url = get_endpoint('regie/104/invoice/1312-30/pay/')
|
||||
data = {
|
||||
'transaction_date': '2023-03-03T18:38:00',
|
||||
'transaction_id': 'xxx',
|
||||
}
|
||||
|
||||
freezer.move_to('2023-03-03 18:39:00')
|
||||
resp = app.post_json(url + '?NameID=ignored', params=data)
|
||||
assert resp.json['err'] == 0
|
||||
invoice = con.invoice_set.get(regie_id=104, invoice_id=30)
|
||||
assert invoice.lingo_notification_date.strftime('%Y-%m-%d %H:%M:%S') == '2023-03-03 18:39:00'
|
||||
assert invoice.maelis_notification_date is None
|
||||
assert invoice.maelis_notification_data is None
|
||||
assert invoice.status() == 'paid'
|
||||
|
||||
freezer.move_to('2023-03-03 18:40:00')
|
||||
con.notify_invoices_paid()
|
||||
invoice = con.invoice_set.get(regie_id=104, invoice_id=30)
|
||||
assert invoice.maelis_notification_date is None
|
||||
assert invoice.maelis_notification_data is None
|
||||
assert invoice.status() == 'paid'
|
||||
|
||||
freezer.move_to('2023-03-03 18:55:00')
|
||||
con.notify_invoices_paid()
|
||||
invoice = con.invoice_set.get(regie_id=104, invoice_id=30)
|
||||
assert invoice.maelis_notification_date.strftime('%Y-%m-%d %H:%M:%S') == '2023-03-03 18:55:00'
|
||||
assert invoice.maelis_notification_data == 4
|
||||
assert invoice.status() == 'notified'
|
||||
|
||||
|
||||
def test_pay_invoice_wrong_referential_key_error(con, app):
|
||||
|
@ -9129,6 +9234,19 @@ def test_pay_invoice_not_found_invoice(invoice_service, con, app):
|
|||
assert resp.json['err_desc'] == 'Invoice not found'
|
||||
|
||||
|
||||
def test_pay_historical_invoice(invoice_service, con, app):
|
||||
invoice_service.add_soap_response('readInvoices', get_xml_file('R_read_invoices.xml'))
|
||||
url = get_endpoint('regie/104/invoice/1312-8/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'] == 1
|
||||
assert resp.json['err_desc'] == 'Invoice already paid'
|
||||
|
||||
|
||||
def test_invoice_pdf(invoice_service, con, app):
|
||||
def request_check(request):
|
||||
assert request.codeRegie == 104
|
||||
|
|
Loading…
Reference in New Issue