from django.db import models
from django.urls import reverse
from django.contrib.auth.models import User as AuthUser
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.urls import reverse
from django.utils.html import format_html
from djadhere.utils import get_active_filter
from banking.models import RecurringPayment, PaymentUpdate
class ActiveAdhesionManager(models.Manager):
def get_queryset(self):
qs = super().get_queryset()
qs = qs.annotate(
payment_method=models.Subquery(
PaymentUpdate.objects.filter(payment=models.OuterRef('membership__pk'))
.values('payment_method')[:1]
)
)
qs = qs.annotate(
active=models.Case(
models.When(payment_method__isnull=True, then=None),
models.When(payment_method=PaymentUpdate.STOP, then=False),
default=True,
output_field=models.NullBooleanField()
)
)
return qs
class User(AuthUser):
def get_model_perms(self, request):
return {}
@property
def adhesions(self): # user and corporations (for which the user is a member) adhesions
return self.profile.adhesions
class Meta:
proxy = True
verbose_name = 'personne physique'
verbose_name_plural = 'personnes physiques'
def get_absolute_url(self):
return reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name), args=(self.pk,))
def __str__(self):
return self.get_full_name() or self.username
class Corporation(models.Model):
social_reason = models.CharField(max_length=256, verbose_name='Raison sociale', unique=True)
description = models.TextField(blank=True, default='')
members = models.ManyToManyField(User, blank=True, verbose_name='Membres',
related_name='corporations', related_query_name='corporation')
email = models.EmailField(verbose_name='Adresse e-mail', blank=True)
phone_number = models.CharField(max_length=16, blank=True, default='',
verbose_name='Numéro de téléphone')
address = models.TextField(blank=True, default='', verbose_name='Adresse')
notes = models.TextField(blank=True, default='')
class Meta:
verbose_name = 'personne morale'
verbose_name_plural = 'personnes morales'
def get_absolute_url(self):
return reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name), args=(self.pk,))
def __str__(self):
return self.social_reason
# Terminologie : une « adhésion » désgine une instance de ce modèle
# tandis qu’un·e « adhérent·e » désigne un·e user ou une corporation.
class Adhesion(models.Model):
limit = models.Q(app_label='auth', model='user') \
| models.Q(app_label='adhesions', model='corporation')
id = models.AutoField(verbose_name='Numéro d’adhérent·e', primary_key=True, editable=True)
created = models.DateTimeField(null=True, blank=True, auto_now_add=True)
notes = models.TextField(blank=True, default='', verbose_name='Notes (obsolète)', help_text='Obsolète, ne plus ajouter d’informations ici.')
active_legacy = models.NullBooleanField(default=None, verbose_name='Adhésion en cours')
user = models.OneToOneField(User, null=True, on_delete=models.PROTECT)
corporation = models.OneToOneField(Corporation, null=True, on_delete=models.PROTECT)
membership = models.OneToOneField(RecurringPayment, on_delete=models.CASCADE)
objects = ActiveAdhesionManager()
def save(self, *args, **kwargs):
if not hasattr(self, 'membership'):
self.membership = RecurringPayment.objects.create()
super().save(*args, **kwargs)
class Meta:
verbose_name = 'adhésion'
ordering = ('id',)
def is_physical(self):
return self.user is not None
def is_moral(self):
return self.corporation is not None
@property
def type(self):
if self.is_physical():
return 'Personne physique'
else:
return 'Personne morale'
@property
def adherent(self):
if self.is_physical():
return self.user
else:
return self.corporation
def get_adherent_link(self):
return format_html(u'{}', self.adherent.get_absolute_url(), self.adherent)
get_adherent_link.short_description = 'Nom ou raison sociale'
def get_adhesion_link(self):
return format_html(u'ADT{}', self.get_absolute_url(), str(self.id))
get_adhesion_link.short_description = 'Numéro d’adhérent·e'
def get_absolute_url(self):
return reverse('admin:%s_%s_change' % (self._meta.app_label, self._meta.model_name), args=(self.pk,))
def is_active(self):
return self.active
is_active.boolean = True
is_active.short_description = 'Actif'
def __str__(self):
return 'ADT%d' % self.id
if self.id is None:
return '?'
else:
return 'ADT%d (%s)' % (self.id, self.adherent)