Commit | Line | Data |
---|---|---|
e3c3296e | 1 | # -*- encoding: utf-8 -*- |
9093aa5d EMS |
2 | from django.contrib.auth.decorators import login_required, permission_required |
3 | from django.contrib import messages | |
4 | from django.core.urlresolvers import reverse as url | |
03ba3d5f | 5 | from django.db.models import get_model, Count |
e3c3296e | 6 | from django.http import HttpResponseRedirect |
e3c3296e | 7 | from django.shortcuts import render_to_response |
9093aa5d | 8 | from django.template import Context, RequestContext |
e3c3296e | 9 | |
6508c994 | 10 | from chercheurs.models import Chercheur, GroupeChercheur, DomaineRecherche |
693c606b | 11 | from auf.django.references.models import Thematique, Pays, Region |
656b9c0f PP |
12 | from savoirs.models import Record, Discipline, Actualite, Serveur, RecordCategorie |
13 | from savoirs.forms import CategorieForm, PaysForm, RegionsForm, ThematiquesForm, DisciplinesForm, ConfirmationForm | |
e3c3296e | 14 | |
6d885e0c | 15 | # Dashboard |
16 | class RecordDashboard: | |
17 | """Cette classe permet d'afficher une liste de tâche à faire en fonction de l'usagé""" | |
18 | context = None | |
19 | ||
20 | def __init__(self, context): | |
21 | """Récupère le context""" | |
22 | self.context = context | |
23 | ||
24 | def get_fitre_serveurs(self,): | |
25 | """Retourner la liste des serveurs sélectionnés. | |
26 | S'il n'y en a pas, tous les serveurs sont retournés.""" | |
27 | try: | |
28 | user = self.context.get('user') | |
29 | profile = user.get_profile() | |
30 | serveurs = profile.serveurs.all() | |
31 | except: | |
32 | serveurs = Serveur.objects.all() | |
33 | return [s.nom for s in serveurs] | |
34 | ||
6d885e0c | 35 | def total_a_faire(self,): |
36 | """Retourne le total des références à traiter""" | |
37 | return len(self.tout_mes_records()) | |
38 | ||
39 | def tout_mes_records(self,): | |
40 | """Retourne la liste des références à traiter en fonction du filtre""" | |
41 | filtre = self.get_fitre_serveurs() | |
d566e9c1 | 42 | return [r for r in Record.all_objects.filter(server__in=filtre) if not r.est_complet()] |
6d885e0c | 43 | |
44 | def mes_records(self,): | |
45 | """Retourne la liste des références à traiter en fonction du filtre""" | |
46 | return self.tout_mes_records() | |
47 | ||
48 | def ref_apercu(self, record): | |
49 | return "[%s] %s" % (record.server, record.title) | |
50 | ||
51 | def change_url(self, object): | |
52 | """Retourne l'url pour éditer le record""" | |
264a3210 | 53 | return url('admin:%s_%s_change' %(object._meta.app_label, object._meta.module_name), args=[object.id]) |
6d885e0c | 54 | |
55 | def a_traiter(self, ): | |
56 | """Retourne la structure de données nécessaire pour le widget de django-admin-tool""" | |
57 | records = self.mes_records() | |
58 | return [{'title':self.ref_apercu(r), 'url':self.change_url(r), 'external': False} for r in records] | |
59 | ||
e3c3296e | 60 | @login_required |
656b9c0f PP |
61 | def assigner_categorie(request): |
62 | ids = request.GET.get("ids").split(",") | |
63 | records = Record.all_objects.in_bulk(ids) | |
64 | if request.method == 'POST': | |
65 | categorie_form = CategorieForm(request.POST) | |
66 | ||
67 | if categorie_form.is_valid(): | |
68 | ||
69 | # charger la categorie | |
70 | categorie_id = request.POST.get("categorie") | |
71 | categorie = RecordCategorie.objects.get(id=categorie_id) | |
72 | ||
73 | # assigner la catégorie à chaque référence | |
74 | for r in records.values(): | |
75 | r.categorie = categorie | |
76 | r.save() | |
77 | ||
78 | # retouner un status à l'utilisateur sur la liste des références | |
9093aa5d EMS |
79 | messages.success( |
80 | request, | |
81 | u"La catégorie %s a été assigné à %s références" % (categorie.nom, len(ids)) | |
82 | ) | |
656b9c0f PP |
83 | return HttpResponseRedirect('/admin/savoirs/record') |
84 | else: | |
85 | categorie_form = CategorieForm() | |
86 | ||
87 | return render_to_response ("savoirs/assigner.html", | |
88 | Context ({'records': records, | |
89 | 'form': categorie_form, | |
90 | 'titre': u"Assignation d'une catégorie par lots", | |
91 | 'description': u"Sélectionner la catégorie qui sera associé aux références suivantes :" , | |
92 | }), | |
93 | context_instance = RequestContext(request)) | |
94 | ||
95 | @login_required | |
e3c3296e | 96 | def assigner_pays(request): |
97 | ids = request.GET.get("ids").split(",") | |
d566e9c1 | 98 | records = Record.all_objects.in_bulk(ids) |
e3c3296e | 99 | if request.method == 'POST': |
100 | pays_form = PaysForm(request.POST) | |
101 | ||
102 | if pays_form.is_valid(): | |
103 | ||
104 | # charger tous les objets pays | |
105 | pays = [] | |
480fec39 PP |
106 | for pays_id in request.POST.getlist("pays"): |
107 | pays.append(Pays.objects.get(pk=pays_id)) | |
e3c3296e | 108 | |
109 | # assigner chaque pays à chaque référence | |
110 | for r in records.values(): | |
111 | for p in pays: | |
112 | r.pays.add(p) | |
113 | r.save() | |
114 | ||
115 | # retouner un status à l'utilisateur sur la liste des références | |
116 | pays_noms = u", ".join([p.nom for p in pays]) | |
9093aa5d EMS |
117 | messages.success( |
118 | request, | |
119 | u"Les pays %s ont été assignés à %s références" % (pays_noms, len(ids)) | |
120 | ) | |
e3c3296e | 121 | return HttpResponseRedirect('/admin/savoirs/record') |
122 | else: | |
123 | pays_form = PaysForm() | |
124 | ||
125 | return render_to_response ("savoirs/assigner.html", | |
126 | Context ({'records': records, | |
127 | 'form': pays_form, | |
128 | 'titre': u"Assignation de pays par lots", | |
129 | 'description': u"Sélectionner les pays qui seront associés aux références suivantes :" , | |
130 | }), | |
131 | context_instance = RequestContext(request)) | |
132 | ||
133 | @login_required | |
264a3210 | 134 | def assigner_regions(request, app_name, model_name): |
e3c3296e | 135 | ids = request.GET.get("ids").split(",") |
264a3210 EMS |
136 | model = get_model(app_name, model_name) |
137 | objects = model.objects.filter(pk__in=ids) | |
e3c3296e | 138 | if request.method == 'POST': |
139 | regions_form = RegionsForm(request.POST) | |
140 | ||
141 | if regions_form.is_valid(): | |
264a3210 EMS |
142 | regions = regions_form.cleaned_data['regions'] |
143 | for o in objects: | |
144 | o.assigner_regions(regions) | |
145 | o.save() | |
e3c3296e | 146 | |
e3c3296e | 147 | # retouner un status à l'utilisateur sur la liste des références |
148 | regions_noms = u", ".join([p.nom for p in regions]) | |
9093aa5d EMS |
149 | messages.success( |
150 | request, | |
151 | u"Les regions %s ont été assignées à %s objets" % | |
152 | (regions_noms, len(ids)) | |
153 | ) | |
264a3210 | 154 | return HttpResponseRedirect(url('admin:%s_%s_changelist' % (app_name, model_name))) |
e3c3296e | 155 | else: |
156 | regions_form = RegionsForm() | |
264a3210 EMS |
157 | return render_to_response( |
158 | "savoirs/assigner.html", | |
159 | dict(objects=objects, | |
160 | form=regions_form, | |
161 | titre=u"Assignation de régions par lots", | |
162 | description=u"Sélectionner les régions qui seront associées aux références suivantes :"), | |
163 | context_instance = RequestContext(request) | |
164 | ) | |
e3c3296e | 165 | |
166 | @login_required | |
264a3210 | 167 | def assigner_disciplines(request, app_name, model_name): |
e3c3296e | 168 | ids = request.GET.get("ids").split(",") |
264a3210 EMS |
169 | model = get_model(app_name, model_name) |
170 | objects = model.objects.filter(pk__in=ids) | |
e3c3296e | 171 | if request.method == 'POST': |
172 | disciplines_form = DisciplinesForm(request.POST) | |
173 | ||
174 | if disciplines_form.is_valid(): | |
264a3210 EMS |
175 | disciplines = disciplines_form.cleaned_data['disciplines'] |
176 | for o in objects: | |
177 | o.assigner_disciplines(disciplines) | |
178 | o.save() | |
e3c3296e | 179 | |
180 | # retouner un status à l'utilisateur sur la liste des références | |
181 | disciplines_noms = u", ".join([p.nom for p in disciplines]) | |
9093aa5d EMS |
182 | messages.success( |
183 | request, | |
184 | u"Les disciplines %s ont été assignées à %s objets" % | |
185 | (disciplines_noms, len(ids)) | |
186 | ) | |
264a3210 | 187 | return HttpResponseRedirect(url('admin:%s_%s_changelist' % (app_name, model_name))) |
e3c3296e | 188 | else: |
189 | disciplines_form = DisciplinesForm() | |
190 | ||
264a3210 EMS |
191 | return render_to_response( |
192 | "savoirs/assigner.html", | |
193 | dict(objects=objects, | |
194 | form=disciplines_form, | |
195 | titre=u"Assignation de disciplines par lots", | |
196 | description=u"Sélectionner les disciplines qui seront associées aux références suivantes :"), | |
197 | context_instance = RequestContext(request) | |
198 | ) | |
e3c3296e | 199 | |
200 | @login_required | |
201 | def assigner_thematiques(request): | |
202 | ids = request.GET.get("ids").split(",") | |
d566e9c1 | 203 | records = Record.all_objects.in_bulk(ids) |
e3c3296e | 204 | if request.method == 'POST': |
205 | thematiques_form = ThematiquesForm(request.POST) | |
206 | ||
207 | if thematiques_form.is_valid(): | |
208 | ||
209 | # charger tous les objets thematiques | |
210 | thematiques = [] | |
211 | for thematique_id in request.POST.getlist("thematiques"): | |
212 | thematiques.append(Thematique.objects.get(id=thematique_id)) | |
213 | ||
214 | # assigner chaque thematiques à chaque référence | |
215 | for r in records.values(): | |
216 | for p in thematiques: | |
217 | r.thematiques.add(p) | |
218 | r.save() | |
219 | ||
220 | # retouner un status à l'utilisateur sur la liste des références | |
221 | thematiques_noms = u", ".join([p.nom for p in thematiques]) | |
9093aa5d EMS |
222 | messages.success( |
223 | request, | |
224 | u"Les thématiques %s ont été assignées à %s références" % | |
225 | (thematiques_noms, len(ids)) | |
226 | ) | |
e3c3296e | 227 | return HttpResponseRedirect('/admin/savoirs/record') |
228 | else: | |
229 | thematiques_form = ThematiquesForm() | |
230 | ||
231 | return render_to_response ("savoirs/assigner.html", | |
232 | Context ({'records': records, | |
233 | 'form': thematiques_form, | |
234 | 'titre': u"Assignation de thématiques par lots", | |
235 | 'description': u"Sélectionner les thématiques qui seront associées aux références suivantes :" , | |
236 | }), | |
237 | context_instance = RequestContext(request)) | |
2be148fe | 238 | |
239 | @login_required | |
240 | def confirmation(request, action): | |
241 | ids = request.GET.get("ids").split(",") | |
f554ef70 | 242 | type, action = action.split('/')[0:2] |
2be148fe | 243 | |
244 | # determination du contexte de validation | |
245 | if action == u'valider': | |
d566e9c1 | 246 | objects = [r for r in Record.all_objects.in_bulk(ids).values() if r.est_complet()] |
f554ef70 | 247 | action = ('validated', True) |
2be148fe | 248 | desc = u'validées' |
f554ef70 | 249 | model = u'références' |
250 | ||
2be148fe | 251 | elif action == u'invalider': |
d566e9c1 | 252 | objects = Record.all_objects.in_bulk(ids).values() |
f554ef70 | 253 | action = ('validated', False) |
2be148fe | 254 | desc = u'invalidées' |
f554ef70 | 255 | model = u'références' |
256 | ||
257 | elif action == u'visible': | |
011804bb | 258 | objects = Actualite.all_objects.in_bulk(ids).values() |
f554ef70 | 259 | action = ('visible', True) |
260 | desc = u'visibles' | |
261 | model = u'actualités' | |
262 | ||
263 | elif action == u'invisible': | |
011804bb | 264 | objects = Actualite.all_objects.in_bulk(ids).values() |
f554ef70 | 265 | action = ('visible', False) |
266 | desc = u'invisibles' | |
267 | model = u'actualités' | |
268 | ||
2be148fe | 269 | else: |
270 | raise Exception("action invalide %s " % action) | |
271 | ||
272 | if request.method == 'POST': | |
273 | confirmation_form = ConfirmationForm(request.POST) | |
274 | ||
275 | if confirmation_form.is_valid(): | |
f554ef70 | 276 | for o in objects: |
277 | setattr(o, action[0], action[1]) | |
278 | o.save() | |
2be148fe | 279 | |
9093aa5d EMS |
280 | messages.success( |
281 | request, | |
282 | u"Les références ont été %s" % desc | |
283 | ) | |
f554ef70 | 284 | return HttpResponseRedirect('/admin/savoirs/%s' % type) |
2be148fe | 285 | else: |
286 | confirmation_form = ConfirmationForm() | |
287 | ||
288 | ||
289 | return render_to_response ("savoirs/confirmation.html", | |
f554ef70 | 290 | Context ({'objects': objects, |
2be148fe | 291 | 'action': action, |
292 | 'form': confirmation_form, | |
293 | 'titre': u"Validation par lots", | |
f554ef70 | 294 | 'description': u"Les %s suivantes vont être %s:" % (model, desc) , |
2be148fe | 295 | }), |
296 | context_instance = RequestContext(request)) | |
9c29b8d4 EMS |
297 | |
298 | # Stats | |
299 | ||
811f79a4 | 300 | @permission_required('savoirs.statistiques') |
9c29b8d4 | 301 | def stats(request): |
03ba3d5f EMS |
302 | |
303 | def mises_a_jour(qs): | |
304 | return qs.filter(date_modification__gte='2010-11-17').count() | |
305 | ||
306 | def par_region(qs): | |
307 | qs = qs.extra(select={ | |
308 | 'region': '''(SELECT p.region FROM ref_pays p | |
309 | WHERE p.code = CASE WHEN chercheurs_chercheur.etablissement IS NULL | |
310 | THEN chercheurs_chercheur.etablissement_autre_pays | |
311 | ELSE (SELECT e.pays FROM ref_etablissement e | |
312 | WHERE e.id = chercheurs_chercheur.etablissement) END)''' | |
313 | }) | |
314 | return dict(qs.values_list('region').annotate(count=Count('pk'))) | |
315 | ||
316 | def par_hemisphere(qs): | |
317 | qs = qs.extra(select={ | |
318 | 'hemisphere': '''(SELECT p.nord_sud FROM ref_pays p | |
319 | WHERE p.code = CASE WHEN chercheurs_chercheur.etablissement IS NULL | |
320 | THEN chercheurs_chercheur.etablissement_autre_pays | |
321 | ELSE (SELECT e.pays FROM ref_etablissement e | |
322 | WHERE e.id = chercheurs_chercheur.etablissement) END)''' | |
323 | }) | |
324 | return dict(qs.values_list('hemisphere').annotate(count=Count('pk'))) | |
325 | ||
326 | def par_discipline(qs): | |
327 | return dict(qs.values_list('discipline').annotate(count=Count('pk'))) | |
328 | ||
329 | def par_domaine(qs): | |
18407f73 PP |
330 | qs = qs.extra(tables=['chercheurs_adhesiongroupe', 'chercheurs_groupe'], |
331 | where=['chercheurs_adhesiongroupe.chercheur = chercheurs_chercheur.personne_ptr_id', | |
332 | 'chercheurs_adhesiongroupe.groupe = chercheurs_groupe.id', | |
6508c994 | 333 | 'chercheurs_groupe.groupe_chercheur = 0'], |
18407f73 | 334 | select={'groupe': 'chercheurs_adhesiongroupe.groupe'}) |
6508c994 PP |
335 | return dict(qs.values_list('groupe').annotate(count=Count('pk'))) |
336 | ||
337 | def par_groupe(qs): | |
18407f73 PP |
338 | qs = qs.extra(tables=['chercheurs_adhesiongroupe', 'chercheurs_groupe'], |
339 | where=['chercheurs_adhesiongroupe.chercheur = chercheurs_chercheur.personne_ptr_id', | |
340 | 'chercheurs_adhesiongroupe.groupe = chercheurs_groupe.id', | |
6508c994 | 341 | 'chercheurs_groupe.groupe_chercheur = 1'], |
18407f73 | 342 | select={'groupe': 'chercheurs_adhesiongroupe.groupe'}) |
03ba3d5f EMS |
343 | return dict(qs.values_list('groupe').annotate(count=Count('pk'))) |
344 | ||
345 | chercheurs = Chercheur.objects | |
346 | hommes = chercheurs.filter(genre='m') | |
347 | femmes = chercheurs.filter(genre='f') | |
9c29b8d4 | 348 | return render_to_response( |
03ba3d5f EMS |
349 | 'savoirs/stats.html', { |
350 | 'nb_chercheurs': chercheurs.count(), | |
351 | 'nb_hommes': hommes.count(), | |
352 | 'nb_femmes': femmes.count(), | |
353 | 'mises_a_jour': mises_a_jour(chercheurs), | |
354 | 'mises_a_jour_hommes': mises_a_jour(hommes), | |
355 | 'mises_a_jour_femmes': mises_a_jour(femmes), | |
356 | 'regions': Region.objects.order_by('nom'), | |
357 | 'chercheurs_par_region': par_region(chercheurs), | |
358 | 'hommes_par_region': par_region(hommes), | |
359 | 'femmes_par_region': par_region(femmes), | |
360 | 'hemispheres': ['Nord', 'Sud'], | |
361 | 'chercheurs_par_hemisphere': par_hemisphere(chercheurs), | |
362 | 'hommes_par_hemisphere': par_hemisphere(hommes), | |
363 | 'femmes_par_hemisphere': par_hemisphere(femmes), | |
364 | 'disciplines': Discipline.objects.order_by('nom'), | |
365 | 'chercheurs_par_discipline': par_discipline(chercheurs), | |
366 | 'hommes_par_discipline': par_discipline(hommes), | |
367 | 'femmes_par_discipline': par_discipline(femmes), | |
6508c994 | 368 | 'domaines': DomaineRecherche.objects.order_by('nom'), |
03ba3d5f EMS |
369 | 'chercheurs_par_domaine': par_domaine(chercheurs), |
370 | 'hommes_par_domaine': par_domaine(hommes), | |
371 | 'femmes_par_domaine': par_domaine(femmes), | |
6508c994 PP |
372 | 'groupeschercheurs': GroupeChercheur.objects.order_by('nom'), |
373 | 'chercheurs_par_groupe': par_groupe(chercheurs), | |
374 | 'hommes_par_groupe': par_groupe(hommes), | |
375 | 'femmes_par_groupe': par_groupe(femmes), | |
03ba3d5f | 376 | }, context_instance=RequestContext(request) |
9c29b8d4 | 377 | ) |