Merge lp:~camptocamp/openobject-addons/extra-6.0-syleam-document_csv-improvements into lp:~syleam/openobject-addons/extra-6.0-syleam
- extra-6.0-syleam-document_csv-improvements
- Merge into extra-6.0-syleam
Status: | Merged |
---|---|
Merged at revision: | 96 |
Proposed branch: | lp:~camptocamp/openobject-addons/extra-6.0-syleam-document_csv-improvements |
Merge into: | lp:~syleam/openobject-addons/extra-6.0-syleam |
Diff against target: |
870 lines (+371/-281) 14 files modified
document_csv/__openerp__.py (+2/-1) document_csv/document.py (+82/-1) document_csv/document_view.xml (+2/-1) document_csv/ir_attachment.py (+11/-6) document_csv/menu_view.xml (+1/-1) document_csv/wizard/export_yml.py (+72/-93) document_csv/wizard/export_yml_view.xml (+36/-0) document_csv/wizard/import_yml.py (+101/-128) document_csv/wizard/import_yml_view.xml (+42/-0) document_csv/wizard/launch.py (+13/-2) document_csv/wizard/launch_view.xml (+3/-1) document_csv/wizard/read_csv.py (+4/-0) document_csv/wizard/read_csv_view.xml (+2/-1) document_csv/wizard/wizard.xml (+0/-46) |
To merge this branch: | bzr merge lp:~camptocamp/openobject-addons/extra-6.0-syleam-document_csv-improvements |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Sylvain Garancher (community) | Approve | ||
openerp-syleam | Pending | ||
Review via email: mp+83785@code.launchpad.net |
Commit message
Description of the change
Hello,
Here is some improvements for your 6.0 branch on the document_csv module.
That's thoses I've done for 6.1 and backported for the 6.0 version.
- Ported old wizard.interface wizards to osv_memory
- Button to generate a structure with all fields of a model
- Choose in which translation import a file
- use /id and /.id as specified in the import_data documentation in orm.py
- Fixed the menu and misplaced and a cast on a variable
Do you agree to merge that ?
Thanks
Guewen
- 101. By Yannick Vaucher @ Camptocamp
-
[ADD] document_csv - field auto-completion option from csv in document import list
Yannick Vaucher @ Camptocamp (yvaucher-c2c) wrote : | # |
- 102. By Guewen Baconnier @ Camptocamp <email address hidden>
-
[FIX] allow to get references by db id or xmlid also for sub-lines (relation and relation field selected like bom_lines/
product_ uom/.id when importing a mrp.bom) - 103. By Guewen Baconnier @ Camptocamp <email address hidden>
-
[IMP] review auto-completion
Guewen Baconnier @ Camptocamp (gbaconnier-c2c) wrote : | # |
Hello,
I just commit 2 new revisions:
- Now the selection DB ID / ID / Search is also applied on sub items searches like bom_lines/
- Some modifications on the Yannick's autocompletion
Do you agree to merge please ?
Thanks
Guewen
- 104. By Guewen Baconnier @ Camptocamp <email address hidden>
-
[FIX] help message
Sylvain Garancher (sylvain-garancher) : | # |
Preview Diff
1 | === modified file 'document_csv/__openerp__.py' |
2 | --- document_csv/__openerp__.py 2011-11-11 10:21:25 +0000 |
3 | +++ document_csv/__openerp__.py 2012-01-11 07:46:28 +0000 |
4 | @@ -44,9 +44,10 @@ |
5 | 'format_data.xml', |
6 | 'directory_data.xml', |
7 | 'content_type_data.xml', |
8 | - 'wizard/wizard.xml', |
9 | 'wizard/launch_view.xml', |
10 | 'wizard/read_csv_view.xml', |
11 | + 'wizard/export_yml_view.xml', |
12 | + 'wizard/import_yml_view.xml', |
13 | 'document_view.xml', |
14 | #'export_view.xml', |
15 | ], |
16 | |
17 | === modified file 'document_csv/document.py' |
18 | --- document_csv/document.py 2011-11-11 10:21:25 +0000 |
19 | +++ document_csv/document.py 2012-01-11 07:46:28 +0000 |
20 | @@ -3,6 +3,8 @@ |
21 | # |
22 | # document_csv module for OpenERP |
23 | # Copyright (C) 2009-2011 SYLEAM (<http://www.syleam.fr>) Christophe CHAUVET |
24 | +# Copyright (C) 2011 Camptocamp (http://www.camptocamp.com) |
25 | +# Guewen Baconnier |
26 | # |
27 | # This file is a part of document_csv |
28 | # |
29 | @@ -99,7 +101,7 @@ |
30 | 'ctx': fields.char('Context', size=256, help='this part complete the original context'), |
31 | 'disable': fields.boolean('Disable', help='Check this, if you want to disable it'), |
32 | 'err_mail': fields.boolean('Send log by mail', help='The log file was send to all users of the groupes'), |
33 | - 'err_reject': fields.boolean('Reject all if error', help='Reject all lines if there is an error'), |
34 | + 'err_reject': fields.boolean('Reject all if error', help='Reject all lines if there is an error. You need to activate this flag if you import sub-items (like a BoM and its components) in the same file.'), |
35 | 'csv_sep': fields.char('Separator', size=1, required=True), |
36 | 'csv_esc': fields.char('Escape', size=1), |
37 | 'lang_id': fields.many2one('res.lang', 'Language', help='Language use in this import, to convert correctly date and float'), |
38 | @@ -158,6 +160,85 @@ |
39 | |
40 | return {'warning': False} |
41 | |
42 | + def _prepare_structure_line(self, cr, uid, ids, field, context=None): |
43 | + """ |
44 | + Prepare vals to write in document lines. |
45 | + @param field: browse instance of a field |
46 | + @return: dict of vals to write in the document for the field |
47 | + """ |
48 | + import_line_obj = self.pool.get('document.import.list.line') |
49 | + line_vals = { |
50 | + 'name': field.name, |
51 | + 'field_id': field.id, |
52 | + } |
53 | + onchange_res = import_line_obj.onchange_model_field(cr, uid, [], field.id, context=context) |
54 | + line_vals.update(onchange_res['value']) |
55 | + return line_vals |
56 | + |
57 | + def _get_model_fields(self, cr, uid, model_id, context=None): |
58 | + fields_obj = self.pool.get('ir.model.fields') |
59 | + ctx_import = context.copy() |
60 | + ctx_import.update({'import': True}) |
61 | + |
62 | + all_field_ids = fields_obj.search(cr, uid, |
63 | + [('model_id', '=', model_id), |
64 | + ('readonly', '=', False)], |
65 | + context=ctx_import, order='name asc') |
66 | + return all_field_ids |
67 | + |
68 | + def complete_structure_from_model(self, cr, uid, ids, context=None): |
69 | + context = context or {} |
70 | + if not isinstance(ids, list): |
71 | + ids = [ids] |
72 | + fields_obj = self.pool.get('ir.model.fields') |
73 | + for import_list in self.browse(cr, uid, ids, context=context): |
74 | + existing_lines = import_list.line_ids |
75 | + struct_fields_ids = self._get_model_fields(cr, uid, import_list.model_id.id, context) |
76 | + struct_fields = fields_obj.browse(cr, uid, struct_fields_ids, context) |
77 | + |
78 | + existing_line_names = [f.name for f in existing_lines] |
79 | + |
80 | + lines = [] |
81 | + # filter fields that match both list |
82 | + # then prepare those lines to be updated |
83 | + fields_to_replace = [(ef, sf) for ef in existing_lines for sf in struct_fields if ef.name[:].split('/')[0].split('.')[0] == sf.name] |
84 | + for field in fields_to_replace: |
85 | + line_vals = self._prepare_structure_line(cr, uid, ids, field[1], context=context) |
86 | + line_vals.update({'name': field[0].name}) # ensure that we keep the csv header name |
87 | + lines.append((1, field[0].id, line_vals)) |
88 | + |
89 | + # list fields that are mandatory but not listed in the csv file |
90 | + missing_fields = [sf for sf in struct_fields if sf.name not in existing_line_names and sf.required == 't'] |
91 | + for field in missing_fields: |
92 | + line_vals = self._prepare_structure_line(cr, uid, ids, field, context=context) |
93 | + lines.append((0, 0, line_vals)) |
94 | + |
95 | + self.write(cr, uid, import_list.id, |
96 | + {'line_ids': lines}, |
97 | + context=context) |
98 | + return True |
99 | + |
100 | + def generate_structure_from_model(self, cr, uid, ids, context=None): |
101 | + fields_obj = self.pool.get('ir.model.fields') |
102 | + for import_list in self.browse(cr, uid, ids, context=context): |
103 | + existing_fields_ids = [il_field.id for il_field in [l.field_id for l in import_list.line_ids]] |
104 | + all_fields_ids = self._get_model_fields(cr, uid, import_list.model_id.id, context=context) |
105 | + # keep only non existing fields but keep the sort |
106 | + fields_to_add_ids = [f_id for f_id in all_fields_ids if f_id not in existing_fields_ids] |
107 | + |
108 | + lines = [] |
109 | + for field in fields_obj.browse(cr, uid, fields_to_add_ids, context=context): |
110 | + line_vals = self._prepare_structure_line(cr, uid, ids, field, context=context) |
111 | + if line_vals: |
112 | + lines.append((0, 0, line_vals)) |
113 | + |
114 | + self.write(cr, uid, import_list.id, |
115 | + {'line_ids': lines}, |
116 | + context=context) |
117 | + |
118 | + return True |
119 | + |
120 | + |
121 | import_list() |
122 | |
123 | |
124 | |
125 | === modified file 'document_csv/document_view.xml' |
126 | --- document_csv/document_view.xml 2011-11-11 10:21:25 +0000 |
127 | +++ document_csv/document_view.xml 2012-01-11 07:46:28 +0000 |
128 | @@ -123,7 +123,8 @@ |
129 | <group colspan="2" col="2"> |
130 | <separator string="Actions" colspan="2"/> |
131 | <button string="Read CSV Header" type="action" name="%(document_csv.action_wizard_read_csv_file_view)d" colspan="2"/> |
132 | - <button string="Export structure" type="action" name="%(document_csv.document_csv_export_wizard)d" colspan="2"/> |
133 | + <button string="Generate structure from model" type="object" name="generate_structure_from_model" colspan="2"/> |
134 | + <button string="Export structure" type="action" name="%(document_csv.action_document_import_csv_export_yaml)d" colspan="2"/> |
135 | <separator string="Import file information" colspan="2"/> |
136 | <field name="csv_sep"/> |
137 | <field name="csv_esc"/> |
138 | |
139 | === modified file 'document_csv/ir_attachment.py' |
140 | --- document_csv/ir_attachment.py 2011-11-23 11:00:10 +0000 |
141 | +++ document_csv/ir_attachment.py 2012-01-11 07:46:28 +0000 |
142 | @@ -4,6 +4,8 @@ |
143 | # document_csv module for OpenERP, Import structure in CSV |
144 | # Copyright (C) 2011 SYLEAM (<http://www.syleam.fr/>) |
145 | # Christophe CHAUVET <christophe.chauvet@syleam.fr> |
146 | +# Copyright (C) 2011 Camptocamp (http://www.camptocamp.com) |
147 | +# Guewen Baconnier |
148 | # |
149 | # This file is a part of document_csv |
150 | # |
151 | @@ -88,7 +90,7 @@ |
152 | args = { |
153 | 'name': l.name, |
154 | 'field': l.field_id.name, |
155 | - 'rel_field': l .field_relation_id.name, |
156 | + 'rel_field': l.field_relation_id.name, |
157 | 'type': l.field_id.ttype, |
158 | 'relation': l.field_id.relation, |
159 | 'key': l.refkey, |
160 | @@ -113,7 +115,7 @@ |
161 | header.append(u'id') |
162 | if rel_uniq_key: |
163 | for x in rel_uniq_key: |
164 | - header.append('%s:id' % x) |
165 | + header.append('%s/id' % x) |
166 | |
167 | for h in fld: |
168 | rej_header.append(h['name']) |
169 | @@ -121,11 +123,14 @@ |
170 | header.append(h['field']) |
171 | else: |
172 | if h['rel_field']: |
173 | - header.append('%s/%s' % (h['field'], h['rel_field'])) |
174 | - elif h['ref'] in ('id', 'db_id'): |
175 | - header.append('%s:%s' % (h['field'], h['ref'])) |
176 | + base_field = '%s/%s' % (h['field'], h['rel_field']) |
177 | else: |
178 | - header.append(h['field']) |
179 | + base_field = h['field'] |
180 | + if h['ref'] == 'db_id': |
181 | + base_field = '%s/.id' % (base_field,) |
182 | + elif h['ref'] == 'id': |
183 | + base_field = '%s/id' % (base_field,) |
184 | + header.append(base_field) |
185 | |
186 | _logger.debug('module document_csv: ' + log_compose('%s: %s' % ('Object', imp_data.model_id.model))) |
187 | _logger.debug('module document_csv: ' + log_compose('%s: %r' % ('Context', context))) |
188 | |
189 | === modified file 'document_csv/menu_view.xml' |
190 | --- document_csv/menu_view.xml 2011-11-11 10:21:25 +0000 |
191 | +++ document_csv/menu_view.xml 2012-01-11 07:46:28 +0000 |
192 | @@ -32,7 +32,7 @@ |
193 | <menuitem id="menu_document_import_configuration" |
194 | sequence="30" |
195 | name="Exchange Datas" |
196 | - parent="base.menu_lunch_survey_root"/> |
197 | + parent="base.menu_tools"/> |
198 | |
199 | </data> |
200 | </openerp> |
201 | |
202 | === modified file 'document_csv/wizard/export_yml.py' |
203 | --- document_csv/wizard/export_yml.py 2011-11-11 10:21:25 +0000 |
204 | +++ document_csv/wizard/export_yml.py 2012-01-11 07:46:28 +0000 |
205 | @@ -3,6 +3,7 @@ |
206 | # |
207 | # document_csv module for OpenERP |
208 | # Copyright (C) 2009-2011 SYLEAM (<http://www.syleam.fr>) Christophe CHAUVET |
209 | +# Copyright (C) 2011 Camptocamp Guewen Baconnier |
210 | # |
211 | # This file is a part of document_csv |
212 | # |
213 | @@ -21,103 +22,81 @@ |
214 | # |
215 | ############################################################################## |
216 | |
217 | -import wizard |
218 | -import pooler |
219 | -from cStringIO import StringIO |
220 | +from osv import osv, fields |
221 | +try: |
222 | + from cStringIO import StringIO |
223 | +except ImportError: |
224 | + from StringIO import StringIO |
225 | import base64 |
226 | from tools.translate import _ |
227 | |
228 | -init_form = """<?xml version="1.0" ?> |
229 | -<form string="Export file structure"> |
230 | - <separator string="The export file is available, save it to a local drive" colspan="4"/> |
231 | - <field name="name" invisible="1"/> |
232 | - <field name="filename" colspan="4" width="350" fieldname="name" readonly="1"/> |
233 | -</form> |
234 | -""" |
235 | - |
236 | -init_fields = { |
237 | - 'name': {'string': 'File name', 'type': 'char', 'size': 128}, |
238 | - 'filename': {'string': 'Select a filename, and save it', 'type': 'binary', 'required': True, 'filters': '*.yml'}, |
239 | -} |
240 | - |
241 | - |
242 | -def _init(self, cr, uid, data, context): |
243 | - if context is None: |
244 | - context = {} |
245 | - |
246 | - try: |
247 | - import yaml |
248 | - except ImportError: |
249 | - raise wizard.except_wizard(_('Error'), _('Python Yaml Module not found, see description module')) |
250 | - pool = pooler.get_pool(cr.dbname) |
251 | - doc_obj = pool.get('document.import.list') |
252 | - doc = doc_obj.browse(cr, uid, data['id'], context=context) |
253 | - yml_file = '%s.yml' % doc.name.lower().replace(' ', '_').replace('-', '') |
254 | - content = { |
255 | - 'version': '1.3', |
256 | - 'name': doc.name, |
257 | - 'object': doc.model_id.model, |
258 | - 'context': doc.ctx, |
259 | - 'separator': doc.csv_sep, |
260 | - 'escape': doc.csv_esc, |
261 | - 'encoding': doc.encoding, |
262 | - 'key_field_name': doc.key_field_name, |
263 | - 'reject_all': doc.err_reject, |
264 | - 'log_filename': doc.log_filename, |
265 | - 'reject_filename': doc.reject_filename, |
266 | - 'backup_filename': doc.backup_filename, |
267 | - 'lang': doc.lang_id.code or 'en_US', |
268 | - 'notes': doc.notes or '', |
269 | - 'send_mail': doc.err_mail, |
270 | - 'mail_from': doc.mail_from, |
271 | - 'mail_cc': doc.mail_cc, |
272 | - 'mail_subject': doc.mail_subject, |
273 | - 'mail_body': doc.mail_body, |
274 | - 'mail_cc_err': doc.mail_cc_err, |
275 | - 'mail_subject_err': doc.mail_subject_err, |
276 | - 'mail_body_err': doc.mail_body_err, |
277 | +class ExportYaml(osv.osv_memory): |
278 | + |
279 | + _name = 'document.import.csv.export.yaml' |
280 | + |
281 | + _columns = { |
282 | + 'name': fields.char('Filename', size=128), |
283 | + 'filename': fields.binary('Select a filename and save it', required=True, filters='*.yml'), |
284 | } |
285 | - lines = [] |
286 | - for l in doc.line_ids: |
287 | - line = {} |
288 | - line['name'] = l.name |
289 | - line['field'] = l.field_id.name |
290 | - if l.field_id.ttype in ('many2one', 'one2many', 'many2many'): |
291 | - line['model'] = l.model_relation_id.model and str(l.model_relation_id.model) or False |
292 | - line['model_field'] = l.field_relation_id.name and str(l.field_relation_id.name) or False |
293 | - line['relation'] = l.relation and str(l.relation) or False |
294 | - line['refkey'] = l.refkey |
295 | - lines.append(line) |
296 | - |
297 | - content['lines'] = lines |
298 | - buf = StringIO() |
299 | - buf.write(yaml.dump(content, encoding='utf-8', default_flow_style=False)) |
300 | - out = base64.encodestring(buf.getvalue()) |
301 | - buf.close() |
302 | - return {'filename': out, 'name': yml_file} |
303 | - |
304 | - |
305 | -class export_yaml(wizard.interface): |
306 | - |
307 | - states = { |
308 | - 'init': { |
309 | - 'actions': [_init], |
310 | - 'result': { |
311 | - 'type': 'form', |
312 | - 'arch': init_form, |
313 | - 'fields': init_fields, |
314 | - 'state': [('end', 'Cancel', 'gtk-cancel'), ('valid', 'OK', 'gtk-ok', True)], |
315 | - } |
316 | - }, |
317 | - 'valid': { |
318 | - 'actions': [], |
319 | - 'result': { |
320 | - 'type': 'state', |
321 | - 'state': 'end' |
322 | - } |
323 | + |
324 | + def default_get(self, cr, uid, fields_list, context=None): |
325 | + if context is None: context = {} |
326 | + res = super(ExportYaml, self).default_get(cr, uid, fields_list, context=context) |
327 | + |
328 | + try: |
329 | + import yaml |
330 | + except ImportError: |
331 | + raise osv.except_osv(_('Error'), _('Python Yaml Module not found, see description module')) |
332 | + |
333 | + doc_id = context.get('active_id') |
334 | + doc_obj = self.pool.get('document.import.list') |
335 | + doc = doc_obj.browse(cr, uid, doc_id, context=context) |
336 | + |
337 | + yml_file = '%s.yml' % doc.name.lower().replace(' ', '_').replace('-', '') |
338 | + content = { |
339 | + 'version': '1.3', |
340 | + 'name': doc.name, |
341 | + 'object': doc.model_id.model, |
342 | + 'context': doc.ctx, |
343 | + 'separator': doc.csv_sep, |
344 | + 'escape': doc.csv_esc, |
345 | + 'encoding': doc.encoding, |
346 | + 'key_field_name': doc.key_field_name, |
347 | + 'reject_all': doc.err_reject, |
348 | + 'log_filename': doc.log_filename, |
349 | + 'reject_filename': doc.reject_filename, |
350 | + 'backup_filename': doc.backup_filename, |
351 | + 'lang': doc.lang_id.code or 'en_US', |
352 | + 'notes': doc.notes or '', |
353 | + 'send_mail': doc.err_mail, |
354 | + 'mail_from': doc.mail_from, |
355 | + 'mail_cc': doc.mail_cc, |
356 | + 'mail_subject': doc.mail_subject, |
357 | + 'mail_body': doc.mail_body, |
358 | + 'mail_cc_err': doc.mail_cc_err, |
359 | + 'mail_subject_err': doc.mail_subject_err, |
360 | + 'mail_body_err': doc.mail_body_err, |
361 | } |
362 | - } |
363 | - |
364 | -export_yaml('document_csv.export') |
365 | + lines = [] |
366 | + for l in doc.line_ids: |
367 | + line = {} |
368 | + line['name'] = l.name |
369 | + line['field'] = l.field_id.name |
370 | + if l.field_id.ttype in ('many2one', 'one2many', 'many2many'): |
371 | + line['model'] = l.model_relation_id.model and str(l.model_relation_id.model) or False |
372 | + line['model_field'] = l.field_relation_id.name and str(l.field_relation_id.name) or False |
373 | + line['relation'] = l.relation and str(l.relation) or False |
374 | + line['refkey'] = l.refkey |
375 | + lines.append(line) |
376 | + |
377 | + content['lines'] = lines |
378 | + buf = StringIO() |
379 | + buf.write(yaml.dump(content, encoding='utf-8', default_flow_style=False)) |
380 | + out = base64.encodestring(buf.getvalue()) |
381 | + buf.close() |
382 | + res.update({'filename': out, 'name': yml_file}) |
383 | + return res |
384 | + |
385 | +ExportYaml() |
386 | |
387 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
388 | |
389 | === added file 'document_csv/wizard/export_yml_view.xml' |
390 | --- document_csv/wizard/export_yml_view.xml 1970-01-01 00:00:00 +0000 |
391 | +++ document_csv/wizard/export_yml_view.xml 2012-01-11 07:46:28 +0000 |
392 | @@ -0,0 +1,36 @@ |
393 | +<?xml version="1.0" encoding="UTF-8"?> |
394 | +<openerp> |
395 | + <data> |
396 | + |
397 | + <record id="view_document_import_csv_export_yaml_form" model="ir.ui.view"> |
398 | + <field name="name">document.import.csv.export.yaml.form</field> |
399 | + <field name="model">document.import.csv.export.yaml</field> |
400 | + <field name="type">form</field> |
401 | + <field name="priority" eval="8"/> |
402 | + <field name="arch" type="xml"> |
403 | + <form string="Export file structure"> |
404 | + <separator string="The export file is available, save it to a local drive" colspan="4"/> |
405 | + <field name="name" invisible="1"/> |
406 | + <field name="filename" colspan="4" width="350" fieldname="name" readonly="1"/> |
407 | + <separator string=""/> |
408 | + <group colspan="4" col="6"> |
409 | + <label string ="" colspan="2"/> |
410 | + <button icon="gtk-cancel" special="cancel" string="Close"/> |
411 | + </group> |
412 | + </form> |
413 | + </field> |
414 | + </record> |
415 | + |
416 | + <record model="ir.actions.act_window" id="action_document_import_csv_export_yaml"> |
417 | + <field name="name">Export Yaml</field> |
418 | + <field name="type">ir.actions.act_window</field> |
419 | + <field name="res_model">document.import.csv.export.yaml</field> |
420 | + <field name="view_type">form</field> |
421 | + <field name="view_mode">form</field> |
422 | + <field name="domain">[]</field> |
423 | + <field name="context">{}</field> |
424 | + <field name="target">new</field> |
425 | + </record> |
426 | + |
427 | + </data> |
428 | +</openerp> |
429 | |
430 | === modified file 'document_csv/wizard/import_yml.py' |
431 | --- document_csv/wizard/import_yml.py 2011-11-11 10:21:25 +0000 |
432 | +++ document_csv/wizard/import_yml.py 2012-01-11 07:46:28 +0000 |
433 | @@ -21,140 +21,113 @@ |
434 | # |
435 | ############################################################################## |
436 | |
437 | -import wizard |
438 | -import pooler |
439 | import base64 |
440 | import yaml |
441 | +from osv import osv, fields |
442 | from tools.translate import _ |
443 | |
444 | -init_form = """<?xml version="1.0" ?> |
445 | -<form string="Import CSV structure"> |
446 | - <field name="name" colspan="4"/> |
447 | - <separator string="Select file to import" colspan="4"/> |
448 | - <field name="filename" colspan="4" width="350"/> |
449 | -</form> |
450 | -""" |
451 | - |
452 | -init_fields = { |
453 | - 'filename': {'string': 'Select File', 'type': 'binary', 'required': True, 'filters': '*.yml'}, |
454 | - 'name': {'string': 'Name of the new import', 'type': 'char', 'size': 64, 'required': False}, |
455 | -} |
456 | - |
457 | - |
458 | -def _import(self, cr, uid, data, context): |
459 | - if context is None: |
460 | - context = {} |
461 | - |
462 | - pool = pooler.get_pool(cr.dbname) |
463 | - model_obj = pool.get('ir.model') |
464 | - fld_obj = pool.get('ir.model.fields') |
465 | - dat_obj = pool.get('ir.model.data') |
466 | - dir_obj = pool.get('document.directory') |
467 | - imp_obj = pool.get('document.import.list') |
468 | - act_obj = pool.get('ir.actions.act_window') |
469 | - |
470 | - context['import'] = True |
471 | - |
472 | - content = base64.decodestring(data['form']['filename']) |
473 | - st = yaml.load(content) |
474 | - |
475 | - # Search the model_id |
476 | - mod_ids = model_obj.search(cr, uid, [('model', '=', st['object'])]) |
477 | - if not mod_ids: |
478 | - raise wizard.except_wizard(_('Error'), |
479 | - _('No model name %s found') % st['object']) |
480 | - mod_id = mod_ids[0] |
481 | - imp = { |
482 | - 'name': data['form']['name'] or st['name'], |
483 | - 'ctx': st['context'], |
484 | - 'model_id': mod_id, |
485 | - 'csv_sep': st.get('separator', ';'), |
486 | - 'csv_esc': st.get('escape', '"'), |
487 | - 'encoding': st.get('encoding', 'utf-8'), |
488 | +class ImportYaml(osv.osv_memory): |
489 | + _name = 'document.import.csv.import.yaml' |
490 | + |
491 | + _columns = { |
492 | + 'filename': fields.binary('Select file to import', required=True, filters='*.yml'), |
493 | + 'name': fields.char('Name of the new import', size=64), |
494 | } |
495 | - if st.get('version', '0.0') >= '1.1': |
496 | - imp['err_reject'] = st.get('reject_all', False) |
497 | - imp['log_filename'] = st.get('log_filename', False) |
498 | - imp['reject_filename'] = st.get('reject_filename', False) |
499 | - imp['backup_filename'] = st.get('backup_filename', False) |
500 | - |
501 | - if st.get('version', '0.0') >= '1.2': |
502 | - imp['notes'] = st.get('notes', False) |
503 | - imp['lang'] = st.get('lang', 'en_US') |
504 | - imp['err_mail'] = st.get('send_mail', False) |
505 | - imp['mail_from'] = st.get('mail_from', False) |
506 | - imp['mail_cc'] = st.get('mail_cc', False) |
507 | - imp['mail_subject'] = st.get('mail_subject', False) |
508 | - imp['mail_body'] = st.get('mail_body', False) |
509 | - imp['mail_cc_err'] = st.get('mail_cc_err', False) |
510 | - imp['mail_subject_err'] = st.get('mail_subject_err', False) |
511 | - imp['mail_body_err'] = st.get('mail_body_err', False) |
512 | - |
513 | - if st.get('version', '0.0') >= '1.3': |
514 | - imp['key_field_name'] = st.get('key_field_name', False) |
515 | - |
516 | - lines_ids = [] |
517 | - for i in st['lines']: |
518 | - # The field id associate to the name |
519 | - fld_ids = fld_obj.search(cr, uid, [('model_id', '=', mod_id), ('name', '=', i['field'])], context=context) |
520 | - if not fld_ids: |
521 | - raise wizard.except_wizard(_('Error'), _('No field %s found in the object') % i['field']) |
522 | - |
523 | - l = { |
524 | - 'name': i['name'], |
525 | - 'field_id': fld_ids[0], |
526 | - 'relation': i.get('relation', False), |
527 | - 'refkey': i.get('refkey', False), |
528 | + |
529 | + def action_import(self, cr, uid, ids, context): |
530 | + if context is None: |
531 | + context = {} |
532 | + |
533 | + context['import'] = True |
534 | + |
535 | + model_obj = self.pool.get('ir.model') |
536 | + fld_obj = self.pool.get('ir.model.fields') |
537 | + dat_obj = self.pool.get('ir.model.data') |
538 | + imp_obj = self.pool.get('document.import.list') |
539 | + act_obj = self.pool.get('ir.actions.act_window') |
540 | + |
541 | + form_id = ids |
542 | + if isinstance(form_id, list): |
543 | + form_id = form_id[0] |
544 | + form = self.read(cr, uid, form_id, context=context) |
545 | + |
546 | + content = base64.decodestring(form['filename']) |
547 | + st = yaml.load(content) |
548 | + |
549 | + # Search the model_id |
550 | + mod_ids = model_obj.search(cr, uid, [('model', '=', st['object'])]) |
551 | + if not mod_ids: |
552 | + raise osv.except_osv(_('Error'), |
553 | + _('No model name %s found') % st['object']) |
554 | + mod_id = mod_ids[0] |
555 | + imp = { |
556 | + 'name': form['name'] or st['name'], |
557 | + 'ctx': st['context'], |
558 | + 'model_id': mod_id, |
559 | + 'csv_sep': st.get('separator', ';'), |
560 | + 'csv_esc': st.get('escape', '"'), |
561 | + 'encoding': st.get('encoding', 'utf-8'), |
562 | } |
563 | - if i.get('model') and i.get('model') not in ('None', 'False'): |
564 | - mod_ids = model_obj.search(cr, uid, [('model', '=', i['model'])]) |
565 | - if not mod_ids: |
566 | - raise wizard.except_wizard(_('Error'), |
567 | - _('No model name %s found') % i['model']) |
568 | - |
569 | - l['model_relation_id'] = mod_ids[0] |
570 | - if i.get('model_field') and i.get('model_field') not in ('None', 'False'): |
571 | - fld_ids = fld_obj.search(cr, uid, [('model_id', '=', mod_ids[0]), ('name', '=', i['model_field'])]) |
572 | + if st.get('version', '0.0') >= '1.1': |
573 | + imp['err_reject'] = st.get('reject_all', False) |
574 | + imp['log_filename'] = st.get('log_filename', False) |
575 | + imp['reject_filename'] = st.get('reject_filename', False) |
576 | + imp['backup_filename'] = st.get('backup_filename', False) |
577 | + |
578 | + if st.get('version', '0.0') >= '1.2': |
579 | + imp['notes'] = st.get('notes', False) |
580 | + imp['lang'] = st.get('lang', 'en_US') |
581 | + imp['err_mail'] = st.get('send_mail', False) |
582 | + imp['mail_from'] = st.get('mail_from', False) |
583 | + imp['mail_cc'] = st.get('mail_cc', False) |
584 | + imp['mail_subject'] = st.get('mail_subject', False) |
585 | + imp['mail_body'] = st.get('mail_body', False) |
586 | + imp['mail_cc_err'] = st.get('mail_cc_err', False) |
587 | + imp['mail_subject_err'] = st.get('mail_subject_err', False) |
588 | + imp['mail_body_err'] = st.get('mail_body_err', False) |
589 | + |
590 | + if st.get('version', '0.0') >= '1.3': |
591 | + imp['key_field_name'] = st.get('key_field_name', False) |
592 | + |
593 | + lines_ids = [] |
594 | + for i in st['lines']: |
595 | + # The field id associate to the name |
596 | + fld_ids = fld_obj.search(cr, uid, [('model_id', '=', mod_id), ('name', '=', i['field'])], context=context) |
597 | if not fld_ids: |
598 | - raise wizard.except_wizard(_('Error'), _('No field %s found in the object') % i['model_field']) |
599 | - l['field_relation_id'] = fld_ids[0] |
600 | - |
601 | - lines_ids.append((0, 0, l)) |
602 | - imp['line_ids'] = lines_ids |
603 | - |
604 | - imp_id = imp_obj.create(cr, uid, imp, context=context) |
605 | - if not imp_id: |
606 | - raise wizard.except_wizard(_('Error'), _('Failed to create the list entry')) |
607 | - |
608 | - result = dat_obj._get_id(cr, uid, 'document_csv', 'action_document_import_list') |
609 | - id = dat_obj.read(cr, uid, result, ['res_id'])['res_id'] |
610 | - result = act_obj.read(cr, uid, id) |
611 | - result['domain'] = "[('id','in', [" + ','.join(map(str, [imp_id])) + "])]" |
612 | - return result |
613 | - |
614 | - |
615 | -class import_yaml(wizard.interface): |
616 | - |
617 | - states = { |
618 | - 'init': { |
619 | - 'actions': [], |
620 | - 'result': { |
621 | - 'type': 'form', |
622 | - 'arch': init_form, |
623 | - 'fields': init_fields, |
624 | - 'state': [('end', 'Cancel', 'gtk-cancel'), ('valid', 'OK', 'gtk-ok', True)], |
625 | - } |
626 | - }, |
627 | - 'valid': { |
628 | - 'actions': [], |
629 | - 'result': { |
630 | - 'type': 'action', |
631 | - 'action': _import, |
632 | - 'state': 'end' |
633 | - } |
634 | - } |
635 | - } |
636 | - |
637 | -import_yaml('document_csv.import') |
638 | + raise osv.except_osv(_('Error'), _('No field %s found in the object') % i['field']) |
639 | + |
640 | + l = { |
641 | + 'name': i['name'], |
642 | + 'field_id': fld_ids[0], |
643 | + 'relation': i.get('relation', False), |
644 | + 'refkey': i.get('refkey', False), |
645 | + } |
646 | + if i.get('model') and i.get('model') not in ('None', 'False'): |
647 | + mod_ids = model_obj.search(cr, uid, [('model', '=', i['model'])]) |
648 | + if not mod_ids: |
649 | + raise osv.except_osv(_('Error'), |
650 | + _('No model name %s found') % i['model']) |
651 | + |
652 | + l['model_relation_id'] = mod_ids[0] |
653 | + if i.get('model_field') and i.get('model_field') not in ('None', 'False'): |
654 | + fld_ids = fld_obj.search(cr, uid, [('model_id', '=', mod_ids[0]), ('name', '=', i['model_field'])]) |
655 | + if not fld_ids: |
656 | + raise osv.except_osv(_('Error'), _('No field %s found in the object') % i['model_field']) |
657 | + l['field_relation_id'] = fld_ids[0] |
658 | + |
659 | + lines_ids.append((0, 0, l)) |
660 | + imp['line_ids'] = lines_ids |
661 | + |
662 | + imp_id = imp_obj.create(cr, uid, imp, context=context) |
663 | + if not imp_id: |
664 | + raise osv.except_osv(_('Error'), _('Failed to create the list entry')) |
665 | + |
666 | + result = dat_obj._get_id(cr, uid, 'document_csv', 'action_document_import_list') |
667 | + id = dat_obj.read(cr, uid, result, ['res_id'])['res_id'] |
668 | + result = act_obj.read(cr, uid, id) |
669 | + result['domain'] = "[('id','in', [" + ','.join(map(str, [imp_id])) + "])]" |
670 | + return result |
671 | + |
672 | +ImportYaml() |
673 | |
674 | # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: |
675 | |
676 | === added file 'document_csv/wizard/import_yml_view.xml' |
677 | --- document_csv/wizard/import_yml_view.xml 1970-01-01 00:00:00 +0000 |
678 | +++ document_csv/wizard/import_yml_view.xml 2012-01-11 07:46:28 +0000 |
679 | @@ -0,0 +1,42 @@ |
680 | +<?xml version="1.0" encoding="UTF-8"?> |
681 | +<openerp> |
682 | + <data> |
683 | + |
684 | + <record id="view_document_import_csv_import_yaml_form" model="ir.ui.view"> |
685 | + <field name="name">document.import.csv.import.yaml.form</field> |
686 | + <field name="model">document.import.csv.import.yaml</field> |
687 | + <field name="type">form</field> |
688 | + <field name="priority" eval="8"/> |
689 | + <field name="arch" type="xml"> |
690 | + <form string="Import file structure"> |
691 | + <field name="name" colspan="4"/> |
692 | + <field name="filename" colspan="4" width="350"/> |
693 | + <separator string=""/> |
694 | + <group colspan="4" col="6"> |
695 | + <label string ="" colspan="2"/> |
696 | + <button icon="gtk-cancel" special="cancel" string="Close"/> |
697 | + <button icon="terp-gtk-go-back-rtl" string="Import Yaml structure" name="action_import" type="object" default_focus="1"/> |
698 | + </group> |
699 | + </form> |
700 | + </field> |
701 | + </record> |
702 | + |
703 | + <record model="ir.actions.act_window" id="action_document_import_csv_import_yaml"> |
704 | + <field name="name">Import Yaml</field> |
705 | + <field name="type">ir.actions.act_window</field> |
706 | + <field name="res_model">document.import.csv.import.yaml</field> |
707 | + <field name="view_type">form</field> |
708 | + <field name="view_mode">form</field> |
709 | + <field name="domain">[]</field> |
710 | + <field name="context">{}</field> |
711 | + <field name="target">new</field> |
712 | + </record> |
713 | + |
714 | + <menuitem id="menu_document_csv_import" |
715 | + sequence="20" |
716 | + name="Import Structure" |
717 | + action="action_document_import_csv_import_yaml" |
718 | + parent="menu_document_import_configuration"/> |
719 | + |
720 | + </data> |
721 | +</openerp> |
722 | |
723 | === modified file 'document_csv/wizard/launch.py' |
724 | --- document_csv/wizard/launch.py 2011-11-11 10:21:25 +0000 |
725 | +++ document_csv/wizard/launch.py 2012-01-11 07:46:28 +0000 |
726 | @@ -4,6 +4,8 @@ |
727 | # document_csv module for OpenERP, Import structure in CSV |
728 | # Copyright (C) 2011 SYLEAM (<http://www.syleam.fr/>) |
729 | # Christophe CHAUVET <christophe.chauvet@syleam.fr> |
730 | +# Copyright (C) 2011 Camptocamp (http://www.camptocamp.com) |
731 | +# Guewen Baconnier |
732 | # |
733 | # This file is a part of document_csv |
734 | # |
735 | @@ -41,6 +43,7 @@ |
736 | _columns = { |
737 | 'import_list': fields.selection(_import_list, 'List', help='List of available import structure', required=True), |
738 | 'import_file': fields.binary('Filename', required=True), |
739 | + 'lang_id': fields.many2one('res.lang', 'Language', help='Translation to update.'), |
740 | 'email_result': fields.char('Email', size=256, help='Email to send notification when import is finished'), |
741 | } |
742 | |
743 | @@ -52,15 +55,23 @@ |
744 | context = {} |
745 | |
746 | res = super(LaunchImport, self).default_get(cr, uid, fields_list, context=context) |
747 | - res['email_result'] = self.pool.get('res.users').browse(cr, uid, uid, context=context).user_email or '' |
748 | + user = self.pool.get('res.users').browse(cr, uid, uid, context=context) |
749 | + res['email_result'] = user.user_email or '' |
750 | + if context.get('lang'): |
751 | + res['lang_id'] = self.pool.get('res.lang').search(cr, uid, [('code', '=', context['lang'])], context=context) |
752 | return res |
753 | |
754 | def launch_import(self, cr, uid, ids, context=None): |
755 | """ |
756 | Save file, and execute importation |
757 | """ |
758 | + if context is None: |
759 | + context = {} |
760 | cur = self.browse(cr, uid, ids[0], context=context) |
761 | - self.pool.get('ir.attachment').import_csv(cr, uid, cur.import_list, cur.import_file, cur.email_result, context=context) |
762 | + ctx = context.copy() |
763 | + if cur.lang_id: |
764 | + ctx.update({'lang': cur.lang_id.code}) |
765 | + self.pool.get('ir.attachment').import_csv(cr, uid, int(cur.import_list), cur.import_file, cur.email_result, context=ctx) |
766 | return {'type': 'ir.actions.act_window_close'} |
767 | |
768 | LaunchImport() |
769 | |
770 | === modified file 'document_csv/wizard/launch_view.xml' |
771 | --- document_csv/wizard/launch_view.xml 2011-11-11 10:21:25 +0000 |
772 | +++ document_csv/wizard/launch_view.xml 2012-01-11 07:46:28 +0000 |
773 | @@ -35,7 +35,9 @@ |
774 | <field name="import_list" nolabel="1" /> |
775 | <separator string="Select file to import" colspan="4"/> |
776 | <field name="import_file" nolabel="1" /> |
777 | - <separator string="Email to send notificaiton when import is finished" colspan="4"/> |
778 | + <separator string="Translation to update from this file" colspan="4"/> |
779 | + <field name="lang_id" widget="selection" nolabel="1"/> |
780 | + <separator string="Email to send notification when import is finished" colspan="4"/> |
781 | <field name="email_result" nolabel="1" /> |
782 | <separator string="" colspan="4" /> |
783 | <group colspan="4" col="6"> |
784 | |
785 | === modified file 'document_csv/wizard/read_csv.py' |
786 | --- document_csv/wizard/read_csv.py 2011-11-11 10:21:25 +0000 |
787 | +++ document_csv/wizard/read_csv.py 2012-01-11 07:46:28 +0000 |
788 | @@ -40,6 +40,7 @@ |
789 | |
790 | _columns = { |
791 | 'import_file': fields.binary('Filename', required=True), |
792 | + 'auto_completion': fields.boolean('Automatic Completion', help="Auto-complete the fields and relations based on the header names if the header names are the same as the OpenERP field names."), |
793 | } |
794 | |
795 | def read_header(self, cr, uid, ids, context=None): |
796 | @@ -73,6 +74,9 @@ |
797 | finally: |
798 | fpcsv.close() |
799 | |
800 | + if cur.auto_completion: |
801 | + implist_obj.complete_structure_from_model(cr, uid, implist.id, context=context) |
802 | + |
803 | return {'type': 'ir.actions.act_window_close'} |
804 | |
805 | ReadCsv() |
806 | |
807 | === modified file 'document_csv/wizard/read_csv_view.xml' |
808 | --- document_csv/wizard/read_csv_view.xml 2011-11-11 10:21:25 +0000 |
809 | +++ document_csv/wizard/read_csv_view.xml 2012-01-11 07:46:28 +0000 |
810 | @@ -32,7 +32,8 @@ |
811 | <field name="arch" type="xml"> |
812 | <form string="Import Form"> |
813 | <separator string="Select file to analyse" colspan="4"/> |
814 | - <field name="import_file" nolabel="1" /> |
815 | + <field name="import_file" nolabel="1" colspan="4"/> |
816 | + <field name="auto_completion" /> |
817 | <separator string="" colspan="4" /> |
818 | <group colspan="4" col="6"> |
819 | <label string ="" colspan="2"/> |
820 | |
821 | === removed file 'document_csv/wizard/wizard.xml' |
822 | --- document_csv/wizard/wizard.xml 2011-11-11 10:21:25 +0000 |
823 | +++ document_csv/wizard/wizard.xml 1970-01-01 00:00:00 +0000 |
824 | @@ -1,46 +0,0 @@ |
825 | -<?xml version="1.0" encoding="UTF-8"?> |
826 | -<openerp> |
827 | - <data> |
828 | - ############################################################################## |
829 | - # |
830 | - # document_csv module for OpenERP |
831 | - # Copyright (C) 2009-2011 SYLEAM ([http://www.syleam.fr]) Christophe CHAUVET |
832 | - # |
833 | - # This file is a part of document_csv |
834 | - # |
835 | - # document_csv is free software: you can redistribute it and/or modify |
836 | - # it under the terms of the GNU General Public License as published by |
837 | - # the Free Software Foundation, either version 3 of the License, or |
838 | - # (at your option) any later version. |
839 | - # |
840 | - # document_csv is distributed in the hope that it will be useful, |
841 | - # but WITHOUT ANY WARRANTY; without even the implied warranty of |
842 | - # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
843 | - # GNU General Public License for more details. |
844 | - # |
845 | - # You should have received a copy of the GNU General Public License |
846 | - # along with this program. If not, see [http://www.gnu.org/licenses/]. |
847 | - # |
848 | - ############################################################################## |
849 | - |
850 | - <wizard id="document_csv_export_wizard" |
851 | - name="document_csv.export" |
852 | - model="document.import.list" |
853 | - menu="False" |
854 | - string="Export structure"/> |
855 | - |
856 | - <wizard id='document_csv_import_wizard' |
857 | - name="document_csv.import" |
858 | - model="document.import.list" |
859 | - string="Import structure" |
860 | - menu="False"/> |
861 | - |
862 | - <menuitem id="menu_document_csv_import" |
863 | - sequence="20" |
864 | - name="Import Structure" |
865 | - action="document_csv_import_wizard" |
866 | - parent="menu_document_import_configuration" |
867 | - type="wizard"/> |
868 | - |
869 | - </data> |
870 | -</openerp> |
Hello,
I just added an option in csv import wizard to auto fill fields of the document import lines.
It also adds all fields that are mandatory to the column list.
Regards,
Yannick