# coding: utf8 from django.db import models from django.db.models import Q from django.forms import ModelForm, Form from django import forms from django.db.models.signals import post_save, post_delete from django.dispatch import receiver from amap.settings import RIGHTS_LINK, REQ_EXPIRE_HRS import re, uuid import datetime from django.utils import timezone from django.contrib.auth.models import AbstractBaseUser, BaseUserManager from panier.models import Credit, Commande, Panier def get_admin_right(): try: admin_right = ListRight.objects.get(listright="admin") except ListRight.DoesNotExist: admin_right = ListRight(listright="admin") admin_right.save() return admin_right class UserManager(BaseUserManager): def _create_user(self, pseudo, name, surname, email, password=None, su=False): if not pseudo: raise ValueError('Users must have an username') user = self.model( pseudo=pseudo, name=name, surname=surname, email=self.normalize_email(email), ) user.set_password(password) user.save(using=self._db) if su: user.make_admin() return user def create_user(self, pseudo, name, surname, email, password=None): """ Creates and saves a User with the given pseudo, name, surname, email, and password. """ return self._create_user(pseudo, name, surname, email, password, False) def create_superuser(self, pseudo, name, surname, email, password): """ Creates and saves a superuser with the given pseudo, name, surname, email, and password. """ return self._create_user(pseudo, name, surname, email, password, True) class User(AbstractBaseUser): STATE_ACTIVE = 0 STATE_DEACTIVATED = 1 STATE_ARCHIVED = 2 STATES = ( (0, 'STATE_ACTIVE'), (1, 'STATE_DEACTIVATED'), (2, 'STATE_ARCHIVED'), ) def auto_uid(): uids = list(range(int(min(UID_RANGES['users'])),int(max(UID_RANGES['users'])))) used_uids = [ user.uid_number for user in User.objects.all()] free_uids = [ id for id in uids if id not in used_uids] return min(free_uids) name = models.CharField(max_length=255) surname = models.CharField(max_length=255) pseudo = models.CharField(max_length=32, unique=True, help_text="Doit contenir uniquement des lettres, chiffres, ou tirets. ") email = models.EmailField(unique=True) telephone = models.CharField(max_length=15) comment = models.CharField(help_text="Commentaire, promo", max_length=255, blank=True) is_ens = models.BooleanField(default=True) state = models.IntegerField(choices=STATES, default=STATE_ACTIVE) registered = models.DateTimeField(auto_now_add=True) sac_consignes = models.IntegerField(default=0) USERNAME_FIELD = 'pseudo' REQUIRED_FIELDS = ['name', 'surname', 'email'] objects = UserManager() @property def is_active(self): return self.state == self.STATE_ACTIVE @property def is_staff(self): return self.is_admin @property def is_admin(self): try: Right.objects.get(user=self, right__listright='admin') except Right.DoesNotExist: return False return True @is_admin.setter def is_admin(self, value): if value and not self.is_admin: self.make_admin() elif not value and self.is_admin: self.un_admin() def get_full_name(self): return '%s %s' % (self.name, self.surname) def get_short_name(self): return self.name def has_perms(self, perms, obj=None): for perm in perms: if perm in RIGHTS_LINK: query = Q() for right in RIGHTS_LINK[perm]: query = query | Q(right__listright=right) if Right.objects.filter(Q(user=self) & query): return True try: Right.objects.get(user=self, right__listright=perm) except Right.DoesNotExist: return False return True def has_perm(self, perm, obj=None): return True def has_module_perms(self, app_label): # Simplest version again return True def make_admin(self): """ Make User admin """ user_admin_right = Right(user=self, right=get_admin_right()) user_admin_right.save() def un_admin(self): try: user_right = Right.objects.get(user=self,right=get_admin_right()) except Right.DoesNotExist: return user_right.delete() def solde(self): """ Renvoie le solde dynamiquement""" try: sac_prix = Panier.objects.get(nom="Sac").prix except Panier.DoesNotExist: # Pass silencieusement si l'objet n'existe pas sac_prix = 1 credit = sum(credit.montant for credit in Credit.objects.filter(user=self) if credit.validite) debit = sum(commande.prix_unitaire*commande.quantite for commande in Commande.objects.filter(user=self)) + self.sac_consignes*sac_prix return credit-debit def __str__(self): return self.pseudo class Right(models.Model): user = models.ForeignKey('User', on_delete=models.PROTECT) right = models.ForeignKey('ListRight', on_delete=models.PROTECT) class Meta: unique_together = ("user", "right") def __str__(self): return str(self.user) + " - " + str(self.right) class ListRight(models.Model): listright = models.CharField(max_length=255, unique=True) def __str__(self): return self.listright class Request(models.Model): PASSWD = 'PW' EMAIL = 'EM' TYPE_CHOICES = ( (PASSWD, 'Mot de passe'), (EMAIL, 'Email'), ) type = models.CharField(max_length=2, choices=TYPE_CHOICES) token = models.CharField(max_length=32) user = models.ForeignKey('User', on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now_add=True, editable=False) expires_at = models.DateTimeField() def save(self): if not self.expires_at: self.expires_at = timezone.now() \ + datetime.timedelta(hours=REQ_EXPIRE_HRS) if not self.token: self.token = str(uuid.uuid4()).replace('-', '') # remove hyphens super(Request, self).save() class BaseInfoForm(ModelForm): def __init__(self, *args, **kwargs): super(BaseInfoForm, self).__init__(*args, **kwargs) self.fields['name'].label = 'Prénom' self.fields['surname'].label = 'Nom' self.fields['comment'].label = 'Commentaire' self.fields['is_ens'].label = 'Eleve ou personnel ENS Paris-Saclay' class Meta: model = User fields = [ 'name', 'surname', 'pseudo', 'email', 'telephone', 'comment', 'is_ens', ] class EditInfoForm(BaseInfoForm): class Meta(BaseInfoForm.Meta): fields = [ 'name', 'surname', 'pseudo', 'email', 'telephone', 'comment', 'is_ens', ] class UserForm(BaseInfoForm): class Meta(BaseInfoForm.Meta): fields = '__all__' class PasswordForm(ModelForm): class Meta: model = User fields = ['password'] class StateForm(ModelForm): class Meta: model = User fields = ['state'] class ListRightForm(ModelForm): class Meta: model = ListRight fields = ['listright'] def __init__(self, *args, **kwargs): super(ListRightForm, self).__init__(*args, **kwargs) self.fields['listright'].label = 'Nom du droit/groupe' class NewListRightForm(ListRightForm): class Meta(ListRightForm.Meta): fields = '__all__' def __init__(self, *args, **kwargs): super(NewListRightForm, self).__init__(*args, **kwargs) class DelListRightForm(ModelForm): listrights = forms.ModelMultipleChoiceField(queryset=ListRight.objects.all(), label="Droits actuels", widget=forms.CheckboxSelectMultiple) class Meta: exclude = ['listright'] model = ListRight class RightForm(ModelForm): def __init__(self, *args, **kwargs): super(RightForm, self).__init__(*args, **kwargs) self.fields['right'].label = 'Droit' self.fields['right'].empty_label = "Choisir un nouveau droit" class Meta: model = Right fields = ['right'] class DelRightForm(ModelForm): rights = forms.ModelMultipleChoiceField(queryset=Right.objects.all(), label="Droits actuels", widget=forms.CheckboxSelectMultiple) class Meta: model = Right exclude = ['user', 'right'] class ProfilForm(Form): user = forms.CharField(label='Ok', max_length=100)