Improved Rules System

bzr revid: fp@tinyerp.com-e04f6fe9c0cc68d8aa49f010590d828fcb627a0a
This commit is contained in:
Fabien Pinckaers 2008-02-08 15:55:30 +00:00
parent c346e6a79a
commit ffa98ae4e7
2 changed files with 44 additions and 40 deletions

View File

@ -993,8 +993,8 @@
<field name="name" colspan="4"/>
<group colspan="4" col="6" expand="1">
<field name="rules" nolabel="1" colspan="6"/>
<label string="The rule is satisfied if at least one test is True" colspan="6" align="0.0"/>
<label string="If there is no test defined, the rule is always satified if not global" colspan="6" align="0.0"/>
<label string="The rule is satisfied if all test are True (AND)" colspan="6" align="0.0"/>
<label string="Multiple rules on same objects are joined using operator OR" colspan="6" align="0.0"/>
</group>
</form>
</field>
@ -1013,29 +1013,31 @@
</record>
<record model="ir.ui.view" id="view_rule_form">
<field name="name">Test</field>
<field name="name">Rule Definition</field>
<field name="model">ir.rule</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Test">
<separator string="Simple domain setup" colspan="4"/>
<group colspan="4" col="6">
<field name="field_id"/>
<field name="operator"/>
<field name="operand"/>
</group>
<separator string="Manual domain setup" colspan="4"/>
<field name="domain_force"/>
<label string="If you don't force the domain, it will use the simple domain setup" colspan="4"/>
</form>
</field>
</record>
<record model="ir.ui.view" id="view_rule_tree">
<field name="name">Test</field>
<field name="name">Rules</field>
<field name="model">ir.rule</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Test">
<field name="field_id"/>
<field name="operator"/>
<field name="operand"/>
<field name="domain"/>
</tree>
</field>
</record>
@ -1051,6 +1053,11 @@
<field name="model_id" search="[('model', '=', 'ir.property')]" model="ir.model"/>
<field name="global" eval="True"/>
</record>
<record model="ir.rule.group" id="property_rule_group2">
<field name="name">Property multi-company 2</field>
<field name="model_id" search="[('model', '=', 'ir.property')]" model="ir.model"/>
<field name="global" eval="True"/>
</record>
<record model="ir.rule" id="property_rule">
<field name="field_id" search="[('model', '=', 'ir.property'), ('name', '=', 'company_id')]" model="ir.model.fields"/>
<field name="operator">child_of</field>
@ -1061,7 +1068,7 @@
<field name="field_id" search="[('model', '=', 'ir.property'), ('name', '=', 'company_id')]" model="ir.model.fields"/>
<field name="operator">=</field>
<field name="operand">False</field>
<field name="rule_group" ref="property_rule_group"/>
<field name="rule_group" ref="property_rule_group2"/>
</record>

View File

@ -110,13 +110,36 @@ class ir_rule(osv.osv):
recur=['many2one'], root_tech='user', root='User')
return res
def _domain_force_get(self, cr, uid, ids, field_name, arg, context={}):
res = {}
for rule in self.browse(cr, uid, ids, context):
if rule.domain_force:
res[rule.id] = rule.domain_force
else:
if rule.operator in ('in', 'child_of'):
dom = eval("[('%s', '%s', [%s])]" % (rule.field_id.name, rule.operator,
rule.operand), {'user': self.pool.get('res.users').browse(cr, 1, uid),
'time':time})
else:
dom = eval("[('%s', '%s', %s)]" % (rule.field_id.name, rule.operator,
rule.operand), {'user': self.pool.get('res.users').browse(cr, 1, uid),
'time':time})
res[rule.id] = dom
return res
_columns = {
'field_id': fields.many2one('ir.model.fields', 'Field',domain= "[('model_id','=', parent.model_id)]", select=1, required=True),
'operator':fields.selection((('=', '='), ('<>', '<>'), ('<=', '<='), ('>=', '>='), ('in', 'in'), ('child_of', 'child_of')), 'Operator', required=True),
'operand':fields.selection(_operand,'Operand', size=64, required=True),
'rule_group': fields.many2one('ir.rule.group', 'Group', select=2, required=True, ondelete="cascade")
'rule_group': fields.many2one('ir.rule.group', 'Group', select=2, required=True, ondelete="cascade"),
'domain_force': fields.char('Force Domain', size=250),
'domain': fields.function(_domain_force_get, method=True, string='Domain', type='char', size=250)
}
def onchange_all(self, cr, uid, ids, field_id, operator, operand):
if not (field_id or operator or operand):
return {}
def domain_get(self, cr, uid, model_name):
# root user above constraint
if uid == 1:
@ -142,17 +165,8 @@ class ir_rule(osv.osv):
sub_str = []
clause={}
clause_global={}
# Use root user to prevent recursion
for rule in self.browse(cr, 1, ids):
if rule.operator in ('in', 'child_of'):
dom = eval("[('%s', '%s', [%s])]" % (rule.field_id.name, rule.operator,
rule.operand), {'user': self.pool.get('res.users').browse(cr, 1, uid),
'time':time})
else:
dom = eval("[('%s', '%s', %s)]" % (rule.field_id.name, rule.operator,
rule.operand), {'user': self.pool.get('res.users').browse(cr, 1, uid),
'time':time})
for rule in self.browse(cr, uid, ids):
dom = rule.domain
if rule.rule_group['global']:
clause_global.setdefault(rule.rule_group.id, [])
clause_global[rule.rule_group.id].append(obj._where_calc(cr, uid, dom, active_test=False))
@ -172,7 +186,7 @@ class ir_rule(osv.osv):
first = True
for c in g:
if not first:
query += ' OR '
query += ' AND '
first = False
query += '('
first2 = True
@ -186,25 +200,8 @@ class ir_rule(osv.osv):
query += ')'
return query, val
query = ''
val = []
# Test if there is no rule_group that have no rule
cr.execute("""SELECT g.id FROM
ir_rule_group g
JOIN ir_model m ON (g.model_id = m.id)
WHERE m.model = %s
AND (g.id NOT IN (SELECT rule_group FROM ir_rule))
AND (g.id IN (SELECT rule_group_id FROM user_rule_group_rel
WHERE user_id = %d
UNION SELECT rule_group_id FROM group_rule_group_rel g_rel
JOIN res_groups_users_rel u_rel
ON g_rel.group_id = u_rel.gid
WHERE u_rel.uid = %d))""", (model_name, uid, uid))
if not cr.fetchall():
query, val = _query(clause, 'OR')
query_global, val_global = _query(clause_global, 'AND')
query, val = _query(clause, 'OR')
query_global, val_global = _query(clause_global, 'OR')
if query_global:
if query:
query = '('+query+') AND '+query_global