invoicing: callback on invoice cancellation (#88590)
gitea/lingo/pipeline/head This commit looks good Details

This commit is contained in:
Lauréline Guérin 2024-04-25 14:13:13 +02:00
parent 4b255c2da4
commit 72d8be1775
No known key found for this signature in database
GPG Key ID: 1FAB9B9B4F93D473
4 changed files with 29 additions and 23 deletions

View File

@ -15,10 +15,8 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import datetime
import logging
import pytz
import requests
from django.db import transaction
from django.db.models import Q
from django.http import Http404, HttpResponse
@ -46,7 +44,6 @@ from lingo.invoicing.models import (
Refund,
Regie,
)
from lingo.utils.requests_wrapper import requests as requests_wrapper
class InvoicingRegies(APIView):
@ -307,7 +304,7 @@ class InvoicingInvoicePay(APIView):
order_id=order_id,
order_date=order_date,
)
self.notify(invoice, payment)
invoice.notify(payload={'payment_id': payment.uuid}, notification_type='payment')
return Response(
{
'data': {
@ -316,24 +313,6 @@ class InvoicingInvoicePay(APIView):
}
)
def notify(self, invoice, payment):
url = invoice.payment_callback_url
if not url:
return
try:
response = requests_wrapper.post(
url, data={'payment_id': payment.uuid}, remote_service='auto', timeout=15
)
if response and not response.ok:
logging.error(
'error (HTTP %s) notifying payment',
response.status_code,
)
except requests.Timeout:
logging.error('error (timeout) notifying payment')
except Exception as e: # noqa pylint: disable=broad-except
logging.error('error (%s) notifying payment', e)
invoicing_invoice_pay = InvoicingInvoicePay.as_view()

View File

@ -781,6 +781,7 @@ class RegieInvoiceCancelForm(forms.ModelForm):
self.instance.cancelled_at = now()
self.instance.cancelled_by = self.request.user
self.instance.save()
self.instance.notify(payload={'invoice_id': self.instance.uuid}, notification_type='cancel')
return self.instance

View File

@ -20,10 +20,12 @@ import copy
import dataclasses
import datetime
import decimal
import logging
import sys
import traceback
import uuid
import requests
from django.conf import settings
from django.contrib.auth.models import Group
from django.core import validators
@ -43,6 +45,7 @@ from lingo.agendas.models import Agenda
from lingo.export_import.models import WithApplicationMixin
from lingo.utils.fields import RichTextField
from lingo.utils.misc import LingoImportError, clean_import_data, generate_slug
from lingo.utils.requests_wrapper import requests as requests_wrapper
from lingo.utils.wcs import (
WCSError,
get_wcs_dependencies_from_template,
@ -1151,6 +1154,23 @@ class Invoice(AbstractInvoice):
def get_cancellation_info(self):
return get_cancellation_info(self)
def notify(self, notification_type, payload):
url = getattr(self, '%s_callback_url' % notification_type, None)
if not url:
return
try:
response = requests_wrapper.post(url, data=payload, remote_service='auto', timeout=15)
if response and not response.ok:
logging.error(
'error (HTTP %s) notifying %s',
response.status_code,
notification_type,
)
except requests.Timeout:
logging.error('error (timeout) notifying %s', notification_type)
except Exception as e: # noqa pylint: disable=broad-except
logging.error('error (%s) notifying %s', e, notification_type)
class Credit(AbstractInvoiceObject):
number = models.PositiveIntegerField(default=0)

View File

@ -1,5 +1,6 @@
import datetime
import decimal
from unittest import mock
import pytest
from django.utils.formats import date_format
@ -1159,6 +1160,7 @@ def test_regie_invoice_cancel(app, admin_user):
payer_address='41 rue des kangourous\n99999 Kangourou Ville',
payer_demat=True,
payer_direct_debit=False,
cancel_callback_url='http://cancel.com',
)
invoice1.set_number()
invoice1.save()
@ -1225,7 +1227,11 @@ def test_regie_invoice_cancel(app, admin_user):
]
resp.form['cancellation_reason'] = cancellation_reason.pk
resp.form['cancellation_description'] = 'foo bar blah'
resp = resp.form.submit()
with mock.patch('lingo.utils.requests_wrapper.RequestsSession.send') as mock_send:
resp = resp.form.submit()
assert {x[0][0].url for x in mock_send.call_args_list} == {
'http://cancel.com/',
}
assert resp.location.endswith(
'/manage/invoicing/regie/%s/invoices/?number=%s' % (regie.pk, invoice1.formatted_number)
)