diff --git a/noethysweb/core/decorators.py b/noethysweb/core/decorators.py index 2a3d24f2..42585211 100644 --- a/noethysweb/core/decorators.py +++ b/noethysweb/core/decorators.py @@ -2,12 +2,12 @@ # Copyright (c) 2019-2021 Ivan LUCAS. # Noethysweb, application de gestion multi-activités. # Distribué sous licence GNU GPL. - +import logging +logger = logging.getLogger(__name__) from django.urls import reverse_lazy, reverse from django.http import HttpResponseRedirect, HttpResponseBadRequest, HttpResponseForbidden -from django.contrib.auth import REDIRECT_FIELD_NAME -from django.contrib.auth.decorators import user_passes_test from reglements.utils import utils_ventilation +from core.models import PortailParametre def Verifie_ventilation(function): @@ -39,6 +39,10 @@ def _function(request, *args, **kwargs): def secure_ajax_portail(function): """ A associer aux requêtes AJAX """ def _function(request, *args, **kwargs): + compte_famille = PortailParametre.objects.filter(code="compte_famille").first() + compte_individu = PortailParametre.objects.filter(code="compte_individu").first() + # logger.debug("compte_famille: %s" % compte_famille.valeur) + # logger.debug("compte_individu: %s" % compte_individu.valeur) # Vérifie que c'est une requête AJAX if not request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest': return HttpResponseBadRequest() @@ -46,8 +50,11 @@ def _function(request, *args, **kwargs): if not request.user.is_authenticated: return HttpResponseForbidden() # Vérifie que c'est un user de type utilisateur - if request.user.categorie != "famille": + # et que si le paramètre de compte individu est true ( coché ) alors interdire l'accès ou l'utilisation des identifiants famille + if((request.user.categorie not in ["famille", "individu"]) # Vérification de la catégorie : Si l'utilisateur n'est ni "famille" ni "individu", l'accès est interdit. + or (compte_famille != "True" and request.user.categorie == "famille") #Compte famille non activé pour une famille: Si compte_famille n'est pas "True" et que la catégorie est "famille", l'accès est interdit. + or ( compte_individu == "True" and request.user.categorie == "famille")): #Compte individu activé pour une famille: Si compte_individu est "True" alors que l'utilisateur est de catégorie "famille", l'accès est interdit. + # if request.user.categorie != "individu": return HttpResponseForbidden() return function(request, *args, **kwargs) return _function - diff --git a/noethysweb/core/models.py b/noethysweb/core/models.py index 3075ab72..056ada44 100644 --- a/noethysweb/core/models.py +++ b/noethysweb/core/models.py @@ -1649,7 +1649,17 @@ class Meta: def __str__(self): return "Remplissage ID%d" % self.idremplissage if self.idremplissage else "Nouveau" +class CategorieCompteInternet(models.Model): + idcategorie = models.AutoField(verbose_name="ID", db_column='IDcategorie', primary_key=True) + nom = models.CharField(verbose_name="Nom", max_length=200) + class Meta: + db_table = 'categories_compte_internet' + verbose_name = "catégorie de compte internet" + verbose_name_plural = "catégories de compte internet" + + def __str__(self): + return self.nom class Individu(models.Model): idindividu = models.AutoField(verbose_name="ID", db_column='IDindividu', primary_key=True) @@ -1696,6 +1706,17 @@ class Individu(models.Model): type_garde_choix = [(1, "Mère"), (2, "Père"), (3, "Garde alternée"), (4, "Autre personne")] type_garde = models.IntegerField(verbose_name=_("Type de garde"), choices=type_garde_choix, blank=True, null=True) info_garde = models.TextField(verbose_name=_("Information sur la garde"), blank=True, null=True) + # new attributs + internet_categorie = models.ForeignKey(CategorieCompteInternet, verbose_name="Catégorie",related_name="internet_categori", on_delete=models.PROTECT, blank=True,null=True) + internet_actif = models.BooleanField(verbose_name="Compte internet activé", default=True) + internet_identifiant = encrypt(models.CharField(verbose_name="Identifiant", max_length=200, blank=True, null=True)) + internet_mdp = encrypt(models.CharField(verbose_name="Mot de passe", max_length=200, blank=True, null=True)) + internet_secquest = models.CharField(verbose_name="Question", max_length=200, blank=True, null=True) + internet_reservations = models.BooleanField(verbose_name="Autoriser les réservations sur le portail", default=True) + mobile = encrypt(models.CharField(verbose_name="Portable favori", max_length=100, blank=True, null=True)) + utilisateur = models.OneToOneField(Utilisateur, on_delete=models.CASCADE, null=True) + certification_date = models.DateTimeField(verbose_name="Date de certification", blank=True, null=True) + blocage_impayes_off = models.BooleanField(verbose_name="Ne jamais appliquer le blocage des réservations si impayés",default=False,help_text="En cochant cette case, vous permettez à cette famille d'accéder aux réservations du portail même s'il y a des impayés et que le paramètre 'blocage si impayés' a été activé dans les paramètres généraux du portail.") class Meta: db_table = 'individus' @@ -1767,6 +1788,9 @@ def Maj_infos(self): self.ville_resid = dict_adresse["ville"] self.secteur = dict_adresse["secteur"] self.save() + def save_individu(sender, instance, **kwargs): + if hasattr(instance, 'individu'): + instance.individu.save() class Scolarite(models.Model): @@ -1787,19 +1811,6 @@ def __str__(self): return "Etape de scolarité du %s au %s" % (self.date_debut.strftime('%d/%m/%Y'), self.date_fin.strftime('%d/%m/%Y')) -class CategorieCompteInternet(models.Model): - idcategorie = models.AutoField(verbose_name="ID", db_column='IDcategorie', primary_key=True) - nom = models.CharField(verbose_name="Nom", max_length=200) - - class Meta: - db_table = 'categories_compte_internet' - verbose_name = "catégorie de compte internet" - verbose_name_plural = "catégories de compte internet" - - def __str__(self): - return self.nom - - class Famille(models.Model): idfamille = models.AutoField(verbose_name="ID", db_column='IDfamille', primary_key=True) date_creation = models.DateTimeField(verbose_name="Date de création", auto_now_add=True) @@ -1848,7 +1859,8 @@ class Famille(models.Model): mobile_blocage = models.BooleanField(verbose_name="La famille ne souhaite pas recevoir de SMS groupés", default=False, help_text="L'éditeur de SMS groupés du menu Outils ne proposera pas cette famille dans les destinataires.") individus_masques = models.ManyToManyField(Individu, verbose_name="Individus masqués", related_name="individus_masques", blank=True) blocage_impayes_off = models.BooleanField(verbose_name="Ne jamais appliquer le blocage des réservations si impayés", default=False, help_text="En cochant cette case, vous permettez à cette famille d'accéder aux réservations du portail même s'il y a des impayés et que le paramètre 'blocage si impayés' a été activé dans les paramètres généraux du portail.") - + contact_facturation = models.ForeignKey(Individu, verbose_name="Contact facturation", related_name="contact_facturation", on_delete=models.SET_NULL, blank=True, null=True) + utilisateur = models.OneToOneField(Utilisateur, on_delete=models.CASCADE, null=True) class Meta: db_table = 'familles' verbose_name = "famille" @@ -1907,18 +1919,25 @@ def Maj_infos(self, maj_adresse=True, maj_mail=True, maj_mobile=True, maj_titula # Titulaire Hélios if maj_titulaire_helios: - if self.titulaire_helios: - # recherche si le titulaire est toujours dans la famille - found = False - for rattachement in rattachements: - if rattachement.individu == self.titulaire_helios: - found = True - if not found: - self.titulaire_helios = None - if not self.titulaire_helios: - # Recherche un individu valide parmi les titulaires de la famille - if rattachements: - self.titulaire_helios = rattachements.first().individu + try: + if self.titulaire_helios: + # Recherche si le titulaire est toujours dans la famille + found = False + for rattachement in rattachements: + if rattachement.individu == self.titulaire_helios: + found = True + break # Si trouvé, on sort de la boucle + if not found: + # Si le titulaire n'est pas trouvé dans la famille, on le met à None + self.titulaire_helios = None + except Individu.DoesNotExist: + # Si le titulaire a été supprimé, on le met à None + self.titulaire_helios = None + + # Assurez-vous qu'il y a un titulaire dans la famille si nécessaire + if not self.titulaire_helios and rattachements.exists(): + # Recherche un individu valide parmi les rattachements + self.titulaire_helios = rattachements.first().individu if maj_tiers_solidaire: if self.tiers_solidaire: @@ -1949,6 +1968,11 @@ def Maj_infos(self, maj_adresse=True, maj_mail=True, maj_mobile=True, maj_titula def Get_rue_resid(self): return self.rue_resid.replace("\n", "
") if self.rue_resid else None + + def Get_nom(self): + texte = "" + texte = self.nom + return texte def Get_infos(self, avec_civilite=False): """ Renvoie le nom des titulaires """ @@ -3042,6 +3066,8 @@ class Destinataire(models.Model): categorie = models.CharField(verbose_name="Catégorie", max_length=300, blank=True, null=True) individu = models.ForeignKey(Individu, verbose_name="Individu", blank=True, null=True, on_delete=models.CASCADE) famille = models.ForeignKey(Famille, verbose_name="Famille", blank=True, null=True, on_delete=models.CASCADE) + inscription = models.ForeignKey(Inscription, verbose_name="Inscription", blank=True, null=True,on_delete=models.CASCADE) + activites = models.ForeignKey(Activite, verbose_name="Activites", blank=True, null=True, on_delete=models.CASCADE) collaborateur = models.ForeignKey("Collaborateur", verbose_name="Collaborateur", blank=True, null=True, on_delete=models.CASCADE) contact = models.ForeignKey(Contact, verbose_name="Contact", blank=True, null=True, on_delete=models.CASCADE) liste_diffusion = models.ForeignKey(ListeDiffusion, verbose_name="Liste de diffusion", blank=True, null=True, on_delete=models.CASCADE) @@ -3144,7 +3170,7 @@ def Is_famille_authorized(self, famille=None): class PortailParametre(models.Model): idparametre = models.AutoField(verbose_name="ID", db_column='IDparametre', primary_key=True) - code = models.CharField(verbose_name="Code", max_length=200, blank=True, null=True) + code = models.CharField(verbose_name="Code", max_length=200, blank=True, null=True, unique=True) valeur = models.TextField(verbose_name="Valeur", blank=True, null=True) class Meta: @@ -3202,9 +3228,10 @@ def __str__(self): class PortailMessage(models.Model): idmessage = models.AutoField(verbose_name="ID", db_column='IDmessage', primary_key=True) - famille = models.ForeignKey(Famille, verbose_name="Famille", on_delete=models.CASCADE) - structure = models.ForeignKey(Structure, verbose_name="Structure", on_delete=models.CASCADE) - utilisateur = models.ForeignKey(Utilisateur, verbose_name="Utilisateur", blank=True, null=True, on_delete=models.PROTECT) + famille = models.ForeignKey(Famille, verbose_name="Famille", on_delete=models.CASCADE, db_index=True) + individu = models.ForeignKey(Individu, verbose_name="Individu", on_delete=models.CASCADE, null=True, db_index=True) + structure = models.ForeignKey(Structure, verbose_name="Structure", on_delete=models.CASCADE, db_index=True) + utilisateur = models.ForeignKey(Utilisateur, verbose_name="Utilisateur", blank=True, null=True,on_delete=models.PROTECT) texte = models.TextField(verbose_name="Texte") date_creation = models.DateTimeField(verbose_name="Date de création", auto_now_add=True) date_lecture = models.DateTimeField(verbose_name="Date de lecture", max_length=200, blank=True, null=True) @@ -3213,6 +3240,14 @@ class Meta: db_table = 'portail_messages' verbose_name = "message" verbose_name_plural = "messages" + indexes = [ + models.Index(fields=["famille"]), + models.Index(fields=["individu"]), + models.Index(fields=["structure"]), + models.Index(fields=["utilisateur"]), + models.Index(fields=["date_creation"]), + models.Index(fields=["date_lecture"]), + ] def __str__(self): return "Message ID%d" % self.idmessage if self.idmessage else "Nouveau message" diff --git a/noethysweb/core/templates/core/header.html b/noethysweb/core/templates/core/header.html index 5b468fdf..3783812d 100644 --- a/noethysweb/core/templates/core/header.html +++ b/noethysweb/core/templates/core/header.html @@ -104,7 +104,7 @@ {% if perms.core.factures_generation %}{% endif %} {% if perms.core.rappels_generation %}{% endif %} {% endif %} - + {% if perms.core.famille_reglements_ajouter %}{% endif %} @@ -120,7 +120,6 @@ - {# Messagerie #} {% if liste_messages_non_lus %} {% endif %} @@ -166,7 +175,7 @@