from django.db import models from django.core.validators import MinValueValidator, MaxValueValidator from django.core.exceptions import ValidationError from django.core.urlresolvers import reverse class RecurringPayment(models.Model): def get_last_validated_update(self): for update in self.updates.all(): if update.validated: return update get_last_validated_update.short_description = 'Paiement' def payment_type(self): if hasattr(self, 'adhesion'): return 'Adhésion' if hasattr(self, 'service'): return 'Service' payment_type.short_description = 'Type' def payment_object(self): return self.adhesion if hasattr(self, 'adhesion') else self.service def get_absolute_url(self): return reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name), args=(self.pk,)) def get_status(self): payment = self.get_last_validated_update() return payment is not None and payment.payment_method != PaymentUpdate.STOP get_status.short_description = 'Actif' get_status.boolean = True class Meta: verbose_name = 'paiement récurrent' verbose_name_plural = 'paiements récurrents' def __str__(self): payment = self.get_last_validated_update() return str(payment) if payment else "pas de paiement" class PaymentUpdate(models.Model): STOP = 0 FREE = 1 DEBIT = 2 TRANSFER = 3 PAYMENT_CHOICES = ( (DEBIT, 'Prélèvement'), (TRANSFER, 'Virement'), (FREE, 'Gratuit'), (STOP, 'Arrêt'), ) created = models.DateTimeField(auto_now_add=True) payment = models.ForeignKey(RecurringPayment, related_name='updates') amount = models.DecimalField(max_digits=9, decimal_places=2, verbose_name='Montant') period = models.PositiveIntegerField(validators=[MinValueValidator(1), MaxValueValidator(12)], verbose_name='Période (mois)') payment_method = models.IntegerField(choices=PAYMENT_CHOICES, default=DEBIT, verbose_name='Méthode de paiement') start = models.DateTimeField(verbose_name='Date') validated = models.BooleanField(default=False, verbose_name='Saisie bancaire effectuée') class Meta: verbose_name = 'paiement' ordering = ('-start',) def clean(self): super().clean() errors = {} if self.payment_method == PaymentUpdate.STOP and self.amount: errors.update({'amount': "Pour l’arrêt d’un paiement, le montant doit être nul."}) if errors: raise ValidationError(errors) def period_verbose(self): if self.period == 0: return 'non récurrent' elif self.period == 1: return 'mensuel' elif self.period == 3: return 'trimestriel' elif self.period == 6: return 'biannuel' elif self.period == 12: return 'annuel' else: return '%d mois' % self.period def __str__(self): if self.payment_method == self.STOP: return 'paiement arrêté' s = str(self.amount) + '€' if self.period: if self.period == 1: s += '/mois' elif self.period == 12: s += '/an' else: s += '/%d mois' % self.period if self.payment_method == self.DEBIT: s += ' (prélèvement)' elif self.payment_method == self.TRANSFER: s += ' (virement)' elif self.payment_method == self.CASH: s += ' (liquide)' return s