Lots of modifs
bzr revid: fp@tinyerp.com-f1b00f3bf53ab89508b79dcf313516f3455ed06c
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -56,42 +56,6 @@
|
||||
<field name="perm_unlink" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_actions_execute">
|
||||
<field name="name">Actions Execute</field>
|
||||
<field name="model_id" model="ir.model" search="[('model', '=', 'ir.actions.execute')]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_actions_execute_admin">
|
||||
<field name="name">Actions Execute</field>
|
||||
<field name="model_id" model="ir.model" search="[('model', '=', 'ir.actions.execute')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_unlink" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_actions_group">
|
||||
<field name="name">Actions Group</field>
|
||||
<field name="model_id" model="ir.model" search="[('model', '=', 'ir.actions.group')]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="False"/>
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_actions_group_admin">
|
||||
<field name="name">Actions Group</field>
|
||||
<field name="model_id" model="ir.model" search="[('model', '=', 'ir.actions.group')]"/>
|
||||
<field name="group_id" ref="group_admin"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_unlink" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.model.access" id="access_actions_report_custom">
|
||||
<field name="name">Actions Report Custom</field>
|
||||
<field name="model_id" model="ir.model" search="[('model', '=', 'ir.actions.report.custom')]"/>
|
||||
|
||||
@@ -162,74 +162,6 @@
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low Level/Base/Actions/" action="ir_sequence_actions" id="menu_ir_sequence_actions"/>
|
||||
|
||||
<record model="ir.ui.view" id="act_execute_view">
|
||||
<field name="name">ir.actions.execute</field>
|
||||
<field name="model">ir.actions.execute</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Execute">
|
||||
<field name="name" select="1"/>
|
||||
<field name="type" select="1"/>
|
||||
<field name="func_name"/>
|
||||
<field name="func_arg"/>
|
||||
<field name="usage"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="act_execute_view_tree">
|
||||
<field name="name">ir.actions.execute.tree</field>
|
||||
<field name="model">ir.actions.execute</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Execute">
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.actions.act_window" id="ir_action_execute">
|
||||
<field name="name">Execute</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.actions.execute</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="act_execute_view_tree"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low Level/Base/Actions/" action="ir_action_execute" id="menu_ir_action_execute"/>
|
||||
|
||||
<record model="ir.ui.view" id="act_group_view_form">
|
||||
<field name="name">ir.actions.group.form</field>
|
||||
<field name="model">ir.actions.group</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Group">
|
||||
<field name="name" select="1"/>
|
||||
<field name="type" select="1"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="act_group_view_tree">
|
||||
<field name="name">ir.actions.group.tree</field>
|
||||
<field name="model">ir.actions.group</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Group">
|
||||
<field name="name"/>
|
||||
<field name="type"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="ir_action_group">
|
||||
<field name="name">Group</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">ir.actions.group</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="act_group_view_tree"/>
|
||||
</record>
|
||||
<menuitem name="Administration/Custom/Low Level/Base/Actions/" action="ir_action_group" id="menu_ir_action_group"/>
|
||||
|
||||
<record model="ir.ui.view" id="act_report_custom_view">
|
||||
<field name="name">ir.actions.report.custom</field>
|
||||
<field name="model">ir.actions.report.custom</field>
|
||||
@@ -979,6 +911,10 @@
|
||||
<field name="name"/>
|
||||
<field name="model_id"/>
|
||||
<field name="group_id"/>
|
||||
<field name="perm_read"/>
|
||||
<field name="perm_write"/>
|
||||
<field name="perm_create"/>
|
||||
<field name="perm_unlink"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
-->
|
||||
<record id="res_partner_title_pvt_ltd" model="res.partner.title">
|
||||
<field name="domain">partner</field>
|
||||
<field name="name">Pvt. Ltd</field>
|
||||
<field name="shortcut">pvt ltd</field>
|
||||
<field name="name">Corp.</field>
|
||||
<field name="shortcut">Corp./field>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_title_ltd" model="res.partner.title">
|
||||
|
||||
@@ -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
|
||||
|
||||
+48
-12
@@ -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={}
|
||||
|
||||
+1
-23
@@ -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):
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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'])
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
+26
-15
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user