[MERGE] merge 6.0 branch.
bzr revid: vmt@openerp.com-20110303133011-758wfx7zompu5ugq
This commit is contained in:
commit
dd1943c45e
|
@ -14,7 +14,7 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-02-23 04:36+0000\n"
|
||||
"X-Launchpad-Export-Date: 2011-02-23 06:17+0000\n"
|
||||
"X-Generator: Launchpad (build 12351)\n"
|
||||
|
||||
#. Type: string
|
||||
|
|
|
@ -8,13 +8,13 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-server\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2009-08-24 22:41+0300\n"
|
||||
"PO-Revision-Date: 2010-11-07 07:06+0000\n"
|
||||
"Last-Translator: OpenERP Administrators <Unknown>\n"
|
||||
"PO-Revision-Date: 2011-02-23 22:44+0000\n"
|
||||
"Last-Translator: Emerson <Unknown>\n"
|
||||
"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-02-16 05:00+0000\n"
|
||||
"X-Launchpad-Export-Date: 2011-03-01 06:00+0000\n"
|
||||
"X-Generator: Launchpad (build 12351)\n"
|
||||
|
||||
#. Type: string
|
||||
|
@ -39,4 +39,4 @@ msgstr ""
|
|||
#. Description
|
||||
#: ../openerp-server.templates:1001
|
||||
msgid "Please choose that account's username."
|
||||
msgstr "Escolha um usuário para a conta"
|
||||
msgstr "Por favor, escolha um usuário para a conta."
|
||||
|
|
|
@ -93,6 +93,7 @@
|
|||
'test/test_context.xml',
|
||||
'test/bug_lp541545.xml',
|
||||
'test/test_osv_expression.yml',
|
||||
'test/test_ir_rule.yml', # <-- These tests modify/add/delete ir_rules.
|
||||
],
|
||||
'installable': True,
|
||||
'active': True,
|
||||
|
|
|
@ -7,14 +7,14 @@ msgstr ""
|
|||
"Project-Id-Version: OpenERP Server 5.0.0\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2011-01-19 08:35+0000\n"
|
||||
"Last-Translator: Stefan Rijnhart (Therp) <Unknown>\n"
|
||||
"PO-Revision-Date: 2011-02-21 08:40+0000\n"
|
||||
"Last-Translator: Niels Huylebroeck <Unknown>\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-01-20 04:48+0000\n"
|
||||
"X-Generator: Launchpad (build 12177)\n"
|
||||
"X-Launchpad-Export-Date: 2011-02-22 14:26+0000\n"
|
||||
"X-Generator: Launchpad (build 12351)\n"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.filters:0
|
||||
|
@ -2905,7 +2905,7 @@ msgstr "Verplicht"
|
|||
#. module: base
|
||||
#: view:res.users:0
|
||||
msgid "Default Filters"
|
||||
msgstr "Stadaard filters"
|
||||
msgstr "Standaard filters"
|
||||
|
||||
#. module: base
|
||||
#: field:res.request.history,name:0
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -8,14 +8,14 @@ msgstr ""
|
|||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: support@openerp.com\n"
|
||||
"POT-Creation-Date: 2011-01-11 11:14+0000\n"
|
||||
"PO-Revision-Date: 2011-01-11 08:47+0000\n"
|
||||
"Last-Translator: OpenERP Administrators <Unknown>\n"
|
||||
"PO-Revision-Date: 2011-02-27 01:05+0000\n"
|
||||
"Last-Translator: phi_binh <Unknown>\n"
|
||||
"Language-Team: Vietnamese <vi@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2011-01-12 04:52+0000\n"
|
||||
"X-Generator: Launchpad (build Unknown)\n"
|
||||
"X-Launchpad-Export-Date: 2011-03-01 06:00+0000\n"
|
||||
"X-Generator: Launchpad (build 12351)\n"
|
||||
|
||||
#. module: base
|
||||
#: view:ir.filters:0
|
||||
|
@ -381,7 +381,7 @@ msgstr "Tiếng Hy Lạp"
|
|||
#. module: base
|
||||
#: selection:base.language.install,lang:0
|
||||
msgid "Bosnian / bosanski jezik"
|
||||
msgstr ""
|
||||
msgstr "Tiếng Bosnia"
|
||||
|
||||
#. module: base
|
||||
#: help:ir.actions.report.xml,attachment_use:0
|
||||
|
|
|
@ -31,15 +31,18 @@ class ir_rule(osv.osv):
|
|||
_order = 'name'
|
||||
_MODES = ['read', 'write', 'create', 'unlink']
|
||||
|
||||
def _domain_force_get(self, cr, uid, ids, field_name, arg, context={}):
|
||||
def _domain_force_get(self, cr, uid, ids, field_name, arg, context=None):
|
||||
res = {}
|
||||
for rule in self.browse(cr, uid, ids, context):
|
||||
eval_user_data = {'user': self.pool.get('res.users').browse(cr, 1, uid),
|
||||
'time':time}
|
||||
res[rule.id] = eval(rule.domain_force, eval_user_data)
|
||||
if rule.domain_force:
|
||||
eval_user_data = {'user': self.pool.get('res.users').browse(cr, 1, uid),
|
||||
'time':time}
|
||||
res[rule.id] = eval(rule.domain_force, eval_user_data)
|
||||
else:
|
||||
res[rule.id] = []
|
||||
return res
|
||||
|
||||
def _get_value(self, cr, uid, ids, field_name, arg, context={}):
|
||||
def _get_value(self, cr, uid, ids, field_name, arg, context=None):
|
||||
res = {}
|
||||
for rule in self.browse(cr, uid, ids, context):
|
||||
if not rule.groups:
|
||||
|
@ -81,10 +84,15 @@ class ir_rule(osv.osv):
|
|||
]
|
||||
|
||||
def domain_create(self, cr, uid, rule_ids):
|
||||
dom = ['&'] * (len(rule_ids)-1)
|
||||
count = 0
|
||||
dom = []
|
||||
for rule in self.browse(cr, uid, rule_ids):
|
||||
dom += rule.domain
|
||||
return dom
|
||||
if rule.domain:
|
||||
dom += rule.domain
|
||||
count += 1
|
||||
if count:
|
||||
return ['&'] * (count-1) + dom
|
||||
return []
|
||||
|
||||
@tools.cache()
|
||||
def _compute_domain(self, cr, uid, model_name, mode="read"):
|
||||
|
@ -110,11 +118,19 @@ class ir_rule(osv.osv):
|
|||
group_rule.setdefault(group.id, []).append(rule.id)
|
||||
if not rule.groups:
|
||||
global_rules.append(rule.id)
|
||||
dom = self.domain_create(cr, uid, global_rules)
|
||||
dom += ['|'] * (len(group_rule)-1)
|
||||
global_domain = self.domain_create(cr, uid, global_rules)
|
||||
count = 0
|
||||
group_domains = []
|
||||
for value in group_rule.values():
|
||||
dom += self.domain_create(cr, uid, value)
|
||||
return dom
|
||||
group_domain = self.domain_create(cr, uid, value)
|
||||
if group_domain:
|
||||
group_domains += group_domain
|
||||
count += 1
|
||||
if count and global_domain:
|
||||
return ['&'] + global_domain + ['|'] * (count-1) + group_domains
|
||||
if count:
|
||||
return ['|'] * (count-1) + group_domains
|
||||
return global_domain
|
||||
return []
|
||||
|
||||
def clear_cache(self, cr, uid):
|
||||
|
@ -135,10 +151,14 @@ class ir_rule(osv.osv):
|
|||
[clear(model, mode) for model in models for mode in self._MODES]
|
||||
|
||||
|
||||
def domain_get(self, cr, uid, model_name, mode='read', context={}):
|
||||
def domain_get(self, cr, uid, model_name, mode='read', context=None):
|
||||
dom = self._compute_domain(cr, uid, model_name, mode=mode)
|
||||
if dom:
|
||||
query = self.pool.get(model_name)._where_calc(cr, uid, dom, active_test=False)
|
||||
# _where_calc is called as superuser. This means that rules can
|
||||
# involve objects on which the real uid has no acces rights.
|
||||
# This means also there is no implicit restriction (e.g. an object
|
||||
# references another object the user can't see).
|
||||
query = self.pool.get(model_name)._where_calc(cr, 1, dom, active_test=False)
|
||||
return query.where_clause, query.where_clause_params, query.tables
|
||||
return [], [], ['"'+self.pool.get(model_name)._table+'"']
|
||||
|
||||
|
@ -155,8 +175,6 @@ class ir_rule(osv.osv):
|
|||
return res
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
if not context:
|
||||
context={}
|
||||
res = super(ir_rule, self).write(cr, uid, ids, vals, context=context)
|
||||
# Restart the cache on the _compute_domain method
|
||||
self._compute_domain.clear_cache(cr.dbname)
|
||||
|
|
|
@ -25,7 +25,7 @@ import netsvc
|
|||
import report,pooler,tools
|
||||
from operator import itemgetter
|
||||
|
||||
def graph_get(cr, graph, wkf_ids, nested=False, workitem={}):
|
||||
def graph_get(cr, graph, wkf_ids, nested, workitem, processed_subflows):
|
||||
import pydot
|
||||
cr.execute('select * from wkf_activity where wkf_id in ('+','.join(['%s']*len(wkf_ids))+')', wkf_ids)
|
||||
nodes = cr.dictfetchall()
|
||||
|
@ -34,11 +34,12 @@ def graph_get(cr, graph, wkf_ids, nested=False, workitem={}):
|
|||
actto = {}
|
||||
for n in nodes:
|
||||
activities[n['id']] = n
|
||||
if n['subflow_id'] and nested:
|
||||
if n['subflow_id'] and nested and n['subflow_id'] not in processed_subflows:
|
||||
processed_subflows.add(n['subflow_id']) # don't create multiple times the same cluster.
|
||||
cr.execute('select * from wkf where id=%s', (n['subflow_id'],))
|
||||
wkfinfo = cr.dictfetchone()
|
||||
graph2 = pydot.Cluster('subflow'+str(n['subflow_id']), fontsize='12', label = """\"Subflow: %s\\nOSV: %s\"""" % ( n['name'], wkfinfo['osv']) )
|
||||
(s1,s2) = graph_get(cr, graph2, [n['subflow_id']], nested,workitem)
|
||||
graph2 = pydot.Cluster('subflow'+str(n['subflow_id']), fontsize='12', label = "\"Subflow: %s\\nOSV: %s\"" % ( n['name'], wkfinfo['osv']) )
|
||||
(s1,s2) = graph_get(cr, graph2, [n['subflow_id']], True, workitem, processed_subflows)
|
||||
graph.add_subgraph(graph2)
|
||||
actfrom[n['id']] = s2
|
||||
actto[n['id']] = s1
|
||||
|
@ -48,11 +49,22 @@ def graph_get(cr, graph, wkf_ids, nested=False, workitem={}):
|
|||
args['style']='filled'
|
||||
args['color']='lightgrey'
|
||||
args['label']=n['name']
|
||||
workitems = ''
|
||||
if n['id'] in workitem:
|
||||
workitems = '\\nx ' + str(workitem[n['id']])
|
||||
args['label'] += workitems
|
||||
args['color'] = "red"
|
||||
args['style']='filled'
|
||||
if n['subflow_id']:
|
||||
args['shape'] = 'box'
|
||||
if n['id'] in workitem:
|
||||
args['label']+='\\nx '+str(workitem[n['id']])
|
||||
args['color'] = "red"
|
||||
if nested and n['subflow_id'] in processed_subflows:
|
||||
cr.execute('select * from wkf where id=%s', (n['subflow_id'],))
|
||||
wkfinfo = cr.dictfetchone()
|
||||
args['label'] = \
|
||||
'\"Subflow: %s\\nOSV: %s\\n(already expanded)%s\"' % \
|
||||
(n['name'], wkfinfo['osv'], workitems)
|
||||
args['color'] = 'green'
|
||||
args['style'] ='filled'
|
||||
graph.add_node(pydot.Node(n['id'], **args))
|
||||
actfrom[n['id']] = (n['id'],{})
|
||||
actto[n['id']] = (n['id'],{})
|
||||
|
@ -104,7 +116,9 @@ def graph_instance_get(cr, graph, inst_id, nested=False):
|
|||
for (subflow_id,) in cr.fetchall():
|
||||
workitems.update(workitem_get(subflow_id))
|
||||
return workitems
|
||||
graph_get(cr, graph, [x[0] for x in inst], nested, workitem_get(inst_id))
|
||||
|
||||
processed_subflows = set()
|
||||
graph_get(cr, graph, [x[0] for x in inst], nested, workitem_get(inst_id), processed_subflows)
|
||||
|
||||
#
|
||||
# TODO: pas clean: concurrent !!!
|
||||
|
|
|
@ -98,7 +98,11 @@ class res_company(osv.osv):
|
|||
context = {}
|
||||
user_preference = context.get('user_preference', False)
|
||||
if user_preference:
|
||||
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
|
||||
# We browse as superuser. Otherwise, the user would be able to
|
||||
# select only the currently visible companies (according to rules,
|
||||
# which are probably to allow to see the child companies) even if
|
||||
# she belongs to some other companies.
|
||||
user = self.pool.get('res.users').browse(cr, 1, uid, context=context)
|
||||
cmp_ids = list(set([user.company_id.id] + [cmp.id for cmp in user.company_ids]))
|
||||
return cmp_ids
|
||||
return super(res_company, self)._search(cr, uid, args, offset=offset, limit=limit, order=order,
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<field model="ir.model" name="model_id" ref="model_res_company"/>
|
||||
<field eval="True" name="global"/>
|
||||
<!-- TODO: review this <field name="domain_force">['|', ('child_ids', 'child_of', [user.company_id.id]), ('parent_id', 'child_of', [user.company_id.id])]</field> -->
|
||||
<field name="domain_force">[]</field>
|
||||
<field name="domain_force">[('id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<!-- Record Rule For User -->
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
-
|
||||
Exercise ir_rule.py code (and indirectly expression.py).
|
||||
-
|
||||
Create an ir_rule for the Employee group (called base.group_user)
|
||||
with an blank domain.
|
||||
-
|
||||
!record {model: ir.rule, id: test_rule}:
|
||||
model_id: base.model_res_partner
|
||||
domain_force: False
|
||||
name: test_rule
|
||||
groups:
|
||||
- base.group_user
|
||||
perm_unlink: 1
|
||||
perm_write: 1
|
||||
perm_read: 1
|
||||
perm_create: 1
|
||||
-
|
||||
Read as demo user the partners (one blank domain).
|
||||
-
|
||||
!python {model: res.partner }: |
|
||||
ids = self.search(cr, ref('base.user_demo'), [])
|
||||
assert ids, "Demo user should see some partner."
|
||||
-
|
||||
Domain is not empty.
|
||||
-
|
||||
!record {model: ir.rule, id: test_rule}:
|
||||
model_id: base.model_res_partner
|
||||
domain_force: "[(1,'=',1)]"
|
||||
-
|
||||
Read as demo user the partners (one 1=1 domain).
|
||||
-
|
||||
!python {model: res.partner }: |
|
||||
ids = self.search(cr, ref('base.user_demo'), [])
|
||||
assert ids, "Demo user should see some partner."
|
||||
-
|
||||
Domain is an empty list.
|
||||
-
|
||||
!record {model: ir.rule, id: test_rule}:
|
||||
model_id: base.model_res_partner
|
||||
domain_force: "[]"
|
||||
-
|
||||
Read as demo user the partners (one [] domain).
|
||||
-
|
||||
!python {model: res.partner }: |
|
||||
ids = self.search(cr, ref('base.user_demo'), [])
|
||||
assert ids, "Demo user should see some partner."
|
||||
-
|
||||
Create another ir_rule for the Employee group (to test rules from
|
||||
multiple groups).
|
||||
-
|
||||
!record {model: ir.rule, id: test_rule2}:
|
||||
model_id: base.model_res_partner
|
||||
domain_force: False
|
||||
name: test_rule2
|
||||
groups:
|
||||
- base.group_user
|
||||
perm_unlink: 1
|
||||
perm_write: 1
|
||||
perm_read: 1
|
||||
perm_create: 1
|
||||
-
|
||||
Read as demo user the partners (blank and [] domains).
|
||||
-
|
||||
!python {model: res.partner }: |
|
||||
ids = self.search(cr, ref('base.user_demo'), [])
|
||||
assert ids, "Demo user should see some partner."
|
||||
-
|
||||
Domain is not empty.
|
||||
-
|
||||
!record {model: ir.rule, id: test_rule}:
|
||||
model_id: base.model_res_partner
|
||||
domain_force: "[(1,'=',1)]"
|
||||
-
|
||||
Read as demo user the partners (1=1 and blank domain).
|
||||
-
|
||||
!python {model: res.partner }: |
|
||||
ids = self.search(cr, ref('base.user_demo'), [])
|
||||
assert ids, "Demo user should see some partner."
|
||||
-
|
||||
Domain is not empty.
|
||||
-
|
||||
!record {model: ir.rule, id: test_rule2}:
|
||||
model_id: base.model_res_partner
|
||||
domain_force: "[(1,'=',1)]"
|
||||
-
|
||||
Read as demo user the partners (two 1=1 domains).
|
||||
-
|
||||
!python {model: res.partner }: |
|
||||
ids = self.search(cr, ref('base.user_demo'), [])
|
||||
assert ids, "Demo user should see some partner."
|
||||
-
|
||||
Create another ir_rule for the Employee group (to test rules from
|
||||
multiple groups).
|
||||
-
|
||||
!record {model: ir.rule, id: test_rule3}:
|
||||
model_id: base.model_res_partner
|
||||
domain_force: False
|
||||
name: test_rule3
|
||||
groups:
|
||||
- base.group_user
|
||||
perm_unlink: 1
|
||||
perm_write: 1
|
||||
perm_read: 1
|
||||
perm_create: 1
|
||||
-
|
||||
Read as demo user the partners.
|
||||
-
|
||||
!python {model: res.partner }: |
|
||||
ids = self.search(cr, ref('base.user_demo'), [])
|
||||
assert ids, "Demo user should see some partner."
|
||||
-
|
||||
Domain is not empty.
|
||||
-
|
||||
!record {model: ir.rule, id: test_rule3}:
|
||||
model_id: base.model_res_partner
|
||||
domain_force: "[(1,'=',1)]"
|
||||
-
|
||||
Read as demo user the partners (three 1=1 domains).
|
||||
-
|
||||
!python {model: res.partner }: |
|
||||
ids = self.search(cr, ref('base.user_demo'), [])
|
||||
assert ids, "Demo user should see some partner."
|
||||
-
|
||||
Modify the global rule on res_company which triggers a recursive check
|
||||
of the rules on company.
|
||||
-
|
||||
!record {model: ir.rule, id: base.res_company_rule}:
|
||||
domain_force: "[('id','child_of',[user.company_id.id])]"
|
||||
-
|
||||
Read as demo user the partners (exercising the global company rule).
|
||||
-
|
||||
!python {model: res.partner }: |
|
||||
ids = self.search(cr, ref('base.user_demo'), [])
|
||||
assert ids, "Demo user should see some partner."
|
||||
-
|
||||
Delete global domains (to combine only group domains).
|
||||
-
|
||||
!python {model: ir.rule}: |
|
||||
ids = self.search(cr, uid, [('groups','=',False)])
|
||||
assert ids, "Demo user should see some partner."
|
||||
self.unlink(cr, uid, ids)
|
||||
-
|
||||
Read as demo user the partners (three 1=1 domains, no global domain).
|
||||
-
|
||||
!python {model: res.partner }: |
|
||||
ids = self.search(cr, ref('base.user_demo'), [])
|
||||
assert ids, "Demo user should see some partner."
|
Loading…
Reference in New Issue