From 33d8f038d78c693b62f880883720db9a005e90d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Tue, 15 Mar 2016 18:59:11 +0100 Subject: [PATCH] Add workflow graph on ir.model issue5292 review15961002 --- CHANGELOG | 1 + trytond/ir/__init__.py | 1 + trytond/ir/model.py | 58 +++++++++++++++++++++++++++++++++++++++++- trytond/ir/model.xml | 12 +++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index f20cbd57ed..015b1f865a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add workflow graph on ir.model * Add context model on ir.action.act_window * Switch to WSGI API * Limit the login size in LoginAttempt diff --git a/trytond/ir/__init__.py b/trytond/ir/__init__.py index ad5a5cc087..a000482ec6 100644 --- a/trytond/ir/__init__.py +++ b/trytond/ir/__init__.py @@ -98,4 +98,5 @@ def register(): module='ir', type_='wizard') Pool.register( ModelGraph, + ModelWorkflowGraph, module='ir', type_='report') diff --git a/trytond/ir/model.py b/trytond/ir/model.py index 0fe55cce5d..9045980843 100644 --- a/trytond/ir/model.py +++ b/trytond/ir/model.py @@ -12,7 +12,7 @@ try: except ImportError: import json -from ..model import ModelView, ModelSQL, fields, Unique +from ..model import ModelView, ModelSQL, Workflow, fields, Unique from ..report import Report from ..wizard import Wizard, StateView, StateAction, Button from ..transaction import Transaction @@ -31,6 +31,7 @@ except ImportError: __all__ = [ 'Model', 'ModelField', 'ModelAccess', 'ModelFieldAccess', 'ModelButton', 'ModelData', 'PrintModelGraphStart', 'PrintModelGraph', 'ModelGraph', + 'ModelWorkflowGraph', ] IDENTIFIER = re.compile(r'^[a-zA-z_][a-zA-Z0-9_]*$') @@ -1095,3 +1096,58 @@ class ModelGraph(Report): edge = pydot.Edge(str(tail), str(head), **args) graph.add_edge(edge) + + +class ModelWorkflowGraph(Report): + __name__ = 'ir.model.workflow_graph' + + @classmethod + def execute(cls, ids, data): + import pydot + pool = Pool() + Model = pool.get('ir.model') + ActionReport = pool.get('ir.action.report') + + action_report_ids = ActionReport.search([ + ('report_name', '=', cls.__name__) + ]) + if not action_report_ids: + raise Exception('Error', 'Report (%s) not find!' % cls.__name__) + action_report = ActionReport(action_report_ids[0]) + + models = Model.browse(ids) + + graph = pydot.Dot() + graph.set('center', '1') + graph.set('ratio', 'auto') + direction = Transaction().context.get('language_direction', 'ltr') + graph.set('rankdir', {'ltr': 'LR', 'rtl': 'RL'}[direction]) + cls.fill_graph(models, graph) + data = graph.create(prog='dot', format='png') + return ('png', fields.Binary.cast(data), False, action_report.name) + + @classmethod + def fill_graph(cls, models, graph): + 'Fills pydot graph with models wizard.' + import pydot + pool = Pool() + + for record in models: + Model = pool.get(record.model) + + if not issubclass(Model, Workflow): + continue + + subgraph = pydot.Cluster('%s' % record.id, label=record.model) + graph.add_subgraph(subgraph) + + state_field = getattr(Model, Model._transition_state) + for state, _ in state_field.selection: + node = pydot.Node( + '"%s"' % state, shape='octagon', label=state) + subgraph.add_node(node) + + for from_, to in Model._transitions: + edge = pydot.Edge('"%s"' % from_, '"%s"' % to, + arrowhead='normal') + subgraph.add_edge(edge) diff --git a/trytond/ir/model.xml b/trytond/ir/model.xml index ae4d69d879..4983161869 100644 --- a/trytond/ir/model.xml +++ b/trytond/ir/model.xml @@ -143,6 +143,18 @@ this repository contains the full copyright notices and license terms. --> + + Workflow Graph + ir.model + ir.model.workflow_graph + + + form_print + ir.model,-1 + + + ir.model.button tree