8
0
Fork 0
mirror of https://gitlab2.federez.net/re2o/re2o synced 2024-09-12 01:03:09 +00:00

Permet la création et l'édition de moyen de paiement personnalisés.

This commit is contained in:
Hugo LEVY-FALK 2018-07-02 21:13:13 +02:00
parent 10a54639b6
commit bfefca6832
13 changed files with 198 additions and 62 deletions

View file

@ -242,17 +242,12 @@ class PaiementForm(FormRevMixin, ModelForm):
class Meta:
model = Paiement
# TODO : change moyen to method and type_paiement to payment_type
fields = ['moyen', 'type_paiement', 'allow_self_subscription']
fields = ['moyen', 'allow_self_subscription']
def __init__(self, *args, **kwargs):
prefix = kwargs.pop('prefix', self.Meta.model.__name__)
super(PaiementForm, self).__init__(*args, prefix=prefix, **kwargs)
self.fields['moyen'].label = _("Payment method name")
self.fields['type_paiement'].label = _("Payment type")
self.fields['type_paiement'].help_text = \
_("The payement type is used for specific behaviour.\
The \"cheque\" type means a cheque number and a bank name\
may be added when using this payment method.")
# TODO : change paiement to payment

View file

@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-28 17:28
# Generated by Django 1.10.7 on 2018-07-02 18:56
from __future__ import unicode_literals
import cotisations.payment_methods.comnpay.aes_field
import cotisations.payment_methods.models
from django.db import migrations, models
import django.db.models.deletion
@ -29,6 +30,8 @@ def add_comnpay(apps, schema_editor):
comnpay.payment_pass = options.payment_pass
comnpay.payment = payment
comnpay.save()
payment.moyen = "ComnPay"
payment.save()
class Migration(migrations.Migration):
@ -42,18 +45,20 @@ class Migration(migrations.Migration):
name='ChequePayment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('payment', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
],
bases=(cotisations.payment_methods.models.PaymentMethodMixin, models.Model),
),
migrations.CreateModel(
name='ComnpayPayment',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('payment_user', models.CharField(blank=True, default='', max_length=255)),
('payment_credential', models.CharField(blank=True, default='', max_length=255)),
('payment_pass', cotisations.payment_methods.comnpay.aes_field.AESEncryptedField(blank=True, max_length=255, null=True)),
('payment', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
],
bases=(cotisations.payment_methods.models.PaymentMethodMixin, models.Model),
),
migrations.RunPython(add_cheque),
migrations.RunPython(add_comnpay),
migrations.RunPython(add_cheque),
]

View file

@ -1,20 +0,0 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.7 on 2018-06-28 19:57
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cotisations', '0032_chequepayment_comnpaypayment'),
]
operations = [
migrations.AlterField(
model_name='comnpaypayment',
name='payment_id',
field=models.CharField(blank=True, default='', max_length=255),
),
]

View file

@ -1,4 +1,5 @@
from django.conf.urls import include, url
from django.utils.translation import ugettext_lazy as _l
from . import comnpay, cheque
@ -7,3 +8,18 @@ urlpatterns = [
url(r'^comnpay/', include(comnpay.urls, namespace='comnpay')),
url(r'^cheque/', include(cheque.urls, namespace='cheque')),
]
PAYMENT_METHODS = [
comnpay,
cheque,
]
def find_payment_method(payment):
for method in PAYMENT_METHODS:
try:
o = method.PaymentMethod.objects.get(payment=payment)
return o
except method.PaymentMethod.DoesNotExist:
pass
return None

View file

@ -4,4 +4,4 @@ This module contains a method to pay online using cheque.
from . import models, urls, views
NAME = "CHEQUE"
Payment = models.ChequePayment
PaymentMethod = models.ChequePayment

View file

@ -1,10 +1,12 @@
from django import forms
from django.utils.translation import ugettext_lazy as _l
from cotisations.models import Banque as Bank
from re2o.mixins import FormRevMixin
from cotisations.models import Facture as Invoice
class ChequeForm(forms.Form):
class InvoiceForm(FormRevMixin, forms.ModelForm):
"""A simple form to get the bank a the cheque number."""
bank = forms.ModelChoiceField(Bank.objects.all(), label=_l("Bank"))
number = forms.CharField(label=_l("Cheque number"))
class Meta:
model = Invoice
fields = ['banque', 'cheque']

View file

@ -2,16 +2,19 @@ from django.db import models
from django.shortcuts import redirect
from django.urls import reverse
from cotisations.models import Paiement as BasePayment
from cotisations.models import Paiement
from cotisations.payment_methods.mixins import PaymentMethodMixin
class ChequePayment(models.Model):
class ChequePayment(PaymentMethodMixin, models.Model):
"""
The model allowing you to pay with a cheque. It redefines post_payment
method. See `cotisations.models.Paiement for further details.
The model allowing you to pay with a cheque.
"""
payment = models.OneToOneField(BasePayment, related_name='payment_method')
payment = models.OneToOneField(
Paiement,
related_name='payment_method',
editable=False
)
def end_payment(self, invoice, request):
invoice.valid = False
invoice.save()

View file

@ -3,4 +3,4 @@ This module contains a method to pay online using comnpay.
"""
from . import models, urls, views
NAME = "COMNPAY"
Payment = models.ComnpayPayment
PaymentMethod = models.ComnpayPayment

View file

@ -1,19 +1,22 @@
from django.db import models
from django.shortcuts import render
from cotisations.models import Paiement as BasePayment
from cotisations.models import Paiement
from cotisations.payment_methods.mixins import PaymentMethodMixin
from .aes_field import AESEncryptedField
from .views import comnpay
class ComnpayPayment(models.Model):
class ComnpayPayment(PaymentMethodMixin, models.Model):
"""
The model allowing you to pay with COMNPAY. It redefines post_payment
method. See `cotisations.models.Paiement for further details.
The model allowing you to pay with COMNPAY.
"""
payment = models.OneToOneField(BasePayment, related_name='payment_method')
payment = models.OneToOneField(
Paiement,
related_name='payment_method',
editable=False
)
payment_credential = models.CharField(
max_length=255,
default='',

View file

@ -0,0 +1,59 @@
from django import forms
from django.utils.translation import ugettext as _
from django.utils.translation import ugettext_lazy as _l
from . import PAYMENT_METHODS, find_payment_method
def payment_method_factory(payment, *args, **kwargs):
payment_method = kwargs.pop('instance', find_payment_method(payment))
if payment_method is not None:
return forms.modelform_factory(type(payment_method), fields='__all__')(
*args,
instance=payment_method,
**kwargs
)
return PaymentMethodForm(payment_method, *args, **kwargs)
class PaymentMethodForm(forms.Form):
"""A special form which allows you to add a payment method to a `Payment`
objects if it hasn't one yet, or to edit the existing payment method.
To do so it replaces itself with a `modelform_factory`.
"""
payment_method = forms.ChoiceField(
label=_l("Special payment method"),
required=False
)
def __init__(self, payment_method, *args, **kwargs):
super(PaymentMethodForm, self).__init__(*args, **kwargs)
if payment_method is None:
prefix = kwargs.get('prefix', None)
self.fields['payment_method'].choices = [(i,p.NAME) for (i,p) in enumerate(PAYMENT_METHODS)]
self.fields['payment_method'].choices.insert(0, ('', _l('no')))
self.fields['payment_method'].widget.attrs = {
'id': 'paymentMethodSelect'
}
self.templates = [
forms.modelform_factory(p.PaymentMethod, fields='__all__')(prefix=prefix)
for p in PAYMENT_METHODS
]
else:
self.fields = {}
def save(self, *args, payment=None, **kwargs):
commit = kwargs.pop('commit', True)
choice = self.cleaned_data['payment_method']
if choice=='':
return
choice = int(choice)
model = PAYMENT_METHODS[choice].PaymentMethod
form = forms.modelform_factory(model, fields='__all__')(self.data, prefix=self.prefix)
payment_method = form.save(commit=False)
payment_method.payment = payment
if commit:
payment_method.save()
return payment_method

View file

@ -0,0 +1,21 @@
from django.db import models
from cotisations.models import Paiement
class PaymentMethodMixin:
"""The base class for payment models. They should inherit from this."""
payment = models.OneToOneField(
Paiement,
related_name='payment_method',
editable=False
)
def end_payment(self, invoice, request):
"""Redefine this method in order to get a different ending to the
payment session if you whish.
Must return a HttpResponse-like object.
"""
return self.payment.end_payment(
invoice, request, use_payment_method=False)

View file

@ -57,16 +57,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
</p>
{% endif %}
{% bootstrap_form factureform %}
{% if payment_method %}
{% bootstrap_form payment_method %}
<div id="paymentMethod"></div>
{% endif %}
{% bootstrap_button action_name button_type='submit' icon='star' %}
</form>
{% if articlesformset %}
{% if articlesformset or payment_method%}
<script type="text/javascript">
{% if articlesformset %}
var prices = {};
{% for article in articles %}
prices[{{ article.id|escapejs }}] = {{ article.prix }};
{% endfor %}
var template = `Article : &nbsp;
{% bootstrap_form articlesformset.empty_form label_class='sr-only' %}
&nbsp;
@ -134,6 +139,34 @@ with this program; if not, write to the Free Software Foundation, Inc.,
}
update_price();
});
{% endif %}
{% if payment_method.templates %}
var TEMPLATES = [
"",
{% for t in payment_method.templates %}
{% if t %}
`{% bootstrap_form t %}`,
{% else %}
"",
{% endif %}
{% endfor %}
];
function update_payment_method_form(){
var method = document.getElementById('paymentMethodSelect').value;
if(method==""){
method=0;
}
else{
method = Number(method);
method += 1;
}
console.log(method);
var html = TEMPLATES[method];
document.getElementById('paymentMethod').innerHTML = html;
}
document.getElementById("paymentMethodSelect").addEventListener("change", update_payment_method_form);
{% endif %}
</script>
{% endif %}

View file

@ -74,6 +74,7 @@ from .forms import (
RechargeForm
)
from .tex import render_invoice
from .payment_methods.forms import payment_method_factory
@login_required
@ -473,9 +474,15 @@ def add_paiement(request):
"""
View used to add a payment method.
"""
payment = PaiementForm(request.POST or None)
if payment.is_valid():
payment.save()
payment = PaiementForm(request.POST or None, prefix='payment')
payment_method = payment_method_factory(
payment.instance,
request.POST or None,
prefix='payment_method'
)
if payment.is_valid() and payment_method.is_valid():
payment = payment.save()
payment_method.save(payment=payment)
messages.success(
request,
_("The payment method has been successfully created.")
@ -483,6 +490,7 @@ def add_paiement(request):
return redirect(reverse('cotisations:index-paiement'))
return form({
'factureform': payment,
'payment_method': payment_method,
'action_name': _("Add")
}, 'cotisations/facture.html', request)
@ -494,17 +502,28 @@ def edit_paiement(request, paiement_instance, **_kwargs):
"""
View used to edit a payment method.
"""
payment = PaiementForm(request.POST or None, instance=paiement_instance)
if payment.is_valid():
if payment.changed_data:
payment.save()
messages.success(
request,
_("The payement method has been successfully edited.")
)
payment = PaiementForm(
request.POST or None,
instance=paiement_instance,
prefix="payment"
)
payment_method = payment_method_factory(
paiement_instance,
request.POST or None,
prefix='payment_method'
)
if payment.is_valid() and payment_method.is_valid():
payment.save()
payment_method.save()
messages.success(
request,
_("The payement method has been successfully edited.")
)
return redirect(reverse('cotisations:index-paiement'))
return form({
'factureform': payment,
'payment_method': payment_method,
'action_name': _("Edit")
}, 'cotisations/facture.html', request)