teamnet axel: use GenericConnectorView (#23593)

This commit is contained in:
Josue Kouka 2018-06-14 14:54:06 +02:00
parent ca597a7c3b
commit 0d894dadbb
6 changed files with 199 additions and 330 deletions

View File

@ -14,12 +14,14 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import base64
import xml.etree.ElementTree as ET
from datetime import datetime
import json
import logging
import xml.etree.ElementTree as ET
from django.db import models
from django.http import HttpResponse, HttpResponseNotFound
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_text
@ -27,7 +29,9 @@ from django.utils.encoding import smart_text
from jsonfield import JSONField
from passerelle.base.models import BaseResource
from passerelle.utils.api import endpoint
from passerelle.utils.jsonresponse import APIError
from passerelle.views import WrongParameter
from . import soap
from .utils import normalize_person, normalize_invoice
@ -42,6 +46,12 @@ DATE_IN_FORMAT = '%Y-%m-%dT%H:%M:%S'
DATE_OUT_FORMAT = '%d/%m/%Y %H:%M:%S'
def get_name_id(request):
if 'NameID' not in request.GET:
raise WrongParameter(['NameID'], [])
return request.GET['NameID']
class TeamnetAxel(BaseResource):
wsdl_url = models.CharField(
max_length=128, blank=False,
@ -93,7 +103,7 @@ class TeamnetAxel(BaseResource):
return xml_result.find('DATA')
# Axel authentication
def auth(self, login, pwd):
def authenticate(self, login, pwd):
'''return False or an AXEL user dict:
{
"login": "23060A",
@ -123,7 +133,21 @@ class TeamnetAxel(BaseResource):
return False
return data
def get_famille(self, idfamille, annee=None):
def get_family_id(self, request):
nameid = get_name_id(request)
links = Link.objects.filter(resource=self, nameid=nameid)
if len(links) > 1:
raise APIError('multiple links')
if not links:
return None
user = self.authenticate(links[0].login, links[0].pwd)
if not user:
raise APIError('authentication failed')
if 'idfamille' not in user:
raise APIError('user without idfamille')
return user['idfamille']
def get_family_data(self, idfamille, annee=None):
xml_famille = ET.Element('FAMILLE')
ET.SubElement(xml_famille, 'IDFAMILLE').text = idfamille
if annee:
@ -138,11 +162,75 @@ class TeamnetAxel(BaseResource):
individu['text'] = '%(prenom)s %(nom)s' % individu
adults = [normalize_person(i) for i in individus if i['indtype'] in (ADULT1, ADULT2)]
children = [normalize_person(i) for i in individus if i['indtype'] == CHILD]
return {
'family': idfamille,
'adults': adults,
'children': children,
}
return {'family': idfamille, 'adults': adults, 'children': children}
@endpoint(perm='can_access')
def ping(self, request, *args, **kwargs):
try:
client = soap.get_client(self)
except (Exception, ) as exc:
raise APIError('Client Error: %s' % exc.message)
res = {'ping': 'pong'}
if 'debug' in request.GET:
res['client'] = soap.client_to_jsondict(client)
return {'data': res}
@endpoint(perm='can_access')
def auth(self, request, *args, **kwargs):
login = request.GET.get('login')
pwd = request.GET.get('pwd')
return {'data': self.authenticate(login, pwd)}
@endpoint(name='family', perm='can_access')
def family_data(self, request, *args, **kwargs):
idfamille = self.get_family_id(request)
if not idfamille:
return {'data': None}
data = self.get_family_data(idfamille)
return {'data': data}
@endpoint(name='family', perm='can_access', pattern='^adults/$')
def family_adults(self, request, *args, **kwargs):
idfamille = self.get_family_id(request)
if not idfamille:
return {'data': None}
data = self.get_family_data(idfamille)
return {'data': data.get('adults')}
@endpoint(name='family', perm='can_access', pattern='^children/$')
def family_children(self, request, *args, **kwargs):
idfamille = self.get_family_id(request)
if not idfamille:
return {'data': None}
data = self.get_family_data(idfamille)
return {'data': data.get('children')}
@endpoint(name='family', perm='can_access', pattern='^link/$')
def family_link(self, request, *args, **kwargs):
nameid = get_name_id(request)
login = request.GET.get('login')
pwd = request.GET.get('password')
user = self.authenticate(login, pwd)
if not user:
raise APIError('authentication failed')
if 'idfamille' not in user:
raise APIError('user without idfamille')
famille = self.get_family_data(user['idfamille'])
Link.objects.update_or_create(
resource=self, nameid=nameid, defaults={'login': login, 'pwd': pwd})
user['_famille'] = famille
user['_nameid'] = nameid
return {'data': user}
@endpoint(name='family', perm='can_access', pattern='^unlink/$')
def family_unlink(self, request, *args, **kwargs):
nameid = get_name_id(request)
logins = [v['login'] for v in Link.objects.filter(resource=self, nameid=nameid).values('login')]
Link.objects.filter(resource=self, nameid=nameid).delete()
if logins:
return {'data': {'login_was': logins}}
else:
return {'data': None}
def get_teamnet_payable_invoices(self, regie_id, family_id):
operation = 'FacturesApayerRegie'
@ -157,6 +245,15 @@ class TeamnetAxel(BaseResource):
payable_invoices.update(normalize_invoice(i.attrib, family_id))
return payable_invoices
@endpoint(name='regie', pattern='^(?P<regie_id>\w+)/invoices/$')
def active_invoices(self, request, regie_id, **kwargs):
family_id = self.get_family_id(request)
if not family_id:
return {'data': []}
invoices = self.get_teamnet_payable_invoices(regie_id, family_id)
invoices = sorted([p for i, p in invoices.iteritems()], key=lambda i: i['created'], reverse=True)
return {'data': invoices}
def get_teamnet_historical_invoices(self, regie_id, family_id):
"""
returns historical invoices for a given regie.
@ -175,54 +272,59 @@ class TeamnetAxel(BaseResource):
historical_invoices.update(normalize_invoice(i.attrib, family_id, historical=True))
return historical_invoices
def get_payable_invoices(self, regie_id, family_id):
"""
returns payable invoices list sorted by creation date
"""
@endpoint(name='regie', perm='can_access', pattern='^(?P<regie_id>\w+)/invoices/history/$')
def invoices_history(self, request, regie_id, **kwargs):
family_id = self.get_family_id(request)
if not family_id:
return []
invoices = self.get_teamnet_payable_invoices(regie_id, family_id)
return sorted([p for i, p in invoices.iteritems()], key=lambda i: i['created'], reverse=True)
def get_historical_invoices(self, regie_id, family_id):
"""
Removes the invoices from get_teamnet_historical_invoices which are in
get_teamnet_payable_invoices, as the Teamnet webservices mixes them.
Returns historical invoices list sorted by creation date.
"""
if not family_id:
return []
return {'data': []}
payable = self.get_teamnet_payable_invoices(regie_id, family_id)
historical = self.get_teamnet_historical_invoices(regie_id, family_id)
historical = [v for i, v in historical.iteritems() if i not in payable]
return sorted(historical, key=lambda i: i['created'], reverse=True)
invoices = sorted(historical, key=lambda i: i['created'], reverse=True)
return {'data': invoices}
def get_invoice(self, regie_id, invoice_id):
@endpoint(name='regie', perm='can_access',
pattern='^(?P<regie_id>\w+)/invoice/(?P<invoice_id>[\w,-]+)/$')
def get_invoice_details(self, request, regie_id, invoice_id, **kwargs):
family_id, i = invoice_id.split('-', 1)
payable = self.get_teamnet_payable_invoices(regie_id, family_id)
if invoice_id in payable:
return payable[invoice_id]
return {'data': payable[invoice_id]}
historical = self.get_teamnet_historical_invoices(regie_id, family_id)
if invoice_id in historical:
return historical[invoice_id]
return {'data': historical[invoice_id]}
return {'data': None}
def get_invoice_pdf(self, invoice_id):
@endpoint(name='regie', perm='can_access',
pattern='^(?P<regie_id>\w+)/invoice/(?P<invoice_id>[\w,-]+)/pdf/$')
def invoice_pdf(self, request, regie_id, invoice_id, **kwargs):
family_id, invoice = invoice_id.split('-', 1)
invoice_xml = ET.Element('FACTUREPDF')
ET.SubElement(invoice_xml, 'IDFAMILLE').text = family_id
ET.SubElement(ET.SubElement(invoice_xml, 'FACTURES'), 'NOFACTURE').text = invoice
data = self.get_data('FacturesPDF', invoice_xml)
pdf = data.find('PORTAIL/PDF')
return base64.b64decode(pdf.get('FILE'))
b64content = base64.b64decode(pdf.get('FILE'))
if not b64content:
return HttpResponseNotFound()
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="%s.pdf"' % invoice_id
response.write(b64content)
return response
@endpoint(name='regie', methods=['post'],
perm='can_access', pattern='^(?P<regie_id>\w+)/invoice/(?P<invoice_id>[\w,-]+)/pay/$')
def pay_invoice(self, request, regie_id, invoice_id, **kwargs):
data = json.loads(request.body)
transaction_id = data.get('transaction_id')
transaction_date = data.get('transaction_date')
email = data.get('email')
def pay_invoice(self, regie_id, invoice_id, transaction_id,
transaction_date, email=None):
family_id, invoice = invoice_id.split('-', 1)
payable_invoices = self.get_teamnet_payable_invoices(regie_id, family_id)
if invoice_id not in payable_invoices:
return False
return {'data': False}
invoice_to_pay = payable_invoices[invoice_id]
t_date = datetime.strptime(transaction_date, DATE_IN_FORMAT)
@ -244,7 +346,7 @@ class TeamnetAxel(BaseResource):
ET.SubElement(payment_xml, 'CODERETOUR')
ET.SubElement(ET.SubElement(payment_xml, 'FACTURE'), 'NOFACTURE').text = invoice
self.get_data('PaiementFactures', payment_xml)
return True
return {'data': True}
class Link(models.Model):

View File

@ -1,69 +0,0 @@
{% extends "passerelle/manage/service_view.html" %}
{% load i18n passerelle %}
{% block description %}
{% endblock %}
{% block endpoints %}
<h4>{% trans "Family related" %}</h4>
<ul>
<li>{% trans 'Check WSDL availability:' %} <a href="{% url 'teamnet-axel-ping' slug=object.slug %}"
>{{ site_base_uri }}{% url 'teamnet-axel-ping' slug=object.slug %}</a>[?debug]</li>
<li>{% trans 'Authentication:' %} <a href="{% url 'teamnet-axel-auth' slug=object.slug %}"
>{{ site_base_uri }}{% url 'teamnet-axel-auth' slug=object.slug %}?login=...&pwd=...</a></li>
<li>{% trans 'Link:' %} <a href="{% url 'teamnet-axel-link' slug=object.slug %}"
>{{ site_base_uri }}{% url 'teamnet-axel-link' slug=object.slug %}?NameID=...&login=...&pwd=...</a></li>
<li>{% trans 'Unlink:' %} <a href="{% url 'teamnet-axel-unlink' slug=object.slug %}"
>{{ site_base_uri }}{% url 'teamnet-axel-unlink' slug=object.slug %}?NameID=...</a></li>
<li>{% trans 'Get all family informations:' %} <a href="{% url 'teamnet-axel-family' slug=object.slug %}"
>{{ site_base_uri }}{% url 'teamnet-axel-family' slug=object.slug %}?NameID=...</a></li>
<li>{% trans 'Get specific family informations (list of children):' %}
<a href="{% url 'teamnet-axel-family-filtered' slug=object.slug key='key' %}"
>{{ site_base_uri }}{% url 'teamnet-axel-family-filtered' slug=object.slug key='key' %}?NameID=...</a>
<em>key</em> is <em>adults</em> or <em>children</em></li>
</ul>
<h4>{% trans "Invoices related" %}</h4>
<ul>
<li>{% trans 'Get invoice history list:' %}
{% url 'teamnet-axel-invoices-history' regie_id='42' slug=object.slug as invoices_history_url %}
<a href="{{ invoices_history_url }}">
{{ site_base_uri }}{{ invoices_history_url }}?NameID=...
</a> <em>42</em> {% trans 'is regie identifier' %}
</li>
<li>{% trans 'Get invoice list:' %}
{% url 'teamnet-axel-invoices' regie_id='42' slug=object.slug as invoices_url %}
<a href="{{ invoices_url }}">
{{ site_base_uri }}{{ invoices_url }}?NameID=...
</a> <em>42</em> {% trans 'is regie identifier' %}
</li>
<li>{% trans 'Show invoice details:' %}
{% url 'teamnet-axel-invoice' slug=object.slug regie_id='42' invoice_id='2345-20150916' as invoice_details_url %}
<a href="{{ invoice_details_url }}">
{{ site_base_uri }}{{ invoice_details_url }}
</a>
<em>42</em> {% trans 'is regie identifier' %},
<em>2345</em> {% trans 'is family identifier' %},
<em>20150916</em> {% trans 'is invoice identifier' %}
</li>
<li>{% trans 'Get invoice pdf:' %}
{% url 'teamnet-axel-invoice-pdf' slug=object.slug regie_id='42' invoice_id='2345-20150916' as invoice_download_url %}
<a href="{{ invoice_download_url }}">
{{ site_base_uri }}{{ invoice_download_url }}
</a>
</li>
<li>{% trans 'Pay invoice:' %}
{% url 'teamnet-axel-invoice-payment' slug=object.slug regie_id='42' invoice_id='2345-20150808' as payment_url %}
<a href="{{ payment_url }}">
{{ site_base_uri }}{{ payment_url }}?NameID=...
</a>
</li>
</ul>
{% endblock %}
{% block security %}
<p>
{% trans 'Access is limited to the following API users:' %}
</p>
{% access_rights_table resource=object permission='can_access' %}
{% endblock %}

View File

@ -0,0 +1,60 @@
{% extends "passerelle/manage/service_view.html" %}
{% load i18n passerelle %}
{% block endpoints %}
<h4>{% trans "Family related" %}</h4>
<ul>
{% url "generic-endpoint" connector="teamnet-axel" slug=object.slug endpoint="ping" as endpoint_ping %}
<li>{% trans 'Check WSDL availability:' %} <a href="{{ endpoint_ping }}">{{ endpoint_ping }}</a>[?debug]</li>
{% url "generic-endpoint" connector="teamnet-axel" slug=object.slug endpoint="auth" as endpoint_auth %}
<li>{% trans 'Authentication:' %} <a href="{{ endpoint_auth }}?login=foo&password=bar">{{ endpoint_auth }}?login=foo&password=bar</a></li>
{% url "generic-endpoint" connector="teamnet-axel" slug=object.slug endpoint="family" rest="link/" as endpoint_link %}
<li>{% trans 'Link:' %} <a href="{{ endpoint_link }}?NameID=...&login=foo&password=bar">{{ endpoint_link }}?NameID=...&login=foo&password=bar</a></li>
{% url "generic-endpoint" connector="teamnet-axel" slug=object.slug endpoint="family" rest="unlink/" as endpoint_unlink %}
<li>{% trans 'Unlink:' %} <a href="{{ endpoint_unlink }}?NameID=...">{{ endpoint_unlink }}?NameID=...</a></li>
{% url "generic-endpoint" connector="teamnet-axel" slug=object.slug endpoint="family" rest="" as endpoint_family %}
<li>{% trans 'Get all family informations:' %} <a href="{{ endpoint_family }}?NameID">{{ endpoint_family }}?NameID=...</a></li>
{% url "generic-endpoint" connector="teamnet-axel" slug=object.slug endpoint="family" rest="adults/" as endpoint_family %}
<li>{% trans 'Get family adults informations:' %} <a href="{{ endpoint_family }}?NameID">{{ endpoint_family }}?NameID=...</a></li>
{% url "generic-endpoint" connector="teamnet-axel" slug=object.slug endpoint="family" rest="children/" as endpoint_family %}
<li>{% trans 'Get family children informations:' %} <a href="{{ endpoint_family }}?NameID">{{ endpoint_family }}?NameID=...</a></li>
</ul>
<h4>{% trans "Invoices related" %}</h4>
<ul>
<li>{% trans 'Get invoice history list:' %}
{% url "generic-endpoint" connector="teamnet-axel" slug=object.slug endpoint="regie" rest="42/invoices/history/" as invoices_history_url %}
<a href="{{ invoices_history_url }}?NameID"> {{ invoices_history_url }}?NameID=...</a>
<em>42</em> {% trans 'is regie identifier' %}
</li>
<li>{% trans 'Get invoice list:' %}
{% url "generic-endpoint" connector="teamnet-axel" slug=object.slug endpoint="regie" rest="42/invoices/" as invoices_url %}
<a href="{{ invoices_url }}?NameID"> {{ invoices_url }}?NameID=... </a>
<em>42</em> {% trans 'is regie identifier' %}
</li>
<li>{% trans 'Show invoice details:' %}
{% url "generic-endpoint" connector="teamnet-axel" slug=object.slug endpoint="regie" rest="42/invoices/2345-20150916/" as invoice_details_url %}
<a href="{{ invoice_details_url }}"> {{ site_base_uri }}{{ invoice_details_url }} </a>
<em>42</em> {% trans 'is regie identifier' %},
<em>2345</em> {% trans 'is family identifier' %},
<em>20150916</em> {% trans 'is invoice identifier' %}
</li>
<li>{% trans 'Get invoice pdf:' %}
{% url "generic-endpoint" connector="teamnet-axel" slug=object.slug endpoint="regie" rest="42/invoices/2345-20150916/pdf/" as invoice_download_url %}
<a href="{{ invoice_download_url }}"> {{ site_base_uri }}{{ invoice_download_url }} </a>
</li>
<li>{% trans 'Pay invoice:' %}
{% url "generic-endpoint" connector="teamnet-axel" slug=object.slug endpoint="regie" rest="42/invoices/2345-20150916/pay/" as payment_url %}
<a href="{{ payment_url }}"> {{ site_base_uri }}{{ payment_url }}?NameID=... </a>
</li>
</ul>
{% endblock %}

View File

@ -1,47 +0,0 @@
# passerelle.contrib.teamnet_axel
# Copyright (C) 2015 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.conf.urls import url
from .views import (AuthView, FamilyView, HistoryInvoicesView, InvoiceView,
InvoicesView, InvoicePayView, InvoicePDFView, LinkView,
PingView, UnlinkView)
urlpatterns = [
url(r'^(?P<slug>[\w,-]+)/ping/$', PingView.as_view(),
name='teamnet-axel-ping'),
url(r'^(?P<slug>[\w,-]+)/auth/$', AuthView.as_view(),
name='teamnet-axel-auth'),
url(r'^(?P<slug>[\w,-]+)/family/link/$', LinkView.as_view(),
name='teamnet-axel-link'),
url(r'^(?P<slug>[\w,-]+)/family/unlink/$', UnlinkView.as_view(),
name='teamnet-axel-unlink'),
url(r'^(?P<slug>[\w,-]+)/family/$', FamilyView.as_view(),
name='teamnet-axel-family'),
url(r'^(?P<slug>[\w,-]+)/family/(?P<key>[\w,-]+)/$', FamilyView.as_view(),
name='teamnet-axel-family-filtered'),
url(r'^(?P<slug>[\w,-]+)/regie/(?P<regie_id>[\w,-]+)/invoices/history/$', HistoryInvoicesView.as_view(),
name='teamnet-axel-invoices-history'),
url(r'^(?P<slug>[\w,-]+)/regie/(?P<regie_id>[\w,-]+)/invoices/$', InvoicesView.as_view(),
name='teamnet-axel-invoices'),
url(r'^(?P<slug>[\w,-]+)/regie/(?P<regie_id>[\w,-]+)/invoice/(?P<invoice_id>[\w,-]+)/$', InvoiceView.as_view(),
name='teamnet-axel-invoice'),
url(r'^(?P<slug>[\w,-]+)/regie/(?P<regie_id>[\w,-]+)/invoice/(?P<invoice_id>[\w,-]+)/pdf/$', InvoicePDFView.as_view(),
name='teamnet-axel-invoice-pdf'),
url(r'^(?P<slug>[\w,-]+)/regie/(?P<regie_id>[\w,-]+)/invoice/(?P<invoice_id>[\w,-]+)/pay/$',
InvoicePayView.as_view(),
name='teamnet-axel-invoice-payment'),
]

View File

@ -1,177 +0,0 @@
# passerelle.contrib.teamnet_axel
# Copyright (C) 2015 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import json
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt
from django.views.generic import DetailView as GenericDetailView
from django.http import HttpResponse, HttpResponseNotFound
from passerelle import utils
from passerelle.views import WrongParameter
from .models import TeamnetAxel, Link, APIError
from . import soap
def get_name_id(request):
if 'NameID' not in request.GET:
raise WrongParameter(['NameID'], [])
return request.GET['NameID']
class DetailView(GenericDetailView):
model = TeamnetAxel
def get_data(self, request, *args, **kwargs):
raise NotImplementedError
@utils.protected_api('can_access')
@utils.to_json()
def get(self, request, *args, **kwargs):
self.object = self.get_object()
data = self.get_data(request, *args, **kwargs)
if isinstance(data, HttpResponse):
return data
return {'data': data}
class PingView(DetailView):
def get_data(self, request, *args, **kwargs):
try:
client = soap.get_client(self.object)
except (Exception, ) as exc:
raise APIError('Client Error: %s' % exc.message)
res = {'ping': 'pong'}
if 'debug' in request.GET:
res['client'] = soap.client_to_jsondict(client)
return res
class AuthView(DetailView):
def get_data(self, request, *args, **kwargs):
login = request.GET.get('login')
pwd = request.GET.get('password')
return self.object.auth(login, pwd)
class LinkView(DetailView):
def get_data(self, request, *args, **kwargs):
nameid = get_name_id(request)
login = request.GET.get('login')
pwd = request.GET.get('password')
user = self.object.auth(login, pwd)
if not user:
raise APIError('authentication failed')
if 'idfamille' not in user:
raise APIError('user without idfamille')
famille = self.object.get_famille(user['idfamille'])
Link.objects.update_or_create(
resource=self.object, nameid=nameid, defaults={'login': login, 'pwd': pwd})
user['_famille'] = famille
user['_nameid'] = nameid
return user
class UnlinkView(DetailView):
def get_data(self, request, *args, **kwargs):
nameid = get_name_id(request)
logins = [v['login'] for v in Link.objects.filter(resource=self.object, nameid=nameid).values('login')]
Link.objects.filter(resource=self.object, nameid=nameid).delete()
if logins:
return {'login_was': logins}
else:
return None
class FamilyView(DetailView):
def get_family_id(self, request):
nameid = get_name_id(request)
links = Link.objects.filter(resource=self.object, nameid=nameid)
if len(links) > 1:
raise APIError('multiple links')
if not links:
return None
user = self.object.auth(links[0].login, links[0].pwd)
if not user:
raise APIError('authentication failed')
if 'idfamille' not in user:
raise APIError('user without idfamille')
return user['idfamille']
def get_data(self, request, *args, **kwargs):
family_id = self.get_family_id(request)
if not family_id:
return
famille = self.object.get_famille(family_id)
if 'key' not in kwargs:
return famille
else:
return famille.get(kwargs['key'])
class InvoicesView(FamilyView):
def get_data(self, request, regie_id, **kwargs):
return self.object.get_payable_invoices(regie_id, self.get_family_id(request))
class HistoryInvoicesView(FamilyView):
def get_data(self, request, regie_id, **kwargs):
return self.object.get_historical_invoices(regie_id, self.get_family_id(request))
class InvoiceView(DetailView):
def get_data(self, request, *args, **kwargs):
return self.object.get_invoice(kwargs['regie_id'], kwargs['invoice_id'])
class InvoicePDFView(DetailView):
def get_data(self, request, *args, **kwargs):
invoice_id = kwargs['invoice_id']
pdf = self.object.get_invoice_pdf(invoice_id)
if not pdf:
return HttpResponseNotFound()
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="%s.pdf"' % invoice_id
response.write(pdf)
return response
class InvoicePayView(DetailView):
@method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(InvoicePayView, self).dispatch(*args, **kwargs)
@utils.to_json()
@utils.protected_api('can_access')
def post(self, request, *args, **kwargs):
self.object = self.get_object()
data = json.loads(request.body)
return {'data': self.object.pay_invoice(kwargs['regie_id'],
kwargs['invoice_id'], data['transaction_id'],
data['transaction_date'])}

View File

@ -162,7 +162,7 @@ INVOICE_PAYMENT_RESPONSE = '''
def test_authentication_failed(app, setup):
with mock.patch('passerelle.contrib.teamnet_axel.views.FamilyView.get_family_id') as mocked:
with mock.patch('passerelle.contrib.teamnet_axel.models.TeamnetAxel.get_family_id') as mocked:
mocked.side_effect = APIError('authentication failed')
NameID = 'abcd' * 8
resp = app.get('/teamnet-axel/test/family/', params={'NameID': NameID})