Modification User.email modifi personne.courriel au besoin
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / chercheurs / models.py
CommitLineData
932eef9a 1# -*- encoding: utf-8 -*-
92990258 2import hashlib
fdcf5874 3
5212238e 4from datamaster_modeles.models import *
43ed73e7 5from django.conf import settings
fdcf5874
EMS
6from django.contrib.auth.models import User
7from django.core.urlresolvers import reverse as url
932eef9a 8from django.db import models
a2c6bb72 9from django.db.models import Q
92990258 10from django.utils.encoding import smart_str
43ed73e7 11from django.utils.hashcompat import sha_constructor
0827a595 12from django.db.models.signals import post_save
5212238e 13from djangosphinx.models import SphinxSearch
fdcf5874
EMS
14
15from savoirs.models import Discipline, SEPManager, SEPSphinxQuerySet, SEPQuerySet, Search
932eef9a 16
13146d99 17GENRE_CHOICES = (('m', 'Homme'), ('f', 'Femme'))
932eef9a 18class Personne(models.Model):
ece89aca 19 user = models.OneToOneField(User, related_name="chercheur", verbose_name="utilisateur", null=True, blank=True)
595ab4d6 20 salutation = models.CharField(max_length=128, null=True, blank=True)
932eef9a 21 nom = models.CharField(max_length=255)
595ab4d6 22 prenom = models.CharField(max_length=128, verbose_name='prénom')
165da916
EMS
23 courriel = models.EmailField(max_length=128, verbose_name="courriel")
24 afficher_courriel = models.BooleanField(default=True)
595ab4d6 25 fonction = models.CharField(max_length=128, null=True, blank=True)
c18af6bd 26 date_naissance = models.DateField(null=True, blank=True)
595ab4d6 27 sousfonction = models.CharField(max_length=128, null=True, blank=True, verbose_name='sous-fonction')
0a379c77
EMS
28 telephone = models.CharField(max_length=32, null=True, blank=True, verbose_name='numéro de téléphone')
29 adresse_postale = models.TextField(blank=True)
932eef9a 30 genre = models.CharField(max_length=1, choices=GENRE_CHOICES)
595ab4d6 31 commentaire = models.TextField(verbose_name='commentaires', null=True, blank=True)
3e556e66 32 actif = models.BooleanField(editable=False, default=False)
932eef9a
AJ
33
34 def __unicode__(self):
35 return u"%s %s, %s" % (self.prenom, self.nom, self.courriel)
36
37 class Meta:
13ec4813 38 ordering = ["nom", "prenom"]
92990258 39
a00480ad
PP
40 def save(self, *args, **kwargs):
41
6adcf00f
PP
42 try:
43 old_instance = Personne.objects.get(pk=self.pk)
44 if self.courriel != old_instance.courriel:
45 try:
46 user = User.objects.get(email=old_instance.courriel)
47 user.email = self.courriel
48 user.save()
49 except User.DoesNotExist:
50 pass
51 except Personne.DoesNotExist:
52 pass
a00480ad
PP
53
54 super(Personne, self).save(*args, **kwargs)
55
705013cb
EMS
56 @property
57 def civilite(self):
58 if self.genre == 'm':
59 return 'M.'
60 elif self.genre == 'f':
61 return 'Mme'
62 else:
63 return ''
64
bd93f955
PP
65 @property
66 def prenom_nom(self):
67 return u"%s %s" % (self.prenom, self.nom)
68
3a3d9c6f
EMS
69 def courriel_display(self):
70 return self.courriel.replace(u'@', u' (à) ')
71
0827a595
PP
72
73def change_personne_courriel(sender, **kwargs):
74 user = kwargs['instance']
75 try:
76 if user.chercheur:
77 if user.email != user.chercheur.courriel:
78 chercheur = user.chercheur
79 chercheur.courriel = user.email
80 chercheur.save()
81 except:
82 pass
83
84post_save.connect(change_personne_courriel, sender=User)
85
86
5212238e 87class ChercheurQuerySet(SEPQuerySet):
a2c6bb72 88
5212238e
EMS
89 def filter_groupe(self, groupe):
90 return self.filter(groupes=groupe)
91
92 def filter_pays(self, pays):
93 return self.filter(Q(etablissement__pays=pays) | Q(etablissement_autre_pays=pays))
94
95 def filter_region(self, region):
96 return self.filter(Q(etablissement__pays__region=region) | Q(etablissement_autre_pays__region=region))
a2c6bb72 97
5212238e
EMS
98 def filter_nord_sud(self, nord_sud):
99 return self.filter(Q(etablissement__pays__nord_sud=nord_sud) | Q(etablissement_autre_pays__nord_sud=nord_sud))
116db1fd 100
5c9bae2d
OL
101 def filter_genre(self, genre):
102 return self.filter(genre=genre)
103
5212238e
EMS
104 def filter_statut(self, statut):
105 return self.filter(statut=statut)
106
107 def filter_expert(self):
108 return self.exclude(expertises=None)
109
230671ff
EMS
110 def filter_date_modification(self, min=None, max=None):
111 return self._filter_date('date_modification', min=min, max=max)
112
acd5cd8f 113 def order_by_nom(self, direction=''):
3648b3d6 114 return self.order_by(direction + 'nom', direction + 'prenom', '-date_modification')
acd5cd8f
EMS
115
116 def order_by_etablissement(self, direction=''):
1760a3e9
EMS
117 return self.extra(select=dict(etablissement_nom='IFNULL(ref_etablissement.nom, chercheurs_chercheur.etablissement_autre_nom)'),
118 order_by=[direction + 'etablissement_nom', '-date_modification'])
acd5cd8f
EMS
119
120 def order_by_pays(self, direction=''):
121 return self.extra(select=dict(
122 pays_etablissement='''(SELECT nom FROM ref_pays
123 WHERE ref_pays.code = IFNULL(ref_etablissement.pays, chercheurs_chercheur.etablissement_autre_pays))'''
124 ), order_by=[direction + 'pays_etablissement', '-date_modification'])
125
5212238e
EMS
126class ChercheurSphinxQuerySet(SEPSphinxQuerySet):
127
128 def __init__(self, model=None):
4134daa0 129 return SEPSphinxQuerySet.__init__(self, model=model, index='savoirsenpartage_chercheurs',
acd5cd8f 130 weights=dict(nom=2, prenom=2))
d9da735f 131
c1b134f8 132 def filter_region(self, region):
5212238e
EMS
133 return self.filter(region_id=region.id)
134
27effd89
PP
135 def filter_discipline(self, discipline):
136 return self.filter(discipline_id=discipline.id)
137
5212238e
EMS
138 def filter_groupe(self, groupe):
139 return self.filter(groupe_ids=groupe.id)
140
141 def filter_pays(self, pays):
142 return self.filter(pays_id=pays.id)
c1b134f8 143
5212238e
EMS
144 NORD_SUD_CODES = {'Nord': 1, 'Sud': 2}
145 def filter_nord_sud(self, nord_sud):
146 return self.filter(nord_sud=self.NORD_SUD_CODES[nord_sud])
147
c6efde25
OL
148 GENRE_CODES = dict([(k, i+1) for i, (k, v) in enumerate(GENRE_CHOICES)])
149 def filter_genre(self, genre):
150 return self.filter(genre=self.GENRE_CODES[genre])
151
5212238e
EMS
152 STATUT_CODES = {'enseignant': 1, 'etudiant': 2, 'independant': 3}
153 def filter_statut(self, statut):
154 return self.filter(statut=self.STATUT_CODES[statut])
155
d9da735f
EMS
156 def filter_expert(self):
157 return self.filter(expert=True)
158
230671ff 159 def filter_date_modification(self, min=None, max=None):
7ed3ee8f 160 return self._filter_date('date_modification', min=min, max=max)
230671ff 161
acd5cd8f
EMS
162 def order_by_nom(self, direction=''):
163 return self.order_by(direction + 'nom_complet', '-date_modification')
164
165 def order_by_etablissement(self, direction=''):
166 return self.order_by(direction + 'etablissement_attr', '-date_modification')
167
168 def order_by_pays(self, direction=''):
169 return self.order_by(direction + 'pays_attr', '-date_modification')
170
5212238e 171class ChercheurManager(SEPManager):
a2c6bb72
EMS
172
173 def get_query_set(self):
695930dd 174 return ChercheurQuerySet(self.model).filter(actif=True)
a2c6bb72 175
5212238e
EMS
176 def get_sphinx_query_set(self):
177 return ChercheurSphinxQuerySet(self.model).order_by('-date_modification')
5212238e 178
116db1fd 179 def filter_region(self, region):
5212238e 180 """Le filtrage de chercheurs par région n'est pas une recherche texte."""
c1b134f8
EMS
181 return self.get_query_set().filter_region(region)
182
5212238e
EMS
183 def filter_groupe(self, groupe):
184 return self.get_query_set().filter_groupe(groupe)
bae03b7b 185
5212238e
EMS
186 def filter_pays(self, pays):
187 return self.get_query_set().filter_pays(pays)
188
189 def filter_nord_sud(self, nord_sud):
190 return self.get_query_set().filter_nord_sud(nord_sud)
191
a7bf6c5a 192 def filter_genre(self, genre):
634d46da 193 return self.get_query_set().filter_genre(genre=genre)
a7bf6c5a 194
5212238e
EMS
195 def filter_statut(self, statut):
196 return self.get_query_set().filter_statut(statut)
197
198 def filter_expert(self):
199 return self.get_query_set().filter_expert()
3efbacbe 200
230671ff
EMS
201 def filter_date_modification(self, min=None, max=None):
202 return self.get_query_set().filter_date_modification(min=min, max=max)
203
acd5cd8f
EMS
204 def order_by_nom(self, direction=''):
205 return self.get_query_set().order_by_nom(self, direction=direction)
206
207 def order_by_etablissement(self, direction=''):
208 return self.get_query_set().order_by_etablissement(self, direction=direction)
209
210 def order_by_pays(self, direction=''):
211 return self.get_query_set().order_by_pays(self, direction=direction)
212
bc15119b
EMS
213STATUT_CHOICES = (
214 ('enseignant', 'Enseignant-chercheur dans un établissement'),
215 ('etudiant', 'Étudiant-chercheur doctorant'),
216 ('independant', 'Chercheur indépendant docteur')
217)
218
13ec4813 219class Chercheur(Personne):
bc15119b
EMS
220 RESEAU_INSTITUTIONNEL_CHOICES = (
221 ('AFELSH', 'Association des facultés ou établissements de lettres et sciences humaines des universités d’expression française (AFELSH)'),
222 ('CIDEGEF', 'Conférence internationale des dirigeants des institutions d’enseignement supérieur et de recherche de gestion d’expression française (CIDEGEF)'),
223 ('RIFEFF', 'Réseau international francophone des établissements de formation de formateurs (RIFEFF)'),
224 ('CIDMEF', 'Conférence internationale des doyens des facultés de médecine d’expression française (CIDMEF)'),
225 ('CIDCDF', 'Conférence internationale des doyens des facultés de chirurgie dentaire d’expression totalement ou partiellement française (CIDCDF)'),
226 ('CIFDUF', 'Conférence internationale des facultés de droit ayant en commun l’usage du français (CIFDUF)'),
227 ('CIRUISEF', 'Conférence internationale des responsables des universités et institutions à dominante scientifique et technique d’expression française (CIRUISEF)'),
228 ('Theophraste', 'Réseau Théophraste (Réseau de centres francophones de formation au journalisme)'),
229 ('CIDPHARMEF', 'Conférence internationale des doyens des facultés de pharmacie d’expression française (CIDPHARMEF)'),
230 ('CIDEFA', 'Conférence internationale des directeurs et doyens des établissements supérieurs d’expression française des sciences de l’agriculture et de l’alimentation (CIDEFA)'),
231 ('CITEF', 'Conférence internationale des formations d’ingénieurs et techniciens d’expression française (CITEF)'),
232 ('APERAU', 'Association pour la promotion de l’enseignement et de la recherche en aménagement et urbanisme (APERAU)'),
233 )
234 INSTANCE_AUF_CHOICES = (
235 ('CASSOC', 'Conseil associatif'),
236 ('CA', "Conseil d'administration"),
237 ('CS', 'Conseil scientifique'),
2fcf82c9
EMS
238 ('CRE', "Commission régionale d'experts"),
239 ('CR', 'Conférence des recteurs'),
240 ('CNO', "Conseil national d'orientation")
bc15119b
EMS
241 )
242
00755d9b 243 nationalite = models.ForeignKey(Pays, null = True, db_column='nationalite', to_field='code',
0b0fbbd7 244 verbose_name = 'nationalité', related_name='nationalite')
a4e383ac 245 statut = models.CharField(max_length=36, choices=STATUT_CHOICES)
0b0fbbd7 246 diplome = models.CharField(max_length=255, null=True, verbose_name = 'diplôme le plus élevé')
73cabd75 247 etablissement = models.ForeignKey(Etablissement, db_column='etablissement', null=True, blank=True)
0b0fbbd7 248 etablissement_autre_nom = models.CharField(max_length=255, null=True, blank=True, verbose_name = 'autre établissement')
00755d9b 249 etablissement_autre_pays = models.ForeignKey(Pays, null = True, blank=True, db_column='etablissement_autre_pays',
0b0fbbd7
EMS
250 to_field='code', related_name='etablissement_autre_pays',
251 verbose_name = "pays de l'établissement")
0874e7d1 252 attestation = models.BooleanField()
73cabd75 253
0b0fbbd7 254 #Domaine
602e4194 255 thematique = models.ForeignKey(Thematique, db_column='thematique', blank=True, null=True, verbose_name='thematique')
518d0b44 256 mots_cles = models.CharField(max_length=255, null=True, verbose_name='mots-clés')
0b0fbbd7 257 discipline = models.ForeignKey(Discipline, db_column='discipline', null=True, verbose_name='Discipline')
518d0b44 258 theme_recherche = models.TextField(null=True, blank=True, verbose_name='thèmes de recherche')
35b0778c 259 equipe_recherche = models.CharField(max_length=255, blank=True, verbose_name='équipe de recherche')
219710da
EMS
260 url_site_web = models.URLField(max_length=255, null=True, blank=True,
261 verbose_name='adresse site Internet', verify_exists=False)
262 url_blog = models.URLField(max_length=255, null=True, blank=True, verbose_name='blog',
263 verify_exists=False)
3c576696
EMS
264 url_reseau_social = models.URLField(
265 max_length=255, null=True, blank=True, verbose_name='Réseau social',
219710da 266 verify_exists=False,
3c576696
EMS
267 help_text=u"Vous pouvez indiquer ici l'adresse de votre page personnelle dans votre réseau social préféré (e.g. Facebook, LinkedIn, Twitter, Identica, ...)"
268 )
00755d9b 269
18407f73 270 groupes = models.ManyToManyField('Groupe', through='AdhesionGroupe', related_name='membres', blank=True, verbose_name='groupes')
932eef9a 271
a7b16ec9 272 # Activités en francophonie
121d9439 273 membre_instance_auf = models.NullBooleanField(verbose_name="est ou a déjà été membre d'une instance de l'AUF")
bc15119b
EMS
274 membre_instance_auf_nom = models.CharField(max_length=10, blank=True, choices=INSTANCE_AUF_CHOICES, verbose_name="instance")
275 membre_instance_auf_fonction = models.CharField(max_length=255, blank=True, verbose_name="fonction")
a7b16ec9 276 membre_instance_auf_dates = models.CharField(max_length=255, blank=True, verbose_name="dates")
121d9439 277 expert_oif = models.NullBooleanField(verbose_name="a été sollicité par l'OIF")
614b3269
EMS
278 expert_oif_details = models.CharField(max_length=255, blank=True, verbose_name="détails")
279 expert_oif_dates = models.CharField(max_length=255, blank=True, verbose_name="dates")
121d9439 280 membre_association_francophone = models.NullBooleanField(verbose_name="est membre d'une association francophone")
c073c94d 281 membre_association_francophone_details = models.CharField(max_length=255, blank=True, verbose_name="nom de l'association")
121d9439
EMS
282 membre_reseau_institutionnel = models.NullBooleanField(
283 verbose_name="est membre des instances d'un réseau institutionnel de l'AUF"
bc15119b
EMS
284 )
285 membre_reseau_institutionnel_nom = models.CharField(
286 max_length=15, choices=RESEAU_INSTITUTIONNEL_CHOICES, blank=True,
287 verbose_name="réseau institutionnel"
c073c94d 288 )
bc15119b
EMS
289 membre_reseau_institutionnel_fonction = models.CharField(
290 max_length=255, blank=True, verbose_name="fonction"
c073c94d
EMS
291 )
292 membre_reseau_institutionnel_dates = models.CharField(
293 max_length=255, blank=True, verbose_name="dates"
294 )
a7b16ec9 295
cb591fb3 296 # Expertises
121d9439 297 expertises_auf = models.NullBooleanField(verbose_name="est disposé à réaliser des expertises pour l'AUF")
cb591fb3 298
00755d9b
AJ
299 #meta
300 date_creation = models.DateField(auto_now_add=True, db_column='date_creation')
301 date_modification = models.DateField(auto_now=True, db_column='date_modification')
302
a2c6bb72
EMS
303 # Manager
304 objects = ChercheurManager()
c59dba82 305 all_objects = models.Manager()
a2c6bb72 306
588d6b93 307 def __unicode__(self):
13ec4813 308 return u"%s %s" % (self.nom.upper(), self.prenom.title())
e427f068 309
b57a7362
AJ
310 def statut_display(self):
311 for s in STATUT_CHOICES:
312 if self.statut == s[0]:
313 return s[1]
e427f068 314 return "-"
588d6b93 315
e4d01d1d
EMS
316 @property
317 def etablissement_display(self):
230671ff 318 return (self.nom_etablissement or '') + (', ' + self.pays.nom if self.pays else '')
e4d01d1d 319
d32102bd
EMS
320 @property
321 def pays(self):
322 return self.etablissement.pays if self.etablissement else self.etablissement_autre_pays
323
324 @property
d264c787
EMS
325 def nom_etablissement(self):
326 return self.etablissement.nom if self.etablissement else self.etablissement_autre_nom
327
328 @property
d32102bd
EMS
329 def region(self):
330 return self.pays.region
331
5b55252d
PP
332 @property
333 def domaines_recherche(self):
334 return self.groupes.filter(groupe_chercheur=False)
335
336 @property
337 def groupes_chercheur(self):
338 return self.groupes.filter(groupe_chercheur=True)
339
71e3d741
EMS
340 def save(self):
341 """Si on a donné un établissement membre, on laisse tomber l'autre établissement."""
342 if self.etablissement:
343 self.etablissement_autre_nom = None
344 self.etablissement_autre_pays = None
345 super(Chercheur, self).save()
346
43ed73e7
EMS
347 def activation_token(self):
348 return sha_constructor(settings.SECRET_KEY + unicode(self.id)).hexdigest()[::2]
349
4b89a7df
EMS
350 def get_absolute_url(self):
351 return url('chercheur', kwargs={'id': self.id})
352
81fe476e
PP
353class ChercheurVoir(Chercheur):
354
355 class Meta:
356 proxy = True
429222f1
PP
357 verbose_name = 'chercheur (visualisation)'
358 verbose_name_plural = 'chercheur (visualisation)'
81fe476e 359
00755d9b 360class Publication(models.Model):
595ab4d6 361 chercheur = models.ForeignKey(Chercheur, related_name='publications')
1df3737b 362 auteurs = models.CharField(max_length=255, blank=True, verbose_name='auteur(s)')
595ab4d6 363 titre = models.CharField(max_length=255, null=True, blank=True, verbose_name='titre')
1df3737b
EMS
364 revue = models.CharField(max_length=255, null=True, blank=True, verbose_name='revue')
365 annee = models.IntegerField(null=True, blank=True, verbose_name='année de publication')
366 editeur = models.CharField(max_length=255, null=True, blank=True, verbose_name='éditeur')
367 lieu_edition = models.CharField(max_length=255, null=True, blank=True, verbose_name="lieu d'édition")
368 nb_pages = models.CharField(max_length=255, null=True, blank=True, verbose_name='nombre de pages')
912e3c6c 369 url = models.URLField(max_length=255, null=True, blank=True, verbose_name='lien vers la publication', verify_exists=False)
6befc7c9 370 #Migration des publications depuis l'ancien repertoire de chercheurs
1df3737b 371 publication_affichage = models.TextField(verbose_name='publication', null=True, blank=True)
595ab4d6 372 actif = models.BooleanField(editable=False)
2a36714f
AJ
373
374 def __unicode__(self):
c59dba82 375 return self.titre or '(Aucun)'
2a36714f 376
3eb41a6d
EMS
377 def save(self):
378 if self.publication_affichage and (self.auteurs or self.titre or
379 self.revue or self.annee or
380 self.editeur or self.lieu_edition
381 or self.nb_pages or self.url):
382 self.publication_affichage = ''
383 super(Publication, self).save()
384
595ab4d6
EMS
385class These(models.Model):
386 chercheur = models.OneToOneField(Chercheur, primary_key=True)
14fd1c3f 387 titre = models.CharField(max_length=255, verbose_name='Titre')
595ab4d6 388 annee = models.IntegerField(verbose_name='Année de soutenance (réalisée ou prévue)')
14fd1c3f 389 directeur = models.CharField(max_length=255, verbose_name='Directeur')
595ab4d6
EMS
390 etablissement = models.CharField(max_length=255, verbose_name='Établissement de soutenance')
391 nb_pages = models.IntegerField(verbose_name='Nombre de pages', blank=True, null=True)
912e3c6c 392 url = models.URLField(max_length=255, verbose_name='Lien vers la publication', blank=True, verify_exists=False)
595ab4d6
EMS
393
394 def __unicode__(self):
395 return self.titre
396
2a36714f
AJ
397class Expertise(models.Model):
398 id = models.AutoField(primary_key=True, db_column='id')
ee8b3a49 399 chercheur = models.ForeignKey(Chercheur, related_name='expertises')
356cc691 400 nom = models.CharField(max_length=255, verbose_name = "Objet de l'expertise")
c1234eb8 401 date = models.CharField(max_length=255, blank=True)
ee8b3a49 402 lieu = models.CharField(max_length=255, null=True, blank=True, verbose_name = "Lieu de l'expertise")
b16bcbaf
EMS
403 organisme_demandeur = models.CharField(max_length=255, null=True, blank=True, verbose_name = 'Organisme demandeur')
404 organisme_demandeur_visible = models.BooleanField(verbose_name="Afficher l'organisme demandeur")
2a36714f 405 actif = models.BooleanField(editable = False, db_column='actif')
5b9abc81
AJ
406
407 def __unicode__(self):
408 return u"%s" % (self.nom)
2a36714f 409
057c3327
PP
410class GroupeManager(models.Manager):
411 def search(self, text):
412 return self.get_query_set().filter(nom__icontains=text)
413
414class GroupeChercheurManager(GroupeManager):
5b55252d
PP
415 def get_query_set(self):
416 return super(GroupeChercheurManager, self).get_query_set().filter(groupe_chercheur=True)
417
057c3327 418class DomaineRechercheManager(GroupeManager):
5b55252d
PP
419 def get_query_set(self):
420 return super(DomaineRechercheManager, self).get_query_set().filter(groupe_chercheur=False)
421
932eef9a
AJ
422class Groupe(models.Model):
423 id = models.AutoField(primary_key=True, db_column='id')
424 nom = models.CharField(max_length=255, db_column='nom')
00755d9b
AJ
425 url = models.URLField(max_length=255, null=True, blank=True,
426 verbose_name='Site web')
427 liste_diffusion = models.URLField(max_length=255, null=True, blank=True,
428 verbose_name='Liste de diffusion')
429 bulletin = models.URLField(max_length=255, null=True, blank=True,
430 verbose_name='Bulletin')
932eef9a 431 actif = models.BooleanField(editable = False, db_column='actif')
04985abd 432 groupe_chercheur = models.BooleanField(default=False, editable=False, verbose_name='Groupe de chercheur')
5b55252d 433
34d0147e 434 responsables = models.ManyToManyField(User, related_name='responsable_groupe', verbose_name='gestionnaire de communauté', blank=True)
cec3f8db 435
2094c7e5
PP
436 recherches = models.ManyToManyField(Search, related_name='recherche_groupe', verbose_name='recherches prédéfinies', blank=True)
437
0c0d997c 438 page_accueil = models.TextField(null=True, blank=True)
5b55252d 439
057c3327 440 objects = GroupeManager()
5b55252d
PP
441 groupe_chercheur_objects = GroupeChercheurManager()
442 domaine_recherche_objects = DomaineRechercheManager()
932eef9a 443
55ef8558 444 class Meta:
b803eb99 445 ordering = ['nom']
55ef8558
EMS
446 verbose_name = 'domaine de recherche'
447 verbose_name_plural = 'domaines de recherche'
448
932eef9a
AJ
449 def __unicode__(self):
450 return u"%s" % (self.nom)
5b55252d 451
bf2904f0
PP
452 def get_absolute_url(self):
453 return url('groupe_retrieve', kwargs={'id': self.id})
454
e7db286c
PP
455 def membres_actif(self):
456 return self.membership.filter(statut="accepte")
457
bf2904f0 458
5b55252d
PP
459class GroupeChercheur(Groupe):
460 objects = GroupeChercheurManager()
461
462 class Meta:
463 proxy = True
5c9d31cf
PP
464 verbose_name = 'communauté de chercheurs'
465 verbose_name_plural = 'communautés de chercheurs'
5b55252d 466
04985abd
PP
467 def save(self, *args, **kwargs):
468 self.groupe_chercheur = True
469 super(GroupeChercheur, self).save(*args, **kwargs)
470
5b55252d
PP
471class DomaineRecherche(Groupe):
472 objects = DomaineRechercheManager()
473
474 class Meta:
475 proxy = True
476 verbose_name = 'domaine de recherche'
477 verbose_name_plural = 'domaines de recherche'
478
04985abd
PP
479 def save(self, *args, **kwargs):
480 self.groupe_chercheur = False
481 super(DomaineRecherche, self).save(*args, **kwargs)
482
e548663a
PP
483CG_STATUT_CHOICES = (
484 ('nouveau', 'Nouveau'),
485 ('refuse', 'Refusé'),
486 ('accepte', 'Accepté'),
487 ('resilie', 'Résilié'),
488 ('exclus', 'Exclus'),
489)
dd70b25a 490
dca3ff65
PP
491class AdhesionCommunauteManager(GroupeManager):
492 def get_query_set(self):
493 return super(AdhesionCommunauteManager, self).get_query_set().filter(groupe__groupe_chercheur=True)
494
495class AdhesionDomaineRechercheManager(GroupeManager):
496 def get_query_set(self):
497 return super(AdhesionDomaineRechercheManager, self).get_query_set().filter(groupe__groupe_chercheur=False)
498
18407f73 499class AdhesionGroupe(models.Model):
73cabd75 500 id = models.AutoField(primary_key=True, db_column='id')
6d5279ff 501 chercheur = models.ForeignKey('Chercheur', db_column='chercheur')
0c0d997c 502 groupe = models.ForeignKey('Groupe', db_column='groupe', related_name="membership")
00755d9b
AJ
503 date_inscription = models.DateField(auto_now_add=True)
504 date_modification = models.DateField(auto_now=True)
dd70b25a 505 statut = models.CharField(max_length=100, choices=CG_STATUT_CHOICES, default='nouveau')
2a36714f 506
55ef8558 507 class Meta:
80da57fc
PP
508 verbose_name = 'adhésion aux groupes'
509 verbose_name_plural = 'adhésions aux groupes'
510 ordering = ['chercheur']
55ef8558 511
c3d51177
PP
512 def save(self, *args, **kwargs):
513 if self.pk:
514 old_instance = AdhesionGroupe.objects.get(pk=self.pk)
515 if old_instance.statut=='nouveau' and self.statut=='accepte':
516 from django.template.loader import get_template
517 from django.template import Context
518 from django.core.mail import send_mail
519 from django.conf import settings
520
521 template = get_template('chercheurs/groupe_confirmation.txt')
522 domain = settings.SITE_DOMAIN
523 message = template.render(Context(dict(groupe=self.groupe, domain=domain)))
524 send_mail('Votre inscription à Savoirs en partage', message, None, [self.chercheur.courriel])
525
526 super(AdhesionGroupe, self).save(*args, **kwargs)
527
2a36714f
AJ
528 def __unicode__(self):
529 return u"%s - %s" % (self.chercheur, self.groupe)
fdcf5874 530
dca3ff65
PP
531class AdhesionCommunaute(AdhesionGroupe):
532 objects = AdhesionCommunauteManager()
533
534 class Meta:
535 proxy = True
536 verbose_name = 'adhésion aux communautés de chercheurs'
537 verbose_name_plural = 'adhésion aux communautés de chercheurs'
538
539class AdhesionDomaineRecherche(AdhesionGroupe):
540 objects = AdhesionDomaineRechercheManager()
541
542 class Meta:
543 proxy = True
544 verbose_name = 'adhésion aux domaines de recherche'
545 verbose_name_plural = 'adhésion aux domaines de recherche'
546
fdcf5874
EMS
547class ChercheurSearch(Search):
548 nom_chercheur = models.CharField(max_length=100, blank=True, verbose_name='nom')
5b55252d 549 domaine = models.ForeignKey(DomaineRecherche, blank=True, null=True, verbose_name='domaine de recherche')
35b0778c
PP
550 equipe_recherche = models.CharField(max_length=100, blank=True, null=True,
551 verbose_name='Équipe de recherche',
fdcf5874
EMS
552 help_text='ou Laboratoire, ou Groupement inter-universitaire')
553 statut = models.CharField(max_length=100, blank=True, choices=STATUT_CHOICES + (('expert', 'Expert'),))
554 pays = models.ForeignKey(Pays, blank=True, null=True)
555 nord_sud = models.CharField(max_length=4, blank=True, choices=(('Nord', 'Nord'), ('Sud', 'Sud')),
556 verbose_name='Nord/Sud',
557 help_text="Distinction d'ordre géopolitique et économique, non géographique, qui conditionne souvent l'attribution de soutiens par les agences internationales: on entend par Nord les pays développés, par Sud les pays en développement (pays les moins avancés, pays émergents et pays à économies en transition)")
558 activites_francophonie = models.CharField(
559 max_length=25, blank=True, verbose_name='activités en Francophonie',
560 choices=(('instance_auf', "Membre d'une instance de l'AUF"),
561 ('expert_oif', "Sollicité par l'OIF"),
562 ('association_francophone', "Membre d'une association ou d'une société savante francophone"),
563 ('reseau_institutionnel', "Membre des instances d'un réseau institutionnel de l'AUF"))
564 )
565 genre = models.CharField(max_length=1, blank=True, choices=GENRE_CHOICES)
566
567 class Meta:
568 verbose_name = 'recherche de chercheurs'
569 verbose_name_plural = 'recherches de chercheurs'
570
4b89a7df 571 def run(self, min_date=None, max_date=None):
fdcf5874
EMS
572 results = Chercheur.objects
573 if self.q:
574 results = results.search(self.q)
575 if self.nom_chercheur:
576 results = results.add_to_query('@(nom,prenom) ' + self.nom_chercheur)
35b0778c
PP
577 if self.equipe_recherche:
578 results = results.add_to_query('@equipe_recherche ' + self.equipe_recherche)
fdcf5874
EMS
579 if self.discipline:
580 results = results.filter_discipline(self.discipline)
581 if self.region:
582 results = results.filter_region(self.region)
583 if self.statut:
584 if self.statut == "expert":
585 results = results.filter_expert()
586 else:
587 results = results.filter_statut(self.statut)
588 if self.domaine:
589 results = results.filter_groupe(self.domaine)
590 if self.pays:
591 results = results.filter_pays(self.pays)
592 if self.nord_sud:
593 results = results.filter_nord_sud(self.nord_sud)
594 if self.genre:
595 results = results.filter_genre(self.genre)
596 if self.activites_francophonie == 'instance_auf':
597 results = results.filter(membre_instance_auf=True)
598 elif self.activites_francophonie == 'expert_oif':
599 results = results.filter(expert_oif=True)
600 elif self.activites_francophonie == 'association_francophone':
601 results = results.filter(membre_association_francophone=True)
602 elif self.activites_francophonie == 'reseau_institutionnel':
603 results = results.filter(membre_reseau_institutionnel=True)
4b89a7df
EMS
604 if min_date:
605 results = results.filter_date_modification(min=min_date)
606 if max_date:
607 results = results.filter_date_modification(max=max_date)
fdcf5874
EMS
608 return results.all()
609
610 def url(self):
611 qs = self.query_string()
612 return url('chercheurs') + ('?' + qs if qs else '')
da5bf7e9
EMS
613
614 def rss_url(self):
615 qs = self.query_string()
616 return url('rss_chercheurs') + ('?' + qs if qs else '')
4b89a7df
EMS
617
618 def get_email_alert_content(self, results):
619 content = ''
620 for chercheur in results:
621 content += u'- [%s %s](%s%s) \n' % (chercheur.nom.upper(),
622 chercheur.prenom,
623 settings.SITE_ROOT_URL,
624 chercheur.get_absolute_url())
625 content += u' %s\n\n' % chercheur.etablissement_display
626 return content
cdaadee3
PP
627
628class GroupeSearch(Search):
629
630 class Meta:
631 verbose_name = 'recherche de groupe'
632 verbose_name_plural = 'recherches de groupes'
633
634 def run(self):
3e04a423 635 results = Groupe.groupe_chercheur_objects
cdaadee3
PP
636 if self.q:
637 results = results.search(self.q)
638 return results.all()
639
640 #def url(self):
641 # qs = self.query_string()
642 # return url('groupes') + ('?' + qs if qs else '')
643
644 #def rss_url(self):
645 # qs = self.query_string()
646 # return url('rss_groupes') + ('?' + qs if qs else '')
2048049e
PP
647
648class Message(models.Model):
649
650 chercheur = models.ForeignKey('Chercheur', db_column='chercheur')
651 groupe = models.ForeignKey('Groupe', db_column='groupe')
652 titre = models.CharField(max_length=255)
653 contenu = models.TextField()
654
fd6352ea 655 date_creation = models.DateTimeField(auto_now_add=True, db_column='date_creation')
2048049e 656
bf2904f0
PP
657 class Meta:
658 ordering = ['-date_creation']
659
2048049e
PP
660 def __unicode__(self):
661 return u"%s - %s" % (self.chercheur, self.titre)
c8d6b979 662
bf2904f0
PP
663 def get_absolute_url(self):
664 return url('groupe_messages', kwargs={'id': self.groupe.id})
665
544dec4f
PP
666
667class AuthLDAP(models.Model):
668 username = models.CharField('utilisateur', max_length=255, unique=True)
669 ldap_hash = models.CharField('hash LDAP', max_length=255)
670 date_modification = models.DateTimeField(auto_now=True)
671
672 def __unicode__(self):
673 return self.username