Commit | Line | Data |
---|---|---|
82af5c19 JPC |
1 | # -*- encoding: utf-8 -*- |
2 | ||
5c0f1778 | 3 | from datetime import date |
b31ce2d7 | 4 | |
5c0f1778 JPC |
5 | from django.db.models import Q |
6 | from django.core.urlresolvers import reverse | |
75f0e87b | 7 | import pygraphviz as pgv |
5c0f1778 | 8 | |
7000b7b3 | 9 | from project.permissions import user_can_change_obj |
75f0e87b | 10 | from project.rh import models as rh |
5c0f1778 | 11 | |
b31ce2d7 | 12 | |
7000b7b3 | 13 | def bind_poste_to_graph(user, graph, postes_by_id): |
5c0f1778 | 14 | for n in graph.nodes(): |
7000b7b3 DB |
15 | # poste = node |
16 | poste = postes_by_id[int(n)] | |
17 | ||
18 | # dossiers actifs pour ce poste | |
a88783f9 JPC |
19 | dossiers = rh.Dossier.objects.select_related('employe').filter( |
20 | (Q(date_fin__gt=date.today()) | Q(date_fin=None)) & | |
21 | (Q(date_debut__lt=date.today()) | Q(date_debut=None)) & | |
22 | Q(poste__id=n) | |
45066657 | 23 | ).all() |
a88783f9 | 24 | |
7000b7b3 | 25 | # affichage |
a88783f9 JPC |
26 | if dossiers: |
27 | employes = "\\n".join( | |
b31ce2d7 EMS |
28 | ["[%s] %s %s" % |
29 | (d.employe_id, d.employe.nom.upper(), | |
a88783f9 JPC |
30 | d.employe.prenom |
31 | ) for d in dossiers] | |
32 | ) | |
b31ce2d7 EMS |
33 | label = u"%s\\n%s\\n%s" % ( |
34 | d.poste.nom, employes, d.poste.implantation | |
35 | ) | |
a88783f9 | 36 | else: |
ca2b4ba8 | 37 | label = u"%s\\n---\\n%s" % (poste.nom, poste.implantation) |
5c0f1778 JPC |
38 | n.attr['fillcolor'] = 'azure4' |
39 | n.attr['style'] = 'filled' | |
40 | ||
242b2ec7 | 41 | n.attr['label'] = label.encode('ascii', 'xmlcharrefreplace') |
7000b7b3 DB |
42 | # lien seulement si user peut editer poste |
43 | if user_can_change_obj(user, poste): | |
44 | n.attr['href'] = reverse("admin:rh_poste_change", args=(n,)) | |
5c0f1778 JPC |
45 | |
46 | return graph | |
82af5c19 | 47 | |
b31ce2d7 | 48 | |
7000b7b3 | 49 | def organigramme_postes_cluster(user, cluster_filter, titre=u"Organigramme", |
b31ce2d7 EMS |
50 | cluster_titre=u"Cluster 1"): |
51 | """ | |
52 | Crée un organigramme des postes avec un cluster défini par le keyword | |
53 | qui sera rajouté au queryset en tant que filter. | |
54 | ||
55 | cluster_filter doit être un map de format (field: value) qui sera | |
56 | appliqué au queryset. | |
57 | ||
82af5c19 JPC |
58 | Par exemple: cluster_filter={"service__exact": 19} |
59 | """ | |
60 | if type(titre) != type(unicode()): | |
61 | raise "Le titre du graphique doit être un unicode" | |
62 | if type(cluster_titre) != type(unicode()): | |
63 | raise "Le titre du cluster doit être un unicode" | |
64 | ||
65 | postes_by_id = dict((p.id, p) for p in rh.Poste.objects.all()) | |
66 | ||
b31ce2d7 EMS |
67 | postes = rh.Poste.objects.select_related('implantation').filter( |
68 | Q(date_fin__gt=date.today()) | Q(date_fin=None), | |
69 | Q(date_debut__lt=date.today()) | Q(date_debut=None), | |
70 | **cluster_filter | |
45066657 | 71 | ).exclude(responsable=None) |
82af5c19 JPC |
72 | |
73 | nom = titre.encode('ascii', 'xmlcharrefreplace') | |
74 | graph = pgv.AGraph(directed=True, name=nom) | |
75 | #pour mettre l'organigramme de gauche à droite (au lieu du haut à bas) | |
76 | #graph.rankdir='LR' | |
b31ce2d7 | 77 | graph_service = graph.subgraph(nbunch=[1, 2], name="cluster1") |
8912e5a9 JPC |
78 | graph_service.graph_attr['style'] = 'filled' |
79 | graph_service.graph_attr['color'] = 'lightgrey' | |
b31ce2d7 EMS |
80 | graph_service.graph_attr['label'] = \ |
81 | cluster_titre.encode('ascii', 'xmlcharrefreplace') | |
8912e5a9 | 82 | graph_service.graph_attr['labeljust'] = 'l' |
82af5c19 JPC |
83 | |
84 | for p in postes: | |
85 | graph_service.add_node(p.id) | |
86 | if p.responsable_id: | |
87 | graph.add_edge(p.responsable_id, p.id) | |
88 | ||
89 | for p_id in graph_service.nodes(): | |
90 | if postes_by_id[int(p_id)].responsable_id: | |
91 | poste_remontant = postes_by_id[int(p_id)] | |
b31ce2d7 EMS |
92 | while poste_remontant.responsable_id \ |
93 | and poste_remontant.responsable_id \ | |
94 | and poste_remontant.responsable_id != poste_remontant.id: | |
82af5c19 JPC |
95 | poste_remontant = postes_by_id[poste_remontant.responsable_id] |
96 | if poste_remontant.responsable_id: | |
b31ce2d7 EMS |
97 | graph.add_edge( |
98 | poste_remontant.responsable_id, poste_remontant.id | |
99 | ) | |
82af5c19 | 100 | |
7000b7b3 | 101 | bind_poste_to_graph(user, graph, postes_by_id) |
82af5c19 JPC |
102 | |
103 | graph.layout(prog='dot') | |
104 | ||
105 | svg = graph.draw(format='svg') | |
82af5c19 | 106 | |
b31ce2d7 | 107 | return svg |