mirror of https://gitlab.federez.net/re2o/re2o
Browse Source
Module de paiement par note See merge request federez/re2o!285add_link_port_search_results
9 changed files with 365 additions and 2 deletions
@ -0,0 +1,31 @@ |
|||
# -*- coding: utf-8 -*- |
|||
# Generated by Django 1.10.7 on 2018-09-01 11:27 |
|||
from __future__ import unicode_literals |
|||
|
|||
import cotisations.payment_methods.mixins |
|||
from django.db import migrations, models |
|||
import django.db.models.deletion |
|||
|
|||
|
|||
class Migration(migrations.Migration): |
|||
|
|||
dependencies = [ |
|||
('cotisations', '0034_auto_20180831_1532'), |
|||
] |
|||
|
|||
operations = [ |
|||
migrations.CreateModel( |
|||
name='NotePayment', |
|||
fields=[ |
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), |
|||
('server', models.CharField(max_length=255, verbose_name='server')), |
|||
('port', models.PositiveIntegerField(blank=True, null=True)), |
|||
('id_note', models.PositiveIntegerField(blank=True, null=True)), |
|||
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')), |
|||
], |
|||
options={ |
|||
'verbose_name': 'NoteKfet', |
|||
}, |
|||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model), |
|||
), |
|||
] |
|||
@ -0,0 +1,26 @@ |
|||
# -*- mode: python; coding: utf-8 -*- |
|||
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il |
|||
# se veut agnostique au réseau considéré, de manière à être installable en |
|||
# quelques clics. |
|||
# |
|||
# Copyright © 2018 Gabriel Detraz, Pierre-Antoine Comby |
|||
# |
|||
# This program is free software; you can redistribute it and/or modify |
|||
# it under the terms of the GNU General Public License as published by |
|||
# the Free Software Foundation; either version 2 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 General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU General Public License along |
|||
# with this program; if not, write to the Free Software Foundation, Inc., |
|||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|||
""" |
|||
This module contains a method to pay online using comnpay. |
|||
""" |
|||
from . import models, urls |
|||
NAME = "NOTE" |
|||
PaymentMethod = models.NotePayment |
|||
@ -0,0 +1,38 @@ |
|||
# -*- mode: python; coding: utf-8 -*- |
|||
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il |
|||
# se veut agnostique au réseau considéré, de manière à être installable en |
|||
# quelques clics. |
|||
# |
|||
# Copyright © 2018 Pierre-Antoine Comby |
|||
# Copyright © 2018 Gabriel Detraz |
|||
# |
|||
# This program is free software; you can redistribute it and/or modify |
|||
# it under the terms of the GNU General Public License as published by |
|||
# the Free Software Foundation; either version 2 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 General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU General Public License along |
|||
# with this program; if not, write to the Free Software Foundation, Inc., |
|||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|||
from django import forms |
|||
from django.utils.translation import ugettext_lazy as _ |
|||
|
|||
from cotisations.utils import find_payment_method |
|||
|
|||
class NoteCredentialForm(forms.Form): |
|||
"""A special form to get credential to connect to a NoteKfet2015 server throught his API |
|||
object. |
|||
""" |
|||
login = forms.CharField( |
|||
label=_("pseudo note") |
|||
) |
|||
password = forms.CharField( |
|||
label=_("Password"), |
|||
widget=forms.PasswordInput |
|||
) |
|||
|
|||
@ -0,0 +1,65 @@ |
|||
# -*- mode: python; coding: utf-8 -*- |
|||
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il |
|||
# se veut agnostique au réseau considéré, de manière à être installable en |
|||
# quelques clics. |
|||
# |
|||
# Copyright © 2018 Pierre-Antoine Comby |
|||
# Copyright © 2018 Gabriel Detraz |
|||
# |
|||
# This program is free software; you can redistribute it and/or modify |
|||
# it under the terms of the GNU General Public License as published by |
|||
# the Free Software Foundation; either version 2 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 General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU General Public License along |
|||
# with this program; if not, write to the Free Software Foundation, Inc., |
|||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|||
from django.db import models |
|||
from django.shortcuts import render |
|||
from django.urls import reverse |
|||
from django.utils.translation import ugettext_lazy as _ |
|||
from django.contrib import messages |
|||
|
|||
from cotisations.models import Paiement |
|||
from cotisations.payment_methods.mixins import PaymentMethodMixin |
|||
|
|||
from django.shortcuts import render, redirect |
|||
|
|||
|
|||
class NotePayment(PaymentMethodMixin, models.Model): |
|||
""" |
|||
The model allowing you to pay with NoteKfet2015. |
|||
""" |
|||
|
|||
class Meta: |
|||
verbose_name = _("NoteKfet") |
|||
|
|||
payment = models.OneToOneField( |
|||
Paiement, |
|||
on_delete = models.CASCADE, |
|||
related_name = 'payment_method', |
|||
editable = False |
|||
) |
|||
server = models.CharField( |
|||
max_length=255, |
|||
verbose_name=_("server") |
|||
) |
|||
port = models.PositiveIntegerField( |
|||
blank = True, |
|||
null = True |
|||
) |
|||
id_note = models.PositiveIntegerField( |
|||
blank = True, |
|||
null = True |
|||
) |
|||
|
|||
def end_payment(self, invoice, request): |
|||
return redirect(reverse( |
|||
'cotisations:note_kfet:note_payment', |
|||
kwargs={'factureid': invoice.id} |
|||
)) |
|||
@ -0,0 +1,74 @@ |
|||
#!/usr/bin/python3 |
|||
# -*- coding:utf-8 -*- |
|||
|
|||
# Codé par PAC , forké de 20-100 |
|||
|
|||
""" Module pour dialoguer avec la NoteKfet2015 """ |
|||
|
|||
import socket |
|||
import json |
|||
import ssl |
|||
import traceback |
|||
|
|||
|
|||
def get_response(socket): |
|||
length_str = b'' |
|||
char = socket.recv(1) |
|||
while char != b'\n': |
|||
length_str += char |
|||
char = socket.recv(1) |
|||
total = int(length_str) |
|||
return json.loads(socket.recv(total).decode('utf-8')) |
|||
|
|||
def connect(server, port): |
|||
sock = socket.socket() |
|||
try: |
|||
# On établit la connexion sur port 4242 |
|||
sock.connect((server, port)) |
|||
# On passe en SSL |
|||
sock = ssl.wrap_socket(sock) |
|||
# On fait un hello |
|||
sock.send(b'["hello", "manual"]') |
|||
retcode = get_response(sock) |
|||
except: |
|||
# Si on a foiré quelque part, c'est que le serveur est down |
|||
return (False, sock, "Serveur indisponible") |
|||
return (True, sock, "") |
|||
|
|||
def login(server, port, username, password, masque = [[], [], True]): |
|||
result, sock, err = connect(server, port) |
|||
if not result: |
|||
return (False, None, err) |
|||
try: |
|||
commande = ["login", [username, password, "bdd", masque]] |
|||
sock.send(json.dumps(commande).encode("utf-8")) |
|||
response = get_response(sock) |
|||
retcode = response['retcode'] |
|||
if retcode == 0: |
|||
return (True, sock, "") |
|||
elif retcode == 5: |
|||
return (False, sock, "Login incorrect") |
|||
else: |
|||
return (False, sock, "Erreur inconnue " + str(retcode)) |
|||
except: |
|||
# Si on a foiré quelque part, c'est que le serveur est down |
|||
return (False, sock, "Erreur de communication avec le serveur") |
|||
|
|||
|
|||
def don(sock, montant, id_note, facture): |
|||
""" |
|||
Faire faire un don à l'id_note |
|||
""" |
|||
try: |
|||
sock.send(json.dumps(["dons", [[id_note], round(montant*100), "Facture : id=%s, designation=%s" % (facture.id, facture.name())]]).encode("utf-8")) |
|||
response = get_response(sock) |
|||
retcode = response['retcode'] |
|||
transaction_retcode = response["msg"][0][0] |
|||
if 0 < retcode < 100 or 200 <= retcode or 0 < transaction_retcode < 100 or 200 <= transaction_retcode: |
|||
return (False, "Transaction échouée. (Solde trop négatif ?)") |
|||
elif retcode == 0: |
|||
return (True, "") |
|||
else: |
|||
return (False, "Erreur inconnue " + str(retcode)) |
|||
except: |
|||
return (False, "Erreur de communication avec le serveur") |
|||
@ -0,0 +1,30 @@ |
|||
# -*- mode: python; coding: utf-8 -*- |
|||
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il |
|||
# se veut agnostique au réseau considéré, de manière à être installable en |
|||
# quelques clics. |
|||
# |
|||
# Copyright © 2018 Gabriel Detraz |
|||
# |
|||
# This program is free software; you can redistribute it and/or modify |
|||
# it under the terms of the GNU General Public License as published by |
|||
# the Free Software Foundation; either version 2 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 General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU General Public License along |
|||
# with this program; if not, write to the Free Software Foundation, Inc., |
|||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|||
from django.conf.urls import url |
|||
from . import views |
|||
|
|||
urlpatterns = [ |
|||
url( |
|||
r'^note_payment/(?P<factureid>[0-9]+)$', |
|||
views.note_payment, |
|||
name='note_payment' |
|||
), |
|||
] |
|||
@ -0,0 +1,97 @@ |
|||
# -*- mode: python; coding: utf-8 -*- |
|||
# Re2o est un logiciel d'administration développé initiallement au rezometz. Il |
|||
# se veut agnostique au réseau considéré, de manière à être installable en |
|||
# quelques clics. |
|||
# |
|||
# Copyright © 2018 Gabriel Detraz |
|||
# Copyright © 2018 Pierre-Antoine Comby |
|||
# |
|||
# This program is free software; you can redistribute it and/or modify |
|||
# it under the terms of the GNU General Public License as published by |
|||
# the Free Software Foundation; either version 2 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 General Public License for more details. |
|||
# |
|||
# You should have received a copy of the GNU General Public License along |
|||
# with this program; if not, write to the Free Software Foundation, Inc., |
|||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
|||
"""Payment |
|||
|
|||
Here are the views needed by comnpay |
|||
""" |
|||
|
|||
from collections import OrderedDict |
|||
|
|||
from django.urls import reverse |
|||
from django.shortcuts import redirect, get_object_or_404 |
|||
from django.contrib.auth.decorators import login_required |
|||
from django.contrib import messages |
|||
from django.views.decorators.csrf import csrf_exempt |
|||
from django.utils.datastructures import MultiValueDictKeyError |
|||
from django.utils.translation import ugettext as _ |
|||
from django.http import HttpResponse, HttpResponseBadRequest |
|||
|
|||
from cotisations.models import Facture |
|||
from cotisations.utils import find_payment_method |
|||
from .models import NotePayment |
|||
from re2o.views import form |
|||
from re2o.acl import ( |
|||
can_create, |
|||
can_edit |
|||
) |
|||
from .note import login, don |
|||
from .forms import NoteCredentialForm |
|||
|
|||
@login_required |
|||
@can_edit(Facture) |
|||
def note_payment(request, facture, factureid): |
|||
""" |
|||
Build a request to start the negociation with NoteKfet by using |
|||
a facture id, the price and the login/password data stored in |
|||
the preferences. |
|||
""" |
|||
user = facture.user |
|||
payment_method = find_payment_method(facture.paiement) |
|||
if not payment_method or not isinstance(payment_method, NotePayment): |
|||
messages.error(request, "Erreur inconnue") |
|||
return redirect(reverse( |
|||
'users:profil', |
|||
kwargs={'userid': user.id} |
|||
)) |
|||
noteform = NoteCredentialForm(request.POST or None) |
|||
if noteform.is_valid(): |
|||
pseudo = noteform.cleaned_data['login'] |
|||
password = noteform.cleaned_data['password'] |
|||
result, sock, err = login(payment_method.server, payment_method.port, pseudo, password) |
|||
if not result: |
|||
messages.error(request, err) |
|||
return form( |
|||
{'form': noteform, 'amount': facture.prix_total()}, |
|||
"cotisations/payment.html", |
|||
request |
|||
) |
|||
else: |
|||
result, err = don(sock, facture.prix_total(), payment_method.id_note, facture) |
|||
if not result: |
|||
messages.error(request, err) |
|||
return form( |
|||
{'form': noteform, 'amount': facture.prix_total()}, |
|||
"cotisations/payment.html", |
|||
request |
|||
) |
|||
facture.valid = True |
|||
facture.save() |
|||
messages.success(request, "Le paiement par note a bien été effectué") |
|||
return redirect(reverse( |
|||
'users:profil', |
|||
kwargs={'userid': user.id} |
|||
)) |
|||
return form( |
|||
{'form': noteform, 'amount': facture.prix_total()}, |
|||
"cotisations/payment.html", |
|||
request |
|||
) |
|||
Loading…
Reference in new issue