Organigrammes, modification du lien vers les postes
[auf_rh_dae.git] / project / rh / graph.py
1 # -*- encoding: utf-8 -*-
2
3 import pygraphviz as pgv
4
5 from datetime import date
6 from django.db.models import Q
7 from django.core.urlresolvers import reverse
8
9 from rh import models as rh
10
11 def bind_poste_to_graph(graph, postes_by_id):
12 for n in graph.nodes():
13 p = postes_by_id[int(n)]
14 try:
15 d = rh.Dossier.objects.select_related('employe').filter((Q(date_fin__gt=date.today()) | Q(date_fin=None)) & (Q(date_debut__lt=date.today()) | Q(date_debut=None)) & Q(poste=p)).exclude(supprime=True).all()[0]
16
17
18 label = u"%s\\n[%s] %s\\n%s" % (d.poste.nom, d.employe_id, "%s %s" %
19 (d.employe.nom.upper(), d.employe.prenom),
20 d.poste.implantation)
21 except IndexError:
22 label = u"%s\\n---\\n%s" % (d.poste.nom, d.poste.implantation)
23 n.attr['fillcolor'] = 'azure4'
24 n.attr['style'] = 'filled'
25
26 n.attr['label'] = label.encode('ascii', 'xmlcharrefreplace')
27 n.attr['href'] = reverse("admin:rh_poste_change", args=(d.poste_id,))
28
29 return graph
30
31 def organigramme_postes_cluster(cluster_filter, titre=u"Organigramme", cluster_titre=u"Cluster 1"):
32 """ Crée un organigramme des postes avec un cluster défini par le keyword qui sera
33 rajouté au queryset en tant que filter.
34 cluster_filter doit être un map de format (field: value) qui sera appliqué au queryset.
35 Par exemple: cluster_filter={"service__exact": 19}
36 """
37 if type(titre) != type(unicode()):
38 raise "Le titre du graphique doit être un unicode"
39 if type(cluster_titre) != type(unicode()):
40 raise "Le titre du cluster doit être un unicode"
41
42 postes_by_id = dict((p.id, p) for p in rh.Poste.objects.all())
43
44 postes = rh.Poste.objects.select_related('implantation').filter((Q(date_fin__gt=date.today()) | Q(date_fin=None)) & (Q(date_debut__lt=date.today()) | Q(date_debut=None)) ).filter(**cluster_filter).exclude(supprime=True, responsable=None).all()
45
46 nom = titre.encode('ascii', 'xmlcharrefreplace')
47 graph = pgv.AGraph(directed=True, name=nom)
48 #pour mettre l'organigramme de gauche à droite (au lieu du haut à bas)
49 #graph.rankdir='LR'
50 graph_service = graph.subgraph(nbunch=[1,2], \
51 name="cluster1", \
52 style='filled', \
53 color='lightgrey', \
54 label=cluster_titre.encode('ascii', 'xmlcharrefreplace'),
55 labeljust="l")
56
57 for p in postes:
58 graph_service.add_node(p.id)
59 if p.responsable_id:
60 graph.add_edge(p.responsable_id, p.id)
61
62 for p_id in graph_service.nodes():
63 if postes_by_id[int(p_id)].responsable_id:
64 poste_remontant = postes_by_id[int(p_id)]
65 while poste_remontant.responsable_id and poste_remontant.responsable_id and poste_remontant.responsable_id != poste_remontant.id:
66 poste_remontant = postes_by_id[poste_remontant.responsable_id]
67 if poste_remontant.responsable_id:
68 graph.add_edge(poste_remontant.responsable_id, poste_remontant.id)
69
70 bind_poste_to_graph(graph, postes_by_id)
71
72 graph.layout(prog='dot')
73
74 svg = graph.draw(format='svg')
75
76 return svg
77
78