models.py 4.13 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# -*- 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  Hugo Levy-Falk
#
# 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.
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
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.
    """
37 38 39 40

    class Meta:
        verbose_name = _l("User Balance")

41 42
    payment = models.OneToOneField(
        Paiement,
43
        on_delete=models.CASCADE,
44 45 46 47 48 49 50 51 52 53 54
        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,
55
        default=0,
56
    )
57 58 59 60 61
    maximum_balance = models.DecimalField(
        verbose_name=_l("Maximum balance"),
        help_text=_l("The maximal amount of money allowed for the balance."),
        max_digits=5,
        decimal_places=2,
62 63 64
        default=50,
        blank=True,
        null=True,
65
    )
66 67 68 69
    credit_balance_allowed = models.BooleanField(
        verbose_name=_l("Allow user to credit their balance"),
        default=False,
    )
70 71

    def end_payment(self, invoice, request):
72 73 74
        """Changes the user's balance to pay the invoice. If it is not
        possible, shows an error and invalidates the invoice.
        """
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
        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
        )
93 94

    def valid_form(self, form):
95
        """Checks that there is not already a balance payment method."""
96 97 98 99 100 101 102 103
        p = Paiement.objects.filter(is_balance=True)
        if len(p) > 0:
            form.add_error(
                'payment_method',
                _("There is already a payment type for user balance")
            )

    def alter_payment(self, payment):
104
        """Register the payment as a balance payment."""
105
        self.payment.is_balance = True
106

107 108
    def check_price(self, price, user, *args, **kwargs):
        """Checks that the price meets the requirement to be paid with user
109 110
        balance.
        """
111 112 113 114
        return (
            float(user.solde) - float(price) >= self.minimum_balance,
            _("Your balance is too low for this operation.")
        )
115 116 117 118 119 120

    def can_credit_balance(self, user_request):
        return (
            len(Paiement.find_allowed_payments(user_request)
                .exclude(is_balance=True)) > 0
        ) and self.credit_balance_allowed