[ADD] force linking to existing o2m being updated
bzr revid: xmo@openerp.com-20120920102545-30tkodb4s1dng5hp
This commit is contained in:
parent
9805c665c8
commit
c9e0cfd64a
|
@ -5,6 +5,22 @@ import warnings
|
|||
from openerp.osv import orm, fields
|
||||
from openerp.tools.translate import _
|
||||
|
||||
REFERENCING_FIELDS = set([None, 'id', '.id'])
|
||||
def only_ref_fields(record):
|
||||
return dict((k, v) for k, v in record.iteritems()
|
||||
if k in REFERENCING_FIELDS)
|
||||
def exclude_ref_fields(record):
|
||||
return dict((k, v) for k, v in record.iteritems()
|
||||
if k not in REFERENCING_FIELDS)
|
||||
|
||||
CREATE = lambda values: (0, False, values)
|
||||
UPDATE = lambda id, values: (1, id, values)
|
||||
DELETE = lambda id: (2, id, False)
|
||||
FORGET = lambda id: (3, id, False)
|
||||
LINK_TO = lambda id: (4, id, False)
|
||||
DELETE_ALL = lambda: (5, False, False)
|
||||
REPLACE_WITH = lambda ids: (6, False, ids)
|
||||
|
||||
class ConversionNotFound(ValueError): pass
|
||||
|
||||
class ir_fields_converter(orm.Model):
|
||||
|
@ -145,9 +161,8 @@ class ir_fields_converter(orm.Model):
|
|||
:rtype: str
|
||||
"""
|
||||
# Can import by name_get, external id or database id
|
||||
allowed_fields = set([None, 'id', '.id'])
|
||||
fieldset = set(record.iterkeys())
|
||||
if fieldset - allowed_fields:
|
||||
if fieldset - REFERENCING_FIELDS:
|
||||
raise ValueError(
|
||||
_(u"Can not create Many-To-One records indirectly, import the field separately"))
|
||||
if len(fieldset) > 1:
|
||||
|
@ -190,4 +205,17 @@ class ir_fields_converter(orm.Model):
|
|||
|
||||
return [(6, 0, ids)]
|
||||
def _str_to_one2many(self, cr, uid, model, column, value, context=None):
|
||||
return value
|
||||
commands = []
|
||||
for subfield, record in zip((self._referencing_subfield(
|
||||
only_ref_fields(record))
|
||||
for record in value),
|
||||
value):
|
||||
id, subfield_type = self.db_id_for(
|
||||
cr, uid, model, column, subfield, record[subfield], context=context)
|
||||
writable = exclude_ref_fields(record)
|
||||
if id:
|
||||
commands.append(LINK_TO(id))
|
||||
commands.append(UPDATE(id, writable))
|
||||
else:
|
||||
commands.append(CREATE(writable))
|
||||
return commands
|
||||
|
|
|
@ -869,10 +869,13 @@ class test_o2m(ImporterCase):
|
|||
"invalid literal for int() with base 10: '%d,%d'" % (id1, id2))
|
||||
|
||||
def test_link(self):
|
||||
id1 = self.registry('export.one2many.child').create(self.cr, openerp.SUPERUSER_ID, {
|
||||
""" O2M relating to an existing record (update) force a LINK_TO as well
|
||||
"""
|
||||
O2M = self.registry('export.one2many.child')
|
||||
id1 = O2M.create(self.cr, openerp.SUPERUSER_ID, {
|
||||
'str': 'Bf', 'value': 109
|
||||
})
|
||||
id2 = self.registry('export.one2many.child').create(self.cr, openerp.SUPERUSER_ID, {
|
||||
id2 = O2M.create(self.cr, openerp.SUPERUSER_ID, {
|
||||
'str': 'Me', 'value': 262
|
||||
})
|
||||
|
||||
|
@ -880,17 +883,14 @@ class test_o2m(ImporterCase):
|
|||
['42', str(id1)],
|
||||
['', str(id2)],
|
||||
])
|
||||
self.assertEqual(len(ids), 2)
|
||||
self.assertFalse(messages)
|
||||
self.assertEqual(len(ids), 1)
|
||||
|
||||
# No record values alongside id => o2m resolution skipped altogether,
|
||||
# creates 2 records => remove/don't import columns sideshow columns,
|
||||
# get completely different semantics
|
||||
b, b1 = self.browse()
|
||||
[b] = self.browse()
|
||||
self.assertEqual(b.const, 42)
|
||||
self.assertEqual(values(b.value), [])
|
||||
self.assertEqual(b1.const, 4)
|
||||
self.assertEqual(values(b1.value), [])
|
||||
# automatically forces link between core record and o2ms
|
||||
self.assertEqual(values(b.value), [109, 262])
|
||||
self.assertEqual(values(b.value, field='parent_id'), [b, b])
|
||||
|
||||
def test_link_2(self):
|
||||
O2M_c = self.registry('export.one2many.child')
|
||||
|
@ -905,24 +905,13 @@ class test_o2m(ImporterCase):
|
|||
['42', str(id1), '1'],
|
||||
['', str(id2), '2'],
|
||||
])
|
||||
self.assertEqual(len(ids), 2)
|
||||
self.assertFalse(messages)
|
||||
self.assertEqual(len(ids), 1)
|
||||
|
||||
(b,) = self.browse()
|
||||
# if an id (db or xid) is provided, expectations that objects are
|
||||
# *already* linked and emits UPDATE (1, id, {}).
|
||||
# Noid => CREATE (0, ?, {})
|
||||
# TODO: xid ignored aside from getting corresponding db id?
|
||||
[b] = self.browse()
|
||||
self.assertEqual(b.const, 42)
|
||||
self.assertEqual(values(b.value), [])
|
||||
|
||||
# FIXME: updates somebody else's records?
|
||||
self.assertEqual(
|
||||
O2M_c.read(self.cr, openerp.SUPERUSER_ID, id1),
|
||||
{'id': id1, 'str': 'Bf', 'value': 1, 'parent_id': False})
|
||||
self.assertEqual(
|
||||
O2M_c.read(self.cr, openerp.SUPERUSER_ID, id2),
|
||||
{'id': id2, 'str': 'Me', 'value': 2, 'parent_id': False})
|
||||
self.assertEqual(values(b.value), [1, 2])
|
||||
self.assertEqual(values(b.value, field='parent_id'), [b, b])
|
||||
|
||||
class test_o2m_multiple(ImporterCase):
|
||||
model_name = 'export.one2many.multiple'
|
||||
|
|
Loading…
Reference in New Issue