Skip to content
Permalink
Browse files

[FIX] convert: enable kwargs in tag <function>

  • Loading branch information...
rco-odoo committed Feb 14, 2019
1 parent e44dede commit b09462c545668c45467f04a02c557f0825035138
@@ -368,8 +368,8 @@ Andrew</p>]]></field>

<!-- Call Function to Cancel the leads (set as Dead) -->
<function model="crm.lead" name="action_set_lost"
eval="[ref('crm_case_7'), ref('crm_case_9'), ref('crm_case_11'), ref('crm_case_12')],
{'install_mode': True}"/>
eval="[[ref('crm_case_7'), ref('crm_case_9'), ref('crm_case_11'), ref('crm_case_12')]]"
context="{'install_mode': True}"/>

<!-- Demo Opportunities -->
<record id="crm_case_13" model="crm.lead">
@@ -1161,13 +1161,13 @@ Andrew</p>]]></field>

<!-- Call Function to set dome opportunities as Lost -->
<function model="crm.lead" name="action_set_lost"
eval="[ref('crm_case_28')],
{'install_mode': True}"/>
eval="[[ref('crm_case_28')]]"
context="{'install_mode': True}"/>

<!-- Call Function to set some opportunities as Won -->
<function model="crm.lead" name="action_set_won"
eval="[ref('crm_case_20'), ref('crm_case_23'), ref('crm_case_27')],
{'install_mode': True}"/>
eval="[[ref('crm_case_20'), ref('crm_case_23'), ref('crm_case_27')]]"
context="{'install_mode': True}"/>

<!-- Activities -->
<record id="activity_1" model="mail.activity">
@@ -264,34 +264,41 @@
<value model="link.tracker.code"
search="[('link_id.url', '=', 'http://www.example.com')]"
use="code"/>
<value eval="{'ip': '100.01.02.03', 'country_code': 'BE', 'mail_stat_id': ref('mass_mail_1_stat_0')}"/>
<value name="ip">100.01.02.03</value>
<value name="country_code">BE</value>
<value name="mail_stat_id" eval="ref('mass_mail_1_stat_0')"/>
</function>
<function model="link.tracker.click" name="add_click">
<value model="link.tracker.code"
search="[('link_id.url', '=', 'http://www.example.net/page/contactus')]"
use="code"/>
<value eval="{'ip': '100.01.02.03', 'country_code': 'BE', 'mail_stat_id': ref('mass_mail_1_stat_0')}"/>
<value name="ip">100.01.02.03</value>
<value name="country_code">BE</value>
<value name="mail_stat_id" eval="ref('mass_mail_1_stat_0')"/>
</function>
<function model="link.tracker.click" name="add_click">
<value model="link.tracker.code"
search="[('link_id.url', '=', 'http://www.example.com')]"
use="code"/>
<value eval="{'ip': '100.01.02.04', 'country_code': 'BE', 'mail_stat_id': ref('mass_mail_1_stat_1')}"/>
<value name="ip">100.01.02.04</value>
<value name="country_code">BE</value>
<value name="mail_stat_id" eval="ref('mass_mail_1_stat_1')"/>
</function>
<function model="link.tracker.click" name="add_click">
<value model="link.tracker.code"
search="[('link_id.url', '=', 'http://www.example.net/page/contactus')]"
use="code"/>
<value eval="{'ip': '100.01.02.04', 'country_code': 'BE', 'mail_stat_id': ref('mass_mail_1_stat_0')}"/>
<value eval="'100.01.02.04'"/>
<value eval="'BE'"/>
<value eval="ref('mass_mail_1_stat_0')"/>
<value name="ip">100.01.02.04</value>
<value name="country_code">BE</value>
<value name="mail_stat_id" eval="ref('mass_mail_1_stat_0')"/>
</function>
<function model="link.tracker.click" name="add_click">
<value model="link.tracker.code"
search="[('link_id.url', '=', 'http://www.example.com')]"
use="code"/>
<value eval="{'ip': '100.01.02.05', 'country_code': 'BE', 'mail_stat_id': ref('mass_mail_1_stat_2')}"/>
<value name="ip">100.01.02.05</value>
<value name="country_code">BE</value>
<value name="mail_stat_id" eval="ref('mass_mail_1_stat_2')"/>
</function>

</data>
@@ -143,20 +143,10 @@
</function>

<!-- create the transit location for each company existing -->
<function model="res.company" name="create_missing_transit_location">
<value model="res.company" eval="obj()"/>
</function>
<function model="res.company" name="create_missing_warehouse">
<value model="res.company" eval="obj()"/>
</function>
<function model="res.company" name="create_missing_inventory_loss_location">
<value model="res.company" eval="obj()"/>
</function>
<function model="res.company" name="create_missing_production_location">
<value model="res.company" eval="obj()"/>
</function>
<function model="res.company" name="create_missing_scrap_location">
<value model="res.company" eval="obj()"/>
</function>
<function model="res.company" name="create_missing_transit_location"/>
<function model="res.company" name="create_missing_warehouse"/>
<function model="res.company" name="create_missing_inventory_loss_location"/>
<function model="res.company" name="create_missing_production_location"/>
<function model="res.company" name="create_missing_scrap_location"/>
</data>
</odoo>
@@ -1,10 +1,4 @@
from odoo import fields, models
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.


class Usered(models.Model):
_name = 'test_convert.usered'
_description = "z test model ignore"

name = fields.Char()
user_id = fields.Many2one('res.users', default=lambda self: self.env.user)
tz = fields.Char(default=lambda self: self.env.context.get('tz') or self.env.user.tz)
from . import models
@@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import models, fields, api


class Usered(models.Model):
_name = 'test_convert.usered'
_description = "z test model ignore"

name = fields.Char()
user_id = fields.Many2one('res.users', default=lambda self: self.env.user)
tz = fields.Char(default=lambda self: self.env.context.get('tz') or self.env.user.tz)

@api.model
def model_method(self, *args, **kwargs):
return self, args, kwargs

def method(self, *args, **kwargs):
return self, args, kwargs
@@ -7,7 +7,7 @@
from lxml.builder import E

from odoo.tests import common
from odoo.tools.convert import _eval_xml
from odoo.tools.convert import xml_import, _eval_xml

Field = E.field
Value = E.value
@@ -74,6 +74,118 @@ def test_file(self):
with self.assertRaises(IOError):
self.eval_xml(Field('test_nofile.txt', type='file'), obj)

def test_function(self):
obj = xml_import(self.cr, 'test_convert', None, 'init')

# pass args in eval
xml = E.function(
model="test_convert.usered",
name="model_method",
eval="[1, 2]",
)
rec, args, kwargs = self.eval_xml(xml, obj)
self.assertEqual(rec.env.context, self.env.context)
self.assertEqual(rec.ids, [])
self.assertEqual(args, (1, 2))
self.assertEqual(kwargs, {})

xml = E.function(
model="test_convert.usered",
name="method",
eval="[1, 2]",
)
rec, args, kwargs = self.eval_xml(xml, obj)
self.assertEqual(rec.env.context, self.env.context)
self.assertEqual(rec.ids, [1])
self.assertEqual(args, (2,))
self.assertEqual(kwargs, {})

# pass args in child elements
xml = E.function(
E.value(eval="1"), E.value(eval="2"),
model="test_convert.usered",
name="model_method",
)
rec, args, kwargs = self.eval_xml(xml, obj)
self.assertEqual(rec.env.context, self.env.context)
self.assertEqual(rec.ids, [])
self.assertEqual(args, (1, 2))
self.assertEqual(kwargs, {})

xml = E.function(
E.value(eval="1"), E.value(eval="2"),
model="test_convert.usered",
name="method",
)
rec, args, kwargs = self.eval_xml(xml, obj)
self.assertEqual(rec.env.context, self.env.context)
self.assertEqual(rec.ids, [1])
self.assertEqual(args, (2,))
self.assertEqual(kwargs, {})

def test_function_kwargs(self):
obj = xml_import(self.cr, 'test_convert', None, 'init')

# pass args and kwargs in child elements
xml = E.function(
E.value(eval="1"), E.value(name="foo", eval="2"),
model="test_convert.usered",
name="model_method",
)
rec, args, kwargs = self.eval_xml(xml, obj)
self.assertEqual(rec.env.context, self.env.context)
self.assertEqual(rec.ids, [])
self.assertEqual(args, (1,))
self.assertEqual(kwargs, {'foo': 2})

xml = E.function(
E.value(eval="1"), E.value(name="foo", eval="2"),
model="test_convert.usered",
name="method",
)
rec, args, kwargs = self.eval_xml(xml, obj)
self.assertEqual(rec.env.context, self.env.context)
self.assertEqual(rec.ids, [1])
self.assertEqual(args, ())
self.assertEqual(kwargs, {'foo': 2})

# pass args and context in kwargs
xml = E.function(
E.value(eval="1"), E.value(name="context", eval="{'foo': 2}"),
model="test_convert.usered",
name="model_method",
)
rec, args, kwargs = self.eval_xml(xml, obj)
self.assertEqual(rec.env.context, {'foo': 2})
self.assertEqual(rec.ids, [])
self.assertEqual(args, (1,))
self.assertEqual(kwargs, {})

xml = E.function(
E.value(eval="1"), E.value(name="context", eval="{'foo': 2}"),
model="test_convert.usered",
name="method",
)
rec, args, kwargs = self.eval_xml(xml, obj)
self.assertEqual(rec.env.context, {'foo': 2})
self.assertEqual(rec.ids, [1])
self.assertEqual(args, ())
self.assertEqual(kwargs, {})

def test_function_function(self):
obj = xml_import(self.cr, 'test_convert', None, 'init')

xml = E.function(
E.function(model="test_convert.usered", name="search", eval="[[]]"),
model="test_convert.usered",
name="method",
)
rec, args, kwargs = self.eval_xml(xml, obj)
self.assertEqual(rec.env.context, {})
self.assertEqual(rec.ids, [])
self.assertEqual(args, ())
self.assertEqual(kwargs, {})

@unittest.skip("not tested")
def test_xml(self):
pass
@@ -23,6 +23,7 @@

<rng:define name="value">
<rng:element name="value">
<rng:optional><rng:attribute name="name" /></rng:optional>
<rng:optional><rng:attribute name="model" /></rng:optional>
<rng:choice>
<rng:attribute name="search" />
@@ -177,32 +177,24 @@ def _process(s):
return tuple(res)
return res
elif node.tag == "function":
model = env[node.get('model')]
method_name = node.get('name')
# determine arguments
args = []
kwargs = {}
a_eval = node.get('eval')
if a_eval:
self.idref['ref'] = self.id_get
# ensure the args are a list (sometimes folks eval a tuple which
# is inconvenient when trying to concatenate w/ a list)
args = list(safe_eval(a_eval, self.idref))
else:
args = [
r for r in (_eval_xml(self, n, env) for n in node)
if r is not None
]

model = env[node.get('model')]
method_name = node.get('name')
method = getattr(model, method_name)

# this mess is necessary to merge @context and a possible positional
# context parameter, as <function> works on the old API so ids and
# context are just args
ids, args = [], list(args)
if getattr(method, '_api', None) not in ('model', 'model_create'):
ids, args = args[:1], args[1:]
context, args, kwargs = api.split_context(method, args, {})
kwargs['context'] = {**env.context, **(context or {})}

return odoo.api.call_kw(model, method_name, ids + args, kwargs)
for child in node:
if child.tag == 'value' and child.get('name'):
kwargs[child.get('name')] = _eval_xml(self, child, env)
else:
args.append(_eval_xml(self, child, env))
# merge current context with context in kwargs
kwargs['context'] = {**env.context, **kwargs.get('context', {})}
# invoke method
return odoo.api.call_kw(model, method_name, args, kwargs)
elif node.tag == "test":
return node.text

0 comments on commit b09462c

Please sign in to comment.
You can’t perform that action at this time.