diff --git a/cotisations/migrations/0030_custom_payment.py b/cotisations/migrations/0030_custom_payment.py index bdd7cde9..785cc06c 100644 --- a/cotisations/migrations/0030_custom_payment.py +++ b/cotisations/migrations/0030_custom_payment.py @@ -103,6 +103,7 @@ class Migration(migrations.Migration): ('payment_credential', models.CharField(blank=True, default='', max_length=255, verbose_name='ComNpay VAD Number')), ('payment_pass', re2o.aes_field.AESEncryptedField(blank=True, max_length=255, null=True, verbose_name='ComNpay Secret Key')), ('payment', models.OneToOneField(editable=False, on_delete=django.db.models.deletion.CASCADE, related_name='payment_method', to='cotisations.Paiement')), + ('minimum_payment', models.DecimalField(decimal_places=2, default=1, help_text='The minimal amount of money you have to use when paying with ComNpay', max_digits=5, verbose_name='Minimum payment')), ], bases=(cotisations.payment_methods.mixins.PaymentMethodMixin, models.Model), ), diff --git a/cotisations/models.py b/cotisations/models.py index 923b0b98..8b6d5a8c 100644 --- a/cotisations/models.py +++ b/cotisations/models.py @@ -155,7 +155,7 @@ class Facture(RevMixin, AclMixin, FieldPermissionModelMixin, models.Model): models.F('prix')*models.F('number'), output_field=models.FloatField() ) - )['total'] + )['total'] or 0 def name(self): """ diff --git a/cotisations/payment_methods/balance/models.py b/cotisations/payment_methods/balance/models.py index 958906fa..b4ae7e40 100644 --- a/cotisations/payment_methods/balance/models.py +++ b/cotisations/payment_methods/balance/models.py @@ -95,3 +95,24 @@ class BalancePayment(PaymentMethodMixin, models.Model): def alter_payment(self, payment): """Register the payment as a balance payment.""" self.payment.is_balance = True + + def check_invoice(self, invoice_form): + """Checks that a invoice meets the requirement to be paid with user + balance. + + Args: + invoice_form: The invoice_form which is to be checked. + + Returns: + True if the form is valid for this payment. + + """ + user = invoice_form.instance.user + total_price = invoice_form.instance.prix_total() + if float(user.solde) - float(total_price) < self.minimum_balance: + invoice_form.add_error( + 'paiement', + _("Your balance is too low for this operation.") + ) + return False + return True diff --git a/cotisations/payment_methods/comnpay/models.py b/cotisations/payment_methods/comnpay/models.py index d32e0a06..4dfe62de 100644 --- a/cotisations/payment_methods/comnpay/models.py +++ b/cotisations/payment_methods/comnpay/models.py @@ -53,6 +53,14 @@ class ComnpayPayment(PaymentMethodMixin, models.Model): blank=True, verbose_name=_l("ComNpay Secret Key"), ) + minimum_payment = models.DecimalField( + verbose_name=_l("Minimum payment"), + help_text=_l("The minimal amount of money you have to use when paying" + " with ComNpay"), + max_digits=5, + decimal_places=2, + default=1, + ) def end_payment(self, invoice, request): """ @@ -86,3 +94,23 @@ class ComnpayPayment(PaymentMethodMixin, models.Model): 'amount': invoice.prix_total(), } return render(request, 'cotisations/payment.html', r) + + def check_invoice(self, invoice_form): + """Checks that a invoice meets the requirement to be paid with ComNpay. + + Args: + invoice_form: The invoice_form which is to be checked. + + Returns: + True if the form is valid for ComNpay. + + """ + if invoice_form.instance.prix_total() < self.minimum_payment: + invoice_form.add_error( + 'paiement', + _('In order to pay your invoice with ComNpay' + ', the price must be grater than {} €') + .format(self.minimum_payment) + ) + return False + return True diff --git a/cotisations/views.py b/cotisations/views.py index f561147b..2d7de6c6 100644 --- a/cotisations/views.py +++ b/cotisations/views.py @@ -74,6 +74,7 @@ from .forms import ( ) from .tex import render_invoice from .payment_methods.forms import payment_method_factory +from cotisations.utils import find_payment_method @login_required @@ -118,8 +119,8 @@ def new_facture(request, user, userid): # Check if at leat one article has been selected if any(art.cleaned_data for art in articles): new_invoice_instance.save() - # Building a purchase for each article sold + purchases = [] for art_item in articles: if art_item.cleaned_data: article = art_item.cleaned_data['article'] @@ -132,17 +133,24 @@ def new_facture(request, user, userid): duration=article.duration, number=quantity ) - new_purchase.save() - - return new_invoice_instance.paiement.end_payment( - new_invoice_instance, - request + purchases.append(new_purchase) + p = find_payment_method(new_invoice_instance.paiement) + if hasattr(p, 'check_invoice'): + accept = p.check_invoice(invoice_form) + else: + accept = True + if accept: + return new_invoice_instance.paiement.end_payment( + new_invoice_instance, + request + ) + else: + new_invoice_instance.delete() + else: + messages.error( + request, + _("You need to choose at least one article.") ) - - messages.error( - request, - _("You need to choose at least one article.") - ) p = Paiement.objects.filter(is_balance=True) if len(p) and p[0].can_use_payment(request.user): balance = user.solde