Merge lp:~credativ/openobject-server/trunk-csv-import-domain into lp:openobject-server

Proposed by Craig Gowing (credativ)
Status: Needs review
Proposed branch: lp:~credativ/openobject-server/trunk-csv-import-domain
Merge into: lp:openobject-server
Diff against target: 73 lines (+30/-1)
2 files modified
openerp/addons/base/ir/ir_fields.py (+11/-1)
openerp/osv/orm.py (+19/-0)
To merge this branch: bzr merge lp:~credativ/openobject-server/trunk-csv-import-domain
Reviewer Review Type Date Requested Status
OpenERP Core Team Pending
Review via email: mp+216989@code.launchpad.net

Description of the change

When importing CSV files, allow a domain to be specified so that unique matches to records can be made when either name search is not accurate enough (too many matches) or the external XML ID does not exist or is unknown.

The field is similar to /id and /.id, it is defined as /.domain
The domain is safe_eval'ed and a standard search is run on the object using the domain, so correct security limitations will be in effect.

https://blueprints.launchpad.net/openobject-addons/+spec/csv-import-domain

To post a comment you must log in.

Unmerged revisions

5196. By Craig Gowing (credativ)

[IMP] Allow domain searches on CSV import

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openerp/addons/base/ir/ir_fields.py'
2--- openerp/addons/base/ir/ir_fields.py 2014-02-06 11:04:23 +0000
3+++ openerp/addons/base/ir/ir_fields.py 2014-04-24 07:39:42 +0000
4@@ -14,8 +14,9 @@
5 from openerp.tools.misc import DEFAULT_SERVER_DATE_FORMAT,\
6 DEFAULT_SERVER_DATETIME_FORMAT
7 from openerp.tools import html_sanitize
8+from openerp.tools.safe_eval import safe_eval as eval
9
10-REFERENCING_FIELDS = set([None, 'id', '.id'])
11+REFERENCING_FIELDS = set([None, 'id', '.id', '.domain'])
12 def only_ref_fields(record):
13 return dict((k, v) for k, v in record.iteritems()
14 if k in REFERENCING_FIELDS)
15@@ -338,6 +339,15 @@
16 _(u"Found multiple matches for field '%%(field)s' (%d matches)")
17 % (len(ids))))
18 id, _name = ids[0]
19+ elif subfield == '.domain':
20+ field_type = _(u"domain")
21+ try:
22+ ids = RelatedModel.search(cr, uid, eval(value), context=context)
23+ if ids:
24+ id = ids[0]
25+ except ValueError:
26+ raise ValueError(
27+ _(u"Invalid domain '%s'") % value, {'moreinfo': action})
28 else:
29 raise Exception(_(u"Unknown sub-field '%s'") % subfield)
30
31
32=== modified file 'openerp/osv/orm.py'
33--- openerp/osv/orm.py 2014-04-16 14:34:31 +0000
34+++ openerp/osv/orm.py 2014-04-24 07:39:42 +0000
35@@ -1420,12 +1420,14 @@
36 * None is the name_get for the record (to use with name_create/name_search)
37 * "id" is the External ID for the record
38 * ".id" is the Database ID for the record
39+ * ".domain" is a domain expression for the record
40 """
41 columns = dict((k, v.column) for k, v in self._all_columns.iteritems())
42 # Fake columns to avoid special cases in extractor
43 columns[None] = fields.char('rec_name')
44 columns['id'] = fields.char('External ID')
45 columns['.id'] = fields.integer('Database ID')
46+ columns['.domain'] = fields.char('Domain')
47
48 # m2o fields can't be on multiple lines so exclude them from the
49 # is_relational field rows filter, but special-case it later on to
50@@ -1537,6 +1539,23 @@
51 field='.id',
52 message=_(u"Unknown database identifier '%s'") % dbid))
53 dbid = False
54+ if '.domain' in record:
55+ try:
56+ dbids = self.search(cr, uid, eval(record['.domain']), context=context)
57+ if not dbids:
58+ log(dict(extras,
59+ type='error',
60+ record=stream.index,
61+ field='.domain',
62+ message=_(u"Domain did not match record '%s'") % record['.domain']))
63+ else:
64+ dbid = dbids[0]
65+ except ValueError:
66+ log(dict(extras,
67+ type='error',
68+ record=stream.index,
69+ field='.domain',
70+ message=_(u"Domain could not be parsed '%s'") % record['.domain']))
71
72 converted = convert(record, lambda field, err:\
73 _log(dict(extras, record=stream.index, field=field_names[field]), field, err))