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.core.urlresolvers import reverse
from django.utils.html import format_html
from djadhere.utils import get_active_filter
from banking.models import Payment
# Terminologie : une « adhésion » désgine une instance de ce modèle
# tandis qu’un « adhérent » désigne un 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', primary_key=True, editable=True)
adherent_type = models.ForeignKey(ContentType, on_delete=models.CASCADE,
limit_choices_to=limit, verbose_name='Type d’adhérent')
adherent_id = models.PositiveIntegerField(verbose_name='ID')
adherent = GenericForeignKey('adherent_type', 'adherent_id')
contributions = GenericRelation(Payment,
content_type_field='reason_type',
object_id_field='reason_id',
related_query_name='adhesion')
created = models.DateTimeField(null=True, blank=True, auto_now_add=True)
notes = models.TextField(blank=True, default='')
class Meta:
verbose_name = 'adhésion'
unique_together = ("adherent_type", "adherent_id")
ordering = ('id',)
@property
def contribution(self):
try:
return self.contributions.exclude(period=0).filter(get_active_filter()).get()
except Payment.DoesNotExist:
return None
# MultipleObjectsReturned non catché volontairement, le filtrage par la méthode clean est censé
# empêcher cette possibilité, si cette exception est levé on veut recevoir un mail avec l’erreur !
def is_physical(self):
return self.adherent_type.app_label == 'auth' and self.adherent_type.model == 'user'
def is_moral(self):
return self.adherent_type.app_label == 'adhesions' and self.adherent_type.model == 'corporation'
@property
def type(self):
if self.is_physical():
return 'Personne physique'
else:
return 'Personne morale'
def get_adherent_name(self):
if self.is_physical():
return str(self.adherent.profile)
else:
return str(self.adherent)
get_adherent_name.short_description = 'Nom ou raison sociale'
def get_adherent_link(self):
url = reverse('admin:adhesions_%s_change' % self.adherent._meta.model_name, args=(self.adherent.id,))
return format_html(u'{}', url, self.get_adherent_name())
get_adherent_link.short_description = 'Nom ou raison sociale'
def get_adhesion_link(self):
url = reverse('admin:adhesions_adhesion_change', args=(self.id,))
return format_html(u'ADT{}', url, str(self.id))
def __str__(self):
return 'ADT%d' % self.id
if self.id is None:
return '?'
else:
return 'ADT%d (%s)' % (self.id, self.get_adherent_name())
class User(AuthUser):
class Meta:
proxy = True
verbose_name = 'personne physique'
verbose_name_plural = 'personnes physiques'
def get_model_perms(self, request):
return {}
@property
def adhesion(self): # user adhesion
return self.profile.adhesion
@property
def adhesions(self): # user and corporations (for which the user is a member) adhesions
return self.profile.adhesions
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='')
@property
def adhesion(self):
ctype = ContentType.objects.get_for_model(self)
try:
return Adhesion.objects.get(adherent_type=ctype, adherent_id=self.pk)
except Adhesion.DoesNotExist:
return None
class Meta:
verbose_name = 'personne morale'
verbose_name_plural = 'personnes morales'
def __str__(self):
return self.social_reason