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