mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-12-23 15:33:45 +00:00
Permet la création et l'édition de moyen de paiement personnalisés.
This commit is contained in:
parent
10a54639b6
commit
bfefca6832
13 changed files with 198 additions and 62 deletions
|
@ -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
|
||||
|
|
|
@ -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),
|
||||
]
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
]
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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']
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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='',
|
||||
|
|
59
cotisations/payment_methods/forms.py
Normal file
59
cotisations/payment_methods/forms.py
Normal 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
|
21
cotisations/payment_methods/mixins.py
Normal file
21
cotisations/payment_methods/mixins.py
Normal 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)
|
|
@ -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 :
|
||||
{% bootstrap_form articlesformset.empty_form label_class='sr-only' %}
|
||||
|
||||
|
@ -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 %}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Loading…
Reference in a new issue