mirror of
https://gitlab2.federez.net/re2o/re2o
synced 2024-11-25 22:22:26 +00:00
Passage du paiement par solde en paiement personnalisé.
This commit is contained in:
parent
3e18ebb7fb
commit
692b3b70b6
9 changed files with 128 additions and 61 deletions
|
@ -3,7 +3,7 @@
|
|||
from __future__ import unicode_literals
|
||||
|
||||
import cotisations.payment_methods.comnpay.aes_field
|
||||
import cotisations.payment_methods.models
|
||||
import cotisations.payment_methods.mixins
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
@ -47,7 +47,7 @@ class Migration(migrations.Migration):
|
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('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),
|
||||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ComnpayPayment',
|
||||
|
@ -57,7 +57,7 @@ class Migration(migrations.Migration):
|
|||
('payment_pass', cotisations.payment_methods.comnpay.aes_field.AESEncryptedField(blank=True, max_length=255, null=True)),
|
||||
('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),
|
||||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||
),
|
||||
migrations.RunPython(add_comnpay),
|
||||
migrations.RunPython(add_cheque),
|
||||
|
|
41
cotisations/migrations/0033_balancepayment.py
Normal file
41
cotisations/migrations/0033_balancepayment.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.7 on 2018-07-03 13:53
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import cotisations.payment_methods.mixins
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
def add_solde(apps, schema_editor):
|
||||
OptionalUser = apps.get_model('preferences', 'OptionalUser')
|
||||
options, _created = OptionalUser.objects.get_or_create()
|
||||
|
||||
Payment = apps.get_model('cotisations', 'Paiement')
|
||||
BalancePayment = apps.get_model('cotisations', 'BalancePayment')
|
||||
|
||||
solde, _created = Payment.objects.get_or_create(moyen="solde")
|
||||
balance = BalancePayment()
|
||||
balance.payment = solde
|
||||
balance.minimum_balance = options.solde_negatif
|
||||
balance.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cotisations', '0032_chequepayment_comnpaypayment'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='BalancePayment',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('minimum_balance', models.DecimalField(decimal_places=2, help_text='The minimal amount of money allowed for the balance at the end of a payment. You can specify negative amount.', max_digits=5, verbose_name='Minimum balance')),
|
||||
('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')),
|
||||
],
|
||||
bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model),
|
||||
),
|
||||
migrations.RunPython(add_solde)
|
||||
]
|
|
@ -668,7 +668,7 @@ class Paiement(RevMixin, AclMixin, models.Model):
|
|||
)
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': request.user.pk}
|
||||
kwargs={'userid': invoice.user.pk}
|
||||
))
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from . import comnpay, cheque, urls
|
||||
from . import comnpay, cheque, balance, urls
|
||||
|
||||
PAYMENT_METHODS = [
|
||||
comnpay,
|
||||
cheque,
|
||||
balance,
|
||||
]
|
||||
|
|
BIN
cotisations/payment_methods/balance/.views.py.swo
Normal file
BIN
cotisations/payment_methods/balance/.views.py.swo
Normal file
Binary file not shown.
7
cotisations/payment_methods/balance/__init__.py
Normal file
7
cotisations/payment_methods/balance/__init__.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
"""
|
||||
This module contains a method to pay online using user balance.
|
||||
"""
|
||||
from . import models
|
||||
NAME = "BALANCE"
|
||||
|
||||
PaymentMethod = models.BalancePayment
|
50
cotisations/payment_methods/balance/models.py
Normal file
50
cotisations/payment_methods/balance/models.py
Normal file
|
@ -0,0 +1,50 @@
|
|||
from django.db import models
|
||||
from django.shortcuts import redirect
|
||||
from django.urls import reverse
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import ugettext_lazy as _l
|
||||
from django.contrib import messages
|
||||
|
||||
|
||||
from cotisations.models import Paiement
|
||||
from cotisations.payment_methods.mixins import PaymentMethodMixin
|
||||
|
||||
|
||||
class BalancePayment(PaymentMethodMixin, models.Model):
|
||||
"""
|
||||
The model allowing you to pay with a cheque.
|
||||
"""
|
||||
payment = models.OneToOneField(
|
||||
Paiement,
|
||||
related_name='payment_method',
|
||||
editable=False
|
||||
)
|
||||
minimum_balance = models.DecimalField(
|
||||
verbose_name=_l("Minimum balance"),
|
||||
help_text=_l("The minimal amount of money allowed for the balance"
|
||||
" at the end of a payment. You can specify negative "
|
||||
"amount."
|
||||
),
|
||||
max_digits=5,
|
||||
decimal_places=2,
|
||||
)
|
||||
|
||||
def end_payment(self, invoice, request):
|
||||
user = invoice.user
|
||||
total_price = invoice.prix_total()
|
||||
if float(user.solde) - float(total_price) < self.minimum_balance:
|
||||
invoice.valid = False
|
||||
invoice.save()
|
||||
messages.error(
|
||||
request,
|
||||
_("Your balance is too low for this operation.")
|
||||
)
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': user.id}
|
||||
))
|
||||
return invoice.paiement.end_payment(
|
||||
invoice,
|
||||
request,
|
||||
use_payment_method=False
|
||||
)
|
|
@ -139,33 +139,6 @@ def new_facture(request, user, userid):
|
|||
articles = article_formset
|
||||
# Check if at leat one article has been selected
|
||||
if any(art.cleaned_data for art in articles):
|
||||
user_balance = OptionalUser.get_cached_value('user_solde')
|
||||
negative_balance = OptionalUser.get_cached_value('solde_negatif')
|
||||
# If the paiement using balance has been activated,
|
||||
# checking that the total price won't get the user under
|
||||
# the authorized minimum (negative_balance)
|
||||
if user_balance:
|
||||
# TODO : change Paiement to Payment
|
||||
if new_invoice_instance.paiement == (
|
||||
Paiement.objects.get_or_create(moyen='solde')[0]
|
||||
):
|
||||
total_price = 0
|
||||
for art_item in articles:
|
||||
if art_item.cleaned_data:
|
||||
total_price += (
|
||||
art_item.cleaned_data['article'].prix *
|
||||
art_item.cleaned_data['quantity']
|
||||
)
|
||||
if (float(user.solde) - float(total_price)
|
||||
< negative_balance):
|
||||
messages.error(
|
||||
request,
|
||||
_("Your balance is too low for this operation.")
|
||||
)
|
||||
return redirect(reverse(
|
||||
'users:profil',
|
||||
kwargs={'userid': userid}
|
||||
))
|
||||
new_invoice_instance.save()
|
||||
|
||||
# Building a purchase for each article sold
|
||||
|
|
|
@ -426,36 +426,31 @@ class User(RevMixin, FieldPermissionModelMixin, AbstractBaseUser,
|
|||
|
||||
@cached_property
|
||||
def solde(self):
|
||||
""" Renvoie le solde d'un user. Vérifie que l'option solde est
|
||||
activé, retourne 0 sinon.
|
||||
""" Renvoie le solde d'un user.
|
||||
Somme les crédits de solde et retire les débit payés par solde"""
|
||||
user_solde = OptionalUser.get_cached_value('user_solde')
|
||||
if user_solde:
|
||||
solde_objects = Paiement.objects.filter(moyen='Solde')
|
||||
somme_debit = Vente.objects.filter(
|
||||
facture__in=Facture.objects.filter(
|
||||
user=self,
|
||||
paiement__in=solde_objects,
|
||||
valid=True
|
||||
)
|
||||
).aggregate(
|
||||
total=models.Sum(
|
||||
models.F('prix')*models.F('number'),
|
||||
output_field=models.FloatField()
|
||||
)
|
||||
)['total'] or 0
|
||||
somme_credit = Vente.objects.filter(
|
||||
facture__in=Facture.objects.filter(user=self, valid=True),
|
||||
name="solde"
|
||||
).aggregate(
|
||||
total=models.Sum(
|
||||
models.F('prix')*models.F('number'),
|
||||
output_field=models.FloatField()
|
||||
)
|
||||
)['total'] or 0
|
||||
return somme_credit - somme_debit
|
||||
else:
|
||||
return 0
|
||||
solde_objects = Paiement.objects.filter(moyen='solde')
|
||||
somme_debit = Vente.objects.filter(
|
||||
facture__in=Facture.objects.filter(
|
||||
user=self,
|
||||
paiement__in=solde_objects,
|
||||
valid=True
|
||||
)
|
||||
).aggregate(
|
||||
total=models.Sum(
|
||||
models.F('prix')*models.F('number'),
|
||||
output_field=models.FloatField()
|
||||
)
|
||||
)['total'] or 0
|
||||
somme_credit = Vente.objects.filter(
|
||||
facture__in=Facture.objects.filter(user=self, valid=True),
|
||||
name="solde"
|
||||
).aggregate(
|
||||
total=models.Sum(
|
||||
models.F('prix')*models.F('number'),
|
||||
output_field=models.FloatField()
|
||||
)
|
||||
)['total'] or 0
|
||||
return somme_credit - somme_debit
|
||||
|
||||
def user_interfaces(self, active=True):
|
||||
""" Renvoie toutes les interfaces dont les machines appartiennent à
|
||||
|
|
Loading…
Reference in a new issue