8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-12-23 07:23:46 +00:00

Merge branch 'paiement_note' into 'dev'

Module de paiement par note

See merge request federez/re2o!285
This commit is contained in:
klafyvel 2018-09-01 21:25:35 +02:00
commit 865c24cfde
9 changed files with 365 additions and 2 deletions

View file

@ -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),
),
]

View file

@ -127,10 +127,11 @@ method to your model, where `form` is an instance of
""" """
from . import comnpay, cheque, balance, urls from . import comnpay, cheque, balance, note_kfet, urls
PAYMENT_METHODS = [ PAYMENT_METHODS = [
comnpay, comnpay,
cheque, cheque,
balance, balance,
note_kfet
] ]

View file

@ -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

View file

@ -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
)

View file

@ -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}
))

View file

@ -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")

View file

@ -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'
),
]

View file

@ -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
)

View file

@ -19,9 +19,10 @@
# with this program; if not, write to the Free Software Foundation, Inc., # with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
from django.conf.urls import include, url from django.conf.urls import include, url
from . import comnpay, cheque from . import comnpay, cheque, note_kfet
urlpatterns = [ urlpatterns = [
url(r'^comnpay/', include(comnpay.urls, namespace='comnpay')), url(r'^comnpay/', include(comnpay.urls, namespace='comnpay')),
url(r'^cheque/', include(cheque.urls, namespace='cheque')), url(r'^cheque/', include(cheque.urls, namespace='cheque')),
url(r'^note_kfet/', include(note_kfet.urls, namespace='note_kfet')),
] ]