-import unicodedata
+# -*- encoding: utf-8 -*-
+
+import pygraphviz as pgv
+
from datetime import date
from django.db.models import Q
from django.core.urlresolvers import reverse
def bind_poste_to_graph(graph, postes_by_id):
for n in graph.nodes():
- p = postes_by_id[int(n)]
- try:
- 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]
+ dossiers = 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__id=n)
+ ).exclude(supprime=True).all()
- label = u"%s\\n[%s] %s\\n%s" % (d.poste.nom, d.employe_id, "%s %s" %
- (d.employe.nom.upper(), d.employe.prenom),
- d.poste.implantation)
- except IndexError:
+ if dossiers:
+ employes = "\\n".join(
+ ["[%s] %s %s" %
+ (d.employe_id, d.employe.nom.upper(),
+ d.employe.prenom
+ ) for d in dossiers]
+ )
+ label = u"%s\\n%s\\n%s" % (d.poste.nom, employes, d.poste.implantation)
+ else:
label = u"%s\\n---\\n%s" % (d.poste.nom, d.poste.implantation)
n.attr['fillcolor'] = 'azure4'
n.attr['style'] = 'filled'
- label = unicodedata.normalize('NFKD', label).encode('ascii','ignore')
- n.attr['label'] = label
- n.attr['href'] = reverse("admin:rh_employe_change", args=(d.employe_id,))
+ n.attr['label'] = label.encode('ascii', 'xmlcharrefreplace')
+ n.attr['href'] = reverse("admin:rh_poste_change", args=(n,))
return graph
+
+def organigramme_postes_cluster(cluster_filter, titre=u"Organigramme", cluster_titre=u"Cluster 1"):
+ """ Crée un organigramme des postes avec un cluster défini par le keyword qui sera
+ rajouté au queryset en tant que filter.
+ cluster_filter doit être un map de format (field: value) qui sera appliqué au queryset.
+ Par exemple: cluster_filter={"service__exact": 19}
+ """
+ if type(titre) != type(unicode()):
+ raise "Le titre du graphique doit être un unicode"
+ if type(cluster_titre) != type(unicode()):
+ raise "Le titre du cluster doit être un unicode"
+
+ postes_by_id = dict((p.id, p) for p in rh.Poste.objects.all())
+
+ 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()
+
+ nom = titre.encode('ascii', 'xmlcharrefreplace')
+ graph = pgv.AGraph(directed=True, name=nom)
+ #pour mettre l'organigramme de gauche à droite (au lieu du haut à bas)
+ #graph.rankdir='LR'
+ graph_service = graph.subgraph(nbunch=[1,2], \
+ name="cluster1", \
+ # style='filled', \
+ # color='lightgrey', \
+ # label=cluster_titre.encode('ascii', 'xmlcharrefreplace'),
+ # labeljust="l")
+ )
+ graph_service.graph_attr['style'] = 'filled'
+ graph_service.graph_attr['color'] = 'lightgrey'
+ graph_service.graph_attr['label'] = cluster_titre.encode('ascii', 'xmlcharrefreplace')
+ graph_service.graph_attr['labeljust'] = 'l'
+
+ for p in postes:
+ graph_service.add_node(p.id)
+ if p.responsable_id:
+ graph.add_edge(p.responsable_id, p.id)
+
+ for p_id in graph_service.nodes():
+ if postes_by_id[int(p_id)].responsable_id:
+ poste_remontant = postes_by_id[int(p_id)]
+ while poste_remontant.responsable_id and poste_remontant.responsable_id and poste_remontant.responsable_id != poste_remontant.id:
+ poste_remontant = postes_by_id[poste_remontant.responsable_id]
+ if poste_remontant.responsable_id:
+ graph.add_edge(poste_remontant.responsable_id, poste_remontant.id)
+
+ bind_poste_to_graph(graph, postes_by_id)
+
+ graph.layout(prog='dot')
+
+ svg = graph.draw(format='svg')
+
+ return svg
+
+