From f6e206997406ea5f267210c4296a4e17c1c7b08a Mon Sep 17 00:00:00 2001 From: Serghei Mihai Date: Wed, 19 Aug 2015 11:17:03 +0200 Subject: [PATCH] contrib.teamnet_axel: invoice payment notify endpoint (#8201) --- .../migrations/0002_management_billing_regies.py | 21 ++++++++++++++++ passerelle/contrib/teamnet_axel/models.py | 26 ++++++++++++++++++++ .../passerelle/contrib/teamnet_axel/detail.html | 6 +++++ passerelle/contrib/teamnet_axel/urls.py | 7 +++--- passerelle/contrib/teamnet_axel/views.py | 28 ++++++++++++++++++++-- 5 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 passerelle/contrib/teamnet_axel/migrations/0002_management_billing_regies.py diff --git a/passerelle/contrib/teamnet_axel/migrations/0002_management_billing_regies.py b/passerelle/contrib/teamnet_axel/migrations/0002_management_billing_regies.py new file mode 100644 index 0000000..d894ead --- /dev/null +++ b/passerelle/contrib/teamnet_axel/migrations/0002_management_billing_regies.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import jsonfield.fields + + +class Migration(migrations.Migration): + + dependencies = [ + ('teamnet_axel', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='management', + name='billing_regies', + field=jsonfield.fields.JSONField(default=dict, verbose_name='Mapping between regie ids and billing ids'), + preserve_default=True, + ), + ] diff --git a/passerelle/contrib/teamnet_axel/models.py b/passerelle/contrib/teamnet_axel/models.py index a0937b4..d9953d2 100644 --- a/passerelle/contrib/teamnet_axel/models.py +++ b/passerelle/contrib/teamnet_axel/models.py @@ -17,11 +17,14 @@ import logging import base64 import xml.etree.ElementTree as ET +from datetime import datetime from django.core.urlresolvers import reverse from django.db import models from django.utils.translation import ugettext_lazy as _ +from jsonfield import JSONField + from passerelle.base.models import BaseResource from . import soap, utils @@ -47,6 +50,8 @@ class Management(BaseResource): verbose_name=_('Keystore'), help_text=_('Certificate and private key in PEM format')) + billing_regies = JSONField(_('Mapping between regie ids and billing ids')) + category = _('Business Process Connectors') class Meta: @@ -162,6 +167,27 @@ class Management(BaseResource): return base64.b64decode(pdf.get('FILE')) + def pay_invoice(self, regie_id, family_id, invoice, email=None): + payment_xml = ET.Element('PAIEMENT') + ET.SubElement(payment_xml, 'IDDEMANDE') + ET.SubElement(payment_xml, 'IDFAMILLE').text = family_id + ET.SubElement(payment_xml, 'IDREGIEENC').text = self.billing_regies.get(regie_id) + ET.SubElement(payment_xml, 'MODEREGLEMENT').text = 'PAY' + ET.SubElement(payment_xml, 'MONTANT').text = str(invoice['amount']) + ET.SubElement(payment_xml, 'URL') + if email: + ET.SubElement(payment_xml, 'COURRIEL').text = email + else: + ET.SubElement(payment_xml, 'COURRIEL') + ET.SubElement(payment_xml, 'REFPAIEMENT') + ET.SubElement(payment_xml, 'DATEENVOI').text = datetime.now().strftime('%d/%m/%Y %H:%M:%S') + ET.SubElement(payment_xml, 'DATERETOUR').text = datetime.now().strftime('%d/%m/%Y %H:%M:%S') + ET.SubElement(payment_xml, 'CODERETOUR') + ET.SubElement(ET.SubElement(payment_xml, 'FACTURE'), 'NOFACTURE').text = invoice['display_id'] + data = self.get_data('PaiementFactures', payment_xml) + return data.text + + class Link(models.Model): resource = models.ForeignKey(Management) nameid = models.CharField(blank=False, max_length=256) diff --git a/passerelle/contrib/teamnet_axel/templates/passerelle/contrib/teamnet_axel/detail.html b/passerelle/contrib/teamnet_axel/templates/passerelle/contrib/teamnet_axel/detail.html index f17fd07..17bb8d9 100644 --- a/passerelle/contrib/teamnet_axel/templates/passerelle/contrib/teamnet_axel/detail.html +++ b/passerelle/contrib/teamnet_axel/templates/passerelle/contrib/teamnet_axel/detail.html @@ -64,6 +64,12 @@ {{ site_base_uri }}{{ invoice_download_url }} +
  • {% trans 'Pay invoice:' %} + {% url 'teamnet-axel-invoice-payment' slug=object.slug regie_id='42' invoice_id='2345-20150808' as payment_url %} + + {{ site_base_uri }}{{ payment_url }}?NameID=... + +
  • diff --git a/passerelle/contrib/teamnet_axel/urls.py b/passerelle/contrib/teamnet_axel/urls.py index 9753c74..62f4978 100644 --- a/passerelle/contrib/teamnet_axel/urls.py +++ b/passerelle/contrib/teamnet_axel/urls.py @@ -43,10 +43,9 @@ public_urlpatterns = patterns('', name='teamnet-axel-invoice'), url(r'^(?P[\w,-]+)/regie/(?P[\w,-]+)/invoice/(?P[\w,-]+)/pdf/$', InvoicePDFView.as_view(), name='teamnet-axel-invoice-pdf'), - #url(r'^(?P[\w,-]+)/invoice-pdf/(?P[\w,-]+)/$', InvoicePDFView.as_view(), - # name='teamnet-axel-unlink'), - #url(r'^(?P[\w,-]+)/invoice-paid/(?P[\w,-]+)/$', InvoicePayView.as_view(), - # name='teamnet-axel-unlink'), + url(r'^(?P[\w,-]+)/regie/(?P[\w,-]+)/invoice/(?P[\w,-]+)/pay/$', + InvoicePayView.as_view(), + name='teamnet-axel-invoice-payment'), ) management_urlpatterns = patterns('', diff --git a/passerelle/contrib/teamnet_axel/views.py b/passerelle/contrib/teamnet_axel/views.py index b917f7b..f2ce8b0 100644 --- a/passerelle/contrib/teamnet_axel/views.py +++ b/passerelle/contrib/teamnet_axel/views.py @@ -19,6 +19,7 @@ from django.core.urlresolvers import reverse from django.views.generic import DetailView as GenericDetailView from django.views.generic.edit import CreateView, UpdateView, DeleteView from django.http import HttpResponse, Http404 +from django.views.decorators.csrf import csrf_exempt from passerelle import utils @@ -57,12 +58,23 @@ class DetailView(GenericDetailView): def get_data(self, request, *args, **kwargs): raise NotImplementedError - @utils.protected_api('can_access') + def post_data(self, request, *args, **kwargs): + raise NotImplementedError + @utils.to_json('api') def get(self, request, *args, **kwargs): - self.object = self.get_object() return self.get_data(request, *args, **kwargs) + @csrf_exempt + @utils.protected_api('can_access') + def dispatch(self, request, *args, **kwargs): + self.object = self.get_object() + return super(DetailView, self).dispatch(request, *args, **kwargs) + + @utils.to_json('api') + def post(self, request, *args, **kwargs): + return self.post_data(request, *args, **kwargs) + class PingView(DetailView): def get_data(self, request, *args, **kwargs): @@ -180,3 +192,15 @@ class InvoicePDFView(DetailView): response['Content-Disposition'] = 'attachment; filename="%s.pdf"' % invoice_id response.write(pdf) return response + + +class InvoicePayView(DetailView): + + def post_data(self, request, *args, **kwargs): + family_id, invoice_id = kwargs['invoice_id'].split('-', 1) + regie_id = kwargs['regie_id'] + + invoices = self.object.get_invoices(regie_id, family_id) + for invoice in invoices: + if invoice['id'] == kwargs['invoice_id'] and invoice['online_payment']: + return self.object.pay_invoice(regie_id, family_id, invoice) -- 2.5.3