Added a processus module
bzr revid: fp@tinyerp.com-20080714170130-prxnz5qp1c4if445
This commit is contained in:
parent
339cd70703
commit
50af83dac6
|
@ -0,0 +1,29 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
# Fabien Pinckaers <fp@tiny.Be>
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import processus
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name" : "Enterprise Processus",
|
||||
"version" : "1.0",
|
||||
"author" : "Tiny",
|
||||
"website" : "http://tinyerp.com",
|
||||
"category" : "Generic Modules/Base",
|
||||
"description": """
|
||||
This module allows you to manage your processus for the end-users.
|
||||
""",
|
||||
"depends" : ["base"],
|
||||
"init_xml" : [],
|
||||
"demo_xml" : [],
|
||||
"update_xml" : [
|
||||
'processus_view.xml',
|
||||
'ir.model.access.csv'],
|
||||
"active": False,
|
||||
"installable": True
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_processus,processus.processus,model_processus_processus,,1,0,0,0
|
||||
access_node,processus.node,model_processus_node,,1,0,0,0
|
||||
access_transition,processus.transition,model_processus_transition,,1,0,0,0
|
||||
access_action,processus.transition.action,model_processus_transition_action,,1,0,0,0
|
||||
access_group_processus,processus.processus,model_processus_processus,base.group_admin,1,1,1,1
|
||||
access_group_node,processus.node,model_processus_node,base.group_admin,1,1,1,1
|
||||
access_group_transition,processus.transition,model_processus_transition,base.group_admin,1,1,1,1
|
||||
access_group_action,processus.transition.action,model_processus_transition_action,base.group_admin,1,1,1,1
|
|
|
@ -0,0 +1,103 @@
|
|||
##############################################################################
|
||||
#
|
||||
# Copyright (c) 2005-TODAY TINY SPRL. (http://tiny.be) All Rights Reserved.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contract a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import netsvc
|
||||
from osv import fields, osv
|
||||
|
||||
|
||||
class processus_processus(osv.osv):
|
||||
_name = "processus.processus"
|
||||
_description = "Processus"
|
||||
_columns = {
|
||||
'name': fields.char('Processus', size=30,required=True),
|
||||
'active': fields.boolean('Active'),
|
||||
'note': fields.text('Notes'),
|
||||
'node_ids': fields.one2many('processus.node', 'processus_id', 'Nodes')
|
||||
}
|
||||
_defaults = {
|
||||
'active' : lambda *a: True,
|
||||
}
|
||||
processus_processus()
|
||||
|
||||
class processus_node(osv.osv):
|
||||
_name = 'processus.node'
|
||||
_description ='Processus Nodes'
|
||||
_columns = {
|
||||
'name': fields.char('Processus', size=30,required=True),
|
||||
'processus_id': fields.many2one('processus.processus', 'Processus', required=True),
|
||||
'kind': fields.selection([('state','State'),('router','Router'),('subflow','Subflow')],'Kind of Node', required=True),
|
||||
'menu_id': fields.many2one('ir.ui.menu', 'Related Menu'),
|
||||
'note': fields.text('Notes'),
|
||||
'model_id': fields.many2one('ir.model', 'Model', ondelete='set null'),
|
||||
'model_states': fields.char('States Expression', size=128),
|
||||
'flow_start': fields.boolean('Starting Flow'),
|
||||
'transition_in': fields.one2many('processus.transition', 'node_from_id', 'Starting Transitions'),
|
||||
'transition_out': fields.one2many('processus.transition', 'node_to_id', 'Ending Transitions'),
|
||||
}
|
||||
_defaults = {
|
||||
'kind': lambda *args: 'state',
|
||||
'model_states': lambda *args: False,
|
||||
'flow_start': lambda *args: False,
|
||||
}
|
||||
processus_node()
|
||||
|
||||
class processus_transition(osv.osv):
|
||||
_name = 'processus.transition'
|
||||
_description ='Processus Transitions'
|
||||
_columns = {
|
||||
'name': fields.char('Transitions', size=32, required=True),
|
||||
'node_from_id': fields.many2one('processus.node', 'Origin Node', required=True, ondelete='cascade'),
|
||||
'node_to_id': fields.many2one('processus.node', 'Destination Node', required=True, ondelete='cascade'),
|
||||
'transition_ids': fields.many2many('workflow.transition', 'processus_transition_ids', 'trans1_id', 'trans2_id', 'Workflow Transitions'),
|
||||
'note': fields.text('Description'),
|
||||
'action_ids': fields.one2many('processus.transition.action', 'transition_id', 'Buttons')
|
||||
}
|
||||
_defaults = {
|
||||
}
|
||||
processus_transition()
|
||||
|
||||
class processus_transition_action(osv.osv):
|
||||
_name = 'processus.transition.action'
|
||||
_description ='Processus Transitions Actions'
|
||||
_columns = {
|
||||
'name': fields.char('Transitions', size=32, required=True),
|
||||
'state': fields.selection([('dummy','Dummy'),('method','Object Method'),('workflow','Workflow Trigger'),('action','Action')], 'Type', required=True),
|
||||
'action': fields.char('Action ID', size=64, states={
|
||||
'dummy':[('readonly',1)],
|
||||
'method':[('required',1)],
|
||||
'workflow':[('required',1)],
|
||||
'action':[('required',1)],
|
||||
},),
|
||||
'transition_id': fields.many2one('processus.transition', 'Transition', required=True, ondelete='cascade')
|
||||
}
|
||||
_defaults = {
|
||||
'state': lambda *args: 'dummy',
|
||||
}
|
||||
processus_transition_action()
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
<?xml version="1.0" ?>
|
||||
<terp>
|
||||
<data>
|
||||
|
||||
<menuitem
|
||||
id="menu_processus"
|
||||
name="Enterprise Processus"
|
||||
parent="base.menu_custom"/>
|
||||
|
||||
<!-- Views for Processus -->
|
||||
<record model="ir.ui.view" id="view_processus_form">
|
||||
<field name="name">processus.processus.form</field>
|
||||
<field name="model">processus.processus</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Processus">
|
||||
<notebook>
|
||||
<page string="Processus">
|
||||
<field name="name" select="1"/>
|
||||
<field name="active" select="2"/>
|
||||
<field name="note" colspan="4"/>
|
||||
</page><page string="Nodes">
|
||||
<field name="node_ids" colspan="4" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_processus_tree">
|
||||
<field name="name">processus.processus.tree</field>
|
||||
<field name="model">processus.processus</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Processus">
|
||||
<field name="name"/>
|
||||
<field name="active"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_processus_form">
|
||||
<field name="name">Processus</field>
|
||||
<field name="res_model">processus.processus</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem
|
||||
id="menu_processus_form"
|
||||
action="action_processus_form"
|
||||
parent="menu_processus"/>
|
||||
|
||||
<!-- Views for Processus Nodes -->
|
||||
|
||||
<record model="ir.ui.view" id="view_processus_node_tree">
|
||||
<field name="name">processus.node.tree</field>
|
||||
<field name="model">processus.node</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Processus Node">
|
||||
<field name="name"/>
|
||||
<field name="processus_id"/>
|
||||
<field name="flow_start"/>
|
||||
<field name="kind"/>
|
||||
<field name="model_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_processus_node_form">
|
||||
<field name="name">processus.node.form</field>
|
||||
<field name="model">processus.node</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Processus Node">
|
||||
<notebook>
|
||||
<page string="Node Description">
|
||||
<field name="name" select="1"/>
|
||||
<newline/>
|
||||
<field name="processus_id" select="1"/>
|
||||
<field name="flow_start"/>
|
||||
<field name="kind" select="1"/>
|
||||
<field name="model_id" select="1"/>
|
||||
<field name="model_states"/>
|
||||
<newline/>
|
||||
<field name="menu_id" select="2"/>
|
||||
<separator string="Outgoing Transitions" colspan="4"/>
|
||||
<field name="transition_out" colspan="4" nolabel="1">
|
||||
<tree string="Outgoing Transitions">
|
||||
<field name="name"/>
|
||||
<field name="node_to_id"/>
|
||||
</tree>
|
||||
<form string="Outgoing Transitions">
|
||||
<notebook>
|
||||
<page name="Description">
|
||||
<field name="name"/>
|
||||
<newline/>
|
||||
<field name="node_from_id"/>
|
||||
<field name="node_to_id"/>
|
||||
<field name="note" colspan="4"/>
|
||||
</page><page string="Transitions">
|
||||
<field name="action_ids" colspan="4"/>
|
||||
<field name="transition_ids" colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Extra Information">
|
||||
<field name="note" nolabel="1" colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_processus_node_form">
|
||||
<field name="name">Processus Node</field>
|
||||
<field name="res_model">processus.node</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<menuitem
|
||||
action="action_processus_node_form"
|
||||
parent="menu_processus"
|
||||
id="menu_partner_address_form"/>
|
||||
|
||||
|
||||
<!-- Views for Partners -->
|
||||
<record model="ir.ui.view" id="view_transition_form">
|
||||
<field name="name">Processus Transitions</field>
|
||||
<field name="model">processus.transition</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Transitions">
|
||||
<notebook>
|
||||
<page name="Description">
|
||||
<field name="name"/>
|
||||
<newline/>
|
||||
<field name="node_from_id"/>
|
||||
<field name="node_to_id"/>
|
||||
<field name="note" colspan="4"/>
|
||||
</page><page string="Transitions">
|
||||
<field name="action_ids" colspan="4">
|
||||
<tree string="Actions">
|
||||
<field name="name"/>
|
||||
<field name="state"/>
|
||||
<field name="action"/>
|
||||
</tree>
|
||||
<form string="Actions">
|
||||
<field name="name"/>
|
||||
<newline/>
|
||||
<field name="state"/>
|
||||
<field name="action"/>
|
||||
</form>
|
||||
</field>
|
||||
<field name="transition_ids" colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_transition_tree">
|
||||
<field name="name">Processus Transitions</field>
|
||||
<field name="model">processus.transition</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Transitions">
|
||||
<field name="name"/>
|
||||
<field name="node_from_id"/>
|
||||
<field name="node_to_id"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_transition_open">
|
||||
<field name="name">Processus Transitions</field>
|
||||
<field name="res_model">processus.transition</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<menuitem
|
||||
action="action_transition_open"
|
||||
parent="menu_processus"
|
||||
id="menu_action_transition_open"/>
|
||||
|
||||
</data>
|
||||
</terp>
|
|
@ -0,0 +1,73 @@
|
|||
import Image
|
||||
import ImageDraw
|
||||
import ImageFont
|
||||
|
||||
ROUNDED = 30
|
||||
BGCOLOR = (228,233,237)
|
||||
TITLECOLOR = (253,171,44)
|
||||
FONT = 'sb.ttf'
|
||||
BOXSIZE = (300,140)
|
||||
|
||||
size = 800,600
|
||||
img = Image.new('RGB',size,'#ffffff')
|
||||
|
||||
class draw(object):
|
||||
def rounding_box(self, x, y, width, height, title=None, bgcolor=BGCOLOR):
|
||||
d = ImageDraw.Draw(self.img)
|
||||
|
||||
DR = ROUNDED/2
|
||||
d.polygon( (x+DR,y,x+width-DR,y,x+width,y+DR,x+width,y+height-DR,x+width-DR,y+height,x+DR,y+height,x,y+height-DR,x,y+DR), fill=bgcolor)
|
||||
if title:
|
||||
d.polygon( (x+width/3, y, x+width-DR, y, x+width, y+DR, x+width, y+30, x+width/3+30, y+30), fill=TITLECOLOR)
|
||||
self.draw_text(x+width/3+30, y+3, 20, title, (255,255,255), width*2/3-40)
|
||||
|
||||
d.pieslice((x,y,x+ROUNDED,y+ROUNDED),180,270,fill=bgcolor)
|
||||
d.pieslice((x+width-ROUNDED,y,x+width,y+ROUNDED),270,0,fill=title and TITLECOLOR or bgcolor)
|
||||
d.pieslice((x+width-ROUNDED,y+height-ROUNDED,x+width,y+height),0,90,fill=bgcolor)
|
||||
d.pieslice((x,y+height-ROUNDED,x+ROUNDED,y+height),90,180,fill=bgcolor)
|
||||
|
||||
def intersect(self, start, stop):
|
||||
x1 = start[0] + BOXSIZE[0]/2
|
||||
y1 = start[1] - (start[1] - stop[1]) * (start[0]-x1) / (start[0] - stop[0])
|
||||
return (x1,y1,stop[0],stop[1])
|
||||
|
||||
def arrow(self, start, stop):
|
||||
d = ImageDraw.Draw(self.img)
|
||||
start = (start[0]+BOXSIZE[0]/2, start[1]+BOXSIZE[1]/2)
|
||||
stop = (stop[0]+BOXSIZE[0]/2, stop[1]+BOXSIZE[1]/2)
|
||||
arrow = self.intersect(start,stop)
|
||||
|
||||
d.line(arrow, width=10, fill=(100,0,0))
|
||||
|
||||
def draw_text(self, x, y, size, title, color=(155,255,255), maxlength=None, font_name=FONT):
|
||||
d = ImageDraw.Draw(self.img)
|
||||
font = ImageFont.truetype(font_name, size)
|
||||
d.setfont(font)
|
||||
size2 = d.textsize(title)
|
||||
fontsize = min(size, size * maxlength / size2[0])
|
||||
font = ImageFont.truetype(font_name, fontsize)
|
||||
d.setfont(font)
|
||||
size = d.textsize(title)
|
||||
d.text( (x, y+(size2[1]-size[1])/2), title, color)
|
||||
|
||||
def __init__(self, img):
|
||||
self.img = img
|
||||
|
||||
class graph(object):
|
||||
def __init__(self, img):
|
||||
self.draw = draw(img)
|
||||
|
||||
def node(self, x, y, data, start_color=BGCOLOR):
|
||||
self.draw.rounding_box(x-20,y,BOXSIZE[0],BOXSIZE[1], bgcolor=start_color)
|
||||
self.draw.rounding_box(x-4,y,BOXSIZE[0],BOXSIZE[1], bgcolor=(255,255,255))
|
||||
self.draw.rounding_box(x,y,BOXSIZE[0],BOXSIZE[1],data.get('title','Unknown'))
|
||||
|
||||
def arrow(self, node_from, node_to):
|
||||
self.draw.arrow(node_from,node_to)
|
||||
|
||||
g = graph(img)
|
||||
g.node(50,50,{'title':'SALE AZER ORDER'}, start_color=(200,100,100))
|
||||
g.node(450,150,{'title':'SALE AZER AZE ORDER'})
|
||||
g.arrow((50,50),(450,150))
|
||||
|
||||
img.show()
|
Binary file not shown.
Loading…
Reference in New Issue