[MERGE] merge 6.0 branch.

bzr revid: vmt@openerp.com-20110303133011-758wfx7zompu5ugq
This commit is contained in:
Vo Minh Thu 2011-03-03 14:30:11 +01:00
commit dd1943c45e
11 changed files with 451 additions and 172 deletions

2
debian/po/he.po vendored
View File

@ -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
debian/po/pt_BR.po vendored
View File

@ -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."

View File

@ -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,

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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 !!!

View File

@ -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,

View File

@ -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 -->

View File

@ -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."