[REM] base, workflow: removed res.roles object, replaced by dedicated res.groups
bzr revid: odo@openerp.com-20101013215340-jaiihef9chsym48z
This commit is contained in:
parent
a79d0ee8e3
commit
88117959b5
|
@ -159,20 +159,6 @@ CREATE TABLE res_groups (
|
|||
primary key(id)
|
||||
);
|
||||
|
||||
create table res_roles (
|
||||
id serial NOT NULL,
|
||||
parent_id int references res_roles on delete set null,
|
||||
name varchar(64) NOT NULL,
|
||||
primary key(id)
|
||||
);
|
||||
|
||||
CREATE TABLE res_roles_users_rel (
|
||||
uid integer NOT NULL references res_users on delete cascade,
|
||||
rid integer NOT NULL references res_roles on delete cascade
|
||||
);
|
||||
create index res_roles_users_rel_uid_idx on res_roles_users_rel (uid);
|
||||
create index res_roles_users_rel_rid_idx on res_roles_users_rel (rid);
|
||||
|
||||
CREATE TABLE res_groups_users_rel (
|
||||
uid integer NOT NULL references res_users on delete cascade,
|
||||
gid integer NOT NULL references res_groups on delete cascade
|
||||
|
@ -222,7 +208,7 @@ create table wkf_transition
|
|||
trigger_expr_id varchar(128) default NULL,
|
||||
|
||||
signal varchar(64) default null,
|
||||
role_id int references res_roles on delete set null,
|
||||
group_id int references res_groups on delete set null,
|
||||
|
||||
primary key(id)
|
||||
);
|
||||
|
|
|
@ -144,13 +144,10 @@
|
|||
<field colspan="2" name="signature" nolabel="1"/>
|
||||
</group>
|
||||
<group colspan="2" col="2" expand="1">
|
||||
<separator string="Access Rights (groups)" colspan="2"/>
|
||||
<separator string="Groups" colspan="2"/>
|
||||
<field colspan="2" nolabel="1" name="groups_id"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Roles">
|
||||
<field colspan="4" nolabel="1" name="roles_id"/>
|
||||
</page>
|
||||
<page string="Companies" groups="base.group_multi_company">
|
||||
<field colspan="4" nolabel="1" name="company_ids" select="1"/>
|
||||
</page>
|
||||
|
|
|
@ -708,7 +708,7 @@
|
|||
</record>
|
||||
<menuitem action="action_res_company_form" id="menu_action_res_company_form" parent="base.menu_res_company_global"/>
|
||||
|
||||
<!-- User Roles -->
|
||||
<!-- Users -->
|
||||
<record id="action_res_users" model="ir.actions.act_window">
|
||||
<field name="name">Users</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
|
@ -761,68 +761,6 @@
|
|||
<menuitem action="action_res_groups" id="menu_action_res_groups" parent="base.menu_users"
|
||||
groups="base.group_extended"/>
|
||||
|
||||
<record id="view_roles_form" model="ir.ui.view">
|
||||
<field name="name">res.roles.form</field>
|
||||
<field name="model">res.roles</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Role">
|
||||
<field name="name"/>
|
||||
<field name="parent_id"/>
|
||||
<separator string="Description" colspan="4"/>
|
||||
<field name="description" nolabel="1" colspan="4"/>
|
||||
<separator string="Workflow transitions" colspan="4"/>
|
||||
<field name="workflow_transition_ids" nolabel="1" colspan="4">
|
||||
<tree string="Workflow transitions">
|
||||
<field name="wkf_id"/>
|
||||
<field name="act_from"/>
|
||||
<field name="act_to"/>
|
||||
<field name="signal"/>
|
||||
<field name="condition"/>
|
||||
</tree>
|
||||
</field>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_roles_tree" model="ir.ui.view">
|
||||
<field name="name">res.roles.tree</field>
|
||||
<field name="model">res.roles</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="field_parent">child_id</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Roles">
|
||||
<field name="name"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="description"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_roles_search" model="ir.ui.view">
|
||||
<field name="name">res.roles.search</field>
|
||||
<field name="model">res.roles</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Role">
|
||||
<field name="name"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="description"/>
|
||||
<newline/>
|
||||
<group expand="0" string="Group By..." colspan="11" col="11" groups="base.group_extended">
|
||||
<filter string="Parent" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'parent_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_res_roles_form" model="ir.actions.act_window">
|
||||
<field name="name">Roles</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">res.roles</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="search_view_id" ref="view_roles_search"/>
|
||||
</record>
|
||||
<menuitem action="action_res_roles_form" id="menu_action_res_roles_form" parent="base.menu_users"/>
|
||||
|
||||
<!-- View -->
|
||||
<record id="view_view_form" model="ir.ui.view">
|
||||
<field name="name">ir.ui.view</field>
|
||||
|
|
|
@ -554,7 +554,7 @@ class ir_model_data(osv.osv):
|
|||
if model=='workflow.activity':
|
||||
cr.execute('select res_type,res_id from wkf_instance where id IN (select inst_id from wkf_workitem where act_id=%s)', (res_id,))
|
||||
wkf_todo.extend(cr.fetchall())
|
||||
cr.execute("update wkf_transition set condition='True', role_id=NULL, signal=NULL,act_to=act_from,act_from=%s where act_to=%s", (res_id,res_id))
|
||||
cr.execute("update wkf_transition set condition='True', group_id=NULL, signal=NULL,act_to=act_from,act_from=%s where act_to=%s", (res_id,res_id))
|
||||
cr.execute("delete from wkf_transition where act_to=%s", (res_id,))
|
||||
|
||||
for model,id in wkf_todo:
|
||||
|
|
|
@ -149,8 +149,8 @@ class wkf_transition(osv.osv):
|
|||
'signal': fields.char('Signal (button Name)', size=64,
|
||||
help="When the operation of transition comes from a button pressed in the client form, "\
|
||||
"signal tests the name of the pressed button. If signal is NULL, no button is necessary to validate this transition."),
|
||||
'role_id': fields.many2one('res.roles', 'Role Required',
|
||||
help="The role that a user must have to validate this transition."),
|
||||
'group_id': fields.many2one('res.groups', 'Group Required',
|
||||
help="The group that a user must have to be authorized to validate this transition."),
|
||||
'condition': fields.char('Condition', required=True, size=128,
|
||||
help="Expression to be satisfied if we want the transition done."),
|
||||
'act_from': fields.many2one('workflow.activity', 'Source Activity', required=True, select=True, ondelete='cascade',
|
||||
|
|
|
@ -217,7 +217,7 @@
|
|||
<field name="condition"/>
|
||||
<field name="trigger_model"/>
|
||||
<field name="trigger_expr_id"/>
|
||||
<field name="role_id"/>
|
||||
<field name="group_id"/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
|
|
|
@ -82,32 +82,6 @@ class groups(osv.osv):
|
|||
|
||||
groups()
|
||||
|
||||
class roles(osv.osv):
|
||||
_name = "res.roles"
|
||||
_columns = {
|
||||
'name': fields.char('Role Name', size=64, required=True),
|
||||
'parent_id': fields.many2one('res.roles', 'Parent', select=True,
|
||||
help="The parent role can be used to construct a hierarchy of roles. Parent roles inherit from the roles of their descendants."),
|
||||
'child_id': fields.one2many('res.roles', 'parent_id', 'Children'),
|
||||
'users': fields.many2many('res.users', 'res_roles_users_rel', 'rid', 'uid', 'Users'),
|
||||
'description': fields.text('Description', help="Description of this role and where it is relevant in workflows and processes"),
|
||||
'workflow_transition_ids': fields.one2many('workflow.transition', 'role_id', 'Workflow Transitions',
|
||||
help="The workflow transitions associated with this role"),
|
||||
}
|
||||
def check(self, cr, uid, ids, role_id):
|
||||
"""Verifies that the role with id ``role_id`` is granted directly or indirectly to a
|
||||
user that possesses the roles with ids ``ids``. Indirectly means that one of the
|
||||
roles with id in ``ids`` is an ancestor role of the role with id ``role_id``.
|
||||
"""
|
||||
if role_id in ids:
|
||||
return True
|
||||
cr.execute('select parent_id from res_roles where id=%s', (role_id,))
|
||||
roles = cr.fetchone()[0]
|
||||
if roles:
|
||||
return self.check(cr, uid, ids, roles)
|
||||
return False
|
||||
roles()
|
||||
|
||||
def _lang_get(self, cr, uid, context={}):
|
||||
obj = self.pool.get('res.lang')
|
||||
ids = obj.search(cr, uid, [('translatable','=',True)])
|
||||
|
@ -236,7 +210,6 @@ class users(osv.osv):
|
|||
'action_id': fields.many2one('ir.actions.actions', 'Home Action', help="If specified, this action will be opened at logon for this user, in addition to the standard menu."),
|
||||
'menu_id': fields.many2one('ir.actions.actions', 'Menu Action', help="If specified, the action will replace the standard menu for this user."),
|
||||
'groups_id': fields.many2many('res.groups', 'res_groups_users_rel', 'uid', 'gid', 'Groups'),
|
||||
'roles_id': fields.many2many('res.roles', 'res_roles_users_rel', 'uid', 'rid', 'Roles'),
|
||||
|
||||
# Special behavior for this field: res.company.search() will only return the companies
|
||||
# available to the current user (should be the user's companies?), when the user_preference
|
||||
|
|
|
@ -108,8 +108,6 @@
|
|||
"access_ir_actions_server_group_system","ir_actions_server_group_system","model_ir_actions_server","group_system",1,1,1,1
|
||||
"access_res_bank_group_system","res_bank_group_system","model_res_bank","group_system",1,1,1,1
|
||||
"access_res_payterm_group_system","res_payterm_group_system","model_res_payterm","group_system",1,1,1,1
|
||||
"access_res_roles_group_erpmanager","res_roles_group_erp_manager","model_res_roles","group_erp_manager",1,1,1,1
|
||||
"access_res_roles_all","res_roles_all","model_res_roles",,1,0,0,0
|
||||
"access_res_bank_group_partner_manager","res_bank_group_partner_manager","model_res_bank","group_partner_manager",1,1,1,1
|
||||
"access_res_bank_user","res_bank user","model_res_bank","group_user",1,0,0,0
|
||||
"access_maintenance_group_user","maintenance_contract group_user","model_maintenance_contract","group_system",1,1,1,1
|
||||
|
|
|
|
@ -1365,47 +1365,33 @@ class orm_template(object):
|
|||
|
||||
return fields
|
||||
|
||||
def __view_look_dom_arch(self, cr, user, node, view_id, context=None):
|
||||
fields_def = self.__view_look_dom(cr, user, node, view_id, context=context)
|
||||
def _disable_workflow_buttons(self, cr, user, node):
|
||||
if user == 1:
|
||||
# admin user can always activate workflow buttons
|
||||
return node
|
||||
|
||||
rolesobj = self.pool.get('res.roles')
|
||||
# TODO handle the case of more than one workflow for a model or multiple
|
||||
# transitions with different groups and same signal
|
||||
usersobj = self.pool.get('res.users')
|
||||
|
||||
buttons = (n for n in node.getiterator('button') if n.get('type') != 'object')
|
||||
for button in buttons:
|
||||
can_click = True
|
||||
if user != 1: # admin user has all roles
|
||||
user_roles = usersobj.read(cr, user, [user], ['roles_id'])[0]['roles_id']
|
||||
# TODO handle the case of more than one workflow for a model
|
||||
cr.execute("""SELECT DISTINCT t.role_id
|
||||
FROM wkf
|
||||
INNER JOIN wkf_activity a ON a.wkf_id = wkf.id
|
||||
INNER JOIN wkf_transition t ON (t.act_to = a.id)
|
||||
WHERE wkf.osv = %s
|
||||
AND t.signal = %s
|
||||
""", (self._name, button.get('name'),))
|
||||
roles = cr.fetchall()
|
||||
|
||||
# draft -> valid = signal_next (role X)
|
||||
# draft -> cancel = signal_cancel (no role)
|
||||
#
|
||||
# valid -> running = signal_next (role Y)
|
||||
# valid -> cancel = signal_cancel (role Z)
|
||||
#
|
||||
# running -> done = signal_next (role Z)
|
||||
# running -> cancel = signal_cancel (role Z)
|
||||
|
||||
# As we don't know the object state, in this scenario,
|
||||
# the button "signal_cancel" will be always shown as there is no restriction to cancel in draft
|
||||
# the button "signal_next" will be show if the user has any of the roles (X Y or Z)
|
||||
# The verification will be made later in workflow process...
|
||||
if roles:
|
||||
can_click = any((not role) or rolesobj.check(cr, user, user_roles, role) for (role,) in roles)
|
||||
|
||||
user_groups = usersobj.read(cr, user, [user], ['groups_id'])[0]['groups_id']
|
||||
cr.execute("""SELECT DISTINCT t.group_id
|
||||
FROM wkf
|
||||
INNER JOIN wkf_activity a ON a.wkf_id = wkf.id
|
||||
INNER JOIN wkf_transition t ON (t.act_to = a.id)
|
||||
WHERE wkf.osv = %s
|
||||
AND t.signal = %s
|
||||
""", (self._name, button.get('name')))
|
||||
group_ids = [x[0] for x in cr.fetchall()]
|
||||
can_click = not group_ids or bool(set(user_groups).intersection(group_ids))
|
||||
button.set('readonly', str(int(not can_click)))
|
||||
return node
|
||||
|
||||
def __view_look_dom_arch(self, cr, user, node, view_id, context=None):
|
||||
fields_def = self.__view_look_dom(cr, user, node, view_id, context=context)
|
||||
node = self._disable_workflow_buttons(cr, user, node)
|
||||
arch = etree.tostring(node, encoding="utf-8").replace('\t', '')
|
||||
|
||||
fields = {}
|
||||
if node.tag == 'diagram':
|
||||
if node.getchildren()[0].tag == 'node':
|
||||
|
|
|
@ -68,17 +68,17 @@ def execute(cr, ident, workitem, activity):
|
|||
return _eval_expr(cr, ident, workitem, activity['action'])
|
||||
|
||||
def check(cr, workitem, ident, transition, signal):
|
||||
ok = True
|
||||
if transition['signal']:
|
||||
ok = (signal==transition['signal'])
|
||||
if transition['signal'] and signal != transition['signal']:
|
||||
return False
|
||||
|
||||
uid = ident[0]
|
||||
if transition['role_id'] and uid != 1:
|
||||
if transition['group_id'] and uid != 1:
|
||||
pool = pooler.get_pool(cr.dbname)
|
||||
user_roles = pool.get('res.users').read(cr, uid, [uid], ['roles_id'])[0]['roles_id']
|
||||
ok = ok and pool.get('res.roles').check(cr, uid, user_roles, transition['role_id'])
|
||||
ok = ok and _eval_expr(cr, ident, workitem, transition['condition'])
|
||||
return ok
|
||||
user_groups = pool.get('res.users').read(cr, uid, [uid], ['groups_id'])[0]['groups_id']
|
||||
if not transition['group_id'] in user_groups:
|
||||
return False
|
||||
|
||||
return _eval_expr(cr, ident, workitem, transition['condition'])
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
Loading…
Reference in New Issue