[IMP] Allows to put a view argument in a YAML record and OpenERP will
call all the on_change and default_get correctly. This increases a lot the coverage and reduce lines of test to develop. Put the XML_ID of the view of False so that OpenERP will find the first form view itself. Example to create a PO with all on_change: !record {model: purchase.order, id: purchase_new, view: False}: partner_id: base.res_partner_asus order_line: - product_id: product.product_product_pc1 product_qty: 5.0 bzr revid: fp@tinyerp.com-20111113223056-g65pf5vzg7dwkks1
This commit is contained in:
parent
edd35657f8
commit
aefa8b8c65
|
@ -11,6 +11,8 @@ import misc
|
|||
from config import config
|
||||
import yaml_tag
|
||||
import yaml
|
||||
import re
|
||||
from lxml import etree
|
||||
|
||||
# YAML import needs both safe and unsafe eval, but let's
|
||||
# default to /safe/.
|
||||
|
@ -164,9 +166,11 @@ class YamlInterpreter(object):
|
|||
self.logger.log(logging.ERROR, 'id: %s is to long (max: 64)', id)
|
||||
|
||||
def get_id(self, xml_id):
|
||||
if not xml_id:
|
||||
raise YamlImportException("The xml_id should be a non empty string.")
|
||||
if isinstance(xml_id, types.IntType):
|
||||
if xml_id is False:
|
||||
return False
|
||||
#if not xml_id:
|
||||
# raise YamlImportException("The xml_id should be a non empty string.")
|
||||
elif isinstance(xml_id, types.IntType):
|
||||
id = xml_id
|
||||
elif xml_id in self.id_map:
|
||||
id = self.id_map[xml_id]
|
||||
|
@ -307,6 +311,11 @@ class YamlInterpreter(object):
|
|||
import openerp.osv as osv
|
||||
record, fields = node.items()[0]
|
||||
model = self.get_model(record.model)
|
||||
|
||||
view_id = record.view
|
||||
if record.view:
|
||||
view_id = self.pool.get('ir.model.data')._get_id(self.cr, 1, self.module, record.view)
|
||||
|
||||
if model.is_transient():
|
||||
record_dict=self.create_osv_memory_record(record, fields)
|
||||
else:
|
||||
|
@ -321,22 +330,85 @@ class YamlInterpreter(object):
|
|||
if not self._coerce_bool(record.forcecreate):
|
||||
return None
|
||||
|
||||
record_dict = self._create_record(model, fields)
|
||||
self.logger.debug("RECORD_DICT %s" % record_dict)
|
||||
|
||||
#context = self.get_context(record, self.eval_context)
|
||||
context = record.context #TOFIX: record.context like {'withoutemployee':True} should pass from self.eval_context. example: test_project.yml in project module
|
||||
if view_id is not None:
|
||||
view = model.fields_view_get(self.cr, 1, view_id, 'form', context)
|
||||
view_id = etree.fromstring(view['arch'].encode('utf-8'))
|
||||
|
||||
record_dict = self._create_record(model, fields, view_id)
|
||||
self.logger.debug("RECORD_DICT %s" % record_dict)
|
||||
id = self.pool.get('ir.model.data')._update(self.cr, 1, record.model, \
|
||||
self.module, record_dict, record.id, noupdate=self.isnoupdate(record), mode=self.mode, context=context)
|
||||
self.id_map[record.id] = int(id)
|
||||
if config.get('import_partial'):
|
||||
self.cr.commit()
|
||||
|
||||
def _create_record(self, model, fields):
|
||||
def _create_record(self, model, fields, view=None, parent={}):
|
||||
allfields = model.fields_get(self.cr, 1, context=self.context)
|
||||
defaults = model.default_get(self.cr, 1, allfields, context=self.context)
|
||||
record_dict = {}
|
||||
fields = fields or {}
|
||||
fg = model.fields_get(self.cr, 1, context=self.context)
|
||||
|
||||
# Process all on_change calls
|
||||
nodes = view and [view] or []
|
||||
while nodes:
|
||||
el = nodes.pop(0)
|
||||
if el.tag=='field':
|
||||
field_name = el.attrib['name']
|
||||
if field_name in fields:
|
||||
view2 = None
|
||||
# if the form view is not inline, we call fields_view_get
|
||||
if (fg[field_name]['type']=='one2many') and view:
|
||||
view2 = view.find("field[@name='%s']/form"%(field_name,))
|
||||
if not view2:
|
||||
view2 = self.pool.get(fg[field_name]['relation']).fields_view_get(self.cr, 1, False, 'form', self.context)
|
||||
view2 = etree.fromstring(view2['arch'].encode('utf-8'))
|
||||
|
||||
field_value = self._eval_field(model, field_name, fields[field_name], view2, parent=record_dict)
|
||||
record_dict[field_name] = field_value
|
||||
elif (field_name in defaults) and (field_name not in record_dict):
|
||||
record_dict[field_name] = defaults[field_name]
|
||||
else:
|
||||
continue
|
||||
|
||||
if not el.attrib.get('on_change', False):
|
||||
continue
|
||||
match = re.match("([a-z_1-9A-Z]+)\((.*)\)", el.attrib['on_change'])
|
||||
assert match, "Unable to parse the on_change '%s'!" % (el.attrib['on_change'], )
|
||||
|
||||
# creating the context
|
||||
class parent2(object):
|
||||
def __init__(self, d):
|
||||
self.d = d
|
||||
def __getattr__(self, name):
|
||||
return self.d.get(name, False)
|
||||
|
||||
ctx = record_dict.copy()
|
||||
ctx['context'] = self.context
|
||||
ctx['uid'] = 1
|
||||
ctx['parent'] = parent2(parent)
|
||||
for a in fg:
|
||||
if a not in ctx:
|
||||
ctx[a]=False
|
||||
|
||||
# Evaluation args
|
||||
args = map(lambda x: eval(x, ctx), match.group(2).split(','))
|
||||
result = getattr(model, match.group(1))(self.cr, 1, [], *args)
|
||||
for key, val in result.get('value', {}).items():
|
||||
if key not in fields:
|
||||
record_dict[key] = val
|
||||
else:
|
||||
nodes = list(el) + nodes
|
||||
|
||||
for field_name, expression in fields.items():
|
||||
if field_name in record_dict:
|
||||
continue
|
||||
field_value = self._eval_field(model, field_name, expression)
|
||||
record_dict[field_name] = field_value
|
||||
|
||||
return record_dict
|
||||
|
||||
def process_ref(self, node, column=None):
|
||||
|
@ -365,7 +437,7 @@ class YamlInterpreter(object):
|
|||
def process_eval(self, node):
|
||||
return eval(node.expression, self.eval_context)
|
||||
|
||||
def _eval_field(self, model, field_name, expression):
|
||||
def _eval_field(self, model, field_name, expression, view=None, parent={}):
|
||||
# TODO this should be refactored as something like model.get_field() in bin/osv
|
||||
if field_name in model._columns:
|
||||
column = model._columns[field_name]
|
||||
|
@ -386,7 +458,7 @@ class YamlInterpreter(object):
|
|||
value = self.get_id(expression)
|
||||
elif column._type == "one2many":
|
||||
other_model = self.get_model(column._obj)
|
||||
value = [(0, 0, self._create_record(other_model, fields)) for fields in expression]
|
||||
value = [(0, 0, self._create_record(other_model, fields, view, parent)) for fields in expression]
|
||||
elif column._type == "many2many":
|
||||
ids = [self.get_id(xml_id) for xml_id in expression]
|
||||
value = [(6, 0, ids)]
|
||||
|
|
Loading…
Reference in New Issue