diff --git a/bin/addons/base/base.sql b/bin/addons/base/base.sql
index 1584fd15bb8..911b90fe5da 100644
--- a/bin/addons/base/base.sql
+++ b/bin/addons/base/base.sql
@@ -93,24 +93,6 @@ create table ir_act_report_custom (
)
INHERITS (ir_actions);
-CREATE TABLE ir_act_group (
- exec_type varchar(64) DEFAULT 'serial'::varchar NOT NULL,
- primary key(id)
-)
-INHERITS (ir_actions);
-
-CREATE TABLE ir_act_group_link (
- aid integer NOT NULL,
- gid integer NOT NULL
-);
-
-CREATE TABLE ir_act_execute (
- func_name varchar(64) NOT NULL,
- func_arg varchar(64),
- primary key(id)
-)
-INHERITS (ir_actions);
-
CREATE TABLE ir_act_wizard (
wiz_name varchar(64) NOT NULL,
primary key(id)
@@ -124,6 +106,12 @@ CREATE TABLE ir_act_url (
)
INHERITS (ir_actions);
+CREATE TABLE ir_act_server (
+ primary key(id)
+)
+INHERITS (ir_actions);
+
+
CREATE TABLE ir_ui_view (
id serial NOT NULL,
name varchar(64) DEFAULT ''::varchar NOT NULL,
diff --git a/bin/addons/base/base_security.xml b/bin/addons/base/base_security.xml
index f356e401dfa..f4ce4f68777 100644
--- a/bin/addons/base/base_security.xml
+++ b/bin/addons/base/base_security.xml
@@ -56,42 +56,6 @@
-
- Actions Execute
-
-
-
-
-
-
-
- Actions Execute
-
-
-
-
-
-
-
-
-
- Actions Group
-
-
-
-
-
-
-
- Actions Group
-
-
-
-
-
-
-
-
Actions Report Custom
diff --git a/bin/addons/base/ir/ir.xml b/bin/addons/base/ir/ir.xml
index fdeb93cc942..89649ecb299 100644
--- a/bin/addons/base/ir/ir.xml
+++ b/bin/addons/base/ir/ir.xml
@@ -162,74 +162,6 @@
-
- ir.actions.execute
- ir.actions.execute
- form
-
-
-
-
-
- ir.actions.execute.tree
- ir.actions.execute
- tree
-
-
-
-
-
-
-
-
-
-
- Execute
- ir.actions.act_window
- ir.actions.execute
- form
-
-
-
-
-
- ir.actions.group.form
- ir.actions.group
- form
-
-
-
-
-
- ir.actions.group.tree
- ir.actions.group
- tree
-
-
-
-
-
-
-
-
-
- Group
- ir.actions.act_window
- ir.actions.group
- form
-
-
-
-
ir.actions.report.custom
ir.actions.report.custom
@@ -979,6 +911,10 @@
+
+
+
+
diff --git a/bin/addons/base/ir/ir_actions.py b/bin/addons/base/ir/ir_actions.py
index f046bb98e28..d3e3db1a542 100644
--- a/bin/addons/base/ir/ir_actions.py
+++ b/bin/addons/base/ir/ir_actions.py
@@ -28,6 +28,7 @@
from osv import fields,osv
import tools
+import time
class actions(osv.osv):
_name = 'ir.actions.actions'
@@ -35,38 +36,14 @@ class actions(osv.osv):
_columns = {
'name': fields.char('Action Name', required=True, size=64),
'type': fields.char('Action Type', required=True, size=32),
- 'usage': fields.char('Action Usage', size=32)
+ 'usage': fields.char('Action Usage', size=32),
+ 'parent_id': fields.many2one('ir.actions.server', 'Parent Action'),
}
_defaults = {
'usage': lambda *a: False,
}
actions()
-class act_execute(osv.osv):
- _name = 'ir.actions.execute'
- _table = 'ir_act_execute'
- _sequence = 'ir_actions_id_seq'
- _columns = {
- 'name': fields.char('name', size=64, required=True, translate=True),
- 'type': fields.char('type', size=32, required=True),
- 'func_name': fields.char('Function Name', size=64, required=True),
- 'func_arg': fields.char('Function Argument', size=64),
- 'usage': fields.char('Action Usage', size=32)
- }
-act_execute()
-
-class group(osv.osv):
- _name = 'ir.actions.group'
- _table = 'ir_act_group'
- _sequence = 'ir_actions_id_seq'
- _columns = {
- 'name': fields.char('Group Name', size=64, required=True),
- 'type': fields.char('Action Type', size=32, required=True),
- 'exec_type': fields.char('Execution sequence', size=64, required=True),
- 'usage': fields.char('Action Usage', size=32)
- }
-group()
-
class report_custom(osv.osv):
_name = 'ir.actions.report.custom'
_table = 'ir_act_report_custom'
@@ -81,6 +58,7 @@ class report_custom(osv.osv):
}
_defaults = {
'multi': lambda *a: False,
+ 'type': lambda *a: 'ir.actions.report.custom',
}
report_custom()
@@ -260,9 +238,10 @@ class act_url(osv.osv):
'type': fields.char('Action Type', size=32, required=True),
'url': fields.text('Action Url',required=True),
'target': fields.selection((
- ('new', 'New Window'),
- ('self', 'This Window')),
- 'Action Target', required=True)
+ ('new', 'New Window'),
+ ('self', 'This Window')),
+ 'Action Target', required=True
+ )
}
_defaults = {
'type': lambda *a: 'ir.actions.act_url',
@@ -270,3 +249,75 @@ class act_url(osv.osv):
}
act_url()
+#
+# Actions that are run on the server side
+#
+class actions_server(osv.osv):
+ _name = 'ir.actions.server'
+ _table = 'ir_act_server'
+ _sequence = 'ir_actions_id_seq'
+ _columns = {
+ 'name': fields.char('Action Name', required=True, size=64),
+ 'state': fields.selection([
+ ('python','Python Code'),
+ ('dummy','Dummy'),
+ ('trigger','Trigger'),
+ ('email','Email'),
+ ('sms','SMS'),
+ ('object_create','Create Object'),
+ ('object_write','Write Object'),
+ ('client_action','Client Action'),
+ ('other','Others Actions'),
+ ], 'Action State', required=True, size=32),
+ 'code': fields.text('Python Code'),
+ 'sequence': fields.integer('Sequence'),
+ 'model_id': fields.many2one('ir.model', 'Model', required=True),
+ 'trigger_name': fields.char('Trigger Name', size=128),
+ 'trigger_object': fields.char('Trigger Object', size=128),
+ 'trigger_object_id': fields.char('Trigger Object ID', size=128),
+ 'message': fields.text('Message', translate=True),
+ 'address': fields.char('Address', size=128),
+ 'child_ids': fields.one2many('ir.actions.actions', 'parent_id', 'Others Actions'),
+ 'usage': fields.char('Action Usage', size=32),
+ 'type': fields.char('Report Type', size=32, required=True),
+ }
+ _defaults = {
+ 'state': lambda *a: 'dummy',
+ 'type': lambda *a: 'ir.actions.server',
+ 'sequence': lambda *a: 0,
+ 'code': lambda *a: """# You can use the following variables
+# - object
+# - object2
+# - time
+# - cr
+# - uid
+# - ids
+# If you plan to return an action, assign: action = {...}
+"""
+ }
+ #
+ # Context should contains:
+ # ids : original ids
+ # id : current id of the object
+ # OUT:
+ # False : Finnished correctly
+ # ACTION_ID : Action to launch
+ def run(self, cr, uid, ids, context={}):
+ for action in self.browse(cr, uid, ids, context):
+ if action.state=='python':
+ localdict = {
+ 'self': self.pool.get(action.model_id.model),
+ 'context': context,
+ 'time': time,
+ 'ids': ids,
+ 'cr': cr,
+ 'uid': uid
+ }
+ print action.code
+ exec action.code in localdict
+ print localdict.keys()
+ if 'action' in localdict:
+ return localdict['action']
+ return False
+actions_server()
+
diff --git a/bin/addons/base/ir/workflow/workflow.py b/bin/addons/base/ir/workflow/workflow.py
index 466c49005c7..cb55fd3d402 100644
--- a/bin/addons/base/ir/workflow/workflow.py
+++ b/bin/addons/base/ir/workflow/workflow.py
@@ -100,7 +100,8 @@ class wkf_activity(osv.osv):
'split_mode': fields.selection([('XOR', 'Xor'), ('OR','Or'), ('AND','And')], 'Split Mode', size=3, required=True),
'join_mode': fields.selection([('XOR', 'Xor'), ('AND', 'And')], 'Join Mode', size=3, required=True),
'kind': fields.selection([('dummy', 'Dummy'), ('function', 'Function'), ('subflow', 'Subflow'), ('stopall', 'Stop All')], 'Kind', size=64, required=True),
- 'action': fields.char('Action', size=256),
+ 'action': fields.char('Python Action', size=256),
+ 'action_id': fields.many2one('ir.actions.server', 'Server Action', ondelete='set null'),
'flow_start': fields.boolean('Flow Start'),
'flow_stop': fields.boolean('Flow Stop'),
'subflow_id': fields.many2one('workflow', 'Subflow'),
diff --git a/bin/addons/base/res/partner/partner_demo.xml b/bin/addons/base/res/partner/partner_demo.xml
index c54031b0ed9..a534f4f4a86 100644
--- a/bin/addons/base/res/partner/partner_demo.xml
+++ b/bin/addons/base/res/partner/partner_demo.xml
@@ -7,8 +7,8 @@
-->
partner
- Pvt. Ltd
- pvt ltd
+ Corp.
+ Corp./field>
diff --git a/bin/osv/fields.py b/bin/osv/fields.py
index 061399c62fc..619746e0235 100644
--- a/bin/osv/fields.py
+++ b/bin/osv/fields.py
@@ -262,6 +262,15 @@ class one2one(_column):
def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None):
return obj.pool.get(self._obj).search(cr, uid, args+self._domain+[('name','like',value)], offset, limit)
+class many2one_memory(_column):
+ _classic_read = True
+ _classic_write = True
+ _type = 'many2one'
+ def __init__(self, obj, string='unknown', **args):
+ _column.__init__(self, string=string, **args)
+ self._obj = obj
+
+
class many2one(_column):
_classic_read = False
@@ -333,6 +342,104 @@ class many2one(_column):
def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None):
return obj.pool.get(self._obj).search(cr, uid, args+self._domain+[('name','like',value)], offset, limit)
+class one2many_memory(_column):
+ _classic_read = False
+ _classic_write = False
+ _type = 'one2many'
+ def __init__(self, obj, fields_id, string='unknown', limit=None, **args):
+ _column.__init__(self, string=string, **args)
+ self._obj = obj
+ self._fields_id = fields_id
+ self._limit = limit
+ assert(self.change_default != True)
+
+ def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
+ print 'Get O2M'
+ if not context:
+ context = {}
+ if not values:
+ values = {}
+ res = {}
+ for id in ids:
+ res[id] = []
+ ids2 = obj.pool.get(self._obj).search(cr, user, [(self._fields_id,'in',ids)], limit=self._limit)
+ for r in obj.pool.get(self._obj).read(cr, user, ids2, [self._fields_id], context=context, load='_classic_write'):
+ if r[self._fields_id] in res:
+ res[r[self._fields_id]].append( r['id'] )
+ print 'Ok', res
+ return res
+
+ def set(self, cr, obj, id, field, values, user=None, context=None):
+ if not context:
+ context={}
+ if not values:
+ return
+ obj = obj.pool.get(self._obj)
+ for act in values:
+ if act[0]==0:
+ act[2][self._fields_id] = id
+ obj.create(cr, user, act[2], context=context)
+ elif act[0]==1:
+ obj.write(cr, user, [act[1]] , act[2], context=context)
+ elif act[0]==2:
+ obj.unlink(cr, user, [act[1]], context=context)
+ elif act[0]==3:
+ obj.datas[act[1]][self._fields_id] = False
+ elif act[0]==4:
+ obj.datas[act[1]] = id
+ elif act[0]==5:
+ for o in obj.datas.values():
+ if o[self._fields_id]==id:
+ o[self._fields_id] = False
+ elif act[0]==6:
+ for id2 in (act[2] or []):
+ obj.datas[id2][self._fields_id] = id
+
+ def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like'):
+ raise 'Not Implemented'
+
+class many2many_memory(_column):
+ _classic_read = False
+ _classic_write = False
+ _type = 'many2many'
+
+ def __init__(self, obj, string='unknown', limit=None, **args):
+ _column.__init__(self, string=string, **args)
+ self._obj = obj
+ self._limit = limit
+
+ def get(self, cr, obj, ids, name, user=None, offset=0, context=None, values=None):
+ result = {}
+ for id in ids:
+ result[id] = obj.datas[id][name]
+ return result
+
+ def set(self, cr, obj, id, name, values, user=None, context=None):
+ if not values:
+ return
+ for act in values:
+ if act[0]==0:
+ raise 'Not Implemented'
+ elif act[0]==1:
+ raise 'Not Implemented'
+ elif act[0]==2:
+ raise 'Not Implemented'
+ elif act[0]==3:
+ raise 'Not Implemented'
+ elif act[0]==4:
+ raise 'Not Implemented'
+ elif act[0]==5:
+ raise 'Not Implemented'
+ elif act[0]==6:
+ obj.datas[id][name] = act[2]
+
+ #
+ # TODO: use a name_search
+ #
+ def search(self, cr, obj, args, name, value, offset=0, limit=None, uid=None, operator='like'):
+ raise 'Not Implemented'
+
+
class one2many(_column):
_classic_read = False
_classic_write = False
diff --git a/bin/osv/orm.py b/bin/osv/orm.py
index b60e98f3951..33d49217078 100644
--- a/bin/osv/orm.py
+++ b/bin/osv/orm.py
@@ -156,7 +156,7 @@ class browse_record(object):
elif name in self._table._inherit_fields:
col = self._table._inherit_fields[name][2]
elif hasattr(self._table, name):
- return getattr(self._table, name)
+ return lambda *args, **argv: getattr(self._table, name)(self._cr, self._uid, [self._id], *args, **argv)
else:
logger = netsvc.Logger()
logger.notifyChannel('orm', netsvc.LOG_ERROR, "Programming error: field '%s' does not exist in object '%s' !" % (name, self._table._name))
@@ -1028,13 +1028,14 @@ class orm_template(object):
class orm_memory(orm_template):
_protected = ['read','write','create','default_get','perm_read','unlink','fields_get','fields_view_get','search','name_get','distinct_field_get','name_search','copy','import_data','search_count']
+ _inherit_fields = {}
def __init__(self, cr):
super(orm_memory, self).__init__(cr)
self.datas = {}
self.next_id = 0
def read(self, cr, user, ids, fields=None, context=None, load='_classic_read'):
- print 'Read', ids
+ self.pool.get('ir.model.access').check(cr, user, self._name, 'read')
if not fields:
fields = self._columns.keys()
result = []
@@ -1043,24 +1044,56 @@ class orm_memory(orm_template):
for f in fields:
r[f] = self.datas[id].get(f, False)
result.append(r)
+ fields_post = filter(lambda x: x in self._columns and not getattr(self._columns[x], load), fields)
+ for f in fields_post:
+ res2 = self._columns[f].get(cr, self, ids, f, user, context=context, values=False)
+ for record in result:
+ record[f] = res2[record['id']]
return result
+ def write(self, cr, user, ids, vals, context=None):
+ self.pool.get('ir.model.access').check(cr, user, self._name, 'write')
+ vals2 = {}
+ upd_todo = []
+ for field in vals:
+ if self._columns[field]._classic_write:
+ vals2[field] = vals[field]
+ else:
+ upd_todo.append(field)
+ for id_new in ids:
+ self.datas[id_new].update(vals2)
+ for field in upd_todo:
+ self._columns[field].set(cr, self, id_new, field, vals[field], user, context)
+ self._validate(cr, user, [id_new])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_write(user, self._name, id_new, cr)
+ return id_new
+
+
def create(self, cr, user, vals, context=None):
+ self.pool.get('ir.model.access').check(cr, user, self._name, 'create')
self.next_id += 1
- nid = self.next_id
+ id_new = self.next_id
default = []
- for f in self._columns.keys(): # + self._inherit_fields.keys():
+ for f in self._columns.keys():
if not f in vals:
default.append(f)
if len(default):
vals.update(self.default_get(cr, user, default, context))
- self.datas[nid] = vals
- return nid
-
- def write(self, cr, user, ids, vals, context=None):
- for id in ids:
- self.datas[id].update(vals)
- return True
+ vals2 = {}
+ upd_todo = []
+ for field in vals:
+ if self._columns[field]._classic_write:
+ vals2[field] = vals[field]
+ else:
+ upd_todo.append(field)
+ self.datas[id_new] = vals2
+ for field in upd_todo:
+ self._columns[field].set(cr, self, id_new, field, vals[field], user, context)
+ self._validate(cr, user, [id_new])
+ wf_service = netsvc.LocalService("workflow")
+ wf_service.trg_create(user, self._name, id_new, cr)
+ return id_new
def default_get(self, cr, uid, fields_list, context=None):
if not context:
@@ -1116,8 +1149,10 @@ class orm_memory(orm_template):
return self.datas.keys()
def unlink(self, cr, uid, ids, context=None):
+ self.pool.get('ir.model.access').check(cr, uid, self._name, 'unlink')
for id in ids:
- del self.datas[id]
+ if id in self.datas:
+ del self.datas[id]
return True
def perm_read(self, cr, user, ids, context=None, details=True):
@@ -1640,6 +1675,7 @@ class orm(orm_template):
else:
vals[field] = False
return res
+
def perm_read(self, cr, user, ids, context=None, details=True):
if not context:
context={}
diff --git a/bin/osv/osv.py b/bin/osv/osv.py
index 186d21cc31b..2a4d5a5f139 100644
--- a/bin/osv/osv.py
+++ b/bin/osv/osv.py
@@ -130,8 +130,7 @@ class osv_pool(netsvc.Service):
def exec_workflow_cr(self, cr, uid, obj, method, *args):
wf_service = netsvc.LocalService("workflow")
- wf_service.trg_validate(uid, obj, args[0], method, cr)
- return True
+ return wf_service.trg_validate(uid, obj, args[0], method, cr)
def exec_workflow(self, db, uid, obj, method, *args):
cr = pooler.get_db(db).cursor()
@@ -184,27 +183,6 @@ class osv_pool(netsvc.Service):
#pooler.get_pool(cr.dbname) = osv_pool()
-#
-# See if we can use the pool var instead of the class_pool one
-#
-# XXX no more used
-#class inheritor(type):
-# def __new__(cls, name, bases, d):
-# parent_name = d.get('_inherit', None)
-# if parent_name:
-# parent_class = class_pool.get(parent_name)
-# assert parent_class, "parent class %s does not exist !" % parent_name
-# for s in ('_columns', '_defaults', '_inherits'):
-# new_dict = copy.copy(getattr(parent_class, s))
-# new_dict.update(d.get(s, {}))
-# d[s] = new_dict
-# bases = (parent_class,)
-# res = type.__new__(cls, name, bases, d)
-# #
-# # update _inherits of others objects
-# #
-# return res
-
class osv_memory(orm.orm_memory):
#__metaclass__ = inheritor
def __new__(cls):
diff --git a/bin/workflow/instance.py b/bin/workflow/instance.py
index 0701ccbcec7..8eb40b6cbd2 100644
--- a/bin/workflow/instance.py
+++ b/bin/workflow/instance.py
@@ -39,7 +39,8 @@ def create(cr, ident, wkf_id):
cr.execute('insert into wkf_instance (id,res_type,res_id,uid,wkf_id) values (%d,%s,%s,%s,%s)', (id_new,res_type,res_id,uid,wkf_id))
cr.execute('select * from wkf_activity where flow_start=True and wkf_id=%d', (wkf_id,))
res = cr.dictfetchall()
- workitem.create(cr, res, id_new, ident)
+ stack = []
+ workitem.create(cr, res, id_new, ident, stack=stack)
update(cr, id_new, ident)
return id_new
@@ -50,13 +51,20 @@ def delete(cr, ident):
def validate(cr, inst_id, ident, signal, force_running=False):
cr.execute("select * from wkf_workitem where inst_id=%d", (inst_id,))
for witem in cr.dictfetchall():
- workitem.process(cr, witem, ident, signal, force_running)
- return _update_end(cr, inst_id, ident)
+ print '-----'
+ stack = []
+ workitem.process(cr, witem, ident, signal, force_running, stack=stack)
+ # An action is returned
+ print '----- Got', stack
+ _update_end(cr, inst_id, ident)
+ return stack and stack[0] or False
def update(cr, inst_id, ident):
cr.execute("select * from wkf_workitem where inst_id=%d", (inst_id,))
for witem in cr.dictfetchall():
- workitem.process(cr, witem, ident)
+ stack = []
+ workitem.process(cr, witem, ident, stack=stack)
+ print 'End Update'
return _update_end(cr, inst_id, ident)
def _update_end(cr, inst_id, ident):
diff --git a/bin/workflow/wkf_expr.py b/bin/workflow/wkf_expr.py
index 833c106d719..aec79f89163 100644
--- a/bin/workflow/wkf_expr.py
+++ b/bin/workflow/wkf_expr.py
@@ -55,18 +55,19 @@ class Env(dict):
self.columns = self.obj._columns.keys() + self.obj._inherit_fields.keys()
def __getitem__(self, key):
- if (key in self.columns) and (not super(Env, self).__contains__(key)):
- res=self.wf_service.execute_cr(self.cr, self.uid, self.model, 'read',\
- self.ids, [key])[0][key]
- super(Env, self).__setitem__(key, res)
- return res
- elif key in dir(self.obj):
- return EnvCall(self.wf_service, (self.cr, self.uid, self.model, key,\
- self.ids))
+ if (key in self.columns) or (key in dir(self.obj)):
+ res = self.obj.browse(self.cr, self.uid, self.ids[0])
+ return res[key]
+ #res=self.wf_service.execute_cr(self.cr, self.uid, self.model, 'read',\
+ # self.ids, [key])[0][key]
+ #super(Env, self).__setitem__(key, res)
+ #return res
+ #elif key in dir(self.obj):
+ # return EnvCall(self.wf_service, (self.cr, self.uid, self.model, key,\
+ # self.ids))
else:
return super(Env, self).__getitem__(key)
-
def _eval_expr(cr, ident, workitem, action):
ret=False
for line in action.split('\n'):
@@ -83,6 +84,15 @@ def _eval_expr(cr, ident, workitem, action):
ret = eval(line, env)
return ret
+def execute_action(cr, ident, workitem, activity):
+ print 'Execute Action'
+ wf_service = netsvc.LocalService("object_proxy")
+ obj = pooler.get_pool(cr.dbname).get('ir.actions.server')
+ ctx = {'active_id':ident[2], 'active_ids':[ident[2]]}
+ result = obj.run(cr, ident[0], [activity['action_id']], ctx)
+ print 'Result', result
+ return result
+
def execute(cr, ident, workitem, activity):
return _eval_expr(cr, ident, workitem, activity['action'])
diff --git a/bin/workflow/wkf_service.py b/bin/workflow/wkf_service.py
index 5700896181d..2a905d406c3 100644
--- a/bin/workflow/wkf_service.py
+++ b/bin/workflow/wkf_service.py
@@ -79,11 +79,15 @@ class workflow_service(netsvc.Service):
instance.create(cr, ident, wkf_id)
def trg_validate(self, uid, res_type, res_id, signal, cr):
+ result = False
ident = (uid,res_type,res_id)
# ids of all active workflow instances for a corresponding resource (id, model_nam)
cr.execute('select id from wkf_instance where res_id=%d and res_type=%s and state=%s', (res_id, res_type, 'active'))
for (id,) in cr.fetchall():
- instance.validate(cr, id, ident, signal)
+ res2 = instance.validate(cr, id, ident, signal)
+ print 'Inst val,', res2
+ result = result or res2
+ return result
# make all workitems which are waiting for a (subflow) workflow instance
# for the old resource point to the (first active) workflow instance for
diff --git a/bin/workflow/workitem.py b/bin/workflow/workitem.py
index 93991b2ef29..47b7834a1f6 100644
--- a/bin/workflow/workitem.py
+++ b/bin/workflow/workitem.py
@@ -37,7 +37,7 @@ import instance
import wkf_expr
import wkf_logs
-def create(cr, act_datas, inst_id, ident):
+def create(cr, act_datas, inst_id, ident, stack):
for act in act_datas:
cr.execute("select nextval('wkf_workitem_id_seq')")
id_new = cr.fetchone()[0]
@@ -45,23 +45,27 @@ def create(cr, act_datas, inst_id, ident):
cr.execute('select * from wkf_workitem where id=%d',(id_new,))
res = cr.dictfetchone()
wkf_logs.log(cr,ident,act['id'],'active')
- process(cr, res, ident)
+ process(cr, res, ident, stack=stack)
-def process(cr, workitem, ident, signal=None, force_running=False):
+def process(cr, workitem, ident, signal=None, force_running=False, stack=None):
+ if stack is None:
+ raise 'Error !!!'
+ result = True
cr.execute('select * from wkf_activity where id=%d', (workitem['act_id'],))
activity = cr.dictfetchone()
triggers = False
if workitem['state']=='active':
triggers = True
- if not _execute(cr, workitem, activity, ident):
+ result = _execute(cr, workitem, activity, ident, stack)
+ if not result:
return False
if workitem['state']=='running':
pass
if workitem['state']=='complete' or force_running:
- ok = _split_test(cr, workitem, activity['split_mode'], ident, signal)
+ ok = _split_test(cr, workitem, activity['split_mode'], ident, signal, stack)
triggers = triggers and not ok
if triggers:
@@ -75,7 +79,7 @@ def process(cr, workitem, ident, signal=None, force_running=False):
id =cr.fetchone()[0]
cr.execute('insert into wkf_triggers (model,res_id,instance_id,workitem_id,id) values (%s,%d,%d,%d,%d)', (trans['trigger_model'],res_id,workitem['inst_id'], workitem['id'], id))
- return True
+ return result
# ---------------------- PRIVATE FUNCS --------------------------------
@@ -85,7 +89,8 @@ def _state_set(cr, workitem, activity, state, ident):
workitem['state'] = state
wkf_logs.log(cr,ident,activity['id'],state)
-def _execute(cr, workitem, activity, ident):
+def _execute(cr, workitem, activity, ident, stack):
+ result = True
#
# send a signal to parent workflow (signal: subflow.signal_name)
#
@@ -94,8 +99,6 @@ def _execute(cr, workitem, activity, ident):
for i in cr.fetchall():
instance.validate(cr, i[0], (ident[0],i[1],i[2]), activity['signal_send'], force_running=True)
-
-
if activity['kind']=='dummy':
if workitem['state']=='active':
_state_set(cr, workitem, activity, 'complete', ident)
@@ -103,6 +106,12 @@ def _execute(cr, workitem, activity, ident):
if workitem['state']=='active':
_state_set(cr, workitem, activity, 'running', ident)
wkf_expr.execute(cr, ident, workitem, activity)
+ if activity['action_id']:
+ res2 = wkf_expr.execute_action(cr, ident, workitem, activity)
+ # A client action has been returned
+ if res2:
+ stack.append(res2)
+ result=res2
_state_set(cr, workitem, activity, 'complete', ident)
elif activity['kind']=='stopall':
if workitem['state']=='active':
@@ -131,9 +140,11 @@ def _execute(cr, workitem, activity, ident):
state= cr.fetchone()[0]
if state=='complete':
_state_set(cr, workitem, activity, 'complete', ident)
- return True
+ return result
-def _split_test(cr, workitem, split_mode, ident, signal=None):
+def _split_test(cr, workitem, split_mode, ident, signal=None, stack=None):
+ if stack is None:
+ raise 'Error !!!'
cr.execute('select * from wkf_transition where act_from=%d', (workitem['act_id'],))
test = False
transitions = []
@@ -158,15 +169,15 @@ def _split_test(cr, workitem, split_mode, ident, signal=None):
cr.executemany('insert into wkf_witm_trans (trans_id,inst_id) values (%d,%d)', transitions)
cr.execute('delete from wkf_workitem where id=%d', (workitem['id'],))
for t in transitions:
- _join_test(cr, t[0], t[1], ident)
+ _join_test(cr, t[0], t[1], ident, stack)
return True
return False
-def _join_test(cr, trans_id, inst_id, ident):
+def _join_test(cr, trans_id, inst_id, ident, stack):
cr.execute('select * from wkf_activity where id=(select act_to from wkf_transition where id=%d)', (trans_id,))
activity = cr.dictfetchone()
if activity['join_mode']=='XOR':
- create(cr,[activity], inst_id, ident)
+ create(cr,[activity], inst_id, ident, stack)
cr.execute('delete from wkf_witm_trans where inst_id=%d and trans_id=%d', (inst_id,trans_id))
else:
cr.execute('select id from wkf_transition where act_to=%d', (activity['id'],))
@@ -181,4 +192,4 @@ def _join_test(cr, trans_id, inst_id, ident):
if ok:
for (id,) in trans_ids:
cr.execute('delete from wkf_witm_trans where trans_id=%d and inst_id=%d', (id,inst_id))
- create(cr, [activity], inst_id, ident)
+ create(cr, [activity], inst_id, ident, stack)