1 # -*- encoding: utf-8 -*-
3 from datetime
import date
5 from django
.db
.models
import Q
6 from django
.core
.urlresolvers
import reverse
7 import pygraphviz
as pgv
9 from project
.permissions
import user_can_change_obj
10 from project
.rh
import models
as rh
13 def bind_poste_to_graph(user
, graph
, postes_by_id
):
14 for n
in graph
.nodes():
16 poste
= postes_by_id
[int(n
)]
18 # dossiers actifs pour ce poste
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)) &
27 employes
= "\\n".join(
29 (d
.employe_id
, d
.employe
.nom
.upper(),
33 label
= u
"%s\\n%s\\n%s" % (
34 d
.poste
.nom
, employes
, d
.poste
.implantation
37 label
= u
"%s\\n---\\n%s" % (poste
.nom
, poste
.implantation
)
38 n
.attr
['fillcolor'] = 'azure4'
39 n
.attr
['style'] = 'filled'
41 n
.attr
['label'] = label
.encode('ascii', 'xmlcharrefreplace')
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
,))
49 def organigramme_postes_cluster(user
, cluster_filter
, titre
=u
"Organigramme",
50 cluster_titre
=u
"Cluster 1"):
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.
55 cluster_filter doit être un map de format (field: value) qui sera
58 Par exemple: cluster_filter={"service__exact": 19}
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"
65 postes_by_id
= dict((p
.id, p
) for p
in rh
.Poste
.objects
.all())
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),
71 ).exclude(responsable
=None)
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)
77 graph_service
= graph
.subgraph(nbunch
=[1, 2], name
="cluster1")
78 graph_service
.graph_attr
['style'] = 'filled'
79 graph_service
.graph_attr
['color'] = 'lightgrey'
80 graph_service
.graph_attr
['label'] = \
81 cluster_titre
.encode('ascii', 'xmlcharrefreplace')
82 graph_service
.graph_attr
['labeljust'] = 'l'
85 graph_service
.add_node(p
.id)
87 graph
.add_edge(p
.responsable_id
, p
.id)
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
)]
92 while poste_remontant
.responsable_id \
93 and poste_remontant
.responsable_id \
94 and poste_remontant
.responsable_id
!= poste_remontant
.id:
95 poste_remontant
= postes_by_id
[poste_remontant
.responsable_id
]
96 if poste_remontant
.responsable_id
:
98 poste_remontant
.responsable_id
, poste_remontant
.id
101 bind_poste_to_graph(user
, graph
, postes_by_id
)
103 graph
.layout(prog
='dot')
105 svg
= graph
.draw(format
='svg')