Changement de Groupe de recherche en Équipe de recherche
[auf_savoirs_en_partage_django.git] / auf_savoirs_en_partage / chercheurs / admin.py
CommitLineData
6f8d521e 1# -*- coding: utf-8 -*-
cbae0173 2from django.db import models
6f8d521e 3from django.db.models import Q
cbae0173 4from django.contrib import admin
55ef8558
EMS
5from django.core.urlresolvers import reverse as url
6from django.forms.models import BaseInlineFormSet
7from django.http import HttpResponseRedirect
d264c787
EMS
8from django.utils.encoding import smart_str
9from django_exportateur.exportateur import exportateur
cbae0173 10
81fe476e
PP
11from chercheurs.models import Chercheur, ChercheurVoir, Publication, \
12 GroupeChercheur, DomaineRecherche, \
18407f73 13 AdhesionGroupe, ChercheurQuerySet, These
2094c7e5 14from savoirs.models import Search
6f8d521e 15
55ef8558 16class ChercheurAdmin(admin.ModelAdmin):
6f8d521e 17 list_filter = ['genre']
b1d4c7ac
PP
18 alphabet_filter = 'nom'
19 alphabet_filter_table = 'chercheurs_personne'
20 DEFAULT_ALPHABET = ''
21
d264c787 22 actions = ('remove_from_group', 'export_as_ods', 'export_as_csv')
62354bdb 23 search_fields = ('nom', 'prenom')
cbae0173 24
afc30c28 25 def lookup_allowed(self, lookup, value):
6f8d521e
EMS
26 return lookup in ['genre', 'statut', 'membre_reseau_institutionnel',
27 'membre_instance_auf', 'discipline', 'region', 'pays',
b1d4c7ac 28 'groupes', 'nord_sud'] or \
afc30c28 29 admin.ModelAdmin.lookup_allowed(self, lookup, value)
c0d2903e 30
55ef8558
EMS
31 def remove_from_group(self, request, queryset):
32 groupe_id = request.GET.get('groupes__id__exact')
33 chercheur_ids = queryset.values_list('id', flat=True)
18407f73 34 matches = AdhesionGroupe.objects.filter(groupe=groupe_id, chercheur__in=chercheur_ids)
55ef8558
EMS
35 matches.delete()
36 return HttpResponseRedirect(url('admin:chercheurs_chercheur_changelist') + '?groupes__id__exact=' + groupe_id)
37
38 def get_actions(self, request):
39 actions = super(ChercheurAdmin, self).get_actions(request)
40
35b0778c 41 # Si on filtre par groupes, offrir d'en retirer les
55ef8558
EMS
42 # chercheurs sélectionnés.
43 groupe_id = request.GET.get('groupes__id__exact')
44 if groupe_id:
45 groupe = Groupe.objects.get(id=groupe_id)
46 action_desc = actions['remove_from_group']
e7b9234a 47 actions['remove_from_group'] = (action_desc[0], action_desc[1], u'Retirer du domaine de recherche « %s »' % groupe.nom)
55ef8558
EMS
48 else:
49 del actions['remove_from_group']
50 return actions
51
6f8d521e
EMS
52 def queryset(self, request):
53 return ChercheurAdminQuerySet(Chercheur)
54
ee2ef0e8
EMS
55 def get_object(self, request, object_id):
56 """On doit réimplémenter cette méthode à cause de ce qu'on fait avec "initial" dans la méthode queryset()."""
57 try:
58 return Chercheur.objects.get(id=object_id)
59 except Chercheur.DoesNotExist:
60 return None
61
d264c787
EMS
62 def export(self, queryset, type):
63 if queryset.count() == 0:
64 return None
65 obj = queryset[0]
35b0778c 66 headers = ['Nom', 'Prénom', 'Genre', 'Courriel', 'Téléphone', 'Adresse postale',
d264c787 67 'Statut', 'Diplôme', 'Établissement', 'Pays', 'Domaines de recherche',
35b0778c 68 'Thèse', 'Directeur', 'Discipline', 'Thèmes de recherche', 'Équipe de recherche', 'Mots-clés',
d264c787
EMS
69 'Site web', 'Blog', 'Réseau social',
70 'Membre instance AUF', "Sollicité par l'OIF", 'Membre société francophone',
35b0778c 71 'Membre instance réseau institutionnel AUF', 'Expertises', 'Solliciter pour expertises',
d264c787
EMS
72 'Publications']
73 data = []
74 for c in queryset:
75 row = []
76 row.append(c.nom)
77 row.append(c.prenom)
78 row.append(c.get_genre_display())
79 row.append(c.courriel)
80 row.append(c.telephone)
81 row.append(c.adresse_postale)
82 row.append(c.get_statut_display())
83 row.append(c.diplome)
84 row.append(c.nom_etablissement)
85 row.append(c.pays)
86 row.append(', '.join(g.nom for g in c.groupes.all()))
87 try:
88 t = c.these
89 row.append('%s, %s, %s, %s pages.' % (t.titre, t.etablissement, t.annee, t.nb_pages))
90 row.append(t.directeur)
91 except These.DoesNotExist:
92 row.append('')
93 row.append('')
94 row.append(c.discipline.nom if c.discipline else '')
95 row.append(c.theme_recherche)
35b0778c 96 row.append(c.equipe_recherche)
d264c787
EMS
97 row.append(c.mots_cles)
98 row.append(c.url_site_web)
99 row.append(c.url_blog)
100 row.append(c.url_reseau_social)
101 if c.membre_instance_auf:
102 row.append(', '.join([c.membre_instance_auf_nom, c.membre_instance_auf_fonction, c.membre_instance_auf_dates]))
103 else:
104 row.append('')
105 if c.expert_oif:
106 row.append(', '.join([c.expert_oif_details, c.expert_oif_dates]))
107 else:
108 row.append('')
109 if c.membre_association_francophone:
110 row.append(c.membre_association_francophone_details)
111 else:
112 row.append('')
113 if c.membre_reseau_institutionnel:
114 row.append(', '.join([c.membre_reseau_institutionnel_nom, c.membre_reseau_institutionnel_fonction, c.membre_reseau_institutionnel_dates]))
115 else:
116 row.append('')
117 row.append('; '.join(', '.join([e.nom, e.date, e.organisme_demandeur]) for e in c.expertises.all()))
118 if c.expertises_auf is None:
119 row.append('')
120 else:
121 row.append('Oui' if c.expertises_auf else 'Non')
122 row.append('; '.join(p.publication_affichage if p.publication_affichage else
123 '%s, %s, %s, %s, %s, %s, %s pages.' %
124 (p.auteurs, p.titre, p.revue, p.annee, p.editeur, p.lieu_edition, p.nb_pages)
125 for p in c.publications.all()))
126 data.append([smart_str(x) if x else '' for x in row])
127 return exportateur(headers, data, type, filename='chercheurs.%s' % type)
128
129 def export_as_csv(self, request, queryset):
130 return self.export(queryset, 'csv')
131 export_as_csv.short_description = 'Export CSV'
132
133 def export_as_ods(self, request, queryset):
134 return self.export(queryset, 'ods')
135 export_as_ods.short_description = 'Export ODS'
136
81fe476e
PP
137
138class ChercheurVoirAdmin(ChercheurAdmin):
139
140 list_editable = []
141 fields = ['salutation', 'nom', 'prenom', 'courriel', 'afficher_courriel',
142 'fonction', 'date_naissance', 'sousfonction', 'telephone',
143 'adresse_postale', 'genre', 'commentaire',
144
145 'nationalite', 'statut', 'diplome', 'etablissement',
146 'etablissement_autre_nom', 'etablissement_autre_pays',
147 'attestation', 'thematique', 'mots_cles', 'discipline',
35b0778c 148 'theme_recherche', 'equipe_recherche', 'url_site_web',
81fe476e
PP
149 'url_blog', 'url_reseau_social',
150 'membre_instance_auf', 'membre_instance_auf_nom',
151 'membre_instance_auf_fonction', 'membre_instance_auf_dates',
152 'expert_oif', 'expert_oif_details', 'expert_oif_dates',
153 'membre_association_francophone', 'membre_association_francophone_details',
154 'membre_reseau_institutionnel', 'membre_reseau_institutionnel_nom',
155 'membre_reseau_institutionnel_fonction', 'membre_reseau_institutionnel_dates',
156 'expertises_auf']
157
158 def __init__(self, model, admin_site):
159 super(ChercheurVoirAdmin, self).__init__(model, admin_site)
160 self.readonly_fields = self.fields
161
162
163admin.site.register(ChercheurVoir, ChercheurVoirAdmin)
164
6f8d521e
EMS
165class ChercheurAdminQuerySet(ChercheurQuerySet):
166
167 def filter(self, *args, **kwargs):
168 """Gère des filtres supplémentaires pour l'admin.
169
170 C'est la seule façon que j'ai trouvée de contourner les mécanismes
171 de recherche de l'admin."""
6f8d521e
EMS
172 pays = kwargs.pop('pays', None)
173 region = kwargs.pop('region', None)
15ceabe6 174 nord_sud = kwargs.pop('nord_sud', None)
6f8d521e 175 expert = kwargs.pop('expert', None)
b1d4c7ac 176 qs = self
6f8d521e 177 if pays is not None:
15ceabe6
EMS
178 qs = qs.filter(Q(etablissement__pays=pays) |
179 (Q(etablissement=None) & Q(etablissement_autre_pays=pays)))
6f8d521e 180 elif region is not None:
15ceabe6
EMS
181 qs = qs.filter(Q(etablissement__pays__region=region) |
182 (Q(etablissement=None) & Q(etablissement_autre_pays__region=region)))
183 elif nord_sud is not None:
184 qs = qs.filter(Q(etablissement__pays__nord_sud=nord_sud) |
185 (Q(etablissement=None) & Q(etablissement_autre_pays__nord_sud=nord_sud)))
6f8d521e
EMS
186 if expert is not None:
187 if expert in ['1', 1, True]:
188 qs = qs.exclude(expertises=None)
189 else:
190 qs = qs.filter(expertises=None)
191
192 return super(ChercheurAdminQuerySet, qs).filter(*args, **kwargs)
193
cec3f8db 194
18407f73 195class AdhesionGroupeAdmin(admin.ModelAdmin):
e92dbca5 196 list_filter = ('groupe','statut')
61c05759
PP
197 list_display = ('groupe', 'chercheur', 'statut')
198 list_editable = ('statut',)
5cba4157 199 search_fields = ('chercheur__nom', 'chercheur__prenom')
4ef9751d 200
b0db5c3e
PP
201 alphabet_filter = 'chercheur__nom'
202 DEFAULT_ALPHABET = ''
203
1fd4a630
PP
204 actions = ['assigner_cgstatut']
205
b0db5c3e
PP
206
207 def lookup_allowed(self, lookup, value):
208 return lookup in ['chercheur__nom__istartswith'] or \
209 admin.ModelAdmin.lookup_allowed(self, lookup, value)
210
4ef9751d 211 def queryset(self, request):
18407f73 212 qs = super(AdhesionGroupeAdmin, self).queryset(request)
4ef9751d 213
18407f73 214 if not request.user.is_superuser and not request.user.has_perm('chercheurs.change_adhesiongroupe'):
4ef9751d
PP
215 qs = qs.filter(groupe__responsables=request.user)
216
217 return qs
218
219 def has_change_permission(self, request, obj=None):
220
221 if not obj:
222 if request.user.responsable_groupe.count():
223 return True
224 else:
225 if request.user in obj.groupe.responsables.all():
226 return True
227
18407f73 228 return super(AdhesionGroupeAdmin, self).has_change_permission(request, obj)
4ef9751d 229
1fd4a630
PP
230 def assigner_cgstatut(self, request, queryset):
231 selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
232 return HttpResponseRedirect("/admin/assigner_%s?ids=%s" % ('cgstatut', ",".join(selected)))
233 assigner_cgstatut.short_description = u'Assigner un statut'
234
6d5279ff 235
44e07248 236class BaseGroupeAdmin(admin.ModelAdmin):
6d5279ff 237 fieldsets = (
0c0d997c
PP
238 (('Options générales'), {'fields': ('nom', 'url', 'liste_diffusion',
239 'bulletin', 'page_accueil')}),
6d5279ff 240 (('Responsables'), {'fields': ('responsables',)}),
2094c7e5 241 (('Recherches prédéfinies'), {'fields': ('recherches',)}),
6d5279ff 242 )
cec3f8db 243
0c0d997c
PP
244 class Media:
245 js = ['js/tiny_mce/tiny_mce.js', 'js/tiny_mce_textareas.js']
246
734b288c
PP
247 def save_model(self, request, obj, form, change):
248 responsables = form.cleaned_data['responsables']
249 for user in responsables:
250 user.is_staff = True
251 user.save()
252
2094c7e5
PP
253 if not request.user.is_superuser:
254 recherches = Search.objects.exclude(user=request.user)
255 form.cleaned_data['recherches'] = form.cleaned_data['recherches'] | recherches
256
734b288c
PP
257 super(BaseGroupeAdmin, self).save_model(request, obj, form, change)
258
4a7399ee
PP
259 def queryset(self, request):
260 qs = super(BaseGroupeAdmin, self).queryset(request)
261
f522cbdf 262 if not request.user.is_superuser and not request.user.has_perm('chercheurs.change_groupechercheur'):
85f53a92
PP
263 qs = qs.filter(responsables=request.user)
264
265 return qs
4a7399ee
PP
266
267 def has_change_permission(self, request, obj=None, groupe_chercheur=False):
268
269 if not obj:
270 if request.user.responsable_groupe.filter(groupe_chercheur=groupe_chercheur).count():
271 return True
272 else:
273 if request.user in obj.responsables.all():
274 return True
275
276 return super(BaseGroupeAdmin, self).has_change_permission(request, obj)
734b288c 277
2094c7e5
PP
278 def formfield_for_manytomany(self, db_field, request, **kwargs):
279 if db_field.name == "recherches" and not request.user.is_superuser:
280 kwargs["queryset"] = Search.objects.filter(user=request.user)
281 return db_field.formfield(**kwargs)
282 return super(BaseGroupeAdmin, self).formfield_for_manytomany(db_field, request, **kwargs)
283
284
44e07248 285class GroupeChercheurAdmin(BaseGroupeAdmin):
4a7399ee
PP
286
287 def has_change_permission(self, request, obj=None):
288 return super(GroupeChercheurAdmin, self).has_change_permission(request, obj, groupe_chercheur=True)
289
44e07248
PP
290
291class DomaineRechercheAdmin(BaseGroupeAdmin):
4a7399ee
PP
292
293 def has_change_permission(self, request, obj=None):
294 return super(DomaineRechercheAdmin, self).has_change_permission(request, obj, groupe_chercheur=False)
cec3f8db 295
78399ad5
PP
296class PublicationAdmin(admin.ModelAdmin):
297 search_fields = ('auteurs', 'titre', 'revue', 'editeur')
298
299
55ef8558 300admin.site.register(Chercheur, ChercheurAdmin)
78399ad5 301admin.site.register(Publication, PublicationAdmin)
cec3f8db
PP
302admin.site.register(GroupeChercheur, GroupeChercheurAdmin)
303admin.site.register(DomaineRecherche, DomaineRechercheAdmin)
18407f73 304admin.site.register(AdhesionGroupe, AdhesionGroupeAdmin)
cbae0173 305